From c3a938b2fffe76aa6c93af453d07ecaf5fda50eb Mon Sep 17 00:00:00 2001 From: vatka Date: Fri, 12 Jan 2024 16:34:02 +0200 Subject: [PATCH 01/21] Implementing responsive dialog box + Responsive buttons + Responsive dialog text box + Limit on text in buttons + Ability to set fixed button size --- src/dialog.ts | 14 ++++++++++++++ src/types.ts | 1 + src/ui.tsx | 38 +++++++++++++++++++++++++------------- 3 files changed, 40 insertions(+), 13 deletions(-) diff --git a/src/dialog.ts b/src/dialog.ts index 17e6eb2..cb880ba 100644 --- a/src/dialog.ts +++ b/src/dialog.ts @@ -182,11 +182,25 @@ export function getButtonText(button:number){ let dialogData = npcDialogComponent.get(activeNPC) if(dialogData.isQuestion && dialogData.buttons > button){ text = dialogData.script[dialogData.index].buttons[button].label + text = text.slice(0, 15) } } return text } +export function getbuttonSize(button:number) { + let ButtonSize: number | string | undefined + if (activeNPC != 0 && npcDialogComponent.has(activeNPC)) { + let dialogData = npcDialogComponent.get(activeNPC); + if (dialogData.isQuestion && dialogData.buttons > button) { + if (dialogData.script[dialogData.index].buttons[button].size !== undefined) { + ButtonSize = dialogData.script[dialogData.index].buttons[button]?.size; + } + } + } + return ButtonSize +} + export function getFontSize(){ return !isActiveNpcSet() ? 22 : npcDialogComponent.get(activeNPC).fontSize } diff --git a/src/types.ts b/src/types.ts index 2910f8e..c091dbe 100644 --- a/src/types.ts +++ b/src/types.ts @@ -80,6 +80,7 @@ export type ButtonData = { fontSize?: number offsetX?: number offsetY?: number + size?: number | string } export enum ButtonStyles { diff --git a/src/ui.tsx b/src/ui.tsx index 98eab9c..5da5835 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -12,6 +12,7 @@ import { displaySecondButtonContainer, displaySkipable, getButtonText, + getbuttonSize, getFontSize, getImage, getImageAtlasMapping, @@ -127,7 +128,17 @@ function getScaledFontSize(size: number): number { function getScaledTextWrap(size: number): number { return size * modalTextWrapScale } - +function getScaledParentsButtonWidth(firstButton:number, secondButton:number) { + return getScaledSize(getButtonText(firstButton).length * 16 + getButtonText(secondButton).length * 16) >= 300 && (getbuttonSize(firstButton) != '' || getbuttonSize(secondButton) != '') + ? getScaledSize( + (typeof(getbuttonSize(firstButton)) === 'number' ? getbuttonSize(firstButton) as number : getButtonText(firstButton).length * 14) + + (typeof(getbuttonSize(secondButton)) === 'number' ? getbuttonSize(secondButton) as number : getButtonText(secondButton).length * 14)) + : getScaledSize(300) +} +function getScaledButtonWidth(button:number) { + return getbuttonSize(button) === 'auto' ? getScaledSize(getButtonText(button).length * 8 + 80) + : getScaledSize(typeof(getbuttonSize(button)) === 'number' ? getbuttonSize(button) as number : getScaledSize(150)) +} export const NpcUtilsUi = () => { const width = getScaledSize(realWidth(700)) const height = getScaledSize(realHeight(225)) @@ -141,9 +152,9 @@ export const NpcUtilsUi = () => { justifyContent: 'center', positionType: 'absolute', position: { bottom: '10%', left: '50%' }, - margin: { top: -height / 2, left: -width / 2 }, + margin: { top: (-height + getText().length / 2) / 2, left: -width / 2 }, width, - height + height: height + getText().length / 1.5 }} > { alignItems: 'flex-start', justifyContent: 'flex-start', flexDirection: 'row', - position: getTextPosition() + position: getTextPosition(), + margin: {bottom: getText().length/10} }} uiText={{ value: getText(), @@ -270,25 +282,25 @@ export const NpcUtilsUi = () => { {/* Button1 (Top-Left) */} { {/* Button2 (Top-Right) */} { {/* Second row of buttons */} {/* Button3 */} { {/* Button4 */} Date: Fri, 12 Jan 2024 18:58:12 +0200 Subject: [PATCH 02/21] Demo + Add demo scene ~ fix text bottom spacing --- demo/.dclignore | 20 ++ demo/.gitignore | 9 + demo/images/hi.png | Bin 0 -> 90482 bytes demo/models/hi.glb | Bin 0 -> 987192 bytes demo/package.json | 27 ++ demo/scene.json | 53 +++ demo/src/bubble.ts | 487 +++++++++++++++++++++++++ demo/src/components.ts | 15 + demo/src/config.ts | 99 ++++++ demo/src/dialog.ts | 677 +++++++++++++++++++++++++++++++++++ demo/src/faceUserSystem.ts | 37 ++ demo/src/index.ts | 47 +++ demo/src/npc.ts | 712 +++++++++++++++++++++++++++++++++++++ demo/src/npcData.ts | 14 + demo/src/systems.ts | 148 ++++++++ demo/src/types.ts | 245 +++++++++++++ demo/src/ui.tsx | 434 ++++++++++++++++++++++ demo/src/uiComp.tsx | 18 + demo/src/uiResources.ts | 320 +++++++++++++++++ demo/src/utils.ts | 9 + demo/tsconfig.json | 11 + src/ui.tsx | 2 +- 22 files changed, 3383 insertions(+), 1 deletion(-) create mode 100644 demo/.dclignore create mode 100644 demo/.gitignore create mode 100644 demo/images/hi.png create mode 100644 demo/models/hi.glb create mode 100644 demo/package.json create mode 100644 demo/scene.json create mode 100644 demo/src/bubble.ts create mode 100644 demo/src/components.ts create mode 100644 demo/src/config.ts create mode 100644 demo/src/dialog.ts create mode 100644 demo/src/faceUserSystem.ts create mode 100644 demo/src/index.ts create mode 100644 demo/src/npc.ts create mode 100644 demo/src/npcData.ts create mode 100644 demo/src/systems.ts create mode 100644 demo/src/types.ts create mode 100644 demo/src/ui.tsx create mode 100644 demo/src/uiComp.tsx create mode 100644 demo/src/uiResources.ts create mode 100644 demo/src/utils.ts create mode 100644 demo/tsconfig.json diff --git a/demo/.dclignore b/demo/.dclignore new file mode 100644 index 0000000..7499ff3 --- /dev/null +++ b/demo/.dclignore @@ -0,0 +1,20 @@ +.* +bin/*.map +package-lock.json +yarn-lock.json +build.json +export +tsconfig.json +tslint.json +node_modules +*.ts +*.tsx +.vscode +Dockerfile +dist +README.md +*.blend +*.fbx +*.zip +*.rar +src diff --git a/demo/.gitignore b/demo/.gitignore new file mode 100644 index 0000000..24fe526 --- /dev/null +++ b/demo/.gitignore @@ -0,0 +1,9 @@ +package-lock.json +*.js +node_modules +bin/ +.DS_Store +**/.DS_Store +npm-debug.log* +yarn-debug.log* +yarn-error.log* \ No newline at end of file diff --git a/demo/images/hi.png b/demo/images/hi.png new file mode 100644 index 0000000000000000000000000000000000000000..678bd19a4826033c04aace2f6cd037513b540f79 GIT binary patch literal 90482 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 vh{0idna~^s&o}jyIxeL4Wd-K+{`?gdF}h+ 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

k74f+_zY$P8_ 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�5z+iG$4 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


yoct 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

D-m8dQ})-PZaMvzfZ^a6&%qd2cbD1b*bEk}k{( z*hYK3TSfhD_>p_pb>QRY9D4oE5_(iDyens)4wUU&MqiyzqPE%oq~jtT2pN?`pC`_v zQ$PBXfnhq3%1x)6$41edkO1Ogrvn@Aj-YmWeQ11P0QvM)8)hx-L4z-0+Ur9A8M;jm zHfLihzH3Ik)%;0|UIyT{vNN^5)tc(G^Cfd%8Ns0V4)n$9*Sv|kH^E6J;67BDJ{(-h zZ&&mrSKFFHr^q|JL7NqP^ZR0QcZDS&RmPu*>A|m%V)CN3HTdPN;3G;OmhE1`k(Kjo zVfw6LynnxnQfXgzLT}l_!Zz*sZ!3~SHSJu<7?C4H-peTKu4TxHjyMsoHqNl~f{Xi+ zM^m`OM_owF9Tx~RmWt*@KnfblhM%6TScv3E~93NJro4~dz=fT!87p6aWGD}~P z2dgfbv-xpD*c6Km(BzOFOV{qrw$0xF(R(%6s@?wV&aDk_Z9`L*AAp%I&W9!DAL!0n z2i9{{K7=>DO-pB*v6OfDK<=HOl^VM2Ku7_!uiQt^Y;MgyZZCjmc{#M&Lzy`=FNDgt zWO{V(YdU6hA-Eq1r`PY+(Derj;a&_!-?TeK=dLb2 zSP13!2lI{vu~f5DAsEbbDNEnlo4)y20OFTArF;u>diGoaC^SCre&)&>e#hnl2>v!h zWUy)_zbLK%!ZW6FH^+P^8{5AC=7wD6KEC34Uxxy?vrP-JNwW*A8y{cgw70a z!j>21gX8_D=%#afrcs>_2PQYdFH}rf`nP;|@>UHiUUOnCI9C3INv` zW5f8~tl5MD7(K%dJMu>E5TAiiP=9(zp6rl}WzX8a2La?erbQk)N&NtyWE$Rq6i;CyJ8 zwjA%#Jk0hh=fkq4%kZ+Jm2CRf4WO}dDV{p(Aam`x0hX-Gz%_#U}%p`aJ$CZ;kNoeQs0eDSEg39MpHE~rPlW8;_8*rBDlVB5zU&zd%h9o>`* zT}1}??3Z5b1mr@5K^ttA;K@#3%!P%*-q*RR4(#0HTnN7S5?xF;U>6nhAUXRoveazF zu4v}Lp)nLGh(6I8>pW0$%tJeUtLP2SJP?0PLIZp4rM01XP?tUkwGh@0S_t2bG_gS8 zR|iw)jk$1U(nIdZn+|kH_gpAm6T|rl*GkFn)L6w_0R_ zy?O-Q@+6xo_RNM6wP|$vu}!qkY(dX$q%*djpj+~@;mdL zA?)*^9Ppp-Ch%BAv)~swVC&$+atdQvzSeqZeFy^be6kt15-0w4}FiuF(Z#{jOne1V;vW=+>d+NxVGy7OoA`@fd6+jn!|R@h<| zUd`CDnjF}6FqLWV6_n?I#_J?z>%Win-Jb*3 z`zErR#zm~z_8i#E&u1A5yIIMG93b!KvRj`wv5A5|mQyA&`w#1x)x`DC?)69(^L8b> zTP4IjI+SS?rn7Y<7y7CPLSsoPn!h$1)nsasm|KCshb~2n+pR~JM|2>ghX=qFuPkJ7 zEDwzoYZK?2e(>6AE$Te00L|>6OP(hBg2L_PDC*N1RI8y+O3i&>b9x$j61^0KsTh!= z3NKjfoQM)`EJXY#L-M}2Cv4w552<;_po0%Pk=3;lh`KrfUGa%R-sepSgo|N^!Z6hS zeJE;LY)0Z9U^u1I6D6(jK{r-dkfy^Ba5i2@)2$0yHL)|9a8U$dZcZrmR7a%ZXH9B7 z+#wsAqC z!V()GY1LeU-yW_;MMR{>tf2qN51d}F3tW#i9AV!q;pVg!=)T8Wu7f!y7cDFxpr&XT@>ajA$uZCK&?549v-(6o;~p(o^hQZCA~Y6*h!G1jTgDM z#1PEXhohe9z0t6>-sI%!j&M17D*F6z3}VW@#5PAyxNnevT8ri)qtSjuoUH>Zccvj; zybwi5{fYBREqE|63ndO(il(&5w48_G-bKFIi~cwPk2cT>xo* zMF+Y+UyNGfMM!C(Ke_W>56-+xL~AC;p$Y1KL|wxG5+2V(k3FN2Qicx+F*AZ!SH>gn zv_a^Wsy7+sB3vhyhM~}7{>WmsC(-aQ1;@qR5&Gza6z@q$dtY;y9ZHavfe}jg6BEwI z5<2PFq9(W{`j&@@FR_C67xmG|t#7#5!hI}72OHRz(h|+Pc!G2C5fL|iJLoa{Ge;GTbK$MUJF> zvJ1?$n9N;2;^vMc9mvZNH|VC*g$o&(SeCuqj)>ZdK)2T&(Xa~|d`XE7Ie(Ia?i0O5 z^2Cy4IE$f$V@}!FKIQz}59TEQmIQ)6wdU0gAMlai zOo?cLC*(Zo!CTcerG;OO$#D~JD7Ia}7d382%j=BDAm#&mA}jfz7DjaB69Xdc?gv^M zU-PqD+tPDa^vUrn!n*gf*0ic6N0C&Q1P%;@Q;p2&U1fiICs&)?xD*64%s8rWwI8jT z+ks3{4FYwmVCs?@PPN0dh*%T|$BjqOmQK@Y9;Z!ujtPL{t*6r`58`R0rm%;8nLjLj zKc7zCl|sip*CDag4-#)IrpG5OrK=C>lG5A0Z~<1*b+)VNhfF|_(o_^REL(6t_B*|7jP_kzN9l(#GIr|JqTDmvf7~G$B>lj22lo$$J+Fmec zt0#@QU{5tlj0hj=0W0;bY2hYKT65NfjBhLkGOImZdHy4xd)=ILoq@nyNrBcbJ;Zma z?o7^JbB7Mq=lEFl3|{@X4T-dOg^pA6`Nuom`BgjZ$;xmiD0?8~ed5)wRH}BE zPmpq?Ym6maF}I+FQ?K)Fk};`^Fo%sZ1Rlhyx4c@Am^|-c3VH{8>5dgms7F%|66IhF zTN?MJc1VLJm3b1CmPT;RXasHYx+66i<4yAKbOdmYrjTt-lUn(bdHeL>v#=NBg+xS? zxBHRv@j9?^^?d4G3FGX4_Bh| zx(iJI)P_H5u}x&s+L=5-&al?IRhdhn4_8^yg;>pT1+z<8qV9uNbA86xlklDHa3_!B zQo_!2fl9W-QP_h~I5d-UFHlCh%dAM&ek}Y?ImH>K8=|wJmSp}SF>KIljIu`~w6wiB z+1uL#a_aQad$Uk<=9me2uHgmRW$tLjiOJ~w)K28n0dGhe(g)2oPeSu_49Vo_!oCfs zaOBc>37Sx;PdXa=!@4hX(ebXryJI4B$(LgRu;4>7(%ZilU1+TR%e|)h>!vLuVpzZ0 z&FpY71vYmQ>)a%lt+ila>NtvhwOGj}u41tGVLx`JYdZ654)A_mAj^wRWcsrKCSM{f zyCR0YxD4=0&5=2pO=btWl*0sXb7pmP6kEQy9G=eBWt}2IS@`2}h$w2!wAF%`yRQ@; zJXT`rJ1}dJCxzoauV}L#_Uy)2DID5cO%+~uV!QfRK!x!E`hHn^mawk^=+Z6pnX?M( zqj3O=8!e;9cD<(-;|{=x+tX?B+Zy`m=m8ig^`{%%Drohx0}!08O*7{d(vq+PkpA(K zFsByLm6iwKMPxL8M|A|9{!EbUoVo?%1#mRCT{<@WAkr&qjlN(B_oTP#xWPUPG7 zsQ?R&CftPlVP$U(Dq!9SFK*~*GycM3DMSp2<@U@>;rHy5!t#V1ZlBr#J|k8N<=cQO z&iTks43fgx7j4kS!ydGUrW7hv{m{&g3Dnq03cHPkdlpv<==%^Ugmlb8hcb`SqZ6bM zV6_`XhCHEb(xk#%JAqUao3im+r6BUThidM0U>?V$u*yOK@9?l>?H)*>y`374%Mr2r z$`z2|tc`nr4PvF8Dxf7Y!xjSvvs6h1BzrpI&n4s8kgy795+K3%Q({<`ITa8e+zp>~ zU&xeKSHRak190iXC9JBr0%i>g#~ZR%u`QP>plQw>L zixcsX{32%dSql3^X*i%4Wx;!-@P;kJj*Sno8DphzQauCLL|3ppLn-8sSd0^HGIpY> z9Omv{gsr-lvA4q5=%bp9FVOu=-?toW2PNX!Rz=M3D?qcI3D|h`P8Piv;AW#Zd{Si_ zTNMcqy=5+*GJO*}&z#zc{ijpyBU*G!gS9M>#Td%&U>gwIo zyUt8cPj~OI);ir?o~&s~B8|!*(7Tjn8@_C&N~a0*b(yiQ?Mvvx+XM!dYOyuf{pqeZ z1O~h0SfkU9)N}-e4@<|ghq6uSD^-5{`oBnKlQP}QQs}OKi;_aeQl}6K{q+yfhvZM> z(-sPY^%qgI|08m&fWoKx1E^N5jLh?-@TEQu9q&&j6MysLm&`_To7~9lvjo1CsPR63 zxSfj#h}pkjYERGQET<4qjoHY|k1XZ7Z*%Zc%uXV}ijx2%4r+%# zt2xu4Ovb(xLd>;YLj4yuLs20m>-pf(KO%DRMLX~+|qHh$4{9WtrUW~rULbzWlm?E5Q6Oq zZCWwgmDi6Ff}g$x9Y1F-Jur=fW#yQz30Os84hOqTz3DrHSlXGzK|y5@-EWvqrS5W2 zZXH2Ajq<3GIDwm2qUjH#5;}_|(8lbfXN*r#ciwJZ5kvKRPE(e*ovy^v(pbI z#8bV+71V&YW&IQAN!4>yjkn`U6RB?dc`C=-z5Pk_#J);8p0@*-6sjF?iHh@fZE7k# zHt90uXQl)LQ5w~%ucm{%ou`>WkEYkqF5dndy_;&dbF`heBO#L>5$7S0yxlN1o2p+0 zdY8B5=B888jw`g5w?j`P(R8~?TE*L?pJJ)~*D^YH4*}?Nh4~Hh5VJ4_9V9BaQ{Nq` zCay)Aq9hdiT?vN;dccT-afmg{L?ay(aoP?~h}FzMdp71F(1P#)*odO^(C zB&6?|fY=URJ4D$F`n2LuQSf%OUYC#SMtFh!j_t@mX${g?sel!`Ji)tsJ<@&=j=aw+ zU_<^nB;FQ<4wVF=?oSGM@k4jmzc2!QDf2>?OO)`iI#)DGqX5nq02D-I*Jkma+ zkFh2LvvS6uEnoV0W|XIhvMo;6ISyDiS_<28sM4oAO7b}=y!!DOISD+<#uwv_()w^(5Qg5gE1-+{EN*(I4@cDIBhZ&YA?*lD z)f&Jxi4YXFc?_DQfpEhiLnv$UL0*dnn4)zIc8W2A)-!gL4a55n!(iI$*BB!KJzrz26uE>K&;U))JoSfGv8U^@dvD7_^(zbkWOcgIa%P1 z4z^HMbcxxM`CTwK*A$=N`z=wc)_q%BW%5d1^>@8nS-I7wpMZm7&`1BZ1+f} zvEE0x*IO4q3wDApLlJ@^xi(?K8ZEq>kJB3O$v>c@3^~L)N$gVGsO4wbHk^NAP&YFc&D>7gxnlWB&JLv8m~0)jyxxDR8=OvvT7uJ zuO?3Da0Ey+BQw-Y$yWz0J`Z#R)uqm)^dw7`{?x*jOB_JfI*_=l`4IUF+W5gydl>&= zIk}fMk4#*mgHOG}(B-(D1Tc~On7a6}B8EX8ua?xlnLNFzi(lljp!Z}W3C#*6UZ?bM zyd;m?*IGcfIy;hx6n%VW6N2A-@2BaHHjxWAz+G<{SSK(gr^k;aT9!PZbS484Z{^7S zNv}C>m=S(jC4l9-hLMU_XSkd9jPSci{`ysE;FcS%;9P=DvH!&B&^q}TN8^79q0Jme z7FoiRh9}(B5nfz^n-x}6G>4DwVx+$_o$EO<9lyvnfi5*!qULmgi}`JfwSO9d?vN4L zm)FcaabxhZdHS&bf-_mx_=k&0VsYvP9WZeWCgsJG$^I+$_~0}x$Sa>oEKZCgCSp$5 zVuw2DNPChArzMCKa=~XrD)2Ybk)-+kfmNndEqBBr@{Q22ISqTMoxa37Y^4~1hP?+RLRtFK07_}t#L~5uw9W%R~C- zfD)v;Od)g4%eW#F5B%YgG8j~hBQKqcxx6HITzO6f>SQHITW~fP-R6d;XQ{%3k-xdz z=s3>G%nfggQUi_lJ}ysgIrlEX6>oD_2f6C!T#mmFw_D_bEi^PhC%>LcE->Tt^!PmS zmj;~NRLhNhJ%yuNoN-+Pj~@;>&oRqC3H|Rl;XP-x!1u*rPPV2-*e2_QN5yJGeMBzT zsT3=Wj&Q_#-1I<4GKo9lJV7|_FUBBl2np`1Ila}dudK~PxcHJW_}!bu6|XM03z{mx zQS;5_IO3HFJKw0pcH6 zcvy)eTv#&!33hv+vV1N4VV^VD6quuD>lPthzAlo(>%i~(GzX13z72)D^3Nl_*Yr=n z>7Vs~y?4tti}E1`waE}cjD8vo?Y>Mc?~A~0S|ZIbI8V*SHp9m;F;p0Jni_jI!`$y1 zXm|M$s-Mvehnkkt=CS+fy}o96QyEHct;nWPzR$p5&rEvpZW0}L{uz&faiPw$x6+D9 zEl}lUOI0Q=rM~N1;Fqou{q=A*9c*j?M+r45%CM)|(_48={bX9{X++KTwZem1Ntz|8 zK%e|*1#RX#iM%C2*M+pfxi2qChGZ9+Oxu7xUq@UMYRM&)cBor%j{N$&j|9ZFgTHnm z`JS9Zj{3Dj?bTi6^Mu{xBk$8-?MprsBoT*!HW)mkO!`$~NESbim}48)Fwrx=?y;RT&&72>5qdAS9yx0og`{uLdGji#H$E~2CvXafe zaggrrZv}zhHg>1o2^uq|4Jv9A*rn&r(d%Wcureo+O}}%VO3Y{l!zD@Vxz`t{$3P48 z*d((JKPzcQb_<*ylfr(Re2LbZwZQV{DXgM#6`l0-8R(u*W$oQA(}4BQpo_=&MTAw; zeN&#n@qlzTb;}jnR@DpKW`qRoyeWd?C9hGK z&0F%LP6XN$?xK^CwPYfH-JRZf9t{@lC%W|_FzhcxYl@eX&HQmygvOxzy)((}2oZ$r z_eHt_J0fc)g2h{uQ9`OZS^BF99-V7pUWi7Ms@qL)sC^By!TT*Ik<$dVOUwku@2j|g z`Ar~J_{sKdVlsD3uL)ve-__W-m~x*#HG+LwywLCWVWCTHBS=0^;HG>j=kn4UA?DdT zZbiO4=?rLu?UCB#zF7#dRBr^EWkDo=Nft@yYk(i-iF~c>9C=#Z0L^B_2zX^H|J+wD!qG&jKKTy5H!9ZD;88)5Ne3(8GjMMJhU!qXf~bD!^|;&&UtQO28A zT}!6r3QcfsZxB_VnoZ}dXadzq5j1moA^k0Ef~-A!Zp9s<$H$7`kMvHuMEVq+5h{XB zl`-^|#~GRyB7!yZ3>1MwSO$$~t)V8oZ99g?oK7Y*DnJD0RasPX2GEmp zM4-QL4^2qEN;~~UpguN-cGg~}s=U2EESpxC)l&IYBA7nW0d}2`M2G8)(Ec@n2| zY8GfCQH3j#`lgA6QZ68I&k21IEI?Tc)v*_kQ&6A05Y?UBgsxsw!7<0&z%6M$GVol3 zgni2R&|G(r`8p4^zh8!K%PQkj<2@j0Nih1EybyKSE8*O$9&olH02OP_MXJjc@q%@p zQ0U-~dSDjXkUb4cY4SXg@|kG#TrbpJ#cMG?^@0vrUnKR>3B|O@<2SM1;2Z0W#-uaI zewaL#HSvK9?>&&Sx)svZlEcC!UNG#o8_HKPMkBHnuuGl?Sk*eB`|tIT@;60XP~!$F z+neWi0U@WC3S#v{5{gMGqKj zEGcOQ>DP2o-3$ffINt_G-8Tl0ZhbT@SP6~UY=_sR8$$JHBV-k#ioT>WcplH&I;3HO zt_NzM#vB%J{hq1sFym&9p6=XHMmpnc|uQQ_;w zchq2!n=@j52#~}X7d+;%3QVZ;M!7*Q=o=p=eSfM1^;?3_ubp1#S*1JndBWp}bQYt} zhi0NIQ%`JgUmo5*T8)O&K=k{B7p}c33qk9*q2k6+B&Ohlx3$TGVs<=Q_$eG^MtkAX z57QuWQ7YOyHWFRG=7EQcD?_Sj7AofRWXk7tQPQgL<$Esrro9oJo#l$p%c_GK-H*oW zZbx*FGd?1(3A?u+LMGC&NcNs1mYu2%6_&?Q*{B5c{*OK8Ty?=St`OzPEJa4EG0s?} z4?5S=&|NWCWZHnR)^0i#g#x0o<1O|7srABTzM37Mpp1i{o`3tYRw z20r$#VPZi~n7-KzPxiF~wfRkgmT+0FH{Ar^Rc0XRSX0d@hd6FWt`Sb^MDTc&8rR!i z%_Z$Mz(YLl4^HK9D|QTU0ZDq8_&GrOqb6?C7@q&SMh74G;s}esj3p_4#^ivX7B<=A z4Ar}g$nQ8$a!E%6&sKGXqHjLL{^$}S^+grCKjC>DLLV|>@*>jrQW_ z&LARjNQrdWYT&6>&agCY9`R3|LbMAtupiI=_DGyh0@sftzdmbV%MvF@I1)_E+{clz zb2M?EzY`q4=1)4NjU&yKnz-_#J!lWw5S6+f?rnt*E{J0xWrPyhX->GA#rjx*=N?;+ z7)B1nW^#eCM)>wxTd?T4!_AAqoL8VJwraG7b=UTAp`F)-F)9|=MadG<=L@+-Bi*^J z_pR{eU^A$1?&N%X^SPEt8@waU7>p;6A|FrR;dFo4VX5;5U~_mHd2I2E`>+M!=3BbZ z8Er~Dvt>!x0LC_tv|y^03(@>#O6~yV6;H5Gg?GEN$vpF9Vx#GbRdQ6p+a{CO2Z|%~oeMVks0u1C z(}_r92iafdg7IuMSe}?ltTwJEcUQY$?@Be$*G(pMu!8uSyI_AAb(mL|K(fTbiOwfy ztg%ZS4CLd;&&&LGDs#pW-Rh9uu#=3A_9K=N&RB7d2F%~Ih146k5eX${>zg)bQj#c$`)!5e`MSu21bJb`A}6LJ+ycK;wS}B_m4f#AQsyXUily=d5Z@KdT&aA; zq(~a$8Q&0CzOQ0@Qu#WKhXD@WWe+D(#n97L+UNt;#s5>o=D+f#f40}2%BPER>Zq|~ zKPW*CO+9ymY8dvzorY|B?m;b;_3MZA-Mgu%o1UT zei8P=%dWNb-r-W(^P(S8oFeG0v_g8@YyeD40_nB2S@cN!06hEQLFwEix~p*jVgneu zK5;9Zr!xq87mR7toMm+SmO*$tPK_?s3ZOFg24Tx`85;80i4G_Zf%?snboNa%dT-Sb zrTHvUUhMzcmo&h;cMw(g&!`05a#|UlO+X0~}O6O*D!-2~+g}wqDF7L&JVAK=lS<298U*R`_=?9DsT|?L{=fC->1l`HG?q0 zs2&aNswWMpgRpy`3*8+4nb;i}1c_iV_P*mddWahYmzuHcba7QWs%a47r^&O2Zkp4T z1A}mFyB0e(*@Zrp9D-rb&Df3ZLDW`#2pllWzLZ))4+(}~*C9{V^WF|BF=q(qut0XM zYYL6x&&BUW;p~JHd+3woA>c{Q?9EXJsBP&GY}4A#Ze7M}U3d&Zs8a%Ka;Ka|4h_QZ zb!lv;-enrUZxD)(X0!X!YUu%oLBK1s*t0#9UVJ|QudOoKo8E-SLJdITpA5FOTu9&8 z4uJ0MbarTb4gK?~AMRzPv7^>h)2V6wuqr5(ReW4UP0ag2S}lb&H@`&PTl%2#eG==Q zQ%S?(`XJy!B0K-ndAdcv558|rVAsz%NB2JIg(9bTHm$0Hp5EFEcx)VdNS5cesQ1Fg zj~m#Fr;gB0wii}DT*}@S?588=^+Lp{V7B!^Hr3wL3n2+!Y(F1EyXN$Q{{qB{cW$Fg z&-Q}1oe66wxtyll>jkGNYV2&o0D7vc7wiTnv0MF|=-m;0V17@WJ-ptO_NerMzjq(H zQ>aA8GJW7Y{4pBjM$;T^-lzH^GP^cF6ejk8`l>>-WAt58`m+~Q-8Z8LvyKwox4j^C z5hGjc9pvnzUT9Mpg&yBBBi6!R*erXHc~NnnBgcASWXJ|a?8GC^IlC7WQcW4Pk_N7o zKbDXvk-)K_nOm#V3(~u%3Bt45ILVJaeE(peCL#GHS3-M0H}R(M*se~_I;{t`=jm{_ zHofB>%;|w;%c8ih)xBJ}S`U;REaW7Y4RSwvyFqo7kkbwO#O=JAB%NxCZ{x(VI< zwZM`X;}`NHvll)e z4yOHU^JtlMA56U+LAl0*G%lqNruRhCberQekpEu=PS{E39;l!lZGFJWCsMsXRdn@> zK6qe|PQQi${rRd7+R+|*>-ue)(%A?7z6BIbuA`H?`k>RZfL>f&M-RR4gJ&)U)bLUr zHSFz!hxP^Z$jCdiy1x%@2nwh|z#Zx`)CXhpZJ}_H9P{X6KC{5V6j!zipxQr|iBP}K zln9Nm_%p=!Cq#^<;|Nr@%m7cji{af>p6N|gt!N-;u!Wu*RCt@A6)WV>Ya>;h;Oz=CG>W`|Eka?3QZQMnVOt<^>EBxR817EK&>*Adcf zw9%aMiRf#J7M}9f0cQNxK&SnrQEGuUo+IV}_562x^I<%Cc2oze%kyzryb6-Z9f#V^ z>Ec9F3=5o<5VjnPvV?j#)|G`M@o6ZE*Q@Bhp^qPhA&7fA5lO`kN0XiyV7Dy{IFw2v z*?FIsq;^BR-`tMpYy4qeUF~2bLQU|rj_GhCy_bnrdde(lFvBY8Jnm4ng_*ME8e{8Z ziGS)_!07VZj1hO9!KbY8nCqrsWp#;}B3{aN5Z(WR(AGu(sxyo=fC$$>>aZGWz2JpggA`!hbYFB^Yz#6w>V+2;D!^n-78&QiV_xp{!gt>(!28{X zs4uyOapd#1@7B{G`L6=X-;=?N^6|oSkrD(QkwRWa5Q8f{@V8_YC{7q;&f^;bXC9Y$ z?SvY97=Dc@dpT(LcbO|rtkrj2l?Bo1Dz{c z1hGj*oRgyic6qJ`n&0E?hUrCfhTAbNZ8m@+=|W+k?|zOwi}2^0M)3TGF6R@)aau10 zIJ?{gd|TtVYX#4_d6IV6ILi#omY?VDEfFIUx;8i^(gLz1UUCfy6G69CFfMsab}w~ROBO(7)nf;%z&t%S`SJfSX*$0Gz_@}hGZj%@dW!4du>G{K6jY>~$oqkUjWqA$5p zV?dG~%Hl`aUOfNMi)baPlPO^e*zAM{KhJ?1k#UnJ_j`D~j!SNE;fE6`8757Fqg8NG zjSF0pwkJK8B*=thD^LWls~&$T4#2WvUO4a<1zScf8aA`-f;kkjgBg?=gmu!%q0YD>e9jG=!|ylO?T1F1RsF1sar>lEY#e zL@Lt_-*~17r_!T|-veVZaia(RZg z;Z;=%Njx%(h=+P%u_k$_<#j!sD(92l1zz}PnLIq*kwX-2MG~<^Uf3gE9wu}Yl7ZHZ zgbnw??}FqZ)T5ZVZH*--`0W%2d6<3Z2)WdhL{$DfPf>S!IA9ndFDbVxrLRh97dO5Y-b)lD>M7o5rp<$y@^#99d2h%1wCw zpEEWs(Sq~^zGQR26k@sC5zim43(qH5k$ZigxvVqx_&DDmY_C=z$F#3(6)fE5YyZ1ZLVKv;T|N^iR(8AFSSggt?zDQHD?A zR`8!Kex7AsWAs1!|KUXaXOG3+RsYJ*y|Cb4`8_;+@n88(%&h-celybE{{Q_Z$JdDc zv;6nL{;$XWkI#Rt|N9j*>wo!;{ujRo4*$-t$Nb;0vEzeV!@uivBl_t8Jg|2*&i L(|*AF{ImQYYaD>K literal 0 HcmV?d00001 diff --git a/demo/package.json b/demo/package.json new file mode 100644 index 0000000..c210579 --- /dev/null +++ b/demo/package.json @@ -0,0 +1,27 @@ +{ + "name": "dcl-project", + "version": "1.0.0", + "description": "SDK7 Template scene", + "scripts": { + "start": "sdk-commands start", + "deploy": "sdk-commands deploy", + "build": "sdk-commands build", + "upgrade-sdk": "npm install --save-dev @dcl/sdk@latest", + "upgrade-sdk:next": "npm install --save-dev @dcl/sdk@next" + }, + "devDependencies": { + "@dcl/js-runtime": "7.3.36", + "@dcl/sdk": "latest", + "@dcl/asset-packs": "latest" + }, + "engines": { + "node": ">=16.0.0", + "npm": ">=6.0.0" + }, + "prettier": { + "semi": false, + "singleQuote": true, + "printWidth": 120, + "trailingComma": "none" + } +} \ No newline at end of file diff --git a/demo/scene.json b/demo/scene.json new file mode 100644 index 0000000..df57d42 --- /dev/null +++ b/demo/scene.json @@ -0,0 +1,53 @@ +{ + "ecs7": true, + "runtimeVersion": "7", + "display": { + "title": "SDK7 Scene Template", + "description": "template scene with SDK7", + "navmapThumbnail": "images/scene-thumbnail.png", + "favicon": "favicon_asset" + }, + "owner": "", + "contact": { + "name": "SDK", + "email": "" + }, + "main": "bin/index.js", + "tags": [], + "scene": { + "parcels": [ + "0,0" + ], + "base": "0,0" + }, + "spawnPoints": [ + { + "name": "spawn1", + "default": true, + "position": { + "x": [ + 0, + 3 + ], + "y": [ + 0, + 0 + ], + "z": [ + 0, + 3 + ] + }, + "cameraTarget": { + "x": 8, + "y": 1, + "z": 8 + } + } + ], + "requiredPermissions": [ + "ALLOW_TO_TRIGGER_AVATAR_EMOTE", + "ALLOW_TO_MOVE_PLAYER_INSIDE_SCENE" + ], + "featureToggles": {} +} diff --git a/demo/src/bubble.ts b/demo/src/bubble.ts new file mode 100644 index 0000000..9d6c80b --- /dev/null +++ b/demo/src/bubble.ts @@ -0,0 +1,487 @@ + +import { Animator, AudioSource, AvatarShape, Billboard, BillboardMode, engine, Entity, Font, GltfContainer, InputAction,Material,MeshCollider,MeshRenderer,pointerEventsSystem,TextAlignMode,TextShape,Transform, TransformType, VisibilityComponent } from '@dcl/sdk/ecs' +import * as utils from '@dcl-sdk/utils' +import { Dialog, ImageSection } from './types' +import { Color3,Color4, Quaternion, Vector3 } from '@dcl/sdk/math' +import { addLineBreak, addLineBreaks, findDialogByName } from './dialog' +import { IsTypingBubble } from './components' +import { npcDataComponent } from './npc' + +export let bubblesTexture = 'https://decentraland.org/images/ui/dialog-bubbles.png' + +export let bubbles: Map = new Map() + +let textSize = 1 +let textYPos = 0 + +let maxLengthShortBubble = 8 +let maxLengthNormalBubble = 25 +let maxLengthLongBubble = 50 +let maxLengthHugeBubble = 100 + +let shortBubbleXOffset = 0.1 +let normalBubbleXOffset = 0.5 +let longBubbleXOffset = 0.8 +let hugeBubbleXOffset = 0.8 + +let shortBubbleYOffset = -0.2 +let normalBubbleYOffset = -0.2 +let longBubbleYOffset = 0 +let hugeBubbleYOffset = 0.2 + +let shortBubbleTextWidth = 0.7 +let normalBubbleTextWidth = 1.5 +let longBubbleTextWidth = 2 +let hugeBubbleTextWidth = 1.5 + +let shortBubbleX = 116 * 0.005 +let shortBubbleY = 84 * 0.005 + +let normalBubbleX = 286 * 0.005 +let normalBubbleY = 84 * 0.005 + +let longBubbleX = 497 * 0.005 +let longBubbleY = 153 * 0.005 + +let hugeBubbleX = 497 * 0.005 +let hugeBubbleY = 239 * 0.005 + +let defaultYOffset = 2.5 + + + +export function createDialogBubble(npc:Entity, height?:number, sound?:string){ + let baseYOffset = height ? height : defaultYOffset + + let root = engine.addEntity() + Billboard.create(root,{ + billboardMode:BillboardMode.BM_Y + }) + + Transform.create(root,{ + parent:npc + }) + + let container = engine.addEntity() + Transform.create(container,{ + parent:root, + position:Vector3.create(shortBubbleXOffset,baseYOffset,0) + }) + + let panel = engine.addEntity() + Transform.create(panel,{ + parent:container, + scale: Vector3.create(2,1,1), + //rotation:Quaternion.fromEulerDegrees(0,0,90) + }) + MeshRenderer.setPlane(panel, + setUVSection( + bubbleOptions.normal, + 1024, + 1024 + )) + + VisibilityComponent.create(panel, {visible: false}) + + Material.setBasicMaterial(panel, { + texture: Material.Texture.Common({ + src: bubblesTexture + }) + }) + + let text = engine.addEntity() + Transform.create(text,{ + position:Vector3.create(0,textYPos, -.05), + parent:container + }) + TextShape.create(text, { + text:"", + fontSize:textSize, + font: Font.F_SANS_SERIF, + textColor: Color4.create(0,0,0,1), + textAlign:TextAlignMode.TAM_MIDDLE_CENTER + }) + VisibilityComponent.create(text, {visible: false}) + + bubbles.set(npc, { + container:container, + panel:panel, + text:text, + baseYOffset: baseYOffset, + isBubbleOpen:false, + typing:false, + visibleText:"", + visibleChars:0, + fullText:"", + timer:0, + speed:30, + script:[], + index:0, + sound: sound ? sound : undefined, + soundPlayer: sound ? engine.addEntity() : undefined, + }) +} + +export function openBubble(npc:Entity, dialog:Dialog[], startIndex?:number | string){ + let bubble = bubbles.get(npc) + + bubble.script = dialog.slice() + let index:any + if (!startIndex) { + index = 0 + } else if (typeof startIndex === 'number') { + index = startIndex + } else { + index = findDialogByName(dialog, startIndex) + } + + bubble.index = index + + let currentText: Dialog = dialog[bubble.index] ? dialog[bubble.index] : { text: '' } + bubble.currentText = currentText + + if (currentText.audio) { + AudioSource.createOrReplace(bubble.soundPlayer, { + audioClipUrl: currentText.audio, + loop: false, + playing: false + }) + let audio = AudioSource.getMutable(bubble.soundPlayer) + audio.volume = 0.5 + audio.playing = true + } else if (bubble.sound) { + AudioSource.createOrReplace(bubble.soundPlayer, { + audioClipUrl: bubble.sound, + loop: false, + playing: false + }) + let audio = AudioSource.getMutable(bubble.soundPlayer) + audio.volume = 0.5 + audio.playing = true + } + + let text = bubble.text + TextShape.getMutable(text).fontSize = currentText.fontSize ? currentText.fontSize : textSize + Transform.getMutable(text).position.y = currentText.offsetY ? currentText.offsetY + textYPos : textYPos + Transform.getMutable(text).position.x = currentText.offsetX ? currentText.offsetX : 0 + + VisibilityComponent.getMutable(bubble.panel).visible = true + + if (currentText.text.length < maxLengthHugeBubble) { + currentText.text.slice(0, maxLengthHugeBubble) + } + + beginTyping( + npc, + currentText.text, + bubble.index, + currentText.timeOn ? currentText.timeOn : undefined, + currentText.typeSpeed ? currentText.typeSpeed : undefined + ) + + adjustBubble(npc, currentText.text.length) + layoutDialogWindow(npc, bubble.index) + bubble.isBubbleOpen = true +} + +export function closeBubble(npc:Entity){ + let bubble = bubbles.get(npc) + bubble.isBubbleOpen = false + bubble.typing = false + bubble.visibleText = "" + bubble.visibleChars = 0 + bubble.fullText = "" + bubble.timer = 0 + bubble.index = 0 + bubble.script = [] + bubble.buttons = 0 + bubble.margin = 0 + bubble.currentText = null + TextShape.getMutable(bubble.text).text = "" + VisibilityComponent.getMutable(bubble.text).visible = false + VisibilityComponent.getMutable(bubble.panel).visible = false +} + +export function closeBubbleEndAll(npc:Entity): void { + let bubble = bubbles.get(npc) + if (bubble.isBubbleOpen) { + bubble.done = true + closeBubble(npc) + } + } + +const DEFAULT_SPEED = 45 + +const DEFAULT_TIME_ON = 3 + +function beginTyping(npc:Entity, text:string, textId:number, timeOn?:number, speed?:number){ + let dialogData = bubbles.get(npc) + dialogData.fullText = addLineBreak(dialogData.script[dialogData.index].text, true) + dialogData.typing = true + dialogData.done = false + dialogData.visibleText = "" + dialogData.visibleChars = 0 + dialogData.timer = 0 + dialogData.buttons = 0 + dialogData.timeOn = timeOn ? timeOn : DEFAULT_TIME_ON + dialogData.speed = speed ? speed : DEFAULT_SPEED + + dialogData.openTime = Math.floor(Date.now()) + + if(dialogData.speed <= 0){ + rushText(npc) + } + else{ + if(!IsTypingBubble.has(npc)){ + console.log('creating typuing bubble') + IsTypingBubble.create(npc) + } + } +} + +function rushText(npc:Entity){ + let dialogData = bubbles.get(npc) + dialogData.typing = false + dialogData.timer = 0 + dialogData.visibleChars = dialogData.fullText.length + dialogData.visibleText = dialogData.fullText +} + +function adjustBubble(npc:Entity, textLength:number){ + let bubble = bubbles.get(npc) + let npcData = npcDataComponent.get(npc) + + if (textLength < maxLengthShortBubble) { + MeshRenderer.setPlane(bubble.panel, + setUVSection( + bubbleOptions.short, + 1024, + 1024 + )) + + Transform.getMutable(bubble.panel).scale.x = shortBubbleX + Transform.getMutable(bubble.panel).scale.y = shortBubbleY + Transform.getMutable(bubble.container).position.x = shortBubbleXOffset + npcData.bubbleXOffset + Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + shortBubbleYOffset + npcData.bubbleYOffset + TextShape.getMutable(bubble.text).width = shortBubbleTextWidth + } else if (textLength < maxLengthNormalBubble) { + MeshRenderer.setPlane(bubble.panel, + setUVSection( + bubbleOptions.normal, + 1024, + 1024 + )) + + Transform.getMutable(bubble.panel).scale.x = normalBubbleX + Transform.getMutable(bubble.panel).scale.y = normalBubbleY + Transform.getMutable(bubble.container).position.x = normalBubbleXOffset + npcData.bubbleXOffset + Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + normalBubbleYOffset + npcData.bubbleYOffset + TextShape.getMutable(bubble.text).width = normalBubbleTextWidth + } else if (textLength < maxLengthLongBubble) { + MeshRenderer.setPlane(bubble.panel, + setUVSection( + bubbleOptions.long, + 1024, + 1024 + )) + + Transform.getMutable(bubble.panel).scale.x = longBubbleX + Transform.getMutable(bubble.panel).scale.y = longBubbleY + Transform.getMutable(bubble.container).position.x = longBubbleXOffset + npcData.bubbleXOffset + Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + longBubbleYOffset + npcData.bubbleYOffset + TextShape.getMutable(bubble.text).width = longBubbleTextWidth + } else { + MeshRenderer.setPlane(bubble.panel, + setUVSection( + bubbleOptions.huge, + 1024, + 1024 + )) + Transform.getMutable(bubble.panel).scale.x = hugeBubbleX + Transform.getMutable(bubble.panel).scale.y = hugeBubbleY + Transform.getMutable(bubble.container).position.x = hugeBubbleXOffset + npcData.bubbleXOffset + Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + hugeBubbleYOffset + npcData.bubbleYOffset + TextShape.getMutable(bubble.text).width = hugeBubbleTextWidth + } +} + +// Adds the buttons or mouse icon depending on the type of window +function layoutDialogWindow(npc:Entity, textId: number): void { + let bubble = bubbles.get(npc) + let currentText: Dialog = bubble.script[textId] + ? bubble.script[textId] + : { text: '' } + + // Update text + let textY = currentText.offsetY ? currentText.offsetY + textYPos : textYPos + + if (currentText.buttons && currentText.buttons.length >= 3) { + textY += 50 + } else if (currentText.buttons && currentText.buttons.length >= 1) { + textY += 24 + } + TextShape.getMutable(bubble.text).fontSize = currentText.fontSize + ? currentText.fontSize + : textSize + + VisibilityComponent.getMutable(bubble.text).visible = true + Transform.getMutable(bubble.text).position.y = textY + + if (currentText.audio) { + AudioSource.createOrReplace(bubble.soundPlayer, { + audioClipUrl: currentText.audio, + loop: false, + playing: false + }) + let audio = AudioSource.getMutable(bubble.soundPlayer) + audio.volume = 0.5 + audio.playing = true + } else if (bubble.sound) { + AudioSource.createOrReplace(bubble.soundPlayer, { + audioClipUrl: bubble.sound, + loop: false, + playing: false + }) + let audio = AudioSource.getMutable(bubble.soundPlayer) + audio.volume = 0.5 + audio.playing = true + } + + } + +// Progresses text +export function next(npc:Entity): void { + let bubble = bubbles.get(npc) + + if(bubble.isBubbleOpen){ + let currentText = bubble.script[bubble.index] + + if(!currentText){ + currentText = bubble.script[bubble.index-1] + } + + if (currentText.triggeredByNext) { + currentText.triggeredByNext() + } + + if (currentText.isEndOfDialog) { + closeBubble(npc) + return + } + + // Update active text + bubble.index++ + + // Update active text with new active text + currentText = bubble.script[bubble.index] + + if (currentText.text.length < maxLengthHugeBubble) { + currentText.text.slice(0, maxLengthHugeBubble) + } + + TextShape.getMutable(bubble.text).text = "" + + adjustBubble(npc, currentText.text.length) + + beginTyping( + npc, + currentText.text, + bubble.index, + currentText.timeOn ? currentText.timeOn : undefined, + currentText.typeSpeed ? currentText.typeSpeed : undefined + ) + layoutDialogWindow(npc, bubble.index) + } + + + } + +function setUVSection( + section: ImageSection, + sizeX: number, + sizeY: number + ) { + return setUVs( + {x: section.sourceLeft! / sizeX, y: (sizeY - section.sourceTop! - section.sourceHeight) / sizeY}, + {x: (section.sourceLeft! + section.sourceWidth) / sizeX, y: (sizeY - section.sourceTop! - section.sourceHeight) / sizeY}, + {x: (section.sourceLeft! + section.sourceWidth) / sizeX, y: (sizeY - section.sourceTop!) / sizeY}, + {x: section.sourceLeft! / sizeX, y: (sizeY - section.sourceTop!) / sizeY}, + ) + } + +function setUVs( + _uv00: any, + _uv10: any, + _uv11: any, + _uv01: any + ) { + + return [ + _uv00.x, + _uv00.y, + + _uv10.x, + _uv10.y, + + _uv11.x, + _uv11.y, + + _uv01.x, + _uv01.y, + //---- + _uv00.x, + _uv00.y, + + _uv10.x, + _uv10.y, + + _uv11.x, + _uv11.y, + + _uv01.x, + _uv01.y, + ] + } + + let bubbleOptions:any = { + short: { + sourceWidth: 116 * 2, + sourceHeight: 84 * 2, + sourceLeft: 305 * 2, + sourceTop: 417 * 2, + }, + normal: { + sourceWidth: 286 * 2, + sourceHeight: 84 * 2, + sourceLeft: 8 * 2, + sourceTop: 417 * 2, + }, + long: { + sourceWidth: 497 * 2, + sourceHeight: 153 * 2, + sourceLeft: 6 * 2, + sourceTop: 254 * 2, + }, + huge: { + sourceWidth: 497 * 2, + sourceHeight: 239 * 2, + sourceLeft: 6 * 2, + sourceTop: 7 * 2, + }, +} + + +export function getBubbleTextLength(text:string){ + if(text.length >= maxLengthHugeBubble){ + return 40 + } + else if(text.length >= maxLengthLongBubble){ + return 40 + } + else if(text.length >= maxLengthNormalBubble){ + return 40 + } + else if(text.length >= maxLengthShortBubble){ + return 40 + } + } \ No newline at end of file diff --git a/demo/src/components.ts b/demo/src/components.ts new file mode 100644 index 0000000..5230b64 --- /dev/null +++ b/demo/src/components.ts @@ -0,0 +1,15 @@ +import { Schemas, Transform, engine } from "@dcl/sdk/ecs" + +export const IsFollowingPath = engine.defineComponent("npcutils::isFollowingPath", {}) +export const IsTypingDialog = engine.defineComponent("npcutils::isTypingDialog", {}) +export const IsTypingBubble = engine.defineComponent("npcutils::isTypingBubble", {}) + +export const TrackUserFlag = engine.defineComponent( + "npcutils::trackUserFlag", + { + lockXZRotation: Schemas.Boolean, + active: Schemas.Boolean, + rotSpeed: Schemas.Number + }) + + diff --git a/demo/src/config.ts b/demo/src/config.ts new file mode 100644 index 0000000..f1ed841 --- /dev/null +++ b/demo/src/config.ts @@ -0,0 +1,99 @@ +import { Color4 } from "@dcl/sdk/math" + +export let extraFemaleShoes:any[] =[ + "urn:decentraland:off-chain:base-avatars:bun_shoes", + "urn:decentraland:off-chain:base-avatars:pink_blue_socks", + "urn:decentraland:off-chain:base-avatars:SchoolShoes", + "urn:decentraland:off-chain:base-avatars:ruby_blue_loafer" +] + +export let extraFemalePants:any[] =[ + "urn:decentraland:off-chain:base-avatars:f_stripe_white_pants", + "urn:decentraland:off-chain:base-avatars:f_red_modern_pants", + "urn:decentraland:off-chain:base-avatars:f_school_skirt", + "urn:decentraland:off-chain:base-avatars:f_capris", + "urn:decentraland:off-chain:base-avatars:f_red_comfy_pants" +] + +export let extraFemaleTop:any[] =[ + "urn:decentraland:off-chain:base-avatars:baggy_pullover", + "urn:decentraland:off-chain:base-avatars:light_green_shirt", + "urn:decentraland:off-chain:base-avatars:school_shirt", + "urn:decentraland:off-chain:base-avatars:f_blue_jacket", + "urn:decentraland:matic:collections-v2:0xb8326d69371668bb8403463e4f71c10b408535c3:1" +] + +export let extraMaleShoes:any[] =[ + "urn:decentraland:off-chain:base-avatars:comfy_sport_sandals", + "urn:decentraland:off-chain:base-avatars:crocs", + "urn:decentraland:off-chain:base-avatars:m_mountainshoes.glb", + "urn:decentraland:off-chain:base-avatars:citycomfortableshoes", + "urn:decentraland:off-chain:base-avatars:classic_shoes", + "urn:decentraland:off-chain:base-avatars:sneakers", + "urn:decentraland:off-chain:base-avatars:moccasin" +] + +export let extraMalePants:any[] =[ + "urn:decentraland:off-chain:base-avatars:soccer_pants", + "urn:decentraland:off-chain:base-avatars:swim_short", + "urn:decentraland:off-chain:base-avatars:kilt", + "urn:decentraland:off-chain:base-avatars:hip_hop_joggers", + "urn:decentraland:off-chain:base-avatars:brown_pants_02", + "urn:decentraland:off-chain:base-avatars:basketball_shorts", + "urn:decentraland:off-chain:base-avatars:brown_pants_02", + "urn:decentraland:off-chain:base-avatars:puffer_jacket_hoodie" +] + +export let extraMaleTop:any[] =[ + "urn:decentraland:off-chain:base-avatars:yellow_tshirt", + "urn:decentraland:off-chain:base-avatars:m_sweater", + "urn:decentraland:off-chain:base-avatars:turtle_neck_sweater", + "urn:decentraland:off-chain:base-avatars:puffer_jacket_hoodie", + "urn:decentraland:off-chain:base-avatars:elegant_sweater", + "urn:decentraland:off-chain:base-avatars:pride_tshirt", + "urn:decentraland:off-chain:base-avatars:elegant_sweater", + "urn:decentraland:matic:collections-v2:0xb8326d69371668bb8403463e4f71c10b408535c3:1" +] + +export let extraskin:any[]= [ + Color4.create(.24,.13,.04), + Color4.create(.6,.37,.22), + Color4.create(.48,.28, .09), + Color4.create(.98, .82,.51), +] + +export let extrahair:any[]= [ + Color4.create(.6,.37,.22), + Color4.create(.3,.52,.4), + Color4.create(.55,.13,.08), + Color4.create(.11,.11,.11), + Color4.create(.48,.28, .09), + Color4.create(.98, .82,.51), + Color4.create(.55, .13,.08), +] + +export let extraFemaleHairstyle:any[] = [ + "urn:decentraland:off-chain:base-avatars:hair_anime_01", + "urn:decentraland:off-chain:base-avatars:pony_tail", + "urn:decentraland:off-chain:base-avatars:standard_hair", + "urn:decentraland:off-chain:base-avatars:shoulder_hair", + "urn:decentraland:off-chain:base-avatars:two_tails" +] + +export let extraMaleHairstyle:any[] = [ + "urn:decentraland:off-chain:base-avatars:standard_hair", + "urn:decentraland:off-chain:base-avatars:hair_oldie", + "urn:decentraland:off-chain:base-avatars:keanu_hair", + "urn:decentraland:off-chain:base-avatars:tall_front_01", + "urn:decentraland:off-chain:base-avatars:00_bald" +] + +export let extraeyes:any[] = [ + Color4.create(.22,.49,.69), + Color4.create(.6,.37,.22), + Color4.create(.3,.52,.4), + Color4.create(.55,.13,.08), + Color4.create(.11,.11,.11), + Color4.create(.48,.28, .09), + Color4.create(.98, .82,.51), +] diff --git a/demo/src/dialog.ts b/demo/src/dialog.ts new file mode 100644 index 0000000..388daad --- /dev/null +++ b/demo/src/dialog.ts @@ -0,0 +1,677 @@ +import * as utils from '@dcl-sdk/utils' + +import { AudioSource, Entity, engine } from "@dcl/sdk/ecs"; +import { activeNPC, clearNPC, closeDialogWindow, followPath, isActiveNpcSet, npcDataComponent, setActiveNPC, stopPath, stopWalking } from "./npc"; +import { IsTypingDialog } from "./components"; +import { handleDialogTyping } from "./systems"; +import { Dialog, ImageData, NPCState } from "./types"; +import { leftClickSection, leftClickSectionbBlack, lightTheme, section, skipButtonSection, skipButtonSectionBlack } from './ui'; +import { getBubbleTextLength } from './bubble'; +import { Color4 } from '@dcl/sdk/math'; + + +export const npcDialogComponent: Map = new Map() +export const npcDialogTypingSystems: Map = new Map() +export const npcDialogInputListener: Map = new Map() + +export enum ConfirmMode { + Confirm = 0, + Cancel = 1, + Next = 2, + Button3 = 3, + Button4 = 4 + } + +export let UIscaleMultiplier = 0.75 + +let portraitXPos = -50 * UIscaleMultiplier +let portraitYPos = 20 * UIscaleMultiplier + +let imageXPos = 350 * UIscaleMultiplier +let imageYPos = 50 * UIscaleMultiplier + +let portraitScale = 256 * UIscaleMultiplier +let imageScale = 256 * UIscaleMultiplier + +let textSize = 24 * UIscaleMultiplier +let textYPos = 10 * UIscaleMultiplier + +let buttonWidth = 174* UIscaleMultiplier +let buttonHeight = 46* UIscaleMultiplier + + +let buttonTextSize = 20 * UIscaleMultiplier + +let button1XPos = 150 * UIscaleMultiplier +let button2XPos = -80 * UIscaleMultiplier +let button3XPos = -80 * UIscaleMultiplier +let button4XPos = 150 * UIscaleMultiplier + +let button1YPos = -65 * UIscaleMultiplier +let button2YPos = -65 * UIscaleMultiplier +let button1YPos4 = -20 * UIscaleMultiplier +let button2YPos4 = -20 * UIscaleMultiplier +let button3YPos = -80 * UIscaleMultiplier +let button4YPos = -80 * UIscaleMultiplier + +let skipButtonXPos = -300 * UIscaleMultiplier +let skipButtonYPos = -100 * UIscaleMultiplier + +let buttonIconWidth = 26 * UIscaleMultiplier +let buttonIconHeight = 26 * UIscaleMultiplier + +// + +export function addDialog(npc:Entity, sound?:string, defaultPortrait?:ImageData){ + console.log('adding dialog for npc', npc) + npcDialogComponent.set(npc, { + typing:true, + visible:false, + visibleText:"", + visibleChars:0, + fullText:"", + timer:0, + speed:30, + originalScript:[], + script:[], + index:0, + sound: sound ? sound : undefined, + soundPlayer: sound ? engine.addEntity() : undefined, + fontSize:22, + isQuestion:false, + buttons:0, + displayPortrait: defaultPortrait ? true : false, + defaultPortrait: defaultPortrait ? defaultPortrait : null, + defaultPortraitTexture: defaultPortrait ? defaultPortrait.path : lightTheme, + currentPortrait: defaultPortrait ? defaultPortrait.path : lightTheme, + portraitWidth: defaultPortrait && defaultPortrait.width ? defaultPortrait.width * UIscaleMultiplier : portraitScale, + portraitHeight: defaultPortrait && defaultPortrait.height ? defaultPortrait.height * UIscaleMultiplier : portraitScale, + portraitX: defaultPortrait && defaultPortrait.offsetX ? defaultPortrait.offsetX * UIscaleMultiplier + portraitXPos : portraitXPos, + portraitY: defaultPortrait && defaultPortrait.offsetY ? defaultPortrait.offsetY * UIscaleMultiplier + portraitYPos : portraitYPos, + portaitSHeight: defaultPortrait && defaultPortrait.section && defaultPortrait.section.sourceHeight ? defaultPortrait.section.sourceHeight : 256, + portraitSWidth: defaultPortrait && defaultPortrait.section && defaultPortrait.section.sourceWidth ? defaultPortrait.section.sourceWidth : 256, + portaitSTop: defaultPortrait && defaultPortrait.section && defaultPortrait.section.sourceTop ? defaultPortrait.section.sourceTop : 0, + portraitSLeft: defaultPortrait && defaultPortrait.section && defaultPortrait.section.sourceLeft ? defaultPortrait.section.sourceLeft : 0 + }) +} + +export function displayImage(){ + return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).displayImage +} + +export function displayPortrait(){ + return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).displayPortrait +} + +export function displaySkipable(){ + return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).skipable +} + +export function getSkipableTheme(){ + return !isActiveNpcSet() ? skipButtonSectionBlack : npcDataComponent.get(activeNPC).theme == lightTheme ? skipButtonSectionBlack : skipButtonSection +} + +export function getLeftClickTheme(){ + return !isActiveNpcSet() ? leftClickSection : npcDataComponent.get(activeNPC).theme == lightTheme ? leftClickSection : leftClickSectionbBlack +} + +export function positionTextX(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).positionX +} + +export function positionTextY(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).positionY +} + +export function positionPortaitX(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).portraitX +} + +export function positionPortaitY(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).portraitY +} + +export function portraitWidth(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).portraitWidth +} + +export function portraitHeight(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).portraitHeight +} + +export function positionImageX(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).imageX +} + +export function positionImageY(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).imageY +} + +export function imageWidth(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).imageWidth +} + +export function imageHeight(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).imageHeight +} + +export function getPortrait(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).currentPortrait +} + +export function getImage(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).dialogImageTexture +} + +export function getText(){ + return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).visibleText +} + +export function getTextColor(){ + return !isActiveNpcSet() ? Color4.Black() : npcDataComponent.get(activeNPC).theme == lightTheme ? Color4.Black() : Color4.White() +} + +export function getTheme(){ + return !isActiveNpcSet() ? lightTheme : npcDataComponent.get(activeNPC).theme +} + +export function getButtonText(button:number){ + let text = "" + + if(activeNPC != 0 && npcDialogComponent.has(activeNPC)){ + let dialogData = npcDialogComponent.get(activeNPC) + if(dialogData.isQuestion && dialogData.buttons > button){ + text = dialogData.script[dialogData.index].buttons[button].label + text = text.slice(0, 15) + } + } + return text +} + +export function getbuttonSize(button:number) { + let ButtonSize: number | string | undefined + if (activeNPC != 0 && npcDialogComponent.has(activeNPC)) { + let dialogData = npcDialogComponent.get(activeNPC); + if (dialogData.isQuestion && dialogData.buttons > button) { + if (dialogData.script[dialogData.index].buttons[button].size !== undefined) { + ButtonSize = dialogData.script[dialogData.index].buttons[button]?.size; + } + } + } + return ButtonSize +} + +export function getFontSize(){ + return !isActiveNpcSet() ? 22 : npcDialogComponent.get(activeNPC).fontSize +} + +export function displayDialog(){ + return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).visible +} + +export function displayButton(button:number){ + return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).isQuestion && npcDialogComponent.get(activeNPC).buttons >= button +} + +export function displayFirstButtonContainer(){ + return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).isQuestion && npcDialogComponent.get(activeNPC).buttons >= 1 +} + +export function displaySecondButtonContainer(){ + return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).isQuestion && npcDialogComponent.get(activeNPC).buttons >= 3 +} + +export function getTextPosition(){ + //console.log(npcDialogComponent.get(activeNPC).buttons) + return !isActiveNpcSet() ? {top:0, left:0} : {top:npcDialogComponent.get(activeNPC).margin + npcDialogComponent.get(activeNPC).positionY, left: npcDialogComponent.get(activeNPC).positionX} +} + +export function buttonClick(button:number){ + if(isActiveNpcSet()){ + confirmText(activeNPC, button) + } +} + +export function closeDialog(npc:Entity){ + let dialogData = npcDialogComponent.get(npc) + dialogData.visible = false + dialogData.typing = false + dialogData.visibleText = "" + dialogData.visibleChars = 0 + dialogData.fullText = "" + dialogData.timer = 0 + dialogData.index = 0 + dialogData.script.length = 0 + dialogData.buttons = 0 + dialogData.margin = 0 + dialogData.displayPortrait = false + dialogData.skipable = false + dialogData.displayImage = false + console.log('dialog data is now ', dialogData) + + if(IsTypingDialog.has(npc)){ + IsTypingDialog.deleteFrom(npc) + } + // if(npcDataComponent.get(npc).manualStop){ + // console.log('dialog ended, needto walk again') + // followPath(npc) + // } + clearNPC() +} + +export function talk(npc:Entity, dialog:Dialog[], startIndex?:number | string, duration?:number){ + npcDataComponent.get(npc).introduced = true + if(npcDialogComponent.has(npc)){ + + setActiveNPC(npc) + if(npcDataComponent.get(npc).state == NPCState.FOLLOWPATH){ + console.log("speaking dialog, need to stop path") + stopWalking(npc) + } + + npcDataComponent.get(npc).state = NPCState.TALKING + + + let index:any + + if (!startIndex) { + index = 0 + } else if (typeof startIndex === 'number') { + index = startIndex + } else { + index = findDialogByName(dialog, startIndex) + } + + openDialog(npc,dialog, index) + } +} + +export function openDialog(npc:Entity, dialog:Dialog[], startIndex:number){ + console.log('script to talk is', dialog) + let dialogData = npcDialogComponent.get(npc) + dialogData.script = dialog.slice() + dialogData.index = startIndex + + console.log('dialog data is now', dialogData) + + let currentText: Dialog = dialog[startIndex] ? dialog[startIndex] : { text: '' } + + if (currentText.audio) { + AudioSource.createOrReplace(dialogData.soundPlayer, { + audioClipUrl: currentText.audio, + loop: false, + playing: false + }) + let audio = AudioSource.getMutable(dialogData.soundPlayer) + audio.volume = 0.5 + audio.playing = true + } else if (dialogData.sound) { + AudioSource.createOrReplace(dialogData.soundPlayer, { + audioClipUrl: dialogData.sound, + loop: false, + playing: false + }) + let audio = AudioSource.getMutable(dialogData.soundPlayer) + audio.volume = 0.5 + audio.playing = true + } + + //TODO + //set image on the right + //set text + beginTyping(npc) +} + +export function addLineBreak(text:string, bubble?:boolean){ + return lineBreak(text, bubble? getBubbleTextLength(text)! : 45) +} + +function beginTyping(npc:Entity){ + let dialogData = npcDialogComponent.get(npc) + dialogData.fullText = addLineBreak(dialogData.script[dialogData.index].text) //dialogData.script[dialogData.index].text + dialogData.visible = true + dialogData.typing = true + dialogData.visibleText = "" + dialogData.visibleChars = 0 + dialogData.timer = 0 + dialogData.isQuestion = false + dialogData.buttons = 0 + dialogData.displayPortrait = false + dialogData.displayImage = false + dialogData.skipable = false + + let currentText: Dialog = dialogData.script[dialogData.index] ? dialogData.script[dialogData.index] : { text: '' } + if(currentText.portrait){ + dialogData.currentPortrait = currentText.portrait.path + + dialogData.portraitX = currentText.portrait.offsetX + ? currentText.portrait.offsetX * UIscaleMultiplier + portraitXPos + : portraitXPos + + dialogData.portraitY = currentText.portrait.offsetY + ? currentText.portrait.offsetY * UIscaleMultiplier + portraitYPos + : portraitYPos + + dialogData.portraitWidth = currentText.portrait.width ? currentText.portrait.width * UIscaleMultiplier : portraitScale + + dialogData.portraitHeight = currentText.portrait.height ? currentText.portrait.height * UIscaleMultiplier : portraitScale + dialogData.displayPortrait = true + }else if(dialogData.defaultPortrait){ + dialogData.currentPortrait = dialogData.defaultPortraitTexture + dialogData.displayPortrait = true + } + else{ + dialogData.displayPortrait = false + } + + if(dialogData.script[dialogData.index].isQuestion){ + dialogData.buttons = dialogData.script[dialogData.index].buttons.length + if(dialogData.buttons >= 3){ + dialogData.margin = -25 + } + else if(dialogData.buttons >=1){ + dialogData.margin = -25 + } + + console.log(dialogData) + utils.timers.setTimeout( + function() { + console.log('setting question to true') + dialogData.isQuestion = true + }, + 700 + ) + } + + dialogData.openTime = Math.floor(Date.now()) + if(dialogData.script[dialogData.index].fontSize){ + dialogData.fontSize = dialogData.script[dialogData.index].fontSize + } + + if(dialogData.script[dialogData.index].skipable){ + dialogData.skipable = true + } + else{ + dialogData.skipable = false + } + + if(dialogData.script[dialogData.index].image){ + dialogData.dialogImageTexture = dialogData.script[dialogData.index].image.path + dialogData.imageX = dialogData.script[dialogData.index].image.offsetX ? dialogData.script[dialogData.index].image.offsetX * UIscaleMultiplier + imageXPos : -40 + dialogData.imageY = dialogData.script[dialogData.index].image.offsetY ? dialogData.script[dialogData.index].image.offsetY * UIscaleMultiplier + imageYPos : 40 + dialogData.imageHeight = dialogData.script[dialogData.index].image.height ? dialogData.script[dialogData.index].height * UIscaleMultiplier : imageScale + dialogData.imageWidth = dialogData.script[dialogData.index].image.width ? dialogData.script[dialogData.index].width * UIscaleMultiplier : imageScale + dialogData.displayImage = true + } + + dialogData.positionX = dialogData.script[dialogData.index].offsetX ? dialogData.script[dialogData.index].offsetX * UIscaleMultiplier : '22%' + dialogData.positionY = dialogData.script[dialogData.index].offsetY ? dialogData.script[dialogData.index].offsetY * UIscaleMultiplier + textYPos : textYPos + + if(dialogData.script[dialogData.index].hasOwnProperty("typeSpeed")){ + dialogData.speed = dialogData.script[dialogData.index].typeSpeed + } + else{ + dialogData.speed = 30 + } + + if(dialogData.speed <= 0){ + rushText(npc) + } + else{ + if(!IsTypingDialog.has(npc)){ + IsTypingDialog.create(npc) + } + + // if(!npcDialogTypingSystems.has(npc)){ + // npcDialogTypingSystems.set(npc,engine.addSystem(handleDialogTyping)) + // } + } +} + +export function addLineBreaks(dialog:Dialog[], bubble?:boolean){ + let cleaned:Dialog[] = dialog.slice() + cleaned.forEach((d)=>{ + d.text = lineBreak(d.text, bubble? getBubbleTextLength(d.text)! : 50) + }) + return cleaned +} + +function lineBreak(text: string, maxLineLength: number): string { + const words = text.split(' '); + let currentLine = ''; + const lines = []; + + for (const word of words) { + if (currentLine.length + word.length + 1 <= maxLineLength) { + currentLine += `${word} `; + } else { + lines.push(currentLine.trim()); + currentLine = `${word} `; + } + } + lines.push(currentLine.trim()); + return lines.join('\n'); +} + +export function handleDialogClick(){ + console.log('handling click') + let npc = activeNPC + if(npcDialogComponent.has(npc)){ + let dialogData = npcDialogComponent.get(npc) + if(!dialogData.visible || (Math.floor(Date.now()) - dialogData.openTime < 100)) return + + if(dialogData.typing){ + rushText(npc) + } + else{ + confirmText(npc, ConfirmMode.Next) + } + } +} + +export function rushText(npc:Entity){ + let dialogData = npcDialogComponent.get(npc) + dialogData.typing = false + dialogData.timer = 0 + dialogData.visibleChars = dialogData.fullText.length + dialogData.visibleText = dialogData.fullText + //engine.removeSystem(npcDialogTypingSystems.get(npc)) +} + +export function confirmText(npc:Entity, mode: ConfirmMode): void { + console.log('confirm text') + let dialogData = npcDialogComponent.get(npc) + dialogData.openTime = Math.floor(Date.now()) + + let currentText = dialogData.script[dialogData.index] + // Update active text + if (mode == ConfirmMode.Next) { + if (!currentText.isQuestion) { + if (currentText.triggeredByNext) { + currentText.triggeredByNext() + } + if (currentText.isEndOfDialog) { + closeDialog(npc) + return + } + dialogData.index++ + } + } + + if (mode == ConfirmMode.Confirm) { + if (currentText.buttons && currentText.buttons.length >= 1) { + if (typeof currentText.buttons[0].goToDialog === 'number') { + dialogData.index = currentText.buttons[0].goToDialog + } + + //TODO + //allow dialogs to be index by name + // else { + // this.activeTextId = findDialogByName(this.NPCScript, currentText.buttons[0].goToDialog) + // } + if (currentText.buttons[0].triggeredActions) { + currentText.buttons[0].triggeredActions() + } + } + } + + if (mode == ConfirmMode.Cancel) { + if (currentText.buttons && currentText.buttons.length >= 1) { + if (typeof currentText.buttons[1].goToDialog === 'number') { + dialogData.index = currentText.buttons[1].goToDialog + } + + //TODO + //allow dialogs to be index by name + // else { + // this.activeTextId = findDialogByName(this.NPCScript, currentText.buttons[0].goToDialog) + // } + if (currentText.buttons[1].triggeredActions) { + currentText.buttons[1].triggeredActions() + } + } + } + + if (mode == ConfirmMode.Button3) { + if (currentText.buttons && currentText.buttons.length >= 1) { + if (typeof currentText.buttons[2].goToDialog === 'number') { + dialogData.index = currentText.buttons[2].goToDialog + } + + //TODO + //allow dialogs to be index by name + // else { + // this.activeTextId = findDialogByName(this.NPCScript, currentText.buttons[0].goToDialog) + // } + if (currentText.buttons[2].triggeredActions) { + currentText.buttons[2].triggeredActions() + } + } + } + + if (mode == ConfirmMode.Button4) { + if (currentText.buttons && currentText.buttons.length >= 1) { + if (typeof currentText.buttons[3].goToDialog === 'number') { + dialogData.index = currentText.buttons[3].goToDialog + } + + //TODO + //allow dialogs to be index by name + // else { + // this.activeTextId = findDialogByName(this.NPCScript, currentText.buttons[0].goToDialog) + // } + if (currentText.buttons[3].triggeredActions) { + currentText.buttons[3].triggeredActions() + } + } + } + + + beginTyping(npc) +} + +export function skipDialogs(npc:Entity) { + let dialogData = npcDialogComponent.get(npc) + if (!dialogData.visible || +Date.now() - dialogData.openTime < 100) return + + while ( + dialogData.script[dialogData.index] && + dialogData.script[dialogData.index].skipable && + dialogData.script[dialogData.index].isQuestion + ){ + if(dialogData.script[dialogData.index].triggeredByNext){ + dialogData.script[dialogData.index].triggeredByNext() + } + + if(dialogData.script[dialogData.index].skipable && + dialogData.script[dialogData.index].isEndOfDialog + ){ + closeDialogWindow(npc) + return + } + + dialogData.index += 1 + } + confirmText(npc, ConfirmMode.Next) +} + +export type ImageAtlasData = { + atlasWidth: number; + atlasHeight: number; + sourceWidth: number; + sourceHeight: number; + sourceLeft: number; + sourceTop: number; + } + + +export function getImageAtlasMapping(data?: ImageAtlasData): number[] { + if (!data) return [] + + const { + atlasWidth, + atlasHeight, + sourceWidth, + sourceHeight, + sourceTop, + sourceLeft, + } = data + + return [ + sourceLeft / atlasWidth, (atlasHeight - sourceTop - sourceHeight) / atlasHeight, + sourceLeft / atlasWidth, (atlasHeight - sourceTop) / atlasHeight, + (sourceLeft + sourceWidth) / atlasWidth, (atlasHeight - sourceTop) / atlasHeight, + (sourceLeft + sourceWidth) / atlasWidth, (atlasHeight - sourceTop - sourceHeight) / atlasHeight, + ] + } + + export function realWidth(width?:number): number { + return width ? width : section.sourceWidth + } + + export function realHeight(height?:number): number { + return height ? height : section.sourceHeight + } + + export function findDialogByName(dialogs: Dialog[], name: string) { + for (let i = 0; i < dialogs.length; i++) { + if (dialogs[i].name && dialogs[i].name == name) { + return i + } + } + return 0 + } + + + +export function closeTag(dialogData:any, newChars: number){ + if(dialogData.visibleChars == 0 || newChars ==0 ) return + +let openTag: boolean = false +let closeTag : boolean = false +for(let i = dialogData.visibleChars-newChars; i < dialogData.visibleChars ; i++){ + + if(!openTag){ + if(dialogData.fullText.substr(i, 1) == '<'){ + openTag= true + + } + } else { + if(dialogData.fullText.substr(i, 1) == '>'){ + closeTag= true + + } + } +} + +if(!openTag || closeTag){ + return +} + +while(dialogData.visibleChars < dialogData.fullText.length && dialogData.fullText.substr(dialogData.visibleChars-1, 1) != '>'){ + dialogData.visibleChars+=1 +} +return +} + +export { Dialog }; diff --git a/demo/src/faceUserSystem.ts b/demo/src/faceUserSystem.ts new file mode 100644 index 0000000..c90e256 --- /dev/null +++ b/demo/src/faceUserSystem.ts @@ -0,0 +1,37 @@ +import { Schemas, Transform, engine } from "@dcl/sdk/ecs" +import { Quaternion, Vector3 } from "@dcl/sdk/math" + + +let faceUserAdded: boolean = false + +export function addFaceUserSystem() { + faceUserAdded = true + + engine.addSystem(faceUserSystem) +} + +export const TrackUserFlag = engine.defineComponent( + "npcutils::trackUserFlag", + { + lockXZRotation: Schemas.Boolean, + active: Schemas.Boolean, + rotSpeed: Schemas.Number + }) + +export function faceUserSystem(dt: number) { + for (const [entity, track] of engine.getEntitiesWith(TrackUserFlag)) { + if (track.active) { + const player = Transform.get(engine.PlayerEntity) + let lookAtTarget = Vector3.create(player.position.x, player.position.y, player.position.z) + let direction = Vector3.subtract(lookAtTarget, Transform.get(entity).position) + + let transform = Transform.getMutable(entity) + transform.rotation = Quaternion.slerp(player.rotation, Quaternion.lookRotation(direction), dt * track.rotSpeed) + + if (track.lockXZRotation) { + transform.rotation.x = 0 + transform.rotation.z = 0 + } + } + } +} diff --git a/demo/src/index.ts b/demo/src/index.ts new file mode 100644 index 0000000..b722516 --- /dev/null +++ b/demo/src/index.ts @@ -0,0 +1,47 @@ +import { Quaternion, Vector3 } from '@dcl/sdk/math' +import { Animator, AudioSource, AvatarAttach, GltfContainer, Material, MeshCollider, Transform, VideoPlayer, VisibilityComponent, engine, pointerEventsSystem } from '@dcl/sdk/ecs' +import { initAssetPacks } from '@dcl/asset-packs/dist/scene-entrypoint' +import { talk } from './dialog' +import { NPCType } from './types'; +import { create } from './npc'; +import { setupUi } from './uiComp'; + +initAssetPacks(engine, pointerEventsSystem, { + Animator, + AudioSource, + AvatarAttach, + Transform, + VisibilityComponent, + GltfContainer, + Material, + VideoPlayer +}) + +export function main() { + + setupUi() + + let myNPC = create( + { position: Vector3.create(8, 1, 8), rotation: Quaternion.Zero(), scale: Vector3.create(1, 1, 1) }, + { + type: NPCType.CUSTOM, + model: 'models/hi.glb', + portrait: { path: 'images/hi.png', height: 220, width: 220 }, + onActivate: () => { + talk(myNPC, [ + { + text: `Quest Overview: In the mystical realm of Eldoria, a sinister force has swept through the winter lands, freezing the hearts of magical creatures and stealing the essence of Frostfire Crystals - the source of warmth and magic. As a valiant hero, you are called upon to embark on a quest to restore balance and save the fantastical festivities.`, + isQuestion: true, + buttons: [ + { label: `Restore magic!`, goToDialog: 2, size: 'auto'}, + { label: `Crystal theft`, goToDialog: 1, size: 'auto'}, + { label: `Icy crisis`, goToDialog: 1, size: 100}, + { label: `Heroes darkness.`, goToDialog: 1 }, + ], + } + ]) + } + } + ) + MeshCollider.setBox(myNPC) +} diff --git a/demo/src/npc.ts b/demo/src/npc.ts new file mode 100644 index 0000000..c815a24 --- /dev/null +++ b/demo/src/npc.ts @@ -0,0 +1,712 @@ +import * as utils from '@dcl-sdk/utils' +import { + Animator, + AvatarShape, + engine, + Entity, + GltfContainer, + InputAction, + MeshCollider, + MeshRenderer, + PBAvatarShape, + PBGltfContainer, + pointerEventsSystem, + Transform, + TransformType, + PBAnimationState +} from '@dcl/sdk/ecs' +import { Color3, Quaternion, Vector3 } from '@dcl/sdk/math' +import { bubbles, closeBubble, createDialogBubble, openBubble } from './bubble' +import { IsFollowingPath, TrackUserFlag } from './components' +import { addDialog, closeDialog, findDialogByName, npcDialogComponent, openDialog } from './dialog' +import { faceUserSystem, handleBubbletyping, handleDialogTyping, handlePathTimes, inputListenerSystem } from './systems' +import { Dialog, FollowPathData, ImageData, NPCData, NPCPathType, NPCState, NPCType, TriggerData } from './types' +import { darkTheme, lightTheme } from './ui' + +export const walkingTimers: Map = new Map() +export const npcDataComponent: Map = new Map() +export let NULL_NPC: Entity = 0 as Entity +export let activeNPC: Entity = NULL_NPC +export let blankDialog: number = 0 + +engine.addSystem(handlePathTimes) +engine.addSystem(handleDialogTyping) +engine.addSystem(handleBubbletyping) +engine.addSystem(faceUserSystem) +engine.addSystem(inputListenerSystem) + +//TODO MAKE isCooldown and no longer have to track with map to remove memory leak issues +const isCooldown: Map = new Map() +const onActivateCbs: Map = new Map() +const onWalkAwayCbs: Map = new Map() +const animTimers: Map = new Map() +const pointReachedCallbacks: Map = new Map() +const onFinishCallbacks: Map = new Map() + +export function showDebug(debug: boolean) { + utils.triggers.enableDebugDraw(debug) +} + +export function getData(npc: Entity) { + return npcDataComponent.get(npc) +} + +export function create(transform: any, data: NPCData) { + let npc = engine.addEntity() + + let t: TransformType = { + position: transform.position ? transform.position : Vector3.create(0, 0, 0), + rotation: transform.rotation ? transform.rotation : Quaternion.Zero(), + scale: transform.scale ? transform.scale : Vector3.One() + } + Transform.create(npc, t) + + npcDataComponent.set(npc, { + introduced: false, + inCooldown: false, + coolDownDuration: data && data.coolDownDuration ? data.coolDownDuration : 5, + faceUser: data && data.faceUser ? data.faceUser : undefined, + walkingSpeed: 2, + walkingAnim: data && data.walkingAnim ? data.walkingAnim : undefined, + pathData: data.pathData ? data.pathData : undefined, + currentPathData: [], + manualStop: false, + pathIndex: 0, + state: NPCState.STANDING, + idleAnim: data && data.idleAnim ? data.idleAnim : 'Idle', + bubbleHeight: data && data.textBubble && data.bubbleHeight ? data.bubbleHeight : undefined, + bubbleSound: data.dialogSound ? data.dialogSound : undefined, + hasBubble: data && data.textBubble ? true : false, + turnSpeed: data && data.turningSpeed ? data.turningSpeed : 2, + theme: data.darkUI ? darkTheme : lightTheme, + bubbleXOffset: data.bubbleXOffset ? data.bubbleXOffset : 0, + bubbleYOffset: data.bubbleYOffset ? data.bubbleYOffset : 0 + }) + + if (data && data.noUI) { + } else if (data && data.portrait) { + addDialog( + npc, + data && data.dialogSound ? data.dialogSound : undefined, + typeof data.portrait === `string` ? { path: data.portrait } : data.portrait + ) + } else { + addDialog(npc, data && data.dialogSound ? data.dialogSound : undefined) + } + + if (data && data.textBubble) { + createDialogBubble(npc, npcDataComponent.get(npc).bubbleHeight) + } + + onActivateCbs.set(npc, (other: Entity) => { + data.onActivate(other) + }) + + if (data && data.hasOwnProperty('onWalkAway')) { + onWalkAwayCbs.set(npc, (other: Entity) => { + if (!data || !data.continueOnWalkAway) { + if (npcDialogComponent.has(npc)) { + npcDialogComponent.get(npc).visible = false + } + } else { + if (npcDialogComponent.has(npc)) { + npcDialogComponent.get(npc).visible = false + } + } + data.onWalkAway!(other) + }) + } + + addNPCBones(npc, data) + addClickReactions(npc, data) + addTriggerArea(npc, data) + + if (data && data.pathData && data.pathData.speed) { + let npcData = npcDataComponent.get(npc) + npcData.walkingSpeed = data.pathData.speed + } + + if (data && data.coolDownDuration) { + let npcData = npcDataComponent.get(npc) + npcData.coolDownDuration = data.coolDownDuration + } + + if (data && data.pathData) { + let npcData = npcDataComponent.get(npc) + npcData.pathData.loop = true + followPath(npc, npcData.pathData) + } + + return npc +} + +function addNPCBones(npc: Entity, data: NPCData) { + const modelIsString = data && data.model && typeof data.model === `string` + const modelAvatarData: PBAvatarShape | undefined = modelIsString + ? undefined + : data.model && (data.model as any).bodyShape + ? (data.model as PBAvatarShape) + : undefined + const modelGLTFData: PBGltfContainer | undefined = modelIsString + ? undefined + : data.model && (data.model as any).src + ? (data.model as PBGltfContainer) + : undefined + + switch (data.type) { + case NPCType.AVATAR: + AvatarShape.create( + npc, + !data || !data.model || !modelAvatarData + ? { + id: 'npc', + name: 'NPC', + bodyShape: 'urn:decentraland:off-chain:base-avatars:BaseMale', + emotes: [], + wearables: [ + 'urn:decentraland:off-chain:base-avatars:f_eyes_00', + 'urn:decentraland:off-chain:base-avatars:f_eyebrows_00', + 'urn:decentraland:off-chain:base-avatars:f_mouth_00', + 'urn:decentraland:off-chain:base-avatars:comfy_sport_sandals', + 'urn:decentraland:off-chain:base-avatars:soccer_pants', + 'urn:decentraland:off-chain:base-avatars:elegant_sweater' + ] + } + : modelAvatarData + ) + break + + case NPCType.CUSTOM: + GltfContainer.create( + npc, + modelIsString && typeof data.model === `string` ? { src: data && data.model ? data.model : '' } : modelGLTFData + ) + Animator.create(npc, { + states: [ + { + clip: data && data.idleAnim ? data.idleAnim : 'Idle', + loop: true + } + ] + }) + + let npcData = npcDataComponent.get(npc) + npcData.idleAnim = data && data.idleAnim ? data.idleAnim : 'Idle' + npcData.lastPlayedAnim = npcDataComponent.get(npc).idleAnim + + Animator.playSingleAnimation(npc, npcDataComponent.get(npc).idleAnim) + + if (data && data.walkingAnim) { + npcDataComponent.get(npc).walkingAnim = data.walkingAnim + let animations = Animator.getMutable(npc) + animations.states.push({ clip: data.walkingAnim, loop: true }) + } + + break + + case NPCType.BLANK: + MeshRenderer.setBox(npc) + MeshCollider.setBox(npc) + break + } +} + +function addClickReactions(npc: Entity, data: NPCData) { + let activateButton = data && data.onlyClickTrigger ? InputAction.IA_POINTER : InputAction.IA_PRIMARY + + /* + pointerEventsSystem.onPointerDown( + { + entity: npc, + opts: { + button: activateButton, + hoverText: data && data.hoverText ? data.hoverText : 'Talk', + showFeedback: data && data.onlyExternalTrigger ? false : true + } + }, + () => { + if (isCooldown.has(npc) || npcDialogComponent.get(npc).visible) return + activate(npc, engine.PlayerEntity) + }, + ) + */ + + pointerEventsSystem.onPointerDown( + npc, + function () { + if (isCooldown.has(npc) || npcDialogComponent.get(npc).visible) return + activate(npc, engine.PlayerEntity) + }, + { + button: activateButton, + hoverText: data && data.hoverText ? data.hoverText : 'Talk', + showFeedback: data && data.onlyExternalTrigger ? false : true + } + ) + + if (data && data.onlyExternalTrigger) { + pointerEventsSystem.removeOnPointerDown(npc) + } +} + +function addTriggerArea(npc: Entity, data: NPCData) { + let triggerData: TriggerData = {} + + if (!data || (data && !data.onlyExternalTrigger && !data.onlyClickTrigger && !data.onlyETrigger)) { + onActivateCbs.set(npc, (other: Entity) => { + if (isCooldown.has(npc)) { + console.log(npc, ' in cooldown') + return + } else if ( + (npcDialogComponent.has(npc) && npcDialogComponent.get(npc).visible) || + (data && data.onlyExternalTrigger) || + (data && data.onlyClickTrigger) + ) { + return + } + data.onActivate(other) + }) + triggerData.onCameraEnter = onActivateCbs.get(npc) + } + + // when exiting trigger + if (!data || (data && !data.continueOnWalkAway)) { + triggerData.onCameraExit = (other) => { + handleWalkAway(npc, other) + } + } + + // when entering trigger + if (!data || (data && !data.onlyExternalTrigger && !data.onlyClickTrigger && !data.onlyETrigger)) { + triggerData.onCameraEnter = (other) => { + if (isCooldown.has(npc)) { + console.log(npc, ' in cooldown') + return + } + // else if ( + // (this.dialog && this.dialog.isDialogOpen) || + // (data && data.onlyExternalTrigger) || + // (data && data.onlyClickTrigger) + // ) { + // return + // } + activate(npc, other) + } + } + + // add trigger + if (triggerData.onCameraEnter || triggerData.onCameraExit) { + utils.triggers.addTrigger( + npc, + triggerData.layer != undefined ? triggerData.layer : utils.NO_LAYERS, + triggerData.triggeredByLayer != undefined ? triggerData.triggeredByLayer : utils.LAYER_1, + [{ type: 'sphere', position: Vector3.Zero(), radius: data.reactDistance != undefined ? data.reactDistance : 6 }], + (other) => { + if (triggerData.onCameraEnter) triggerData.onCameraEnter(other) + }, + (other) => { + if (triggerData.onCameraExit) triggerData.onCameraExit(other) + }, + Color3.Red() + ) + } +} + +export function followPath(npc: Entity, data?: FollowPathData) { + let npcData = npcDataComponent.get(npc) + let path: any[] = [] + + if (npcData.faceUser) { + if (TrackUserFlag.has(npc)) { + TrackUserFlag.deleteFrom(npc) + } + } + + if (npcData.manualStop) { + let duration = npcData.pathData.totalDuration + let currentTimer: number = walkingTimers.get(npc)! + console.log('current time is', currentTimer) + if (currentTimer) { + duration -= currentTimer + } + + let path: any[] = [] + npcData.pathData.path.forEach((p: any) => { + path.push(p) + }) + path.splice(0, npcData.pathIndex) + + let pos = Transform.get(npc).position + path.unshift(Vector3.create(pos.x, pos.y, pos.z)) + walkNPC( + npc, + npcData, + npcData.pathData.pathType, + duration, + path, + pointReachedCallbacks.get(npc), + onFinishCallbacks.get(npc) + ) + } else { + if (data) { + npcData.pathData = data + + if (data.startingPoint) { + data.path?.splice(0, data.startingPoint - 1) + } + + let pos = Transform.get(npc).position + path.push(Vector3.create(pos.x, pos.y, pos.z)) + data.path?.forEach((p) => { + path.push(p) + }) + + onFinishCallbacks.set(npc, () => { + console.log('on finished callback') + if (data && data.onFinishCallback && !data.loop) { + data.onFinishCallback() + } + stopPath(npc) + }) + + pointReachedCallbacks.set(npc, () => { + console.log('on point reached callback') + let data = npcDataComponent.get(npc) + data.pathIndex += 1 + data.onReachedPointCallback ? data.onReachedPointCallback : undefined + }) + walkNPC( + npc, + npcData, + data.pathType!, + data.totalDuration, + path, + pointReachedCallbacks.get(npc), + onFinishCallbacks.get(npc) + ) + } else { + if (npcData.manualStop) { + console.log('we have manual stop, need to pick back up where we left off') + } else { + console.log('we are trying to follow a path witout starting one prior') + } + } + } +} + +function walkNPC( + npc: Entity, + npcData: any, + type: NPCPathType, + duration: number, + path: Vector3[], + pointReachedCallback?: any, + finishedCallback?: any +) { + if (IsFollowingPath.has(npc)) { + IsFollowingPath.deleteFrom(npc) + walkingTimers.delete(npc) + } + IsFollowingPath.create(npc) + + if (type) { + if (type == NPCPathType.RIGID_PATH) { + utils.paths.startStraightPath( + npc, + path, + duration, + true, + () => { + finishedCallback() + }, + () => { + pointReachedCallback() + } + ) + } else { + utils.paths.startSmoothPath( + npc, + path, + duration, + 30, + true, + () => { + finishedCallback() + }, + () => { + pointReachedCallback() + } + ) + } + } else { + utils.paths.startSmoothPath( + npc, + path, + duration, + 20, + true, + () => { + finishedCallback() + }, + () => { + pointReachedCallback() + } + ) + } + + if (npcData.walkingAnim) { + clearAnimationTimer(npc) + Animator.playSingleAnimation(npc, npcDataComponent.get(npc).walkingAnim, true) + npcData.lastPlayedAnim = npcDataComponent.get(npc).walkingAnim + } + npcData.state = NPCState.FOLLOWPATH + npcData.manualStop = false +} + +export function stopWalking(npc: Entity, duration?: number, finished?: boolean) { + let npcData = npcDataComponent.get(npc) + npcData.state = NPCState.STANDING + npcData.manualStop = true + + stopPath(npc) + + if (duration) { + utils.timers.setTimeout(() => { + //if (this.dialog && this.dialog.isDialogOpen) return + if (npcData.path) { + Animator.stopAllAnimations(npc, true) + if (npcDataComponent.get(npc).walkingAnim) { + clearAnimationTimer(npc) + Animator.playSingleAnimation(npc, npcDataComponent.get(npc).walkingAnim, true) + npcData.lastPlayedAnim = npcDataComponent.get(npc).walkingAnim + } + let duration = npcData.pathData.totalDuration + let currentTimer: number = walkingTimers.get(npc)! + console.log('current time is', currentTimer) + if (currentTimer) { + duration -= currentTimer + } + + let path: any[] = [] + npcData.pathData.path.forEach((p: any) => { + path.push(p) + }) + path.splice(0, npcData.pathIndex) + + let pos = Transform.get(npc).position + path.unshift(Vector3.create(pos.x, pos.y, pos.z)) + + //npcData.manualStop = false + walkNPC( + npc, + npcData, + npcData.pathData.pathType, + duration, + path, + pointReachedCallbacks.get(npc), + onFinishCallbacks.get(npc) + ) + } + }, duration * 1000) + } +} + +export function stopPath(npc: Entity) { + utils.paths.stopPath(npc) + IsFollowingPath.deleteFrom(npc) + + let npcData = npcDataComponent.get(npc) + if (npcData.walkingAnim) { + clearAnimationTimer(npc) + Animator.playSingleAnimation(npc, npcDataComponent.get(npc).idleAnim) + npcData.lastPlayedAnim = npcData.idleAnim + } + + if (!npcData.manualStop) { + if (npcData.pathData.loop) { + npcData.pathIndex = 0 + walkingTimers.delete(npc) + console.log('we are looping path', npcData) + followPath(npc, npcData.pathData) + console.log(npcData) + } + } +} + +export function clearNPC() { + activeNPC = NULL_NPC +} + +export function setActiveNPC(npc: Entity) { + activeNPC = npc +} + +export function isActiveNpcSet() { + return activeNPC && npcDialogComponent.has(activeNPC) +} + +/** + * Calls the NPC's activation function (set on NPC definition). If NPC has `faceUser` = true, it will rotate to face the player. It starts a cooldown counter to avoid reactivating. + */ +export function activate(npc: Entity, other: Entity) { + if (activeNPC != 0) { + console.log('we have a current npc, needto remove') + endInteraction(activeNPC) + // closeDialog(activeNPC) + } + + activeNPC = npc + onActivateCbs.get(npc)(other) + + let npcData = npcDataComponent.get(npc) + if (npcData.faceUser) { + if (TrackUserFlag.has(npc)) { + TrackUserFlag.deleteFrom(npc) + } + + TrackUserFlag.create(npc, { + lockXZRotation: true, + active: true, + rotSpeed: npcData.turnSpeed + }) + } + isCooldown.set(npc, true) + npcData.inCooldown = true + + utils.timers.setTimeout(function () { + isCooldown.delete(npc) + npcDataComponent.get(npc).inCooldown = false + }, 1000 * npcData.coolDownDuration) + console.log('activated npc,', npcDataComponent.get(npc)) +} + +function endInteraction(npc: Entity) { + let npcData = npcDataComponent.get(npc) + npcData.state = NPCState.STANDING + + if (npcDialogComponent.has(npc)) { + //} && npcDialogComponent.get(npc).visible) { + closeDialog(npc) + } + + if (npcData.faceUser) { + if (TrackUserFlag.has(npc)) { + TrackUserFlag.deleteFrom(npc) + } + } + + console.log('ending interaction', npcData, bubbles.get(npc)) + if (npcData.hasBubble && bubbles.get(npc).isBubbleOpen) { + closeBubble(npc) + } +} + +/** + * Ends interaction and calls the onWalkAway function + */ +export function handleWalkAway(npc: Entity, other: Entity) { + let npcData = npcDataComponent.get(npc) + if (npcData.state == NPCState.FOLLOWPATH) { + return + } + + endInteraction(npc) + + if (onWalkAwayCbs.get(npc)) { + onWalkAwayCbs.get(npc)(other) + } +} + +export function playAnimation(npc: Entity, anim: string, noLoop?: boolean, duration?: number) { + let animations = Animator.getMutable(npc) + let npcData = npcDataComponent.get(npc) + + if (!animations || !npcData) return + + if (animations.states && animations.states.filter((animation: PBAnimationState) => animation.clip === anim).length == 0) { + animations.states.push({ clip: anim, loop: noLoop ? false : true }) + } + + if (npcData.state == NPCState.FOLLOWPATH) { + utils.paths.stopPath(npc) + } + + clearAnimationTimer(npc) + + Animator.stopAllAnimations(npc, true) + Animator.playSingleAnimation(npc, anim, true) + if (duration) { + console.log('have a duration to play animation') + clearAnimationTimer(npc) + animTimers.set( + npc, + utils.timers.setTimeout(() => { + clearAnimationTimer(npc) + Animator.stopAllAnimations(npc, true) + if (npcData.idleAnim) { + Animator.playSingleAnimation(npc, npcData.idleAnim) + npcData.lastPlayedAnim = npcData.idleAnim + } + }, 1000 * duration) + ) // + } + + npcData.lastPlayedAnim = anim +} + +export function changeIdleAnim(npc: Entity, animation: string, play?: boolean) { + let npcData = npcDataComponent.get(npc) + npcData.idleAnim = animation + + let animations = Animator.getMutable(npc) + if (animations.states.filter((anim) => anim.clip === animation).length == 0) { + animations.states.push({ clip: animation, loop: true }) + } + + if (play) { + playAnimation(npc, animation, true) + npcDataComponent.get(npc).lastPlayedAnim = animation + } +} + +export function talkBubble(npc: Entity, script: Dialog[], startIndex?: number | string) { + openBubble(npc, script, startIndex) +} + +export function createDialogWindow(defaultPortrait?: ImageData, sound?: string) { + let dialog = engine.addEntity() + addDialog(dialog, sound, defaultPortrait) + return dialog +} + +export function openDialogWindow(npc: Entity, dialog: Dialog[], startIndex?: number | string) { + activeNPC = npc + + if (npcDialogComponent.has(npc)) { + let index: any + if (!startIndex) { + index = 0 + } else if (typeof startIndex === 'number') { + index = startIndex + } else { + index = findDialogByName(dialog, startIndex) + } + openDialog(npc, dialog, index) + } +} + +export function closeDialogWindow(window: Entity) { + let dialog = npcDialogComponent.get(window) + if (window) { + closeDialog(dialog) + } +} + +function clearAnimationTimer(npc: Entity): boolean { + if (animTimers.has(npc)) { + utils.timers.clearTimeout(animTimers.get(npc) as number) + animTimers.delete(npc) + return true + } + return false +} diff --git a/demo/src/npcData.ts b/demo/src/npcData.ts new file mode 100644 index 0000000..dc25b9a --- /dev/null +++ b/demo/src/npcData.ts @@ -0,0 +1,14 @@ +import { Schemas, engine } from '@dcl/sdk/ecs' +export const NPCDataComponent = engine.defineComponent('npcdatacomponent', { + introduced: Schemas.Boolean, + inCooldown: Schemas.Boolean, + coolDownDuration: Schemas.Number, + faceUser: Schemas.Boolean, + walkingSpeed: Schemas.Number, + bubbleHeight: Schemas.Number, + state: Schemas.String, + walkingAnim: Schemas.String, + idleAnim: Schemas.String, + lastPlayedAnim: Schemas.String, + path: Schemas.Array(Schemas.Vector3) +}) diff --git a/demo/src/systems.ts b/demo/src/systems.ts new file mode 100644 index 0000000..c24dfdb --- /dev/null +++ b/demo/src/systems.ts @@ -0,0 +1,148 @@ +import { Entity, InputAction, PointerEventType, TextShape, Transform, engine, inputSystem } from "@dcl/sdk/ecs"; +import { IsFollowingPath, IsTypingBubble, IsTypingDialog, TrackUserFlag } from "./components"; +import { activeNPC, walkingTimers } from "./npc"; +import { ConfirmMode, closeTag, confirmText, npcDialogComponent, rushText, skipDialogs } from "./dialog"; +import { bubbles, next } from "./bubble"; +import { Quaternion, Vector3 } from "@dcl/sdk/math"; + +export function handlePathTimes(dt:number) { + for (const [entity] of engine.getEntitiesWith(IsFollowingPath)) { + if(walkingTimers.has(entity)){ + let elapsed:number = walkingTimers.get(entity)! + elapsed += dt + walkingTimers.set(entity, walkingTimers.get(entity)! + dt) + } + else{ + walkingTimers.set(entity, dt) + } + } + } + +export function handleDialogTyping(dt:number) { + for (const [entity] of engine.getEntitiesWith(IsTypingDialog)) { + let dialogData = npcDialogComponent.get(entity) + if(!dialogData.typing){ + return + } + + dialogData.timer += dt + if (dialogData.timer >= 2 / dialogData.speed) { + let charsToAdd = Math.floor(dialogData.timer / (1 / dialogData.speed)) + dialogData.timer = 0 + + dialogData.visibleChars += charsToAdd + closeTag(dialogData, charsToAdd) + + + if (dialogData.visibleChars >= dialogData.fullText.length) { + dialogData.typing = false + dialogData.visibleChars = dialogData.fullText.length + IsTypingDialog.deleteFrom(entity) + } + + dialogData.visibleText = dialogData.fullText.substr(0, dialogData.visibleChars) + } + } + } + + export function handleBubbletyping(dt:number) { + for (const [entity] of engine.getEntitiesWith(IsTypingBubble)) { + let dialogData = bubbles.get(entity) + if(dialogData.done){ + continue + } + + dialogData.timer += dt + + if (!dialogData.typing) { + if (dialogData.timer > dialogData.timeOn) { + //dialogData.isBubbleOpen = false + dialogData.done = true + dialogData.typing = false + dialogData.timer = 0 + next(entity) + } + } + else if (dialogData.timer >= 2 / dialogData.speed) { + let charsToAdd = Math.floor(dialogData.timer / (1 / dialogData.speed)) + dialogData.timer = 0 + dialogData.visibleChars += charsToAdd + + if (dialogData.visibleChars >= dialogData.fullText.length || dialogData.done) { + dialogData.typing = false + dialogData.visibleChars = dialogData.fullText.length + IsTypingDialog.deleteFrom(entity) + } + TextShape.getMutable(dialogData.text).text = dialogData.fullText.substr(0, dialogData.visibleChars) + } + } + } + +export function faceUserSystem(dt: number) { + for (const [entity, track] of engine.getEntitiesWith(TrackUserFlag)) { + if (track.active) { + const player = Transform.get(engine.PlayerEntity) + let lookAtTarget = Vector3.create(player.position.x, player.position.y, player.position.z) + let direction = Vector3.subtract(lookAtTarget, Transform.get(entity).position) + + let transform = Transform.getMutable(entity) + transform.rotation = Quaternion.slerp(transform.rotation, Quaternion.lookRotation(direction), dt * track.rotSpeed) + + if (track.lockXZRotation) { + transform.rotation.x = 0 + transform.rotation.z = 0 + } + } + } +} + +export function inputListenerSystem(){ + const PET = inputSystem.isTriggered(InputAction.IA_PRIMARY,PointerEventType.PET_DOWN) + const PEP = inputSystem.isPressed(InputAction.IA_PRIMARY) + + const PPET = inputSystem.isTriggered(InputAction.IA_POINTER,PointerEventType.PET_DOWN) + const PPEP = inputSystem.isPressed(InputAction.IA_POINTER) + + const SET = inputSystem.isTriggered(InputAction.IA_SECONDARY,PointerEventType.PET_DOWN) + const SEP = inputSystem.isPressed(InputAction.IA_SECONDARY) + + if(PPET && PPEP){ + if(activeNPC){ + let dialogData = npcDialogComponent.get(activeNPC) + if(!dialogData.visible || Date.now() - dialogData.openTime < 100)return + if(dialogData.typing){ + rushText(activeNPC) + }else if(!dialogData.isQuestion){ + confirmText(activeNPC, ConfirmMode.Next) + } + } + } + + if(SET && SEP){ + if(activeNPC){ + let dialogData = npcDialogComponent.get(activeNPC) + if(!dialogData.visible || Date.now() - dialogData.openTime < 100)return + if(dialogData.isQuestion){ + confirmText(activeNPC, ConfirmMode.Confirm) + }else if(!dialogData.isQuestion){ + confirmText(activeNPC, ConfirmMode.Next) + } + } + } + + if(PET && PEP){ + if(activeNPC){ + let dialogData = npcDialogComponent.get(activeNPC) + if(!dialogData.visible || Date.now() - dialogData.openTime < 100)return + if(dialogData.isQuestion){ + confirmText(activeNPC, ConfirmMode.Cancel) + }else if(dialogData.script[dialogData.index].skipable && !dialogData.isFixedScreen){ + skipDialogs(activeNPC) + } + } + } + + + +// +} \ No newline at end of file diff --git a/demo/src/types.ts b/demo/src/types.ts new file mode 100644 index 0000000..c091dbe --- /dev/null +++ b/demo/src/types.ts @@ -0,0 +1,245 @@ +import { Entity, PBAvatarShape, PBGltfContainer } from '@dcl/sdk/ecs' +import { Vector3 } from '@dcl/sdk/math' + +/** + * Fragment of a conversation with an NPC + * + * @typedef {Object} Dialog - An entry in an NPC conversation + * @property {string} text The dialog text + * @property {string} name Optional name of the dialog entry, to link other entries to this one and not worry about changes in the array length + * @property {number} fontSize Size of the text + * @property {number} offsetX Offset of the text on the X axis, relative to its normal position. + * @property {number} offsetY Offset of the text on the Y axis, relative to its normal position. + * @property {ImageData} portrait Sets the portrait image to use on the left. This field expects a `Portrait` object. + * @property {ImageData} image Sets a second image to use on the right of the dialog, and slightly up. This field expects an `ImageData` object. + * @property {number} typeSpeed The text appears one character at a time, simulating typing. Players can click to skip the animation. Tune the speed of this typing (30 by default) to go slower or faster. Set to _-1_ to skip the animation. + * @property {boolean} isQuestion If true, allows to use buttons to trigger different actions + * @property {boolean} isFixedScreen If true, has no buttons or "next page" functionality + * @property {ButtonData[]} buttons An array of buttons `ButtonData` objects to use in a question entry + * @property {string} audio Path to sound file to play when the dialog is shown in the UI + * @property {boolean} skipable If true, a "Skip" button on the UI lets players skip to the next non-skipable entry. + * @property {number} timeOn How long to keep the text visible before moving on to the next entry. Only for bubble dialogs! + * + */ +export type Dialog = { + text: string + name?: string + fontSize?: number + offsetX?: number + offsetY?: number + typeSpeed?: number + isEndOfDialog?: boolean + triggeredByNext?: () => void + portrait?: ImageData + image?: ImageData + isQuestion?: boolean + isFixedScreen?: boolean + buttons?: ButtonData[] + audio?: string + skipable?: boolean + timeOn?: number +} + +/** + * + * @typedef {Object} TriggerData - Object with data for a NPCTriggerComponent + * @property {number} layer layer of the Trigger, useful to discriminate between trigger events. You can set multiple layers by using a | symbol. defaults to NO_LAYERS + * @property {number} triggeredByLayer against which layers to check collisions. defaults to LAYER_1 + * @property {(entity: Entity) => void } onTriggerEnter callback when an entity of a valid layer enters the trigger area + * @property {(entity: Entity) => void} onTriggerExit callback when an entity of a valid layer leaves the trigger area + * @property {() => void} onCameraEnter callback when the player enters the trigger area + * @property {() => void} onCameraExit callback when the player leaves the trigger area + * @property {boolean} enableDebug when true makes the trigger area visible for debug purposes. + */ +export type TriggerData = { + layer?: number + triggeredByLayer?: number + onTriggerEnter?: (other: Entity) => void + onTriggerExit?: (other: Entity) => void + onCameraEnter?: (other: Entity) => void + onCameraExit?: (other: Entity) => void + enableDebug?: boolean +} + +/** + * Data for Button to show on a question in a Dialog entry + * + * @typedef {Object} ButtonData - Object with data for a Dialog UI button + * @property {string|number} goToDialog The index or name of the next dialog entry to display when activated. + * @property {string} label The label to show on the button. + * @property {() => void} triggeredActions An additional function to run whenever the button is activated + * @property {number} fontSize Font size of the text + * @property {number}offsetX Offset of the text on the X axis, relative to its normal position. + * @property {number} offsetY Offset of the text on the Y axis, relative to its normal position. + * + */ +export type ButtonData = { + goToDialog: number | string + label: string + triggeredActions?: () => void + fontSize?: number + offsetX?: number + offsetY?: number + size?: number | string +} + +export enum ButtonStyles { + E = `e`, + F = `f`, + DARK = `dark`, + RED = `red`, + ROUNDBLACK = `roundblack`, + ROUNDWHITE = `roundwhite`, + ROUNDSILVER = `roundsilver`, + ROUNDGOLD = `roundgold`, + SQUAREBLACK = `squareblack`, + SQUAREWHITE = `squarewhite`, + SQUARESILVER = `squaresilver`, + SQUAREGOLD = `squaregold`, + WHITE = `white` +} + +/** + * An NPC capable of having conversations with the player, and play different animations. + * + * @typedef {Object} NPCData Object with data to instance a new NPC + * @property {string|ImageData} portrait 2D image to show on the left-hand side of the dialog window. The structure of an `ImageData` object is described in detail below. + * @property {number} reactDistance Radius in meters for the player to activate the NPC or trigger the `onWalkAway()` function when leaving the radius. + * @property {string} idleAnim Name of the idle animation in the model. This animation is always looped. After playing a non-looping animation it returns to looping this one. + * @property {boolean} faceUser Set if the NPC rotates to face the user while active. + * @property {boolean} onlyExternalTrigger If true, the NPC can't be activated by clicking or walking near. Just by calling its `activate()` function. + * @property {boolean} onlyClickTrigger If true, the NPC can't be activated by walking near. Just by clicking on it or calling its `activate()` function. + * @property {boolean} onlyETrigger If true, the NPC can't be activated by walking near. Just by pressing E on it or calling its `activate()` function. + * @property {() => void} onWalkAway Function to call every time the player walks out of the `reactDistance` radius. + * @property {boolean} continueOnWalkAway f true,when the player walks out of the `reactDistance` radius, the dialog window stays open and the NPC keeps turning to face the player (if applicable). It doesn't affect the triggering of the `onWalkAway()` function. + * @property {boolean} darkUI If true, the dialog UI uses the dark theme. + * @property {number} coolDownDuration Change the cooldown period for activating the NPC again. The number is in seconds. + * @property {string} hoverText Set the UI hover feedback when pointing the cursor at the NPC. _TALK_ by default. + * @property {string} dialogSound Path to sound file to play once for every line of dialog read on the UI. + * @property {string} walkingAnim Animation to play when walking with followPath + * @property {number} walkingSpeed Default speed to use when walking with followPath + * @property {Vector3[]} path Array of Vector3 points representing the default path to walk over. The NPC will walk looping over these points + * @property {boolean} textBubble If true, the NPC can display text bubbles with dialogs + * @property {number} bubbleHeight The default height to display text bubbles over the NPC's position + * @property {boolean} noUI If true, no UI dialog elements are constructed. The NPC can use speech bubbles. + * + */ + +export type NPCData = { + type: NPCType + body?: NPCBodyType + model?: string | PBGltfContainer | PBAvatarShape + + walkingAnim?: string + portrait?: string | ImageData + reactDistance?: number + idleAnim?: string + faceUser?: boolean + turningSpeed?: number + onlyExternalTrigger?: boolean + onlyClickTrigger?: boolean + onlyETrigger?: boolean + onActivate: (other: Entity) => void + onWalkAway?: (other: Entity) => void + continueOnWalkAway?: boolean + darkUI?: boolean + coolDownDuration?: number + hoverText?: string + dialogSound?: string + //dialogCustomTheme?: Texture + textBubble?: boolean + bubbleHeight?: number + noUI?: boolean + + pathData?: FollowPathData + + bubbleXOffset?: number + bubbleYOffset?: number +} + +/** + * Make an NPC walk following a path + * + * @typedef {Object} FollowPathData - Object with data to describe a path that an NPC can walk + * @property {Vector3[]} path Array of `Vector3` positions to walk over. + * @property {number} speed Speed to move at while walking this path. If no `speed` or `totalDuration` is provided, it uses the NPC's `walkingSpeed`, which is _2_ by default. + * @property {number} totalDuration The duration in _seconds_ that the whole path should take. The NPC will move at the constant speed required to finish in that time. This value overrides that of the _speed_. + * @property {boolean} loop _boolean_ If true, the NPC walks in circles over the provided set of points in the path. _false_ by default, unless the NPC is initiated with a `path`, in which case it starts as _true_. + * @property {boolean} curve _boolean_ If true, the path is traced a single smooth curve that passes over each of the indicated points. The curve is made out of straight-line segments, the path is stored with 4 times as many points as originally defined. _false_ by default. + * @property {number} startingPoint Index position for what point to start from on the path. _0_ by default. + * @property {() => void} onFinishCallback Function to call when the NPC finished walking over all the points on the path. This is only called when `loop` is _false_. + * @property {() => void} onReachedPointCallback Function to call once every time the NPC reaches a point in the path. + * + */ +export type FollowPathData = { + startingPoint?: number + loop?: boolean + curve?: boolean + totalDuration: number + speed?: number + path?: Vector3[] + pathType?: NPCPathType + onFinishCallback?: () => void + onReachedPointCallback?: () => void +} + +/** + * Cut out a section of an image file + * + * @typedef {Object} ImageSection - Object with data to only display a section of an image + * @property {number} sourceWidth Width in pixels to select from image, starting from the sourceLeft, going right + * @property {number} sourceHeight Height in pixels to select from image, starting from the sourceTop, going down + * @property {number} sourceLeft Leftmost pixel to select from image + * @property {number} sourceTop Topmost pixel to select from image + * + */ +export type ImageSection = { + sourceWidth: number + sourceHeight: number + sourceLeft?: number + sourceTop?: number +} + +/** + * + * + * @typedef {Object} ImageData - Object with data for displaying an image + * @property {string} path Path to the image file. + * @property {number} offsetX Offset on X, relative to the normal position of the image. + * @property {number} offsetY Offset on Y, relative to the normal position of the image. + * @property {number} height The height to show the image onscreen. + * @property {number} width The width to show the image onscreen. + * @property {ImageSection} section Use only a section of the image file, useful when arranging multiple icons into an image atlas. This field takes an `ImageSection` object, specifying `sourceWidth` and `sourceHeight`, and optionally also `sourceLeft` and `sourceTop`. + * + */ +export type ImageData = { + path: string + offsetX?: number + offsetY?: number + height?: number + width?: number + section?: ImageSection +} + +export enum NPCState { + STANDING = 'standing', + TALKING = 'talking', + FOLLOWPATH = 'followPath' + //FOLLOWPLAYER = 'followPlayer' +} + +export enum NPCBodyType { + MALE = 'BaseMale', + FEMALE = 'BaseFemale' +} + +export enum NPCType { + BLANK = 'blank', + CUSTOM = 'custom', + AVATAR = 'avatar' +} + +export enum NPCPathType { + SMOOTH_PATH = 'smooth', //will follow the path but can cut sharp corners + RIGID_PATH = 'rigid' //will ensure each corner is hit +} diff --git a/demo/src/ui.tsx b/demo/src/ui.tsx new file mode 100644 index 0000000..f5716ce --- /dev/null +++ b/demo/src/ui.tsx @@ -0,0 +1,434 @@ +import { Color4 } from '@dcl/sdk/math' +import ReactEcs, { Button, Label, ReactEcsRenderer, UiEntity } from '@dcl/sdk/react-ecs' +import { Entity } from '@dcl/sdk/ecs' +import { + buttonClick, + confirmText, + displayButton, + displayDialog, + displayFirstButtonContainer, + displayImage, + displayPortrait, + displaySecondButtonContainer, + displaySkipable, + getButtonText, + getbuttonSize, + getFontSize, + getImage, + getImageAtlasMapping, + getLeftClickTheme, + getPortrait, + getSkipableTheme, + getText, + getTextColor, + getTextPosition, + getTheme, + handleDialogClick, + imageHeight, + imageWidth, + portraitHeight, + portraitWidth, + positionImageX, + positionImageY, + positionPortaitX, + positionPortaitY, + positionTextX, + positionTextY, + realHeight, + realWidth, + skipDialogs +} from './dialog' +import { sourcesComponentsCoordinates } from './uiResources' +import { activeNPC } from './npc' + +export let lightTheme = 'https://decentraland.org/images/ui/light-atlas-v3.png' +export let darkTheme = 'https://decentraland.org/images/ui/dark-atlas-v3.png' + +export let bubblesTexture = 'https://decentraland.org/images/ui/dialog-bubbles.png' + +export let section = { + ...sourcesComponentsCoordinates.backgrounds.NPCDialog, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + +export let skipButtonSection = { + ...sourcesComponentsCoordinates.buttons.F, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + +export let skipButtonSectionBlack = { + ...sourcesComponentsCoordinates.buttons.FBlack, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + +export let leftClickSection = { + ...sourcesComponentsCoordinates.icons.ClickWhite, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + +export let leftClickSectionbBlack = { + ...sourcesComponentsCoordinates.icons.ClickDark, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + +export let primaryButtonSection = { + ...sourcesComponentsCoordinates.buttons.E, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + +export let secondaryButtonSection = { + ...sourcesComponentsCoordinates.buttons.F, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + +export let darkButtonSection = { + ...sourcesComponentsCoordinates.buttons.buttonF, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + +export let redButtonSection = { + ...sourcesComponentsCoordinates.buttons.buttonE, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + +let modalScale = 1 +let modelFontSizeScale = 1 +let modalTextWrapScale = 1 + +export function setupNPCUiScaling(inModalScale: number, inFontSize: number, inModalTextWrapScale: number) { + modalScale = inModalScale + modelFontSizeScale = inFontSize + modalTextWrapScale = inModalTextWrapScale + console.log( + 'NPC-TOOLKIT', + 'Scale UI:', + modalScale, + 'TextFontSize:', + modelFontSizeScale, + 'TextWrapScaling:', + modalTextWrapScale + ) +} + +function getScaledSize(size: number): number { + return size * modalScale +} +function getScaledFontSize(size: number): number { + return size * modelFontSizeScale +} +function getScaledTextWrap(size: number): number { + return size * modalTextWrapScale +} +function getScaledParentsButtonWidth(firstButton:number, secondButton:number) { + return getScaledSize(getButtonText(firstButton).length * 16 + getButtonText(secondButton).length * 16) >= 300 && (getbuttonSize(firstButton) != '' || getbuttonSize(secondButton) != '') + ? getScaledSize( + (typeof(getbuttonSize(firstButton)) === 'number' ? getbuttonSize(firstButton) as number : getButtonText(firstButton).length * 14) + + (typeof(getbuttonSize(secondButton)) === 'number' ? getbuttonSize(secondButton) as number : getButtonText(secondButton).length * 14)) + : getScaledSize(300) +} +function getScaledButtonWidth(button:number) { + return getbuttonSize(button) === 'auto' ? getScaledSize(getButtonText(button).length * 8 + 80) + : getScaledSize(typeof(getbuttonSize(button)) === 'number' ? getbuttonSize(button) as number : getScaledSize(150)) +} +export const NpcUtilsUi = () => { + const width = getScaledSize(realWidth(700)) + const height = getScaledSize(realHeight(225)) + + return ( + + { + handleDialogClick() + }} + /> + + + + + + { + skipDialogs(activeNPC) + }} + > + + + + + + + + + {/* Button1 (Top-Left) */} + { + buttonClick(0) + }} + > + + + + {/* Button2 (Top-Right) */} + { + buttonClick(1) + }} + > + + + + + {/* Second row of buttons */} + + {/* Button3 */} + { + buttonClick(3) + }} + > + + {/* Button4 */} + { + buttonClick(4) + }} + > + + + ) +} diff --git a/demo/src/uiComp.tsx b/demo/src/uiComp.tsx new file mode 100644 index 0000000..fd6d101 --- /dev/null +++ b/demo/src/uiComp.tsx @@ -0,0 +1,18 @@ +import ReactEcs, { ReactEcsRenderer, UiEntity } from '@dcl/sdk/react-ecs' +import { NpcUtilsUi } from './ui'; + +export function setupUi() { + ReactEcsRenderer.setUiRenderer(uiComponent) +} + +const uiComponent = () => ( + + + + +) \ No newline at end of file diff --git a/demo/src/uiResources.ts b/demo/src/uiResources.ts new file mode 100644 index 0000000..c761ef8 --- /dev/null +++ b/demo/src/uiResources.ts @@ -0,0 +1,320 @@ +export const sourcesComponentsCoordinates = { + atlasHeight: 1024, + atlasWidth: 1024, + buttons: { + E: { + sourceWidth: 26, + sourceHeight: 26, + sourceLeft: 697, + sourceTop: 611, + }, + F: { + sourceWidth: 26, + sourceHeight: 26, + sourceLeft: 733, + sourceTop: 611, + }, + EBlack: { + sourceWidth: 26, + sourceHeight: 26, + sourceLeft: 766, + sourceTop: 611, + }, + FBlack: { + sourceWidth: 26, + sourceHeight: 26, + sourceLeft: 802, + sourceTop: 611, + }, + buttonE: { + sourceWidth: 174, + sourceHeight: 46, + sourceLeft: 512, + sourceTop: 662, + }, + buttonF: { + sourceWidth: 174, + sourceHeight: 46, + sourceLeft: 512, + sourceTop: 612, + }, + white: { + sourceWidth: 174, + sourceHeight: 46, + sourceLeft: 698, + sourceTop: 662, + }, + red: { + sourceWidth: 174, + sourceHeight: 46, + sourceLeft: 512, + sourceTop: 662, + }, + dark: { + sourceWidth: 174, + sourceHeight: 46, + sourceLeft: 512, + sourceTop: 612, + }, + roundBlack: { + sourceWidth: 128, + sourceHeight: 32, + sourceLeft: 512, + sourceTop: 458, + }, + squareBlack: { + sourceWidth: 128, + sourceHeight: 32, + sourceLeft: 646, + sourceTop: 457, + }, + roundWhite: { + sourceWidth: 128, + sourceHeight: 32, + sourceLeft: 512, + sourceTop: 494, + }, + squareWhite: { + sourceWidth: 128, + sourceHeight: 32, + sourceLeft: 646, + sourceTop: 493, + }, + roundSilver: { + sourceWidth: 128, + sourceHeight: 32, + sourceLeft: 512, + sourceTop: 532, + }, + squareSilver: { + sourceWidth: 128, + sourceHeight: 32, + sourceLeft: 646, + sourceTop: 532, + }, + roundGold: { + sourceWidth: 128, + sourceHeight: 32, + sourceLeft: 512, + sourceTop: 568, + }, + squareGold: { + sourceWidth: 128, + sourceHeight: 32, + sourceLeft: 646, + sourceTop: 568, + }, + }, + backgrounds: { + promptBackground: { + sourceWidth: 416, + sourceHeight: 352, + sourceLeft: 501, + sourceTop: 12, + }, + promptLargeBackground: { + sourceWidth: 480, + sourceHeight: 384, + sourceLeft: 7, + sourceTop: 12, + }, + promptSlantedBackground: { + sourceWidth: 486, + sourceHeight: 326, + sourceLeft: 7, + sourceTop: 413, + }, + NPCDialog: { + sourceWidth: 766, + sourceHeight: 248, + sourceLeft: 22, + sourceTop: 756, + }, + }, + icons: { + closeW: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 942, + sourceTop: 306, + }, + closeD: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 986, + sourceTop: 306, + }, + closeWLarge: { + sourceWidth: 64, + sourceHeight: 64, + sourceLeft: 512, + sourceTop: 381, + }, + closeDLarge: { + sourceWidth: 64, + sourceHeight: 64, + sourceLeft: 583, + sourceTop: 381, + }, + closeWNoBack: { + sourceWidth: 24, + sourceHeight: 24, + sourceLeft: 946, + sourceTop: 252, + }, + closeDNoBack: { + sourceWidth: 24, + sourceHeight: 24, + sourceLeft: 946, + sourceTop: 214, + }, + closeWNoBackLarge: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 987, + sourceTop: 214, + }, + closeDNoBackLarge: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 987, + sourceTop: 260, + }, + FDark: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 950, + sourceTop: 4, + }, + FWhite: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 987, + sourceTop: 4, + }, + EDark: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 950, + sourceTop: 40, + }, + EWhite: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 987, + sourceTop: 40, + }, + Timer: { + sourceWidth: 24, + sourceHeight: 32.2, + sourceLeft: 718, + sourceTop: 388, + }, + TimerLarge: { + sourceWidth: 50, + sourceHeight: 66, + sourceLeft: 661, + sourceTop: 385, + }, + ClickWhite: { + sourceWidth: 32, + sourceHeight: 48, + sourceLeft: 799, + sourceTop: 389, + }, + ClickDark: { + sourceWidth: 32, + sourceHeight: 48, + sourceLeft: 757, + sourceTop: 389, + }, + }, + checkboxes: { + wOff: { + sourceWidth: 24, + sourceHeight: 24, + sourceLeft: 987, + sourceTop: 76, + }, + wOn: { + sourceWidth: 24, + sourceHeight: 24, + sourceLeft: 987, + sourceTop: 104, + }, + dOff: { + sourceWidth: 24, + sourceHeight: 24, + sourceLeft: 958, + sourceTop: 76, + }, + dOn: { + sourceWidth: 24, + sourceHeight: 24, + sourceLeft: 958, + sourceTop: 104, + }, + wLargeOff: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 987, + sourceTop: 132, + }, + wLargeOn: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 987, + sourceTop: 168, + }, + dLargeOff: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 950, + sourceTop: 132, + }, + dLargeOn: { + sourceWidth: 32, + sourceHeight: 32, + sourceLeft: 950, + sourceTop: 168, + }, + }, + switches: { + roundOff: { + sourceWidth: 64, + sourceHeight: 32, + sourceLeft: 783, + sourceTop: 454, + }, + squareOff: { + sourceWidth: 64, + sourceHeight: 32, + sourceLeft: 783, + sourceTop: 501, + }, + roundRed: { + sourceWidth: 64, + sourceHeight: 32, + sourceLeft: 853, + sourceTop: 454, + }, + roundGreen: { + sourceWidth: 64, + sourceHeight: 32, + sourceLeft: 923, + sourceTop: 454, + }, + squareRed: { + sourceWidth: 64, + sourceHeight: 32, + sourceLeft: 852, + sourceTop: 501, + }, + squareGreen: { + sourceWidth: 64, + sourceHeight: 32, + sourceLeft: 921, + sourceTop: 500, + }, + }, + } \ No newline at end of file diff --git a/demo/src/utils.ts b/demo/src/utils.ts new file mode 100644 index 0000000..36f8a6b --- /dev/null +++ b/demo/src/utils.ts @@ -0,0 +1,9 @@ +export function getRandomHexColor(): string { + const letters = "0123456789ABCDEF"; + let color = "#"; + for (let i = 0; i < 6; i++) { + color += letters[Math.floor(Math.random() * 16)]; + } + return color; +} + diff --git a/demo/tsconfig.json b/demo/tsconfig.json new file mode 100644 index 0000000..d84fa28 --- /dev/null +++ b/demo/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "allowJs": true, + "strict": true + }, + "include": [ + "src/**/*.ts", + "src/**/*.tsx" + ], + "extends": "@dcl/sdk/types/tsconfig.ecs7.json" +} \ No newline at end of file diff --git a/src/ui.tsx b/src/ui.tsx index 5da5835..f5716ce 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -270,7 +270,7 @@ export const NpcUtilsUi = () => { justifyContent: 'flex-start', flexDirection: 'row', position: getTextPosition(), - margin: {bottom: getText().length/10} + margin: {bottom: getText().length <= 100 ? getText().length/3 : getText().length/10} }} uiText={{ value: getText(), From 7920228ecc17206aca38865c72577aa7ee561457 Mon Sep 17 00:00:00 2001 From: vatka Date: Mon, 15 Jan 2024 18:53:19 +0200 Subject: [PATCH 03/21] Button bottom position ~ fix buttoms bottom position ~ Fix spacing betwen text and buttons ~ fix initial height of window --- demo/src/ui.tsx | 10 +++++----- src/ui.tsx | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/demo/src/ui.tsx b/demo/src/ui.tsx index f5716ce..1002823 100644 --- a/demo/src/ui.tsx +++ b/demo/src/ui.tsx @@ -154,7 +154,7 @@ export const NpcUtilsUi = () => { position: { bottom: '10%', left: '50%' }, margin: { top: (-height + getText().length / 2) / 2, left: -width / 2 }, width, - height: height + getText().length / 1.5 + height: getText().length <= 25 ? height : height + getText().length / 1.5 - 20 }} > { justifyContent: 'flex-start', flexDirection: 'row', position: getTextPosition(), - margin: {bottom: getText().length <= 100 ? getText().length/3 : getText().length/10} + margin: {bottom: getText().length <= 100 ? (getText().length <= 25 ? -40 : getText().length/3 - 60) : getText().length/10 - 50} }} uiText={{ value: getText(), @@ -287,7 +287,7 @@ export const NpcUtilsUi = () => { flexDirection: 'row', justifyContent: 'space-between', display: displayFirstButtonContainer() ? 'flex' : 'none', - position: { top: getText().length / 4 } + position: { top: 70 + getText().length / 4 }, }} > {/* Button1 (Top-Left) */} @@ -377,9 +377,9 @@ export const NpcUtilsUi = () => { alignItems: 'center', flexDirection: 'row', justifyContent: 'space-between', - margin: { top: getScaledSize(20) }, + margin: { top: getScaledSize(20), bottom:getScaledSize(40)}, display: displaySecondButtonContainer() ? 'flex' : 'none', - position: { top: getText().length / 4 } + position: { top: 70 + getText().length / 4}, }} > {/* Button3 */} diff --git a/src/ui.tsx b/src/ui.tsx index f5716ce..1002823 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -154,7 +154,7 @@ export const NpcUtilsUi = () => { position: { bottom: '10%', left: '50%' }, margin: { top: (-height + getText().length / 2) / 2, left: -width / 2 }, width, - height: height + getText().length / 1.5 + height: getText().length <= 25 ? height : height + getText().length / 1.5 - 20 }} > { justifyContent: 'flex-start', flexDirection: 'row', position: getTextPosition(), - margin: {bottom: getText().length <= 100 ? getText().length/3 : getText().length/10} + margin: {bottom: getText().length <= 100 ? (getText().length <= 25 ? -40 : getText().length/3 - 60) : getText().length/10 - 50} }} uiText={{ value: getText(), @@ -287,7 +287,7 @@ export const NpcUtilsUi = () => { flexDirection: 'row', justifyContent: 'space-between', display: displayFirstButtonContainer() ? 'flex' : 'none', - position: { top: getText().length / 4 } + position: { top: 70 + getText().length / 4 }, }} > {/* Button1 (Top-Left) */} @@ -377,9 +377,9 @@ export const NpcUtilsUi = () => { alignItems: 'center', flexDirection: 'row', justifyContent: 'space-between', - margin: { top: getScaledSize(20) }, + margin: { top: getScaledSize(20), bottom:getScaledSize(40)}, display: displaySecondButtonContainer() ? 'flex' : 'none', - position: { top: getText().length / 4 } + position: { top: 70 + getText().length / 4}, }} > {/* Button3 */} From edb5e9823de58553756fabc4eab9008597857203 Mon Sep 17 00:00:00 2001 From: vatka Date: Mon, 15 Jan 2024 20:16:31 +0200 Subject: [PATCH 04/21] Refactoring + bug fix ~ fix windows height ~ fix bug with button movement ~ refactor text margin style --- demo/src/ui.tsx | 14 ++++++++------ src/ui.tsx | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/demo/src/ui.tsx b/demo/src/ui.tsx index 1002823..29b1676 100644 --- a/demo/src/ui.tsx +++ b/demo/src/ui.tsx @@ -141,7 +141,7 @@ function getScaledButtonWidth(button:number) { } export const NpcUtilsUi = () => { const width = getScaledSize(realWidth(700)) - const height = getScaledSize(realHeight(225)) + const height = getScaledSize(realHeight(300)) return ( { position: { bottom: '10%', left: '50%' }, margin: { top: (-height + getText().length / 2) / 2, left: -width / 2 }, width, - height: getText().length <= 25 ? height : height + getText().length / 1.5 - 20 + height: getText().length <= 100 ? height : height + getText().length / 1.6 - 60 }} > { justifyContent: 'flex-start', flexDirection: 'row', position: getTextPosition(), - margin: {bottom: getText().length <= 100 ? (getText().length <= 25 ? -40 : getText().length/3 - 60) : getText().length/10 - 50} + margin: {bottom: getText().length/10 + 70} }} uiText={{ value: getText(), @@ -287,7 +287,8 @@ export const NpcUtilsUi = () => { flexDirection: 'row', justifyContent: 'space-between', display: displayFirstButtonContainer() ? 'flex' : 'none', - position: { top: 70 + getText().length / 4 }, + positionType: 'absolute', + position: { bottom: 90 }, }} > {/* Button1 (Top-Left) */} @@ -339,7 +340,7 @@ export const NpcUtilsUi = () => { alignItems: 'center', justifyContent: 'flex-start', alignContent: 'flex-start', - display: displayButton(2) ? 'flex' : 'none' + display: displayButton(2) ? 'flex' : 'none', }} uiBackground={{ textureMode: 'stretch', @@ -379,7 +380,8 @@ export const NpcUtilsUi = () => { justifyContent: 'space-between', margin: { top: getScaledSize(20), bottom:getScaledSize(40)}, display: displaySecondButtonContainer() ? 'flex' : 'none', - position: { top: 70 + getText().length / 4}, + positionType: 'absolute', + position: { bottom: -10 }, }} > {/* Button3 */} diff --git a/src/ui.tsx b/src/ui.tsx index 1002823..29b1676 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -141,7 +141,7 @@ function getScaledButtonWidth(button:number) { } export const NpcUtilsUi = () => { const width = getScaledSize(realWidth(700)) - const height = getScaledSize(realHeight(225)) + const height = getScaledSize(realHeight(300)) return ( { position: { bottom: '10%', left: '50%' }, margin: { top: (-height + getText().length / 2) / 2, left: -width / 2 }, width, - height: getText().length <= 25 ? height : height + getText().length / 1.5 - 20 + height: getText().length <= 100 ? height : height + getText().length / 1.6 - 60 }} > { justifyContent: 'flex-start', flexDirection: 'row', position: getTextPosition(), - margin: {bottom: getText().length <= 100 ? (getText().length <= 25 ? -40 : getText().length/3 - 60) : getText().length/10 - 50} + margin: {bottom: getText().length/10 + 70} }} uiText={{ value: getText(), @@ -287,7 +287,8 @@ export const NpcUtilsUi = () => { flexDirection: 'row', justifyContent: 'space-between', display: displayFirstButtonContainer() ? 'flex' : 'none', - position: { top: 70 + getText().length / 4 }, + positionType: 'absolute', + position: { bottom: 90 }, }} > {/* Button1 (Top-Left) */} @@ -339,7 +340,7 @@ export const NpcUtilsUi = () => { alignItems: 'center', justifyContent: 'flex-start', alignContent: 'flex-start', - display: displayButton(2) ? 'flex' : 'none' + display: displayButton(2) ? 'flex' : 'none', }} uiBackground={{ textureMode: 'stretch', @@ -379,7 +380,8 @@ export const NpcUtilsUi = () => { justifyContent: 'space-between', margin: { top: getScaledSize(20), bottom:getScaledSize(40)}, display: displaySecondButtonContainer() ? 'flex' : 'none', - position: { top: 70 + getText().length / 4}, + positionType: 'absolute', + position: { bottom: -10 }, }} > {/* Button3 */} From 249f6df4e2acc0763b3180b29e89c5c979415485 Mon Sep 17 00:00:00 2001 From: vatka Date: Mon, 15 Jan 2024 21:46:02 +0200 Subject: [PATCH 05/21] Text size + implemented ability to resize text box by number or auto --- demo/src/dialog.ts | 13 +++++++++++++ demo/src/types.ts | 1 + demo/src/ui.tsx | 5 +++-- src/dialog.ts | 17 ++++++++++++++++- src/types.ts | 1 + src/ui.tsx | 5 +++-- 6 files changed, 37 insertions(+), 5 deletions(-) diff --git a/demo/src/dialog.ts b/demo/src/dialog.ts index 388daad..689348a 100644 --- a/demo/src/dialog.ts +++ b/demo/src/dialog.ts @@ -209,6 +209,19 @@ export function displayDialog(){ return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).visible } +export function getTextSize() { + let textSizes: number | string | undefined + if (activeNPC != 0 && npcDialogComponent.has(activeNPC)) { + let dialogData = npcDialogComponent.get(activeNPC); + if (dialogData.isQuestion) { + if (dialogData.script[dialogData.index].textSize !== undefined) { + textSizes = dialogData.script[dialogData.index]?.textSize; + } + } + } + return textSizes +} + export function displayButton(button:number){ return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).isQuestion && npcDialogComponent.get(activeNPC).buttons >= button } diff --git a/demo/src/types.ts b/demo/src/types.ts index c091dbe..0a1a95a 100644 --- a/demo/src/types.ts +++ b/demo/src/types.ts @@ -23,6 +23,7 @@ import { Vector3 } from '@dcl/sdk/math' */ export type Dialog = { text: string + textSize?: string | number name?: string fontSize?: number offsetX?: number diff --git a/demo/src/ui.tsx b/demo/src/ui.tsx index 29b1676..d92bf7f 100644 --- a/demo/src/ui.tsx +++ b/demo/src/ui.tsx @@ -36,7 +36,8 @@ import { positionTextY, realHeight, realWidth, - skipDialogs + skipDialogs, + getTextSize } from './dialog' import { sourcesComponentsCoordinates } from './uiResources' import { activeNPC } from './npc' @@ -154,7 +155,7 @@ export const NpcUtilsUi = () => { position: { bottom: '10%', left: '50%' }, margin: { top: (-height + getText().length / 2) / 2, left: -width / 2 }, width, - height: getText().length <= 100 ? height : height + getText().length / 1.6 - 60 + height: typeof(getTextSize()) === 'number' ? getTextSize() as number : (getText().length <= 100 ? height : height + getText().length / 1.6 - 60) }} > = button } @@ -672,4 +685,6 @@ while(dialogData.visibleChars < dialogData.fullText.length && dialogData.fullTex dialogData.visibleChars+=1 } return -} \ No newline at end of file +} + +export { Dialog }; diff --git a/src/types.ts b/src/types.ts index c091dbe..0a1a95a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -23,6 +23,7 @@ import { Vector3 } from '@dcl/sdk/math' */ export type Dialog = { text: string + textSize?: string | number name?: string fontSize?: number offsetX?: number diff --git a/src/ui.tsx b/src/ui.tsx index 29b1676..d92bf7f 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -36,7 +36,8 @@ import { positionTextY, realHeight, realWidth, - skipDialogs + skipDialogs, + getTextSize } from './dialog' import { sourcesComponentsCoordinates } from './uiResources' import { activeNPC } from './npc' @@ -154,7 +155,7 @@ export const NpcUtilsUi = () => { position: { bottom: '10%', left: '50%' }, margin: { top: (-height + getText().length / 2) / 2, left: -width / 2 }, width, - height: getText().length <= 100 ? height : height + getText().length / 1.6 - 60 + height: typeof(getTextSize()) === 'number' ? getTextSize() as number : (getText().length <= 100 ? height : height + getText().length / 1.6 - 60) }} > Date: Tue, 16 Jan 2024 19:35:09 +0200 Subject: [PATCH 06/21] types fix --- src/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.ts b/src/types.ts index 0a1a95a..f528744 100644 --- a/src/types.ts +++ b/src/types.ts @@ -23,7 +23,7 @@ import { Vector3 } from '@dcl/sdk/math' */ export type Dialog = { text: string - textSize?: string | number + textSize?: 'auto' | number name?: string fontSize?: number offsetX?: number @@ -81,7 +81,7 @@ export type ButtonData = { fontSize?: number offsetX?: number offsetY?: number - size?: number | string + size?: number | 'auto' } export enum ButtonStyles { From ee9bbbaf83a9221fd599c913e925745ed94386b3 Mon Sep 17 00:00:00 2001 From: vatka Date: Wed, 17 Jan 2024 11:54:30 +0200 Subject: [PATCH 07/21] Auto sizing ~ Change sizing of buttons, text to auto --- demo/src/ui.tsx | 38 ++++++++++++++++++++------------------ src/ui.tsx | 38 ++++++++++++++++++++------------------ 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/demo/src/ui.tsx b/demo/src/ui.tsx index d92bf7f..534e580 100644 --- a/demo/src/ui.tsx +++ b/demo/src/ui.tsx @@ -137,12 +137,11 @@ function getScaledParentsButtonWidth(firstButton:number, secondButton:number) { : getScaledSize(300) } function getScaledButtonWidth(button:number) { - return getbuttonSize(button) === 'auto' ? getScaledSize(getButtonText(button).length * 8 + 80) - : getScaledSize(typeof(getbuttonSize(button)) === 'number' ? getbuttonSize(button) as number : getScaledSize(150)) +return typeof(getbuttonSize(button)) === 'number' ? getScaledSize(getbuttonSize(button) as number) : 'auto' } export const NpcUtilsUi = () => { const width = getScaledSize(realWidth(700)) - const height = getScaledSize(realHeight(300)) + const height = getScaledSize(realHeight(284)) return ( { alignItems: 'center', justifyContent: 'center', positionType: 'absolute', + flexGrow: 1, position: { bottom: '10%', left: '50%' }, margin: { top: (-height + getText().length / 2) / 2, left: -width / 2 }, + padding: {top: 40, bottom: 40}, width, - height: typeof(getTextSize()) === 'number' ? getTextSize() as number : (getText().length <= 100 ? height : height + getText().length / 1.6 - 60) - }} + // minHeight: typeof(getTextSize()) === 'number' ? 0 : 100, + height: typeof(getTextSize()) === 'number' ? getTextSize() as number : (getText().length <= 100 ? height : 'auto') + }} > { { {/* Button1 (Top-Left) */} @@ -298,7 +302,7 @@ export const NpcUtilsUi = () => { width: getScaledButtonWidth(0), height: getScaledSize(45), margin: { right: '5%' }, - flexDirection: 'row', + flexDirection: 'row-reverse', alignItems: 'center', justifyContent: 'flex-start', alignContent: 'flex-start', @@ -320,7 +324,7 @@ export const NpcUtilsUi = () => { uiTransform={{ width: getScaledSize(25), height: getScaledSize(25), - position: { left: getScaledSize(5) } + margin: {left: 5, right: 5} }} uiBackground={{ textureMode: 'stretch', @@ -337,7 +341,7 @@ export const NpcUtilsUi = () => { uiTransform={{ width: getScaledButtonWidth(1), height: getScaledSize(45), - flexDirection: 'row', + flexDirection: 'row-reverse', alignItems: 'center', justifyContent: 'flex-start', alignContent: 'flex-start', @@ -359,7 +363,7 @@ export const NpcUtilsUi = () => { uiTransform={{ width: getScaledSize(25), height: getScaledSize(25), - position: { left: getScaledSize(5) } + margin: {left: 5, right: 5} }} uiBackground={{ textureMode: 'stretch', @@ -375,14 +379,12 @@ export const NpcUtilsUi = () => { {/* Second row of buttons */} {/* Button3 */} @@ -417,7 +419,7 @@ export const NpcUtilsUi = () => { alignItems: 'center', justifyContent: 'center', alignContent: 'flex-start', - display: displayButton(4) ? 'flex' : 'none' + display: displayButton(4) ? 'flex' : 'none', }} uiBackground={{ textureMode: 'stretch', diff --git a/src/ui.tsx b/src/ui.tsx index d92bf7f..534e580 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -137,12 +137,11 @@ function getScaledParentsButtonWidth(firstButton:number, secondButton:number) { : getScaledSize(300) } function getScaledButtonWidth(button:number) { - return getbuttonSize(button) === 'auto' ? getScaledSize(getButtonText(button).length * 8 + 80) - : getScaledSize(typeof(getbuttonSize(button)) === 'number' ? getbuttonSize(button) as number : getScaledSize(150)) +return typeof(getbuttonSize(button)) === 'number' ? getScaledSize(getbuttonSize(button) as number) : 'auto' } export const NpcUtilsUi = () => { const width = getScaledSize(realWidth(700)) - const height = getScaledSize(realHeight(300)) + const height = getScaledSize(realHeight(284)) return ( { alignItems: 'center', justifyContent: 'center', positionType: 'absolute', + flexGrow: 1, position: { bottom: '10%', left: '50%' }, margin: { top: (-height + getText().length / 2) / 2, left: -width / 2 }, + padding: {top: 40, bottom: 40}, width, - height: typeof(getTextSize()) === 'number' ? getTextSize() as number : (getText().length <= 100 ? height : height + getText().length / 1.6 - 60) - }} + // minHeight: typeof(getTextSize()) === 'number' ? 0 : 100, + height: typeof(getTextSize()) === 'number' ? getTextSize() as number : (getText().length <= 100 ? height : 'auto') + }} > { { {/* Button1 (Top-Left) */} @@ -298,7 +302,7 @@ export const NpcUtilsUi = () => { width: getScaledButtonWidth(0), height: getScaledSize(45), margin: { right: '5%' }, - flexDirection: 'row', + flexDirection: 'row-reverse', alignItems: 'center', justifyContent: 'flex-start', alignContent: 'flex-start', @@ -320,7 +324,7 @@ export const NpcUtilsUi = () => { uiTransform={{ width: getScaledSize(25), height: getScaledSize(25), - position: { left: getScaledSize(5) } + margin: {left: 5, right: 5} }} uiBackground={{ textureMode: 'stretch', @@ -337,7 +341,7 @@ export const NpcUtilsUi = () => { uiTransform={{ width: getScaledButtonWidth(1), height: getScaledSize(45), - flexDirection: 'row', + flexDirection: 'row-reverse', alignItems: 'center', justifyContent: 'flex-start', alignContent: 'flex-start', @@ -359,7 +363,7 @@ export const NpcUtilsUi = () => { uiTransform={{ width: getScaledSize(25), height: getScaledSize(25), - position: { left: getScaledSize(5) } + margin: {left: 5, right: 5} }} uiBackground={{ textureMode: 'stretch', @@ -375,14 +379,12 @@ export const NpcUtilsUi = () => { {/* Second row of buttons */} {/* Button3 */} @@ -417,7 +419,7 @@ export const NpcUtilsUi = () => { alignItems: 'center', justifyContent: 'center', alignContent: 'flex-start', - display: displayButton(4) ? 'flex' : 'none' + display: displayButton(4) ? 'flex' : 'none', }} uiBackground={{ textureMode: 'stretch', From ab549c844764a4678d2bb15c6847f2cac0779349 Mon Sep 17 00:00:00 2001 From: vatka Date: Wed, 17 Jan 2024 13:14:55 +0200 Subject: [PATCH 08/21] Fix demo, button size ~ fix not working demo auto sizing ~ fix gap between button text and border --- demo/src/index.ts | 14 ++------------ demo/src/ui.tsx | 15 ++++----------- src/ui.tsx | 15 ++++----------- 3 files changed, 10 insertions(+), 34 deletions(-) diff --git a/demo/src/index.ts b/demo/src/index.ts index b722516..7109eb2 100644 --- a/demo/src/index.ts +++ b/demo/src/index.ts @@ -6,17 +6,6 @@ import { NPCType } from './types'; import { create } from './npc'; import { setupUi } from './uiComp'; -initAssetPacks(engine, pointerEventsSystem, { - Animator, - AudioSource, - AvatarAttach, - Transform, - VisibilityComponent, - GltfContainer, - Material, - VideoPlayer -}) - export function main() { setupUi() @@ -30,7 +19,8 @@ export function main() { onActivate: () => { talk(myNPC, [ { - text: `Quest Overview: In the mystical realm of Eldoria, a sinister force has swept through the winter lands, freezing the hearts of magical creatures and stealing the essence of Frostfire Crystals - the source of warmth and magic. As a valiant hero, you are called upon to embark on a quest to restore balance and save the fantastical festivities.`, + text: `Quest Overview: In the mystical realm of Eldoria, a sinister force has swept through the winter lands, freezing the hearts of magical creatures and stealing the essence of Frostfire Crystals - the source of warmth and magic. As a valiant hero, you are called upon to embark on a quest to restore balance and save the fantastical festivities. `, + textSize: 'auto', isQuestion: true, buttons: [ { label: `Restore magic!`, goToDialog: 2, size: 'auto'}, diff --git a/demo/src/ui.tsx b/demo/src/ui.tsx index 534e580..4e48b86 100644 --- a/demo/src/ui.tsx +++ b/demo/src/ui.tsx @@ -129,13 +129,6 @@ function getScaledFontSize(size: number): number { function getScaledTextWrap(size: number): number { return size * modalTextWrapScale } -function getScaledParentsButtonWidth(firstButton:number, secondButton:number) { - return getScaledSize(getButtonText(firstButton).length * 16 + getButtonText(secondButton).length * 16) >= 300 && (getbuttonSize(firstButton) != '' || getbuttonSize(secondButton) != '') - ? getScaledSize( - (typeof(getbuttonSize(firstButton)) === 'number' ? getbuttonSize(firstButton) as number : getButtonText(firstButton).length * 14) - + (typeof(getbuttonSize(secondButton)) === 'number' ? getbuttonSize(secondButton) as number : getButtonText(secondButton).length * 14)) - : getScaledSize(300) -} function getScaledButtonWidth(button:number) { return typeof(getbuttonSize(button)) === 'number' ? getScaledSize(getbuttonSize(button) as number) : 'auto' } @@ -289,10 +282,10 @@ export const NpcUtilsUi = () => { @@ -379,10 +372,10 @@ export const NpcUtilsUi = () => { {/* Second row of buttons */} = 300 && (getbuttonSize(firstButton) != '' || getbuttonSize(secondButton) != '') - ? getScaledSize( - (typeof(getbuttonSize(firstButton)) === 'number' ? getbuttonSize(firstButton) as number : getButtonText(firstButton).length * 14) - + (typeof(getbuttonSize(secondButton)) === 'number' ? getbuttonSize(secondButton) as number : getButtonText(secondButton).length * 14)) - : getScaledSize(300) -} function getScaledButtonWidth(button:number) { return typeof(getbuttonSize(button)) === 'number' ? getScaledSize(getbuttonSize(button) as number) : 'auto' } @@ -289,10 +282,10 @@ export const NpcUtilsUi = () => { @@ -379,10 +372,10 @@ export const NpcUtilsUi = () => { {/* Second row of buttons */} Date: Fri, 19 Jan 2024 18:20:40 +0200 Subject: [PATCH 09/21] added new function in README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index f53ca00..5afd4e0 100644 --- a/README.md +++ b/README.md @@ -1360,6 +1360,7 @@ The script must adhere to the following schema: ```ts class Dialog { text: string +textSize?: 'auto' | number name?: string fontSize?: number offsetX?: number @@ -1506,6 +1507,11 @@ When on a question entry, you must provide at least the following for each butto +- `size`: _('auto' | number)_ The size of the button. + + + + > TIP: It's always better to refer to an entry by name, since the array index might shift if you add more entries and it can get hard to keep track of these references. From 8b0e122685055a3997696ecd72d1ec8026842388 Mon Sep 17 00:00:00 2001 From: vatka Date: Sun, 21 Jan 2024 18:43:22 +0200 Subject: [PATCH 10/21] Fix demo, minHeight ~ fix demo ~ fix min height of text box --- demo/package.json | 3 +- demo/src/bubble.ts | 487 ------------------------- demo/src/components.ts | 15 - demo/src/config.ts | 99 ------ demo/src/dialog.ts | 690 ----------------------------------- demo/src/faceUserSystem.ts | 37 -- demo/src/index.ts | 15 +- demo/src/npc.ts | 712 ------------------------------------- demo/src/npcData.ts | 14 - demo/src/systems.ts | 148 -------- demo/src/types.ts | 246 ------------- demo/src/ui.tsx | 432 ---------------------- demo/src/uiComp.tsx | 4 +- demo/src/uiResources.ts | 320 ----------------- demo/src/utils.ts | 9 - package.json | 13 +- src/ui.tsx | 7 +- 17 files changed, 23 insertions(+), 3228 deletions(-) delete mode 100644 demo/src/bubble.ts delete mode 100644 demo/src/components.ts delete mode 100644 demo/src/config.ts delete mode 100644 demo/src/dialog.ts delete mode 100644 demo/src/faceUserSystem.ts delete mode 100644 demo/src/npc.ts delete mode 100644 demo/src/npcData.ts delete mode 100644 demo/src/systems.ts delete mode 100644 demo/src/types.ts delete mode 100644 demo/src/ui.tsx delete mode 100644 demo/src/uiResources.ts delete mode 100644 demo/src/utils.ts diff --git a/demo/package.json b/demo/package.json index c210579..180b072 100644 --- a/demo/package.json +++ b/demo/package.json @@ -7,7 +7,8 @@ "deploy": "sdk-commands deploy", "build": "sdk-commands build", "upgrade-sdk": "npm install --save-dev @dcl/sdk@latest", - "upgrade-sdk:next": "npm install --save-dev @dcl/sdk@next" + "upgrade-sdk:next": "npm install --save-dev @dcl/sdk@next", + "link-sdk": "cd node_modules/@dcl/sdk && npm link && cd ../js-runtime && npm link" }, "devDependencies": { "@dcl/js-runtime": "7.3.36", diff --git a/demo/src/bubble.ts b/demo/src/bubble.ts deleted file mode 100644 index 9d6c80b..0000000 --- a/demo/src/bubble.ts +++ /dev/null @@ -1,487 +0,0 @@ - -import { Animator, AudioSource, AvatarShape, Billboard, BillboardMode, engine, Entity, Font, GltfContainer, InputAction,Material,MeshCollider,MeshRenderer,pointerEventsSystem,TextAlignMode,TextShape,Transform, TransformType, VisibilityComponent } from '@dcl/sdk/ecs' -import * as utils from '@dcl-sdk/utils' -import { Dialog, ImageSection } from './types' -import { Color3,Color4, Quaternion, Vector3 } from '@dcl/sdk/math' -import { addLineBreak, addLineBreaks, findDialogByName } from './dialog' -import { IsTypingBubble } from './components' -import { npcDataComponent } from './npc' - -export let bubblesTexture = 'https://decentraland.org/images/ui/dialog-bubbles.png' - -export let bubbles: Map = new Map() - -let textSize = 1 -let textYPos = 0 - -let maxLengthShortBubble = 8 -let maxLengthNormalBubble = 25 -let maxLengthLongBubble = 50 -let maxLengthHugeBubble = 100 - -let shortBubbleXOffset = 0.1 -let normalBubbleXOffset = 0.5 -let longBubbleXOffset = 0.8 -let hugeBubbleXOffset = 0.8 - -let shortBubbleYOffset = -0.2 -let normalBubbleYOffset = -0.2 -let longBubbleYOffset = 0 -let hugeBubbleYOffset = 0.2 - -let shortBubbleTextWidth = 0.7 -let normalBubbleTextWidth = 1.5 -let longBubbleTextWidth = 2 -let hugeBubbleTextWidth = 1.5 - -let shortBubbleX = 116 * 0.005 -let shortBubbleY = 84 * 0.005 - -let normalBubbleX = 286 * 0.005 -let normalBubbleY = 84 * 0.005 - -let longBubbleX = 497 * 0.005 -let longBubbleY = 153 * 0.005 - -let hugeBubbleX = 497 * 0.005 -let hugeBubbleY = 239 * 0.005 - -let defaultYOffset = 2.5 - - - -export function createDialogBubble(npc:Entity, height?:number, sound?:string){ - let baseYOffset = height ? height : defaultYOffset - - let root = engine.addEntity() - Billboard.create(root,{ - billboardMode:BillboardMode.BM_Y - }) - - Transform.create(root,{ - parent:npc - }) - - let container = engine.addEntity() - Transform.create(container,{ - parent:root, - position:Vector3.create(shortBubbleXOffset,baseYOffset,0) - }) - - let panel = engine.addEntity() - Transform.create(panel,{ - parent:container, - scale: Vector3.create(2,1,1), - //rotation:Quaternion.fromEulerDegrees(0,0,90) - }) - MeshRenderer.setPlane(panel, - setUVSection( - bubbleOptions.normal, - 1024, - 1024 - )) - - VisibilityComponent.create(panel, {visible: false}) - - Material.setBasicMaterial(panel, { - texture: Material.Texture.Common({ - src: bubblesTexture - }) - }) - - let text = engine.addEntity() - Transform.create(text,{ - position:Vector3.create(0,textYPos, -.05), - parent:container - }) - TextShape.create(text, { - text:"", - fontSize:textSize, - font: Font.F_SANS_SERIF, - textColor: Color4.create(0,0,0,1), - textAlign:TextAlignMode.TAM_MIDDLE_CENTER - }) - VisibilityComponent.create(text, {visible: false}) - - bubbles.set(npc, { - container:container, - panel:panel, - text:text, - baseYOffset: baseYOffset, - isBubbleOpen:false, - typing:false, - visibleText:"", - visibleChars:0, - fullText:"", - timer:0, - speed:30, - script:[], - index:0, - sound: sound ? sound : undefined, - soundPlayer: sound ? engine.addEntity() : undefined, - }) -} - -export function openBubble(npc:Entity, dialog:Dialog[], startIndex?:number | string){ - let bubble = bubbles.get(npc) - - bubble.script = dialog.slice() - let index:any - if (!startIndex) { - index = 0 - } else if (typeof startIndex === 'number') { - index = startIndex - } else { - index = findDialogByName(dialog, startIndex) - } - - bubble.index = index - - let currentText: Dialog = dialog[bubble.index] ? dialog[bubble.index] : { text: '' } - bubble.currentText = currentText - - if (currentText.audio) { - AudioSource.createOrReplace(bubble.soundPlayer, { - audioClipUrl: currentText.audio, - loop: false, - playing: false - }) - let audio = AudioSource.getMutable(bubble.soundPlayer) - audio.volume = 0.5 - audio.playing = true - } else if (bubble.sound) { - AudioSource.createOrReplace(bubble.soundPlayer, { - audioClipUrl: bubble.sound, - loop: false, - playing: false - }) - let audio = AudioSource.getMutable(bubble.soundPlayer) - audio.volume = 0.5 - audio.playing = true - } - - let text = bubble.text - TextShape.getMutable(text).fontSize = currentText.fontSize ? currentText.fontSize : textSize - Transform.getMutable(text).position.y = currentText.offsetY ? currentText.offsetY + textYPos : textYPos - Transform.getMutable(text).position.x = currentText.offsetX ? currentText.offsetX : 0 - - VisibilityComponent.getMutable(bubble.panel).visible = true - - if (currentText.text.length < maxLengthHugeBubble) { - currentText.text.slice(0, maxLengthHugeBubble) - } - - beginTyping( - npc, - currentText.text, - bubble.index, - currentText.timeOn ? currentText.timeOn : undefined, - currentText.typeSpeed ? currentText.typeSpeed : undefined - ) - - adjustBubble(npc, currentText.text.length) - layoutDialogWindow(npc, bubble.index) - bubble.isBubbleOpen = true -} - -export function closeBubble(npc:Entity){ - let bubble = bubbles.get(npc) - bubble.isBubbleOpen = false - bubble.typing = false - bubble.visibleText = "" - bubble.visibleChars = 0 - bubble.fullText = "" - bubble.timer = 0 - bubble.index = 0 - bubble.script = [] - bubble.buttons = 0 - bubble.margin = 0 - bubble.currentText = null - TextShape.getMutable(bubble.text).text = "" - VisibilityComponent.getMutable(bubble.text).visible = false - VisibilityComponent.getMutable(bubble.panel).visible = false -} - -export function closeBubbleEndAll(npc:Entity): void { - let bubble = bubbles.get(npc) - if (bubble.isBubbleOpen) { - bubble.done = true - closeBubble(npc) - } - } - -const DEFAULT_SPEED = 45 - -const DEFAULT_TIME_ON = 3 - -function beginTyping(npc:Entity, text:string, textId:number, timeOn?:number, speed?:number){ - let dialogData = bubbles.get(npc) - dialogData.fullText = addLineBreak(dialogData.script[dialogData.index].text, true) - dialogData.typing = true - dialogData.done = false - dialogData.visibleText = "" - dialogData.visibleChars = 0 - dialogData.timer = 0 - dialogData.buttons = 0 - dialogData.timeOn = timeOn ? timeOn : DEFAULT_TIME_ON - dialogData.speed = speed ? speed : DEFAULT_SPEED - - dialogData.openTime = Math.floor(Date.now()) - - if(dialogData.speed <= 0){ - rushText(npc) - } - else{ - if(!IsTypingBubble.has(npc)){ - console.log('creating typuing bubble') - IsTypingBubble.create(npc) - } - } -} - -function rushText(npc:Entity){ - let dialogData = bubbles.get(npc) - dialogData.typing = false - dialogData.timer = 0 - dialogData.visibleChars = dialogData.fullText.length - dialogData.visibleText = dialogData.fullText -} - -function adjustBubble(npc:Entity, textLength:number){ - let bubble = bubbles.get(npc) - let npcData = npcDataComponent.get(npc) - - if (textLength < maxLengthShortBubble) { - MeshRenderer.setPlane(bubble.panel, - setUVSection( - bubbleOptions.short, - 1024, - 1024 - )) - - Transform.getMutable(bubble.panel).scale.x = shortBubbleX - Transform.getMutable(bubble.panel).scale.y = shortBubbleY - Transform.getMutable(bubble.container).position.x = shortBubbleXOffset + npcData.bubbleXOffset - Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + shortBubbleYOffset + npcData.bubbleYOffset - TextShape.getMutable(bubble.text).width = shortBubbleTextWidth - } else if (textLength < maxLengthNormalBubble) { - MeshRenderer.setPlane(bubble.panel, - setUVSection( - bubbleOptions.normal, - 1024, - 1024 - )) - - Transform.getMutable(bubble.panel).scale.x = normalBubbleX - Transform.getMutable(bubble.panel).scale.y = normalBubbleY - Transform.getMutable(bubble.container).position.x = normalBubbleXOffset + npcData.bubbleXOffset - Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + normalBubbleYOffset + npcData.bubbleYOffset - TextShape.getMutable(bubble.text).width = normalBubbleTextWidth - } else if (textLength < maxLengthLongBubble) { - MeshRenderer.setPlane(bubble.panel, - setUVSection( - bubbleOptions.long, - 1024, - 1024 - )) - - Transform.getMutable(bubble.panel).scale.x = longBubbleX - Transform.getMutable(bubble.panel).scale.y = longBubbleY - Transform.getMutable(bubble.container).position.x = longBubbleXOffset + npcData.bubbleXOffset - Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + longBubbleYOffset + npcData.bubbleYOffset - TextShape.getMutable(bubble.text).width = longBubbleTextWidth - } else { - MeshRenderer.setPlane(bubble.panel, - setUVSection( - bubbleOptions.huge, - 1024, - 1024 - )) - Transform.getMutable(bubble.panel).scale.x = hugeBubbleX - Transform.getMutable(bubble.panel).scale.y = hugeBubbleY - Transform.getMutable(bubble.container).position.x = hugeBubbleXOffset + npcData.bubbleXOffset - Transform.getMutable(bubble.container).position.y = bubble.baseYOffset + hugeBubbleYOffset + npcData.bubbleYOffset - TextShape.getMutable(bubble.text).width = hugeBubbleTextWidth - } -} - -// Adds the buttons or mouse icon depending on the type of window -function layoutDialogWindow(npc:Entity, textId: number): void { - let bubble = bubbles.get(npc) - let currentText: Dialog = bubble.script[textId] - ? bubble.script[textId] - : { text: '' } - - // Update text - let textY = currentText.offsetY ? currentText.offsetY + textYPos : textYPos - - if (currentText.buttons && currentText.buttons.length >= 3) { - textY += 50 - } else if (currentText.buttons && currentText.buttons.length >= 1) { - textY += 24 - } - TextShape.getMutable(bubble.text).fontSize = currentText.fontSize - ? currentText.fontSize - : textSize - - VisibilityComponent.getMutable(bubble.text).visible = true - Transform.getMutable(bubble.text).position.y = textY - - if (currentText.audio) { - AudioSource.createOrReplace(bubble.soundPlayer, { - audioClipUrl: currentText.audio, - loop: false, - playing: false - }) - let audio = AudioSource.getMutable(bubble.soundPlayer) - audio.volume = 0.5 - audio.playing = true - } else if (bubble.sound) { - AudioSource.createOrReplace(bubble.soundPlayer, { - audioClipUrl: bubble.sound, - loop: false, - playing: false - }) - let audio = AudioSource.getMutable(bubble.soundPlayer) - audio.volume = 0.5 - audio.playing = true - } - - } - -// Progresses text -export function next(npc:Entity): void { - let bubble = bubbles.get(npc) - - if(bubble.isBubbleOpen){ - let currentText = bubble.script[bubble.index] - - if(!currentText){ - currentText = bubble.script[bubble.index-1] - } - - if (currentText.triggeredByNext) { - currentText.triggeredByNext() - } - - if (currentText.isEndOfDialog) { - closeBubble(npc) - return - } - - // Update active text - bubble.index++ - - // Update active text with new active text - currentText = bubble.script[bubble.index] - - if (currentText.text.length < maxLengthHugeBubble) { - currentText.text.slice(0, maxLengthHugeBubble) - } - - TextShape.getMutable(bubble.text).text = "" - - adjustBubble(npc, currentText.text.length) - - beginTyping( - npc, - currentText.text, - bubble.index, - currentText.timeOn ? currentText.timeOn : undefined, - currentText.typeSpeed ? currentText.typeSpeed : undefined - ) - layoutDialogWindow(npc, bubble.index) - } - - - } - -function setUVSection( - section: ImageSection, - sizeX: number, - sizeY: number - ) { - return setUVs( - {x: section.sourceLeft! / sizeX, y: (sizeY - section.sourceTop! - section.sourceHeight) / sizeY}, - {x: (section.sourceLeft! + section.sourceWidth) / sizeX, y: (sizeY - section.sourceTop! - section.sourceHeight) / sizeY}, - {x: (section.sourceLeft! + section.sourceWidth) / sizeX, y: (sizeY - section.sourceTop!) / sizeY}, - {x: section.sourceLeft! / sizeX, y: (sizeY - section.sourceTop!) / sizeY}, - ) - } - -function setUVs( - _uv00: any, - _uv10: any, - _uv11: any, - _uv01: any - ) { - - return [ - _uv00.x, - _uv00.y, - - _uv10.x, - _uv10.y, - - _uv11.x, - _uv11.y, - - _uv01.x, - _uv01.y, - //---- - _uv00.x, - _uv00.y, - - _uv10.x, - _uv10.y, - - _uv11.x, - _uv11.y, - - _uv01.x, - _uv01.y, - ] - } - - let bubbleOptions:any = { - short: { - sourceWidth: 116 * 2, - sourceHeight: 84 * 2, - sourceLeft: 305 * 2, - sourceTop: 417 * 2, - }, - normal: { - sourceWidth: 286 * 2, - sourceHeight: 84 * 2, - sourceLeft: 8 * 2, - sourceTop: 417 * 2, - }, - long: { - sourceWidth: 497 * 2, - sourceHeight: 153 * 2, - sourceLeft: 6 * 2, - sourceTop: 254 * 2, - }, - huge: { - sourceWidth: 497 * 2, - sourceHeight: 239 * 2, - sourceLeft: 6 * 2, - sourceTop: 7 * 2, - }, -} - - -export function getBubbleTextLength(text:string){ - if(text.length >= maxLengthHugeBubble){ - return 40 - } - else if(text.length >= maxLengthLongBubble){ - return 40 - } - else if(text.length >= maxLengthNormalBubble){ - return 40 - } - else if(text.length >= maxLengthShortBubble){ - return 40 - } - } \ No newline at end of file diff --git a/demo/src/components.ts b/demo/src/components.ts deleted file mode 100644 index 5230b64..0000000 --- a/demo/src/components.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Schemas, Transform, engine } from "@dcl/sdk/ecs" - -export const IsFollowingPath = engine.defineComponent("npcutils::isFollowingPath", {}) -export const IsTypingDialog = engine.defineComponent("npcutils::isTypingDialog", {}) -export const IsTypingBubble = engine.defineComponent("npcutils::isTypingBubble", {}) - -export const TrackUserFlag = engine.defineComponent( - "npcutils::trackUserFlag", - { - lockXZRotation: Schemas.Boolean, - active: Schemas.Boolean, - rotSpeed: Schemas.Number - }) - - diff --git a/demo/src/config.ts b/demo/src/config.ts deleted file mode 100644 index f1ed841..0000000 --- a/demo/src/config.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { Color4 } from "@dcl/sdk/math" - -export let extraFemaleShoes:any[] =[ - "urn:decentraland:off-chain:base-avatars:bun_shoes", - "urn:decentraland:off-chain:base-avatars:pink_blue_socks", - "urn:decentraland:off-chain:base-avatars:SchoolShoes", - "urn:decentraland:off-chain:base-avatars:ruby_blue_loafer" -] - -export let extraFemalePants:any[] =[ - "urn:decentraland:off-chain:base-avatars:f_stripe_white_pants", - "urn:decentraland:off-chain:base-avatars:f_red_modern_pants", - "urn:decentraland:off-chain:base-avatars:f_school_skirt", - "urn:decentraland:off-chain:base-avatars:f_capris", - "urn:decentraland:off-chain:base-avatars:f_red_comfy_pants" -] - -export let extraFemaleTop:any[] =[ - "urn:decentraland:off-chain:base-avatars:baggy_pullover", - "urn:decentraland:off-chain:base-avatars:light_green_shirt", - "urn:decentraland:off-chain:base-avatars:school_shirt", - "urn:decentraland:off-chain:base-avatars:f_blue_jacket", - "urn:decentraland:matic:collections-v2:0xb8326d69371668bb8403463e4f71c10b408535c3:1" -] - -export let extraMaleShoes:any[] =[ - "urn:decentraland:off-chain:base-avatars:comfy_sport_sandals", - "urn:decentraland:off-chain:base-avatars:crocs", - "urn:decentraland:off-chain:base-avatars:m_mountainshoes.glb", - "urn:decentraland:off-chain:base-avatars:citycomfortableshoes", - "urn:decentraland:off-chain:base-avatars:classic_shoes", - "urn:decentraland:off-chain:base-avatars:sneakers", - "urn:decentraland:off-chain:base-avatars:moccasin" -] - -export let extraMalePants:any[] =[ - "urn:decentraland:off-chain:base-avatars:soccer_pants", - "urn:decentraland:off-chain:base-avatars:swim_short", - "urn:decentraland:off-chain:base-avatars:kilt", - "urn:decentraland:off-chain:base-avatars:hip_hop_joggers", - "urn:decentraland:off-chain:base-avatars:brown_pants_02", - "urn:decentraland:off-chain:base-avatars:basketball_shorts", - "urn:decentraland:off-chain:base-avatars:brown_pants_02", - "urn:decentraland:off-chain:base-avatars:puffer_jacket_hoodie" -] - -export let extraMaleTop:any[] =[ - "urn:decentraland:off-chain:base-avatars:yellow_tshirt", - "urn:decentraland:off-chain:base-avatars:m_sweater", - "urn:decentraland:off-chain:base-avatars:turtle_neck_sweater", - "urn:decentraland:off-chain:base-avatars:puffer_jacket_hoodie", - "urn:decentraland:off-chain:base-avatars:elegant_sweater", - "urn:decentraland:off-chain:base-avatars:pride_tshirt", - "urn:decentraland:off-chain:base-avatars:elegant_sweater", - "urn:decentraland:matic:collections-v2:0xb8326d69371668bb8403463e4f71c10b408535c3:1" -] - -export let extraskin:any[]= [ - Color4.create(.24,.13,.04), - Color4.create(.6,.37,.22), - Color4.create(.48,.28, .09), - Color4.create(.98, .82,.51), -] - -export let extrahair:any[]= [ - Color4.create(.6,.37,.22), - Color4.create(.3,.52,.4), - Color4.create(.55,.13,.08), - Color4.create(.11,.11,.11), - Color4.create(.48,.28, .09), - Color4.create(.98, .82,.51), - Color4.create(.55, .13,.08), -] - -export let extraFemaleHairstyle:any[] = [ - "urn:decentraland:off-chain:base-avatars:hair_anime_01", - "urn:decentraland:off-chain:base-avatars:pony_tail", - "urn:decentraland:off-chain:base-avatars:standard_hair", - "urn:decentraland:off-chain:base-avatars:shoulder_hair", - "urn:decentraland:off-chain:base-avatars:two_tails" -] - -export let extraMaleHairstyle:any[] = [ - "urn:decentraland:off-chain:base-avatars:standard_hair", - "urn:decentraland:off-chain:base-avatars:hair_oldie", - "urn:decentraland:off-chain:base-avatars:keanu_hair", - "urn:decentraland:off-chain:base-avatars:tall_front_01", - "urn:decentraland:off-chain:base-avatars:00_bald" -] - -export let extraeyes:any[] = [ - Color4.create(.22,.49,.69), - Color4.create(.6,.37,.22), - Color4.create(.3,.52,.4), - Color4.create(.55,.13,.08), - Color4.create(.11,.11,.11), - Color4.create(.48,.28, .09), - Color4.create(.98, .82,.51), -] diff --git a/demo/src/dialog.ts b/demo/src/dialog.ts deleted file mode 100644 index 689348a..0000000 --- a/demo/src/dialog.ts +++ /dev/null @@ -1,690 +0,0 @@ -import * as utils from '@dcl-sdk/utils' - -import { AudioSource, Entity, engine } from "@dcl/sdk/ecs"; -import { activeNPC, clearNPC, closeDialogWindow, followPath, isActiveNpcSet, npcDataComponent, setActiveNPC, stopPath, stopWalking } from "./npc"; -import { IsTypingDialog } from "./components"; -import { handleDialogTyping } from "./systems"; -import { Dialog, ImageData, NPCState } from "./types"; -import { leftClickSection, leftClickSectionbBlack, lightTheme, section, skipButtonSection, skipButtonSectionBlack } from './ui'; -import { getBubbleTextLength } from './bubble'; -import { Color4 } from '@dcl/sdk/math'; - - -export const npcDialogComponent: Map = new Map() -export const npcDialogTypingSystems: Map = new Map() -export const npcDialogInputListener: Map = new Map() - -export enum ConfirmMode { - Confirm = 0, - Cancel = 1, - Next = 2, - Button3 = 3, - Button4 = 4 - } - -export let UIscaleMultiplier = 0.75 - -let portraitXPos = -50 * UIscaleMultiplier -let portraitYPos = 20 * UIscaleMultiplier - -let imageXPos = 350 * UIscaleMultiplier -let imageYPos = 50 * UIscaleMultiplier - -let portraitScale = 256 * UIscaleMultiplier -let imageScale = 256 * UIscaleMultiplier - -let textSize = 24 * UIscaleMultiplier -let textYPos = 10 * UIscaleMultiplier - -let buttonWidth = 174* UIscaleMultiplier -let buttonHeight = 46* UIscaleMultiplier - - -let buttonTextSize = 20 * UIscaleMultiplier - -let button1XPos = 150 * UIscaleMultiplier -let button2XPos = -80 * UIscaleMultiplier -let button3XPos = -80 * UIscaleMultiplier -let button4XPos = 150 * UIscaleMultiplier - -let button1YPos = -65 * UIscaleMultiplier -let button2YPos = -65 * UIscaleMultiplier -let button1YPos4 = -20 * UIscaleMultiplier -let button2YPos4 = -20 * UIscaleMultiplier -let button3YPos = -80 * UIscaleMultiplier -let button4YPos = -80 * UIscaleMultiplier - -let skipButtonXPos = -300 * UIscaleMultiplier -let skipButtonYPos = -100 * UIscaleMultiplier - -let buttonIconWidth = 26 * UIscaleMultiplier -let buttonIconHeight = 26 * UIscaleMultiplier - -// - -export function addDialog(npc:Entity, sound?:string, defaultPortrait?:ImageData){ - console.log('adding dialog for npc', npc) - npcDialogComponent.set(npc, { - typing:true, - visible:false, - visibleText:"", - visibleChars:0, - fullText:"", - timer:0, - speed:30, - originalScript:[], - script:[], - index:0, - sound: sound ? sound : undefined, - soundPlayer: sound ? engine.addEntity() : undefined, - fontSize:22, - isQuestion:false, - buttons:0, - displayPortrait: defaultPortrait ? true : false, - defaultPortrait: defaultPortrait ? defaultPortrait : null, - defaultPortraitTexture: defaultPortrait ? defaultPortrait.path : lightTheme, - currentPortrait: defaultPortrait ? defaultPortrait.path : lightTheme, - portraitWidth: defaultPortrait && defaultPortrait.width ? defaultPortrait.width * UIscaleMultiplier : portraitScale, - portraitHeight: defaultPortrait && defaultPortrait.height ? defaultPortrait.height * UIscaleMultiplier : portraitScale, - portraitX: defaultPortrait && defaultPortrait.offsetX ? defaultPortrait.offsetX * UIscaleMultiplier + portraitXPos : portraitXPos, - portraitY: defaultPortrait && defaultPortrait.offsetY ? defaultPortrait.offsetY * UIscaleMultiplier + portraitYPos : portraitYPos, - portaitSHeight: defaultPortrait && defaultPortrait.section && defaultPortrait.section.sourceHeight ? defaultPortrait.section.sourceHeight : 256, - portraitSWidth: defaultPortrait && defaultPortrait.section && defaultPortrait.section.sourceWidth ? defaultPortrait.section.sourceWidth : 256, - portaitSTop: defaultPortrait && defaultPortrait.section && defaultPortrait.section.sourceTop ? defaultPortrait.section.sourceTop : 0, - portraitSLeft: defaultPortrait && defaultPortrait.section && defaultPortrait.section.sourceLeft ? defaultPortrait.section.sourceLeft : 0 - }) -} - -export function displayImage(){ - return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).displayImage -} - -export function displayPortrait(){ - return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).displayPortrait -} - -export function displaySkipable(){ - return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).skipable -} - -export function getSkipableTheme(){ - return !isActiveNpcSet() ? skipButtonSectionBlack : npcDataComponent.get(activeNPC).theme == lightTheme ? skipButtonSectionBlack : skipButtonSection -} - -export function getLeftClickTheme(){ - return !isActiveNpcSet() ? leftClickSection : npcDataComponent.get(activeNPC).theme == lightTheme ? leftClickSection : leftClickSectionbBlack -} - -export function positionTextX(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).positionX -} - -export function positionTextY(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).positionY -} - -export function positionPortaitX(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).portraitX -} - -export function positionPortaitY(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).portraitY -} - -export function portraitWidth(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).portraitWidth -} - -export function portraitHeight(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).portraitHeight -} - -export function positionImageX(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).imageX -} - -export function positionImageY(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).imageY -} - -export function imageWidth(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).imageWidth -} - -export function imageHeight(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).imageHeight -} - -export function getPortrait(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).currentPortrait -} - -export function getImage(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).dialogImageTexture -} - -export function getText(){ - return !isActiveNpcSet() ? "" : npcDialogComponent.get(activeNPC).visibleText -} - -export function getTextColor(){ - return !isActiveNpcSet() ? Color4.Black() : npcDataComponent.get(activeNPC).theme == lightTheme ? Color4.Black() : Color4.White() -} - -export function getTheme(){ - return !isActiveNpcSet() ? lightTheme : npcDataComponent.get(activeNPC).theme -} - -export function getButtonText(button:number){ - let text = "" - - if(activeNPC != 0 && npcDialogComponent.has(activeNPC)){ - let dialogData = npcDialogComponent.get(activeNPC) - if(dialogData.isQuestion && dialogData.buttons > button){ - text = dialogData.script[dialogData.index].buttons[button].label - text = text.slice(0, 15) - } - } - return text -} - -export function getbuttonSize(button:number) { - let ButtonSize: number | string | undefined - if (activeNPC != 0 && npcDialogComponent.has(activeNPC)) { - let dialogData = npcDialogComponent.get(activeNPC); - if (dialogData.isQuestion && dialogData.buttons > button) { - if (dialogData.script[dialogData.index].buttons[button].size !== undefined) { - ButtonSize = dialogData.script[dialogData.index].buttons[button]?.size; - } - } - } - return ButtonSize -} - -export function getFontSize(){ - return !isActiveNpcSet() ? 22 : npcDialogComponent.get(activeNPC).fontSize -} - -export function displayDialog(){ - return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).visible -} - -export function getTextSize() { - let textSizes: number | string | undefined - if (activeNPC != 0 && npcDialogComponent.has(activeNPC)) { - let dialogData = npcDialogComponent.get(activeNPC); - if (dialogData.isQuestion) { - if (dialogData.script[dialogData.index].textSize !== undefined) { - textSizes = dialogData.script[dialogData.index]?.textSize; - } - } - } - return textSizes -} - -export function displayButton(button:number){ - return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).isQuestion && npcDialogComponent.get(activeNPC).buttons >= button -} - -export function displayFirstButtonContainer(){ - return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).isQuestion && npcDialogComponent.get(activeNPC).buttons >= 1 -} - -export function displaySecondButtonContainer(){ - return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).isQuestion && npcDialogComponent.get(activeNPC).buttons >= 3 -} - -export function getTextPosition(){ - //console.log(npcDialogComponent.get(activeNPC).buttons) - return !isActiveNpcSet() ? {top:0, left:0} : {top:npcDialogComponent.get(activeNPC).margin + npcDialogComponent.get(activeNPC).positionY, left: npcDialogComponent.get(activeNPC).positionX} -} - -export function buttonClick(button:number){ - if(isActiveNpcSet()){ - confirmText(activeNPC, button) - } -} - -export function closeDialog(npc:Entity){ - let dialogData = npcDialogComponent.get(npc) - dialogData.visible = false - dialogData.typing = false - dialogData.visibleText = "" - dialogData.visibleChars = 0 - dialogData.fullText = "" - dialogData.timer = 0 - dialogData.index = 0 - dialogData.script.length = 0 - dialogData.buttons = 0 - dialogData.margin = 0 - dialogData.displayPortrait = false - dialogData.skipable = false - dialogData.displayImage = false - console.log('dialog data is now ', dialogData) - - if(IsTypingDialog.has(npc)){ - IsTypingDialog.deleteFrom(npc) - } - // if(npcDataComponent.get(npc).manualStop){ - // console.log('dialog ended, needto walk again') - // followPath(npc) - // } - clearNPC() -} - -export function talk(npc:Entity, dialog:Dialog[], startIndex?:number | string, duration?:number){ - npcDataComponent.get(npc).introduced = true - if(npcDialogComponent.has(npc)){ - - setActiveNPC(npc) - if(npcDataComponent.get(npc).state == NPCState.FOLLOWPATH){ - console.log("speaking dialog, need to stop path") - stopWalking(npc) - } - - npcDataComponent.get(npc).state = NPCState.TALKING - - - let index:any - - if (!startIndex) { - index = 0 - } else if (typeof startIndex === 'number') { - index = startIndex - } else { - index = findDialogByName(dialog, startIndex) - } - - openDialog(npc,dialog, index) - } -} - -export function openDialog(npc:Entity, dialog:Dialog[], startIndex:number){ - console.log('script to talk is', dialog) - let dialogData = npcDialogComponent.get(npc) - dialogData.script = dialog.slice() - dialogData.index = startIndex - - console.log('dialog data is now', dialogData) - - let currentText: Dialog = dialog[startIndex] ? dialog[startIndex] : { text: '' } - - if (currentText.audio) { - AudioSource.createOrReplace(dialogData.soundPlayer, { - audioClipUrl: currentText.audio, - loop: false, - playing: false - }) - let audio = AudioSource.getMutable(dialogData.soundPlayer) - audio.volume = 0.5 - audio.playing = true - } else if (dialogData.sound) { - AudioSource.createOrReplace(dialogData.soundPlayer, { - audioClipUrl: dialogData.sound, - loop: false, - playing: false - }) - let audio = AudioSource.getMutable(dialogData.soundPlayer) - audio.volume = 0.5 - audio.playing = true - } - - //TODO - //set image on the right - //set text - beginTyping(npc) -} - -export function addLineBreak(text:string, bubble?:boolean){ - return lineBreak(text, bubble? getBubbleTextLength(text)! : 45) -} - -function beginTyping(npc:Entity){ - let dialogData = npcDialogComponent.get(npc) - dialogData.fullText = addLineBreak(dialogData.script[dialogData.index].text) //dialogData.script[dialogData.index].text - dialogData.visible = true - dialogData.typing = true - dialogData.visibleText = "" - dialogData.visibleChars = 0 - dialogData.timer = 0 - dialogData.isQuestion = false - dialogData.buttons = 0 - dialogData.displayPortrait = false - dialogData.displayImage = false - dialogData.skipable = false - - let currentText: Dialog = dialogData.script[dialogData.index] ? dialogData.script[dialogData.index] : { text: '' } - if(currentText.portrait){ - dialogData.currentPortrait = currentText.portrait.path - - dialogData.portraitX = currentText.portrait.offsetX - ? currentText.portrait.offsetX * UIscaleMultiplier + portraitXPos - : portraitXPos - - dialogData.portraitY = currentText.portrait.offsetY - ? currentText.portrait.offsetY * UIscaleMultiplier + portraitYPos - : portraitYPos - - dialogData.portraitWidth = currentText.portrait.width ? currentText.portrait.width * UIscaleMultiplier : portraitScale - - dialogData.portraitHeight = currentText.portrait.height ? currentText.portrait.height * UIscaleMultiplier : portraitScale - dialogData.displayPortrait = true - }else if(dialogData.defaultPortrait){ - dialogData.currentPortrait = dialogData.defaultPortraitTexture - dialogData.displayPortrait = true - } - else{ - dialogData.displayPortrait = false - } - - if(dialogData.script[dialogData.index].isQuestion){ - dialogData.buttons = dialogData.script[dialogData.index].buttons.length - if(dialogData.buttons >= 3){ - dialogData.margin = -25 - } - else if(dialogData.buttons >=1){ - dialogData.margin = -25 - } - - console.log(dialogData) - utils.timers.setTimeout( - function() { - console.log('setting question to true') - dialogData.isQuestion = true - }, - 700 - ) - } - - dialogData.openTime = Math.floor(Date.now()) - if(dialogData.script[dialogData.index].fontSize){ - dialogData.fontSize = dialogData.script[dialogData.index].fontSize - } - - if(dialogData.script[dialogData.index].skipable){ - dialogData.skipable = true - } - else{ - dialogData.skipable = false - } - - if(dialogData.script[dialogData.index].image){ - dialogData.dialogImageTexture = dialogData.script[dialogData.index].image.path - dialogData.imageX = dialogData.script[dialogData.index].image.offsetX ? dialogData.script[dialogData.index].image.offsetX * UIscaleMultiplier + imageXPos : -40 - dialogData.imageY = dialogData.script[dialogData.index].image.offsetY ? dialogData.script[dialogData.index].image.offsetY * UIscaleMultiplier + imageYPos : 40 - dialogData.imageHeight = dialogData.script[dialogData.index].image.height ? dialogData.script[dialogData.index].height * UIscaleMultiplier : imageScale - dialogData.imageWidth = dialogData.script[dialogData.index].image.width ? dialogData.script[dialogData.index].width * UIscaleMultiplier : imageScale - dialogData.displayImage = true - } - - dialogData.positionX = dialogData.script[dialogData.index].offsetX ? dialogData.script[dialogData.index].offsetX * UIscaleMultiplier : '22%' - dialogData.positionY = dialogData.script[dialogData.index].offsetY ? dialogData.script[dialogData.index].offsetY * UIscaleMultiplier + textYPos : textYPos - - if(dialogData.script[dialogData.index].hasOwnProperty("typeSpeed")){ - dialogData.speed = dialogData.script[dialogData.index].typeSpeed - } - else{ - dialogData.speed = 30 - } - - if(dialogData.speed <= 0){ - rushText(npc) - } - else{ - if(!IsTypingDialog.has(npc)){ - IsTypingDialog.create(npc) - } - - // if(!npcDialogTypingSystems.has(npc)){ - // npcDialogTypingSystems.set(npc,engine.addSystem(handleDialogTyping)) - // } - } -} - -export function addLineBreaks(dialog:Dialog[], bubble?:boolean){ - let cleaned:Dialog[] = dialog.slice() - cleaned.forEach((d)=>{ - d.text = lineBreak(d.text, bubble? getBubbleTextLength(d.text)! : 50) - }) - return cleaned -} - -function lineBreak(text: string, maxLineLength: number): string { - const words = text.split(' '); - let currentLine = ''; - const lines = []; - - for (const word of words) { - if (currentLine.length + word.length + 1 <= maxLineLength) { - currentLine += `${word} `; - } else { - lines.push(currentLine.trim()); - currentLine = `${word} `; - } - } - lines.push(currentLine.trim()); - return lines.join('\n'); -} - -export function handleDialogClick(){ - console.log('handling click') - let npc = activeNPC - if(npcDialogComponent.has(npc)){ - let dialogData = npcDialogComponent.get(npc) - if(!dialogData.visible || (Math.floor(Date.now()) - dialogData.openTime < 100)) return - - if(dialogData.typing){ - rushText(npc) - } - else{ - confirmText(npc, ConfirmMode.Next) - } - } -} - -export function rushText(npc:Entity){ - let dialogData = npcDialogComponent.get(npc) - dialogData.typing = false - dialogData.timer = 0 - dialogData.visibleChars = dialogData.fullText.length - dialogData.visibleText = dialogData.fullText - //engine.removeSystem(npcDialogTypingSystems.get(npc)) -} - -export function confirmText(npc:Entity, mode: ConfirmMode): void { - console.log('confirm text') - let dialogData = npcDialogComponent.get(npc) - dialogData.openTime = Math.floor(Date.now()) - - let currentText = dialogData.script[dialogData.index] - // Update active text - if (mode == ConfirmMode.Next) { - if (!currentText.isQuestion) { - if (currentText.triggeredByNext) { - currentText.triggeredByNext() - } - if (currentText.isEndOfDialog) { - closeDialog(npc) - return - } - dialogData.index++ - } - } - - if (mode == ConfirmMode.Confirm) { - if (currentText.buttons && currentText.buttons.length >= 1) { - if (typeof currentText.buttons[0].goToDialog === 'number') { - dialogData.index = currentText.buttons[0].goToDialog - } - - //TODO - //allow dialogs to be index by name - // else { - // this.activeTextId = findDialogByName(this.NPCScript, currentText.buttons[0].goToDialog) - // } - if (currentText.buttons[0].triggeredActions) { - currentText.buttons[0].triggeredActions() - } - } - } - - if (mode == ConfirmMode.Cancel) { - if (currentText.buttons && currentText.buttons.length >= 1) { - if (typeof currentText.buttons[1].goToDialog === 'number') { - dialogData.index = currentText.buttons[1].goToDialog - } - - //TODO - //allow dialogs to be index by name - // else { - // this.activeTextId = findDialogByName(this.NPCScript, currentText.buttons[0].goToDialog) - // } - if (currentText.buttons[1].triggeredActions) { - currentText.buttons[1].triggeredActions() - } - } - } - - if (mode == ConfirmMode.Button3) { - if (currentText.buttons && currentText.buttons.length >= 1) { - if (typeof currentText.buttons[2].goToDialog === 'number') { - dialogData.index = currentText.buttons[2].goToDialog - } - - //TODO - //allow dialogs to be index by name - // else { - // this.activeTextId = findDialogByName(this.NPCScript, currentText.buttons[0].goToDialog) - // } - if (currentText.buttons[2].triggeredActions) { - currentText.buttons[2].triggeredActions() - } - } - } - - if (mode == ConfirmMode.Button4) { - if (currentText.buttons && currentText.buttons.length >= 1) { - if (typeof currentText.buttons[3].goToDialog === 'number') { - dialogData.index = currentText.buttons[3].goToDialog - } - - //TODO - //allow dialogs to be index by name - // else { - // this.activeTextId = findDialogByName(this.NPCScript, currentText.buttons[0].goToDialog) - // } - if (currentText.buttons[3].triggeredActions) { - currentText.buttons[3].triggeredActions() - } - } - } - - - beginTyping(npc) -} - -export function skipDialogs(npc:Entity) { - let dialogData = npcDialogComponent.get(npc) - if (!dialogData.visible || +Date.now() - dialogData.openTime < 100) return - - while ( - dialogData.script[dialogData.index] && - dialogData.script[dialogData.index].skipable && - dialogData.script[dialogData.index].isQuestion - ){ - if(dialogData.script[dialogData.index].triggeredByNext){ - dialogData.script[dialogData.index].triggeredByNext() - } - - if(dialogData.script[dialogData.index].skipable && - dialogData.script[dialogData.index].isEndOfDialog - ){ - closeDialogWindow(npc) - return - } - - dialogData.index += 1 - } - confirmText(npc, ConfirmMode.Next) -} - -export type ImageAtlasData = { - atlasWidth: number; - atlasHeight: number; - sourceWidth: number; - sourceHeight: number; - sourceLeft: number; - sourceTop: number; - } - - -export function getImageAtlasMapping(data?: ImageAtlasData): number[] { - if (!data) return [] - - const { - atlasWidth, - atlasHeight, - sourceWidth, - sourceHeight, - sourceTop, - sourceLeft, - } = data - - return [ - sourceLeft / atlasWidth, (atlasHeight - sourceTop - sourceHeight) / atlasHeight, - sourceLeft / atlasWidth, (atlasHeight - sourceTop) / atlasHeight, - (sourceLeft + sourceWidth) / atlasWidth, (atlasHeight - sourceTop) / atlasHeight, - (sourceLeft + sourceWidth) / atlasWidth, (atlasHeight - sourceTop - sourceHeight) / atlasHeight, - ] - } - - export function realWidth(width?:number): number { - return width ? width : section.sourceWidth - } - - export function realHeight(height?:number): number { - return height ? height : section.sourceHeight - } - - export function findDialogByName(dialogs: Dialog[], name: string) { - for (let i = 0; i < dialogs.length; i++) { - if (dialogs[i].name && dialogs[i].name == name) { - return i - } - } - return 0 - } - - - -export function closeTag(dialogData:any, newChars: number){ - if(dialogData.visibleChars == 0 || newChars ==0 ) return - -let openTag: boolean = false -let closeTag : boolean = false -for(let i = dialogData.visibleChars-newChars; i < dialogData.visibleChars ; i++){ - - if(!openTag){ - if(dialogData.fullText.substr(i, 1) == '<'){ - openTag= true - - } - } else { - if(dialogData.fullText.substr(i, 1) == '>'){ - closeTag= true - - } - } -} - -if(!openTag || closeTag){ - return -} - -while(dialogData.visibleChars < dialogData.fullText.length && dialogData.fullText.substr(dialogData.visibleChars-1, 1) != '>'){ - dialogData.visibleChars+=1 -} -return -} - -export { Dialog }; diff --git a/demo/src/faceUserSystem.ts b/demo/src/faceUserSystem.ts deleted file mode 100644 index c90e256..0000000 --- a/demo/src/faceUserSystem.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Schemas, Transform, engine } from "@dcl/sdk/ecs" -import { Quaternion, Vector3 } from "@dcl/sdk/math" - - -let faceUserAdded: boolean = false - -export function addFaceUserSystem() { - faceUserAdded = true - - engine.addSystem(faceUserSystem) -} - -export const TrackUserFlag = engine.defineComponent( - "npcutils::trackUserFlag", - { - lockXZRotation: Schemas.Boolean, - active: Schemas.Boolean, - rotSpeed: Schemas.Number - }) - -export function faceUserSystem(dt: number) { - for (const [entity, track] of engine.getEntitiesWith(TrackUserFlag)) { - if (track.active) { - const player = Transform.get(engine.PlayerEntity) - let lookAtTarget = Vector3.create(player.position.x, player.position.y, player.position.z) - let direction = Vector3.subtract(lookAtTarget, Transform.get(entity).position) - - let transform = Transform.getMutable(entity) - transform.rotation = Quaternion.slerp(player.rotation, Quaternion.lookRotation(direction), dt * track.rotSpeed) - - if (track.lockXZRotation) { - transform.rotation.x = 0 - transform.rotation.z = 0 - } - } - } -} diff --git a/demo/src/index.ts b/demo/src/index.ts index 7109eb2..10d75d7 100644 --- a/demo/src/index.ts +++ b/demo/src/index.ts @@ -1,23 +1,20 @@ +import * as npc from 'dcl-npc-toolkit' +import { MeshCollider } from '@dcl/sdk/ecs' import { Quaternion, Vector3 } from '@dcl/sdk/math' -import { Animator, AudioSource, AvatarAttach, GltfContainer, Material, MeshCollider, Transform, VideoPlayer, VisibilityComponent, engine, pointerEventsSystem } from '@dcl/sdk/ecs' -import { initAssetPacks } from '@dcl/asset-packs/dist/scene-entrypoint' -import { talk } from './dialog' -import { NPCType } from './types'; -import { create } from './npc'; -import { setupUi } from './uiComp'; +import { setupUi } from './uiComp' export function main() { setupUi() - let myNPC = create( + let myNPC = npc.create( { position: Vector3.create(8, 1, 8), rotation: Quaternion.Zero(), scale: Vector3.create(1, 1, 1) }, { - type: NPCType.CUSTOM, + type: npc.NPCType.CUSTOM, model: 'models/hi.glb', portrait: { path: 'images/hi.png', height: 220, width: 220 }, onActivate: () => { - talk(myNPC, [ + npc.talk(myNPC, [ { text: `Quest Overview: In the mystical realm of Eldoria, a sinister force has swept through the winter lands, freezing the hearts of magical creatures and stealing the essence of Frostfire Crystals - the source of warmth and magic. As a valiant hero, you are called upon to embark on a quest to restore balance and save the fantastical festivities. `, textSize: 'auto', diff --git a/demo/src/npc.ts b/demo/src/npc.ts deleted file mode 100644 index c815a24..0000000 --- a/demo/src/npc.ts +++ /dev/null @@ -1,712 +0,0 @@ -import * as utils from '@dcl-sdk/utils' -import { - Animator, - AvatarShape, - engine, - Entity, - GltfContainer, - InputAction, - MeshCollider, - MeshRenderer, - PBAvatarShape, - PBGltfContainer, - pointerEventsSystem, - Transform, - TransformType, - PBAnimationState -} from '@dcl/sdk/ecs' -import { Color3, Quaternion, Vector3 } from '@dcl/sdk/math' -import { bubbles, closeBubble, createDialogBubble, openBubble } from './bubble' -import { IsFollowingPath, TrackUserFlag } from './components' -import { addDialog, closeDialog, findDialogByName, npcDialogComponent, openDialog } from './dialog' -import { faceUserSystem, handleBubbletyping, handleDialogTyping, handlePathTimes, inputListenerSystem } from './systems' -import { Dialog, FollowPathData, ImageData, NPCData, NPCPathType, NPCState, NPCType, TriggerData } from './types' -import { darkTheme, lightTheme } from './ui' - -export const walkingTimers: Map = new Map() -export const npcDataComponent: Map = new Map() -export let NULL_NPC: Entity = 0 as Entity -export let activeNPC: Entity = NULL_NPC -export let blankDialog: number = 0 - -engine.addSystem(handlePathTimes) -engine.addSystem(handleDialogTyping) -engine.addSystem(handleBubbletyping) -engine.addSystem(faceUserSystem) -engine.addSystem(inputListenerSystem) - -//TODO MAKE isCooldown and no longer have to track with map to remove memory leak issues -const isCooldown: Map = new Map() -const onActivateCbs: Map = new Map() -const onWalkAwayCbs: Map = new Map() -const animTimers: Map = new Map() -const pointReachedCallbacks: Map = new Map() -const onFinishCallbacks: Map = new Map() - -export function showDebug(debug: boolean) { - utils.triggers.enableDebugDraw(debug) -} - -export function getData(npc: Entity) { - return npcDataComponent.get(npc) -} - -export function create(transform: any, data: NPCData) { - let npc = engine.addEntity() - - let t: TransformType = { - position: transform.position ? transform.position : Vector3.create(0, 0, 0), - rotation: transform.rotation ? transform.rotation : Quaternion.Zero(), - scale: transform.scale ? transform.scale : Vector3.One() - } - Transform.create(npc, t) - - npcDataComponent.set(npc, { - introduced: false, - inCooldown: false, - coolDownDuration: data && data.coolDownDuration ? data.coolDownDuration : 5, - faceUser: data && data.faceUser ? data.faceUser : undefined, - walkingSpeed: 2, - walkingAnim: data && data.walkingAnim ? data.walkingAnim : undefined, - pathData: data.pathData ? data.pathData : undefined, - currentPathData: [], - manualStop: false, - pathIndex: 0, - state: NPCState.STANDING, - idleAnim: data && data.idleAnim ? data.idleAnim : 'Idle', - bubbleHeight: data && data.textBubble && data.bubbleHeight ? data.bubbleHeight : undefined, - bubbleSound: data.dialogSound ? data.dialogSound : undefined, - hasBubble: data && data.textBubble ? true : false, - turnSpeed: data && data.turningSpeed ? data.turningSpeed : 2, - theme: data.darkUI ? darkTheme : lightTheme, - bubbleXOffset: data.bubbleXOffset ? data.bubbleXOffset : 0, - bubbleYOffset: data.bubbleYOffset ? data.bubbleYOffset : 0 - }) - - if (data && data.noUI) { - } else if (data && data.portrait) { - addDialog( - npc, - data && data.dialogSound ? data.dialogSound : undefined, - typeof data.portrait === `string` ? { path: data.portrait } : data.portrait - ) - } else { - addDialog(npc, data && data.dialogSound ? data.dialogSound : undefined) - } - - if (data && data.textBubble) { - createDialogBubble(npc, npcDataComponent.get(npc).bubbleHeight) - } - - onActivateCbs.set(npc, (other: Entity) => { - data.onActivate(other) - }) - - if (data && data.hasOwnProperty('onWalkAway')) { - onWalkAwayCbs.set(npc, (other: Entity) => { - if (!data || !data.continueOnWalkAway) { - if (npcDialogComponent.has(npc)) { - npcDialogComponent.get(npc).visible = false - } - } else { - if (npcDialogComponent.has(npc)) { - npcDialogComponent.get(npc).visible = false - } - } - data.onWalkAway!(other) - }) - } - - addNPCBones(npc, data) - addClickReactions(npc, data) - addTriggerArea(npc, data) - - if (data && data.pathData && data.pathData.speed) { - let npcData = npcDataComponent.get(npc) - npcData.walkingSpeed = data.pathData.speed - } - - if (data && data.coolDownDuration) { - let npcData = npcDataComponent.get(npc) - npcData.coolDownDuration = data.coolDownDuration - } - - if (data && data.pathData) { - let npcData = npcDataComponent.get(npc) - npcData.pathData.loop = true - followPath(npc, npcData.pathData) - } - - return npc -} - -function addNPCBones(npc: Entity, data: NPCData) { - const modelIsString = data && data.model && typeof data.model === `string` - const modelAvatarData: PBAvatarShape | undefined = modelIsString - ? undefined - : data.model && (data.model as any).bodyShape - ? (data.model as PBAvatarShape) - : undefined - const modelGLTFData: PBGltfContainer | undefined = modelIsString - ? undefined - : data.model && (data.model as any).src - ? (data.model as PBGltfContainer) - : undefined - - switch (data.type) { - case NPCType.AVATAR: - AvatarShape.create( - npc, - !data || !data.model || !modelAvatarData - ? { - id: 'npc', - name: 'NPC', - bodyShape: 'urn:decentraland:off-chain:base-avatars:BaseMale', - emotes: [], - wearables: [ - 'urn:decentraland:off-chain:base-avatars:f_eyes_00', - 'urn:decentraland:off-chain:base-avatars:f_eyebrows_00', - 'urn:decentraland:off-chain:base-avatars:f_mouth_00', - 'urn:decentraland:off-chain:base-avatars:comfy_sport_sandals', - 'urn:decentraland:off-chain:base-avatars:soccer_pants', - 'urn:decentraland:off-chain:base-avatars:elegant_sweater' - ] - } - : modelAvatarData - ) - break - - case NPCType.CUSTOM: - GltfContainer.create( - npc, - modelIsString && typeof data.model === `string` ? { src: data && data.model ? data.model : '' } : modelGLTFData - ) - Animator.create(npc, { - states: [ - { - clip: data && data.idleAnim ? data.idleAnim : 'Idle', - loop: true - } - ] - }) - - let npcData = npcDataComponent.get(npc) - npcData.idleAnim = data && data.idleAnim ? data.idleAnim : 'Idle' - npcData.lastPlayedAnim = npcDataComponent.get(npc).idleAnim - - Animator.playSingleAnimation(npc, npcDataComponent.get(npc).idleAnim) - - if (data && data.walkingAnim) { - npcDataComponent.get(npc).walkingAnim = data.walkingAnim - let animations = Animator.getMutable(npc) - animations.states.push({ clip: data.walkingAnim, loop: true }) - } - - break - - case NPCType.BLANK: - MeshRenderer.setBox(npc) - MeshCollider.setBox(npc) - break - } -} - -function addClickReactions(npc: Entity, data: NPCData) { - let activateButton = data && data.onlyClickTrigger ? InputAction.IA_POINTER : InputAction.IA_PRIMARY - - /* - pointerEventsSystem.onPointerDown( - { - entity: npc, - opts: { - button: activateButton, - hoverText: data && data.hoverText ? data.hoverText : 'Talk', - showFeedback: data && data.onlyExternalTrigger ? false : true - } - }, - () => { - if (isCooldown.has(npc) || npcDialogComponent.get(npc).visible) return - activate(npc, engine.PlayerEntity) - }, - ) - */ - - pointerEventsSystem.onPointerDown( - npc, - function () { - if (isCooldown.has(npc) || npcDialogComponent.get(npc).visible) return - activate(npc, engine.PlayerEntity) - }, - { - button: activateButton, - hoverText: data && data.hoverText ? data.hoverText : 'Talk', - showFeedback: data && data.onlyExternalTrigger ? false : true - } - ) - - if (data && data.onlyExternalTrigger) { - pointerEventsSystem.removeOnPointerDown(npc) - } -} - -function addTriggerArea(npc: Entity, data: NPCData) { - let triggerData: TriggerData = {} - - if (!data || (data && !data.onlyExternalTrigger && !data.onlyClickTrigger && !data.onlyETrigger)) { - onActivateCbs.set(npc, (other: Entity) => { - if (isCooldown.has(npc)) { - console.log(npc, ' in cooldown') - return - } else if ( - (npcDialogComponent.has(npc) && npcDialogComponent.get(npc).visible) || - (data && data.onlyExternalTrigger) || - (data && data.onlyClickTrigger) - ) { - return - } - data.onActivate(other) - }) - triggerData.onCameraEnter = onActivateCbs.get(npc) - } - - // when exiting trigger - if (!data || (data && !data.continueOnWalkAway)) { - triggerData.onCameraExit = (other) => { - handleWalkAway(npc, other) - } - } - - // when entering trigger - if (!data || (data && !data.onlyExternalTrigger && !data.onlyClickTrigger && !data.onlyETrigger)) { - triggerData.onCameraEnter = (other) => { - if (isCooldown.has(npc)) { - console.log(npc, ' in cooldown') - return - } - // else if ( - // (this.dialog && this.dialog.isDialogOpen) || - // (data && data.onlyExternalTrigger) || - // (data && data.onlyClickTrigger) - // ) { - // return - // } - activate(npc, other) - } - } - - // add trigger - if (triggerData.onCameraEnter || triggerData.onCameraExit) { - utils.triggers.addTrigger( - npc, - triggerData.layer != undefined ? triggerData.layer : utils.NO_LAYERS, - triggerData.triggeredByLayer != undefined ? triggerData.triggeredByLayer : utils.LAYER_1, - [{ type: 'sphere', position: Vector3.Zero(), radius: data.reactDistance != undefined ? data.reactDistance : 6 }], - (other) => { - if (triggerData.onCameraEnter) triggerData.onCameraEnter(other) - }, - (other) => { - if (triggerData.onCameraExit) triggerData.onCameraExit(other) - }, - Color3.Red() - ) - } -} - -export function followPath(npc: Entity, data?: FollowPathData) { - let npcData = npcDataComponent.get(npc) - let path: any[] = [] - - if (npcData.faceUser) { - if (TrackUserFlag.has(npc)) { - TrackUserFlag.deleteFrom(npc) - } - } - - if (npcData.manualStop) { - let duration = npcData.pathData.totalDuration - let currentTimer: number = walkingTimers.get(npc)! - console.log('current time is', currentTimer) - if (currentTimer) { - duration -= currentTimer - } - - let path: any[] = [] - npcData.pathData.path.forEach((p: any) => { - path.push(p) - }) - path.splice(0, npcData.pathIndex) - - let pos = Transform.get(npc).position - path.unshift(Vector3.create(pos.x, pos.y, pos.z)) - walkNPC( - npc, - npcData, - npcData.pathData.pathType, - duration, - path, - pointReachedCallbacks.get(npc), - onFinishCallbacks.get(npc) - ) - } else { - if (data) { - npcData.pathData = data - - if (data.startingPoint) { - data.path?.splice(0, data.startingPoint - 1) - } - - let pos = Transform.get(npc).position - path.push(Vector3.create(pos.x, pos.y, pos.z)) - data.path?.forEach((p) => { - path.push(p) - }) - - onFinishCallbacks.set(npc, () => { - console.log('on finished callback') - if (data && data.onFinishCallback && !data.loop) { - data.onFinishCallback() - } - stopPath(npc) - }) - - pointReachedCallbacks.set(npc, () => { - console.log('on point reached callback') - let data = npcDataComponent.get(npc) - data.pathIndex += 1 - data.onReachedPointCallback ? data.onReachedPointCallback : undefined - }) - walkNPC( - npc, - npcData, - data.pathType!, - data.totalDuration, - path, - pointReachedCallbacks.get(npc), - onFinishCallbacks.get(npc) - ) - } else { - if (npcData.manualStop) { - console.log('we have manual stop, need to pick back up where we left off') - } else { - console.log('we are trying to follow a path witout starting one prior') - } - } - } -} - -function walkNPC( - npc: Entity, - npcData: any, - type: NPCPathType, - duration: number, - path: Vector3[], - pointReachedCallback?: any, - finishedCallback?: any -) { - if (IsFollowingPath.has(npc)) { - IsFollowingPath.deleteFrom(npc) - walkingTimers.delete(npc) - } - IsFollowingPath.create(npc) - - if (type) { - if (type == NPCPathType.RIGID_PATH) { - utils.paths.startStraightPath( - npc, - path, - duration, - true, - () => { - finishedCallback() - }, - () => { - pointReachedCallback() - } - ) - } else { - utils.paths.startSmoothPath( - npc, - path, - duration, - 30, - true, - () => { - finishedCallback() - }, - () => { - pointReachedCallback() - } - ) - } - } else { - utils.paths.startSmoothPath( - npc, - path, - duration, - 20, - true, - () => { - finishedCallback() - }, - () => { - pointReachedCallback() - } - ) - } - - if (npcData.walkingAnim) { - clearAnimationTimer(npc) - Animator.playSingleAnimation(npc, npcDataComponent.get(npc).walkingAnim, true) - npcData.lastPlayedAnim = npcDataComponent.get(npc).walkingAnim - } - npcData.state = NPCState.FOLLOWPATH - npcData.manualStop = false -} - -export function stopWalking(npc: Entity, duration?: number, finished?: boolean) { - let npcData = npcDataComponent.get(npc) - npcData.state = NPCState.STANDING - npcData.manualStop = true - - stopPath(npc) - - if (duration) { - utils.timers.setTimeout(() => { - //if (this.dialog && this.dialog.isDialogOpen) return - if (npcData.path) { - Animator.stopAllAnimations(npc, true) - if (npcDataComponent.get(npc).walkingAnim) { - clearAnimationTimer(npc) - Animator.playSingleAnimation(npc, npcDataComponent.get(npc).walkingAnim, true) - npcData.lastPlayedAnim = npcDataComponent.get(npc).walkingAnim - } - let duration = npcData.pathData.totalDuration - let currentTimer: number = walkingTimers.get(npc)! - console.log('current time is', currentTimer) - if (currentTimer) { - duration -= currentTimer - } - - let path: any[] = [] - npcData.pathData.path.forEach((p: any) => { - path.push(p) - }) - path.splice(0, npcData.pathIndex) - - let pos = Transform.get(npc).position - path.unshift(Vector3.create(pos.x, pos.y, pos.z)) - - //npcData.manualStop = false - walkNPC( - npc, - npcData, - npcData.pathData.pathType, - duration, - path, - pointReachedCallbacks.get(npc), - onFinishCallbacks.get(npc) - ) - } - }, duration * 1000) - } -} - -export function stopPath(npc: Entity) { - utils.paths.stopPath(npc) - IsFollowingPath.deleteFrom(npc) - - let npcData = npcDataComponent.get(npc) - if (npcData.walkingAnim) { - clearAnimationTimer(npc) - Animator.playSingleAnimation(npc, npcDataComponent.get(npc).idleAnim) - npcData.lastPlayedAnim = npcData.idleAnim - } - - if (!npcData.manualStop) { - if (npcData.pathData.loop) { - npcData.pathIndex = 0 - walkingTimers.delete(npc) - console.log('we are looping path', npcData) - followPath(npc, npcData.pathData) - console.log(npcData) - } - } -} - -export function clearNPC() { - activeNPC = NULL_NPC -} - -export function setActiveNPC(npc: Entity) { - activeNPC = npc -} - -export function isActiveNpcSet() { - return activeNPC && npcDialogComponent.has(activeNPC) -} - -/** - * Calls the NPC's activation function (set on NPC definition). If NPC has `faceUser` = true, it will rotate to face the player. It starts a cooldown counter to avoid reactivating. - */ -export function activate(npc: Entity, other: Entity) { - if (activeNPC != 0) { - console.log('we have a current npc, needto remove') - endInteraction(activeNPC) - // closeDialog(activeNPC) - } - - activeNPC = npc - onActivateCbs.get(npc)(other) - - let npcData = npcDataComponent.get(npc) - if (npcData.faceUser) { - if (TrackUserFlag.has(npc)) { - TrackUserFlag.deleteFrom(npc) - } - - TrackUserFlag.create(npc, { - lockXZRotation: true, - active: true, - rotSpeed: npcData.turnSpeed - }) - } - isCooldown.set(npc, true) - npcData.inCooldown = true - - utils.timers.setTimeout(function () { - isCooldown.delete(npc) - npcDataComponent.get(npc).inCooldown = false - }, 1000 * npcData.coolDownDuration) - console.log('activated npc,', npcDataComponent.get(npc)) -} - -function endInteraction(npc: Entity) { - let npcData = npcDataComponent.get(npc) - npcData.state = NPCState.STANDING - - if (npcDialogComponent.has(npc)) { - //} && npcDialogComponent.get(npc).visible) { - closeDialog(npc) - } - - if (npcData.faceUser) { - if (TrackUserFlag.has(npc)) { - TrackUserFlag.deleteFrom(npc) - } - } - - console.log('ending interaction', npcData, bubbles.get(npc)) - if (npcData.hasBubble && bubbles.get(npc).isBubbleOpen) { - closeBubble(npc) - } -} - -/** - * Ends interaction and calls the onWalkAway function - */ -export function handleWalkAway(npc: Entity, other: Entity) { - let npcData = npcDataComponent.get(npc) - if (npcData.state == NPCState.FOLLOWPATH) { - return - } - - endInteraction(npc) - - if (onWalkAwayCbs.get(npc)) { - onWalkAwayCbs.get(npc)(other) - } -} - -export function playAnimation(npc: Entity, anim: string, noLoop?: boolean, duration?: number) { - let animations = Animator.getMutable(npc) - let npcData = npcDataComponent.get(npc) - - if (!animations || !npcData) return - - if (animations.states && animations.states.filter((animation: PBAnimationState) => animation.clip === anim).length == 0) { - animations.states.push({ clip: anim, loop: noLoop ? false : true }) - } - - if (npcData.state == NPCState.FOLLOWPATH) { - utils.paths.stopPath(npc) - } - - clearAnimationTimer(npc) - - Animator.stopAllAnimations(npc, true) - Animator.playSingleAnimation(npc, anim, true) - if (duration) { - console.log('have a duration to play animation') - clearAnimationTimer(npc) - animTimers.set( - npc, - utils.timers.setTimeout(() => { - clearAnimationTimer(npc) - Animator.stopAllAnimations(npc, true) - if (npcData.idleAnim) { - Animator.playSingleAnimation(npc, npcData.idleAnim) - npcData.lastPlayedAnim = npcData.idleAnim - } - }, 1000 * duration) - ) // - } - - npcData.lastPlayedAnim = anim -} - -export function changeIdleAnim(npc: Entity, animation: string, play?: boolean) { - let npcData = npcDataComponent.get(npc) - npcData.idleAnim = animation - - let animations = Animator.getMutable(npc) - if (animations.states.filter((anim) => anim.clip === animation).length == 0) { - animations.states.push({ clip: animation, loop: true }) - } - - if (play) { - playAnimation(npc, animation, true) - npcDataComponent.get(npc).lastPlayedAnim = animation - } -} - -export function talkBubble(npc: Entity, script: Dialog[], startIndex?: number | string) { - openBubble(npc, script, startIndex) -} - -export function createDialogWindow(defaultPortrait?: ImageData, sound?: string) { - let dialog = engine.addEntity() - addDialog(dialog, sound, defaultPortrait) - return dialog -} - -export function openDialogWindow(npc: Entity, dialog: Dialog[], startIndex?: number | string) { - activeNPC = npc - - if (npcDialogComponent.has(npc)) { - let index: any - if (!startIndex) { - index = 0 - } else if (typeof startIndex === 'number') { - index = startIndex - } else { - index = findDialogByName(dialog, startIndex) - } - openDialog(npc, dialog, index) - } -} - -export function closeDialogWindow(window: Entity) { - let dialog = npcDialogComponent.get(window) - if (window) { - closeDialog(dialog) - } -} - -function clearAnimationTimer(npc: Entity): boolean { - if (animTimers.has(npc)) { - utils.timers.clearTimeout(animTimers.get(npc) as number) - animTimers.delete(npc) - return true - } - return false -} diff --git a/demo/src/npcData.ts b/demo/src/npcData.ts deleted file mode 100644 index dc25b9a..0000000 --- a/demo/src/npcData.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Schemas, engine } from '@dcl/sdk/ecs' -export const NPCDataComponent = engine.defineComponent('npcdatacomponent', { - introduced: Schemas.Boolean, - inCooldown: Schemas.Boolean, - coolDownDuration: Schemas.Number, - faceUser: Schemas.Boolean, - walkingSpeed: Schemas.Number, - bubbleHeight: Schemas.Number, - state: Schemas.String, - walkingAnim: Schemas.String, - idleAnim: Schemas.String, - lastPlayedAnim: Schemas.String, - path: Schemas.Array(Schemas.Vector3) -}) diff --git a/demo/src/systems.ts b/demo/src/systems.ts deleted file mode 100644 index c24dfdb..0000000 --- a/demo/src/systems.ts +++ /dev/null @@ -1,148 +0,0 @@ -import { Entity, InputAction, PointerEventType, TextShape, Transform, engine, inputSystem } from "@dcl/sdk/ecs"; -import { IsFollowingPath, IsTypingBubble, IsTypingDialog, TrackUserFlag } from "./components"; -import { activeNPC, walkingTimers } from "./npc"; -import { ConfirmMode, closeTag, confirmText, npcDialogComponent, rushText, skipDialogs } from "./dialog"; -import { bubbles, next } from "./bubble"; -import { Quaternion, Vector3 } from "@dcl/sdk/math"; - -export function handlePathTimes(dt:number) { - for (const [entity] of engine.getEntitiesWith(IsFollowingPath)) { - if(walkingTimers.has(entity)){ - let elapsed:number = walkingTimers.get(entity)! - elapsed += dt - walkingTimers.set(entity, walkingTimers.get(entity)! + dt) - } - else{ - walkingTimers.set(entity, dt) - } - } - } - -export function handleDialogTyping(dt:number) { - for (const [entity] of engine.getEntitiesWith(IsTypingDialog)) { - let dialogData = npcDialogComponent.get(entity) - if(!dialogData.typing){ - return - } - - dialogData.timer += dt - if (dialogData.timer >= 2 / dialogData.speed) { - let charsToAdd = Math.floor(dialogData.timer / (1 / dialogData.speed)) - dialogData.timer = 0 - - dialogData.visibleChars += charsToAdd - closeTag(dialogData, charsToAdd) - - - if (dialogData.visibleChars >= dialogData.fullText.length) { - dialogData.typing = false - dialogData.visibleChars = dialogData.fullText.length - IsTypingDialog.deleteFrom(entity) - } - - dialogData.visibleText = dialogData.fullText.substr(0, dialogData.visibleChars) - } - } - } - - export function handleBubbletyping(dt:number) { - for (const [entity] of engine.getEntitiesWith(IsTypingBubble)) { - let dialogData = bubbles.get(entity) - if(dialogData.done){ - continue - } - - dialogData.timer += dt - - if (!dialogData.typing) { - if (dialogData.timer > dialogData.timeOn) { - //dialogData.isBubbleOpen = false - dialogData.done = true - dialogData.typing = false - dialogData.timer = 0 - next(entity) - } - } - else if (dialogData.timer >= 2 / dialogData.speed) { - let charsToAdd = Math.floor(dialogData.timer / (1 / dialogData.speed)) - dialogData.timer = 0 - dialogData.visibleChars += charsToAdd - - if (dialogData.visibleChars >= dialogData.fullText.length || dialogData.done) { - dialogData.typing = false - dialogData.visibleChars = dialogData.fullText.length - IsTypingDialog.deleteFrom(entity) - } - TextShape.getMutable(dialogData.text).text = dialogData.fullText.substr(0, dialogData.visibleChars) - } - } - } - -export function faceUserSystem(dt: number) { - for (const [entity, track] of engine.getEntitiesWith(TrackUserFlag)) { - if (track.active) { - const player = Transform.get(engine.PlayerEntity) - let lookAtTarget = Vector3.create(player.position.x, player.position.y, player.position.z) - let direction = Vector3.subtract(lookAtTarget, Transform.get(entity).position) - - let transform = Transform.getMutable(entity) - transform.rotation = Quaternion.slerp(transform.rotation, Quaternion.lookRotation(direction), dt * track.rotSpeed) - - if (track.lockXZRotation) { - transform.rotation.x = 0 - transform.rotation.z = 0 - } - } - } -} - -export function inputListenerSystem(){ - const PET = inputSystem.isTriggered(InputAction.IA_PRIMARY,PointerEventType.PET_DOWN) - const PEP = inputSystem.isPressed(InputAction.IA_PRIMARY) - - const PPET = inputSystem.isTriggered(InputAction.IA_POINTER,PointerEventType.PET_DOWN) - const PPEP = inputSystem.isPressed(InputAction.IA_POINTER) - - const SET = inputSystem.isTriggered(InputAction.IA_SECONDARY,PointerEventType.PET_DOWN) - const SEP = inputSystem.isPressed(InputAction.IA_SECONDARY) - - if(PPET && PPEP){ - if(activeNPC){ - let dialogData = npcDialogComponent.get(activeNPC) - if(!dialogData.visible || Date.now() - dialogData.openTime < 100)return - if(dialogData.typing){ - rushText(activeNPC) - }else if(!dialogData.isQuestion){ - confirmText(activeNPC, ConfirmMode.Next) - } - } - } - - if(SET && SEP){ - if(activeNPC){ - let dialogData = npcDialogComponent.get(activeNPC) - if(!dialogData.visible || Date.now() - dialogData.openTime < 100)return - if(dialogData.isQuestion){ - confirmText(activeNPC, ConfirmMode.Confirm) - }else if(!dialogData.isQuestion){ - confirmText(activeNPC, ConfirmMode.Next) - } - } - } - - if(PET && PEP){ - if(activeNPC){ - let dialogData = npcDialogComponent.get(activeNPC) - if(!dialogData.visible || Date.now() - dialogData.openTime < 100)return - if(dialogData.isQuestion){ - confirmText(activeNPC, ConfirmMode.Cancel) - }else if(dialogData.script[dialogData.index].skipable && !dialogData.isFixedScreen){ - skipDialogs(activeNPC) - } - } - } - - - -// -} \ No newline at end of file diff --git a/demo/src/types.ts b/demo/src/types.ts deleted file mode 100644 index 0a1a95a..0000000 --- a/demo/src/types.ts +++ /dev/null @@ -1,246 +0,0 @@ -import { Entity, PBAvatarShape, PBGltfContainer } from '@dcl/sdk/ecs' -import { Vector3 } from '@dcl/sdk/math' - -/** - * Fragment of a conversation with an NPC - * - * @typedef {Object} Dialog - An entry in an NPC conversation - * @property {string} text The dialog text - * @property {string} name Optional name of the dialog entry, to link other entries to this one and not worry about changes in the array length - * @property {number} fontSize Size of the text - * @property {number} offsetX Offset of the text on the X axis, relative to its normal position. - * @property {number} offsetY Offset of the text on the Y axis, relative to its normal position. - * @property {ImageData} portrait Sets the portrait image to use on the left. This field expects a `Portrait` object. - * @property {ImageData} image Sets a second image to use on the right of the dialog, and slightly up. This field expects an `ImageData` object. - * @property {number} typeSpeed The text appears one character at a time, simulating typing. Players can click to skip the animation. Tune the speed of this typing (30 by default) to go slower or faster. Set to _-1_ to skip the animation. - * @property {boolean} isQuestion If true, allows to use buttons to trigger different actions - * @property {boolean} isFixedScreen If true, has no buttons or "next page" functionality - * @property {ButtonData[]} buttons An array of buttons `ButtonData` objects to use in a question entry - * @property {string} audio Path to sound file to play when the dialog is shown in the UI - * @property {boolean} skipable If true, a "Skip" button on the UI lets players skip to the next non-skipable entry. - * @property {number} timeOn How long to keep the text visible before moving on to the next entry. Only for bubble dialogs! - * - */ -export type Dialog = { - text: string - textSize?: string | number - name?: string - fontSize?: number - offsetX?: number - offsetY?: number - typeSpeed?: number - isEndOfDialog?: boolean - triggeredByNext?: () => void - portrait?: ImageData - image?: ImageData - isQuestion?: boolean - isFixedScreen?: boolean - buttons?: ButtonData[] - audio?: string - skipable?: boolean - timeOn?: number -} - -/** - * - * @typedef {Object} TriggerData - Object with data for a NPCTriggerComponent - * @property {number} layer layer of the Trigger, useful to discriminate between trigger events. You can set multiple layers by using a | symbol. defaults to NO_LAYERS - * @property {number} triggeredByLayer against which layers to check collisions. defaults to LAYER_1 - * @property {(entity: Entity) => void } onTriggerEnter callback when an entity of a valid layer enters the trigger area - * @property {(entity: Entity) => void} onTriggerExit callback when an entity of a valid layer leaves the trigger area - * @property {() => void} onCameraEnter callback when the player enters the trigger area - * @property {() => void} onCameraExit callback when the player leaves the trigger area - * @property {boolean} enableDebug when true makes the trigger area visible for debug purposes. - */ -export type TriggerData = { - layer?: number - triggeredByLayer?: number - onTriggerEnter?: (other: Entity) => void - onTriggerExit?: (other: Entity) => void - onCameraEnter?: (other: Entity) => void - onCameraExit?: (other: Entity) => void - enableDebug?: boolean -} - -/** - * Data for Button to show on a question in a Dialog entry - * - * @typedef {Object} ButtonData - Object with data for a Dialog UI button - * @property {string|number} goToDialog The index or name of the next dialog entry to display when activated. - * @property {string} label The label to show on the button. - * @property {() => void} triggeredActions An additional function to run whenever the button is activated - * @property {number} fontSize Font size of the text - * @property {number}offsetX Offset of the text on the X axis, relative to its normal position. - * @property {number} offsetY Offset of the text on the Y axis, relative to its normal position. - * - */ -export type ButtonData = { - goToDialog: number | string - label: string - triggeredActions?: () => void - fontSize?: number - offsetX?: number - offsetY?: number - size?: number | string -} - -export enum ButtonStyles { - E = `e`, - F = `f`, - DARK = `dark`, - RED = `red`, - ROUNDBLACK = `roundblack`, - ROUNDWHITE = `roundwhite`, - ROUNDSILVER = `roundsilver`, - ROUNDGOLD = `roundgold`, - SQUAREBLACK = `squareblack`, - SQUAREWHITE = `squarewhite`, - SQUARESILVER = `squaresilver`, - SQUAREGOLD = `squaregold`, - WHITE = `white` -} - -/** - * An NPC capable of having conversations with the player, and play different animations. - * - * @typedef {Object} NPCData Object with data to instance a new NPC - * @property {string|ImageData} portrait 2D image to show on the left-hand side of the dialog window. The structure of an `ImageData` object is described in detail below. - * @property {number} reactDistance Radius in meters for the player to activate the NPC or trigger the `onWalkAway()` function when leaving the radius. - * @property {string} idleAnim Name of the idle animation in the model. This animation is always looped. After playing a non-looping animation it returns to looping this one. - * @property {boolean} faceUser Set if the NPC rotates to face the user while active. - * @property {boolean} onlyExternalTrigger If true, the NPC can't be activated by clicking or walking near. Just by calling its `activate()` function. - * @property {boolean} onlyClickTrigger If true, the NPC can't be activated by walking near. Just by clicking on it or calling its `activate()` function. - * @property {boolean} onlyETrigger If true, the NPC can't be activated by walking near. Just by pressing E on it or calling its `activate()` function. - * @property {() => void} onWalkAway Function to call every time the player walks out of the `reactDistance` radius. - * @property {boolean} continueOnWalkAway f true,when the player walks out of the `reactDistance` radius, the dialog window stays open and the NPC keeps turning to face the player (if applicable). It doesn't affect the triggering of the `onWalkAway()` function. - * @property {boolean} darkUI If true, the dialog UI uses the dark theme. - * @property {number} coolDownDuration Change the cooldown period for activating the NPC again. The number is in seconds. - * @property {string} hoverText Set the UI hover feedback when pointing the cursor at the NPC. _TALK_ by default. - * @property {string} dialogSound Path to sound file to play once for every line of dialog read on the UI. - * @property {string} walkingAnim Animation to play when walking with followPath - * @property {number} walkingSpeed Default speed to use when walking with followPath - * @property {Vector3[]} path Array of Vector3 points representing the default path to walk over. The NPC will walk looping over these points - * @property {boolean} textBubble If true, the NPC can display text bubbles with dialogs - * @property {number} bubbleHeight The default height to display text bubbles over the NPC's position - * @property {boolean} noUI If true, no UI dialog elements are constructed. The NPC can use speech bubbles. - * - */ - -export type NPCData = { - type: NPCType - body?: NPCBodyType - model?: string | PBGltfContainer | PBAvatarShape - - walkingAnim?: string - portrait?: string | ImageData - reactDistance?: number - idleAnim?: string - faceUser?: boolean - turningSpeed?: number - onlyExternalTrigger?: boolean - onlyClickTrigger?: boolean - onlyETrigger?: boolean - onActivate: (other: Entity) => void - onWalkAway?: (other: Entity) => void - continueOnWalkAway?: boolean - darkUI?: boolean - coolDownDuration?: number - hoverText?: string - dialogSound?: string - //dialogCustomTheme?: Texture - textBubble?: boolean - bubbleHeight?: number - noUI?: boolean - - pathData?: FollowPathData - - bubbleXOffset?: number - bubbleYOffset?: number -} - -/** - * Make an NPC walk following a path - * - * @typedef {Object} FollowPathData - Object with data to describe a path that an NPC can walk - * @property {Vector3[]} path Array of `Vector3` positions to walk over. - * @property {number} speed Speed to move at while walking this path. If no `speed` or `totalDuration` is provided, it uses the NPC's `walkingSpeed`, which is _2_ by default. - * @property {number} totalDuration The duration in _seconds_ that the whole path should take. The NPC will move at the constant speed required to finish in that time. This value overrides that of the _speed_. - * @property {boolean} loop _boolean_ If true, the NPC walks in circles over the provided set of points in the path. _false_ by default, unless the NPC is initiated with a `path`, in which case it starts as _true_. - * @property {boolean} curve _boolean_ If true, the path is traced a single smooth curve that passes over each of the indicated points. The curve is made out of straight-line segments, the path is stored with 4 times as many points as originally defined. _false_ by default. - * @property {number} startingPoint Index position for what point to start from on the path. _0_ by default. - * @property {() => void} onFinishCallback Function to call when the NPC finished walking over all the points on the path. This is only called when `loop` is _false_. - * @property {() => void} onReachedPointCallback Function to call once every time the NPC reaches a point in the path. - * - */ -export type FollowPathData = { - startingPoint?: number - loop?: boolean - curve?: boolean - totalDuration: number - speed?: number - path?: Vector3[] - pathType?: NPCPathType - onFinishCallback?: () => void - onReachedPointCallback?: () => void -} - -/** - * Cut out a section of an image file - * - * @typedef {Object} ImageSection - Object with data to only display a section of an image - * @property {number} sourceWidth Width in pixels to select from image, starting from the sourceLeft, going right - * @property {number} sourceHeight Height in pixels to select from image, starting from the sourceTop, going down - * @property {number} sourceLeft Leftmost pixel to select from image - * @property {number} sourceTop Topmost pixel to select from image - * - */ -export type ImageSection = { - sourceWidth: number - sourceHeight: number - sourceLeft?: number - sourceTop?: number -} - -/** - * - * - * @typedef {Object} ImageData - Object with data for displaying an image - * @property {string} path Path to the image file. - * @property {number} offsetX Offset on X, relative to the normal position of the image. - * @property {number} offsetY Offset on Y, relative to the normal position of the image. - * @property {number} height The height to show the image onscreen. - * @property {number} width The width to show the image onscreen. - * @property {ImageSection} section Use only a section of the image file, useful when arranging multiple icons into an image atlas. This field takes an `ImageSection` object, specifying `sourceWidth` and `sourceHeight`, and optionally also `sourceLeft` and `sourceTop`. - * - */ -export type ImageData = { - path: string - offsetX?: number - offsetY?: number - height?: number - width?: number - section?: ImageSection -} - -export enum NPCState { - STANDING = 'standing', - TALKING = 'talking', - FOLLOWPATH = 'followPath' - //FOLLOWPLAYER = 'followPlayer' -} - -export enum NPCBodyType { - MALE = 'BaseMale', - FEMALE = 'BaseFemale' -} - -export enum NPCType { - BLANK = 'blank', - CUSTOM = 'custom', - AVATAR = 'avatar' -} - -export enum NPCPathType { - SMOOTH_PATH = 'smooth', //will follow the path but can cut sharp corners - RIGID_PATH = 'rigid' //will ensure each corner is hit -} diff --git a/demo/src/ui.tsx b/demo/src/ui.tsx deleted file mode 100644 index 4e48b86..0000000 --- a/demo/src/ui.tsx +++ /dev/null @@ -1,432 +0,0 @@ -import { Color4 } from '@dcl/sdk/math' -import ReactEcs, { Button, Label, ReactEcsRenderer, UiEntity } from '@dcl/sdk/react-ecs' -import { Entity } from '@dcl/sdk/ecs' -import { - buttonClick, - confirmText, - displayButton, - displayDialog, - displayFirstButtonContainer, - displayImage, - displayPortrait, - displaySecondButtonContainer, - displaySkipable, - getButtonText, - getbuttonSize, - getFontSize, - getImage, - getImageAtlasMapping, - getLeftClickTheme, - getPortrait, - getSkipableTheme, - getText, - getTextColor, - getTextPosition, - getTheme, - handleDialogClick, - imageHeight, - imageWidth, - portraitHeight, - portraitWidth, - positionImageX, - positionImageY, - positionPortaitX, - positionPortaitY, - positionTextX, - positionTextY, - realHeight, - realWidth, - skipDialogs, - getTextSize -} from './dialog' -import { sourcesComponentsCoordinates } from './uiResources' -import { activeNPC } from './npc' - -export let lightTheme = 'https://decentraland.org/images/ui/light-atlas-v3.png' -export let darkTheme = 'https://decentraland.org/images/ui/dark-atlas-v3.png' - -export let bubblesTexture = 'https://decentraland.org/images/ui/dialog-bubbles.png' - -export let section = { - ...sourcesComponentsCoordinates.backgrounds.NPCDialog, - atlasHeight: sourcesComponentsCoordinates.atlasHeight, - atlasWidth: sourcesComponentsCoordinates.atlasWidth -} - -export let skipButtonSection = { - ...sourcesComponentsCoordinates.buttons.F, - atlasHeight: sourcesComponentsCoordinates.atlasHeight, - atlasWidth: sourcesComponentsCoordinates.atlasWidth -} - -export let skipButtonSectionBlack = { - ...sourcesComponentsCoordinates.buttons.FBlack, - atlasHeight: sourcesComponentsCoordinates.atlasHeight, - atlasWidth: sourcesComponentsCoordinates.atlasWidth -} - -export let leftClickSection = { - ...sourcesComponentsCoordinates.icons.ClickWhite, - atlasHeight: sourcesComponentsCoordinates.atlasHeight, - atlasWidth: sourcesComponentsCoordinates.atlasWidth -} - -export let leftClickSectionbBlack = { - ...sourcesComponentsCoordinates.icons.ClickDark, - atlasHeight: sourcesComponentsCoordinates.atlasHeight, - atlasWidth: sourcesComponentsCoordinates.atlasWidth -} - -export let primaryButtonSection = { - ...sourcesComponentsCoordinates.buttons.E, - atlasHeight: sourcesComponentsCoordinates.atlasHeight, - atlasWidth: sourcesComponentsCoordinates.atlasWidth -} - -export let secondaryButtonSection = { - ...sourcesComponentsCoordinates.buttons.F, - atlasHeight: sourcesComponentsCoordinates.atlasHeight, - atlasWidth: sourcesComponentsCoordinates.atlasWidth -} - -export let darkButtonSection = { - ...sourcesComponentsCoordinates.buttons.buttonF, - atlasHeight: sourcesComponentsCoordinates.atlasHeight, - atlasWidth: sourcesComponentsCoordinates.atlasWidth -} - -export let redButtonSection = { - ...sourcesComponentsCoordinates.buttons.buttonE, - atlasHeight: sourcesComponentsCoordinates.atlasHeight, - atlasWidth: sourcesComponentsCoordinates.atlasWidth -} - -let modalScale = 1 -let modelFontSizeScale = 1 -let modalTextWrapScale = 1 - -export function setupNPCUiScaling(inModalScale: number, inFontSize: number, inModalTextWrapScale: number) { - modalScale = inModalScale - modelFontSizeScale = inFontSize - modalTextWrapScale = inModalTextWrapScale - console.log( - 'NPC-TOOLKIT', - 'Scale UI:', - modalScale, - 'TextFontSize:', - modelFontSizeScale, - 'TextWrapScaling:', - modalTextWrapScale - ) -} - -function getScaledSize(size: number): number { - return size * modalScale -} -function getScaledFontSize(size: number): number { - return size * modelFontSizeScale -} -function getScaledTextWrap(size: number): number { - return size * modalTextWrapScale -} -function getScaledButtonWidth(button:number) { -return typeof(getbuttonSize(button)) === 'number' ? getScaledSize(getbuttonSize(button) as number) : 'auto' -} -export const NpcUtilsUi = () => { - const width = getScaledSize(realWidth(700)) - const height = getScaledSize(realHeight(284)) - - return ( - - { - handleDialogClick() - }} - /> - - - - - - { - skipDialogs(activeNPC) - }} - > - - - - - - - - - {/* Button1 (Top-Left) */} - { - buttonClick(0) - }} - > - - - - {/* Button2 (Top-Right) */} - { - buttonClick(1) - }} - > - - - - - {/* Second row of buttons */} - - {/* Button3 */} - { - buttonClick(3) - }} - > - - {/* Button4 */} - { - buttonClick(4) - }} - > - - - ) -} diff --git a/demo/src/uiComp.tsx b/demo/src/uiComp.tsx index fd6d101..76c7f5a 100644 --- a/demo/src/uiComp.tsx +++ b/demo/src/uiComp.tsx @@ -1,5 +1,5 @@ import ReactEcs, { ReactEcsRenderer, UiEntity } from '@dcl/sdk/react-ecs' -import { NpcUtilsUi } from './ui'; +import * as npc from 'dcl-npc-toolkit' export function setupUi() { ReactEcsRenderer.setUiRenderer(uiComponent) @@ -12,7 +12,7 @@ const uiComponent = () => ( height: '100%', }} > - + ) \ No newline at end of file diff --git a/demo/src/uiResources.ts b/demo/src/uiResources.ts deleted file mode 100644 index c761ef8..0000000 --- a/demo/src/uiResources.ts +++ /dev/null @@ -1,320 +0,0 @@ -export const sourcesComponentsCoordinates = { - atlasHeight: 1024, - atlasWidth: 1024, - buttons: { - E: { - sourceWidth: 26, - sourceHeight: 26, - sourceLeft: 697, - sourceTop: 611, - }, - F: { - sourceWidth: 26, - sourceHeight: 26, - sourceLeft: 733, - sourceTop: 611, - }, - EBlack: { - sourceWidth: 26, - sourceHeight: 26, - sourceLeft: 766, - sourceTop: 611, - }, - FBlack: { - sourceWidth: 26, - sourceHeight: 26, - sourceLeft: 802, - sourceTop: 611, - }, - buttonE: { - sourceWidth: 174, - sourceHeight: 46, - sourceLeft: 512, - sourceTop: 662, - }, - buttonF: { - sourceWidth: 174, - sourceHeight: 46, - sourceLeft: 512, - sourceTop: 612, - }, - white: { - sourceWidth: 174, - sourceHeight: 46, - sourceLeft: 698, - sourceTop: 662, - }, - red: { - sourceWidth: 174, - sourceHeight: 46, - sourceLeft: 512, - sourceTop: 662, - }, - dark: { - sourceWidth: 174, - sourceHeight: 46, - sourceLeft: 512, - sourceTop: 612, - }, - roundBlack: { - sourceWidth: 128, - sourceHeight: 32, - sourceLeft: 512, - sourceTop: 458, - }, - squareBlack: { - sourceWidth: 128, - sourceHeight: 32, - sourceLeft: 646, - sourceTop: 457, - }, - roundWhite: { - sourceWidth: 128, - sourceHeight: 32, - sourceLeft: 512, - sourceTop: 494, - }, - squareWhite: { - sourceWidth: 128, - sourceHeight: 32, - sourceLeft: 646, - sourceTop: 493, - }, - roundSilver: { - sourceWidth: 128, - sourceHeight: 32, - sourceLeft: 512, - sourceTop: 532, - }, - squareSilver: { - sourceWidth: 128, - sourceHeight: 32, - sourceLeft: 646, - sourceTop: 532, - }, - roundGold: { - sourceWidth: 128, - sourceHeight: 32, - sourceLeft: 512, - sourceTop: 568, - }, - squareGold: { - sourceWidth: 128, - sourceHeight: 32, - sourceLeft: 646, - sourceTop: 568, - }, - }, - backgrounds: { - promptBackground: { - sourceWidth: 416, - sourceHeight: 352, - sourceLeft: 501, - sourceTop: 12, - }, - promptLargeBackground: { - sourceWidth: 480, - sourceHeight: 384, - sourceLeft: 7, - sourceTop: 12, - }, - promptSlantedBackground: { - sourceWidth: 486, - sourceHeight: 326, - sourceLeft: 7, - sourceTop: 413, - }, - NPCDialog: { - sourceWidth: 766, - sourceHeight: 248, - sourceLeft: 22, - sourceTop: 756, - }, - }, - icons: { - closeW: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 942, - sourceTop: 306, - }, - closeD: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 986, - sourceTop: 306, - }, - closeWLarge: { - sourceWidth: 64, - sourceHeight: 64, - sourceLeft: 512, - sourceTop: 381, - }, - closeDLarge: { - sourceWidth: 64, - sourceHeight: 64, - sourceLeft: 583, - sourceTop: 381, - }, - closeWNoBack: { - sourceWidth: 24, - sourceHeight: 24, - sourceLeft: 946, - sourceTop: 252, - }, - closeDNoBack: { - sourceWidth: 24, - sourceHeight: 24, - sourceLeft: 946, - sourceTop: 214, - }, - closeWNoBackLarge: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 987, - sourceTop: 214, - }, - closeDNoBackLarge: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 987, - sourceTop: 260, - }, - FDark: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 950, - sourceTop: 4, - }, - FWhite: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 987, - sourceTop: 4, - }, - EDark: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 950, - sourceTop: 40, - }, - EWhite: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 987, - sourceTop: 40, - }, - Timer: { - sourceWidth: 24, - sourceHeight: 32.2, - sourceLeft: 718, - sourceTop: 388, - }, - TimerLarge: { - sourceWidth: 50, - sourceHeight: 66, - sourceLeft: 661, - sourceTop: 385, - }, - ClickWhite: { - sourceWidth: 32, - sourceHeight: 48, - sourceLeft: 799, - sourceTop: 389, - }, - ClickDark: { - sourceWidth: 32, - sourceHeight: 48, - sourceLeft: 757, - sourceTop: 389, - }, - }, - checkboxes: { - wOff: { - sourceWidth: 24, - sourceHeight: 24, - sourceLeft: 987, - sourceTop: 76, - }, - wOn: { - sourceWidth: 24, - sourceHeight: 24, - sourceLeft: 987, - sourceTop: 104, - }, - dOff: { - sourceWidth: 24, - sourceHeight: 24, - sourceLeft: 958, - sourceTop: 76, - }, - dOn: { - sourceWidth: 24, - sourceHeight: 24, - sourceLeft: 958, - sourceTop: 104, - }, - wLargeOff: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 987, - sourceTop: 132, - }, - wLargeOn: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 987, - sourceTop: 168, - }, - dLargeOff: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 950, - sourceTop: 132, - }, - dLargeOn: { - sourceWidth: 32, - sourceHeight: 32, - sourceLeft: 950, - sourceTop: 168, - }, - }, - switches: { - roundOff: { - sourceWidth: 64, - sourceHeight: 32, - sourceLeft: 783, - sourceTop: 454, - }, - squareOff: { - sourceWidth: 64, - sourceHeight: 32, - sourceLeft: 783, - sourceTop: 501, - }, - roundRed: { - sourceWidth: 64, - sourceHeight: 32, - sourceLeft: 853, - sourceTop: 454, - }, - roundGreen: { - sourceWidth: 64, - sourceHeight: 32, - sourceLeft: 923, - sourceTop: 454, - }, - squareRed: { - sourceWidth: 64, - sourceHeight: 32, - sourceLeft: 852, - sourceTop: 501, - }, - squareGreen: { - sourceWidth: 64, - sourceHeight: 32, - sourceLeft: 921, - sourceTop: 500, - }, - }, - } \ No newline at end of file diff --git a/demo/src/utils.ts b/demo/src/utils.ts deleted file mode 100644 index 36f8a6b..0000000 --- a/demo/src/utils.ts +++ /dev/null @@ -1,9 +0,0 @@ -export function getRandomHexColor(): string { - const letters = "0123456789ABCDEF"; - let color = "#"; - for (let i = 0; i < 6; i++) { - color += letters[Math.floor(Math.random() * 16)]; - } - return color; -} - diff --git a/package.json b/package.json index 003fddb..ac9bb34 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,14 @@ "type": "git", "url": "https://github.com/decentraland-scenes/dcl-npc-toolkit.git" }, - "keywords": ["decentraland", "sdk7", "sdk 7", "sdk utils", "npc", "sdk library"], + "keywords": [ + "decentraland", + "sdk7", + "sdk 7", + "sdk utils", + "npc", + "sdk library" + ], "author": "Decentraland", "license": "Apache-2.0", "bugs": { @@ -19,9 +26,9 @@ }, "homepage": "https://github.com/decentraland-scenes/dcl-npc-toolkit#readme", "devDependencies": { + "@dcl-sdk/utils": "latest", "@dcl/sdk": "latest", - "typescript": "^5.0.2", - "@dcl-sdk/utils": "latest" + "typescript": "^5.0.2" }, "files": [ "dist" diff --git a/src/ui.tsx b/src/ui.tsx index 4e48b86..a2f7c34 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -149,8 +149,7 @@ export const NpcUtilsUi = () => { margin: { top: (-height + getText().length / 2) / 2, left: -width / 2 }, padding: {top: 40, bottom: 40}, width, - // minHeight: typeof(getTextSize()) === 'number' ? 0 : 100, - height: typeof(getTextSize()) === 'number' ? getTextSize() as number : (getText().length <= 100 ? height : 'auto') + height: typeof(getTextSize()) === 'number' ? getTextSize() as number : 'auto' }} > { flexDirection: 'row', position: getTextPosition(), display: 'flex', - flexGrow: 1 - // margin: {bottom: getText().length/10 + 70} + flexGrow: 1, + minHeight: 100 }} uiText={{ value: getText(), From 69fc660a74e9c6dd749c85c91cf9c514150d8966 Mon Sep 17 00:00:00 2001 From: vatka Date: Wed, 24 Jan 2024 17:16:41 +0200 Subject: [PATCH 11/21] Rename textSize, smal fix of UI ~ Rename textSize => windowHeight ~ Use getScaledSize when need ~ set maxWidth to button --- README.md | 2 +- demo/src/index.ts | 2 +- src/dialog.ts | 13 +++++-------- src/types.ts | 2 +- src/ui.tsx | 18 +++++++++++++----- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 5afd4e0..be6af2e 100644 --- a/README.md +++ b/README.md @@ -1360,7 +1360,7 @@ The script must adhere to the following schema: ```ts class Dialog { text: string -textSize?: 'auto' | number +windowHeight?: 'auto' | number name?: string fontSize?: number offsetX?: number diff --git a/demo/src/index.ts b/demo/src/index.ts index 10d75d7..3ca050c 100644 --- a/demo/src/index.ts +++ b/demo/src/index.ts @@ -17,7 +17,7 @@ export function main() { npc.talk(myNPC, [ { text: `Quest Overview: In the mystical realm of Eldoria, a sinister force has swept through the winter lands, freezing the hearts of magical creatures and stealing the essence of Frostfire Crystals - the source of warmth and magic. As a valiant hero, you are called upon to embark on a quest to restore balance and save the fantastical festivities. `, - textSize: 'auto', + windowHeight: 'auto', isQuestion: true, buttons: [ { label: `Restore magic!`, goToDialog: 2, size: 'auto'}, diff --git a/src/dialog.ts b/src/dialog.ts index 689348a..354825a 100644 --- a/src/dialog.ts +++ b/src/dialog.ts @@ -182,7 +182,6 @@ export function getButtonText(button:number){ let dialogData = npcDialogComponent.get(activeNPC) if(dialogData.isQuestion && dialogData.buttons > button){ text = dialogData.script[dialogData.index].buttons[button].label - text = text.slice(0, 15) } } return text @@ -209,17 +208,17 @@ export function displayDialog(){ return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).visible } -export function getTextSize() { - let textSizes: number | string | undefined +export function getWindowHeight() { + let windowHeights: number | string | undefined if (activeNPC != 0 && npcDialogComponent.has(activeNPC)) { let dialogData = npcDialogComponent.get(activeNPC); if (dialogData.isQuestion) { - if (dialogData.script[dialogData.index].textSize !== undefined) { - textSizes = dialogData.script[dialogData.index]?.textSize; + if (dialogData.script[dialogData.index].windowHeight !== undefined) { + windowHeights = dialogData.script[dialogData.index]?.windowHeight; } } } - return textSizes + return windowHeights } export function displayButton(button:number){ @@ -686,5 +685,3 @@ while(dialogData.visibleChars < dialogData.fullText.length && dialogData.fullTex } return } - -export { Dialog }; diff --git a/src/types.ts b/src/types.ts index f528744..3d4e1f0 100644 --- a/src/types.ts +++ b/src/types.ts @@ -23,7 +23,7 @@ import { Vector3 } from '@dcl/sdk/math' */ export type Dialog = { text: string - textSize?: 'auto' | number + windowHeight?: 'auto' | number name?: string fontSize?: number offsetX?: number diff --git a/src/ui.tsx b/src/ui.tsx index a2f7c34..efe6976 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -37,7 +37,7 @@ import { realHeight, realWidth, skipDialogs, - getTextSize + getWindowHeight } from './dialog' import { sourcesComponentsCoordinates } from './uiResources' import { activeNPC } from './npc' @@ -146,10 +146,10 @@ export const NpcUtilsUi = () => { positionType: 'absolute', flexGrow: 1, position: { bottom: '10%', left: '50%' }, - margin: { top: (-height + getText().length / 2) / 2, left: -width / 2 }, + margin: { top: -height / 2, left: -width / 2 }, padding: {top: 40, bottom: 40}, width, - height: typeof(getTextSize()) === 'number' ? getTextSize() as number : 'auto' + height: typeof(getWindowHeight()) === 'number' ? getWindowHeight() as number : 'auto' }} > { { uiTransform={{ width: getScaledSize(25), height: getScaledSize(25), - margin: {left: 5, right: 5} + margin: {left: getScaledSize(5), right: getScaledSize(5)} }} uiBackground={{ textureMode: 'stretch', @@ -332,6 +334,8 @@ export const NpcUtilsUi = () => { { uiTransform={{ width: getScaledSize(25), height: getScaledSize(25), - margin: {left: 5, right: 5} + margin: {left: getScaledSize(5), right: getScaledSize(5)} }} uiBackground={{ textureMode: 'stretch', @@ -383,6 +387,8 @@ export const NpcUtilsUi = () => { { Date: Wed, 24 Jan 2024 19:35:54 +0200 Subject: [PATCH 12/21] Change button text ~ Change button text structure --- src/ui.tsx | 65 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/src/ui.tsx b/src/ui.tsx index efe6976..21d16fb 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -296,7 +296,7 @@ export const NpcUtilsUi = () => { overflow: 'hidden', height: getScaledSize(45), margin: { right: '5%' }, - flexDirection: 'row-reverse', + flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', alignContent: 'flex-start', @@ -309,7 +309,6 @@ export const NpcUtilsUi = () => { }, uvs: getImageAtlasMapping(darkButtonSection) }} - uiText={{ value: getButtonText(0), fontSize: getScaledFontSize(16) }} onMouseDown={() => { buttonClick(0) }} @@ -318,7 +317,8 @@ export const NpcUtilsUi = () => { uiTransform={{ width: getScaledSize(25), height: getScaledSize(25), - margin: {left: getScaledSize(5), right: getScaledSize(5)} + margin: {left: getScaledSize(5), right: getScaledSize(5)}, + positionType: 'absolute' }} uiBackground={{ textureMode: 'stretch', @@ -328,6 +328,17 @@ export const NpcUtilsUi = () => { uvs: getImageAtlasMapping(secondaryButtonSection) }} > + + {/* Button2 (Top-Right) */} @@ -335,9 +346,8 @@ export const NpcUtilsUi = () => { uiTransform={{ width: getScaledButtonWidth(1), maxWidth: getScaledSize(300), - overflow: 'hidden', height: getScaledSize(45), - flexDirection: 'row-reverse', + flexDirection: 'row', alignItems: 'center', justifyContent: 'flex-start', alignContent: 'flex-start', @@ -350,7 +360,6 @@ export const NpcUtilsUi = () => { }, uvs: getImageAtlasMapping(redButtonSection) }} - uiText={{ value: getButtonText(1), fontSize: getScaledFontSize(16) }} onMouseDown={() => { buttonClick(1) }} @@ -359,7 +368,8 @@ export const NpcUtilsUi = () => { uiTransform={{ width: getScaledSize(25), height: getScaledSize(25), - margin: {left: getScaledSize(5), right: getScaledSize(5)} + margin: {left: getScaledSize(5), right: getScaledSize(5)}, + positionType: 'absolute', }} uiBackground={{ textureMode: 'stretch', @@ -369,6 +379,17 @@ export const NpcUtilsUi = () => { uvs: getImageAtlasMapping(primaryButtonSection) }} > + + @@ -403,11 +424,22 @@ export const NpcUtilsUi = () => { }, uvs: getImageAtlasMapping(darkButtonSection) }} - uiText={{ value: getButtonText(2), fontSize: getScaledFontSize(16) }} onMouseDown={() => { buttonClick(3) }} - > + > + + + {/* Button4 */} { }, uvs: getImageAtlasMapping(darkButtonSection) }} - uiText={{ value: getButtonText(3), fontSize: getScaledFontSize(16) }} onMouseDown={() => { buttonClick(4) }} - > + > + + + ) From 0475ecb64abdca437d65baf443b3e920be3feb74 Mon Sep 17 00:00:00 2001 From: vatka Date: Thu, 25 Jan 2024 20:43:28 +0200 Subject: [PATCH 13/21] Button fix ~ fix scale of buttons row ~ Change button text width to auto, ~ Delete height of text in button --- src/ui.tsx | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/ui.tsx b/src/ui.tsx index 21d16fb..d8033e1 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -144,7 +144,6 @@ export const NpcUtilsUi = () => { alignItems: 'center', justifyContent: 'center', positionType: 'absolute', - flexGrow: 1, position: { bottom: '10%', left: '50%' }, margin: { top: -height / 2, left: -width / 2 }, padding: {top: 40, bottom: 40}, @@ -281,7 +280,7 @@ export const NpcUtilsUi = () => { { > { > { {/* Second row of buttons */} { > { > Date: Sat, 27 Jan 2024 23:18:02 +0200 Subject: [PATCH 14/21] Button text overflow fix --- src/ui.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ui.tsx b/src/ui.tsx index d8033e1..79c6093 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -267,7 +267,6 @@ export const NpcUtilsUi = () => { flexDirection: 'row', position: getTextPosition(), display: 'flex', - flexGrow: 1, minHeight: 100 }} uiText={{ @@ -332,6 +331,7 @@ export const NpcUtilsUi = () => { width: 'auto', maxWidth: getScaledSize(265), overflow: 'hidden', + padding: {right: 5}, margin: {left: getScaledSize(30), right: getScaledSize(5)} }} uiText={{ value: getButtonText(0), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} @@ -382,6 +382,7 @@ export const NpcUtilsUi = () => { width: 'auto', maxWidth: getScaledSize(265), overflow: 'hidden', + padding: {right: 5}, margin: {left: getScaledSize(30), right: getScaledSize(5)} }} uiText={{ value: getButtonText(1), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} @@ -430,6 +431,7 @@ export const NpcUtilsUi = () => { width: 'auto', maxWidth: getScaledSize(300), overflow: 'hidden', + padding: {right: 3}, margin: {left: getScaledSize(5), right: getScaledSize(5)} }} uiText={{ value: getButtonText(2), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} @@ -465,6 +467,7 @@ export const NpcUtilsUi = () => { width: 'auto', maxWidth: getScaledSize(300), overflow: 'hidden', + padding: {right: 3}, margin: {left: getScaledSize(5), right: getScaledSize(5)} }} uiText={{ value: getButtonText(3), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} From e052ff714244974f5438a9f8ada97b9531b2d060 Mon Sep 17 00:00:00 2001 From: vatka Date: Sat, 27 Jan 2024 23:21:40 +0200 Subject: [PATCH 15/21] flexGrow fix --- src/ui.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui.tsx b/src/ui.tsx index 79c6093..e2e8d67 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -267,6 +267,7 @@ export const NpcUtilsUi = () => { flexDirection: 'row', position: getTextPosition(), display: 'flex', + flexGrow: 1, minHeight: 100 }} uiText={{ From adb686ba3a9d34f89e5cb88b59b4a43a31c08221 Mon Sep 17 00:00:00 2001 From: vatka Date: Mon, 29 Jan 2024 20:03:09 +0200 Subject: [PATCH 16/21] Fix button corners + Add button corner, edge from atlas ~ fix buttons corners ~ fix margin, padding in buttons --- src/ui.tsx | 387 ++++++++++++++++++++++++++++++--------------- src/uiResources.ts | 28 +++- 2 files changed, 287 insertions(+), 128 deletions(-) diff --git a/src/ui.tsx b/src/ui.tsx index e2e8d67..bd2b4bf 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -95,12 +95,36 @@ export let darkButtonSection = { atlasWidth: sourcesComponentsCoordinates.atlasWidth } +export let darkButtonCorner = { + ...sourcesComponentsCoordinates.buttons.buttonFCorner, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + +export let darkButtonEdge = { + ...sourcesComponentsCoordinates.buttons.buttonFEdge, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + export let redButtonSection = { ...sourcesComponentsCoordinates.buttons.buttonE, atlasHeight: sourcesComponentsCoordinates.atlasHeight, atlasWidth: sourcesComponentsCoordinates.atlasWidth } +export let redButtonCorner = { + ...sourcesComponentsCoordinates.buttons.buttonECorner, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + +export let redButtonEdge = { + ...sourcesComponentsCoordinates.buttons.buttonEEdge, + atlasHeight: sourcesComponentsCoordinates.atlasHeight, + atlasWidth: sourcesComponentsCoordinates.atlasWidth +} + let modalScale = 1 let modelFontSizeScale = 1 let modalTextWrapScale = 1 @@ -129,9 +153,10 @@ function getScaledFontSize(size: number): number { function getScaledTextWrap(size: number): number { return size * modalTextWrapScale } -function getScaledButtonWidth(button:number) { -return typeof(getbuttonSize(button)) === 'number' ? getScaledSize(getbuttonSize(button) as number) : 'auto' +function getScaledButtonWidth(button: number) { + return typeof (getbuttonSize(button)) === 'number' ? getScaledSize(getbuttonSize(button) as number) : 'auto' } + export const NpcUtilsUi = () => { const width = getScaledSize(realWidth(700)) const height = getScaledSize(realHeight(284)) @@ -145,11 +170,11 @@ export const NpcUtilsUi = () => { justifyContent: 'center', positionType: 'absolute', position: { bottom: '10%', left: '50%' }, - margin: { top: -height / 2, left: -width / 2 }, - padding: {top: 40, bottom: 40}, + margin: { top: -height / 2, left: -width / 2 }, + padding: { top: 40, bottom: 40 }, width, - height: typeof(getWindowHeight()) === 'number' ? getWindowHeight() as number : 'auto' - }} + height: typeof (getWindowHeight()) === 'number' ? getWindowHeight() as number : 'auto' + }} > { {/* Button1 (Top-Left) */} { - buttonClick(0) }} > + /> { + buttonClick(0) }} - uiText={{ value: getButtonText(0), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} > + + + + {/* Button2 (Top-Right) */} - { - buttonClick(1) - }} - > + + /> { + buttonClick(1) }} - uiText={{ value: getButtonText(1), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} > + + + + @@ -399,81 +482,133 @@ export const NpcUtilsUi = () => { alignItems: 'center', flexDirection: 'row', justifyContent: 'center', - margin: { top: getScaledSize(20)}, + margin: { top: getScaledSize(20) }, display: displaySecondButtonContainer() ? 'flex' : 'none', }} > {/* Button3 */} - { - buttonClick(3) - }} - > + + { + buttonClick(3) }} - uiText={{ value: getButtonText(2), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} > + + + {/* Button4 */} - { - buttonClick(4) - }} - > + + { + buttonClick(4) }} - uiText={{ value: getButtonText(3), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} > + + + diff --git a/src/uiResources.ts b/src/uiResources.ts index c761ef8..52a055a 100644 --- a/src/uiResources.ts +++ b/src/uiResources.ts @@ -27,17 +27,41 @@ export const sourcesComponentsCoordinates = { sourceTop: 611, }, buttonE: { - sourceWidth: 174, + sourceWidth: 126, + sourceHeight: 46, + sourceLeft: 536, + sourceTop: 662, + }, + buttonECorner: { + sourceWidth: 12, sourceHeight: 46, sourceLeft: 512, sourceTop: 662, }, + buttonEEdge: { + sourceWidth: 12, + sourceHeight: 46, + sourceLeft: 674, + sourceTop: 662, + }, buttonF: { - sourceWidth: 174, + sourceWidth: 126, + sourceHeight: 46, + sourceLeft: 536, + sourceTop: 612, + }, + buttonFCorner: { + sourceWidth: 12, sourceHeight: 46, sourceLeft: 512, sourceTop: 612, }, + buttonFEdge: { + sourceWidth: 12, + sourceHeight: 46, + sourceLeft: 674, + sourceTop: 612, + }, white: { sourceWidth: 174, sourceHeight: 46, From df808482c264975ad7dfbb0e58ac62c32b3eff74 Mon Sep 17 00:00:00 2001 From: vatka Date: Tue, 30 Jan 2024 17:27:42 +0200 Subject: [PATCH 17/21] Refactor buttons --- src/ui.tsx | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/ui.tsx b/src/ui.tsx index bd2b4bf..f0d1881 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -301,7 +301,7 @@ export const NpcUtilsUi = () => { fontSize: getScaledFontSize(getFontSize()), textAlign: 'middle-left' }} - > + /> { }} > {/* Button1 (Top-Left) */} - + { }, uvs: getImageAtlasMapping(secondaryButtonSection) }} - > + /> { margin: { left: getScaledSize(30) } }} uiText={{ value: getButtonText(0), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} - > - + /> { }, uvs: getImageAtlasMapping(primaryButtonSection) }} - > + /> { margin: { left: getScaledSize(30) } }} uiText={{ value: getButtonText(1), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} - > - + /> { overflow: 'hidden', }} uiText={{ value: getButtonText(2), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} - > - + /> { overflow: 'hidden', }} uiText={{ value: getButtonText(3), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} - > - + /> Date: Tue, 30 Jan 2024 20:31:31 +0200 Subject: [PATCH 18/21] ScaledSize text overflow fix --- src/ui.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui.tsx b/src/ui.tsx index f0d1881..aee15fb 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -369,7 +369,7 @@ export const NpcUtilsUi = () => { width: 'auto', overflow: 'hidden', maxWidth: getScaledSize(217), - padding: { right: 5 }, + padding: { right: getScaledSize(5) }, margin: { left: getScaledSize(30) } }} uiText={{ value: getButtonText(0), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} @@ -448,7 +448,7 @@ export const NpcUtilsUi = () => { width: 'auto', maxWidth: getScaledSize(217), overflow: 'hidden', - padding: { right: 5 }, + padding: { right: getScaledSize(5) }, margin: { left: getScaledSize(30) } }} uiText={{ value: getButtonText(1), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} From 17156d8139923fa687098e967995622e1eb759b8 Mon Sep 17 00:00:00 2001 From: vatka Date: Tue, 30 Jan 2024 21:10:35 +0200 Subject: [PATCH 19/21] fix button corner click ~ fix demo ~ fix proper button click --- demo/src/index.ts | 8 ++++---- src/ui.tsx | 38 +++++++++++++++++++++----------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/demo/src/index.ts b/demo/src/index.ts index 3ca050c..8ebe75f 100644 --- a/demo/src/index.ts +++ b/demo/src/index.ts @@ -20,10 +20,10 @@ export function main() { windowHeight: 'auto', isQuestion: true, buttons: [ - { label: `Restore magic!`, goToDialog: 2, size: 'auto'}, - { label: `Crystal theft`, goToDialog: 1, size: 'auto'}, - { label: `Icy crisis`, goToDialog: 1, size: 100}, - { label: `Heroes darkness.`, goToDialog: 1 }, + { label: `Restore magic!`, goToDialog: 0, size: 'auto'}, + { label: `Crystal theft`, goToDialog: 0, size: 'auto'}, + { label: `Icy crisis`, goToDialog: 0, size: 100}, + { label: `Heroes darkness.`, goToDialog: 0 }, ], } ]) diff --git a/src/ui.tsx b/src/ui.tsx index aee15fb..f080d5e 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -288,7 +288,7 @@ export const NpcUtilsUi = () => { width: 'auto', alignSelf: 'flex-start', alignItems: 'flex-start', - justifyContent: 'flex-start', + justifyContent: 'center', flexDirection: 'row', position: getTextPosition(), display: 'flex', @@ -313,7 +313,11 @@ export const NpcUtilsUi = () => { }} > {/* Button1 (Top-Left) */} - + { + buttonClick(0) + }} + > { }, uvs: getImageAtlasMapping(darkButtonSection) }} - onMouseDown={() => { - buttonClick(0) - }} > { {/* Button2 (Top-Right) */} - + { + buttonClick(1) + }} + > { }, uvs: getImageAtlasMapping(redButtonSection) }} - onMouseDown={() => { - buttonClick(1) - }} > { }} > {/* Button3 */} - + { + buttonClick(3) + }} + > { }, uvs: getImageAtlasMapping(darkButtonSection) }} - onMouseDown={() => { - buttonClick(3) - }} > { {/* Button4 */} - + { + buttonClick(4) + }} + > { }, uvs: getImageAtlasMapping(darkButtonSection) }} - onMouseDown={() => { - buttonClick(4) - }} > Date: Tue, 30 Jan 2024 21:49:38 +0200 Subject: [PATCH 20/21] Fix not working fontsize in button --- src/dialog.ts | 13 +++++++++++++ src/ui.tsx | 11 ++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/dialog.ts b/src/dialog.ts index 354825a..9e23e92 100644 --- a/src/dialog.ts +++ b/src/dialog.ts @@ -204,6 +204,19 @@ export function getFontSize(){ return !isActiveNpcSet() ? 22 : npcDialogComponent.get(activeNPC).fontSize } +export function getButtonFontSize(button:number){ + let ButtonFontSize: number = 54 + if (activeNPC != 0 && npcDialogComponent.has(activeNPC)) { + let dialogData = npcDialogComponent.get(activeNPC); + if (dialogData.isQuestion && dialogData.buttons > button) { + if (dialogData.script[dialogData.index].buttons[button].fontSize !== undefined) { + ButtonFontSize = dialogData.script[dialogData.index].buttons[button]?.fontSize; + } else {ButtonFontSize = 16} + } + } + return ButtonFontSize +} + export function displayDialog(){ return !isActiveNpcSet() ? false : npcDialogComponent.get(activeNPC).visible } diff --git a/src/ui.tsx b/src/ui.tsx index f080d5e..927896e 100644 --- a/src/ui.tsx +++ b/src/ui.tsx @@ -14,6 +14,7 @@ import { getButtonText, getbuttonSize, getFontSize, + getButtonFontSize, getImage, getImageAtlasMapping, getLeftClickTheme, @@ -288,7 +289,7 @@ export const NpcUtilsUi = () => { width: 'auto', alignSelf: 'flex-start', alignItems: 'flex-start', - justifyContent: 'center', + justifyContent: 'flex-start', flexDirection: 'row', position: getTextPosition(), display: 'flex', @@ -373,7 +374,7 @@ export const NpcUtilsUi = () => { padding: { right: getScaledSize(5) }, margin: { left: getScaledSize(30) } }} - uiText={{ value: getButtonText(0), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} + uiText={{ value: getButtonText(0), fontSize: getScaledFontSize(getButtonFontSize(0)), textAlign: 'middle-left' }} /> { padding: { right: getScaledSize(5) }, margin: { left: getScaledSize(30) } }} - uiText={{ value: getButtonText(1), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} + uiText={{ value: getButtonText(1), fontSize: getScaledFontSize(getButtonFontSize(1)), textAlign: 'middle-left' }} /> { maxWidth: getScaledSize(252), overflow: 'hidden', }} - uiText={{ value: getButtonText(2), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} + uiText={{ value: getButtonText(2), fontSize: getScaledFontSize(getButtonFontSize(2)), textAlign: 'middle-left' }} /> { maxWidth: getScaledSize(252), overflow: 'hidden', }} - uiText={{ value: getButtonText(3), fontSize: getScaledFontSize(16), textAlign: 'middle-left' }} + uiText={{ value: getButtonText(3), fontSize: getScaledFontSize(getButtonFontSize(3)), textAlign: 'middle-left' }} /> Date: Tue, 30 Jan 2024 21:50:52 +0200 Subject: [PATCH 21/21] ButtonFontSize = 0 --- src/dialog.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dialog.ts b/src/dialog.ts index 9e23e92..fe071ca 100644 --- a/src/dialog.ts +++ b/src/dialog.ts @@ -205,7 +205,7 @@ export function getFontSize(){ } export function getButtonFontSize(button:number){ - let ButtonFontSize: number = 54 + let ButtonFontSize: number = 0 if (activeNPC != 0 && npcDialogComponent.has(activeNPC)) { let dialogData = npcDialogComponent.get(activeNPC); if (dialogData.isQuestion && dialogData.buttons > button) {