From 637582c252b6ae51f411ab20c103d75694dbe3cc Mon Sep 17 00:00:00 2001 From: Pseudonian Date: Sat, 9 Mar 2024 06:44:30 -0500 Subject: [PATCH] EXALT Upgrades, more perks! --- .../Default/ShopAmbrosiaLuckMultiplier4.png | Bin 0 -> 1930 bytes Pictures/Default/ShopCalculator7.png | Bin 0 -> 697 bytes Pictures/Default/ShopOcteractAmbrosiaLuck.png | Bin 0 -> 1245 bytes Pictures/Default/perkdilatedFiveLeaf.png | Bin 0 -> 602 bytes Pictures/Default/perktwoHundredSixtyNine.png | Bin 0 -> 615 bytes .../Legacy/ShopAmbrosiaLuckMultiplier4.png | Bin 0 -> 1930 bytes Pictures/Legacy/ShopCalculator7.png | Bin 0 -> 642 bytes Pictures/Legacy/ShopOcteractAmbrosiaLuck.png | Bin 0 -> 1245 bytes Pictures/Legacy/perkdilatedFiveLeaf.png | Bin 0 -> 916 bytes Pictures/Legacy/perktwoHundredSixtyNine.png | Bin 0 -> 928 bytes Pictures/Simplified/perkdilatedFiveLeaf.png | Bin 0 -> 406 bytes index.html | 18 + src/BlueberryUpgrades.ts | 11 +- src/Calculate.ts | 17 +- src/CheckVariables.ts | 6 + src/Config.ts | 8 +- src/EventListeners.ts | 1706 ++++++++----- src/Helper.ts | 386 +-- src/ImportExport.ts | 1454 ++++++----- src/Shop.ts | 2041 +++++++++------- src/SingularityChallenges.ts | 370 +-- src/StatCache.ts | 392 +-- src/Statistics.ts | 14 +- src/Synergism.ts | 5 + src/UpdateVisuals.ts | 2171 +++++++++++------ src/singularity.ts | 32 +- src/types/Synergism.d.ts | 1879 +++++++------- translations/en.json | 33 +- 28 files changed, 6212 insertions(+), 4331 deletions(-) create mode 100644 Pictures/Default/ShopAmbrosiaLuckMultiplier4.png create mode 100644 Pictures/Default/ShopCalculator7.png create mode 100644 Pictures/Default/ShopOcteractAmbrosiaLuck.png create mode 100644 Pictures/Default/perkdilatedFiveLeaf.png create mode 100644 Pictures/Default/perktwoHundredSixtyNine.png create mode 100644 Pictures/Legacy/ShopAmbrosiaLuckMultiplier4.png create mode 100644 Pictures/Legacy/ShopCalculator7.png create mode 100644 Pictures/Legacy/ShopOcteractAmbrosiaLuck.png create mode 100644 Pictures/Legacy/perkdilatedFiveLeaf.png create mode 100644 Pictures/Legacy/perktwoHundredSixtyNine.png create mode 100644 Pictures/Simplified/perkdilatedFiveLeaf.png diff --git a/Pictures/Default/ShopAmbrosiaLuckMultiplier4.png b/Pictures/Default/ShopAmbrosiaLuckMultiplier4.png new file mode 100644 index 0000000000000000000000000000000000000000..458538d4569fbd13dbb284c7da0001a6d67f6154 GIT binary patch literal 1930 zcmV;52X**~P)P8}SuBH7c!`i*8sv#Z(NX&jtI2%?88;-`q8}!mKYTW+H06xNrb_ z>Q5y09=z&UHZj%>zPZa;Uy?0<%&aoHug+-LdeF-$6r9V)SR!ol0Jv&TpP+KnmxlPn z(I)64lTv3|CGS@+&UjQr@&Y=S#R{pmazp|E28;RDjY~sZol%wi)cG8y_J6OHD?$iV zPwrP9M--b7N&u?CGf~6AVjfq{RK@QpS)EatIR zuIL+2F|d?d)>E!$+$Bpw0Ej%agQP@4Zc#x(pD?wRLPh^H|tAV%RGpDlsJKL-q~*O&0TKl>Xx>a`J)@> zF>$nszVta{Mtsy4z}7wB^}{j?ntcG+S_TCB+i}~yaUPF=j;@ujG>qDf6bb5F7SOWxrNumu21>Pg z+^l{EC)+ZDYvqc^D|C$(168nD&7xGBN2&iTN&qs&ifBjluZt5*xrA8)iLZ`=Iue~r zdi-5#18lefCm(lR$PB^B$F#iOX6-xiR;Tb0ImSY7EBIr;N~Z;*JxWZiXEw!E080} zsBwU?0D#VUKe;qj5Gv~B3MPj)aP<$jo#a3-CWkk0eK}`T7l09Ypz{W*kpO^jJ3p## zrx_-7m#^=isNtKx`#t6S>HuEiKs@q52mt`$x4(2jj!fwOi5k8h&fwSO9U%mQEDWHX zI1rya@IeFq9~+=Xbyv<*@#Alw3PYya008*mi#qC8+sCW=e~KR8stqvp0z_Pm+K7bg zzB+jUg4`BGnS;f=$Rs-n!Kwf#7f{L5HkK|IkU@UF)PEL$s|h3kvi@{GD2*muo89n@ z159%PE7@SF|12`71cs~4Y8IK13Z{^QQ*C(sI%$A&yn(5a95U!k9)K&znAu>gP*~0e z34Z%`x==Vd(A#G1!@^|OI0)90AvF!j8udWD6Ag%I15zWwm0i@vBz#L8{DkVxe1Zu&r?FB zLL^(#hsejx2CaDkxjgL&%GR9Rmz)Xeynt@^h`fi`Yn1zXn_fWPl9r$7$b(qgTISRH zyTT=@u4)^Cpza$2Euot33Y)@s2_(k4!B-ld#`$W4tDjR(a=377R?L*D($D@`0N_n$ zcb~l!SstJl7Lh;oB&Y3Hj7fRJzbTqasBV0gZ7VrG@;PI}1Dg~BHF{KgX&_6|x) z%fQb?>hAl&ub!^IIEZvarmYbl7pW_&{;zJHnA8jF>il5kprp<_$iY&SHiPO#-TU){ zm2A*7PKXQJV4O}OL zpmuDLw|ZEbU~OhB9*GaaJMqHA+Ql;K8Fw|I(}@w=u&x17v37A^{V%@Ve%}cVI7lP_ z|M%(+Gl=sC4LIll95jRg-lt_Cb4~c&IIK`Pwz)yMz+ritG-zVk`~Ld;e`(6|JjYbF Q_5c6?07*qoM6N<$f(UJ|)Bpeg literal 0 HcmV?d00001 diff --git a/Pictures/Default/ShopCalculator7.png b/Pictures/Default/ShopCalculator7.png new file mode 100644 index 0000000000000000000000000000000000000000..8f373f6bd3f9571cf7ef19199d8e9c5892e0b91a GIT binary patch literal 697 zcmV;q0!ICbP)=gJEdAB$H7qNtk4{)cnUQ^Uq8gfj6#&4j@D~W5jgNqX zWiT~fFV%wwI_{6zxLPD z>ZUxc#0uJZsOV_T?Jld_o()6nh&V<0BjDRjR1-f!^Zds zFkS%CDbT&!9E(jJS)y`O8?_x4HUcP(t0NXyPGSQa8v&HYv*ds<8*%NjVk3akxXl3t zz~%sSiv`174;P&39f2%4AWNRe%6hoqWK#h9;DQQ!D4O>tFL^@qnp}ZE%K^ta4W>X( zfcBWx0Staw8leMuWBh}V0}%dQU6~O++X%?J19`I(z@%v)`|5;Mloi#-gJn=|P?pc> fq6U_k{`veLk&_QV+r5Sl00000NkvXXu0mjfZE!k~ literal 0 HcmV?d00001 diff --git a/Pictures/Default/ShopOcteractAmbrosiaLuck.png b/Pictures/Default/ShopOcteractAmbrosiaLuck.png new file mode 100644 index 0000000000000000000000000000000000000000..c84684db37662dfbe2c33b518a7b124c95b18689 GIT binary patch literal 1245 zcmV<31S0#1P)yeYF0m2|wXraPaDuAef{^kR40$zS!=6yPDBK0 zE@(jNF}gvoRXeBDE`UuWr!&F;d4#IPB}J?YOiY83P_v4%IUXXxWT$@EVQ`WVmIP+s zMG#vQ%BzIZ7|Qs*61+9D9vb@)KQVDG;7u8BxG+OVKL#{Fd&8Te*s-l#fB?|Hpowk+ zQ3{YpZGJ@lEKsmr%a87?@u6z2z#?E*vuBinB+EtDW!j&cE0AKumG zuRW@B7r-Xc>D+Q><_YCX*QU1nL_+*j##gW}c(ui4TH@Zr0qngUNTi0w&{QfN1u4fJKkNH^AM7h+YBGW=0RV zfN66EAdv-xO-qgTSwl}R+3Pw%47jcqq44D_1}t4yfn&hrJHe(XPqVo9CSZWd2iE3k z-#;rC2qCQ5@K>G8v?vUVLX7Y_dP!YVs{m>1I<$w!*EE$65Qa|xhEMFc>h!U*9EC4| z@2IW#+|~hDA7{-F_c>Q^axk(xFaxGHEtQV2?~HGr#i4Hi0MHsXTUr!7TksTsvH+&9 zIwOYk&3%86TK$TkhG$hwOan!IMRLJY0Le@)DCMZL0|0SKrjaVCs7d)&T+I+c!4ZIkM0=rNI75L91_ex1q(n0C#O23iG3 zr?iXe-E=EM)0)6`t)Lk}?l16dI&}tc^fAN@K;o=(+D*{Y>*7k#1|}iXo4&)9poG<% zwIv=v;9E_w5RqU{@P;VF*`8ns;eo}i>pY;R=P(9HCd1rV=svRA5b1F^ITsL5Z1Mn$ zUY_Ry*Ah&=@6HCJ&fxTCYT>rc%}TCkgL-;lzBq|og{b^`m-%>kgLAZhxp5JnBIB)5 zC=K?yBQAeX0y|GIFejc{WP6!;@bd=QNmAT2IXM+ANXetC1&CUAjVOBUHro_F>ohqc zKUFTz+2&m$Use`iI}b@x(Xz(q&We!2X9xDSIEpD(9(5&4TnB6-!5qo_S%9SgZ(7$% zfYt6Q!7ADt5UYUbl=JRcLO^#v-8cmR^M7?5bYrpPLg~KDPL9S@C1ha{S&i@Pr>U&n zAgl3%*I*hqxM>h&EtqcfDpVOmE+9V8D}R$lO)TE_-{=1W7?5J)qglZT00000NkvXX Hu0mjf4CF=- literal 0 HcmV?d00001 diff --git a/Pictures/Default/perkdilatedFiveLeaf.png b/Pictures/Default/perkdilatedFiveLeaf.png new file mode 100644 index 0000000000000000000000000000000000000000..89266cabbbbbb2ec956e5481bfc8cd339e80cb5c GIT binary patch literal 602 zcmV-g0;T$j}ZjkgY?1p(_1=E=bU+Q^V4w6XIVeOkG&ojfo<$@Bsn(3mv*;Vd;{g zNY??KbtLx1DNvr|A@Q@{`OZF{6(WKQqE3j7n;-q%>#h~=e;(HKM2olrZ?DNtzZHmR zZ4Xf$`-3W)`uc+^#;Y@oS7##UA*vhusEOjzz%osmOSy*NSn!Jo7caL)3%{P`#u#V$ zHlC9K7caNyhk>#0a?-}nyLXipwefAxA&5F5W_KOtlxa?^mO`l?66Uw4!MXsQ|=N)9WJ+PMn+1#In zi?_T*T(J&zNj62;Bx&vh5EgO8T#`x0&?PGps9=%c0qmC4{{_n&Ih1DeFO0|v^}B?wR9Fzc#xQF2*p^C zS@xFwLr}hCi`$voZ+8B6mmwnfAW1`vujk^s-O8CPzk4_p3k|Y8c+K#jdF1ON*c+vKXQ90o!_ zuGj^VG{nH=exKd_7V-7m-3MlmePb1vzU3;Aq3a1o1BRRfz#@6ng$Q5W5mY*n)figG z)R2O9D`)aaW>elK?jBCD-O3q5L>RmsVSM#1NNpXE@YNj^zAK#w0E#)IdP3e9aXNEA zjXy0~=|sW^BG>(E3Ll{au(&|PSIbG;?&SoNiPxkGFzBwrBj=r`fnLoAhx(-jGHVX+|qC|;@m3&bhP5L!!Nefr6C z7ZSNGtDc~iE2C~PKya>m4Szlk@%cE!ycS_zi;&;kVqS}o=GVQZiz@Jb$!q~K*GBIG zx^M!xPdyWyXMqiJ+<$$7?)quA^T(-o4*b>g{0F+U+YSlk4pjgE002ovPDHLkV1nQf B9e)4- literal 0 HcmV?d00001 diff --git a/Pictures/Legacy/ShopAmbrosiaLuckMultiplier4.png b/Pictures/Legacy/ShopAmbrosiaLuckMultiplier4.png new file mode 100644 index 0000000000000000000000000000000000000000..458538d4569fbd13dbb284c7da0001a6d67f6154 GIT binary patch literal 1930 zcmV;52X**~P)P8}SuBH7c!`i*8sv#Z(NX&jtI2%?88;-`q8}!mKYTW+H06xNrb_ z>Q5y09=z&UHZj%>zPZa;Uy?0<%&aoHug+-LdeF-$6r9V)SR!ol0Jv&TpP+KnmxlPn z(I)64lTv3|CGS@+&UjQr@&Y=S#R{pmazp|E28;RDjY~sZol%wi)cG8y_J6OHD?$iV zPwrP9M--b7N&u?CGf~6AVjfq{RK@QpS)EatIR zuIL+2F|d?d)>E!$+$Bpw0Ej%agQP@4Zc#x(pD?wRLPh^H|tAV%RGpDlsJKL-q~*O&0TKl>Xx>a`J)@> zF>$nszVta{Mtsy4z}7wB^}{j?ntcG+S_TCB+i}~yaUPF=j;@ujG>qDf6bb5F7SOWxrNumu21>Pg z+^l{EC)+ZDYvqc^D|C$(168nD&7xGBN2&iTN&qs&ifBjluZt5*xrA8)iLZ`=Iue~r zdi-5#18lefCm(lR$PB^B$F#iOX6-xiR;Tb0ImSY7EBIr;N~Z;*JxWZiXEw!E080} zsBwU?0D#VUKe;qj5Gv~B3MPj)aP<$jo#a3-CWkk0eK}`T7l09Ypz{W*kpO^jJ3p## zrx_-7m#^=isNtKx`#t6S>HuEiKs@q52mt`$x4(2jj!fwOi5k8h&fwSO9U%mQEDWHX zI1rya@IeFq9~+=Xbyv<*@#Alw3PYya008*mi#qC8+sCW=e~KR8stqvp0z_Pm+K7bg zzB+jUg4`BGnS;f=$Rs-n!Kwf#7f{L5HkK|IkU@UF)PEL$s|h3kvi@{GD2*muo89n@ z159%PE7@SF|12`71cs~4Y8IK13Z{^QQ*C(sI%$A&yn(5a95U!k9)K&znAu>gP*~0e z34Z%`x==Vd(A#G1!@^|OI0)90AvF!j8udWD6Ag%I15zWwm0i@vBz#L8{DkVxe1Zu&r?FB zLL^(#hsejx2CaDkxjgL&%GR9Rmz)Xeynt@^h`fi`Yn1zXn_fWPl9r$7$b(qgTISRH zyTT=@u4)^Cpza$2Euot33Y)@s2_(k4!B-ld#`$W4tDjR(a=377R?L*D($D@`0N_n$ zcb~l!SstJl7Lh;oB&Y3Hj7fRJzbTqasBV0gZ7VrG@;PI}1Dg~BHF{KgX&_6|x) z%fQb?>hAl&ub!^IIEZvarmYbl7pW_&{;zJHnA8jF>il5kprp<_$iY&SHiPO#-TU){ zm2A*7PKXQJV4O}OL zpmuDLw|ZEbU~OhB9*GaaJMqHA+Ql;K8Fw|I(}@w=u&x17v37A^{V%@Ve%}cVI7lP_ z|M%(+Gl=sC4LIll95jRg-lt_Cb4~c&IIK`Pwz)yMz+ritG-zVk`~Ld;e`(6|JjYbF Q_5c6?07*qoM6N<$f(UJ|)Bpeg literal 0 HcmV?d00001 diff --git a/Pictures/Legacy/ShopCalculator7.png b/Pictures/Legacy/ShopCalculator7.png new file mode 100644 index 0000000000000000000000000000000000000000..d330c8e239c66646d41cc9ac23b4193dec2b8329 GIT binary patch literal 642 zcmV-|0)737P)Nkl9ejZ)hQ z@&Do`_9slYJ#7;_lz9oz;*|0b0iLaA3rR1qj?UmPKn58z%~P99KXat zQyt;t`#e$BIb{ZPC3qrzEK&oy6udwc(~bdM3|=6M%@;vqg=B2^K`NdaWvrP2$v9gk z4@MHEghZK%3Fa96ftv#DEQFpWEYkZ*@NJmA4md^Y^X^M%y5>8Qy4o z5!3~or)Z8iE(D*=PBy>187S}u_qXU7$4vq|uN?w>1V3 z5%u3*;hL>5AdQAB!4tK>0It**u&o05j@KPMp}{r!M2rTAPN&guXB5iRk?Q zp?XBV2JmJ8$B3bEJ_DRLfOQItu2^F*psC$p4$KUQ zr$I>M@Smjt9k7k_HDJd8-3LZ(M;4nj1G;E}DkkL==#mM#ShPj3OD3prz6fqIKzvK< c8qR0HA8-B7Ju?P;0000007*qoM6N<$f|mRh6#xJL literal 0 HcmV?d00001 diff --git a/Pictures/Legacy/ShopOcteractAmbrosiaLuck.png b/Pictures/Legacy/ShopOcteractAmbrosiaLuck.png new file mode 100644 index 0000000000000000000000000000000000000000..c84684db37662dfbe2c33b518a7b124c95b18689 GIT binary patch literal 1245 zcmV<31S0#1P)yeYF0m2|wXraPaDuAef{^kR40$zS!=6yPDBK0 zE@(jNF}gvoRXeBDE`UuWr!&F;d4#IPB}J?YOiY83P_v4%IUXXxWT$@EVQ`WVmIP+s zMG#vQ%BzIZ7|Qs*61+9D9vb@)KQVDG;7u8BxG+OVKL#{Fd&8Te*s-l#fB?|Hpowk+ zQ3{YpZGJ@lEKsmr%a87?@u6z2z#?E*vuBinB+EtDW!j&cE0AKumG zuRW@B7r-Xc>D+Q><_YCX*QU1nL_+*j##gW}c(ui4TH@Zr0qngUNTi0w&{QfN1u4fJKkNH^AM7h+YBGW=0RV zfN66EAdv-xO-qgTSwl}R+3Pw%47jcqq44D_1}t4yfn&hrJHe(XPqVo9CSZWd2iE3k z-#;rC2qCQ5@K>G8v?vUVLX7Y_dP!YVs{m>1I<$w!*EE$65Qa|xhEMFc>h!U*9EC4| z@2IW#+|~hDA7{-F_c>Q^axk(xFaxGHEtQV2?~HGr#i4Hi0MHsXTUr!7TksTsvH+&9 zIwOYk&3%86TK$TkhG$hwOan!IMRLJY0Le@)DCMZL0|0SKrjaVCs7d)&T+I+c!4ZIkM0=rNI75L91_ex1q(n0C#O23iG3 zr?iXe-E=EM)0)6`t)Lk}?l16dI&}tc^fAN@K;o=(+D*{Y>*7k#1|}iXo4&)9poG<% zwIv=v;9E_w5RqU{@P;VF*`8ns;eo}i>pY;R=P(9HCd1rV=svRA5b1F^ITsL5Z1Mn$ zUY_Ry*Ah&=@6HCJ&fxTCYT>rc%}TCkgL-;lzBq|og{b^`m-%>kgLAZhxp5JnBIB)5 zC=K?yBQAeX0y|GIFejc{WP6!;@bd=QNmAT2IXM+ANXetC1&CUAjVOBUHro_F>ohqc zKUFTz+2&m$Use`iI}b@x(Xz(q&We!2X9xDSIEpD(9(5&4TnB6-!5qo_S%9SgZ(7$% zfYt6Q!7ADt5UYUbl=JRcLO^#v-8cmR^M7?5bYrpPLg~KDPL9S@C1ha{S&i@Pr>U&n zAgl3%*I*hqxM>h&EtqcfDpVOmE+9V8D}R$lO)TE_-{=1W7?5J)qglZT00000NkvXX Hu0mjf4CF=- literal 0 HcmV?d00001 diff --git a/Pictures/Legacy/perkdilatedFiveLeaf.png b/Pictures/Legacy/perkdilatedFiveLeaf.png new file mode 100644 index 0000000000000000000000000000000000000000..e60b92eb1d305404003154a32051db8ae5a4d7f8 GIT binary patch literal 916 zcmV;F18e+=P)4Tx0C=2zkv&MmKpe$iTT4YM4i>E9kfDl$1yK=4sbUc+gyEO_^lTK1F2KZkr>th56>;lcYWqlu8R`Ue#Jp)&2+h1(}v!A5b z+gjuZ=-UP^uG^Zl2VCv|;U`VhMO*UG^cD)h`x$*x4(PuHde)rYTKhPC05a6o@(pls z2#gjfd)?*T-JQMtd#2Uj54KQp!WQ$)SpWb44rN$LW=%~1DgXcg2mk;800000(o>TF z00FQ`L_t(|oXuA|Zi7G&9V{9wB{dxdSBRVoxIuzc?vlohOT(-F6OPbb;M=K8jQH6-E~@ zL60%JJ`r~^f{O`Wl`Uy?O)-keCnvOQ;qP!e$V%gVGZa?MSH z>gVO%kezb&y$B%Ii`CV=I7`4ygR0DnE2n6WHUI!+UXW_cIH#QSLxUxt14fC_uNSN4 zC)=PM6%?5QRqj<}RBLgTkn6n_7z$bfs_2G*whQ7cVY`64=47Y3fF)4oMQvbPZ2peL z0X)lBlEL?I1Bpz5Zh8%g-d%7k4y}LB@&TY-GjWzQZR+foRi_jnNE^e-No4&wd%VsKurLAC{|HbbbqTbATiu?(uRIU1|eA zSX7w221o_Yo0CEA-NIOwl|ZQnA%G;P`$&u<(shjAX9`phBXrZC`tM-sOhAN~_r5#m q**9_3R!jDS9zPJutXN73(S0AQN{00004Tx0C=2zkv&MmKpe$iTT4YM4i>E9kfDl$1yK=4sbUc+gyEO_^lTK1F2KZkr>th56>;lcYWqlu8R`Ue#Jp)&2+h1(}v!A5b z+gjuZ=-UP^uG^Zl2VCv|;U`VhMO*UG^cD)h`x$*x4(PuHde)rYTKhPC05a6o@(pls z2#gjfd)?*T-JQMtd#2Uj54KQp!WQ$)SpWb44rN$LW=%~1DgXcg2mk;800000(o>TF z00F#7L_t(|oXuCgio!q;o;?l(@eY&}TG%DEjbQC_7+)cz@G&gJS4i$TZ11>hthKZ7 z3W*>gkZP}x3F|tu`7x({Ad>84=bLYSmKC4hZxSAeR{((Jq6wa#z;e;Ni&OOF`3VSB zfzj|J?m^(|=RNb8Dew{glFnD{9+{%?abL)uvKtLgV&ZnC=OOw97Q*?D8w+qrBWV?WS=47Y3fF-bwV*of850}5g zd<)jhHj=@8xWPrHfHVFNRPKVqe0%Y4&1?X;teG?jvo>9|d$Lpt5PJSmUTbDwIj6qm z(q|-Kie4=+)p6BsVHMyu%!{Zjo_`RTpwE6CMbu(bfFJ8stvWA)yg5J;P|tWhiZZp) z*=@u)hv36&fK*_7+zaaLR>!ig1WJ9ePgMd)f_jg{1`Lt1WBfT&V1gQ9)OX~qgQ+wD z6>8qAo}f1osN>jvo~xPXCopllcex9AKG2ubN8k_rG}n(VX|&(~0000b;@5S)wL_y=?;_=8_Sg9NGk0XIB~h7V8?BpP18A5zfe2W}#nB3iPTo!hfx=~866 z)9rcpW@gtHx~@Y`ykyP(UjTr@3wYfwOp{zU=a3T5;@kq{L&dB#_veRo_wn`~`bk+l zLttH?3uvnPX@7Uw0|350+oz-wFEJ8lv60;aCIfv+Ee3$c8>YlqEKm;&(UK+Cd%6&f z>=L*I#BMhQ+&Qqj?4w;^tr_iB7bKaG;nW_nELU_N_%i3?kP9ef{O5%W`!ug2~WSHEq9W0kPX_gXzR$yM;24GTElU-ycLVG*um?K7}nR zfgEP8PSxC-1B2TzWhx5f!4gAu510~MH|Joz1&di}N(1~*Jrwjw#?XH&%CPaYX2>qV zUArtists

a0

a0

a0

+

a0

+

a0

+

Multipliers (Additive)0

TOTAL AMBROSIA LUCK: 0

@@ -3852,6 +3855,21 @@

Artists

+
+ Ambrosia Luck Multiplier 4 +

+ +
+
+ Calculator 7 +

+ +
+
+ Octeract-Based Ambrosia Luck +

+ +
Ambrosia Generation Improvement 1

diff --git a/src/BlueberryUpgrades.ts b/src/BlueberryUpgrades.ts index 4a1484b91..ce073a258 100644 --- a/src/BlueberryUpgrades.ts +++ b/src/BlueberryUpgrades.ts @@ -412,7 +412,7 @@ export const blueberryUpgradeData: Record< }, rewards: (n: number) => { const baseVal = 0.0002 * n; - const val = 1 + baseVal * player.caches.ambrosiaLuck.totalVal; + const val = 1 + baseVal * player.caches.ambrosiaLuck.usedTotal; return { cubes: val, desc: String( @@ -470,8 +470,9 @@ export const blueberryUpgradeData: Record< rewards: (n: number) => { const baseVal = 0.0001 * n; const effectiveLuck = Math.min( - player.caches.ambrosiaLuck.totalVal, - Math.pow(1000, 0.5) * Math.pow(player.caches.ambrosiaLuck.totalVal, 0.5) + player.caches.ambrosiaLuck.usedTotal, + Math.pow(1000, 0.5) * + Math.pow(player.caches.ambrosiaLuck.usedTotal, 0.5) ); const val = 1 + baseVal * effectiveLuck; return { @@ -667,7 +668,7 @@ export const blueberryUpgradeData: Record< return baseCost + 0 * level; }, rewards: (n: number) => { - const luck = player.caches.ambrosiaLuck.totalVal; + const luck = player.caches.ambrosiaLuck.usedTotal; return { luckMult: n, obtainiumMult: n * luck, @@ -687,7 +688,7 @@ export const blueberryUpgradeData: Record< return baseCost + 0 * level; }, rewards: (n: number) => { - const luck = player.caches.ambrosiaLuck.totalVal; + const luck = player.caches.ambrosiaLuck.usedTotal; return { luckMult: n, offeringMult: n * luck, diff --git a/src/Calculate.ts b/src/Calculate.ts index 39f297b8a..7b30f1470 100644 --- a/src/Calculate.ts +++ b/src/Calculate.ts @@ -2408,9 +2408,9 @@ export const calculateSingularityQuarkMilestoneMultiplier = () => { let multiplier = 1; // dprint-ignore const singThresholds = [ - 5, 20, 35, 50, 65, 80, 90, 100, 121, 144, 150, 160, 166, 169, 170, 175, 180, - 190, 196, 200, 200, 201, 202, 203, 204, 205, 210, 212, 214, 216, 218, 220, - 225, 250, + 5, 7, 10, 20, 35, 50, 65, 80, 90, 100, 121, 144, 150, 160, 166, 169, 170, + 175, 180, 190, 196, 200, 201, 202, 203, 204, 205, 210, 212, 214, 216, 218, + 220, 225, 250, 255, 260, 261, 262, ]; for (const sing of singThresholds) { if (player.highestSingularityCount >= sing) { @@ -3242,7 +3242,7 @@ export const calculateRequiredBlueberryTime = () => { export const calculateSingularityMilestoneBlueberries = () => { let val = 0; - if (player.highestSingularityCount >= 254) val = 4; + if (player.highestSingularityCount >= 264) val = 4; else if (player.highestSingularityCount >= 198) val = 3; else if (player.highestSingularityCount >= 132) val = 2; else if (player.highestSingularityCount >= 66) val = 1; @@ -3282,6 +3282,15 @@ export const calculateAmbrosiaQuarkMult = () => { return multiplier; }; +export const calculateDilatedFiveLeafBonus = () => { + const singThresholds = [100, 200, 250, 260, 266]; + for (let i = 0; i < singThresholds.length; i++) { + if (player.highestSingularityCount <= singThresholds[i]) return i / 100; + } + + return singThresholds.length / 100; +}; + export const dailyResetCheck = () => { if (!player.dayCheck) { return; diff --git a/src/CheckVariables.ts b/src/CheckVariables.ts index 4f08fa087..a42df2a7e 100644 --- a/src/CheckVariables.ts +++ b/src/CheckVariables.ts @@ -37,6 +37,7 @@ import { } from "./SingularityChallenges"; import { AmbrosiaGenerationCache, + AmbrosiaLuckAdditiveMultCache, AmbrosiaLuckCache, BlueberryInventoryCache, cacheReinitialize, @@ -1009,6 +1010,7 @@ export const checkVariablesOnLoad = (data: PlayerSave) => { calculator4: 0, calculator5: 0, calculator6: 0, + calculator7: 0, constantEX: 0, powderEX: 0, chronometer2: 0, @@ -1041,6 +1043,8 @@ export const checkVariablesOnLoad = (data: PlayerSave) => { seasonPassInfinity: 0, chronometerInfinity: 0, shopSingularityPenaltyDebuff: 0, + shopAmbrosiaLuckMultiplier4: 0, + shopOcteractAmbrosiaLuck: 0, shopAmbrosiaGeneration1: 0, shopAmbrosiaGeneration2: 0, shopAmbrosiaGeneration3: 0, @@ -1436,6 +1440,7 @@ export const checkVariablesOnLoad = (data: PlayerSave) => { singularityRequirement: singularityChallengeData[k].singularityRequirement, effect: singularityChallengeData[k].effect, + cacheUpdates: singularityChallengeData[k].cacheUpdates, }; player.singularityChallenges[k] = new SingularityChallenge( updatedData, @@ -1634,6 +1639,7 @@ export const checkVariablesOnLoad = (data: PlayerSave) => { } player.caches = { + ambrosiaLuckAdditiveMult: new AmbrosiaLuckAdditiveMultCache(), ambrosiaLuck: new AmbrosiaLuckCache(), ambrosiaGeneration: new AmbrosiaGenerationCache(), blueberryInventory: new BlueberryInventoryCache(), diff --git a/src/Config.ts b/src/Config.ts index f849dac65..e48e11407 100644 --- a/src/Config.ts +++ b/src/Config.ts @@ -1,4 +1,4 @@ -export const version = '3.0.0 pt 3: December 13, 2023: Quarks' +export const version = "3.0.0 pt 4: March 9, 2024: EXALTed Upgrades"; /** * PSEUDO DO NOT CHANGE THIS LINE @@ -8,9 +8,9 @@ export const version = '3.0.0 pt 3: December 13, 2023: Quarks' * PSEUDO DO NOT CHANGE THIS LINE * PSEUDO DO NOT CHANGE THIS LINE */ -export const testing: boolean = false -export const lastUpdated = new Date('##LAST_UPDATED##') +export const testing: boolean = false; +export const lastUpdated = new Date("##LAST_UPDATED##"); /** * CHANGE THIS ONE INSTEAD */ -export const prod: boolean = false +export const prod: boolean = false; diff --git a/src/EventListeners.ts b/src/EventListeners.ts index 716a63611..f07d1115c 100644 --- a/src/EventListeners.ts +++ b/src/EventListeners.ts @@ -1,20 +1,23 @@ -import i18next from 'i18next' -import { achievementdescriptions, achievementpointvalues } from './Achievements' +import i18next from "i18next"; +import { + achievementdescriptions, + achievementpointvalues, +} from "./Achievements"; import { antRepeat, antUpgradeDescription, buyAntProducers, buyAntUpgrade, sacrificeAnts, - updateAntDescription -} from './Ants' + updateAntDescription, +} from "./Ants"; import { createLoadoutDescription, exportBlueberryTree, importBlueberryTree, loadoutHandler, - resetBlueberryTree -} from './BlueberryUpgrades' + resetBlueberryTree, +} from "./BlueberryUpgrades"; import { boostAccelerator, buyAccelerator, @@ -24,25 +27,25 @@ import { buyParticleBuilding, buyProducer, buyRuneBonusLevels, - buyTesseractBuilding -} from './Buy' -import { DOMCacheGetOrSet } from './Cache/DOM' -import { exitOffline, forcedDailyReset, timeWarp } from './Calculate' -import { challengeDisplay, toggleRetryChallenges } from './Challenges' -import { testing } from './Config' -import { corruptionCleanseConfirm, corruptionDisplay } from './Corruptions' -import { buyCubeUpgrades, cubeUpgradeDesc } from './Cubes' -import { clickSmith } from './Event' + buyTesseractBuilding, +} from "./Buy"; +import { DOMCacheGetOrSet } from "./Cache/DOM"; +import { exitOffline, forcedDailyReset, timeWarp } from "./Calculate"; +import { challengeDisplay, toggleRetryChallenges } from "./Challenges"; +import { testing } from "./Config"; +import { corruptionCleanseConfirm, corruptionDisplay } from "./Corruptions"; +import { buyCubeUpgrades, cubeUpgradeDesc } from "./Cubes"; +import { clickSmith } from "./Event"; import { hepteractDescriptions, hepteractToOverfluxOrbDescription, overfluxPowderDescription, overfluxPowderWarp, toggleAutoBuyOrbs, - tradeHepteractToOverfluxOrb -} from './Hepteracts' -import { resetHistoryTogglePerSecond } from './History' -import { resetHotkeys } from './Hotkeys' + tradeHepteractToOverfluxOrb, +} from "./Hepteracts"; +import { resetHistoryTogglePerSecond } from "./History"; +import { resetHotkeys } from "./Hotkeys"; import { addCodeAvailableUses, exportSynergism, @@ -53,18 +56,34 @@ import { promocodesPrompt, reloadDeleteGame, resetGame, - updateSaveString -} from './ImportExport' -import { buyPlatonicUpgrades, createPlatonicDescription } from './Platonic' -import { buyResearch, researchDescriptions } from './Research' -import { resetrepeat, updateAutoCubesOpens, updateAutoReset, updateTesseractAutoBuyAmount } from './Reset' -import { displayRuneInformation, redeemShards } from './Runes' -import { buyShopUpgrades, resetShopUpgrades, shopData, shopDescriptions, shopUpgradeTypes, useConsumable } from './Shop' -import { buyGoldenQuarks, getLastUpgradeInfo, singularityPerks } from './singularity' -import { displayStats } from './Statistics' -import { generateExportSummary } from './Summary' -import { player, resetCheck, saveSynergy } from './Synergism' -import { changeSubTab, Tabs } from './Tabs' + updateSaveString, +} from "./ImportExport"; +import { buyPlatonicUpgrades, createPlatonicDescription } from "./Platonic"; +import { buyResearch, researchDescriptions } from "./Research"; +import { + resetrepeat, + updateAutoCubesOpens, + updateAutoReset, + updateTesseractAutoBuyAmount, +} from "./Reset"; +import { displayRuneInformation, redeemShards } from "./Runes"; +import { + buyShopUpgrades, + resetShopUpgrades, + shopData, + shopDescriptions, + shopUpgradeTypes, + useConsumable, +} from "./Shop"; +import { + buyGoldenQuarks, + getLastUpgradeInfo, + singularityPerks, +} from "./singularity"; +import { displayStats } from "./Statistics"; +import { generateExportSummary } from "./Summary"; +import { player, resetCheck, saveSynergy } from "./Synergism"; +import { changeSubTab, Tabs } from "./Tabs"; import { buyAllTalismanResources, buyTalismanEnhance, @@ -78,9 +97,15 @@ import { showTalismanEffect, showTalismanPrices, toggleTalismanBuy, - updateTalismanCostDisplay -} from './Talismans' -import { IconSets, imgErrorHandler, toggleAnnotation, toggleIconSet, toggleTheme } from './Themes' + updateTalismanCostDisplay, +} from "./Talismans"; +import { + IconSets, + imgErrorHandler, + toggleAnnotation, + toggleIconSet, + toggleTheme, +} from "./Themes"; import { autoCubeUpgradesToggle, autoPlatonicUpgradesToggle, @@ -114,20 +139,20 @@ import { toggleShopConfirmation, toggleShops, updateAutoChallenge, - updateRuneBlessingBuyAmount -} from './Toggles' -import type { OneToFive, Player } from './types/Synergism' -import { Confirm } from './UpdateHTML' -import { shopMouseover } from './UpdateVisuals' + updateRuneBlessingBuyAmount, +} from "./Toggles"; +import type { OneToFive, Player } from "./types/Synergism"; +import { Confirm } from "./UpdateHTML"; +import { shopMouseover } from "./UpdateVisuals"; import { buyConstantUpgrades, categoryUpgrades, clickUpgrades, constantUpgradeDescriptions, crystalupgradedescriptions, - upgradedescriptions -} from './Upgrades' -import { Globals as G } from './Variables' + upgradedescriptions, +} from "./Upgrades"; +import { Globals as G } from "./Variables"; /* STYLE GUIDE */ /* @@ -147,643 +172,1053 @@ import { Globals as G } from './Variables' */ export const generateEventHandlers = () => { - const ordinals = ['null', 'first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth'] as const + const ordinals = [ + "null", + "first", + "second", + "third", + "fourth", + "fifth", + "sixth", + "seventh", + "eighth", + ] as const; if (testing) { - const warp = document.createElement('button') - const dayReset = document.createElement('button') - warp.textContent = 'Click here to warp time! [TESTING ONLY]' - warp.setAttribute('style', 'width: auto; height: 30px; border: 6px solid gold;') - warp.addEventListener('click', () => timeWarp()) - dayReset.textContent = 'Click to force a new day! [TESTING ONLY]' - dayReset.setAttribute('style', 'width: auto; height: 30px; border: 6px solid orange;') - dayReset.addEventListener('click', () => forcedDailyReset()) - - const consumables = DOMCacheGetOrSet('actualConsumables') - consumables.appendChild(warp) - consumables.appendChild(dayReset) + const warp = document.createElement("button"); + const dayReset = document.createElement("button"); + warp.textContent = "Click here to warp time! [TESTING ONLY]"; + warp.setAttribute( + "style", + "width: auto; height: 30px; border: 6px solid gold;" + ); + warp.addEventListener("click", () => timeWarp()); + dayReset.textContent = "Click to force a new day! [TESTING ONLY]"; + dayReset.setAttribute( + "style", + "width: auto; height: 30px; border: 6px solid orange;" + ); + dayReset.addEventListener("click", () => forcedDailyReset()); + + const consumables = DOMCacheGetOrSet("actualConsumables"); + consumables.appendChild(warp); + consumables.appendChild(dayReset); } // Offline Button - DOMCacheGetOrSet('exitOffline').addEventListener('click', () => exitOffline()) - DOMCacheGetOrSet('offlineContainer').addEventListener('dblclick', () => exitOffline()) + DOMCacheGetOrSet("exitOffline").addEventListener("click", () => + exitOffline() + ); + DOMCacheGetOrSet("offlineContainer").addEventListener("dblclick", () => + exitOffline() + ); // UPPER UI ELEMENTS // Prelude: Cube/Tesseract/Hypercube/Platonic display UIs (Onclicks) - DOMCacheGetOrSet('ascCubeStats').addEventListener('click', () => toggleAscStatPerSecond(1)) - DOMCacheGetOrSet('ascTessStats').addEventListener('click', () => toggleAscStatPerSecond(2)) - DOMCacheGetOrSet('ascHyperStats').addEventListener('click', () => toggleAscStatPerSecond(3)) - DOMCacheGetOrSet('ascPlatonicStats').addEventListener('click', () => toggleAscStatPerSecond(4)) - DOMCacheGetOrSet('ascHepteractStats').addEventListener('click', () => toggleAscStatPerSecond(5)) - DOMCacheGetOrSet('ascTimeTakenStats').addEventListener('click', () => toggleAscStatPerSecond(6)) + DOMCacheGetOrSet("ascCubeStats").addEventListener("click", () => + toggleAscStatPerSecond(1) + ); + DOMCacheGetOrSet("ascTessStats").addEventListener("click", () => + toggleAscStatPerSecond(2) + ); + DOMCacheGetOrSet("ascHyperStats").addEventListener("click", () => + toggleAscStatPerSecond(3) + ); + DOMCacheGetOrSet("ascPlatonicStats").addEventListener("click", () => + toggleAscStatPerSecond(4) + ); + DOMCacheGetOrSet("ascHepteractStats").addEventListener("click", () => + toggleAscStatPerSecond(5) + ); + DOMCacheGetOrSet("ascTimeTakenStats").addEventListener("click", () => + toggleAscStatPerSecond(6) + ); // Part 1: Reset Tiers // Onmouseover Events - DOMCacheGetOrSet('prestigebtn').addEventListener('mouseover', () => resetrepeat('prestige')) - DOMCacheGetOrSet('transcendbtn').addEventListener('mouseover', () => resetrepeat('transcension')) - DOMCacheGetOrSet('reincarnatebtn').addEventListener('mouseover', () => resetrepeat('reincarnation')) - DOMCacheGetOrSet('acceleratorboostbtn').addEventListener('mouseover', () => resetrepeat('acceleratorBoost')) - DOMCacheGetOrSet('challengebtn').addEventListener('mouseover', () => resetrepeat('transcensionChallenge')) - DOMCacheGetOrSet('reincarnatechallengebtn').addEventListener('mouseover', () => resetrepeat('reincarnationChallenge')) - DOMCacheGetOrSet('ascendChallengeBtn').addEventListener('mouseover', () => resetrepeat('ascensionChallenge')) - DOMCacheGetOrSet('ascendbtn').addEventListener('mouseover', () => resetrepeat('ascension')) - DOMCacheGetOrSet('singularitybtn').addEventListener('mouseover', () => resetrepeat('singularity')) - - for (const resetButton of Array.from(document.getElementsByClassName('resetbtn'))) { - resetButton.addEventListener('mouseover', () => { - resetButton.classList.add('hover') - }) - - resetButton.addEventListener('mouseout', () => { - resetButton.classList.remove('hover') + DOMCacheGetOrSet("prestigebtn").addEventListener("mouseover", () => + resetrepeat("prestige") + ); + DOMCacheGetOrSet("transcendbtn").addEventListener("mouseover", () => + resetrepeat("transcension") + ); + DOMCacheGetOrSet("reincarnatebtn").addEventListener("mouseover", () => + resetrepeat("reincarnation") + ); + DOMCacheGetOrSet("acceleratorboostbtn").addEventListener("mouseover", () => + resetrepeat("acceleratorBoost") + ); + DOMCacheGetOrSet("challengebtn").addEventListener("mouseover", () => + resetrepeat("transcensionChallenge") + ); + DOMCacheGetOrSet("reincarnatechallengebtn").addEventListener( + "mouseover", + () => resetrepeat("reincarnationChallenge") + ); + DOMCacheGetOrSet("ascendChallengeBtn").addEventListener("mouseover", () => + resetrepeat("ascensionChallenge") + ); + DOMCacheGetOrSet("ascendbtn").addEventListener("mouseover", () => + resetrepeat("ascension") + ); + DOMCacheGetOrSet("singularitybtn").addEventListener("mouseover", () => + resetrepeat("singularity") + ); + + for (const resetButton of Array.from( + document.getElementsByClassName("resetbtn") + )) { + resetButton.addEventListener("mouseover", () => { + resetButton.classList.add("hover"); + }); + + resetButton.addEventListener("mouseout", () => { + resetButton.classList.remove("hover"); if (player.currentChallenge.reincarnation) { - resetrepeat('reincarnationChallenge') + resetrepeat("reincarnationChallenge"); } else if (player.currentChallenge.transcension) { - resetrepeat('transcensionChallenge') + resetrepeat("transcensionChallenge"); } - }) + }); } // Onclick Events (this is particularly bad) - DOMCacheGetOrSet('prestigebtn').addEventListener('click', () => resetCheck('prestige')) - DOMCacheGetOrSet('transcendbtn').addEventListener('click', () => resetCheck('transcension')) - DOMCacheGetOrSet('reincarnatebtn').addEventListener('click', () => resetCheck('reincarnation')) - DOMCacheGetOrSet('acceleratorboostbtn').addEventListener('click', () => boostAccelerator()) - DOMCacheGetOrSet('challengebtn').addEventListener('click', () => resetCheck('transcensionChallenge', undefined, true)) - DOMCacheGetOrSet('reincarnatechallengebtn').addEventListener( - 'click', - () => resetCheck('reincarnationChallenge', undefined, true) - ) - DOMCacheGetOrSet('ascendChallengeBtn').addEventListener('click', () => resetCheck('ascensionChallenge')) - DOMCacheGetOrSet('ascendbtn').addEventListener('click', () => resetCheck('ascension')) - DOMCacheGetOrSet('singularitybtn').addEventListener('click', () => resetCheck('singularity')) + DOMCacheGetOrSet("prestigebtn").addEventListener("click", () => + resetCheck("prestige") + ); + DOMCacheGetOrSet("transcendbtn").addEventListener("click", () => + resetCheck("transcension") + ); + DOMCacheGetOrSet("reincarnatebtn").addEventListener("click", () => + resetCheck("reincarnation") + ); + DOMCacheGetOrSet("acceleratorboostbtn").addEventListener("click", () => + boostAccelerator() + ); + DOMCacheGetOrSet("challengebtn").addEventListener("click", () => + resetCheck("transcensionChallenge", undefined, true) + ); + DOMCacheGetOrSet("reincarnatechallengebtn").addEventListener("click", () => + resetCheck("reincarnationChallenge", undefined, true) + ); + DOMCacheGetOrSet("ascendChallengeBtn").addEventListener("click", () => + resetCheck("ascensionChallenge") + ); + DOMCacheGetOrSet("ascendbtn").addEventListener("click", () => + resetCheck("ascension") + ); + DOMCacheGetOrSet("singularitybtn").addEventListener("click", () => + resetCheck("singularity") + ); // BUILDINGS TAB // Part 1: Upper portion (Subtab toggle) - const buildingTypes = ['Coin', 'Diamond', 'Mythos', 'Particle', 'Tesseract'] + const buildingTypes = ["Coin", "Diamond", "Mythos", "Particle", "Tesseract"]; for (let index = 0; index < buildingTypes.length; index++) { - DOMCacheGetOrSet(`switchTo${buildingTypes[index]}Building`).addEventListener( - 'click', - () => changeSubTab(Tabs.Buildings, { page: index }) - ) + DOMCacheGetOrSet( + `switchTo${buildingTypes[index]}Building` + ).addEventListener("click", () => + changeSubTab(Tabs.Buildings, { page: index }) + ); } // Part 2: Building Amount Toggles - const buildingTypesAlternate = ['coin', 'crystal', 'mythos', 'particle', 'tesseract', 'offering'] as const - const buildingOrds = ['one', 'ten', 'hundred', 'thousand', '10k', '100k'] - const buildingOrdsToNum = [1, 10, 100, 1000, 10000, 100000] as const + const buildingTypesAlternate = [ + "coin", + "crystal", + "mythos", + "particle", + "tesseract", + "offering", + ] as const; + const buildingOrds = ["one", "ten", "hundred", "thousand", "10k", "100k"]; + const buildingOrdsToNum = [1, 10, 100, 1000, 10000, 100000] as const; for (let index = 0; index < buildingOrds.length; index++) { for (let index2 = 0; index2 < buildingTypesAlternate.length; index2++) { - DOMCacheGetOrSet(buildingTypesAlternate[index2] + buildingOrds[index]).addEventListener( - 'click', - () => - toggleBuyAmount( - buildingOrdsToNum[index], - buildingTypesAlternate[index2] - ) - ) + DOMCacheGetOrSet( + buildingTypesAlternate[index2] + buildingOrds[index] + ).addEventListener("click", () => + toggleBuyAmount( + buildingOrdsToNum[index], + buildingTypesAlternate[index2] + ) + ); } } // Part 3: Building Purchasers + Upgrades // Accelerator, Multiplier, Accelerator Boost - DOMCacheGetOrSet('buyaccelerator').addEventListener('click', () => buyAccelerator()) - DOMCacheGetOrSet('buymultiplier').addEventListener('click', () => buyMultiplier()) - DOMCacheGetOrSet('buyacceleratorboost').addEventListener('click', () => boostAccelerator()) + DOMCacheGetOrSet("buyaccelerator").addEventListener("click", () => + buyAccelerator() + ); + DOMCacheGetOrSet("buymultiplier").addEventListener("click", () => + buyMultiplier() + ); + DOMCacheGetOrSet("buyacceleratorboost").addEventListener("click", () => + boostAccelerator() + ); // Coin, Diamond and Mythos Buildings - const buildingTypesAlternate2 = ['coin', 'diamond', 'mythos'] - const buildingTypesAlternate3 = ['Coin', 'Diamonds', 'Mythos'] as const // TODO: A cleaner way to implement this dumb shit + const buildingTypesAlternate2 = ["coin", "diamond", "mythos"]; + const buildingTypesAlternate3 = ["Coin", "Diamonds", "Mythos"] as const; // TODO: A cleaner way to implement this dumb shit for (let index = 0; index < 3; index++) { for (let index2 = 1; index2 <= 5; index2++) { - DOMCacheGetOrSet(`buy${buildingTypesAlternate2[index]}${index2}`).addEventListener( - 'click', - () => - buyProducer( - ordinals[index2 as OneToFive], - buildingTypesAlternate3[index], - index === 0 ? index2 : index2 * (index2 + 1) / 2 - ) - ) + DOMCacheGetOrSet( + `buy${buildingTypesAlternate2[index]}${index2}` + ).addEventListener("click", () => + buyProducer( + ordinals[index2 as OneToFive], + buildingTypesAlternate3[index], + index === 0 ? index2 : (index2 * (index2 + 1)) / 2 + ) + ); } } // Crystal Upgrades (Mouseover and Onclick) for (let index = 1; index <= 5; index++) { - DOMCacheGetOrSet(`buycrystalupgrade${index}`).addEventListener('mouseover', () => crystalupgradedescriptions(index)) - DOMCacheGetOrSet(`buycrystalupgrade${index}`).addEventListener('click', () => buyCrystalUpgrades(index)) + DOMCacheGetOrSet(`buycrystalupgrade${index}`).addEventListener( + "mouseover", + () => crystalupgradedescriptions(index) + ); + DOMCacheGetOrSet(`buycrystalupgrade${index}`).addEventListener( + "click", + () => buyCrystalUpgrades(index) + ); } // Particle Buildings for (let index = 0; index < 5; index++) { - DOMCacheGetOrSet(`buyparticles${index + 1}`).addEventListener('click', () => - buyParticleBuilding( - index + 1 as OneToFive - )) + DOMCacheGetOrSet(`buyparticles${index + 1}`).addEventListener("click", () => + buyParticleBuilding((index + 1) as OneToFive) + ); } // Tesseract Buildings for (let index = 0; index < 5; index++) { DOMCacheGetOrSet(`buyTesseracts${index + 1}`).addEventListener( - 'click', - () => buyTesseractBuilding(index + 1 as OneToFive) - ) - DOMCacheGetOrSet(`tesseractAutoToggle${index + 1}`).addEventListener('click', () => toggleAutoTesseracts(index + 1)) + "click", + () => buyTesseractBuilding((index + 1) as OneToFive) + ); + DOMCacheGetOrSet(`tesseractAutoToggle${index + 1}`).addEventListener( + "click", + () => toggleAutoTesseracts(index + 1) + ); } // Constant Upgrades for (let index = 0; index < 10; index++) { DOMCacheGetOrSet(`buyConstantUpgrade${index + 1}`).addEventListener( - 'mouseover', + "mouseover", () => constantUpgradeDescriptions(index + 1) - ) - DOMCacheGetOrSet(`buyConstantUpgrade${index + 1}`).addEventListener('click', () => buyConstantUpgrades(index + 1)) + ); + DOMCacheGetOrSet(`buyConstantUpgrade${index + 1}`).addEventListener( + "click", + () => buyConstantUpgrades(index + 1) + ); } // Part 4: Toggles // I'm just addressing all global toggles here - const toggles = document.querySelectorAll('.auto[toggleid]') - toggles.forEach((b) => b.addEventListener('click', () => toggleSettings(b))) + const toggles = document.querySelectorAll(".auto[toggleid]"); + toggles.forEach((b) => b.addEventListener("click", () => toggleSettings(b))); // Toggles auto reset type (between TIME and AMOUNT for 3 first Tiers, and between PERCENTAGE and AMOUNT for Tesseracts) - DOMCacheGetOrSet('prestigeautotoggle').addEventListener('click', () => toggleautoreset(1)) - DOMCacheGetOrSet('transcendautotoggle').addEventListener('click', () => toggleautoreset(2)) - DOMCacheGetOrSet('reincarnateautotoggle').addEventListener('click', () => toggleautoreset(3)) - DOMCacheGetOrSet('tesseractautobuymode').addEventListener('click', () => toggleautoreset(4)) + DOMCacheGetOrSet("prestigeautotoggle").addEventListener("click", () => + toggleautoreset(1) + ); + DOMCacheGetOrSet("transcendautotoggle").addEventListener("click", () => + toggleautoreset(2) + ); + DOMCacheGetOrSet("reincarnateautotoggle").addEventListener("click", () => + toggleautoreset(3) + ); + DOMCacheGetOrSet("tesseractautobuymode").addEventListener("click", () => + toggleautoreset(4) + ); // Toggles auto reset amount required to trigger - DOMCacheGetOrSet('prestigeamount').addEventListener('blur', () => updateAutoReset(1)) - DOMCacheGetOrSet('transcendamount').addEventListener('blur', () => updateAutoReset(2)) - DOMCacheGetOrSet('reincarnationamount').addEventListener('blur', () => updateAutoReset(3)) - DOMCacheGetOrSet('ascensionAmount').addEventListener('blur', () => updateAutoReset(4)) - DOMCacheGetOrSet('autoAntSacrificeAmount').addEventListener('blur', () => updateAutoReset(5)) + DOMCacheGetOrSet("prestigeamount").addEventListener("blur", () => + updateAutoReset(1) + ); + DOMCacheGetOrSet("transcendamount").addEventListener("blur", () => + updateAutoReset(2) + ); + DOMCacheGetOrSet("reincarnationamount").addEventListener("blur", () => + updateAutoReset(3) + ); + DOMCacheGetOrSet("ascensionAmount").addEventListener("blur", () => + updateAutoReset(4) + ); + DOMCacheGetOrSet("autoAntSacrificeAmount").addEventListener("blur", () => + updateAutoReset(5) + ); // Tesseract-specific of the above. I don't know why I didn't standardize names here. - DOMCacheGetOrSet('tesseractautobuytoggle').addEventListener('click', () => toggleautobuytesseract()) - DOMCacheGetOrSet('tesseractAmount').addEventListener('blur', () => updateTesseractAutoBuyAmount()) + DOMCacheGetOrSet("tesseractautobuytoggle").addEventListener("click", () => + toggleautobuytesseract() + ); + DOMCacheGetOrSet("tesseractAmount").addEventListener("blur", () => + updateTesseractAutoBuyAmount() + ); // Auto Opening of Cubes - DOMCacheGetOrSet('cubeOpensInput').addEventListener('blur', () => updateAutoCubesOpens(1)) - DOMCacheGetOrSet('tesseractsOpensInput').addEventListener('blur', () => updateAutoCubesOpens(2)) - DOMCacheGetOrSet('hypercubesOpensInput').addEventListener('blur', () => updateAutoCubesOpens(3)) - DOMCacheGetOrSet('platonicCubeOpensInput').addEventListener('blur', () => updateAutoCubesOpens(4)) - DOMCacheGetOrSet('openCubes').addEventListener('click', () => toggleautoopensCubes(1)) - DOMCacheGetOrSet('openTesseracts').addEventListener('click', () => toggleautoopensCubes(2)) - DOMCacheGetOrSet('openHypercubes').addEventListener('click', () => toggleautoopensCubes(3)) - DOMCacheGetOrSet('openPlatonicCube').addEventListener('click', () => toggleautoopensCubes(4)) + DOMCacheGetOrSet("cubeOpensInput").addEventListener("blur", () => + updateAutoCubesOpens(1) + ); + DOMCacheGetOrSet("tesseractsOpensInput").addEventListener("blur", () => + updateAutoCubesOpens(2) + ); + DOMCacheGetOrSet("hypercubesOpensInput").addEventListener("blur", () => + updateAutoCubesOpens(3) + ); + DOMCacheGetOrSet("platonicCubeOpensInput").addEventListener("blur", () => + updateAutoCubesOpens(4) + ); + DOMCacheGetOrSet("openCubes").addEventListener("click", () => + toggleautoopensCubes(1) + ); + DOMCacheGetOrSet("openTesseracts").addEventListener("click", () => + toggleautoopensCubes(2) + ); + DOMCacheGetOrSet("openHypercubes").addEventListener("click", () => + toggleautoopensCubes(3) + ); + DOMCacheGetOrSet("openPlatonicCube").addEventListener("click", () => + toggleautoopensCubes(4) + ); // UPGRADES TAB // For all upgrades in the Upgrades Tab (125) count, we have the same mouseover event. So we'll work on those first. for (let index = 1; index <= 125; index++) { // Onmouseover events () - DOMCacheGetOrSet(`upg${index}`).addEventListener('mouseover', () => upgradedescriptions(index)) + DOMCacheGetOrSet(`upg${index}`).addEventListener("mouseover", () => + upgradedescriptions(index) + ); } // Generates all upgrade button events for (let index = 1; index <= 125; index++) { - DOMCacheGetOrSet(`upg${index}`).addEventListener('click', () => clickUpgrades(index, false)) + DOMCacheGetOrSet(`upg${index}`).addEventListener("click", () => + clickUpgrades(index, false) + ); } for (let index = 1; index <= 6; index++) { - DOMCacheGetOrSet(`upgrades${index}`).addEventListener('click', () => categoryUpgrades(index, false)) + DOMCacheGetOrSet(`upgrades${index}`).addEventListener("click", () => + categoryUpgrades(index, false) + ); } // Next part: Shop-specific toggles - DOMCacheGetOrSet('coinAutoUpgrade').addEventListener('click', () => toggleShops('coin')) - DOMCacheGetOrSet('prestigeAutoUpgrade').addEventListener('click', () => toggleShops('prestige')) - DOMCacheGetOrSet('transcendAutoUpgrade').addEventListener('click', () => toggleShops('transcend')) - DOMCacheGetOrSet('generatorsAutoUpgrade').addEventListener('click', () => toggleShops('generators')) - DOMCacheGetOrSet('reincarnateAutoUpgrade').addEventListener('click', () => toggleShops('reincarnate')) + DOMCacheGetOrSet("coinAutoUpgrade").addEventListener("click", () => + toggleShops("coin") + ); + DOMCacheGetOrSet("prestigeAutoUpgrade").addEventListener("click", () => + toggleShops("prestige") + ); + DOMCacheGetOrSet("transcendAutoUpgrade").addEventListener("click", () => + toggleShops("transcend") + ); + DOMCacheGetOrSet("generatorsAutoUpgrade").addEventListener("click", () => + toggleShops("generators") + ); + DOMCacheGetOrSet("reincarnateAutoUpgrade").addEventListener("click", () => + toggleShops("reincarnate") + ); // ACHIEVEMENTS TAB // TODO: Remove 1 indexing for (let index = 1; index <= achievementpointvalues.length - 1; index++) { // Onmouseover events (Achievement descriptions) - DOMCacheGetOrSet(`ach${index}`).addEventListener('mouseover', () => achievementdescriptions(index)) + DOMCacheGetOrSet(`ach${index}`).addEventListener("mouseover", () => + achievementdescriptions(index) + ); } // RUNES TAB [And all corresponding subtabs] // Part 0: Upper UI portion // Auto sacrifice toggle button - DOMCacheGetOrSet('toggleautosacrifice').addEventListener('click', () => toggleAutoSacrifice(0)) + DOMCacheGetOrSet("toggleautosacrifice").addEventListener("click", () => + toggleAutoSacrifice(0) + ); // Toggle subtabs of Runes tab for (let index = 0; index < 4; index++) { DOMCacheGetOrSet(`toggleRuneSubTab${index + 1}`).addEventListener( - 'click', + "click", () => changeSubTab(Tabs.Runes, { page: index }) - ) + ); } // Part 1: Runes Subtab for (let index = 0; index < 7; index++) { - DOMCacheGetOrSet(`rune${index + 1}`).addEventListener('mouseover', () => displayRuneInformation(index + 1)) - DOMCacheGetOrSet(`rune${index + 1}`).addEventListener('click', () => toggleAutoSacrifice(index + 1)) - - DOMCacheGetOrSet(`activaterune${index + 1}`).addEventListener('mouseover', () => displayRuneInformation(index + 1)) - DOMCacheGetOrSet(`activaterune${index + 1}`).addEventListener('click', () => redeemShards(index + 1)) + DOMCacheGetOrSet(`rune${index + 1}`).addEventListener("mouseover", () => + displayRuneInformation(index + 1) + ); + DOMCacheGetOrSet(`rune${index + 1}`).addEventListener("click", () => + toggleAutoSacrifice(index + 1) + ); + + DOMCacheGetOrSet(`activaterune${index + 1}`).addEventListener( + "mouseover", + () => displayRuneInformation(index + 1) + ); + DOMCacheGetOrSet(`activaterune${index + 1}`).addEventListener("click", () => + redeemShards(index + 1) + ); } // Part 2: Talismans Subtab - const talismanBuyPercents = [10, 25, 50, 100] - const talismanBuyPercentsOrd = ['Ten', 'TwentyFive', 'Fifty', 'Hundred'] + const talismanBuyPercents = [10, 25, 50, 100]; + const talismanBuyPercentsOrd = ["Ten", "TwentyFive", "Fifty", "Hundred"]; for (let index = 0; index < talismanBuyPercents.length; index++) { - DOMCacheGetOrSet(`talisman${talismanBuyPercentsOrd[index]}`).addEventListener( - 'click', - () => toggleTalismanBuy(talismanBuyPercents[index]) - ) + DOMCacheGetOrSet( + `talisman${talismanBuyPercentsOrd[index]}` + ).addEventListener("click", () => + toggleTalismanBuy(talismanBuyPercents[index]) + ); } - DOMCacheGetOrSet('toggleautoBuyFragments').addEventListener('click', () => toggleAutoBuyFragment()) - DOMCacheGetOrSet('toggleautoenhance').addEventListener('click', () => toggleautoenhance()) - DOMCacheGetOrSet('toggleautofortify').addEventListener('click', () => toggleautofortify()) + DOMCacheGetOrSet("toggleautoBuyFragments").addEventListener("click", () => + toggleAutoBuyFragment() + ); + DOMCacheGetOrSet("toggleautoenhance").addEventListener("click", () => + toggleautoenhance() + ); + DOMCacheGetOrSet("toggleautofortify").addEventListener("click", () => + toggleautofortify() + ); // Talisman Fragments/Shards const talismanItemNames = [ - 'shard', - 'commonFragment', - 'uncommonFragment', - 'rareFragment', - 'epicFragment', - 'legendaryFragment', - 'mythicalFragment' - ] as const + "shard", + "commonFragment", + "uncommonFragment", + "rareFragment", + "epicFragment", + "legendaryFragment", + "mythicalFragment", + ] as const; for (let index = 0; index < talismanItemNames.length; index++) { DOMCacheGetOrSet(`buyTalismanItem${index + 1}`).addEventListener( - 'mouseover', + "mouseover", () => updateTalismanCostDisplay(talismanItemNames[index]) - ) + ); DOMCacheGetOrSet(`buyTalismanItem${index + 1}`).addEventListener( - 'click', + "click", () => buyTalismanResources(talismanItemNames[index]) - ) + ); } - DOMCacheGetOrSet('buyTalismanAll').addEventListener('mouseover', () => updateTalismanCostDisplay(null)) - DOMCacheGetOrSet('buyTalismanAll').addEventListener('click', () => buyAllTalismanResources()) + DOMCacheGetOrSet("buyTalismanAll").addEventListener("mouseover", () => + updateTalismanCostDisplay(null) + ); + DOMCacheGetOrSet("buyTalismanAll").addEventListener("click", () => + buyAllTalismanResources() + ); for (let index = 0; index < 7; index++) { - DOMCacheGetOrSet(`talisman${index + 1}`).addEventListener('click', () => showTalismanEffect(index)) - DOMCacheGetOrSet(`leveluptalisman${index + 1}`).addEventListener('mouseover', () => showTalismanPrices(index)) - DOMCacheGetOrSet(`leveluptalisman${index + 1}`).addEventListener('click', () => buyTalismanLevels(index)) + DOMCacheGetOrSet(`talisman${index + 1}`).addEventListener("click", () => + showTalismanEffect(index) + ); + DOMCacheGetOrSet(`leveluptalisman${index + 1}`).addEventListener( + "mouseover", + () => showTalismanPrices(index) + ); + DOMCacheGetOrSet(`leveluptalisman${index + 1}`).addEventListener( + "click", + () => buyTalismanLevels(index) + ); DOMCacheGetOrSet(`enhancetalisman${index + 1}`).addEventListener( - 'mouseover', + "mouseover", () => showEnhanceTalismanPrices(index) - ) - DOMCacheGetOrSet(`enhancetalisman${index + 1}`).addEventListener('click', () => buyTalismanEnhance(index)) - DOMCacheGetOrSet(`respectalisman${index + 1}`).addEventListener('click', () => showRespecInformation(index)) + ); + DOMCacheGetOrSet(`enhancetalisman${index + 1}`).addEventListener( + "click", + () => buyTalismanEnhance(index) + ); + DOMCacheGetOrSet(`respectalisman${index + 1}`).addEventListener( + "click", + () => showRespecInformation(index) + ); } - DOMCacheGetOrSet('respecAllTalismans').addEventListener('click', () => showRespecInformation(7)) - DOMCacheGetOrSet('confirmTalismanRespec').addEventListener('click', () => respecTalismanConfirm(G.talismanRespec)) - DOMCacheGetOrSet('cancelTalismanRespec').addEventListener('click', () => respecTalismanCancel(G.talismanRespec)) + DOMCacheGetOrSet("respecAllTalismans").addEventListener("click", () => + showRespecInformation(7) + ); + DOMCacheGetOrSet("confirmTalismanRespec").addEventListener("click", () => + respecTalismanConfirm(G.talismanRespec) + ); + DOMCacheGetOrSet("cancelTalismanRespec").addEventListener("click", () => + respecTalismanCancel(G.talismanRespec) + ); for (let index = 0; index < 5; index++) { DOMCacheGetOrSet(`talismanRespecButton${index + 1}`).addEventListener( - 'click', + "click", () => changeTalismanModifier(index + 1) - ) + ); } // Part 3: Blessings and Spirits for (let index = 0; index < 5; index++) { DOMCacheGetOrSet(`runeBlessingPurchase${index + 1}`).addEventListener( - 'click', - () => buyRuneBonusLevels('Blessings', index + 1) - ) + "click", + () => buyRuneBonusLevels("Blessings", index + 1) + ); DOMCacheGetOrSet(`runeSpiritPurchase${index + 1}`).addEventListener( - 'click', - () => buyRuneBonusLevels('Spirits', index + 1) - ) + "click", + () => buyRuneBonusLevels("Spirits", index + 1) + ); } - DOMCacheGetOrSet('buyRuneBlessingInput').addEventListener('blur', () => updateRuneBlessingBuyAmount(1)) - DOMCacheGetOrSet('buyRuneSpiritInput').addEventListener('blur', () => updateRuneBlessingBuyAmount(2)) - - DOMCacheGetOrSet('buyAllBlessings').addEventListener('click', () => buyAllBlessings('Blessings')) - DOMCacheGetOrSet('buyAllSpirits').addEventListener('click', () => buyAllBlessings('Spirits')) + DOMCacheGetOrSet("buyRuneBlessingInput").addEventListener("blur", () => + updateRuneBlessingBuyAmount(1) + ); + DOMCacheGetOrSet("buyRuneSpiritInput").addEventListener("blur", () => + updateRuneBlessingBuyAmount(2) + ); + + DOMCacheGetOrSet("buyAllBlessings").addEventListener("click", () => + buyAllBlessings("Blessings") + ); + DOMCacheGetOrSet("buyAllSpirits").addEventListener("click", () => + buyAllBlessings("Spirits") + ); // CHALLENGES TAB // Part 1: Challenges // Challenge 1-15 buttons for (let index = 0; index < 15; index++) { - DOMCacheGetOrSet(`challenge${index + 1}`).addEventListener('click', () => challengeDisplay(index + 1)) - DOMCacheGetOrSet(`challenge${index + 1}`).addEventListener('dblclick', () => { + DOMCacheGetOrSet(`challenge${index + 1}`).addEventListener("click", () => challengeDisplay(index + 1) - toggleChallenges(G.triggerChallenge, false) - }) + ); + DOMCacheGetOrSet(`challenge${index + 1}`).addEventListener( + "dblclick", + () => { + challengeDisplay(index + 1); + toggleChallenges(G.triggerChallenge, false); + } + ); } // Part 2: QoL Buttons // Individual buttons (Start, Retry) - DOMCacheGetOrSet('startChallenge').addEventListener('click', () => toggleChallenges(G.triggerChallenge, false)) - DOMCacheGetOrSet('retryChallenge').addEventListener('click', () => toggleRetryChallenges()) + DOMCacheGetOrSet("startChallenge").addEventListener("click", () => + toggleChallenges(G.triggerChallenge, false) + ); + DOMCacheGetOrSet("retryChallenge").addEventListener("click", () => + toggleRetryChallenges() + ); // Autochallenge buttons - DOMCacheGetOrSet('toggleAutoChallengeIgnore').addEventListener( - 'click', - () => toggleAutoChallengesIgnore(G.triggerChallenge) - ) - DOMCacheGetOrSet('toggleAutoChallengeStart').addEventListener('click', () => toggleAutoChallengeRun()) - DOMCacheGetOrSet('startAutoChallengeTimerInput').addEventListener('input', () => updateAutoChallenge(1)) - DOMCacheGetOrSet('exitAutoChallengeTimerInput').addEventListener('input', () => updateAutoChallenge(2)) - DOMCacheGetOrSet('enterAutoChallengeTimerInput').addEventListener('input', () => updateAutoChallenge(3)) + DOMCacheGetOrSet("toggleAutoChallengeIgnore").addEventListener("click", () => + toggleAutoChallengesIgnore(G.triggerChallenge) + ); + DOMCacheGetOrSet("toggleAutoChallengeStart").addEventListener("click", () => + toggleAutoChallengeRun() + ); + DOMCacheGetOrSet("startAutoChallengeTimerInput").addEventListener( + "input", + () => updateAutoChallenge(1) + ); + DOMCacheGetOrSet("exitAutoChallengeTimerInput").addEventListener( + "input", + () => updateAutoChallenge(2) + ); + DOMCacheGetOrSet("enterAutoChallengeTimerInput").addEventListener( + "input", + () => updateAutoChallenge(3) + ); // RESEARCH TAB // Part 1: Researches // There are 200 researches, ideally in rewrite 200 would instead be length of research list/array for (let index = 1; index < 200; index++) { // Eliminates listeners on index.html 1404-1617 - DOMCacheGetOrSet(`res${index}`).addEventListener('click', () => buyResearch(index)) - DOMCacheGetOrSet(`res${index}`).addEventListener('mouseover', () => researchDescriptions(index)) + DOMCacheGetOrSet(`res${index}`).addEventListener("click", () => + buyResearch(index) + ); + DOMCacheGetOrSet(`res${index}`).addEventListener("mouseover", () => + researchDescriptions(index) + ); } // Research 200 is special, uses more params - DOMCacheGetOrSet('res200').addEventListener('click', () => buyResearch(200, false, 0.01)) - DOMCacheGetOrSet('res200').addEventListener('mouseover', () => researchDescriptions(200, false, 0.01)) + DOMCacheGetOrSet("res200").addEventListener("click", () => + buyResearch(200, false, 0.01) + ); + DOMCacheGetOrSet("res200").addEventListener("mouseover", () => + researchDescriptions(200, false, 0.01) + ); // Part 2: QoL buttons - DOMCacheGetOrSet('toggleresearchbuy').addEventListener('click', () => toggleResearchBuy()) - DOMCacheGetOrSet('toggleautoresearch').addEventListener('click', () => toggleAutoResearch()) - DOMCacheGetOrSet('toggleautoresearchmode').addEventListener('click', () => toggleAutoResearchMode()) + DOMCacheGetOrSet("toggleresearchbuy").addEventListener("click", () => + toggleResearchBuy() + ); + DOMCacheGetOrSet("toggleautoresearch").addEventListener("click", () => + toggleAutoResearch() + ); + DOMCacheGetOrSet("toggleautoresearchmode").addEventListener("click", () => + toggleAutoResearchMode() + ); // ANTHILL TAB // Part 1: Ant Producers (Tiers 1-8) - const antProducerCostVals = ['null', '1e700', '3', '100', '10000', '1e12', '1e36', '1e100', '1e300'] + const antProducerCostVals = [ + "null", + "1e700", + "3", + "100", + "10000", + "1e12", + "1e36", + "1e100", + "1e300", + ]; for (let index = 1; index <= 8; index++) { // Onmouse Events - DOMCacheGetOrSet(`anttier${index}`).addEventListener('mouseover', () => updateAntDescription(index)) - DOMCacheGetOrSet(`anttier${index}`).addEventListener('mouseover', () => antRepeat(index)) + DOMCacheGetOrSet(`anttier${index}`).addEventListener("mouseover", () => + updateAntDescription(index) + ); + DOMCacheGetOrSet(`anttier${index}`).addEventListener("mouseover", () => + antRepeat(index) + ); // Onclick Events - DOMCacheGetOrSet(`anttier${index}`).addEventListener('click', () => + DOMCacheGetOrSet(`anttier${index}`).addEventListener("click", () => buyAntProducers( ordinals[index] as Parameters[0], antProducerCostVals[index], index - )) + ) + ); } // Part 2: Ant Upgrades (1-12) const antUpgradeCostVals = [ - 'null', - '100', - '100', - '1000', - '1000', - '1e5', - '1e6', - '1e8', - '1e11', - '1e15', - '1e20', - '1e40', - '1e100' - ] + "null", + "100", + "100", + "1000", + "1000", + "1e5", + "1e6", + "1e8", + "1e11", + "1e15", + "1e20", + "1e40", + "1e100", + ]; for (let index = 1; index <= 12; index++) { // Onmouse Event - DOMCacheGetOrSet(`antUpgrade${index}`).addEventListener('mouseover', () => antUpgradeDescription(index)) + DOMCacheGetOrSet(`antUpgrade${index}`).addEventListener("mouseover", () => + antUpgradeDescription(index) + ); // Onclick Event - DOMCacheGetOrSet(`antUpgrade${index}`).addEventListener( - 'click', - () => buyAntUpgrade(antUpgradeCostVals[index], false, index) - ) + DOMCacheGetOrSet(`antUpgrade${index}`).addEventListener("click", () => + buyAntUpgrade(antUpgradeCostVals[index], false, index) + ); } // Part 3: Sacrifice - DOMCacheGetOrSet('antSacrifice').addEventListener('click', () => sacrificeAnts()) + DOMCacheGetOrSet("antSacrifice").addEventListener("click", () => + sacrificeAnts() + ); // Part 4: QoL Buttons - DOMCacheGetOrSet('toggleAntMax').addEventListener('click', () => toggleAntMaxBuy()) - DOMCacheGetOrSet('toggleAutoSacrificeAnt').addEventListener('click', () => toggleAntAutoSacrifice(0)) - DOMCacheGetOrSet('autoSacrificeAntMode').addEventListener('click', () => toggleAntAutoSacrifice(1)) + DOMCacheGetOrSet("toggleAntMax").addEventListener("click", () => + toggleAntMaxBuy() + ); + DOMCacheGetOrSet("toggleAutoSacrificeAnt").addEventListener("click", () => + toggleAntAutoSacrifice(0) + ); + DOMCacheGetOrSet("autoSacrificeAntMode").addEventListener("click", () => + toggleAntAutoSacrifice(1) + ); // WOW! Cubes Tab // Part 0: Subtab UI for (let index = 0; index < 7; index++) { DOMCacheGetOrSet(`switchCubeSubTab${index + 1}`).addEventListener( - 'click', + "click", () => changeSubTab(Tabs.WowCubes, { page: index }) - ) + ); } // Part 1: Cube Upgrades for (let index = 1; index < player.cubeUpgrades.length; index++) { - DOMCacheGetOrSet(`cubeUpg${index}`).addEventListener('mouseover', () => cubeUpgradeDesc(index)) - DOMCacheGetOrSet(`cubeUpg${index}`).addEventListener('click', () => buyCubeUpgrades(index)) + DOMCacheGetOrSet(`cubeUpg${index}`).addEventListener("mouseover", () => + cubeUpgradeDesc(index) + ); + DOMCacheGetOrSet(`cubeUpg${index}`).addEventListener("click", () => + buyCubeUpgrades(index) + ); } // Toggle - DOMCacheGetOrSet('toggleCubeBuy').addEventListener('click', () => toggleMaxBuyCube()) - DOMCacheGetOrSet('toggleAutoCubeUpgrades').addEventListener('click', () => autoCubeUpgradesToggle()) + DOMCacheGetOrSet("toggleCubeBuy").addEventListener("click", () => + toggleMaxBuyCube() + ); + DOMCacheGetOrSet("toggleAutoCubeUpgrades").addEventListener("click", () => + autoCubeUpgradesToggle() + ); // Part 2: Cube Opening Buttons // Wow Cubes - DOMCacheGetOrSet('open1Cube').addEventListener('click', () => player.wowCubes.open(1, false)) - DOMCacheGetOrSet('open20Cube').addEventListener( - 'click', - () => player.wowCubes.open(Math.floor(Number(player.wowCubes) / 10), false) - ) - DOMCacheGetOrSet('open1000Cube').addEventListener( - 'click', - () => player.wowCubes.open(Math.floor(Number(player.wowCubes) / 2), false) - ) - DOMCacheGetOrSet('openCustomCube').addEventListener('click', () => player.wowCubes.openCustom()) - DOMCacheGetOrSet('openMostCube').addEventListener('click', () => player.wowCubes.open(0, true)) + DOMCacheGetOrSet("open1Cube").addEventListener("click", () => + player.wowCubes.open(1, false) + ); + DOMCacheGetOrSet("open20Cube").addEventListener("click", () => + player.wowCubes.open(Math.floor(Number(player.wowCubes) / 10), false) + ); + DOMCacheGetOrSet("open1000Cube").addEventListener("click", () => + player.wowCubes.open(Math.floor(Number(player.wowCubes) / 2), false) + ); + DOMCacheGetOrSet("openCustomCube").addEventListener("click", () => + player.wowCubes.openCustom() + ); + DOMCacheGetOrSet("openMostCube").addEventListener("click", () => + player.wowCubes.open(0, true) + ); // Wow Tesseracts - DOMCacheGetOrSet('open1Tesseract').addEventListener('click', () => player.wowTesseracts.open(1, false)) - DOMCacheGetOrSet('open20Tesseract').addEventListener( - 'click', - () => player.wowTesseracts.open(Math.floor(Number(player.wowTesseracts) / 10), false) - ) - DOMCacheGetOrSet('open1000Tesseract').addEventListener( - 'click', - () => player.wowTesseracts.open(Math.floor(Number(player.wowTesseracts) / 2), false) - ) - DOMCacheGetOrSet('openCustomTesseract').addEventListener('click', () => player.wowTesseracts.openCustom()) - DOMCacheGetOrSet('openMostTesseract').addEventListener('click', () => player.wowTesseracts.open(1, true)) + DOMCacheGetOrSet("open1Tesseract").addEventListener("click", () => + player.wowTesseracts.open(1, false) + ); + DOMCacheGetOrSet("open20Tesseract").addEventListener("click", () => + player.wowTesseracts.open( + Math.floor(Number(player.wowTesseracts) / 10), + false + ) + ); + DOMCacheGetOrSet("open1000Tesseract").addEventListener("click", () => + player.wowTesseracts.open( + Math.floor(Number(player.wowTesseracts) / 2), + false + ) + ); + DOMCacheGetOrSet("openCustomTesseract").addEventListener("click", () => + player.wowTesseracts.openCustom() + ); + DOMCacheGetOrSet("openMostTesseract").addEventListener("click", () => + player.wowTesseracts.open(1, true) + ); // Wow Hypercubes - DOMCacheGetOrSet('open1Hypercube').addEventListener('click', () => player.wowHypercubes.open(1, false)) - DOMCacheGetOrSet('open20Hypercube').addEventListener( - 'click', - () => player.wowHypercubes.open(Math.floor(Number(player.wowHypercubes) / 10), false) - ) - DOMCacheGetOrSet('open1000Hypercube').addEventListener( - 'click', - () => player.wowHypercubes.open(Math.floor(Number(player.wowHypercubes) / 2), false) - ) - DOMCacheGetOrSet('openCustomHypercube').addEventListener('click', () => player.wowHypercubes.openCustom()) - DOMCacheGetOrSet('openMostHypercube').addEventListener('click', () => player.wowHypercubes.open(1, true)) + DOMCacheGetOrSet("open1Hypercube").addEventListener("click", () => + player.wowHypercubes.open(1, false) + ); + DOMCacheGetOrSet("open20Hypercube").addEventListener("click", () => + player.wowHypercubes.open( + Math.floor(Number(player.wowHypercubes) / 10), + false + ) + ); + DOMCacheGetOrSet("open1000Hypercube").addEventListener("click", () => + player.wowHypercubes.open( + Math.floor(Number(player.wowHypercubes) / 2), + false + ) + ); + DOMCacheGetOrSet("openCustomHypercube").addEventListener("click", () => + player.wowHypercubes.openCustom() + ); + DOMCacheGetOrSet("openMostHypercube").addEventListener("click", () => + player.wowHypercubes.open(1, true) + ); // Wow Platonic Cubes - DOMCacheGetOrSet('open1PlatonicCube').addEventListener('click', () => player.wowPlatonicCubes.open(1, false)) - DOMCacheGetOrSet('open40kPlatonicCube').addEventListener( - 'click', - () => player.wowPlatonicCubes.open(Math.floor(Number(player.wowPlatonicCubes) / 10), false) - ) - DOMCacheGetOrSet('open1mPlatonicCube').addEventListener( - 'click', - () => player.wowPlatonicCubes.open(Math.floor(Number(player.wowPlatonicCubes) / 2), false) - ) - DOMCacheGetOrSet('openCustomPlatonicCube').addEventListener('click', () => player.wowPlatonicCubes.openCustom()) - DOMCacheGetOrSet('openMostPlatonicCube').addEventListener('click', () => player.wowPlatonicCubes.open(1, true)) - - DOMCacheGetOrSet('saveOffToggle').addEventListener('click', () => toggleSaveOff()) + DOMCacheGetOrSet("open1PlatonicCube").addEventListener("click", () => + player.wowPlatonicCubes.open(1, false) + ); + DOMCacheGetOrSet("open40kPlatonicCube").addEventListener("click", () => + player.wowPlatonicCubes.open( + Math.floor(Number(player.wowPlatonicCubes) / 10), + false + ) + ); + DOMCacheGetOrSet("open1mPlatonicCube").addEventListener("click", () => + player.wowPlatonicCubes.open( + Math.floor(Number(player.wowPlatonicCubes) / 2), + false + ) + ); + DOMCacheGetOrSet("openCustomPlatonicCube").addEventListener("click", () => + player.wowPlatonicCubes.openCustom() + ); + DOMCacheGetOrSet("openMostPlatonicCube").addEventListener("click", () => + player.wowPlatonicCubes.open(1, true) + ); + + DOMCacheGetOrSet("saveOffToggle").addEventListener("click", () => + toggleSaveOff() + ); // Part 3: Platonic Upgrade Section - const platonicUpgrades = document.getElementsByClassName('platonicUpgradeImage') + const platonicUpgrades = document.getElementsByClassName( + "platonicUpgradeImage" + ); for (let index = 0; index < platonicUpgrades.length; index++) { - platonicUpgrades[index].addEventListener('mouseover', () => createPlatonicDescription(index + 1)) - platonicUpgrades[index].addEventListener('click', () => buyPlatonicUpgrades(index + 1)) + platonicUpgrades[index].addEventListener("mouseover", () => + createPlatonicDescription(index + 1) + ); + platonicUpgrades[index].addEventListener("click", () => + buyPlatonicUpgrades(index + 1) + ); } - DOMCacheGetOrSet('toggleAutoPlatonicUpgrades').addEventListener('click', () => autoPlatonicUpgradesToggle()) + DOMCacheGetOrSet("toggleAutoPlatonicUpgrades").addEventListener("click", () => + autoPlatonicUpgradesToggle() + ); // Part 4: Hepteract Subtab - DOMCacheGetOrSet('chronosHepteract').addEventListener('mouseover', () => hepteractDescriptions('chronos')) - DOMCacheGetOrSet('hyperrealismHepteract').addEventListener('mouseover', () => hepteractDescriptions('hyperrealism')) - DOMCacheGetOrSet('quarkHepteract').addEventListener('mouseover', () => hepteractDescriptions('quark')) - DOMCacheGetOrSet('challengeHepteract').addEventListener('mouseover', () => hepteractDescriptions('challenge')) - DOMCacheGetOrSet('abyssHepteract').addEventListener('mouseover', () => hepteractDescriptions('abyss')) - DOMCacheGetOrSet('acceleratorHepteract').addEventListener('mouseover', () => hepteractDescriptions('accelerator')) - DOMCacheGetOrSet('acceleratorBoostHepteract').addEventListener( - 'mouseover', - () => hepteractDescriptions('acceleratorBoost') - ) - DOMCacheGetOrSet('multiplierHepteract').addEventListener('mouseover', () => hepteractDescriptions('multiplier')) - - DOMCacheGetOrSet('chronosHepteractCraft').addEventListener('click', () => player.hepteractCrafts.chronos.craft()) - DOMCacheGetOrSet('hyperrealismHepteractCraft').addEventListener( - 'click', - () => player.hepteractCrafts.hyperrealism.craft() - ) - DOMCacheGetOrSet('quarkHepteractCraft').addEventListener('click', () => player.hepteractCrafts.quark.craft()) - DOMCacheGetOrSet('challengeHepteractCraft').addEventListener('click', () => player.hepteractCrafts.challenge.craft()) - DOMCacheGetOrSet('abyssHepteractCraft').addEventListener('click', () => player.hepteractCrafts.abyss.craft()) - DOMCacheGetOrSet('acceleratorHepteractCraft').addEventListener( - 'click', - () => player.hepteractCrafts.accelerator.craft() - ) - DOMCacheGetOrSet('acceleratorBoostHepteractCraft').addEventListener( - 'click', + DOMCacheGetOrSet("chronosHepteract").addEventListener("mouseover", () => + hepteractDescriptions("chronos") + ); + DOMCacheGetOrSet("hyperrealismHepteract").addEventListener("mouseover", () => + hepteractDescriptions("hyperrealism") + ); + DOMCacheGetOrSet("quarkHepteract").addEventListener("mouseover", () => + hepteractDescriptions("quark") + ); + DOMCacheGetOrSet("challengeHepteract").addEventListener("mouseover", () => + hepteractDescriptions("challenge") + ); + DOMCacheGetOrSet("abyssHepteract").addEventListener("mouseover", () => + hepteractDescriptions("abyss") + ); + DOMCacheGetOrSet("acceleratorHepteract").addEventListener("mouseover", () => + hepteractDescriptions("accelerator") + ); + DOMCacheGetOrSet("acceleratorBoostHepteract").addEventListener( + "mouseover", + () => hepteractDescriptions("acceleratorBoost") + ); + DOMCacheGetOrSet("multiplierHepteract").addEventListener("mouseover", () => + hepteractDescriptions("multiplier") + ); + + DOMCacheGetOrSet("chronosHepteractCraft").addEventListener("click", () => + player.hepteractCrafts.chronos.craft() + ); + DOMCacheGetOrSet("hyperrealismHepteractCraft").addEventListener("click", () => + player.hepteractCrafts.hyperrealism.craft() + ); + DOMCacheGetOrSet("quarkHepteractCraft").addEventListener("click", () => + player.hepteractCrafts.quark.craft() + ); + DOMCacheGetOrSet("challengeHepteractCraft").addEventListener("click", () => + player.hepteractCrafts.challenge.craft() + ); + DOMCacheGetOrSet("abyssHepteractCraft").addEventListener("click", () => + player.hepteractCrafts.abyss.craft() + ); + DOMCacheGetOrSet("acceleratorHepteractCraft").addEventListener("click", () => + player.hepteractCrafts.accelerator.craft() + ); + DOMCacheGetOrSet("acceleratorBoostHepteractCraft").addEventListener( + "click", () => player.hepteractCrafts.acceleratorBoost.craft() - ) - DOMCacheGetOrSet('multiplierHepteractCraft').addEventListener( - 'click', - () => player.hepteractCrafts.multiplier.craft() - ) - - DOMCacheGetOrSet('chronosHepteractCraftMax').addEventListener( - 'click', - () => player.hepteractCrafts.chronos.craft(true) - ) - DOMCacheGetOrSet('hyperrealismHepteractCraftMax').addEventListener( - 'click', + ); + DOMCacheGetOrSet("multiplierHepteractCraft").addEventListener("click", () => + player.hepteractCrafts.multiplier.craft() + ); + + DOMCacheGetOrSet("chronosHepteractCraftMax").addEventListener("click", () => + player.hepteractCrafts.chronos.craft(true) + ); + DOMCacheGetOrSet("hyperrealismHepteractCraftMax").addEventListener( + "click", () => player.hepteractCrafts.hyperrealism.craft(true) - ) - DOMCacheGetOrSet('quarkHepteractCraftMax').addEventListener('click', () => player.hepteractCrafts.quark.craft(true)) - DOMCacheGetOrSet('challengeHepteractCraftMax').addEventListener( - 'click', - () => player.hepteractCrafts.challenge.craft(true) - ) - DOMCacheGetOrSet('abyssHepteractCraftMax').addEventListener('click', () => player.hepteractCrafts.abyss.craft(true)) - DOMCacheGetOrSet('acceleratorHepteractCraftMax').addEventListener( - 'click', + ); + DOMCacheGetOrSet("quarkHepteractCraftMax").addEventListener("click", () => + player.hepteractCrafts.quark.craft(true) + ); + DOMCacheGetOrSet("challengeHepteractCraftMax").addEventListener("click", () => + player.hepteractCrafts.challenge.craft(true) + ); + DOMCacheGetOrSet("abyssHepteractCraftMax").addEventListener("click", () => + player.hepteractCrafts.abyss.craft(true) + ); + DOMCacheGetOrSet("acceleratorHepteractCraftMax").addEventListener( + "click", () => player.hepteractCrafts.accelerator.craft(true) - ) - DOMCacheGetOrSet('acceleratorBoostHepteractCraftMax').addEventListener( - 'click', + ); + DOMCacheGetOrSet("acceleratorBoostHepteractCraftMax").addEventListener( + "click", () => player.hepteractCrafts.acceleratorBoost.craft(true) - ) - DOMCacheGetOrSet('multiplierHepteractCraftMax').addEventListener( - 'click', + ); + DOMCacheGetOrSet("multiplierHepteractCraftMax").addEventListener( + "click", () => player.hepteractCrafts.multiplier.craft(true) - ) - - DOMCacheGetOrSet('chronosHepteractCap').addEventListener('click', () => player.hepteractCrafts.chronos.expand()) - DOMCacheGetOrSet('hyperrealismHepteractCap').addEventListener( - 'click', - () => player.hepteractCrafts.hyperrealism.expand() - ) - DOMCacheGetOrSet('quarkHepteractCap').addEventListener('click', () => player.hepteractCrafts.quark.expand()) - DOMCacheGetOrSet('challengeHepteractCap').addEventListener('click', () => player.hepteractCrafts.challenge.expand()) - DOMCacheGetOrSet('abyssHepteractCap').addEventListener('click', () => player.hepteractCrafts.abyss.expand()) - DOMCacheGetOrSet('acceleratorHepteractCap').addEventListener( - 'click', - () => player.hepteractCrafts.accelerator.expand() - ) - DOMCacheGetOrSet('acceleratorBoostHepteractCap').addEventListener( - 'click', + ); + + DOMCacheGetOrSet("chronosHepteractCap").addEventListener("click", () => + player.hepteractCrafts.chronos.expand() + ); + DOMCacheGetOrSet("hyperrealismHepteractCap").addEventListener("click", () => + player.hepteractCrafts.hyperrealism.expand() + ); + DOMCacheGetOrSet("quarkHepteractCap").addEventListener("click", () => + player.hepteractCrafts.quark.expand() + ); + DOMCacheGetOrSet("challengeHepteractCap").addEventListener("click", () => + player.hepteractCrafts.challenge.expand() + ); + DOMCacheGetOrSet("abyssHepteractCap").addEventListener("click", () => + player.hepteractCrafts.abyss.expand() + ); + DOMCacheGetOrSet("acceleratorHepteractCap").addEventListener("click", () => + player.hepteractCrafts.accelerator.expand() + ); + DOMCacheGetOrSet("acceleratorBoostHepteractCap").addEventListener( + "click", () => player.hepteractCrafts.acceleratorBoost.expand() - ) - DOMCacheGetOrSet('multiplierHepteractCap').addEventListener('click', () => player.hepteractCrafts.multiplier.expand()) - - DOMCacheGetOrSet('chronosHepteractAuto').addEventListener( - 'click', - () => player.hepteractCrafts.chronos.toggleAutomatic() - ) - DOMCacheGetOrSet('hyperrealismHepteractAuto').addEventListener( - 'click', - () => player.hepteractCrafts.hyperrealism.toggleAutomatic() - ) - DOMCacheGetOrSet('quarkHepteractAuto').addEventListener('click', () => player.hepteractCrafts.quark.toggleAutomatic()) - DOMCacheGetOrSet('challengeHepteractAuto').addEventListener( - 'click', - () => player.hepteractCrafts.challenge.toggleAutomatic() - ) - DOMCacheGetOrSet('abyssHepteractAuto').addEventListener('click', () => player.hepteractCrafts.abyss.toggleAutomatic()) - DOMCacheGetOrSet('acceleratorHepteractAuto').addEventListener( - 'click', - () => player.hepteractCrafts.accelerator.toggleAutomatic() - ) - DOMCacheGetOrSet('acceleratorBoostHepteractAuto').addEventListener( - 'click', + ); + DOMCacheGetOrSet("multiplierHepteractCap").addEventListener("click", () => + player.hepteractCrafts.multiplier.expand() + ); + + DOMCacheGetOrSet("chronosHepteractAuto").addEventListener("click", () => + player.hepteractCrafts.chronos.toggleAutomatic() + ); + DOMCacheGetOrSet("hyperrealismHepteractAuto").addEventListener("click", () => + player.hepteractCrafts.hyperrealism.toggleAutomatic() + ); + DOMCacheGetOrSet("quarkHepteractAuto").addEventListener("click", () => + player.hepteractCrafts.quark.toggleAutomatic() + ); + DOMCacheGetOrSet("challengeHepteractAuto").addEventListener("click", () => + player.hepteractCrafts.challenge.toggleAutomatic() + ); + DOMCacheGetOrSet("abyssHepteractAuto").addEventListener("click", () => + player.hepteractCrafts.abyss.toggleAutomatic() + ); + DOMCacheGetOrSet("acceleratorHepteractAuto").addEventListener("click", () => + player.hepteractCrafts.accelerator.toggleAutomatic() + ); + DOMCacheGetOrSet("acceleratorBoostHepteractAuto").addEventListener( + "click", () => player.hepteractCrafts.acceleratorBoost.toggleAutomatic() - ) - DOMCacheGetOrSet('multiplierHepteractAuto').addEventListener( - 'click', - () => player.hepteractCrafts.multiplier.toggleAutomatic() - ) - - DOMCacheGetOrSet('hepteractToQuark').addEventListener('mouseover', () => hepteractToOverfluxOrbDescription()) - DOMCacheGetOrSet('hepteractToQuarkTrade').addEventListener('click', () => tradeHepteractToOverfluxOrb()) - DOMCacheGetOrSet('hepteractToQuarkTradeMax').addEventListener('click', () => tradeHepteractToOverfluxOrb(true)) - DOMCacheGetOrSet('hepteractToQuarkTradeAuto').addEventListener('click', () => toggleAutoBuyOrbs()) - DOMCacheGetOrSet('overfluxPowder').addEventListener('mouseover', () => overfluxPowderDescription()) - DOMCacheGetOrSet('powderDayWarp').addEventListener('click', () => overfluxPowderWarp(false)) - DOMCacheGetOrSet('warpAuto').addEventListener('click', () => overfluxPowderWarp(true)) - - DOMCacheGetOrSet('hepteractAutoPercentageButton').addEventListener('click', () => toggleHepteractAutoPercentage()) + ); + DOMCacheGetOrSet("multiplierHepteractAuto").addEventListener("click", () => + player.hepteractCrafts.multiplier.toggleAutomatic() + ); + + DOMCacheGetOrSet("hepteractToQuark").addEventListener("mouseover", () => + hepteractToOverfluxOrbDescription() + ); + DOMCacheGetOrSet("hepteractToQuarkTrade").addEventListener("click", () => + tradeHepteractToOverfluxOrb() + ); + DOMCacheGetOrSet("hepteractToQuarkTradeMax").addEventListener("click", () => + tradeHepteractToOverfluxOrb(true) + ); + DOMCacheGetOrSet("hepteractToQuarkTradeAuto").addEventListener("click", () => + toggleAutoBuyOrbs() + ); + DOMCacheGetOrSet("overfluxPowder").addEventListener("mouseover", () => + overfluxPowderDescription() + ); + DOMCacheGetOrSet("powderDayWarp").addEventListener("click", () => + overfluxPowderWarp(false) + ); + DOMCacheGetOrSet("warpAuto").addEventListener("click", () => + overfluxPowderWarp(true) + ); + + DOMCacheGetOrSet("hepteractAutoPercentageButton").addEventListener( + "click", + () => toggleHepteractAutoPercentage() + ); // CORRUPTION TAB // Part 0: Subtabs - DOMCacheGetOrSet('corrStatsBtn').addEventListener('click', () => changeSubTab(Tabs.Corruption, { page: 0 })) - DOMCacheGetOrSet('corrLoadoutsBtn').addEventListener('click', () => changeSubTab(Tabs.Corruption, { page: 1 })) + DOMCacheGetOrSet("corrStatsBtn").addEventListener("click", () => + changeSubTab(Tabs.Corruption, { page: 0 }) + ); + DOMCacheGetOrSet("corrLoadoutsBtn").addEventListener("click", () => + changeSubTab(Tabs.Corruption, { page: 1 }) + ); // Part 1: Displays - DOMCacheGetOrSet('corruptionDisplays').addEventListener('click', () => corruptionDisplay(10)) - DOMCacheGetOrSet('corruptionCleanse').addEventListener('click', () => corruptionCleanseConfirm()) - DOMCacheGetOrSet('corruptionCleanseConfirm').addEventListener('click', () => toggleCorruptionLevel(10, 999)) + DOMCacheGetOrSet("corruptionDisplays").addEventListener("click", () => + corruptionDisplay(10) + ); + DOMCacheGetOrSet("corruptionCleanse").addEventListener("click", () => + corruptionCleanseConfirm() + ); + DOMCacheGetOrSet("corruptionCleanseConfirm").addEventListener("click", () => + toggleCorruptionLevel(10, 999) + ); // Extra toggle - DOMCacheGetOrSet('ascensionAutoEnable').addEventListener('click', () => toggleAutoAscend(0)) - DOMCacheGetOrSet('ascensionAutoToggle').addEventListener('click', () => toggleAutoAscend(1)) + DOMCacheGetOrSet("ascensionAutoEnable").addEventListener("click", () => + toggleAutoAscend(0) + ); + DOMCacheGetOrSet("ascensionAutoToggle").addEventListener("click", () => + toggleAutoAscend(1) + ); // SETTNGS TAB // Part 0: Subtabs - const settingSubTabs = Array.from(document.querySelectorAll('[id^="switchSettingSubTab"]')) + const settingSubTabs = Array.from( + document.querySelectorAll('[id^="switchSettingSubTab"]') + ); for (const subtab of settingSubTabs) { - subtab.addEventListener('click', () => changeSubTab(Tabs.Settings, { page: settingSubTabs.indexOf(subtab) })) + subtab.addEventListener("click", () => + changeSubTab(Tabs.Settings, { page: settingSubTabs.indexOf(subtab) }) + ); } - const t = Array.from(document.querySelectorAll('button.statsNerds')) + const t = Array.from( + document.querySelectorAll("button.statsNerds") + ); for (const s of t) { - s.addEventListener('click', (e) => displayStats(e.target as HTMLElement)) + s.addEventListener("click", (e) => displayStats(e.target as HTMLElement)); } - DOMCacheGetOrSet('summaryGeneration').addEventListener('click', () => generateExportSummary()) + DOMCacheGetOrSet("summaryGeneration").addEventListener("click", () => + generateExportSummary() + ); // Various functions - DOMCacheGetOrSet('exportgame').addEventListener('click', () => exportSynergism()) - DOMCacheGetOrSet('saveStringInput').addEventListener('blur', (e) => updateSaveString(e.target as HTMLInputElement)) - DOMCacheGetOrSet('savegame').addEventListener('click', () => saveSynergy(true)) - DOMCacheGetOrSet('deleteGame').addEventListener('click', () => resetGame()) - DOMCacheGetOrSet('preloadDeleteGame').addEventListener('click', () => reloadDeleteGame()) - DOMCacheGetOrSet('promocodes').addEventListener('click', () => promocodesPrompt()) - DOMCacheGetOrSet('addCodeBox').addEventListener('mouseover', () => promocodesInfo('add')) - DOMCacheGetOrSet('addCode').addEventListener('click', () => promocodes('add')) - DOMCacheGetOrSet('addCodeAll').addEventListener('click', () => promocodes('add', addCodeAvailableUses())) - DOMCacheGetOrSet('addCodeOne').addEventListener('click', () => promocodes('add', 1)) - DOMCacheGetOrSet('dailyCode').addEventListener('click', () => promocodes('daily')) - DOMCacheGetOrSet('dailyCode').addEventListener('mouseover', () => promocodesInfo('daily')) - DOMCacheGetOrSet('timeCode').addEventListener('click', () => promocodes('time')) - DOMCacheGetOrSet('timeCode').addEventListener('mouseover', () => promocodesInfo('time')) - DOMCacheGetOrSet('historyTogglePerSecondButton').addEventListener('click', () => resetHistoryTogglePerSecond()) - DOMCacheGetOrSet('resetHotkeys').addEventListener('click', () => resetHotkeys()) - DOMCacheGetOrSet('notation').addEventListener('click', () => toggleAnnotation()) - DOMCacheGetOrSet('iconSet').addEventListener('click', () => toggleIconSet(player.iconSet + 1)) + DOMCacheGetOrSet("exportgame").addEventListener("click", () => + exportSynergism() + ); + DOMCacheGetOrSet("saveStringInput").addEventListener("blur", (e) => + updateSaveString(e.target as HTMLInputElement) + ); + DOMCacheGetOrSet("savegame").addEventListener("click", () => + saveSynergy(true) + ); + DOMCacheGetOrSet("deleteGame").addEventListener("click", () => resetGame()); + DOMCacheGetOrSet("preloadDeleteGame").addEventListener("click", () => + reloadDeleteGame() + ); + DOMCacheGetOrSet("promocodes").addEventListener("click", () => + promocodesPrompt() + ); + DOMCacheGetOrSet("addCodeBox").addEventListener("mouseover", () => + promocodesInfo("add") + ); + DOMCacheGetOrSet("addCode").addEventListener("click", () => + promocodes("add") + ); + DOMCacheGetOrSet("addCodeAll").addEventListener("click", () => + promocodes("add", addCodeAvailableUses()) + ); + DOMCacheGetOrSet("addCodeOne").addEventListener("click", () => + promocodes("add", 1) + ); + DOMCacheGetOrSet("dailyCode").addEventListener("click", () => + promocodes("daily") + ); + DOMCacheGetOrSet("dailyCode").addEventListener("mouseover", () => + promocodesInfo("daily") + ); + DOMCacheGetOrSet("timeCode").addEventListener("click", () => + promocodes("time") + ); + DOMCacheGetOrSet("timeCode").addEventListener("mouseover", () => + promocodesInfo("time") + ); + DOMCacheGetOrSet("historyTogglePerSecondButton").addEventListener( + "click", + () => resetHistoryTogglePerSecond() + ); + DOMCacheGetOrSet("resetHotkeys").addEventListener("click", () => + resetHotkeys() + ); + DOMCacheGetOrSet("notation").addEventListener("click", () => + toggleAnnotation() + ); + DOMCacheGetOrSet("iconSet").addEventListener("click", () => + toggleIconSet(player.iconSet + 1) + ); // SHOP TAB @@ -794,201 +1229,280 @@ TODO: Fix this entire tab it's utter shit */ // Part 1: The Settings - /*Respec The Upgrades*/ DOMCacheGetOrSet('resetShopUpgrades').addEventListener('click', () => resetShopUpgrades()) - /*Toggle Shop Confirmations*/ DOMCacheGetOrSet('toggleConfirmShop').addEventListener( - 'click', - () => toggleShopConfirmation() - ) - /*Toggle Shop Buy Max*/ DOMCacheGetOrSet('toggleBuyMaxShop').addEventListener( - 'click', + /*Respec The Upgrades*/ DOMCacheGetOrSet( + "resetShopUpgrades" + ).addEventListener("click", () => resetShopUpgrades()); + /*Toggle Shop Confirmations*/ DOMCacheGetOrSet( + "toggleConfirmShop" + ).addEventListener("click", () => toggleShopConfirmation()); + /*Toggle Shop Buy Max*/ DOMCacheGetOrSet("toggleBuyMaxShop").addEventListener( + "click", (event) => toggleBuyMaxShop(event) - ) - /*Toggle Hide Permanent Maxed*/ DOMCacheGetOrSet('toggleHideShop').addEventListener('click', () => toggleHideShop()) + ); + /*Toggle Hide Permanent Maxed*/ DOMCacheGetOrSet( + "toggleHideShop" + ).addEventListener("click", () => toggleHideShop()); // Part 2: Potions /*Offering Potion*/ - DOMCacheGetOrSet('offeringPotions').addEventListener('mouseover', () => shopDescriptions('offeringPotion')) - DOMCacheGetOrSet('offeringpotionowned').addEventListener('mouseover', () => shopDescriptions('offeringPotion')) - DOMCacheGetOrSet('buyofferingpotion').addEventListener('mouseover', () => shopDescriptions('offeringPotion')) - DOMCacheGetOrSet('useofferingpotion').addEventListener('mouseover', () => shopDescriptions('offeringPotion')) - DOMCacheGetOrSet('buyofferingpotion').addEventListener('click', () => buyShopUpgrades('offeringPotion')) + DOMCacheGetOrSet("offeringPotions").addEventListener("mouseover", () => + shopDescriptions("offeringPotion") + ); + DOMCacheGetOrSet("offeringpotionowned").addEventListener("mouseover", () => + shopDescriptions("offeringPotion") + ); + DOMCacheGetOrSet("buyofferingpotion").addEventListener("mouseover", () => + shopDescriptions("offeringPotion") + ); + DOMCacheGetOrSet("useofferingpotion").addEventListener("mouseover", () => + shopDescriptions("offeringPotion") + ); + DOMCacheGetOrSet("buyofferingpotion").addEventListener("click", () => + buyShopUpgrades("offeringPotion") + ); // DOMCacheGetOrSet('offeringPotions').addEventListener('click', () => buyShopUpgrades("offeringPotion")) //Allow clicking of image to buy also - DOMCacheGetOrSet('useofferingpotion').addEventListener('click', () => useConsumable('offeringPotion')) - DOMCacheGetOrSet('toggle42').addEventListener('click', () => { - player.autoPotionTimer = 0 - }) + DOMCacheGetOrSet("useofferingpotion").addEventListener("click", () => + useConsumable("offeringPotion") + ); + DOMCacheGetOrSet("toggle42").addEventListener("click", () => { + player.autoPotionTimer = 0; + }); /*Obtainium Potion*/ - DOMCacheGetOrSet('obtainiumPotions').addEventListener('mouseover', () => shopDescriptions('obtainiumPotion')) - DOMCacheGetOrSet('obtainiumpotionowned').addEventListener('mouseover', () => shopDescriptions('obtainiumPotion')) - DOMCacheGetOrSet('buyobtainiumpotion').addEventListener('mouseover', () => shopDescriptions('obtainiumPotion')) - DOMCacheGetOrSet('useobtainiumpotion').addEventListener('mouseover', () => shopDescriptions('obtainiumPotion')) - DOMCacheGetOrSet('buyobtainiumpotion').addEventListener('click', () => buyShopUpgrades('obtainiumPotion')) + DOMCacheGetOrSet("obtainiumPotions").addEventListener("mouseover", () => + shopDescriptions("obtainiumPotion") + ); + DOMCacheGetOrSet("obtainiumpotionowned").addEventListener("mouseover", () => + shopDescriptions("obtainiumPotion") + ); + DOMCacheGetOrSet("buyobtainiumpotion").addEventListener("mouseover", () => + shopDescriptions("obtainiumPotion") + ); + DOMCacheGetOrSet("useobtainiumpotion").addEventListener("mouseover", () => + shopDescriptions("obtainiumPotion") + ); + DOMCacheGetOrSet("buyobtainiumpotion").addEventListener("click", () => + buyShopUpgrades("obtainiumPotion") + ); // DOMCacheGetOrSet('obtainiumPotions').addEventListener('click', () => buyShopUpgrades("obtainiumPotion")) //Allow clicking of image to buy also - DOMCacheGetOrSet('useobtainiumpotion').addEventListener('click', () => useConsumable('obtainiumPotion')) - DOMCacheGetOrSet('toggle43').addEventListener('click', () => { - player.autoPotionTimerObtainium = 0 - }) + DOMCacheGetOrSet("useobtainiumpotion").addEventListener("click", () => + useConsumable("obtainiumPotion") + ); + DOMCacheGetOrSet("toggle43").addEventListener("click", () => { + player.autoPotionTimerObtainium = 0; + }); /* Permanent Upgrade Images */ - const shopKeys = Object.keys(player.shopUpgrades) as (keyof Player['shopUpgrades'])[] + const shopKeys = Object.keys( + player.shopUpgrades + ) as (keyof Player["shopUpgrades"])[]; for (const key of shopKeys) { - const shopItem = shopData[key] + const shopItem = shopData[key]; if (shopItem.type === shopUpgradeTypes.UPGRADE) { - DOMCacheGetOrSet(`${key}`).addEventListener('mouseover', () => shopDescriptions(key)) - DOMCacheGetOrSet(`${key}Level`).addEventListener('mouseover', () => shopDescriptions(key)) - DOMCacheGetOrSet(`${key}Button`).addEventListener('mouseover', () => shopDescriptions(key)) + DOMCacheGetOrSet(`${key}`).addEventListener("mouseover", () => + shopDescriptions(key) + ); + DOMCacheGetOrSet(`${key}Level`).addEventListener("mouseover", () => + shopDescriptions(key) + ); + DOMCacheGetOrSet(`${key}Button`).addEventListener("mouseover", () => + shopDescriptions(key) + ); // DOMCacheGetOrSet(`${key}`).addEventListener('click', () => buyShopUpgrades(key)) //Allow clicking of image to buy also - DOMCacheGetOrSet(`${key}Button`).addEventListener('click', () => buyShopUpgrades(key)) + DOMCacheGetOrSet(`${key}Button`).addEventListener("click", () => + buyShopUpgrades(key) + ); } } - DOMCacheGetOrSet('buySingularityQuarksButton').addEventListener('click', () => buyGoldenQuarks()) + DOMCacheGetOrSet("buySingularityQuarksButton").addEventListener("click", () => + buyGoldenQuarks() + ); // SINGULARITY TAB - const singularityUpgrades = Object.keys(player.singularityUpgrades) as (keyof Player['singularityUpgrades'])[] + const singularityUpgrades = Object.keys( + player.singularityUpgrades + ) as (keyof Player["singularityUpgrades"])[]; for (const key of singularityUpgrades) { - if (key === 'offeringAutomatic') { - continue + if (key === "offeringAutomatic") { + continue; } - DOMCacheGetOrSet(`${String(key)}`).addEventListener( - 'mouseover', - () => player.singularityUpgrades[`${String(key)}`].updateUpgradeHTML() - ) - DOMCacheGetOrSet(`${String(key)}`).addEventListener( - 'click', - (event) => player.singularityUpgrades[`${String(key)}`].buyLevel(event) - ) + DOMCacheGetOrSet(`${String(key)}`).addEventListener("mouseover", () => + player.singularityUpgrades[`${String(key)}`].updateUpgradeHTML() + ); + DOMCacheGetOrSet(`${String(key)}`).addEventListener("click", (event) => + player.singularityUpgrades[`${String(key)}`].buyLevel(event) + ); } - DOMCacheGetOrSet('actualSingularityUpgradeContainer').addEventListener('mouseover', () => shopMouseover(true)) - DOMCacheGetOrSet('actualSingularityUpgradeContainer').addEventListener('mouseout', () => shopMouseover(false)) - - const perkImage = DOMCacheGetOrSet('singularityPerksIcon') as HTMLImageElement - const perksText = DOMCacheGetOrSet('singularityPerksText') - const perksDesc = DOMCacheGetOrSet('singularityPerksDesc') + DOMCacheGetOrSet("actualSingularityUpgradeContainer").addEventListener( + "mouseover", + () => shopMouseover(true) + ); + DOMCacheGetOrSet("actualSingularityUpgradeContainer").addEventListener( + "mouseout", + () => shopMouseover(false) + ); + + const perkImage = DOMCacheGetOrSet( + "singularityPerksIcon" + ) as HTMLImageElement; + const perksText = DOMCacheGetOrSet("singularityPerksText"); + const perksDesc = DOMCacheGetOrSet("singularityPerksDesc"); for (const perk of singularityPerks) { - const perkHTML = document.createElement('span') - perkHTML.innerHTML = `${perk.name()}` - perkHTML.id = perk.ID - perkHTML.classList.add('oldPerk') - perkHTML.style.display = 'none' // Ensure the perk is hidden if not unlocked as an anti-spoiler failsafe. - DOMCacheGetOrSet('singularityPerksGrid').append(perkHTML) - DOMCacheGetOrSet(perk.ID).addEventListener('mouseover', () => { - const perkInfo = getLastUpgradeInfo(perk, player.highestSingularityCount) - const levelInfo = i18next.t('singularity.perks.levelInfo', { + const perkHTML = document.createElement("span"); + perkHTML.innerHTML = `${perk.name()}`; + perkHTML.id = perk.ID; + perkHTML.classList.add("oldPerk"); + perkHTML.style.display = "none"; // Ensure the perk is hidden if not unlocked as an anti-spoiler failsafe. + DOMCacheGetOrSet("singularityPerksGrid").append(perkHTML); + DOMCacheGetOrSet(perk.ID).addEventListener("mouseover", () => { + const perkInfo = getLastUpgradeInfo(perk, player.highestSingularityCount); + const levelInfo = i18next.t("singularity.perks.levelInfo", { level: perkInfo.level, - singularity: perkInfo.singularity - }) - perkImage.src = `Pictures/${IconSets[player.iconSet][0]}/perk${perk.ID}.png` - perksText.textContent = levelInfo - perksDesc.textContent = perk.description(player.highestSingularityCount, perk.levels) - }) + singularity: perkInfo.singularity, + }); + perkImage.src = `Pictures/${IconSets[player.iconSet][0]}/perk${ + perk.ID + }.png`; + perksText.innerHTML = levelInfo; + perksDesc.innerHTML = perk.description( + player.highestSingularityCount, + perk.levels + ); + }); } // Octeract Upgrades - const octeractUpgrades = Object.keys(player.octeractUpgrades) as (keyof Player['octeractUpgrades'])[] + const octeractUpgrades = Object.keys( + player.octeractUpgrades + ) as (keyof Player["octeractUpgrades"])[]; for (const key of octeractUpgrades) { - DOMCacheGetOrSet(`${String(key)}`).addEventListener( - 'mouseover', - () => player.octeractUpgrades[`${String(key)}`].updateUpgradeHTML() - ) - DOMCacheGetOrSet(`${String(key)}`).addEventListener( - 'click', - (event) => player.octeractUpgrades[`${String(key)}`].buyLevel(event) - ) + DOMCacheGetOrSet(`${String(key)}`).addEventListener("mouseover", () => + player.octeractUpgrades[`${String(key)}`].updateUpgradeHTML() + ); + DOMCacheGetOrSet(`${String(key)}`).addEventListener("click", (event) => + player.octeractUpgrades[`${String(key)}`].buyLevel(event) + ); } - DOMCacheGetOrSet('octeractUpgradeContainer').addEventListener('mouseover', () => shopMouseover(true)) - DOMCacheGetOrSet('octeractUpgradeContainer').addEventListener('mouseout', () => shopMouseover(false)) + DOMCacheGetOrSet("octeractUpgradeContainer").addEventListener( + "mouseover", + () => shopMouseover(true) + ); + DOMCacheGetOrSet("octeractUpgradeContainer").addEventListener( + "mouseout", + () => shopMouseover(false) + ); // EXALT - const singularityChallenges = Object.keys(player.singularityChallenges) as (keyof Player['singularityChallenges'])[] + const singularityChallenges = Object.keys( + player.singularityChallenges + ) as (keyof Player["singularityChallenges"])[]; for (const key of singularityChallenges) { - DOMCacheGetOrSet(`${String(key)}`).addEventListener( - 'mouseover', - () => player.singularityChallenges[`${String(key)}`].updateChallengeHTML() - ) - DOMCacheGetOrSet(`${String(key)}`).addEventListener( - 'click', - () => player.singularityChallenges[`${String(key)}`].challengeEntryHandler() - ) + DOMCacheGetOrSet(`${String(key)}`).addEventListener("mouseover", () => + player.singularityChallenges[`${String(key)}`].updateChallengeHTML() + ); + DOMCacheGetOrSet(`${String(key)}`).addEventListener("click", () => + player.singularityChallenges[`${String(key)}`].challengeEntryHandler() + ); } // BLUEBERRY UPGRADES - const blueberryUpgrades = Object.keys(player.blueberryUpgrades) as (keyof Player['blueberryUpgrades'])[] + const blueberryUpgrades = Object.keys( + player.blueberryUpgrades + ) as (keyof Player["blueberryUpgrades"])[]; for (const key of blueberryUpgrades) { - DOMCacheGetOrSet(`${String(key)}`).addEventListener( - 'mouseover', - () => player.blueberryUpgrades[`${String(key)}`].updateUpgradeHTML() - ) - DOMCacheGetOrSet(`${String(key)}`).addEventListener( - 'click', - (event) => player.blueberryUpgrades[`${String(key)}`].buyLevel(event) - ) + DOMCacheGetOrSet(`${String(key)}`).addEventListener("mouseover", () => + player.blueberryUpgrades[`${String(key)}`].updateUpgradeHTML() + ); + DOMCacheGetOrSet(`${String(key)}`).addEventListener("click", (event) => + player.blueberryUpgrades[`${String(key)}`].buyLevel(event) + ); } // BLUEBERRY LOADOUTS - const blueberryLoadouts = Array.from(document.querySelectorAll('[id^="blueberryLoadout"]')) - const loadoutContainer = DOMCacheGetOrSet('blueberryUpgradeContainer') + const blueberryLoadouts = Array.from( + document.querySelectorAll('[id^="blueberryLoadout"]') + ); + const loadoutContainer = DOMCacheGetOrSet("blueberryUpgradeContainer"); for (let i = 0; i < blueberryLoadouts.length; i++) { - const shiftedKey = i + 1 - const el = blueberryLoadouts[i] - el.addEventListener('mouseover', () => { - createLoadoutDescription(shiftedKey, player.blueberryLoadouts[shiftedKey] ?? { ambrosiaTutorial: 0 }) - loadoutContainer.classList.add(`hoveredBlueberryLoadout${shiftedKey}`) - }) - el.addEventListener('mouseout', () => { - loadoutContainer.classList.remove(`hoveredBlueberryLoadout${shiftedKey}`) - }) - el.addEventListener( - 'click', - () => loadoutHandler(shiftedKey, player.blueberryLoadouts[shiftedKey] ?? { ambrosiaTutorial: 0 }) - ) + const shiftedKey = i + 1; + const el = blueberryLoadouts[i]; + el.addEventListener("mouseover", () => { + createLoadoutDescription( + shiftedKey, + player.blueberryLoadouts[shiftedKey] ?? { ambrosiaTutorial: 0 } + ); + loadoutContainer.classList.add(`hoveredBlueberryLoadout${shiftedKey}`); + }); + el.addEventListener("mouseout", () => { + loadoutContainer.classList.remove(`hoveredBlueberryLoadout${shiftedKey}`); + }); + el.addEventListener("click", () => + loadoutHandler( + shiftedKey, + player.blueberryLoadouts[shiftedKey] ?? { ambrosiaTutorial: 0 } + ) + ); } - DOMCacheGetOrSet('blueberryToggleMode').addEventListener('click', () => toggleBlueberryLoadoutmode()) + DOMCacheGetOrSet("blueberryToggleMode").addEventListener("click", () => + toggleBlueberryLoadoutmode() + ); - DOMCacheGetOrSet('getBlueberries').addEventListener('click', () => exportBlueberryTree()) - DOMCacheGetOrSet('refundBlueberries').addEventListener('click', () => resetBlueberryTree()) + DOMCacheGetOrSet("getBlueberries").addEventListener("click", () => + exportBlueberryTree() + ); + DOMCacheGetOrSet("refundBlueberries").addEventListener("click", () => + resetBlueberryTree() + ); // Import blueberries - DOMCacheGetOrSet('importBlueberries').addEventListener('change', async (e) => importData(e, importBlueberryTree)) + DOMCacheGetOrSet("importBlueberries").addEventListener("change", async (e) => + importData(e, importBlueberryTree) + ); // Toggle subtabs of Singularity tab for (let index = 0; index < 5; index++) { DOMCacheGetOrSet(`toggleSingularitySubTab${index + 1}`).addEventListener( - 'click', + "click", () => changeSubTab(Tabs.Singularity, { page: index }) - ) + ); } // EVENT TAB (Replace as events are created) - DOMCacheGetOrSet('unsmith').addEventListener('click', () => clickSmith()) + DOMCacheGetOrSet("unsmith").addEventListener("click", () => clickSmith()); // Import button - DOMCacheGetOrSet('importfile').addEventListener('change', async (e) => importData(e, importSynergism)) + DOMCacheGetOrSet("importfile").addEventListener("change", async (e) => + importData(e, importSynergism) + ); for (let i = 1; i <= 5; i++) { - DOMCacheGetOrSet(`switchTheme${i}`).addEventListener('click', () => toggleTheme(false, i, true)) + DOMCacheGetOrSet(`switchTheme${i}`).addEventListener("click", () => + toggleTheme(false, i, true) + ); } - DOMCacheGetOrSet('saveType').addEventListener('click', async (event) => { - const element = event.target as HTMLInputElement + DOMCacheGetOrSet("saveType").addEventListener("click", async (event) => { + const element = event.target as HTMLInputElement; if (!element.checked) { - localStorage.removeItem('copyToClipboard') - event.stopPropagation() - return + localStorage.removeItem("copyToClipboard"); + event.stopPropagation(); + return; } - event.preventDefault() + event.preventDefault(); - const confirmed = await Confirm(i18next.t('save.saveToClipboard')) + const confirmed = await Confirm(i18next.t("save.saveToClipboard")); if (confirmed) { - element.checked = !element.checked - localStorage.setItem('copyToClipboard', '') + element.checked = !element.checked; + localStorage.setItem("copyToClipboard", ""); } else { - localStorage.removeItem('copyToClipboard') + localStorage.removeItem("copyToClipboard"); } - }) + }); // Window - window.addEventListener('error', imgErrorHandler, { capture: true }) -} + window.addEventListener("error", imgErrorHandler, { capture: true }); +}; diff --git a/src/Helper.ts b/src/Helper.ts index e265b8f29..2e138bbf2 100644 --- a/src/Helper.ts +++ b/src/Helper.ts @@ -1,5 +1,5 @@ -import { sacrificeAnts } from './Ants' -import { buyAllBlessings } from './Buy' +import { sacrificeAnts } from "./Ants"; +import { buyAllBlessings } from "./Buy"; import { calculateAscensionAcceleration, calculateAutomaticObtainium, @@ -8,28 +8,32 @@ import { calculateObtainium, calculateRequiredBlueberryTime, calculateTimeAcceleration, - octeractGainPerSecond -} from './Calculate' -import { quarkHandler } from './Quark' -import { checkMaxRunes, redeemShards, unlockedRune } from './Runes' -import { useConsumable } from './Shop' -import { player } from './Synergism' -import { Tabs } from './Tabs' -import { buyAllTalismanResources } from './Talismans' -import { visualUpdateAmbrosia, visualUpdateOcteracts, visualUpdateResearch } from './UpdateVisuals' -import { Globals as G } from './Variables' + octeractGainPerSecond, +} from "./Calculate"; +import { quarkHandler } from "./Quark"; +import { checkMaxRunes, redeemShards, unlockedRune } from "./Runes"; +import { useConsumable } from "./Shop"; +import { player } from "./Synergism"; +import { Tabs } from "./Tabs"; +import { buyAllTalismanResources } from "./Talismans"; +import { + visualUpdateAmbrosia, + visualUpdateOcteracts, + visualUpdateResearch, +} from "./UpdateVisuals"; +import { Globals as G } from "./Variables"; type TimerInput = - | 'prestige' - | 'transcension' - | 'reincarnation' - | 'ascension' - | 'quarks' - | 'goldenQuarks' - | 'singularity' - | 'octeracts' - | 'autoPotion' - | 'ambrosia' + | "prestige" + | "transcension" + | "reincarnation" + | "ascension" + | "quarks" + | "goldenQuarks" + | "singularity" + | "octeracts" + | "autoPotion" + | "ambrosia"; /** * addTimers will add (in milliseconds) time to the reset counters, and quark export timer @@ -37,160 +41,204 @@ type TimerInput = * @param time */ export const addTimers = (input: TimerInput, time = 0) => { - const timeMultiplier = (input === 'ascension' || input === 'quarks' || input === 'goldenQuarks' - || input === 'singularity' || input === 'octeracts' || input === 'autoPotion' || input === 'ambrosia') - ? 1 - : calculateTimeAcceleration().mult + const timeMultiplier = + input === "ascension" || + input === "quarks" || + input === "goldenQuarks" || + input === "singularity" || + input === "octeracts" || + input === "autoPotion" || + input === "ambrosia" + ? 1 + : calculateTimeAcceleration().mult; switch (input) { - case 'prestige': { - player.prestigecounter += time * timeMultiplier - break + case "prestige": { + player.prestigecounter += time * timeMultiplier; + break; } - case 'transcension': { - player.transcendcounter += time * timeMultiplier - break + case "transcension": { + player.transcendcounter += time * timeMultiplier; + break; } - case 'reincarnation': { - player.reincarnationcounter += time * timeMultiplier - break + case "reincarnation": { + player.reincarnationcounter += time * timeMultiplier; + break; } - case 'ascension': { // Anything in here is affected by add code - const ascensionSpeedMulti = (player.singularityUpgrades.oneMind.getEffect().bonus) + case "ascension": { + // Anything in here is affected by add code + const ascensionSpeedMulti = player.singularityUpgrades.oneMind.getEffect() + .bonus ? 10 - : calculateAscensionAcceleration() - player.ascensionCounter += time * timeMultiplier * ascensionSpeedMulti - player.ascensionCounterReal += time * timeMultiplier - break + : calculateAscensionAcceleration(); + player.ascensionCounter += time * timeMultiplier * ascensionSpeedMulti; + player.ascensionCounterReal += time * timeMultiplier; + break; } - case 'singularity': { - player.ascensionCounterRealReal += time - player.singularityCounter += time * timeMultiplier - break + case "singularity": { + player.ascensionCounterRealReal += time; + player.singularityCounter += time * timeMultiplier; + break; } - case 'quarks': { + case "quarks": { // First get maximum Quark Clock (25h, up to +25 from Research 8x20) - const maxQuarkTimer = quarkHandler().maxTime - player.quarkstimer += time * timeMultiplier + const maxQuarkTimer = quarkHandler().maxTime; + player.quarkstimer += time * timeMultiplier; // Checks if this new time is greater than maximum, in which it will default to that time. // Otherwise returns itself. - player.quarkstimer = (player.quarkstimer > maxQuarkTimer) ? maxQuarkTimer : player.quarkstimer - break + player.quarkstimer = + player.quarkstimer > maxQuarkTimer ? maxQuarkTimer : player.quarkstimer; + break; } - case 'goldenQuarks': { + case "goldenQuarks": { if (+player.singularityUpgrades.goldenQuarks3.getEffect().bonus === 0) { - return + return; } else { - player.goldenQuarksTimer += time * timeMultiplier - player.goldenQuarksTimer = (player.goldenQuarksTimer > 3600 * 168) ? 3600 * 168 : player.goldenQuarksTimer + player.goldenQuarksTimer += time * timeMultiplier; + player.goldenQuarksTimer = + player.goldenQuarksTimer > 3600 * 168 + ? 3600 * 168 + : player.goldenQuarksTimer; } - break + break; } - case 'octeracts': { + case "octeracts": { if (!player.singularityUpgrades.octeractUnlock.getEffect().bonus) { - return + return; } else { - player.octeractTimer += time * timeMultiplier + player.octeractTimer += time * timeMultiplier; } if (player.octeractTimer >= 1) { - const amountOfGiveaways = player.octeractTimer - (player.octeractTimer % 1) - player.octeractTimer %= 1 + const amountOfGiveaways = + player.octeractTimer - (player.octeractTimer % 1); + player.octeractTimer %= 1; - const perSecond = octeractGainPerSecond() - player.wowOcteracts += amountOfGiveaways * perSecond - player.totalWowOcteracts += amountOfGiveaways * perSecond + const perSecond = octeractGainPerSecond(); + player.wowOcteracts += amountOfGiveaways * perSecond; + player.totalWowOcteracts += amountOfGiveaways * perSecond; if (player.highestSingularityCount >= 160) { - const levels = [160, 173, 185, 194, 204, 210, 219, 229, 240, 249] - const frac = 1e-6 - let actualLevel = 0 + const levels = [160, 173, 185, 194, 204, 210, 219, 229, 240, 249]; + const frac = 1e-6; + let actualLevel = 0; for (const sing of levels) { if (player.highestSingularityCount >= sing) { - actualLevel += 1 + actualLevel += 1; } } for (let i = 0; i < amountOfGiveaways; i++) { - const quarkFraction = player.quarksThisSingularity * frac * actualLevel - player.goldenQuarks += quarkFraction * calculateGoldenQuarkGain(true) - player.quarksThisSingularity -= quarkFraction + const quarkFraction = + player.quarksThisSingularity * frac * actualLevel; + player.goldenQuarks += + quarkFraction * calculateGoldenQuarkGain(true); + player.quarksThisSingularity -= quarkFraction; } } - visualUpdateOcteracts() + visualUpdateOcteracts(); } - break + break; } - case 'autoPotion': { + case "autoPotion": { if (player.highestSingularityCount < 6) { - return + return; } else { // player.toggles[42] enables FAST Offering Potion Expenditure, but actually spends the potion. // Hence, you need at least one potion to be able to use fast spend. - const toggleOfferingOn = player.toggles[42] && player.shopUpgrades.offeringPotion > 0 + const toggleOfferingOn = + player.toggles[42] && player.shopUpgrades.offeringPotion > 0; // player.toggles[43] enables FAST Obtainium Potion Expenditure, but actually spends the potion. - const toggleObtainiumOn = player.toggles[43] && player.shopUpgrades.obtainiumPotion > 0 + const toggleObtainiumOn = + player.toggles[43] && player.shopUpgrades.obtainiumPotion > 0; - player.autoPotionTimer += time * timeMultiplier - player.autoPotionTimerObtainium += time * timeMultiplier + player.autoPotionTimer += time * timeMultiplier; + player.autoPotionTimerObtainium += time * timeMultiplier; - const timerThreshold = 180 * Math.pow(1.03, -player.highestSingularityCount) - / +player.octeractUpgrades.octeractAutoPotionSpeed.getEffect().bonus + const timerThreshold = + (180 * Math.pow(1.03, -player.highestSingularityCount)) / + +player.octeractUpgrades.octeractAutoPotionSpeed.getEffect().bonus; - const effectiveOfferingThreshold = toggleOfferingOn ? Math.min(1, timerThreshold) / 20 : timerThreshold - const effectiveObtainiumThreshold = toggleObtainiumOn ? Math.min(1, timerThreshold) / 20 : timerThreshold + const effectiveOfferingThreshold = toggleOfferingOn + ? Math.min(1, timerThreshold) / 20 + : timerThreshold; + const effectiveObtainiumThreshold = toggleObtainiumOn + ? Math.min(1, timerThreshold) / 20 + : timerThreshold; if (player.autoPotionTimer >= effectiveOfferingThreshold) { - const amountOfPotions = ((player.autoPotionTimer) - (player.autoPotionTimer % effectiveOfferingThreshold)) - / effectiveOfferingThreshold - player.autoPotionTimer %= effectiveOfferingThreshold - void useConsumable('offeringPotion', true, amountOfPotions, toggleOfferingOn) + const amountOfPotions = + (player.autoPotionTimer - + (player.autoPotionTimer % effectiveOfferingThreshold)) / + effectiveOfferingThreshold; + player.autoPotionTimer %= effectiveOfferingThreshold; + void useConsumable( + "offeringPotion", + true, + amountOfPotions, + toggleOfferingOn + ); } if (player.autoPotionTimerObtainium >= effectiveObtainiumThreshold) { const amountOfPotions = - ((player.autoPotionTimerObtainium) - (player.autoPotionTimerObtainium % effectiveObtainiumThreshold)) - / effectiveObtainiumThreshold - player.autoPotionTimerObtainium %= effectiveObtainiumThreshold - void useConsumable('obtainiumPotion', true, amountOfPotions, toggleObtainiumOn) + (player.autoPotionTimerObtainium - + (player.autoPotionTimerObtainium % effectiveObtainiumThreshold)) / + effectiveObtainiumThreshold; + player.autoPotionTimerObtainium %= effectiveObtainiumThreshold; + void useConsumable( + "obtainiumPotion", + true, + amountOfPotions, + toggleObtainiumOn + ); } } - break + break; } - case 'ambrosia': { - const compute = player.caches.ambrosiaGeneration.totalVal + case "ambrosia": { + const compute = player.caches.ambrosiaGeneration.totalVal; if (compute === 0) { - break + break; } - G.ambrosiaTimer += time * timeMultiplier + G.ambrosiaTimer += time * timeMultiplier; if (G.ambrosiaTimer < 1) { - break + break; } - const ambrosiaLuck = player.caches.ambrosiaLuck.totalVal - player.blueberryTime += Math.floor(G.ambrosiaTimer) * player.caches.ambrosiaGeneration.totalVal - G.ambrosiaTimer %= 1 + const ambrosiaLuck = player.caches.ambrosiaLuck.usedTotal; + player.blueberryTime += + Math.floor(G.ambrosiaTimer) * player.caches.ambrosiaGeneration.totalVal; + G.ambrosiaTimer %= 1; - const timeToAmbrosia = calculateRequiredBlueberryTime() + const timeToAmbrosia = calculateRequiredBlueberryTime(); if (player.blueberryTime >= timeToAmbrosia) { - const RNG = Math.random() - const ambrosiaMult = Math.floor(ambrosiaLuck / 100) + 1 - const luckMult = (RNG < (ambrosiaLuck / 100 - Math.floor(ambrosiaLuck / 100))) ? 1 : 0 - const timeMult = Math.min(100, Math.floor(player.blueberryTime / timeToAmbrosia)) + const RNG = Math.random(); + const ambrosiaMult = Math.floor(ambrosiaLuck / 100) + 1; + const luckMult = + RNG < ambrosiaLuck / 100 - Math.floor(ambrosiaLuck / 100) ? 1 : 0; + const timeMult = Math.min( + 100, + Math.floor(player.blueberryTime / timeToAmbrosia) + ); - player.ambrosia += 1 * (ambrosiaMult + luckMult) * timeMult - player.lifetimeAmbrosia += 1 * (ambrosiaMult + luckMult) * timeMult - player.blueberryTime -= timeToAmbrosia * timeMult + player.ambrosia += 1 * (ambrosiaMult + luckMult) * timeMult; + player.lifetimeAmbrosia += 1 * (ambrosiaMult + luckMult) * timeMult; + player.blueberryTime -= timeToAmbrosia * timeMult; } - visualUpdateAmbrosia() + visualUpdateAmbrosia(); } } -} +}; -type AutoToolInput = 'addObtainium' | 'addOfferings' | 'runeSacrifice' | 'antSacrifice' +type AutoToolInput = + | "addObtainium" + | "addOfferings" + | "runeSacrifice" + | "antSacrifice"; /** * Assortment of tools which are used when actions are automated. @@ -198,92 +246,122 @@ type AutoToolInput = 'addObtainium' | 'addOfferings' | 'runeSacrifice' | 'antSac * @param time */ export const automaticTools = (input: AutoToolInput, time: number) => { - const timeMultiplier = (input === 'runeSacrifice' || input === 'addOfferings') ? 1 : calculateTimeAcceleration().mult + const timeMultiplier = + input === "runeSacrifice" || input === "addOfferings" + ? 1 + : calculateTimeAcceleration().mult; switch (input) { - case 'addObtainium': { + case "addObtainium": { // If in challenge 14, abort and do not award obtainium if (player.currentChallenge.ascension === 14) { - break + break; } // Update Obtainium Multipliers + Amount to gain - calculateObtainium() - const obtainiumGain = calculateAutomaticObtainium() + calculateObtainium(); + const obtainiumGain = calculateAutomaticObtainium(); // Add Obtainium - player.researchPoints = Math.min(1e300, player.researchPoints + obtainiumGain * time * timeMultiplier) + player.researchPoints = Math.min( + 1e300, + player.researchPoints + obtainiumGain * time * timeMultiplier + ); // Update visual displays if appropriate if (G.currentTab === Tabs.Research) { - visualUpdateResearch() + visualUpdateResearch(); } - break + break; } - case 'addOfferings': + case "addOfferings": // This counter can be increased through challenge 3 reward // As well as cube upgrade 1x2 (2). - G.autoOfferingCounter += time + G.autoOfferingCounter += time; // Any time this exceeds 1 it adds an offering - player.runeshards = Math.min(1e300, player.runeshards + Math.floor(G.autoOfferingCounter)) - G.autoOfferingCounter %= 1 - break - case 'runeSacrifice': + player.runeshards = Math.min( + 1e300, + player.runeshards + Math.floor(G.autoOfferingCounter) + ); + G.autoOfferingCounter %= 1; + break; + case "runeSacrifice": // Every real life second this will trigger - player.sacrificeTimer += time - if (player.sacrificeTimer >= 1 && isFinite(player.runeshards) && player.runeshards > 0) { + player.sacrificeTimer += time; + if ( + player.sacrificeTimer >= 1 && + isFinite(player.runeshards) && + player.runeshards > 0 + ) { // Automatic purchase of Blessings if (player.highestSingularityCount >= 15) { - let ratio = 4 + let ratio = 4; if (player.toggles[36]) { - buyAllBlessings('Blessings', 100 / ratio, true) - ratio-- + buyAllBlessings("Blessings", 100 / ratio, true); + ratio--; } if (player.toggles[37]) { - buyAllBlessings('Spirits', 100 / ratio, true) - ratio-- + buyAllBlessings("Spirits", 100 / ratio, true); + ratio--; } } - if (player.autoBuyFragment && player.highestSingularityCount >= 40 && player.cubeUpgrades[51] > 0) { - buyAllTalismanResources() + if ( + player.autoBuyFragment && + player.highestSingularityCount >= 40 && + player.cubeUpgrades[51] > 0 + ) { + buyAllTalismanResources(); } // If you bought cube upgrade 2x10 then it sacrifices to all runes equally if (player.cubeUpgrades[20] === 1) { - const maxi = player.highestSingularityCount >= 50 ? 7 : (player.highestSingularityCount >= 30 ? 6 : 5) - const notMaxed = maxi - checkMaxRunes(maxi) + const maxi = + player.highestSingularityCount >= 50 + ? 7 + : player.highestSingularityCount >= 30 + ? 6 + : 5; + const notMaxed = maxi - checkMaxRunes(maxi); if (notMaxed > 0) { - const baseAmount = Math.floor(player.runeshards / notMaxed / 2) + const baseAmount = Math.floor(player.runeshards / notMaxed / 2); for (let i = 0; i < maxi; i++) { - if (!(!unlockedRune(i + 1) || player.runelevels[i] >= calculateMaxRunes(i + 1))) { - redeemShards(i + 1, true, baseAmount) + if ( + !( + !unlockedRune(i + 1) || + player.runelevels[i] >= calculateMaxRunes(i + 1) + ) + ) { + redeemShards(i + 1, true, baseAmount); } } } } else { // If you did not buy cube upgrade 2x10 it sacrifices to selected rune. - const rune = player.autoSacrifice - redeemShards(rune, true, 0) + const rune = player.autoSacrifice; + redeemShards(rune, true, 0); } // Modulo used in event of a large delta time (this could happen for a number of reasons) - player.sacrificeTimer %= 1 + player.sacrificeTimer %= 1; } - break - case 'antSacrifice': { + break; + case "antSacrifice": { // Increments real and 'fake' timers. the Real timer is on real life seconds. - player.antSacrificeTimer += time * timeMultiplier - player.antSacrificeTimerReal += time + player.antSacrificeTimer += time * timeMultiplier; + player.antSacrificeTimerReal += time; // Equal to real time iff "Real Time" option selected in ants tab. - const antSacrificeTimer = (player.autoAntSacrificeMode === 2) - ? player.antSacrificeTimerReal - : player.antSacrificeTimer + const antSacrificeTimer = + player.autoAntSacrificeMode === 2 + ? player.antSacrificeTimerReal + : player.antSacrificeTimer; if ( - antSacrificeTimer >= player.autoAntSacTimer && player.antSacrificeTimerReal > 0.1 - && player.researches[124] === 1 - && player.autoAntSacrifice && player.antPoints.gte('1e40') + antSacrificeTimer >= player.autoAntSacTimer && + player.antSacrificeTimerReal > 0.1 && + player.researches[124] === 1 && + player.autoAntSacrifice && + player.antPoints.gte("1e40") ) { - void sacrificeAnts(true) + void sacrificeAnts(true); } - break + break; } } -} +}; diff --git a/src/ImportExport.ts b/src/ImportExport.ts index 52472f844..cdda5c5a4 100644 --- a/src/ImportExport.ts +++ b/src/ImportExport.ts @@ -1,493 +1,555 @@ -import ClipboardJS from 'clipboard' -import i18next from 'i18next' -import localforage from 'localforage' -import LZString from 'lz-string' -import { achievementaward } from './Achievements' -import { DOMCacheGetOrSet } from './Cache/DOM' -import { octeractGainPerSecond } from './Calculate' -import { testing, version } from './Config' -import { getEvent } from './Event' -import { Synergism } from './Events' -import { addTimers } from './Helper' -import { quarkHandler } from './Quark' -import { shopData } from './Shop' -import { singularityData } from './singularity' -import { synergismStage } from './Statistics' -import { blankSave, format, player, reloadShit, saveCheck, saveSynergy } from './Synergism' -import { changeSubTab, changeTab, Tabs } from './Tabs' -import type { Player } from './types/Synergism' -import { Alert, Confirm, Prompt } from './UpdateHTML' -import { cleanString, getElementById, productContents, sumContents } from './Utility' -import { btoa } from './Utility' -import { Globals as G } from './Variables' - -const format24 = new Intl.DateTimeFormat('EN-GB', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', +import ClipboardJS from "clipboard"; +import i18next from "i18next"; +import localforage from "localforage"; +import LZString from "lz-string"; +import { achievementaward } from "./Achievements"; +import { DOMCacheGetOrSet } from "./Cache/DOM"; +import { octeractGainPerSecond } from "./Calculate"; +import { testing, version } from "./Config"; +import { getEvent } from "./Event"; +import { Synergism } from "./Events"; +import { addTimers } from "./Helper"; +import { quarkHandler } from "./Quark"; +import { shopData } from "./Shop"; +import { singularityData } from "./singularity"; +import { synergismStage } from "./Statistics"; +import { + blankSave, + format, + player, + reloadShit, + saveCheck, + saveSynergy, +} from "./Synergism"; +import { changeSubTab, changeTab, Tabs } from "./Tabs"; +import type { Player } from "./types/Synergism"; +import { Alert, Confirm, Prompt } from "./UpdateHTML"; +import { + cleanString, + getElementById, + productContents, + sumContents, +} from "./Utility"; +import { btoa } from "./Utility"; +import { Globals as G } from "./Variables"; + +const format24 = new Intl.DateTimeFormat("EN-GB", { + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", hour12: false, - minute: '2-digit', - second: '2-digit' -}) -const format12 = new Intl.DateTimeFormat('EN-GB', { - year: 'numeric', - month: '2-digit', - day: '2-digit', - hour: '2-digit', + minute: "2-digit", + second: "2-digit", +}); +const format12 = new Intl.DateTimeFormat("EN-GB", { + year: "numeric", + month: "2-digit", + day: "2-digit", + hour: "2-digit", hour12: true, - minute: '2-digit', - second: '2-digit' -}) + minute: "2-digit", + second: "2-digit", +}); -const hour = 3600000 +const hour = 3600000; -const getRealTime = (type = 'default', use12 = false) => { - const format = use12 ? format12 : format24 +const getRealTime = (type = "default", use12 = false) => { + const format = use12 ? format12 : format24; const datePartsArr = format .formatToParts(new Date()) - .filter((x) => x.type !== 'literal') - .map((p) => ({ [p.type]: p.value })) + .filter((x) => x.type !== "literal") + .map((p) => ({ [p.type]: p.value })); - const dateParts = Object.assign({}, ...datePartsArr) as Record + const dateParts = Object.assign({}, ...datePartsArr) as Record< + string, + string + >; - const period = use12 ? ` ${dateParts.dayPeriod.toUpperCase()}` : '' - const weekday = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'] + const period = use12 ? ` ${dateParts.dayPeriod.toUpperCase()}` : ""; + const weekday = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"]; switch (type) { - case 'default': - return `${dateParts.year}-${dateParts.month}-${dateParts.day} ${dateParts.hour}_${dateParts.minute}_${dateParts.second}${period}` - case 'short': - return `${dateParts.year}${dateParts.month}${dateParts.day}${dateParts.hour}${dateParts.minute}${dateParts.second}` - case 'year': - return `${dateParts.year}` - case 'month': - return `${dateParts.month}` - case 'day': - return `${dateParts.day}` - case 'hour': - return `${dateParts.hour}` - case 'minute': - return `${dateParts.minute}` - case 'second': - return `${dateParts.second}` - case 'period': - return `${dateParts.dayPeriod.toUpperCase()}` - case 'weekday': - return `${weekday[new Date().getUTCDay()]}` + case "default": + return `${dateParts.year}-${dateParts.month}-${dateParts.day} ${dateParts.hour}_${dateParts.minute}_${dateParts.second}${period}`; + case "short": + return `${dateParts.year}${dateParts.month}${dateParts.day}${dateParts.hour}${dateParts.minute}${dateParts.second}`; + case "year": + return `${dateParts.year}`; + case "month": + return `${dateParts.month}`; + case "day": + return `${dateParts.day}`; + case "hour": + return `${dateParts.hour}`; + case "minute": + return `${dateParts.minute}`; + case "second": + return `${dateParts.second}`; + case "period": + return `${dateParts.dayPeriod.toUpperCase()}`; + case "weekday": + return `${weekday[new Date().getUTCDay()]}`; default: - return type + return type; } -} +}; export const updateSaveString = (input: HTMLInputElement) => { - const value = input.value.slice(0, 100) - player.saveString = value === '' ? blankSave.saveString : cleanString(value) - ;(DOMCacheGetOrSet('saveStringInput') as HTMLInputElement).value = player.saveString -} + const value = input.value.slice(0, 100); + player.saveString = value === "" ? blankSave.saveString : cleanString(value); + (DOMCacheGetOrSet("saveStringInput") as HTMLInputElement).value = + player.saveString; +}; -export const getVer = () => /[\d?=.]+/.exec(version)?.[0] ?? version +export const getVer = () => /[\d?=.]+/.exec(version)?.[0] ?? version; export const saveFilename = () => { - const s = player.saveString + const s = player.saveString; const t = s.replace(/\$(.*?)\$/g, (_, b) => { switch (b) { - case 'VERSION': - return `v${version}` - case 'TIME': - return getRealTime() - case 'TIME12': - return getRealTime(undefined, true) - case 'SING': - return `Singularity ${player.singularityCount}` - case 'SINGS': - return `${player.singularityCount}` - case 'VER': - return getVer() - case 'TIMES': - return getRealTime('short') - case 'YEAR': - return getRealTime('year') - case 'Y': - return getRealTime('year') - case 'MONTH': - return getRealTime('month') - case 'M': - return getRealTime('month') - case 'DAY': - return getRealTime('day') - case 'D': - return getRealTime('day') - case 'HOUR': - return getRealTime('hour') - case 'H': - return getRealTime('hour') - case 'H12': - return getRealTime('hour', true) - case 'MINUTE': - return getRealTime('minute') - case 'MI': - return getRealTime('minute') - case 'SECOND': - return getRealTime('second') - case 'S': - return getRealTime('second') - case 'PERIOD': - return getRealTime('period', true) - case 'P': - return getRealTime('period', true) - case 'WEEKDAY': - return getRealTime('weekday') - case 'W': - return getRealTime('weekday') - case 'DATE': - return `${Date.now()}` - case 'DATES': - return `${Math.floor(Date.now() / 1000)}` - case 'QUARK': - return `${Math.floor(Number(player.worlds))}` - case 'QUARKS': - return format(Number(player.worlds)) - case 'GQ': - return `${Math.floor(player.goldenQuarks)}` - case 'GQS': - return format(player.goldenQuarks) - case 'STAGE': - return synergismStage(0) + case "VERSION": + return `v${version}`; + case "TIME": + return getRealTime(); + case "TIME12": + return getRealTime(undefined, true); + case "SING": + return `Singularity ${player.singularityCount}`; + case "SINGS": + return `${player.singularityCount}`; + case "VER": + return getVer(); + case "TIMES": + return getRealTime("short"); + case "YEAR": + return getRealTime("year"); + case "Y": + return getRealTime("year"); + case "MONTH": + return getRealTime("month"); + case "M": + return getRealTime("month"); + case "DAY": + return getRealTime("day"); + case "D": + return getRealTime("day"); + case "HOUR": + return getRealTime("hour"); + case "H": + return getRealTime("hour"); + case "H12": + return getRealTime("hour", true); + case "MINUTE": + return getRealTime("minute"); + case "MI": + return getRealTime("minute"); + case "SECOND": + return getRealTime("second"); + case "S": + return getRealTime("second"); + case "PERIOD": + return getRealTime("period", true); + case "P": + return getRealTime("period", true); + case "WEEKDAY": + return getRealTime("weekday"); + case "W": + return getRealTime("weekday"); + case "DATE": + return `${Date.now()}`; + case "DATES": + return `${Math.floor(Date.now() / 1000)}`; + case "QUARK": + return `${Math.floor(Number(player.worlds))}`; + case "QUARKS": + return format(Number(player.worlds)); + case "GQ": + return `${Math.floor(player.goldenQuarks)}`; + case "GQS": + return format(player.goldenQuarks); + case "STAGE": + return synergismStage(0); default: - return `${b}` + return `${b}`; } - }) + }); - return cleanString(t) -} + return cleanString(t); +}; export const exportData = async (text: string, fileName: string) => { - const toClipboard = getElementById('saveType').checked + const toClipboard = getElementById("saveType").checked; if (toClipboard) { try { // This can fail for two reasons: // - TypeError (browser doesn't support this feature) // - Failed to copy (browser limitation; Safari) - await navigator.clipboard.writeText(text) - DOMCacheGetOrSet('exportinfo').textContent = i18next.t('importexport.copiedSave') + await navigator.clipboard.writeText(text); + DOMCacheGetOrSet("exportinfo").textContent = i18next.t( + "importexport.copiedSave" + ); } catch (err) { // So we fallback to the deprecated way of doing it, // which isn't limited by any browser. // Old/bad browsers (legacy Edge, Safari because of limitations) - const textArea = document.createElement('textarea') + const textArea = document.createElement("textarea"); - textArea.setAttribute('style', 'top: 0; left: 0; position: fixed;') + textArea.setAttribute("style", "top: 0; left: 0; position: fixed;"); // For future Khafra: html5 attributes have no limit in length - textArea.setAttribute('data-clipboard-text', text) + textArea.setAttribute("data-clipboard-text", text); - document.body.appendChild(textArea) - textArea.focus() - textArea.select() + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); - const clipboard = new ClipboardJS(textArea) + const clipboard = new ClipboardJS(textArea); const cleanup = () => { - clipboard.destroy() - document.body.removeChild(textArea) - } - - clipboard.on('success', () => { - DOMCacheGetOrSet('exportinfo').textContent = i18next.t('importexport.copiedSave') - cleanup() - }) - - clipboard.on('error', () => { - DOMCacheGetOrSet('exportinfo').textContent = i18next.t('importexport.exportFailed') - void Alert(i18next.t('importexport.unableCopySave')).finally(cleanup) - }) + clipboard.destroy(); + document.body.removeChild(textArea); + }; + + clipboard.on("success", () => { + DOMCacheGetOrSet("exportinfo").textContent = i18next.t( + "importexport.copiedSave" + ); + cleanup(); + }); + + clipboard.on("error", () => { + DOMCacheGetOrSet("exportinfo").textContent = i18next.t( + "importexport.exportFailed" + ); + void Alert(i18next.t("importexport.unableCopySave")).finally(cleanup); + }); } } else { - const a = document.createElement('a') - a.setAttribute('href', `data:text/plain;charset=utf-8,${text}`) - a.setAttribute('download', fileName) - a.setAttribute('id', 'downloadSave') + const a = document.createElement("a"); + a.setAttribute("href", `data:text/plain;charset=utf-8,${text}`); + a.setAttribute("download", fileName); + a.setAttribute("id", "downloadSave"); // "Starting in Firefox 75, the click() function works even when the element is not attached to a DOM tree." // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click // so let's have it work on older versions of Firefox, doesn't change functionality. - document.body.appendChild(a) - a.click() - document.body.removeChild(a) - DOMCacheGetOrSet('exportinfo').textContent = i18next.t('importexport.copiedFile') + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + DOMCacheGetOrSet("exportinfo").textContent = i18next.t( + "importexport.copiedFile" + ); } - setTimeout(() => DOMCacheGetOrSet('exportinfo').textContent = '', 15_000) -} + setTimeout(() => (DOMCacheGetOrSet("exportinfo").textContent = ""), 15_000); +}; -export const exportSynergism = async (shouldSetLastSaveSoWeStopFuckingBotheringPeople = true) => { - player.offlinetick = Date.now() +export const exportSynergism = async ( + shouldSetLastSaveSoWeStopFuckingBotheringPeople = true +) => { + player.offlinetick = Date.now(); if (shouldSetLastSaveSoWeStopFuckingBotheringPeople) { - player.lastExportedSave = Date.now() + player.lastExportedSave = Date.now(); - const quarkData = quarkHandler() + const quarkData = quarkHandler(); - let bonusGQMultiplier = 1 - bonusGQMultiplier *= 1 + player.worlds.BONUS / 100 - bonusGQMultiplier *= player.highestSingularityCount >= 100 ? 1 + player.highestSingularityCount / 50 : 1 + let bonusGQMultiplier = 1; + bonusGQMultiplier *= 1 + player.worlds.BONUS / 100; + bonusGQMultiplier *= + player.highestSingularityCount >= 100 + ? 1 + player.highestSingularityCount / 50 + : 1; if (+player.singularityUpgrades.goldenQuarks3.getEffect().bonus > 0) { player.goldenQuarks += - Math.floor(player.goldenQuarksTimer / (3600 / +player.singularityUpgrades.goldenQuarks3.getEffect().bonus)) - * bonusGQMultiplier - player.goldenQuarksTimer = player.goldenQuarksTimer - % (3600 / +player.singularityUpgrades.goldenQuarks3.getEffect().bonus) + Math.floor( + player.goldenQuarksTimer / + (3600 / +player.singularityUpgrades.goldenQuarks3.getEffect().bonus) + ) * bonusGQMultiplier; + player.goldenQuarksTimer = + player.goldenQuarksTimer % + (3600 / +player.singularityUpgrades.goldenQuarks3.getEffect().bonus); } if (quarkData.gain >= 1) { - player.worlds.add(quarkData.gain) - player.quarkstimer = player.quarkstimer % (3600 / quarkData.perHour) + player.worlds.add(quarkData.gain); + player.quarkstimer = player.quarkstimer % (3600 / quarkData.perHour); } } - const saved = await saveSynergy() + const saved = await saveSynergy(); if (!saved) { - return + return; } - const save = await localforage.getItem('Synergysave2') - ?? localStorage.getItem('Synergysave2') - const saveString = typeof save === 'string' ? save : await save?.text() + const save = + (await localforage.getItem("Synergysave2")) ?? + localStorage.getItem("Synergysave2"); + const saveString = typeof save === "string" ? save : await save?.text(); if (saveString === undefined) { - return Alert('How?') + return Alert("How?"); } - await exportData(saveString, saveFilename()) - setTimeout(() => DOMCacheGetOrSet('exportinfo').textContent = '', 15_000) -} + await exportData(saveString, saveFilename()); + setTimeout(() => (DOMCacheGetOrSet("exportinfo").textContent = ""), 15_000); +}; export const reloadDeleteGame = async () => { - await Alert(i18next.t('importexport.reloadDeletePrompt')) - await resetGame() -} + await Alert(i18next.t("importexport.reloadDeletePrompt")); + await resetGame(); +}; export const resetGame = async () => { - const a = window.crypto.getRandomValues(new Uint16Array(1))[0] % 16 - const b = window.crypto.getRandomValues(new Uint16Array(1))[0] % 16 + const a = window.crypto.getRandomValues(new Uint16Array(1))[0] % 16; + const b = window.crypto.getRandomValues(new Uint16Array(1))[0] % 16; - const result = await Prompt(i18next.t('importexport.resetPrompt', { a, b, sum: a + b })) + const result = await Prompt( + i18next.t("importexport.resetPrompt", { a, b, sum: a + b }) + ); if (result === null || Number(result) !== a + b) { - return Alert(i18next.t('importexport.wrongAnswer')) + return Alert(i18next.t("importexport.wrongAnswer")); } const hold = Object.assign({}, blankSave, { - codes: Array.from(blankSave.codes) - }) as Player + codes: Array.from(blankSave.codes), + }) as Player; // Reset Displays - changeTab(Tabs.Buildings) - changeSubTab(Tabs.Buildings, { page: 0 }) - changeSubTab(Tabs.Runes, { page: 0 }) // Set 'runes' subtab back to 'runes' tab - changeSubTab(Tabs.WowCubes, { page: 0 }) // Set 'cube tribues' subtab back to 'cubes' tab - changeSubTab(Tabs.Corruption, { page: 0 }) // set 'corruption main' - changeSubTab(Tabs.Singularity, { page: 0 }) // set 'singularity main' - changeSubTab(Tabs.Settings, { page: 0 }) // set 'statistics main' + changeTab(Tabs.Buildings); + changeSubTab(Tabs.Buildings, { page: 0 }); + changeSubTab(Tabs.Runes, { page: 0 }); // Set 'runes' subtab back to 'runes' tab + changeSubTab(Tabs.WowCubes, { page: 0 }); // Set 'cube tribues' subtab back to 'cubes' tab + changeSubTab(Tabs.Corruption, { page: 0 }); // set 'corruption main' + changeSubTab(Tabs.Singularity, { page: 0 }); // set 'singularity main' + changeSubTab(Tabs.Settings, { page: 0 }); // set 'statistics main' // Import Game - await importSynergism(btoa(JSON.stringify(hold)), true) -} - -export const importData = async (e: Event, importFunc: (save: string | null) => Promise | Promise) => { - const element = e.target as HTMLInputElement - const file = element.files![0] - let save = '' + await importSynergism(btoa(JSON.stringify(hold)), true); +}; + +export const importData = async ( + e: Event, + importFunc: (save: string | null) => Promise | Promise +) => { + const element = e.target as HTMLInputElement; + const file = element.files![0]; + let save = ""; // https://developer.mozilla.org/en-US/docs/Web/API/Blob/text // not available in (bad) browsers like Safari 11 - if (typeof Blob.prototype.text === 'function') { - save = await file.text() + if (typeof Blob.prototype.text === "function") { + save = await file.text(); } else { - const reader = new FileReader() - reader.readAsText(file) + const reader = new FileReader(); + reader.readAsText(file); const text = await new Promise((res) => { - reader.addEventListener('load', () => res(reader.result!.toString())) - }) + reader.addEventListener("load", () => res(reader.result!.toString())); + }); - save = text + save = text; } - element.value = '' - handleLastModified(file.lastModified) + element.value = ""; + handleLastModified(file.lastModified); - return importFunc(save) -} + return importFunc(save); +}; export const importSynergism = async (input: string | null, reset = false) => { - if (typeof input !== 'string') { - return Alert(i18next.t('importexport.unableImport')) + if (typeof input !== "string") { + return Alert(i18next.t("importexport.unableImport")); } - const d = LZString.decompressFromBase64(input) - const f = d ? JSON.parse(d) as Player : JSON.parse(atob(input)) as Player + const d = LZString.decompressFromBase64(input); + const f = d ? (JSON.parse(d) as Player) : (JSON.parse(atob(input)) as Player); if ( - (f.exporttest === 'YES!' || f.exporttest === true) - || (f.exporttest === false && testing) - || (f.exporttest === 'NO!' && testing) + f.exporttest === "YES!" || + f.exporttest === true || + (f.exporttest === false && testing) || + (f.exporttest === "NO!" && testing) ) { - const saveString = btoa(JSON.stringify(f)) + const saveString = btoa(JSON.stringify(f)); if (saveString === null) { - return Alert(i18next.t('importexport.unableImport')) + return Alert(i18next.t("importexport.unableImport")); } - saveCheck.canSave = false - const item = new Blob([saveString], { type: 'text/plain' }) - localStorage.setItem('Synergysave2', saveString) - await localforage.setItem('Synergysave2', item) + saveCheck.canSave = false; + const item = new Blob([saveString], { type: "text/plain" }); + localStorage.setItem("Synergysave2", saveString); + await localforage.setItem("Synergysave2", item); - localStorage.setItem('saveScumIsCheating', Date.now().toString()) + localStorage.setItem("saveScumIsCheating", Date.now().toString()); - await reloadShit(reset) - saveCheck.canSave = true - return + await reloadShit(reset); + saveCheck.canSave = true; + return; } else { - return Alert(i18next.t('importexport.loadTestInLive')) + return Alert(i18next.t("importexport.loadTestInLive")); } -} +}; export const promocodesInfo = (input: string) => { - const textElement = DOMCacheGetOrSet('promocodeinfo') - let textMessage = `'${input}': ` - let availableUses = 0 + const textElement = DOMCacheGetOrSet("promocodeinfo"); + let textMessage = `'${input}': `; + let availableUses = 0; switch (input) { - case 'daily': + case "daily": if (player.dailyCodeUsed) { - textMessage += i18next.t('importexport.daily0Uses') + textMessage += i18next.t("importexport.daily0Uses"); } else { - textMessage += i18next.t('importexport.daily1Uses') + textMessage += i18next.t("importexport.daily1Uses"); } - break - case 'add': - availableUses = addCodeAvailableUses() + break; + case "add": + availableUses = addCodeAvailableUses(); if (availableUses === 0) { - textMessage += i18next.t('importexport.add0Uses', { + textMessage += i18next.t("importexport.add0Uses", { x: 0, - y: format(addCodeTimeToNextUse(), 0) - }) + y: format(addCodeTimeToNextUse(), 0), + }); } else if (availableUses !== 1) { - textMessage += i18next.t('importexport.addUses', { x: availableUses }) + textMessage += i18next.t("importexport.addUses", { x: availableUses }); } else { - textMessage += i18next.t('importexport.add1Uses', { x: availableUses }) + textMessage += i18next.t("importexport.add1Uses", { x: availableUses }); } - break - case 'time': - availableUses = timeCodeAvailableUses() + break; + case "time": + availableUses = timeCodeAvailableUses(); if (availableUses === 0) { - textMessage += i18next.t('importexport.add0Uses', { + textMessage += i18next.t("importexport.add0Uses", { x: 0, - y: format(timeCodeTimeToNextUse(), 0) - }) + y: format(timeCodeTimeToNextUse(), 0), + }); } else { - textMessage += i18next.t('importexport.timeMultiplier', { + textMessage += i18next.t("importexport.timeMultiplier", { x: availableUses, - y: format(timeCodeRewardMultiplier(), 2, true) - }) + y: format(timeCodeRewardMultiplier(), 2, true), + }); } - break + break; default: - textMessage = '' + textMessage = ""; } - textElement.textContent = textMessage -} + textElement.textContent = textMessage; +}; export const promocodesPrompt = async () => { - const input = await Prompt(i18next.t('importexport.promocodePrompt')) - void promocodes(input) -} + const input = await Prompt(i18next.t("importexport.promocodePrompt")); + void promocodes(input); +}; export const promocodes = async (input: string | null, amount?: number) => { - const el = DOMCacheGetOrSet('promocodeinfo') + const el = DOMCacheGetOrSet("promocodeinfo"); if (input === null) { - return Alert(i18next.t('importexport.comeBackSoon')) + return Alert(i18next.t("importexport.comeBackSoon")); } if ( - input === 'synergism2023' && !player.codes.get(46) && G.isEvent - && getEvent()?.name === 'Synergism 3: More Synergies' + input === "synergism2023" && + !player.codes.get(46) && + G.isEvent && + getEvent()?.name === "Synergism 3: More Synergies" ) { if (!player.dailyCodeUsed) { return Alert( - 'This event code gives you another usage of code \'daily\'. Please use that code and try this event code again.' - ) + "This event code gives you another usage of code 'daily'. Please use that code and try this event code again." + ); } - player.codes.set(46, true) - player.quarkstimer = quarkHandler().maxTime - player.goldenQuarksTimer = 3600 * 24 - addTimers('ascension', 4 * 3600) - player.dailyCodeUsed = false + player.codes.set(46, true); + player.quarkstimer = quarkHandler().maxTime; + player.goldenQuarksTimer = 3600 * 24; + addTimers("ascension", 4 * 3600); + player.dailyCodeUsed = false; - if (player.challenge15Exponent >= 1e15 || player.highestSingularityCount > 0) { - player.hepteractCrafts.quark.CAP *= 2 - player.hepteractCrafts.quark.BAL += Math.min(1e13, player.hepteractCrafts.quark.CAP / 2) + if ( + player.challenge15Exponent >= 1e15 || + player.highestSingularityCount > 0 + ) { + player.hepteractCrafts.quark.CAP *= 2; + player.hepteractCrafts.quark.BAL += Math.min( + 1e13, + player.hepteractCrafts.quark.CAP / 2 + ); } if (player.highestSingularityCount > 0) { - player.singularityUpgrades.goldenQuarks1.freeLevels += 1 + Math.floor(player.highestSingularityCount / 25) - player.singularityUpgrades.goldenQuarks2.freeLevels += 1 + Math.floor(player.highestSingularityCount / 25) - player.singularityUpgrades.goldenQuarks3.freeLevels += 1 + Math.floor(player.highestSingularityCount / 25) + player.singularityUpgrades.goldenQuarks1.freeLevels += + 1 + Math.floor(player.highestSingularityCount / 25); + player.singularityUpgrades.goldenQuarks2.freeLevels += + 1 + Math.floor(player.highestSingularityCount / 25); + player.singularityUpgrades.goldenQuarks3.freeLevels += + 1 + Math.floor(player.highestSingularityCount / 25); if (player.singularityUpgrades.octeractUnlock.getEffect().bonus) { - player.octeractUpgrades.octeractAscensionsOcteractGain.freeLevels += 0.2 + player.octeractUpgrades.octeractAscensionsOcteractGain.freeLevels += 0.2; } } return Alert( `Happy 3rd anniversary of Synergism!!!! Your Quark timer(s) have been replenished and you have been given 4 real life hours of Ascension progress! Your daily code has also been reset for you. ${ - (player.challenge15Exponent >= 1e15 || player.highestSingularityCount > 0) - ? 'Derpsmith also hacked your save to expand Quark Hepteract for free, and (to a limit) automatically filled the extra amount! What a generous, handsome fella.' - : '' - } - ${(player.highestSingularityCount > 0) ? 'You were also given free levels of GQ1-3!' : ''} + player.challenge15Exponent >= 1e15 || + player.highestSingularityCount > 0 + ? "Derpsmith also hacked your save to expand Quark Hepteract for free, and (to a limit) automatically filled the extra amount! What a generous, handsome fella." + : "" + } ${ - (player.singularityUpgrades.octeractUnlock.getEffect().bonus) - ? 'Finally, you were given free levels of Octeract Accumulator!' - : '' - }` - ) + player.highestSingularityCount > 0 + ? "You were also given free levels of GQ1-3!" + : "" + } + ${ + player.singularityUpgrades.octeractUnlock.getEffect() + .bonus + ? "Finally, you were given free levels of Octeract Accumulator!" + : "" + }` + ); } - if (input === 'synergism2021' && !player.codes.get(1)) { - player.codes.set(1, true) - player.runeshards += 25 - player.worlds.add(50) - el.textContent = i18next.t('importexport.promocodes.synergism2021') - } else if (input === ':unsmith:' && player.achievements[243] < 1) { - achievementaward(243) - el.textContent = i18next.t('importexport.promocodes.unsmith') - } else if (input === ':antismith:' && player.achievements[244] < 1) { - achievementaward(244) - el.textContent = i18next.t('importexport.promocodes.antismith') - } else if (input === 'Khafra' && !player.codes.get(26)) { - player.codes.set(26, true) - const quarks = Math.floor(Math.random() * (400 - 100 + 1) + 100) - player.worlds.add(quarks) - el.textContent = i18next.t('importexport.promocodes.khafra', { - x: player.worlds.applyBonus(quarks) - }) - } else if (input.toLowerCase() === 'daily' && !player.dailyCodeUsed) { - player.dailyCodeUsed = true - let rewardMessage = i18next.t('importexport.promocodes.daily.message') - - const rewards = dailyCodeReward() - const quarkMultiplier = 1 + Math.min(49, player.highestSingularityCount) - - let actualQuarkAward = player.worlds.applyBonus(rewards.quarks * quarkMultiplier) + if (input === "synergism2021" && !player.codes.get(1)) { + player.codes.set(1, true); + player.runeshards += 25; + player.worlds.add(50); + el.textContent = i18next.t("importexport.promocodes.synergism2021"); + } else if (input === ":unsmith:" && player.achievements[243] < 1) { + achievementaward(243); + el.textContent = i18next.t("importexport.promocodes.unsmith"); + } else if (input === ":antismith:" && player.achievements[244] < 1) { + achievementaward(244); + el.textContent = i18next.t("importexport.promocodes.antismith"); + } else if (input === "Khafra" && !player.codes.get(26)) { + player.codes.set(26, true); + const quarks = Math.floor(Math.random() * (400 - 100 + 1) + 100); + player.worlds.add(quarks); + el.textContent = i18next.t("importexport.promocodes.khafra", { + x: player.worlds.applyBonus(quarks), + }); + } else if (input.toLowerCase() === "daily" && !player.dailyCodeUsed) { + player.dailyCodeUsed = true; + let rewardMessage = i18next.t("importexport.promocodes.daily.message"); + + const rewards = dailyCodeReward(); + const quarkMultiplier = 1 + Math.min(49, player.highestSingularityCount); + + let actualQuarkAward = player.worlds.applyBonus( + rewards.quarks * quarkMultiplier + ); if (actualQuarkAward > 1e5) { - actualQuarkAward = Math.pow(1e5, 0.75) * Math.pow(actualQuarkAward, 0.25) + actualQuarkAward = Math.pow(1e5, 0.75) * Math.pow(actualQuarkAward, 0.25); } - player.worlds.add(actualQuarkAward, false) - player.goldenQuarks += rewards.goldenQuarks + player.worlds.add(actualQuarkAward, false); + player.goldenQuarks += rewards.goldenQuarks; - rewardMessage += `\n${format(actualQuarkAward, 0, true)} Quarks` + rewardMessage += `\n${format(actualQuarkAward, 0, true)} Quarks`; if (rewards.goldenQuarks > 0) { - rewardMessage += `\n${format(rewards.goldenQuarks, 0, true)} Golden Quarks` + rewardMessage += `\n${format( + rewards.goldenQuarks, + 0, + true + )} Golden Quarks`; } - await Alert(rewardMessage) + await Alert(rewardMessage); if (player.highestSingularityCount > 0) { const upgradeDistribution = { @@ -503,170 +565,219 @@ export const promocodes = async (input: string | null, amount?: number) => { singCubes1: { value: 1, pdf: (x: number) => 200 < x && x <= 400 }, singObtainium1: { value: 1, pdf: (x: number) => 400 < x && x <= 600 }, singOfferings1: { value: 1, pdf: (x: number) => 600 < x && x <= 800 }, - ascensions: { value: 1, pdf: (x: number) => 800 < x && x <= 1000 } - } - let rolls = 3 * Math.sqrt(player.highestSingularityCount) - rolls += +player.octeractUpgrades.octeractImprovedDaily.getEffect().bonus - rolls += player.shopUpgrades.shopImprovedDaily2 - rolls += player.shopUpgrades.shopImprovedDaily3 - rolls += player.shopUpgrades.shopImprovedDaily4 - rolls += +player.singularityUpgrades.platonicPhi.getEffect().bonus - * Math.min(50, 5 * player.singularityCounter / (3600 * 24)) - rolls += +player.octeractUpgrades.octeractImprovedDaily3.getEffect().bonus - rolls *= +player.octeractUpgrades.octeractImprovedDaily2.getEffect().bonus - rolls *= 1 + +player.octeractUpgrades.octeractImprovedDaily3.getEffect().bonus / 200 + ascensions: { value: 1, pdf: (x: number) => 800 < x && x <= 1000 }, + }; + let rolls = 3 * Math.sqrt(player.highestSingularityCount); + rolls += +player.octeractUpgrades.octeractImprovedDaily.getEffect().bonus; + rolls += player.shopUpgrades.shopImprovedDaily2; + rolls += player.shopUpgrades.shopImprovedDaily3; + rolls += player.shopUpgrades.shopImprovedDaily4; + rolls += + +player.singularityUpgrades.platonicPhi.getEffect().bonus * + Math.min(50, (5 * player.singularityCounter) / (3600 * 24)); + rolls += + +player.octeractUpgrades.octeractImprovedDaily3.getEffect().bonus; + rolls *= + +player.octeractUpgrades.octeractImprovedDaily2.getEffect().bonus; + rolls *= + 1 + + +player.octeractUpgrades.octeractImprovedDaily3.getEffect().bonus / 200; if (player.highestSingularityCount >= 200) { - rolls *= 2 + rolls *= 2; } - rolls = Math.floor(rolls) + rolls = Math.floor(rolls); - const keys = Object - .keys(player.singularityUpgrades) - .filter((key) => key in upgradeDistribution) as (keyof typeof upgradeDistribution)[] + const keys = Object.keys(player.singularityUpgrades).filter( + (key) => key in upgradeDistribution + ) as (keyof typeof upgradeDistribution)[]; - rewardMessage = i18next.t('importexport.promocodes.daily.message2') + rewardMessage = i18next.t("importexport.promocodes.daily.message2"); // The same upgrade can be drawn several times, so we save the sum of the levels gained, to display them only once at the end - const freeLevels: Record = {} + const freeLevels: Record = {}; for (let i = 0; i < rolls; i++) { - const num = 1000 * Math.random() + const num = 1000 * Math.random(); for (const key of keys) { if (upgradeDistribution[key].pdf(num)) { - player.singularityUpgrades[key].freeLevels += upgradeDistribution[key].value + player.singularityUpgrades[key].freeLevels += + upgradeDistribution[key].value; freeLevels[key] - ? freeLevels[key] += upgradeDistribution[key].value - : freeLevels[key] = upgradeDistribution[key].value + ? (freeLevels[key] += upgradeDistribution[key].value) + : (freeLevels[key] = upgradeDistribution[key].value); } } } if (player.highestSingularityCount >= 20) { - player.singularityUpgrades.goldenQuarks1.freeLevels += 0.2 - freeLevels.goldenQuarks1 ? freeLevels.goldenQuarks1 += 0.2 : freeLevels.goldenQuarks1 = 0.2 - player.singularityUpgrades.goldenQuarks2.freeLevels += 0.2 - freeLevels.goldenQuarks2 ? freeLevels.goldenQuarks2 += 0.2 : freeLevels.goldenQuarks2 = 0.2 - player.singularityUpgrades.goldenQuarks3.freeLevels += 1 - freeLevels.goldenQuarks3 ? freeLevels.goldenQuarks3 += 1 : freeLevels.goldenQuarks3 = 1 + player.singularityUpgrades.goldenQuarks1.freeLevels += 0.2; + freeLevels.goldenQuarks1 + ? (freeLevels.goldenQuarks1 += 0.2) + : (freeLevels.goldenQuarks1 = 0.2); + player.singularityUpgrades.goldenQuarks2.freeLevels += 0.2; + freeLevels.goldenQuarks2 + ? (freeLevels.goldenQuarks2 += 0.2) + : (freeLevels.goldenQuarks2 = 0.2); + player.singularityUpgrades.goldenQuarks3.freeLevels += 1; + freeLevels.goldenQuarks3 + ? (freeLevels.goldenQuarks3 += 1) + : (freeLevels.goldenQuarks3 = 1); } if (player.highestSingularityCount >= 200) { - player.octeractUpgrades.octeractGain.freeLevels += player.octeractUpgrades.octeractGain.level / 100 - freeLevels.octeractGain = player.octeractUpgrades.octeractGain.level / 100 + player.octeractUpgrades.octeractGain.freeLevels += + player.octeractUpgrades.octeractGain.level / 100; + freeLevels.octeractGain = + player.octeractUpgrades.octeractGain.level / 100; } if (player.highestSingularityCount >= 205) { - player.octeractUpgrades.octeractGain2.freeLevels += player.octeractUpgrades.octeractGain2.level / 100 - freeLevels.octeractGain2 = player.octeractUpgrades.octeractGain2.level / 100 + player.octeractUpgrades.octeractGain2.freeLevels += + player.octeractUpgrades.octeractGain2.level / 100; + freeLevels.octeractGain2 = + player.octeractUpgrades.octeractGain2.level / 100; } for (const key of Object.keys(freeLevels)) { - rewardMessage += dailyCodeFormatFreeLevelMessage(key, freeLevels[key]) + rewardMessage += dailyCodeFormatFreeLevelMessage(key, freeLevels[key]); } - await Alert(rewardMessage) + await Alert(rewardMessage); } - return - } else if (input.toLowerCase() === 'add') { - const availableUses = addCodeAvailableUses() - const maxUses = addCodeMaxUses().total - const timeToNextUse = format(addCodeTimeToNextUse(), 0) - const timeInterval = addCodeInterval().time + return; + } else if (input.toLowerCase() === "add") { + const availableUses = addCodeAvailableUses(); + const maxUses = addCodeMaxUses().total; + const timeToNextUse = format(addCodeTimeToNextUse(), 0); + const timeInterval = addCodeInterval().time; if (availableUses < 1) { - el.textContent = i18next.t('importexport.noAddCodes', { x: timeToNextUse }) - return + el.textContent = i18next.t("importexport.noAddCodes", { + x: timeToNextUse, + }); + return; } - let attemptsUsed: string | null = null + let attemptsUsed: string | null = null; if (amount) { - attemptsUsed = amount.toString() + attemptsUsed = amount.toString(); } else { - attemptsUsed = await Prompt(i18next.t('importexport.useXAdds', { x: availableUses }), availableUses.toString()) + attemptsUsed = await Prompt( + i18next.t("importexport.useXAdds", { x: availableUses }), + availableUses.toString() + ); } if (attemptsUsed === null) { - return Alert(i18next.t('importexport.cancelAdd')) + return Alert(i18next.t("importexport.cancelAdd")); } - const toUse = Number(attemptsUsed) + const toUse = Number(attemptsUsed); if ( - Number.isNaN(toUse) - || !Number.isInteger(toUse) - || toUse === 0 - || (toUse < 0 && -toUse >= availableUses) + Number.isNaN(toUse) || + !Number.isInteger(toUse) || + toUse === 0 || + (toUse < 0 && -toUse >= availableUses) ) { - return Alert(i18next.t('general.validation.invalidNumber')) + return Alert(i18next.t("general.validation.invalidNumber")); } - const addEffects = addCodeBonuses() + const addEffects = addCodeBonuses(); - const realAttemptsUsed = toUse > 0 ? Math.min(availableUses, toUse) : availableUses + toUse - const actualQuarks = Math.floor(addEffects.quarks * realAttemptsUsed) - const [first, second] = window.crypto.getRandomValues(new Uint8Array(2)) + const realAttemptsUsed = + toUse > 0 ? Math.min(availableUses, toUse) : availableUses + toUse; + const actualQuarks = Math.floor(addEffects.quarks * realAttemptsUsed); + const [first, second] = window.crypto.getRandomValues(new Uint8Array(2)); // Allows storage of up to (24 + 2 * calc2 levels) Add Codes, lol! const v = Math.max( Date.now() - (maxUses - realAttemptsUsed) * timeInterval, player.rngCode + timeInterval * realAttemptsUsed - ) - const remaining = Math.floor((Date.now() - v) / timeInterval) - const timeToNext = Math.floor((timeInterval - (Date.now() - v - timeInterval * remaining)) / 1000) + ); + const remaining = Math.floor((Date.now() - v) / timeInterval); + const timeToNext = Math.floor( + (timeInterval - (Date.now() - v - timeInterval * remaining)) / 1000 + ); // Calculator 3: Adds ascension timer. - const ascensionTimer = realAttemptsUsed * addEffects.ascensionTimer - const ascensionTimerText = (player.shopUpgrades.calculator3 > 0) - ? i18next.t('importexport.promocodes.add.calculator3', { x: format(ascensionTimer) }) - : '' + const ascensionTimer = realAttemptsUsed * addEffects.ascensionTimer; + const ascensionTimerText = + player.shopUpgrades.calculator3 > 0 + ? i18next.t("importexport.promocodes.add.calculator3", { + x: format(ascensionTimer), + }) + : ""; // Calculator 5: Adds GQ export timer. - const gqTimer = realAttemptsUsed * addEffects.gqTimer - const gqTimerText = (player.shopUpgrades.calculator5 > 0) - ? i18next.t('importexport.promocodes.add.calculator5', { x: format(gqTimer) }) - : '' + const gqTimer = realAttemptsUsed * addEffects.gqTimer; + const gqTimerText = + player.shopUpgrades.calculator5 > 0 + ? i18next.t("importexport.promocodes.add.calculator5", { + x: format(gqTimer), + }) + : ""; // Calculator 6: Octeract Generation - const octeractTime = realAttemptsUsed * addEffects.octeractTime - const octeractTimeText = (player.shopUpgrades.calculator6 > 0) - ? i18next.t('importexport.promocodes.add.calculator6', { x: format(octeractTime) }) - : '' + const octeractTime = realAttemptsUsed * addEffects.octeractTime; + const octeractTimeText = + player.shopUpgrades.calculator6 > 0 + ? i18next.t("importexport.promocodes.add.calculator6", { + x: format(octeractTime), + }) + : ""; + + // Calculator 7: Blueberry Generation Time + const blueberryTime = realAttemptsUsed * addEffects.blueberryTime; + const blueberryTimeText = + player.shopUpgrades.calculator7 > 0 + ? i18next.t("importexport.promocodes.add.calculator7", { + x: format(blueberryTime, 2, true), + }) + : ""; // Midas' Millenium-Aged Gold perk - const freeLevelsText = (player.highestSingularityCount >= 150) - ? i18next.t('importexport.promocodes.add.freeLevel', { - x: format(0.01 * realAttemptsUsed, 2), - y: format(0.05 * realAttemptsUsed, 2) - }) - : '' + const freeLevelsText = + player.highestSingularityCount >= 150 + ? i18next.t("importexport.promocodes.add.freeLevel", { + x: format(0.01 * realAttemptsUsed, 2), + y: format(0.05 * realAttemptsUsed, 2), + }) + : ""; // Calculator Maxed: you don't need to insert anything! if (player.shopUpgrades.calculator === shopData.calculator.maxLevel) { - player.worlds.add(actualQuarks) - addTimers('ascension', ascensionTimer) - player.goldenQuarksTimer += gqTimer - addTimers('octeracts', octeractTime) + player.worlds.add(actualQuarks); + addTimers("ascension", ascensionTimer); + player.goldenQuarksTimer += gqTimer; + addTimers("octeracts", octeractTime); + addTimers("ambrosia", blueberryTime); if (player.highestSingularityCount >= 150) { - player.singularityUpgrades.goldenQuarks1.freeLevels += 0.01 * realAttemptsUsed - player.singularityUpgrades.goldenQuarks3.freeLevels += 0.05 * realAttemptsUsed + player.singularityUpgrades.goldenQuarks1.freeLevels += + 0.01 * realAttemptsUsed; + player.singularityUpgrades.goldenQuarks3.freeLevels += + 0.05 * realAttemptsUsed; } - player.rngCode = v + player.rngCode = v; if (amount) { // No message when using Add x1 Special action, we refresh the info message - promocodesInfo('add') - return + promocodesInfo("add"); + return; } else { - return Alert(i18next.t('importexport.promocodes.add.calculatorMaxed', { - a: first, - b: second, - c: first + second, - d: player.worlds.toString(actualQuarks), - e: ascensionTimerText, - f: gqTimerText, - g: octeractTimeText, - h: freeLevelsText, - i: remaining, - j: timeToNext.toLocaleString() - })) + return Alert( + i18next.t("importexport.promocodes.add.calculatorMaxed", { + a: first, + b: second, + c: first + second, + d: player.worlds.toString(actualQuarks), + e: ascensionTimerText, + f: gqTimerText, + g: octeractTimeText, + h: freeLevelsText, + i: blueberryTimeText, + j: remaining, + k: timeToNext.toLocaleString(), + }) + ); } } @@ -675,181 +786,225 @@ export const promocodes = async (input: string | null, amount?: number) => { w: player.worlds.toString(actualQuarks), x: first, y: second, - z: first + second - } + z: first + second, + }; - const promptText = (player.shopUpgrades.calculator > 0) - ? i18next.t('importexport.promocodes.add.calculatorSolution', options) - : i18next.t('importexport.promocodes.add.calculatorPrompt', options) + const promptText = + player.shopUpgrades.calculator > 0 + ? i18next.t("importexport.promocodes.add.calculatorSolution", options) + : i18next.t("importexport.promocodes.add.calculatorPrompt", options); - const addPrompt = await Prompt(promptText) + const addPrompt = await Prompt(promptText); if (addPrompt === null) { - return Alert(i18next.t('importexport.promocodes.add.cancelled')) + return Alert(i18next.t("importexport.promocodes.add.cancelled")); } - player.rngCode = v + player.rngCode = v; if (first + second === +addPrompt) { - player.worlds.add(actualQuarks) - addTimers('ascension', ascensionTimer) - player.goldenQuarksTimer += gqTimer - addTimers('octeracts', octeractTime) - - await Alert(i18next.t('importexport.promocodes.add.reward', { - a: player.worlds.toString(actualQuarks), - b: ascensionTimerText, - c: gqTimerText, - d: octeractTimeText, - e: remaining, - f: timeToNext.toLocaleString(navigator.language) - })) + player.worlds.add(actualQuarks); + addTimers("ascension", ascensionTimer); + player.goldenQuarksTimer += gqTimer; + addTimers("octeracts", octeractTime); + addTimers("ambrosia", blueberryTime); + + await Alert( + i18next.t("importexport.promocodes.add.reward", { + a: player.worlds.toString(actualQuarks), + b: ascensionTimerText, + c: gqTimerText, + d: octeractTimeText, + e: remaining, + f: timeToNext.toLocaleString(navigator.language), + }) + ); } else { - await Alert(i18next.t('importexport.promocodes.add.wrong', { - w: addPrompt, - x: first + second, - y: remaining, - z: timeToNext.toLocaleString(navigator.language) - })) + await Alert( + i18next.t("importexport.promocodes.add.wrong", { + w: addPrompt, + x: first + second, + y: remaining, + z: timeToNext.toLocaleString(navigator.language), + }) + ); } - } else if (input === 'sub') { - const amount = 1 + window.crypto.getRandomValues(new Uint16Array(1))[0] % 16 // [1, 16] - const quarks = Number(player.worlds) - await Alert(i18next.t('importexport.promocodes.sub.subbed', { x: amount })) + } else if (input === "sub") { + const amount = + 1 + (window.crypto.getRandomValues(new Uint16Array(1))[0] % 16); // [1, 16] + const quarks = Number(player.worlds); + await Alert(i18next.t("importexport.promocodes.sub.subbed", { x: amount })); if (quarks < amount) { - await Alert(i18next.t('importexport.promocodes.sub.gave', { - x: amount - quarks, - y: amount - })) + await Alert( + i18next.t("importexport.promocodes.sub.gave", { + x: amount - quarks, + y: amount, + }) + ); } - player.worlds.sub(quarks < amount ? amount - quarks : amount) - } else if (input === 'gamble') { + player.worlds.sub(quarks < amount ? amount - quarks : amount); + } else if (input === "gamble") { if ( - typeof player.skillCode === 'number' - || typeof localStorage.getItem('saveScumIsCheating') === 'string' + typeof player.skillCode === "number" || + typeof localStorage.getItem("saveScumIsCheating") === "string" ) { if ( - (Date.now() - player.skillCode!) / 1000 < 3600 - || (Date.now() - Number(localStorage.getItem('saveScumIsCheating'))) / 1000 < 3600 + (Date.now() - player.skillCode!) / 1000 < 3600 || + (Date.now() - Number(localStorage.getItem("saveScumIsCheating"))) / + 1000 < + 3600 ) { - return el.textContent = i18next.t('importexport.promocodes.gamble.wait') + return (el.textContent = i18next.t( + "importexport.promocodes.gamble.wait" + )); } } - const confirmed = await Confirm(i18next.t('importexport.promocodes.gamble.confirm')) + const confirmed = await Confirm( + i18next.t("importexport.promocodes.gamble.confirm") + ); if (!confirmed) { - return el.textContent = i18next.t('importexport.promocodes.gamble.cancelled') + return (el.textContent = i18next.t( + "importexport.promocodes.gamble.cancelled" + )); } - const bet = Number(await Prompt(i18next.t('importexport.promocodes.gamble.betPrompt'))) + const bet = Number( + await Prompt(i18next.t("importexport.promocodes.gamble.betPrompt")) + ); if (Number.isNaN(bet) || bet <= 0) { - return el.textContent = i18next.t('general.validation.zeroOrLess') + return (el.textContent = i18next.t("general.validation.zeroOrLess")); } else if (bet > 1e4) { - return el.textContent = i18next.t('importexport.promocodes.gamble.cheaters') + return (el.textContent = i18next.t( + "importexport.promocodes.gamble.cheaters" + )); } else if (Number(player.worlds) < bet) { - return el.textContent = i18next.t('general.validation.moreThanPlayerHas') + return (el.textContent = i18next.t( + "general.validation.moreThanPlayerHas" + )); } - localStorage.setItem('saveScumIsCheating', Date.now().toString()) - const dice = window.crypto.getRandomValues(new Uint8Array(1))[0] % 6 + 1 // [1, 6] + localStorage.setItem("saveScumIsCheating", Date.now().toString()); + const dice = (window.crypto.getRandomValues(new Uint8Array(1))[0] % 6) + 1; // [1, 6] if (dice === 1) { - const won = bet * .25 // lmao - player.worlds.add(won, false) + const won = bet * 0.25; // lmao + player.worlds.add(won, false); - player.skillCode = Date.now() - return el.textContent = i18next.t('importexport.promocodes.gamble.won', { x: won }) + player.skillCode = Date.now(); + return (el.textContent = i18next.t("importexport.promocodes.gamble.won", { + x: won, + })); } - player.worlds.sub(bet) - el.textContent = i18next.t('importexport.promocodes.gamble.lost', { x: bet }) - } else if (input === 'time') { - const availableUses = timeCodeAvailableUses() + player.worlds.sub(bet); + el.textContent = i18next.t("importexport.promocodes.gamble.lost", { + x: bet, + }); + } else if (input === "time") { + const availableUses = timeCodeAvailableUses(); if (availableUses === 0) { - return Alert(i18next.t('importexport.promocodes.time.wait')) + return Alert(i18next.t("importexport.promocodes.time.wait")); } - const rewardMult = timeCodeRewardMultiplier() + const rewardMult = timeCodeRewardMultiplier(); - const random = Math.random() * 15000 // random time within 15 seconds - const start = Date.now() - const playerConfirmed = await Confirm(i18next.t('importexport.promocodes.time.confirm', { - x: format(2500 + 125 * player.cubeUpgrades[61], 0, true), - y: format(rewardMult, 2, true) - })) + const random = Math.random() * 15000; // random time within 15 seconds + const start = Date.now(); + const playerConfirmed = await Confirm( + i18next.t("importexport.promocodes.time.confirm", { + x: format(2500 + 125 * player.cubeUpgrades[61], 0, true), + y: format(rewardMult, 2, true), + }) + ); if (playerConfirmed) { - const diff = Math.abs(Date.now() - (start + random)) - player.promoCodeTiming.time = Date.now() + const diff = Math.abs(Date.now() - (start + random)); + player.promoCodeTiming.time = Date.now(); - if (diff <= (2500 + 125 * player.cubeUpgrades[61])) { + if (diff <= 2500 + 125 * player.cubeUpgrades[61]) { const reward = Math.floor( - Math.min(1000, 125 + 25 * player.highestSingularityCount) * (1 + player.cubeUpgrades[61] / 50) - ) - let actualQuarkAward = player.worlds.applyBonus(reward) - let blueberryTime = 0 + Math.min(1000, 125 + 25 * player.highestSingularityCount) * + (1 + player.cubeUpgrades[61] / 50) + ); + let actualQuarkAward = player.worlds.applyBonus(reward); + let blueberryTime = 0; if (actualQuarkAward > 66666) { - actualQuarkAward = Math.pow(actualQuarkAward, 0.35) * Math.pow(66666, 0.65) + actualQuarkAward = + Math.pow(actualQuarkAward, 0.35) * Math.pow(66666, 0.65); } if (player.visitedAmbrosiaSubtab) { - blueberryTime = 1800 * rewardMult + blueberryTime = 1800 * rewardMult; } - player.worlds.add(actualQuarkAward * rewardMult, false) - G.ambrosiaTimer += blueberryTime - const winText = i18next.t('importexport.promocodes.time.won', { - x: format(actualQuarkAward * rewardMult, 0, true) - }) - const ambrosiaText = (blueberryTime > 0) - ? i18next.t('importexport.promocodes.time.ambrosia', { blueberryTime }) - : '' - return Alert(winText + ambrosiaText) + player.worlds.add(actualQuarkAward * rewardMult, false); + G.ambrosiaTimer += blueberryTime; + const winText = i18next.t("importexport.promocodes.time.won", { + x: format(actualQuarkAward * rewardMult, 0, true), + }); + const ambrosiaText = + blueberryTime > 0 + ? i18next.t("importexport.promocodes.time.ambrosia", { + blueberryTime, + }) + : ""; + return Alert(winText + ambrosiaText); } else { - return Alert(i18next.t('importexport.promocodes.time.lost')) + return Alert(i18next.t("importexport.promocodes.time.lost")); } } - } else if (input === 'spoiler') { - const perSecond = octeractGainPerSecond() + } else if (input === "spoiler") { + const perSecond = octeractGainPerSecond(); if (perSecond > 1) { - return Alert(i18next.t('importexport.promocodes.spoiler.moreThan1', { x: format(perSecond, 2, true) })) + return Alert( + i18next.t("importexport.promocodes.spoiler.moreThan1", { + x: format(perSecond, 2, true), + }) + ); } else { - return Alert(i18next.t('importexport.promocodes.spoiler.one', { x: format(1 / perSecond, 2, true) })) + return Alert( + i18next.t("importexport.promocodes.spoiler.one", { + x: format(1 / perSecond, 2, true), + }) + ); } } else { - el.textContent = i18next.t('importexport.promocodes.invalid') + el.textContent = i18next.t("importexport.promocodes.invalid"); } - const saved = await saveSynergy() // should fix refresh bug where you can continuously enter promocodes + const saved = await saveSynergy(); // should fix refresh bug where you can continuously enter promocodes if (!saved) { - return + return; } - Synergism.emit('promocode', input) + Synergism.emit("promocode", input); - setTimeout(() => el.textContent = '', 15000) -} + setTimeout(() => (el.textContent = ""), 15000); +}; const addCodeSingularityPerkBonus = (): number => { - const levels = [10, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 235, 240] - let count = 0 + const levels = [ + 10, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 235, 240, + ]; + let count = 0; for (let i = 0; i < levels.length; i++) { if (player.highestSingularityCount >= levels[i]) { - count += 1 + count += 1; } else { - break + break; } } - return 1 + count / 5 -} + return 1 + count / 5; +}; export const addCodeMaxUses = () => { - let calc5uses = Math.floor(player.shopUpgrades.calculator5 / 10) + let calc5uses = Math.floor(player.shopUpgrades.calculator5 / 10); if (player.shopUpgrades.calculator5 === shopData.calculator5.maxLevel) { - calc5uses += 6 + calc5uses += 6; } const arr = [ @@ -857,86 +1012,103 @@ export const addCodeMaxUses = () => { 2 * player.shopUpgrades.calculator2, // PL-AT X player.shopUpgrades.calculator4 === shopData.calculator4.maxLevel ? 32 : 0, // PL-AT δ calc5uses, // PL-AT Γ - player.shopUpgrades.calculator6 === shopData.calculator6.maxLevel ? 24 : 0 // PL_AT _ - ] + player.shopUpgrades.calculator6 === shopData.calculator6.maxLevel ? 24 : 0, // PL_AT _ + player.shopUpgrades.calculator7 === shopData.calculator7.maxLevel ? 48 : 0, // Plat ΩΩ + ]; - let maxUses = sumContents(arr) + let maxUses = sumContents(arr); - arr.push(addCodeSingularityPerkBonus()) - maxUses *= addCodeSingularityPerkBonus() + arr.push(addCodeSingularityPerkBonus()); + maxUses *= addCodeSingularityPerkBonus(); return { list: arr, - total: Math.ceil(maxUses) - } -} + total: Math.ceil(maxUses), + }; +}; export const addCodeInterval = () => { const arr = [ hour, // base value 1 - 0.04 * player.shopUpgrades.calculator4, - 1 - Math.min( - .6, - (player.highestSingularityCount >= 125 ? player.highestSingularityCount / 800 : 0) - + (player.highestSingularityCount >= 200 ? player.highestSingularityCount / 800 : 0) - ), + 1 - + Math.min( + 0.6, + (player.highestSingularityCount >= 125 + ? player.highestSingularityCount / 800 + : 0) + + (player.highestSingularityCount >= 200 + ? player.highestSingularityCount / 800 + : 0) + ), player.runelevels[6] > 0 ? 0.8 : 1, - 1 / addCodeSingularityPerkBonus() - ] + 1 / addCodeSingularityPerkBonus(), + ]; return { list: arr, - time: productContents(arr) - } -} + time: productContents(arr), + }; +}; export const addCodeAvailableUses = (): number => { - const maxUses = addCodeMaxUses().total - const timeInterval = addCodeInterval().time + const maxUses = addCodeMaxUses().total; + const timeInterval = addCodeInterval().time; - return Math.floor(Math.min(maxUses, (Date.now() - player.rngCode) / timeInterval)) -} + return Math.floor( + Math.min(maxUses, (Date.now() - player.rngCode) / timeInterval) + ); +}; export const addCodeTimeToNextUse = (): number => { - const timeToFirst = Math.floor(addCodeInterval().time + player.rngCode - Date.now()) / 1000 + const timeToFirst = + Math.floor(addCodeInterval().time + player.rngCode - Date.now()) / 1000; if (timeToFirst > 0) { - return timeToFirst + return timeToFirst; } else if (addCodeAvailableUses() === addCodeMaxUses().total) { - return 0 + return 0; } else { - const addTimerElapsedTime = Date.now() - player.rngCode - const remainder = addTimerElapsedTime - addCodeInterval().time * addCodeAvailableUses() + const addTimerElapsedTime = Date.now() - player.rngCode; + const remainder = + addTimerElapsedTime - addCodeInterval().time * addCodeAvailableUses(); - return Math.floor(addCodeInterval().time - remainder) / 1000 + return Math.floor(addCodeInterval().time - remainder) / 1000; } -} +}; export const addCodeBonuses = () => { - const perkRewardDivisor = addCodeSingularityPerkBonus() + const perkRewardDivisor = addCodeSingularityPerkBonus(); - let commonQuarkMult = 1 + 0.14 * player.shopUpgrades.calculator // Calculator Shop Upgrade (+14% / level) - commonQuarkMult *= (player.shopUpgrades.calculator2 === shopData.calculator2.maxLevel) ? 1.25 : 1 // Calculator 2 Max Level (+25%) - commonQuarkMult /= perkRewardDivisor + let commonQuarkMult = 1 + 0.14 * player.shopUpgrades.calculator; // Calculator Shop Upgrade (+14% / level) + commonQuarkMult *= + player.shopUpgrades.calculator2 === shopData.calculator2.maxLevel + ? 1.25 + : 1; // Calculator 2 Max Level (+25%) + commonQuarkMult /= perkRewardDivisor; const sampledMult = Math.max( 0.4 + 0.02 * player.shopUpgrades.calculator3, 2 / 5 + (window.crypto.getRandomValues(new Uint16Array(2))[0] % 128) / 640 - ) // [0.4, 0.6], slightly biased in favor of 0.4. =) - const minMult = 0.4 + 0.02 * player.shopUpgrades.calculator3 - const maxMult = 0.6 + ); // [0.4, 0.6], slightly biased in favor of 0.4. =) + const minMult = 0.4 + 0.02 * player.shopUpgrades.calculator3; + const maxMult = 0.6; - const quarkBase = commonQuarkMult * quarkHandler().perHour + const quarkBase = commonQuarkMult * quarkHandler().perHour; // Calculator 3: Adds ascension timer. Also includes Expert Pack multiplier. - const ascMult = (player.singularityUpgrades.expertPack.level > 0) ? 1.2 : 1 - const ascensionTimer = 60 * player.shopUpgrades.calculator3 * ascMult / perkRewardDivisor + const ascMult = player.singularityUpgrades.expertPack.level > 0 ? 1.2 : 1; + const ascensionTimer = + (60 * player.shopUpgrades.calculator3 * ascMult) / perkRewardDivisor; // Calculator 5: Adds GQ export timer. - const gqTimer = 6 * player.shopUpgrades.calculator5 / perkRewardDivisor + const gqTimer = (6 * player.shopUpgrades.calculator5) / perkRewardDivisor; // Calculator 6: Octeract Generation - const octeractTime = player.shopUpgrades.calculator6 / perkRewardDivisor + const octeractTime = player.shopUpgrades.calculator6 / perkRewardDivisor; + + // Calculator 7: Blueberry Timer Generation + const blueberryTime = player.shopUpgrades.calculator7 / perkRewardDivisor; return { quarks: sampledMult * quarkBase, // The quarks to actually reward (if not for stats) @@ -944,122 +1116,130 @@ export const addCodeBonuses = () => { maxQuarks: maxMult * quarkBase, ascensionTimer, gqTimer, - octeractTime - } -} + octeractTime, + blueberryTime, + }; +}; const timeCodeAvailableUses = (): number => { - return ((Date.now() - player.promoCodeTiming.time) / 1000 < 900) ? 0 : 1 -} + return (Date.now() - player.promoCodeTiming.time) / 1000 < 900 ? 0 : 1; +}; const timeCodeTimeToNextUse = (): number => { - return 900 - ((Date.now() - player.promoCodeTiming.time) / 1000) -} + return 900 - (Date.now() - player.promoCodeTiming.time) / 1000; +}; const timeCodeRewardMultiplier = (): number => { - return Math.min(24, (Date.now() - player.promoCodeTiming.time) / (1000 * 3600)) -} - -const dailyCodeFormatFreeLevelMessage = (upgradeKey: string, freeLevelAmount: number): string => { - const upgradeNiceName = (upgradeKey in singularityData) - ? i18next.t(`singularity.data.${upgradeKey}.name`) - : i18next.t(`octeract.data.${upgradeKey}.name`) - return `\n+${freeLevelAmount} extra levels of '${upgradeNiceName}'` -} + return Math.min( + 24, + (Date.now() - player.promoCodeTiming.time) / (1000 * 3600) + ); +}; + +const dailyCodeFormatFreeLevelMessage = ( + upgradeKey: string, + freeLevelAmount: number +): string => { + const upgradeNiceName = + upgradeKey in singularityData + ? i18next.t(`singularity.data.${upgradeKey}.name`) + : i18next.t(`octeract.data.${upgradeKey}.name`); + return `\n+${freeLevelAmount} extra levels of '${upgradeNiceName}'`; +}; const dailyCodeReward = () => { - let quarks = 0 - let goldenQuarks = 0 + let quarks = 0; + let goldenQuarks = 0; - const ascended = player.ascensionCount > 0 - const singularity = player.highestSingularityCount > 0 + const ascended = player.ascensionCount > 0; + const singularity = player.highestSingularityCount > 0; if (player.reincarnationCount > 0 || ascended || singularity) { - quarks += 20 + quarks += 20; } if (player.challengecompletions[6] > 0 || ascended || singularity) { - quarks += 20 + quarks += 20; } // 40 if (player.challengecompletions[7] > 0 || ascended || singularity) { - quarks += 30 + quarks += 30; } // 70 if (player.challengecompletions[8] > 0 || ascended || singularity) { - quarks += 30 + quarks += 30; } // 100 if (player.challengecompletions[9] > 0 || ascended || singularity) { - quarks += 40 + quarks += 40; } // 140 if (player.challengecompletions[10] > 0 || ascended || singularity) { - quarks += 60 + quarks += 60; } // 200 if (ascended || singularity) { - quarks += 50 + quarks += 50; } // 250 if (player.challengecompletions[11] > 0 || singularity) { - quarks += 50 + quarks += 50; } // 300 if (player.challengecompletions[12] > 0 || singularity) { - quarks += 50 + quarks += 50; } // 350 if (player.challengecompletions[13] > 0 || singularity) { - quarks += 50 + quarks += 50; } // 400 if (player.challengecompletions[14] > 0 || singularity) { - quarks += 100 + quarks += 100; } // 500 if (player.researches[200] === G.researchMaxLevels[200]) { - quarks += 250 + quarks += 250; } // 750 if (player.cubeUpgrades[50] === 100000) { - quarks += 250 + quarks += 250; } // 1000 if (player.platonicUpgrades[5] > 0) { - quarks += 250 + quarks += 250; } // 1250 if (player.platonicUpgrades[10] > 0) { - quarks += 500 + quarks += 500; } // 1750 if (player.platonicUpgrades[15] > 0) { - quarks += 750 + quarks += 750; } // 2500 if (player.challenge15Exponent > 1e18) { - quarks += Math.floor(1000 * (Math.log10(player.challenge15Exponent) - 18)) + quarks += Math.floor(1000 * (Math.log10(player.challenge15Exponent) - 18)); } // at least 2500 if (player.platonicUpgrades[20] > 0) { - quarks += 2500 + quarks += 2500; } // at least 5k - quarks *= 1 + 0.05 * player.shopUpgrades.shopImprovedDaily - quarks = Math.floor(quarks) + quarks *= 1 + 0.05 * player.shopUpgrades.shopImprovedDaily; + quarks = Math.floor(quarks); if (singularity) { - goldenQuarks += 2 + 3 * player.highestSingularityCount - goldenQuarks *= 1 + 0.2 * player.shopUpgrades.shopImprovedDaily2 - goldenQuarks *= 1 + 0.15 * player.shopUpgrades.shopImprovedDaily3 - goldenQuarks *= 1 + player.shopUpgrades.shopImprovedDaily4 + goldenQuarks += 2 + 3 * player.highestSingularityCount; + goldenQuarks *= 1 + 0.2 * player.shopUpgrades.shopImprovedDaily2; + goldenQuarks *= 1 + 0.15 * player.shopUpgrades.shopImprovedDaily3; + goldenQuarks *= 1 + player.shopUpgrades.shopImprovedDaily4; } return { quarks, - goldenQuarks - } -} + goldenQuarks, + }; +}; export const handleLastModified = (lastModified: number) => { - const localStorageFirstPlayed = localStorage.getItem('firstPlayed') - const lastModifiedDate = new Date(lastModified) + const localStorageFirstPlayed = localStorage.getItem("firstPlayed"); + const lastModifiedDate = new Date(lastModified); if (localStorageFirstPlayed === null) { - localStorage.setItem('firstPlayed', lastModifiedDate.toISOString()) - return + localStorage.setItem("firstPlayed", lastModifiedDate.toISOString()); + return; } - const localFirstPlayedDate = new Date(localStorageFirstPlayed) + const localFirstPlayedDate = new Date(localStorageFirstPlayed); // The larger the ms value, the newer the file. // So if the current oldest date is newer than the last modified date // for the new file, set the oldest date to the last modified. if (localFirstPlayedDate.getTime() > lastModifiedDate.getTime()) { - player.firstPlayed = lastModifiedDate.toISOString() - localStorage.setItem('firstPlayed', player.firstPlayed) + player.firstPlayed = lastModifiedDate.toISOString(); + localStorage.setItem("firstPlayed", player.firstPlayed); } -} +}; diff --git a/src/Shop.ts b/src/Shop.ts index 10e4fa31b..11682047e 100644 --- a/src/Shop.ts +++ b/src/Shop.ts @@ -1,39 +1,46 @@ -import i18next from 'i18next' -import { DOMCacheGetOrSet } from './Cache/DOM' -import { calculatePowderConversion, calculateSummationNonLinear, calculateTimeAcceleration } from './Calculate' -import type { IMultiBuy } from './Cubes' -import { format, player } from './Synergism' -import type { Player } from './types/Synergism' -import { Alert, Confirm, Prompt, revealStuff } from './UpdateHTML' +import i18next from "i18next"; +import { DOMCacheGetOrSet } from "./Cache/DOM"; +import { + calculatePowderConversion, + calculateSummationNonLinear, + calculateTimeAcceleration, +} from "./Calculate"; +import type { IMultiBuy } from "./Cubes"; +import { format, player } from "./Synergism"; +import type { Player } from "./types/Synergism"; +import { Alert, Confirm, Prompt, revealStuff } from "./UpdateHTML"; /** * Standardization of metadata contained for each shop upgrade. */ export enum shopUpgradeTypes { - CONSUMABLE = 'consume', - UPGRADE = 'upgrade' + CONSUMABLE = "consume", + UPGRADE = "upgrade", } type shopResetTier = - | 'Reincarnation' - | 'Ascension' - | 'Singularity' - | 'SingularityVol2' - | 'SingularityVol3' - | 'SingularityVol4' - | 'Exalt' + | "Reincarnation" + | "Ascension" + | "Singularity" + | "SingularityVol2" + | "SingularityVol3" + | "SingularityVol4" + | "Exalt1" + | "Exalt2" + | "Exalt3" + | "Exalt4"; export interface IShopData { - price: number - priceIncrease: number - maxLevel: number - type: shopUpgradeTypes - refundable: boolean - refundMinimumLevel: number - tier: shopResetTier + price: number; + priceIncrease: number; + maxLevel: number; + type: shopUpgradeTypes; + refundable: boolean; + refundMinimumLevel: number; + tier: shopResetTier; } -export const shopData: Record = { +export const shopData: Record = { offeringPotion: { price: 100, priceIncrease: 0, @@ -41,1141 +48,1300 @@ export const shopData: Record = { type: shopUpgradeTypes.CONSUMABLE, refundable: false, refundMinimumLevel: 0, - tier: 'Reincarnation' + tier: "Reincarnation", }, obtainiumPotion: { - tier: 'Reincarnation', + tier: "Reincarnation", price: 100, priceIncrease: 0, maxLevel: 999999999, type: shopUpgradeTypes.CONSUMABLE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, offeringEX: { - tier: 'Reincarnation', + tier: "Reincarnation", price: 150, priceIncrease: 10, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, offeringAuto: { - tier: 'Reincarnation', + tier: "Reincarnation", price: 150, priceIncrease: 10, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 1 + refundMinimumLevel: 1, }, obtainiumEX: { - tier: 'Reincarnation', + tier: "Reincarnation", price: 150, priceIncrease: 10, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, obtainiumAuto: { - tier: 'Reincarnation', + tier: "Reincarnation", price: 150, priceIncrease: 10, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 1 + refundMinimumLevel: 1, }, instantChallenge: { - tier: 'Reincarnation', + tier: "Reincarnation", price: 300, priceIncrease: 99999, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, antSpeed: { - tier: 'Reincarnation', + tier: "Reincarnation", price: 200, priceIncrease: 25, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, cashGrab: { - tier: 'Reincarnation', + tier: "Reincarnation", price: 100, priceIncrease: 40, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopTalisman: { - tier: 'Reincarnation', + tier: "Reincarnation", price: 1500, priceIncrease: 99999, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, seasonPass: { - tier: 'Ascension', + tier: "Ascension", price: 500, priceIncrease: 75, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, challengeExtension: { - tier: 'Ascension', + tier: "Ascension", price: 500, priceIncrease: 250, maxLevel: 5, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, challengeTome: { - tier: 'Ascension', + tier: "Ascension", price: 500, priceIncrease: 250, maxLevel: 15, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, cubeToQuark: { - tier: 'Ascension', + tier: "Ascension", price: 2000, priceIncrease: 99999, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, tesseractToQuark: { - tier: 'Ascension', + tier: "Ascension", price: 3500, priceIncrease: 99999, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, hypercubeToQuark: { - tier: 'Ascension', + tier: "Ascension", price: 5000, priceIncrease: 99999, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, seasonPass2: { - tier: 'Ascension', + tier: "Ascension", price: 2500, priceIncrease: 250, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, seasonPass3: { - tier: 'Ascension', + tier: "Ascension", price: 5000, priceIncrease: 500, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, chronometer: { - tier: 'Ascension', + tier: "Ascension", price: 2000, priceIncrease: 500, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, infiniteAscent: { - tier: 'Ascension', + tier: "Ascension", price: 50000, priceIncrease: 9999999, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, calculator: { - tier: 'Reincarnation', + tier: "Reincarnation", price: 1000, priceIncrease: 500, maxLevel: 5, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 1 + refundMinimumLevel: 1, }, calculator2: { - tier: 'Ascension', + tier: "Ascension", price: 3000, priceIncrease: 1000, maxLevel: 12, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, calculator3: { - tier: 'Ascension', + tier: "Ascension", price: 10000, priceIncrease: 2000, maxLevel: 10, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, calculator4: { - tier: 'Singularity', + tier: "Singularity", price: 1e7, priceIncrease: 1e6, maxLevel: 10, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, calculator5: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 1e8, priceIncrease: 1e8, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, calculator6: { - tier: 'SingularityVol3', + tier: "SingularityVol3", price: 1e11, priceIncrease: 2e10, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, constantEX: { - tier: 'Ascension', + tier: "Ascension", price: 100000, priceIncrease: 899999, maxLevel: 2, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, powderEX: { - tier: 'Ascension', + tier: "Ascension", price: 1000, priceIncrease: 750, maxLevel: 50, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, chronometer2: { - tier: 'Ascension', + tier: "Ascension", price: 5000, priceIncrease: 1500, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, chronometer3: { - tier: 'Singularity', + tier: "Singularity", price: 250, priceIncrease: 250, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, seasonPassY: { - tier: 'Ascension', + tier: "Ascension", price: 10000, priceIncrease: 1500, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: true, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, seasonPassZ: { - tier: 'Singularity', + tier: "Singularity", price: 250, priceIncrease: 250, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, challengeTome2: { - tier: 'Singularity', + tier: "Singularity", price: 1000000, priceIncrease: 1000000, maxLevel: 5, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, instantChallenge2: { - tier: 'Singularity', + tier: "Singularity", price: 20000000, priceIncrease: 0, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, cubeToQuarkAll: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 2222222, priceIncrease: 0, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, cashGrab2: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 5000, priceIncrease: 5000, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, chronometerZ: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 12500, priceIncrease: 12500, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, offeringEX2: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 10000, priceIncrease: 10000, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, obtainiumEX2: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 10000, priceIncrease: 10000, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, powderAuto: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 5e6, priceIncrease: 0, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, seasonPassLost: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 1000000, priceIncrease: 25000, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, challenge15Auto: { - tier: 'SingularityVol3', + tier: "SingularityVol3", price: 5e11, priceIncrease: 0, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, extraWarp: { - tier: 'SingularityVol3', + tier: "SingularityVol3", price: 1.25e11, priceIncrease: 0, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, autoWarp: { - tier: 'SingularityVol3', + tier: "SingularityVol3", price: 5e11, priceIncrease: 0, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, improveQuarkHept: { - tier: 'Ascension', + tier: "Ascension", price: 2e5 - 1, priceIncrease: 0, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, improveQuarkHept2: { - tier: 'Singularity', + tier: "Singularity", price: 2e7 - 1, priceIncrease: 0, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, improveQuarkHept3: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 2e9 - 1, priceIncrease: 0, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, improveQuarkHept4: { - tier: 'SingularityVol3', + tier: "SingularityVol3", price: 2e11 - 1, priceIncrease: 0, maxLevel: 1, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopImprovedDaily: { - tier: 'Ascension', + tier: "Ascension", price: 5000, priceIncrease: 2500, maxLevel: 20, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopImprovedDaily2: { - tier: 'Singularity', + tier: "Singularity", price: 500000, priceIncrease: 500000, maxLevel: 10, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopImprovedDaily3: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 5000000, priceIncrease: 12500000, maxLevel: 15, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopImprovedDaily4: { - tier: 'SingularityVol3', + tier: "SingularityVol3", price: 5e9, priceIncrease: 5e9, maxLevel: 25, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, offeringEX3: { - tier: 'SingularityVol3', + tier: "SingularityVol3", price: 1, priceIncrease: 1.25e12, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, obtainiumEX3: { - tier: 'SingularityVol3', + tier: "SingularityVol3", price: 1, priceIncrease: 1.25e12, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, improveQuarkHept5: { - tier: 'SingularityVol4', + tier: "SingularityVol4", price: 1, priceIncrease: 2.5e13, maxLevel: 100, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, chronometerInfinity: { - tier: 'SingularityVol4', + tier: "SingularityVol4", price: 1, priceIncrease: 2.5e12, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, seasonPassInfinity: { - tier: 'SingularityVol4', + tier: "SingularityVol4", price: 1, priceIncrease: 3.75e12, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopSingularityPenaltyDebuff: { - tier: 'Exalt', + tier: "Exalt1", price: 1e17, priceIncrease: 9.99e19, maxLevel: 4, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, + }, + shopAmbrosiaLuckMultiplier4: { + tier: "Exalt2", + price: 1e20, + priceIncrease: 3e20, + maxLevel: 4, + type: shopUpgradeTypes.UPGRADE, + refundable: false, + refundMinimumLevel: 0, + }, + calculator7: { + tier: "Exalt3", + price: 1e20, + priceIncrease: 1e19, + maxLevel: 50, + type: shopUpgradeTypes.UPGRADE, + refundable: false, + refundMinimumLevel: 0, + }, + shopOcteractAmbrosiaLuck: { + tier: "Exalt4", + price: 1e21, + priceIncrease: 9e21, + maxLevel: 2, + type: shopUpgradeTypes.UPGRADE, + refundable: false, + refundMinimumLevel: 0, }, shopAmbrosiaGeneration1: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 50000000, priceIncrease: 50000000, maxLevel: 25, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopAmbrosiaGeneration2: { - tier: 'SingularityVol3', + tier: "SingularityVol3", price: 5e11, priceIncrease: 5e11, maxLevel: 30, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopAmbrosiaGeneration3: { - tier: 'SingularityVol4', + tier: "SingularityVol4", price: 5e13, priceIncrease: 5e13, maxLevel: 35, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopAmbrosiaGeneration4: { - tier: 'SingularityVol4', + tier: "SingularityVol4", price: 1e17, priceIncrease: 4 * 1e16, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopAmbrosiaLuck1: { - tier: 'SingularityVol2', + tier: "SingularityVol2", price: 20000000, priceIncrease: 20000000, maxLevel: 40, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopAmbrosiaLuck2: { - tier: 'SingularityVol3', + tier: "SingularityVol3", price: 2e11, priceIncrease: 2e11, maxLevel: 50, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopAmbrosiaLuck3: { - tier: 'SingularityVol4', + tier: "SingularityVol4", price: 2e13, priceIncrease: 2e13, maxLevel: 60, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 + refundMinimumLevel: 0, }, shopAmbrosiaLuck4: { - tier: 'SingularityVol4', + tier: "SingularityVol4", price: 1e17, priceIncrease: 4 * 1e16, maxLevel: 1000, type: shopUpgradeTypes.UPGRADE, refundable: false, - refundMinimumLevel: 0 - } -} + refundMinimumLevel: 0, + }, +}; // Names of shop upgrades || Top row indicates potions, and all other upgrades are labeled in order. // If you are adding more upgrades please make sure the order of labelled upgrades is correct! type ShopUpgradeNames = - | 'offeringPotion' - | 'obtainiumPotion' - | 'offeringEX' - | 'offeringAuto' - | 'offeringEX2' - | 'obtainiumEX' - | 'obtainiumAuto' - | 'obtainiumEX2' - | 'instantChallenge' - | 'instantChallenge2' - | 'antSpeed' - | 'cashGrab' - | 'cashGrab2' - | 'shopTalisman' - | 'seasonPass' - | 'challengeExtension' - | 'challengeTome' - | 'challengeTome2' - | 'cubeToQuark' - | 'tesseractToQuark' - | 'cubeToQuarkAll' - | 'hypercubeToQuark' - | 'seasonPass2' - | 'seasonPass3' - | 'seasonPassY' - | 'seasonPassZ' - | 'seasonPassLost' - | 'chronometer' - | 'chronometer2' - | 'chronometer3' - | 'chronometerZ' - | 'infiniteAscent' - | 'calculator' - | 'calculator2' - | 'calculator3' - | 'constantEX' - | 'powderEX' - | 'powderAuto' - | 'challenge15Auto' - | 'extraWarp' - | 'autoWarp' // And Golden Quarks - | 'improveQuarkHept' - | 'improveQuarkHept2' - | 'improveQuarkHept3' - | 'improveQuarkHept4' - | 'shopImprovedDaily' - | 'shopImprovedDaily2' - | 'shopImprovedDaily3' - | 'shopImprovedDaily4' - | 'calculator4' - | 'calculator5' - | 'calculator6' - | 'offeringEX3' - | 'obtainiumEX3' - | 'improveQuarkHept5' - | 'seasonPassInfinity' - | 'chronometerInfinity' - | 'shopSingularityPenaltyDebuff' - | 'shopAmbrosiaGeneration1' - | 'shopAmbrosiaGeneration2' - | 'shopAmbrosiaGeneration3' - | 'shopAmbrosiaGeneration4' - | 'shopAmbrosiaLuck1' - | 'shopAmbrosiaLuck2' - | 'shopAmbrosiaLuck3' - | 'shopAmbrosiaLuck4' + | "offeringPotion" + | "obtainiumPotion" + | "offeringEX" + | "offeringAuto" + | "offeringEX2" + | "obtainiumEX" + | "obtainiumAuto" + | "obtainiumEX2" + | "instantChallenge" + | "instantChallenge2" + | "antSpeed" + | "cashGrab" + | "cashGrab2" + | "shopTalisman" + | "seasonPass" + | "challengeExtension" + | "challengeTome" + | "challengeTome2" + | "cubeToQuark" + | "tesseractToQuark" + | "cubeToQuarkAll" + | "hypercubeToQuark" + | "seasonPass2" + | "seasonPass3" + | "seasonPassY" + | "seasonPassZ" + | "seasonPassLost" + | "chronometer" + | "chronometer2" + | "chronometer3" + | "chronometerZ" + | "infiniteAscent" + | "calculator" + | "calculator2" + | "calculator3" + | "constantEX" + | "powderEX" + | "powderAuto" + | "challenge15Auto" + | "extraWarp" + | "autoWarp" // And Golden Quarks + | "improveQuarkHept" + | "improveQuarkHept2" + | "improveQuarkHept3" + | "improveQuarkHept4" + | "shopImprovedDaily" + | "shopImprovedDaily2" + | "shopImprovedDaily3" + | "shopImprovedDaily4" + | "calculator4" + | "calculator5" + | "calculator6" + | "calculator7" + | "offeringEX3" + | "obtainiumEX3" + | "improveQuarkHept5" + | "seasonPassInfinity" + | "chronometerInfinity" + | "shopSingularityPenaltyDebuff" + | "shopAmbrosiaLuckMultiplier4" + | "shopOcteractAmbrosiaLuck" + | "shopAmbrosiaGeneration1" + | "shopAmbrosiaGeneration2" + | "shopAmbrosiaGeneration3" + | "shopAmbrosiaGeneration4" + | "shopAmbrosiaLuck1" + | "shopAmbrosiaLuck2" + | "shopAmbrosiaLuck3" + | "shopAmbrosiaLuck4"; export const getShopCosts = (input: ShopUpgradeNames) => { - if (shopData[input].type === shopUpgradeTypes.CONSUMABLE || shopData[input].maxLevel === 1) { - return shopData[input].price + if ( + shopData[input].type === shopUpgradeTypes.CONSUMABLE || + shopData[input].maxLevel === 1 + ) { + return shopData[input].price; } else { - const priceIncreaseMult = player.shopUpgrades[input] - return shopData[input].price + shopData[input].priceIncrease * priceIncreaseMult + const priceIncreaseMult = player.shopUpgrades[input]; + return ( + shopData[input].price + shopData[input].priceIncrease * priceIncreaseMult + ); } -} +}; export const shopDescriptions = (input: ShopUpgradeNames) => { - const rofl = DOMCacheGetOrSet('quarkdescription')! - const lol = DOMCacheGetOrSet('quarkeffect')! - const refundable = DOMCacheGetOrSet('quarkRefundable')! + const rofl = DOMCacheGetOrSet("quarkdescription")!; + const lol = DOMCacheGetOrSet("quarkeffect")!; + const refundable = DOMCacheGetOrSet("quarkRefundable")!; - rofl.innerHTML = i18next.t(`shop.upgradeDescriptions.${input}`) + rofl.innerHTML = i18next.t(`shop.upgradeDescriptions.${input}`); shopData[input].refundable // TODO(@KhafraDev): i18n - ? refundable.textContent = `This item is refundable! Will be set to level ${ - shopData[input].refundMinimumLevel - } when refunded.` - : refundable.textContent = i18next.t('shop.cannotRefund') + ? (refundable.textContent = `This item is refundable! Will be set to level ${shopData[input].refundMinimumLevel} when refunded.`) + : (refundable.textContent = i18next.t("shop.cannotRefund")); switch (input) { - case 'offeringPotion': - lol.innerHTML = i18next.t('shop.upgradeEffects.offeringPotion', { + case "offeringPotion": + lol.innerHTML = i18next.t("shop.upgradeEffects.offeringPotion", { amount: format( - 7200 * player.offeringpersecond * calculateTimeAcceleration().mult - * +player.singularityUpgrades.potionBuff.getEffect().bonus, + 7200 * + player.offeringpersecond * + calculateTimeAcceleration().mult * + +player.singularityUpgrades.potionBuff.getEffect().bonus, 0, true - ) - }) - break - case 'obtainiumPotion': - lol.innerHTML = i18next.t('shop.upgradeEffects.obtainiumPotion', { + ), + }); + break; + case "obtainiumPotion": + lol.innerHTML = i18next.t("shop.upgradeEffects.obtainiumPotion", { amount: format( - 7200 * player.maxobtainiumpersecond * calculateTimeAcceleration().mult - * +player.singularityUpgrades.potionBuff.getEffect().bonus, + 7200 * + player.maxobtainiumpersecond * + calculateTimeAcceleration().mult * + +player.singularityUpgrades.potionBuff.getEffect().bonus, 0, true - ) - }) - break - case 'offeringEX': - lol.innerHTML = i18next.t('shop.upgradeEffects.offeringEX', { - amount: format(4 * player.shopUpgrades.offeringEX, 2, true) - }) - break - case 'offeringAuto': - lol.innerHTML = i18next.t('shop.upgradeEffects.offeringAuto', { + ), + }); + break; + case "offeringEX": + lol.innerHTML = i18next.t("shop.upgradeEffects.offeringEX", { + amount: format(4 * player.shopUpgrades.offeringEX, 2, true), + }); + break; + case "offeringAuto": + lol.innerHTML = i18next.t("shop.upgradeEffects.offeringAuto", { amount1: format(Math.pow(2, player.shopUpgrades.offeringAuto)), - amount2: format(2 * player.shopUpgrades.offeringAuto, 2) - }) - break - case 'obtainiumEX': - lol.innerHTML = i18next.t('shop.upgradeEffects.obtainiumEX', { - amount: format(4 * player.shopUpgrades.obtainiumEX, 2, true) - }) - break - case 'obtainiumAuto': - lol.innerHTML = i18next.t('shop.upgradeEffects.obtainiumAuto', { - amount: format(player.shopUpgrades.obtainiumAuto * 2, 2) - }) - break - case 'instantChallenge': - lol.innerHTML = i18next.t('shop.upgradeEffects.instantChallenge') - break - case 'antSpeed': - lol.innerHTML = i18next.t('shop.upgradeEffects.antSpeed', { - amount: format(Math.pow(1.2, player.shopUpgrades.antSpeed), 2) - }) - break - case 'cashGrab': - lol.innerHTML = i18next.t('shop.upgradeEffects.cashGrab', { amount: format(player.shopUpgrades.cashGrab, 2) }) - break - case 'shopTalisman': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopTalisman') - break - case 'seasonPass': - lol.innerHTML = i18next.t('shop.upgradeEffects.seasonPass', { - amount: format(2.25 * player.shopUpgrades.seasonPass) - }) - break - case 'challengeExtension': - lol.innerHTML = i18next.t('shop.upgradeEffects.challengeExtension', { - amount: format(2 * player.shopUpgrades.challengeExtension) - }) - break - case 'challengeTome': - lol.innerHTML = i18next.t('shop.upgradeEffects.challengeTome', { + amount2: format(2 * player.shopUpgrades.offeringAuto, 2), + }); + break; + case "obtainiumEX": + lol.innerHTML = i18next.t("shop.upgradeEffects.obtainiumEX", { + amount: format(4 * player.shopUpgrades.obtainiumEX, 2, true), + }); + break; + case "obtainiumAuto": + lol.innerHTML = i18next.t("shop.upgradeEffects.obtainiumAuto", { + amount: format(player.shopUpgrades.obtainiumAuto * 2, 2), + }); + break; + case "instantChallenge": + lol.innerHTML = i18next.t("shop.upgradeEffects.instantChallenge"); + break; + case "antSpeed": + lol.innerHTML = i18next.t("shop.upgradeEffects.antSpeed", { + amount: format(Math.pow(1.2, player.shopUpgrades.antSpeed), 2), + }); + break; + case "cashGrab": + lol.innerHTML = i18next.t("shop.upgradeEffects.cashGrab", { + amount: format(player.shopUpgrades.cashGrab, 2), + }); + break; + case "shopTalisman": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopTalisman"); + break; + case "seasonPass": + lol.innerHTML = i18next.t("shop.upgradeEffects.seasonPass", { + amount: format(2.25 * player.shopUpgrades.seasonPass), + }); + break; + case "challengeExtension": + lol.innerHTML = i18next.t("shop.upgradeEffects.challengeExtension", { + amount: format(2 * player.shopUpgrades.challengeExtension), + }); + break; + case "challengeTome": + lol.innerHTML = i18next.t("shop.upgradeEffects.challengeTome", { amount1: format(20 * player.shopUpgrades.challengeTome), - amount2: format(1 - (player.shopUpgrades.challengeTome + player.shopUpgrades.challengeTome2) / 100, 2, true) - }) - break - case 'cubeToQuark': - lol.innerHTML = i18next.t('shop.upgradeEffects.cubeToQuark') - break - case 'tesseractToQuark': - lol.innerHTML = i18next.t('shop.upgradeEffects.tesseractToQuark') - break - case 'hypercubeToQuark': - lol.innerHTML = i18next.t('shop.upgradeEffects.hypercubeToQuark') - break - case 'seasonPass2': - lol.innerHTML = i18next.t('shop.upgradeEffects.seasonPass2', { - amount: format(1.5 * player.shopUpgrades.seasonPass2) - }) - break - case 'seasonPass3': - lol.innerHTML = i18next.t('shop.upgradeEffects.seasonPass3', { - amount: format(1.5 * player.shopUpgrades.seasonPass3) - }) - break - case 'chronometer': - lol.innerHTML = i18next.t('shop.upgradeEffects.chronometer', { - amount: format(1.2 * player.shopUpgrades.chronometer) - }) - break - case 'infiniteAscent': - lol.innerHTML = i18next.t('shop.upgradeEffects.infiniteAscent') - break - case 'calculator': - lol.innerHTML = i18next.t('shop.upgradeEffects.calculator', { + amount2: format( + 1 - + (player.shopUpgrades.challengeTome + + player.shopUpgrades.challengeTome2) / + 100, + 2, + true + ), + }); + break; + case "cubeToQuark": + lol.innerHTML = i18next.t("shop.upgradeEffects.cubeToQuark"); + break; + case "tesseractToQuark": + lol.innerHTML = i18next.t("shop.upgradeEffects.tesseractToQuark"); + break; + case "hypercubeToQuark": + lol.innerHTML = i18next.t("shop.upgradeEffects.hypercubeToQuark"); + break; + case "seasonPass2": + lol.innerHTML = i18next.t("shop.upgradeEffects.seasonPass2", { + amount: format(1.5 * player.shopUpgrades.seasonPass2), + }); + break; + case "seasonPass3": + lol.innerHTML = i18next.t("shop.upgradeEffects.seasonPass3", { + amount: format(1.5 * player.shopUpgrades.seasonPass3), + }); + break; + case "chronometer": + lol.innerHTML = i18next.t("shop.upgradeEffects.chronometer", { + amount: format(1.2 * player.shopUpgrades.chronometer), + }); + break; + case "infiniteAscent": + lol.innerHTML = i18next.t("shop.upgradeEffects.infiniteAscent"); + break; + case "calculator": + lol.innerHTML = i18next.t("shop.upgradeEffects.calculator", { amount1: format(14 * player.shopUpgrades.calculator), bool1: player.shopUpgrades.calculator > 0, - bool2: player.shopUpgrades.calculator === shopData.calculator.maxLevel - }) - break - case 'calculator2': - lol.innerHTML = i18next.t('shop.upgradeEffects.calculator2', { + bool2: player.shopUpgrades.calculator === shopData.calculator.maxLevel, + }); + break; + case "calculator2": + lol.innerHTML = i18next.t("shop.upgradeEffects.calculator2", { amount1: format(2 * player.shopUpgrades.calculator2), - amount2: format((player.shopUpgrades.calculator2 === shopData.calculator2.maxLevel) ? 25 : 0) - }) - break - case 'calculator3': - lol.innerHTML = i18next.t('shop.upgradeEffects.calculator3', { + amount2: format( + player.shopUpgrades.calculator2 === shopData.calculator2.maxLevel + ? 25 + : 0 + ), + }); + break; + case "calculator3": + lol.innerHTML = i18next.t("shop.upgradeEffects.calculator3", { amount1: format(10 * player.shopUpgrades.calculator3), - amount2: format(60 * player.shopUpgrades.calculator3) - }) - break - case 'calculator4': - lol.innerHTML = i18next.t('shop.upgradeEffects.calculator4', { + amount2: format(60 * player.shopUpgrades.calculator3), + }); + break; + case "calculator4": + lol.innerHTML = i18next.t("shop.upgradeEffects.calculator4", { amount1: format(2 * player.shopUpgrades.calculator4), - amount2: player.shopUpgrades.calculator4 === 10 ? 32 : 0 - }) - break - case 'calculator5': - lol.innerHTML = i18next.t('shop.upgradeEffects.calculator5', { + amount2: player.shopUpgrades.calculator4 === 10 ? 32 : 0, + }); + break; + case "calculator5": + lol.innerHTML = i18next.t("shop.upgradeEffects.calculator5", { amount1: format(6 * player.shopUpgrades.calculator5), - amount2: Math.floor(player.shopUpgrades.calculator5 / 10) - + (player.shopUpgrades.calculator4 === shopData.calculator5.maxLevel ? 6 : 0) - }) - break - case 'calculator6': - lol.innerHTML = i18next.t('shop.upgradeEffects.calculator6', { + amount2: + Math.floor(player.shopUpgrades.calculator5 / 10) + + (player.shopUpgrades.calculator4 === shopData.calculator5.maxLevel + ? 6 + : 0), + }); + break; + case "calculator6": + lol.innerHTML = i18next.t("shop.upgradeEffects.calculator6", { amount1: format(player.shopUpgrades.calculator6), - amount2: player.shopUpgrades.calculator6 === shopData.calculator6.maxLevel ? 24 : 0 - }) - break - case 'constantEX': - lol.innerHTML = i18next.t('shop.upgradeEffects.constantEX', { - amount: format(player.shopUpgrades.constantEX, 0, true) - }) - break - case 'powderEX': - lol.innerHTML = i18next.t('shop.upgradeEffects.powderEX', { amount: format(2 * player.shopUpgrades.powderEX) }) - break - case 'chronometer2': - lol.innerHTML = i18next.t('shop.upgradeEffects.chronometer2', { - amount: format(0.6 * player.shopUpgrades.chronometer2, 1) - }) - break - case 'chronometer3': - lol.innerHTML = i18next.t('shop.upgradeEffects.chronometer3', { - amount: format(1.5 * player.shopUpgrades.chronometer3, 1) - }) - break - case 'seasonPassY': - lol.innerHTML = i18next.t('shop.upgradeEffects.seasonPassY', { - amount: format(0.75 * player.shopUpgrades.seasonPassY, 2) - }) - break - case 'seasonPassZ': - lol.innerHTML = i18next.t('shop.upgradeEffects.seasonPassZ', { - amount: format(1 * player.shopUpgrades.seasonPassZ * player.singularityCount, 0, true) - }) - break - case 'challengeTome2': - lol.innerHTML = i18next.t('shop.upgradeEffects.challengeTome2', { + amount2: + player.shopUpgrades.calculator6 === shopData.calculator6.maxLevel + ? 24 + : 0, + }); + break; + case "calculator7": + lol.innerHTML = i18next.t("shop.upgradeEffects.calculator7", { + amount1: format(player.shopUpgrades.calculator7, 0, true), + amount2: + player.shopUpgrades.calculator7 === shopData.calculator7.maxLevel + ? 48 + : 0, + }); + break; + case "constantEX": + lol.innerHTML = i18next.t("shop.upgradeEffects.constantEX", { + amount: format(player.shopUpgrades.constantEX, 0, true), + }); + break; + case "powderEX": + lol.innerHTML = i18next.t("shop.upgradeEffects.powderEX", { + amount: format(2 * player.shopUpgrades.powderEX), + }); + break; + case "chronometer2": + lol.innerHTML = i18next.t("shop.upgradeEffects.chronometer2", { + amount: format(0.6 * player.shopUpgrades.chronometer2, 1), + }); + break; + case "chronometer3": + lol.innerHTML = i18next.t("shop.upgradeEffects.chronometer3", { + amount: format(1.5 * player.shopUpgrades.chronometer3, 1), + }); + break; + case "seasonPassY": + lol.innerHTML = i18next.t("shop.upgradeEffects.seasonPassY", { + amount: format(0.75 * player.shopUpgrades.seasonPassY, 2), + }); + break; + case "seasonPassZ": + lol.innerHTML = i18next.t("shop.upgradeEffects.seasonPassZ", { + amount: format( + 1 * player.shopUpgrades.seasonPassZ * player.singularityCount, + 0, + true + ), + }); + break; + case "challengeTome2": + lol.innerHTML = i18next.t("shop.upgradeEffects.challengeTome2", { amount1: 20 * player.shopUpgrades.challengeTome2, - amount2: format(1 - (player.shopUpgrades.challengeTome + player.shopUpgrades.challengeTome2) / 100, 2, true) - }) - break - case 'instantChallenge2': - lol.innerHTML = i18next.t('shop.upgradeEffects.instantChallenge2', { - amount: format(player.shopUpgrades.instantChallenge2 * player.singularityCount, 0) - }) - break - case 'cashGrab2': - lol.innerHTML = i18next.t('shop.upgradeEffects.cashGrab2', { - amount: format(0.5 * player.shopUpgrades.cashGrab2, 1) - }) - break - case 'cubeToQuarkAll': - lol.innerHTML = i18next.t('shop.upgradeEffects.cubeToQuarkAll', { - amount: format(0.2 * player.shopUpgrades.cubeToQuarkAll, 2) - }) - break - case 'chronometerZ': - lol.innerHTML = i18next.t('shop.upgradeEffects.chronometerZ', { - amount: format(0.1 * player.singularityCount * player.shopUpgrades.chronometerZ, 2) - }) - break - case 'offeringEX2': - lol.innerHTML = i18next.t('shop.upgradeEffects.offeringEX2', { - amount: format(1 * player.singularityCount * player.shopUpgrades.offeringEX2, 2) - }) - break - case 'obtainiumEX2': - lol.innerHTML = i18next.t('shop.upgradeEffects.obtainiumEX2', { - amount: format(1 * player.singularityCount * player.shopUpgrades.obtainiumEX2, 2) - }) - break - case 'powderAuto': - lol.innerHTML = i18next.t('shop.upgradeEffects.powderAuto', { - amount: format(100 / (Math.max(1, player.shopUpgrades.powderAuto) * calculatePowderConversion().mult), 2, true) - }) - break - case 'seasonPassLost': - lol.innerHTML = i18next.t('shop.upgradeEffects.seasonPassLost', { - amount: format(0.1 * player.shopUpgrades.seasonPassLost, 2) - }) - break - case 'challenge15Auto': - lol.innerHTML = i18next.t('shop.upgradeEffects.challenge15Auto') - break - case 'extraWarp': - lol.innerHTML = i18next.t('shop.upgradeEffects.extraWarp', { amount: player.shopUpgrades.extraWarp }) - break - case 'autoWarp': - lol.innerHTML = i18next.t('shop.upgradeEffects.autoWarp') - break - case 'improveQuarkHept': - lol.innerHTML = i18next.t('shop.upgradeEffects.improveQuarkHept', { - amount: 2 * player.shopUpgrades.improveQuarkHept - }) - break - case 'improveQuarkHept2': - lol.innerHTML = i18next.t('shop.upgradeEffects.improveQuarkHept2', { - amount: 2 * player.shopUpgrades.improveQuarkHept2 - }) - break - case 'improveQuarkHept3': - lol.innerHTML = i18next.t('shop.upgradeEffects.improveQuarkHept3', { - amount: 2 * player.shopUpgrades.improveQuarkHept3 - }) - break - case 'improveQuarkHept4': - lol.innerHTML = i18next.t('shop.upgradeEffects.improveQuarkHept4', { - amount: 2 * player.shopUpgrades.improveQuarkHept4 - }) - break - case 'shopImprovedDaily': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopImprovedDaily', { - amount: format(5 * player.shopUpgrades.shopImprovedDaily) - }) - break - case 'shopImprovedDaily2': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopImprovedDaily2', { + amount2: format( + 1 - + (player.shopUpgrades.challengeTome + + player.shopUpgrades.challengeTome2) / + 100, + 2, + true + ), + }); + break; + case "instantChallenge2": + lol.innerHTML = i18next.t("shop.upgradeEffects.instantChallenge2", { + amount: format( + player.shopUpgrades.instantChallenge2 * player.singularityCount, + 0 + ), + }); + break; + case "cashGrab2": + lol.innerHTML = i18next.t("shop.upgradeEffects.cashGrab2", { + amount: format(0.5 * player.shopUpgrades.cashGrab2, 1), + }); + break; + case "cubeToQuarkAll": + lol.innerHTML = i18next.t("shop.upgradeEffects.cubeToQuarkAll", { + amount: format(0.2 * player.shopUpgrades.cubeToQuarkAll, 2), + }); + break; + case "chronometerZ": + lol.innerHTML = i18next.t("shop.upgradeEffects.chronometerZ", { + amount: format( + 0.1 * player.singularityCount * player.shopUpgrades.chronometerZ, + 2 + ), + }); + break; + case "offeringEX2": + lol.innerHTML = i18next.t("shop.upgradeEffects.offeringEX2", { + amount: format( + 1 * player.singularityCount * player.shopUpgrades.offeringEX2, + 2 + ), + }); + break; + case "obtainiumEX2": + lol.innerHTML = i18next.t("shop.upgradeEffects.obtainiumEX2", { + amount: format( + 1 * player.singularityCount * player.shopUpgrades.obtainiumEX2, + 2 + ), + }); + break; + case "powderAuto": + lol.innerHTML = i18next.t("shop.upgradeEffects.powderAuto", { + amount: format( + 100 / + (Math.max(1, player.shopUpgrades.powderAuto) * + calculatePowderConversion().mult), + 2, + true + ), + }); + break; + case "seasonPassLost": + lol.innerHTML = i18next.t("shop.upgradeEffects.seasonPassLost", { + amount: format(0.1 * player.shopUpgrades.seasonPassLost, 2), + }); + break; + case "challenge15Auto": + lol.innerHTML = i18next.t("shop.upgradeEffects.challenge15Auto"); + break; + case "extraWarp": + lol.innerHTML = i18next.t("shop.upgradeEffects.extraWarp", { + amount: player.shopUpgrades.extraWarp, + }); + break; + case "autoWarp": + lol.innerHTML = i18next.t("shop.upgradeEffects.autoWarp"); + break; + case "improveQuarkHept": + lol.innerHTML = i18next.t("shop.upgradeEffects.improveQuarkHept", { + amount: 2 * player.shopUpgrades.improveQuarkHept, + }); + break; + case "improveQuarkHept2": + lol.innerHTML = i18next.t("shop.upgradeEffects.improveQuarkHept2", { + amount: 2 * player.shopUpgrades.improveQuarkHept2, + }); + break; + case "improveQuarkHept3": + lol.innerHTML = i18next.t("shop.upgradeEffects.improveQuarkHept3", { + amount: 2 * player.shopUpgrades.improveQuarkHept3, + }); + break; + case "improveQuarkHept4": + lol.innerHTML = i18next.t("shop.upgradeEffects.improveQuarkHept4", { + amount: 2 * player.shopUpgrades.improveQuarkHept4, + }); + break; + case "shopImprovedDaily": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopImprovedDaily", { + amount: format(5 * player.shopUpgrades.shopImprovedDaily), + }); + break; + case "shopImprovedDaily2": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopImprovedDaily2", { amount1: player.shopUpgrades.shopImprovedDaily2, - amount2: player.shopUpgrades.shopImprovedDaily2 * 20 - }) - break - case 'shopImprovedDaily3': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopImprovedDaily3', { + amount2: player.shopUpgrades.shopImprovedDaily2 * 20, + }); + break; + case "shopImprovedDaily3": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopImprovedDaily3", { amount1: player.shopUpgrades.shopImprovedDaily3, - amount2: player.shopUpgrades.shopImprovedDaily3 * 15 - }) - break - case 'shopImprovedDaily4': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopImprovedDaily4', { + amount2: player.shopUpgrades.shopImprovedDaily3 * 15, + }); + break; + case "shopImprovedDaily4": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopImprovedDaily4", { amount1: player.shopUpgrades.shopImprovedDaily4, - amount2: player.shopUpgrades.shopImprovedDaily4 * 100 - }) - break - case 'offeringEX3': - lol.innerHTML = i18next.t('shop.upgradeEffects.offeringEX3', { - amount: format(100 * (Math.pow(1.02, player.shopUpgrades.offeringEX3) - 1), 2, true) - }) - break - case 'obtainiumEX3': - lol.innerHTML = i18next.t('shop.upgradeEffects.obtainiumEX3', { - amount: format(100 * (Math.pow(1.02, player.shopUpgrades.obtainiumEX3) - 1), 2, true) - }) - break - case 'improveQuarkHept5': - lol.innerHTML = i18next.t('shop.upgradeEffects.improveQuarkHept5', { - amount: format(player.shopUpgrades.improveQuarkHept5 / 25, 2, true) - }) - break - case 'seasonPassInfinity': - lol.innerHTML = i18next.t('shop.upgradeEffects.seasonPassInfinity', { - amount: format(100 * (Math.pow(1.02, player.shopUpgrades.seasonPassInfinity) - 1), 2, true) - }) - break - case 'chronometerInfinity': - lol.innerHTML = i18next.t('shop.upgradeEffects.chronometerInfinity', { - amount: format(100 * (Math.pow(1.01, player.shopUpgrades.chronometerInfinity) - 1), 2, true) - }) - break - case 'shopSingularityPenaltyDebuff': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopSingularityPenaltyDebuff', { - amount1: format(player.singularityCount), - amount2: format(player.singularityCount - player.shopUpgrades.shopSingularityPenaltyDebuff) - }) - break - case 'shopAmbrosiaGeneration1': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopAmbrosiaGeneration1', { - amount: format(player.shopUpgrades.shopAmbrosiaGeneration1) - }) - break - case 'shopAmbrosiaGeneration2': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopAmbrosiaGeneration2', { - amount: format(player.shopUpgrades.shopAmbrosiaGeneration2) - }) - break - case 'shopAmbrosiaGeneration3': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopAmbrosiaGeneration3', { - amount: format(player.shopUpgrades.shopAmbrosiaGeneration3) - }) - break - case 'shopAmbrosiaGeneration4': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopAmbrosiaGeneration4', { - amount: format(player.shopUpgrades.shopAmbrosiaGeneration4 / 10, 1, true) - }) - break - case 'shopAmbrosiaLuck1': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopAmbrosiaLuck1', { - amount: format(2 * player.shopUpgrades.shopAmbrosiaLuck1) - }) - break - case 'shopAmbrosiaLuck2': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopAmbrosiaLuck2', { - amount: format(2 * player.shopUpgrades.shopAmbrosiaLuck2) - }) - break - case 'shopAmbrosiaLuck3': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopAmbrosiaLuck3', { - amount: format(2 * player.shopUpgrades.shopAmbrosiaLuck3) - }) - break - case 'shopAmbrosiaLuck4': - lol.innerHTML = i18next.t('shop.upgradeEffects.shopAmbrosiaLuck4', { - amount: format(6 * player.shopUpgrades.shopAmbrosiaLuck4 / 10, 1, true) - }) - break + amount2: player.shopUpgrades.shopImprovedDaily4 * 100, + }); + break; + case "offeringEX3": + lol.innerHTML = i18next.t("shop.upgradeEffects.offeringEX3", { + amount: format( + 100 * (Math.pow(1.02, player.shopUpgrades.offeringEX3) - 1), + 2, + true + ), + }); + break; + case "obtainiumEX3": + lol.innerHTML = i18next.t("shop.upgradeEffects.obtainiumEX3", { + amount: format( + 100 * (Math.pow(1.02, player.shopUpgrades.obtainiumEX3) - 1), + 2, + true + ), + }); + break; + case "improveQuarkHept5": + lol.innerHTML = i18next.t("shop.upgradeEffects.improveQuarkHept5", { + amount: format(player.shopUpgrades.improveQuarkHept5 / 25, 2, true), + }); + break; + case "seasonPassInfinity": + lol.innerHTML = i18next.t("shop.upgradeEffects.seasonPassInfinity", { + amount: format( + 100 * (Math.pow(1.02, player.shopUpgrades.seasonPassInfinity) - 1), + 2, + true + ), + }); + break; + case "chronometerInfinity": + lol.innerHTML = i18next.t("shop.upgradeEffects.chronometerInfinity", { + amount: format( + 100 * (Math.pow(1.01, player.shopUpgrades.chronometerInfinity) - 1), + 2, + true + ), + }); + break; + case "shopSingularityPenaltyDebuff": + lol.innerHTML = i18next.t( + "shop.upgradeEffects.shopSingularityPenaltyDebuff", + { + amount1: format(player.singularityCount), + amount2: format( + player.singularityCount - + player.shopUpgrades.shopSingularityPenaltyDebuff + ), + } + ); + break; + case "shopAmbrosiaLuckMultiplier4": + lol.innerHTML = i18next.t( + "shop.upgradeEffects.shopAmbrosiaLuckMultiplier4", + { + amount: format(player.shopUpgrades.shopAmbrosiaLuckMultiplier4), + } + ); + break; + case "shopOcteractAmbrosiaLuck": + lol.innerHTML = i18next.t( + "shop.upgradeEffects.shopOcteractAmbrosiaLuck", + { + amount: format( + player.shopUpgrades.shopOcteractAmbrosiaLuck * + (1 + Math.floor(Math.log10(player.totalWowOcteracts + 1))) + ), + } + ); + break; + case "shopAmbrosiaGeneration1": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopAmbrosiaGeneration1", { + amount: format(player.shopUpgrades.shopAmbrosiaGeneration1), + }); + break; + case "shopAmbrosiaGeneration2": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopAmbrosiaGeneration2", { + amount: format(player.shopUpgrades.shopAmbrosiaGeneration2), + }); + break; + case "shopAmbrosiaGeneration3": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopAmbrosiaGeneration3", { + amount: format(player.shopUpgrades.shopAmbrosiaGeneration3), + }); + break; + case "shopAmbrosiaGeneration4": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopAmbrosiaGeneration4", { + amount: format( + player.shopUpgrades.shopAmbrosiaGeneration4 / 10, + 1, + true + ), + }); + break; + case "shopAmbrosiaLuck1": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopAmbrosiaLuck1", { + amount: format(2 * player.shopUpgrades.shopAmbrosiaLuck1), + }); + break; + case "shopAmbrosiaLuck2": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopAmbrosiaLuck2", { + amount: format(2 * player.shopUpgrades.shopAmbrosiaLuck2), + }); + break; + case "shopAmbrosiaLuck3": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopAmbrosiaLuck3", { + amount: format(2 * player.shopUpgrades.shopAmbrosiaLuck3), + }); + break; + case "shopAmbrosiaLuck4": + lol.innerHTML = i18next.t("shop.upgradeEffects.shopAmbrosiaLuck4", { + amount: format( + (6 * player.shopUpgrades.shopAmbrosiaLuck4) / 10, + 1, + true + ), + }); + break; } -} +}; // strentax 07/21 Add function to convert code-name display to end-user friendly display of shop upgrades export const friendlyShopName = (input: ShopUpgradeNames) => { // TODO(i18n): add these under shop.names const names: Record = { - offeringPotion: 'Offering Potion', - obtainiumPotion: 'Obtainium Potion', - offeringEX: 'Offering EX', - offeringAuto: 'Offering Auto', - obtainiumEX: 'Obtainium EX', - obtainiumAuto: 'Obtainium Auto', - instantChallenge: 'Instant Challenge Completions', - antSpeed: 'Ant Speed', - cashGrab: 'Cash Grab', - shopTalisman: 'the Plastic talisman', - seasonPass: 'Season Pass', - challengeExtension: 'Reincarnation Challenge EX', - challengeTome: 'Challenge 10 Requirement Reduce', - cubeToQuark: 'Cube Quarks +50%', - tesseractToQuark: 'Tesseract Quarks +50%', - hypercubeToQuark: 'Hypercube Quarks +50%', - seasonPass2: 'Season Pass 2', - seasonPass3: 'Season Pass 3', - chronometer: 'Chronometer 1', - infiniteAscent: 'Infinite Ascent', - calculator: 'PL-AT calculator', - calculator2: 'PL-AT X calculator', - calculator3: 'PL-AT Ω calculator', - calculator4: 'PL-AT δ calculator', - calculator5: 'PL-AT Γ calculator', - calculator6: 'QUAAA-T calculator', - constantEX: 'Constant EX', - powderEX: 'Powder EX', - chronometer2: 'Chronometer 2', - chronometer3: 'Chronometer 3', - seasonPassY: 'Season Pass Y', - seasonPassZ: 'Season Pass Z', - challengeTome2: 'Challenge 10 Requirement Reduction 2', - instantChallenge2: 'Instant Challenge Completions 2', - cubeToQuarkAll: 'Quark Gain Cube Improvement 2', - cashGrab2: 'Cash Grab 2', - chronometerZ: 'Chronometer Z', - obtainiumEX2: 'Obtainium EX 2', - offeringEX2: 'Offering EX 2', - powderAuto: 'Automated Powder', - seasonPassLost: 'Season Pass LOST', - challenge15Auto: 'Challenge 15 Automation', - extraWarp: 'Extra Warp', - autoWarp: 'a quack powered Warps?', - improveQuarkHept: 'Quark Hepteract 1', - improveQuarkHept2: 'Quark Hepteract 2', - improveQuarkHept3: 'Quark Hepteract 3', - improveQuarkHept4: 'Quack Hepteract 4', - shopImprovedDaily: 'Improved Daily Code 1', - shopImprovedDaily2: 'Improved Daily Code 2', - shopImprovedDaily3: 'Improved Daily Code 3', - shopImprovedDaily4: 'Improved Daily Code 4', - offeringEX3: 'The final Offering Upgrade', - obtainiumEX3: 'The final Obtainium Upgrade', - improveQuarkHept5: 'The final Quark Hepteract Improver', - chronometerInfinity: 'The final Chronometer', - seasonPassInfinity: 'The final Season pass', - shopSingularityPenaltyDebuff: 'A Singularity Tenderizer', - shopAmbrosiaGeneration1: 'Ambrosia Generation Speedup', - shopAmbrosiaGeneration2: 'Another Ambrosia Generation Speedup', - shopAmbrosiaGeneration3: 'A better Ambrosia Generation Speedup', - shopAmbrosiaGeneration4: 'A FINAL Ambrosia Generation Speedup', - shopAmbrosiaLuck1: 'Ambrosia Luck Increaser', - shopAmbrosiaLuck2: 'Another Ambrosia Luck Increaser', - shopAmbrosiaLuck3: 'A better Ambrosia Generation Speedup', - shopAmbrosiaLuck4: 'A FINAL Ambrosia Generation Speedup' - } + offeringPotion: "Offering Potion", + obtainiumPotion: "Obtainium Potion", + offeringEX: "Offering EX", + offeringAuto: "Offering Auto", + obtainiumEX: "Obtainium EX", + obtainiumAuto: "Obtainium Auto", + instantChallenge: "Instant Challenge Completions", + antSpeed: "Ant Speed", + cashGrab: "Cash Grab", + shopTalisman: "the Plastic talisman", + seasonPass: "Season Pass", + challengeExtension: "Reincarnation Challenge EX", + challengeTome: "Challenge 10 Requirement Reduce", + cubeToQuark: "Cube Quarks +50%", + tesseractToQuark: "Tesseract Quarks +50%", + hypercubeToQuark: "Hypercube Quarks +50%", + seasonPass2: "Season Pass 2", + seasonPass3: "Season Pass 3", + chronometer: "Chronometer 1", + infiniteAscent: "Infinite Ascent", + calculator: "PL-AT calculator", + calculator2: "PL-AT X calculator", + calculator3: "PL-AT Ω calculator", + calculator4: "PL-AT δ calculator", + calculator5: "PL-AT Γ calculator", + calculator6: "QUAAA-T calculator", + calculator7: "PL-AT ΩΩ calculator", + constantEX: "Constant EX", + powderEX: "Powder EX", + chronometer2: "Chronometer 2", + chronometer3: "Chronometer 3", + seasonPassY: "Season Pass Y", + seasonPassZ: "Season Pass Z", + challengeTome2: "Challenge 10 Requirement Reduction 2", + instantChallenge2: "Instant Challenge Completions 2", + cubeToQuarkAll: "Quark Gain Cube Improvement 2", + cashGrab2: "Cash Grab 2", + chronometerZ: "Chronometer Z", + obtainiumEX2: "Obtainium EX 2", + offeringEX2: "Offering EX 2", + powderAuto: "Automated Powder", + seasonPassLost: "Season Pass LOST", + challenge15Auto: "Challenge 15 Automation", + extraWarp: "Extra Warp", + autoWarp: "a quack powered Warps?", + improveQuarkHept: "Quark Hepteract 1", + improveQuarkHept2: "Quark Hepteract 2", + improveQuarkHept3: "Quark Hepteract 3", + improveQuarkHept4: "Quack Hepteract 4", + shopImprovedDaily: "Improved Daily Code 1", + shopImprovedDaily2: "Improved Daily Code 2", + shopImprovedDaily3: "Improved Daily Code 3", + shopImprovedDaily4: "Improved Daily Code 4", + offeringEX3: "The final Offering Upgrade", + obtainiumEX3: "The final Obtainium Upgrade", + improveQuarkHept5: "The final Quark Hepteract Improver", + chronometerInfinity: "The final Chronometer", + seasonPassInfinity: "The final Season pass", + shopSingularityPenaltyDebuff: "A Singularity Tenderizer", + shopAmbrosiaLuckMultiplier4: + "The Fourth Multiplicative Ambrosia Luck Multiplier", + shopOcteractAmbrosiaLuck: "Octeract-Based Ambrosia Luck Amplifier", + shopAmbrosiaGeneration1: "Ambrosia Generation Speedup", + shopAmbrosiaGeneration2: "Another Ambrosia Generation Speedup", + shopAmbrosiaGeneration3: "A better Ambrosia Generation Speedup", + shopAmbrosiaGeneration4: "A FINAL Ambrosia Generation Speedup", + shopAmbrosiaLuck1: "Ambrosia Luck Increaser", + shopAmbrosiaLuck2: "Another Ambrosia Luck Increaser", + shopAmbrosiaLuck3: "A better Ambrosia Generation Speedup", + shopAmbrosiaLuck4: "A FINAL Ambrosia Generation Speedup", + }; - return names[input] -} + return names[input]; +}; export const buyShopUpgrades = async (input: ShopUpgradeNames) => { - const shopItem = shopData[input] + const shopItem = shopData[input]; if (player.shopUpgrades[input] >= shopItem.maxLevel) { return player.shopConfirmationToggle ? Alert( - `You can't purchase ${friendlyShopName(input)} because you are already at the maximum ${ - shopItem.type === shopUpgradeTypes.UPGRADE ? 'level' : 'capacity' - }!` - ) - : null + `You can't purchase ${friendlyShopName( + input + )} because you are already at the maximum ${ + shopItem.type === shopUpgradeTypes.UPGRADE ? "level" : "capacity" + }!` + ) + : null; } else if (Number(player.worlds) < getShopCosts(input)) { return player.shopConfirmationToggle - ? Alert(`You can't purchase ${friendlyShopName(input)} because you don't have enough Quarks!`) - : null + ? Alert( + `You can't purchase ${friendlyShopName( + input + )} because you don't have enough Quarks!` + ) + : null; } // Actually lock for HTML exploit if (!isShopUpgradeUnlocked(input)) { - return Alert(`You do not have the right to purchase ${friendlyShopName(input)}!`) + return Alert( + `You do not have the right to purchase ${friendlyShopName(input)}!` + ); } - let buyData: IMultiBuy - const maxBuyAmount = shopItem.maxLevel - player.shopUpgrades[input] - let buyAmount: number - let buyCost: number + let buyData: IMultiBuy; + const maxBuyAmount = shopItem.maxLevel - player.shopUpgrades[input]; + let buyAmount: number; + let buyCost: number; switch (player.shopBuyMaxToggle) { case false: - buyAmount = 1 - buyCost = getShopCosts(input) - break - case 'TEN': + buyAmount = 1; + buyCost = getShopCosts(input); + break; + case "TEN": buyData = calculateSummationNonLinear( player.shopUpgrades[input], shopItem.price, +player.worlds, shopItem.priceIncrease / shopItem.price, Math.min(10, maxBuyAmount) - ) - buyAmount = buyData.levelCanBuy - player.shopUpgrades[input] - buyCost = buyData.cost - break + ); + buyAmount = buyData.levelCanBuy - player.shopUpgrades[input]; + buyCost = buyData.cost; + break; default: buyData = calculateSummationNonLinear( player.shopUpgrades[input], @@ -1183,45 +1349,60 @@ export const buyShopUpgrades = async (input: ShopUpgradeNames) => { +player.worlds, shopItem.priceIncrease / shopItem.price, maxBuyAmount - ) - buyAmount = buyData.levelCanBuy - player.shopUpgrades[input] - buyCost = buyData.cost + ); + buyAmount = buyData.levelCanBuy - player.shopUpgrades[input]; + buyCost = buyData.cost; } - const singular = shopItem.maxLevel === 1 - const merch = buyAmount.toLocaleString() + (shopItem.type === shopUpgradeTypes.UPGRADE ? ' level' : ' vial') - + (buyAmount === 1 ? '' : 's') - const noRefunds = shopItem.refundable ? '' : '\n\n\u26A0\uFE0F !! No Refunds !! \u26A0\uFE0F' - const maxPots = shopItem.type === shopUpgradeTypes.CONSUMABLE - ? '\n\nType -1 in Buy: ANY to buy equal amounts of both Potions.' - : '' + const singular = shopItem.maxLevel === 1; + const merch = + buyAmount.toLocaleString() + + (shopItem.type === shopUpgradeTypes.UPGRADE ? " level" : " vial") + + (buyAmount === 1 ? "" : "s"); + const noRefunds = shopItem.refundable + ? "" + : "\n\n\u26A0\uFE0F !! No Refunds !! \u26A0\uFE0F"; + const maxPots = + shopItem.type === shopUpgradeTypes.CONSUMABLE + ? "\n\nType -1 in Buy: ANY to buy equal amounts of both Potions." + : ""; - if (player.shopBuyMaxToggle === 'ANY' && !singular) { + if (player.shopBuyMaxToggle === "ANY" && !singular) { const buyInput = await Prompt( - `You can afford to purchase up to ${merch} of ${ - friendlyShopName(input) - } for ${buyCost.toLocaleString()} Quarks. How many would you like to buy?${maxPots + noRefunds}` - ) - let buyAny: number - if (Number(buyInput) === -1 && shopItem.type === shopUpgradeTypes.CONSUMABLE) { - const other = input === 'offeringPotion' ? 'obtainiumPotion' : 'offeringPotion' - const toSpend = Math.max(+player.worlds / 2, +player.worlds - buyCost) + `You can afford to purchase up to ${merch} of ${friendlyShopName( + input + )} for ${buyCost.toLocaleString()} Quarks. How many would you like to buy?${ + maxPots + noRefunds + }` + ); + let buyAny: number; + if ( + Number(buyInput) === -1 && + shopItem.type === shopUpgradeTypes.CONSUMABLE + ) { + const other = + input === "offeringPotion" ? "obtainiumPotion" : "offeringPotion"; + const toSpend = Math.max(+player.worlds / 2, +player.worlds - buyCost); const otherPot: IMultiBuy = calculateSummationNonLinear( player.shopUpgrades[other], shopData[other].price, toSpend, shopData[other].priceIncrease / shopData[other].price, shopData[other].maxLevel - player.shopUpgrades[other] - ) - player.worlds.sub(otherPot.cost) - player.shopUpgrades[other] = otherPot.levelCanBuy - buyAny = buyAmount + ); + player.worlds.sub(otherPot.cost); + player.shopUpgrades[other] = otherPot.levelCanBuy; + buyAny = buyAmount; } else { - buyAny = Math.floor(Number(buyInput)) + buyAny = Math.floor(Number(buyInput)); if (buyAny === 0) { - return - } else if (Number.isNaN(buyAny) || !Number.isFinite(buyAny) || buyAny < 0) { - return Alert('Amount must be a finite, positive integer.') + return; + } else if ( + Number.isNaN(buyAny) || + !Number.isFinite(buyAny) || + buyAny < 0 + ) { + return Alert("Amount must be a finite, positive integer."); } } const anyData: IMultiBuy = calculateSummationNonLinear( @@ -1230,270 +1411,380 @@ export const buyShopUpgrades = async (input: ShopUpgradeNames) => { +player.worlds, shopItem.priceIncrease / shopItem.price, Math.min(buyAny, buyAmount) - ) - player.worlds.sub(anyData.cost) - player.shopUpgrades[input] = anyData.levelCanBuy - revealStuff() - player.caches.ambrosiaGeneration.updateVal('ShopUpgrades') - player.caches.ambrosiaLuck.updateVal('ShopUpgrades') - return + ); + player.worlds.sub(anyData.cost); + player.shopUpgrades[input] = anyData.levelCanBuy; + revealStuff(); + player.caches.ambrosiaGeneration.updateVal("ShopUpgrades"); + player.caches.ambrosiaLuck.updateVal("ShopUpgrades"); + return; } - let p = true - if (player.shopConfirmationToggle || (!shopItem.refundable && player.shopBuyMaxToggle !== false)) { + let p = true; + if ( + player.shopConfirmationToggle || + (!shopItem.refundable && player.shopBuyMaxToggle !== false) + ) { p = await Confirm( - `You are about to ${singular ? 'unlock' : `purchase ${merch} of`} ${ - friendlyShopName(input) - } for ${buyCost.toLocaleString()} Quarks. Press 'OK' to finalize purchase.${maxPots + noRefunds}` - ) + `You are about to ${ + singular ? "unlock" : `purchase ${merch} of` + } ${friendlyShopName( + input + )} for ${buyCost.toLocaleString()} Quarks. Press 'OK' to finalize purchase.${ + maxPots + noRefunds + }` + ); } if (p) { - player.worlds.sub(buyCost) - player.shopUpgrades[input] += buyAmount - player.caches.ambrosiaGeneration.updateVal('ShopUpgrades') - player.caches.ambrosiaLuck.updateVal('ShopUpgrades') - revealStuff() + player.worlds.sub(buyCost); + player.shopUpgrades[input] += buyAmount; + player.caches.ambrosiaGeneration.updateVal("ShopUpgrades"); + player.caches.ambrosiaLuck.updateVal("ShopUpgrades"); + revealStuff(); } -} +}; export const autoBuyConsumable = (input: ShopUpgradeNames) => { const maxBuyablePotions = Math.floor( Math.min( Number(player.worlds) / 100, - Math.min(shopData[input].maxLevel - player.shopUpgrades[input], Math.pow(player.highestSingularityCount, 2) * 100) + Math.min( + shopData[input].maxLevel - player.shopUpgrades[input], + Math.pow(player.highestSingularityCount, 2) * 100 + ) ) - ) + ); if (shopData[input].maxLevel <= player.shopUpgrades[input]) { - return + return; } if (maxBuyablePotions <= 0) { - return + return; } - player.worlds.sub(100 * maxBuyablePotions) - player.shopUpgrades[input] += maxBuyablePotions -} + player.worlds.sub(100 * maxBuyablePotions); + player.shopUpgrades[input] += maxBuyablePotions; +}; -export const useConsumable = async (input: ShopUpgradeNames, automatic = false, used = 1, spend = true) => { - const p = (player.shopConfirmationToggle && !automatic) - ? await Confirm('Would you like to use some of this potion?') - : true +export const useConsumable = async ( + input: ShopUpgradeNames, + automatic = false, + used = 1, + spend = true +) => { + const p = + player.shopConfirmationToggle && !automatic + ? await Confirm("Would you like to use some of this potion?") + : true; if (p) { - const multiplier = +player.singularityUpgrades.potionBuff.getEffect().bonus - * +player.singularityUpgrades.potionBuff2.getEffect().bonus - * +player.singularityUpgrades.potionBuff3.getEffect().bonus - * +player.octeractUpgrades.octeractAutoPotionEfficiency.getEffect().bonus - * used + const multiplier = + +player.singularityUpgrades.potionBuff.getEffect().bonus * + +player.singularityUpgrades.potionBuff2.getEffect().bonus * + +player.singularityUpgrades.potionBuff3.getEffect().bonus * + +player.octeractUpgrades.octeractAutoPotionEfficiency.getEffect().bonus * + used; - if (input === 'offeringPotion') { + if (input === "offeringPotion") { if (player.shopUpgrades.offeringPotion >= used || !spend) { - player.shopUpgrades.offeringPotion -= spend ? used : 0 - player.runeshards += Math.floor(7200 * player.offeringpersecond * calculateTimeAcceleration().mult * multiplier) - player.runeshards = Math.min(1e300, player.runeshards) + player.shopUpgrades.offeringPotion -= spend ? used : 0; + player.runeshards += Math.floor( + 7200 * + player.offeringpersecond * + calculateTimeAcceleration().mult * + multiplier + ); + player.runeshards = Math.min(1e300, player.runeshards); } - } else if (input === 'obtainiumPotion') { + } else if (input === "obtainiumPotion") { if (player.shopUpgrades.obtainiumPotion >= used || !spend) { - player.shopUpgrades.obtainiumPotion -= spend ? used : 0 + player.shopUpgrades.obtainiumPotion -= spend ? used : 0; player.researchPoints += Math.floor( - 7200 * player.maxobtainiumpersecond * calculateTimeAcceleration().mult * multiplier - ) - player.researchPoints = Math.min(1e300, player.researchPoints) + 7200 * + player.maxobtainiumpersecond * + calculateTimeAcceleration().mult * + multiplier + ); + player.researchPoints = Math.min(1e300, player.researchPoints); } } } -} +}; export const resetShopUpgrades = async (ignoreBoolean = false) => { - let p = false + let p = false; if (!ignoreBoolean) { p = player.shopConfirmationToggle ? await Confirm( - 'This will fully refund most of your permanent upgrades for an upfront cost of 15 Quarks. Would you like to do this?' - ) - : true + "This will fully refund most of your permanent upgrades for an upfront cost of 15 Quarks. Would you like to do this?" + ) + : true; } if (p || ignoreBoolean) { - const singularityQuarks = player.quarksThisSingularity - let refunds = false + const singularityQuarks = player.quarksThisSingularity; + let refunds = false; for (const shopItem in shopData) { - const key = shopItem as keyof typeof shopData - const item = shopData[key] - if (item.refundable && player.shopUpgrades[key] > item.refundMinimumLevel) { - refunds = true + const key = shopItem as keyof typeof shopData; + const item = shopData[key]; + if ( + item.refundable && + player.shopUpgrades[key] > item.refundMinimumLevel + ) { + refunds = true; // Determines how many quarks one would not be refunded, based on minimum refund level - const doNotRefund = item.price * item.refundMinimumLevel - + item.priceIncrease * (item.refundMinimumLevel) * (item.refundMinimumLevel - 1) / 2 + const doNotRefund = + item.price * item.refundMinimumLevel + + (item.priceIncrease * + item.refundMinimumLevel * + (item.refundMinimumLevel - 1)) / + 2; // Refunds Quarks based on the shop level and price vals player.worlds.add( - item.price * player.shopUpgrades[key] - + item.priceIncrease * (player.shopUpgrades[key]) * (player.shopUpgrades[key] - 1) / 2 - - doNotRefund, + item.price * player.shopUpgrades[key] + + (item.priceIncrease * + player.shopUpgrades[key] * + (player.shopUpgrades[key] - 1)) / + 2 - + doNotRefund, false - ) + ); - player.shopUpgrades[key] = item.refundMinimumLevel + player.shopUpgrades[key] = item.refundMinimumLevel; } } if (refunds) { - player.worlds.sub(15) + player.worlds.sub(15); } else if (!ignoreBoolean && player.shopConfirmationToggle) { - void Alert('Nothing to Refund!') + void Alert("Nothing to Refund!"); } - player.quarksThisSingularity = singularityQuarks + player.quarksThisSingularity = singularityQuarks; } -} +}; export const getQuarkInvestment = (upgrade: ShopUpgradeNames) => { if (!(upgrade in shopData) || !(upgrade in player.shopUpgrades)) { - return 0 + return 0; } - const val = shopData[upgrade].price * player.shopUpgrades[upgrade] - + shopData[upgrade].priceIncrease * (player.shopUpgrades[upgrade] - 1) * (player.shopUpgrades[upgrade]) / 2 + const val = + shopData[upgrade].price * player.shopUpgrades[upgrade] + + (shopData[upgrade].priceIncrease * + (player.shopUpgrades[upgrade] - 1) * + player.shopUpgrades[upgrade]) / + 2; - return val -} + return val; +}; export const isShopUpgradeUnlocked = (upgrade: ShopUpgradeNames): boolean => { switch (upgrade) { - case 'offeringPotion': - return true - case 'obtainiumPotion': - return true - case 'offeringEX': - return player.reincarnationCount > 0 || player.highestSingularityCount > 0 - case 'offeringAuto': - return player.reincarnationCount > 0 || player.highestSingularityCount > 0 - case 'obtainiumEX': - return player.reincarnationCount > 0 || player.highestSingularityCount > 0 - case 'obtainiumAuto': - return player.reincarnationCount > 0 || player.highestSingularityCount > 0 - case 'instantChallenge': - return player.reincarnationCount > 0 || player.highestSingularityCount > 0 - case 'antSpeed': - return player.highestchallengecompletions[8] > 0 || player.ascensionCount > 0 - || player.highestSingularityCount > 0 - case 'cashGrab': - return player.highestchallengecompletions[8] > 0 || player.ascensionCount > 0 - || player.highestSingularityCount > 0 - case 'shopTalisman': - return player.highestchallengecompletions[9] > 0 || player.ascensionCount > 0 - || player.highestSingularityCount > 0 - case 'seasonPass': - return player.ascensionCount > 0 || player.highestSingularityCount > 0 - case 'challengeExtension': - return player.ascensionCount > 0 || player.highestSingularityCount > 0 - case 'challengeTome': - return player.ascensionCount > 0 || player.highestSingularityCount > 0 - case 'cubeToQuark': - return player.ascensionCount > 0 || player.highestSingularityCount > 0 - case 'tesseractToQuark': - return player.highestchallengecompletions[11] > 0 || player.highestSingularityCount > 0 - case 'hypercubeToQuark': - return player.highestchallengecompletions[13] > 0 || player.highestSingularityCount > 0 - case 'seasonPass2': - return player.highestchallengecompletions[14] > 0 || player.highestSingularityCount > 0 - case 'seasonPass3': - return player.highestchallengecompletions[14] > 0 || player.highestSingularityCount > 0 - case 'chronometer': - return player.highestchallengecompletions[12] > 0 || player.highestSingularityCount > 0 - case 'infiniteAscent': - return player.highestchallengecompletions[14] > 0 || player.highestSingularityCount > 0 - case 'calculator': - return player.ascensionCount > 0 || player.highestSingularityCount > 0 - case 'calculator2': - return player.highestchallengecompletions[11] > 0 || player.highestSingularityCount > 0 - case 'calculator3': - return player.highestchallengecompletions[13] > 0 || player.highestSingularityCount > 0 - case 'calculator4': - return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus) - case 'calculator5': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'calculator6': - return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus) - case 'constantEX': - return player.highestchallengecompletions[14] > 0 || player.highestSingularityCount > 0 - case 'powderEX': - return player.challenge15Exponent >= 1e15 || player.highestSingularityCount > 0 - case 'chronometer2': - return player.challenge15Exponent >= 1e15 || player.highestSingularityCount > 0 - case 'chronometer3': - return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus) - case 'seasonPassY': - return player.challenge15Exponent >= 1e15 || player.highestSingularityCount > 0 - case 'seasonPassZ': - return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus) - case 'challengeTome2': - return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus) - case 'instantChallenge2': - return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus) - case 'cashGrab2': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'cubeToQuarkAll': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'chronometerZ': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'offeringEX2': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'obtainiumEX2': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'powderAuto': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'seasonPassLost': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'challenge15Auto': - return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus) - case 'extraWarp': - return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus) - case 'autoWarp': - return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus) - case 'improveQuarkHept': - return player.challenge15Exponent >= 1e15 || player.highestSingularityCount > 0 - case 'improveQuarkHept2': - return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus) - case 'improveQuarkHept3': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'improveQuarkHept4': - return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus) - case 'shopImprovedDaily': - return player.highestchallengecompletions[14] > 0 || player.highestSingularityCount > 0 - case 'shopImprovedDaily2': - return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus) - case 'shopImprovedDaily3': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'shopImprovedDaily4': - return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus) - case 'offeringEX3': - return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus) - case 'obtainiumEX3': - return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus) - case 'improveQuarkHept5': - return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus) - case 'chronometerInfinity': - return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus) - case 'seasonPassInfinity': - return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus) - case 'shopSingularityPenaltyDebuff': - return Boolean(player.singularityChallenges.noSingularityUpgrades.rewards.shopUpgrade) - case 'shopAmbrosiaGeneration1': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'shopAmbrosiaGeneration2': - return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus) - case 'shopAmbrosiaGeneration3': - return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus) - case 'shopAmbrosiaGeneration4': - return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus) - case 'shopAmbrosiaLuck1': - return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus) - case 'shopAmbrosiaLuck2': - return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus) - case 'shopAmbrosiaLuck3': - return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus) - case 'shopAmbrosiaLuck4': - return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus) + case "offeringPotion": + return true; + case "obtainiumPotion": + return true; + case "offeringEX": + return ( + player.reincarnationCount > 0 || player.highestSingularityCount > 0 + ); + case "offeringAuto": + return ( + player.reincarnationCount > 0 || player.highestSingularityCount > 0 + ); + case "obtainiumEX": + return ( + player.reincarnationCount > 0 || player.highestSingularityCount > 0 + ); + case "obtainiumAuto": + return ( + player.reincarnationCount > 0 || player.highestSingularityCount > 0 + ); + case "instantChallenge": + return ( + player.reincarnationCount > 0 || player.highestSingularityCount > 0 + ); + case "antSpeed": + return ( + player.highestchallengecompletions[8] > 0 || + player.ascensionCount > 0 || + player.highestSingularityCount > 0 + ); + case "cashGrab": + return ( + player.highestchallengecompletions[8] > 0 || + player.ascensionCount > 0 || + player.highestSingularityCount > 0 + ); + case "shopTalisman": + return ( + player.highestchallengecompletions[9] > 0 || + player.ascensionCount > 0 || + player.highestSingularityCount > 0 + ); + case "seasonPass": + return player.ascensionCount > 0 || player.highestSingularityCount > 0; + case "challengeExtension": + return player.ascensionCount > 0 || player.highestSingularityCount > 0; + case "challengeTome": + return player.ascensionCount > 0 || player.highestSingularityCount > 0; + case "cubeToQuark": + return player.ascensionCount > 0 || player.highestSingularityCount > 0; + case "tesseractToQuark": + return ( + player.highestchallengecompletions[11] > 0 || + player.highestSingularityCount > 0 + ); + case "hypercubeToQuark": + return ( + player.highestchallengecompletions[13] > 0 || + player.highestSingularityCount > 0 + ); + case "seasonPass2": + return ( + player.highestchallengecompletions[14] > 0 || + player.highestSingularityCount > 0 + ); + case "seasonPass3": + return ( + player.highestchallengecompletions[14] > 0 || + player.highestSingularityCount > 0 + ); + case "chronometer": + return ( + player.highestchallengecompletions[12] > 0 || + player.highestSingularityCount > 0 + ); + case "infiniteAscent": + return ( + player.highestchallengecompletions[14] > 0 || + player.highestSingularityCount > 0 + ); + case "calculator": + return player.ascensionCount > 0 || player.highestSingularityCount > 0; + case "calculator2": + return ( + player.highestchallengecompletions[11] > 0 || + player.highestSingularityCount > 0 + ); + case "calculator3": + return ( + player.highestchallengecompletions[13] > 0 || + player.highestSingularityCount > 0 + ); + case "calculator4": + return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus); + case "calculator5": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "calculator6": + return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus); + case "calculator7": + return Boolean( + player.singularityChallenges.limitedAscensions.rewards.shopUpgrade + ); + case "constantEX": + return ( + player.highestchallengecompletions[14] > 0 || + player.highestSingularityCount > 0 + ); + case "powderEX": + return ( + player.challenge15Exponent >= 1e15 || player.highestSingularityCount > 0 + ); + case "chronometer2": + return ( + player.challenge15Exponent >= 1e15 || player.highestSingularityCount > 0 + ); + case "chronometer3": + return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus); + case "seasonPassY": + return ( + player.challenge15Exponent >= 1e15 || player.highestSingularityCount > 0 + ); + case "seasonPassZ": + return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus); + case "challengeTome2": + return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus); + case "instantChallenge2": + return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus); + case "cashGrab2": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "cubeToQuarkAll": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "chronometerZ": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "offeringEX2": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "obtainiumEX2": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "powderAuto": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "seasonPassLost": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "challenge15Auto": + return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus); + case "extraWarp": + return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus); + case "autoWarp": + return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus); + case "improveQuarkHept": + return ( + player.challenge15Exponent >= 1e15 || player.highestSingularityCount > 0 + ); + case "improveQuarkHept2": + return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus); + case "improveQuarkHept3": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "improveQuarkHept4": + return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus); + case "shopImprovedDaily": + return ( + player.highestchallengecompletions[14] > 0 || + player.highestSingularityCount > 0 + ); + case "shopImprovedDaily2": + return Boolean(player.singularityUpgrades.wowPass.getEffect().bonus); + case "shopImprovedDaily3": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "shopImprovedDaily4": + return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus); + case "offeringEX3": + return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus); + case "obtainiumEX3": + return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus); + case "improveQuarkHept5": + return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus); + case "chronometerInfinity": + return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus); + case "seasonPassInfinity": + return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus); + case "shopSingularityPenaltyDebuff": + return Boolean( + player.singularityChallenges.noSingularityUpgrades.rewards.shopUpgrade + ); + case "shopAmbrosiaLuckMultiplier4": + return Boolean( + player.singularityChallenges.oneChallengeCap.rewards.shopUpgrade + ); + case "shopOcteractAmbrosiaLuck": + return Boolean( + player.singularityChallenges.noOcteracts.rewards.shopUpgrade + ); + case "shopAmbrosiaGeneration1": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "shopAmbrosiaGeneration2": + return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus); + case "shopAmbrosiaGeneration3": + return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus); + case "shopAmbrosiaGeneration4": + return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus); + case "shopAmbrosiaLuck1": + return Boolean(player.singularityUpgrades.wowPass2.getEffect().bonus); + case "shopAmbrosiaLuck2": + return Boolean(player.singularityUpgrades.wowPass3.getEffect().bonus); + case "shopAmbrosiaLuck3": + return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus); + case "shopAmbrosiaLuck4": + return Boolean(player.singularityUpgrades.wowPass4.getEffect().bonus); } -} +}; diff --git a/src/SingularityChallenges.ts b/src/SingularityChallenges.ts index 1d1f31de5..c8eb1ba8e 100644 --- a/src/SingularityChallenges.ts +++ b/src/SingularityChallenges.ts @@ -1,159 +1,189 @@ -import i18next from 'i18next' -import { DOMCacheGetOrSet } from './Cache/DOM' -import { calculateGoldenQuarkGain } from './Calculate' -import { singularity } from './Reset' -import { player } from './Synergism' -import type { Player } from './types/Synergism' -import { Alert, Confirm } from './UpdateHTML' -import { toOrdinal } from './Utility' +import i18next from "i18next"; +import { DOMCacheGetOrSet } from "./Cache/DOM"; +import { calculateGoldenQuarkGain } from "./Calculate"; +import { singularity } from "./Reset"; +import { player } from "./Synergism"; +import type { Player } from "./types/Synergism"; +import { Alert, Confirm } from "./UpdateHTML"; +import { toOrdinal } from "./Utility"; export interface ISingularityChallengeData { - baseReq: number - maxCompletions: number - unlockSingularity: number - HTMLTag: string - singularityRequirement: (baseReq: number, completions: number) => number - effect: (n: number) => Record - completions?: number - enabled?: boolean - highestSingularityCompleted?: number + baseReq: number; + maxCompletions: number; + unlockSingularity: number; + HTMLTag: string; + singularityRequirement: (baseReq: number, completions: number) => number; + effect: (n: number) => Record; + completions?: number; + enabled?: boolean; + highestSingularityCompleted?: number; + cacheUpdates?: (() => void)[]; } export class SingularityChallenge { - public name - public description - public rewardDescription - public baseReq - public completions - public maxCompletions - public unlockSingularity - public HTMLTag - public highestSingularityCompleted - public enabled - public singularityRequirement - public effect - public constructor (data: ISingularityChallengeData, key: string) { - const name = i18next.t(`singularityChallenge.data.${key}.name`) - const description = i18next.t(`singularityChallenge.data.${key}.description`) - const rewardDescription = i18next.t(`singularityChallenge.data.${key}.rewardDescription`) - this.name = name - this.description = description - this.rewardDescription = rewardDescription - this.baseReq = data.baseReq - this.completions = data.completions ?? 0 - this.maxCompletions = data.maxCompletions - this.unlockSingularity = data.unlockSingularity - this.HTMLTag = data.HTMLTag - this.highestSingularityCompleted = data.highestSingularityCompleted ?? 0 - this.enabled = data.enabled ?? false - this.singularityRequirement = data.singularityRequirement - this.effect = data.effect + public name; + public description; + public rewardDescription; + public baseReq; + public completions; + public maxCompletions; + public unlockSingularity; + public HTMLTag; + public highestSingularityCompleted; + public enabled; + public singularityRequirement; + public effect; + readonly cacheUpdates: (() => void)[] | undefined; - this.updateIconHTML() - this.updateChallengeCompletions() + public constructor(data: ISingularityChallengeData, key: string) { + const name = i18next.t(`singularityChallenge.data.${key}.name`); + const description = i18next.t( + `singularityChallenge.data.${key}.description` + ); + const rewardDescription = i18next.t( + `singularityChallenge.data.${key}.rewardDescription` + ); + this.name = name; + this.description = description; + this.rewardDescription = rewardDescription; + this.baseReq = data.baseReq; + this.completions = data.completions ?? 0; + this.maxCompletions = data.maxCompletions; + this.unlockSingularity = data.unlockSingularity; + this.HTMLTag = data.HTMLTag; + this.highestSingularityCompleted = data.highestSingularityCompleted ?? 0; + this.enabled = data.enabled ?? false; + this.singularityRequirement = data.singularityRequirement; + this.effect = data.effect; + + this.updateIconHTML(); + this.updateChallengeCompletions(); + this.cacheUpdates = data.cacheUpdates ?? undefined; } - public computeSingularityRquirement () { - return this.singularityRequirement(this.baseReq, this.completions) + public computeSingularityRquirement() { + return this.singularityRequirement(this.baseReq, this.completions); } - public updateChallengeCompletions () { - let updateVal = 0 - while (this.singularityRequirement(this.baseReq, updateVal) <= this.highestSingularityCompleted) { - updateVal += 1 + public updateChallengeCompletions() { + let updateVal = 0; + while ( + this.singularityRequirement(this.baseReq, updateVal) <= + this.highestSingularityCompleted + ) { + updateVal += 1; } - this.completions = Math.min(this.maxCompletions, updateVal) + this.completions = Math.min(this.maxCompletions, updateVal); } - public challengeEntryHandler () { + public challengeEntryHandler() { if (!this.enabled) { - return this.enableChallenge() + return this.enableChallenge(); } else { - return this.exitChallenge(player.runelevels[6] > 0) + return this.exitChallenge(player.runelevels[6] > 0); } } - public async enableChallenge () { + public async enableChallenge() { if (player.highestSingularityCount < this.unlockSingularity) { - return Alert(i18next.t('singularityChallenge.enterChallenge.lowSingularity')) + return Alert( + i18next.t("singularityChallenge.enterChallenge.lowSingularity") + ); } - const confirmation = - await (Confirm(i18next.t('singularityChallenge.enterChallenge.confirmation', { name: this.name }))) + const confirmation = await Confirm( + i18next.t("singularityChallenge.enterChallenge.confirmation", { + name: this.name, + }) + ); if (!confirmation) { - return Alert(i18next.t('singularityChallenge.enterChallenge.decline')) + return Alert(i18next.t("singularityChallenge.enterChallenge.decline")); } if (!player.insideSingularityChallenge) { - const setSingularity = this.computeSingularityRquirement() - const holdSingTimer = player.singularityCounter - const holdQuarkExport = player.quarkstimer - const holdGoldenQuarkExport = player.goldenQuarksTimer - const goldenQuarkGain = calculateGoldenQuarkGain() - const currentGQ = player.goldenQuarks - this.enabled = true - player.insideSingularityChallenge = true - await singularity(setSingularity) - player.singularityCounter = holdSingTimer - player.goldenQuarks = currentGQ + goldenQuarkGain - player.quarkstimer = holdQuarkExport - player.goldenQuarksTimer = holdGoldenQuarkExport + const setSingularity = this.computeSingularityRquirement(); + const holdSingTimer = player.singularityCounter; + const holdQuarkExport = player.quarkstimer; + const holdGoldenQuarkExport = player.goldenQuarksTimer; + const goldenQuarkGain = calculateGoldenQuarkGain(); + const currentGQ = player.goldenQuarks; + this.enabled = true; + player.insideSingularityChallenge = true; + await singularity(setSingularity); + player.singularityCounter = holdSingTimer; + player.goldenQuarks = currentGQ + goldenQuarkGain; + player.quarkstimer = holdQuarkExport; + player.goldenQuarksTimer = holdGoldenQuarkExport; - this.updateChallengeHTML() + this.updateChallengeHTML(); return Alert( - i18next.t('singularityChallenge.enterChallenge.acceptSuccess', { + i18next.t("singularityChallenge.enterChallenge.acceptSuccess", { name: this.name, tier: this.completions + 1, - singReq: this.computeSingularityRquirement() + singReq: this.computeSingularityRquirement(), }) - ) + ); } else { - return Alert(i18next.t('singularityChallenge.exitChallenge.acceptFailure')) + return Alert( + i18next.t("singularityChallenge.exitChallenge.acceptFailure") + ); } } - public async exitChallenge (success: boolean) { + public async exitChallenge(success: boolean) { if (!success) { - const extra = (player.runelevels[6] === 0) - ? i18next.t('singularityChallenge.exitChallenge.incompleteWarning') - : '' - const confirmation = await (Confirm( - i18next.t('singularityChallenge.exitChallenge.confirmation', { + const extra = + player.runelevels[6] === 0 + ? i18next.t("singularityChallenge.exitChallenge.incompleteWarning") + : ""; + const confirmation = await Confirm( + i18next.t("singularityChallenge.exitChallenge.confirmation", { name: this.name, tier: this.completions + 1, - warning: extra + warning: extra, }) - )) + ); if (!confirmation) { - return Alert(i18next.t('singularityChallenge.exitChallenge.decline')) + return Alert(i18next.t("singularityChallenge.exitChallenge.decline")); } } - this.enabled = false - player.insideSingularityChallenge = false - const highestSingularityHold = player.highestSingularityCount - const holdSingTimer = player.singularityCounter - const holdQuarkExport = player.quarkstimer - const holdGoldenQuarkExport = player.goldenQuarksTimer - this.updateIconHTML() + this.enabled = false; + player.insideSingularityChallenge = false; + const highestSingularityHold = player.highestSingularityCount; + const holdSingTimer = player.singularityCounter; + const holdQuarkExport = player.quarkstimer; + const holdGoldenQuarkExport = player.goldenQuarksTimer; + this.updateIconHTML(); if (success) { - this.highestSingularityCompleted = player.singularityCount - this.updateChallengeCompletions() - await singularity(highestSingularityHold) - player.singularityCounter = holdSingTimer + this.highestSingularityCompleted = player.singularityCount; + this.updateChallengeCompletions(); + await singularity(highestSingularityHold); + player.singularityCounter = holdSingTimer; + this.updateCaches(); return Alert( - i18next.t('singularityChallenge.exitChallenge.acceptSuccess', { + i18next.t("singularityChallenge.exitChallenge.acceptSuccess", { tier: toOrdinal(this.completions), - name: this.name + name: this.name, }) - ) + ); } else { - await singularity(highestSingularityHold) - player.singularityCounter = holdSingTimer - player.quarkstimer = holdQuarkExport - player.goldenQuarksTimer = holdGoldenQuarkExport - return Alert(i18next.t('singularityChallenge.exitChallenge.acceptFailure')) + await singularity(highestSingularityHold); + player.singularityCounter = holdSingTimer; + player.quarkstimer = holdQuarkExport; + player.goldenQuarksTimer = holdGoldenQuarkExport; + return Alert( + i18next.t("singularityChallenge.exitChallenge.acceptFailure") + ); + } + } + + updateCaches(): void { + if (this.cacheUpdates !== undefined) { + for (const cache of this.cacheUpdates) { + cache(); + } } } @@ -161,108 +191,128 @@ export class SingularityChallenge { * Given a Singularity Challenge, give a concise information regarding its data. * @returns A string that details the name, description, metadata. */ - toString (): string { - const color = (this.completions === this.maxCompletions) ? 'var(--orchid-text-color)' : 'white' - const enabled = (this.enabled) - ? `${i18next.t('general.enabled')}` - : '' + toString(): string { + const color = + this.completions === this.maxCompletions + ? "var(--orchid-text-color)" + : "white"; + const enabled = this.enabled + ? `${i18next.t( + "general.enabled" + )}` + : ""; return `${this.name} ${enabled} ${this.description} - ${ - i18next.t('singularityChallenge.toString.canEnter', { - unlockSing: this.unlockSingularity, - highestSing: player.highestSingularityCount - }) + ${i18next.t( + "singularityChallenge.toString.canEnter", + { + unlockSing: this.unlockSingularity, + highestSing: player.highestSingularityCount, + } + )} + ${i18next.t( + "singularityChallenge.toString.tiersCompleted" + )}: ${this.completions}/${ + this.maxCompletions } - ${ - i18next.t('singularityChallenge.toString.tiersCompleted') - }: ${this.completions}/${this.maxCompletions} - ${ - i18next.t('singularityChallenge.toString.currentTierSingularity') - } ${ - this.singularityRequirement(this.baseReq, this.completions) - } - ${this.rewardDescription}` + ${i18next.t( + "singularityChallenge.toString.currentTierSingularity" + )} ${this.singularityRequirement( + this.baseReq, + this.completions + )} + ${this.rewardDescription}`; } - public updateChallengeHTML (): void { - DOMCacheGetOrSet('singularityChallengesMultiline').innerHTML = this.toString() + public updateChallengeHTML(): void { + DOMCacheGetOrSet("singularityChallengesMultiline").innerHTML = + this.toString(); } - public updateIconHTML (): void { - const color = (this.enabled) ? 'orchid' : '' - DOMCacheGetOrSet(`${this.HTMLTag}`).style.backgroundColor = color + public updateIconHTML(): void { + const color = this.enabled ? "orchid" : ""; + DOMCacheGetOrSet(`${this.HTMLTag}`).style.backgroundColor = color; } - public get rewards () { - return this.effect(this.completions) + public get rewards() { + return this.effect(this.completions); } } -export const singularityChallengeData: Record = { +export const singularityChallengeData: Record< + keyof Player["singularityUpgrades"], + ISingularityChallengeData +> = { noSingularityUpgrades: { baseReq: 1, maxCompletions: 30, unlockSingularity: 25, - HTMLTag: 'noSingularityUpgrades', + HTMLTag: "noSingularityUpgrades", singularityRequirement: (baseReq: number, completions: number) => { - return baseReq + 8 * completions + return baseReq + 8 * completions; }, effect: (n: number) => { return { cubes: 1 + 0.5 * n, goldenQuarks: 1 + 0.12 * +(n > 0), blueberries: +(n > 0), - shopUpgrade: (n >= 20) - } - } + shopUpgrade: n >= 20, + luckBonus: n >= 30 ? 0.04 : 0, + }; + }, + cacheUpdates: [ + () => player.caches.blueberryInventory.updateVal("Exalt1"), + () => player.caches.ambrosiaLuckAdditiveMult.updateVal("Exalt1"), + ], }, oneChallengeCap: { baseReq: 10, maxCompletions: 25, unlockSingularity: 40, - HTMLTag: 'oneChallengeCap', + HTMLTag: "oneChallengeCap", singularityRequirement: (baseReq: number, completions: number) => { - return baseReq + 11 * completions + return baseReq + 11 * completions; }, effect: (n: number) => { return { corrScoreIncrease: 0.03 * n, capIncrease: 3 * +(n > 0), - freeCorruptionLevel: (n >= 20) - } - } + freeCorruptionLevel: n >= 20, + shopUpgrade: n >= 20, + }; + }, }, noOcteracts: { baseReq: 75, maxCompletions: 10, unlockSingularity: 100, - HTMLTag: 'noOcteracts', + HTMLTag: "noOcteracts", singularityRequirement: (baseReq: number, completions: number) => { - return baseReq + 13 * completions + return baseReq + 13 * completions; }, effect: (n: number) => { return { octeractPow: 0.02 * n, - offeringBonus: (n > 0), - obtainiumBonus: (n === 10) - } - } + offeringBonus: n > 0, + obtainiumBonus: n >= 10, + shopUpgrade: n >= 10, + }; + }, }, limitedAscensions: { baseReq: 10, maxCompletions: 25, unlockSingularity: 50, - HTMLTag: 'limitedAscensions', + HTMLTag: "limitedAscensions", singularityRequirement: (baseReq: number, completions: number) => { - return baseReq + 10 * completions + return baseReq + 10 * completions; }, effect: (n: number) => { return { - ascensionSpeedMult: 0.1 * n / 100, - hepteractCap: (n > 0), - calculatorUnlock: (n >= 25) - } - } - } -} + ascensionSpeedMult: (0.1 * n) / 100, + hepteractCap: n > 0, + shopUpgrade: n >= 25, + }; + }, + }, +}; diff --git a/src/StatCache.ts b/src/StatCache.ts index 6007c03cf..7e270383e 100644 --- a/src/StatCache.ts +++ b/src/StatCache.ts @@ -3,52 +3,53 @@ import { calculateAmbrosiaGenerationSingularityUpgrade, calculateAmbrosiaLuckOcteractUpgrade, calculateAmbrosiaLuckSingularityUpgrade, + calculateDilatedFiveLeafBonus, calculateEventBuff, - calculateSingularityMilestoneBlueberries -} from './Calculate' + calculateSingularityMilestoneBlueberries, +} from "./Calculate"; import { calculateAmbrosiaGenerationShopUpgrade, calculateAmbrosiaLuckShopUpgrade, - calculateSingularityAmbrosiaLuckMilestoneBonus -} from './Calculate' -import { BuffType } from './Event' -import { player } from './Synergism' -import { productContents } from './Utility' -import { Globals } from './Variables' + calculateSingularityAmbrosiaLuckMilestoneBonus, +} from "./Calculate"; +import { BuffType } from "./Event"; +import { player } from "./Synergism"; +import { productContents } from "./Utility"; +import { Globals } from "./Variables"; interface StatCache { - totalVal: number + totalVal: number; /** * Updates the cache value for a statistic * @param key: Statistic which we must update for value */ - updateVal(key: T, init: boolean): void + updateVal(key: T, init: boolean): void; /** * Initializes the cache by establishing statistics for each value as well as * updating the total statistic. */ - initialize(): void + initialize(): void; } abstract class AdditionCache implements StatCache { - public totalVal = 0 - abstract vals: Record + public totalVal = 0; + abstract vals: Record; /** * Updates a particular statistic 'key' and updates total accordingly * @param key The statistic to update */ - abstract updateVal (key: T, init: boolean): void + abstract updateVal(key: T, init: boolean): void; /** * Initialize all statistics of interest and compute a total value as sum of all statistics */ - initialize (): void { - this.totalVal = 0 - for (const val of (Object.keys(this.vals) as T[])) { - this.updateVal(val, true) + initialize(): void { + this.totalVal = 0; + for (const val of Object.keys(this.vals) as T[]) { + this.updateVal(val, true); } } @@ -57,11 +58,11 @@ abstract class AdditionCache implements StatCache { * @param oldVal: Value present in values[key] before update * @param newVal: Value present in values[key] after update */ - updateTotal (oldVal: number, newVal: number, init = false): void { + updateTotal(oldVal: number, newVal: number, init = false): void { if (init) { - this.totalVal += newVal + this.totalVal += newVal; } else { - this.totalVal += newVal - oldVal + this.totalVal += newVal - oldVal; } } @@ -69,46 +70,46 @@ abstract class AdditionCache implements StatCache { * Flattens the value object into an array, for use in statistics. * @returns Array consisting of all additive values as well as sum of elements */ - flatten (): number[] { - const arr: number[] = Object.values(this.vals) - arr.push(this.totalVal) - return arr + flatten(): number[] { + const arr: number[] = Object.values(this.vals); + arr.push(this.totalVal); + return arr; } } abstract class MultiplicationCache implements StatCache { - public totalVal = 1 - abstract vals: Record + public totalVal = 1; + abstract vals: Record; /** * Updates a particular statistic 'key' and updates total accordingly * @param key The statistic to update */ - abstract updateVal (key: T, init: boolean): void + abstract updateVal(key: T, init: boolean): void; /** * Initialize all statistics of interest and compute a total value as product of all statistics */ - initialize (): void { - this.totalVal = 1 - for (const val of (Object.keys(this.vals) as T[])) { - this.updateVal(val, true) + initialize(): void { + this.totalVal = 1; + for (const val of Object.keys(this.vals) as T[]) { + this.updateVal(val, true); } } - updateTotal (oldVal: number, newVal: number, init = false): void { + updateTotal(oldVal: number, newVal: number, init = false): void { if (init) { - this.totalVal *= newVal + this.totalVal *= newVal; } else { // Optimization: if neither old total or new val is 0 then we can safely just compute factor - if (this.totalVal !== 0 && newVal !== 0) this.totalVal *= newVal / oldVal + if (this.totalVal !== 0 && newVal !== 0) this.totalVal *= newVal / oldVal; // Optimization: if newVal is 0 we don't have to care about computing - else if (newVal === 0) this.totalVal = 0 + else if (newVal === 0) this.totalVal = 0; // Else: Brute force compute total val (TODO: Optimize) else { - const arr = this.flatten() + const arr = this.flatten(); // remove last elm - arr.pop() - this.totalVal = productContents(arr) + arr.pop(); + this.totalVal = productContents(arr); } } } @@ -117,10 +118,10 @@ abstract class MultiplicationCache implements StatCache { * Flattens the value object into an array, for use in statistics. * @returns Array consisting of all additive values as well as sum of elements */ - flatten (): number[] { - const arr: number[] = Object.values(this.vals) - arr.push(this.totalVal) - return arr + flatten(): number[] { + const arr: number[] = Object.values(this.vals); + arr.push(this.totalVal); + return arr; } } @@ -129,33 +130,85 @@ abstract class MultiplicationCache implements StatCache { */ type AmbrosialLuck = - | 'SingPerks' - | 'OcteractBerries' - | 'ShopUpgrades' - | 'BlueberryUpgrade1' - | 'Event' - | 'BlueberryCubeLuck1' - | 'BlueberryQuarkLuck1' - | 'SingularityBerries' - | 'BlueberryUpgrade2' + | "SingPerks" + | "OcteractBerries" + | "ShopUpgrades" + | "BlueberryUpgrade1" + | "Event" + | "BlueberryCubeLuck1" + | "BlueberryQuarkLuck1" + | "SingularityBerries" + | "BlueberryUpgrade2" + | "ShopOcteractAmbrosiaLuck" + | "TwoHundredSixtyNine"; type AmbrosiaGeneration = - | 'DefaultVal' - | 'Blueberries' - | 'SingularityBerries' - | 'ShopUpgrades' - | 'Event' - | 'OcteractBerries' - | 'BlueberryPatreon' + | "DefaultVal" + | "Blueberries" + | "SingularityBerries" + | "ShopUpgrades" + | "Event" + | "OcteractBerries" + | "BlueberryPatreon"; -type BlueberryInventory = 'Exalt1' | 'SingularityUpgrade' | 'SingularityPerk' +type BlueberryInventory = "Exalt1" | "SingularityUpgrade" | "SingularityPerk"; + +type AmbrosiaLuckAdditiveMult = + | "Base" + | "Exalt1" + | "SingularityPerk" + | "ShopUpgrades"; + +export class AmbrosiaLuckAdditiveMultCache extends AdditionCache { + vals: Record; + public totalVal: number; + + constructor() { + super(); + this.vals = { + Base: 1, + Exalt1: 0, + SingularityPerk: 0, + ShopUpgrades: 0, + }; + this.totalVal = 1; + } + + updateVal(key: AmbrosiaLuckAdditiveMult, init = false): void { + const oldVal = this.vals[key]; + switch (key) { + case "Base": { + this.vals[key] = 1; + break; + } + case "Exalt1": { + this.vals[key] = + +player.singularityChallenges.noSingularityUpgrades.rewards.luckBonus; + break; + } + case "SingularityPerk": { + this.vals[key] = calculateDilatedFiveLeafBonus(); + break; + } + case "ShopUpgrades": { + this.vals[key] = player.shopUpgrades.shopAmbrosiaLuckMultiplier4 / 100; + break; + } + } + const newVal = this.vals[key]; + this.updateTotal(oldVal, newVal, init); + console.log(this.totalVal); + player.caches.ambrosiaLuck.updateVal("Event"); // Dependant cache, though maybe need a better system than calling Event + } +} export class AmbrosiaLuckCache extends AdditionCache { - vals: Record - public totalVal: number + vals: Record; + public totalVal: number; + public usedTotal: number; - constructor () { - super() + constructor() { + super(); this.vals = { SingPerks: 0, ShopUpgrades: 0, @@ -165,62 +218,84 @@ export class AmbrosiaLuckCache extends AdditionCache { BlueberryUpgrade2: 0, BlueberryCubeLuck1: 0, BlueberryQuarkLuck1: 0, - Event: 0 - } - this.totalVal = 0 + TwoHundredSixtyNine: 0, + ShopOcteractAmbrosiaLuck: 0, + Event: 0, + }; + this.totalVal = 0; + this.usedTotal = 0; } - updateVal (key: AmbrosialLuck, init = false): void { - const oldVal = this.vals[key] + updateVal(key: AmbrosialLuck, init = false): void { + const oldVal = this.vals[key]; switch (key) { - case 'SingPerks': { - this.vals[key] = calculateSingularityAmbrosiaLuckMilestoneBonus() - break + case "SingPerks": { + this.vals[key] = calculateSingularityAmbrosiaLuckMilestoneBonus(); + break; } - case 'ShopUpgrades': { - this.vals[key] = calculateAmbrosiaLuckShopUpgrade() - break + case "ShopUpgrades": { + this.vals[key] = calculateAmbrosiaLuckShopUpgrade(); + break; } - case 'SingularityBerries': { - this.vals[key] = calculateAmbrosiaLuckSingularityUpgrade() - break + case "SingularityBerries": { + this.vals[key] = calculateAmbrosiaLuckSingularityUpgrade(); + break; } - case 'OcteractBerries': { - this.vals[key] = calculateAmbrosiaLuckOcteractUpgrade() - break + case "OcteractBerries": { + this.vals[key] = calculateAmbrosiaLuckOcteractUpgrade(); + break; } - case 'BlueberryUpgrade1': { - this.vals[key] = +player.blueberryUpgrades.ambrosiaLuck1.bonus.ambrosiaLuck - break + case "BlueberryUpgrade1": { + this.vals[key] = + +player.blueberryUpgrades.ambrosiaLuck1.bonus.ambrosiaLuck; + break; } - case 'BlueberryUpgrade2': { - this.vals[key] = +player.blueberryUpgrades.ambrosiaLuck2.bonus.ambrosiaLuck - break + case "BlueberryUpgrade2": { + this.vals[key] = + +player.blueberryUpgrades.ambrosiaLuck2.bonus.ambrosiaLuck; + break; } - case 'BlueberryCubeLuck1': { - this.vals[key] = +player.blueberryUpgrades.ambrosiaCubeLuck1.bonus.ambrosiaLuck - break + case "BlueberryCubeLuck1": { + this.vals[key] = + +player.blueberryUpgrades.ambrosiaCubeLuck1.bonus.ambrosiaLuck; + break; } - case 'BlueberryQuarkLuck1': { - this.vals[key] = +player.blueberryUpgrades.ambrosiaQuarkLuck1.bonus.ambrosiaLuck - break + case "BlueberryQuarkLuck1": { + this.vals[key] = + +player.blueberryUpgrades.ambrosiaQuarkLuck1.bonus.ambrosiaLuck; + break; } - case 'Event': { - this.vals[key] = (Globals.isEvent) ? 100 * calculateEventBuff(BuffType.AmbrosiaLuck) : 0 - break + case "TwoHundredSixtyNine": { + this.vals[key] = player.highestSingularityCount >= 269 ? 269 : 0; + break; + } + case "ShopOcteractAmbrosiaLuck": { + this.vals[key] = + player.shopUpgrades.shopOcteractAmbrosiaLuck * + (1 + Math.floor(Math.log10(player.totalWowOcteracts + 1))); + break; + } + case "Event": { + this.vals[key] = Globals.isEvent + ? 100 * calculateEventBuff(BuffType.AmbrosiaLuck) + : 0; + break; } } - const newVal = this.vals[key] - this.updateTotal(oldVal, newVal, init) + const newVal = this.vals[key]; + this.updateTotal(oldVal, newVal, init); + this.usedTotal = Math.floor( + this.totalVal * player.caches.ambrosiaLuckAdditiveMult.totalVal + ); } } export class AmbrosiaGenerationCache extends MultiplicationCache { - vals: Record - public totalVal: number + vals: Record; + public totalVal: number; - constructor () { - super() + constructor() { + super(); this.vals = { DefaultVal: 1, Blueberries: 1, @@ -228,87 +303,94 @@ export class AmbrosiaGenerationCache extends MultiplicationCache { - vals: Record - public totalVal: number + vals: Record; + public totalVal: number; - constructor () { - super() + constructor() { + super(); this.vals = { Exalt1: 0, SingularityUpgrade: 0, - SingularityPerk: 0 - } - this.totalVal = 0 + SingularityPerk: 0, + }; + this.totalVal = 0; } - updateVal (key: BlueberryInventory, init = false): void { - const oldVal = this.vals[key] + updateVal(key: BlueberryInventory, init = false): void { + const oldVal = this.vals[key]; switch (key) { - case 'Exalt1': { - this.vals[key] = +(player.singularityChallenges.noSingularityUpgrades.completions > 0) - break + case "Exalt1": { + this.vals[key] = +( + player.singularityChallenges.noSingularityUpgrades.completions > 0 + ); + break; } - case 'SingularityUpgrade': { - this.vals[key] = +(player.singularityUpgrades.blueberries.getEffect().bonus) - break + case "SingularityUpgrade": { + this.vals[key] = + +player.singularityUpgrades.blueberries.getEffect().bonus; + break; } - case 'SingularityPerk': { - this.vals[key] = calculateSingularityMilestoneBlueberries() - break + case "SingularityPerk": { + this.vals[key] = calculateSingularityMilestoneBlueberries(); + break; } } - const newVal = this.vals[key] - this.updateTotal(oldVal, newVal, init) - player.caches.ambrosiaGeneration.updateVal('Blueberries') // Dependant cache + const newVal = this.vals[key]; + this.updateTotal(oldVal, newVal, init); + player.caches.ambrosiaGeneration.updateVal("Blueberries"); // Dependant cache } } export const cacheReinitialize = () => { // TODO: Create a hierarchy of cache dependencies (ambrosia generation depends on blueberry inventory) - player.caches.blueberryInventory.initialize() - player.caches.ambrosiaGeneration.initialize() - player.caches.ambrosiaLuck.initialize() -} + player.caches.ambrosiaLuckAdditiveMult.initialize(); + player.caches.blueberryInventory.initialize(); + player.caches.ambrosiaGeneration.initialize(); + player.caches.ambrosiaLuck.initialize(); +}; diff --git a/src/Statistics.ts b/src/Statistics.ts index 87399a742..767f0cc8f 100644 --- a/src/Statistics.ts +++ b/src/Statistics.ts @@ -1093,7 +1093,9 @@ export const loadStatisticsAmbrosiaLuck = () => { 6: { acc: 1, desc: "Ambrosia Luck Module II" }, 7: { acc: 2, desc: "Ambrosia Cube-Luck Hybrid Module I" }, 8: { acc: 2, desc: "Ambrosia Quark-Luck Hybrid Module I" }, - 9: { acc: 1, desc: "Event Bonus" }, + 9: { acc: 0, desc: "Perk: Two Hundred Sixty Nine!" }, + 10: { acc: 0, desc: "Shop: Octeract-Based Ambrosia Luck" }, + 11: { acc: 1, desc: "Event Bonus" }, }; for (let i = 0; i < arr.length - 1; i++) { const statALuckMi = DOMCacheGetOrSet(`statALuckM${i + 1}`); @@ -1105,7 +1107,15 @@ export const loadStatisticsAmbrosiaLuck = () => { )}`; } - const totalVal = arr[arr.length - 1]; + DOMCacheGetOrSet("sALuckMult").textContent = `x${format( + player.caches.ambrosiaLuckAdditiveMult.totalVal, + 2, + true + )}`; + + const totalVal = Math.floor( + arr[arr.length - 1] * player.caches.ambrosiaLuckAdditiveMult.totalVal + ); DOMCacheGetOrSet("sALuckMT").innerHTML = `☘ ${format(totalVal, 0)}`; }; diff --git a/src/Synergism.ts b/src/Synergism.ts index 840bacbd5..ba7603d05 100644 --- a/src/Synergism.ts +++ b/src/Synergism.ts @@ -196,6 +196,7 @@ import { } from "./SingularityChallenges"; import { AmbrosiaGenerationCache, + AmbrosiaLuckAdditiveMultCache, AmbrosiaLuckCache, BlueberryInventoryCache, cacheReinitialize, @@ -599,6 +600,7 @@ export const player: Player = { calculator4: 0, calculator5: 0, calculator6: 0, + calculator7: 0, constantEX: 0, powderEX: 0, chronometer2: 0, @@ -631,6 +633,8 @@ export const player: Player = { seasonPassInfinity: 0, chronometerInfinity: 0, shopSingularityPenaltyDebuff: 0, + shopAmbrosiaLuckMultiplier4: 0, + shopOcteractAmbrosiaLuck: 0, shopAmbrosiaGeneration1: 0, shopAmbrosiaGeneration2: 0, shopAmbrosiaGeneration3: 0, @@ -1484,6 +1488,7 @@ export const player: Player = { blueberryLoadoutMode: "saveTree", caches: { + ambrosiaLuckAdditiveMult: new AmbrosiaLuckAdditiveMultCache(), ambrosiaLuck: new AmbrosiaLuckCache(), ambrosiaGeneration: new AmbrosiaGenerationCache(), blueberryInventory: new BlueberryInventoryCache(), diff --git a/src/UpdateVisuals.ts b/src/UpdateVisuals.ts index a567e66ba..784b7b5ad 100644 --- a/src/UpdateVisuals.ts +++ b/src/UpdateVisuals.ts @@ -1,7 +1,7 @@ -import Decimal from 'break_infinity.js' -import i18next from 'i18next' -import { showSacrifice } from './Ants' -import { DOMCacheGetOrSet } from './Cache/DOM' +import Decimal from "break_infinity.js"; +import i18next from "i18next"; +import { showSacrifice } from "./Ants"; +import { DOMCacheGetOrSet } from "./Cache/DOM"; import { calcAscensionCount, CalcCorruptionStuff, @@ -22,583 +22,869 @@ import { calculateTotalOcteractObtainiumBonus, calculateTotalOcteractOfferingBonus, calculateTotalOcteractQuarkBonus, - octeractGainPerSecond -} from './Calculate' -import { CalcECC } from './Challenges' -import { version } from './Config' -import type { IMultiBuy } from './Cubes' -import type { hepteractTypes } from './Hepteracts' -import { hepteractTypeList } from './Hepteracts' -import { quarkHandler } from './Quark' -import { displayRuneInformation } from './Runes' -import { getShopCosts, isShopUpgradeUnlocked, shopData, shopUpgradeTypes } from './Shop' -import { getGoldenQuarkCost } from './singularity' -import { loadStatisticsUpdate } from './Statistics' -import { format, formatTimeShort, player } from './Synergism' -import { Tabs } from './Tabs' -import { calculateMaxTalismanLevel } from './Talismans' -import type { Player, ZeroToFour } from './types/Synergism' -import { sumContents } from './Utility' -import { Globals as G } from './Variables' + octeractGainPerSecond, +} from "./Calculate"; +import { CalcECC } from "./Challenges"; +import { version } from "./Config"; +import type { IMultiBuy } from "./Cubes"; +import type { hepteractTypes } from "./Hepteracts"; +import { hepteractTypeList } from "./Hepteracts"; +import { quarkHandler } from "./Quark"; +import { displayRuneInformation } from "./Runes"; +import { + getShopCosts, + isShopUpgradeUnlocked, + shopData, + shopUpgradeTypes, +} from "./Shop"; +import { getGoldenQuarkCost } from "./singularity"; +import { loadStatisticsUpdate } from "./Statistics"; +import { format, formatTimeShort, player } from "./Synergism"; +import { Tabs } from "./Tabs"; +import { calculateMaxTalismanLevel } from "./Talismans"; +import type { Player, ZeroToFour } from "./types/Synergism"; +import { sumContents } from "./Utility"; +import { Globals as G } from "./Variables"; export const visualUpdateBuildings = () => { if (G.currentTab !== Tabs.Buildings) { - return + return; } // When you're in Building --> Coin, update these. - if (G.buildingSubTab === 'coin') { + if (G.buildingSubTab === "coin") { // For the display of Coin Buildings - const upper = ['produceFirst', 'produceSecond', 'produceThird', 'produceFourth', 'produceFifth'] as const - const names = [null, 'workers', 'investments', 'printers', 'coinMints', 'alchemies'] - - let totalProductionDivisor = new Decimal(G.produceTotal) + const upper = [ + "produceFirst", + "produceSecond", + "produceThird", + "produceFourth", + "produceFifth", + ] as const; + const names = [ + null, + "workers", + "investments", + "printers", + "coinMints", + "alchemies", + ]; + + let totalProductionDivisor = new Decimal(G.produceTotal); if (totalProductionDivisor.equals(0)) { - totalProductionDivisor = new Decimal(1) + totalProductionDivisor = new Decimal(1); } for (let i = 1; i <= 5; i++) { - const place = G[upper[i - 1]] - const ith = G.ordinals[i - 1 as ZeroToFour] - - DOMCacheGetOrSet(`buildtext${2 * i - 1}`).textContent = i18next.t(`buildings.names.${names[i]}`, { - amount: format(player[`${ith}OwnedCoin` as const], 0, true), - gain: format(player[`${ith}GeneratedCoin` as const]) - }) - - DOMCacheGetOrSet(`buycoin${i}`).textContent = i18next.t('buildings.costCoins', { - coins: format(player[`${ith}CostCoin` as const]) - }) - - const percentage = Decimal - .fromMantissaExponent( - place.mantissa / totalProductionDivisor.mantissa, - place.exponent - totalProductionDivisor.exponent - ) - .times(100) + const place = G[upper[i - 1]]; + const ith = G.ordinals[(i - 1) as ZeroToFour]; + + DOMCacheGetOrSet(`buildtext${2 * i - 1}`).textContent = i18next.t( + `buildings.names.${names[i]}`, + { + amount: format(player[`${ith}OwnedCoin` as const], 0, true), + gain: format(player[`${ith}GeneratedCoin` as const]), + } + ); - DOMCacheGetOrSet(`buildtext${2 * i}`).textContent = i18next.t('buildings.coinsPerSecond', { - coins: format((place.dividedBy(G.taxdivisor)).times(40), 2), - percent: format(percentage, 3) - }) + DOMCacheGetOrSet(`buycoin${i}`).textContent = i18next.t( + "buildings.costCoins", + { + coins: format(player[`${ith}CostCoin` as const]), + } + ); + + const percentage = Decimal.fromMantissaExponent( + place.mantissa / totalProductionDivisor.mantissa, + place.exponent - totalProductionDivisor.exponent + ).times(100); + + DOMCacheGetOrSet(`buildtext${2 * i}`).textContent = i18next.t( + "buildings.coinsPerSecond", + { + coins: format(place.dividedBy(G.taxdivisor).times(40), 2), + percent: format(percentage, 3), + } + ); } - DOMCacheGetOrSet('buildtext11').textContent = i18next.t('buildings.names.accelerators', { - amount: format(player.acceleratorBought, 0, true), - gain: format(G.freeAccelerator, 0, true) - }) - - DOMCacheGetOrSet('buildtext12').textContent = i18next.t('buildings.acceleratorPower', { - power: format((G.acceleratorPower - 1) * 100, 2), - mult: format(G.acceleratorEffect, 2) - }) - - DOMCacheGetOrSet('buildtext13').textContent = i18next.t('buildings.names.multipliers', { - amount: format(player.multiplierBought, 0, true), - gain: format(G.freeMultiplier, 0, true) - }) - - DOMCacheGetOrSet('buildtext14').textContent = i18next.t('buildings.multiplierPower', { - power: format(G.multiplierPower, 2), - mult: format(G.multiplierEffect, 2) - }) - - DOMCacheGetOrSet('buildtext15').textContent = i18next.t('buildings.names.acceleratorBoost', { - amount: format(player.acceleratorBoostBought, 0, true), - gain: format(G.freeAcceleratorBoost, 0, false) - }) - - DOMCacheGetOrSet('buildtext16').textContent = i18next.t('buildings.acceleratorBoost', { - amount: format( - G.tuSevenMulti * (1 + player.researches[16] / 50) - * (1 + CalcECC('transcend', player.challengecompletions[2]) / 100), - 2 - ) - }) - - DOMCacheGetOrSet('buyaccelerator').textContent = i18next.t('buildings.costCoins', { - coins: format(player.acceleratorCost) - }) - DOMCacheGetOrSet('buymultiplier').textContent = i18next.t('buildings.costCoins', { - coins: format(player.multiplierCost) - }) - DOMCacheGetOrSet('buyacceleratorboost').textContent = i18next.t('buildings.costDiamonds', { - diamonds: format(player.acceleratorBoostCost) - }) + DOMCacheGetOrSet("buildtext11").textContent = i18next.t( + "buildings.names.accelerators", + { + amount: format(player.acceleratorBought, 0, true), + gain: format(G.freeAccelerator, 0, true), + } + ); + + DOMCacheGetOrSet("buildtext12").textContent = i18next.t( + "buildings.acceleratorPower", + { + power: format((G.acceleratorPower - 1) * 100, 2), + mult: format(G.acceleratorEffect, 2), + } + ); + + DOMCacheGetOrSet("buildtext13").textContent = i18next.t( + "buildings.names.multipliers", + { + amount: format(player.multiplierBought, 0, true), + gain: format(G.freeMultiplier, 0, true), + } + ); + + DOMCacheGetOrSet("buildtext14").textContent = i18next.t( + "buildings.multiplierPower", + { + power: format(G.multiplierPower, 2), + mult: format(G.multiplierEffect, 2), + } + ); + + DOMCacheGetOrSet("buildtext15").textContent = i18next.t( + "buildings.names.acceleratorBoost", + { + amount: format(player.acceleratorBoostBought, 0, true), + gain: format(G.freeAcceleratorBoost, 0, false), + } + ); + + DOMCacheGetOrSet("buildtext16").textContent = i18next.t( + "buildings.acceleratorBoost", + { + amount: format( + G.tuSevenMulti * + (1 + player.researches[16] / 50) * + (1 + CalcECC("transcend", player.challengecompletions[2]) / 100), + 2 + ), + } + ); + + DOMCacheGetOrSet("buyaccelerator").textContent = i18next.t( + "buildings.costCoins", + { + coins: format(player.acceleratorCost), + } + ); + DOMCacheGetOrSet("buymultiplier").textContent = i18next.t( + "buildings.costCoins", + { + coins: format(player.multiplierCost), + } + ); + DOMCacheGetOrSet("buyacceleratorboost").textContent = i18next.t( + "buildings.costDiamonds", + { + diamonds: format(player.acceleratorBoostCost), + } + ); // update the tax text - let warning = '' + let warning = ""; if (player.reincarnationCount > 0.5) { - warning = i18next.t('buildings.taxWarning', { - gain: format(Decimal.pow(10, G.maxexponent - Decimal.log(G.taxdivisorcheck, 10))) - }) + warning = i18next.t("buildings.taxWarning", { + gain: format( + Decimal.pow(10, G.maxexponent - Decimal.log(G.taxdivisorcheck, 10)) + ), + }); } - DOMCacheGetOrSet('taxinfo').textContent = i18next.t('buildings.excessiveWealth', { - div: format(G.taxdivisor, 2), - warning - }) - } else if (G.buildingSubTab === 'diamond') { + DOMCacheGetOrSet("taxinfo").textContent = i18next.t( + "buildings.excessiveWealth", + { + div: format(G.taxdivisor, 2), + warning, + } + ); + } else if (G.buildingSubTab === "diamond") { // For the display of Diamond Buildings const upper = [ - 'produceFirstDiamonds', - 'produceSecondDiamonds', - 'produceThirdDiamonds', - 'produceFourthDiamonds', - 'produceFifthDiamonds' - ] as const - const names = ['refineries', 'coalPlants', 'coalRigs', 'pickaxes', 'pandorasBoxes'] - const perSecNames = ['crystal', 'ref', 'plants', 'rigs', 'pickaxes'] - - DOMCacheGetOrSet('prestigeshardinfo').textContent = i18next.t('buildings.crystalMult', { - crystals: format(player.prestigeShards, 2), - gain: format(G.prestigeMultiplier, 2) - }) + "produceFirstDiamonds", + "produceSecondDiamonds", + "produceThirdDiamonds", + "produceFourthDiamonds", + "produceFifthDiamonds", + ] as const; + const names = [ + "refineries", + "coalPlants", + "coalRigs", + "pickaxes", + "pandorasBoxes", + ]; + const perSecNames = ["crystal", "ref", "plants", "rigs", "pickaxes"]; + + DOMCacheGetOrSet("prestigeshardinfo").textContent = i18next.t( + "buildings.crystalMult", + { + crystals: format(player.prestigeShards, 2), + gain: format(G.prestigeMultiplier, 2), + } + ); for (let i = 1; i <= 5; i++) { - const place = G[upper[i - 1]] - const ith = G.ordinals[i - 1 as ZeroToFour] - - DOMCacheGetOrSet(`prestigetext${2 * i - 1}`).textContent = i18next.t(`buildings.names.${names[i - 1]}`, { - amount: format(player[`${ith}OwnedDiamonds` as const], 0, true), - gain: format(player[`${ith}GeneratedDiamonds` as const], 2) - }) + const place = G[upper[i - 1]]; + const ith = G.ordinals[(i - 1) as ZeroToFour]; + + DOMCacheGetOrSet(`prestigetext${2 * i - 1}`).textContent = i18next.t( + `buildings.names.${names[i - 1]}`, + { + amount: format(player[`${ith}OwnedDiamonds` as const], 0, true), + gain: format(player[`${ith}GeneratedDiamonds` as const], 2), + } + ); - DOMCacheGetOrSet(`prestigetext${2 * i}`).textContent = i18next.t(`buildings.per.${perSecNames[i - 1]}`, { - amount: format(place.times(40), 2) - }) + DOMCacheGetOrSet(`prestigetext${2 * i}`).textContent = i18next.t( + `buildings.per.${perSecNames[i - 1]}`, + { + amount: format(place.times(40), 2), + } + ); - DOMCacheGetOrSet(`buydiamond${i}`).textContent = i18next.t('buildings.costDiamonds', { - diamonds: format(player[`${ith}CostDiamonds` as const], 2) - }) + DOMCacheGetOrSet(`buydiamond${i}`).textContent = i18next.t( + "buildings.costDiamonds", + { + diamonds: format(player[`${ith}CostDiamonds` as const], 2), + } + ); } if (player.resettoggle1 === 1 || player.resettoggle1 === 0) { const p = Decimal.pow( 10, - Decimal.log(G.prestigePointGain.add(1), 10) - Decimal.log(player.prestigePoints.sub(1), 10) - ) - DOMCacheGetOrSet('autoprestige').textContent = i18next.t('buildings.autoPrestige', { - name: 'Diamonds', - action: 'Prestige', - factor: format(Decimal.pow(10, player.prestigeamount)), - mult: format(p) - }) + Decimal.log(G.prestigePointGain.add(1), 10) - + Decimal.log(player.prestigePoints.sub(1), 10) + ); + DOMCacheGetOrSet("autoprestige").textContent = i18next.t( + "buildings.autoPrestige", + { + name: "Diamonds", + action: "Prestige", + factor: format(Decimal.pow(10, player.prestigeamount)), + mult: format(p), + } + ); } else if (player.resettoggle1 === 2) { - DOMCacheGetOrSet('autoprestige').textContent = i18next.t('buildings.autoReincarnate', { - name: 'Prestige', - amount: player.prestigeamount, - timer: format(G.autoResetTimers.prestige, 1) - }) + DOMCacheGetOrSet("autoprestige").textContent = i18next.t( + "buildings.autoReincarnate", + { + name: "Prestige", + amount: player.prestigeamount, + timer: format(G.autoResetTimers.prestige, 1), + } + ); } - } else if (G.buildingSubTab === 'mythos') { + } else if (G.buildingSubTab === "mythos") { // For the display of Mythos Buildings const upper = [ - 'produceFirstMythos', - 'produceSecondMythos', - 'produceThirdMythos', - 'produceFourthMythos', - 'produceFifthMythos' - ] as const - const names = ['augments', 'enchantments', 'wizards', 'oracles', 'grandmasters'] - const perSecNames = ['shards', 'augments', 'enchantments', 'wizards', 'oracles'] - - DOMCacheGetOrSet('transcendshardinfo').textContent = i18next.t('buildings.mythosYouHave', { - shards: format(player.transcendShards, 2), - mult: format(G.totalMultiplierBoost, 0, true) - }) + "produceFirstMythos", + "produceSecondMythos", + "produceThirdMythos", + "produceFourthMythos", + "produceFifthMythos", + ] as const; + const names = [ + "augments", + "enchantments", + "wizards", + "oracles", + "grandmasters", + ]; + const perSecNames = [ + "shards", + "augments", + "enchantments", + "wizards", + "oracles", + ]; + + DOMCacheGetOrSet("transcendshardinfo").textContent = i18next.t( + "buildings.mythosYouHave", + { + shards: format(player.transcendShards, 2), + mult: format(G.totalMultiplierBoost, 0, true), + } + ); for (let i = 1; i <= 5; i++) { - const place = G[upper[i - 1]] - const ith = G.ordinals[i - 1 as ZeroToFour] - - DOMCacheGetOrSet(`transcendtext${2 * i - 1}`).textContent = i18next.t(`buildings.names.${names[i - 1]}`, { - amount: format(player[`${ith}OwnedMythos` as const], 0, true), - gain: format(player[`${ith}GeneratedMythos` as const], 2) - }) + const place = G[upper[i - 1]]; + const ith = G.ordinals[(i - 1) as ZeroToFour]; + + DOMCacheGetOrSet(`transcendtext${2 * i - 1}`).textContent = i18next.t( + `buildings.names.${names[i - 1]}`, + { + amount: format(player[`${ith}OwnedMythos` as const], 0, true), + gain: format(player[`${ith}GeneratedMythos` as const], 2), + } + ); - DOMCacheGetOrSet(`transcendtext${2 * i}`).textContent = i18next.t(`buildings.per.${perSecNames[i - 1]}`, { - amount: format(place.times(40), 2) - }) + DOMCacheGetOrSet(`transcendtext${2 * i}`).textContent = i18next.t( + `buildings.per.${perSecNames[i - 1]}`, + { + amount: format(place.times(40), 2), + } + ); - DOMCacheGetOrSet(`buymythos${i}`).textContent = i18next.t('buildings.costMythos', { - mythos: format(player[`${ith}CostMythos` as const], 2) - }) + DOMCacheGetOrSet(`buymythos${i}`).textContent = i18next.t( + "buildings.costMythos", + { + mythos: format(player[`${ith}CostMythos` as const], 2), + } + ); } if (player.resettoggle2 === 1 || player.resettoggle2 === 0) { - DOMCacheGetOrSet('autotranscend').textContent = i18next.t('buildings.autoPrestige', { - name: 'Mythos', - action: 'Prestige', - factor: format(Decimal.pow(10, player.transcendamount)), - mult: format( - Decimal.pow( - 10, - Decimal.log(G.transcendPointGain.add(1), 10) - Decimal.log(player.transcendPoints.add(1), 10) + DOMCacheGetOrSet("autotranscend").textContent = i18next.t( + "buildings.autoPrestige", + { + name: "Mythos", + action: "Prestige", + factor: format(Decimal.pow(10, player.transcendamount)), + mult: format( + Decimal.pow( + 10, + Decimal.log(G.transcendPointGain.add(1), 10) - + Decimal.log(player.transcendPoints.add(1), 10) + ), + 2 ), - 2 - ) - }) + } + ); } if (player.resettoggle2 === 2) { // TODO(@KhafraDev): i18n this - DOMCacheGetOrSet('autotranscend').textContent = - `Transcend when the autotimer is at least ${player.transcendamount} real-life seconds. [Toggle number above]. Current timer: ${ - format(G.autoResetTimers.transcension, 1) - }s.` + DOMCacheGetOrSet( + "autotranscend" + ).textContent = `Transcend when the autotimer is at least ${ + player.transcendamount + } real-life seconds. [Toggle number above]. Current timer: ${format( + G.autoResetTimers.transcension, + 1 + )}s.`; } - } else if (G.buildingSubTab === 'particle') { + } else if (G.buildingSubTab === "particle") { // For the display of Particle Buildings - const upper = ['FirstParticles', 'SecondParticles', 'ThirdParticles', 'FourthParticles', 'FifthParticles'] as const - const names = ['protons', 'elements', 'pulsars', 'quasars', 'galacticNuclei'] - const perSecNames = ['atoms', 'protons', 'elements', 'pulsars', 'quasars'] + const upper = [ + "FirstParticles", + "SecondParticles", + "ThirdParticles", + "FourthParticles", + "FifthParticles", + ] as const; + const names = [ + "protons", + "elements", + "pulsars", + "quasars", + "galacticNuclei", + ]; + const perSecNames = ["atoms", "protons", "elements", "pulsars", "quasars"]; for (let i = 1; i <= 5; i++) { - const ith = G.ordinals[i - 1 as ZeroToFour] - const place = G[`produce${upper[i - 1]}` as const] - - DOMCacheGetOrSet(`reincarnationtext${i}`).textContent = i18next.t(`buildings.names.${names[i - 1]}`, { - amount: format(player[`${ith}OwnedParticles` as const], 0, true), - gain: format(player[`${ith}GeneratedParticles` as const], 2) - }) - DOMCacheGetOrSet(`reincarnationtext${i + 5}`).textContent = i18next.t(`buildings.per.${perSecNames[i - 1]}`, { - amount: format(place.times(40), 2) - }) - DOMCacheGetOrSet(`buyparticles${i}`).textContent = i18next.t('buildings.costParticles', { - particles: format(player[`${ith}CostParticles` as const], 2) - }) + const ith = G.ordinals[(i - 1) as ZeroToFour]; + const place = G[`produce${upper[i - 1]}` as const]; + + DOMCacheGetOrSet(`reincarnationtext${i}`).textContent = i18next.t( + `buildings.names.${names[i - 1]}`, + { + amount: format(player[`${ith}OwnedParticles` as const], 0, true), + gain: format(player[`${ith}GeneratedParticles` as const], 2), + } + ); + DOMCacheGetOrSet(`reincarnationtext${i + 5}`).textContent = i18next.t( + `buildings.per.${perSecNames[i - 1]}`, + { + amount: format(place.times(40), 2), + } + ); + DOMCacheGetOrSet(`buyparticles${i}`).textContent = i18next.t( + "buildings.costParticles", + { + particles: format(player[`${ith}CostParticles` as const], 2), + } + ); } - DOMCacheGetOrSet('reincarnationshardinfo').textContent = i18next.t('buildings.atomsYouHave', { - atoms: format(player.reincarnationShards, 2), - power: format(G.buildingPower, 4), - mult: format(G.reincarnationMultiplier) - }) + DOMCacheGetOrSet("reincarnationshardinfo").textContent = i18next.t( + "buildings.atomsYouHave", + { + atoms: format(player.reincarnationShards, 2), + power: format(G.buildingPower, 4), + mult: format(G.reincarnationMultiplier), + } + ); - DOMCacheGetOrSet('reincarnationCrystalInfo').textContent = i18next.t('buildings.thanksR2x14', { - mult: format(Decimal.pow(G.reincarnationMultiplier, 1 / 50), 3, false) - }) + DOMCacheGetOrSet("reincarnationCrystalInfo").textContent = i18next.t( + "buildings.thanksR2x14", + { + mult: format(Decimal.pow(G.reincarnationMultiplier, 1 / 50), 3, false), + } + ); - DOMCacheGetOrSet('reincarnationMythosInfo').textContent = i18next.t('buildings.thanksR2x15', { - mult: format(Decimal.pow(G.reincarnationMultiplier, 1 / 250), 3, false) - }) + DOMCacheGetOrSet("reincarnationMythosInfo").textContent = i18next.t( + "buildings.thanksR2x15", + { + mult: format(Decimal.pow(G.reincarnationMultiplier, 1 / 250), 3, false), + } + ); if (player.resettoggle3 === 1 || player.resettoggle3 === 0) { - DOMCacheGetOrSet('autoreincarnate').textContent = i18next.t('buildings.autoPrestige', { - name: 'Particles', - action: 'Reincarnate', - factor: format(Decimal.pow(10, player.reincarnationamount)), - mult: format( - Decimal.pow( - 10, - Decimal.log(G.reincarnationPointGain.add(1), 10) - Decimal.log(player.reincarnationPoints.add(1), 10) + DOMCacheGetOrSet("autoreincarnate").textContent = i18next.t( + "buildings.autoPrestige", + { + name: "Particles", + action: "Reincarnate", + factor: format(Decimal.pow(10, player.reincarnationamount)), + mult: format( + Decimal.pow( + 10, + Decimal.log(G.reincarnationPointGain.add(1), 10) - + Decimal.log(player.reincarnationPoints.add(1), 10) + ), + 2 ), - 2 - ) - }) + } + ); } else if (player.resettoggle3 === 2) { - DOMCacheGetOrSet('autoreincarnate').textContent = i18next.t('buildings.autoReincarnate', { - name: 'Reincarnate', - amount: player.reincarnationamount, - timer: format(G.autoResetTimers.reincarnation, 1) - }) + DOMCacheGetOrSet("autoreincarnate").textContent = i18next.t( + "buildings.autoReincarnate", + { + name: "Reincarnate", + amount: player.reincarnationamount, + timer: format(G.autoResetTimers.reincarnation, 1), + } + ); } - } else if (G.buildingSubTab === 'tesseract') { - const names = ['dot', 'vector', 'threeSpace', 'bentTime', 'hilbertSpace'] - const perSecNames = ['constant', 'dot', 'vector', 'threeSpace', 'bentTime'] + } else if (G.buildingSubTab === "tesseract") { + const names = ["dot", "vector", "threeSpace", "bentTime", "hilbertSpace"]; + const perSecNames = ["constant", "dot", "vector", "threeSpace", "bentTime"]; for (let i = 1; i <= 5; i++) { - const ascendBuildingI = `ascendBuilding${i as 1 | 2 | 3 | 4 | 5}` as const - - DOMCacheGetOrSet(`ascendText${i}`).textContent = i18next.t(`buildings.names.${names[i - 1]}`, { - amount: format(player[ascendBuildingI].owned, 0, true), - gain: format(player[ascendBuildingI].generated, 2) - }) - - DOMCacheGetOrSet(`ascendText${5 + i}`).textContent = i18next.t(`buildings.per.${perSecNames[i - 1]}`, { - amount: format((G.ascendBuildingProduction as Record)[G.ordinals[i - 1]], 2) - }) + const ascendBuildingI = `ascendBuilding${ + i as 1 | 2 | 3 | 4 | 5 + }` as const; + + DOMCacheGetOrSet(`ascendText${i}`).textContent = i18next.t( + `buildings.names.${names[i - 1]}`, + { + amount: format(player[ascendBuildingI].owned, 0, true), + gain: format(player[ascendBuildingI].generated, 2), + } + ); + + DOMCacheGetOrSet(`ascendText${5 + i}`).textContent = i18next.t( + `buildings.per.${perSecNames[i - 1]}`, + { + amount: format( + (G.ascendBuildingProduction as Record)[ + G.ordinals[i - 1] + ], + 2 + ), + } + ); - DOMCacheGetOrSet(`buyTesseracts${i}`).textContent = i18next.t('buildings.costTesseracts', { - tesseracts: format(player[ascendBuildingI].cost, 0) - }) + DOMCacheGetOrSet(`buyTesseracts${i}`).textContent = i18next.t( + "buildings.costTesseracts", + { + tesseracts: format(player[ascendBuildingI].cost, 0), + } + ); } - DOMCacheGetOrSet('tesseractInfo').textContent = i18next.t('buildings.tesseractsYouHave', { - tesseracts: format(player.wowTesseracts) - }) - - DOMCacheGetOrSet('ascendShardInfo').textContent = i18next.t('buildings.constantYouHave', { - const: format(player.ascendShards, 2), - amount: format( - Math.pow( - Decimal.log(player.ascendShards.add(1), 10) + 1, - 1 + .2 / 60 * player.challengecompletions[10] * player.upgrades[125] + 0.1 * player.platonicUpgrades[5] - + 0.2 * player.platonicUpgrades[10] + (G.platonicBonusMultiplier[5] - 1) + DOMCacheGetOrSet("tesseractInfo").textContent = i18next.t( + "buildings.tesseractsYouHave", + { + tesseracts: format(player.wowTesseracts), + } + ); + + DOMCacheGetOrSet("ascendShardInfo").textContent = i18next.t( + "buildings.constantYouHave", + { + const: format(player.ascendShards, 2), + amount: format( + Math.pow( + Decimal.log(player.ascendShards.add(1), 10) + 1, + 1 + + (0.2 / 60) * + player.challengecompletions[10] * + player.upgrades[125] + + 0.1 * player.platonicUpgrades[5] + + 0.2 * player.platonicUpgrades[10] + + (G.platonicBonusMultiplier[5] - 1) + ), + 4, + true ), - 4, - true - ) - }) + } + ); if (player.resettoggle4 === 1 || player.resettoggle4 === 0) { - DOMCacheGetOrSet('autotessbuyeramount').textContent = i18next.t('buildings.autoTesseract', { - tesseracts: format(player.tesseractAutoBuyerAmount) - }) + DOMCacheGetOrSet("autotessbuyeramount").textContent = i18next.t( + "buildings.autoTesseract", + { + tesseracts: format(player.tesseractAutoBuyerAmount), + } + ); } else if (player.resettoggle4 === 2) { - DOMCacheGetOrSet('autotessbuyeramount').textContent = i18next.t('buildings.autoAscensionTesseract', { - percent: format(Math.min(100, player.tesseractAutoBuyerAmount)) - }) + DOMCacheGetOrSet("autotessbuyeramount").textContent = i18next.t( + "buildings.autoAscensionTesseract", + { + percent: format(Math.min(100, player.tesseractAutoBuyerAmount)), + } + ); } } -} +}; -export const visualUpdateUpgrades = () => {} +export const visualUpdateUpgrades = () => {}; -export const visualUpdateAchievements = () => {} +export const visualUpdateAchievements = () => {}; export const visualUpdateRunes = () => { if (G.currentTab !== Tabs.Runes) { - return + return; } - if (G.runescreen === 'runes') { // Placeholder and place work similarly to buildings, except for the specific Talismans. + if (G.runescreen === "runes") { + // Placeholder and place work similarly to buildings, except for the specific Talismans. const talismans = [ - 'rune1Talisman', - 'rune2Talisman', - 'rune3Talisman', - 'rune4Talisman', - 'rune5Talisman' - ] as const - - DOMCacheGetOrSet('offeringCount').textContent = i18next.t('runes.offeringsYouHave', { - offerings: format(player.runeshards, 0, true) - }) - - for (let i = 1; i <= 7; i++) { // First one updates level, second one updates TNL, third updates orange bonus levels - let place = G[talismans[i - 1]] + "rune1Talisman", + "rune2Talisman", + "rune3Talisman", + "rune4Talisman", + "rune5Talisman", + ] as const; + + DOMCacheGetOrSet("offeringCount").textContent = i18next.t( + "runes.offeringsYouHave", + { + offerings: format(player.runeshards, 0, true), + } + ); + + for (let i = 1; i <= 7; i++) { + // First one updates level, second one updates TNL, third updates orange bonus levels + let place = G[talismans[i - 1]]; if (i > 5) { - place = 0 + place = 0; } - const runeLevel = player.runelevels[i - 1] - const maxLevel = calculateMaxRunes(i) - DOMCacheGetOrSet(`rune${i}level`).childNodes[0].textContent = i18next.t('cubes.cubeMetadata.level', { - value1: format(runeLevel), - value2: format(maxLevel) - }) + const runeLevel = player.runelevels[i - 1]; + const maxLevel = calculateMaxRunes(i); + DOMCacheGetOrSet(`rune${i}level`).childNodes[0].textContent = i18next.t( + "cubes.cubeMetadata.level", + { + value1: format(runeLevel), + value2: format(maxLevel), + } + ); if (runeLevel < maxLevel) { - DOMCacheGetOrSet(`rune${i}exp`).textContent = i18next.t('runes.TNL', { - EXP: format(calculateRuneExpToLevel(i - 1) - player.runeexp[i - 1], 2) - }) + DOMCacheGetOrSet(`rune${i}exp`).textContent = i18next.t("runes.TNL", { + EXP: format( + calculateRuneExpToLevel(i - 1) - player.runeexp[i - 1], + 2 + ), + }); } else { - DOMCacheGetOrSet(`rune${i}exp`).textContent = i18next.t('runes.maxLevel') + DOMCacheGetOrSet(`rune${i}exp`).textContent = + i18next.t("runes.maxLevel"); } if (i <= 5) { - DOMCacheGetOrSet(`bonusrune${i}`).textContent = i18next.t('runes.bonusAmount', { - x: format(7 * player.constantUpgrades[7] + Math.min(1e7, player.antUpgrades[8]! + G.bonusant9) + place) - }) + DOMCacheGetOrSet(`bonusrune${i}`).textContent = i18next.t( + "runes.bonusAmount", + { + x: format( + 7 * player.constantUpgrades[7] + + Math.min(1e7, player.antUpgrades[8]! + G.bonusant9) + + place + ), + } + ); } else { - DOMCacheGetOrSet(`bonusrune${i}`).textContent = i18next.t('runes.bonusNope') + DOMCacheGetOrSet(`bonusrune${i}`).textContent = + i18next.t("runes.bonusNope"); } - displayRuneInformation(i, false) + displayRuneInformation(i, false); } - const calculateRecycle = calculateRecycleMultiplier() + const calculateRecycle = calculateRecycleMultiplier(); const allRuneExpAdditiveMultiplier = sumContents([ // Base amount multiplied per offering 1 * calculateRecycle, // +1 if C1 completion Math.min(1, player.highestchallengecompletions[1]), // +0.10 per C1 completion - 0.4 / 10 * player.highestchallengecompletions[1], + (0.4 / 10) * player.highestchallengecompletions[1], // Research 5x2 0.6 * player.researches[22], // Research 5x3 0.3 * player.researches[23], // Particle Upgrade 1x1 - 2 * player.upgrades[61] - ]) + 2 * player.upgrades[61], + ]); - DOMCacheGetOrSet('offeringExperienceValue').textContent = i18next.t('runes.gainExp', { - amount: format(allRuneExpAdditiveMultiplier, 2, true) - }) + DOMCacheGetOrSet("offeringExperienceValue").textContent = i18next.t( + "runes.gainExp", + { + amount: format(allRuneExpAdditiveMultiplier, 2, true), + } + ); - DOMCacheGetOrSet('offeringRecycleInfo').textContent = i18next.t('runes.recycleChance', { - percent: format((1 - 1 / calculateRecycle) * 100, 2, true), - mult: format(calculateRecycle, 2, true) - }) + DOMCacheGetOrSet("offeringRecycleInfo").textContent = i18next.t( + "runes.recycleChance", + { + percent: format((1 - 1 / calculateRecycle) * 100, 2, true), + mult: format(calculateRecycle, 2, true), + } + ); } - if (G.runescreen === 'talismans') { + if (G.runescreen === "talismans") { for (let i = 0; i < 7; i++) { - const maxTalismanLevel = calculateMaxTalismanLevel(i) + const maxTalismanLevel = calculateMaxTalismanLevel(i); // TODO(@KhafraDev): i18n - DOMCacheGetOrSet(`talisman${i + 1}level`).textContent = `${player.ascensionCount > 0 ? '' : 'Level '} ${ - format(player.talismanLevels[i]) - }/${format(maxTalismanLevel)}` + DOMCacheGetOrSet(`talisman${i + 1}level`).textContent = `${ + player.ascensionCount > 0 ? "" : "Level " + } ${format(player.talismanLevels[i])}/${format(maxTalismanLevel)}`; } } - if (G.runescreen === 'blessings') { - const blessingMultiplierArray = [0, 8, 10, 6.66, 2, 1] - let t = 0 + if (G.runescreen === "blessings") { + const blessingMultiplierArray = [0, 8, 10, 6.66, 2, 1]; + let t = 0; for (let i = 1; i <= 5; i++) { - DOMCacheGetOrSet(`runeBlessingLevel${i}Value`).innerHTML = i18next.t('runes.blessings.blessingLevel', { - amount: format(player.runeBlessingLevels[i]) - }) - - DOMCacheGetOrSet(`runeBlessingPower${i}Value1`).innerHTML = i18next.t('runes.blessings.blessingPower', { - reward: i18next.t(`runes.blessings.rewards.${i - 1}`), - value: format(G.runeBlessings[i]), - speed: format(1 - t + blessingMultiplierArray[i] * G.effectiveRuneBlessingPower[i], 4, true) - }) - - const levelsPurchasable = calculateSummationLinear( - player.runeBlessingLevels[i], - G.blessingBaseCost, - player.runeshards, - player.runeBlessingBuyAmount - )[0] - player.runeBlessingLevels[i] + DOMCacheGetOrSet(`runeBlessingLevel${i}Value`).innerHTML = i18next.t( + "runes.blessings.blessingLevel", + { + amount: format(player.runeBlessingLevels[i]), + } + ); + + DOMCacheGetOrSet(`runeBlessingPower${i}Value1`).innerHTML = i18next.t( + "runes.blessings.blessingPower", + { + reward: i18next.t(`runes.blessings.rewards.${i - 1}`), + value: format(G.runeBlessings[i]), + speed: format( + 1 - + t + + blessingMultiplierArray[i] * G.effectiveRuneBlessingPower[i], + 4, + true + ), + } + ); + + const levelsPurchasable = + calculateSummationLinear( + player.runeBlessingLevels[i], + G.blessingBaseCost, + player.runeshards, + player.runeBlessingBuyAmount + )[0] - player.runeBlessingLevels[i]; levelsPurchasable > 0 - ? DOMCacheGetOrSet(`runeBlessingPurchase${i}`).classList.add('runeButtonsAvailable') - : DOMCacheGetOrSet(`runeBlessingPurchase${i}`).classList.remove('runeButtonsAvailable') - - DOMCacheGetOrSet(`runeBlessingPurchase${i}`).innerHTML = i18next.t('runes.blessings.increaseLevel', { - amount: format(Math.max(1, levelsPurchasable)), - offerings: format( - Math.max( - G.blessingBaseCost * (1 + player.runeBlessingLevels[i]), - calculateSummationLinear( - player.runeBlessingLevels[i], - G.blessingBaseCost, - player.runeshards, - player.runeBlessingBuyAmount - )[1] + ? DOMCacheGetOrSet(`runeBlessingPurchase${i}`).classList.add( + "runeButtonsAvailable" ) - ) - }) + : DOMCacheGetOrSet(`runeBlessingPurchase${i}`).classList.remove( + "runeButtonsAvailable" + ); + + DOMCacheGetOrSet(`runeBlessingPurchase${i}`).innerHTML = i18next.t( + "runes.blessings.increaseLevel", + { + amount: format(Math.max(1, levelsPurchasable)), + offerings: format( + Math.max( + G.blessingBaseCost * (1 + player.runeBlessingLevels[i]), + calculateSummationLinear( + player.runeBlessingLevels[i], + G.blessingBaseCost, + player.runeshards, + player.runeBlessingBuyAmount + )[1] + ) + ), + } + ); if (i === 5) { - t = 1 + t = 1; } } } - if (G.runescreen === 'spirits') { - const spiritMultiplierArray = [0, 1, 1, 20, 1, 100] - const subtract = [0, 0, 0, 1, 0, 0] + if (G.runescreen === "spirits") { + const spiritMultiplierArray = [0, 1, 1, 20, 1, 100]; + const subtract = [0, 0, 0, 1, 0, 0]; for (let i = 1; i <= 5; i++) { - spiritMultiplierArray[i] *= calculateCorruptionPoints() / 400 - - DOMCacheGetOrSet(`runeSpiritLevel${i}Value`).innerHTML = i18next.t('runes.spirits.spiritLevel', { - amount: format(player.runeSpiritLevels[i]) - }) - - DOMCacheGetOrSet(`runeSpiritPower${i}Value1`).innerHTML = i18next.t('runes.spirits.spiritPower', { - reward: i18next.t(`runes.spirits.rewards.${i - 1}`), - value: format(G.runeSpirits[i]), - speed: format(1 - subtract[i] + spiritMultiplierArray[i] * G.effectiveRuneSpiritPower[i], 4, true) - }) - - const levelsPurchasable = calculateSummationLinear( - player.runeSpiritLevels[i], - G.spiritBaseCost, - player.runeshards, - player.runeSpiritBuyAmount - )[0] - player.runeSpiritLevels[i] + spiritMultiplierArray[i] *= calculateCorruptionPoints() / 400; + + DOMCacheGetOrSet(`runeSpiritLevel${i}Value`).innerHTML = i18next.t( + "runes.spirits.spiritLevel", + { + amount: format(player.runeSpiritLevels[i]), + } + ); + + DOMCacheGetOrSet(`runeSpiritPower${i}Value1`).innerHTML = i18next.t( + "runes.spirits.spiritPower", + { + reward: i18next.t(`runes.spirits.rewards.${i - 1}`), + value: format(G.runeSpirits[i]), + speed: format( + 1 - + subtract[i] + + spiritMultiplierArray[i] * G.effectiveRuneSpiritPower[i], + 4, + true + ), + } + ); + + const levelsPurchasable = + calculateSummationLinear( + player.runeSpiritLevels[i], + G.spiritBaseCost, + player.runeshards, + player.runeSpiritBuyAmount + )[0] - player.runeSpiritLevels[i]; levelsPurchasable > 0 - ? DOMCacheGetOrSet(`runeSpiritPurchase${i}`).classList.add('runeButtonsAvailable') - : DOMCacheGetOrSet(`runeSpiritPurchase${i}`).classList.remove('runeButtonsAvailable') - - DOMCacheGetOrSet(`runeSpiritPurchase${i}`).innerHTML = i18next.t('runes.blessings.increaseLevel', { - amount: format(Math.max(1, levelsPurchasable)), - offerings: format( - Math.max( - G.spiritBaseCost * (1 + player.runeSpiritLevels[i]), - calculateSummationLinear( - player.runeSpiritLevels[i], - G.spiritBaseCost, - player.runeshards, - player.runeSpiritBuyAmount - )[1] + ? DOMCacheGetOrSet(`runeSpiritPurchase${i}`).classList.add( + "runeButtonsAvailable" ) - ) - }) + : DOMCacheGetOrSet(`runeSpiritPurchase${i}`).classList.remove( + "runeButtonsAvailable" + ); + + DOMCacheGetOrSet(`runeSpiritPurchase${i}`).innerHTML = i18next.t( + "runes.blessings.increaseLevel", + { + amount: format(Math.max(1, levelsPurchasable)), + offerings: format( + Math.max( + G.spiritBaseCost * (1 + player.runeSpiritLevels[i]), + calculateSummationLinear( + player.runeSpiritLevels[i], + G.spiritBaseCost, + player.runeshards, + player.runeSpiritBuyAmount + )[1] + ) + ), + } + ); } } -} +}; export const visualUpdateChallenges = () => { if (G.currentTab !== Tabs.Challenges) { - return + return; } if (player.researches[150] > 0) { - DOMCacheGetOrSet('autoIncrementerAmount').innerHTML = i18next.t('challenges.autoTimer', { - time: format(G.autoChallengeTimerIncrement, 2) - }) + DOMCacheGetOrSet("autoIncrementerAmount").innerHTML = i18next.t( + "challenges.autoTimer", + { + time: format(G.autoChallengeTimerIncrement, 2), + } + ); } -} +}; export const visualUpdateResearch = () => { if (G.currentTab !== Tabs.Research) { - return + return; } if (player.researches[61] > 0) { - DOMCacheGetOrSet('automaticobtainium').textContent = i18next.t('researches.thanksToResearches', { - x: format(calculateAutomaticObtainium() * calculateTimeAcceleration().mult, 3, true) - }) + DOMCacheGetOrSet("automaticobtainium").textContent = i18next.t( + "researches.thanksToResearches", + { + x: format( + calculateAutomaticObtainium() * calculateTimeAcceleration().mult, + 3, + true + ), + } + ); } -} +}; export const visualUpdateAnts = () => { if (G.currentTab !== Tabs.AntHill) { - return + return; } - DOMCacheGetOrSet('crumbcount').textContent = i18next.t('ants.youHaveGalacticCrumbs', { - x: format(player.antPoints, 2), - y: format(G.antOneProduce, 2), - z: format( - Decimal.pow( - Decimal.max(1, player.antPoints), - 100000 + calculateSigmoidExponential(49900000, (player.antUpgrades[1]! + G.bonusant2) / 5000 * 500 / 499) - ) - ) - }) - - const mode = player.autoAntSacrificeMode === 2 ? i18next.t('ants.modeRealTime') : i18next.t('ants.modeInGameTime') - const timer = player.autoAntSacrificeMode === 2 ? player.antSacrificeTimerReal : player.antSacrificeTimer - - DOMCacheGetOrSet('autoAntSacrifice').textContent = i18next.t('ants.sacrificeWhenTimer', { - x: player.autoAntSacTimer, - y: mode, - z: format(timer, 2) - }) + DOMCacheGetOrSet("crumbcount").textContent = i18next.t( + "ants.youHaveGalacticCrumbs", + { + x: format(player.antPoints, 2), + y: format(G.antOneProduce, 2), + z: format( + Decimal.pow( + Decimal.max(1, player.antPoints), + 100000 + + calculateSigmoidExponential( + 49900000, + (((player.antUpgrades[1]! + G.bonusant2) / 5000) * 500) / 499 + ) + ) + ), + } + ); + + const mode = + player.autoAntSacrificeMode === 2 + ? i18next.t("ants.modeRealTime") + : i18next.t("ants.modeInGameTime"); + const timer = + player.autoAntSacrificeMode === 2 + ? player.antSacrificeTimerReal + : player.antSacrificeTimer; + + DOMCacheGetOrSet("autoAntSacrifice").textContent = i18next.t( + "ants.sacrificeWhenTimer", + { + x: player.autoAntSacTimer, + y: mode, + z: format(timer, 2), + } + ); if (player.achievements[173] === 1) { - DOMCacheGetOrSet('antSacrificeTimer').textContent = formatTimeShort(player.antSacrificeTimer) - showSacrifice() + DOMCacheGetOrSet("antSacrificeTimer").textContent = formatTimeShort( + player.antSacrificeTimer + ); + showSacrifice(); } -} +}; interface cubeNames { - cube: number - tesseract: number - hypercube: number - platonicCube: number + cube: number; + tesseract: number; + hypercube: number; + platonicCube: number; } export const visualUpdateCubes = () => { if (G.currentTab !== Tabs.WowCubes) { - return + return; } - const cubeMult = (player.shopUpgrades.cubeToQuark) ? 1.5 : 1 - const tesseractMult = (player.shopUpgrades.tesseractToQuark) ? 1.5 : 1 - const hypercubeMult = (player.shopUpgrades.hypercubeToQuark) ? 1.5 : 1 - const platonicMult = 1.5 + const cubeMult = player.shopUpgrades.cubeToQuark ? 1.5 : 1; + const tesseractMult = player.shopUpgrades.tesseractToQuark ? 1.5 : 1; + const hypercubeMult = player.shopUpgrades.hypercubeToQuark ? 1.5 : 1; + const platonicMult = 1.5; const toNextQuark: cubeNames = { - cube: Number(player.wowCubes.checkCubesToNextQuark(5, cubeMult, player.cubeQuarkDaily, player.cubeOpenedDaily)), + cube: Number( + player.wowCubes.checkCubesToNextQuark( + 5, + cubeMult, + player.cubeQuarkDaily, + player.cubeOpenedDaily + ) + ), tesseract: Number( player.wowTesseracts.checkCubesToNextQuark( 7, @@ -622,40 +908,51 @@ export const visualUpdateCubes = () => { player.platonicCubeQuarkDaily, player.platonicCubeOpenedDaily ) - ) - } + ), + }; - const names = Object.keys(toNextQuark) as (keyof cubeNames)[] + const names = Object.keys(toNextQuark) as (keyof cubeNames)[]; for (const name of names) { - DOMCacheGetOrSet(`${name}QuarksToday`).innerHTML = i18next.t(`wowCubes.quarks.${name}QuarksToday`, { - amount: format(player[`${name}QuarkDaily` as const]) - }) - DOMCacheGetOrSet(`${name}QuarksOpenToday`).innerHTML = i18next.t(`wowCubes.quarks.${name}QuarksOpenToday`, { - amount: format(player[`${name}OpenedDaily` as const]) - }) + DOMCacheGetOrSet(`${name}QuarksToday`).innerHTML = i18next.t( + `wowCubes.quarks.${name}QuarksToday`, + { + amount: format(player[`${name}QuarkDaily` as const]), + } + ); + DOMCacheGetOrSet(`${name}QuarksOpenToday`).innerHTML = i18next.t( + `wowCubes.quarks.${name}QuarksOpenToday`, + { + amount: format(player[`${name}OpenedDaily` as const]), + } + ); DOMCacheGetOrSet(`${name}QuarksOpenRequirement`).innerHTML = i18next.t( `wowCubes.quarks.${name}QuarksOpenRequirement`, { amount: format(Math.max(1, toNextQuark[name])) } - ) + ); // Change color of requirement text if 1 or less required :D - DOMCacheGetOrSet(`${name}QuarksOpenRequirement`).style.color = (Math.max(1, toNextQuark[name]) === 1) - ? 'gold' - : 'white' + DOMCacheGetOrSet(`${name}QuarksOpenRequirement`).style.color = + Math.max(1, toNextQuark[name]) === 1 ? "gold" : "white"; } // TODO: this code is fucking terrible holy shit. Also pretty sure there's a bug. - let accuracy: [null | number, ...number[]] + let accuracy: [null | number, ...number[]]; switch (player.subtabNumber) { case 0: { if (player.autoOpenCubes) { - DOMCacheGetOrSet('openCubes').textContent = i18next.t('wowCubes.autoOn', { - percent: format(player.openCubes, 0) - }) + DOMCacheGetOrSet("openCubes").textContent = i18next.t( + "wowCubes.autoOn", + { + percent: format(player.openCubes, 0), + } + ); } - DOMCacheGetOrSet('cubeQuantity').innerHTML = i18next.t('wowCubes.cubes.inventory', { - amount: format(player.wowCubes, 0, true) - }) + DOMCacheGetOrSet("cubeQuantity").innerHTML = i18next.t( + "wowCubes.cubes.inventory", + { + amount: format(player.wowCubes, 0, true), + } + ); const cubeArray = [ null, player.cubeBlessings.accelerator, @@ -667,35 +964,51 @@ export const visualUpdateCubes = () => { player.cubeBlessings.antSacrifice, player.cubeBlessings.antELO, player.cubeBlessings.talismanBonus, - player.cubeBlessings.globalSpeed - ] + player.cubeBlessings.globalSpeed, + ]; - accuracy = [null, 2, 2, 2, 2, 2, 2, 2, 1, 4, 3] + accuracy = [null, 2, 2, 2, 2, 2, 2, 2, 1, 4, 3]; for (let i = 1; i <= 10; i++) { - let augmentAccuracy = 0 + let augmentAccuracy = 0; if (cubeArray[i]! >= 1000 && i !== 6) { - augmentAccuracy += 2 + augmentAccuracy += 2; } - const aestheticMultiplier = (i === 1 || i === 8 || i === 9) ? 1 : 100 - DOMCacheGetOrSet(`cube${i}Bonus`).innerHTML = i18next.t(`wowCubes.cubes.items.${i}`, { - amount: format(cubeArray[i], 0, true), - bonus: format(aestheticMultiplier * (G.cubeBonusMultiplier[i]! - 1), accuracy[i]! + augmentAccuracy, true) - }) + const aestheticMultiplier = i === 1 || i === 8 || i === 9 ? 1 : 100; + DOMCacheGetOrSet(`cube${i}Bonus`).innerHTML = i18next.t( + `wowCubes.cubes.items.${i}`, + { + amount: format(cubeArray[i], 0, true), + bonus: format( + aestheticMultiplier * (G.cubeBonusMultiplier[i]! - 1), + accuracy[i]! + augmentAccuracy, + true + ), + } + ); } - DOMCacheGetOrSet('cubeBlessingsTotal').innerHTML = i18next.t('wowCubes.cubes.total', { - amount: format(sumContents(cubeArray.slice(1) as number[]), 0, true) - }) - break + DOMCacheGetOrSet("cubeBlessingsTotal").innerHTML = i18next.t( + "wowCubes.cubes.total", + { + amount: format(sumContents(cubeArray.slice(1) as number[]), 0, true), + } + ); + break; } case 1: { if (player.autoOpenTesseracts) { - DOMCacheGetOrSet('openTesseracts').textContent = i18next.t('wowCubes.autoOn', { - percent: format(player.openTesseracts, 0) - }) + DOMCacheGetOrSet("openTesseracts").textContent = i18next.t( + "wowCubes.autoOn", + { + percent: format(player.openTesseracts, 0), + } + ); } - DOMCacheGetOrSet('tesseractQuantity').innerHTML = i18next.t('wowCubes.tesseracts.inventory', { - amount: format(player.wowTesseracts, 0, true) - }) + DOMCacheGetOrSet("tesseractQuantity").innerHTML = i18next.t( + "wowCubes.tesseracts.inventory", + { + amount: format(player.wowTesseracts, 0, true), + } + ); const tesseractArray = [ null, player.tesseractBlessings.accelerator, @@ -707,33 +1020,53 @@ export const visualUpdateCubes = () => { player.tesseractBlessings.antSacrifice, player.tesseractBlessings.antELO, player.tesseractBlessings.talismanBonus, - player.tesseractBlessings.globalSpeed - ] - accuracy = [null, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] + player.tesseractBlessings.globalSpeed, + ]; + accuracy = [null, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]; for (let i = 1; i <= 10; i++) { - let augmentAccuracy = 0 + let augmentAccuracy = 0; if (tesseractArray[i]! >= 1000 && i !== 6) { - augmentAccuracy += 2 + augmentAccuracy += 2; } - DOMCacheGetOrSet(`tesseract${i}Bonus`).innerHTML = i18next.t(`wowCubes.tesseracts.items.${i}`, { - amount: format(tesseractArray[i], 0, true), - bonus: format(100 * (G.tesseractBonusMultiplier[i]! - 1), accuracy[i]! + augmentAccuracy, true) - }) + DOMCacheGetOrSet(`tesseract${i}Bonus`).innerHTML = i18next.t( + `wowCubes.tesseracts.items.${i}`, + { + amount: format(tesseractArray[i], 0, true), + bonus: format( + 100 * (G.tesseractBonusMultiplier[i]! - 1), + accuracy[i]! + augmentAccuracy, + true + ), + } + ); } - DOMCacheGetOrSet('tesseractBlessingsTotal').innerHTML = i18next.t('wowCubes.tesseracts.total', { - amount: format(sumContents(tesseractArray.slice(1) as number[]), 0, true) - }) - break + DOMCacheGetOrSet("tesseractBlessingsTotal").innerHTML = i18next.t( + "wowCubes.tesseracts.total", + { + amount: format( + sumContents(tesseractArray.slice(1) as number[]), + 0, + true + ), + } + ); + break; } case 2: { if (player.autoOpenHypercubes) { - DOMCacheGetOrSet('openHypercubes').textContent = i18next.t('wowCubes.autoOn', { - percent: format(player.openHypercubes, 0) - }) + DOMCacheGetOrSet("openHypercubes").textContent = i18next.t( + "wowCubes.autoOn", + { + percent: format(player.openHypercubes, 0), + } + ); } - DOMCacheGetOrSet('hypercubeQuantity').innerHTML = i18next.t('wowCubes.hypercubes.inventory', { - amount: format(player.wowHypercubes, 0, true) - }) + DOMCacheGetOrSet("hypercubeQuantity").innerHTML = i18next.t( + "wowCubes.hypercubes.inventory", + { + amount: format(player.wowHypercubes, 0, true), + } + ); const hypercubeArray = [ null, player.hypercubeBlessings.accelerator, @@ -745,33 +1078,53 @@ export const visualUpdateCubes = () => { player.hypercubeBlessings.antSacrifice, player.hypercubeBlessings.antELO, player.hypercubeBlessings.talismanBonus, - player.hypercubeBlessings.globalSpeed - ] - accuracy = [null, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2] + player.hypercubeBlessings.globalSpeed, + ]; + accuracy = [null, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]; for (let i = 1; i <= 10; i++) { - let augmentAccuracy = 0 + let augmentAccuracy = 0; if (hypercubeArray[i]! >= 1000) { - augmentAccuracy += 2 + augmentAccuracy += 2; } - DOMCacheGetOrSet(`hypercube${i}Bonus`).innerHTML = i18next.t(`wowCubes.hypercubes.items.${i}`, { - amount: format(hypercubeArray[i], 0, true), - bonus: format(100 * (G.hypercubeBonusMultiplier[i]! - 1), accuracy[i]! + augmentAccuracy, true) - }) + DOMCacheGetOrSet(`hypercube${i}Bonus`).innerHTML = i18next.t( + `wowCubes.hypercubes.items.${i}`, + { + amount: format(hypercubeArray[i], 0, true), + bonus: format( + 100 * (G.hypercubeBonusMultiplier[i]! - 1), + accuracy[i]! + augmentAccuracy, + true + ), + } + ); } - DOMCacheGetOrSet('hypercubeBlessingsTotal').innerHTML = i18next.t('wowCubes.hypercubes.total', { - amount: format(sumContents(hypercubeArray.slice(1) as number[]), 0, true) - }) - break + DOMCacheGetOrSet("hypercubeBlessingsTotal").innerHTML = i18next.t( + "wowCubes.hypercubes.total", + { + amount: format( + sumContents(hypercubeArray.slice(1) as number[]), + 0, + true + ), + } + ); + break; } case 3: { if (player.autoOpenPlatonicsCubes) { - DOMCacheGetOrSet('openPlatonicCube').textContent = i18next.t('wowCubes.autoOn', { - percent: format(player.openPlatonicsCubes, 0) - }) + DOMCacheGetOrSet("openPlatonicCube").textContent = i18next.t( + "wowCubes.autoOn", + { + percent: format(player.openPlatonicsCubes, 0), + } + ); } - DOMCacheGetOrSet('platonicQuantity').innerHTML = i18next.t('wowCubes.platonics.inventory', { - amount: format(player.wowPlatonicCubes, 0, true) - }) + DOMCacheGetOrSet("platonicQuantity").innerHTML = i18next.t( + "wowCubes.platonics.inventory", + { + amount: format(player.wowPlatonicCubes, 0, true), + } + ); const platonicArray = [ player.platonicBlessings.cubes, player.platonicBlessings.tesseracts, @@ -780,417 +1133,620 @@ export const visualUpdateCubes = () => { player.platonicBlessings.hypercubeBonus, player.platonicBlessings.taxes, player.platonicBlessings.scoreBonus, - player.platonicBlessings.globalSpeed - ] - const DRThreshold = [4e6, 4e6, 4e6, 8e4, 1e4, 1e4, 1e4, 1e4] - accuracy = [5, 5, 5, 5, 2, 3, 3, 2] + player.platonicBlessings.globalSpeed, + ]; + const DRThreshold = [4e6, 4e6, 4e6, 8e4, 1e4, 1e4, 1e4, 1e4]; + accuracy = [5, 5, 5, 5, 2, 3, 3, 2]; for (let i = 0; i < platonicArray.length; i++) { - let augmentAccuracy = 0 + let augmentAccuracy = 0; if (platonicArray[i] >= DRThreshold[i]) { - augmentAccuracy += 1 + augmentAccuracy += 1; } - DOMCacheGetOrSet(`platonicCube${i + 1}Bonus`).innerHTML = i18next.t(`wowCubes.platonics.items.${i + 1}`, { - amount: format(platonicArray[i], 0, true), - bonus: format(100 * (G.platonicBonusMultiplier[i] - 1), accuracy[i]! + augmentAccuracy, true) - }) + DOMCacheGetOrSet(`platonicCube${i + 1}Bonus`).innerHTML = i18next.t( + `wowCubes.platonics.items.${i + 1}`, + { + amount: format(platonicArray[i], 0, true), + bonus: format( + 100 * (G.platonicBonusMultiplier[i] - 1), + accuracy[i]! + augmentAccuracy, + true + ), + } + ); } - DOMCacheGetOrSet('platonicBlessingsTotal').innerHTML = i18next.t('wowCubes.platonics.total', { - amount: format(sumContents(platonicArray), 0, true) - }) - break + DOMCacheGetOrSet("platonicBlessingsTotal").innerHTML = i18next.t( + "wowCubes.platonics.total", + { + amount: format(sumContents(platonicArray), 0, true), + } + ); + break; } case 4: - DOMCacheGetOrSet('cubeAmount2').textContent = `You have ${format(player.wowCubes, 0, true)} Wow! Cubes =)` - break + DOMCacheGetOrSet("cubeAmount2").textContent = `You have ${format( + player.wowCubes, + 0, + true + )} Wow! Cubes =)`; + break; case 5: - break + break; case 6: - DOMCacheGetOrSet('hepteractQuantity').innerHTML = i18next.t('wowCubes.hepteractForge.youPossessHepteracts', { - x: format(player.wowAbyssals, 0, true) - }) + DOMCacheGetOrSet("hepteractQuantity").innerHTML = i18next.t( + "wowCubes.hepteractForge.youPossessHepteracts", + { + x: format(player.wowAbyssals, 0, true), + } + ); // Update the grid hepteractTypeList.forEach((type) => { - UpdateHeptGridValues(type) - }) + UpdateHeptGridValues(type); + }); // orbs - DOMCacheGetOrSet('heptGridOrbBalance').textContent = format(player.overfluxOrbs) - DOMCacheGetOrSet('heptGridOrbEffect').textContent = `${ - format(100 * (-1 + calculateCubeQuarkMultiplier()), 2, true) - }%` + DOMCacheGetOrSet("heptGridOrbBalance").textContent = format( + player.overfluxOrbs + ); + DOMCacheGetOrSet("heptGridOrbEffect").textContent = `${format( + 100 * (-1 + calculateCubeQuarkMultiplier()), + 2, + true + )}%`; // powder - DOMCacheGetOrSet('heptGridPowderBalance').textContent = format(player.overfluxPowder) - DOMCacheGetOrSet('heptGridPowderWarps').textContent = format(player.dailyPowderResetUses) - break + DOMCacheGetOrSet("heptGridPowderBalance").textContent = format( + player.overfluxPowder + ); + DOMCacheGetOrSet("heptGridPowderWarps").textContent = format( + player.dailyPowderResetUses + ); + break; default: - break + break; } -} +}; const UpdateHeptGridValues = (type: hepteractTypes) => { - const text = `${type}ProgressBarText` - const bar = `${type}ProgressBar` - const textEl = DOMCacheGetOrSet(text) - const barEl = DOMCacheGetOrSet(bar) - const unlocked = player.hepteractCrafts[type].UNLOCKED + const text = `${type}ProgressBarText`; + const bar = `${type}ProgressBar`; + const textEl = DOMCacheGetOrSet(text); + const barEl = DOMCacheGetOrSet(bar); + const unlocked = player.hepteractCrafts[type].UNLOCKED; if (!unlocked) { - textEl.textContent = 'LOCKED' - barEl.style.width = '100%' - barEl.style.backgroundColor = 'var(--hepteract-bar-red)' + textEl.textContent = "LOCKED"; + barEl.style.width = "100%"; + barEl.style.backgroundColor = "var(--hepteract-bar-red)"; } else { - const balance = player.hepteractCrafts[type].BAL - const cap = player.hepteractCrafts[type].computeActualCap() - const barWidth = Math.round((balance / cap) * 100) + const balance = player.hepteractCrafts[type].BAL; + const cap = player.hepteractCrafts[type].computeActualCap(); + const barWidth = Math.round((balance / cap) * 100); - let barColor = '' + let barColor = ""; if (barWidth < 34) { - barColor = 'var(--hepteract-bar-red)' + barColor = "var(--hepteract-bar-red)"; } else if (barWidth >= 34 && barWidth < 68) { - barColor = 'var(--hepteract-bar-yellow)' + barColor = "var(--hepteract-bar-yellow)"; } else { - barColor = 'var(--hepteract-bar-green)' + barColor = "var(--hepteract-bar-green)"; } - textEl.textContent = `${format(balance)} / ${format(cap)}` - barEl.style.width = `${barWidth}%` - barEl.style.backgroundColor = barColor + textEl.textContent = `${format(balance)} / ${format(cap)}`; + barEl.style.width = `${barWidth}%`; + barEl.style.backgroundColor = barColor; } -} +}; export const visualUpdateCorruptions = () => { if (G.currentTab !== Tabs.Corruption) { - return + return; } - const metaData = CalcCorruptionStuff() - const ascCount = calcAscensionCount() - DOMCacheGetOrSet('autoAscend').innerHTML = player.autoAscendMode === 'c10Completions' - ? i18next.t('corruptions.autoAscend.c10Completions', { - input: format(player.autoAscendThreshold), - completions: format(player.challengecompletions[10]) - }) - : i18next.t('corruptions.autoAscend.realTime', { - input: format(player.autoAscendThreshold), - time: format(player.ascensionCounterRealReal) - }) + const metaData = CalcCorruptionStuff(); + const ascCount = calcAscensionCount(); + DOMCacheGetOrSet("autoAscend").innerHTML = + player.autoAscendMode === "c10Completions" + ? i18next.t("corruptions.autoAscend.c10Completions", { + input: format(player.autoAscendThreshold), + completions: format(player.challengecompletions[10]), + }) + : i18next.t("corruptions.autoAscend.realTime", { + input: format(player.autoAscendThreshold), + time: format(player.ascensionCounterRealReal), + }); /*DOMCacheGetOrSet('autoAscendText').textContent = player.autoAscendMode === 'c10Completions' ? ' you\'ve completed Sadistic Challenge I a total of ' : ' the timer is at least '; DOMCacheGetOrSet('autoAscendMetric').textContent = format(player.autoAscendThreshold); DOMCacheGetOrSet('autoAscendText2').textContent = player.autoAscendMode === 'c10Completions' ? ' times, Currently ' : ' seconds (Real-time), Currently '; DOMCacheGetOrSet('autoAscendMetric2').textContent = player.autoAscendMode === 'c10Completions' ? String(player.challengecompletions[10]) : format(player.ascensionCounterRealReal);*/ - DOMCacheGetOrSet('corruptionBank').innerHTML = i18next.t('corruptions.corruptionBank', { - number: format(metaData[0], 0, true) - }) - DOMCacheGetOrSet('corruptionScore').innerHTML = i18next.t('corruptions.corruptionScore', { - ascScore: format(metaData[1], 1, true), - corrMult: format(metaData[2], 1, true), - bonusMult: format(metaData[9], 2, true), - totalScore: format(metaData[3], 1, true) - }) - DOMCacheGetOrSet('corruptionCubes').innerHTML = i18next.t('corruptions.corruptionCubes', { - cubeAmount: format(metaData[4], 0, true) - }) - DOMCacheGetOrSet('corruptionTesseracts').innerHTML = i18next.t('corruptions.corruptionTesseracts', { - tesseractAmount: format(metaData[5], 0, true) - }) - DOMCacheGetOrSet('corruptionHypercubes').innerHTML = i18next.t('corruptions.corruptionHypercubes', { - hypercubeAmount: format(metaData[6], 0, true) - }) - DOMCacheGetOrSet('corruptionPlatonicCubes').innerHTML = i18next.t('corruptions.corruptionPlatonics', { - platonicAmount: format(metaData[7], 0, true) - }) - DOMCacheGetOrSet('corruptionHepteracts').innerHTML = i18next.t('corruptions.corruptionHepteracts', { - hepteractAmount: format(metaData[8], 0, true) - }) - DOMCacheGetOrSet('corruptionAntExponent').innerHTML = i18next.t('corruptions.antExponent', { - exponent: format( - (1 - 0.9 / 90 * sumContents(player.usedCorruptions)) * G.extinctionMultiplier[player.usedCorruptions[7]], - 3 - ) - }) - DOMCacheGetOrSet('corruptionSpiritBonus').innerHTML = i18next.t('corruptions.spiritBonus', { - multiplier: format(calculateCorruptionPoints() / 400, 2, true) - }) - DOMCacheGetOrSet('corruptionAscensionCount').style.display = ascCount > 1 ? 'block' : 'none' + DOMCacheGetOrSet("corruptionBank").innerHTML = i18next.t( + "corruptions.corruptionBank", + { + number: format(metaData[0], 0, true), + } + ); + DOMCacheGetOrSet("corruptionScore").innerHTML = i18next.t( + "corruptions.corruptionScore", + { + ascScore: format(metaData[1], 1, true), + corrMult: format(metaData[2], 1, true), + bonusMult: format(metaData[9], 2, true), + totalScore: format(metaData[3], 1, true), + } + ); + DOMCacheGetOrSet("corruptionCubes").innerHTML = i18next.t( + "corruptions.corruptionCubes", + { + cubeAmount: format(metaData[4], 0, true), + } + ); + DOMCacheGetOrSet("corruptionTesseracts").innerHTML = i18next.t( + "corruptions.corruptionTesseracts", + { + tesseractAmount: format(metaData[5], 0, true), + } + ); + DOMCacheGetOrSet("corruptionHypercubes").innerHTML = i18next.t( + "corruptions.corruptionHypercubes", + { + hypercubeAmount: format(metaData[6], 0, true), + } + ); + DOMCacheGetOrSet("corruptionPlatonicCubes").innerHTML = i18next.t( + "corruptions.corruptionPlatonics", + { + platonicAmount: format(metaData[7], 0, true), + } + ); + DOMCacheGetOrSet("corruptionHepteracts").innerHTML = i18next.t( + "corruptions.corruptionHepteracts", + { + hepteractAmount: format(metaData[8], 0, true), + } + ); + DOMCacheGetOrSet("corruptionAntExponent").innerHTML = i18next.t( + "corruptions.antExponent", + { + exponent: format( + (1 - (0.9 / 90) * sumContents(player.usedCorruptions)) * + G.extinctionMultiplier[player.usedCorruptions[7]], + 3 + ), + } + ); + DOMCacheGetOrSet("corruptionSpiritBonus").innerHTML = i18next.t( + "corruptions.spiritBonus", + { + multiplier: format(calculateCorruptionPoints() / 400, 2, true), + } + ); + DOMCacheGetOrSet("corruptionAscensionCount").style.display = + ascCount > 1 ? "block" : "none"; if (ascCount > 1) { - DOMCacheGetOrSet('corruptionAscensionCount').innerHTML = i18next.t('corruptions.ascensionCount', { - ascCount: format(calcAscensionCount()) - }) + DOMCacheGetOrSet("corruptionAscensionCount").innerHTML = i18next.t( + "corruptions.ascensionCount", + { + ascCount: format(calcAscensionCount()), + } + ); } -} +}; export const visualUpdateSettings = () => { if (G.currentTab !== Tabs.Settings) { - return + return; } if (player.subtabNumber === 0) { - DOMCacheGetOrSet('saveString').textContent = i18next.t('settings.currently', { - x: player.saveString.replace('$VERSION$', `v${version}`) - }) - - const quarkData = quarkHandler() - const onExportQuarks = quarkData.gain - const maxExportQuarks = quarkData.capacity - - let goldenQuarkMultiplier = 1 - goldenQuarkMultiplier *= 1 + player.worlds.BONUS / 100 - goldenQuarkMultiplier *= player.highestSingularityCount >= 100 ? 1 + player.highestSingularityCount / 50 : 1 - - DOMCacheGetOrSet('quarktimerdisplay').textContent = i18next.t('settings.exportQuark', { - x: format(3600 / (quarkData.perHour) - (player.quarkstimer % (3600.00001 / (quarkData.perHour))), 2), - y: player.worlds.toString(1) - }) - DOMCacheGetOrSet('quarktimeramount').textContent = i18next.t('settings.quarksOnExport', { - x: player.worlds.toString(onExportQuarks), - y: player.worlds.toString(maxExportQuarks) - }) - - DOMCacheGetOrSet('goldenQuarkTimerDisplay').textContent = i18next.t('settings.exportGoldenQuark', { - x: format( - 3600 / Math.max(1, +player.singularityUpgrades.goldenQuarks3.getEffect().bonus) - - (player.goldenQuarksTimer - % (3600.00001 / Math.max(1, +player.singularityUpgrades.goldenQuarks3.getEffect().bonus))) - ), - y: format(goldenQuarkMultiplier, 2, true) - }) - - DOMCacheGetOrSet('goldenQuarkTimerAmount').textContent = i18next.t('settings.goldenQuarksOnExport', { - x: format( - Math.floor(player.goldenQuarksTimer * +player.singularityUpgrades.goldenQuarks3.getEffect().bonus / 3600) - * goldenQuarkMultiplier, - 2 - ), - y: format(Math.floor(168 * +player.singularityUpgrades.goldenQuarks3.getEffect().bonus * goldenQuarkMultiplier)) - }) + DOMCacheGetOrSet("saveString").textContent = i18next.t( + "settings.currently", + { + x: player.saveString.replace("$VERSION$", `v${version}`), + } + ); + + const quarkData = quarkHandler(); + const onExportQuarks = quarkData.gain; + const maxExportQuarks = quarkData.capacity; + + let goldenQuarkMultiplier = 1; + goldenQuarkMultiplier *= 1 + player.worlds.BONUS / 100; + goldenQuarkMultiplier *= + player.highestSingularityCount >= 100 + ? 1 + player.highestSingularityCount / 50 + : 1; + + DOMCacheGetOrSet("quarktimerdisplay").textContent = i18next.t( + "settings.exportQuark", + { + x: format( + 3600 / quarkData.perHour - + (player.quarkstimer % (3600.00001 / quarkData.perHour)), + 2 + ), + y: player.worlds.toString(1), + } + ); + DOMCacheGetOrSet("quarktimeramount").textContent = i18next.t( + "settings.quarksOnExport", + { + x: player.worlds.toString(onExportQuarks), + y: player.worlds.toString(maxExportQuarks), + } + ); + + DOMCacheGetOrSet("goldenQuarkTimerDisplay").textContent = i18next.t( + "settings.exportGoldenQuark", + { + x: format( + 3600 / + Math.max( + 1, + +player.singularityUpgrades.goldenQuarks3.getEffect().bonus + ) - + (player.goldenQuarksTimer % + (3600.00001 / + Math.max( + 1, + +player.singularityUpgrades.goldenQuarks3.getEffect().bonus + ))) + ), + y: format(goldenQuarkMultiplier, 2, true), + } + ); + + DOMCacheGetOrSet("goldenQuarkTimerAmount").textContent = i18next.t( + "settings.goldenQuarksOnExport", + { + x: format( + Math.floor( + (player.goldenQuarksTimer * + +player.singularityUpgrades.goldenQuarks3.getEffect().bonus) / + 3600 + ) * goldenQuarkMultiplier, + 2 + ), + y: format( + Math.floor( + 168 * + +player.singularityUpgrades.goldenQuarks3.getEffect().bonus * + goldenQuarkMultiplier + ) + ), + } + ); } if (player.subtabNumber === 3) { - loadStatisticsUpdate() + loadStatisticsUpdate(); } -} +}; export const visualUpdateSingularity = () => { if (G.currentTab !== Tabs.Singularity) { - return + return; } if (player.subtabNumber === 0) { - DOMCacheGetOrSet('goldenQuarkamount').textContent = i18next.t('singularity.goldenQuarkAmount', { - goldenQuarks: format(player.goldenQuarks, 0, true) - }) + DOMCacheGetOrSet("goldenQuarkamount").textContent = i18next.t( + "singularity.goldenQuarkAmount", + { + goldenQuarks: format(player.goldenQuarks, 0, true), + } + ); - const keys = Object.keys(player.singularityUpgrades) as (keyof Player['singularityUpgrades'])[] - const val = G.shopEnhanceVision + const keys = Object.keys( + player.singularityUpgrades + ) as (keyof Player["singularityUpgrades"])[]; + const val = G.shopEnhanceVision; for (const key of keys) { - if (key === 'offeringAutomatic') { - continue + if (key === "offeringAutomatic") { + continue; } - const singItem = player.singularityUpgrades[key] - const el = DOMCacheGetOrSet(`${String(key)}`) - if (singItem.maxLevel !== -1 && singItem.level >= singItem.computeMaxLevel()) { - el.style.filter = val ? 'brightness(.9)' : 'none' - } else if (singItem.getCostTNL() > player.goldenQuarks || player.singularityCount < singItem.minimumSingularity) { - el.style.filter = val ? 'grayscale(.9) brightness(.8)' : 'none' - } else if (singItem.maxLevel === -1 || singItem.level < singItem.computeMaxLevel()) { + const singItem = player.singularityUpgrades[key]; + const el = DOMCacheGetOrSet(`${String(key)}`); + if ( + singItem.maxLevel !== -1 && + singItem.level >= singItem.computeMaxLevel() + ) { + el.style.filter = val ? "brightness(.9)" : "none"; + } else if ( + singItem.getCostTNL() > player.goldenQuarks || + player.singularityCount < singItem.minimumSingularity + ) { + el.style.filter = val ? "grayscale(.9) brightness(.8)" : "none"; + } else if ( + singItem.maxLevel === -1 || + singItem.level < singItem.computeMaxLevel() + ) { if (singItem.freeLevels > singItem.level) { - el.style.filter = val ? 'blur(1px) invert(.9) saturate(200)' : 'none' + el.style.filter = val ? "blur(1px) invert(.9) saturate(200)" : "none"; } else { - el.style.filter = val ? 'invert(.9) brightness(1.1)' : 'none' + el.style.filter = val ? "invert(.9) brightness(1.1)" : "none"; } } } } if (player.subtabNumber === 2) { - const keys = Object.keys(player.octeractUpgrades) as (keyof Player['octeractUpgrades'])[] - const val = G.shopEnhanceVision + const keys = Object.keys( + player.octeractUpgrades + ) as (keyof Player["octeractUpgrades"])[]; + const val = G.shopEnhanceVision; for (const key of keys) { - const octItem = player.octeractUpgrades[key] - const el = DOMCacheGetOrSet(`${String(key)}`) + const octItem = player.octeractUpgrades[key]; + const el = DOMCacheGetOrSet(`${String(key)}`); if (octItem.maxLevel !== -1 && octItem.level >= octItem.maxLevel) { - el.style.filter = val ? 'brightness(.9)' : 'none' + el.style.filter = val ? "brightness(.9)" : "none"; } else if (octItem.getCostTNL() > player.wowOcteracts) { - el.style.filter = val ? 'grayscale(.9) brightness(.8)' : 'none' + el.style.filter = val ? "grayscale(.9) brightness(.8)" : "none"; } else if (octItem.maxLevel === -1 || octItem.level < octItem.maxLevel) { if (octItem.freeLevels > octItem.level) { - el.style.filter = val ? 'blur(2px) invert(.9) saturate(200)' : 'none' + el.style.filter = val ? "blur(2px) invert(.9) saturate(200)" : "none"; } else { - el.style.filter = val ? 'invert(.9) brightness(1.1)' : 'none' + el.style.filter = val ? "invert(.9) brightness(1.1)" : "none"; } } } } -} +}; export const shopMouseover = (value: boolean) => { - G.shopEnhanceVision = value -} + G.shopEnhanceVision = value; +}; export const visualUpdateOcteracts = () => { if (G.currentTab !== Tabs.Singularity) { - return + return; } - DOMCacheGetOrSet('octeractAmount').innerHTML = i18next.t('octeract.amount', { - octeracts: format(player.wowOcteracts, 2, true, true, true) - }) - - const perSecond = octeractGainPerSecond() - - DOMCacheGetOrSet('secondsPerOcteract').style.display = perSecond < 1 ? 'block' : 'none' - DOMCacheGetOrSet('secondsPerOcteract').innerHTML = i18next.t('octeract.secondsPerOcteract', { - seconds: format(1 / perSecond, 2, true) - }) - DOMCacheGetOrSet('octeractPerSeconds').style.display = perSecond >= 1 ? 'block' : 'none' - DOMCacheGetOrSet('octeractPerSeconds').innerHTML = i18next.t('octeract.octeractsPerSecond', { - octeracts: format(perSecond, 2, true) - }) - - const cTOCB = (calculateTotalOcteractCubeBonus() - 1) * 100 - const cTOQB = (calculateTotalOcteractQuarkBonus() - 1) * 100 - const cTOOB = (calculateTotalOcteractOfferingBonus() - 1) * 100 - const cTOOOB = (calculateTotalOcteractObtainiumBonus() - 1) * 100 - DOMCacheGetOrSet('totalOcteractAmount').innerHTML = i18next.t('octeract.totalGenerated', { - octeracts: format(player.totalWowOcteracts, 2, true, true, true) - }) - DOMCacheGetOrSet('totalOcteractCubeBonus').style.display = cTOCB >= 0.001 ? 'block' : 'none' - DOMCacheGetOrSet('totalOcteractQuarkBonus').style.display = cTOQB >= 0.001 ? 'block' : 'none' - DOMCacheGetOrSet('totalOcteractOfferingBonus').style.display = cTOOB >= 0.001 ? 'block' : 'none' - DOMCacheGetOrSet('totalOcteractObtainiumBonus').style.display = cTOOOB >= 0.001 ? 'block' : 'none' - DOMCacheGetOrSet('totalOcteractCubeBonus').innerHTML = i18next.t('octeract.generatedCubeBonus', { - cubeBonus: format(cTOCB, 3, true) - }) - DOMCacheGetOrSet('totalOcteractQuarkBonus').innerHTML = i18next.t('octeract.generatedQuarkBonus', { - quarkBonus: format(cTOQB, 3, true) - }) - DOMCacheGetOrSet('totalOcteractOfferingBonus').innerHTML = i18next.t('octeract.generatedOfferingBonus', { - offeringBonus: format(cTOOB, 3, true) - }) - DOMCacheGetOrSet('totalOcteractObtainiumBonus').innerHTML = i18next.t('octeract.generatedObtainiumBonus', { - obtainiumBonus: format(cTOOOB, 3, true) - }) -} + DOMCacheGetOrSet("octeractAmount").innerHTML = i18next.t("octeract.amount", { + octeracts: format(player.wowOcteracts, 2, true, true, true), + }); + + const perSecond = octeractGainPerSecond(); + + DOMCacheGetOrSet("secondsPerOcteract").style.display = + perSecond < 1 ? "block" : "none"; + DOMCacheGetOrSet("secondsPerOcteract").innerHTML = i18next.t( + "octeract.secondsPerOcteract", + { + seconds: format(1 / perSecond, 2, true), + } + ); + DOMCacheGetOrSet("octeractPerSeconds").style.display = + perSecond >= 1 ? "block" : "none"; + DOMCacheGetOrSet("octeractPerSeconds").innerHTML = i18next.t( + "octeract.octeractsPerSecond", + { + octeracts: format(perSecond, 2, true), + } + ); + + const cTOCB = (calculateTotalOcteractCubeBonus() - 1) * 100; + const cTOQB = (calculateTotalOcteractQuarkBonus() - 1) * 100; + const cTOOB = (calculateTotalOcteractOfferingBonus() - 1) * 100; + const cTOOOB = (calculateTotalOcteractObtainiumBonus() - 1) * 100; + DOMCacheGetOrSet("totalOcteractAmount").innerHTML = i18next.t( + "octeract.totalGenerated", + { + octeracts: format(player.totalWowOcteracts, 2, true, true, true), + } + ); + DOMCacheGetOrSet("totalOcteractCubeBonus").style.display = + cTOCB >= 0.001 ? "block" : "none"; + DOMCacheGetOrSet("totalOcteractQuarkBonus").style.display = + cTOQB >= 0.001 ? "block" : "none"; + DOMCacheGetOrSet("totalOcteractOfferingBonus").style.display = + cTOOB >= 0.001 ? "block" : "none"; + DOMCacheGetOrSet("totalOcteractObtainiumBonus").style.display = + cTOOOB >= 0.001 ? "block" : "none"; + DOMCacheGetOrSet("totalOcteractCubeBonus").innerHTML = i18next.t( + "octeract.generatedCubeBonus", + { + cubeBonus: format(cTOCB, 3, true), + } + ); + DOMCacheGetOrSet("totalOcteractQuarkBonus").innerHTML = i18next.t( + "octeract.generatedQuarkBonus", + { + quarkBonus: format(cTOQB, 3, true), + } + ); + DOMCacheGetOrSet("totalOcteractOfferingBonus").innerHTML = i18next.t( + "octeract.generatedOfferingBonus", + { + offeringBonus: format(cTOOB, 3, true), + } + ); + DOMCacheGetOrSet("totalOcteractObtainiumBonus").innerHTML = i18next.t( + "octeract.generatedObtainiumBonus", + { + obtainiumBonus: format(cTOOOB, 3, true), + } + ); +}; export const visualUpdateAmbrosia = () => { if (G.currentTab !== Tabs.Singularity) { - return + return; } - const luck = player.caches.ambrosiaLuck.totalVal - const guaranteed = 1 + Math.floor(luck / 100) - const chance = luck - 100 * Math.floor(luck / 100) - const requiredTime = calculateRequiredBlueberryTime() - const cubePercent = 100 * (calculateAmbrosiaCubeMult() - 1) - const quarkPercent = 100 * (calculateAmbrosiaQuarkMult() - 1) - const availableBlueberries = player.caches.blueberryInventory.totalVal - player.spentBlueberries - DOMCacheGetOrSet('ambrosiaAmount').innerHTML = i18next.t('ambrosia.amount', { + const luck = player.caches.ambrosiaLuck.usedTotal; + const baseLuck = player.caches.ambrosiaLuck.totalVal; + const luckBonusPercent = + 100 * (player.caches.ambrosiaLuckAdditiveMult.totalVal - 1); + const guaranteed = 1 + Math.floor(luck / 100); + const chance = luck - 100 * Math.floor(luck / 100); + const requiredTime = calculateRequiredBlueberryTime(); + const cubePercent = 100 * (calculateAmbrosiaCubeMult() - 1); + const quarkPercent = 100 * (calculateAmbrosiaQuarkMult() - 1); + const availableBlueberries = + player.caches.blueberryInventory.totalVal - player.spentBlueberries; + + const extraLuckHTML = + luckBonusPercent > 0.01 + ? `[☘${format( + baseLuck, + 0, + true + )} +${format(luckBonusPercent, 0, true)}%]` + : ""; + + DOMCacheGetOrSet("ambrosiaAmount").innerHTML = i18next.t("ambrosia.amount", { ambrosia: format(player.ambrosia, 0, true), - lifetimeAmbrosia: format(player.lifetimeAmbrosia, 0, true) - }) - DOMCacheGetOrSet('ambrosiaChance').innerHTML = i18next.t('ambrosia.blueberryGeneration', { - chance: format(player.caches.ambrosiaGeneration.totalVal, 2, true) - }) - DOMCacheGetOrSet('ambrosiaAmountPerGeneration').innerHTML = i18next.t('ambrosia.perGen', { - guaranteed: format(guaranteed, 0, true), - extraChance: format(chance, 0, true), - ambrosiaLuck: format(luck, 0, true) - }) - DOMCacheGetOrSet('ambrosiaRNG').innerHTML = i18next.t('ambrosia.blueberrySecond', { - blueberrySecond: format(player.blueberryTime, 0, true), - thresholdTimer: format(requiredTime, 0, true) - }) - DOMCacheGetOrSet('ambrosiaRewards').innerHTML = i18next.t('ambrosia.bonuses', { - cube: format(cubePercent, 0, true), - quark: format(quarkPercent, 0, true) - }) - DOMCacheGetOrSet('ambrosiaBlueberries').innerHTML = i18next.t('ambrosia.availableBlueberries', { - availableBlueberries - }) -} + lifetimeAmbrosia: format(player.lifetimeAmbrosia, 0, true), + }); + DOMCacheGetOrSet("ambrosiaChance").innerHTML = i18next.t( + "ambrosia.blueberryGeneration", + { + chance: format(player.caches.ambrosiaGeneration.totalVal, 2, true), + } + ); + DOMCacheGetOrSet("ambrosiaAmountPerGeneration").innerHTML = i18next.t( + "ambrosia.perGen", + { + guaranteed: format(guaranteed, 0, true), + extraChance: format(chance, 0, true), + ambrosiaLuck: format(luck, 0, true), + extra: extraLuckHTML, + } + ); + DOMCacheGetOrSet("ambrosiaRNG").innerHTML = i18next.t( + "ambrosia.blueberrySecond", + { + blueberrySecond: format(player.blueberryTime, 0, true), + thresholdTimer: format(requiredTime, 0, true), + } + ); + DOMCacheGetOrSet("ambrosiaRewards").innerHTML = i18next.t( + "ambrosia.bonuses", + { + cube: format(cubePercent, 0, true), + quark: format(quarkPercent, 0, true), + } + ); + DOMCacheGetOrSet("ambrosiaBlueberries").innerHTML = i18next.t( + "ambrosia.availableBlueberries", + { + availableBlueberries, + } + ); +}; export const visualUpdateShop = () => { if (G.currentTab !== Tabs.Shop) { - return + return; } - DOMCacheGetOrSet('quarkamount').textContent = i18next.t('shop.youHaveQuarks', { x: format(player.worlds, 0, true) }) - DOMCacheGetOrSet('offeringpotionowned').textContent = format(player.shopUpgrades.offeringPotion, 0, true) - DOMCacheGetOrSet('obtainiumpotionowned').textContent = format(player.shopUpgrades.obtainiumPotion, 0, true) + DOMCacheGetOrSet("quarkamount").textContent = i18next.t( + "shop.youHaveQuarks", + { x: format(player.worlds, 0, true) } + ); + DOMCacheGetOrSet("offeringpotionowned").textContent = format( + player.shopUpgrades.offeringPotion, + 0, + true + ); + DOMCacheGetOrSet("obtainiumpotionowned").textContent = format( + player.shopUpgrades.obtainiumPotion, + 0, + true + ); // Create Keys with the correct type - const keys = Object.keys(player.shopUpgrades) as (keyof Player['shopUpgrades'])[] + const keys = Object.keys( + player.shopUpgrades + ) as (keyof Player["shopUpgrades"])[]; for (const key of keys) { // Create a copy of shopItem instead of accessing many times - const shopItem = shopData[key] + const shopItem = shopData[key]; if (shopItem.type === shopUpgradeTypes.CONSUMABLE) { const maxBuyablePotions = Math.min( Math.floor(Number(player.worlds) / getShopCosts(key)), shopItem.maxLevel - player.shopUpgrades[key] - ) - const el = DOMCacheGetOrSet(`buy${key.toLowerCase()}`) + ); + const el = DOMCacheGetOrSet(`buy${key.toLowerCase()}`); switch (player.shopBuyMaxToggle) { case false: - el.textContent = 'BUY: 100 Quarks Each' - break - case 'TEN': - el.textContent = `+${Math.min(10, maxBuyablePotions)} for ${ - format(getShopCosts(key) * Math.min(10, maxBuyablePotions), 0, true) - } Quarks` - break + el.textContent = "BUY: 100 Quarks Each"; + break; + case "TEN": + el.textContent = `+${Math.min(10, maxBuyablePotions)} for ${format( + getShopCosts(key) * Math.min(10, maxBuyablePotions), + 0, + true + )} Quarks`; + break; default: - el.textContent = `+${maxBuyablePotions} for ${format(getShopCosts(key) * maxBuyablePotions)} Quarks` + el.textContent = `+${maxBuyablePotions} for ${format( + getShopCosts(key) * maxBuyablePotions + )} Quarks`; } } if (shopItem.type === shopUpgradeTypes.UPGRADE) { - if (player.shopHideToggle && player.shopUpgrades[key] >= shopItem.maxLevel && !shopItem.refundable) { - DOMCacheGetOrSet(`${key}Hide`).style.display = 'none' - continue + if ( + player.shopHideToggle && + player.shopUpgrades[key] >= shopItem.maxLevel && + !shopItem.refundable + ) { + DOMCacheGetOrSet(`${key}Hide`).style.display = "none"; + continue; } else { - DOMCacheGetOrSet(`${key}Hide`).style.display = isShopUpgradeUnlocked(key) ? 'block' : 'none' + DOMCacheGetOrSet(`${key}Hide`).style.display = isShopUpgradeUnlocked( + key + ) + ? "block" + : "none"; } // Case: If max level is 1, then it can be considered a boolean "bought" or "not bought" item if (shopItem.maxLevel === 1) { // TODO(@KhafraDev): i18n - DOMCacheGetOrSet(`${key}Level`).textContent = player.shopUpgrades[key] >= shopItem.maxLevel - ? 'Bought!' - : 'Not Bought!' + DOMCacheGetOrSet(`${key}Level`).textContent = + player.shopUpgrades[key] >= shopItem.maxLevel + ? "Bought!" + : "Not Bought!"; } else { // Case: max level greater than 1, treat it as a fraction out of max level // TODO(@KhafraDev): i18n - DOMCacheGetOrSet(`${key}Level`).textContent = - `${(player.highestSingularityCount > 0 || player.ascensionCount > 0 ? '' : 'Level ')}${ - format(player.shopUpgrades[key]) - }/${format(shopItem.maxLevel)}` + DOMCacheGetOrSet(`${key}Level`).textContent = `${ + player.highestSingularityCount > 0 || player.ascensionCount > 0 + ? "" + : "Level " + }${format(player.shopUpgrades[key])}/${format(shopItem.maxLevel)}`; } // Handles Button - max level needs no price indicator, otherwise it's necessary - const buyMaxAmount = shopItem.maxLevel - player.shopUpgrades[key] - let buyData: IMultiBuy + const buyMaxAmount = shopItem.maxLevel - player.shopUpgrades[key]; + let buyData: IMultiBuy; switch (player.shopBuyMaxToggle) { case false: - DOMCacheGetOrSet(`${key}Button`).textContent = player.shopUpgrades[key] >= shopItem.maxLevel - ? i18next.t('shop.maxed') - : i18next.t('shop.upgradeFor', { x: format(getShopCosts(key)) }) - break - case 'TEN': + DOMCacheGetOrSet(`${key}Button`).textContent = + player.shopUpgrades[key] >= shopItem.maxLevel + ? i18next.t("shop.maxed") + : i18next.t("shop.upgradeFor", { x: format(getShopCosts(key)) }); + break; + case "TEN": buyData = calculateSummationNonLinear( player.shopUpgrades[key], shopItem.price, +player.worlds, shopItem.priceIncrease / shopItem.price, Math.min(10, buyMaxAmount) - ) - DOMCacheGetOrSet(`${key}Button`).textContent = player.shopUpgrades[key] >= shopItem.maxLevel - ? i18next.t('shop.maxed') - : i18next.t('shop.plusForQuarks', { - x: format(buyData.levelCanBuy - player.shopUpgrades[key], 0, true), - y: format(buyData.cost) - }) - break + ); + DOMCacheGetOrSet(`${key}Button`).textContent = + player.shopUpgrades[key] >= shopItem.maxLevel + ? i18next.t("shop.maxed") + : i18next.t("shop.plusForQuarks", { + x: format( + buyData.levelCanBuy - player.shopUpgrades[key], + 0, + true + ), + y: format(buyData.cost), + }); + break; default: buyData = calculateSummationNonLinear( player.shopUpgrades[key], @@ -1198,21 +1754,28 @@ export const visualUpdateShop = () => { +player.worlds, shopItem.priceIncrease / shopItem.price, buyMaxAmount - ) - DOMCacheGetOrSet(`${key}Button`).textContent = player.shopUpgrades[key] >= shopItem.maxLevel - ? i18next.t('shop.maxed') - : i18next.t('shop.plusForQuarks', { - x: format(buyData.levelCanBuy - player.shopUpgrades[key], 0, true), - y: format(buyData.cost) - }) + ); + DOMCacheGetOrSet(`${key}Button`).textContent = + player.shopUpgrades[key] >= shopItem.maxLevel + ? i18next.t("shop.maxed") + : i18next.t("shop.plusForQuarks", { + x: format( + buyData.levelCanBuy - player.shopUpgrades[key], + 0, + true + ), + y: format(buyData.cost), + }); } } } - DOMCacheGetOrSet('buySingularityQuarksAmount').textContent = `${player.goldenQuarks < 1000 ? 'Owned: ' : ''}${ - format(player.goldenQuarks) - }` - DOMCacheGetOrSet('buySingularityQuarksButton').textContent = `Buy! ${format(getGoldenQuarkCost().cost)} Quarks Each` -} + DOMCacheGetOrSet("buySingularityQuarksAmount").textContent = `${ + player.goldenQuarks < 1000 ? "Owned: " : "" + }${format(player.goldenQuarks)}`; + DOMCacheGetOrSet("buySingularityQuarksButton").textContent = `Buy! ${format( + getGoldenQuarkCost().cost + )} Quarks Each`; +}; -export const visualUpdateEvent = () => {} +export const visualUpdateEvent = () => {}; diff --git a/src/singularity.ts b/src/singularity.ts index d270bd317..dd7f7b961 100644 --- a/src/singularity.ts +++ b/src/singularity.ts @@ -2068,6 +2068,24 @@ export const singularityPerks: SingularityPerk[] = [ }, ID: "platonicClones", }, + { + name: () => { + return i18next.t("singularity.perkNames.dilatedFiveLeaf"); + }, + levels: [100, 200, 250, 260, 266], + description: (n: number, levels: number[]) => { + for (let i = levels.length - 1; i >= 0; i--) { + if (n >= levels[i]) { + return i18next.t("singularity.perks.dilatedFiveLeaf.desc", { + percent: i + 1, + }); + } + } + + return i18next.t("singularity.perks.evenMoreQuarks.bug"); + }, + ID: "dilatedFiveLeaf", + }, { name: () => { return i18next.t("singularity.perkNames.platSigma"); @@ -2175,6 +2193,16 @@ export const singularityPerks: SingularityPerk[] = [ }, ID: "skrauQ", }, + { + name: () => { + return i18next.t("singularity.perkNames.twoHundredSixtyNine"); + }, + levels: [269], + description: () => { + return i18next.t("singularity.perks.twoHundredSixtyNine"); + }, + ID: "twoHundredSixtyNine", + }, ]; // Placeholder text for Perk Info that is seen upon first load, check Line 645 EventListeners.ts for actual Perk Info code. @@ -2280,7 +2308,7 @@ const handlePerks = (singularityCount: number) => { const nextUnlockedId = DOMCacheGetOrSet("singualrityUnlockNext"); if (singularityCountForNextPerk) { nextUnlockedId.style.display = ""; - nextUnlockedId.textContent = i18next.t("singularity.perks.unlockedIn", { + nextUnlockedId.innerHTML = i18next.t("singularity.perks.unlockedIn", { sing: singularityCountForNextPerk, }); } else { @@ -2289,7 +2317,7 @@ const handlePerks = (singularityCount: number) => { const countNext = DOMCacheGetOrSet("singualrityImproveNext"); if (singularityCountForNextPerkUpgrade < Infinity) { countNext.style.display = ""; - countNext.textContent = i18next.t("singularity.perks.improvedIn", { + countNext.innerHTML = i18next.t("singularity.perks.improvedIn", { sing: singularityCountForNextPerkUpgrade, }); } else { diff --git a/src/types/Synergism.d.ts b/src/types/Synergism.d.ts index cc64aed61..f80f95060 100644 --- a/src/types/Synergism.d.ts +++ b/src/types/Synergism.d.ts @@ -1,1011 +1,1044 @@ -import type Decimal from 'break_infinity.js' -import { BlueberryUpgrade } from '../BlueberryUpgrades' -import type { WowCubes, WowHypercubes, WowPlatonicCubes, WowTesseracts } from '../CubeExperimental' -import { HepteractCraft } from '../Hepteracts' -import { Category, ResetHistoryEntryUnion } from '../History' -import { OcteractUpgrade } from '../Octeracts' -import { IPlatBaseCost } from '../Platonic' -import type { QuarkHandler } from '../Quark' -import { SingularityUpgrade } from '../singularity' -import { SingularityChallenge, singularityChallengeData } from '../SingularityChallenges' -import { AmbrosiaGenerationCache, AmbrosiaLuckCache, BlueberryInventoryCache } from '../StatCache' -import type { Tabs } from '../Tabs' +import type Decimal from "break_infinity.js"; +import { BlueberryUpgrade } from "../BlueberryUpgrades"; +import type { + WowCubes, + WowHypercubes, + WowPlatonicCubes, + WowTesseracts, +} from "../CubeExperimental"; +import { HepteractCraft } from "../Hepteracts"; +import { Category, ResetHistoryEntryUnion } from "../History"; +import { OcteractUpgrade } from "../Octeracts"; +import { IPlatBaseCost } from "../Platonic"; +import type { QuarkHandler } from "../Quark"; +import { SingularityUpgrade } from "../singularity"; +import { + SingularityChallenge, + singularityChallengeData, +} from "../SingularityChallenges"; +import { + AmbrosiaGenerationCache, + AmbrosiaLuckAdditiveMultCache, + AmbrosiaLuckCache, + BlueberryInventoryCache, +} from "../StatCache"; +import type { Tabs } from "../Tabs"; export interface Player { - firstPlayed: string - worlds: QuarkHandler - coins: Decimal - coinsThisPrestige: Decimal - coinsThisTranscension: Decimal - coinsThisReincarnation: Decimal - coinsTotal: Decimal - - firstOwnedCoin: number - firstGeneratedCoin: Decimal - firstCostCoin: Decimal - firstProduceCoin: number - - secondOwnedCoin: number - secondGeneratedCoin: Decimal - secondCostCoin: Decimal - secondProduceCoin: number - - thirdOwnedCoin: number - thirdGeneratedCoin: Decimal - thirdCostCoin: Decimal - thirdProduceCoin: number - - fourthOwnedCoin: number - fourthGeneratedCoin: Decimal - fourthCostCoin: Decimal - fourthProduceCoin: number - - fifthOwnedCoin: number - fifthGeneratedCoin: Decimal - fifthCostCoin: Decimal - fifthProduceCoin: number - - firstOwnedDiamonds: number - firstGeneratedDiamonds: Decimal - firstCostDiamonds: Decimal - firstProduceDiamonds: number - - secondOwnedDiamonds: number - secondGeneratedDiamonds: Decimal - secondCostDiamonds: Decimal - secondProduceDiamonds: number - - thirdOwnedDiamonds: number - thirdGeneratedDiamonds: Decimal - thirdCostDiamonds: Decimal - thirdProduceDiamonds: number - - fourthOwnedDiamonds: number - fourthGeneratedDiamonds: Decimal - fourthCostDiamonds: Decimal - fourthProduceDiamonds: number - - fifthOwnedDiamonds: number - fifthGeneratedDiamonds: Decimal - fifthCostDiamonds: Decimal - fifthProduceDiamonds: number - - firstOwnedMythos: number - firstGeneratedMythos: Decimal - firstCostMythos: Decimal - firstProduceMythos: number - - secondOwnedMythos: number - secondGeneratedMythos: Decimal - secondCostMythos: Decimal - secondProduceMythos: number - - thirdOwnedMythos: number - thirdGeneratedMythos: Decimal - thirdCostMythos: Decimal - thirdProduceMythos: number - - fourthOwnedMythos: number - fourthGeneratedMythos: Decimal - fourthCostMythos: Decimal - fourthProduceMythos: number - - fifthOwnedMythos: number - fifthGeneratedMythos: Decimal - fifthCostMythos: Decimal - fifthProduceMythos: number - - firstOwnedParticles: number - firstGeneratedParticles: Decimal - firstCostParticles: Decimal - firstProduceParticles: number - - secondOwnedParticles: number - secondGeneratedParticles: Decimal - secondCostParticles: Decimal - secondProduceParticles: number - - thirdOwnedParticles: number - thirdGeneratedParticles: Decimal - thirdCostParticles: Decimal - thirdProduceParticles: number - - fourthOwnedParticles: number - fourthGeneratedParticles: Decimal - fourthCostParticles: Decimal - fourthProduceParticles: number - - fifthOwnedParticles: number - fifthGeneratedParticles: Decimal - fifthCostParticles: Decimal - fifthProduceParticles: number - - firstOwnedAnts: number - firstGeneratedAnts: Decimal - firstCostAnts: Decimal - firstProduceAnts: number - - secondOwnedAnts: number - secondGeneratedAnts: Decimal - secondCostAnts: Decimal - secondProduceAnts: number - - thirdOwnedAnts: number - thirdGeneratedAnts: Decimal - thirdCostAnts: Decimal - thirdProduceAnts: number - - fourthOwnedAnts: number - fourthGeneratedAnts: Decimal - fourthCostAnts: Decimal - fourthProduceAnts: number - - fifthOwnedAnts: number - fifthGeneratedAnts: Decimal - fifthCostAnts: Decimal - fifthProduceAnts: number - - sixthOwnedAnts: number - sixthGeneratedAnts: Decimal - sixthCostAnts: Decimal - sixthProduceAnts: number - - seventhOwnedAnts: number - seventhGeneratedAnts: Decimal - seventhCostAnts: Decimal - seventhProduceAnts: number - - eighthOwnedAnts: number - eighthGeneratedAnts: Decimal - eighthCostAnts: Decimal - eighthProduceAnts: number + firstPlayed: string; + worlds: QuarkHandler; + coins: Decimal; + coinsThisPrestige: Decimal; + coinsThisTranscension: Decimal; + coinsThisReincarnation: Decimal; + coinsTotal: Decimal; + + firstOwnedCoin: number; + firstGeneratedCoin: Decimal; + firstCostCoin: Decimal; + firstProduceCoin: number; + + secondOwnedCoin: number; + secondGeneratedCoin: Decimal; + secondCostCoin: Decimal; + secondProduceCoin: number; + + thirdOwnedCoin: number; + thirdGeneratedCoin: Decimal; + thirdCostCoin: Decimal; + thirdProduceCoin: number; + + fourthOwnedCoin: number; + fourthGeneratedCoin: Decimal; + fourthCostCoin: Decimal; + fourthProduceCoin: number; + + fifthOwnedCoin: number; + fifthGeneratedCoin: Decimal; + fifthCostCoin: Decimal; + fifthProduceCoin: number; + + firstOwnedDiamonds: number; + firstGeneratedDiamonds: Decimal; + firstCostDiamonds: Decimal; + firstProduceDiamonds: number; + + secondOwnedDiamonds: number; + secondGeneratedDiamonds: Decimal; + secondCostDiamonds: Decimal; + secondProduceDiamonds: number; + + thirdOwnedDiamonds: number; + thirdGeneratedDiamonds: Decimal; + thirdCostDiamonds: Decimal; + thirdProduceDiamonds: number; + + fourthOwnedDiamonds: number; + fourthGeneratedDiamonds: Decimal; + fourthCostDiamonds: Decimal; + fourthProduceDiamonds: number; + + fifthOwnedDiamonds: number; + fifthGeneratedDiamonds: Decimal; + fifthCostDiamonds: Decimal; + fifthProduceDiamonds: number; + + firstOwnedMythos: number; + firstGeneratedMythos: Decimal; + firstCostMythos: Decimal; + firstProduceMythos: number; + + secondOwnedMythos: number; + secondGeneratedMythos: Decimal; + secondCostMythos: Decimal; + secondProduceMythos: number; + + thirdOwnedMythos: number; + thirdGeneratedMythos: Decimal; + thirdCostMythos: Decimal; + thirdProduceMythos: number; + + fourthOwnedMythos: number; + fourthGeneratedMythos: Decimal; + fourthCostMythos: Decimal; + fourthProduceMythos: number; + + fifthOwnedMythos: number; + fifthGeneratedMythos: Decimal; + fifthCostMythos: Decimal; + fifthProduceMythos: number; + + firstOwnedParticles: number; + firstGeneratedParticles: Decimal; + firstCostParticles: Decimal; + firstProduceParticles: number; + + secondOwnedParticles: number; + secondGeneratedParticles: Decimal; + secondCostParticles: Decimal; + secondProduceParticles: number; + + thirdOwnedParticles: number; + thirdGeneratedParticles: Decimal; + thirdCostParticles: Decimal; + thirdProduceParticles: number; + + fourthOwnedParticles: number; + fourthGeneratedParticles: Decimal; + fourthCostParticles: Decimal; + fourthProduceParticles: number; + + fifthOwnedParticles: number; + fifthGeneratedParticles: Decimal; + fifthCostParticles: Decimal; + fifthProduceParticles: number; + + firstOwnedAnts: number; + firstGeneratedAnts: Decimal; + firstCostAnts: Decimal; + firstProduceAnts: number; + + secondOwnedAnts: number; + secondGeneratedAnts: Decimal; + secondCostAnts: Decimal; + secondProduceAnts: number; + + thirdOwnedAnts: number; + thirdGeneratedAnts: Decimal; + thirdCostAnts: Decimal; + thirdProduceAnts: number; + + fourthOwnedAnts: number; + fourthGeneratedAnts: Decimal; + fourthCostAnts: Decimal; + fourthProduceAnts: number; + + fifthOwnedAnts: number; + fifthGeneratedAnts: Decimal; + fifthCostAnts: Decimal; + fifthProduceAnts: number; + + sixthOwnedAnts: number; + sixthGeneratedAnts: Decimal; + sixthCostAnts: Decimal; + sixthProduceAnts: number; + + seventhOwnedAnts: number; + seventhGeneratedAnts: Decimal; + seventhCostAnts: Decimal; + seventhProduceAnts: number; + + eighthOwnedAnts: number; + eighthGeneratedAnts: Decimal; + eighthCostAnts: Decimal; + eighthProduceAnts: number; ascendBuilding1: { - cost: number - owned: number - generated: Decimal - multiplier: number - } + cost: number; + owned: number; + generated: Decimal; + multiplier: number; + }; ascendBuilding2: { - cost: number - owned: number - generated: Decimal - multiplier: number - } + cost: number; + owned: number; + generated: Decimal; + multiplier: number; + }; ascendBuilding3: { - cost: number - owned: number - generated: Decimal - multiplier: number - } + cost: number; + owned: number; + generated: Decimal; + multiplier: number; + }; ascendBuilding4: { - cost: number - owned: number - generated: Decimal - multiplier: number - } + cost: number; + owned: number; + generated: Decimal; + multiplier: number; + }; ascendBuilding5: { - cost: number - owned: number - generated: Decimal - multiplier: number - } + cost: number; + owned: number; + generated: Decimal; + multiplier: number; + }; - multiplierCost: Decimal - multiplierBought: number + multiplierCost: Decimal; + multiplierBought: number; - acceleratorCost: Decimal - acceleratorBought: number + acceleratorCost: Decimal; + acceleratorBought: number; - acceleratorBoostBought: number - acceleratorBoostCost: Decimal + acceleratorBoostBought: number; + acceleratorBoostCost: Decimal; - upgrades: number[] + upgrades: number[]; - prestigeCount: number - transcendCount: number - reincarnationCount: number + prestigeCount: number; + transcendCount: number; + reincarnationCount: number; - prestigePoints: Decimal - transcendPoints: Decimal - reincarnationPoints: Decimal + prestigePoints: Decimal; + transcendPoints: Decimal; + reincarnationPoints: Decimal; - prestigeShards: Decimal - transcendShards: Decimal - reincarnationShards: Decimal + prestigeShards: Decimal; + transcendShards: Decimal; + reincarnationShards: Decimal; - toggles: Record + toggles: Record; - challengecompletions: number[] - highestchallengecompletions: number[] - challenge15Exponent: number - highestChallenge15Exponent: number + challengecompletions: number[]; + highestchallengecompletions: number[]; + challenge15Exponent: number; + highestChallenge15Exponent: number; - retrychallenges: boolean + retrychallenges: boolean; currentChallenge: { - transcension: number - reincarnation: number - ascension: number - } - researchPoints: number - obtainiumtimer: number - obtainiumpersecond: number - maxobtainiumpersecond: number - maxobtainium: number + transcension: number; + reincarnation: number; + ascension: number; + }; + researchPoints: number; + obtainiumtimer: number; + obtainiumpersecond: number; + maxobtainiumpersecond: number; + maxobtainium: number; // Ignore the first index. The other 25 are shaped in a 5x5 grid similar to the production appearance - researches: number[] + researches: number[]; unlocks: { - coinone: boolean - cointwo: boolean - cointhree: boolean - coinfour: boolean - prestige: boolean - generation: boolean - transcend: boolean - reincarnate: boolean - rrow1: boolean - rrow2: boolean - rrow3: boolean - rrow4: boolean - } - achievements: number[] - - achievementPoints: number - - prestigenomultiplier: boolean - prestigenoaccelerator: boolean - transcendnomultiplier: boolean - transcendnoaccelerator: boolean - reincarnatenomultiplier: boolean - reincarnatenoaccelerator: boolean - prestigenocoinupgrades: boolean - transcendnocoinupgrades: boolean - transcendnocoinorprestigeupgrades: boolean - reincarnatenocoinupgrades: boolean - reincarnatenocoinorprestigeupgrades: boolean - reincarnatenocoinprestigeortranscendupgrades: boolean - reincarnatenocoinprestigetranscendorgeneratorupgrades: boolean - - crystalUpgrades: number[] - crystalUpgradesCost: number[] - - runelevels: number[] - runeexp: number[] - runeshards: number - maxofferings: number - offeringpersecond: number - - prestigecounter: number - transcendcounter: number - reincarnationcounter: number - offlinetick: number - - prestigeamount: number - transcendamount: number - reincarnationamount: number - - fastestprestige: number - fastesttranscend: number - fastestreincarnate: number - - resettoggle1: number - resettoggle2: number - resettoggle3: number - resettoggle4: number - - tesseractAutoBuyerToggle: number - tesseractAutoBuyerAmount: number - - coinbuyamount: number - crystalbuyamount: number - mythosbuyamount: number - particlebuyamount: number - offeringbuyamount: number - tesseractbuyamount: number + coinone: boolean; + cointwo: boolean; + cointhree: boolean; + coinfour: boolean; + prestige: boolean; + generation: boolean; + transcend: boolean; + reincarnate: boolean; + rrow1: boolean; + rrow2: boolean; + rrow3: boolean; + rrow4: boolean; + }; + achievements: number[]; + + achievementPoints: number; + + prestigenomultiplier: boolean; + prestigenoaccelerator: boolean; + transcendnomultiplier: boolean; + transcendnoaccelerator: boolean; + reincarnatenomultiplier: boolean; + reincarnatenoaccelerator: boolean; + prestigenocoinupgrades: boolean; + transcendnocoinupgrades: boolean; + transcendnocoinorprestigeupgrades: boolean; + reincarnatenocoinupgrades: boolean; + reincarnatenocoinorprestigeupgrades: boolean; + reincarnatenocoinprestigeortranscendupgrades: boolean; + reincarnatenocoinprestigetranscendorgeneratorupgrades: boolean; + + crystalUpgrades: number[]; + crystalUpgradesCost: number[]; + + runelevels: number[]; + runeexp: number[]; + runeshards: number; + maxofferings: number; + offeringpersecond: number; + + prestigecounter: number; + transcendcounter: number; + reincarnationcounter: number; + offlinetick: number; + + prestigeamount: number; + transcendamount: number; + reincarnationamount: number; + + fastestprestige: number; + fastesttranscend: number; + fastestreincarnate: number; + + resettoggle1: number; + resettoggle2: number; + resettoggle3: number; + resettoggle4: number; + + tesseractAutoBuyerToggle: number; + tesseractAutoBuyerAmount: number; + + coinbuyamount: number; + crystalbuyamount: number; + mythosbuyamount: number; + particlebuyamount: number; + offeringbuyamount: number; + tesseractbuyamount: number; shoptoggles: { - coin: boolean - prestige: boolean - transcend: boolean - generators: boolean - reincarnate: boolean - } - tabnumber: number - subtabNumber: number + coin: boolean; + prestige: boolean; + transcend: boolean; + generators: boolean; + reincarnate: boolean; + }; + tabnumber: number; + subtabNumber: number; // create a Map with keys defaulting to boolean - codes: Map + codes: Map; - loaded1009: boolean - loaded1009hotfix1: boolean - loaded10091: boolean - loaded1010: boolean - loaded10101: boolean + loaded1009: boolean; + loaded1009hotfix1: boolean; + loaded10091: boolean; + loaded1010: boolean; + loaded10101: boolean; shopUpgrades: { - offeringPotion: number - obtainiumPotion: number - offeringEX: number - offeringAuto: number - obtainiumEX: number - obtainiumAuto: number - instantChallenge: number - antSpeed: number - cashGrab: number - shopTalisman: number - seasonPass: number - challengeExtension: number - challengeTome: number - cubeToQuark: number - tesseractToQuark: number - hypercubeToQuark: number - seasonPass2: number - seasonPass3: number - chronometer: number - infiniteAscent: number - calculator: number - calculator2: number - calculator3: number - calculator4: number - calculator5: number - calculator6: number - constantEX: number - powderEX: number - chronometer2: number - chronometer3: number - seasonPassY: number - seasonPassZ: number - challengeTome2: number - instantChallenge2: number - cubeToQuarkAll: number - cashGrab2: number - seasonPassLost: number - chronometerZ: number - powderAuto: number - offeringEX2: number - obtainiumEX2: number - challenge15Auto: number - extraWarp: number - autoWarp: number - improveQuarkHept: number - improveQuarkHept2: number - improveQuarkHept3: number - improveQuarkHept4: number - shopImprovedDaily: number - shopImprovedDaily2: number - shopImprovedDaily3: number - shopImprovedDaily4: number - offeringEX3: number - obtainiumEX3: number - improveQuarkHept5: number - seasonPassInfinity: number - chronometerInfinity: number - shopSingularityPenaltyDebuff: number - shopAmbrosiaGeneration1: number - shopAmbrosiaGeneration2: number - shopAmbrosiaGeneration3: number - shopAmbrosiaGeneration4: number - shopAmbrosiaLuck1: number - shopAmbrosiaLuck2: number - shopAmbrosiaLuck3: number - shopAmbrosiaLuck4: number - } - shopConfirmationToggle: boolean - shopBuyMaxToggle: boolean | 'TEN' | 'ANY' - shopHideToggle: boolean - autoPotionTimer: number - autoPotionTimerObtainium: number - - autoSacrificeToggle: boolean - autoBuyFragment: boolean - autoFortifyToggle: boolean - autoEnhanceToggle: boolean - autoResearchToggle: boolean - researchBuyMaxToggle: boolean - autoResearchMode: 'cheapest' | 'manual' - autoResearch: number - autoSacrifice: number - sacrificeTimer: number - quarkstimer: number - goldenQuarksTimer: number - - antPoints: Decimal - antUpgrades: (null | number)[] - antSacrificePoints: number - antSacrificeTimer: number - antSacrificeTimerReal: number - - talismanLevels: number[] - talismanRarity: number[] - talismanOne: (null | number)[] - talismanTwo: (null | number)[] - talismanThree: (null | number)[] - talismanFour: (null | number)[] - talismanFive: (null | number)[] - talismanSix: (null | number)[] - talismanSeven: (null | number)[] - talismanShards: number - commonFragments: number - uncommonFragments: number - rareFragments: number - epicFragments: number - legendaryFragments: number - mythicalFragments: number - - buyTalismanShardPercent: number - - autoAntSacrifice: boolean - autoAntSacTimer: number - autoAntSacrificeMode: number - antMax: boolean - - ascensionCount: number - ascensionCounter: number - ascensionCounterReal: number - ascensionCounterRealReal: number - autoOpenCubes: boolean - openCubes: number - autoOpenTesseracts: boolean - openTesseracts: number - autoOpenHypercubes: boolean - openHypercubes: number - autoOpenPlatonicsCubes: boolean - openPlatonicsCubes: number - cubeUpgrades: [null, ...number[]] - cubeUpgradesBuyMaxToggle: boolean - autoCubeUpgradesToggle: boolean - autoPlatonicUpgradesToggle: boolean - platonicUpgrades: number[] - saveOfferingToggle: boolean - wowCubes: WowCubes - wowTesseracts: WowTesseracts - wowHypercubes: WowHypercubes - wowPlatonicCubes: WowPlatonicCubes - wowAbyssals: number - wowOcteracts: number - totalWowOcteracts: number + offeringPotion: number; + obtainiumPotion: number; + offeringEX: number; + offeringAuto: number; + obtainiumEX: number; + obtainiumAuto: number; + instantChallenge: number; + antSpeed: number; + cashGrab: number; + shopTalisman: number; + seasonPass: number; + challengeExtension: number; + challengeTome: number; + cubeToQuark: number; + tesseractToQuark: number; + hypercubeToQuark: number; + seasonPass2: number; + seasonPass3: number; + chronometer: number; + infiniteAscent: number; + calculator: number; + calculator2: number; + calculator3: number; + calculator4: number; + calculator5: number; + calculator6: number; + calculator7: number; + constantEX: number; + powderEX: number; + chronometer2: number; + chronometer3: number; + seasonPassY: number; + seasonPassZ: number; + challengeTome2: number; + instantChallenge2: number; + cubeToQuarkAll: number; + cashGrab2: number; + seasonPassLost: number; + chronometerZ: number; + powderAuto: number; + offeringEX2: number; + obtainiumEX2: number; + challenge15Auto: number; + extraWarp: number; + autoWarp: number; + improveQuarkHept: number; + improveQuarkHept2: number; + improveQuarkHept3: number; + improveQuarkHept4: number; + shopImprovedDaily: number; + shopImprovedDaily2: number; + shopImprovedDaily3: number; + shopImprovedDaily4: number; + offeringEX3: number; + obtainiumEX3: number; + improveQuarkHept5: number; + seasonPassInfinity: number; + chronometerInfinity: number; + shopSingularityPenaltyDebuff: number; + shopAmbrosiaLuckMultiplier4: number; + shopOcteractAmbrosiaLuck: number; + shopAmbrosiaGeneration1: number; + shopAmbrosiaGeneration2: number; + shopAmbrosiaGeneration3: number; + shopAmbrosiaGeneration4: number; + shopAmbrosiaLuck1: number; + shopAmbrosiaLuck2: number; + shopAmbrosiaLuck3: number; + shopAmbrosiaLuck4: number; + }; + shopConfirmationToggle: boolean; + shopBuyMaxToggle: boolean | "TEN" | "ANY"; + shopHideToggle: boolean; + autoPotionTimer: number; + autoPotionTimerObtainium: number; + + autoSacrificeToggle: boolean; + autoBuyFragment: boolean; + autoFortifyToggle: boolean; + autoEnhanceToggle: boolean; + autoResearchToggle: boolean; + researchBuyMaxToggle: boolean; + autoResearchMode: "cheapest" | "manual"; + autoResearch: number; + autoSacrifice: number; + sacrificeTimer: number; + quarkstimer: number; + goldenQuarksTimer: number; + + antPoints: Decimal; + antUpgrades: (null | number)[]; + antSacrificePoints: number; + antSacrificeTimer: number; + antSacrificeTimerReal: number; + + talismanLevels: number[]; + talismanRarity: number[]; + talismanOne: (null | number)[]; + talismanTwo: (null | number)[]; + talismanThree: (null | number)[]; + talismanFour: (null | number)[]; + talismanFive: (null | number)[]; + talismanSix: (null | number)[]; + talismanSeven: (null | number)[]; + talismanShards: number; + commonFragments: number; + uncommonFragments: number; + rareFragments: number; + epicFragments: number; + legendaryFragments: number; + mythicalFragments: number; + + buyTalismanShardPercent: number; + + autoAntSacrifice: boolean; + autoAntSacTimer: number; + autoAntSacrificeMode: number; + antMax: boolean; + + ascensionCount: number; + ascensionCounter: number; + ascensionCounterReal: number; + ascensionCounterRealReal: number; + autoOpenCubes: boolean; + openCubes: number; + autoOpenTesseracts: boolean; + openTesseracts: number; + autoOpenHypercubes: boolean; + openHypercubes: number; + autoOpenPlatonicsCubes: boolean; + openPlatonicsCubes: number; + cubeUpgrades: [null, ...number[]]; + cubeUpgradesBuyMaxToggle: boolean; + autoCubeUpgradesToggle: boolean; + autoPlatonicUpgradesToggle: boolean; + platonicUpgrades: number[]; + saveOfferingToggle: boolean; + wowCubes: WowCubes; + wowTesseracts: WowTesseracts; + wowHypercubes: WowHypercubes; + wowPlatonicCubes: WowPlatonicCubes; + wowAbyssals: number; + wowOcteracts: number; + totalWowOcteracts: number; cubeBlessings: { - accelerator: number - multiplier: number - offering: number - runeExp: number - obtainium: number - antSpeed: number - antSacrifice: number - antELO: number - talismanBonus: number - globalSpeed: 0 - } + accelerator: number; + multiplier: number; + offering: number; + runeExp: number; + obtainium: number; + antSpeed: number; + antSacrifice: number; + antELO: number; + talismanBonus: number; + globalSpeed: 0; + }; tesseractBlessings: { - accelerator: number - multiplier: number - offering: number - runeExp: number - obtainium: number - antSpeed: number - antSacrifice: number - antELO: number - talismanBonus: number - globalSpeed: number - } + accelerator: number; + multiplier: number; + offering: number; + runeExp: number; + obtainium: number; + antSpeed: number; + antSacrifice: number; + antELO: number; + talismanBonus: number; + globalSpeed: number; + }; hypercubeBlessings: { - accelerator: number - multiplier: number - offering: number - runeExp: number - obtainium: number - antSpeed: number - antSacrifice: number - antELO: number - talismanBonus: number - globalSpeed: number - } + accelerator: number; + multiplier: number; + offering: number; + runeExp: number; + obtainium: number; + antSpeed: number; + antSacrifice: number; + antELO: number; + talismanBonus: number; + globalSpeed: number; + }; platonicBlessings: { - cubes: number - tesseracts: number - hypercubes: number - platonics: number - hypercubeBonus: number - taxes: number - scoreBonus: number - globalSpeed: number - } - ascendShards: Decimal - autoAscend: boolean - autoAscendMode: string - autoAscendThreshold: number - roombaResearchIndex: number - ascStatToggles: Record - - prototypeCorruptions: number[] - usedCorruptions: number[] - corruptionLoadouts: Record - corruptionLoadoutNames: string[] - corruptionShowStats: boolean - - constantUpgrades: [null, ...number[]] - history: Record - historyShowPerSecond: boolean - - autoChallengeRunning: boolean - autoChallengeIndex: number - autoChallengeToggles: boolean[] - autoChallengeStartExponent: number - autoChallengeTimer: Record - - runeBlessingLevels: number[] - runeSpiritLevels: number[] - runeBlessingBuyAmount: number - runeSpiritBuyAmount: number - - autoTesseracts: boolean[] - - saveString: string - exporttest: string | boolean - - dayCheck: Date | null - dayTimer: number - cubeOpenedDaily: number - cubeQuarkDaily: number - tesseractOpenedDaily: number - tesseractQuarkDaily: number - hypercubeOpenedDaily: number - hypercubeQuarkDaily: number - platonicCubeOpenedDaily: number - platonicCubeQuarkDaily: number - loadedOct4Hotfix: boolean - loadedNov13Vers: boolean - loadedDec16Vers: boolean - loadedV253: boolean - loadedV255: boolean - loadedV297Hotfix1: boolean - loadedV2927Hotfix1: boolean - loadedV2930Hotfix1: boolean - loadedV2931Hotfix1: boolean - loadedV21003Hotfix1: boolean - loadedV21007Hotfix1: boolean - version: string - - rngCode: number - skillCode?: number + cubes: number; + tesseracts: number; + hypercubes: number; + platonics: number; + hypercubeBonus: number; + taxes: number; + scoreBonus: number; + globalSpeed: number; + }; + ascendShards: Decimal; + autoAscend: boolean; + autoAscendMode: string; + autoAscendThreshold: number; + roombaResearchIndex: number; + ascStatToggles: Record; + + prototypeCorruptions: number[]; + usedCorruptions: number[]; + corruptionLoadouts: Record; + corruptionLoadoutNames: string[]; + corruptionShowStats: boolean; + + constantUpgrades: [null, ...number[]]; + history: Record; + historyShowPerSecond: boolean; + + autoChallengeRunning: boolean; + autoChallengeIndex: number; + autoChallengeToggles: boolean[]; + autoChallengeStartExponent: number; + autoChallengeTimer: Record; + + runeBlessingLevels: number[]; + runeSpiritLevels: number[]; + runeBlessingBuyAmount: number; + runeSpiritBuyAmount: number; + + autoTesseracts: boolean[]; + + saveString: string; + exporttest: string | boolean; + + dayCheck: Date | null; + dayTimer: number; + cubeOpenedDaily: number; + cubeQuarkDaily: number; + tesseractOpenedDaily: number; + tesseractQuarkDaily: number; + hypercubeOpenedDaily: number; + hypercubeQuarkDaily: number; + platonicCubeOpenedDaily: number; + platonicCubeQuarkDaily: number; + loadedOct4Hotfix: boolean; + loadedNov13Vers: boolean; + loadedDec16Vers: boolean; + loadedV253: boolean; + loadedV255: boolean; + loadedV297Hotfix1: boolean; + loadedV2927Hotfix1: boolean; + loadedV2930Hotfix1: boolean; + loadedV2931Hotfix1: boolean; + loadedV21003Hotfix1: boolean; + loadedV21007Hotfix1: boolean; + version: string; + + rngCode: number; + skillCode?: number; promoCodeTiming: { - time: number - } + time: number; + }; hepteractCrafts: { - chronos: HepteractCraft - hyperrealism: HepteractCraft - quark: HepteractCraft - challenge: HepteractCraft - abyss: HepteractCraft - accelerator: HepteractCraft - acceleratorBoost: HepteractCraft - multiplier: HepteractCraft - } - overfluxOrbs: number - overfluxOrbsAutoBuy: boolean - overfluxPowder: number - dailyPowderResetUses: number - autoWarpCheck: boolean - - singularityCount: number - highestSingularityCount: number - singularityCounter: number - goldenQuarks: number - quarksThisSingularity: number - totalQuarksEver: number - hotkeys: Record - theme: string - iconSet: number - notation: string - - singularityUpgrades: Record - octeractUpgrades: Record - dailyCodeUsed: boolean - hepteractAutoCraftPercentage: number - octeractTimer: number - - insideSingularityChallenge: boolean - singularityChallenges: Record - - ambrosia: number - lifetimeAmbrosia: number - blueberryTime: number - ambrosiaRNG: number // DEPRECIATED, DO NOT USE - visitedAmbrosiaSubtab: boolean - spentBlueberries: number - blueberryUpgrades: Record - blueberryLoadouts: Record - blueberryLoadoutMode: BlueberryLoadoutMode + chronos: HepteractCraft; + hyperrealism: HepteractCraft; + quark: HepteractCraft; + challenge: HepteractCraft; + abyss: HepteractCraft; + accelerator: HepteractCraft; + acceleratorBoost: HepteractCraft; + multiplier: HepteractCraft; + }; + overfluxOrbs: number; + overfluxOrbsAutoBuy: boolean; + overfluxPowder: number; + dailyPowderResetUses: number; + autoWarpCheck: boolean; + + singularityCount: number; + highestSingularityCount: number; + singularityCounter: number; + goldenQuarks: number; + quarksThisSingularity: number; + totalQuarksEver: number; + hotkeys: Record; + theme: string; + iconSet: number; + notation: string; + + singularityUpgrades: Record; + octeractUpgrades: Record; + dailyCodeUsed: boolean; + hepteractAutoCraftPercentage: number; + octeractTimer: number; + + insideSingularityChallenge: boolean; + singularityChallenges: Record< + keyof typeof singularityChallengeData, + SingularityChallenge + >; + + ambrosia: number; + lifetimeAmbrosia: number; + blueberryTime: number; + ambrosiaRNG: number; // DEPRECIATED, DO NOT USE + visitedAmbrosiaSubtab: boolean; + spentBlueberries: number; + blueberryUpgrades: Record< + keyof typeof blueberryUpgradeData, + BlueberryUpgrade + >; + blueberryLoadouts: Record; + blueberryLoadoutMode: BlueberryLoadoutMode; caches: { - ambrosiaLuck: AmbrosiaLuckCache - ambrosiaGeneration: AmbrosiaGenerationCache - blueberryInventory: BlueberryInventoryCache - } + ambrosiaLuckAdditiveMult: AmbrosiaLuckAdditiveMultCache; + ambrosiaLuck: AmbrosiaLuckCache; + ambrosiaGeneration: AmbrosiaGenerationCache; + blueberryInventory: BlueberryInventoryCache; + }; /** * When the player last exported the save. */ - lastExportedSave: number + lastExportedSave: number; } export interface GlobalVariables { - runediv: number[] - runeexpbase: number[] - runeMaxLvl: number - upgradeCosts: number[] + runediv: number[]; + runeexpbase: number[]; + runeMaxLvl: number; + upgradeCosts: number[]; // Mega list of Variables to be used elsewhere - crystalUpgradesCost: number[] - crystalUpgradeCostIncrement: number[] - researchBaseCosts: number[] - - researchMaxLevels: number[] - - ticker: number - - costDivisor: number - - freeAccelerator: number - totalAccelerator: number - freeAcceleratorBoost: number - totalAcceleratorBoost: number - acceleratorPower: number - acceleratorEffect: Decimal - acceleratorEffectDisplay: Decimal - generatorPower: Decimal - - freeMultiplier: number - totalMultiplier: number - multiplierPower: number - multiplierEffect: Decimal - challengeOneLog: number - freeMultiplierBoost: number - totalMultiplierBoost: number - - globalCoinMultiplier: Decimal - totalCoinOwned: number - prestigeMultiplier: Decimal - buildingPower: number - reincarnationMultiplier: Decimal - - coinOneMulti: Decimal - coinTwoMulti: Decimal - coinThreeMulti: Decimal - coinFourMulti: Decimal - coinFiveMulti: Decimal - - globalCrystalMultiplier: Decimal - globalMythosMultiplier: Decimal - grandmasterMultiplier: Decimal - - atomsMultiplier: Decimal - - mythosBuildingPower: number - challengeThreeMultiplier: Decimal - totalMythosOwned: number - - prestigePointGain: Decimal - challengeFivePower: number - - transcendPointGain: Decimal - reincarnationPointGain: Decimal - - produceFirst: Decimal - produceSecond: Decimal - produceThird: Decimal - produceFourth: Decimal - produceFifth: Decimal - produceTotal: Decimal - - produceFirstDiamonds: Decimal - produceSecondDiamonds: Decimal - produceThirdDiamonds: Decimal - produceFourthDiamonds: Decimal - produceFifthDiamonds: Decimal - produceDiamonds: Decimal - - produceFirstMythos: Decimal - produceSecondMythos: Decimal - produceThirdMythos: Decimal - produceFourthMythos: Decimal - produceFifthMythos: Decimal - produceMythos: Decimal - - produceFirstParticles: Decimal - produceSecondParticles: Decimal - produceThirdParticles: Decimal - produceFourthParticles: Decimal - produceFifthParticles: Decimal - produceParticles: Decimal - - producePerSecond: Decimal - producePerSecondDiamonds: Decimal - producePerSecondMythos: Decimal - producePerSecondParticles: Decimal - - uFourteenMulti: Decimal - uFifteenMulti: Decimal - tuSevenMulti: number - currentTab: Tabs - - researchfiller1: string - researchfiller2: string - - ordinals: readonly ['first', 'second', 'third', 'fourth', 'fifth', 'sixth', 'seventh', 'eighth', ...string[]] - cardinals: string[] - - challengeBaseRequirements: number[] - - prestigeamount: number - taxdivisor: Decimal - taxdivisorcheck: Decimal + crystalUpgradesCost: number[]; + crystalUpgradeCostIncrement: number[]; + researchBaseCosts: number[]; + + researchMaxLevels: number[]; + + ticker: number; + + costDivisor: number; + + freeAccelerator: number; + totalAccelerator: number; + freeAcceleratorBoost: number; + totalAcceleratorBoost: number; + acceleratorPower: number; + acceleratorEffect: Decimal; + acceleratorEffectDisplay: Decimal; + generatorPower: Decimal; + + freeMultiplier: number; + totalMultiplier: number; + multiplierPower: number; + multiplierEffect: Decimal; + challengeOneLog: number; + freeMultiplierBoost: number; + totalMultiplierBoost: number; + + globalCoinMultiplier: Decimal; + totalCoinOwned: number; + prestigeMultiplier: Decimal; + buildingPower: number; + reincarnationMultiplier: Decimal; + + coinOneMulti: Decimal; + coinTwoMulti: Decimal; + coinThreeMulti: Decimal; + coinFourMulti: Decimal; + coinFiveMulti: Decimal; + + globalCrystalMultiplier: Decimal; + globalMythosMultiplier: Decimal; + grandmasterMultiplier: Decimal; + + atomsMultiplier: Decimal; + + mythosBuildingPower: number; + challengeThreeMultiplier: Decimal; + totalMythosOwned: number; + + prestigePointGain: Decimal; + challengeFivePower: number; + + transcendPointGain: Decimal; + reincarnationPointGain: Decimal; + + produceFirst: Decimal; + produceSecond: Decimal; + produceThird: Decimal; + produceFourth: Decimal; + produceFifth: Decimal; + produceTotal: Decimal; + + produceFirstDiamonds: Decimal; + produceSecondDiamonds: Decimal; + produceThirdDiamonds: Decimal; + produceFourthDiamonds: Decimal; + produceFifthDiamonds: Decimal; + produceDiamonds: Decimal; + + produceFirstMythos: Decimal; + produceSecondMythos: Decimal; + produceThirdMythos: Decimal; + produceFourthMythos: Decimal; + produceFifthMythos: Decimal; + produceMythos: Decimal; + + produceFirstParticles: Decimal; + produceSecondParticles: Decimal; + produceThirdParticles: Decimal; + produceFourthParticles: Decimal; + produceFifthParticles: Decimal; + produceParticles: Decimal; + + producePerSecond: Decimal; + producePerSecondDiamonds: Decimal; + producePerSecondMythos: Decimal; + producePerSecondParticles: Decimal; + + uFourteenMulti: Decimal; + uFifteenMulti: Decimal; + tuSevenMulti: number; + currentTab: Tabs; + + researchfiller1: string; + researchfiller2: string; + + ordinals: readonly [ + "first", + "second", + "third", + "fourth", + "fifth", + "sixth", + "seventh", + "eighth", + ...string[] + ]; + cardinals: string[]; + + challengeBaseRequirements: number[]; + + prestigeamount: number; + taxdivisor: Decimal; + taxdivisorcheck: Decimal; runemultiplierincrease: { - one: number - two: number - three: number - four: number - five: number - } - - mythosupgrade13: Decimal - mythosupgrade14: Decimal - mythosupgrade15: Decimal - challengefocus: number - - maxexponent: number - - effectiveLevelMult: number - optimalOfferingTimer: number - optimalObtainiumTimer: number - - runeSum: number - - globalAntMult: Decimal - antMultiplier: Decimal - - antOneProduce: Decimal - antTwoProduce: Decimal - antThreeProduce: Decimal - antFourProduce: Decimal - antFiveProduce: Decimal - antSixProduce: Decimal - antSevenProduce: Decimal - antEightProduce: Decimal - - antCostGrowth: number[] - - antUpgradeBaseCost: number[] - antUpgradeCostIncreases: number[] - - bonusant1: number - bonusant2: number - bonusant3: number - bonusant4: number - bonusant5: number - bonusant6: number - bonusant7: number - bonusant8: number - bonusant9: number - bonusant10: number - bonusant11: number - bonusant12: number - - rune1level: number - rune2level: number - rune3level: number - rune4level: number - rune5level: number - rune1Talisman: number - rune2Talisman: number - rune3Talisman: number - rune4Talisman: number - rune5Talisman: number - - talisman1Effect: [null, ...number[]] - talisman2Effect: [null, ...number[]] - talisman3Effect: [null, ...number[]] - talisman4Effect: [null, ...number[]] - talisman5Effect: [null, ...number[]] - talisman6Effect: [null, ...number[]] - talisman7Effect: [null, ...number[]] - - talisman6Power: number - talisman7Quarks: number - - runescreen: string - settingscreen: string - - talismanResourceObtainiumCosts: number[] - talismanResourceOfferingCosts: number[] - - talismanLevelCostMultiplier: number[] - - talismanPositiveModifier: [null, ...number[]] - talismanNegativeModifier: [null, ...number[]] - - commonTalismanEnhanceCost: [null, ...number[]] - uncommonTalismanEnchanceCost: [null, ...number[]] - rareTalismanEnchanceCost: [null, ...number[]] - epicTalismanEnhanceCost: [null, ...number[]] - legendaryTalismanEnchanceCost: [null, ...number[]] - mythicalTalismanEnchanceCost: [null, ...number[]] - - talismanRespec: number - - obtainiumGain: number - - mirrorTalismanStats: [null, ...number[]] - antELO: number - effectiveELO: number - - timeWarp: boolean - - blessingMultiplier: number - spiritMultiplier: number - runeBlessings: number[] - runeSpirits: number[] - - effectiveRuneBlessingPower: number[] - effectiveRuneSpiritPower: number[] - - blessingBaseCost: number - spiritBaseCost: number + one: number; + two: number; + three: number; + four: number; + five: number; + }; + + mythosupgrade13: Decimal; + mythosupgrade14: Decimal; + mythosupgrade15: Decimal; + challengefocus: number; + + maxexponent: number; + + effectiveLevelMult: number; + optimalOfferingTimer: number; + optimalObtainiumTimer: number; + + runeSum: number; + + globalAntMult: Decimal; + antMultiplier: Decimal; + + antOneProduce: Decimal; + antTwoProduce: Decimal; + antThreeProduce: Decimal; + antFourProduce: Decimal; + antFiveProduce: Decimal; + antSixProduce: Decimal; + antSevenProduce: Decimal; + antEightProduce: Decimal; + + antCostGrowth: number[]; + + antUpgradeBaseCost: number[]; + antUpgradeCostIncreases: number[]; + + bonusant1: number; + bonusant2: number; + bonusant3: number; + bonusant4: number; + bonusant5: number; + bonusant6: number; + bonusant7: number; + bonusant8: number; + bonusant9: number; + bonusant10: number; + bonusant11: number; + bonusant12: number; + + rune1level: number; + rune2level: number; + rune3level: number; + rune4level: number; + rune5level: number; + rune1Talisman: number; + rune2Talisman: number; + rune3Talisman: number; + rune4Talisman: number; + rune5Talisman: number; + + talisman1Effect: [null, ...number[]]; + talisman2Effect: [null, ...number[]]; + talisman3Effect: [null, ...number[]]; + talisman4Effect: [null, ...number[]]; + talisman5Effect: [null, ...number[]]; + talisman6Effect: [null, ...number[]]; + talisman7Effect: [null, ...number[]]; + + talisman6Power: number; + talisman7Quarks: number; + + runescreen: string; + settingscreen: string; + + talismanResourceObtainiumCosts: number[]; + talismanResourceOfferingCosts: number[]; + + talismanLevelCostMultiplier: number[]; + + talismanPositiveModifier: [null, ...number[]]; + talismanNegativeModifier: [null, ...number[]]; + + commonTalismanEnhanceCost: [null, ...number[]]; + uncommonTalismanEnchanceCost: [null, ...number[]]; + rareTalismanEnchanceCost: [null, ...number[]]; + epicTalismanEnhanceCost: [null, ...number[]]; + legendaryTalismanEnchanceCost: [null, ...number[]]; + mythicalTalismanEnchanceCost: [null, ...number[]]; + + talismanRespec: number; + + obtainiumGain: number; + + mirrorTalismanStats: [null, ...number[]]; + antELO: number; + effectiveELO: number; + + timeWarp: boolean; + + blessingMultiplier: number; + spiritMultiplier: number; + runeBlessings: number[]; + runeSpirits: number[]; + + effectiveRuneBlessingPower: number[]; + effectiveRuneSpiritPower: number[]; + + blessingBaseCost: number; + spiritBaseCost: number; - triggerChallenge: number - - prevReductionValue: number - - buildingSubTab: BuildingSubtab + triggerChallenge: number; + + prevReductionValue: number; + + buildingSubTab: BuildingSubtab; // number000 of each before Diminishing Returns - blessingbase: [null, ...number[]] - blessingDRPower: [null, ...number[]] - giftbase: number[] - giftDRPower: number[] - benedictionbase: [null, ...number[]] - benedictionDRPower: [null, ...number[]] + blessingbase: [null, ...number[]]; + blessingDRPower: [null, ...number[]]; + giftbase: number[]; + giftDRPower: number[]; + benedictionbase: [null, ...number[]]; + benedictionDRPower: [null, ...number[]]; // 10 Million of each before Diminishing returns on first number 200k for second, and 10k for the last few - platonicCubeBase: number[] - platonicDRPower: number[] + platonicCubeBase: number[]; + platonicDRPower: number[]; - cubeBonusMultiplier: [null, ...number[]] - tesseractBonusMultiplier: [null, ...number[]] - hypercubeBonusMultiplier: [null, ...number[]] - platonicBonusMultiplier: number[] + cubeBonusMultiplier: [null, ...number[]]; + tesseractBonusMultiplier: [null, ...number[]]; + hypercubeBonusMultiplier: [null, ...number[]]; + platonicBonusMultiplier: number[]; - autoOfferingCounter: number + autoOfferingCounter: number; - researchOrderByCost: number[] + researchOrderByCost: number[]; - viscosityPower: number[] - lazinessMultiplier: number[] - hyperchallengedMultiplier: number[] - illiteracyPower: number[] - deflationMultiplier: number[] - extinctionMultiplier: number[] - droughtMultiplier: number[] - financialcollapsePower: number[] + viscosityPower: number[]; + lazinessMultiplier: number[]; + hyperchallengedMultiplier: number[]; + illiteracyPower: number[]; + deflationMultiplier: number[]; + extinctionMultiplier: number[]; + droughtMultiplier: number[]; + financialcollapsePower: number[]; - corruptionPointMultipliers: number[] + corruptionPointMultipliers: number[]; ascendBuildingProduction: { - first: Decimal - second: Decimal - third: Decimal - fourth: Decimal - fifth: Decimal - } - freeUpgradeAccelerator: number - freeUpgradeMultiplier: number + first: Decimal; + second: Decimal; + third: Decimal; + fourth: Decimal; + fifth: Decimal; + }; + freeUpgradeAccelerator: number; + freeUpgradeMultiplier: number; - acceleratorMultiplier: number - multiplierMultiplier: number + acceleratorMultiplier: number; + multiplierMultiplier: number; - constUpgradeCosts: [null, ...number[]] + constUpgradeCosts: [null, ...number[]]; - globalConstantMult: Decimal - autoTalismanTimer: number + globalConstantMult: Decimal; + autoTalismanTimer: number; - autoChallengeTimerIncrement: number - corruptionTrigger: number + autoChallengeTimerIncrement: number; + corruptionTrigger: number; challenge15Rewards: { - cube1: number - ascensions: number - coinExponent: number - taxes: number - obtainium: number - offering: number - accelerator: number - multiplier: number - runeExp: number - runeBonus: number - cube2: number - transcendChallengeReduction: number - reincarnationChallengeReduction: number - antSpeed: number - bonusAntLevel: number - cube3: number - talismanBonus: number - globalSpeed: number - blessingBonus: number - constantBonus: number - cube4: number - spiritBonus: number - score: number - quarks: number - hepteractUnlocked: number - cube5: number - powder: number - exponent: number - freeOrbs: number - ascensionSpeed: number - } + cube1: number; + ascensions: number; + coinExponent: number; + taxes: number; + obtainium: number; + offering: number; + accelerator: number; + multiplier: number; + runeExp: number; + runeBonus: number; + cube2: number; + transcendChallengeReduction: number; + reincarnationChallengeReduction: number; + antSpeed: number; + bonusAntLevel: number; + cube3: number; + talismanBonus: number; + globalSpeed: number; + blessingBonus: number; + constantBonus: number; + cube4: number; + spiritBonus: number; + score: number; + quarks: number; + hepteractUnlocked: number; + cube5: number; + powder: number; + exponent: number; + freeOrbs: number; + ascensionSpeed: number; + }; autoResetTimers: { - prestige: number - transcension: number - reincarnation: number - ascension: 0 - } + prestige: number; + transcension: number; + reincarnation: number; + ascension: 0; + }; - timeMultiplier: number - upgradeMultiplier: number + timeMultiplier: number; + upgradeMultiplier: number; - historyCountMax: number + historyCountMax: number; - isEvent: boolean - shopEnhanceVision: boolean + isEvent: boolean; + shopEnhanceVision: boolean; - eventClicked: boolean + eventClicked: boolean; - ambrosiaTimer: number - TIME_PER_AMBROSIA: number + ambrosiaTimer: number; + TIME_PER_AMBROSIA: number; } export interface SynergismEvents { - achievement: [number] - historyAdd: [Category, ResetHistoryEntryUnion] - promocode: [string] - boughtPlatonicUpgrade: [IPlatBaseCost] - openPlatonic: [number] + achievement: [number]; + historyAdd: [Category, ResetHistoryEntryUnion]; + promocode: [string]; + boughtPlatonicUpgrade: [IPlatBaseCost]; + openPlatonic: [number]; } // If changing these, make reset tiers on top, then challenge types, then specific actions export type resetNames = - | 'prestige' - | 'transcension' - | 'reincarnation' - | 'ascension' - | 'singularity' - | 'transcensionChallenge' - | 'reincarnationChallenge' - | 'ascensionChallenge' - | 'acceleratorBoost' + | "prestige" + | "transcension" + | "reincarnation" + | "ascension" + | "singularity" + | "transcensionChallenge" + | "reincarnationChallenge" + | "ascensionChallenge" + | "acceleratorBoost"; // If adding new cube types add them below the last listed type. Thank you export type cubeNames = - | 'cubes' - | 'tesseracts' - | 'hypercubes' - | 'platonics' - | 'hepteracts' + | "cubes" + | "tesseracts" + | "hypercubes" + | "platonics" + | "hepteracts"; export type BuildingSubtab = - | 'coin' - | 'diamond' - | 'mythos' - | 'particle' - | 'tesseract' + | "coin" + | "diamond" + | "mythos" + | "particle" + | "tesseract"; -export type ZeroToFour = 0 | 1 | 2 | 3 | 4 +export type ZeroToFour = 0 | 1 | 2 | 3 | 4; -export type OneToFive = 1 | 2 | 3 | 4 | 5 +export type OneToFive = 1 | 2 | 3 | 4 | 5; -export type ZeroToSeven = ZeroToFour | 5 | 6 | 7 +export type ZeroToSeven = ZeroToFour | 5 | 6 | 7; -export type FirstToFifth = GlobalVariables['ordinals'][ZeroToFour] +export type FirstToFifth = GlobalVariables["ordinals"][ZeroToFour]; -export type FirstToEighth = GlobalVariables['ordinals'][ZeroToSeven] +export type FirstToEighth = GlobalVariables["ordinals"][ZeroToSeven]; diff --git a/translations/en.json b/translations/en.json index 373314c30..466071770 100644 --- a/translations/en.json +++ b/translations/en.json @@ -13,7 +13,7 @@ "ambrosia": "Ambrosia", "amount": "You have <> Ambrosia! [Lifetime: <>]", "blueberryGeneration": "Each second, gain <> seconds of Blueberry Time.", - "perGen": "Currently gaining <> with a <> chance of another. [<>]", + "perGen": "Currently gaining <> with a <> chance of another. [<>] {{extra}}", "blueberrySecond": "You currently have <> accumulated Blueberry Seconds! Generating Ambrosia when <> is accumulated.", "bonuses": "Your ambrosia is giving <> ALL cubes and <> Quarks!", "prerequisite": "Prerequisites:", @@ -1385,6 +1385,7 @@ "calculator4": "The PL-AT δ runs at 4,096Hz, which is a huge improvement over previous models. Add attempts refill 4% faster per level! Final level adds 32 additional capacity!", "calculator5": "The PL-AT Γ model somehow performs more 'powerful' computations, whatever that means. +6 seconds of GQ Export timer per level. +1 capacity every 10 levels, with 6 more at final level!", "calculator6": "The PL-AT _ model was made by Derpsmith, before he was banished from the industry forever. Gain 1 second of Octeract per usage per level. Final level grants 24 additional capacity!", + "calculator7": "The PL-AT ΩΩ model was made by Derpsmith Ω, before he was banished from the industry forever. Gain 1 second of Blueberry Time per usage per level. Final level grants 48 additional capacity!", "constantEX": "The merchant has one last trick up its sleeve: It can augment your second constant upgrade to be marginally better, but it'll cost an arm and a leg! Instead of the cap being 10% (or 11% with achievements) it will be raised by 1% per level.", "powderEX": "Platonic himself gives you 2% better conversion rate on Overflux Orbs to Powder per level. This activates when Orbs expire.", "chronometer2": "Okay, fine. Here's another +0.6% Ascension Speed per level, stacks multiplicatively with the first upgrade!", @@ -1424,7 +1425,9 @@ "shopAmbrosiaLuck1": "Buying this charm grants +2 ☘ Ambrosia luck per level, for more Ambrosia! Don't know what that means? You soon will.", "shopAmbrosiaLuck2": "You get a slightly larger four leaf clover, giving +2 ☘ Ambrosia luck per level, stacking additively.", "shopAmbrosiaLuck3": "You get a slightly greener four leaf clover, giving +2 ☘ Ambrosia luck per level, stacking additively.", - "shopAmbrosiaLuck4": "You get a slightly 'better' four leaf clover, what ever that means, giving +0.6 ☘ Ambrosia luck per level, stacking additively." + "shopAmbrosiaLuck4": "You get a slightly 'better' four leaf clover, what ever that means, giving +0.6 ☘ Ambrosia luck per level, stacking additively.", + "shopAmbrosiaLuckMultiplier4": "Gain ☘ +1% Ambrosia Luck per level! Simple as that.", + "shopOcteractAmbrosiaLuck": "Gain ☘ +1 Ambrosia Luck per digit in your Wow! Octeract inventory per level. Simple as that." }, "maxed": "Maxed!", "upgradeFor": "Upgrade for {{x}} Quarks", @@ -1474,6 +1477,7 @@ "calculator4": "Code 'add' refills <> faster. Capacity is increased by <>.", "calculator5": "Code 'add' generates <> seconds of GQ export timer. Capacity is increased by <>.", "calculator6": "Code 'add' generates <> seconds of Octeracts. Capacity is increased by <>.", + "calculator7": "Code 'add' generates <> seconds of Blueberry Generation. Capacity is increased by <>.", "constantEX": "<> max percent on Constant Upgrade 2'", "powderEX": "Gain <> Overflux Powder when Overflux Orbs expire (midnight, daily).", "chronometer2": "Ascension timer increases <> faster!", @@ -1506,6 +1510,8 @@ "chronometerInfinity": "Ascension timer increases <> faster.", "seasonPassInfinity": "Ascensions give <> more cubes (of <> types) on Ascension.", "shopSingularityPenaltyDebuff": "At Singularity <>, your debuffs are as if you were in <>.", + "shopAmbrosiaLuckMultiplier4": "Gain <> Ambrosia Luck!", + "shopOcteractAmbrosiaLuck": "Octeracts grant <> Ambrosia Luck!", "shopAmbrosiaGeneration1": "Blueberry Time is generated <> faster.", "shopAmbrosiaGeneration2": "Blueberry Time is generated <> faster.", "shopAmbrosiaGeneration3": "Blueberry Time is generated <> faster.", @@ -1585,7 +1591,7 @@ }, "evenMoreQuarks": { "bug": "This is a bug! Contact Platonic if you see this message, somehow.", - "m": "You gain {{stack}} stacks of 5% Quarks! Total Increase: +{{inc}}%" + "m": "You gain <> stacks of <> Quarks! Total Increase: <>" }, "shopSpecialOffer": { "hasLevel2": "Reincarnation and Ascension tier Shop upgrades are kept permanently!", @@ -1626,6 +1632,9 @@ "hasLevel1": "Automatically buy Platonic Upgrades with each ascension, without spending Obtainium or Offerings, anywhere!", "default": "Automatically buy Platonic Upgrades with each ascension, without spending Obtainium or Offerings, but only in a Singularity Challenge." }, + "dilatedFiveLeaf": { + "desc": "Increase your base ☘ Ambrosia Luck by <>! +1% per perk level." + }, "platSigma": "Code 'add' refills {{counter}}% faster per level per Singularity. Currently: {{current}} (MAX: -60% Cooldown)", "midasMilleniumAgedGold": "Every use of code `add` gives 0.01 free levels of GQ1 and 0.05 free levels of GQ3.", "goldenRevolution4": "Every Octeract tick, convert 1 in {{gq}} GQ you would gain in this singularity to your balance automagically!", @@ -1639,7 +1648,8 @@ "default": "After Singularity 200, Fast Forwards no longer work! Instead, multiply your GQ gain and divide your GQ buy cost by 3." }, "skrauQ": "Multiply all Quark Gain by ((Singularity - 179)/20)^2. Currently: {{amt}}... Yes, it's that good.", - "derpSmithsCornucopia": "With blessing from the Derpsmith, every singularity grants +{{counter}}% more Octeracts!" + "derpSmithsCornucopia": "With blessing from the Derpsmith, every singularity grants +{{counter}}% more Octeracts!", + "twoHundredSixtyNine": "Gain <> Ambrosia Luck!" }, "toString": { "noMinimum": "No minimal Singularity to purchase required", @@ -2063,6 +2073,7 @@ "derpSmithsCornucopia": "Derpsmith's Cornucopia", "coolQOLCubes": "Cool Qol Cubes", "irishAnt": "Irish Ants", + "dilatedFiveLeaf": "Dilated Five Leaf Clover!", "irishAnt2": "Irish Ants II: Electric Boogaloo", "overclocked": "Overclocked", "wowCubeAutomatedShipping": "Wow! Cube Automated Shipping", @@ -2076,7 +2087,8 @@ "goldenRevolution4": "Golden Revolution IV", "octeractMetagenesis": "Octeract Metagenesis", "immaculateAlchemy": "Immaculate Alchemy", - "skrauQ": "skrauQ" + "skrauQ": "skrauQ", + "twoHundredSixtyNine": "Two Hundred and Sixty Nine!" } }, "general": { @@ -3054,17 +3066,17 @@ "noSingularityUpgrades": { "name": "No Singularity Upgrades", "description": "Simply put, you have to beat the target singularity without (most) Singularity Upgrades. Octeracts, Perks and Quality of Life Singularity Upgrades are preserved.", - "rewardDescription": "Each completion increases cube gain of every dimension by 50%! First completion gives +12% Golden Quarks and a Blueberry! 20th awards something `special` ;)" + "rewardDescription": "Each completion increases cube gain of every dimension by 50%! First completion gives +12% Golden Quarks and a Blueberry! 20th awards exclusive shop upgrade! 30th awards +4% Ambrosia Luck for free!" }, "oneChallengeCap": { "name": "One Challenge Caps", "description": "Beat the target Singularity, but the first 14 Challenges have cap of only 1!", - "rewardDescription": "Each completion increases Corruption Multiplier Values by 0.03, no matter what. First Completion gives +3 to Reincarnation Challenge Cap. 20th completion grants +1 free Corruption level!" + "rewardDescription": "Each completion increases Corruption Multiplier Values by 0.03, no matter what. First Completion gives +3 to Reincarnation Challenge Cap. 20th completion grants +1 free Corruption level and an exclusive shop upgrade!" }, "noOcteracts": { "name": "No Octeract Effects", "description": "Beat the target Singularity, but octeracts and their upgrades do nothing! Effective Singularity is also much higher based on tier.", - "rewardDescription": "Each completion increases Octeract to Cube Bonus power by 0.02 (BASE: 2.00). First completion adds a bonus to Offerings based on Octeracts. Final completion adds a bonus to Obtainium based on Octeracts." + "rewardDescription": "Each completion increases Octeract to Cube Bonus power by 0.02 (BASE: 2.00). First completion adds a bonus to Offerings based on Octeracts. Final completion adds a bonus to Obtainium based on Octeracts and an exclusive shop upgrade!" }, "limitedAscensions": { "name": "Twenty Ascensions Challenge", @@ -3366,10 +3378,11 @@ "add": { "calculator3": "Thanks to PL-AT Ω you have also gained {{x}} real-life seconds to your Ascension Timer!", "calculator5": "Thanks to PL-AT Γ you have additionally gained {{x}} real-life seconds to your GQ Export Timer!", - "calculator6": "Finally, thanks to PL-AT _ you have gained {{x}} seconds of Octeract generation!", + "calculator6": "Thanks to PL-AT _ you have gained {{x}} seconds of Octeract generation!", + "calculator7": "Finally, thanks to PL-AT Ω you have gained {{x}} seconds of Blueberry Time Generation!", "calculatorSolution": "For {{w}} Quarks or nothing: What is {{x}} + {{y}}? The answer is {{z}} according to your calculator.", "calculatorPrompt": "For {{w}} Quarks or nothing: What is {{x}} + {{y}}?", - "calculatorMaxed": "Your calculator figured out that {{a}} + {{b}} = {{c}} on its own, so you were awarded {{d}} Quarks! {{e}} {{f}} {{g}} {{h}} You have {{i}} uses of Add. You will gain 1 in {{j}} seconds.", + "calculatorMaxed": "Your calculator figured out that {{a}} + {{b}} = {{c}} on its own, so you were awarded {{d}} Quarks! {{e}} {{f}} {{g}} {{h}} {{i}} You have {{j}} uses of Add. You will gain 1 in {{k}} seconds.", "freeLevel": "Moreover, gain {{x}} free levels of GQ1 and {{y}} free levels of GQ3!!!", "cancelled": "No worries, you didn't lose any of your uses! Come back later!", "reward": "You were awarded {{a}} Quarks! {{b}} {{c}} {{d}} You have {{e}} uses of Add. You will gain 1 in {{f}} seconds.",