From a30d535e9dca7a2c613105305a480f70f710d382 Mon Sep 17 00:00:00 2001 From: HackDev <80620538+Hackx2@users.noreply.github.com> Date: Tue, 26 Nov 2024 21:05:10 +0000 Subject: [PATCH] fixes and other stuff > winished watermark, "BETA(DO NOT LEAK) " > moved Soundtray to games which use BASE_GAME_FILES. --- Project.xml | 14 +- README.md | 2 +- .../shared/images/soundtray/bars_1.png | Bin .../shared/images/soundtray/bars_10.png | Bin .../shared/images/soundtray/bars_2.png | Bin .../shared/images/soundtray/bars_3.png | Bin .../shared/images/soundtray/bars_4.png | Bin .../shared/images/soundtray/bars_5.png | Bin .../shared/images/soundtray/bars_6.png | Bin .../shared/images/soundtray/bars_7.png | Bin .../shared/images/soundtray/bars_8.png | Bin .../shared/images/soundtray/bars_9.png | Bin .../shared/images/soundtray/volumebox.png | Bin assets/shared/data/introText.txt | 2 + assets/shared/images/psych.png | Bin 0 -> 55787 bytes source/_exclude/README.md | 3 - .../backend/native/NativeAudioSource.hx | 592 ------------------ .../game/objects => flixel}/FlxRGBSprite.hx | 4 +- source/funkin/backend/funkinLua/HScript.hx | 2 + .../funkinLua/functions/ExtraFunctions.hx | 34 +- .../backend/system/ui/FunkinSoundTray.hx | 3 +- source/funkin/backend/utils/ClientPrefs.hx | 2 + source/funkin/backend/utils/native/OsAPI.hx | 23 + source/funkin/game/FPS.hx | 6 +- source/funkin/game/Init.hx | 89 ++- source/funkin/game/Main.hx | 36 +- .../game/options/GameplaySettingsSubState.hx | 2 + source/funkin/game/states/LoadingState.hx | 67 +- source/funkin/game/states/PlayState.hx | 2 +- source/funkin/game/states/TitleState.hx | 2 +- .../game/states/VeryFuniState.hx} | 2 +- source/funkin/import.hx | 1 + 32 files changed, 154 insertions(+), 734 deletions(-) rename assets/{ => BASE_GAME}/shared/images/soundtray/bars_1.png (100%) rename assets/{ => BASE_GAME}/shared/images/soundtray/bars_10.png (100%) rename assets/{ => BASE_GAME}/shared/images/soundtray/bars_2.png (100%) rename assets/{ => BASE_GAME}/shared/images/soundtray/bars_3.png (100%) rename assets/{ => BASE_GAME}/shared/images/soundtray/bars_4.png (100%) rename assets/{ => BASE_GAME}/shared/images/soundtray/bars_5.png (100%) rename assets/{ => BASE_GAME}/shared/images/soundtray/bars_6.png (100%) rename assets/{ => BASE_GAME}/shared/images/soundtray/bars_7.png (100%) rename assets/{ => BASE_GAME}/shared/images/soundtray/bars_8.png (100%) rename assets/{ => BASE_GAME}/shared/images/soundtray/bars_9.png (100%) rename assets/{ => BASE_GAME}/shared/images/soundtray/volumebox.png (100%) create mode 100644 assets/shared/images/psych.png delete mode 100644 source/_exclude/README.md delete mode 100644 source/_exclude/lime/_internal/backend/native/NativeAudioSource.hx rename source/{funkin/game/objects => flixel}/FlxRGBSprite.hx (86%) create mode 100644 source/funkin/backend/utils/native/OsAPI.hx rename source/{_exclude/AnimatedImageState.hx => funkin/game/states/VeryFuniState.hx} (96%) diff --git a/Project.xml b/Project.xml index 14087906..06046aec 100644 --- a/Project.xml +++ b/Project.xml @@ -21,11 +21,21 @@ - + + + + + + + + @@ -118,7 +128,7 @@ - + diff --git a/README.md b/README.md index 770aa2dc..8696e86c 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Could not parse frame number of: `haxelib install flixel 5.6.1`

Credits:

