From 0c4fdcc5be4885868cbaca38daec94b391ae2384 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 03:41:47 -0400 Subject: [PATCH 01/25] Gray Arrows --- resources/gfx/eid_inline_icons.anm2 | 16 ++++++++++++++++ resources/gfx/eid_inline_icons.png | Bin 29622 -> 29854 bytes 2 files changed, 16 insertions(+) diff --git a/resources/gfx/eid_inline_icons.anm2 b/resources/gfx/eid_inline_icons.anm2 index 2ee40b43..c9278c31 100644 --- a/resources/gfx/eid_inline_icons.anm2 +++ b/resources/gfx/eid_inline_icons.anm2 @@ -125,6 +125,22 @@ + + + + + + + + + + + + + + + + diff --git a/resources/gfx/eid_inline_icons.png b/resources/gfx/eid_inline_icons.png index 369ca426a82c60a16ebd1be7dc15ba24c72f2de7..3f2c6b0e404c55e7d51d72ab999b21e77018825a 100644 GIT binary patch delta 27041 zcmYg%Wmpy8*Y+IX&`5WeAcClrG$P$dNJvXJ(lrMG>28pgkdSVqk&+OQ?(Xh<=lA@- zydU5y9vwKhLyKsB3bsuwPR9%2o!Xgq?|0ex1l(a^jqg&l4!pK z$I5U`7UyVv$uWG}hJybLDO5~F4l|p{Zv+`89>)-^^2rzc#+5cLT-8*?!r~Y0k!hZ3 zyZC1)@iOi3)-`km8E-2ZjrC@=*~G2$xI-ipjWs&D9{DZ0A1NR~LsLc*ZhQ1oiuL5k zeee|{s9m*MfwOQfBa$JYG{ERI-0YN=$2agnd`0Qqv#O|s`($nYjFP{OTvLMstYA}* zf zvzl}HrwL@UcW%|(l#30-D80>H=ip9zSM{3XpRK_pMg7zz~fbS~vGPH;@y_w8% zYtL_P;Rj=Z2|WFsLylFIL|>byg~Pt{c|O@Yj+J?Uo1+`aWG(VBi<0w2UWwCx|G>F| z)je-6BZD6BQ=9Bk^qD(>_E`smOA3)tUwUP9(c-wvB@KF2at{Dx^^87r@T*NPqTZo^ zZlk(=UJRTuLVNnsYy2atHzv&CcUl!*q7?V`_!sw!cu79FsUxJA4FU(EVs&=)I%PBt zXRJSwSnJG6XA=PoSiHKCd|SU2eqWFRW<~&st&YW$T8lBHxR)4Qu7Ao+6NE;ZVM9yF z`?Ham*R(DyE9aLuWj}gbfk3a8fCo58r&MXuPX2|Zm@WP;->jUI$f@Ro^3rmUU#>JY z+SsUy-Js5tIuH;5YynHkVzR`%tr#XngicHZa`##;1|#7gh}(Xy>Alz`7c@gp=tiT% zFUaiiTSY5BzeTxfetyRhbCvSg?$@cEe05FG%;iKkic8&D*UDUZnXQ5)CY}ST%pSU(E^YWqXRC0mYG$I8AAfmx_PF@8I@kj}R#;3(%yv^G(%9Ff`_7i7y+<{QIT?VjtO^+@3-CVHd1{SWP3(WPl0UMH+&H0?H0fH!Rs95%a^@+ zq$j73CV=7xBrh7+1M?m#UZtGZ(p3B1zGqo*6T!_Jgx;yBy^u;x1L$9G?kZ>uxXuBM zZ|D8a-bD(LeGqE|2m&dPNABR|tEfjGkwFGHfcC4q?nta7Xz3?Iy?$%yG01)Y$tY=nDlXH)n~j_N0Ork_&1mtkfy&qeO-|QBP6FnF$ARKXn>H-ZlZKx=Y1cNtQuXg8j9ReQ zD!v8+@Wd}Nn~e&ueX{XD5L`JtRBrzDYkVK+jxUK7v^1ljzouoO5BPY0=Hi5;GAR_h zYZ?(e7`rHkq0+$xAG6U-SZ)do`N%9Ldm|v0$QtP^PZZevq&`}Mvq_>))SPL+t58VW z$78m(SU$u3%y+a_Pmi=?6jj1e_u(ltHh5Wc);Mzwk@cXbqSFVsdwIoFzQ>S3X9GCf z{(|&$msPU$M<)vLNDkY1DPKbh_wtg=R$#0hPtE!B;>$~NSXIq7r(XkNca2Q%rbk8+ z(FdoW08{E!JTyWnU(n#6L<|377JRNHtn%Kzw&KxwW>&d(ny&qia-f!`b5hkGvHxr; zj}d%9|0en~A&#{>z3;B+o`?rBG;RN&3Sy@P5O9_aO_nW+rMzCqvYxAd*6M&EACH8< zeYTC^5XR4+7Ps_H>Ma$@t9za*%dw{}w`>h?<&*+i3f3P!f|K=B@^UjFxK`C2`KhHE z%tvn{G-c#wEZJtIR8>l)p6BUAXokkH3o9oeV%Rwj>(o$})o&ZG1g!Ah*A~$2o`E=| z)5!dMuRI>Kn=f2w2)KT|gr;5gzifWKv|pIh$`7x*OJ$z(=cF=oj2zn&g+)&)8UyN@ zU1iELGUdd`BPpz^nx=1H(GQ&7;;DfmRy)P5cE%5seJ2W@TzqW`iHVmX(uaK9kJ_Y$ zM}OkJpH~gw+!Afg0~7FQgX#bW5L@gqCPO8>Z#eEe(D>N^8|=Au5lVRP;d|7!=)01= zc)p(4N!aW4!3vrrIDkJr2_qon>4m-_FeFB3XLvHx5hDV0F%kDNk_s+Ol^7Tp9hI7E zZgtq2OdOcn&rj6gBRA9QiI@ltq*0`3)^enmuZIUkM4sussdQ~591{W$KbYo8%F!w>wO>Q0oCya?Jz&X;k=8=mwJxd#{O6RO~=EB7QJxe7BT9%jieF5R+;3Hay#ggJ^u z5Bt2D)T|%QcN1Xz34!bo}%r2EzVPy{+@gS zmA>JQd;$Pq=XXS+>#E=tdv+6Z?zwDo28|@!g`U2QVYup4?Uv{C?{<#AZ|d^~Y7JPy?XKNr}XrMKJBo(0# zz^joh)gIINRib^mu(V_-j!u7nd&$z?-o7L7=1sCzpLXiH7f)_guC3z%RZs0_AD&#U z<$u+b=5YSh6#-M;AtcX30#uCd%K$+nP6=#NTBLKkuw-e>qklZR!=Jc&Rlx zLnPX&3mmntKL-#W25v1Qs|?c^X}!;U|AeK7fDz$Kym~ET31VZKhjh3qtk>Hu+KuKJ z9;jml%5_3!rVqpBz0!4(^9Uia5NCqSSW$x7#x=H1SeA)&)0&$qh{W4hrivt=$nKZJ zT107>yg-U+Npe$Yb)m~snpeqS<}{efqfsRanZkI9cAQpU=vtGdewNj!!Qhqx?;sX8 z_u~)jT{b9OX(s-Z^x~XxL=OK0GV*2FHZ^wl-_>DahmJ3er2aX0z}j42PJFHg6z5%4 zBO8Wrj8-RVAZdb?@l#T3eD9GoE7dWMdhNfXNEicVYju>!BhO)*I)x#Qv#u_Iy5w>) zQ4Q}sJ$TVXBNtxQ&#nHCDv?Z-~IZI^yChFZ^@ZknvbS6~k)ON764_&ayNKJX{gy ztp}lLC27M01dfi5WZV|f(x>sP4=y06DGvi0#w9E$HahAUCbka(%5n+o=UA{EW~NFdS@q4mUb2# zW+>=-Zb!AdvT=N3eER+Rgn}Z4`f$u0jC@)q60u3fMkRM<@LJkv>>zM%b1MFldESEqDEncq*j)J79S8hlExf{vE_aWVS_neO%C5%?`w>~Mqj-6|3UI*sqx$74Z7 z--K#Zo|ljkoqqiNK`^3?)WwSHLlw*{Dt~o$=3ImwFBo!nGxG;+1UtRO@>2W{7+fD9 zdrbV2aV6F)vw)p|!Z`Ot2vO*oCG*`|p z|G}W5Nwa}AwfAu=&+)8&Kszlh{3yS{Iw<^C$nu)TMnqlBY~hz0zYZ$Nfff+j9@HlM zfCJPb4LZ_rz1!7~>_*>nSOukKiCXOp`Um~p?!rV}H_t&WLQ}4gm}f7qsQ82N^kYXYD`)Xv;a#h zO-ADi>modN9(ImQ-$CRWW9K!#Kc6A}M7$nJiuvW{L+*ZnMjr_(seiTB#~FQk`}V(4 zT-(1!xfwmhKVX+p0{!ipI)O@G^OAbpL2+ zudwm(egLlOYhM~|_w0Ij`*I>QyX3GiG2r~sM;ff*j^B^}n^s-}7KAT+t;B8p5v?)g zR%6B1-f5pYToj*?Vdws+6sMovZ#a_m_Pga+z8Q!epOr-yBZ@`QP+iR(*vRBYake3( z`YbE*f+@HUAS7C#e^`jys=`&y7s5#_Y1?Unhl9{Ci>vn0xZH#xEDY@$6YUIC^ z%c8zk`SJ<(5PW6B(^MU4qlHJ^*<`Sjdzg+l(RqG0P`1g)F*%epa8+u4dymtb)-r9u zLGReZ1{0Qz@I^iuJsR4+cUUNETZk}eSOfXg#H2709AWwxWY4e}yL<8r(`Y?A2 zS0ZVn=j6KAySaTCiKKl|^TW?KcwCLxV3fnXXS9v!u0RRF%gQy08G5n=gK8gt4V~QG zF_Y#Yv7EQGf=+nY48)p?$l~Y~JT!Clk+y+oeozh)sZ$fMR*ITr=+D=gNg?@F6yym- z$Ci7`;CaTNct<&>+Aa_xNc$q)kAQ$6IyxGWoJ_{WKtPed*y55*Y(xw&wf)7OlCxw5 zdP{mK0<(iHCZz|SHRvBqk%-`&969yWCUP`-1C=$J9MwX;RJzvxz7RKjo-C6-xH->v zdY3^F7#KFWQsIkytkvr0Zo8s@4SHC`{}}xvkP(rEkg`}=Y&)Zol&U{&V|_!=jh?4< z;i0E1@yir#_ z{DwYg=g3Z{Wxv~b5&W11Gq^QKS|2OnF^mSkTTEsvct!dom6RVwiS1J%i@7eozg2h!E{^vz zLSom9Jj6kjO3P8>>T7*VhkCe!2Ec_|TvbJgvHI!z@QA@zSfB`g;$0e_z2+nkot)g8 z&&+5!+g1SxBzuaE=)xQk{nZzFBdfV+Cv7Wotpxuwi7{hbFE(B?Bn z?N&nDc9h8b%h~id%M6*f)8>&&f4BZ-?Vq4-e-WqrAjwcNj2`rjAoOEwK$k&_#AcAm z^qmZ}(azSBAgtB?UabbGj5KGoR2Dd#FCr1U|JoLV?9D93fygJN?koTuw+hvfm|0N~ z_4RM6EysR`-?42A;vAYu`r>Gv1O)}9^;fRpS~j(*D-q4#R7>YJmI8oM-Vy=v{aTc* z)!^f>B&V7@lpD^Zzsa7sD-gZu9Vh5TCR+TPyDSKLaxWPEy#4COyi^>Jx`4~fN23hLp@HytL<}6r&tJ^e4Ud)&XR+vmyu-hzlDlW?Vevzm(-;*$ za92TZfZ?z>+3;M3&EN_D<>b4(eqZJysZSiQgi|DC%@ZfsGuDP`{v5O`@RK(J03IQs zKL+8`Y%WF-ty}Nnw7mMVElWP`T*<2@?xT+RYyKjp)sh(}yuw!XWAu!a%-?_yt zS9FvlMu?<~*jK%ts&E3&FvT9}L$FDi_a2*KewO#YFVR7fo1=jnN=Ps=Y>!o7`rEb+ z7iSNapp$5l1ZvRSI30aKV20n`bmBC8`To45a*FMqf$~+B!$LSJml4I3B@n^?X_%9O|IzKRQNWQsFd@M8Z06?m?!a$-T_e#*>)VH* z9<=aoH6Oq1SNd~NVAt$y*vD4ick`TTzh{q3PA)DOIGc}h8b#d>NWXeq*lN=vr`}pe zCKdmR)O})a&*`-KTT!x=mr-W%@s{fO10R8zM8!J`=!;5^Q<9|B<>h^xL)Ca^*H8D5 z$hIF|WS1Ji2fS|Yek;0w-|LbD0rI}Ul^wj?p+k{WT;(L`*=p$v2ohT&2#N&{ z<~YaK14;F{OSWN4+hx9;V+Qy6c6?hc8MpMbqAsFtwi0;2)?7u1*<$d2!A_NwF;A?I zmS%xw8C>4iSP2TM>)9C8tsmac)U{sT-7ibU>_H#t^3KOYu-wp??>Ev^`v+rWMu*{8_oVZEhZu==sco>2 z3cdiOOEIlJgHNzeJ}1!^kpijD@_!Wywl%)Ye-TtyN7~@xPO?pl?PRJa|KA`GCGRTv znpHl!_uo^_w*LM%@~?3$#-j1W!Ct;$mk*~K3GM&c;YVzzn=+{#C&vm$ZODEIL|a4G z#thsD8g13TN-l!`p~5oG&fG?q5udhCy0YG;`sk;~Cp@GF>i`}`4nOYI4uY_z$Fic; z6jSkHkJ0%5eaDdXH+BcP4?TbsG_r-sFCp{2-|5?>OqpUjgRD`pOu>tq%a@#v!z&XcSY1a`bRQ3(Aoxu%T~JGK)JT7hjjM)wZ6DT2~QmgB>yijZD-WSZfU9c zDVFzVi+lL&r@ssv3y7{R6gRyB5Sz|A-(v4o=2Pn*r(^-VNXMgoKJX(;g#F_| zEcdT(D%glds%!7NTg{=3rrOe9|Zl>h$t-lBsX#uybtO_96 z=b)w#uJX+oV1~bV_hp(sA)S;hHPd2bfI1kjYu?~gKf^7HXbbpx5u7IBpu zq?XR!ptO4S7pZLlcMO|hx$9z^=O$ir6^db&xeSdHX;+>nRq3H~;I?A#5US0@mvSQc z2dpR@zbH&RndRgW+G}!Pws)M%Ds{+Q!>`UtpE7&u2PUi(x-Gh*(-$_)livYi6LWxU40j zhlUaZuo!7cqrV0-!2@jo0S+We$syh(gf?#I)md$ZBv(1%KK--kKg3~$@e9~wRol5y zLSd$69{hfVnQ9x8;d_&+Rn3ywLe=^y@_i{h#=6pS`ZbxNv)pob?Bhx#wak#lQf3XQ z_JbmHNm^UCYTen#Wd)i)PMEE=UZ^mBySJk)5;C191M{s!dv2UkYb2NVlEfqwW|;7@ zrv39h^7HZ-Sy@L+IgDS_9W%=et%s%GG;t%Ir^m zyqWZckYy-av$Vh7DKFB9yfyW*W<*+o1B+3?YhRm6V70d_#qUo?Al57AEft02m$3Hs z>+6bHH}G|MD%6?rp+%GoVfIC+(;>fit1DXUMFv+qzcVV?!=74^B#e-`jlg%gBe46+ zols74H`-a(cobG4OM!*DL77;|Pvx>(2-1kaYP0)XcDRb=R3uBdvWg{Mx7l7X$Vg`k zPMiMg7?_=vA2VD0b4WFw%P5P@lA5O*M)I}vPi$=Lf6-D_PVV(!9r*abBp{%3-bCv2 z_{%5*i-esnB_(C2(y$$=6ZKVfLRwUri6W`e!gqt>(f`J$>CmS;uC1DR4V8ZxZ|l1- zlTE%>(t00}z{DQzC8RrVy{x8+cR*uj1K9aa5!PWUBdwh{&E6>!zk6yl+O3c*iNfCR zgtV7NNZR!d*&8AxFFwjVRY-P_enKbia{+@Or`jI#;p5Sr^@XT<321z$F|Ql!Z;K<9 zm4>i|76^|}qv53$5AJjw9td24%<$7SUwg{06s;OJPN`dg$X!u}88uL;j+Z;mQun@U zah}_mnDwc?-Ltz6%~G8}2q;MHkAJ3yDtdoL2xLLa2N05?cZg8ng;Pn|a%U#<=_VM# zYdb^7&rjYNBx=2-BZNjbn6qK7dY=Klyez#h^c@z>ciMb$w{QF@Gzod+3tOZ!M&v4C za;GKO|M1fw&E*WAth%$*K!?HK4_eY!C|}cKRrXmL?f@@I?{T!WS}$ybxhVb9NBq=6 z2ECruw!%Cl%+MCITHXwYZ$1NlP1{{Ok96~)F&Z?6Y5J#7+`o_KfH5;+6CpCXZdNrJ zk&b6zM^YQaHBbMnpusKC99W(K*)!dp*Ya>y7$ZZN!q0YjYo1AemPYujtacPIR+|8mkLVh|fE*Ms23pOA9ABv9*5)h4GKK0^cYm_mXF6(FViZs4)}o z?C^fFioQ2?;&gi3p0HP8b+&HSndM7zaPj zBsF|VvD$JjTq_(~j%AHW-HBb?UOMOi9l{uW8uj^*RrTHX_DCkadx#}KKKlM>$MUP`uNA%IX9uxT4?*d-KKE?K-Ne#y6>2KlNSiHj7o;>B67Q4y|Nw zjt0td%#ca^mHD#F3Ya3hTx{jZkn*@-QS$+om3QKPrVMS2l=Hc5|O(6 zs)s!mMYtXxe?EO=H1!_I*Jf;vj}Lgpk+vF>-c)honUPJf6jSCh+i!()cP*V_RciAc zj41$uo)^F|#+EZZlZ_p6|}?ZMbjn zF9v=hZD(9C#ZQb!0np{;#6e>VR!xD+!7P@=R{ijMC3sDnQzVF)1RM<)`K2G_~aqD$8j4s4FRlhUw3#4 zZ^-E}$ws+hU<@ZdJ0JeXz5dWdG}b%%$4UTQI;gGLB$mfdM0^bdv7XlR9f#t3IO z9T2v2&d7L;{H44`L{JZJtV~zU%R897-i4z6qwu5FwOU)yKeOI4*_d+fKDyHD z0`%{>HAl^oEPz<)_4We<+@|DsNwTGb=zA2>&^NHAUYrb#d#-Ql*jqYDR>!m zn*8*=cDwApe5f_i*w(iI2}eix7VqwE*-G>v+r41SwJj^_vB$P$Dz3C!&m0av+xGS% zKyvnG_DP$CVJu6EGZuFL;VAW#$FV`l=Uu}zG4J!A3kOkj(RnY5)DSV zz}#o^&6H9kpGZ3FvOD<5EYAf8bnUysF+a=MQ!C6ax>LYu2uG0l*y$ZVfL(w$5Iaym z)Dmi(L?|gTlQ6K?c5ovfdq?0#c`bTgT=+t>-!B&Ii)B92AY#|9L{W|;Gh(Ti1`OxN z(f^Ro|0*X!4L61gnAkgo0y@Adi1z-K{s%)jUlO02GZ?^rbt1nU7l;JzA{h@{bz&?rIdP8LT;#Z~4H}(P-}!2it4JDZRM84J z_m(={iP+*f*m%V(cs+|_;9`E;5MX#ZVKmk3Lbec6vYbN{eslpohSlkN4cani30#FD zNve*!PV;6pT5yp*hv4AhDDZ-wq<)a(Os}e!S@DIy9It~sT zKR-Y5O6RTewl=Zv1qD#rUO1A0yemj@QPo1ZWYMBaNZc~0p@%$yV;Fqllow%|CF*Dzi7RE>bT^d&o4&XDEn8EDnTKI`mu4P#moKEFb_m|*n zA9vGAN6lz6mDq@?FTH2W36>cvm~DHjujO>fKGha;|Cs}dcc)w|&$>u80N0E(LCm%- z&-bu;2;IM$t$RZFv^9PAiVVeCcn_%%lvsT8Tt;tdRUKv#Oi%V|!}sXGyVv#JW1;ie z&sTsaj?Qz^@f>{BQPfafHh{Xl&YoHd0!CF#0JsJq(rDiu#Px}aKHyKvtA)5%K*HV) z&#q=6t-iB!_08KI5&fjaFE+qHFNNW!DT~@4NUSB?o^u$MQ|7&FtZqL$WjB?;>F)$f z$q!QPqD^a2QBf=+2nzPIzxQUF+5pW}V6hG?|E(AWRW9tMJ}|;x!wW+|N^}XBhWe%l zuHN3w@|I^kP|q>?zmC{~nx(|hVkGz8Rx3U}zKpW6+pd5Rxm&;H`?u0p>+stt1H=L9 z#ne}EWl0GH4p}4RBr&l!n9YSZQ}tSZ3;WM}q3|YL%rRES@yR1xJXo$AdX$8;v_IaL ztu2cvZ?S{#ah9Pk6lFgkd5)6C-?6uRZizDRz3yJ0^CR4xf7(Emic00B&kWH8uQ{{E^YEu?FFUCT9$x*}sEmBX>_f9<3+cc+1j*zetVGhW5`;nXtFl z(HQAf-^k_lHX+N)$i%B8*P_Hnv-%}t04$oEXaLo0$_~SbYlp7$sY|i<0tRhZNSb*_ z?=FX}+wkmHb;w_@lY0f-uT@C;7Y~PH7lQ-1HpdSUs?rbN&;foAaNYc4m1L)z(t&_s z4tg-WF9e6#a0|TLRh4V`jDf)sxv$V&k^ZCJn-$AN_iNTR;-LeR>HM&Y&~hIaP(~9* z1-3j5_R$&PjADkmk9Ygu;{M}Le2}kAKO%WS+wVmGP@7ygh%O7zU3|=cM`)7~_<53Z zWwzQBKrnuIfk8~i&K~|@wW^0BL274?)4}F6b0=2d62y9E%Af~vPO14Vu*GQ6pvMnz z>wQ}PjowgzxpS-0Hu~*du%hl)9zUP6H9nr@;Y`tC=Hi1lmp9hGe}$SMGk#Rkw4A{1 z;e8AVXFlFKUqDNJEdx_?exK4!FHMtZRnRT$c{X|M%Os^NI93uGhEs70w-esi*#`q+yQXX|*i|aG(uA zak<)?Ade1zR3rgX%8!7FC?99=#GD0!#$eD$KW) z*{*R{DW0rSe8_;8UY~0@uD>xJHZ{IZVf?y=i;k``c*l%Bl6=1>VnSW7h3{M*T}4j* z1{Lly6SPW3^lh;BC6$bX4rCVC*-!pVqZ(2^VN_-oEj?z*$xb<;tJr*v@1#r&CdJj* zCrGvyoomCh$Wk8vk;RF!vtx&ZglviFA?_U-1b+plNaxx4#PnLv8upX(p{ z9z%i%2#CA;jJL-0>-qJzFLFH3phb7W>W=HqqWI_aXYqGLCaBV1@V?m2*81UndF9W@ zBlo31V#w^1#cR_?q~yLn*L#9k@b24;p0saZf)^TE_|-c=`Y3AR4sd85=NXvEB*o2g zxVbm8#IS}{D}AQc5n?VR29^R{OaC=vLZwtd*F4hBChc#YW`AVQ6YI4StJ8J!NJD6U z-stb7YA+3Qx-zA-?k$P{%cKH$dkoUEOptmh+6~@=8z2GzWpJ62rBEG}+ zaw>QRl{&-%(m)DDd|PQ35>83f!Z#p}pZ8;Ck}LlW#W#$QSe)r6V&WZD4}!xQtfMi$ zdt$!ckLJ@j`7dq>zD(gnieT-Ov_lS;xv%q+fr~gMcT?)#?m1Tx# zpiekHq5~EXF#BQaC`S@N+y*`2@%)McBz6yX78ne5_Qe&z03K`2|0b$cW;{S!MmX}D zRF^MFK{p4UQqAFB)>p+WFV;R8+1{~q^uOc&RX_}YFsfDRUwc9-Xkxro967>ifg+(& z99}TMH}&@QP3uueBS&nD*-&F{ozMBj1xqj2 zSHOg#g*X3NUH}lQ7RP4RQ-KYb|14PTkS(|O4vVyr)vq&*#BxZmj+o{e)Ndh(y6{4= zR|;znJWX=2&%-R#uA)dq`PZ{h%?KcPTA8*MnPG^fqoBWq8l;_H4rW_mg1lv~)oEPE z(jMRr<`hhF54R#d)HN7yc@fIrZl{s9!DrWujX}nD1O6irGy6YEo`f^52C*MG>-Fwr zS(NfdsicF$ONewDcyqp69NLD>e!VT?Pg**vc5=&0hPs$f=>VPdu@f2o_Wnji3@?$P zF!OE5k$cnodfgn4Wa7OBidoj$Wu^eE^mW+^MC$E1lGDFB>oaG%R*W|ruLQH{k`U%! zEv(#$FL9|u&A$R`vF|4S%y?EWLQ5J+d|O}l9{%yoAsH?rb`g8M|3gYrH+x;e;Lg6nf7k4tSA;IE zi@Izvf$@(T$eK1A3%aBV6^Ib$&KC@WY%o_T7cbz_Syha}_u&XUww^otw%Vlvs}D;V zqM)T3oy3>Pj5*`F*#DTz1|tc_G7OGmQT~q|SwvviUJrcT8vj8EK~$fdZ?KBb(tGmh zE%zI|ncJ)`%_up_XoX!!2ngMb*H1i(;9`^i{d(Hm&hX(nt%%^tR?DD^`$tF@n$^gR z!54pXX#uNC&|I40=Jv&FsjHJ+cZHDD9JVh@S)Nd{cCBx$NHVLgtN%m&Fmu_S&yU`P z0^8Z)xLn^yT-w&J8Td~!!l@_l!_1?4ri`c?HWfJ_Hs!Gf(G^>0x@8Q}F9JmUV_Akt z0uXeUxUJ3HM&D}csfqEje+ldFSqZ^X^x|t_4Ww}-@M zLljLliX-4X?8;2l_hocy6H$Kais$!?vu!AHbX8(1#nrW(#}@Z1S9xXK6pDm*`IA zRqh7`R;JOtuWL+JlymnzA8On|0KGK(uyncXH^BOrbM4cQp6yinijI760x51bg z_vWhW%v4%FyROIX-xLJV3~vf)bn2e0;xDShRG1A>;%Wh_8`aFg?q!#spa~N97R?v_ zT!WGCN&f|UXOxv^NYuv>L{@Lp2xbq44Mxu1L&t@CWLt*Qa&S642gKt;-m=X#q=}*7_t}+ETFPic_vcCVpJ|iTTpYxtZ zvEvTBaQ1X^W>R%@hQNwebs=X(j8iwGJfdJlX7RbcfyX)iPZ~cJwix6*8=)JRTf&H{ zH5<}K$9(e2$KrAsL*5^LP7=A3`!x*n{)s2P<)Jk$G5VS{KnENOKeoV+7X{mXRwI+~ zZ0kW;ISugAYP3n}Ftz-!z{R?!^(sD|NN^J}&!zFLvu_>z;L|;%xx}c}m!ppozmWhB zY}zH3l{X6pDa_*q85byXm8Mt_LTy+;l{#VC;MF)Xfq<;}qSvD(|rO{%PbADYQuAv~wD?gin;}R!Ki?hr1aUYRb)F>Lh33#LcW$JzYkE}7fvlmQe`$sphOF?Mke*WBCJFq0!FT48gIw8$GU-a70EYYuUa!ve*WnR zw74Uq&x0*3pQ8mQS)`=}^k62)NB~55%5p`)z{Mr?K_fsVJKg935cvL}S1z4iM>v#YAYft8h&mlh**E)eyR@I3DyjUS~s|I^et=#+*+ z=Cs_fekK)l2(9lG=of3y3(xw#*zCat7@lqnjuIRJG&W<{1~2pn=OJ~ro%}L0Gb@r; zIQztHH3u}g6(9qyhf319zj5#gg|!*Y&*sY$0cPKeA8K39O9DXFnBOkj@wSKXHI6@` z`ofvC`oiu12Ao5b*+@YF`@Gc_ZB!si(WI1Rc6$|ESrLnjMA;e2{xxiq2T4&?gra3i zx6E%NH>AP=gh6k7V2vszzs3Q|o&P2Q2tRzESBAal@7A+}7Lc;s4`+M<*ngkn&Pp0e z!(**z%tJ`!lxMOsGGYn};kN(rjz*T-FrDsMey0Z+S9Lz+O8Nd9$uLTu=-biwojJ!d zBvmZ6DCn-XeN}6?IM`i%Rpu25cs9%^s@eN7BjwmR;!s~&DMPq8?(rQt2r2(yp87s1 z{h`(LCbL&-6tYX`qJDG4=QdFGDrUYK7(au`c*wntti0UHlmR-ZyhvcvaKgZDGzsa& zY(KxG#XU>PYU6rpGuX=H3s2?4?K+s>E@CibhsncLs^o|hmLL@`uT59&yrLkLkyHK< zRq+#{YJgx!i3hV@juMIozm2f;dKt~3TMPARrXwHADgdWT=eMIXpT!?qGw$H^Em9aN zGAE=8uyD#(WDzul=4|zcORCM6>&AaK_X@XiScs1o-vd?AdP+2$E;vB6?{>K!vp6Q3o5iv?6zG|l!551` zpG#n)jV{Y}IV#pX7D(vVp7IfY<)jhLHZ($7LEbS$iQ#>P3?z9t{ZY71ZK7(BP&d%ckkoB8bvI^vME2rZ;y+gVpo5wf1e1 zgT)`$s0ibpbWgtfS~!;SoVa=snfj9i-%lWW6R7{Tc>#x#VcSM}gE(DjYEVGHn%n9) zdE?V{W3FOZU;cU?8p5Y3G5a55@nHXo_yaP_P_9v_+?C_0Z*`$TARBC8GdVgsOG&u} zdZW*IXI%D*JRI~CQ8K#^WRVsLU!1h*Zd!aoD*L=$sK+H&>OTyl@Lv<{?OZRk008&_ z3hGP+{;y=0+-pz(YZw&LZ{bDU)*G?g)8W_w5XXznoST@83!W_ASElapM=9J3{irVI z;5jk(VS>sRb2GD*AHlGz7rs9l?dIxV^(S#E>*)rf!f^VOoBnMaY#Z|wMPNbiB&_!* zr1Dt9lT-3>;iWwToordM=SMwxnClN0(gR1tDdZ&*rSgerbUm@s# zyJzRCn}aIm<-}1Bl$+-BUv&1AHL$`3c&?WdBCj!U%RX9gYcxQu@0{3Hk5e&ry))+j z!Vaj0j~tzn@*_5r6nTUWI`=d%$`cW+9i5%Wy^N6<1hgJ&_z^sGa)zoWJAZd#{?&W$ zamAMjQY1zBXcBEV@Q4C+y~_Cf2OwZre1ZET&E7SmH8mo>i#m4HE*9(wpdA5Bd623% z$__URJ*^kn21>WLCDMtYtaQmn>Z`mW2xZe;C~6YIwIiyhf{u?P*=@pI7DY~Qpe4+p zh}>qa=_+r|zL1C$wT%tdNU}X^H%_W|h!lLL*a}Hf*E=w=;X2Bd|I6qGGMaWK)Gw-; zrSHOSG>%p`?p>`P?yUDd=4xZbF2Z^457iP70c6*kbm(XsHl5PH47x`#7Qv;LCk|w( zGkPJyNg;XsLI0V!206Rv=YU&ZXh&5@$J|RCB6 z;9w|W;L`i*AgH)Za_ShEYRi(r$v+GmQX_aeuZBg1JW`PNvafTU6Ht_wHp^pdc(`nR ztl7ydt3a`dHPAR76sHAUP$FY}Yv1`I0rM15|Dr|CwVKZ!;e8;P#}lVz3X)Ya!0_eH zsI8*PPlJCqscl&gcZI_n45Nar6Oq5NN2WdW)~2StQ?$MHTGRw28?4}3M}Cd4a5x<| zUse$cD@srG=j|Xnl(2{GgP}pQ8^Pg#`mdN`Q7*d^A=o3?Y%oxer?v0btlU5&@E#WY z9EjUg`qM(0w&?h_XR&;?azb6-SqPXV(1%wU|X)T1-;3{MR(jpc{$S2 zNn6m6y!4yzoJAmRW!w6N%0gY3d+ZUM=^^=e*zmqAvX-sMb?;yFn2p?vA&;2Q_VRVw zvUEgM1fqv6>3!f8J{wZc0XHj2SeKr{1OBj-Ayf<{-09I`zAF<+SC8E>Uk@o%eaGDV z*zkGh6IJ}35LUY-aj~K^&YbBe*NW-Kmb0Xdq@}=b>>t6FGg1f_vFS1X#es>CX2l2* zY}^2=Gjr$rgIO3=AP8koQ4mQ9r;H8u|El=vuqe9s@7bk0l@O5bl$MlkNof}05hSIg zVOJ%TF6r*>u0=vhN>Gpx1d;AsVtI$}@2{8ZIiTm82c*-)-dHv`YGlJZv^*Afi|MYA#|jLAuly%DCr~v zNjtuu=j${%O86a%_{z#wowdNp-|G=U1vd_ZqZ~;QRpZ@{uIes+r3d#mMNk`y0bm{X ze<-Sr{+eQQA2nPQIsV*jBhLfw!Od=MampfcHy>#T3mdZ@At{|9$%M=`;n%2~uq4WG z0^RL@M%Cojx3{H*d=h@=y!i>uJ32ex(M%{6VMedNz zb}$8yQVj3KI-62<{IVdHISU5djyd-@$-{q_H|f~Ajclw&^3X0OQIyi@W@zK>buGx8 zUb5%BTVF2LuEPR@JiC!6idL=_HsB(qpHlW2N)?ZxbD%n;* zB$d^Ex9`N5zx@RAu#|}`YxR0$>O$`~oGuG)GkSjJK%!#j&#zf@@#FG_E0>{kufTP| zfd~%(f#N@~ju=a}TpApCZPw~QR_Oz@>G))y8IG%kYMm)VY!FVT-a9;?o<}5!kaw-1 zdP%TgDNW)XzzA++$P{qf(x=ia#{FZ#GEueDfO5`!z?y&qk#DZq)xIzMkKxx*7P99w zATl*NDBJLs1guhBDb|WLUsZs7US#rxnF6l5j?Pcs{-feTDaJphE+tO5gu-dcIe`sCS24>GV$quG23UuhEKnC_Z{yODDK=HZDL znA@Rmb}6blA%`sxtc~T>Fh}p-gP+wHprm1KMMyQ5eaBaf4UQxQrKu)i9>-z%U)sya zwi~>w+a9Kn$TM)QeE?DR)%Yi}{Drpb9(Z41G+9R=^CNaBXxo^~Yibk){OzMzt3z){ zn%tex1xna<{+kBH8>_P0~}qJt1NM(b!TBqF`H8a_cQ_2TP`jxHFb4R1lwy+sM#8e zQS=Cu+NfH8YZGI>(+C%h{5*Tos)0y&3ND?2Xgzk22hhvbLf>|O>qR_NKSE0|%`ip# zQ^n=Jf(07@Z&SM4qLbG4_sxA&J_yfR?M%`m%Fe8ta8DGkZll1R;iPD9R;$tNMIRp7 zbEDFL?8zpnSZ#yhHzof{=IZ_c#0);2EBbH&g%Y6-z3l^K1&3ehuqOG;YdEaS@ws2K zLxB$#D~f<(u-R#-Cg**8!Xeo~y&55rGS~=l)U*+*ouiIJr5tAiajW(BfsC32CR(^R2cP62QhRK$}056{azx`eHm!Qw7g8SH+XWuVD02OhhFa8Mi+$@0DWWnOnD)GGVUa^vXDc&QqK2p|ikA~u=gp>A0qWu&;bPJ# zmio^4%vg51teF@l_bTHG7<+3kr-2;|=Oc-HH~hFl%{w$Kp$24CKSqFKSaFUv;KhGL z9^mAi_Q3SRC2-FX5xKVWfT4`MhGVTZc#sk0ya6B|1m#DJ=kzNxq{&(5-#6--{fRW8 z?E8b}8|m=chkf+oGMC_t*8lGgogaa_(8MY|6&Im4jl_M>6LoZ-nVH@gyIO@`i9WKt zfDB2+i%zz?y!vMD1)U%&3r%v_5EK#{RNe=>|E0I8xio#J_N{F*NEnKw6TMbNcL>Se zaoz*aKP*zPZ+wGg2kz57!dsT2WAr5eXz^2kB_Hl4ypGAn7n)ru&DO($l$B!v)gS=Y z^Q}&48$ntb-HF=WYhpOV00)de8HDkA`)wNjD!Du0^k8J@ply=lIET%ii-QOYNHS=W zji9^FfVJvWSQ;8sBtn?9m21|@+__mB!D>SU7WPcaQ&t^R^&?GJkb$)ypCO8wTA zXC?r8$y8R-l!1@2l1dq-L)ho~=%v}BC=_t=x%p6taVP&AEzUfWYwzX|BF4LykJ)`( z@v$Zq=C5gR(X)j=xzj$gDBXL4O;J?Hq00O&%7iX!Ph!`igIf}{&Bl7HPDw%0Hx3M} z52ep!6vB-^rmR}*{O@3s#)8(#M}kuE`#ZRxpRQ?i)chX$->b&bHENweV{c-sTQ_3h zt-eWU0#d(7<38#2^niWI?%%v2Kw6J4FN}kN+&k5H%mye2$i1NW0OGgQ;s{%I9u-k| z4XFSY;2-MC6+)VS!DJFCZ%+@zun&BMYiRVwJ|(br*k(>Tw`Y!2g|Xbg0C}p zRmART?3Bx`b^ahR^eq|Ba%o72R5Cz;DI#*6_2pTmdY6Ml#RS-t+cxAFlQ@tu8-SIU zSF3?~fGlPlo2i0sbm~`3CpCYaznFbV;TIpMgp>SdolPV+su5t-;GHXOf+j;C@>dh(?}Qe@Uw%7($*l3A zzrUZ6iRsI_?`$};JXHbQi5S-*g6p>3Mgv(bxGmDiBQhgYU=+Nga28Bx_8^%Wi*ax| zQSe6W^-eq3Cgr$M>38LY2XYnI_20*#Ks|YII4)|TxV^!c}3_6V^Y|M^fVm^On&D>!IW7MSaP#Z^yi-^yC}7l%&!gZWI^ zJIh~^Ch6_r=FK2`s}Nih@4F+&ZThG)@_1}vbY-4dHngMrV;T)xAm6;+d;0WDhXTG` zAMLH#2UDZ7@IDMoR@cSwr41FW8zp7kywuOrO98Eq_!OHQ_P~h6!zuWmISZ43?-#jJ z`~u8eGl-6IuKa8cNWbrQIF~whnj};=pJfi3eX%c9uzU!PyL4F$olt9z;6KOX$_o%& zB6pc0n6Xu&%IHtEnebl^Xf-yW8<<5M3W~!?!Ir~t@Rz!R0@y*+YK5i6gAiEsRtr_? zI$KZdt_APQs9p97i3*d)H}1#s#KPl2|Fk^KQtE)H?B&$GKD9ej(bEH?lPWe=R+A=9 z)^~jKWszh#ud{cbFcy}Xt}z{dhAH2df@=>wz=~NZpSC{e`n)kEA#%7kovX6>J3Px% z=vkI*R6BM_119j_rD5F@`%8RwsS-x^TD$iBt)p3o8h&P7jA?l?Aos44wy~M9lQzq$ z?^lh|$zoPhe0-*+WN&XTsL?FtBJtGfHDzIEXD?rJe(Q>`(G4I6E*+eSuO_Z6qj7Z8 zHrIFVpV>6V4M~>uN`ud6tRo5p6s;igrH^`oN1gYc^XP^>pL;+X!6iCU;qaO_*Puj) ze>pPcQ_iMBu%+M!zS4iT&A3)335TlVksm<~x!CaY&Axn@D*SDna4}w>yJwkJ(pQ zw&nQqIq}8b{C4K*1XX$=pcFIx7$gEvJ!OZyxW&;QZ_gT{US`mNj6uXj0ec!*c*WuXsUuOITX`_0}bDr)j z*Ei9YBqy%PyJaus!k>NkR;g8C%^zSTqQlaQmp4a5giUM8ry>LlaJt#0+<rlA}bk(rfKvLt=Y|GQG-05<(>QK2K{|v=HeAZJLvK$>ukJkasFP0<7#rHx`CK9OFP6W1uu@FHQ{Ri$RUPjP z!{Rp7?x+fY=_nFfk&m}I&HgM1NyPbVB%KS)m;f6-)-Rj7Prdv>(RvUJazaw#-U zTKThnP`hNecjJTyFdtfsb}VFB1XI^BC^5(E2PE(4sN z=o+eqJlvl?t>KgZ?dXP~dEGM@KTiZdSR z5-~f`ix0t;mY3Hr%PM&j><>uZFTv~fS@Fr>5>jq&7dvULn_UMEHpbhAD$Sbk0o{YG zk{`Bpis2q78M0`5py$znY=qqGUf(AJ9E-{@N_*833Y>B%pntqU+W7N@<>QD+UbhpN zNW{57uVo%^b9;+N0NSRJ@gNY>gIS(ht74{*(d3}WB zqPyU~eV<6JlK@#~_Oz)Ds^h>pt(226K1hcw<-4teftObSjy&>$1*s<5>V?%=1`j&u zs93uv0V_e;Do|Xn6T0rDz%q#nm;HweJ zw{qYUX22FNDtyC5QCV_6SV-Fhhc-$Uf|b)U=dn+YKX$-G%MrYIYbaig^Nb#hmFPT^ z9!r&uYsM5boV2|BUKXmt0TO}?pd(AAKn$Jad(iF7=sV8rgeuRXr@a`s#So0#jd6pW z_UEC3QpYhj3jSf|x|E=T@KoR_$ixyogUPwmf-|M~4i@KjjJhvÌnlGgYfU8}Gr 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 Date: Tue, 14 Jun 2022 03:42:11 -0400 Subject: [PATCH 02/25] Gray Arrows, Room Info Markup Conversions --- eid_data.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/eid_data.lua b/eid_data.lua index 1a866bd0..12047e13 100644 --- a/eid_data.lua +++ b/eid_data.lua @@ -133,6 +133,12 @@ EID.InlineIcons = { ["ArrowDown"] = {"ArrowDown", 0, 10, 9, 1}, ["Warning"] = {"Warning", 0, 10, 9, 3}, ["Blank"] = {"Blank", 0, 0, 0}, + + ["ArrowGrayUp"] = {"ArrowGray", 0, 10, 9, 1}, + ["ArrowGrayRight"] = {"ArrowGray", 1, 10, 9, 1}, + ["ArrowGrayDown"] = {"ArrowGray", 2, 10, 9, 1}, + ["ArrowGrayLeft"] = {"ArrowGray", 3, 10, 9, 1}, + ["IconGreenTint"] = function(_) EID._NextIconModifier = function(sprite) sprite.Color = Color(1, 1, 1, EID.Config["Transparency"] * 0.5, 0, 0.5, 0) @@ -803,3 +809,7 @@ EID.TransformationData = { [tostring(EID.TRANSFORMATION.SUPERBUM)] = {}, [tostring(EID.TRANSFORMATION.STOMPY)] = {VanillaForm = REPENTANCE and PlayerForm.PLAYERFORM_STOMPY} } + + +EID.RoomShapeToMarkup = { "{{Room}}", "{{RoomSmallHorizontal}}", "{{RoomSmallVertical}}", "{{RoomLongVertical}}", "{{RoomLongThinVertical}}","{{RoomLongHorizontal}}", "{{RoomLongThinHorizontal}}", "{{RoomXL}}", "{{RoomLTopLeft}}", "{{RoomL}}", "{{RoomLBottomLeft}}", "{{RoomLBottomRight}}" } +EID.RoomTypeToMarkup = { "{{Room}}", "{{Shop}}", "{{ErrorRoom}}", "{{TreasureRoom}}", "{{BossRoom}}", "{{MiniBoss}}", "{{SecretRoom}}", "{{SuperSecretRoom}}", "{{ArcadeRoom}}", "{{CursedRoom}}", "{{ChallengeRoom}}", "{{Library}}", "{{SacrificeRoom}}", "{{DevilRoom}}", "{{AngelRoom}}", "{{LadderRoom}}", "{{Room}}" --[[boss rush]], "{{IsaacsRoom}}", "{{BarrenRoom}}", "{{ChestRoom}}", "{{DiceRoom}}", "{{Shop}}", "{{Room}}", --[[Black Market / Greed Exit]] "{{Planetarium}}", "{{Teleporter}}","{{Teleporter}}", "{{Room}}", "{{Room}}" --[[Blue Key rooms]], "{{UltraSecretRoom}}" } From b46a34c7fe99ecc5521d3cced38760f178bfab1e Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 03:42:55 -0400 Subject: [PATCH 03/25] Teleport! prediction --- eid_holdmapdesc.lua | 47 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/eid_holdmapdesc.lua b/eid_holdmapdesc.lua index 7ac4cb34..fc8d6945 100644 --- a/eid_holdmapdesc.lua +++ b/eid_holdmapdesc.lua @@ -3,6 +3,7 @@ local level local currentRoom local blacklist local holdMapDesc +local currentPlayer -- Rainbow Worm's trinket IDs it grants, in order local rainbowWormEffects = { [0] = 9, 11, 65, 27, 10, 12, 26, 66, 96, 144 } @@ -41,6 +42,43 @@ local function SeedToFloat(seed) return seed * multi; end +-- Teleport! Destination Prediction -- +local function teleport1Prediction() + local level = game:GetLevel() + local currentRoomIndex = level:GetCurrentRoomDesc().SafeGridIndex + local possibleRooms = {} + for i = 0, 168 do + local room = level:GetRoomByIdx(i) + if room.GridIndex >= 0 and room.SafeGridIndex ~= currentRoomIndex and room.Data.Type ~= 29 and (not REPENTANCE or room.Flags & 1024 ~= 1024) then + table.insert(possibleRooms, i) + end + end + local teleSeed = currentPlayer:GetCollectibleRNG(CollectibleType.COLLECTIBLE_TELEPORT):GetSeed() + teleSeed = RNGNext(teleSeed, 5, 9, 7) + teleSeed = RNGNext(teleSeed, 0x02, 0x0F, 0x19) -- magic disassembled numbers! + + local resultRoomIndex = possibleRooms[(teleSeed % #possibleRooms) + 1] + local resultRoom = level:GetRoomByIdx(resultRoomIndex) + local resultSafeIndex = resultRoom.SafeGridIndex + + local roomIcon = EID.RoomTypeToMarkup[resultRoom.Data.Type] + if resultRoom.Data.Type == 1 then roomIcon = EID.RoomShapeToMarkup[resultRoom.Data.Shape] end + -- Find our X/Y difference from the target location + local myPos = Vector(currentRoomIndex % 13, math.floor(currentRoomIndex / 13)) + local newPos = Vector(resultSafeIndex % 13, math.floor(resultSafeIndex / 13)) + local diffX = math.floor(newPos.X - myPos.X) + local diffY = math.floor(newPos.Y - myPos.Y) + + local d = "" + if diffY > 0 then d = d .. "{{ArrowGrayDown}} " .. diffY + elseif diffY < 0 then d = d .. "{{ArrowGrayUp}} " .. math.abs(diffY) end + if d ~= "" and diffX ~= 0 then d = d .. "," end + if diffX > 0 then d = d .. "{{ArrowGrayRight}} " .. diffX + elseif diffX < 0 then d = d .. "{{ArrowGrayLeft}} " .. math.abs(diffX) end + + append("{{Collectible44}}", EID:getObjectName(5, 100, 44) .. EID:getDescriptionEntry("HoldMapHeader"), roomIcon .. " " .. d) +end + -- Teleport 2 Destination Prediction -- local teleport2Order = { 1,5,8,2,4,13,21,12,10,6,11,18,19,9,20,24,7,666,14,3 } local teleport2GreedOrder = { 1,5,2,4,10,23,8,14,3 } @@ -88,7 +126,7 @@ local function sanguinePrediction() if spikes and EID.Config["PredictionSanguineBond"] then local spikeSeed = currentRoom:GetGridEntity(67):GetRNG():GetSeed() spikeSeed = RNGNext(spikeSeed, 5, 9, 7) - spikeSeed = RNGNext(spikeSeed, 1, 5, 0x13) + spikeSeed = RNGNext(spikeSeed, 0x01, 0x05, 0x13) -- magic disassembled numbers! local nextFloat = SeedToFloat(spikeSeed) for _,v in ipairs(sanguineResults) do @@ -120,6 +158,7 @@ function EID:getHoldMapDescription(player, checkingTwin) level = game:GetLevel() currentRoom = level:GetCurrentRoom() + currentPlayer = player -- TODO: -- D1, crooked penny cheats. 404/liberty cap/etc. "what item is it" @@ -141,6 +180,12 @@ function EID:getHoldMapDescription(player, checkingTwin) if REPENTANCE and player:HasCollectible(CollectibleType.COLLECTIBLE_SANGUINE_BOND) and game:GetRoom():GetType() == RoomType.ROOM_DEVIL then sanguinePrediction() end + + -- Teleport! location + if player:HasCollectible(CollectibleType.COLLECTIBLE_TELEPORT) and EID.Config["ItemReminderShowRNGCheats"] or true then + blacklist["5.100.44"] = true + teleport1Prediction() + end -- Teleport 2.0 location if player:HasCollectible(CollectibleType.COLLECTIBLE_TELEPORT_2) and not EID.isMirrorRoom then From 0ac8335203eb054d3934e15b14208b2c26e69b3f Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 04:23:42 -0400 Subject: [PATCH 04/25] Overhaul Teleport room names/icons --- eid_holdmapdesc.lua | 49 ++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/eid_holdmapdesc.lua b/eid_holdmapdesc.lua index fc8d6945..86c0c763 100644 --- a/eid_holdmapdesc.lua +++ b/eid_holdmapdesc.lua @@ -44,6 +44,7 @@ end -- Teleport! Destination Prediction -- local function teleport1Prediction() + if currentPlayer:GetSprite():GetAnimation() == "TeleportUp" then return end local level = game:GetLevel() local currentRoomIndex = level:GetCurrentRoomDesc().SafeGridIndex local possibleRooms = {} @@ -63,27 +64,31 @@ local function teleport1Prediction() local roomIcon = EID.RoomTypeToMarkup[resultRoom.Data.Type] if resultRoom.Data.Type == 1 then roomIcon = EID.RoomShapeToMarkup[resultRoom.Data.Shape] end - -- Find our X/Y difference from the target location - local myPos = Vector(currentRoomIndex % 13, math.floor(currentRoomIndex / 13)) - local newPos = Vector(resultSafeIndex % 13, math.floor(resultSafeIndex / 13)) - local diffX = math.floor(newPos.X - myPos.X) - local diffY = math.floor(newPos.Y - myPos.Y) - + local roomNames = EID:getDescriptionEntry("RoomTypeNames") + local roomName = roomNames[resultRoom.Data.Type] + -- Find our X/Y difference from the target location, if we're on the map local d = "" - if diffY > 0 then d = d .. "{{ArrowGrayDown}} " .. diffY - elseif diffY < 0 then d = d .. "{{ArrowGrayUp}} " .. math.abs(diffY) end - if d ~= "" and diffX ~= 0 then d = d .. "," end - if diffX > 0 then d = d .. "{{ArrowGrayRight}} " .. diffX - elseif diffX < 0 then d = d .. "{{ArrowGrayLeft}} " .. math.abs(diffX) end + if currentRoomIndex >= 0 then + local myPos = Vector(currentRoomIndex % 13, math.floor(currentRoomIndex / 13)) + local newPos = Vector(resultSafeIndex % 13, math.floor(resultSafeIndex / 13)) + local diffX = math.floor(newPos.X - myPos.X) + local diffY = math.floor(newPos.Y - myPos.Y) - append("{{Collectible44}}", EID:getObjectName(5, 100, 44) .. EID:getDescriptionEntry("HoldMapHeader"), roomIcon .. " " .. d) + if diffY > 0 then d = d .. "{{ArrowGrayDown}} " .. diffY + elseif diffY < 0 then d = d .. "{{ArrowGrayUp}} " .. math.abs(diffY) end + if d ~= "" and diffX ~= 0 then d = d .. "," end + if diffX > 0 then d = d .. "{{ArrowGrayRight}} " .. diffX + elseif diffX < 0 then d = d .. "{{ArrowGrayLeft}} " .. math.abs(diffX) end + end + if d ~= "" then d = "#{{Blank}} " .. d end + + append("{{Collectible44}}", EID:getObjectName(5, 100, 44) .. EID:getDescriptionEntry("HoldMapHeader"), roomIcon .. " " .. roomName .. d) end -- Teleport 2 Destination Prediction -- -local teleport2Order = { 1,5,8,2,4,13,21,12,10,6,11,18,19,9,20,24,7,666,14,3 } -local teleport2GreedOrder = { 1,5,2,4,10,23,8,14,3 } -local teleport2Icons = { "{{Room}}","{{BossRoom}}","{{SuperSecretRoom}}","{{Shop}}","{{TreasureRoom}}","{{SacrificeRoom}}","{{DiceRoom}}","{{Library}}","{{CursedRoom}}","{{MiniBoss}}","{{ChallengeRoom}}","{{IsaacsRoom}}","{{BarrenRoom}}","{{ArcadeRoom}}","{{ChestRoom}}","{{Planetarium}}","{{SecretRoom}}","{{RedRoom}}","{{AngelDevilChance}}","{{ErrorRoom}}" } -local teleport2GreedIcons = { "{{RoomLongVertical}}","{{BossRoom}}","{{Shop}}","{{TreasureRoom}}","{{CursedRoom}}","{{Room}}","{{SuperSecretRoom}}","{{AngelDevilChance}}","{{ErrorRoom}}" } +local teleport2Order = { 1,5,8,2,4,13,21,12,10,6,11,18,19,9,20,24,7,1025,666,3 } +local teleport2GreedOrder = { 1,5,2,4,10,23,8,666,3 } +local teleport2Icons = { [1025] = "{{RedRoom}}", [666] = "{{AngelDevilChance}}" } local function teleport2Prediction() local level = game:GetLevel() @@ -95,21 +100,23 @@ local function teleport2Prediction() if not room.Clear then -- Check for Special Red Rooms, which get ordered differently than their non-red version - if REPENTANCE and room.Data.Type ~= 1 and room.Flags & 1024 == 1024 then unclearedTypes[666] = true + if REPENTANCE and room.Data.Type ~= 1 and room.Flags & 1024 == 1024 then unclearedTypes[1025] = true else unclearedTypes[room.Data.Type] = true end end end --Angel/Devil Room check (it lives off the map) - if not level:GetRoomByIdx(-1).Clear then unclearedTypes[14] = true end + if not level:GetRoomByIdx(-1).Clear then unclearedTypes[666] = true end local greed = game:IsGreedMode() local roomOrder = (greed and teleport2GreedOrder) or teleport2Order - local roomIcons = (greed and teleport2GreedIcons) or teleport2Icons - local roomNames = (greed and EID:getDescriptionEntry("Teleport2GreedRoomNames")) or EID:getDescriptionEntry("Teleport2RoomNames") + local roomNames = EID:getDescriptionEntry("RoomTypeNames") for i,v in ipairs(roomOrder) do if unclearedTypes[v] then - append("{{Collectible419}}", EID:getObjectName(5, 100, 419) .. EID:getDescriptionEntry("HoldMapHeader"), roomIcons[i] .. " " .. roomNames[i]) + local descString = (teleport2Icons[v] or EID.RoomTypeToMarkup[v]) .. " " .. roomNames[v] + -- Tall Vertical Main Greed Room exception, because why not, attention to detail + if v == 1 and greed then descString = "{{RoomLongVertical}} " .. roomNames[v] end + append("{{Collectible419}}", EID:getObjectName(5, 100, 419) .. EID:getDescriptionEntry("HoldMapHeader"), descString) return end end From 7e93159a1c25cdc4be2160914ca4e3b3d6f66feb Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 04:24:07 -0400 Subject: [PATCH 05/25] RoomTypeNames --- descriptions/ab+/en_us.lua | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/descriptions/ab+/en_us.lua b/descriptions/ab+/en_us.lua index 20923546..e2a869b2 100644 --- a/descriptions/ab+/en_us.lua +++ b/descriptions/ab+/en_us.lua @@ -885,6 +885,9 @@ EID.descriptions[languageCode].MCM = { -- the Hold Map description will predict the abilities of items with a header like "Item Name Result" EID.descriptions[languageCode].HoldMapHeader = " Result" --- includes Planetarium even though it's unused in AB+ for convenience -EID.descriptions[languageCode].Teleport2RoomNames = { "Normal Room","Boss Room","Super Secret Room","Shop","Treasure Room","Sacrifice Room","Dice Room","Library","Curse Room","Miniboss Room","Challenge/Boss Challenge Room","Isaac's Room","Barren Room","Arcade Room","Chest Room","Planetarium","Secret Room","Special Red Room","Angel/Devil Room","I AM ERROR Room" } -EID.descriptions[languageCode].Teleport2GreedRoomNames = { "Main Room", "Boss Room", "Shop", "Silver/Gold Treasure Room", "Curse Room", "Exit Room", "Super Secret Room", "Angel/Devil Room", "I AM ERROR Room" } + +-- https://wofsauge.github.io/IsaacDocs/rep/enums/RoomType.html +-- Includes Repentance room types for localization convenience +EID.descriptions[languageCode].RoomTypeNames = { "Normal Room", "Shop", "I AM ERROR Room", "Treasure Room", "Boss Room", "Miniboss Room", "Secret Room", "Super Secret Room", "Arcade Room", "Curse Room", "Challenge Room", "Library", "Sacrifice Room", "Devil Room", "Angel Room", "Crawlspace Room", "Boss Rush Room", "Isaac's Room", "Barren Room", "Chest Room", "Dice Room", "Black Market", "Exit Room", "Planetarium", "Teleporter Entrance", "Teleporter Exit", "Alt Path Trapdoor", "Blue Key Room", "Ultra Secret Room", +-- Not technically room types but still potentially useful to have localized +[666] = "Angel/Devil Room", [1024] = "Red Room", [1025] = "Special Red Room" } From 77864675395fbc122495e79444b741e14afd7ff4 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 04:50:35 -0400 Subject: [PATCH 06/25] Fix Spindown Dice + Item Reminder --- eid_modifiers.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eid_modifiers.lua b/eid_modifiers.lua index 2fc6f58e..dae71638 100644 --- a/eid_modifiers.lua +++ b/eid_modifiers.lua @@ -5,6 +5,8 @@ EID.TabPreviewID = 0 EID.inModifierPreview = false -- The "Hold Map Helper" needs to know if it shouldn't display because we're in a Hold Tab desc EID.TabDescThisFrame = false +-- ...and likewise we need to know when we're in the Item Reminder (this is getting out of hand) +EID.ReminderThisFrame = false -- List of collectible IDs for us to check if a player owns them; feel free to add to this in mods that add description modifiers! EID.collectiblesToCheck = { CollectibleType.COLLECTIBLE_VOID, } @@ -318,7 +320,7 @@ if REPENTANCE then if hasCarBattery then EID:appendToDescription(descObj, " (Results with {{Collectible356}})") end - if firstID ~= 0 and EID.TabPreviewID == 0 then + if not EID.ReminderThisFrame and firstID ~= 0 and EID.TabPreviewID == 0 then EID.TabPreviewID = firstID EID:appendToDescription(descObj, "#{{Blank}} ".. EID:getDescriptionEntry("FlipItemToggleInfo")) end From 23d70339744dc5f6f2fc95700ed1474f1c683742 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 05:27:20 -0400 Subject: [PATCH 07/25] temporary sanguine copy --- eid_holdmapdesc.lua | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/eid_holdmapdesc.lua b/eid_holdmapdesc.lua index 86c0c763..fa127283 100644 --- a/eid_holdmapdesc.lua +++ b/eid_holdmapdesc.lua @@ -158,6 +158,37 @@ local function sanguinePrediction() append("{{Collectible692}}", descObj.Name, resultsDesc) end +function EID:trimSanguineDesc(descObj) + local currentRoom = game:GetLevel():GetCurrentRoom() + local spikes = currentRoom:GetGridEntity(67) + if not spikes then return "" end -- don't display anything if we can't find the spikes! + local cheatResult = nil + if spikes and EID.Config["PredictionSanguineBond"] then + local spikeSeed = currentRoom:GetGridEntity(67):GetRNG():GetSeed() + spikeSeed = RNGNext(spikeSeed, 5, 9, 7) + spikeSeed = RNGNext(spikeSeed, 0x01, 0x05, 0x13) -- magic disassembled numbers! + local nextFloat = SeedToFloat(spikeSeed) + + for _,v in ipairs(sanguineResults) do + if nextFloat < v[1] then cheatResult = v[2] break end + end + end + + local resultsDesc = "" + + local lineCount = 0 + -- separate sanguine's description by # or semicolons + for w in string.gmatch(descObj.Description, "([^#;]+)") do + -- we only care about groups that contain a percent sign + if string.find(w,"%%") then + lineCount = lineCount + 1 + if cheatResult == lineCount then resultsDesc = resultsDesc .. "{{ColorBagComplete}}" end + resultsDesc = resultsDesc .. w .. "#" + end + end + return resultsDesc +end + function EID:getHoldMapDescription(player, checkingTwin) -- Starting Blacklist: Recall, Hold blacklist = { ["5.100.714"] = true, ["5.100.715"] = true, } From 96a9f85f2af166044d67bcfaa9d7bc672603e845 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 05:28:05 -0400 Subject: [PATCH 08/25] Sanguine Spikes V1 + spindown reminder fix --- main.lua | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/main.lua b/main.lua index 15bce5e7..81c092b1 100644 --- a/main.lua +++ b/main.lua @@ -30,6 +30,7 @@ EID.permanentDisplayTextObj = nil EID.lastDescriptionEntity = nil EID.lineHeight = 11 EID.sacrificeCounter = {} +local spikePos = Vector(320, 280) EID.itemConfig = Isaac.GetItemConfig() EID.itemUnlockStates = {} EID.CraneItemType = {} @@ -1212,6 +1213,7 @@ local function onRender(t) end EID.TabPreviewID = 0 EID.TabDescThisFrame = false + EID.ReminderThisFrame = false -- If MCM is open, don't show anything unless we're in a tab labeled as "Visuals" or "Crafting" if ModConfigMenu and ModConfigMenu.IsVisible and ModConfigMenu.Config["Mod Config Menu"].HideHudInMenu and EID.MCMCompat_isDisplayingEIDTab ~= "Visuals" and EID.MCMCompat_isDisplayingEIDTab ~= "Crafting" then @@ -1292,6 +1294,8 @@ local function onRender(t) playerSearch = EID.players end + local playerNearSacrificeSpikes = false + -- Check for descriptions to print per player for i,player in ipairs(playerSearch) do local displayedDesc = false @@ -1335,6 +1339,12 @@ local function onRender(t) end end end + -- Test if the player is closer to the center of the room (Sacrifice/Sanguine Spikes) than any other entity + -- If there's more Grid Positions we want to check in the future, this could for example be generalized to a gridPosToCheck table which sets closeToGridPos flags + local spikeDiff = spikePos:__sub(sourcePos) + if EID.lastDist ~= 10000 and spikeDiff:Length() < EID.lastDist then + playerNearSacrificeSpikes = true + end if EID.Config["DisplayAllNearby"] then -- make the closest entity the first to get drawn @@ -1489,20 +1499,24 @@ local function onRender(t) end end - -- if no entities to display, display Sacrifice Room information - -- it will be last priority for the main spot if DisplayAllNearby is on - if #EID.descriptionsToPrint == 0 or EID.Config["DisplayAllNearby"] then + -- if no entities to display, or we're close to the spikes, display Sacrifice Room information + -- it will be last priority for the main spot if DisplayAllNearby is on and we aren't near them + if (#EID.descriptionsToPrint == 0 or playerNearSacrificeSpikes) or EID.Config["DisplayAllNearby"] then if game:GetRoom():GetType() == RoomType.ROOM_SACRIFICE and EID.Config["DisplaySacrificeInfo"] then local curRoomIndex = game:GetLevel():GetCurrentRoomIndex() local curCounter = EID.sacrificeCounter[curRoomIndex] or 1 local sacrificeDesc = EID:getDescriptionObj(-999, -1, curCounter) - EID:addDescriptionToPrint(sacrificeDesc) + EID:addDescriptionToPrint(sacrificeDesc, playerNearSacrificeSpikes and 1 or nil) + elseif REPENTANCE and game:GetRoom():GetType() == RoomType.ROOM_DEVIL and EID:PlayersHaveCollectible(CollectibleType.COLLECTIBLE_SANGUINE_BOND) and (EID.Config["DisplaySanguineInfo"] or true) then + local sanguineDesc = EID:getDescriptionObj(5, 100, 692, nil, false) + sanguineDesc.Description = EID:trimSanguineDesc(sanguineDesc) + if sanguineDesc.Description ~= "" then EID:addDescriptionToPrint(sanguineDesc, playerNearSacrificeSpikes and 1 or nil) end end end -- handle showing the Hold Map Helper description if EID.Config["ItemReminderEnabled"] and EID.holdTabCounter >= 30 and EID.TabDescThisFrame == false and EID.holdTabPlayer ~= nil then - --have we done anything that makes AB+ get angry? still need to test AB+! + EID.ReminderThisFrame = true local demoDescObj = EID:getDescriptionObj(-999, -1, 1) demoDescObj.Name = "" demoDescObj.Description = EID:getHoldMapDescription(EID.holdTabPlayer) From f81c9b1cb29eaff17c4a74a0e5a9c8d5bb97d04d Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 06:33:06 -0400 Subject: [PATCH 09/25] remove the old copy --- eid_holdmapdesc.lua | 37 ------------------------------------- 1 file changed, 37 deletions(-) diff --git a/eid_holdmapdesc.lua b/eid_holdmapdesc.lua index fa127283..43276368 100644 --- a/eid_holdmapdesc.lua +++ b/eid_holdmapdesc.lua @@ -126,38 +126,6 @@ end --order of checking: 15% Pennies, 48% Damage, 58% Hearts, 63% Item, 65% Leviathan, 100% Nothing local sanguineResults = { { 0.15, 3 }, { 0.48, 2 }, { 0.58, 4 }, { 0.63, 5 }, { 0.65, 6 }, { 1, 1 } } -local function sanguinePrediction() - local spikes = currentRoom:GetGridEntity(67) - if not spikes then return end -- don't display anything if we can't find the spikes! - local cheatResult = nil - if spikes and EID.Config["PredictionSanguineBond"] then - local spikeSeed = currentRoom:GetGridEntity(67):GetRNG():GetSeed() - spikeSeed = RNGNext(spikeSeed, 5, 9, 7) - spikeSeed = RNGNext(spikeSeed, 0x01, 0x05, 0x13) -- magic disassembled numbers! - local nextFloat = SeedToFloat(spikeSeed) - - for _,v in ipairs(sanguineResults) do - if nextFloat < v[1] then cheatResult = v[2] break end - end - end - - local descObj = EID:getDescriptionObj(5, 100, 692) - local resultsDesc = "" - - local lineCount = 0 - -- separate sanguine's description by # or semicolons - for w in string.gmatch(descObj.Description, "([^#;]+)") do - -- we only care about groups that contain a percent sign - if string.find(w,"%%") then - lineCount = lineCount + 1 - if cheatResult == lineCount then resultsDesc = resultsDesc .. "{{ColorBagComplete}}" end - resultsDesc = resultsDesc .. w .. "#" - end - end - - append("{{Collectible692}}", descObj.Name, resultsDesc) -end - function EID:trimSanguineDesc(descObj) local currentRoom = game:GetLevel():GetCurrentRoom() local spikes = currentRoom:GetGridEntity(67) @@ -214,11 +182,6 @@ function EID:getHoldMapDescription(player, checkingTwin) end end - -- Sanguine Bond Possible Results - if REPENTANCE and player:HasCollectible(CollectibleType.COLLECTIBLE_SANGUINE_BOND) and game:GetRoom():GetType() == RoomType.ROOM_DEVIL then - sanguinePrediction() - end - -- Teleport! location if player:HasCollectible(CollectibleType.COLLECTIBLE_TELEPORT) and EID.Config["ItemReminderShowRNGCheats"] or true then blacklist["5.100.44"] = true From ac00acc98c5b4e2a1ffd97f0c4b17b2ab4cb8744 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 17:44:38 -0400 Subject: [PATCH 10/25] EID rng function --- eid_holdmapdesc.lua | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/eid_holdmapdesc.lua b/eid_holdmapdesc.lua index 43276368..ccf7801b 100644 --- a/eid_holdmapdesc.lua +++ b/eid_holdmapdesc.lua @@ -30,18 +30,6 @@ local function addObjectDesc(type, variant, subtype, extraIcon) end end --- General RNG functions for RNG predicting -local function RNGNext(num, shift1, shift2, shift3) - num = num ~ ((num >> shift1) & 4294967295) - num = num ~ ((num << shift2) & 4294967295) - num = num ~ ((num >> shift3) & 4294967295) - return num >> 0; -end -local function SeedToFloat(seed) - local multi = 2.3283061589829401E-10; - return seed * multi; -end - -- Teleport! Destination Prediction -- local function teleport1Prediction() if currentPlayer:GetSprite():GetAnimation() == "TeleportUp" then return end @@ -50,13 +38,15 @@ local function teleport1Prediction() local possibleRooms = {} for i = 0, 168 do local room = level:GetRoomByIdx(i) + -- Currently, any non-red room on the grid that we aren't in is a valid choice + -- Is there more criteria to look out for? if room.GridIndex >= 0 and room.SafeGridIndex ~= currentRoomIndex and room.Data.Type ~= 29 and (not REPENTANCE or room.Flags & 1024 ~= 1024) then table.insert(possibleRooms, i) end end local teleSeed = currentPlayer:GetCollectibleRNG(CollectibleType.COLLECTIBLE_TELEPORT):GetSeed() - teleSeed = RNGNext(teleSeed, 5, 9, 7) - teleSeed = RNGNext(teleSeed, 0x02, 0x0F, 0x19) -- magic disassembled numbers! + teleSeed = EID:RNGNext(teleSeed, 5, 9, 7) + teleSeed = EID:RNGNext(teleSeed, 0x02, 0x0F, 0x19) -- magic disassembled numbers! local resultRoomIndex = possibleRooms[(teleSeed % #possibleRooms) + 1] local resultRoom = level:GetRoomByIdx(resultRoomIndex) @@ -126,6 +116,7 @@ end --order of checking: 15% Pennies, 48% Damage, 58% Hearts, 63% Item, 65% Leviathan, 100% Nothing local sanguineResults = { { 0.15, 3 }, { 0.48, 2 }, { 0.58, 4 }, { 0.63, 5 }, { 0.65, 6 }, { 1, 1 } } +-- this isn't even used in this file anymore, it's in main, but there isn't really a better place to put it yet function EID:trimSanguineDesc(descObj) local currentRoom = game:GetLevel():GetCurrentRoom() local spikes = currentRoom:GetGridEntity(67) @@ -133,9 +124,9 @@ function EID:trimSanguineDesc(descObj) local cheatResult = nil if spikes and EID.Config["PredictionSanguineBond"] then local spikeSeed = currentRoom:GetGridEntity(67):GetRNG():GetSeed() - spikeSeed = RNGNext(spikeSeed, 5, 9, 7) - spikeSeed = RNGNext(spikeSeed, 0x01, 0x05, 0x13) -- magic disassembled numbers! - local nextFloat = SeedToFloat(spikeSeed) + spikeSeed = EID:RNGNext(spikeSeed, 5, 9, 7) + spikeSeed = EID:RNGNext(spikeSeed, 0x01, 0x05, 0x13) -- magic disassembled numbers! + local nextFloat = EID:SeedToFloat(spikeSeed) for _,v in ipairs(sanguineResults) do if nextFloat < v[1] then cheatResult = v[2] break end From 908bc7487466705959184a0cda8acd3d01098cea Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 17:47:32 -0400 Subject: [PATCH 11/25] Sanguine Bond update --- eid_config.lua | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/eid_config.lua b/eid_config.lua index 0626f1a7..39f28876 100644 --- a/eid_config.lua +++ b/eid_config.lua @@ -264,6 +264,17 @@ EID.UserConfig = { -- Default = true ["DisplaySacrificeInfo"] = true, + ---------- Sanguine Bond ---------- + + -- Toggle display of Sanguine Bond's list of possible payouts in Devil Rooms + -- REPENTANCE ONLY! + -- Default = true + ["DisplaySanguineInfo"] = true, + -- Highlight what Sanguine Bond's next payout will be + -- REPENTANCE ONLY! + -- Default = false + ["PredictionSanguineBond"] = false, + ---------- Dice Room ---------- -- Toggle display of Dice Room descriptions @@ -309,9 +320,9 @@ EID.UserConfig = { -- Items that grant you items without saying what they are (like Zodiac, Liberty Cap) can have their current granted item revealed in the Item Reminder -- Default = false ["ItemReminderShowHiddenInfo"] = false, - -- Some items (like Sanguine Bond) can have their next result predicted and shown in the Item Reminder + -- Some items (like Teleport!) can have their next result predicted and shown in the Item Reminder -- Default = false - ["PredictionSanguineBond"] = false, + ["ItemReminderShowRNGCheats"] = false, ---------- Bag of Crafting ------------ @@ -513,6 +524,8 @@ EID.DefaultConfig = { ["ShowUnidentifiedPillDescriptions"] = false, ["DisplayGlitchedItemInfo"] = debug and true or false, ["DisplaySacrificeInfo"] = true, + ["DisplaySanguineInfo"] = true, + ["PredictionSanguineBond"] = false, ["DisplayDiceInfo"] = true, ["DisplayBagOfCrafting"] = "always", ["DisplayCraneInfo"] = true, @@ -538,7 +551,7 @@ EID.DefaultConfig = { ["ItemReminderShowTrinketDesc"] = 2, ["ItemReminderShowPoopDesc"] = 1, ["ItemReminderShowHiddenInfo"] = false, - ["PredictionSanguineBond"] = false, + ["ItemReminderShowRNGCheats"] = false, ["SpindownDiceResults"] = 3, ["SpindownDiceDisplayID"] = false, From 3b2c4cb72096f797444f408ec5841a0c870e2215 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 18:02:08 -0400 Subject: [PATCH 12/25] Sanguine Options --- eid_mcm.lua | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/eid_mcm.lua b/eid_mcm.lua index 955ddc0e..831bea07 100644 --- a/eid_mcm.lua +++ b/eid_mcm.lua @@ -409,6 +409,8 @@ if MCMLoaded then EID:AddBooleanSetting("Display", "DisplayDiceInfo", "Dice Room Infos") EID:AddBooleanSetting("Display", "DisplayCraneInfo", "Crane Game Infos", {repOnly = true}) EID:AddBooleanSetting("Display", "DisplayVoidStatInfo", "Void Stat Increase Infos") + EID:AddBooleanSetting("Display", "DisplaySanguineInfo", "Sanguine Bond Infos", {repOnly = true}) + EID:AddBooleanSetting("Display", "PredictionSanguineBond", "Predict Sanguine Bond Result", {repOnly = true, infoText = "The next reward from Sanguine Bond can be predicted and highlighted in the description"}) local diceSteps = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10} -- Spindown Dice Settings @@ -545,20 +547,19 @@ if MCMLoaded then --------------------------------------------------------------------------- ------------------------------Item Reminder-------------------------------- - EID:AddBooleanSetting("Reminder", "ItemReminderEnabled", "Item Reminder Description", {offText = "Disabled", onText = "Enabled", infoText = "Hold Map to show your active item's effect, recently picked up items, and much more"}) + EID:AddBooleanSetting("Reminder", "ItemReminderEnabled", "Item Reminder Description", {displayingTab = "",offText = "Disabled", onText = "Enabled", infoText = "Hold Map to show your active item's effect, recently picked up items, and much more"}) local actionToName = { [0] = "Move Left", "Move Right", "Move Up", "Move Down", "Shoot Left", "Shoot Right", "Shoot Up", "Shoot Down", "Bomb", "Item", "Pill/Card", "Drop", "Pause", "Map" } EID:AddNumberSetting("Reminder", "BagOfCraftingToggleKey", "Hold to Show", 8, 13, {displayTable = actionToName, infoText = {"Hold this key to display the Item Reminder description, show Flip/Spindown previews and control the Bag of Crafting recipe list"}}) - local itemSlotReminders = { [0] = "No", "Yes (max 1)", "Yes (max 2)", "Yes (max 3)", "Yes (max 4)", "Yes (max 5)", - "Yes (max 6)", "Yes (max 7)", "Yes (max 8)" } + local itemSlotReminders = { [0] = "No", "Yes (max 1)", "Yes (max 2)", "Yes (max 3)", "Yes (max 4)", "Yes (max 5)", "Yes (max 6)", "Yes (max 7)", "Yes (max 8)" } MCM.AddSpace("EID", "Reminder") MCM.AddText("EID", "Reminder", "Item Descriptions") -- should these be organized in the order they're shown in the map desc code? - EID:AddNumberSetting("Reminder", "ItemReminderShowRecentItem", "Recent Items", 0, 4, { displayTable = itemSlotReminders, infoText = {"Show recently acquired item descriptions in the Item Reminder (good for Curse of the Blind!)"}}) + EID:AddNumberSetting("Reminder", "ItemReminderShowRecentItem", "Recent Items", 0, 8, { displayTable = itemSlotReminders, infoText = {"Show recently acquired item descriptions in the Item Reminder (good for Curse of the Blind!)"}}) EID:AddNumberSetting("Reminder", "ItemReminderShowActiveDesc", "Active Items", 0, 2, { displayTable = itemSlotReminders, infoText = "Show your active item descriptions in the Item Reminder"}) EID:AddNumberSetting("Reminder", "ItemReminderShowPocketDesc", "Pocket Items", 0, 4, { displayTable = itemSlotReminders, infoText = "Show your pocket item (card, pill, active) descriptions in the Item Reminder"}) EID:AddNumberSetting("Reminder", "ItemReminderShowTrinketDesc", "Trinkets", 0, 2, { displayTable = itemSlotReminders, infoText = "Show your trinket descriptions in the Item Reminder"}) @@ -566,7 +567,7 @@ if MCMLoaded then EID:AddNumberSetting("Reminder", "ItemReminderShowPoopDesc", "Poop Spells", 0, 6, { repOnly = true, displayTable = itemSlotReminders, infoText = "Show Tainted ???'s next Poop Spell descriptions in the Item Reminder"}) EID:AddBooleanSetting("Reminder", "ItemReminderShowHiddenInfo", "Show Hidden Information", { infoText = "Items like Error (404) or Rainbow Worm can have their current granted item revealed in the Item Reminder"}) - EID:AddBooleanSetting("Reminder", "PredictionSanguineBond", "Highlight Sangine Bond Prediction", { infoText = "Highlights the next payout of Sangine Bond"}) + EID:AddBooleanSetting("Reminder", "ItemReminderShowRNGCheats", "Show RNG Predictions", { infoText = "Some items can have their next random result predicted and shown in the Item Reminder"}) From ced314a94b6522b9a71f59542bb69c6864f767ce Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 18:05:03 -0400 Subject: [PATCH 13/25] use new Sanguine option --- main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.lua b/main.lua index 81c092b1..564ea4db 100644 --- a/main.lua +++ b/main.lua @@ -1507,7 +1507,7 @@ local function onRender(t) local curCounter = EID.sacrificeCounter[curRoomIndex] or 1 local sacrificeDesc = EID:getDescriptionObj(-999, -1, curCounter) EID:addDescriptionToPrint(sacrificeDesc, playerNearSacrificeSpikes and 1 or nil) - elseif REPENTANCE and game:GetRoom():GetType() == RoomType.ROOM_DEVIL and EID:PlayersHaveCollectible(CollectibleType.COLLECTIBLE_SANGUINE_BOND) and (EID.Config["DisplaySanguineInfo"] or true) then + elseif REPENTANCE and EID.Config["DisplaySanguineInfo"] and game:GetRoom():GetType() == RoomType.ROOM_DEVIL and EID:PlayersHaveCollectible(CollectibleType.COLLECTIBLE_SANGUINE_BOND) then local sanguineDesc = EID:getDescriptionObj(5, 100, 692, nil, false) sanguineDesc.Description = EID:trimSanguineDesc(sanguineDesc) if sanguineDesc.Description ~= "" then EID:addDescriptionToPrint(sanguineDesc, playerNearSacrificeSpikes and 1 or nil) end From 2a357a07b618789bb9a64ce9ea537671db75b8f1 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 18:14:52 -0400 Subject: [PATCH 14/25] check for Teleport's new cheat option --- eid_holdmapdesc.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eid_holdmapdesc.lua b/eid_holdmapdesc.lua index ccf7801b..097ea6e4 100644 --- a/eid_holdmapdesc.lua +++ b/eid_holdmapdesc.lua @@ -174,7 +174,7 @@ function EID:getHoldMapDescription(player, checkingTwin) end -- Teleport! location - if player:HasCollectible(CollectibleType.COLLECTIBLE_TELEPORT) and EID.Config["ItemReminderShowRNGCheats"] or true then + if player:HasCollectible(CollectibleType.COLLECTIBLE_TELEPORT) and EID.Config["ItemReminderShowRNGCheats"] then blacklist["5.100.44"] = true teleport1Prediction() end From f72084808291fab5171505410a255975f5dfc8e8 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 18:25:56 -0400 Subject: [PATCH 15/25] RNG function comment --- eid_bagofcrafting.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/eid_bagofcrafting.lua b/eid_bagofcrafting.lua index 769afb19..f47bcebf 100644 --- a/eid_bagofcrafting.lua +++ b/eid_bagofcrafting.lua @@ -217,6 +217,7 @@ local recheckPickups = false local customRNGSeed = 0x77777770 local customRNGShift = {0,0,0} +-- Use local RNG functions to possibly reduce processing time a little bit local function RNGNext() local num = customRNGSeed num = num ~ ((num >> customRNGShift[1]) & 4294967295) From 9b6fca8ee351c65b8fcc950b769ec2bce5860e34 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 18:54:12 -0400 Subject: [PATCH 16/25] add a default shift for RNGNext --- eid_api.lua | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/eid_api.lua b/eid_api.lua index 3b038369..825b7524 100644 --- a/eid_api.lua +++ b/eid_api.lua @@ -1711,10 +1711,11 @@ function EID:AddIconToObject(eType, eVariant, eSubType, iconName) end -- reimplementation of RNG Seed shift feature used by the game. Mostly used for RNG Prediction features +-- Default RNG shift values for many things are 5, 9, 7 function EID:RNGNext(rngNum, shift1, shift2, shift3) - rngNum = rngNum ~ ((rngNum >> shift1) & 4294967295) - rngNum = rngNum ~ ((rngNum << shift2) & 4294967295) - rngNum = rngNum ~ ((rngNum >> shift3) & 4294967295) + rngNum = rngNum ~ ((rngNum >> (shift1 or 5)) & 4294967295) + rngNum = rngNum ~ ((rngNum << (shift2 or 9)) & 4294967295) + rngNum = rngNum ~ ((rngNum >> (shift3 or 7)) & 4294967295) return rngNum >> 0; end @@ -1722,4 +1723,4 @@ end function EID:SeedToFloat(seed) local multi = 2.3283061589829401E-10; return seed * multi; -end \ No newline at end of file +end From 2038ec4829672946cacf3066d70d9103296b7cab Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 22:22:52 -0400 Subject: [PATCH 17/25] Passive Damocles can be triggered by Metronome --- descriptions/rep/en_us.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/descriptions/rep/en_us.lua b/descriptions/rep/en_us.lua index 2784c7d2..4626ec4f 100644 --- a/descriptions/rep/en_us.lua +++ b/descriptions/rep/en_us.lua @@ -326,7 +326,7 @@ local repCollectibles={ [653] = {"653", "Vade Retro", "While held, non-ghost enemies spawn small red ghosts on death#On use, causes the ghosts to explode"}, -- Vade Retro [654] = {"654", "False PHD", "{{BlackHeart}} +1 Black Heart#{{Pill}} Identifies all pills#Converts good pills into bad pills#↑ {{Damage}} Stat down pills also grant Damage up#{{BlackHeart}} Other bad pills drop Black Hearts on use"}, -- False PHD [655] = {"655", "Spin to Win", "Adds spinning top orbital that blocks enemy shots#Deals 10.5 contact damage per second#When used, {{Speed}} ↑ +0.5 speed and greatly increases the rotation speed of orbitals"}, -- Spin to Win - [656] = {"656", "Damocles", ""}, -- Damocles + [656] = {"656", "Damocles", "Spawns a sword above your head, which doubles all item pedestals#Does not double Shop, Chest, or Devil deal items#!!! Kills you at a random time after taking damage from an enemy"}, -- Damocles [657] = {"657", "Vasculitis", "Enemies explode into tears upon death, which inherit the effects of Isaac's tears"}, -- Vasculitis [658] = {"658", "Giant Cell", "Spawn Minisaacs when taking damage#They chase and shoot at nearby enemies"}, -- Giant Cell [659] = {"659", "Tropicamide", "↑ {{Range}} +1.5 Range up#↑ {{Tearsize}} Tear Size up"}, -- Tropicamide From ed7baea33d9954c7612876279ba9453234cff639 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Tue, 14 Jun 2022 22:26:02 -0400 Subject: [PATCH 18/25] Same for Birthright Belial --- descriptions/rep/en_us.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/descriptions/rep/en_us.lua b/descriptions/rep/en_us.lua index 4626ec4f..21b58b7a 100644 --- a/descriptions/rep/en_us.lua +++ b/descriptions/rep/en_us.lua @@ -35,7 +35,7 @@ local repCollectibles={ [52] = {"52", "Dr. Fetus", "{{Bomb}} Bomb tears#{{Damage}} Each bomb deals 10x your damage#If that results in over 60 damage, it instead deals 5x your damage + 30#↓ {{Tears}} -60% Fire Rate down"}, --Dr. Fetus [53] = {"53", "Magneto", "Magnetic attraction for pickups#Opens chests remotely, ignoring damage of spike chests"}, -- Magneto [55] = {"55", "Mom's Eye", "50% chance to shoot a tear backwards#{{Luck}} 100% chance at 5 Luck"}, -- Mom's Eye - [59] = {"59", "The Book of Belial", ""}, -- The Book of Belial (Judas's Birthright Version) + [59] = {"59", "The Book of Belial", "↑ {{Damage}} +2 Damage up#{{Collectible7}} +50% Damage if you have Blood of the Martyr#{{AngelDevilChance}} +12.5% Devil/Angel Room chance while held"}, -- The Book of Belial (Judas's Birthright Version) [62] = {"62", "Charm of the Vampire", "↑ {{Damage}} +0.3 Damage up#{{HalfHeart}} Heals half a heart for every 13 enemies killed"}, -- Charm of the Vampire [64] = {"64", "Steam Sale", "{{Shop}} -50% discount on Shop items#Getting this item multiple times reduces the price further"}, -- Steam Sale [67] = {"67", "Sister Maggy", "Normal tear familiar#Deals 6 damage per tear"}, -- Sister Maggy From be67f4d40e33388514063ab032d69a7acc1d89ea Mon Sep 17 00:00:00 2001 From: Buurazu Date: Wed, 15 Jun 2022 00:52:31 -0400 Subject: [PATCH 19/25] Metronome prediction --- eid_holdmapdesc.lua | 49 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/eid_holdmapdesc.lua b/eid_holdmapdesc.lua index 097ea6e4..24ee5741 100644 --- a/eid_holdmapdesc.lua +++ b/eid_holdmapdesc.lua @@ -30,9 +30,50 @@ local function addObjectDesc(type, variant, subtype, extraIcon) end end +-- Banned items: Metronome, Plan C, Glowing Hour Glass, Breath of Life, Clicker, R Key +-- Reduced chance: Death Certificate (15%), Genesis (25%) +-- I saw something in the code about rerolling Forget Me Now but not sure what the criteria was +local metronomeBlacklist = {[488] = 1, [475] = 1, [422] = 1} --AB+ can choose Clicker lol rip +if REPENTANCE then metronomeBlacklist = {[488] = 1, [475] = 1, [422] = 1, [326] = 1, [482] = 1, [636] = 1, [628] = 0.85, [622] = 0.75 } end + +-- Should we account for Car Battery? (Both if we have it, and if it grants it which immediately uses it again) +function EID:MetronomePrediction() + local itemConfig = Isaac.GetItemConfig() + local numCollectibles = EID:GetMaxCollectibleID() + local metronomeRNG = currentPlayer:GetCollectibleRNG(CollectibleType.COLLECTIBLE_METRONOME):GetSeed() + local rerollChance = 0 + if REPENTANCE then + metronomeRNG = EID:RNGNext(metronomeRNG) + rerollChance = metronomeRNG + end + local attempts = 15 + while attempts > 0 do + attempts = attempts - 1 + metronomeRNG = EID:RNGNext(metronomeRNG) + local sel = metronomeRNG % numCollectibles + 1 + if itemConfig:GetCollectible(sel) ~= nil then + if metronomeBlacklist[sel] then + -- A few items have a reroll chance in Repentance + if metronomeBlacklist[sel] < 1 then + rerollChance = EID:RNGNext(rerollChance, 0x02, 0x0F, 0x11) + local rerollFloat = EID:SeedToFloat(rerollChance) + if rerollFloat < 1 - metronomeBlacklist[sel] then + -- We succeeded the reroll chance + return "{{Collectible" .. sel .. "}} {{ColorGray}}" .. EID:getObjectName(5,100,sel) .. "#" .. EID:getDescriptionObj(5,100,sel).Description + end + end + else + return "{{Collectible" .. sel .. "}} {{ColorGray}}" .. EID:getObjectName(5,100,sel) .. "#" .. EID:getDescriptionObj(5,100,sel).Description + end + end + end + -- as the code puts it, [warn] No Collectible found for Metronome! + return "None" +end + -- Teleport! Destination Prediction -- local function teleport1Prediction() - if currentPlayer:GetSprite():GetAnimation() == "TeleportUp" then return end + if REPENTANCE and currentPlayer:GetSprite():GetAnimation() == "TeleportUp" then return end local level = game:GetLevel() local currentRoomIndex = level:GetCurrentRoomDesc().SafeGridIndex local possibleRooms = {} @@ -173,6 +214,12 @@ function EID:getHoldMapDescription(player, checkingTwin) end end + -- Metronome result + if player:HasCollectible(CollectibleType.COLLECTIBLE_METRONOME) and EID.Config["ItemReminderShowRNGCheats"] then + blacklist["5.100.488"] = true + append("{{Collectible488}}", EID:getObjectName(5,100,488) .. EID:getDescriptionEntry("HoldMapHeader"), EID:MetronomePrediction()) + end + -- Teleport! location if player:HasCollectible(CollectibleType.COLLECTIBLE_TELEPORT) and EID.Config["ItemReminderShowRNGCheats"] then blacklist["5.100.44"] = true From 50e44fcb7e57c55f8644b1dff3ecac2f5835e735 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Wed, 15 Jun 2022 01:05:13 -0400 Subject: [PATCH 20/25] Fix Magic Skin breaking Modded Crafting --- eid_bagofcrafting.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eid_bagofcrafting.lua b/eid_bagofcrafting.lua index f47bcebf..de0c3422 100644 --- a/eid_bagofcrafting.lua +++ b/eid_bagofcrafting.lua @@ -543,7 +543,9 @@ local function GameStartCrafting() for i=1,EID.XMLMaxItemID do itemPool:AddRoomBlacklist(i) end local collID = itemPool:GetCollectible(poolNum, false, 1, 25) - while collID ~= 25 and collID > 0 do + local attempts = CraftingMaxItemID + while collID ~= 25 and collID ~= 642 and collID > 0 and attempts > 0 do + attempts = attempts - 1 table.insert(CraftingItemPools[poolNum+1], {collID, 1.0}) itemPool:AddRoomBlacklist(collID) collID = itemPool:GetCollectible(poolNum, false, 1, 25) From 3850239cfcb2c9cf5088c6e297464dae677495b0 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Wed, 15 Jun 2022 23:38:21 -0400 Subject: [PATCH 21/25] VoidNames got a Repentance update for Fire Rate --- eid_modifiers.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/eid_modifiers.lua b/eid_modifiers.lua index dae71638..4ddf508d 100644 --- a/eid_modifiers.lua +++ b/eid_modifiers.lua @@ -118,8 +118,6 @@ local function VoidCallback(descObj, isRune) local voidIntro = ((shopItem or isAltOption) and EID:getDescriptionEntry("VoidShopText")) or EID:getDescriptionEntry("VoidText") local voidNames = EID:getDescriptionEntry("VoidNames") - -- Replace "Tears" with "Fire Rate" - if REPENTANCE then voidNames[2] = EID:getDescriptionEntry("GlitchedItemText", 1) end local eidTable = (isRune and EID.BlackRuneStatIncreases) or EID.VoidStatIncreases local increases = ((isAltOption or not descObj.Entity) and eidTable[3]) or (shopItem and eidTable[2]) or eidTable[1] From 3191fe84757b7d95f84d993a14646c014e187b66 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Wed, 15 Jun 2022 23:58:30 -0400 Subject: [PATCH 22/25] Simplify the VoidNames edit in Repentance --- descriptions/rep/en_us.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/descriptions/rep/en_us.lua b/descriptions/rep/en_us.lua index 21b58b7a..42972b41 100644 --- a/descriptions/rep/en_us.lua +++ b/descriptions/rep/en_us.lua @@ -1066,7 +1066,7 @@ EID.descriptions[languageCode].poopSpells = { EID.descriptions[languageCode].VoidShopText = "If absorbed right after pickup, gain:" EID.descriptions[languageCode].VoidOptionText = " will be absorbed instead" -EID.descriptions[languageCode].VoidNames = {"Speed up", "Fire Rate up", "Damage up", "Range up", "Shot Speed up", "Luck up"} +EID.descriptions[languageCode].VoidNames[2] = "Fire Rate up" EID.descriptions[languageCode].spindownError = "Item disappears" From 0749d41d549dbc489e46dfa8468619ca517806cb Mon Sep 17 00:00:00 2001 From: Buurazu Date: Thu, 16 Jun 2022 00:02:58 -0400 Subject: [PATCH 23/25] Allow better control over Void stat increase --- descriptions/ab+/en_us.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/descriptions/ab+/en_us.lua b/descriptions/ab+/en_us.lua index e2a869b2..da281ce0 100644 --- a/descriptions/ab+/en_us.lua +++ b/descriptions/ab+/en_us.lua @@ -873,7 +873,8 @@ EID.descriptions[languageCode].transformations={ ---------- MISC ---------- EID.descriptions[languageCode].VoidText = "If absorbed, gain:" -EID.descriptions[languageCode].VoidNames = {"Speed up", "Tears up", "Damage up", "Range up", "Shot Speed up", "Luck up"} +-- {1} will become the number text (like "{1} Tears up" -> "+0.5 Tears up") +EID.descriptions[languageCode].VoidNames = {"{1} Speed up", "{1} Tears up", "{1} Damage up", "{1} Range up", "{1} Shot Speed up", "{1} Luck up"} EID.descriptions[languageCode].CollectionPageInfo = "This item needs to be picked up for the collection page!" From f18877f3c6f86f4153227e018c3fd60dae2c544b Mon Sep 17 00:00:00 2001 From: Buurazu Date: Thu, 16 Jun 2022 00:03:17 -0400 Subject: [PATCH 24/25] {1} --- descriptions/rep/en_us.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/descriptions/rep/en_us.lua b/descriptions/rep/en_us.lua index 42972b41..07877897 100644 --- a/descriptions/rep/en_us.lua +++ b/descriptions/rep/en_us.lua @@ -1066,7 +1066,7 @@ EID.descriptions[languageCode].poopSpells = { EID.descriptions[languageCode].VoidShopText = "If absorbed right after pickup, gain:" EID.descriptions[languageCode].VoidOptionText = " will be absorbed instead" -EID.descriptions[languageCode].VoidNames[2] = "Fire Rate up" +EID.descriptions[languageCode].VoidNames[2] = "{1} Fire Rate up" EID.descriptions[languageCode].spindownError = "Item disappears" From 82c723b0354ce7b278b83d15c5b7b9bdd0f12a85 Mon Sep 17 00:00:00 2001 From: Buurazu Date: Thu, 16 Jun 2022 00:04:11 -0400 Subject: [PATCH 25/25] Use gsub for Void stat increase {1} --- eid_modifiers.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/eid_modifiers.lua b/eid_modifiers.lua index 4ddf508d..da5a57a4 100644 --- a/eid_modifiers.lua +++ b/eid_modifiers.lua @@ -125,7 +125,11 @@ local function VoidCallback(descObj, isRune) EID:appendToDescription(descObj, "#" .. prefix .. voidIntro .. "#") for i,v in ipairs(increases) do if v > 0 then - EID:appendToDescription(descObj, "↑ " .. voidStatIcons[i] .. " +" .. string.format("%.4g",v*voidStatUps[i]) .. " " .. voidNames[i] .. "#") + local statIncreaseStr = "↑ " .. voidStatIcons[i] .. " " .. voidNames[i] .. "#" + local replaceCount = 0 + statIncreaseStr, replaceCount = string.gsub(statIncreaseStr, "{1}", "+" .. string.format("%.4g",v*voidStatUps[i])) + if replaceCount == 0 then statIncreaseStr = "↑ " .. voidStatIcons[i] .. " +" .. string.format("%.4g",v*voidStatUps[i]) .. " " .. voidNames[i] .. "#" end + EID:appendToDescription(descObj, statIncreaseStr) end end -- Print unique synergies with Void and Active Items