From 20ce19006fa6843ea31b7184cff261e86789190e Mon Sep 17 00:00:00 2001 From: Alwayssnarky <126915043+EldritchBimbo@users.noreply.github.com> Date: Mon, 27 Mar 2023 07:24:33 -0400 Subject: [PATCH 1/8] Gitaxian Lab Patch Fix to Gitaxian enemies to correct death anim not playing. Fix to waypoints in Gitaxian lab dungeon so enemies patrol properly. --- .../Shandalar/maps/map/phyrexian_b1.tmx | 16 ++++++++-------- .../Shandalar/sprites/gitaxianscientist.png | Bin 1608 -> 2205 bytes .../Shandalar/sprites/gitaxianunderling.png | Bin 1531 -> 1926 bytes 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/forge-gui/res/adventure/Shandalar/maps/map/phyrexian_b1.tmx b/forge-gui/res/adventure/Shandalar/maps/map/phyrexian_b1.tmx index fa6ee774c07..3b65ab87d01 100644 --- a/forge-gui/res/adventure/Shandalar/maps/map/phyrexian_b1.tmx +++ b/forge-gui/res/adventure/Shandalar/maps/map/phyrexian_b1.tmx @@ -48,7 +48,7 @@ - + @@ -109,13 +109,13 @@ - - - - - - - + + + + + + + [{ diff --git a/forge-gui/res/adventure/Shandalar/sprites/gitaxianscientist.png b/forge-gui/res/adventure/Shandalar/sprites/gitaxianscientist.png index 7efaf2659cd91dced69e111b034f138ff9ed01ec..e17e4de0a1f5eafaf5a987aa9e92b155b8fb10f2 100644 GIT binary patch literal 2205 zcmV;O2x9k%P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2r@}TK~#8N?V8W4 zRaF$n&wDDVm5KcTp~wg$nlxw@HESXcN{kAk9}wEGNr+9GBo6umlpulzNn%mrq)FJc zL9;-DA}Pv}ekG6 z&0%Tg7QLCt%KZ=ftj*+`uV5C&334N}`IWURzGySquxX*3uIOG z9zS^oHvR3#hGjBv+P-&&xnSZqLTPo^L!F8HEz0JZ$)V$?!sgtqU?y(&eHV_%3C#nK ztZ&@qxqi_$pS%gK-gZZG?e|~EuKo2JHEg(Ld#HnT55a|a00Q1fvU%7SPn@R4_nz6C zv@MJi!~+n>2cksRhjOi6<-x4W>-WBR1^~{7a;{&c9$0Nr>d=B(ed?vvo%e-=a$B8x z&r_=hvdz+WX~8HxUWMV6=G?{0ZA~j~UikE^FS<^y>>wffp+A>lEA=26Bcso0!Fav& z8t0uLNwQt$YxOc;sux;Nt6$GJ=pNzUf0a|zNa@oLq7Z|8d#wgUYu1YT*Kwi3d_E_`B z7pFdUgQr33@{Ac>Ew$Kz!x$C9(kZXh%PXUc}t$*#RpD_U~zS z@7PR*+n;zkh+$C%Xh%PXK6Z1f*8`Dfwm-V3*|7EI=JI#vn$7p_ra^FwJX#}}JALvH z-1gYs=E{X1NCaTlemYO}CCrE-e_P$3qZa39+;TqUHAhon*Vr*Xm`yR4=rkR==Kc&^^K-q)ezs zd)tjj267D6t1(LTxy=mLx5bzsT7D0h?e_p$B*IopZ-ld~tJMd10J83_Y2uTi~JsnALOcOm4+A~LYw4P4@8t4f*>v-G~g|k5GL1{P)O7(Ie+5|cver7S-UqAbh z7N1!FsMP~4+44?U#kbymeV`Bv|zA4c?i0D=0?Wz zxMw3hHX-!-*3l$-HGiUK2OyfFhzcI-vX0PKkkw;yFjmhD)$4h4`sf6}OYk_59t5cO zUd&?YnOWo{@_PWR%7dY0CbWC2>1!WNc!6L`wXKcHnSQ`(i&BRc1g8k+ zM9FCHBWS7AgC01Eq}uAv1w@NC^nHu3)k`eB2_AyDDj}A3Kr}z`d`jo~6QtKU?*vJb z?MQARW*&VkeMSqSwi3NdU6^{*x6LuD;_Zyy%gM;4YFA8tp%MV*1Z1a+aZs7v{SDhO5p9=0=LFa?p}kPAp*EZp^v5ZK z9v0=?39`INuakfNc%I^Dw*GHxIqzcvx=M#1ywL1=LIBUw6Xqr1-rA zoDbz(zd}7o95lj#8r^q@HjrG&OeB?CV5uI|I51%f4s0hDlhdLRNEn;YeZe5TOF-tq z5C>|)+#Jo! z8l-{?0A&4O2TG_z&G!JLLOoIr(qPfjqP}hJC2YFHf&40r<3ZoeX7v99ENGF=QS|i* zUvr>^MH%(n2bnIQ0R{gR#*uo&nC@E~1GQ?FsY zJI446$0;0VM|3}<9j6WG`S}!jUC{GUAny<4M#b}|a3AApdW$`b*5e;|kv*AvThjHR zT&S1mw!ZRpC%h%GrP|g;N-BxE8SgHp#4osMW1KWwk zf%!45g)P%Y9x;=qV0I543)9PQBS zt7SnNq=E|oWc^?VN~i$!em#1m9HhabrA2+)+)LPWi39mn7{_B& zH02qpx1dELY+Zg2aP&CPa>6JF%3z2#0hZqbmfr*N))D#&rmmL`1cqK7Wt5lS1JJ(w f9?*}_pK1OBD0g_!_3&j100000NkvXXu0mjfNNz%U delta 1604 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 From 3e5b687a2a43235170c9b98184b8710894359a7c Mon Sep 17 00:00:00 2001 From: Alwayssnarky <126915043+EldritchBimbo@users.noreply.github.com> Date: Mon, 27 Mar 2023 08:01:53 -0400 Subject: [PATCH 2/8] Tweak to sprites to correct anim played on enemy victory --- .../Shandalar/sprites/gitaxianscientist.png | Bin 2205 -> 2124 bytes .../Shandalar/sprites/gitaxianunderling.png | Bin 1926 -> 1975 bytes .../Shandalar/sprites/phyrexianangel.png | Bin 2389 -> 2326 bytes .../Shandalar/sprites/phyrexianduelist.png | Bin 2174 -> 2146 bytes 4 files changed, 0 insertions(+), 0 deletions(-) diff --git a/forge-gui/res/adventure/Shandalar/sprites/gitaxianscientist.png b/forge-gui/res/adventure/Shandalar/sprites/gitaxianscientist.png index e17e4de0a1f5eafaf5a987aa9e92b155b8fb10f2..b497e2bb6111ffd80b01742395d9cdee03b52aeb 100644 GIT binary patch delta 2074 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 hzWg50kID1YtB606ka4Y%IgZ2WVk zSwCkN?Khvkhx@Z@gk8>ReC2OGdek?Zhd=+td<$TBpke0J`!Vn~KtptFJ3R32pZ`kG z+2;29o@jpm?K_@ddf7G2NAJAIbH{8VKv%?1f*0?;x_?<;KeyR)=pY~b{9OB5-1xgW zb@F=-hdHhTeC0XrUFCmx_9Y%T$32-7kQN#$XM|OuoJ!W}L70Ba^*#bH`@`~T0iyzz zSHslmLFi)=yQA3S>vn@Od?rj@7n|IuQi0AGYqE-*6-7dWs;%Fxiip2@8-Ln|A zdfpy{a66WVrYa~eUI(ZvlY=|IM9M}j%SM`gRHuK5kA_9h!dTx zoZec`Gf^wx1#oMBkh1oBs4Y1E0rPS)dTKI z8T7aa3;uR{>{k{Xch;g-544ZT^}Sa_i*+wXwI1(n*u`b?t4|ZA9o5PZK<2c(T7Ux3 z@@kk`J*nIdhh<30-_HU6h3^5HlI`%ye-EhL4r^BOdjNXS`QQ&RuYJ9TKhUN!i|+xj zn1B3Ix3dcBbMx;F0c>kAdB|3>bt3EPu>z1QHt;xUB1JZ)9xW;{^ic_lx^nvu^ zL$nD#mXW_*fD8xKdZg7pls3grO#>1pvYCa{?aH&rNf zcyDRw2Cy>E!PL86klk1b;xnaeQilCT@0(Z=kdo05p}wT@Qh`vLQ?{gh^_U2q=kBLt zdQHxLK1NO%Kv<5bzVmu;SobVq=~DGEwp=em0E-4%UM=9O2$olIEGwXH^2CAfapwyjjse!9hL^m&HfVsd?_ z67A&Sx00~9cF$s@>W6#)rh%_QJt)@uN(8^XLtP*||CAO^;cT+fbM~u!2tUzxu zxxP~gEFWbn35#p@EJmt+$bSc58u%*IgJQj}1Oy_6RSt$2)XRbAOx=fi9EEyNt3T^N zoTLgJrXKgzVL=@%jsiXKK63QEx4_Q#09Q#@VY2f*z!flq96du5g{?hX;S$f?7*p20GWi`e6o$moV-vdaE9%Ee62!FZxn-fKJ@<^ms zzvajf;A;eyR|_zM((-B;v+*+Y+lHS5D!vDpjhCSxV#^yZ`Wj5#PXptFNR~drBoX8r zpyGQ#$TAANtOycD^?ns4w#}HkDV)1wh+2IJS8#7V^AHbQFK!nxxEkyY0a-_9{C#`& zmaOCo^dU8s4H=CjX@7vKfB$dI0XcdFm$jhepUhZ{%|$u_I*kA!3Lk7K$M6*>)Gs4~ zgrZ2|c)>V^l|$~sGF2Zx_6zkIrj!Q(l0??*Y)^d8r;S zg78rV$baw(3ikA9xMuei*ZSdj@~3ZmeynwXf2ax$#xj@ZrF?o)`$Z~5Di3R6HNbYV zhRV7(N{6uLMqng?vAIY$0Cr=!TUkx1UV63HyG8_A{zE-&Y9v_^P}2w?OYeG0-q-%U zZD9J1=|>{TZ=H2Wg&E}Tr%Uw=S1GKX1cji`p^s6$(D&0c{{pIs7^_xx<%R$N002ov JPDHLkV1oNUz)t`G delta 1874 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 delta 2341 zcmV+=3EK9S64errNq-~&02U+xn-#_s000Q;Nkl7?+Cg;47d1oaawG^Q-Qq%a^)4&)nrX`0@ky zlZiiBTxW?{&xXZ(_pMhwMc@Qda@gb}VV1(W2hH~PKXr#cf98iz__LsPuygt&la2x+ zAkVrW2G?Vsqr`s<%Bg!%6- zUh4k&$d9{+FTTLzq>YZ~?E&BeCvNI~`q?j~r*}3!jDP>z)qi>UIH5L^9tAie8qD)? zn|-hl0fyP*ulyku=Z1shX#6tlKl$79`;R}Fcm89ES_EYL{f)nN@4w}P>FIc4mS#8` z8jV&t<{-8|^x*xIUKZ6&Fy*@N=-n?YGk8+`_~1m5fQYp^L#ap$e?e)mgb&omXnyV> z3ax_F(SIiR`_I~+Ti4|O!ua1yq8tO{gfM^S;X{Ch2(wX`lD4%}9L4nd5dQaOzZYY0O!ppox7p!hoc6#jV$j^(oi zW(Y^}somY~*>mTt)OByX{+D^#QaOMD1zP!zb$|IKTKT}&^QGNgBEoa?peM@aVb3K8 zp}^GnwiM2t^G1Z9`~CUc0cARkG7t((lAlA+fN=Mktrx=N3u*lbyfz3OUN@{ML*#-< z@_TmygaCr99g;vD9W%fX8u-jwudU<@jA640ViYv-?@Kwzp+e}8lL(>MW=Vj%DZaN8 zzJHW!eAchv5Q?2!9Iy$#b9K6_fws`cM)+|Fs6#23am%R>rBYRSVH14X zm+?s(+ z#9E!9RAiETb>fGJb&xumJfBUFcVh+(seiGDvYvy70k2P*f8^f-j+##hxd-V)$5nC; z3<@g{Je&u0Qc$FuU_qL{n1bSefsb3eg~PZd;a+z+3>F9bN4@W;zW1DqmM1+ z>mZbmkv{m|o_7E^MNz(BWZH`3q~QFl`~iG$t@zR(LxpAf_fCR#SMKhz!ST{RzJKw} zd8L6e%F%|*09*-XZir7C3K*jDLMwli{yhf}a)c5H=Vvd|DQ(CMz^|lgukl0w{?0DY z%8%_;eogi;0L@W<*O?*eQl{%*A$)N|4yeGdRpCZ}sTz9K-K_&OXy z+&m0%;F3Q}@7ms4U4zeVr(jLpuYXUPzx^Iy z$vsFXIxdoPXi!)|7?J@~=I1pO1^i0da33GT-@Ezd?&8~TcOSp;#_sZ!E8W?2r>7sl zb@oh<*)QajZYo@S0Vs7pV|NDo(s*O?dsiW<^={dlS$Dq^paDUnie9*$Y`Sq@YnIAIeG6xNEML;oIttWJeI8+-zU*nfoTbrMbE zWMd7K-H}S-#5&1Q067Arm~sv+iQt_K$$%EV>J?2GMp<0pfPX%kB8YQ9zRIdouB~=! zveNv0>SasCz<|LQ_~fhd#l>(81mqYjESZ3&2+~2w6~QYl-vcy@D7OZ`$$@f=3|w~! z_D+Hf)bRfSJ~)bv;E#5ooHsUtdJY)#`+9^F0b}?h9oQ5>JqNUY4^Zc0`N)iPV9OHh z-39WU-F8*IE`JW|dw_rLLWTr~L_Z|z)Q;?&vdC8+xs=7TXz1}30qVp(IfTM<;($%? zXPQCem^pseXZ;dM)G@Q6kA?Bqj3DR4C7=#-Xb7RRn)1RX`0hZPHEm+Z&v1mz;*jwf zW0qiV4>078Be_6raITxA9A0Djh4F$rfi{D}Hv(?n1AkVCpnNqR^rnGMSGtdzVtcQB z{cCySvE3TkR(=)8no+&>lFwTM2T0DMXD>cSL@x{3!^z{C5uwJ3XyqR&qB5?ylm=3~ zR%a*;Y2^!t>OghoYi}JSrAG0$-vhjqH!atpls^dD?*WE1PBzv+*&V4QPOOt01&|{^ ziYeFo7=O^okPK+yt6tHBVU)!c4(OvPf;a~(TqZa(uX>pvm3;D5`QlH3T4%1d+Gj1LjG9yD9$m zdw^yTIc9GAJzy@s{T^W0eh(0kHKTg%C7-tj4jz!4MbE(ZfUf&L&mmajy5VhL00000 LNkvXXu0mjfxS6OT diff --git a/forge-gui/res/adventure/Shandalar/sprites/phyrexianduelist.png b/forge-gui/res/adventure/Shandalar/sprites/phyrexianduelist.png index 78693e297ae2f808a8dc3a26ad96f92a72da8b9b..a2d8e985c16c5a5a3f61c5746b4c975222fc4837 100644 GIT binary patch delta 2096 zcmV-02+#Na5aJM!Nq-^$02U$v8y13(000N~Nkl^3 zTV_hK86_G-BuSE(7(~BFGEo8(MC^~K{)mX^uj;S-Bar?{Y@XXm2i5zV8(~k~eF#5nb?0g=mlWBS|tC-!bSJ#gH z#d&l=%{IYhT;qC1L}Z#C{PX(i z&GW8}fIXYmkueU`>ADE8dH>ygbTIaLH{o=^;^CXc;Osf-Oi&rNZbZM<@>d~3`>6wm zlsO8&FQ860d<6n?0I^Q!#=!%75ZVcqS6)-58vV~b(|>h?2YMiHUe;GFSEod&&?E5q z=-7AaN{#oH-lVVLbMwFFyC(wd!Q&I$b@(WKe!i@>0NQoB!3p*NBIzwBL5{4?H}FjB zDZiI%039eRI~ua>ksB$pt|zF%ivuNHnZ>Y$#FEVEU7rId< zn0taoIe&C>kSV>d!H5?Vc%R9P-W37WomUNsk->T7IUFd%hHF$Ko|fquOCM?@k=~gM zot&H$rQIX61B3%**c8D*q|nnf)V=MKQSCt1%Y{rF8UIPwbKumY?9g+ z{`Ea8=s+2^Mmmr}Pcz4QbiBM_JsqrHbzr|JAAkQv9QtaE>XYgsUOmb_z4=T~16xiV z7h~59i}8OhhymrEGgCqgPwy2M_Kt{iXDednmHlG*?Mrc~m3ly(^68hJ947~25T&8( z#FF6!xE$#N{z;-YBcOoJgW|LvEe0sVhE79>K{#eItsc-|e0qRR!+{utgT#8H8bJ+A zOn*+%7WtCP`{+O!Hqb~1Qs{{|y`%s~u32?AmC0g}L~lDlgXfMh%aULRKpXV{Iaa!E*jWy4Rs`F1gjXWWQt7c%~>!T zO9FkTNHVFn!!Qyaj#o*>6}}+TdYw9QDu1c$XvnrlZluV%o}dcyZAw>WF>E2RBy)OK zC{P7inNFCvjLITY`ugt+RRQnMj8P8V9ArxGYcS%)1m0&dqjyC>D4!0|Zhfc?t;fvc zh|{|q;LWEM!9k?Z(>0%7E@W}(G|+n2euPVJI{>StH=k~#11a=0b8-44`vDlZy?-B( z?+4`j0r`Fa$liXyqRm@WNdui%3u5jMwBB|=*X#%M-M3bmYWVc#o!XXvRt3i54AS7tG6hS*0|^wkd!epWql^!utS z6zB%BGMzAS8I?t+>*-av?}}b={(p}Pbzg&kZh-f1#wdqw4mw#c$$*S&(< z4!~*|$;W36%@*&hxPxpBP^ag79=SNKp$^q_SH&$)Y_s#}I7pAW&|v1do!$r5Q-uH#y(^zj zyB}fWbc;E7;K-+gK*KYC!+)Il%Gx+F`FtyWzd&O} ze?LI8^4^Pov(zj%N~3z)0kQcst_AXO&FH#EM6p;D{r&y)E`Odte@P?I42fVq-N5hr z19~4%qlcp&8~uW!2M*k_aXW3wU`I#c(lJ`UbJq@0sZ_+X+g~vC5v>^kY4dSST0KCA zCnhFn0L?@o^w6RWlpUars_6hg-a+EfWIj%$)!*McAa0y~xp?r{332C_WAqq8ANVgb z8rCl!|52;ukXI>(0 aV(dSv#=uR0yY}V)0000|` delta 2124 zcmV-S2($O%5dIL5Nq-{%02U(w$x&cy000ORNklY{8$t!S7+70S z7^S`zQhcjfRJ+sto_Ejn&VBdJyqS4VcOLVB*|~G(e(&6S=6}qcId@%4LWn?a0A&#T z`0X#^Wc7qPtTV4NAQs#KYwFv9 z@_ag>?l!??oa1^%MC6(-{CH!{3b8JjM%#hX1f9TRz;GGoxE?f}0L=loqZri8-9u!= z-NhV$J>W9W3x9uY+Ca{D^LIMV^&CJEVBUEiH1C0J<4EWP$N@1%bf6iQWB&ZBqC!#-V`BjL}e)`~H zWe&sN3#iixuRvf9Akqn)ICx+WLOY@M>g&o>r}z11JAZEQKo8`tD|&)zFexgfE`j}H zBj2ktb>3fgvp$FYmjBLoP6XJ4#~$2$QVOT&1Zrd*n0Ye z7`b*(jQ)E;^eOk8ofKkldbhZ+Z%CXQuZdY#^@H&4ir(bqzlpKgbR0ggW zO9vO?bf^#bkwkAsKna}(a+o2VxKo66=j>1T`== zF@H%*pqUP2&=XO5NePZzyZRm~lf@#5-gbZn&mCiyC9xd^qvY;j^q?)0uu zpbD}w9WYTDl|`=fjqeLp0pHJzQI5Mf$d%sLV91LJywBuD?}~u9d^(PH>*Lzcdfa(z zQF@mHy!o^ub`Tl#bk3)j6IoO`4Yc019^um44!~^b&8M5`Kn6YCxhQ>-^#BaqUVo1$ z)&q+5fMPuW1rgT=T5mg`W7Y$D?q8=&b$ojBN^Q%>(U~lI&@R1s z7tF?zP^vRt3i4}8S7tG6hS*15^ub4mJ`au_`yp_J z0$o5>rUND_qq3OldioUZxw2cF|9|sB!)p-G1@QgN80EN&gQ=_+^3K!XtJNxfnfe+G zc`q)CaefKve44TH={TmW{?M9r`p!$pnJx!-^YLbBvp&`dKK;vQs|}yv zwgWI*hVt>*19QZ?EAJ#*6Ex^KpGPi^bErc#-FWq|;atRe0*KTrLXVMo(0`E6&)>g~ zP9S|PZ`wxrw8ZxuHt0De?Rw{JQK?iY{34PdufA355w8B55fIAfF?dWExZvayo5>b~ zb3LHPCyiOA<$@$U;XwgV`i?qBMtugb>vi1*)b5? z9vY}3tA0vA9h6^Fy0hGQ*qZ2kX1%$w-nPrlN2p#3JwcUN>}Vv8w10Z42WPSKl)bGH z*!aFs&nLd08Kd0Hvzu05!d!vBSM2|Lg8ohsoyCSSY&fUp6IVN_^u7*}hoqPej7cnN z047=VAuW@jjYN7^1bFjli4L6zvg)aWmns5X4roa}j^D{Y^TKxV+Rj&!{Jnr?)qNNL zj}o)oEY0d|2Sn!6IDZ$Dk86h4KPt-QvgqyYrEl>B`b!#tW=O>5(@p$-AJF%B7CjvG z`0$q$J#gUGO*?2&1}i!WmyXf;UAuRRTCFCY+wr2Q4{6N^XvOdMiL82n4v&qE(E!p! zAoS3p4U`?AjlgsOAnzb?NSTilS@jQe_lcXP&kzqCKPm3|YJY?tL+E4viHwHzOGbYZ ztInLGGHeC`+JG}{2WZ-ukH_jcg35oKp)G9$_SMGgo6;+2@IC4#XsZcVp7+~#vpp8U&S49LA>jA}jK(QWBtOw}M1J0(B zW@AiJJt)=#iuC}wFV+K!^#CGG1Tw{XK;(LW82KNcx4hM37LNx20000 Date: Tue, 28 Mar 2023 14:49:11 +0200 Subject: [PATCH 3/8] Update wyll_blade_of_frontiers.txt --- forge-gui/res/cardsfolder/w/wyll_blade_of_frontiers.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/cardsfolder/w/wyll_blade_of_frontiers.txt b/forge-gui/res/cardsfolder/w/wyll_blade_of_frontiers.txt index 801e553ece8..09d82a0d8ec 100644 --- a/forge-gui/res/cardsfolder/w/wyll_blade_of_frontiers.txt +++ b/forge-gui/res/cardsfolder/w/wyll_blade_of_frontiers.txt @@ -4,7 +4,7 @@ Types:Legendary Creature Human Warlock PT:1/1 S:Mode$ Continuous | Affected$ You | AddKeyword$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. | Description$ If you would roll one or more dice, instead roll that many dice plus one and ignore the lowest roll. T:Mode$ RolledDieOnce | TriggerZones$ Battlefield | ValidPlayer$ You | Execute$ TrigPut | TriggerDescription$ Whenever you roll one or more dice, put a +1/+1 counter on CARDNAME. -SVar:TrigPut:DB$ PutCounter | CounterType$ P1P1 +SVar:TrigPut:DB$ PutCounter | CounterType$ P1P1 K:Choose a Background AI:RemoveDeck:Random DeckHas:Ability$Counters From 4329e2b0c8e5ec8a91ae7cb1bdbe08f15409ae38 Mon Sep 17 00:00:00 2001 From: tool4ever Date: Tue, 28 Mar 2023 23:11:13 +0200 Subject: [PATCH 4/8] Improve a few parts from previous PR (#2770) --- .../src/main/java/forge/card/DeckHints.java | 77 +++++++------------ .../main/java/forge/card/mana/ManaCost.java | 2 +- .../main/java/forge/game/GameActionUtil.java | 16 ++-- .../src/main/java/forge/game/cost/Cost.java | 8 +- .../java/forge/game/cost/CostAdjustment.java | 8 +- .../java/forge/game/cost/CostPartMana.java | 16 +--- .../game/spellability/AbilityManaPart.java | 2 +- .../forge/game/spellability/SpellAbility.java | 1 - .../test/java/forge/item/DeckHintsTest.java | 14 ++-- .../res/cardsfolder/h/heros_heirloom.txt | 2 +- .../res/cardsfolder/p/phyrexian_purge.txt | 2 +- .../res/cardsfolder/upcoming/mount_doom.txt | 2 +- .../cardsfolder/upcoming/you_cannot_pass!.txt | 2 +- .../gamemodes/limited/LimitedDeckBuilder.java | 7 +- .../src/main/java/forge/player/HumanPlay.java | 4 +- 15 files changed, 65 insertions(+), 98 deletions(-) diff --git a/forge-core/src/main/java/forge/card/DeckHints.java b/forge-core/src/main/java/forge/card/DeckHints.java index 6af5a15dfad..d7078a4120a 100644 --- a/forge-core/src/main/java/forge/card/DeckHints.java +++ b/forge-core/src/main/java/forge/card/DeckHints.java @@ -69,6 +69,7 @@ public class DeckHints { public boolean isValid() { return valid; } + public boolean contains(Type type, String hint) { if (filters == null) { return false; @@ -84,15 +85,19 @@ public class DeckHints { if (filters == null) { return false; } + int num = 0; for (String hint : hints) { for (Pair filter : filters) { + System.out.println(filter.getLeft() + " = type = " + type + " "+ filter.getRight() + " =filter= " + hint); if (filter.getLeft() == type && filter.getRight().equals(hint)) { - continue; + num++; + if (num == hints.length) { + return true; + } } } - return false; } - return true; + return false; } /** @@ -111,7 +116,7 @@ public class DeckHints { Iterable cards = getCardsForFilter(cardList, type, param); if (cards != null) { // if a type is used more than once intersect respective matches - if (ret.get(type) != null) { + if (ret.containsKey(type)) { Iterables.retainAll(cards, new FCollection<>(ret.get(type))); } ret.put(type, cards); @@ -128,17 +133,8 @@ public class DeckHints { * list of cards to be filtered * @return List of Cards that match this DeckHints. */ - public List filter(Iterable cardList) { - List ret = new ArrayList<>(); - for (Pair pair : filters) { - Type type = pair.getLeft(); - String param = pair.getRight(); - Iterable cards = getCardsForFilter(cardList, type, param); - if (cards != null) { - Iterables.addAll(ret, cards); - } - } - return ret; + public Iterable filter(Iterable cardList) { + return Iterables.concat(filterByType(cardList).values()); } private Pair parseHint(String hint) { @@ -164,57 +160,38 @@ public class DeckHints { List cards = new ArrayList<>(); // this is case ABILITY, but other types can also use this when the implicit parsing would miss - String[] abilities = param.split("\\|"); - for (String ability : abilities) { + String[] params = param.split("\\|"); + for (String ability : params) { Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.deckHas(type, ability), PaperCard.FN_GET_RULES)); } // bonus if a DeckHas can satisfy the type with multiple ones - Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.deckHasExactly(type, abilities), PaperCard.FN_GET_RULES)); + if (params.length > 1) { + Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.deckHasExactly(type, params), PaperCard.FN_GET_RULES)); + } - switch (type) { + for (String p : params) { + switch (type) { case COLOR: - String[] colors = param.split("\\|"); - for (String color : colors) { - ColorSet cc = ColorSet.fromNames(color); - if (cc.isColorless()) { - Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.Presets.IS_COLORLESS, PaperCard.FN_GET_RULES)); - } else { - Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.isColor(cc.getColor()), PaperCard.FN_GET_RULES)); - } + ColorSet cc = ColorSet.fromNames(p); + if (cc.isColorless()) { + Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.Presets.IS_COLORLESS, PaperCard.FN_GET_RULES)); + } else { + Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.isColor(cc.getColor()), PaperCard.FN_GET_RULES)); } break; case KEYWORD: - String[] keywords = param.split("\\|"); - for (String keyword : keywords) { - Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.hasKeyword(keyword), PaperCard.FN_GET_RULES)); - } + Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.hasKeyword(p), PaperCard.FN_GET_RULES)); break; case NAME: - String[] names = param.split("\\|"); - for (String name : names) { - Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.name(StringOp.EQUALS, name), PaperCard.FN_GET_RULES)); - } + Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.name(StringOp.EQUALS, p), PaperCard.FN_GET_RULES)); break; case TYPE: - String[] types = param.split("\\|"); - for (String t : types) { - Predicate op; - if (t.contains(".")) { - String[] typeParts = t.split("\\."); - if (CardType.isASupertype(typeParts[0])) { - op = Predicates.and(CardRulesPredicates.superType(true, typeParts[0]), CardRulesPredicates.coreType(true, typeParts[1])); - } else { - op = Predicates.and(CardRulesPredicates.coreType(true, typeParts[0]), CardRulesPredicates.subType(typeParts[1])); - } - } else { - op = CardRulesPredicates.joinedType(StringOp.CONTAINS_IC, t); - } - Iterables.addAll(cards, getMatchingItems(cardList, op, PaperCard.FN_GET_RULES)); - } + Iterables.addAll(cards, getMatchingItems(cardList, CardRulesPredicates.joinedType(StringOp.CONTAINS_IC, p), PaperCard.FN_GET_RULES)); break; case NONE: case ABILITY: // already done above break; + } } return cards; } diff --git a/forge-core/src/main/java/forge/card/mana/ManaCost.java b/forge-core/src/main/java/forge/card/mana/ManaCost.java index 79580f04ba1..cfbde1a74d4 100644 --- a/forge-core/src/main/java/forge/card/mana/ManaCost.java +++ b/forge-core/src/main/java/forge/card/mana/ManaCost.java @@ -391,7 +391,7 @@ public final class ManaCost implements Comparable, Iterable iterator() { return this.shards.iterator(); } - + public int getGlyphCount() { // counts all colored shards or 1 for {0} costs int width = shards.size(); if (genericCost > 0 || (genericCost == 0 && width == 0)) { diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index c6b010d643b..4c9e1ef999a 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -529,7 +529,7 @@ public final class GameActionUtil { for (KeywordInterface inst : source.getKeywords()) { final String keyword = inst.getOriginal(); if (keyword.startsWith("AlternateAdditionalCost")) { - final List newAbilities = Lists.newArrayList(); + abilities.clear(); for (String s : keyword.split(":", 2)[1].split(":")) { final SpellAbility newSA = sa.copy(); @@ -539,24 +539,21 @@ public final class GameActionUtil { newSA.setDescription(sa.getDescription() + " (Additional cost: " + cost.toSimpleString() + ")"); newSA.setPayCosts(cost.add(sa.getPayCosts())); if (newSA.canPlay()) { - newAbilities.add(newSA); + abilities.add(newSA); } } - - abilities.clear(); - abilities.addAll(newAbilities); } } } else if (sa.isActivatedAbility() && sa.hasParam("AlternateCost")) { // need to be handled there because it needs to rebuilt the description for the original ability - final List newAbilities = Lists.newArrayList(); + abilities.clear(); SpellAbility newSA = sa.copy(); newSA.removeParam("AlternateCost"); newSA.rebuiltDescription(); if (newSA.canPlay()) { - newAbilities.add(newSA); + abilities.add(newSA); } // set the cost to this directly to bypass non mana cost @@ -565,11 +562,8 @@ public final class GameActionUtil { newSA2.removeParam("AlternateCost"); newSA2.rebuiltDescription(); if (newSA2.canPlay()) { - newAbilities.add(newSA2); + abilities.add(newSA2); } - - abilities.clear(); - abilities.addAll(newAbilities); } return abilities; } diff --git a/forge-game/src/main/java/forge/game/cost/Cost.java b/forge-game/src/main/java/forge/game/cost/Cost.java index e5222a5f05c..27037e37814 100644 --- a/forge-game/src/main/java/forge/game/cost/Cost.java +++ b/forge-game/src/main/java/forge/game/cost/Cost.java @@ -174,7 +174,7 @@ public class Cost implements Serializable { */ public final ManaCost getTotalMana() { CostPartMana manapart = getCostMana(); - return manapart == null ? ManaCost.ZERO : manapart.getManaToPay(); + return manapart == null ? ManaCost.ZERO : manapart.getMana(); } /** @@ -943,7 +943,8 @@ public class Cost implements Serializable { } else if (part instanceof CostPutCounter || (mergeAdditional && // below usually not desired because they're from different causes (part instanceof CostDiscard || part instanceof CostDraw || part instanceof CostAddMana || part instanceof CostPayLife || - part instanceof CostSacrifice || part instanceof CostTapType))) { + part instanceof CostSacrifice || part instanceof CostTapType|| + part instanceof CostExile))) { boolean alreadyAdded = false; for (final CostPart other : costParts) { if ((other.getClass().equals(part.getClass()) || (part instanceof CostPutCounter && ((CostPutCounter)part).getCounter().is(CounterEnumType.LOYALTY))) && @@ -952,6 +953,7 @@ public class Cost implements Serializable { StringUtils.isNumeric(other.getAmount())) { String amount = String.valueOf(part.convertAmount() + other.convertAmount()); if (part instanceof CostPutCounter) { // CR 606.5 path for Carth + // TODO support X if (other instanceof CostPutCounter && ((CostPutCounter)other).getCounter().equals(((CostPutCounter) part).getCounter())) { costParts.add(new CostPutCounter(amount, ((CostPutCounter) part).getCounter(), part.getType(), part.getTypeDescription())); } else if (other instanceof CostRemoveCounter && ((CostRemoveCounter)other).counter.is(CounterEnumType.LOYALTY)) { @@ -978,6 +980,8 @@ public class Cost implements Serializable { costParts.add(new CostAddMana(amount, part.getType(), part.getTypeDescription())); } else if (part instanceof CostPayLife) { costParts.add(new CostPayLife(amount, part.getTypeDescription())); + } else if (part instanceof CostExile) { + costParts.add(new CostExile(amount, part.getType(), part.getTypeDescription(), ((CostExile) part).getFrom())); } toRemove.add(other); alreadyAdded = true; diff --git a/forge-game/src/main/java/forge/game/cost/CostAdjustment.java b/forge-game/src/main/java/forge/game/cost/CostAdjustment.java index 9011499911e..e60806b2c6d 100644 --- a/forge-game/src/main/java/forge/game/cost/CostAdjustment.java +++ b/forge-game/src/main/java/forge/game/cost/CostAdjustment.java @@ -115,7 +115,13 @@ public class CostAdjustment { int count = 0; if (st.hasParam("ForEachShard")) { - ManaCost mc = sa.getHostCard().getManaCost(); + ManaCost mc = ManaCost.ZERO; + if (sa.isSpell()) { + mc = sa.getHostCard().getManaCost(); + } else if (sa.isAbility() && sa.getPayCosts().hasManaCost()) { + // TODO check for AlternateCost$, it should always be part of the activation cost too + mc = sa.getPayCosts().getCostMana().getMana(); + } byte atom = ManaAtom.fromName(st.getParam("ForEachShard").toLowerCase()); for (ManaCostShard shard : mc) { if ((shard.getColorMask() & atom) != 0) { diff --git a/forge-game/src/main/java/forge/game/cost/CostPartMana.java b/forge-game/src/main/java/forge/game/cost/CostPartMana.java index d07ce100a12..47562d35ea7 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPartMana.java +++ b/forge-game/src/main/java/forge/game/cost/CostPartMana.java @@ -75,7 +75,6 @@ public class CostPartMana extends CostPart { * @return the mana */ public final ManaCost getMana() { - // Only used for Human to pay for non-X cost first return this.cost; } @@ -90,15 +89,6 @@ public class CostPartMana extends CostPart { return !xCantBe0; } - /** - * Gets the mana to pay. - * - * @return the mana to pay - */ - public final ManaCost getManaToPay() { - return cost; - } - /** * @return the isExiledCreatureCost */ @@ -149,13 +139,13 @@ public class CostPartMana extends CostPart { if (timesToPay == 0) { return null; } - ManaCostBeingPaid totalMana = new ManaCostBeingPaid(getManaToPay()); + ManaCostBeingPaid totalMana = new ManaCostBeingPaid(getMana()); for (int i = 1; i < timesToPay; i++) { - totalMana.addManaCost(getManaToPay()); + totalMana.addManaCost(getMana()); } return totalMana.toManaCost(); } - return getManaToPay(); + return getMana(); } @Override diff --git a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java index 8a5a8ce3120..1ee84e2bc8f 100644 --- a/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java +++ b/forge-game/src/main/java/forge/game/spellability/AbilityManaPart.java @@ -374,7 +374,7 @@ public class AbilityManaPart implements java.io.Serializable { if (restriction.endsWith("X") && sa.costHasManaX()) { return true; } - if (restriction.endsWith("C") && sa.getPayCosts().hasManaCost() && sa.getPayCosts().getCostMana().getManaToPay().getShardCount(ManaCostShard.COLORLESS) > 0) { + if (restriction.endsWith("C") && sa.getPayCosts().hasManaCost() && sa.getPayCosts().getCostMana().getMana().getShardCount(ManaCostShard.COLORLESS) > 0) { return true; } continue; diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java index be2f2bb8796..61a52200332 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -618,7 +618,6 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit payingMana.clear(); } - //getSpendPhyrexianMana public final int getSpendPhyrexianMana() { return this.spentPhyrexian; } diff --git a/forge-gui-desktop/src/test/java/forge/item/DeckHintsTest.java b/forge-gui-desktop/src/test/java/forge/item/DeckHintsTest.java index 901c029d15b..b82e3aee81e 100644 --- a/forge-gui-desktop/src/test/java/forge/item/DeckHintsTest.java +++ b/forge-gui-desktop/src/test/java/forge/item/DeckHintsTest.java @@ -44,9 +44,9 @@ public class DeckHintsTest { list.add(readCard("assault_griffin.txt")); list.add(readCard("auramancer.txt")); - List filtered = hints.filter(list); - Assert.assertEquals(1, filtered.size()); - Assert.assertEquals("Assault Griffin", filtered.get(0).getName()); + Iterable filtered = hints.filter(list); + Assert.assertEquals(1, Iterables.size(filtered)); + Assert.assertEquals("Assault Griffin", Iterables.getLast(filtered).getName()); } /** @@ -65,7 +65,7 @@ public class DeckHintsTest { list.add(readCard("scepter_of_empires.txt")); list.add(readCard("crown_of_empires.txt")); - Assert.assertEquals(2, hints.filter(list).size()); + Assert.assertEquals(2, Iterables.size(hints.filter(list))); } /** @@ -82,7 +82,7 @@ public class DeckHintsTest { list.add(readCard("acidic_slime.txt")); list.add(readCard("ajanis_sunstriker.txt")); - Assert.assertEquals(1, hints.filter(list).size()); + Assert.assertEquals(1, Iterables.size(hints.filter(list))); } /** @@ -99,7 +99,7 @@ public class DeckHintsTest { list.add(readCard("llanowar_elves.txt")); list.add(readCard("unsummon.txt")); - Assert.assertEquals(1, hints.filter(list).size()); + Assert.assertEquals(1, Iterables.size(hints.filter(list))); } /** @@ -150,7 +150,7 @@ public class DeckHintsTest { list.add(pc); list.add(readCard("assault_griffin.txt")); - Assert.assertEquals(1, hints.filter(list).size()); + Assert.assertEquals(1, Iterables.size(hints.filter(list))); } /** diff --git a/forge-gui/res/cardsfolder/h/heros_heirloom.txt b/forge-gui/res/cardsfolder/h/heros_heirloom.txt index 93a32b779f8..9c1d7e83c66 100644 --- a/forge-gui/res/cardsfolder/h/heros_heirloom.txt +++ b/forge-gui/res/cardsfolder/h/heros_heirloom.txt @@ -4,5 +4,5 @@ Types:Artifact Equipment K:Equip:2 S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | AddToughness$ 1 | Description$ Equipped creature gets +2/+1. S:Mode$ Continuous | Affected$ Card.EquippedBy+Legendary | AddKeyword$ Trample & Haste | Description$ As long as equipped creature is legendary, it has trample and haste. -DeckNeeds:Type$Creature.Legendary +DeckNeeds:Type$Legendary & Type$Creature Oracle:Equipped creature gets +2/+1.\nAs long as equipped creature is legendary, it has trample and haste.\nEquip {2} diff --git a/forge-gui/res/cardsfolder/p/phyrexian_purge.txt b/forge-gui/res/cardsfolder/p/phyrexian_purge.txt index 637b50c5523..6c1aedf612f 100644 --- a/forge-gui/res/cardsfolder/p/phyrexian_purge.txt +++ b/forge-gui/res/cardsfolder/p/phyrexian_purge.txt @@ -1,7 +1,7 @@ Name:Phyrexian Purge ManaCost:2 B R Types:Sorcery -A:SP$ Destroy | Cost$ 2 B R PayLife | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ MaxPayLifeLimit | SpellDescription$ This spell costs 3 life more to cast for each target. Destroy any number of target creatures. +A:SP$ Destroy | Cost$ 2 B R PayLife | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ MaxPayLifeLimit | CostDesc$ This spell costs 3 life more to cast for each target. | SpellDescription$ Destroy any number of target creatures. SVar:MaxPayLifeLimit:Count$YourLifeTotal/DivideEvenlyDown.3 SVar:X:SVar$Y/Times.3 SVar:Y:Targeted$Amount diff --git a/forge-gui/res/cardsfolder/upcoming/mount_doom.txt b/forge-gui/res/cardsfolder/upcoming/mount_doom.txt index 1a9924c7ce7..f0b7bd32358 100644 --- a/forge-gui/res/cardsfolder/upcoming/mount_doom.txt +++ b/forge-gui/res/cardsfolder/upcoming/mount_doom.txt @@ -5,5 +5,5 @@ A:AB$ Mana | Cost$ T PayLife<1> | Produced$ Combo B R | SpellDescription$ Add {B A:AB$ DealDamage | Cost$ 1 B R T | Defined$ Opponent | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to each opponent. A:AB$ ChooseCard | Cost$ 5 B R T Sac<1/CARDNAME> Sac<1/Artifact.Legendary/legendary artifact> | Defined$ You | Amount$ 2 | Choices$ Creature | ChoiceTitle$ Choose up to two creatures | SorcerySpeed$ True | AILogic$ Duneblast | SubAbility$ DBDestroyAll | StackDescription$ {p:You} chooses up to two creatures. Destroy the rest. | SpellDescription$ Choose up to two creatures, then destroy the rest. Activate only as a sorcery. SVar:DBDestroyAll:DB$ DestroyAll | ValidCards$ Creature.nonChosenCard | StackDescription$ None -DeckNeeds:Type$Legendary.Artifact +DeckNeeds:Type$Legendary & Type$Artifact Oracle:{T}, Pay 1 life: Add {B} or {R}.\n{1}{B}{R}, {T}: Mount Doom deals 1 damage to each opponent.\n{5}{B}{R}, {T}, Sacrifice Mount Doom and a legendary artifact: Choose up to two creatures, then destroy the rest. Activate only as a sorcery. diff --git a/forge-gui/res/cardsfolder/upcoming/you_cannot_pass!.txt b/forge-gui/res/cardsfolder/upcoming/you_cannot_pass!.txt index 976fe3979ad..bac784a6b81 100644 --- a/forge-gui/res/cardsfolder/upcoming/you_cannot_pass!.txt +++ b/forge-gui/res/cardsfolder/upcoming/you_cannot_pass!.txt @@ -2,5 +2,5 @@ Name:You Cannot Pass! ManaCost:W Types:Instant A:SP$ Destroy | ValidTgts$ Creature.blockedValidThisTurn Creature.Legendary,Creature.blockedByValidThisTurn Creature.Legendary | TgtPrompt$ Select target creature that blocked or was blocked by a legendary creature this turn | SpellDescription$ Destroy target creature that blocked or was blocked by a legendary creature this turn. -DeckNeeds:Type$Legendary.Creature +DeckNeeds:Type$Legendary & Type$Creature Oracle:Destroy target creature that blocked or was blocked by a legendary creature this turn. diff --git a/forge-gui/src/main/java/forge/gamemodes/limited/LimitedDeckBuilder.java b/forge-gui/src/main/java/forge/gamemodes/limited/LimitedDeckBuilder.java index 4e6d4874698..59d3bfbec37 100644 --- a/forge-gui/src/main/java/forge/gamemodes/limited/LimitedDeckBuilder.java +++ b/forge-gui/src/main/java/forge/gamemodes/limited/LimitedDeckBuilder.java @@ -18,7 +18,6 @@ import forge.card.CardEdition; import forge.card.CardRules; import forge.card.CardRulesPredicates; import forge.card.ColorSet; -import forge.card.DeckHints; import forge.card.MagicColor; import forge.card.mana.ManaCost; import forge.card.mana.ManaCostShard; @@ -591,12 +590,10 @@ public class LimitedDeckBuilder extends DeckGeneratorBase { if (ai.getRemRandomDecks()) { final List comboCards = new ArrayList<>(); if (ai.getDeckNeeds() != null && ai.getDeckNeeds().isValid()) { - final DeckHints needs = ai.getDeckNeeds(); - comboCards.addAll(needs.filter(deckList)); + Iterables.addAll(comboCards, ai.getDeckNeeds().filter(deckList)); } if (ai.getDeckHints() != null && ai.getDeckHints().isValid()) { - final DeckHints hints = ai.getDeckHints(); - comboCards.addAll(hints.filter(deckList)); + Iterables.addAll(comboCards, ai.getDeckHints().filter(deckList)); } if (comboCards.isEmpty()) { if (logToConsole) { diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index 15d81f2c81a..c2f5b5cd4d8 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -236,7 +236,7 @@ public class HumanPlay { } // 0 mana costs were slipping through because CostPart.getAmount returns 1 else if (costPart instanceof CostPartMana && parts.size() < 2) { - if (((CostPartMana) costPart).getManaToPay().isZero()) { + if (((CostPartMana) costPart).getMana().isZero()) { return p.getController().confirmPayment(costPart, Localizer.getInstance().getMessage("lblDoYouWantPay") + " {0}?" + orString, sourceAbility); } } @@ -438,7 +438,7 @@ public class HumanPlay { if (!hasPaid) { return false; } } else if (part instanceof CostPartMana) { - if (!((CostPartMana) part).getManaToPay().isZero()) { // non-zero costs require input + if (!((CostPartMana) part).getMana().isZero()) { // non-zero costs require input mayRemovePart = false; } } From bce6f930131b336d8315360a4a0e8fce8096030f Mon Sep 17 00:00:00 2001 From: Anthony Calosa Date: Wed, 29 Mar 2023 10:25:53 +0800 Subject: [PATCH 5/8] update inputconfirm cardview - show cardview if possible for plyeffect card (regardless of zone) --- .../java/forge/gamemodes/match/input/InputConfirm.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/forge-gui/src/main/java/forge/gamemodes/match/input/InputConfirm.java b/forge-gui/src/main/java/forge/gamemodes/match/input/InputConfirm.java index ff638c30c50..be1484755c4 100644 --- a/forge-gui/src/main/java/forge/gamemodes/match/input/InputConfirm.java +++ b/forge-gui/src/main/java/forge/gamemodes/match/input/InputConfirm.java @@ -26,6 +26,7 @@ import forge.game.card.Card; import forge.game.card.CardView; import forge.game.spellability.SpellAbility; import forge.gui.GuiBase; +import forge.item.IPaperCard; import forge.localinstance.properties.ForgePreferences; import forge.model.FModel; import forge.player.PlayerControllerHuman; @@ -78,8 +79,12 @@ public class InputConfirm extends InputSyncronizedBase { return controller.getGui().confirm(null, message, defaultIsYes, options); if (sa.getTargets() != null && sa.getTargets().isTargetingAnyCard() && sa.getTargets().size() == 1) return controller.getGui().confirm((sa.getTargetCard()==null)?null:CardView.get(sa.getTargetCard()), message, defaultIsYes, options); - if (ApiType.Play.equals(sa.getApi()) && sa.getPlayEffectCard() != null) + if (ApiType.Play.equals(sa.getApi()) && sa.getPlayEffectCard() != null) { + IPaperCard iPaperCard = sa.getPlayEffectCard().getPaperCard(); + if (iPaperCard != null) //getcardforUI regardless of zone if it's hidden or not... + return controller.getGui().confirm(CardView.getCardForUi(iPaperCard), message, defaultIsYes, options); return controller.getGui().confirm(CardView.get(sa.getPlayEffectCard()), message, defaultIsYes, options); + } return controller.getGui().confirm(CardView.get(sa.getHostCard()), message, defaultIsYes, options); } else { InputConfirm inp; From 03924a4044f5f2b35b2adf7b5cd64a835f3428ee Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Wed, 29 Mar 2023 04:53:26 +0200 Subject: [PATCH 6/8] CardFactory getCloneStates set PT for Vehicle (#2713) * Update CardFactory.java Set PT should also be done for vehicle * Update CardFactory.java * Clean up * Clean up --------- Co-authored-by: tool4EvEr --- forge-game/src/main/java/forge/game/card/Card.java | 10 ++-------- .../src/main/java/forge/game/card/CardFactory.java | 10 ++++++---- .../src/main/java/forge/game/card/CardState.java | 4 ++-- forge-game/src/main/java/forge/game/card/CardUtil.java | 6 +++++- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index d82fbd469d0..984f8e3174a 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -3934,38 +3934,32 @@ public class Card extends GameEntity implements Comparable, IHasSVars { currentState.setBaseLoyalty(Integer.toString(n)); } - // values that are printed on card public final int getBasePower() { return currentState.getBasePower(); } - public final int getBaseToughness() { return currentState.getBaseToughness(); } - // values that are printed on card public final void setBasePower(final int n) { currentState.setBasePower(n); } - public final void setBaseToughness(final int n) { currentState.setBaseToughness(n); } // values that are printed on card public final String getBasePowerString() { - return currentState.getBasePowerString(); + return (null == currentState.getBasePowerString()) ? String.valueOf(getBasePower()) : currentState.getBasePowerString(); } - public final String getBaseToughnessString() { - return currentState.getBaseToughnessString(); + return (null == currentState.getBaseToughnessString()) ? String.valueOf(getBaseToughness()) : currentState.getBaseToughnessString(); } // values that are printed on card public final void setBasePowerString(final String s) { currentState.setBasePowerString(s); } - public final void setBaseToughnessString(final String s) { currentState.setBaseToughnessString(s); } diff --git a/forge-game/src/main/java/forge/game/card/CardFactory.java b/forge-game/src/main/java/forge/game/card/CardFactory.java index b6267e7fb93..7d76f29962e 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactory.java +++ b/forge-game/src/main/java/forge/game/card/CardFactory.java @@ -568,7 +568,7 @@ public class CardFactory { c.setRules(in.getRules()); return c; - } // copyStats() + } /** * Copy characteristics of a particular state of one card to those of a @@ -764,12 +764,14 @@ public class CardFactory { state.removeIntrinsicKeyword(kw); } - if (state.getType().isCreature()) { + // CR 208.3 A noncreature object not on the battlefield has power or toughness only if it has a power and toughness printed on it. + // currently only LKI can be trusted? + if (state.getType().isCreature() || in.getOriginalState(originalState.getStateName()).getBasePowerString() != null) { if (sa.hasParam("SetPower")) { - state.setBasePower(AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("SetPower"), sa)); + state.setBasePower(AbilityUtils.calculateAmount(host, sa.getParam("SetPower"), sa)); } if (sa.hasParam("SetToughness")) { - state.setBaseToughness(AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("SetToughness"), sa)); + state.setBaseToughness(AbilityUtils.calculateAmount(host, sa.getParam("SetToughness"), sa)); } } diff --git a/forge-game/src/main/java/forge/game/card/CardState.java b/forge-game/src/main/java/forge/game/card/CardState.java index 32469ade7f1..a529582a31a 100644 --- a/forge-game/src/main/java/forge/game/card/CardState.java +++ b/forge-game/src/main/java/forge/game/card/CardState.java @@ -202,10 +202,10 @@ public class CardState extends GameObject implements IHasSVars { // values that are printed on card public final String getBasePowerString() { - return (null == basePowerString) ? "" + getBasePower() : basePowerString; + return basePowerString; } public final String getBaseToughnessString() { - return (null == baseToughnessString) ? "" + getBaseToughness() : baseToughnessString; + return baseToughnessString; } // values that are printed on card diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java index e567cd853f0..1110614f04f 100644 --- a/forge-game/src/main/java/forge/game/card/CardUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardUtil.java @@ -222,7 +222,7 @@ public final class CardUtil { newCopy.addAlternateState(CardStateName.Cloner, false); newCopy.getState(CardStateName.Cloner).copyFrom(in.getState(CardStateName.Cloner), true); } - //*/ + */ newCopy.setToken(in.isToken()); newCopy.setCopiedSpell(in.isCopiedSpell()); @@ -233,6 +233,10 @@ public final class CardUtil { newCopy.setBasePower(in.getCurrentPower()); newCopy.setBaseToughness(in.getCurrentToughness()); + // printed P/T + newCopy.setBasePowerString(in.getCurrentState().getBasePowerString()); + newCopy.setBaseToughnessString(in.getCurrentState().getBaseToughnessString()); + // extra copy PT boost newCopy.setPTBoost(in.getPTBoostTable()); From caeeb3116cbb6047e3959af8d7549cdedc1af6fb Mon Sep 17 00:00:00 2001 From: paulsnoops Date: Wed, 29 Mar 2023 10:46:32 +0100 Subject: [PATCH 7/8] Edition updates: MOM, MOC, MUL --- .../editions/March of the Machine Commander.txt | 9 +++++++++ forge-gui/res/editions/March of the Machine.txt | 14 ++++++++++++++ forge-gui/res/editions/Multiverse Legends.txt | 11 +++++++++++ 3 files changed, 34 insertions(+) diff --git a/forge-gui/res/editions/March of the Machine Commander.txt b/forge-gui/res/editions/March of the Machine Commander.txt index 5e9b3ea18a2..7e00a25b51e 100644 --- a/forge-gui/res/editions/March of the Machine Commander.txt +++ b/forge-gui/res/editions/March of the Machine Commander.txt @@ -6,8 +6,17 @@ Type=Commander ScryfallCode=MOC [cards] +1 M Bright-Palm, Soul Awakener @Mila Pesic +2 M Brimaz, Blight of Oreskos @Uriah Voth +3 M Gimbal, Gremlin Prodigy @Fajareka Setiawan +4 M Kasla, the Broken Halo @Martina Fackova +5 M Sidar Jabari of Zhalfir @Simon Dominic +49 C Esper @Bruce Brenneise +61 C Nyx @Piotr Dura 67 C Towashi @Kamila Szutenberg 147 C Isle of Vesuva @Zoltan Boros & Gabor Szikszai +148 C Jund @Aleksi Briclot +153 C Panopticon @John Avon 158 C Spatial Merging @Gabor Szikszai 445 M Goro-Goro and Satoru @Johannes Voss 446 M Katilda and Lier @Justyna Dura diff --git a/forge-gui/res/editions/March of the Machine.txt b/forge-gui/res/editions/March of the Machine.txt index 76cbf48cbd8..aeea56eac7d 100644 --- a/forge-gui/res/editions/March of the Machine.txt +++ b/forge-gui/res/editions/March of the Machine.txt @@ -6,15 +6,25 @@ Type=Expansion ScryfallCode=MOM [cards] +9 R Boon-Bringer Valkyrie @Heonhwa Choe 17 R Heliod, the Radiant Dawn @Victor Adame Minguez 58 R Faerie Mastermind @Joshua Raphael 65 M Jin-Gitaxias @Ekaterina Burmak 67 C Moment of Truth @Rovina Cai +89 R Archpriest of Shadows @Fariba Khamseh 94 R Breach the Multiverse @Liiga Smilshkalne +114 R Invasion of Fiora @Joshua Raphael +117 U Merciless Repurposing @Artur Nakhodkin 134 M Chandra, Hope's Beacon @Kieran Yanner +190 R Invasion of Ikoria @Antonio José Manzanedo +191 R Invasion of Ixalan @Viktor Titov +194 U Invasion of Zendikar @Diego Gisbert 217 M Wrenn and Realmbreaker @Cristi Balanescu 222 R Drana and Linvala @Raluca Marinescu 225 R Ghalta and Mavren @Zezhou Chen +227 U Halo Forager @ +233 U Invasion of Ergamon @Manuel Castañón +239 M Invasion of New Phyrexia @Chris Rallis 249 R Omnath, Locus of All @Bryan Sola 255 M Thalia and The Gitrog Monster @Howard Lyon 256 R Yargle and Multani @Slawomir Maniak @@ -40,5 +50,9 @@ ScryfallCode=MOM 339 M Jin-Gitaxias @Julian Kok Joon Wen 352 R Faerie Mastermind @Joshua Raphael 358 R Breach the Multiverse @Liiga Smilshkalne +381 U Norn's Inquisitor @ +382 U Scrappy Bruiser @David Auden Nash +383 U Kami of Whispered Hopes @Filipe Pagliuso +384 U Botanical Brawler @Jesper Ejsing 386 R Ghalta and Mavren @Betty Jiang 387 R Omnath, Locus of All @Helge C. Balzer diff --git a/forge-gui/res/editions/Multiverse Legends.txt b/forge-gui/res/editions/Multiverse Legends.txt index aa5940c27eb..0969fcae74f 100644 --- a/forge-gui/res/editions/Multiverse Legends.txt +++ b/forge-gui/res/editions/Multiverse Legends.txt @@ -6,5 +6,16 @@ Type=Collector_Edition ScryfallCode=MUL [cards] +3 M Elesh Norn, Grand Cenobite @Flavio Girón +9 R Emry, Lurker of the Loch @Wylie Beckert +11 M Jin-Gitaxias, Core Augur @Kekai Kotaki +16 M Sheoldred, Whispering One @Flavio Girón +17 M Skithiryx, the Blight Dragon @Kekai Kotaki +19 U Yargle, Glutton of Urborg @Serena Malyon 21 M Ragavan, Nimble Pilferer @Magali Villeneuve +23 M Urabrask the Hidden @Flavio Girón +25 U Zada, Hedron Grinder @Dominik Mayer +29 M Vorinclex, Voice of Hunger @JungShan 33 M Atraxa, Praetors' Voice @Justin Hernandez & Alexis Hernandez +49 M Kroxa, Titan of Death's Hunger @Jason A. Engle +53 M Niv-Mizzet Reborn @Illustranesia From 26e7fe4597a8e323c0f756fd3c58d956765fdd76 Mon Sep 17 00:00:00 2001 From: paulsnoops Date: Wed, 29 Mar 2023 10:51:59 +0100 Subject: [PATCH 8/8] artists --- forge-gui/res/editions/March of the Machine.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/forge-gui/res/editions/March of the Machine.txt b/forge-gui/res/editions/March of the Machine.txt index aeea56eac7d..05a926ca2bb 100644 --- a/forge-gui/res/editions/March of the Machine.txt +++ b/forge-gui/res/editions/March of the Machine.txt @@ -22,7 +22,7 @@ ScryfallCode=MOM 217 M Wrenn and Realmbreaker @Cristi Balanescu 222 R Drana and Linvala @Raluca Marinescu 225 R Ghalta and Mavren @Zezhou Chen -227 U Halo Forager @ +227 U Halo Forager @Kevin Sidharta 233 U Invasion of Ergamon @Manuel Castañón 239 M Invasion of New Phyrexia @Chris Rallis 249 R Omnath, Locus of All @Bryan Sola @@ -50,7 +50,7 @@ ScryfallCode=MOM 339 M Jin-Gitaxias @Julian Kok Joon Wen 352 R Faerie Mastermind @Joshua Raphael 358 R Breach the Multiverse @Liiga Smilshkalne -381 U Norn's Inquisitor @ +381 U Norn's Inquisitor @Denis Zhbankov 382 U Scrappy Bruiser @David Auden Nash 383 U Kami of Whispered Hopes @Filipe Pagliuso 384 U Botanical Brawler @Jesper Ejsing