-**[Hackx2](https://twitter.com/AnimatesHack)** - Main **Programmer** +**[Orbl](https://twitter.com/YourFriendOrbl)** - Main **Programmer** --- diff --git a/assets/shared/images/soundtray/bars_1.png b/assets/BASE_GAME/shared/images/soundtray/bars_1.png similarity index 100% rename from assets/shared/images/soundtray/bars_1.png rename to assets/BASE_GAME/shared/images/soundtray/bars_1.png diff --git a/assets/shared/images/soundtray/bars_10.png b/assets/BASE_GAME/shared/images/soundtray/bars_10.png similarity index 100% rename from assets/shared/images/soundtray/bars_10.png rename to assets/BASE_GAME/shared/images/soundtray/bars_10.png diff --git a/assets/shared/images/soundtray/bars_2.png b/assets/BASE_GAME/shared/images/soundtray/bars_2.png similarity index 100% rename from assets/shared/images/soundtray/bars_2.png rename to assets/BASE_GAME/shared/images/soundtray/bars_2.png diff --git a/assets/shared/images/soundtray/bars_3.png b/assets/BASE_GAME/shared/images/soundtray/bars_3.png similarity index 100% rename from assets/shared/images/soundtray/bars_3.png rename to assets/BASE_GAME/shared/images/soundtray/bars_3.png diff --git a/assets/shared/images/soundtray/bars_4.png b/assets/BASE_GAME/shared/images/soundtray/bars_4.png similarity index 100% rename from assets/shared/images/soundtray/bars_4.png rename to assets/BASE_GAME/shared/images/soundtray/bars_4.png diff --git a/assets/shared/images/soundtray/bars_5.png b/assets/BASE_GAME/shared/images/soundtray/bars_5.png similarity index 100% rename from assets/shared/images/soundtray/bars_5.png rename to assets/BASE_GAME/shared/images/soundtray/bars_5.png diff --git a/assets/shared/images/soundtray/bars_6.png b/assets/BASE_GAME/shared/images/soundtray/bars_6.png similarity index 100% rename from assets/shared/images/soundtray/bars_6.png rename to assets/BASE_GAME/shared/images/soundtray/bars_6.png diff --git a/assets/shared/images/soundtray/bars_7.png b/assets/BASE_GAME/shared/images/soundtray/bars_7.png similarity index 100% rename from assets/shared/images/soundtray/bars_7.png rename to assets/BASE_GAME/shared/images/soundtray/bars_7.png diff --git a/assets/shared/images/soundtray/bars_8.png b/assets/BASE_GAME/shared/images/soundtray/bars_8.png similarity index 100% rename from assets/shared/images/soundtray/bars_8.png rename to assets/BASE_GAME/shared/images/soundtray/bars_8.png diff --git a/assets/shared/images/soundtray/bars_9.png b/assets/BASE_GAME/shared/images/soundtray/bars_9.png similarity index 100% rename from assets/shared/images/soundtray/bars_9.png rename to assets/BASE_GAME/shared/images/soundtray/bars_9.png diff --git a/assets/shared/images/soundtray/volumebox.png b/assets/BASE_GAME/shared/images/soundtray/volumebox.png similarity index 100% rename from assets/shared/images/soundtray/volumebox.png rename to assets/BASE_GAME/shared/images/soundtray/volumebox.png diff --git a/assets/shared/data/introText.txt b/assets/shared/data/introText.txt index ba19c6d8..f6dc0595 100644 --- a/assets/shared/data/introText.txt +++ b/assets/shared/data/introText.txt @@ -7,6 +7,7 @@ dope ass game--playstation magazine in loving memory of--henryeyes dancin--forever funkin--forever +erm--erm ritz dx--rest in peace lol rate five--pls no blam rhythm gaming--ultimate @@ -51,6 +52,7 @@ what you know about--rolling down in the deep oh god i'm white--and i'm on twitter i gotta--bucket of chicken dream stans--literally scare me +go play--indigo rebooted! weeg mod--check it out what da dog--doin go mango go--go mango go diff --git a/assets/shared/images/psych.png b/assets/shared/images/psych.png new file mode 100644 index 0000000000000000000000000000000000000000..1a5019fa22c69cf62e9d3f9388fc9165bb64c66c GIT binary patch literal 55787 zcmX6^Wmr^Q7iH*fq`MUyLO>d%TRN03k?t;OX#q*;c98BEq&p;~ySoM$;=8`zk9qFH zFf-?#eRiz9*1l2iRpoFnDKHTb5O5Uar8N)`KyJV*4ILGDM`N439JpXO$?Ll!AYc*x zdx8Ee2Rs08(wWO^s30KtFe4xYg&-i@Jpe;Bs*}ZK4x5iSh zN_?J{Lyvz89Bx_gz6ylIW6>FoM#e>l)xgpD4M8egyJ|i3L%^TI6POWH_u6Qt-F=sy zR}gJ5ZM+V46VZ-Go-V-a$V0{ylD->AkgC8#W|3w3!+qB1`I@wk>~(p-#flm;UEsr0 zyvyt6e}DAGuRbT<74IU@tRV&a-b&zN|NE!L(955YnqLZ0(TG<$Z7@x|wf@s*dCrAQ z57G>wD$F(I%Wbi}g3BrHty{>)0LQtvxq&%ze%6`po zO&sr`F(|gIL>_WQh{$O&CEAGgz<)+^*6izt?st^t$3B>>t)pMbFJ&yj1;u&L4SIg< zv@58_H-5W>K+ffH^l(mW{!BRUtQ>$xmJ-wc@Ag2CX1^a;&Kwb+H^>8*l>IrF(#gmW zB07H|UE@_{z#EVrX*?wPUg1>&pZ$q^bqDgHycGy~zM(Q26G1s4$~_HwO!W0TKzQOk zdiVM3%#u?3zn^V6yD**+*m+^~ypq*PCDGJBvDc1)GE#^CB z*&WwPs8_q7hbf5v90<+`seCj)`f|XnV>`}veFJRJw$A_^XBjl#CJ8w;(gaTMkN?%% znZ-=K{!vfCnMHBun8!r;gA(ktN#xBi;1ITh6X3{eFw(Oy6vA}L zeYSg29bYd;1KQ+q`L|J@ZG=Zl#Kz+6LnLwJC*96d&WXjeCpeZ#j?;l-U`#C4E%t2~ z95yf7nBb%V<4qzw`nP~?cAoJ2O4C|{r`^s|@LrB!MWZcXMt=zQRIm5n<$m-2J#kOS z6M9KIQu*{M@D1cEUGnL}dAeWEqGx@4{**(aglK1Y)zM{vQHB=Fy*|sH|GZfd`p+ss zPeY*Q=S^5(vM`zo)-Ajf>aManR>!GvZoy-b2)^W9Q=|6HF|o{0*!Kkggb+?t3a4S2 zpk$h63&q1x&ngj~@A(33)pmzV*-chm*PcjbMK533r5@1hd{bcOOtehVM!e@kxpow; z@_hhSDg5~2p0e|q?AEc3!ST`t>U)InK;WT%%?lB^#J7!Fa$l4-zdTTK`u|cWxvQNm zAD;-Eu7Iyv{0mH^wYi{Yoak10pB0}4!aH;?T1v??0v+2^Gg3{tX#UW`|GTq((1~gP zuy)oJmq)G<(i6+ssY!%U+vjV@{Ax84j2gnbGrqLRYxf|5Sy;4Uq@&NA3+5@6>oi0& zFf1t{jV=tNyftn*jn?&|CB-U3u{{+w2@IWCgm%h41sru4akPB@ru@%#9SNN)&Kz$4 z?yiu!RG z@fwr=!?rQX)3z?vL=MVX7)R3EosKZ~{s)W_8dxIIjdNM!|38m>(3|izDQyMFIaByQ z>z`q7sl(5O5a6{JmS5*r-#I>G-wJw|-bwZE@mb1!{_n;lI#0~`%tWv68iSrO&W!zI zB_8!-mYpbgC;Daa{etU71ENx_1ETCrhS-?X|78Gw_4#|^QnXH3&@=Pd_(!f%aoYm$ z0*Zyfw{+F82Xx!u2jZW#j;-asts zJ)ZiOwFspKQlltgjQqaRoHO=W&d#s%5OZ(b>`;cp$2SqX`556*x0BYCGW|yJ{r?Y} zVgluT@6hXK+cg!mhD+on8$m`_S`>Vc3kbB*wkE2)+f3>M-#ytR#ocOTH{|)xvq%tq zNp4?tLO~Bg9?45>5*|Jv9#m9~ug+xN0ojMeI>n!3&SM3e6Gq@)cpQTQeYoo<7R7rP zXvKRC7+}@(W{=<6|1)ta&H({Gd^-?x$un0B??z-fI|nJAvf^w{SX>Y8@cj1tzFj&F zwM>5VBb#ODEUJ0TW8Tzq{XhoX?eY&o>!*A6S;V{eYL9_zcmTQJ`+xpqOi>E&^qnu0 z3+z{5xI~z;G4#yt|!gKclKnvTDpmf*AB z_8@bm0`Cf0(_(nOy=5JLqexzmY&Eaue#*6T%f-K`ZuLhRqaqfWabzRtv6dn=`=(L6 zs}GyXRY=ycYu|1L%ytd?uM{9k7$OJ+KZE!y&MVm8i{k}lTR?6*l2bCqD_S`_u9xGy zcH41Hd!^8WnRifADDT_n-C%ugp8Zs`eJ!3@X{KO;BxjaCT39Kzb==WR<04o~GsKa* znmO^sOc^k5o{Pq4Y6A_$H~*dAM+qQvLqle!S2w29c}NWn(IpE=TwoRa&`Y$&-o8=P zl&^vJ2dK%jTV*Wce4FZhzfaPR<&bU~!l`I`twcsJqfjewGO#b3;T3_Szpu>0S>=+&u`Km? z;LY%>A_bPO=WLcdL;KXdN2hV~tK^f*l)OhJEGoo9oDd_%$99wRFk7qmsX-;i=H!MJdO>#5j(0@Kf*Ara0PzHINH-Q4bJ_!fB4Tzuv~KE^mD}b=Nbjq;I$0tl~yB z@BAc1`0Bo&yFY^aaWk~wq=$+|d5^j`29;d_q9>uSBNOAlP$|A%r*zHB+V6MN8Gtqa zbPg96dL2JeV>EX$tiq*9-MkpMDY0ZiL`gZ)&Fern{HDEN-tT@ruXNh)rFM?hE9rqs zXdONxJpy~_EQ+a?b+ab(IA4L}%NtKQD!uj}E9!RPkI92?YuA3gk)_?g6j#W;BNg(#~6E-{zO$^Bq-K{D5U7T80p%304%F0Y2Dt} z*s(|;{_s;k-=IuHSM9lvlsDWWpX`bVwY@OG0yr+`CUNfW0L5=xZ0`Au#-x?L)oBJn z@CNha98=NL96_6%pR~~Df+msA!!JSYkX=xV8(}9ZfGv1UZ`eM>1huMDH+ zj-D@RtJgi*VZvPz(tWTmc6Bv$8$%ti9CK+7*Yz{@85k6Zv&Y36-?FRp`8tU9!AZ(* z7tMC5X_*eay}1Le0$U-AH+`#TGi#mB)YEq0#2o9aTT+p5w{$6Yl!$*o1`Wo*TXNP2 zRK90S+mMGaq&rU5MYbd9pBGzf0Kk}|ns!7AB)x^lRnNV}xfbfr?()js+F35XeR6a- z`(gZ{=x^NE=pSR`2>oKfv#H!GP-+6HY8yp2ZYK=rHWeJQYb1Beb;(FQAG3q@&)=YHnD6 zUCkzT2*>+ZdQ44Hc+qA-+LN=HPXzZSgColvnZ4*a*1&uY^B`OQQhydd*niLlSi@Q79^(Sm5@2aJw*v9*?U-!B}DEKiuw?oWcJ{Sm?F+}1 ztC}&S146xSeyYdl`Sqz+BYFGsilzp`1gC9{F9XiHarhkt&XK%}P6d=m9yhn7YRC{Huz%%9J>lrxmG#1IoI*9GVzB%beSlFTJ)7sZ!@%8t-jNW`D zVD9aCzwzKen_v;)G~Z4_{>i%ShJF57(S{Qm&!E@IWDtu}6w`pncR+0F91CZ`w=?4W!wZQIym=_lEgWp99{!Iotl?+RCdwS4>+` zzg;vN2%MNF=dP!d$di+_0I;dZi1K%KEr&WC+1=(@?_Xg<^;~`Oo_a$l->i$TZ@QQ@ z<#_=ACRP1*Hys=>l(cS!QDP1=S|l2;cDj6Heo}WTH%}7>jW}+4>JfDi#E0%mv_{!4 zDN#wmst4VL;vGtSrP32v9{0%#-&oE< zJl~f*>GOX=>Yt@;_1EILs@dt9M)BBwgl^G@_q<-qisr*)*E`Vy07l$x#VU00-pc%Z zc}-0_Lk|iEDt|~jLH}}EcD>9C!dUg@6zk%+xx-v2X}8cl?)$G3RmMU=;%=nDzui4Y z+!kQ3I&oN2h(|xX#XoHlo)Xr>aM^opXAXP#pt%Ykn>K`a_l0SR)yEpUiG1=5erybW z#=nhrIF-~u^wGaWyvDzMakkoXaNy|DA)^rzq}aQ=v;6&bS-feKa@9bH`h%xRc_iI{ zt4j7?cID-EZr?>ITo~(BoH;MWJc!1|K>8^=2+q){${%hIa*Dh&u&6r1(1W!LBoLj|7$&JtQ)Pc9vb@i{T<$nbf8`%pH~0wiJQr z5351XYK<_HN+51`Fb+7^+6s8>zS!l7=XgNBQ#Xp^K>$zf3`BT9 z1CpAWv85k7-_>v>_pGctrSSD0%kB|_wgE4VmB>^1_=44s?U|u^RJZY@=}h`-t51x9 z=Dqh;A=%Uuzt2rMaPj)6sFg>Y62!=!~#&fZh^k2O|}DnVULZne*E z0gwCP^xMa`#9!R0e*@Da&vW%Lw%2SEhc#@;Wffl39sf?zoARf(V++i8*sv4xxQ$Fp z!w>TDPX{}dq8#p$@%~Hl`xyl=G@hFOQJ|V)vl)N>vapN~@thLcI9TM7UDiAG72G_rkIG8`hoyEMf?i6=N@Hx_Z{CMrL%i&FW zi*vN$kU1rii8^cOG6%Zmnbjd{J>AvRP@EElrY#f+8baF2Sul=IJf6sI1%d;YjzztS zF3*(01Nc&e`EO{=+^;BRxw(1IKG{dIHUmk%=F*D|z;Qmje%t(6tjwbx(nT+vE>)A5 z#srsgsv1Sj9IXeOVN7phIHsm9H7ggGFIBYPOmj4Ensx^ttpe>0R{JBVxc6y^f3|6` z+X*4w`|%;J{kl`I;CodnEWD*38^+yzT5ancvz~bSWN^$9oy9L+ORoLS^aUcEsT^IL zX4L_SruK1_eks_G2YNoe!FSMb>NozWmwORi;hq)0=Dbb?W_w|Qwjndu3-zvTS$8or z;e$-pTMX#3-N}#C!cy0z!lrNKRVWtQJcpNZCKgF?=5t7Bz6)7(92TaHza34x643ul%B+n!tleK_&+R(p;Z;*&YrjsR6O7cVFlseGNTs8xVJ z#E9X$&P!by45#%N=>_DWu0Y2+Q~%oE>rZI~4kNj#kqmJrTNg{0A2Z9e24u`mrl7tC zj$kr);}53VFhhw)I^MfY=D?zWWLkS!1_ND&(^myz9vV`n7#uW*C)aUHFvk84$G2SI z7aWh)4~82QW)YpAua)$Eh#%CQ#v5-V_W|5VgKXzB>1~Iv))?p|B3*2XpjeFHJmr*r zMDc;ctk*V;MD6^ZVH*u06#E`PMh=h~2?eG6U|>p2mK z)nodR-ex97-V1b%zTvgeru*D~r~W-{OWmO+z^djue@j%#B}E*UJZrNB?h+O%jmTyf zgV9D;?Z9G1XH#)fWB}f+cZvV=n)Y=;>bKz;B`}{|!DJw{@bSPV)ruQ^s7sk!{rd2*AanRcP9hSzUoahA~_L1AAvrYs9# zbt#N+DGk56*u0`!9B=s>EI!MaPRY!t__?6HEN3R`wa!-*|H{j6hCcIQE5-=V;%nju zH#C0QKt*_+ZwBdu@$+BQuHQtbZzJ>e0r)Box6f)qEp&+Tw!>??{)+VDT4cGH`b^1R z9uD{Ny6+4QEB4%b%p0Y`d9Bvl>89e`=RG)mvsUV)nmKxI$?r1crIC4Ztq$tiEvq*? z^Hr-Tt}keiW=N4{N^)RirJyo}PCD#9-n6;(QhZe(%w?3LYTF!y_EamxcQJKQA(&Q1%sgtUE;o{&>=MctCmb9{`oW7a3dN4L19Gbj5*GycAZN ziBL7{13fo*0T)^Fpn^)DbgbZ5{N4^4m6ajtXNi1s79Zu$8p+;8tVb&SNHNtaAD(gf zs}6^C)s?{H_hwp?`mkL+|2iL*794g8N!Ji=XG5cst%nwa-PFD1YW0hVCe6o-6{s!WtXu^Vv2ZIs)2;Qe?e}Axa$ZS=!`uR1-k)FsNOk2V5@^v|e9ckYL%qHU zJI$r_!WtOy<>@id&)QHEArm)?OW2OQT1Y+zY2A?FfQEi~oI#a1=Vwm3#cX#Z~4U=(86K2mOE&Z%cD z3jHl{O}^s~9Eb6>g8P@9p-9NxJxkUd1EXN9PzUVgrcqfQ`28c0Qh>n4&+NH1>}Rs_ zXhqK3T0X6~SPVS=KHoOQ6w~IyIId@)Pj2hzJ8&{PffDvN(m3@rK*-F|xr9sf(m|C{ z#Y&^kM;R=>L$_!RUbIYrDJU!F6KN#n$BI2y`ks4mYo^i_p5dcoQ`jdvM>m=Et)?T< zB8j6sH6~N|=%>ENyw$X0dtMaT#}T`X%Gh1li8+ncKhRQ?5SLR>oA?y=CgWAx-58I8 z9dkuQ4$S-ZjvK8NU|z1W#*4VFyHq13edcE0{Ur)HV8MuK1;fWk!E z3yiT3x)oJje$5M%44eYfA!pBbJcIUM<@9%Fz*%oLC-p1U9YdG=TSu#M{w&khHu6~n zT1!8_B{*l=C5QO`UWvQSIAW5PFqD5s{^!EL4q0IDr0<37=m``CM_T{qXTtw_W~y#$P=j(2+YN zJYbHXgm7ZGrRg4EO?duQLA1`Cw}acKZ{O#zzv@OvQXhLd830HZY1`&^MFuAq%?Np! z`xG)_72A=1hS5L*rp&~N!!wsf8lFx0^T|?vBTEvzzUS2Cl<=(xv%oYFvZncwoE@@4 z^Yxvhv1vXl_Dn*oQ&KfWVmfvR_d+RA^p-px`IdhYr6oS1F>)Vi;+eDwcDSLWujL>;$<1TOCy>`m?HjDG0tx7R#Sv25pdM(S8S}a&hMNqB)fq8}`{r_;F0WO< zYPWi3)mM(YyF)2VIptWxP?^P1_1XEeBgfN}Y+`1XUO&~Y9F+z9sJNAdulYLfG5m-*`DS$ywR2j#|c1Lr=_JM_z8y2B&W za5if`5g$F?dS^l|vHyGh#r1Vk5k+O<(Rea`BqY-r3Q60{fT}8Af>1W+Nz2wW$aj7Pam!+4UPuO zrk|{}ul{AiCqMQxBn7Q=^mp;HueN{=ut4&i=eSjiC#)YE&RUj$RRKlnN<^X$@>OpIh+laRp5>aK=<>aF@U0Yk2v{29KzC&86-f@)g`PoKZoR2Luj%G&T0scL zqfyu7?=9)??49icuEx`iD0GSP+@j3F{d5!PE}My13ULwda$}_hodm!^9%{E*ZK!#W z{iqXm^JxxOB&G&aM+j`Uh3hoa0J8p;9Lj?6&xRa!(Y;htxK)2`R-u!}qVwzk z4L4ja=8<;AKWn6&a~)R4T^MCHp+t5?nEy2bTS@JnA>|7BPpyV>(Sc?K+EUYuh;u){ zz0_Pgbw1rp)Z9qtxs1AV^F2Gczm8&0_E5I{Gpb-Ha?)X_N`07{}bb=TX@tcT(R?>vH z`8^wiIEgY!sQNu>aL@3YudcEP9Hy*qmiOvT1JMgBHTr?#8f}tN%-S(ad11=s56|Jf=f#mynx=Us93WBPM3^=j5 zc!~vLa*_p8^VwOUq%Y2&GZtAq@=`{g9|@URSq~6rKb^9{&Y~@QIGQeZG;jH@I z#x%ye!aBA?QG4%rv6AwDqPKY<1@={&KTJI0;`;rs3xq3R9l^d zK&4Wl+jjCSW4ax+b)P>%KXtwb%=nv_V;O1hh9<_S$UG1E3gva`am_AM>bal;7D^vk zitRThR%a=S2f&qd9;SzB-ORD*-akLKoFO|@pf#H! zYiB)CHO|g!Oz1)?;>Md z3lPT1=WN1*Nt1I3ODJC?kmcDEJER!~l@;@e2$MwOi=x@zF;yp02vpzn{wt_&zW;ij z@q8LrAN@HjFZ+&17@ai0%@@(Oyxs-gaRFH-lGe^CJ(#ki{4S&|bjathY|Beg2)OP% zz*<%bu#*Lu=>aYUT67X+Z1!GUeeqj@sA1pyf{k8q6%_!vjM;qi4%^iy`j~ zuq=L&$5TKY`QI+ly1J1~xn{sWrESc9__)<+mfuSJOeM;0b#WKT4!Sk&Fb$4cw?{+__X3myK;rwmIt2~kDJg0 z@Fmhd#lsC-oTGO^*rFNPg&ODjt?H~%uJ`>IfOT04X+fO4Xu#Pi;9{@3)j zYS>`mXlag%8(A&ft8@K#=p-F;l>Jr^e{PE5d(lxBs9Q2Pp9Vu(LPjUj;z~o{=X^24 z`bn~_1VF#j>yf@LPm&E|M?Fyi!B(A=;q(5-t@ELc<-S@=Flh9sjXnwk41KwuXd-(r zs)`Y+5mPp1C-4UKLb=tU3phU?OzLQMWs)3bq`Pn{|K#dwee1XKY8feCK{T7DeE?MS z4BWV|biq17sWQgxpp=-mVxl#^UA_7k!bgf-<%%Yj_mS9tTXM16!$y@Cv_5~y3E8&U z+xqq;xRF}onc{4&S}I!;CPaevXJr}*=Gs?{EI2Au3=*B>mJ)Shgw}2E@%FiwE@kyp zf7hOkZmOh}&p1wyou;`uP=LR+*gM7K^bR}dY{IaNKE&5_F4Nxh3g{4}2 z`QJdQq>G~%hB<1X=(7%7Y)QP6Kxp@gy%kg`%A)J92~L$dvk*z5g!ZSA3JZ$%fbcU| zHwW>4z;GtIT)En5-{^x#1i?r|ST2`r&Y^ZaD8*LGAyZxi`j5!$+$ze|xGbCY6FT&$ zu$pkJYUJ*M_kwKlBR7|5f?Tb3(+BriuZr>Fq3FFOwEQn(ozX^i7p@#6h(` z+B38^%(|n|79Q+v@J`j9eNbW_br#sUjE|r9eq-`Re%HH=yvkMyX~tS$*_3tBEDdIC zrS7)i_TE|g#FOfUA39Y^kQnX6>nrPR8Z*p~KlM0UQ3`=A_v_)b>e=~G-Wsmupam=k z*Y|mZa5n#RUZd&t{nfnN7HJtx8gx@+OQPe#y(>mi*YGV`qiCuKf<;H$HzBO*bt@A; zE+&%SD!`&L{c-vA5S#4h0iX{g9kedaq{h#@h1AO0p8Q&NYI&`Lc%QZPOBH5&)3h&DLkOF_G?O9)GAWWgf^s3^EcN-a>X|Cr8^)#2i4+ zS1pduN=RxPT1b)kju=V_<8l*jof?&KG2gGJ~%Njf)Fe02i;UQIZjyTIA_DL2;XJ9Y)o!{5saiMd)k2$VICVRWq`wN!NX@rx*8RkW08%}{E5zx15 z=c)cbGsj6rP$(oZV`8m|)p3KrDD*^cPg?(g$;^Fd(inlE%3OZE#RnrSa1Xh z14k_dTL{C}m`Bv5LVE55oi|qfND1s+zDIAAoS7z>-c(S7*>Vu3HMf0nj;P_zvJI|> z)D$~ByggC9z3P_gc(_X2?4A$zPQRnRqmZ-`(LnU8WL*4B?VNU8E{&JMtvD8h(|aiu zVZLI!?c(e}D0*FdsQPq^)c*@xTN4RNzmdL=RahonN zKt5=b_tK4O-OdR1xTeN^{H|dljB{dtg+vvph(h9z&FZQr<;I83)vkk8Y8b_8zv}#7 zCvgFLj5jCVQHyC)e_5DS{BZML$TNmni>wb{GI1_2&Ku&Ymip*h{)kVvF5B6JwLTnx z@%BzsKAtW5{r*U=5UcjtkB4rONK~i)r4CZvS4d&SJtr{IeyI7l111HT6LzDt860F;=jC?+ZOo8+bp9;PjI<6^6FDaa z@XHS8u6>~9bX&ufjMIry4nBVY68*2(r3;Y;U0KqP$6`_ag2n+pBi6JuHI1T73Kz|X zJD3V)euRiFB3zi3JQ||kniUvA*iZJX+sq#+l%O3!Cl<*hYXViXzw^u|R{IYYZL=28 zUUfQx;;VGJ7WKd-eg_Qef!(NnKgQm5M`>vcud|) zYJ&F7<*zH>IH8RG>zS?^Zj?<-l0%26bXlLCzigE9GFKU^_aJPJ&R~CPKT}y>dUt$%_!r#3Qxas;Y)n{z} z8@_H_mX6q&_7bTQCLICjrWoE(_kA-q6}~K841SlqhhNTR0jUrpQ z7X!YzyPbyUZz2$9py97@*p{MK>Q`iTmvf7n)4%(X$@8GrIh@IQ>H-0r6R-DXcO*xc zmT#AG&i2tF{O$$`fbkBoe%X36f;R#*+`&_$YMynhhzynVuWFb@CbgRt9$dMu5~j!t zt^wIwcSNwsBWUGVbO6xX1ZN}udR{25e~ijDTb1$f#Ml~7Q0z(i3xdhQyo81*Hpmhc9p2U~iCH;O^!${#F(;n2B-cOiVJ4EjYi9|p<2pYH2 zHLrgfDcv(nH!Gx{$O1QV5{&)w-m zCFls`&HXnh@N&Xexrcw-|Gk<67#fDZ5|qs0<6_()cQFcyv0CMF5S%yDnyXD-Z$)`nN*eyHB)7?K`jo;KNH@2T zQ2bRb(0!l;Dpcs1oO^M%KvYrC%h<>2&NDo*a%e>5ZI)N;<*Pw0~M?qtxL!Cmwn56~Ol zZ^Su0$fdhptc7RjGGX$wmTZUb0ECeyk{0ZxN^40-W@rs=5qD2fTq+>TWHAPtG$J?% z4z|Bz>JD)~=M1X(;u=;gY?&^v_f0KohXJ z6Npr0O~m^7?4PuJ{r7~3JHpq1ogQ7J>#H0-M^*RkYsiZ*hB?-$qtn~m+vaaq zYQl6ZmW{tBLa>abS!Rf)#yu0f0Hoy35bM=NiuwsnU_zE?h$0v=vg;C3?a}QDO-L~i zVXs8ni%Kngfmmpr9yxXdm1+LNo2t>g6Rj3^dq#?8CwlZD=Pt{a%#O5FO<5uw7HjfL zeT#*0hA3q(akkV1m5Y=WGmg&}Vm?YI`pX8nvrhFFRRU>4@8NhefdO4?RsK)zJ`*kt z^x&RuBKmCfGZ}fN!O+qA5hMy+Yfu==Fe!z4mreRJAUF0VZJCg>S~da4F8?s15;0dT zNXqU*hryE6k&Li1S@6U=dB#MB1Z|>0io7HdGd?B(?rd}*=JIzq)kT0*@qSv`%4|{v zY5`Ew;n1(dPec_r9q4E6XMa{3@U33wzAoy#T>i3$i0Hk}3s$Y&=(=Q(c=4_&hh%RF z-;+d^{2{!s_hxvVVbT6vhK*V(g+mDbJs);oT)o2+Pe*NXjx1n(|y;0ofN>%amA z0hUFImRd|Ub;H+OV00IlCQ<+>(6VfZgggba+sCn+b=>G#?1bC|cxRqBq`b(tg$=fnQ| zS-8C*jN}G}8sj^TE}zD4-ipNx^6~}RGL(q9x`*#L2lo(xNGcVW4$T;RWGVSg^si4LN-ang;2dV*nVh-pa@ z%p?$1>ig=#YP)s1jRgFSZ#^2{SXSO|>P+}udW?h?y5;g~$PW&Qg;lZvbmQ6}v3qrT_3V1^XNtU6J`aS|o2ImQq z7(3t(Hu+w+-lxbTwOXUv{NNXo=0ph;wElgUD(J%#6-*2G8eU`Sc4Lat(Km@^YrQ-= za?tPFYTWC|Qz(;JQ>Fx|JzZFi5pMu53S(u;X3JtiwU@n1L_oJxk*<+tqRii^FY{KC zU+328&u92hL)0Ou-H@;mmFA`n`))Y27R{sl0=(M8b9L#tjseOBV@TnRf5^i6&aGBa z-Cjs&@DMXbfAX>~o@c`$&O?;N+lrWs3>9tx{vGnhDJZke@g2A*j?X)IN=Hj zc*3W=c;cTOV%({H4i)@;G*$WIiM4QeJ6wKNW%)3z9Obk6wLv~Z<`xS<_X9%g3+=!E zHsz!AUHt>NaX{sZ1pZ*(lu1XGi9i2fZx%d7#28=O??L7wH*<YJNv(VKs9sS1BeY!x~-5iX&ae-X&N81U-K zo?V21%#x=f_QKA(s3%~Yr~_SQ#@0Lr=ZhZh>A?2d3n2Le8DBytlvr%R!mX>7%=}Cy zh?NnMK+HKdvb6o%6gZTN*D1}K*KIX5l*Exf<16N@ZrwQ+d+`fN=$&;eh=fu$o~KWk z{O{ghPwvlVWa497N-o=9R)c@k+_Mn!geKT4g*CqUH4_rWs#ju$F{uXngd80A1@%(s9yM#~T;C&ORrrSh^yVaAsJ ze3FGIT>;%P<^61SHQSvKo+7Wj^BAuZF;+g!Oh$ZQZ;(TsrQtY$Q$vCB(B@ct&|j@PdgE>9GN) zFM|(rpb@=Fjl^g76A>wK$I4awH0@en^SqGAYEL%hh$W`|)S%oefWIl8FrCPn8=+?M|kZX&v$9F`W z-+F?nE!^)w+&oBD_G^C^ZdDkkY_*Yeb5}D~69Tb3Ut*6Qt09x7k=!#Z!)xzUp+{*# zEpcS(A1leeA?}uAKmV;6_nkLCCWCC_G3&{i{XF;`>*Y*zrPOx16(GZ-1y+v(#Xda5 zZHy>Fb@86a?;@R=6WnL27OK@=4CrxtQLeU8D1k$jty>#ysLEMaJRZ3LFG`}*0tD^f zl+k4B;YmZnRVl&xx9NKInv~=A`o#F5-`FlHu}9R795r9`re0=JqU~f%Ze|S{sfvk- zpOwyYt&HJ!y&logmDJg?%`3CkB~;2Fqs`H zyskxTNmJ8IO#Z@kQKt3y$_6gbXEMDnGGVsACDWp?%Re7pTj=o#V?XpD~2ZE4dFVB7Uch^f1gK5sJDPW?23> zep1`S;7zS|O(|EaAo%E$T8iQtqG+$$jNYRZbZ7HkS8OuIv*aksXAD7rJI2#BhG#8I z`qf(4i|LZa)t~QWDZ|^7!D7`W9gVy#2{IE@@yM%|b&*)6yHoJKz9222J9wvj+LVgs z!i%!!E@zQi_2Y8xTiz7V-vKw)A6MpRdK}%DE{ZBaR;Ro9F2Mzu6b6fuT!$9O}!xOEG}K-B1t{-~umkM4kWB9Cu$xf&<{> zKT#9*@@7l-<&$ckTvmhcSUgOx&g)U!bf*HYq^vS4J-^FmU~ukDj04Q>ONYv8+INFt|%%E21^b3 z-1$lvm%4@s65lt=wUcZ7L`%)jqqMhtahSoS=Jw_5Zj4dQlUvAF`{Fwrs(y)QJ87GOC&;hz^MD;{o z=!gx9s>>bynLyCuTyOjdbnP&>^)XF`m7v$AT-m`)l(?EA;lRts#6=(6_Ge5@n} z#JG1GNq{(4J!+l48|L^KboH{6%1+9R?xmJxri6|NePIKsA@5;AHo{{3rEc|M#M@r8 zb5o;x1e`35> zEM86id2WDM!KnBS)?>Xg2Uw`DmHed<{tLURQRS`! zu;y;JcFRk7DFM@6X4gG2mS*Usb|vQ*ztuvkFP93VUGve2Zl2Y)Q5A=X2IGGw_+*;C z{xBkLm&ouYmk@}e!9S!=Z`P?s*G1pq=b0ng-4*tboGz)?$}_-v-K6QM7?;rXCEG6m zONx8Gi_P4BXOX<%ILpsXA>(eiuS*N`>;!GTVzp0jpCGX(FrG|v240Tmiw`zfv>j<+KX7@N4Voi`|Tdry1!cUC0=aV!|S zy~giG;68bs523L_D$7F(;rCV&6E(`qiXWm~<<(dOfe{G+6Gi@zlj_^F`(j ztn9S$sriqqte2L>6bBlBgTE>$&kFcv^DN}taW3@b`vk~Xo1t+~+&cRwkdlWt|5qgxtI zx0CQCz!fo#F) z`zNjVYxg5YPM{xJsmTXQrH>p%zP-s#<3n-#yoe>Kb#3#8 zv1=f+bxA|-wyq}Im76&gI+4HEDRN?v&Mc@^x^=GyQo&VF<6as%>Maet&S=rdkOWr~ zMTm)Q?3wVu=t)o|!!3CD3eA4sV52fJXA|GtW-+@PD4UuiL!4qWVvOqK%=-U$Qs<6m z#GcqFCuB+&`Y>pS671yPHyQ`OM1AMGdyMO@)B0I7x1N|lW<}xTmb|9Pc#s@DWmz_~10pM14k3N+F?WuZzq$)Vpr1Q5O21VY z{<2NNy^s7}|8+xD!=#8!C`uU$+use7arU{Gz#?xCcgrO|-BNCFy;#3)Z=$sHKai#L z1YHwUFjVeb6!v<3s|CQP98|<)cQWDa*sfS%mym&o8By+w=`;HCGa06rHT18HG=1&@ zvNN@^kf#5~(NzXj)pcR%76j?;?(XjH?vzV62nYyBcU>CkmX_}B?(U8YBI$SDZ-#-N zoY`lez1Mnb1q{zPTeut7(B=cwH5>*sv9~pH=^tj>bv_xo;ZT%=2E~QLrz+m;)U15Tu7DuPFNLeu(o;<+(K_ zL}9RW7FpHs{TS(JZL2@BTpW8E=2r-~a>XVyzJ;^C*Fw->s!`ePSaW*}U!>WIILG8y zi4z%^&WjZN>7r1Qz1Tp~8k}=+8)1Zbmv5=Ts zABUOZ1tUR<$pGI*`5{hi}^Mr8mb5Q>`7Jr zUKCOSbdZm|+@Me`zL(r!=!|CwOQ3VC^$E5*#6YSZCx&mK6r5)(P|dY;>5V7^D{}sa zgz2>>`uM56iw&O7VE6c0YzYillFL+N z#c}Ko{twUcbg6a9JO;rx11N+)qEysU@c~TbUv$dvEWpblf(CV3XLDn1e=YI6CJ=Nq zu@K9S`V62%Cy-GDV?a18ShNSd_H5|@NoXU9O`@HTme4PxFzib%5ctt(=rDUD@C$+q z-3If3)ZA+~z3KIt&S9#{JT$RSQ^SWQLEHb6hW*LBU>^o@*yrQr)Ucqkv${4DOW!5| z-f$hcI^Wg83rD7mC*}2Z`lIc1OTn6M@`~vvh@KQsq zdi9I+^lupZ6~}jxuR$hl#=J%}<8fHKLhCK zs{uk(;EC;AJtbm=+gdbE(YF`0H7hDVyP=BoW13Vmo7Z-oDE=^>u2V3 z;UKqxBHg`H%ZLlfma#hgLt>2wSj|*{#(QD5(?xko9Pphf`~66yum171BIoQxMReTL zwFNNoDo$MjNJwCpd5z2Rrp z0<)5=vy>^Lw^CyIOBHyDobjtCb69}JzvFfalM&Pe?tKjfg9LkJ!DjOHs-7!K3E^WW33(^!+D5Tf0{FhLhOSOyGws&Vda-lq4oL&*{Pg(s#8S$_Qxw^ zcK`KYPwzpvLreq`qhY{_Z|xvVG_y&#PL7S+_`v|R+y{FMOGLR=l3)u$Q&H+sQC}zU zr%}C&vaX>DN+l>hC=bAo<7zo2NzHJj9)oXDTUb;bh^#q;X9IvLL!IVZwW?DvIR<|h zU$+-a==`)UgU1p`YYMz+(P+Gq%*w95WEX+%?ng>ZHB6oHZNFI?I34EyEpR*>JJvGI z5)rEa`Z7*}5?l^fIvyxXER)s0zfoX#cIWSPSF8M&t6;q~OhY3lW%BT8qYnm42R@m zYMbxJK;7R_uc4dDn4(gj$=X?4=!d^*voCz+jX8<&-GQh@<$EV&He4ek8p6D+?P%+m zEP2)@oueppq7fsZ^)!W_&$q5`D}+czJwcPy>=ElM>|xjK>+ z!jd|QUunrb^5|)kl(2dn0$k4@?g_k12AbgR3oK8JY1^wNT#6gg1$L3>soLHAUXJCD$sqgC!fZpa>wK+w>`MsoObJ}#QfvZfo@ z;^eEIXj@+mURDFCT!dD9r%7|+*QYo(na+}njgKL5BZ=-e*mCqhz=G3;)317+LG%Mu z+SbcbEE89)j=!~IvYEF!LnrDoJTpK`uNjE%cziFSh<|-FO_E}Msc)) zAqRAmK<8g{v%ufH=P`VOW>!4k)t%rJ=WKQ21eJffr9=oa&UWp`1E2B<$aS+x$N{i6 z_bPCOET6&R;0f|-P1w?pL8xPGM%H2lCcU^MwQ8(4OhM=0J_=3`XWlvu?Tn{XSsg*3 zJkys}UbuSgBs~{p<;3xPeR8D~f(5=++|lQwNDo@!^+rCvYOlv?!2X|*9)FZBOBtO| z$~u=9t-6rEY;bI-r5? z8*%qNhV*`Fr$bL1`2-(>Q3OB1SX7Qe6@j?5+YWOJ;xmP;B9Gd=h(ZLq!q+|N@6T4Ow3|x{5qkRN8X#C(lZ!xnwRAg) zL``byY|YmJic~=Pu$s?c*oXCA)iN*`&YIC`q!s?IpB}2>hqi<>ebG8%wMri9`@h5 z4BbTuq=XAy=B)|@LUYPi(@TcZKD(e8M->uT4v zrtCNbUK2G`0A(HH_ivY8*PR;NfD!~u!7)Qki!9IiQ%@%(H|h^K<2N6DfeN1xfx8D6c_i!58%6L3PmaNpHhjV`3?GVohAgT2 zUHKv%+WAA9p>ggV!4QZO>8eZA!@mZf-skr(V*N2 zlmb@wyCs(VhP$2)kzGzJuyp>7g>b?6aida`_s%xgEaj{&>OqXgkIsH;j*-6Yv#~FE zt0vX-wwzY=Q&p9={$`naB?7Av6{AE;_SC~fPxT(ZfTsv#82{Gf)JDIAEm*PSId#}?Oq>%9TLmmM?{_0HtNB-9%+7DE=t?5V|Oi@BQ5)3mH zKN0d0YJqxr1xYqcF!u&eBWXB`fHN)~-?ar6BF#E2XU||oY3~MV8oYBG6fk2E(-nQF zz-=Bn*VK?>FiDO*A$HRJX13OAa~4Uqf59j*@36(EW_k_y#!~`rtCHlyjZrrT?N9i< zj<%RyR>qYTs=|G%5Gdv&QLP_R1x}d+Te{r&X}5jxfc4Q?{k=+7A@om=V@idn# zCeyUV&6;OW9EmM}{R^TrRt+L}Qh5^Bk#I9>B7AJenxo1)&k$&*utP*ai221SSNr|d zqFq|Ds71<2qnjd2jy$>?grA}kU&s=@7TXt}H1B8&>P%00J$7A1x5`SXVXA+@bG4qp?i z)32aEgAMQO_|2E!(&zvDYiOR&jU&aONbQ>r_(b4(r2Z{>daC+bC~sN_kNn189!M}6 zGe|9azQAD7JZP{3Ii~bB*oNTb=cyXa&p4^@F!eXrSU&l1MXr?btX^<^X}MHdjkXty zl9CCF*~#=sB|rto;a5^(ofp*3LX|d1+ddT5@`rDEeC#<#I03Gm?@bIO0%?I4R_P7S zmgmyxxiF3?x}CSxc*!W4O-77eZ>MqJ<#DulQ3& zs8@Ew`dEs*;}7tjpX&5M?(R+2;%^e2XU&z3h~V~*w#BRxs(UXMUOLQt4@J040R?R` zwspiJlXK1%x?czJd7=hC7xt+K7JWRV{4|1GP^FO=s~c3VDrk7rfJYFTbf}X0Fey;& z6-t}uj>>b)v4~SLG9XH*4}m&3P1g0ky=k+sprRvbFtHW?MXb z;`%fyt?aXfMC(JLZbzE#LuRVU(Q#CV8nR8Qu|f9G2mg_flaq!Ieph;JZq7;*ztuy< z0U=*^I$X(B^{<2Y2&?_I{?>t=Ld2t#GCE=LCK4BjQ}mzu`Ki3cit7WM(wXd=@Gogz z&_~9Dc7n856>c~uj9Mf~;bp(nIlX!fC2Mh$j|tqNGX1DHP%&7!%2583lWA*NucKH| zPip@}m6_@Q14zIw-ZRrTIXFG9__0&8SFqhlWcl_gE`1ViZTkfUv0$FA4NB0pBG4=H zb~QasFwIt^-80K+P8FexHK^1zbU62C)xWXcg0TRQ1vMA2W*ipdhu5 zAZs}UoC(_Yv5#IX=h$$bd1+M^_W6S0#O!7>s-qC!aaNoK%0$6EvLkDljB8(dru^lO z<_N3JWFML7k|aD?v*_Gx$)4X2g8JWe<+V;VcYplqx3RCzVQy5T& zw8jbexe}fgW~3J=`Xv>oR)DDdI4B;ex+M)?c29$jYscBW#KLUqli9aMM`eq14pR|4 zPwNhVD$N50{p1nLt(ev9q|wc-jf|(a@4pj%G$P7D{Wi0JHiU|IRV(3M@jJg>YwI=Q zrR2qj{B!zNz-gm#5frT&q`HZH=0B?ppCa$+gz1)Sw2oC~*Ofsl7|%db$!os>__`6h zw&d;y@{yk&93U2A(jxVL26p#j9E!$oU2DaW5YCvp$7~7*pB0j2IQt+6;G?Ooj@O@M zh=PS&8Oa-bwHz#j#>nx2EQXA+En}FC(n&^dR9`@;BRA+u%-H;gG12egpaygm;oCyW z&^zlvsd^Q%iskei6lK1a4)=4dFHMw7&RlvX)q5{@=NBCjt2ZhSceGR5Fi!()tC|2= zGndOk%v`H4J!d;wTd(h2-(^&))3krVBBR-oPZIS+6+MME6KfO2c9a38X^h6Y@)GE@ z1C%4(9@S8riyq4-buX_~gd=*Ii8lb0TWPW`RUgO;s$sVf+4iLpxo~`B!jE2;4m9%sN?~48fw_X(mB_a_mzqSy}96 zB*n27KmAZ4HFA?HoEeaVU$7r%oXs0%zf1eXA4A=5K>0$Q*czL=sH9V9_4+8-QgGfj zSse$fNdf!vYi`jN;%^`n4Tu)Of(eOj=7^d-iWJ9I4e1mw&ip$gvrF@%c=^>c-BjXq z9_f6;iKR}XQWFjO04~VSRYYr~Ji?z`%orJ6bp?J_58dCI<6pLhSVR+ZAdu6tvqb^x znS(Hc&7;y{b~G<vpHK2Jyl$=Pacm#q zSn*of6Cc#w2fc#(=H6A{xkJ2D(+&qNk6|Aed!DH!l9xoq5{bI_#HI;F3ROSkv)zA^gfn6jstJW7Cg{+c(98Hk{3G78EA3muA~idumoK~}OK zMwCEkJz^=j*5LTIf0vT;g&dp`BA(5r!kHwLx6dbtVJE>$CW$B) z`$IzDjFRQa{{hK5HM2#D>Ks4=tChyIhEJHjsj;adOnu0l3R`+Jm)w?`Eg3r4E^U^$~N6Hf(boMlluUKvwnP&p={_(HRy6lbwG@Y z`z%Gb;w$E)d3oji~3i(Av6Sa~Xo8s2Y)wOfTvBrR4tePYM`N|`N(NNKPBu5Ois?rhmEIP>k7f+GX zbXM+Evw_%3@AW=_&CW^nBWkz50~S(0HMj&a@A0b)#(;K2H6YyMw?9)=Wb2D

eAX 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

    (mf1)^gHpxC31ZJ*8R#$ZKJT0+|vPHn3K|N2M*< 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 KMNUMnLSTY#49`CR literal 0 HcmV?d00001 diff --git a/source/_exclude/README.md b/source/_exclude/README.md deleted file mode 100644 index 34c58af4..00000000 --- a/source/_exclude/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Stuff that isnt used currently, but may be used in the future. - -still complied cuz why not loll \ No newline at end of file diff --git a/source/_exclude/lime/_internal/backend/native/NativeAudioSource.hx b/source/_exclude/lime/_internal/backend/native/NativeAudioSource.hx deleted file mode 100644 index ee3cc803..00000000 --- a/source/_exclude/lime/_internal/backend/native/NativeAudioSource.hx +++ /dev/null @@ -1,592 +0,0 @@ -package lime._internal.backend.native; - -import haxe.Int64; -import haxe.Timer; -import lime.math.Vector4; -import lime.media.openal.AL; -import lime.media.openal.ALBuffer; -import lime.media.openal.ALSource; -import lime.media.vorbis.VorbisFile; -import lime.media.AudioManager; -import lime.media.AudioSource; -import lime.utils.UInt8Array; - -#if !lime_debug -@:fileXml('tags="haxe,release"') -@:noDebug -#end -@:access(lime.media.AudioBuffer) -class NativeAudioSource -{ - private static var STREAM_BUFFER_SIZE = 48000; - #if (native_audio_buffers && !macro) - private static var STREAM_NUM_BUFFERS = Std.parseInt(haxe.macro.Compiler.getDefine("native_audio_buffers")); - #else - private static var STREAM_NUM_BUFFERS = 3; - #end - private static var STREAM_TIMER_FREQUENCY = 100; - - private var buffers:Array; - private var bufferTimeBlocks:Array; - private var completed:Bool; - private var dataLength:Int; - private var format:Int; - private var handle:ALSource; - private var length:Null; - private var loops:Int; - private var parent:AudioSource; - private var playing:Bool; - private var position:Vector4; - private var samples:Int; - private var stream:Bool; - private var streamTimer:Timer; - private var timer:Timer; - - public function new(parent:AudioSource) - { - this.parent = parent; - - position = new Vector4(); - } - - public function dispose():Void - { - if (handle != null) - { - stop(); - AL.sourcei(handle, AL.BUFFER, null); - AL.deleteSource(handle); - if (buffers != null) - { - for (buffer in buffers) - { - AL.deleteBuffer(buffer); - } - buffers = null; - } - handle = null; - } - } - - public function init():Void - { - dataLength = 0; - format = 0; - - if (parent.buffer.channels == 1) - { - if (parent.buffer.bitsPerSample == 8) - { - format = AL.FORMAT_MONO8; - } - else if (parent.buffer.bitsPerSample == 16) - { - format = AL.FORMAT_MONO16; - } - } - else if (parent.buffer.channels == 2) - { - if (parent.buffer.bitsPerSample == 8) - { - format = AL.FORMAT_STEREO8; - } - else if (parent.buffer.bitsPerSample == 16) - { - format = AL.FORMAT_STEREO16; - } - } - - if (parent.buffer.__srcVorbisFile != null) - { - stream = true; - - var vorbisFile = parent.buffer.__srcVorbisFile; - dataLength = Std.int(Int64.toInt(vorbisFile.pcmTotal()) * parent.buffer.channels * (parent.buffer.bitsPerSample / 8)); - - buffers = new Array(); - bufferTimeBlocks = new Array(); - - for (i in 0...STREAM_NUM_BUFFERS) - { - buffers.push(AL.createBuffer()); - bufferTimeBlocks.push(0); - } - - handle = AL.createSource(); - } - else - { - if (parent.buffer.__srcBuffer == null) - { - parent.buffer.__srcBuffer = AL.createBuffer(); - - if (parent.buffer.__srcBuffer != null) - { - AL.bufferData(parent.buffer.__srcBuffer, format, parent.buffer.data, parent.buffer.data.length, parent.buffer.sampleRate); - } - } - - dataLength = parent.buffer.data.length; - - handle = AL.createSource(); - - if (handle != null) - { - AL.sourcei(handle, AL.BUFFER, parent.buffer.__srcBuffer); - } - } - - samples = Std.int((dataLength * 8) / (parent.buffer.channels * parent.buffer.bitsPerSample)); - } - - public function play():Void - { - /*var pitch:Float = AL.getSourcef (handle, AL.PITCH); - trace(pitch); - AL.sourcef (handle, AL.PITCH, pitch*0.9); - pitch = AL.getSourcef (handle, AL.PITCH); - trace(pitch); */ - /*var pos = getPosition(); - trace(AL.DISTANCE_MODEL); - AL.distanceModel(AL.INVERSE_DISTANCE); - trace(AL.DISTANCE_MODEL); - AL.sourcef(handle, AL.ROLLOFF_FACTOR, 5); - setPosition(new Vector4(10, 10, -100)); - pos = getPosition(); - trace(pos); */ - /*var filter = AL.createFilter(); - trace(AL.getErrorString()); - - AL.filteri(filter, AL.FILTER_TYPE, AL.FILTER_LOWPASS); - trace(AL.getErrorString()); - - AL.filterf(filter, AL.LOWPASS_GAIN, 0.5); - trace(AL.getErrorString()); - - AL.filterf(filter, AL.LOWPASS_GAINHF, 0.5); - trace(AL.getErrorString()); - - AL.sourcei(handle, AL.DIRECT_FILTER, filter); - trace(AL.getErrorString()); */ - - if (playing || handle == null) - { - return; - } - - playing = true; - - if (stream) - { - setCurrentTime(getCurrentTime()); - - streamTimer = new Timer(STREAM_TIMER_FREQUENCY); - streamTimer.run = streamTimer_onRun; - } - else - { - var time = completed ? 0 : getCurrentTime(); - - AL.sourcePlay(handle); - - setCurrentTime(time); - } - } - - public function pause():Void - { - playing = false; - - if (handle == null) return; - AL.sourcePause(handle); - - if (streamTimer != null) - { - streamTimer.stop(); - } - - if (timer != null) - { - timer.stop(); - } - } - - private function readVorbisFileBuffer(vorbisFile:VorbisFile, length:Int):UInt8Array - { - #if lime_vorbis - var buffer = new UInt8Array(length); - var read = 0, total = 0, readMax; - - for (i in 0...STREAM_NUM_BUFFERS-1) - { - bufferTimeBlocks[i] = bufferTimeBlocks[i + 1]; - } - bufferTimeBlocks[STREAM_NUM_BUFFERS-1] = vorbisFile.timeTell(); - - while (total < length) - { - readMax = 4096; - - if (readMax > length - total) - { - readMax = length - total; - } - - read = vorbisFile.read(buffer.buffer, total, readMax); - - if (read > 0) - { - total += read; - } - else - { - break; - } - } - - return buffer; - #else - return null; - #end - } - - private function refillBuffers(buffers:Array = null):Void - { - #if lime_vorbis - var vorbisFile = null; - var position = 0; - - if (buffers == null) - { - var buffersProcessed:Int = AL.getSourcei(handle, AL.BUFFERS_PROCESSED); - - if (buffersProcessed > 0) - { - vorbisFile = parent.buffer.__srcVorbisFile; - position = Int64.toInt(vorbisFile.pcmTell()); - - if (position < dataLength) - { - buffers = AL.sourceUnqueueBuffers(handle, buffersProcessed); - } - } - } - - if (buffers != null) - { - if (vorbisFile == null) - { - vorbisFile = parent.buffer.__srcVorbisFile; - position = Int64.toInt(vorbisFile.pcmTell()); - } - - var numBuffers = 0; - var data; - - for (buffer in buffers) - { - if (dataLength - position >= STREAM_BUFFER_SIZE) - { - data = readVorbisFileBuffer(vorbisFile, STREAM_BUFFER_SIZE); - AL.bufferData(buffer, format, data, data.length, parent.buffer.sampleRate); - position += STREAM_BUFFER_SIZE; - numBuffers++; - } - else if (position < dataLength) - { - data = readVorbisFileBuffer(vorbisFile, dataLength - position); - AL.bufferData(buffer, format, data, data.length, parent.buffer.sampleRate); - numBuffers++; - break; - } - } - - AL.sourceQueueBuffers(handle, numBuffers, buffers); - - // OpenAL can unexpectedly stop playback if the buffers run out - // of data, which typically happens if an operation (such as - // resizing a window) freezes the main thread. - // If AL is supposed to be playing but isn't, restart it here. - if (playing && handle != null && AL.getSourcei(handle, AL.SOURCE_STATE) == AL.STOPPED) - { - AL.sourcePlay(handle); - } - } - #end - } - - public function stop():Void - { - if (playing && handle != null && AL.getSourcei(handle, AL.SOURCE_STATE) == AL.PLAYING) - { - AL.sourceStop(handle); - } - - playing = false; - - if (streamTimer != null) - { - streamTimer.stop(); - } - - if (timer != null) - { - timer.stop(); - } - - setCurrentTime(0); - } - - // Event Handlers - private function streamTimer_onRun():Void - { - refillBuffers(); - } - - private function timer_onRun():Void - { - if (loops > 0) - { - playing = false; - loops--; - setCurrentTime(0); - play(); - return; - } - else - { - stop(); - } - - completed = true; - parent.onComplete.dispatch(); - } - - // Get & Set Methods - public function getCurrentTime():Int - { - if (completed) - { - return getLength(); - } - else if (handle != null) - { - if (stream) - { - var time = (Std.int(bufferTimeBlocks[0] * 1000) + Std.int(AL.getSourcef(handle, AL.SEC_OFFSET) * 1000)) - parent.offset; - if (time < 0) return 0; - return time; - } - else - { - var offset = AL.getSourcei(handle, AL.BYTE_OFFSET); - var ratio = (offset / dataLength); - var totalSeconds = samples / parent.buffer.sampleRate; - - var time = Std.int(totalSeconds * ratio * 1000) - parent.offset; - - // var time = Std.int (AL.getSourcef (handle, AL.SEC_OFFSET) * 1000) - parent.offset; - if (time < 0) return 0; - return time; - } - } - - return 0; - } - - public function setCurrentTime(value:Int):Int - { - // `setCurrentTime()` has side effects and is never safe to skip. - /* if (value == getCurrentTime()) - { - return value; - } */ - - if (handle != null) - { - if (stream) - { - AL.sourceStop(handle); - - parent.buffer.__srcVorbisFile.timeSeek((value + parent.offset) / 1000); - AL.sourceUnqueueBuffers(handle, STREAM_NUM_BUFFERS); - refillBuffers(buffers); - - if (playing) AL.sourcePlay(handle); - } - else if (parent.buffer != null) - { - AL.sourceRewind(handle); - if (playing) AL.sourcePlay(handle); - // AL.sourcef (handle, AL.SEC_OFFSET, (value + parent.offset) / 1000); - - var secondOffset = (value + parent.offset) / 1000; - var totalSeconds = samples / parent.buffer.sampleRate; - - if (secondOffset < 0) secondOffset = 0; - if (secondOffset > totalSeconds) secondOffset = totalSeconds; - - var ratio = (secondOffset / totalSeconds); - var totalOffset = Std.int(dataLength * ratio); - - AL.sourcei(handle, AL.BYTE_OFFSET, totalOffset); - } - } - - if (playing) - { - if (timer != null) - { - timer.stop(); - } - - var timeRemaining = Std.int((getLength() - value) / getPitch()); - - if (timeRemaining > 0) - { - completed = false; - timer = new Timer(timeRemaining); - timer.run = timer_onRun; - } - else - { - playing = false; - completed = true; - } - } - - return value; - } - - public function getGain():Float - { - if (handle != null) - { - return AL.getSourcef(handle, AL.GAIN); - } - else - { - return 1; - } - } - - public function setGain(value:Float):Float - { - if (handle != null) - { - AL.sourcef(handle, AL.GAIN, value); - } - - return value; - } - - public function getLength():Int - { - if (length != null) - { - return length; - } - - return Std.int(samples / parent.buffer.sampleRate * 1000) - parent.offset; - } - - public function setLength(value:Int):Int - { - if (playing && length != value) - { - if (timer != null) - { - timer.stop(); - } - - var timeRemaining = Std.int((value - getCurrentTime()) / getPitch()); - - if (timeRemaining > 0) - { - timer = new Timer(timeRemaining); - timer.run = timer_onRun; - } - } - - return length = value; - } - - public function getLoops():Int - { - return loops; - } - - public function setLoops(value:Int):Int - { - return loops = value; - } - - public function getPitch():Float - { - if (handle != null) - { - return AL.getSourcef(handle, AL.PITCH); - } - else - { - return 1; - } - } - - public function setPitch(value:Float):Float - { - if (playing && value != getPitch()) - { - if (timer != null) - { - timer.stop(); - } - - var timeRemaining = Std.int((getLength() - getCurrentTime()) / value); - - if (timeRemaining > 0) - { - timer = new Timer(timeRemaining); - timer.run = timer_onRun; - } - } - - if (handle != null) - { - AL.sourcef(handle, AL.PITCH, value); - } - - return value; - } - - public function getPosition():Vector4 - { - if (handle != null) - { - #if !emscripten - var value = AL.getSource3f(handle, AL.POSITION); - position.x = value[0]; - position.y = value[1]; - position.z = value[2]; - #end - } - - return position; - } - - public function setPosition(value:Vector4):Vector4 - { - position.x = value.x; - position.y = value.y; - position.z = value.z; - position.w = value.w; - - if (handle != null) - { - AL.distanceModel(AL.NONE); - AL.source3f(handle, AL.POSITION, position.x, position.y, position.z); - } - - return position; - } -} diff --git a/source/funkin/game/objects/FlxRGBSprite.hx b/source/flixel/FlxRGBSprite.hx similarity index 86% rename from source/funkin/game/objects/FlxRGBSprite.hx rename to source/flixel/FlxRGBSprite.hx index 7cad2791..0af05509 100644 --- a/source/funkin/game/objects/FlxRGBSprite.hx +++ b/source/flixel/FlxRGBSprite.hx @@ -1,5 +1,7 @@ -package funkin.game.objects; +package flixel; +import funkin.game.objects.shaders.RGBPalette; +import funkin.game.objects.shaders.RGBPalette.RGBShaderReference; import flixel.FlxSprite; import flixel.system.FlxAssets.FlxGraphicAsset; import flixel.util.FlxColor; diff --git a/source/funkin/backend/funkinLua/HScript.hx b/source/funkin/backend/funkinLua/HScript.hx index 70429058..77e0e208 100644 --- a/source/funkin/backend/funkinLua/HScript.hx +++ b/source/funkin/backend/funkinLua/HScript.hx @@ -136,6 +136,8 @@ class HScript extends Iris #if FLXANIMATE_ALLOWED set('FlxAnimate', FlxAnimate); #end + set('osName', OsAPI.username); + set('osNameHash',OsAPI.hashUsername); // Functions & Variables set('setVar', function(name:String, value:Dynamic) { diff --git a/source/funkin/backend/funkinLua/functions/ExtraFunctions.hx b/source/funkin/backend/funkinLua/functions/ExtraFunctions.hx index 1aaf1533..68391e51 100644 --- a/source/funkin/backend/funkinLua/functions/ExtraFunctions.hx +++ b/source/funkin/backend/funkinLua/functions/ExtraFunctions.hx @@ -3,6 +3,9 @@ package funkin.backend.funkinLua.functions; import flixel.util.FlxSave; import openfl.utils.Assets; +import haxe.crypto.Md5; +import haxe.crypto.Sha1; + // // Things to trivialize some dumb stuff like splitting strings on older Lua // @@ -13,15 +16,7 @@ class ExtraFunctions { var lua:State = funk.lua; - // Keyboard & Gamepads - Lua_helper.add_callback(lua, "keyboardJustPressed", function(name:String) return Reflect.getProperty(FlxG.keys.justPressed, name)); - Lua_helper.add_callback(lua, "keyboardPressed", function(name:String) return Reflect.getProperty(FlxG.keys.pressed, name)); - Lua_helper.add_callback(lua, "keyboardReleased", function(name:String) return Reflect.getProperty(FlxG.keys.justReleased, name)); - - Lua_helper.add_callback(lua, "anyGamepadJustPressed", function(name:String) return FlxG.gamepads.anyJustPressed(name)); - Lua_helper.add_callback(lua, "anyGamepadPressed", function(name:String) FlxG.gamepads.anyPressed(name)); - Lua_helper.add_callback(lua, "anyGamepadReleased", function(name:String) return FlxG.gamepads.anyJustReleased(name)); - + Lua_helper.add_callback(lua, "setDarkmode", function(value:Bool) { #if windows @@ -31,6 +26,27 @@ class ExtraFunctions #end }); + Lua_helper.add_callback(lua, "hash", function(txt:String, type:String = "md5") + { + switch(type.toLowerCase()) { + case "md5": + return Md5.encode(txt); + case "sha1": + return Sha1.encode(txt); + default: + throw "Unsupported hash type: " + type; + } + }); + + // Keyboard & Gamepads + Lua_helper.add_callback(lua, "keyboardJustPressed", function(name:String) return Reflect.getProperty(FlxG.keys.justPressed, name)); + Lua_helper.add_callback(lua, "keyboardPressed", function(name:String) return Reflect.getProperty(FlxG.keys.pressed, name)); + Lua_helper.add_callback(lua, "keyboardReleased", function(name:String) return Reflect.getProperty(FlxG.keys.justReleased, name)); + + Lua_helper.add_callback(lua, "anyGamepadJustPressed", function(name:String) return FlxG.gamepads.anyJustPressed(name)); + Lua_helper.add_callback(lua, "anyGamepadPressed", function(name:String) FlxG.gamepads.anyPressed(name)); + Lua_helper.add_callback(lua, "anyGamepadReleased", function(name:String) return FlxG.gamepads.anyJustReleased(name)); + Lua_helper.add_callback(lua, "gamepadAnalogX", function(id:Int, ?leftStick:Bool = true) { var controller = FlxG.gamepads.getByID(id); diff --git a/source/funkin/backend/system/ui/FunkinSoundTray.hx b/source/funkin/backend/system/ui/FunkinSoundTray.hx index de483a59..4a79269c 100644 --- a/source/funkin/backend/system/ui/FunkinSoundTray.hx +++ b/source/funkin/backend/system/ui/FunkinSoundTray.hx @@ -63,8 +63,7 @@ class FunkinSoundTray extends FlxSoundTray function getPathImage(path:String):Dynamic { - final ext = 'png'; - final file = Paths.getPath('images/$path.$ext'); + final file = Paths.getPath('images/$path.png'); #if MODS_ALLOWED return BitmapData.fromFile(file); diff --git a/source/funkin/backend/utils/ClientPrefs.hx b/source/funkin/backend/utils/ClientPrefs.hx index e254df23..23b15b86 100644 --- a/source/funkin/backend/utils/ClientPrefs.hx +++ b/source/funkin/backend/utils/ClientPrefs.hx @@ -91,7 +91,9 @@ import funkin.game.Init.Volume; public var showRatingStats:Bool = true; public var darkMode:Bool = false; + #if ASTRO_WATERMARKS public var gayFurryStuff:Bool = false; + #end public var stats:Map = ['Max Misses' => 0, 'Max Score' => 0]; diff --git a/source/funkin/backend/utils/native/OsAPI.hx b/source/funkin/backend/utils/native/OsAPI.hx new file mode 100644 index 00000000..c48da91a --- /dev/null +++ b/source/funkin/backend/utils/native/OsAPI.hx @@ -0,0 +1,23 @@ +package funkin.backend.utils.native; + +import haxe.crypto.Md5; + +class OsAPI +{ + public static var username(get, null):String; + + @:noCompletion private inline static function get_username() + { + final environment = Sys.environment(); + + if (environment.exists("USERNAME")) return environment["USERNAME"]; + if (environment.exists("USER")) return environment["USER"]; + + return '???'; + } + + public static var hashUsername(get, null):String; + + @:noCompletion private inline static function get_hashUsername() + return Md5.encode(username); +} diff --git a/source/funkin/game/FPS.hx b/source/funkin/game/FPS.hx index 540b6243..b44db2cd 100644 --- a/source/funkin/game/FPS.hx +++ b/source/funkin/game/FPS.hx @@ -73,19 +73,19 @@ class FPS extends TextField if (currentCount != cacheCount) { - text = '${ClientPrefs.data.gayFurryStuff ? "owo's per second" : 'FPS'}: $currentFPS'; + text = '${#if ASTRO_WATERMARKS ClientPrefs.data.gayFurryStuff ? "owo's per second" : #end 'FPS'}: $currentFPS'; var memoryMegas:Float = 0; #if openfl memoryMegas = Math.abs(FlxMath.roundDecimal(System.totalMemory / 1000000, 1)); - text += '\n${ClientPrefs.data.gayFurryStuff ? "proot mem usage" : 'Memory'}: ${memoryMegas} MB'; + text += '\n${#if ASTRO_WATERMARKS ClientPrefs.data.gayFurryStuff ? "proot mem usage" : #end 'Memory'}: ${memoryMegas} MB'; #end /* text += '\nAstro Engine: ' + EngineData.engineData.coreVersion; */ #if debug - text += '\n${ClientPrefs.data.gayFurryStuff ? "orbl pick one pls 🙏" : "Commit"}: ${GitMacro.commitNumber} [${GitMacro.commitHash}] ${GitMacro.branch}'; + text += '\n${#if ASTRO_WATERMARKS ClientPrefs.data.gayFurryStuff ? "orbl pick one pls 🙏" : #end "Commit"}: ${GitMacro.commitNumber} [${GitMacro.commitHash}] ${GitMacro.branch}'; #end textColor = 0xFFFFFFFF; diff --git a/source/funkin/game/Init.hx b/source/funkin/game/Init.hx index 8a25b7af..893ad06d 100644 --- a/source/funkin/game/Init.hx +++ b/source/funkin/game/Init.hx @@ -1,7 +1,5 @@ package funkin.game; -import openfl.text.TextFormat; -import openfl.text.TextField; import openfl.Lib; import flixel.input.keyboard.FlxKey; import funkin.backend.utils.Paths; @@ -31,13 +29,17 @@ class Init extends flixel.FlxState #if LUA_ALLOWED Lua.set_callbacks_function(cpp.Callable.fromStaticFunction(CallbackHandler.call)); #end #if ACHIEVEMENTS_ALLOWED Achievements.load(); #end - + #if DISCORD_ALLOWED DiscordClient.prepare(); #end #if VIDEOS_ALLOWED hxvlc.util.Handle.init(#if (hxvlc >= "1.8.0") ['--no-lua'] #end); #end #if WATERMARK owoWatermark(); #end + #if CRASH_HANDLER initCrashHandler(); #end + + fragFix(); + funkin.game.objects.Alphabet.AlphaCharacter.loadAlphabetData(); super.create(); @@ -49,29 +51,72 @@ class Init extends flixel.FlxState private function init():Void { + #if html5 + FlxG.mouse.visible = false; + #end + + FlxG.fixedTimestep = #if html5 FlxG.mouse.visible = #end + false; + FlxG.keys.preventDefaultKeys = [TAB]; + FlxG.game.focusLostFramerate = 30; + if (FlxG.save.data != null && FlxG.save.data.fullscreen) FlxG.fullscreen = FlxG.save.data.fullscreen; if (FlxG.save.data.weekCompleted != null) funkin.game.states.StoryMenuState.weekCompleted = FlxG.save.data.weekCompleted; } - #if WATERMARK + #if CRASH_HANDLER + private function initCrashHandler() + { + Lib.current.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, CrashHandler.main); + } + #end + + private function fragFix() + { + FlxG.signals.gameResized.add(function(w, h) + { + if (FlxG.cameras != null) + for (cam in FlxG.cameras.list) + if (cam != null && cam.filters != null) + resetSpriteCache(cam.flashSprite); + + if (FlxG.game != null) + resetSpriteCache(FlxG.game); + }); + } + + private static function resetSpriteCache(sprite:openfl.display.Sprite):Void + { + @:privateAccess { + sprite.__cacheBitmap = null; + sprite.__cacheBitmapData = null; + } + } + private function owoWatermark():Void { // uhh tester text lmao - final owoTxt:TextField = new TextField(); - owoTxt.defaultTextFormat = new TextFormat("assets/fonts/OswaldMedium.ttf", 100, FlxColor.WHITE); - owoTxt.text = 'BETA BUILD OF ASTRO ENGINE'; - owoTxt.alpha = .4; - owoTxt.width = Lib.current.stage.stageWidth; - owoTxt.height = Lib.current.stage.stageHeight; - owoTxt.x = (Lib.current.stage.stageWidth - owoTxt.width) / 2; - owoTxt.y = (Lib.current.stage.stageHeight - owoTxt.height) / 2; - owoTxt.selectable = false; - - Lib.current.addChild(owoTxt); + final width =FlxG.width; + final height = FlxG.height; + final watermarkText:String = 'BETA(DO NOT LEAK)\n${OsAPI.username}\n${OsAPI.hashUsername}'; + + final format:openfl.text.TextFormat = new openfl.text.TextFormat("assets/fonts/OswaldMedium.ttf", 50, FlxColor.WHITE); + format.align = openfl.text.TextFormatAlign.CENTER; + + final watermark:openfl.text.TextField = new openfl.text.TextField(); + watermark.defaultTextFormat = format; + watermark.text = watermarkText; + watermark.alpha = .55; + watermark.width = width; + watermark.height = height; + watermark.selectable = false; + + watermark.y = (height - watermark.textHeight) / 2; + + Lib.current.addChild(watermark); } - #end } class Volume @@ -83,12 +128,12 @@ class Volume class Logs // Modded trace func { - private static final fuckbaby:String = "[Astro System]"; // prefix i guess + private static final fembois:String = "[Astro System]"; // prefix i guess public static function init():Void { haxe.Log.trace = __customTrace; - trace('Finished Setting up custom trace'); + trace('Finished Setting up custom trace.'); } @:noCompletion private static function __customTrace(v:Dynamic, ?infos:haxe.PosInfos):Void @@ -101,18 +146,18 @@ class Logs // Modded trace func extra += ", " + v; #if js if (js.Syntax.typeof(untyped console) != "undefined" && (untyped console).log != null) - (untyped console).log('$fuckbaby: ${v + extra} : $nerddd'); + (untyped console).log('$fembois: ${v + extra} : $nerddd'); #elseif sys - Sys.println('$fuckbaby: ${v + extra} : $nerddd'); + Sys.println('$fembois: ${v + extra} : $nerddd'); #end } else { #if js if (js.Syntax.typeof(untyped console) != "undefined" && (untyped console).log != null) - (untyped console).log('$fuckbaby: $v : $nerddd'); + (untyped console).log('$fembois: $v : $nerddd'); #elseif sys - Sys.println('$fuckbaby: $v : $nerddd'); + Sys.println('$fembois: $v : $nerddd'); #end } } diff --git a/source/funkin/game/Main.hx b/source/funkin/game/Main.hx index ff080b94..4c4bb96a 100644 --- a/source/funkin/game/Main.hx +++ b/source/funkin/game/Main.hx @@ -92,8 +92,10 @@ class Main extends Sprite var game:FlxGame = new FlxGame(Config.gameSize[0], Config.gameSize[1], Init, #if (flixel < "5.0.0") game.zoom, #end game.framerate, game.framerate, Config.skipSplash, Config.startFullscreen); + #if BASE_GAME_FILES @:privateAccess game._customSoundTray = funkin.backend.system.ui.FunkinSoundTray; + #end addChild(game); @@ -105,39 +107,5 @@ class Main extends Sprite if (fpsVar != null) fpsVar.visible = ClientPrefs.data.showFPS; #end - - #if html5 - // FlxG.autoPause = false; - FlxG.mouse.visible = false; - #end - - FlxG.fixedTimestep = false; - FlxG.game.focusLostFramerate = 60; - FlxG.keys.preventDefaultKeys = [TAB]; - - #if CRASH_HANDLER - Lib.current.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, CrashHandler.main); - #end - - FlxG.signals.gameResized.add(function(w, h) - { - if (FlxG.cameras != null) - { - for (cam in FlxG.cameras.list) - if (cam != null && cam.filters != null) - resetSpriteCache(cam.flashSprite); - } - - if (FlxG.game != null) - resetSpriteCache(FlxG.game); - }); - } - - static function resetSpriteCache(sprite:Sprite):Void - { - @:privateAccess { - sprite.__cacheBitmap = null; - sprite.__cacheBitmapData = null; - } } } diff --git a/source/funkin/game/options/GameplaySettingsSubState.hx b/source/funkin/game/options/GameplaySettingsSubState.hx index d36b70fb..9a0ed2a4 100644 --- a/source/funkin/game/options/GameplaySettingsSubState.hx +++ b/source/funkin/game/options/GameplaySettingsSubState.hx @@ -141,8 +141,10 @@ class GameplaySettingsSubState extends BaseOptionsMenu option.changeValue = 0.1; addOption(option); + #if ASTRO_WATERMARKS var option:Option = new Option('Weird Stuff', 'erm, owo?', 'gayFurryStuff', BOOL); addOption(option); + #end super(); } diff --git a/source/funkin/game/states/LoadingState.hx b/source/funkin/game/states/LoadingState.hx index d93466ac..4094702a 100644 --- a/source/funkin/game/states/LoadingState.hx +++ b/source/funkin/game/states/LoadingState.hx @@ -52,18 +52,13 @@ class LoadingState extends MusicBeatState var curPercent:Float = 0; var canChangeState:Bool = true; - #if PSYCH_WATERMARKS + #if ASTRO_WATERMARKS var logo:FlxSprite; - var pessy:FlxSprite; + var loadingText:FlxText; var timePassed:Float; var shakeFl:Float; - var shakeMult:Float = 0; - - var isSpinning:Bool = false; - var spawnedPessy:Bool = false; - var pressedTimes:Int = 0; #else var funkay:FlxSprite; #end @@ -86,7 +81,7 @@ class LoadingState extends MusicBeatState #end } - #if PSYCH_WATERMARKS // PSYCH LOADING SCREEN + #if ASTRO_WATERMARKS // PSYCH LOADING SCREEN var bg = new FlxSprite().loadGraphic(Paths.image('menuDesat')); bg.setGraphicSize(Std.int(FlxG.width)); bg.color = 0xFFD16FFF; @@ -98,7 +93,7 @@ class LoadingState extends MusicBeatState loadingText.borderSize = 2; add(loadingText); - logo = new FlxSprite(0, 0).loadGraphic(Paths.image('loading_screen/icon')); + logo = new FlxSprite(0, 0).loadGraphic(Paths.image('psych')); logo.scale.set(0.75, 0.75); logo.updateHitbox(); logo.antialiasing = ClientPrefs.data.antialiasing; @@ -163,7 +158,7 @@ class LoadingState extends MusicBeatState bar.updateHitbox(); } - #if PSYCH_WATERMARKS // PSYCH LOADING SCREEN + #if ASTRO_WATERMARKS // PSYCH LOADING SCREEN timePassed += elapsed; shakeFl += elapsed * 3000; var dots:String = ''; @@ -177,58 +172,6 @@ class LoadingState extends MusicBeatState dots = '...'; } loadingText.text = 'Now Loading${dots}'; - - if(!spawnedPessy) - { - if(!transitioning && controls.ACCEPT) - { - shakeMult = 1; - FlxG.sound.play(Paths.sound('cancelMenu')); - pressedTimes++; - } - shakeMult = Math.max(0, shakeMult - elapsed * 5); - logo.offset.x = Math.sin(shakeFl * Math.PI / 180) * shakeMult * 100; - - if(pressedTimes >= 5) - { - FlxG.camera.fade(0xAAFFFFFF, 0.5, true); - logo.visible = false; - spawnedPessy = true; - canChangeState = false; - FlxG.sound.play(Paths.sound('secret')); - - pessy = new FlxSprite(700, 140); - new FlxTimer().start(0.01, function(tmr:FlxTimer) { - pessy.frames = Paths.getSparrowAtlas('loading_screen/pessy'); - pessy.antialiasing = ClientPrefs.data.antialiasing; - pessy.flipX = (logo.offset.x > 0); - pessy.x = FlxG.width + 200; - pessy.velocity.x = -1100; - if(pessy.flipX) - { - pessy.x = -pessy.width - 200; - pessy.velocity.x = 1100; - } - - pessy.animation.addByPrefix('run', 'run', 24, true); - pessy.animation.addByPrefix('spin', 'spin', 24, true); - pessy.animation.play('run', true); - - insert(members.indexOf(loadingText), pessy); - new FlxTimer().start(5, function(tmr:FlxTimer) canChangeState = true); - }); - } - } - else if(!isSpinning && (pessy.flipX && pessy.x > FlxG.width) || (!pessy.flipX && pessy.x < -pessy.width)) - { - isSpinning = true; - pessy.animation.play('spin', true); - pessy.flipX = false; - pessy.x = 500; - pessy.y = FlxG.height + 500; - pessy.velocity.x = 0; - FlxTween.tween(pessy, {y: 10}, 0.65, {ease: FlxEase.quadOut}); - } #end } diff --git a/source/funkin/game/states/PlayState.hx b/source/funkin/game/states/PlayState.hx index cd048b89..3190944b 100644 --- a/source/funkin/game/states/PlayState.hx +++ b/source/funkin/game/states/PlayState.hx @@ -549,9 +549,9 @@ class PlayState extends MusicBeatState switch (curStage) { + #if BASE_GAME_FILES case 'stage': new Stage(); // Week 1 - #if BASE_GAME_FILES case 'spooky': new Spooky(); // Week 2 case 'philly': diff --git a/source/funkin/game/states/TitleState.hx b/source/funkin/game/states/TitleState.hx index 8f2b2052..524cdb27 100644 --- a/source/funkin/game/states/TitleState.hx +++ b/source/funkin/game/states/TitleState.hx @@ -101,7 +101,7 @@ class TitleState extends MusicBeatState if (ClientPrefs.data.checkForUpdates && !closedState) { trace('checking for update'); - var http = new haxe.Http("https://raw.githubusercontent.com/Hackx2/FNF-AstroEngine/main/gitVersion.txt"); + var http = new haxe.Http("https://raw.githubusercontent.com/AstroEngineDevs/FNF-AstroEngine/main/gitVersion.txt"); http.onData = function(data:String) { diff --git a/source/_exclude/AnimatedImageState.hx b/source/funkin/game/states/VeryFuniState.hx similarity index 96% rename from source/_exclude/AnimatedImageState.hx rename to source/funkin/game/states/VeryFuniState.hx index 968c2752..8862830e 100644 --- a/source/_exclude/AnimatedImageState.hx +++ b/source/funkin/game/states/VeryFuniState.hx @@ -21,7 +21,7 @@ class AnimatedImageState extends MusicBeatState public function new(text:String, image:String, animPrefix:String, center:Bool, framerate:Int = 24, returnState:FlxState, color:FlxColor = FlxColorPastel.PASTELPINK) { - super(); + super();//TODO!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! FlxG.sound.music.stop(); diff --git a/source/funkin/import.hx b/source/funkin/import.hx index 0071416c..6540f3b4 100644 --- a/source/funkin/import.hx +++ b/source/funkin/import.hx @@ -87,6 +87,7 @@ import haxe.*; import openfl.utils.Assets as OpenFlAssets; // Flixel +import flixel.*; import flixel.sound.FlxSound; import flixel.FlxG; import flixel.FlxObject;