From aeb9da337e506cae3548b23b507ddb89c5975014 Mon Sep 17 00:00:00 2001 From: tertu Date: Sat, 10 Aug 2024 06:33:05 -0500 Subject: [PATCH 01/64] Add some null pointer checks (#5130) * Fix some null pointer uses * fix bad merge --- src/pokemon_storage_system.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/pokemon_storage_system.c b/src/pokemon_storage_system.c index fe65df0114..6c9c53fd7f 100644 --- a/src/pokemon_storage_system.c +++ b/src/pokemon_storage_system.c @@ -1998,7 +1998,10 @@ static void VBlankCB_PokeStorage(void) ProcessSpriteCopyRequests(); UnkUtil_Run(); TransferPlttBuffer(); - SetGpuReg(REG_OFFSET_BG2HOFS, sStorage->bg2_X); + if (sStorage != NULL) + { + SetGpuReg(REG_OFFSET_BG2HOFS, sStorage->bg2_X); + } } static void CB2_PokeStorage(void) @@ -4206,11 +4209,14 @@ static void StopFlashingCloseBoxButton(void) static void UpdateCloseBoxButtonFlash(void) { - if (sStorage->closeBoxFlashing && ++sStorage->closeBoxFlashTimer > 30) + if (sStorage != NULL) { - sStorage->closeBoxFlashTimer = 0; - sStorage->closeBoxFlashState = (sStorage->closeBoxFlashState == FALSE); - UpdateCloseBoxButtonTilemap(sStorage->closeBoxFlashState); + if (sStorage->closeBoxFlashing && ++sStorage->closeBoxFlashTimer > 30) + { + sStorage->closeBoxFlashTimer = 0; + sStorage->closeBoxFlashState = (sStorage->closeBoxFlashState == FALSE); + UpdateCloseBoxButtonTilemap(sStorage->closeBoxFlashState); + } } } From 2237e33ab2feb989888b23beac77261e1a6381b5 Mon Sep 17 00:00:00 2001 From: Cafei <46283144+cafei-uh@users.noreply.github.com> Date: Sat, 10 Aug 2024 21:43:19 +0400 Subject: [PATCH 02/64] Pokemon spite fixes (#5126) Various Gen 8 (+Sawsbuck Summer) sprite fixes for overworld and battle sprites. --- .../pokemon/articuno/galarian/overworld.png | Bin 1354 -> 1352 bytes .../articuno/galarian/overworld_normal.pal | 12 ++++---- .../articuno/galarian/overworld_shiny.pal | 26 +++++++++--------- graphics/pokemon/bounsweet/back.png | Bin 467 -> 424 bytes graphics/pokemon/bounsweet/overworld.png | Bin 1247 -> 524 bytes .../pokemon/bounsweet/overworld_shiny.pal | 4 +-- graphics/pokemon/bruxish/overworld.png | Bin 1559 -> 838 bytes graphics/pokemon/bruxish/overworld_shiny.pal | 4 +-- graphics/pokemon/cursola/front.png | Bin 895 -> 863 bytes graphics/pokemon/cursola/shiny.pal | 8 +++--- .../pokemon/darmanitan/galarian/overworld.png | Bin 747 -> 747 bytes .../darmanitan/galarian/overworld_normal.pal | 14 +++++----- .../darmanitan/galarian/overworld_shiny.pal | 18 ++++++------ graphics/pokemon/darumaka/galarian/back.png | Bin 558 -> 496 bytes .../darumaka/galarian/overworld_shiny.pal | 16 +++++------ graphics/pokemon/darumaka/galarian/shiny.pal | 8 +++--- .../pokemon/farfetchd/galarian/overworld.png | Bin 745 -> 745 bytes .../farfetchd/galarian/overworld_normal.pal | 2 +- .../farfetchd/galarian/overworld_shiny.pal | 12 ++++---- graphics/pokemon/guzzlord/overworld.png | Bin 1871 -> 1882 bytes graphics/pokemon/guzzlord/overworld_shiny.pal | 4 +-- .../pokemon/moltres/galarian/overworld.png | Bin 1172 -> 1192 bytes .../moltres/galarian/overworld_normal.pal | 10 +++---- .../moltres/galarian/overworld_shiny.pal | 20 +++++++------- graphics/pokemon/morelull/overworld.png | Bin 1163 -> 441 bytes .../pokemon/morelull/overworld_normal.pal | 4 +-- graphics/pokemon/morelull/overworld_shiny.pal | 8 +++--- .../pokemon/mr_mime/galarian/overworld.png | Bin 670 -> 670 bytes .../mr_mime/galarian/overworld_normal.pal | 4 +-- .../mr_mime/galarian/overworld_shiny.pal | 14 +++++----- graphics/pokemon/pincurchin/shiny.pal | 4 +-- .../pokemon/ponyta/galarian/overworld.png | Bin 723 -> 738 bytes .../ponyta/galarian/overworld_normal.pal | 2 +- .../ponyta/galarian/overworld_shiny.pal | 22 +++++++-------- .../qwilfish/hisuian/overworld_shiny.pal | 4 +-- .../pokemon/rapidash/galarian/overworld.png | Bin 964 -> 965 bytes .../rapidash/galarian/overworld_shiny.pal | 12 ++++---- graphics/pokemon/regieleki/overworld.png | Bin 963 -> 817 bytes .../pokemon/regieleki/overworld_normal.pal | 2 +- .../pokemon/regieleki/overworld_shiny.pal | 4 +-- graphics/pokemon/runerigus/shiny.pal | 2 +- .../pokemon/samurott/hisuian/overworld.png | Bin 1300 -> 1100 bytes .../samurott/hisuian/overworld_normal.pal | 2 +- .../samurott/hisuian/overworld_shiny.pal | 2 +- .../sawsbuck/summer/overworld_shiny.pal | 12 ++++---- .../pokemon/slowking/galarian/overworld.png | Bin 744 -> 741 bytes .../slowking/galarian/overworld_normal.pal | 6 ++-- .../slowking/galarian/overworld_shiny.pal | 18 ++++++------ .../pokemon/slowpoke/galarian/overworld.png | Bin 642 -> 638 bytes .../slowpoke/galarian/overworld_shiny.pal | 18 ++++++------ .../pokemon/sneasel/hisuian/overworld.png | Bin 683 -> 629 bytes .../sneasel/hisuian/overworld_normal.pal | 8 +++--- .../sneasel/hisuian/overworld_shiny.pal | 18 ++++++------ graphics/pokemon/sneasler/overworld.png | Bin 1061 -> 935 bytes graphics/pokemon/sneasler/overworld_shiny.pal | 12 ++++---- graphics/pokemon/sneasler/shiny.pal | 2 +- .../pokemon/stunfisk/galarian/overworld.png | Bin 519 -> 519 bytes .../stunfisk/galarian/overworld_normal.pal | 10 +++---- .../stunfisk/galarian/overworld_shiny.pal | 8 +++--- .../pokemon/weezing/galarian/overworld.png | Bin 1300 -> 1302 bytes .../weezing/galarian/overworld_normal.pal | 4 +-- .../weezing/galarian/overworld_shiny.pal | 10 +++---- graphics/pokemon/yamask/galarian/back.png | Bin 388 -> 350 bytes .../pokemon/yamask/galarian/overworld.png | Bin 577 -> 577 bytes .../yamask/galarian/overworld_normal.pal | 10 +++---- .../yamask/galarian/overworld_shiny.pal | 20 +++++++------- graphics/pokemon/yamask/galarian/shiny.pal | 4 +-- .../zacian/crowned_sword/overworld.png | Bin 1224 -> 1222 bytes .../zacian/crowned_sword/overworld_shiny.pal | 20 +++++++------- .../zamazenta/crowned_shield/overworld.png | Bin 1166 -> 1166 bytes .../crowned_shield/overworld_normal.pal | 2 +- .../crowned_shield/overworld_shiny.pal | 18 ++++++------ .../pokemon/zapdos/galarian/overworld.png | Bin 1034 -> 915 bytes .../zapdos/galarian/overworld_shiny.pal | 6 ++-- .../pokemon/zigzagoon/galarian/overworld.png | Bin 830 -> 862 bytes .../zigzagoon/galarian/overworld_shiny.pal | 14 +++++----- graphics/pokemon/zorua/hisuian/overworld.png | Bin 845 -> 721 bytes 77 files changed, 232 insertions(+), 232 deletions(-) diff --git a/graphics/pokemon/articuno/galarian/overworld.png b/graphics/pokemon/articuno/galarian/overworld.png index 734f4802d9ac181e17817ad8d8a395d09aa2a3ab..51e46babdbde6230a5451f4b2d8b7c8650b2d90e 100644 GIT binary patch delta 1320 zcmV+@1=sq@3djnOF@G>nOjJcYxR(F`0C>pwpy2psMT*qE>6LH3DI6^5%;>(O#-e_# z%eB$}|Nl5RI2afh0001yIs$C~000nlQchC<|NsC0|NsC0|NsC0|NsBMP>VwV00gQ@ zL_t(oh2>a*a^ortj9OwDZ1ex0`&JTQ4C2yvb2Im5o;yw2V1J|C)k;8Kum9`C{I?PO z#>E|K3V)RW^S@V+`MquTV-%>(wT|*z=sqLi4HtdB@A2Pz3nAPTxK2R(-e;zJeBb97 zAESP}RLDRy&om0gp}U6^|4o5IBM>7f)Z3aafFI)&gg)!`3BLew(2ovzbsAe_1rP2@ zfklKe(lH= zk?!$N=x2{tVKyKC=nzcuypa^YPNesBLejY#0Zbwc1tAC=`;5Ph{}R6E@sc{4@msD& zhd=^)W|2UE*(f|`uPFdFihIN>xe4gTe}&)mc+H$cz<-*EIz)II1%*E}5pj=OgT&_! z3QQO9!TNaTC<)+!z&-9vQk$~xaRde=BQO*Pr6eU-EJD>GfS=OHRcmlAE~G$mz`!j4 zx3xP)$1c807!R@^*YLHHYzZ->F{)*pYP#wZaGe6ZoKz)DZk~^y1 z@(zvI31hdyjQ``50Mw>XcWY1=WKIe&v9kmh1Ai5MV;vTU$dibi(lKfma@Nc$1MM_j zG1GyhMeY=4N#ikAz$FYAx%9graVi!`UYYX4Vq+Z^hlp|#danOVo=WAxvYfV?U|K{m4Ns3IqQ!n}8)S zv=SIg25=F6R|#n2V+yK6Smi${4BJZ0Ku&w}5I-#>H=L-Ts&HaQf3&J}T|tF7d75 zW!zfsgMd0jud?HrcMMqx0HyBbLzvbhY6^R2ol_hj46-=jT-1Sx=M1sbCvzLu6!e`) z9C9`Mv&E|j7?*9bWXM@ho5C{yS*>>@DQDoPT~_GPIY#-;5Yaeweo z*3|noS_#BcH#*zqo{O5oGyYxhi$mn+MY`GV;&%Y8zQ(iZW;^x3HVy`Krh$Q004JMc zMZh|&cOWhdvV*@YQL@bw{7Rr-thfQ(sy`pWWmsj?=3>}T2lQOcqzI9M#4C@NM&KfE zDwx9K$7Z0{P2EgXckqU<9VJGC%74+$WV^@7wvMBI;vwmwuEz=cGiQl=ieL&)pQrdd z+>q=UZ~WzvvPTKqGx+`80M%pb;!sI}^hgq1k0WD;)89u5UTwtb`vs!5Vd%fR5DHW9 z?uL@2<)OGHcmadQGv3cGa=soh3N#X!&&&2%_vfO4{0Ikq(tq*bs^pt<{vpI{KY8*G ee69E2yZ!+({We$q8QPHm00006LH3DI6^6=;^+r#-e_# zc*yvm;P^N=I2afhYnlrp0000FbW%=J0RR90|NsC0|NsC0|NsBxjh?0e00gi}L_t(o zh2>a*j_f83Tq8CFlI8zDw__U!!Orb#`=nQ?oNo6nBrr1`8-K{_^?z+4{AmRLpoIxF z#Xrg*guky~2=8sX9-~P5M@s48iRYew*8qM)qwn|K{(EmR#*0Ge1JJ%tK(A3#+IKt0 z*IB($F)+H znXdkC=&i>a@v!;$SBGGb`;8>{Wgxk45|WNx31ARr$OxIhei;0t|3~%X@psK{^%wt`w~N9lyt*J0ul}JRZLnFn~Ib+G0n& zT3%B_yn?<<;e`KBV`~VAp2!|M_~_5QdH6?mYp&mxnBfpn&T5BS>PPT*=2G^jwe&;?>QK1aAToqh zDSy5r)u&A|6`2B`PX3DZ#owi*dHeU89HRIkk=Y1wh)TI)7w!ZQe#D?Qg@OODCP+Ln zv|<>K4B#UCJ_TU(uOa9TNh1G2aoJW%1Zvrbhr-=Le8Y(h>I#?S=zl<+&nJoyhtGg2 zv<&$4@t>prG$vw)WW}#*=@tzG3<3>Vy??N6X1zuwzZABG68JO5;8r2vGlLi${6c`C zX+Ir?fH*{2+ws^PLlpu*DSP=C&3Z&bVMoDqvICewWe1!OdBEa18+n*sH~6hzLNHe% zcF1Sow-z5F6ztKW_{UjKhr$-X0nK&N4 z0|~vKqn!Y3$Zgx)bJ0-P;y)QbJA{8;%;20EOaL{%*0brRJ9WMulmTy_?hGUYk`xHf zTKlTvUP}k#x{h6~o-9=D^&GnM+ zha2KOR#7#0Wv0001;w}I>c0004VQb$4nuFf3kkv=bf$iRU2@VEc~0B^!5 zfB*miCP_p=R9J=Wl|hz-APfZ!#AN0DuRA0VTI@C;{oc$h_#53+kp#qTTUlB8wLr>O zc#Hw?8$2aU3JN|gD0m2yE#M2ED*zQw^yC0A#0ayCXF=^9ERO}4@o0JED1sAS9M1$7 zTooPAdQ}00@FwtoPgSlM%HU8e7ln<+!L?IcO%-|?G~k}g+Ay5fLn#DpBh~VN7Xcy> z^UH8sKN^Iw5s-!%-PN0K_XAI~^F5mj2!=ERrz+T~Cn%{VnKzvTz5&4aY61kJVFOk^ zzov0F_@F>`iAhfkU9w0000007DOfr2qf`32;bRa{vGi!vFvd!vV){sAK>D0W3*GK~zY`?US)? zgD?<=jfBJsDe8{P3&ef_peH(IBwaf+$C^r2^P*jOm)_Y$#da`Lhe-L?@8iz*ONe`J zIZ2Vn`GYFsTiml@e>YQ?aJ4CwJmcf-d=)tk#4%40_ynE5x8Z5ULxq-Yn;asKUGuAaip>U&Q3sIDTzg^~W@zaEf>pX!}!ndOVfJ zIL4^>lQ|Vw9t(YV12Q)WV@QY`Hkr}<*`F^ZKfeG9R|}{H^S?bQp6L-OS4Tb~rQ%Pn gA!FU(JzZabZ%nKrfeE~7ssI2007*qoM6N<$f}ZNc*#H0l literal 1247 zcmeAS@N?(olHy`uVBq!ia0vp^2Y^_CgBeH`yR~lzQjEnx?oJHr&dI!FU|?nl@CkAK z|NsBP7cUMxD0p##p<;(e$IPh@G8!HvOgJ3aI@2v@g+oNMY)r6}o~^s9f`bCkgi$aW z0>dc;u219K56l<6o-U3d5v^~hJ zbK9O>Ir{O=)!CY3Qkwsv?%s5{o7W(|GrJS!?WY74}N12 z_4^*ZjbkfsmJI8G@3!oQY$>gTe~DWM4fbzSpw diff --git a/graphics/pokemon/bounsweet/overworld_shiny.pal b/graphics/pokemon/bounsweet/overworld_shiny.pal index c97f75961d..769d9abd9e 100644 --- a/graphics/pokemon/bounsweet/overworld_shiny.pal +++ b/graphics/pokemon/bounsweet/overworld_shiny.pal @@ -2,11 +2,11 @@ JASC-PAL 0100 16 255 255 255 -225 232 232 +247 240 184 216 192 248 232 200 0 160 128 240 -136 153 149 +200 192 128 224 104 128 200 112 152 176 64 104 diff --git a/graphics/pokemon/bruxish/overworld.png b/graphics/pokemon/bruxish/overworld.png index 18b2325a80c8bcff63230dad180aa5a88c541990..04757426e6ccfe11dbca043c33b9b45f78f60077 100644 GIT binary patch delta 385 zcmV-{0e=3M48{hKFaiKDkuo$0oANmY0008SlRg6>3f7&;%fa?85<*#%X#;=(+mq@8 zx_|1vAx-!O1m??)f8{rW=yJ^;^^VDyYhn480xw1psz3290pNy1q=zm{#N{v=7`V20s}*K3{m<)q7ohihn~$ f?Vh2j`!B?A9=I&8XZhQq00000NkvXXu0mjfzq`B$ literal 1559 zcmeAS@N?(olHy`uVBq!ia0vp^2Y^_CgBeH`yR~lzQjEnx?oJHr&dI!FU|?nl@CkAK z|NsAwFJHcXbbolqVac@@M@}EwyUY1S#g+}JN3AncdxGY9dr5^GRAlP-sEKO>O&A5E zAuyamK=9zZM+^*1M?GB}Ln2z=PQO@mSAoYRms@#3!@vLeyOmZR-^hAriRW_uu(VG_ z8}@d$T!@{fKCj|Yr~15%iJ!~${~T9*Xqsqwf?xY*ln006z72Xwck5p|#Bk`H(>b!@ z^e(odb%&3q|5?w(*HxU%esQPK1$|2%(XbEmPtV(NBsFV6!7HhTeFjAak1rT(G=Fqq zzQyx}%`b|cT`3M&$+=|SA<6mQ+ZCrzvGEUDqk70rwYt~k>5u!>RfiVl=Oi53{9~K5 zPMWpr_vgp#sVVa%Ss> z8t+E&#T-}X|Cq*5a9Ht@b9CH&)&SR~_s%0p@wdjij=wk*#>x3> zOPWLVg|`AzAALx3(H6XC_N-u^zHXgtX3Mob3wI@4wn;VKXTmI#{i5gTtfG(!7hSxy zv!}YRbqm$h`*Zjpd*7*in;3Q`%`H2d_V;#WCLH>2@xt%6)%w}L#P5Ay7Vy+LzO8xE zl4T*h>)waY%Tw+ZP}|y2x$ZXGahbrq6K_4Pyv`$`>vOI2c(wVRk{!tk7pi@F*589-ei4<$t?ig3e!sHN_jQUtq4Az3p7gmAEYSmt|90$|GcB zo(kVnJM?eM+Ru6Ed^)bHzQ5<%yZ*a#UBT4)$H%Sa6#N#d=;fE?`Lcb*)_<#_Zpl^} z|NAyku%^+ReXeQLmdo>#zs8Bre{^3UXm@(XtAE@dr8|UmX5O6t_XjA0db;|#taD0e F0sy1Mk?Q~e diff --git a/graphics/pokemon/bruxish/overworld_shiny.pal b/graphics/pokemon/bruxish/overworld_shiny.pal index 624b47c64a..7de5796528 100644 --- a/graphics/pokemon/bruxish/overworld_shiny.pal +++ b/graphics/pokemon/bruxish/overworld_shiny.pal @@ -5,13 +5,13 @@ JASC-PAL 248 244 244 232 208 136 225 220 64 -224 216 208 +248 248 248 196 203 194 200 160 80 232 56 40 104 208 152 59 105 101 -140 82 158 +56 160 104 75 74 26 56 160 104 105 44 76 diff --git a/graphics/pokemon/cursola/front.png b/graphics/pokemon/cursola/front.png index 2e4036381214f9435653aec22e26c869cfdbff17..5dd4cea7de0a60382d0071ee68d84310448e1fb2 100644 GIT binary patch delta 803 zcmV+;1Kj-o2Hysd7#0Wv0001;w}I>c0004VQb$4nuFf3kks&pI^78VFifhgQ00P}f zL_t(og{78>va28rh8q%?o~zdPf7_cC#jRqQ>5Q%XAKB^ab+Q1?-rQS|68?l$0B#t- zzuq9|DFQ&s4S|2V1JF}sFXp@l+%X^kEPrBv5lHrKBjEb4fz*>oH`l%Lz`ql?g&&KijD<=S)zpgQnFXU8z0jSRHVrd99*xzAt4^~UG zdE4R(!ZwjQ`H}$4a{rAU6DjKERPv{6}Ch> zAX^Gt-vVU%QFv_nq8=DQY{-zC%(r@yyk?Js0CFksS(ZSGgn{xR2?qdH&1dNeK$+iv zqGyVPA~lVF_$T_mx91`>0iar3+hkxi!2BLYro6}EW6Wn-%~#F( z8DN;lfnC@Gylz!~R8v@!z@K^4AeakbfHo#K=f(A)qS7y(I_p4fAzSHsPOO&(M zkm|E(v`(*#554+mgi;;Y^wqh#j(@j7_0-BQW^>bjz*$>K-*XN0nm6Ie@|yTPyhe`07*qoM6N;tV1mtWdJ_Nu delta 835 zcmV-J1HAm-2LA?-7zqRe00013M{MnpE;WDn@c2~zWrP3#010qNS#tmYE+YT{E+YYW zr9XB6000McNliru=LQD?6C9&xg)jgB0^&(TK~zY`g_gZ;+b|S`DR49jn6#Z;*RtTj zEfmojJ4lws4z9%RHV{8Zw*E|ggg!x#)oF*Uae*SumS*YRJVOs9Igw>a;b7S0$9sS7 zJ-j5$SY-&-JuLFNSpaIkPW_{00YD{Qi5>$M^(6&*57?{`(4~ZI0GPBR8tlJA;V4Z> z4)v{mo{e<+)=?Igw4pLC#B3oO(j4vqK@l}%F`tu7Ibajk4+9wO`64QTkYdrVmjEF1 zNje??N#RimnBj>}LvtKMX#&*%MC5-uh57H)m(2GLDf+7{RDZ}O_j8mo4r|tnEjWqLZLB$BP z)?TGmFtuQc+tL;9H_w2m9;6s(pEfHY&el-SP+-sJsg~FjYB>=Ys}r(EsWE@y={!{u z0+=l610ll6XgwKu)wbhtriB3}n{xuPSv$+J2aSscfS?b+oqnY$Z2*U5+gZh-CoFWosh^G zArK%c)}4dKwu;H6I5XW-j_TC_;N;uPm4XA2P_@gY;xOM88*z0Sjr0Dh-f(ql0^|*6 zS{@%t*4`QXwsHB2?0qk{<^b>ups=6kA2laTM@ve)wr7&(K+Qi^(-40&=y++lsUz)r zixFbd3CwYUye@#pN#{D_S@r^;lSTXLt1aGytRu(U**z|G_IBGAfPVf?boOvd_iez# zT^v8atJy^((ECR}@7|f7ncXx4k3_F;AG-m1^Z1u&*9@>9Pr$Ec;3@}xftZ#R1z|}9!pB-%KbpXBXC0(#KuUQW}dvx)_KY*j{{{af1x2>IlIjjHx N002ovPDHLkV1hU@dV&A| diff --git a/graphics/pokemon/cursola/shiny.pal b/graphics/pokemon/cursola/shiny.pal index 552b1077fc..9259843950 100644 --- a/graphics/pokemon/cursola/shiny.pal +++ b/graphics/pokemon/cursola/shiny.pal @@ -2,16 +2,16 @@ JASC-PAL 0100 16 152 208 160 -184 184 184 +145 145 145 248 240 248 120 120 120 224 216 224 208 200 208 -144 136 144 +92 92 92 184 176 184 -224 96 144 +192 96 224 248 248 248 -248 160 192 +221 173 237 16 16 16 72 72 72 56 56 56 diff --git a/graphics/pokemon/darmanitan/galarian/overworld.png b/graphics/pokemon/darmanitan/galarian/overworld.png index dda43e6e075e81e0cda84e932ceb70ff8daf09b9..f6d78555e5bcf46abb9ae1e10b8bd0e2d29dc9a3 100644 GIT binary patch delta 30 ocmV+(0O9}Z1?vTnMH48%r~m)}c$?8rZ=nDG|K`-J_OV!#0@r;Hk^lez delta 30 ocmV+(0O9}Z1?vTnMH5}T(f|Mec$?8rZ=nDG|C2uO8?jiE0@e8rZ2$lO diff --git a/graphics/pokemon/darmanitan/galarian/overworld_normal.pal b/graphics/pokemon/darmanitan/galarian/overworld_normal.pal index f573721897..2036748fc6 100644 --- a/graphics/pokemon/darmanitan/galarian/overworld_normal.pal +++ b/graphics/pokemon/darmanitan/galarian/overworld_normal.pal @@ -6,14 +6,14 @@ JASC-PAL 167 167 167 215 215 215 10 34 40 -93 188 210 +40 192 168 0 0 0 120 155 209 79 111 160 255 255 255 -10 10 10 -11 11 11 -12 12 12 -13 13 13 -14 14 14 -15 15 15 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 diff --git a/graphics/pokemon/darmanitan/galarian/overworld_shiny.pal b/graphics/pokemon/darmanitan/galarian/overworld_shiny.pal index f573721897..e61043b14e 100644 --- a/graphics/pokemon/darmanitan/galarian/overworld_shiny.pal +++ b/graphics/pokemon/darmanitan/galarian/overworld_shiny.pal @@ -6,14 +6,14 @@ JASC-PAL 167 167 167 215 215 215 10 34 40 -93 188 210 +72 160 216 0 0 0 -120 155 209 -79 111 160 +190 224 117 +74 105 37 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 255 255 255 -10 10 10 -11 11 11 -12 12 12 -13 13 13 -14 14 14 -15 15 15 diff --git a/graphics/pokemon/darumaka/galarian/back.png b/graphics/pokemon/darumaka/galarian/back.png index 94115f536adc13cf784b4068ddda0a3f869c423b..8aef0d7756517a5132535cb4b277f64f5bccd049 100644 GIT binary patch delta 455 zcmV;&0XY7y1n>ip7%&I}0001;w}I>c0004VQb$4nuFf3k0000mP)t-sn9!goU1$&x z5Gbm^Xxiu?lAw`TAAhB>4FCWEZb?KzR9J=WmC=%eAPhxIl$5~#|L=06xU3SS`qWwP zbbR6*2oU;uJ$dqf;=Q|v&of=eUB>6hU0#CA^yIz2yaWgOj=-;it2LAbTwcOGK|($i zMpnld@AIMK(0=jNF~&PLO*4`e6}~7&1f;d9WXD5MMt_BXUq^r(`OOd_QM3x8 z4qpruMa~4&Bl6(_ieu&X3R{3HPSr@DIJZAZ9X^K4Cs`3(7}?{z+$Kv918tba zTY`|2YbB}E;(sjz>0V*pGP{ARpmmdj?sYP;S`Z{QnhAZ%hfQw@(2#9GU^?d+4JqMJ zMCOTx1S&bcO4{NyD&S;1YvTejZX_*LHkx=t^=m#!5G3Ors04OHP|Y_LsWbgzNcQZ? xcX1p@Sc@4W`~F5KduJo(c60D96PXi(@X3k(1N002ovPDHLkV1n^J%eMdk delta 517 zcmV+g0{Z>%1Fi&+7(fIA00013M{Ml?0004VQb$4nuFf3k00004XF*Lt006O%3;baP z0000mP)t-sn9!goXkZW!5GcT?Xz0)&poo!3AAc312><{932;bRa{vGi!vFvd!vV){ zsAK>D0f$LMK~zY`?UONY!Y~kpQ%gvZSc-QTPILGb<1!Jx7R`}6;rx) zX$>1w@q~~7rTKHULkM=_rc#G?=^On%-#h0n-oO4(?D88w4qE-|c-U+6FXD)eTY+2F z4u5nMFly`aiYWy@2fBIw70_YYKX9J!oK24IBUbpF&vuRiy(o@{tnd}FX#zKlMe!Xk zHPc6_|6~K~R6t3U@K*yfi75Y}@^uNaUetl`3_NZ;Ux<~RG3EwqL10~p9P3Vq-36+n#yfu?r^{Ka`#&jR-i zAQuMkmOul5Y+gkO+5{9*?G&LNbpY^Td@SMuvcQ@JPO3?3sjjI#tb?%&1z?Y>k2==2 zC?K&Hf}nLDFsW};Sng`6ZQ~CPEgzeIc;9;A*8A5l%kw?~d4w8$(!|hQ00000NkvXX Hu0mjfTwc~B diff --git a/graphics/pokemon/darumaka/galarian/overworld_shiny.pal b/graphics/pokemon/darumaka/galarian/overworld_shiny.pal index 44a066b5bc..409dc17fba 100644 --- a/graphics/pokemon/darumaka/galarian/overworld_shiny.pal +++ b/graphics/pokemon/darumaka/galarian/overworld_shiny.pal @@ -5,15 +5,15 @@ JASC-PAL 10 34 40 36 36 36 0 0 0 -93 188 210 +120 203 214 215 215 215 -56 134 152 -29 45 70 +32 146 160 +31 51 8 128 128 128 -120 155 209 -79 111 160 +182 212 119 +120 184 40 167 167 167 -55 72 127 +64 104 16 +255 255 255 +40 93 104 255 255 255 -80 108 152 -15 15 15 diff --git a/graphics/pokemon/darumaka/galarian/shiny.pal b/graphics/pokemon/darumaka/galarian/shiny.pal index 21bd015c8a..f7748fd8d4 100644 --- a/graphics/pokemon/darumaka/galarian/shiny.pal +++ b/graphics/pokemon/darumaka/galarian/shiny.pal @@ -2,11 +2,11 @@ JASC-PAL 0100 16 152 208 160 -40 104 96 +40 93 104 16 16 16 -40 192 168 -104 232 208 -32 160 136 +40 170 192 +104 218 232 +32 146 160 184 184 192 232 232 224 64 104 16 diff --git a/graphics/pokemon/farfetchd/galarian/overworld.png b/graphics/pokemon/farfetchd/galarian/overworld.png index 343ece6bd68120ffe37d440cfdd7d708685e032d..bde1b5b7ecf99b8e08858dd3316c1150247279a6 100644 GIT binary patch delta 639 zcmV-_0)YML1?dHlQ5n_J#X)sBIWRF&L_yWk#TXP2DJ&`Nbp?fyYAAo*ma8xbg^MvY zl}O(IZ4cm2J0qaWUYxlQ*UZhglk82<)yLzmyY9N{uDkB~GetyS@gu?E`tORj&p9~b zOMbNcAl`}aP%&rBaG7V})#C@4EynGM)2{~k3|Dl>C0-OD#A-2UPfS;bxz-@$0Vk>~ z0Dpu+EEc&vK>(k&_Go|dkJz8t;YHx`^@yCAdjhJ8-3~CXneYm2V;kBCVj!CaW`WP& z0Rnz*Ifknp3d0B^Ky8gRt?hfH0`mC}gO0@mEL``$Le*f`foMdwpEMCb_PJ{6V$h!R zH})*5LkGuH48p5Zhaxi!f(G=tI+QnrUy}-*5#a+HCII@yq4j^6is>T3j-K+F#HZOm z4j6GM{>o@k_X1;BH*DmCQcBC7#h5O;BN9~TOAn@oIN-*;YXmjOmt_WsFqFO&gr{=> zA>9(B#QusnGz@CMm3vc6paTN0q3r_@uGq>4Kz)zQ5s2qBroZv5N!%g1D>=nXkV38w zml0{huseh5hRuI`>XH?}o#IY}bTsclZa6`KRLL^P0XJ@bjd>Nj6O+`2(FpK?_xWZ` zN}8~eC7=cJpS_-Hnh_k_)i#d<0utOx6IN;`5a9nDGAm>{J^z z^QnTrBfv(T{RN^&RnZqBGyR7};?K}EzHaa2lj6m}Z+_mMx$9095j`pL`HAhXZ+_Q* Zs(-t;D19o?kp%z%002ovPDHLkV1l&tJ<P%OYAAoplIt)CM1y6; zDkGu)|Jw`rk<1vdD_PuG7}w0^w4`o?U3on2y6djH?z-!)KT|~X6+aW4uK%uh`<#O_ zzT{`iPvTt&4;6F93?K6>yn6fuv&FbQar(_5pW%v5xx|YCgjg*G?TP8;FxMJ{JmEx@ z1>lcRh{YneCkWuv-XDKm{t^2#JG=^9z8#S>b5B53vD*RWH4}b9``o8KgBZxBfkoi+ zSAc+DTaMvshr%?&3{ZP#P4CAZsepX`!=PjF1Pj;wKcQ-H7(g^4J5HJiAp2Z3bv0QH2cLC}CcSBLV3@M}_GFe1ER!vw&%I<$X2Q!!m7IM7o*llV0I z#{nZQ#a|gM8X6eGx?>|Blu~;3EXH)*9g(2ISVk~4!~u8iT_dPLzAQ69grSV3AUvH5 z27=lej~2S8|G(Acb5V zt|QW?>2L1^JE+;D;dsgh-o1Mb}X8uKc4Cnl*+vk~A8AM-7m zlr&)_OF%2+KYKmZ)DW;G+aSES*?`3%KPdhWN9g@1HuI^ZHN7M-TTCnDboLEs16pgz zG5E%9ipvZU!mQ6P4jVS}E&Df}Pj0alAn7Y47hvJ#2)0|8tO2~lmnr2j;r;nJsCI1T zQw4uVfQ>r)3q+5qVk|^v`ZtTjpP|qAw!M>2iWdjJ`FVTht~*sk^rFb;7q488 diff --git a/graphics/pokemon/farfetchd/galarian/overworld_normal.pal b/graphics/pokemon/farfetchd/galarian/overworld_normal.pal index 0a555549b1..3df22685d9 100644 --- a/graphics/pokemon/farfetchd/galarian/overworld_normal.pal +++ b/graphics/pokemon/farfetchd/galarian/overworld_normal.pal @@ -10,7 +10,7 @@ JASC-PAL 238 234 255 49 89 41 255 202 49 -0 0 0 +213 210 197 65 117 57 57 48 49 82 68 65 diff --git a/graphics/pokemon/farfetchd/galarian/overworld_shiny.pal b/graphics/pokemon/farfetchd/galarian/overworld_shiny.pal index 0a555549b1..2d02e605e7 100644 --- a/graphics/pokemon/farfetchd/galarian/overworld_shiny.pal +++ b/graphics/pokemon/farfetchd/galarian/overworld_shiny.pal @@ -4,16 +4,16 @@ JASC-PAL 57 153 197 0 0 0 156 161 115 -180 174 156 +200 176 112 180 145 41 -115 93 90 +128 96 96 238 234 255 49 89 41 255 202 49 -0 0 0 -65 117 57 -57 48 49 -82 68 65 213 210 197 +65 117 57 +72 56 64 +96 72 80 +240 216 176 24 20 16 41 44 41 diff --git a/graphics/pokemon/guzzlord/overworld.png b/graphics/pokemon/guzzlord/overworld.png index f9e52bd083253e54a274ecf503c5d489cb18da41..f8e2dd5fe50a5ee03991eec027348821b6f79303 100644 GIT binary patch delta 1083 zcmV-B1jPH#4%!ZoP6IPHJ+V>c0)J8XGdlnP1PDn)K~z|U?N`x~q#z8G5hQTr|9|&7 zAt*Yab6d5w_prD+&NMFFNfU5ce%o*RZNKgRY0T~N75L{HJKnGV4*z^h(I@%vF?|7E zo-_2_8RW>Emc;n{0{onz@6I5{h=0yFqfum%EAa%rw5JR`;Y9cR=D0CTF@J3v_-$L# zA((?J%Tip>tY6`#Z*NZ-dcx_!TvJ>bvJhr^tzmsp{Tc$X2w)0f0Gqy!-zh_-aH+7} z-DeO%q&sun;mQyiobwyrTC_KbG|Yad8U zek$M&uM8#1I6V`4p@tIxhJV2*xEa7z-$4-0h%pA7>JbE>4TmRrx!|2Z?V?ecRfl`L zGK4>f;SO>*U-E^Q79o5N;Hs|@lnhCHg`!-NCUDQd1V89#RFZmYX!Iw%l#I|i+Td{q zmv7|oJs%y0@UG91W(W+eB~9S6&w*u#(~*H9QQ=6DN-WEJ6FkuzUw<-OKpv5@<~&^D z@@KHlP#Ha{J)}{*1Zs%ybD+@r(o!N&c@MJSo0wpNV{H+8XV}c^;e3{)wMqW~D?JM@ z8^gC!|Au!GvzMr7u~UXM$l~G3RdE$aLtGcf;I}n{nZw~-UN;~35O51ify~MaBjBjF zxr-C?06&Upu2Ipc6o1txLX0DrYC*2J3LN1&0*Y(_!~D_%4B@)vi0}g(v#aqXJ@nq? z$e-aw!UBV$D%c#ULDm^B{xMtx4)7ME5I}KVU$57S&!THrXR>#=<1ZdFhSB(m!*&4^ zybfQ8@|H6M6vH&gSSO^jzzshHcKFUOppwESdSJqw74QHK+s2>&Zg-9i=37iLRy%f2Oy z6THF_i$oj3g5rkSCIp3}@YVf`c9`OO0&un}gBcTghE?Ag<~{{lLv)e~KP@Fv^A3SS zoXkN%(oY*F`G3D)Xao&s>oCI`f6&3Ur!`S`Fw|Q*!S={*a;^-Mome%A=p-Z4Y*E&q_+69N~zO2rj86Nr!md#mxq<*sUB6<^IuRk9Ous5V`Fzi#1U`LnLr|SSbPdjLr8&PliMvut%q#nN#>;zVPG+fTPzE=(T zDZboxcr0(-D8sZ(o|^TS-|$Kdl{arK595qF`~_ZYS#T+*25bNT002ovPDHLkV1m*L B3;F;6 delta 1072 zcmV-01kd~04$lsdP6InXMzK-l0)ICq@*4mE1N})vK~z|U?N`xq;~)$)F&K$M|NpzU z5@6#P>|AF$y@x`bI9XA4r3I5^`E9@LxBa&Nr-`(eufRXw#L52p@9@tzj-K_+NB#o5 zJXh$uD=1Nf7Z$vK0e-H~cUMqi#6K5Yu~HP$SCR?*)}AW#h|dc9h*yRjd4Jo$Z`;_W z5D6|XOLoDk{th>NdwZ(T6V4Cjn&QS#l(5ii4eN`_#}G(VfKUhnxa#Zpohp>Ge~fpAZe;s&6NVx){Y6wL;nL`ZPhfJ>#9g5(8=M zrvmQq!cen}%L|EDYPbMk8h^}!n*m((9R%Tw7-PU?9zg=ybQmei8{P@D5X;JJceuw3 zL->OP?jVQjr5|Kz8N&MjF8T^Vt&rwdDe4Pb0rv__@Pm$Jh0R+-qd(y}C#2TV29Gvr!_ zl+W<2X+c)7E3`FYNwyWQ{;9YM9N;ZSA%Nn#zFw~t@7bPRoyo3n$6q~G8OF*_9kvUY z;AQ$ul(qztIrHu>#`bN&3OD=^*x@_BfSnXJv5p0ERv-g7NPj0ln#J2PweRE;9M7{% z+m=@EnAKUfT=*pyyUC?6+^>V+F7Sk_H);X& z6hn+%fi=T$7F%n03z*_1!+O5)J_oXnF&)Et3oka<`#PjsB~)2f?&k?iV2>X|kzvaA zcofei=8atonBXM@T~A*)A!t7{JoHsq4`*daFMz0SB7efvpK~5?Ev*rh%-oWD9$5lr zcnLu-r~J}S3=e%3E=x;?ybV~DBv%*KUz2f;(=rU0000cThfNq57`RJ<{DK+&!$ECX?bVHKN-O|oI1~;5 diff --git a/graphics/pokemon/moltres/galarian/overworld_normal.pal b/graphics/pokemon/moltres/galarian/overworld_normal.pal index ef0bee86ea..ca9a549d10 100644 --- a/graphics/pokemon/moltres/galarian/overworld_normal.pal +++ b/graphics/pokemon/moltres/galarian/overworld_normal.pal @@ -12,8 +12,8 @@ JASC-PAL 249 181 225 120 200 248 160 224 248 -11 11 11 -12 12 12 -13 13 13 -14 14 14 -15 15 15 +0 0 0 +0 0 0 +0 0 0 +0 0 0 +0 0 0 diff --git a/graphics/pokemon/moltres/galarian/overworld_shiny.pal b/graphics/pokemon/moltres/galarian/overworld_shiny.pal index ef0bee86ea..8330f2687a 100644 --- a/graphics/pokemon/moltres/galarian/overworld_shiny.pal +++ b/graphics/pokemon/moltres/galarian/overworld_shiny.pal @@ -5,15 +5,15 @@ JASC-PAL 0 0 0 0 0 0 61 0 25 -24 24 24 -56 56 56 -173 28 86 -235 88 147 -249 181 225 +229 185 8 +248 208 48 +240 80 32 +240 128 48 +248 232 104 120 200 248 160 224 248 -11 11 11 -12 12 12 -13 13 13 -14 14 14 -15 15 15 +255 255 255 +255 255 255 +255 255 255 +255 255 255 +255 255 255 diff --git a/graphics/pokemon/morelull/overworld.png b/graphics/pokemon/morelull/overworld.png index 6d164768a6902a4a5f6556909a928b46e24af0b3..5f85740da2f6f8a4c662c096d45936cfd91e617d 100644 GIT binary patch delta 403 zcmV;E0c`$@3AqE1Fn<6rP)t-s|NsBySw(czAdqARqt$0LZwg*_Z^90003uNkl7`22)G_|8EPnxhb@v z887T)dU*)!nluEL%jI&pTrSr~chX93)%`{iCS1+!0WCK07k@5PT+Ph}FmXY`RooT; z0AR`~aIvApHHh5D45;!*p?1E8$jkCjp z=R9hl@M8vuH!N_<726hLgFG~;@=D!Xj9cT%-+8a$aK^9K7aWnAZ}i}}zsdpMJmM+N zYEb7Fpz|$K!hiHLD^WNed~#glT!F$T@CA=u^LOxa&bM=(Q^6zBBQ((X+5iGRdBNwr zfy%kRfpb8j0h#jz(mLJ)5(Cf-1pb>A@YUQJP{6X6U0Q%}kp>vgcY{&`Eg&i=@`6Q6 x*mj-_N)FY4`U>Z%`FuAh-;fy4di@^I3y6Ul{S~)TFAM+x002ovPDHLkV1hudzdQf{ literal 1163 zcmeAS@N?(olHy`uVBq!ia0vp^2Y^_CgBeH`yR~lzQjEnx?oJHr&dI!FU|?nl@CkAK z|NsB9$1lHLx_Rf)i%&<+9XWDj|Bddd}!hQ;K(D60G{ zRVy{!IU))QeqHZ2om~C3YQq%1^5S}j$>Kk_!ez>fzcWoaG9g3kJ8MJ76fdu(U!)^q z*mMpFZ~Q9toyCFS0I$oH)%k@tKRigXJ)e58U2wvoomnnfhvI6xyB|I%3~+dwdmu>Q zs&tsebFWhN6%xti4&BZ@5scro&VAlfsWRu^^RJBRj~?9)D}Qy}-13q<`>rFdTkChv z|0HXXSl6q=w!E3YFM5uw^h)MgGP91|fABUY@3~d_Vg3(`MK=7n!@#sR^}zQX4JViG zYxZ_{#bh;|Z%ySM)+KBSx&lwk*FM<2(|m!$&zbXYG4yP{cA#>f?h4TjOi9ky*w2I= y+V^?Sf^7>W1Ee2XmCn!Ser3Ld%_ROg^DoxrqEeOe(m$qvQiP|gpUXO@geCw3Ajt9n diff --git a/graphics/pokemon/morelull/overworld_normal.pal b/graphics/pokemon/morelull/overworld_normal.pal index 52cbf93f93..6efa8c740b 100644 --- a/graphics/pokemon/morelull/overworld_normal.pal +++ b/graphics/pokemon/morelull/overworld_normal.pal @@ -6,11 +6,11 @@ JASC-PAL 245 210 217 220 210 232 242 196 206 -196 196 196 +184 131 178 191 196 122 158 158 158 171 152 193 -184 131 178 +196 196 255 146 150 89 224 124 140 120 120 120 diff --git a/graphics/pokemon/morelull/overworld_shiny.pal b/graphics/pokemon/morelull/overworld_shiny.pal index 87d1e9509a..7f3068c455 100644 --- a/graphics/pokemon/morelull/overworld_shiny.pal +++ b/graphics/pokemon/morelull/overworld_shiny.pal @@ -2,11 +2,11 @@ JASC-PAL 0100 16 255 255 255 -176 112 64 -240 144 120 +230 227 233 +186 57 24 220 210 232 -208 120 24 -196 196 196 +209 134 54 +240 192 72 191 196 122 158 158 158 112 40 24 diff --git a/graphics/pokemon/mr_mime/galarian/overworld.png b/graphics/pokemon/mr_mime/galarian/overworld.png index 122bda4a1306a594dc5d24e86ba01c9727dcb55e..fd95946076a2b9c7833996e53e5c485dd14ba1b4 100644 GIT binary patch delta 566 zcmV-60?GZJ1)c?vNFRrGb^rhX_Tu6H|Nl8TIi%k5zP`S3s=jDwXi*?IvXN&me?;My z_kY~kK$C1W9M&I`CgrG#I)4W+H>X>cM~@yodi3c3iR=~)vPP+CYof7@QQQ4LID$g$y`VRv_i^yO$He1IXJ>wsynJAGP2 zyZ2&}hsgn!lit$ntPeD_3DR!u4xlP_t0%Si)jEOzYo%GM>=O(Pa>B|A*&8&bA%rr3 zSXg{zfD)U+CqMOrV?#-iWpPS|<^)DGcpm~qmTSh2<%)5npus78<0ZK_e~t|`MaN!t z*Uo=TL-O8J%*R2hmys5$JQd0wUu_*oXr z0j>n?`T?3xbkOq4-6MkeTP`p--+ZnE0w%;C{k^^bAq*lf{RW=>3;+NC07*qoM6N<$ Eg3l!nq5uE@ delta 566 zcmV-60?GZJ1)c?vNFT47nE(I)_Tu6H|Nl8TIi%k5zP`S3s=jDwXbn!6?2%_Lf1q&d z`#s6Z5*bt8_x(pk8d=1U zW5WuWQFhMNA-t;EB*Kdra%^~=s({fRj3{Y$b%;aNx|hFc2}6zzm;B);doZHpNIuR{ zA3(p>&=Q6m8?FS;=~)w)P})d8fBtCl)B=kba%_0baI`yfdOG?DA7IF_p>L19JAkU_ z2tiEpFgd_-(tCP?^?`;?>9BSOP!+p9kXpiS9YKJ#((Fz435EtaVReP<4Vu#!V;w*& zEWSEGjV<9Pf9eOvhMFSF;?xYy3Cw5=Ax26p*Nh#@72`xvgG=~@*W}(fe>Suf9S7N6 zZ{|OzF^3Q+mB)irk4H%)ksOyWXUkG1%Kn&;Mi~_ zNr6+cXE39J^eL-SQqk3V##ZnP4~pM7Hk^tvb17_>sW_#r%s9!=jjPZELyiq1y)1|P z@-S1Z(2uD8Qqmh%>YL7*f503=jtwHYEZL9VQw@%&?(j}cdoVlzLyiqwy)9CsMlV8z zdDwQ7D%TgrI-OVa^8Kng?4Wx>p1_U6_n?`T?3RbkOrF!y|(ETP`rT-h8bC0w%<7{k^^bBjF+&e~UZ=3;+NC07*qoM6N<$ Eg8iWr5C8xG diff --git a/graphics/pokemon/mr_mime/galarian/overworld_normal.pal b/graphics/pokemon/mr_mime/galarian/overworld_normal.pal index 0166ba80d5..9783b2507f 100644 --- a/graphics/pokemon/mr_mime/galarian/overworld_normal.pal +++ b/graphics/pokemon/mr_mime/galarian/overworld_normal.pal @@ -7,7 +7,7 @@ JASC-PAL 89 106 134 59 49 48 53 69 94 -175 154 153 +135 118 118 0 0 0 246 226 225 255 255 255 @@ -16,4 +16,4 @@ JASC-PAL 190 190 190 113 170 190 104 104 104 -15 15 15 +255 255 255 diff --git a/graphics/pokemon/mr_mime/galarian/overworld_shiny.pal b/graphics/pokemon/mr_mime/galarian/overworld_shiny.pal index 0166ba80d5..b2ee5a4fd1 100644 --- a/graphics/pokemon/mr_mime/galarian/overworld_shiny.pal +++ b/graphics/pokemon/mr_mime/galarian/overworld_shiny.pal @@ -1,19 +1,19 @@ JASC-PAL 0100 16 -197 44 44 +128 63 60 0 0 0 15 20 29 -89 106 134 +112 96 136 59 49 48 -53 69 94 -175 154 153 +96 72 104 +114 93 92 0 0 0 246 226 225 255 255 255 57 57 57 -164 222 242 +144 176 208 190 190 190 -113 170 190 +112 136 184 104 104 104 -15 15 15 +255 255 255 diff --git a/graphics/pokemon/pincurchin/shiny.pal b/graphics/pokemon/pincurchin/shiny.pal index dd03c31a28..a2b0a156a7 100644 --- a/graphics/pokemon/pincurchin/shiny.pal +++ b/graphics/pokemon/pincurchin/shiny.pal @@ -13,7 +13,7 @@ JASC-PAL 248 136 40 248 240 40 192 88 16 -0 0 0 -0 0 0 +173 255 239 +20 255 210 0 0 0 0 0 0 diff --git a/graphics/pokemon/ponyta/galarian/overworld.png b/graphics/pokemon/ponyta/galarian/overworld.png index ac613865766b406f7a743c17bad7381f62e11239..683780312b2bae83528b1b921dae2d0c72fa92f7 100644 GIT binary patch delta 696 zcmV;p0!RJR1>yyeHh-AVpnFJrgLzsYARye+x5aJ6L2+u;nbp0zy&R63?&|*l003&< z-g9w5=DOzg^4^Wcd71zK0$@o*K~z|U?U&uI+#n2uVqB6LKNUtY^`!}4I0P!icEG^4fgeoF4I%fq8VCVA z7*{kEpF@GeoHFt8(F#{E7$ z<9rlp>-uWFT=N%426(xa0gkEXSPG@j-OM7E^P#fG_k`j&d^7-QrUiUX7#t^`bYtxCXM$;<7nyW{ z!$!v1$mM9|gA9~*WN`$>D0s@VZGiE$z|Qz1!8Wkq2BJuz!I*@xe;T?+gADYz#S;jF z3p*dQ+9TN?j|BH05mrzi=0|6*B9m%=n+RO29x;E8=TFA}UR*Qn43nNBZn3{I{>{zA e4!$Ad--%y-L?(TD`=;Lj0000srHR@s5a0i8`(v`FXLbcU+1|7h zX7=hs`BA`ZO1Is1+ikbqcH94AL{w5Km-&Z=oeM%-=85XQOMekp;EaE2*jo0zx(a8U z_F8MH*>jljkBxFQ+g$-uZW4Wc6OId}5*I+oPlY>03L>slshU95OB@$mkziB+Ay2B5 zGsD9ZFykBa<(z4|#&J9}DS(hCZIt=(GgET}%y<#WSwzYu&P-@>&Yr>Qzv6F!Daelhm&VRUHWlO-GJR0+4XTYz#D-`Y} zG7fHJ^464RXb$-wClsTeaYa9t73yUZVFkUaOFV2jK_0&#`$Q{*7b?J zmHCsyW615Ax{s$&``*oMVm%)!e|>k5Aj79X8TZkXI}TQ7tpx&Soc4Y){`%9wPhkBf zaFoE4uYbJ}UNJ5PCE|}sj8SlWPBCqkQ0j*3PVf zz?>CNdG!-u=;L7h;ov8bP=RPtXmB=RoS&JU(ZB;UE=2;7VB+9|)@CHf>){aoBSHkr z!~N*&UF1@mZxeyZoAKv*{$%~{;O6Ojxbzfpi6Z@#^pHSD`Z1H1lbIafMnBi=Z z)SuGvoDIZkAl*3m)JhOvH46bPN>|UofMBxk23_oPR@F*2{_!FXMzjjpo_2He0j~}Z zJb``Erv)8?HywQXca1)wt|#1gYp1-+<-5Qc4#rXD%||-vqr-3bLz9pKF##Ww!U8mZ z-JbJ+yR(vx9EguN3_&AOgzB9L^MwB4`CI~g&)y7}JKydGeEoafn8k`H@x0CsVQfP? zZ^Y9cvhXXsEc^(URyDZVdi%3YEohO(06Q6CBq#}s`x-fl1o5E*i11u8c*VqZcR6aE zBrm`~wHBw-fsV=S@iVVulhBaLk->g@NnL{^B>XvIlrpoe;I!Pj_Wlv;>vKE00000NkvXXu0mjf Djb`~;Ex>6tkZfg?zZ-~*{tb7J zK$#-!^SvzX6R_?dtc!&Yfe0AJ%Xka0NdgCt*mr@zw2fR8w z@C5crpB8io-gNNk-!=M#x}I>~t)22Nmq&p!9E_vPn~!wTM~4siQOBvo{0g&bPY(U;kb=X0aklJg>7u7~9a! z8}YPFL{AaX(&adkDU&dcsoi!;7<#7}M0000J2eAf_7#0Wv0001UMu)cm0004VQb$4nuFf3kks%|0=y$LH0000000000 z000000000000jwHwEzGDuSrBfR9J=WSJ`62APkEk3GM&?@O%K_uyM0>Z((cNA`p_z z)opvqQ=W3Cz#s8{FOC2R>joaaV6 zV#F5@brb)9AG>3JUwr8O9fPhwtPTW68X-=BEO@Z+Pxzx0qrYR&7bsvEL&cFnNNyWM zO)>YSqU&22bOn|M!GIaBO|0&=L26LttNd$&D}lf>Z!`#8KjCr4KQ$P-{+}C!vb;ut zWxZ4O_DSGg^XT9`e`B!QPXq_Z|JoF^4D#~Q1k|O1d*1Cd z9D=z9$=zrG1E>n9Axuf|S4LlgWA)bIL;sAs{Kdd4o~RuS1l0f=1j1p!X#`E+r9bi< z353ue!5F6~3S0crci|WRU|^WZqL8Q1tiKr4Gn6OsD6mWc)F&Z+^BDY20jBB>uiJ2k zxBQ*KQN){nw|R<&Vqj$uOo2sTOeg297W{T{J-B$oKN%bxV09n^QM)W;g9#hV1`_QG zg8-t+!;?N*i5E=kj}?N8d;Fb)Vqn%^3{qYLjQSI&vlT#TPdoy`=Lx(Lvj+M=iq12! zfi>>&H$r%?C54s)=`V&ygo?RjkA9)G7WB+o#aGQ3tA0w>!Q*S}CVq>b z4=G~?iGvi!H3F4?5Wpjh102V(_`#&%_xST^Yw;h`F)VAp-U&JZC_&tM9dCKkb1M<-n>5YgX`2YX_07*qoM6N<$ Ef+}ia^Z)<= delta 922 zcmV;L17-ZN2EzxC7zqRe0002CwraMKE+c;c0000000000000000000000000@G#7* z0009{Nkl!NaG15(pS24YkP@_j2Y510D1A;4>*6aj65xSz(wr!s0qWuL6}G-Ftt-jCLc} zIqw1v8fS%p=dU2!ZS3xW=_0JN8OZbf_Uo@kR|z#*^EEwJ z^ST(A?jP1sxGv(gr$^B-R81F&_Gc-3&?AFSc?tR<(l%CT%Q5VO)p@C`);#Ednm2s| zZ@mRbxzpZ$#DpnPbiXi+7%YD#@QPOZQ-bQR!xv_>62fZ3+klZd%mOk7fskH^@JaD5 zTAg)@6T=O;m0LTWzKdArc9lyps)@xh6ytg!q5(drVs%9B)UM ztV+L)`Vev(ph*p54CuEB7aR0WkV#`Dp(=>?V|tX=L%NG1AS7mg!l*Bm#H4YVNQh1Y zz4f&A?NEVE6GrsC5#E$vZ93LWU@`%F4(87~M*wr*PcOUBWoKummuFr+Y<0ba3SG|E zIJAT}VeSu8Mo-P?3uk|jbqsa)+kx@}6uO-6{^h@p{Dju_t0q9G@|M70Ge9U-i7X2; z>Hp6i=u#dKyq9_YAVJHA`aWM4Xj{X&kfFzWx|9cndvfS2Aj$^2t!FI=R6arbxB!#& w7!R2mY9h)AZ}{0!{?&9XKl+(-J0_2Rae)b&nk+CZ00000Nks-uM6N<$f=6eejsO4v diff --git a/graphics/pokemon/regieleki/overworld_normal.pal b/graphics/pokemon/regieleki/overworld_normal.pal index 1c69e174c2..f6bab934e8 100644 --- a/graphics/pokemon/regieleki/overworld_normal.pal +++ b/graphics/pokemon/regieleki/overworld_normal.pal @@ -10,7 +10,7 @@ JASC-PAL 208 168 8 248 248 192 248 152 192 -0 0 0 +232 119 176 0 0 0 0 0 0 0 0 0 diff --git a/graphics/pokemon/regieleki/overworld_shiny.pal b/graphics/pokemon/regieleki/overworld_shiny.pal index 52fc33ef18..ae43ceece9 100644 --- a/graphics/pokemon/regieleki/overworld_shiny.pal +++ b/graphics/pokemon/regieleki/overworld_shiny.pal @@ -9,8 +9,8 @@ JASC-PAL 172 164 205 172 172 106 238 246 172 -230 238 49 -0 0 0 +248 152 192 +232 119 176 0 0 0 0 0 0 0 0 0 diff --git a/graphics/pokemon/runerigus/shiny.pal b/graphics/pokemon/runerigus/shiny.pal index 6166d5bfd6..8fd4e72f06 100644 --- a/graphics/pokemon/runerigus/shiny.pal +++ b/graphics/pokemon/runerigus/shiny.pal @@ -10,7 +10,7 @@ JASC-PAL 216 208 208 184 88 208 144 40 168 -168 56 208 +56 208 174 0 0 0 0 0 0 0 0 0 diff --git a/graphics/pokemon/samurott/hisuian/overworld.png b/graphics/pokemon/samurott/hisuian/overworld.png index 6dd47d57773cb2526046401c53de0d4d3040207b..7d4db0b87d2c2c0d20004de530cfd9318e49a060 100644 GIT binary patch delta 1045 zcmV+w1nT>g3d{(Q7#0Wv0001UMu)cm0004VQb$4nuFf3kks%iY4i+$xJ05?oxxUK) z00YWNL_t(oh3%N(mf|1`g(Wluu;Tl_?cPwU6qM-BnVtEuoKvmd5Wa*!(bMUF`>4@R z16a)fr2NYxumCCl@(2t-m49^r79jn62^ke)0IL4Y5m<{bdiO8K5@jRnIvK zF4etz8xT9grjtOY7hxKJTXb2V%d;Yx0d6{G2OvmL%o(%P=q4Zr#@;{@kR9OBt9h6K z)^V^zbI^@)+-hckRd-&p+-3-O-Zi=jNJtA*n4v{Leh!Ex5i%Aj4B~$}^UP}x~Ub^@UKq84@>#VO&OJoM9 zOBC^?kdvg0jYcCpF4H-n8c>WoV5Ckq0aFOtQEo%@3AO-H;aK59kg-fM?&LI7`3z7? zY=MDlxG-N`i5Y-eWzK&k=sE@>>d3b2gHncd_$EFZeR`bLz?G+ zL?xbm!sY;jc#n|zJwP2#_Z5Gx^4aU2;~Pc`5FgbeZ{bB&@4iid1xV*oXi4NZJ#HmV zkwxAC)X~TJ(Z&9s;DG@evoU;|>8>fSOOIrRoYc zsha_^z3VJ>fE}=e*pDBjuv;(wvN|p()&95=N&_h4X(p(Itk&1U{loSFc;`C+?tZj$ z$f(s^xIOjZ(RBcf9RZ&7aJH`N6&IYuE&xhObqD0W#wdTGKTJ>+rQVE1b_Z0x8{w04 zGg1)?UosMYI8I^lwSdweCRBHq^>V@GV9*`7YE~OS=`ySd z(DL;e9+3yf(C>gWX86sY^2(R?+x_l^pXvV}U;OvxulpbK_|t!a{gd_wn3Xn~TdaZe P00000NkvXXu0mjfiEZHp delta 1247 zcmV<51R(p&2$Twt7zqRe0002CwraMKE*Aq37%`DZ9)Af0l`sGR1fNMnK~#9!&6a;m z8)X>BpL?&AGJaj@0Ku(XPkzT`U8m?!Mj_eM#TX14jDNUhGei^PrXiVfGv1QIs4iJWA^sXJ!AA_FnU9T&59Bhlk`2Nw}bI)_1 z=icx0+<*JN0RPj0?lq9SSD>J@%ToEZeUnmJb>q-lPgMy-PUjj+euh!n<@CR-fl6~? zIHJ&;Sii{KpG0b@3h7m~EN=OLzP|*8tH-N=C^G9^sd@*J#YpBZMMit~z=}W%6ut(A zS80OQ00LR8LkkGe4ntF* zhA3`WB9R)H#5zfEPJ$*7zy#vUSezuK0R;FXv<0z%GOdXODj+=cRX@PRQ?w=!U?dg5 zNPofYbXEh1N86|!iy7b(36ww!JSTvU7ov4?RaHO`h8!#jti!DZ#8cY$XH*O=iYHJ5 z19aq>>WR^9yMW;}fkvhiJS==+p)`PaypjACMA=QmemTK1Abg$uuB)ug=+XuxbN7L2amjyV&p?Oz6{nGf9Nxu%S$Gx8zR8qORMyAhAR=`2KGZJ zFKqMXg8PBL^iolXuI=Z)A*~QN#iN%W{RN0yXVZeaQf5xK^fY*%AeRA!R0B(`zkd}f z2#pzMc?}?hr#In_$)CI!3`q$Tz#b5U+dOfzdz{=j_Mk0|Tn^;IwyW#vZG#h=uTEmo#^fI>9MAgC>Tnlk*#^){WcP%1P+H>!Zbw!6Z@N0& z&E8nme5JJB0mqBYa+{*M90x#S#D9A-W?#1unE^&P4~@G1(;}c?j5QMr0D60Wg}C8_ z>$g90nX9bc@U6Vm6`1DRo_52`#%nQP{d;%@Td$Ze$h%E>(_Gij73BBvzP0kx8L;30 zvZl4>2=;T+!ThO)>sEMSXGAK!UmrMjR3Dv^rXHTOe{cjGR6cb#cB%olHAJF*+Tnl{nC3$7Q zAPGn$$$pg6@vCR5w{y4bmw+`t0ensl%c_CLJ^onWyQ8t@1!D|27ys5Nfy$sV2Z&l3 z;E;e_S#cnBIm&v-A$=gRz<;ym!hPI^&*EjmI&EH@6`#jNMm39WiV%`OUM)qthyt#x zVo+j?-=@<4c10Jp?rx9Cf>~r7cMy#JipC<&?O~+UQ!T&MO$iP6YRyk zi~H$!+9Pj*$Mqr*8b6HN7pjBdFGu2jX=H~dcjWfnS@KcUnNc`VB}5ysy{N31QP_$7 zhe@JysiM->75vhv;PrOw5Pz1&s18%iT@E0t`5CDJ5DowN_y?ir6SM__iYx#C002ov JPDHLkV1n)APv-yt diff --git a/graphics/pokemon/samurott/hisuian/overworld_normal.pal b/graphics/pokemon/samurott/hisuian/overworld_normal.pal index e6be3b5f56..15854747e9 100644 --- a/graphics/pokemon/samurott/hisuian/overworld_normal.pal +++ b/graphics/pokemon/samurott/hisuian/overworld_normal.pal @@ -6,7 +6,7 @@ JASC-PAL 0 0 0 238 238 255 189 189 197 -16 24 49 +14 22 48 189 49 49 32 24 32 41 49 74 diff --git a/graphics/pokemon/samurott/hisuian/overworld_shiny.pal b/graphics/pokemon/samurott/hisuian/overworld_shiny.pal index 827453552a..494b52f0aa 100644 --- a/graphics/pokemon/samurott/hisuian/overworld_shiny.pal +++ b/graphics/pokemon/samurott/hisuian/overworld_shiny.pal @@ -8,7 +8,7 @@ JASC-PAL 189 189 197 16 24 49 180 164 156 -197 189 197 +84 80 84 222 213 222 139 115 106 238 238 246 diff --git a/graphics/pokemon/sawsbuck/summer/overworld_shiny.pal b/graphics/pokemon/sawsbuck/summer/overworld_shiny.pal index 34f7d0f0b4..4d2a5df53c 100644 --- a/graphics/pokemon/sawsbuck/summer/overworld_shiny.pal +++ b/graphics/pokemon/sawsbuck/summer/overworld_shiny.pal @@ -5,13 +5,13 @@ JASC-PAL 0 0 0 8 136 64 27 81 44 -40 19 12 -199 170 85 -233 219 172 -176 104 32 +238 222 164 +74 16 8 +84 35 16 +178 114 49 128 64 16 -207 124 25 -141 98 51 +183 167 84 +255 255 255 0 0 0 0 0 0 0 0 0 diff --git a/graphics/pokemon/slowking/galarian/overworld.png b/graphics/pokemon/slowking/galarian/overworld.png index 5babfe384b6e99ffc44d02d1f10ced3fde735854..4ff3b7f4b70518426ee559b0e61a19810be7adb6 100644 GIT binary patch delta 690 zcmV;j0!{ts1?2^hKYzCCi00<@oSk!8P;t4lBEoCVqmI9xi+T#DIamkVZ$={b%9gE3_*KZiqs{vxuu!(+Uhgp;H{$q0A>Z4F0)93>fw| z5}0$s?Lv>b3V%tKqk%^__c+5*;L8OEV8SSC4~@sAL@1A_> z-w|?nza*%Pyfh_i33yx%5J8qg8wO^)tt*K|u}ACLo`2-ymH<)F3+(ZJ05b&gX&9LC zbrpvr`tQ$ikzjXj@_FpP&u<6tw(-n>$suSBT|(fWcJ$|Qkr0OvxOV07*qoM6N<$f|cf2;{X5v delta 693 zcmV;m0!sbm1?UBkKYzu_)#m2*oSk!8P;=oFbsroa_Ec<_WQqWcLjHC2U!H#Yx?6f8Is{!qm?ad zG7Rr{$2;EfKSfI4%2UW=x(aFyRIlcP;fs`^HIh1-Z?gGp-MMU5#!8#=VI$>0xN+VmP{T;Z^I|43-C z)Wj_yq)Z@a?tdcG;fNb_S9rC!!m-64un3Q$Wj|_Sx@F*uppJ85_x-Q%_P8Tgcw&>N zT9V<6(} zQr*J-KF2A+*K6a`8#FO}CaAYtjSO@-1Q;!i_8JF{)5S5TMC-cE&AX>D{R;-x_XyKD z2@W_dZs+4n*(1tJYBRR)_i>VpZ zJdXGKIA-+=IN}StjQzD-;jlQ~r%a#Oo0T!O3`&PRe~${tdp)iTKAxBU`i=YRp%^nf zW-3n8rw7D5`v&mdqPH45vmm1N#zngM=XnY0qb@Zxa@YP(-AVA9M2G(RA*%nm{tx&& b{(bxa!!kBqO<;Gz00000NkvXXu0mjf4UAbw diff --git a/graphics/pokemon/slowking/galarian/overworld_normal.pal b/graphics/pokemon/slowking/galarian/overworld_normal.pal index aa19348aaa..7b64228b1d 100644 --- a/graphics/pokemon/slowking/galarian/overworld_normal.pal +++ b/graphics/pokemon/slowking/galarian/overworld_normal.pal @@ -4,16 +4,16 @@ JASC-PAL 41 194 156 49 52 74 16 129 8 -197 202 213 +182 235 136 230 230 246 156 157 115 90 80 115 189 210 139 -148 109 115 +49 52 74 98 36 74 0 0 0 131 121 139 -164 165 180 +82 64 128 131 76 106 189 174 189 131 113 180 diff --git a/graphics/pokemon/slowking/galarian/overworld_shiny.pal b/graphics/pokemon/slowking/galarian/overworld_shiny.pal index aa19348aaa..9a2bdbc76e 100644 --- a/graphics/pokemon/slowking/galarian/overworld_shiny.pal +++ b/graphics/pokemon/slowking/galarian/overworld_shiny.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 41 194 156 -49 52 74 -16 129 8 -197 202 213 +60 52 140 +166 48 112 +215 117 170 230 230 246 156 157 115 -90 80 115 +80 91 138 189 210 139 -148 109 115 -98 36 74 +49 52 74 +128 39 93 0 0 0 131 121 139 -164 165 180 -131 76 106 +82 64 128 +154 70 116 189 174 189 -131 113 180 +112 140 196 diff --git a/graphics/pokemon/slowpoke/galarian/overworld.png b/graphics/pokemon/slowpoke/galarian/overworld.png index 277a1f3a87ffd23d53bf5128ad5ad2d58f02c70d..38352ce27eaf0768de8915ee6db295d718f7735d 100644 GIT binary patch delta 541 zcmV+&0^H?@0 z)=wD@{K{4yZ*f@14EVtDHZL1ccrNjax6lljoc%e+HC7UY<-jj^jY;geT3|BBd*NMP zgdyjDOsnYGxJ9}g#US!2t4&fGsPg5^*OVePCjZRZF1piyOpEUZF~=C`*-D_#adYVL zha6*yR2G1vLA=jJ;MbfJE9X^hkpowHh%3yc4>Rafj0b*MfE1L<5@7dt&e7sEKEzZM zL2Utxv&3Apg_@il=F-|++#dI>ix{afG0|CQB|dA_z|I#nz#_ktdI@ZN`CdM<7>STa zN%DHcmG43H9z}lhQ!^;rR<8EAK#r{$ED2WL7!l;k!1h<;HHccj%i_CVD%&(y7SxTh f;r6Od{C}!1dlMOiWBjv600000NkvXXu0mjfw9^Ps delta 545 zcmV++0^a@p1cC*SHUofwfRQ;QBi$d8qyPW{2}wjjR9J=WmH}?VAPhxgr-lT$|9NK{ z5+#{|k$@S00QiVMEQI;>YB*F*f9L0?Lg$E{W5&0t>xJw8p{%-VeOS993oG@Y@En@=sdgy9+~6pGC#xIC2P1(FXNP->*#&NL0BJ6+ zF)zp#&;3%kULzJ~gT(cjMO-5?66kO>=+s|5fhre!Iv=@7QNN=5TnsMcN{>3zA0GH( zF2GV@`;_s(uWXg^R)=NGP!61K^Sl9vmlD5Z3(G*4i$4IVv5_Dy2Y$h8h-wc?f!Uz! zMR$3B7WtGCui|Ir7HM))gCwVHHc4)v!k05&V+`Dw@-u6@=uZDJdwe%YDTKh!S^{lO zn?pxG

7yvLGG}(tWN%x26kGsEfjy+!D zV~AM+%@*i!k(#TvP?d|rlv`Vh+v2Wv5fe9TCPhB0C}(XN*!f}xSoD`tD}jwK-^<4q z0~7YBNnVe*@I8p#qa<&6S_XC7!p$C6D6uVrIl;m!BSKOc-2Pg;1TpJ(S$y|PW1H&A jjG9q4Twm3Q|4;P=($g7@`2r4`00000NkvXXu0mjfH}(Q) diff --git a/graphics/pokemon/slowpoke/galarian/overworld_shiny.pal b/graphics/pokemon/slowpoke/galarian/overworld_shiny.pal index 39773f539f..ee20b05797 100644 --- a/graphics/pokemon/slowpoke/galarian/overworld_shiny.pal +++ b/graphics/pokemon/slowpoke/galarian/overworld_shiny.pal @@ -1,19 +1,19 @@ JASC-PAL 0100 16 -128 128 128 +152 208 160 66 63 0 -96 40 48 -173 166 8 -239 229 9 +80 72 0 +136 120 16 +171 144 18 0 0 0 -204 109 117 -240 152 160 +200 176 0 +248 216 0 160 168 176 104 80 16 208 168 96 240 216 144 232 232 248 -13 13 13 -14 14 14 -15 15 15 +255 255 255 +255 255 255 +255 255 255 diff --git a/graphics/pokemon/sneasel/hisuian/overworld.png b/graphics/pokemon/sneasel/hisuian/overworld.png index 7f4c335a9e8f96797384e9172ec08d38bbdc31e3..a830d0c0e8db9e6bb97665cb824e98a4b6ffd6b8 100644 GIT binary patch delta 616 zcmV-u0+;=(1@#1w7=H)@0001UMu)cm0004VQb$4nuFf3k0000mP)t-sn9!g~N@5TY z5JnS5VsoUVz1}%WQgK0%dyBOH|NlodVWfNB%`r;$v_a;J5Mdc%aPaC50005=NklzuU-9?SGx8XRzXSKKMAyqQA>3PW+*uz!ksWbaIfU_FR7z$5r^a=^$C%2qkAu z9aen59iu!9{!LkN4X_<%@Yo^)1(%0Ee~VOnSAW~8>nr{}Q*o{E_GSj(wrB+kE^-~R zV2_uabn0zY>>I4Ol^C_g8%BGy;vgRi=CAlp$m<&ASATPL2y`3-7(KKpZ-_7~ft9nj*UJIL9x4%c{)!Kw3Up{RAmylUrQGiVt)u(U6Lkeyc#%2Zyy#y;h3}P2sp(ulbBU-Nk5N)z+6GvPZ_tdSW z1@_;$ieWzn=_U^zs+xlp2jXrJ>dq?Hrdu5Jf&UBdXaY9;7Jj$B3Q)_;6dEa(3W1LCw~!dd+5m?yc867g=O(j zyL%8%EtW;JXq%{&RX2Z3GIWv|W_s+!eT0GEyd*P|nalw6qaXd~$I*qP@-3(8iY9#z z>qA2;^NkzOro#eR4#`qR#i&%s8(7C3HtF6FD{+~%+7O(3Nz$|f%Rk+Q(g_eadW|-< zB#*CijAG}!(SO2lH~4Unr!94-+>t_a_#n+Xj7O(-ZhX4h}dZ??lZ@tz3{UIv;2HIHXJ2N%rCd1SmMH?TIM zV&bFF6_^9JX7h|k5S#_Ln;HS@c&1FT0k)z0fNR`{7={80Vzon)Dft=w+Ni9I-3 zs;nud$bVsvZr(%C;u$wE5YC8FME&2ec&Qj~RIx|9Bm-Vz| zUA{%_zGcYL$BD%3{{{Upf~>O#2wlUTSJ9UKzZjg={{Vsr`XO>iT*?3d002ovPDHLk FV1h0cNJ{_! diff --git a/graphics/pokemon/sneasel/hisuian/overworld_normal.pal b/graphics/pokemon/sneasel/hisuian/overworld_normal.pal index e909571475..3a4e58b0eb 100644 --- a/graphics/pokemon/sneasel/hisuian/overworld_normal.pal +++ b/graphics/pokemon/sneasel/hisuian/overworld_normal.pal @@ -4,16 +4,16 @@ JASC-PAL 152 208 160 74 74 98 16 16 16 -32 24 32 +70 19 70 98 115 164 164 189 222 57 74 82 -74 49 90 +113 65 145 123 139 180 255 255 255 -90 98 106 +71 53 97 164 123 222 205 49 74 246 180 65 230 139 16 -131 148 172 +97 25 97 diff --git a/graphics/pokemon/sneasel/hisuian/overworld_shiny.pal b/graphics/pokemon/sneasel/hisuian/overworld_shiny.pal index e2b78ba441..580e24ee3e 100644 --- a/graphics/pokemon/sneasel/hisuian/overworld_shiny.pal +++ b/graphics/pokemon/sneasel/hisuian/overworld_shiny.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 152 208 160 -82 82 82 +48 48 48 16 16 16 -189 156 49 -98 115 123 +87 68 9 +47 66 69 131 148 156 57 74 82 -230 205 82 -115 131 131 +255 212 0 +79 110 110 255 255 255 -90 82 98 +50 39 61 90 82 98 230 205 82 -156 172 238 -156 172 238 -131 148 172 +135 149 204 +112 128 193 +204 170 0 diff --git a/graphics/pokemon/sneasler/overworld.png b/graphics/pokemon/sneasler/overworld.png index 29f5dc9d48c78cf9a1a38db6c753b7240ec4aa12..b81dedda541b2316facb35115c0682b065c5e970 100644 GIT binary patch delta 865 zcmV-n1D^b)2&V^-7#0Wv0001UMu)cm0004VQb$4nuFf3kks&{SB}qg(a-Z?L*{O6ODDY4XEDr3zs?EPRt`&s z2omWghaXz#Y1fc{@Y)ER@lu|1JVQ#y4LPhOeSsH=s4<}P^ouC_Tb*kSjQJIwM{p!{ z@C_cXe;h}YXcuAMsXPg^VLhYkpfSJn9cg{N)WLI3n}fbDD0Cao*pqH@bkxEvrYM~8 zGr|`XT8HiwI(W`$-J$Ob3imhwJz4`b?+v(1U)w?^Cg?nWhmY6hIp!|!1kN~Z`!~<< z_r9@#wh?MB7;rAPcq@>S0hONuF*h3;)Hy5NIc6MFOqk z(Y8>{%Y@W_Y9k4pP&FZE653{fy#PQPw{z*I#bt+3Qv7~2cHgqQv3A@7$ES?9%pPYk=Dt}Xz9&p{DB9-rrLrrw%O4} z676os`LVm1*{&6D3O>kYKl|PH-t3z3vx zGdi5+fAL{g4YIU>0SM(NKR9cKOJKhlJARA6QeF%9PdNbFSG%r3mT@vA2xXA~jMoET zzqH1VT!STy2Jb%F+>4>G+kJol3yb%c3BpzgixL?QD_H%U<=vn&CDTt?)%(052ASK5 z-1fG$hj9pt1ok-W$Y28Go|J=ZoZ^3nyzd@lh#doaVsPR}2#W;hkbw**3E&P&=K?rl zXlGsTAajQVJht<*6L=|$1n@0`@lFCAo`cK2mHY$u#yT@Q4Vm1zO%@4ZnE+oR7LRdb*r$Y_rpi+_`=h?Yc_%&Pi%K&32rL$}Zx$NwbJL}iIf6{1z!c);yg_XRk zVee}vO|yGaiXAKK8uJovT`Y|e)G?(ow102Pg@#NRY=TKW-DRk4ltpLLYAOY=9G#h6 zFHIocnM3>8S(-N`*9j@kV{ea5%$11LJ+sO40(?uic#g6uI_j;11i6{Z zRyU;Sq?lN=p_}A#qby*p43u?qf?S`@T1n||St!|4n-+R&#C`QF)RcdW^mP_Q$$0{l z>~=dw={%^ifV}4|q3;<1WgP(Q8L1}I%H58Gu&AhSGgy?IcM>5{Gv)hJ2S+9CxOj$H9OCFJ> zXKOG;TZ56@3iunHzo80&ceJCnDGmJwpdn}BI>5>OC^n?<85Bc9tpwb*7)lEy>`XA+ zvU&{nd`_)XucT>2c>?b6%1~s(C!XHpZ=F1OQgy2xkBQ delta 21 dcmZo?X=j-b!j*4rbo}`7XOrG5Z;V^X2moG=33&hj diff --git a/graphics/pokemon/stunfisk/galarian/overworld_normal.pal b/graphics/pokemon/stunfisk/galarian/overworld_normal.pal index 9070fb58ea..5d6a48cd76 100644 --- a/graphics/pokemon/stunfisk/galarian/overworld_normal.pal +++ b/graphics/pokemon/stunfisk/galarian/overworld_normal.pal @@ -11,9 +11,9 @@ JASC-PAL 255 255 255 0 0 0 119 108 95 -111 59 50 +168 20 20 199 199 199 -12 12 12 -13 13 13 -14 14 14 -15 15 15 +255 255 255 +255 255 255 +255 255 255 +255 255 255 diff --git a/graphics/pokemon/stunfisk/galarian/overworld_shiny.pal b/graphics/pokemon/stunfisk/galarian/overworld_shiny.pal index 9070fb58ea..7fe680b775 100644 --- a/graphics/pokemon/stunfisk/galarian/overworld_shiny.pal +++ b/graphics/pokemon/stunfisk/galarian/overworld_shiny.pal @@ -5,13 +5,13 @@ JASC-PAL 29 32 27 59 64 56 95 102 90 -142 172 96 -157 146 133 -205 246 140 +168 160 56 +160 128 112 +240 224 80 255 255 255 0 0 0 119 108 95 -111 59 50 +168 20 20 199 199 199 12 12 12 13 13 13 diff --git a/graphics/pokemon/weezing/galarian/overworld.png b/graphics/pokemon/weezing/galarian/overworld.png index 883a3637decdd256a36a0668c0d15aed30f5dcd0..869fd482d1af89003af74c8cd6e850de2530ff31 100644 GIT binary patch delta 1196 zcmV;d1XKHz3YH3xJOh-Gl#xFt1jV_6Q;}*Pe|SkmK~z|Ut(c3Fq#z7MMH?g9E&u~h;#4g)+dbn6;U)xxou+o1zu#};ar-Gfo;!}-Ie6Vh{l983uj{$arKov6&s7bK zr+G%>b+-L$w~E*EtlYK)w3`vo=O_A~@yjJqH%5w$4LCr3ys~lX*ASQjoTdNSjo=c{ zf5EqaMstpM2s9Lq_?;Ym%&<=2k*u29Q*|5W> z7H3@%;5ZIItEChu93yo;wsUBE_we=XoFLTnDy(%UfrF21$6=vqksMgdg%ggbO3 zUXss-fT>x)8Mg&oL@2Ucu7MH@i9^lrF2}ZkZzfndI#NzPQwUUfmjKr+;Hl(|WyCz_ zZzjQ%*W*YWDlVP9$bygpfGowr;kW{1r*IFDG8Ebcd<$%F9V%o2+!pMAgD&S5f4t_M z0|?R!N)8%e(5!$AFA35C8U>nsba)!-78qg~z?KD&^CU2aB7hD0JUKN9N(0mds&m=n zX{aO+H$5~lMF!hu{MS5tlmeh$@W9onNzf&*EKty?>T>mz1O^X)JBle`7;t=qUKb}c z1z-$X{N9FAEJk2n;>T77kk5Zwe*;l7Oc8s?O8A+F7`$IR)~5)JWql2JCLq)Wno6k0 zxydZkG*iHUUmLvT4zo*b@wZjhcfjocjRJke1J5!~GgipYNB_ee;~htji!^^**}em= zR)S2m{e=he?H8Wr7HznIPgE(wko;%Y0)Y`}S&f0k*EPR}%U zsXudm$8)3e4xgs7G97WY@rp1tn4W5(3^?x%nk8JHA8Z@Ax7^+OG})a1I$UhTJ?I8e zz6+i?Zw=_1zepjy8r*yCn9#&V-0K!OHiq|{WAq#tCKs0%9SJjo0jI+vE>jwU*ZBRG zdB<^!@Kl{hy#!ml?MGZTfA_FRfw~>40G>Iy-*Icf;CAon%$Xl{M;y0mtWI8nHoNp|YXZN0CMiy{C9^&)i63+v8 z=5E2F!mWjW@K;|P=to?QXp(i6;9ghW3Z6NxDe)cUR#)a|!11-Zf6<9bKA}qRh|7Hh z>nznbwaUp8cgZ)Vc%vyU?;8UiVE_DnANq&W6sikf#dH079@kw;6xLUc2aXVTW?GvV zBdwRIY!xq8DXJsSsL}J)>3HT@_v=Q5vKCsOl}e~~!xPct0Y?QPNE77NryBiIbF*n(Sy5{wx9Tri4^f6I&OmbqQ& zDC)$R)O@=5b)#~;NYV&)fRg75(}jVL8igXO_Tt%XOa8nb7$-KyE1`Cf>q?e-H(=Ji zqpOgqsi$c3Jw(f4|?(<5nCIe6V>{l9A9*Y#X|Ez0}zT-CsM z@*a&>Z~M1y6|d*nxa|q(HzQ!oPxSBc%VkkFMv9FMI6!^8vT^R$5tsw?(*GPra0wXT ze_KGOIY&H38VX1JE{;A*zMe6X77b7web3d=2X&+VDA2h|KL<#WQvaH_0=flk1#|;Q z5nDh3U+2kiDTm3N;$nVb{Ds`2EWk!qsTAm(^3|b(me&IM1#ATL1M~@7aM%(X4*1gJ ztSbQ=#{p>NYk|TsQWsK>7XtbPYy{W>e=Z`#=0Gij9RuLvTaSw_Px?0spwTDXp(F8< zeRc#a-2yfoiUO`86j`p+K#7ISq2+g%W7{Bf6RaE^DJP#f1ggACfa@0UQuEF-VjlH3 zlVHm0abyk+m(D?CLCgU_kz(O+TmiCExCh7?iv0q<1$MX&6^j6F3--UkkaLScfAh`( zMCk=J2MsW4RzQZA1nB^s0?j@KJP&mXjHwP_D*`Ba7MNlczy@QUotgyY0onr9xg7C4 zR2GPv9-5dUgKabZTV6cM0Z=b^;Of*Q=n_~LDCkrTxq8Y1V*tP%#gs5iI6gwJ-U-bC z7=s?ax1k)15m=V^vDE>T^Pks1f6@$7!~u#DeuPZP;6oIL(uL&;%#I`_l35_^6 znPr-03K;NfgSXsacB%PrTNQmL+z!ww&{sV2Eb}yDh5SMaKio0iarEe=h1<&Zop7}h zWUB37cqHG!^E9Wl)1k)g#^{m96htBBCtC$?I#0MHI9-UVtuC_(=WSZ1e>pil)7Yi{ z%=sP9jm|rKnkve4#@Qw)!qi}TnuRjqyft{pl|*nh4gB0@3~__6Ps|a^KxvA?>Wa9I512uE-yL~76ubehecebGz72l`z`a1 z;}#L9I*|qmwtCyoxNPpxe@lV79hv~1Il13)Yr)|55a`TV9(HFOw`#0TUYc4gp?+IF zb1IOq?}<`O$J8bP&zz##F)XC?1tHY+_snyUk*l0s5;C$TMmTe04gWdC~p4QK2kP>yuL5UOC2`Mj+Q8-sf6~qt(1nNZG-i@`sIz zOYci%0vc|*UpEpbfBtEPBfGsVI^1G`+GqruAr@P4t5AXwgP)5=k@0VNb=@+zD;-6h z7?YMS7r$;)ju%ND!46RKQenO@@KK{uWYu20xNXUw*8}6k#&{*v4su<|a_F&K*w|$B>BDw^KZY4jXW=oL%(4-ZCmFdfSH91(Sqp=dWX2d1IRb$3GSk zo6Iv2yt=Wx`*!$VIC{6T`@tl0j&(mv85jC9JP^6VtuSf5!#W3T)niQETw3$%mxr%V z-?6!V2d5No!fc?Q@2A}m!JDRLmukUeWP(68nhi8G)OwTx> z3p3|0J(}&X;eNzf%ZXeM>X!DhZs7D#t&U>cv7h@-BI`sw+4>U> z9tU>pcyQy!g@lX=6&*k&aPUj|gglVLS>O>_%)r2R7=#&*=dVZs3f}c}aSZV|{`S&o z-ev4N zhPeB!yTUqQ-B+!BjrD;Cwly;JFd2m~WGtv=%u!OFB`dPi!YL$$!`n=7PN9EJ&$Z6q z9a~wv78!m?;5*}Dc0svRw!`?>_NjBN3|5FH{8g0Mk=c;`W~cjSQ4YDswQQU@%Nwk? z)L7R@UpUO}&VD+9;k~y^erozG2ZpBsMX?OoUHdwlk|KYd|Mb#&i>S8#zxu-K46(^)D_M6d0baelF{r5}E*sK!)A` diff --git a/graphics/pokemon/yamask/galarian/overworld.png b/graphics/pokemon/yamask/galarian/overworld.png index 718654dd3829b1417b7c4934f1a10df0ebfb8a96..54276f9a041015ce66650cd9df234470c67a3a84 100644 GIT binary patch delta 36 scmX@ea*$<$t7MWvsjs_7Lqo&s*yuw$c6QX&Z?-Utw4ZQwW87m#02-zcNB{r; delta 36 scmX@ea*$<$t7N!#hOfIvLqo&s*yuw$c6QX&Z?-V|_jdQ1jd70|0U?_afB*mh diff --git a/graphics/pokemon/yamask/galarian/overworld_normal.pal b/graphics/pokemon/yamask/galarian/overworld_normal.pal index 0e81179680..af4005de75 100644 --- a/graphics/pokemon/yamask/galarian/overworld_normal.pal +++ b/graphics/pokemon/yamask/galarian/overworld_normal.pal @@ -6,14 +6,14 @@ JASC-PAL 24 24 24 56 56 56 159 83 188 -87 43 104 +98 48 117 77 71 72 128 128 128 235 93 91 194 184 185 136 126 127 179 56 54 -12 12 12 -13 13 13 -14 14 14 -15 15 15 +255 255 255 +255 255 255 +255 255 255 +255 255 255 diff --git a/graphics/pokemon/yamask/galarian/overworld_shiny.pal b/graphics/pokemon/yamask/galarian/overworld_shiny.pal index 0e81179680..7cc24b4ab8 100644 --- a/graphics/pokemon/yamask/galarian/overworld_shiny.pal +++ b/graphics/pokemon/yamask/galarian/overworld_shiny.pal @@ -3,17 +3,17 @@ JASC-PAL 16 140 78 78 0 0 0 -24 24 24 -56 56 56 -159 83 188 -87 43 104 +40 40 72 +72 72 128 +24 216 152 +24 128 88 77 71 72 128 128 128 -235 93 91 +209 105 192 194 184 185 136 126 127 -179 56 54 -12 12 12 -13 13 13 -14 14 14 -15 15 15 +173 55 152 +255 255 255 +255 255 255 +255 255 255 +255 255 255 diff --git a/graphics/pokemon/yamask/galarian/shiny.pal b/graphics/pokemon/yamask/galarian/shiny.pal index 7ab1ad8cb2..276ff7ab14 100644 --- a/graphics/pokemon/yamask/galarian/shiny.pal +++ b/graphics/pokemon/yamask/galarian/shiny.pal @@ -8,10 +8,10 @@ JASC-PAL 24 128 88 24 216 152 16 64 48 -200 64 72 +173 55 152 192 184 184 224 216 216 -208 96 104 +209 105 192 144 120 136 0 0 0 0 0 0 diff --git a/graphics/pokemon/zacian/crowned_sword/overworld.png b/graphics/pokemon/zacian/crowned_sword/overworld.png index b8069ecd51e5386ff36aa8be110d183f5db769dc..887fa22ebd2b4b800d2024da826cb226cd441b2d 100644 GIT binary patch delta 1128 zcmV-u1eg2B3C0PKZGS{bL_t(oh3%M)a@;Bmg>4Uifw3+F>GbPha z;!iP0;vnoU%fIn&{Fg?gh2kIZzdfRbK>Mt4#{c$+)>0(;fJQg3$S+PRpqVFH%Q=- ztFl;k237}w*AmaTTrOTFSQh5QEc%f^p=-p2UujjClPX*}4GR3sAuY@Pj(eWB63=*( zClkb|6T~PJ41W?h@jiitk|w%c^r}mjF=$mA1wZ| zTM=>LzT3;5?IF-|->V*ZbhsbK>IvzxRz=cRdDT}utH6l*ia@@VSWR}~{R;Tz^6GFO zF?{?Ak0m;4u0nEJVWjy^aKfuT>-C7VG2ovZnEqxm>whoYcP_`3+GwQ3z+%O@bD6x< z?cfrybGG;)+r*-8l@b%3Ei&V~K6ofvgAZe)IH*hD!n*{#gKSD6goN)Fjw3Rs7){{d zQjeWSv~ICPA|5t?8E*nh6^NTxfu-}@r}u%EcN8>c@C41s8JtN54W zVZIqZReu<#qs0OdHe2p2f+Ot0?R^vD4+15%2##91Kab!c1O4O=7+#ylAIAvJ`(rm)P##gxC!K?vyiskgMZ5s903G@My`}10#}?jsL;BS?|9J= z{U-b}2e>wxs%2v?ah&L zcguj&%edmqEAilwbHX9fuDC4*t@geGn!t%)60n*asX`H`S*%oA#GA`9IPIcg6<)4J zC4b5es8cq9laIJC1m(7UtjuW{H?^x>x8E;%6}gf2zZ3T3xzks1(pt5)uY{uz;b*2tM5ZC z6-lZsBgvwb`az)tS+jGGn(&0nXXKY-P(nAV?EcQ zOn$;ad3%hQ@MDN=QMKU?s?)WI0fXrGx@~aTrX?N+ZNo*zGlF(P1|RN$gZCD1cVUnP z=wB4h5yd^cRd3;*g}&?bqAYG2Mff uCxOjxALV_XQThm*W>~6HSzey=)r*000073CIbMZGT2dL_t(oh3%M$a^xTkL~VylFc$y+x7!l<1P@6zRl8fYq%sGO zn3iaSooV{t{a!OiX7uNog0{mov0wO5{1-VA-603Nw2 zi)CkEbujRn;t`kb>}7&!VouDW9|2^#j=1nEEehA93TIB81V3{~TV;R8EzVntN4(0D z31ZX$$7Eef(wJMT6%ZtA3Sp`PqR|N7c#cHw>Z&$!qmluco zi00#Gc+AmJbrpis3?s}VzyUA%tpAV`#>RkOOz`1vCV#X3!hPd%^prv)B?cDD&Yjcb zC2u>I0UKwF535Zq`esQn(b*y+zUhO9qBW7Cu~8h<1aRR^0Nz11r4T~GyM^P3%xR1U zuye`B#v@9%SRxU33&4n1fw>68#f!k)cIqR z?r=14c{}(nFqje|QWTvFZ~ zDR;LBIK7O^&b$(LZaD`W677u3qS0*cE1&_K_$2_V!I3Hyff~h3xsEuvEQ8Z38fM}7 zYJXIs^<|9{zul|sCpaWBEy$FTXQcTkzGj_5FmKGto4%N9*>f6&rhWZWZYC1mjK9@u$n@nd=g zS%CII;XER{ho|Z#Tr@3R8*YPcgSU(8-cob*O}g{xF#!C$|AzzVm`=aB%z68I>+RER w(DWp*`t7Z}_xR12+oJZ@c#te27bwNRz_38WVanV!SFhbW PFeAaX_(H(OEEN_2CR!VT delta 60 zcmV-C0K@-|362SnIWZ|fln@*_q?sv{93bA(Ak8c})zWH8ND!>9y%;QF0000WFmsfh Stku@u&B8hDrC2kuY9s`+wHSl| diff --git a/graphics/pokemon/zamazenta/crowned_shield/overworld_normal.pal b/graphics/pokemon/zamazenta/crowned_shield/overworld_normal.pal index 54124216e5..0906c9bf94 100644 --- a/graphics/pokemon/zamazenta/crowned_shield/overworld_normal.pal +++ b/graphics/pokemon/zamazenta/crowned_shield/overworld_normal.pal @@ -6,7 +6,7 @@ JASC-PAL 16 28 57 164 153 41 148 28 32 -222 210 32 +232 48 56 205 44 57 213 210 106 74 72 16 diff --git a/graphics/pokemon/zamazenta/crowned_shield/overworld_shiny.pal b/graphics/pokemon/zamazenta/crowned_shield/overworld_shiny.pal index 54124216e5..57e6bf2744 100644 --- a/graphics/pokemon/zamazenta/crowned_shield/overworld_shiny.pal +++ b/graphics/pokemon/zamazenta/crowned_shield/overworld_shiny.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 131 129 131 -41 64 148 +200 48 104 16 28 57 164 153 41 -148 28 32 -222 210 32 -205 44 57 -213 210 106 -74 72 16 +168 48 144 +232 80 192 +232 80 192 +224 208 152 +107 67 47 172 174 189 -24 44 98 +200 48 104 0 0 0 -32 48 115 +160 40 64 148 157 172 213 214 222 -205 194 57 +192 152 96 diff --git a/graphics/pokemon/zapdos/galarian/overworld.png b/graphics/pokemon/zapdos/galarian/overworld.png index 648884dbe6a61c0b9916ec243f200c0a6fb72bb7..47321a67f4362237d457a62d1c122e39b5633277 100644 GIT binary patch delta 845 zcmV-T1G4;z2$Khp7#0Wv0001UMu)cm0004VQb$4nuFf3kks&{S5lKWrR9J=Wn2nO# zAPj_!z`_lF|L5(lu#<)#>pbnvO=p4=CzDTxl@NlvW%;yE`?OE{XD!Iz@tKV3v{?h3UDyNM|j$sd3<@}qX8TaftUI{E)o;QfRh5V zkptI!dE=u293IktiV%k|*MG^OkC!>gs~y7Qrf@aBPQrA}P2U=)A$GVZd?U9PzN_5g z7yvvXzIGqP$>Erm1Txj{ai%yq1)}vy?(wB^q)6o>1yf#1!Q`fx6&3?=9%sYaO27$b zQCY5T@(V~$aW-V7th!l*H(jO8QlCpk-wAhAOWbdArfA|6V~eoPLo>pkJj>Ga#C~^VTErcd zx}9Z@2hmK8N_7ZVxX0@d%ufhI=Xkf1d~(UbY*I6esBo+7kNDVS4PB*oIg(06^}MyE z-s4pv=7`dNBE#Jq7_Sx`7fuhdvy?|E+_3fCL7!7$&dQcE_1)snC_$WJB$#u$2K;a^ zwjBK{Hkky0NEUqWBY4e)*}}atk|}Dwj942*Phd@{AzUd7C+-_3MsJPvJQSY*m5Q%(!;2Hvn9;8&F|tXuS=0 z;%m--S;n=OQk_7O=Qaz(HX(Cxz$uVMjP$U7i#$?i;-J)ZYAba3yu%keBphR#3*Cu= ziBPA1$W1t|t!zU9_PZ=o2Th#4Ck{M$UtnHVXLQD$ybOAN3K!WX0_yKm2c=LM-b2g> z4_+qPtdntczGCnaKK-MjvFinzgBQ=A0h-Dz+pq-Y*faR*KV81-`C9CTr{ymj{D18? XtQ{NHbg64-00000NkvXXu0mjfO6i$Q delta 965 zcmV;$13LVZ2Z{)g7zqRe0002CwraMKE4AWQZd zr)!90m1b@pX2+wDQYgXOUN+VSn!fih+0*`x6}rbVw!vU~%EIW_%MypNb)|JBxonHK z65q*Av1B{C>14^4RT)|+d+LFOe|M6<)2H)&0(jHjw3lm0on`!b0_0};^#nj=OPzmV zKLC~hO+|f0L!MNp0!A$GL$QQ}%(+X92Ay%EP2UF0Fr4XR{)h&MIOQL^0uux}IpGzJ zHrxX#G8{DzfDwUrv1x_RBW`d>rH!S1nB{!7sU1fGM9oul@z~jX)+;?YJv-`*8)OF_ zwV*X`L!$Af-D8myO_>KE=a(sBG5LvcL+Y4bb4SAN}Yp)222f*HpR#ipnhoQDOPWc2sr%L_jc z$5KYaG4lXYtG3!?>*=3^q{c0abAuClbk>C=GeSC~M0%3t$ozuPOQ#k$Pf>rq{EI*xvTlaq-%Zu(^TeOi-c-T%f?*i?T*`EJ+sUG@*rr@KSp7}E{ zDwfxUXgRpUxXqo^*9g8%ZO^c`a*FIwv5Y&rV}sgk6K=kWE-ba2znl!q1v83U^)e!7 zmgO&{WP2N{gsNut{9C3S8vb2-w9f7S(dsA6n=+|~Hym?!5y^n$L7smm+pAxg?ki7O zr#Nw?x$2v*B1S(PQn)K@w9 z8b)veAtz6$z3%RYMjvcYr@C}tCL37Jo~u2u7mluv_E7HURt9nV1&5t9&dk5B)W_S& z&DDR>e>TP&u+=RLv9o_`%reMker1;|y#3QrXmRJjwz)?obE{^UN~EePs_}HIHt|*O zGl*0y{(Z1DvF<+h{E|krVL$tw?DbyZr{bqaN_&WPh)pdaMFAIGz_Cf zQcbBQ=#iQLwat`+Z?6^>qx z8$N*$>bBi>+ikbqcH94AM4NN&UsGI~@&R*Vo*na4eG4N7qo0VLIWYT~{0`=K#)%4v zLwM&U@S!qJ5PeJ`q!j8`gcY#DdL2XB2gl=_J200fPfP+0qeVhPm=oe zXUUH-c0k($qQHdZ;ouE@1t=+tePdjxCf*!x#=-+Ic?P?V1J!JRt=3osDM($7j4+kvG}3~ zJ;DGOz3y@a)bL}l^?V-m#=RQ_|q%z!ZjgjY(yQCEG6`dwyfdX_K^*+GKVS!z) z>z|Qm7@Qp-J!Q=?Rgctlu>z#v_(7Uu>A`NSHWcv57pyc!5;d^#Q~HBOlFOu%r@K@+ z&wwYn>3>5EE&(@*?xP+R^5LSfNdb89iFFELb40AY{`!8CgU~r3hUP);mgp?2Zk5DK zK#b2EYcpn91&p2>Uz}v2+5-j{B9yYDhpUq;9J226sa$odUS0ui3J|@IsOjvJnyUX6 z;QoHV5Rt6_6NhP2K0&#TYOEuCm78w#j{&FwigpR8=Bk;MM%x7qaPqz&uGKk1{d{PU zpb+rbMyLt=L_TyIPq+b2=vz;ZPrD9lE+`;b0l4e)j?t~8p#Gs87yzr>9?(*E_D`XR v0$%WIPnYrnbM>OUTxJi<k} delta 733 zcmV<30wVq12EGQ6ZGXH;L_t(oh3%GsZW|#ChR@i5Ax-oCZ@b@+cF|#=tu`&vVkP91 z-v^(;7>?s*FMHX`UiPy8#fXj&!oQ|in(+a1Vk|*qsy>C0fRQI6i$oEg$ z*{iU)`@l1T-5 zs>0)O&MU@Hnr2Ij0#_-aIq%agV4FZT4UI!+fLfKSHGj^110^D=9rVZ&P@dmkF;XaP zZZR$iTq?zs+zDI)njFwo2yy5#NbXb0}nBc1dcvI8$ zEsP7;0DnLD)H^A$ITC7%efYe|myA?^6k2>LvDglB`1gPehrlTz$TU`2157NPFHNct zB523tkfCcvH6)W1S7F?AW|!p+;9&qs@g*k%JD^Me`v4RXK@u;)2F6E#>&4awhb$vS z)jtF~Aay`>0nI|QcVD($&;iFC)E$u57M%0?npW|8#Y=jNAiVjrcOT%r15O=mpv%?2 zhxHH)kh}!E>+_DUcSQ7Xo2;d}4 diff --git a/graphics/pokemon/zigzagoon/galarian/overworld_shiny.pal b/graphics/pokemon/zigzagoon/galarian/overworld_shiny.pal index 6b74af8455..0277759a9e 100644 --- a/graphics/pokemon/zigzagoon/galarian/overworld_shiny.pal +++ b/graphics/pokemon/zigzagoon/galarian/overworld_shiny.pal @@ -4,16 +4,16 @@ JASC-PAL 52 87 191 31 43 44 36 36 36 -52 52 52 -96 101 106 -62 64 66 +82 9 36 +200 24 88 +144 8 48 163 164 163 245 245 246 0 0 0 178 179 178 -113 119 125 -238 150 178 -217 74 127 -110 59 81 +140 17 62 +152 248 240 +16 232 208 +46 79 75 64 72 80 168 184 208 diff --git a/graphics/pokemon/zorua/hisuian/overworld.png b/graphics/pokemon/zorua/hisuian/overworld.png index 9d98e3fd7af9a6d62940ded1900dca40083d2ed3..1bc82dd88a3c624983f46b21685bda34daa453a3 100644 GIT binary patch delta 649 zcmV;40(Sk)2GIqO7#0Wv0001UMu)cm0004VQb$4nuFf3kks&{SPf0{UR9J=WmeFqP zAPhvq00z_j|L?tHl6KX^kW{HuT`BHM)Z-mICYUVC6Hh$x#1l_E@x<>%yFsrcT*$Z= ze{G;m`JDEQ*DPgDuPt!Wp_}#JG;nHgo*_aU#@K!w20VlyUEdava7bJEial-#=-g!B z3gAn?;ryr6@R}HZfKiD9ju?xGgjdKSB}TZMxQfer0xUs9F%ZC}@9_n-))-orQT?RE zBaWC-p+>BlOG?iAoyS_?a`vZ`q6$EjPvIb7Tsjv%mm?-#m}`f|L?6b5QK* z$9w_HqB*P0o_@-uDC<{mZ{FPB{7pZvTR`=c4*fajOE2z!GhBfgw_Pb}+I{a1C%tp| z;@&V`7s!L<&$%U7Z%Z2spi_^_YAj6+yt#XufE{@8Po4e0!WW=fg>7KactLahiFVGLXMB-N0}2jnbw`DgD`{5Ey8rDeY~C6?1K+umVGYjp zgDD?1yDdI{<7_b7Yr_uNofO6qLxjg+!aUm?q?}XjwVz_&c)t^lTL5e)Y%r+KI8|Gp zg`-I~X1Mk!T8!bi#S0VG{Wz&xWMbf>a zJKXpanF=b`SL4Ksy>_YoTb$S;%g2A2W+pa;Ca4~(U&NNHr~@I7BiV_p91M9_`MG8v z&^JSzi01p~;M}n0jV+R;REi!fgn2z*wO7D~8CdOacm);_dA+~kHKcUYP7BQvJES_! zl3iqhGZ0sQ(G!>qBF(`e5Hpx@PCF6~+*qn-@*UczvRNRpho19V^U)2=mScZw03JEE z32)jS(44L)7@N!~7`_8p;LdtEJl||c^hT_ZNEeK3dJP%CPgCGzMape7thDI`n5sLG z?%Q>^jZFqWP?6#qA95>{aAIAFXEl=-{|J}b=`{FZ^Ocl=NB2gd;?ZmnV!b^rhX07*qoM6N<$ Ef~qNZW&i*H From a4dc9a0480cb3c1ce610540f6e2d928c4a940836 Mon Sep 17 00:00:00 2001 From: kittenchilly Date: Sat, 10 Aug 2024 16:59:23 -0500 Subject: [PATCH 03/64] Add Dowsing Machine expanded name (#5134) --- src/data/items.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/data/items.h b/src/data/items.h index daf1f9b957..f97c4670c1 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -12243,7 +12243,7 @@ const struct Item gItemsInfo[] = [ITEM_DOWSING_MACHINE] = { - .name = _("Dowsing MCHN"), + .name = HANDLE_EXPANDED_ITEM_NAME("Dowsing MCHN", "Dowsing Machine"), .price = 0, .description = COMPOUND_STRING( "A device that\n" From 77afb01477a7fd377f889fdb5d4c8feb97fadc2a Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Sun, 11 Aug 2024 00:23:51 +0200 Subject: [PATCH 04/64] Fixes Zigzgoon battle being able to use a Gimmick (#5129) * Fixes Zigzgoon battle being able to use a Gimmick * add commit * Update src/battle_terastal.c * Update src/battle_dynamax.c --- src/battle_dynamax.c | 4 ++++ src/battle_terastal.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/battle_dynamax.c b/src/battle_dynamax.c index 06a26718a9..cdcf05f7db 100644 --- a/src/battle_dynamax.c +++ b/src/battle_dynamax.c @@ -76,6 +76,10 @@ bool32 CanDynamax(u32 battler) u16 species = gBattleMons[battler].species; u16 holdEffect = GetBattlerHoldEffect(battler, FALSE); + // Prevents Zigzagoon from dynamaxing in vanilla. + if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE && GetBattlerSide(battler) == B_SIDE_OPPONENT) + return FALSE; + // Check if Player has a Dynamax Band. if (!TESTING && (GetBattlerPosition(battler) == B_POSITION_PLAYER_LEFT || (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && GetBattlerPosition(battler) == B_POSITION_PLAYER_RIGHT))) diff --git a/src/battle_terastal.c b/src/battle_terastal.c index 6866c6aaad..a0580a73d2 100644 --- a/src/battle_terastal.c +++ b/src/battle_terastal.c @@ -63,6 +63,10 @@ bool32 CanTerastallize(u32 battler) { u32 holdEffect = GetBattlerHoldEffect(battler, FALSE); + // Prevents Zigzagoon from terastalizing in vanilla. + if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE && GetBattlerSide(battler) == B_SIDE_OPPONENT) + return FALSE; + if (TESTING || GetBattlerSide(battler) == B_SIDE_OPPONENT) { // Skip all other checks in this block, go to HasTrainerUsedGimmick From 527cc33e0d7ae8a338e1b410eaaa3d2e534e6fc9 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Sun, 11 Aug 2024 13:01:10 +0200 Subject: [PATCH 05/64] Adjusted AI calcs for Triple Kick Effect (#5127) * Adjusted AI calcs for Triple Kick Effect * use strikeCount * fix compile --- src/battle_ai_util.c | 41 +++++++++++++++++++++++++++-------------- src/battle_util.c | 5 +---- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index f138252fa8..a094dfd694 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -577,13 +577,13 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u if (critChanceIndex > 1) // Consider crit damage only if a move has at least +2 crit chance { s32 nonCritDmg = CalculateMoveDamageVars(move, battlerAtk, battlerDef, moveType, fixedBasePower, - effectivenessMultiplier, weather, FALSE, - aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef], - aiData->abilities[battlerAtk], aiData->abilities[battlerDef]); + effectivenessMultiplier, weather, FALSE, + aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef], + aiData->abilities[battlerAtk], aiData->abilities[battlerDef]); s32 critDmg = CalculateMoveDamageVars(move, battlerAtk, battlerDef, moveType, fixedBasePower, - effectivenessMultiplier, weather, TRUE, - aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef], - aiData->abilities[battlerAtk], aiData->abilities[battlerDef]); + effectivenessMultiplier, weather, TRUE, + aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef], + aiData->abilities[battlerAtk], aiData->abilities[battlerDef]); u32 critOdds = GetCritHitOdds(critChanceIndex); // With critOdds getting closer to 1, dmg gets closer to critDmg. @@ -596,20 +596,33 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u else if (critChanceIndex == -2) // Guaranteed critical { s32 critDmg = CalculateMoveDamageVars(move, battlerAtk, battlerDef, moveType, fixedBasePower, - effectivenessMultiplier, weather, TRUE, - aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef], - aiData->abilities[battlerAtk], aiData->abilities[battlerDef]); + effectivenessMultiplier, weather, TRUE, + aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef], + aiData->abilities[battlerAtk], aiData->abilities[battlerDef]); simDamage.expected = GetDamageByRollType(critDmg, rollType); simDamage.minimum = LowestRollDmg(critDmg); } else { - s32 nonCritDmg = CalculateMoveDamageVars(move, battlerAtk, battlerDef, moveType, fixedBasePower, - effectivenessMultiplier, weather, FALSE, - aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef], - aiData->abilities[battlerAtk], aiData->abilities[battlerDef]); - + s32 nonCritDmg = 0; + if (gMovesInfo[move].effect == EFFECT_TRIPLE_KICK) + { + for (gMultiHitCounter = gMovesInfo[move].strikeCount; gMultiHitCounter > 0; gMultiHitCounter--) // The global is used to simulate actual damage done + { + nonCritDmg += CalculateMoveDamageVars(move, battlerAtk, battlerDef, moveType, fixedBasePower, + effectivenessMultiplier, weather, FALSE, + aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef], + aiData->abilities[battlerAtk], aiData->abilities[battlerDef]); + } + } + else + { + nonCritDmg = CalculateMoveDamageVars(move, battlerAtk, battlerDef, moveType, fixedBasePower, + effectivenessMultiplier, weather, FALSE, + aiData->holdEffects[battlerAtk], aiData->holdEffects[battlerDef], + aiData->abilities[battlerAtk], aiData->abilities[battlerDef]); + } simDamage.expected = GetDamageByRollType(nonCritDmg, rollType); simDamage.minimum = LowestRollDmg(nonCritDmg); } diff --git a/src/battle_util.c b/src/battle_util.c index 821f785810..329de506d5 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8898,10 +8898,7 @@ static inline u32 CalcMoveBasePower(u32 move, u32 battlerAtk, u32 battlerDef, u3 basePower = gBattleStruct->presentBasePower; break; case EFFECT_TRIPLE_KICK: - if (gMultiHitCounter == 0) // Calc damage with max BP for move consideration - basePower *= 6; - else - basePower *= 1 + gMovesInfo[move].strikeCount - gMultiHitCounter; + basePower *= 1 + gMovesInfo[move].strikeCount - gMultiHitCounter; break; case EFFECT_SPIT_UP: basePower = 100 * gDisableStructs[battlerAtk].stockpileCounter; From 137c15a9ceef368d18b405d0d7ef6d0390e5c702 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Sun, 11 Aug 2024 13:21:49 +0200 Subject: [PATCH 06/64] Clean up for #4928 (#5120) * Clean up for #4928 * agbcc * review comments * agbcc * Update src/battle_util.c --------- Co-authored-by: Bassoonian --- src/battle_util.c | 114 ++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 64 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index 329de506d5..56701e2d99 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -4060,6 +4060,54 @@ static inline bool32 HadMoreThanHalfHpNowDoesnt(u32 battler) && gBattleMons[battler].hp <= cutoff); } +#define ANIM_STAT_HP 0 +#define ANIM_STAT_ATK 1 +#define ANIM_STAT_DEF 2 +#define ANIM_STAT_SPATK 3 +#define ANIM_STAT_SPDEF 4 +#define ANIM_STAT_SPEED 5 +#define ANIM_STAT_ACC 6 +#define ANIM_STAT_EVASION 7 +static void ChooseStatBoostAnimation(u32 battler) +{ + u32 stat; + bool32 statBuffMoreThan1 = FALSE; + u32 static const statsOrder[NUM_BATTLE_STATS] = + { + [ANIM_STAT_HP] = STAT_HP, + [ANIM_STAT_ATK] = STAT_ATK, + [ANIM_STAT_DEF] = STAT_DEF, + [ANIM_STAT_SPATK] = STAT_SPATK, + [ANIM_STAT_SPDEF] = STAT_SPDEF, + [ANIM_STAT_SPEED] = STAT_SPEED, + [ANIM_STAT_ACC] = STAT_ACC, + [ANIM_STAT_EVASION] = STAT_EVASION, + }; + gBattleScripting.animArg1 = 0; + + for (stat = 1; stat < NUM_BATTLE_STATS; stat++) // Start loop at 1 to avoid STAT_HP + { + if ((gQueuedStatBoosts[battler].stats & (1 << statsOrder[stat])) == 0) + continue; + + if (!statBuffMoreThan1) + statBuffMoreThan1 = ((gQueuedStatBoosts[battler].stats & (1 << statsOrder[stat])) > 1); + + if (gBattleScripting.animArg1 != 0) // Already set in a different stat so now boosting multiple stats + gBattleScripting.animArg1 = (statBuffMoreThan1 ? STAT_ANIM_MULTIPLE_PLUS2 : STAT_ANIM_MULTIPLE_PLUS1); + else + gBattleScripting.animArg1 = GET_STAT_BUFF_ID((statsOrder[stat] + 1)) + (!statBuffMoreThan1 ? STAT_ANIM_PLUS1 : STAT_ANIM_PLUS2); + } +} +#undef ANIM_STAT_HP +#undef ANIM_STAT_ATK +#undef ANIM_STAT_DEF +#undef ANIM_STAT_SPATK +#undef ANIM_STAT_SPDEF +#undef ANIM_STAT_SPEED +#undef ANIM_STAT_ACC +#undef ANIM_STAT_EVASION + u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg) { u32 effect = 0; @@ -6024,40 +6072,10 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITY_OPPORTUNIST: if (gProtectStructs[battler].activateOpportunist == 2) { - bool32 statBuffMoreThan1 = FALSE; - bool32 handleSpeedAnimLater = FALSE; gBattleScripting.animArg1 = 0; gBattleScripting.battler = battler; gProtectStructs[battler].activateOpportunist--; - - for (i = 0; i < (NUM_BATTLE_STATS - 1); i++) - { - if ((gQueuedStatBoosts[battler].stats & (1 << i)) == 0) - continue; - - if (i == STAT_SPEED) - { - handleSpeedAnimLater = TRUE; - continue; - } - - if (!statBuffMoreThan1) - statBuffMoreThan1 = ((gQueuedStatBoosts[battler].stats & (1 << i)) > 1); - - if (gBattleScripting.animArg1 != 0) //Already set in a different stat so now boosting multiple stats - gBattleScripting.animArg1 = (!statBuffMoreThan1 ? STAT_ANIM_MULTIPLE_PLUS1 : STAT_ANIM_MULTIPLE_PLUS2); - else - gBattleScripting.animArg1 = GET_STAT_BUFF_ID((i + 1)) + (!statBuffMoreThan1 ? STAT_ANIM_PLUS1 : STAT_ANIM_PLUS2); - - } - if (handleSpeedAnimLater) - { - if (gBattleScripting.animArg1 != 0) //Already set in a different stat so now boosting multiple stats - gBattleScripting.animArg1 = (!statBuffMoreThan1 ? STAT_ANIM_MULTIPLE_PLUS1 : STAT_ANIM_MULTIPLE_PLUS2); - else - gBattleScripting.animArg1 = GET_STAT_BUFF_ID((STAT_SPEED + 1)) + (!statBuffMoreThan1 ? STAT_ANIM_PLUS1 : STAT_ANIM_PLUS2); - } - + ChooseStatBoostAnimation(battler); BattleScriptPushCursorAndCallback(BattleScript_OpportunistCopyStatChange); effect = 1; } @@ -7006,43 +7024,11 @@ static u8 TryConsumeMirrorHerb(u32 battler, bool32 execute) if (gProtectStructs[battler].eatMirrorHerb) { - u32 i; - bool32 statBuffMoreThan1 = FALSE; - bool32 handleSpeedAnimLater = FALSE; - gBattleScripting.animArg1 = 0; gLastUsedItem = gBattleMons[battler].item; gBattleScripting.battler = battler; gProtectStructs[battler].eatMirrorHerb = 0; - - for (i = 0; i < (NUM_BATTLE_STATS - 1); i++) - { - if ((gQueuedStatBoosts[battler].stats & (1 << i)) == 0) - continue; - - if (i == STAT_SPEED) - { - handleSpeedAnimLater = TRUE; - continue; - } - - if (!statBuffMoreThan1) - statBuffMoreThan1 = ((gQueuedStatBoosts[battler].stats & (1 << i)) > 1); - - if (gBattleScripting.animArg1 != 0) //Already set in a different stat so now boosting multiple stats - gBattleScripting.animArg1 = (!statBuffMoreThan1 ? STAT_ANIM_MULTIPLE_PLUS1 : STAT_ANIM_MULTIPLE_PLUS2); - else - gBattleScripting.animArg1 = GET_STAT_BUFF_ID((i + 1)) + (!statBuffMoreThan1 ? STAT_ANIM_PLUS1 : STAT_ANIM_PLUS2); - - } - if (handleSpeedAnimLater) - { - if (gBattleScripting.animArg1 != 0) //Already set in a different stat so now boosting multiple stats - gBattleScripting.animArg1 = (!statBuffMoreThan1 ? STAT_ANIM_MULTIPLE_PLUS1 : STAT_ANIM_MULTIPLE_PLUS2); - else - gBattleScripting.animArg1 = GET_STAT_BUFF_ID((STAT_SPEED + 1)) + (!statBuffMoreThan1 ? STAT_ANIM_PLUS1 : STAT_ANIM_PLUS2); - } - + ChooseStatBoostAnimation(battler); if (execute) { BattleScriptExecute(BattleScript_MirrorHerbCopyStatChangeEnd2); From 97fa0be36e3013d77400cf6572f505281bb87159 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Sun, 11 Aug 2024 14:18:56 +0200 Subject: [PATCH 07/64] Dynamic move type clean up (#5132) * Minor clean up of the new function DynamicMoveType * wrongly removed func * Overworld Weather Bug * wrong comparison --- include/pokemon.h | 3 +- src/pokemon.c | 108 ++++++++++++++++++++++++++++------------------ 2 files changed, 67 insertions(+), 44 deletions(-) diff --git a/include/pokemon.h b/include/pokemon.h index 8337890935..2187b7ab38 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -880,7 +880,6 @@ const u8 *GetMoveName(u16 moveId); const u8 *GetMoveAnimationScript(u16 moveId); void UpdateDaysPassedSinceFormChange(u16 days); void TrySetDayLimitToFormChange(struct Pokemon *mon); -u8 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler); -u8 CalculateHiddenPowerType(struct Pokemon *mon); +u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler); #endif // GUARD_POKEMON_H diff --git a/src/pokemon.c b/src/pokemon.c index 04bdfc9046..78e19dfc8b 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -6929,7 +6929,26 @@ void UpdateDaysPassedSinceFormChange(u16 days) } } -u8 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) +static inline u32 CalculateHiddenPowerType(struct Pokemon *mon) +{ + u32 typehp; + u32 type; + u8 typeBits = ((GetMonData(mon, MON_DATA_HP_IV) & 1) << 0) + | ((GetMonData(mon, MON_DATA_ATK_IV) & 1) << 1) + | ((GetMonData(mon, MON_DATA_DEF_IV) & 1) << 2) + | ((GetMonData(mon, MON_DATA_SPEED_IV) & 1) << 3) + | ((GetMonData(mon, MON_DATA_SPATK_IV) & 1) << 4) + | ((GetMonData(mon, MON_DATA_SPDEF_IV) & 1) << 5); + + type = (15 * typeBits) / 63 + 2; + if (type >= TYPE_MYSTERY) + type++; + type |= 0xC0; + typehp = type & 0x3F; + return typehp; +} + +u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) { u32 type = gMovesInfo[move].type; u32 species = GetMonData(mon, MON_DATA_SPECIES); @@ -6940,9 +6959,9 @@ u8 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) u32 type2 = gSpeciesInfo[species].types[1]; if (move == MOVE_IVY_CUDGEL - && (species == SPECIES_OGERPON_WELLSPRING_MASK || species == SPECIES_OGERPON_WELLSPRING_MASK_TERA - || species == SPECIES_OGERPON_HEARTHFLAME_MASK || species == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA - || species == SPECIES_OGERPON_CORNERSTONE_MASK || species == SPECIES_OGERPON_CORNERSTONE_MASK_TERA)) + && (species == SPECIES_OGERPON_WELLSPRING_MASK || species == SPECIES_OGERPON_WELLSPRING_MASK_TERA + || species == SPECIES_OGERPON_HEARTHFLAME_MASK || species == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA + || species == SPECIES_OGERPON_CORNERSTONE_MASK || species == SPECIES_OGERPON_CORNERSTONE_MASK_TERA)) { type = type2; } @@ -6980,13 +6999,13 @@ u8 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) else return TYPE_NORMAL; } - else if (move == MOVE_RAGING_BULL - && (species == SPECIES_TAUROS_PALDEAN_COMBAT_BREED - || species == SPECIES_TAUROS_PALDEAN_BLAZE_BREED - || species == SPECIES_TAUROS_PALDEAN_AQUA_BREED)) + else if (move == MOVE_RAGING_BULL + && (species == SPECIES_TAUROS_PALDEAN_COMBAT_BREED + || species == SPECIES_TAUROS_PALDEAN_BLAZE_BREED + || species == SPECIES_TAUROS_PALDEAN_AQUA_BREED)) { return type2; - } + } else if (move == MOVE_REVELATION_DANCE) { if (gBattleMons[battler].species != species && type1 != TYPE_MYSTERY) @@ -6994,7 +7013,7 @@ u8 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) else if (gBattleMons[battler].species != species && type2 != TYPE_MYSTERY) type = type2; else if (GetBattlerTeraType(battler) != TYPE_STELLAR && (GetActiveGimmick(battler) == GIMMICK_TERA || IsGimmickSelected(battler, GIMMICK_TERA))) - type = GetMonData(mon, MON_DATA_TERA_TYPE); + type = GetMonData(mon, MON_DATA_TERA_TYPE); else if (gBattleMons[battler].types[0] != TYPE_MYSTERY) type = gBattleMons[battler].types[0]; else if (gBattleMons[battler].types[1] != TYPE_MYSTERY) @@ -7002,10 +7021,10 @@ u8 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) else if (gBattleMons[battler].types[2] != TYPE_MYSTERY) type = gBattleMons[battler].types[2]; } - else if (gMovesInfo[move].effect == EFFECT_TERRAIN_PULSE - && ((IsMonGrounded(heldItemEffect, ability, type1, type2) && gBattleMons[battler].species != species) + else if (gMovesInfo[move].effect == EFFECT_TERRAIN_PULSE + && ((IsMonGrounded(heldItemEffect, ability, type1, type2) && gBattleMons[battler].species != species) || (IsBattlerTerrainAffected(battler, STATUS_FIELD_TERRAIN_ANY) && gBattleMons[battler].species == species))) - { + { if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) return TYPE_ELECTRIC; else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) @@ -7015,21 +7034,45 @@ u8 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) return TYPE_PSYCHIC; else //failsafe - type = TYPE_NORMAL; + type = TYPE_NORMAL; } - if (gMovesInfo[move].effect == EFFECT_WEATHER_BALL && WEATHER_HAS_EFFECT) + if (gMovesInfo[move].effect == EFFECT_WEATHER_BALL) { - if (gBattleWeather & B_WEATHER_RAIN && heldItemEffect != HOLD_EFFECT_UTILITY_UMBRELLA) - return TYPE_WATER; - else if (gBattleWeather & B_WEATHER_SANDSTORM) - return TYPE_ROCK; - else if (gBattleWeather & B_WEATHER_SUN && heldItemEffect != HOLD_EFFECT_UTILITY_UMBRELLA) - return TYPE_FIRE; - else if (gBattleWeather & (B_WEATHER_SNOW | B_WEATHER_HAIL)) - return TYPE_ICE; + if (gMain.inBattle && WEATHER_HAS_EFFECT) + { + if (gBattleWeather & B_WEATHER_RAIN && heldItemEffect != HOLD_EFFECT_UTILITY_UMBRELLA) + return TYPE_WATER; + else if (gBattleWeather & B_WEATHER_SANDSTORM) + return TYPE_ROCK; + else if (gBattleWeather & B_WEATHER_SUN && heldItemEffect != HOLD_EFFECT_UTILITY_UMBRELLA) + return TYPE_FIRE; + else if (gBattleWeather & (B_WEATHER_SNOW | B_WEATHER_HAIL)) + return TYPE_ICE; + else + return TYPE_NORMAL; + } else + { + switch (gWeatherPtr->currWeather) + { + case WEATHER_SUNNY: + if (heldItem != ITEM_UTILITY_UMBRELLA) + return TYPE_FIRE; + break; + case WEATHER_RAIN: + if (heldItem != ITEM_UTILITY_UMBRELLA) + return TYPE_WATER; + break; + case WEATHER_SNOW: + return TYPE_ICE; + break; + case WEATHER_SANDSTORM: + return TYPE_ROCK; + break; + } return TYPE_NORMAL; + } } if (ability == ABILITY_NORMALIZE && gMovesInfo[move].type != TYPE_NORMAL && GetActiveGimmick(battler) != GIMMICK_Z_MOVE) @@ -7055,22 +7098,3 @@ u8 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) return type; } - -u8 CalculateHiddenPowerType(struct Pokemon *mon) -{ - u32 typehp; - u32 type; - u8 typeBits = ((GetMonData(mon, MON_DATA_HP_IV) & 1) << 0) - | ((GetMonData(mon, MON_DATA_ATK_IV) & 1) << 1) - | ((GetMonData(mon, MON_DATA_DEF_IV) & 1) << 2) - | ((GetMonData(mon, MON_DATA_SPEED_IV) & 1) << 3) - | ((GetMonData(mon, MON_DATA_SPATK_IV) & 1) << 4) - | ((GetMonData(mon, MON_DATA_SPDEF_IV) & 1) << 5); - - type = (15 * typeBits) / 63 + 2; - if (type >= TYPE_MYSTERY) - type++; - type |= 0xC0; - typehp = type & 0x3F; - return typehp; -} From d1183f4b8a3d1654e2426a357815b63773f6deb2 Mon Sep 17 00:00:00 2001 From: psf <77138753+pkmnsnfrn@users.noreply.github.com> Date: Sun, 11 Aug 2024 08:55:51 -0700 Subject: [PATCH 08/64] Add B_SHOW_TYPES and cleaned up IsDoubleBattle (#5131) * First attempt at a port * Slightly broken but working * Got images working and opponent palettes * half finished compressed spritesheet approach instead * fix the palettes (smh) * fix hflip, and a lot of clean-up * Add B_SHOW_TYPES * Got Illusion working * Add num type enum * Updated function to get type * Fixed type icon position and cleaned up functions * Updated illusions and Tera handling * Added BATTLE_TYPE_IS_SINGLE and DOUBLE * Removed IS_BATTLE_TYPE_SINGLE * Implemented BATTLE_TYPE_IS_DOUBLE across repo * Removed SIDE macro * Updated config * Deprecated battler alive macro * Reindented file * Added exceptions for 2v1 * Replaced Fainted check with Null check * Added functionality for only types of caught mons * UseDoubleBattleCoords updated * Added ShouldFlipTypeIcon * Renamed TryLoadTypeIcon * Refactored functions * Refactored functions * Refactored functions * Refactored functions * Renamed SEEN to CAUGHT * Reset config * Added useSecondPalette and isOrdinary to gTypesInfo * Further simplified secondPalette and isOrdinary * Changed isordinary to isSpecialCase * Renamed to useSecondTypeIconPalette * Fixed Stellar type interactions * fixed spacing * fixed include/config/battle.h * fixed * fixed include/config/general.h * changed type1 and type2 * Moved IsDoubleBattle to include.battle.h Removed BATTLE_TYPE_IS_DOUBLE Removed IS_DOUBLE_BATTLE * Changed IsBattlerFainted to IsBattlerAlive * Removed IsBattlerNull * Moved GetBattlerData to be inline * Renamed GetMonDefensiveTeraType * Removed IsIllusionActive * Fixed identation * found one last isDoubleBattle hold out * fixed redundant brackets * Fixed spacing for B_SHOW_TYPES * Update src/battle_script_commands.c Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> * Fixed padding * Reindent file and refactored GetTypeIconHideMovement * Update include/data.h --------- Co-authored-by: RavePossum Co-authored-by: Frank Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> --- gflib/sprite.c | 2 - gflib/sprite.h | 2 + graphics/types/battle_icons1.pal | 15 + graphics/types/battle_icons1.png | Bin 0 -> 354 bytes graphics/types/battle_icons2.pal | 15 + graphics/types/battle_icons2.png | Bin 0 -> 372 bytes include/battle.h | 12 + include/battle_anim.h | 1 - include/battle_controllers.h | 5 + include/config/battle.h | 5 + include/constants/battle.h | 1 - include/data.h | 4 +- include/graphics.h | 5 + include/type_icons.h | 18 ++ src/battle_ai_main.c | 10 +- src/battle_ai_switch_items.c | 20 +- src/battle_ai_util.c | 6 +- src/battle_anim_effects_1.c | 8 +- src/battle_anim_effects_2.c | 4 +- src/battle_anim_mons.c | 7 - src/battle_anim_new.c | 22 +- src/battle_controller_opponent.c | 4 +- src/battle_controller_player.c | 20 +- src/battle_controllers.c | 8 +- src/battle_gfx_sfx_util.c | 2 +- src/battle_gimmick.c | 8 +- src/battle_main.c | 6 +- src/battle_message.c | 10 +- src/battle_script_commands.c | 73 +++-- src/battle_terastal.c | 2 +- src/battle_util.c | 22 +- src/battle_util2.c | 2 +- src/data/types_info.h | 42 +++ src/graphics.c | 6 + src/party_menu.c | 2 +- src/pokemon.c | 2 +- src/tv.c | 2 +- src/type_icons.c | 516 +++++++++++++++++++++++++++++++ 38 files changed, 758 insertions(+), 131 deletions(-) create mode 100644 graphics/types/battle_icons1.pal create mode 100644 graphics/types/battle_icons1.png create mode 100644 graphics/types/battle_icons2.pal create mode 100644 graphics/types/battle_icons2.png create mode 100644 include/type_icons.h create mode 100644 src/type_icons.c diff --git a/gflib/sprite.c b/gflib/sprite.c index 7823888cb5..9ba1662c9d 100644 --- a/gflib/sprite.c +++ b/gflib/sprite.c @@ -52,7 +52,6 @@ static void SortSprites(u32 *spritePriorities, s32 n); static u32 CreateSpriteAt(u32 index, const struct SpriteTemplate *template, s16 x, s16 y, u32 subpriority); static void ResetOamMatrices(void); static void ResetSprite(struct Sprite *sprite); -static void RequestSpriteFrameImageCopy(u16 index, u16 tileNum, const struct SpriteFrameImage *images); static void ResetAllSprites(void); static void BeginAnim(struct Sprite *sprite); static void ContinueAnim(struct Sprite *sprite); @@ -75,7 +74,6 @@ static void AffineAnimCmd_end(u8 matrixNum, struct Sprite *sprite); static void AffineAnimCmd_frame(u8 matrixNum, struct Sprite *sprite); static void CopyOamMatrix(u8 destMatrixIndex, struct OamMatrix *srcMatrix); static u8 GetSpriteMatrixNum(struct Sprite *sprite); -static void SetSpriteOamFlipBits(struct Sprite *sprite, u8 hFlip, u8 vFlip); static void AffineAnimStateRestartAnim(u8 matrixNum); static void AffineAnimStateStartAnim(u8 matrixNum, u8 animNum); static void AffineAnimStateReset(u8 matrixNum); diff --git a/gflib/sprite.h b/gflib/sprite.h index 6a3084add2..937ed42ced 100644 --- a/gflib/sprite.h +++ b/gflib/sprite.h @@ -331,5 +331,7 @@ u8 SpriteTileAllocBitmapOp(u16 bit, u8 op); void ClearSpriteCopyRequests(void); void ResetAffineAnimData(void); u32 GetSpanPerImage(u32 shape, u32 size); +void RequestSpriteFrameImageCopy(u16 index, u16 tileNum, const struct SpriteFrameImage *images); +void SetSpriteOamFlipBits(struct Sprite *sprite, u8 hFlip, u8 vFlip); #endif //GUARD_SPRITE_H diff --git a/graphics/types/battle_icons1.pal b/graphics/types/battle_icons1.pal new file mode 100644 index 0000000000..972dfd02af --- /dev/null +++ b/graphics/types/battle_icons1.pal @@ -0,0 +1,15 @@ +JASC-PAL +0100 +12 +120 152 128 +49 49 49 +255 255 255 +164 82 57 +172 189 32 +184 160 90 +213 180 90 +98 98 180 +180 90 164 +172 164 148 +172 172 197 +152 172 246 diff --git a/graphics/types/battle_icons1.png b/graphics/types/battle_icons1.png new file mode 100644 index 0000000000000000000000000000000000000000..c47b07f1171a309220fe403e7ed17b544dce61b2 GIT binary patch literal 354 zcmeAS@N?(olHy`uVBq!ia0vp^96-E)gBeJ&&AV#_q!^2X+?^QKos)S9f0+Ah^6AeDr5qSvozYT0U{!x$`s_r#^L~O? zW`;68@OaH&_v*B4*$Iv5&s|*w(yuXeG{_swkC``BYN3?2$6ECzR%;a2T$7x3-fpK2 zw`)VQ%vH99|B6*k<|Py^@Yg%OV literal 0 HcmV?d00001 diff --git a/graphics/types/battle_icons2.pal b/graphics/types/battle_icons2.pal new file mode 100644 index 0000000000..bddf49ad95 --- /dev/null +++ b/graphics/types/battle_icons2.pal @@ -0,0 +1,15 @@ +JASC-PAL +0100 +12 +120 152 128 +49 49 49 +255 255 255 +240 82 48 +120 200 80 +248 197 49 +80 120 136 +123 98 230 +248 115 164 +57 156 255 +90 205 230 +246 180 246 diff --git a/graphics/types/battle_icons2.png b/graphics/types/battle_icons2.png new file mode 100644 index 0000000000000000000000000000000000000000..44aa4f89547f478a290231112e03bd84f350a08e GIT binary patch literal 372 zcmeAS@N?(olHy`uVBq!ia0vp^96-E)gBeJ&&AV#_q!^2X+?^QKos)S9%Lb!>Ej>Uc_m{DK*PN@0NW zNPrqp{F$eVV~9oX*+~b5njCnX4YfG_{QrMTEphh)*Y7EA%lmU~y*2PL&)#)cl~Kxp z!IERaWLAYID;xWC%9j?$eC*AdA1ZV};4{aCCrl!1c&{l7|6f;|Grv9M#7Uhdjs6y$ zGhY@M>?)gc>-e`yFYyM(vV;e(KVEcyW|W>Ye|kyVjwuaK7z8*qp3hmScV6;#`s8yB zY&Rw}_zHyodQqSi96QT++j%9)ga_;kyc`1Lo)&ZKm)+^(*_kc*uP*H+Qv<_C?~dro zBk$AS%{>(|{aMf3&E9MR8$NG+Qmi1Wad_8vzv-E=vp%1;t6yfmv6;^}dj^LH(8mm( Lu6{1-oD!MaiFlags[B_POSITION_PLAYER_RIGHT] = GetAiFlags(gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)); } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsAiVsAiBattle()) + else if (IsDoubleBattle() && IsAiVsAiBattle()) { AI_THINKING_STRUCT->aiFlags[B_POSITION_PLAYER_RIGHT] = AI_THINKING_STRUCT->aiFlags[B_POSITION_PLAYER_LEFT]; } @@ -275,7 +275,7 @@ u32 BattleAI_ChooseMoveOrAction(void) { u32 ret; - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (!IsDoubleBattle()) ret = ChooseMoveOrAction_Singles(sBattler_AI); else ret = ChooseMoveOrAction_Doubles(sBattler_AI); @@ -323,7 +323,7 @@ void Ai_InitPartyStruct(void) // Save first 2 or 4(in doubles) mons CopyBattlerDataToAIParty(B_POSITION_PLAYER_LEFT, B_SIDE_PLAYER); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) CopyBattlerDataToAIParty(B_POSITION_PLAYER_RIGHT, B_SIDE_PLAYER); // If player's partner is AI, save opponent mons @@ -2050,7 +2050,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } /*if (AI_THINKING_STRUCT->aiFlags[battlerAtk] == AI_SCRIPT_CHECK_BAD_MOVE //Only basic AI - && IS_DOUBLE_BATTLE) //Make the regular AI know how to use Protect minimally in Doubles + && IsDoubleBattle()) //Make the regular AI know how to use Protect minimally in Doubles { u8 shouldProtect = ShouldProtect(battlerAtk, battlerDef, move); if (shouldProtect == USE_PROTECT || shouldProtect == PROTECT_FROM_FOES) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index ef35a95f59..966082f32f 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -82,7 +82,7 @@ static bool32 HasBadOdds(u32 battler, bool32 emitResult) return FALSE; // Double Battles aren't included in AI_FLAG_SMART_MON_CHOICE. Defaults to regular switch in logic - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) return FALSE; opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(battler)); @@ -242,7 +242,7 @@ static bool32 ShouldSwitchIfWonderGuard(u32 battler, bool32 emitResult) struct Pokemon *party = NULL; u16 move; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) return FALSE; opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(battler)); @@ -318,7 +318,7 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler, bool32 emitResult) if (IS_MOVE_STATUS(gLastLandedMoves[battler])) return FALSE; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { battlerIn1 = battler; if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))]) @@ -707,7 +707,7 @@ static bool32 HasSuperEffectiveMoveAgainstOpponents(u32 battler, bool32 noRng) } } } - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (!IsDoubleBattle()) return FALSE; opposingBattler = GetBattlerAtPosition(BATTLE_PARTNER(opposingPosition)); @@ -765,7 +765,7 @@ static bool32 FindMonWithFlagsAndSuperEffective(u32 battler, u16 flags, u32 modu if (IS_MOVE_STATUS(gLastLandedMoves[battler])) return FALSE; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { battlerIn1 = battler; if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))]) @@ -846,7 +846,7 @@ static bool32 CanMonSurviveHazardSwitchin(u32 battler) // Battler will faint to hazards, check to see if another mon can clear them if (hazardDamage > battlerHp) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { battlerIn1 = battler; if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))]) @@ -1023,7 +1023,7 @@ bool32 ShouldSwitch(u32 battler, bool32 emitResult) availableToSwitch = 0; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { battlerIn1 = battler; if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))]) @@ -1140,7 +1140,7 @@ void AI_TrySwitchOrUseItem(u32 battler) s32 monToSwitchId = AI_DATA->mostSuitableMonId[battler]; if (monToSwitchId == PARTY_SIZE) { - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (!IsDoubleBattle()) { battlerIn1 = GetBattlerAtPosition(battlerPosition); battlerIn2 = battlerIn1; @@ -2040,7 +2040,7 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd) if (gBattleTypeFlags & BATTLE_TYPE_ARENA) return gBattlerPartyIndexes[battler] + 1; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { battlerIn1 = battler; if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))]) @@ -2074,7 +2074,7 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd) // Split ideal mon decision between after previous mon KO'd (prioritize offensive options) and after switching active mon out (prioritize defensive options), and expand the scope of both. // Only use better mon selection if AI_FLAG_SMART_MON_CHOICES is set for the trainer. - if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_SMART_MON_CHOICES && !(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) // Double Battles aren't included in AI_FLAG_SMART_MON_CHOICE. Defaults to regular switch in logic + if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_SMART_MON_CHOICES && !IsDoubleBattle()) // Double Battles aren't included in AI_FLAG_SMART_MON_CHOICE. Defaults to regular switch in logic { bestMonId = GetBestMonIntegrated(party, firstId, lastId, battler, opposingBattler, battlerIn1, battlerIn2, switchAfterMonKOd); return bestMonId; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 2af88bea8c..26950882f1 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -3026,7 +3026,7 @@ bool32 AnyPartyMemberStatused(u32 battlerId, bool32 checkSoundproof) else party = gEnemyParty; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { battlerOnField1 = gBattlerPartyIndexes[battlerId]; battlerOnField2 = gBattlerPartyIndexes[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battlerId)))]; @@ -3417,7 +3417,7 @@ s32 CountUsablePartyMons(u32 battlerId) else party = gEnemyParty; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { battlerOnField1 = gBattlerPartyIndexes[battlerId]; battlerOnField2 = gBattlerPartyIndexes[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battlerId)))]; @@ -3828,7 +3828,7 @@ bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u32 move) bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u32 chosenMove) { // simple logic. just upgrades chosen move to z move if possible, unless regular move would kill opponent - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && battlerDef == BATTLE_PARTNER(battlerAtk)) + if ((IsDoubleBattle()) && battlerDef == BATTLE_PARTNER(battlerAtk)) return FALSE; // don't use z move on partner if (HasTrainerUsedGimmick(battlerAtk, GIMMICK_Z_MOVE)) return FALSE; // can't use z move twice diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index b917cdc9a5..a852033133 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -3317,7 +3317,7 @@ static void AnimSolarBeamSmallOrb(struct Sprite *sprite) { InitSpritePosToAnimAttacker(sprite, TRUE); - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gAnimMoveIndex == MOVE_CORE_ENFORCER) + if (IsDoubleBattle() && gAnimMoveIndex == MOVE_CORE_ENFORCER) { CoreEnforcerLoadBeamTarget(sprite); } @@ -6567,11 +6567,11 @@ void PrepareDoubleTeamAnim(u32 taskId, u32 animBattler, bool32 forAllySwitch) gSprites[spriteId].sBattlerFlank = (animBattler != ANIM_ATTACKER); else gSprites[spriteId].sBattlerFlank = (animBattler == ANIM_ATTACKER); - + // correct direction on opponent side if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) gSprites[spriteId].sBattlerFlank ^= 1; - + gSprites[spriteId].callback = AnimDoubleTeam; task->tBlendSpritesCount++; } @@ -6603,7 +6603,7 @@ static void ReloadBattlerSprites(u32 battler, struct Pokemon *party) UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], mon, HEALTHBOX_ALL); // If battler has an indicator for a gimmick, hide the sprite until the move animation finishes. UpdateIndicatorVisibilityAndType(gHealthboxSpriteIds[battler], TRUE); - + // Try to recreate shadow sprite if (gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteId < MAX_SPRITES) { diff --git a/src/battle_anim_effects_2.c b/src/battle_anim_effects_2.c index 3324d276fd..b33c0a8bb6 100755 --- a/src/battle_anim_effects_2.c +++ b/src/battle_anim_effects_2.c @@ -1726,7 +1726,7 @@ void AnimTask_AirCutterProjectile(u8 taskId) attackerX = gTasks[taskId].data[9] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_X); attackerY = gTasks[taskId].data[10] = GetBattlerSpriteCoord(gBattleAnimAttacker, BATTLER_COORD_Y); - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle() && IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimTarget))) { SetAverageBattlerPositions(gBattleAnimTarget, FALSE, &targetX, &targetY); @@ -3854,7 +3854,7 @@ static void AnimPerishSongMusicNote_Step2(struct Sprite *sprite) static void AnimGuardRing(struct Sprite *sprite) { - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker))) + if (IsDoubleBattle() && IsBattlerSpriteVisible(BATTLE_PARTNER(gBattleAnimAttacker))) { SetAverageBattlerPositions(gBattleAnimAttacker, FALSE, &sprite->x, &sprite->y); sprite->y += 40; diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c index 73c1e99448..e0b4820409 100644 --- a/src/battle_anim_mons.c +++ b/src/battle_anim_mons.c @@ -17,8 +17,6 @@ #include "util.h" #include "constants/battle_anim.h" -#define IS_DOUBLE_BATTLE() ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) - extern const struct OamData gOamData_AffineNormal_ObjNormal_64x64; static void AnimTranslateLinear_WithFollowup_SetCornerVecX(struct Sprite *sprite); @@ -868,11 +866,6 @@ bool8 IsBattlerSpritePresent(u8 battlerId) } } -bool8 IsDoubleBattle(void) -{ - return IS_DOUBLE_BATTLE(); -} - #define BG_ANIM_PAL_1 8 #define BG_ANIM_PAL_2 9 #define BG_ANIM_PAL_CONTEST 14 diff --git a/src/battle_anim_new.c b/src/battle_anim_new.c index f023859b59..e03ad2ace6 100644 --- a/src/battle_anim_new.c +++ b/src/battle_anim_new.c @@ -7250,7 +7250,7 @@ static u8 LoadBattleAnimTarget(u8 arg) { u8 battler; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { switch (gBattleAnimArgs[arg]) { @@ -7281,7 +7281,7 @@ static u8 LoadBattleAnimTarget(u8 arg) static u8 GetProperCentredCoord(u8 battler, u8 coordType) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) return (GetBattlerSpriteCoord2(battler, coordType) + GetBattlerSpriteCoord2(BATTLE_PARTNER(battler), coordType)) / 2; return GetBattlerSpriteCoord(battler, coordType); @@ -7471,14 +7471,14 @@ static void SpriteCB_SpriteToCentreOfSide(struct Sprite *sprite) if (gBattleAnimArgs[2] == 0) //Attacker { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) InitSpritePosToAnimAttackersCentre(sprite, var); else InitSpritePosToAnimAttacker(sprite, var); } else { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) InitSpritePosToAnimTargetsCentre(sprite, var); else InitSpritePosToAnimTarget(sprite, var); @@ -7562,7 +7562,7 @@ static void SpriteCB_GrowingSuperpower(struct Sprite *sprite) static void SpriteCB_CentredSpiderWeb(struct Sprite *sprite) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) InitSpritePosToAnimTargetsCentre(sprite, FALSE); else InitSpritePosToAnimTarget(sprite, FALSE); @@ -7576,14 +7576,14 @@ static void SpriteCB_CoreEnforcerHits(struct Sprite *sprite) if (gBattleAnimArgs[2] == 0) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) InitSpritePosToAnimAttackersCentre(sprite, FALSE); else InitSpritePosToAnimAttacker(sprite, FALSE); } else { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) InitSpritePosToAnimTargetsCentre(sprite, FALSE); else InitSpritePosToAnimTarget(sprite, FALSE); @@ -7595,7 +7595,7 @@ static void SpriteCB_CoreEnforcerHits(struct Sprite *sprite) static void SpriteCB_CoreEnforcerBeam(struct Sprite *sprite) { - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (!IsDoubleBattle()) { AnimSolarBeamBigOrb(sprite); } @@ -7867,14 +7867,14 @@ void SpriteCB_RandomCentredHits(struct Sprite *sprite) if (gBattleAnimArgs[0] == 0) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) InitSpritePosToAnimAttackersCentre(sprite, FALSE); else InitSpritePosToAnimAttacker(sprite, FALSE); } else { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) InitSpritePosToAnimTargetsCentre(sprite, FALSE); else InitSpritePosToAnimTarget(sprite, FALSE); @@ -8179,7 +8179,7 @@ static void SpriteCB_BeamUpStep(struct Sprite *sprite) static void SpriteCB_CentredElectricity(struct Sprite *sprite) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) InitSpritePosToAnimTargetsCentre(sprite, FALSE); else InitSpritePosToAnimTarget(sprite, FALSE); diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index a5dc6f3af1..b555711933 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -581,7 +581,7 @@ static void OpponentHandleChooseMove(u32 battler) if (GetBattlerMoveTargetType(battler, move) & (MOVE_TARGET_USER_OR_SELECTED | MOVE_TARGET_USER)) BtlController_EmitTwoReturnValues(battler, BUFFER_B, 10, (chosenMoveId) | (battler << 8)); - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + else if (IsDoubleBattle()) { do { target = GetBattlerAtPosition(Random() & 2); @@ -653,7 +653,7 @@ static void OpponentHandleChoosePokemon(u32 battler) { s32 battler1, battler2, firstId, lastId; - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (!IsDoubleBattle()) { battler2 = battler1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); } diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 5dae29563d..8760252c67 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -44,6 +44,7 @@ #include "level_caps.h" #include "menu.h" #include "pokemon_summary_screen.h" +#include "type_icons.h" static void PlayerBufferExecCompleted(u32 battler); static void PlayerHandleLoadMonSprite(u32 battler); @@ -59,7 +60,6 @@ static void PlayerHandlePrintString(u32 battler); static void PlayerHandlePrintSelectionString(u32 battler); static void PlayerHandleChooseAction(u32 battler); static void PlayerHandleYesNoBox(u32 battler); -static void PlayerHandleChooseMove(u32 battler); static void PlayerHandleChooseItem(u32 battler); static void PlayerHandleChoosePokemon(u32 battler); static void PlayerHandleCmd23(u32 battler); @@ -81,14 +81,11 @@ static void PlayerHandleEndLinkBattle(u32 battler); static void PlayerHandleBattleDebug(u32 battler); static void PlayerBufferRunCommand(u32 battler); -static void HandleInputChooseTarget(u32 battler); -static void HandleInputChooseMove(u32 battler); static void MoveSelectionDisplayPpNumber(u32 battler); static void MoveSelectionDisplayPpString(u32 battler); static void MoveSelectionDisplayMoveType(u32 battler); static void MoveSelectionDisplayMoveNames(u32 battler); static void MoveSelectionDisplayMoveDescription(u32 battler); -static void HandleMoveSwitching(u32 battler); static void SwitchIn_HandleSoundAndEnd(u32 battler); static void WaitForMonSelection(u32 battler); static void CompleteWhenChoseItem(u32 battler); @@ -382,7 +379,7 @@ static void HandleInputChooseAction(u32 battler) } else if (JOY_NEW(B_BUTTON) || gPlayerDpadHoldFrames > 59) { - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle() && GetBattlerPosition(battler) == B_POSITION_PLAYER_RIGHT && !(gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) @@ -426,7 +423,7 @@ static void HandleInputChooseAction(u32 battler) } } -static void HandleInputChooseTarget(u32 battler) +void HandleInputChooseTarget(u32 battler) { s32 i; static const u8 identities[MAX_BATTLERS_COUNT] = {B_POSITION_PLAYER_LEFT, B_POSITION_PLAYER_RIGHT, B_POSITION_OPPONENT_RIGHT, B_POSITION_OPPONENT_LEFT}; @@ -662,7 +659,7 @@ static void TryShowAsTarget(u32 battler) } } -static void HandleInputChooseMove(u32 battler) +void HandleInputChooseMove(u32 battler) { u16 moveTarget; u32 canSelectTarget = 0; @@ -968,7 +965,7 @@ static u32 UNUSED HandleMoveInputUnused(u32 battler) return var; } -static void HandleMoveSwitching(u32 battler) +void HandleMoveSwitching(u32 battler) { u8 perMovePPBonuses[MAX_MON_MOVES]; struct ChooseMoveStruct moveStruct; @@ -1757,7 +1754,7 @@ static void MoveSelectionDisplayMoveType(u32 battler) } else { - end = StringCopy(txtPtr, gTypesInfo[type].name); + end = StringCopy(txtPtr, gTypesInfo[type].name); } PrependFontIdToFit(txtPtr, end, FONT_NORMAL, WindowWidthPx(B_WIN_MOVE_TYPE) - 25); @@ -2075,7 +2072,7 @@ static void PlayerHandleYesNoBox(u32 battler) } } -static void HandleChooseMoveAfterDma3(u32 battler) +void HandleChooseMoveAfterDma3(u32 battler) { if (!IsDma3ManagerBusyWithBgCopy()) { @@ -2097,7 +2094,7 @@ static void PlayerChooseMoveInBattlePalace(u32 battler) } } -static void PlayerHandleChooseMove(u32 battler) +void PlayerHandleChooseMove(u32 battler) { if (gBattleTypeFlags & BATTLE_TYPE_PALACE) { @@ -2125,6 +2122,7 @@ static void PlayerHandleChooseMove(u32 battler) void InitMoveSelectionsVarsAndStrings(u32 battler) { + LoadTypeIcons(battler); MoveSelectionDisplayMoveNames(battler); gMultiUsePlayerCursor = 0xFF; MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); diff --git a/src/battle_controllers.c b/src/battle_controllers.c index fae42939d0..e11406831b 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -175,7 +175,7 @@ static void InitSinglePlayerBtlControllers(void) gBattlerPartyIndexes[3] = 3; } } - else if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + else if (!IsDoubleBattle()) { gBattleMainFunc = BeginBattleIntro; @@ -417,7 +417,7 @@ static void InitLinkBtlControllers(void) s32 i; u8 multiplayerId; - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (!IsDoubleBattle()) { if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER) { @@ -442,7 +442,7 @@ static void InitLinkBtlControllers(void) gBattlersCount = 2; } } - else if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + else if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI) && IsDoubleBattle()) { if (gBattleTypeFlags & BATTLE_TYPE_IS_MASTER) { @@ -610,7 +610,7 @@ static void InitLinkBtlControllers(void) bool32 IsValidForBattle(struct Pokemon *mon) { u32 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG); - return (species != SPECIES_NONE + return (species != SPECIES_NONE && species != SPECIES_EGG && GetMonData(mon, MON_DATA_HP) != 0 && GetMonData(mon, MON_DATA_IS_EGG) == FALSE); diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index cb3349ee32..b396f1d7b5 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -309,7 +309,7 @@ static u8 GetBattlePalaceMoveGroup(u8 battler, u16 move) static u16 GetBattlePalaceTarget(u32 battler) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { u8 opposing1, opposing2; diff --git a/src/battle_gimmick.c b/src/battle_gimmick.c index c8ee932218..2595e4cbda 100644 --- a/src/battle_gimmick.c +++ b/src/battle_gimmick.c @@ -96,7 +96,7 @@ bool32 ShouldTrainerBattlerUseGimmick(u32 battler, enum Gimmick gimmick) bool32 HasTrainerUsedGimmick(u32 battler, enum Gimmick gimmick) { // Check whether partner battler has used gimmick or plans to during turn. - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + if (IsDoubleBattle() && IsPartnerMonFromSameTrainer(battler) && (gBattleStruct->gimmick.activated[BATTLE_PARTNER(battler)][gimmick] || ((gBattleStruct->gimmick.toActivate & gBitTable[BATTLE_PARTNER(battler)] @@ -115,7 +115,7 @@ bool32 HasTrainerUsedGimmick(u32 battler, enum Gimmick gimmick) void SetGimmickAsActivated(u32 battler, enum Gimmick gimmick) { gBattleStruct->gimmick.activated[battler][gimmick] = TRUE; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsPartnerMonFromSameTrainer(battler)) + if (IsDoubleBattle() && IsPartnerMonFromSameTrainer(battler)) gBattleStruct->gimmick.activated[BATTLE_PARTNER(battler)][gimmick] = TRUE; } @@ -155,7 +155,7 @@ void CreateGimmickTriggerSprite(u32 battler) if (gBattleStruct->gimmick.triggerSpriteId == 0xFF) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) gBattleStruct->gimmick.triggerSpriteId = CreateSprite(gimmick->triggerTemplate, gSprites[gHealthboxSpriteIds[battler]].x - DOUBLES_GIMMICK_TRIGGER_POS_X_SLIDE, gSprites[gHealthboxSpriteIds[battler]].y - DOUBLES_GIMMICK_TRIGGER_POS_Y_DIFF, 0); @@ -204,7 +204,7 @@ static void SpriteCb_GimmickTrigger(struct Sprite *sprite) s32 xSlide, xPriority, xOptimal; s32 yDiff; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { xSlide = DOUBLES_GIMMICK_TRIGGER_POS_X_SLIDE; xPriority = DOUBLES_GIMMICK_TRIGGER_POS_X_PRIORITY; diff --git a/src/battle_main.c b/src/battle_main.c index 23047107b8..54da8223af 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4136,7 +4136,7 @@ void SwitchPartyOrder(u32 battler) partyId2 = GetPartyIdFromBattlePartyId(*(gBattleStruct->monToSwitchIntoId + battler)); SwitchPartyMonSlots(partyId1, partyId2); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { for (i = 0; i < (int)ARRAY_COUNT(gBattlePartyCurrentOrder); i++) { @@ -4277,7 +4277,7 @@ static void HandleTurnActionSelectionState(void) i); } - BtlController_EmitChooseMove(battler, BUFFER_A, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0, FALSE, &moveInfo); + BtlController_EmitChooseMove(battler, BUFFER_A, IsDoubleBattle() != 0, FALSE, &moveInfo); MarkBattlerForControllerExec(battler); } break; @@ -4570,7 +4570,7 @@ static void HandleTurnActionSelectionState(void) else i = FALSE; - if (((gBattleTypeFlags & BATTLE_TYPE_MULTI) || !(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (((gBattleTypeFlags & BATTLE_TYPE_MULTI) || !IsDoubleBattle()) || (position & BIT_FLANK) != B_FLANK_LEFT || (*(&gBattleStruct->absentBattlerFlags) & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(position))])) { diff --git a/src/battle_message.c b/src/battle_message.c index 87ac5326fb..b1c536b865 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -2826,7 +2826,7 @@ void BufferStringBattle(u16 stringID, u32 battler) { if (gBattleTypeFlags & BATTLE_TYPE_LEGENDARY) stringPtr = sText_LegendaryPkmnAppeared; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)]])) + else if (IsDoubleBattle() && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)]])) stringPtr = sText_TwoWildPkmnAppeared; else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL) stringPtr = sText_WildPkmnAppearedPause; @@ -2837,7 +2837,7 @@ void BufferStringBattle(u16 stringID, u32 battler) case STRINGID_INTROSENDOUT: // poke first send-out if (GetBattlerSide(battler) == B_SIDE_PLAYER) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsValidForBattle(&gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]])) + if (IsDoubleBattle() && IsValidForBattle(&gPlayerParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]])) { if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER) stringPtr = sText_InGamePartnerSentOutZGoN; @@ -2855,7 +2855,7 @@ void BufferStringBattle(u16 stringID, u32 battler) } else { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]])) + if (IsDoubleBattle() && IsValidForBattle(&gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battler)]])) { if (BATTLE_TWO_VS_ONE_OPPONENT) stringPtr = sText_Trainer1SentOutTwoPkmn; @@ -2886,7 +2886,7 @@ void BufferStringBattle(u16 stringID, u32 battler) { if (*(&gBattleStruct->hpScale) == 0) stringPtr = sText_PkmnThatsEnough; - else if (*(&gBattleStruct->hpScale) == 1 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + else if (*(&gBattleStruct->hpScale) == 1 || IsDoubleBattle()) stringPtr = sText_PkmnComeBack; else if (*(&gBattleStruct->hpScale) == 2) stringPtr = sText_PkmnOkComeBack; @@ -2911,7 +2911,7 @@ void BufferStringBattle(u16 stringID, u32 battler) case STRINGID_SWITCHINMON: // switch-in msg if (GetBattlerSide(gBattleScripting.battler) == B_SIDE_PLAYER) { - if (*(&gBattleStruct->hpScale) == 0 || gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (*(&gBattleStruct->hpScale) == 0 || IsDoubleBattle()) stringPtr = sText_GoPkmn2; else if (*(&gBattleStruct->hpScale) == 1) stringPtr = sText_DoItPkmn; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 575e1cd043..396521f5a0 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1752,7 +1752,7 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u return; } - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && + if (IsDoubleBattle() && (moveTarget == MOVE_TARGET_BOTH || moveTarget == MOVE_TARGET_FOES_AND_ALLY)) gBattleCommunication[MISS_TYPE] = B_MSG_AVOIDED_ATK; else @@ -2498,7 +2498,7 @@ static void Cmd_resultmessage(void) if (gMoveResultFlags & MOVE_RESULT_MISSED && (!(gMoveResultFlags & MOVE_RESULT_DOESNT_AFFECT_FOE) || gBattleCommunication[MISS_TYPE] > B_MSG_AVOIDED_ATK)) { if (gBattleCommunication[MISS_TYPE] > B_MSG_AVOIDED_ATK) // Wonder Guard or Levitate - show the ability pop-up - CreateAbilityPopUp(gBattlerTarget, gBattleMons[gBattlerTarget].ability, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0); + CreateAbilityPopUp(gBattlerTarget, gBattleMons[gBattlerTarget].ability, (IsDoubleBattle()) != 0); stringId = gMissStringIds[gBattleCommunication[MISS_TYPE]]; gBattleCommunication[MSG_DISPLAY] = 1; } @@ -4352,7 +4352,7 @@ static void Cmd_getexp(void) { // Music change in a wild battle after fainting opposing pokemon. if (!(gBattleTypeFlags & BATTLE_TYPE_TRAINER) - && (gBattleMons[0].hp || (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattleMons[2].hp)) + && (gBattleMons[0].hp || (IsDoubleBattle() && gBattleMons[2].hp)) && !IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)) && !IsBattlerAlive(GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT)) && !gBattleStruct->wildVictorySong) @@ -4403,7 +4403,7 @@ static void Cmd_getexp(void) } // get exp getter battler - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { if (gBattlerPartyIndexes[2] == *expMonId && !(gAbsentBattlerFlags & gBitTable[2])) gBattleStruct->expGetterBattlerId = 2; @@ -4483,7 +4483,7 @@ static void Cmd_getexp(void) // update battle mon structure after level up if (gBattlerPartyIndexes[0] == *expMonId && gBattleMons[0].hp) battler = 0; - else if (gBattlerPartyIndexes[2] == *expMonId && gBattleMons[2].hp && (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + else if (gBattlerPartyIndexes[2] == *expMonId && gBattleMons[2].hp && (IsDoubleBattle())) battler = 2; if (battler != 0xFF) @@ -5919,7 +5919,7 @@ static void Cmd_moveend(void) gBattleStruct->targetsDone[gBattlerAttacker] |= gBitTable[gBattlerTarget]; if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) - && gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && IsDoubleBattle() && !gProtectStructs[gBattlerAttacker].chargingTurn && (moveTarget == MOVE_TARGET_BOTH || moveTarget == MOVE_TARGET_FOES_AND_ALLY) @@ -6689,7 +6689,7 @@ bool32 CanBattlerSwitch(u32 battler) { battlerIn1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) battlerIn2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); else battlerIn2 = battlerIn1; @@ -6701,7 +6701,7 @@ bool32 CanBattlerSwitch(u32 battler) // Check if attacker side has mon to switch into battlerIn1 = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) battlerIn2 = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); else battlerIn2 = battlerIn1; @@ -6765,7 +6765,7 @@ static void Cmd_openpartyscreen(void) if (cmd->battler == BS_FAINTED_MULTIPLE_1) { - if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) || !(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if ((gBattleTypeFlags & BATTLE_TYPE_MULTI) || !(IsDoubleBattle())) { for (battler = 0; battler < gBattlersCount; battler++) { @@ -6791,7 +6791,7 @@ static void Cmd_openpartyscreen(void) } } } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + else if (IsDoubleBattle()) { bool8 hasReplacement_0, hasReplacement_1, hasReplacement_2, hasReplacement_3; @@ -6922,7 +6922,7 @@ static void Cmd_openpartyscreen(void) { if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { hitmarkerFaintBits = gHitMarker >> 28; if (gBitTable[2] & hitmarkerFaintBits && gBitTable[0] & hitmarkerFaintBits) @@ -7466,7 +7466,7 @@ static void Cmd_handlelearnnewmove(void) { GiveMoveToBattleMon(&gBattleMons[battler], learnMove); } - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { battler = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); if (gBattlerPartyIndexes[battler] == monId @@ -7572,7 +7572,7 @@ static void Cmd_yesnoboxlearnmove(void) RemoveBattleMonPPBonus(&gBattleMons[0], movePosition); SetBattleMonMoveSlot(&gBattleMons[0], gMoveToLearn, movePosition); } - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + if (IsDoubleBattle() && gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId && MOVE_IS_PERMANENT(2, movePosition)) { @@ -7686,7 +7686,7 @@ static u32 GetTrainerMoneyToGive(u16 trainerId) if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS) moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * trainerMoney; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + else if (IsDoubleBattle()) moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * 2 * trainerMoney; else moneyReward = 4 * lastMonLevel * gBattleStruct->moneyMultiplier * trainerMoney; @@ -8352,7 +8352,7 @@ static bool32 IsMonGettingExpSentOut(void) { if (gBattlerPartyIndexes[0] == gBattleStruct->expGetterMonId) return TRUE; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId) + if (IsDoubleBattle() && gBattlerPartyIndexes[2] == gBattleStruct->expGetterMonId) return TRUE; return FALSE; @@ -8425,7 +8425,7 @@ static void Cmd_hpthresholds(void) { CMD_ARGS(u8 battler); - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (!(IsDoubleBattle())) { u32 battler = GetBattlerForBattleScript(cmd->battler); u32 opposingBattler = BATTLE_OPPOSITE(battler); @@ -8451,7 +8451,7 @@ static void Cmd_hpthresholds2(void) { CMD_ARGS(u8 battler); - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (!(IsDoubleBattle())) { u32 battler = GetBattlerForBattleScript(cmd->battler); u32 opposingBattler = BATTLE_OPPOSITE(battler); @@ -9931,7 +9931,7 @@ static void Cmd_various(void) case VARIOUS_ABILITY_POPUP: { VARIOUS_ARGS(); - CreateAbilityPopUp(battler, gBattleMons[battler].ability, (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) != 0); + CreateAbilityPopUp(battler, gBattleMons[battler].ability, (IsDoubleBattle()) != 0); break; } case VARIOUS_UPDATE_ABILITY_POPUP: @@ -10125,7 +10125,7 @@ static void Cmd_various(void) gSideTimers[GetBattlerSide(battler)].auroraVeilTimer = 5; gSideTimers[GetBattlerSide(battler)].auroraVeilBattlerId = battler; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) + if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) gBattleCommunication[MULTISTRING_CHOOSER] = 5; else gBattleCommunication[MULTISTRING_CHOOSER] = 5; @@ -10301,7 +10301,7 @@ static void Cmd_various(void) case VARIOUS_JUMP_IF_TEAM_HEALTHY: { VARIOUS_ARGS(const u8 *jumpInstr); - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && IsBattlerAlive(BATTLE_PARTNER(battler))) + if ((IsDoubleBattle()) && IsBattlerAlive(BATTLE_PARTNER(battler))) { u8 partner = BATTLE_PARTNER(battler); if ((gBattleMons[battler].hp == gBattleMons[battler].maxHP && !(gBattleMons[battler].status1 & STATUS1_ANY)) @@ -10914,7 +10914,7 @@ static void Cmd_various(void) PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gSelectedMonPartyId], MON_DATA_SPECIES)); // If an on-field battler is revived, it needs to be sent out again. - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && + if (IsDoubleBattle() && gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)] == gSelectedMonPartyId) { gBattleScripting.battler = BATTLE_PARTNER(gBattlerAttacker); @@ -11233,7 +11233,7 @@ static void Cmd_setreflect(void) gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectTimer = 5; gSideTimers[GetBattlerSide(gBattlerAttacker)].reflectBattlerId = gBattlerAttacker; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) + if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_DOUBLE; else gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_REFLECT_SINGLE; @@ -12097,7 +12097,7 @@ static void Cmd_forcerandomswitch(void) battler2PartyId = gBattlerPartyIndexes[gBattlerTarget]; battler1PartyId = gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerTarget)]; } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + else if (IsDoubleBattle()) { firstMonId = 0; lastMonId = PARTY_SIZE; @@ -12295,7 +12295,7 @@ static void Cmd_setlightscreen(void) gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenTimer = 5; gSideTimers[GetBattlerSide(gBattlerAttacker)].lightscreenBattlerId = gBattlerAttacker; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) + if (IsDoubleBattle() && CountAliveMonsInBattle(BATTLE_ALIVE_SIDE, gBattlerAttacker) == 2) gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_DOUBLE; else gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SET_LIGHTSCREEN_SINGLE; @@ -12465,7 +12465,7 @@ static void Cmd_updatestatusicon(void) BtlController_EmitStatusIconUpdate(battler, BUFFER_A, gBattleMons[battler].status1, gBattleMons[battler].status2); MarkBattlerForControllerExec(battler); } - if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if ((IsDoubleBattle())) { battler = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker))); if (!(gAbsentBattlerFlags & gBitTable[battler])) @@ -12502,7 +12502,7 @@ static void Cmd_setfocusenergy(void) CMD_ARGS(u8 battler); u8 battler = GetBattlerForBattleScript(cmd->battler); - if ((gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || (gAbsentBattlerFlags & gBitTable[battler]))) + if ((gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && (!(IsDoubleBattle()) || (gAbsentBattlerFlags & gBitTable[battler]))) || gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY) { gMoveResultFlags |= MOVE_RESULT_FAILED; @@ -13245,7 +13245,7 @@ static void Cmd_healpartystatus(void) gBattleMons[gBattlerAttacker].status1 = 0; gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + if (IsDoubleBattle() && !(gAbsentBattlerFlags & gBitTable[partner])) { gBattleMons[partner].status1 = 0; @@ -14088,7 +14088,7 @@ static void Cmd_trysethelpinghand(void) gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker))); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + if (IsDoubleBattle() && !(gAbsentBattlerFlags & gBitTable[gBattlerTarget]) && !gProtectStructs[gBattlerAttacker].helpingHand && !gProtectStructs[gBattlerTarget].helpingHand) @@ -14910,7 +14910,7 @@ static void Cmd_pursuitdoubles(void) u32 battler = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker))); - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + if (IsDoubleBattle() && !(gAbsentBattlerFlags & gBitTable[battler]) && gChosenActionByBattler[battler] == B_ACTION_USE_MOVE && gMovesInfo[gChosenMoveByBattler[battler]].effect == EFFECT_PURSUIT) @@ -15908,7 +15908,7 @@ bool32 IsMoveAffectedByParentalBond(u32 move, u32 battler) && gMovesInfo[move].strikeCount < 2 && gMovesInfo[move].effect != EFFECT_MULTI_HIT) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { switch (GetBattlerMoveTargetType(battler, move)) { @@ -16025,7 +16025,7 @@ void BS_SetZEffect(void) static void TryUpdateRoundTurnOrder(void) { - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { u32 i; u32 j = 0; @@ -16163,8 +16163,7 @@ void BS_ItemRestoreHP(void) // Check if the recipient is an active battler. if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker]) battler = gBattlerAttacker; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)]) + else if (IsDoubleBattle() && gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)]) battler = BATTLE_PARTNER(gBattlerAttacker); // Get amount to heal. @@ -16201,7 +16200,7 @@ void BS_ItemRestoreHP(void) SetMonData(&party[gBattleStruct->itemPartyIndex[gBattlerAttacker]], MON_DATA_HP, &hp); // Revived battlers on the field need to be brought back. - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && battler != MAX_BATTLERS_COUNT) + if (IsDoubleBattle() && battler != MAX_BATTLERS_COUNT) { gAbsentBattlerFlags &= ~gBitTable[battler]; gBattleMons[battler].hp = hp; @@ -16227,7 +16226,7 @@ void BS_ItemCureStatus(void) previousStatus2 = gBattleMons[battler].status2; gBattleMons[gBattlerAttacker].status2 &= ~GetItemStatus2Mask(gLastUsedItem); } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + else if (IsDoubleBattle() && gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)]) { battler = BATTLE_PARTNER(gBattlerAttacker); @@ -16292,7 +16291,7 @@ void BS_ItemRestorePP(void) // Check if the recipient is an active battler. if (gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[gBattlerAttacker]) battler = gBattlerAttacker; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + else if (IsDoubleBattle() && gBattleStruct->itemPartyIndex[gBattlerAttacker] == gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)]) battler = BATTLE_PARTNER(gBattlerAttacker); @@ -16623,7 +16622,7 @@ void BS_SetPledge(void) gBattleCommunication[MSG_DISPLAY] = 0; } else if ((gChosenActionByBattler[partner] == B_ACTION_USE_MOVE) - && gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && IsDoubleBattle() && IsBattlerAlive(partner) && gCurrentMove != partnerMove && gMovesInfo[partnerMove].effect == EFFECT_PLEDGE) diff --git a/src/battle_terastal.c b/src/battle_terastal.c index 6866c6aaad..c0540f5aa3 100644 --- a/src/battle_terastal.c +++ b/src/battle_terastal.c @@ -30,7 +30,7 @@ void ActivateTera(u32 battler) if (B_FLAG_TERA_ORB_CHARGED != 0 && (B_FLAG_TERA_ORB_NO_COST == 0 || !FlagGet(B_FLAG_TERA_ORB_NO_COST)) && side == B_SIDE_PLAYER - && !(gBattleTypeFlags & BATTLE_TYPE_DOUBLE && !IsPartnerMonFromSameTrainer(battler))) + && !(IsDoubleBattle() && !IsPartnerMonFromSameTrainer(battler))) { FlagClear(B_FLAG_TERA_ORB_CHARGED); } diff --git a/src/battle_util.c b/src/battle_util.c index 3d9338acee..24095c08ed 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -221,7 +221,7 @@ void HandleAction_UseMove(void) { gBattleStruct->moveTarget[gBattlerAttacker] = gBattlerTarget = gSideTimers[side].followmeTarget; // follow me moxie fix } - else if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + else if (IsDoubleBattle() && gSideTimers[side].followmeTimer == 0 && (gMovesInfo[gCurrentMove].power != 0 || (moveTarget != MOVE_TARGET_USER && moveTarget != MOVE_TARGET_ALL_BATTLERS)) && ((GetBattlerAbility(*(gBattleStruct->moveTarget + gBattlerAttacker)) != ABILITY_LIGHTNING_ROD && moveType == TYPE_ELECTRIC) @@ -305,8 +305,7 @@ void HandleAction_UseMove(void) gBattlerTarget = battler; } } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && moveTarget & MOVE_TARGET_RANDOM) + else if (IsDoubleBattle() && moveTarget & MOVE_TARGET_RANDOM) { if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) { @@ -336,8 +335,7 @@ void HandleAction_UseMove(void) else gBattlerTarget = gBattlerAttacker; } - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE - && moveTarget == MOVE_TARGET_FOES_AND_ALLY) + else if (IsDoubleBattle() && moveTarget == MOVE_TARGET_FOES_AND_ALLY) { for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount; gBattlerTarget++) { @@ -3744,7 +3742,7 @@ bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2 u32 i, side, playerId, flankId; struct Pokemon *party; - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (!IsDoubleBattle()) return FALSE; side = GetBattlerSide(battler); @@ -4328,7 +4326,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 target1 = GetBattlerAtPosition(side); target2 = GetBattlerAtPosition(side + BIT_FLANK); gSpecialStatuses[battler].switchInAbilityDone = TRUE; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { if (!gAbilitiesInfo[gBattleMons[target1].ability].cantBeTraced && gBattleMons[target1].hp != 0 && !gAbilitiesInfo[gBattleMons[target2].ability].cantBeTraced && gBattleMons[target2].hp != 0) @@ -5177,7 +5175,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && BlocksPrankster(move, gBattlerAttacker, gBattlerTarget, TRUE) && !(IS_MOVE_STATUS(move) && (gLastUsedAbility == ABILITY_MAGIC_BOUNCE || gProtectStructs[gBattlerTarget].bounceMove))) { - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE) || !(moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) + if (!IsDoubleBattle() || !(moveTarget & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) CancelMultiTurnMoves(gBattlerAttacker); // Don't cancel moves that can hit two targets bc one target might not be protected gBattleScripting.battler = gBattlerAbility = gBattlerTarget; battleScriptBlocksMove = BattleScript_DarkTypePreventsPrankster; @@ -8252,7 +8250,7 @@ u32 SetRandomTarget(u32 battler) [B_SIDE_OPPONENT] = {B_POSITION_PLAYER_LEFT, B_POSITION_PLAYER_RIGHT}, }; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { target = GetBattlerAtPosition(targets[GetBattlerSide(battler)][Random() % 2]); if (!IsBattlerAlive(target)) @@ -8317,7 +8315,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget) side = BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker)); if (IsAffectedByFollowMe(gBattlerAttacker, side, move)) targetBattler = gSideTimers[side].followmeTarget; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE && moveTarget & MOVE_TARGET_RANDOM) + else if (IsDoubleBattle() && moveTarget & MOVE_TARGET_RANDOM) targetBattler = SetRandomTarget(gBattlerAttacker); else targetBattler = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker))); @@ -9983,7 +9981,7 @@ static inline uq4_12_t GetScreensModifier(u32 move, u32 battlerAtk, u32 battlerD if (isCrit || abilityAtk == ABILITY_INFILTRATOR || gProtectStructs[battlerAtk].confusionSelfDmg) return UQ_4_12(1.0); if (reflect || lightScreen || auroraVeil) - return (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) ? UQ_4_12(0.667) : UQ_4_12(0.5); + return (IsDoubleBattle()) ? UQ_4_12(0.667) : UQ_4_12(0.5); return UQ_4_12(1.0); } @@ -11787,7 +11785,7 @@ void SetShellSideArmCategory(void) bool32 CanTargetPartner(u32 battlerAtk, u32 battlerDef) { - return (gBattleTypeFlags & BATTLE_TYPE_DOUBLE + return (IsDoubleBattle() && IsBattlerAlive(BATTLE_PARTNER(battlerDef)) && battlerDef != BATTLE_PARTNER(battlerAtk)); } diff --git a/src/battle_util2.c b/src/battle_util2.c index 2c333978d2..326acf0e40 100644 --- a/src/battle_util2.c +++ b/src/battle_util2.c @@ -80,7 +80,7 @@ void AdjustFriendshipOnBattleFaint(u8 battler) { u8 opposingBattlerId; - if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + if (IsDoubleBattle()) { u8 opposingBattlerId2; diff --git a/src/data/types_info.h b/src/data/types_info.h index f9bd233ca6..df74199bdd 100644 --- a/src/data/types_info.h +++ b/src/data/types_info.h @@ -60,6 +60,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB_WHITE, .damageCategory = DAMAGE_CATEGORY_PHYSICAL, .paletteTMHM = gItemIconPalette_NormalTMHM, + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = TRUE, }, [TYPE_NORMAL] = { @@ -71,6 +73,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB_WHITE, // custom .damageCategory = DAMAGE_CATEGORY_PHYSICAL, .paletteTMHM = gItemIconPalette_NormalTMHM, + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_SILK_SCARF, //.berry = ITEM_CHILAN_BERRY, //.gem = ITEM_NORMAL_GEM, @@ -88,6 +92,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(26, 8, 14), .damageCategory = DAMAGE_CATEGORY_PHYSICAL, .paletteTMHM = gItemIconPalette_FightingTMHM, + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_BLACK_BELT, //.berry = ITEM_CHOPLE_BERRY, //.gem = ITEM_FIGHTING_GEM, @@ -107,6 +113,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(31, 26, 7), .damageCategory = DAMAGE_CATEGORY_PHYSICAL, .paletteTMHM = gItemIconPalette_FlyingTMHM, + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_SHARP_BEAK, //.berry = ITEM_COBA_BERRY, //.gem = ITEM_FLYING_GEM, @@ -126,6 +134,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(26, 10, 25), // custom .damageCategory = DAMAGE_CATEGORY_PHYSICAL, .paletteTMHM = gItemIconPalette_PoisonTMHM, + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_POISON_BARB, //.berry = ITEM_KEBIA_BERRY, //.gem = ITEM_POISON_GEM, @@ -145,6 +155,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(25, 23, 18), .damageCategory = DAMAGE_CATEGORY_PHYSICAL, .paletteTMHM = gItemIconPalette_GroundTMHM, + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_SOFT_SAND, //.berry = ITEM_SHUCA_BERRY, //.gem = ITEM_GROUND_GEM, @@ -164,6 +176,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(18, 16, 8), // custom .damageCategory = DAMAGE_CATEGORY_PHYSICAL, .paletteTMHM = gItemIconPalette_RockTMHM, + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_HARD_STONE, //.berry = ITEM_CHARTI_BERRY, //.gem = ITEM_ROCK_GEM, @@ -183,6 +197,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(18, 24, 6), .damageCategory = DAMAGE_CATEGORY_PHYSICAL, .paletteTMHM = gItemIconPalette_BugTMHM, + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_SILVER_POWDER, //.berry = ITEM_TANGA_BERRY, //.gem = ITEM_BUG_GEM, @@ -202,6 +218,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(12, 10, 16), .damageCategory = DAMAGE_CATEGORY_PHYSICAL, .paletteTMHM = gItemIconPalette_GhostTMHM, + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_SPELL_TAG, //.berry = ITEM_KASIB_BERRY, //.gem = ITEM_GHOST_GEM, @@ -221,6 +239,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(19, 19, 20), .damageCategory = DAMAGE_CATEGORY_PHYSICAL, .paletteTMHM = gItemIconPalette_SteelTMHM, + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_METAL_COAT, //.berry = ITEM_BABIRI_BERRY, //.gem = ITEM_STEEL_GEM, @@ -237,6 +257,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .palette = 15, .teraTypeRGBValue = RGB_WHITE, .damageCategory = DAMAGE_CATEGORY_SPECIAL, + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = TRUE, }, [TYPE_FIRE] = { @@ -248,6 +270,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(31, 20, 11), .damageCategory = DAMAGE_CATEGORY_SPECIAL, .paletteTMHM = gItemIconPalette_FireTMHM, + .useSecondTypeIconPalette = TRUE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_CHARCOAL, //.berry = ITEM_OCCA_BERRY, //.gem = ITEM_FIRE_GEM, @@ -267,6 +291,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(10, 18, 27), .damageCategory = DAMAGE_CATEGORY_SPECIAL, .paletteTMHM = gItemIconPalette_WaterTMHM, + .useSecondTypeIconPalette = TRUE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_MYSTIC_WATER, //.berry = ITEM_PASSHO_BERRY, //.gem = ITEM_WATER_GEM, @@ -286,6 +312,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(12, 24, 11), .damageCategory = DAMAGE_CATEGORY_SPECIAL, .paletteTMHM = gItemIconPalette_GrassTMHM, + .useSecondTypeIconPalette = TRUE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_MIRACLE_SEED, //.berry = ITEM_RINDO_BERRY, //.gem = ITEM_GRASS_GEM, @@ -305,6 +333,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(30, 26, 7), .damageCategory = DAMAGE_CATEGORY_SPECIAL, .paletteTMHM = gItemIconPalette_ElectricTMHM, + .useSecondTypeIconPalette = TRUE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_MAGNET, //.berry = ITEM_WACAN_BERRY, //.gem = ITEM_ELECTRIC_GEM, @@ -324,6 +354,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(31, 14, 15), .damageCategory = DAMAGE_CATEGORY_SPECIAL, .paletteTMHM = gItemIconPalette_PsychicTMHM, + .useSecondTypeIconPalette = TRUE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_TWISTED_SPOON, //.berry = ITEM_PAYAPA_BERRY, //.gem = ITEM_PSYCHIC_GEM, @@ -343,6 +375,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(14, 26, 25), .damageCategory = DAMAGE_CATEGORY_SPECIAL, .paletteTMHM = gItemIconPalette_IceTMHM, + .useSecondTypeIconPalette = TRUE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_NEVER_MELT_ICE, //.berry = ITEM_YACHE_BERRY, //.gem = ITEM_ICE_GEM, @@ -362,6 +396,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(10, 18, 27), .damageCategory = DAMAGE_CATEGORY_SPECIAL, .paletteTMHM = gItemIconPalette_DragonTMHM, + .useSecondTypeIconPalette = TRUE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_DRAGON_FANG, //.berry = ITEM_HABAN_BERRY, //.gem = ITEM_DRAGON_GEM, @@ -381,6 +417,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(6, 5, 8), .damageCategory = DAMAGE_CATEGORY_SPECIAL, .paletteTMHM = gItemIconPalette_DarkTMHM, + .useSecondTypeIconPalette = TRUE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_BLACK_GLASSES, //.berry = ITEM_COLBUR_BERRY, //.gem = ITEM_DARK_GEM, @@ -400,6 +438,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .teraTypeRGBValue = RGB(31, 15, 21), .damageCategory = DAMAGE_CATEGORY_SPECIAL, .paletteTMHM = gItemIconPalette_FairyTMHM, + .useSecondTypeIconPalette = TRUE, + .isSpecialCaseType = FALSE, //.enhanceItem = ITEM_FAIRY_FEATHER, //.berry = ITEM_ROSELI_BERRY, //.gem = ITEM_FAIRY_GEM, @@ -418,6 +458,8 @@ const struct TypeInfo gTypesInfo[NUMBER_OF_MON_TYPES] = .maxMove = MOVE_MAX_STRIKE, .teraTypeRGBValue = RGB(10, 18, 27), .paletteTMHM = gItemIconPalette_NormalTMHM, // failsafe + .useSecondTypeIconPalette = FALSE, + .isSpecialCaseType = TRUE, // .teraShard = ITEM_STELLAR_TERA_SHARD, }, }; diff --git a/src/graphics.c b/src/graphics.c index c35cec3467..9fb0771575 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -2048,3 +2048,9 @@ const u16 gFrontierPassCancelButtonHighlighted_Tilemap[] = INCBIN_U16("graphics/ const u16 gBerryCrush_Crusher_Pal[] = INCBIN_U16("graphics/berry_crush/crusher.gbapal"); const u32 gBerryCrush_Crusher_Gfx[] = INCBIN_U32("graphics/berry_crush/crusher.4bpp.lz"); const u32 gBerryCrush_TextWindows_Tilemap[] = INCBIN_U32("graphics/berry_crush/text_windows.bin.lz"); + +const u32 gBattleIcons_Gfx1[] = INCBIN_U32("graphics/types/battle_icons1.4bpp.lz"); +const u32 gBattleIcons_Gfx2[] = INCBIN_U32("graphics/types/battle_icons2.4bpp.lz"); +const u32 gBattleIcons_Pal1[] = INCBIN_U32("graphics/types/battle_icons1.gbapal.lz"); +const u32 gBattleIcons_Pal2[] = INCBIN_U32("graphics/types/battle_icons2.gbapal.lz"); + diff --git a/src/party_menu.c b/src/party_menu.c index 5214ddc2be..15433854a5 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -1353,7 +1353,7 @@ static void DrawCancelConfirmButtons(void) bool8 IsMultiBattle(void) { - if (gBattleTypeFlags & BATTLE_TYPE_MULTI && gBattleTypeFlags & BATTLE_TYPE_DOUBLE && gMain.inBattle) + if (gBattleTypeFlags & BATTLE_TYPE_MULTI && IsDoubleBattle() && gMain.inBattle) return TRUE; else return FALSE; diff --git a/src/pokemon.c b/src/pokemon.c index 78e19dfc8b..cfb2307126 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -2100,7 +2100,7 @@ u8 GetDefaultMoveTarget(u8 battlerId) { u8 opposing = BATTLE_OPPOSITE(GetBattlerSide(battlerId)); - if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE)) + if (!IsDoubleBattle()) return GetBattlerAtPosition(opposing); if (CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER, battlerId) > 1) { diff --git a/src/tv.c b/src/tv.c index e0f910eaaf..c0e207ce8a 100644 --- a/src/tv.c +++ b/src/tv.c @@ -1262,7 +1262,7 @@ void PutBattleUpdateOnTheAir(u8 opponentLinkPlayerId, u16 move, u16 speciesPlaye if (gBattleTypeFlags & BATTLE_TYPE_MULTI) show->battleUpdate.battleType = 2; - else if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE) + else if (IsDoubleBattle()) show->battleUpdate.battleType = 1; else show->battleUpdate.battleType = 0; diff --git a/src/type_icons.c b/src/type_icons.c new file mode 100644 index 0000000000..a36c347775 --- /dev/null +++ b/src/type_icons.c @@ -0,0 +1,516 @@ +#include "global.h" +#include "battle.h" +#include "battle_anim.h" +#include "battle_controllers.h" +#include "battle_gimmick.h" +#include "decompress.h" +#include "graphics.h" +#include "pokedex.h" +#include "sprite.h" +#include "type_icons.h" + +static void LoadTypeSpritesAndPalettes(void); +static void LoadTypeIconsPerBattler(u32, u32); + +static bool32 UseDoubleBattleCoords(u32); + +static u32 GetMonPublicType(u32, u32); +static bool32 ShouldHideUncaughtType(u32); +static u32 GetMonDefensiveTeraType(struct Pokemon *, struct Pokemon*, u32, u32, u32, u32); +static u32 IsIllusionActiveAndTypeUnchanged(struct Pokemon*, u32, u32); + +static void CreateSpriteFromType(u32, bool32, u32[], u32, u32); +static bool32 ShouldSkipSecondType(u32[], u32); +static void SetTypeIconXY(s32*, s32*, u32, bool32, u32); + +static void CreateSpriteAndSetTypeSpriteAttributes(u32, u32 x, u32 y, u32, u32, bool32); +static bool32 ShouldFlipTypeIcon(bool32, u32, u32); + +static void SpriteCB_TypeIcon(struct Sprite*); +static void DestroyTypeIcon(struct Sprite*); +static bool32 ShouldHideTypeIcon(u32); +static s32 GetTypeIconHideMovement(bool32, u32); +static s32 GetTypeIconSlideMovement(bool32, u32, s32); +static s32 GetTypeIconBounceMovement(s32, u32); + +const struct Coords16 sTypeIconPositions[][2] = +{ + [B_POSITION_PLAYER_LEFT] = + { + [FALSE] = {221, 86}, + [TRUE] = {144, 71}, + }, + [B_POSITION_OPPONENT_LEFT] = + { + [FALSE] = {20, 26}, + [TRUE] = {97, 14}, + }, + [B_POSITION_PLAYER_RIGHT] = + { + [TRUE] = {156, 96}, + }, + [B_POSITION_OPPONENT_RIGHT] = + { + [TRUE] = {85, 39}, + }, +}; + +const union AnimCmd sSpriteAnim_TypeIcon_Normal[] = +{ + ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_NORMAL), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Fighting[] = +{ + ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_FIGHTING), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Flying[] = +{ + ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_FLYING), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Poison[] = +{ + ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_POISON), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Ground[] = +{ + ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_GROUND), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Rock[] = +{ + ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_ROCK), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Bug[] = +{ + ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_BUG), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Ghost[] = +{ + ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_GHOST), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Steel[] = +{ + ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_STEEL), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Mystery[] = +{ + ANIMCMD_FRAME(TYPE_ICON_1_FRAME(TYPE_MYSTERY), 0), + ANIMCMD_END +}; + +const union AnimCmd sSpriteAnim_TypeIcon_Fire[] = +{ + ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_FIRE), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Water[] = +{ + ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_WATER), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Grass[] = +{ + ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_GRASS), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Electric[] = +{ + ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_ELECTRIC), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Psychic[] = +{ + ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_PSYCHIC), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Ice[] = +{ + ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_ICE), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Dragon[] = +{ + ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_DRAGON), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Dark[] = +{ + ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_DARK), 0), + ANIMCMD_END +}; +const union AnimCmd sSpriteAnim_TypeIcon_Fairy[] = +{ + ANIMCMD_FRAME(TYPE_ICON_2_FRAME(TYPE_FAIRY), 0), + ANIMCMD_END +}; + +const union AnimCmd *const sSpriteAnimTable_TypeIcons[] = +{ + [TYPE_NONE] = sSpriteAnim_TypeIcon_Mystery, + [TYPE_NORMAL] = sSpriteAnim_TypeIcon_Normal, + [TYPE_FIGHTING] = sSpriteAnim_TypeIcon_Fighting, + [TYPE_FLYING] = sSpriteAnim_TypeIcon_Flying, + [TYPE_POISON] = sSpriteAnim_TypeIcon_Poison, + [TYPE_GROUND] = sSpriteAnim_TypeIcon_Ground, + [TYPE_ROCK] = sSpriteAnim_TypeIcon_Rock, + [TYPE_BUG] = sSpriteAnim_TypeIcon_Bug, + [TYPE_GHOST] = sSpriteAnim_TypeIcon_Ghost, + [TYPE_STEEL] = sSpriteAnim_TypeIcon_Steel, + [TYPE_MYSTERY] = sSpriteAnim_TypeIcon_Mystery, + [TYPE_FIRE] = sSpriteAnim_TypeIcon_Fire, + [TYPE_WATER] = sSpriteAnim_TypeIcon_Water, + [TYPE_GRASS] = sSpriteAnim_TypeIcon_Grass, + [TYPE_ELECTRIC] = sSpriteAnim_TypeIcon_Electric, + [TYPE_PSYCHIC] = sSpriteAnim_TypeIcon_Psychic, + [TYPE_ICE] = sSpriteAnim_TypeIcon_Ice, + [TYPE_DRAGON] = sSpriteAnim_TypeIcon_Dragon, + [TYPE_DARK] = sSpriteAnim_TypeIcon_Dark, + [TYPE_FAIRY] = sSpriteAnim_TypeIcon_Fairy, + [TYPE_STELLAR] = sSpriteAnim_TypeIcon_Mystery, +}; + +const struct CompressedSpritePalette sTypeIconPal1 = +{ + .data = gBattleIcons_Pal1, + .tag = TYPE_ICON_TAG +}; + +const struct CompressedSpritePalette sTypeIconPal2 = +{ + .data = gBattleIcons_Pal2, + .tag = TYPE_ICON_TAG_2 +}; + +const struct OamData sOamData_TypeIcons = +{ + .affineMode = ST_OAM_AFFINE_OFF, + .objMode = ST_OAM_OBJ_NORMAL, + .shape = SPRITE_SHAPE(8x16), + .size = SPRITE_SIZE(8x16), + .priority = 1, +}; + +const struct CompressedSpriteSheet sSpriteSheet_TypeIcons2 = +{ + .data = gBattleIcons_Gfx2, + .size = (8*16) * 9, + .tag = TYPE_ICON_TAG_2, +}; + +const struct CompressedSpriteSheet sSpriteSheet_TypeIcons1 = +{ + .data = gBattleIcons_Gfx1, + .size = (8*16) * 10, + .tag = TYPE_ICON_TAG, +}; + +const struct SpriteTemplate sSpriteTemplate_TypeIcons1 = +{ + .tileTag = TYPE_ICON_TAG, + .paletteTag = TYPE_ICON_TAG, + .oam = &sOamData_TypeIcons, + .anims = sSpriteAnimTable_TypeIcons, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_TypeIcon +}; + +const struct SpriteTemplate sSpriteTemplate_TypeIcons2 = +{ + .tileTag = TYPE_ICON_TAG_2, + .paletteTag = TYPE_ICON_TAG_2, + .oam = &sOamData_TypeIcons, + .anims = sSpriteAnimTable_TypeIcons, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCB_TypeIcon +}; + +void LoadTypeIcons(u32 battler) +{ + u32 position; + + if (B_SHOW_TYPES == SHOW_TYPES_NEVER) + return; + + LoadTypeSpritesAndPalettes(); + + for (position = 0; position < gBattlersCount; ++position) + LoadTypeIconsPerBattler(battler, position); +} + +static void LoadTypeSpritesAndPalettes(void) +{ + if (IndexOfSpritePaletteTag(TYPE_ICON_TAG) != UCHAR_MAX) + return; + + LoadCompressedSpriteSheet(&sSpriteSheet_TypeIcons1); + LoadCompressedSpriteSheet(&sSpriteSheet_TypeIcons2); + LoadCompressedSpritePalette(&sTypeIconPal1); + LoadCompressedSpritePalette(&sTypeIconPal2); +} + +static void LoadTypeIconsPerBattler(u32 battler, u32 position) +{ + u32 typeNum, types[2]; + u32 battlerId = GetBattlerAtPosition(position); + bool32 useDoubleBattleCoords = UseDoubleBattleCoords(battlerId); + + if (!IsBattlerAlive(battlerId)) + return; + + for (typeNum = 0; typeNum < 2; ++typeNum) + types[typeNum] = GetMonPublicType(battlerId, typeNum); + + for (typeNum = 0; typeNum < 2; ++typeNum) + CreateSpriteFromType(position, useDoubleBattleCoords, types, typeNum, battler); +} + +static bool32 UseDoubleBattleCoords(u32 position) +{ + if (!IsDoubleBattle()) + return FALSE; + + if ((position == B_POSITION_PLAYER_LEFT) && (gBattleMons[B_POSITION_PLAYER_RIGHT].species == SPECIES_NONE)) + return FALSE; + + if ((position == B_POSITION_OPPONENT_LEFT) && (gBattleMons[B_POSITION_OPPONENT_RIGHT].species == SPECIES_NONE)) + return FALSE; + + return TRUE; +} + +static u32 GetMonPublicType(u32 battlerId, u32 typeNum) +{ + struct Pokemon* mon = GetBattlerData(battlerId); + u32 monSpecies = GetMonData(mon,MON_DATA_SPECIES,NULL); + struct Pokemon* monIllusion; + u32 illusionSpecies; + + if (ShouldHideUncaughtType(monSpecies)) + return TYPE_MYSTERY; + + monIllusion = GetIllusionMonPtr(battlerId); + illusionSpecies = GetMonData(monIllusion,MON_DATA_SPECIES,NULL); + + if (GetActiveGimmick(battlerId) == GIMMICK_TERA) + return GetMonDefensiveTeraType(mon,monIllusion,battlerId,typeNum,illusionSpecies,monSpecies); + + if (IsIllusionActiveAndTypeUnchanged(monIllusion,monSpecies, battlerId)) + return gSpeciesInfo[illusionSpecies].types[typeNum]; + + return gBattleMons[battlerId].types[typeNum]; +} + +static bool32 ShouldHideUncaughtType(u32 species) +{ + if (B_SHOW_TYPES != SHOW_TYPES_CAUGHT) + return FALSE; + + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species),FLAG_GET_CAUGHT)) + return FALSE; + + return TRUE; +} + +static u32 GetMonDefensiveTeraType(struct Pokemon * mon, struct Pokemon* monIllusion, u32 battlerId, u32 typeNum, u32 illusionSpecies, u32 monSpecies) +{ + u32 teraType = GetBattlerTeraType(battlerId); + u32 targetSpecies; + + if (teraType != TYPE_STELLAR) + return teraType; + + targetSpecies = (monIllusion != NULL) ? illusionSpecies : monSpecies; + + return gSpeciesInfo[targetSpecies].types[typeNum]; +} + +static u32 IsIllusionActiveAndTypeUnchanged(struct Pokemon* monIllusion, u32 monSpecies, u32 battlerId) +{ + u32 typeNum; + + if (monIllusion == NULL) + return FALSE; + + for (typeNum = 0; typeNum < 2; typeNum++) + if (gSpeciesInfo[monSpecies].types[typeNum] != gBattleMons[battlerId].types[typeNum]) + return FALSE; + + return TRUE; +} + +static void CreateSpriteFromType(u32 position, bool32 useDoubleBattleCoords, u32 types[], u32 typeNum, u32 battler) +{ + s32 x = 0, y = 0; + + if (ShouldSkipSecondType(types, typeNum)) + return; + + SetTypeIconXY(&x, &y, position, useDoubleBattleCoords, typeNum); + + CreateSpriteAndSetTypeSpriteAttributes(types[typeNum], x, y, position, battler, useDoubleBattleCoords); +} + +static bool32 ShouldSkipSecondType(u32 types[], u32 typeNum) +{ + if (!typeNum) + return FALSE; + + if (types[0] != types[1]) + return FALSE; + + return TRUE; +} + +static void SetTypeIconXY(s32* x, s32* y, u32 position, bool32 useDoubleBattleCoords, u32 typeNum) +{ + *x = sTypeIconPositions[position][useDoubleBattleCoords].x; + *y = sTypeIconPositions[position][useDoubleBattleCoords].y + (11 * typeNum); +} + +static void CreateSpriteAndSetTypeSpriteAttributes(u32 type, u32 x, u32 y, u32 position, u32 battler, bool32 useDoubleBattleCoords) +{ + struct Sprite* sprite; + const struct SpriteTemplate* spriteTemplate = gTypesInfo[type].useSecondTypeIconPalette ? &sSpriteTemplate_TypeIcons2 : &sSpriteTemplate_TypeIcons1; + u32 spriteId = CreateSpriteAtEnd(spriteTemplate, x, y, UCHAR_MAX); + + if (spriteId == MAX_SPRITES) + return; + + sprite = &gSprites[spriteId]; + sprite->tMonPosition = position; + sprite->tBattlerId = battler; + sprite->tVerticalPosition = y; + + sprite->hFlip = ShouldFlipTypeIcon(useDoubleBattleCoords, position, type); + + StartSpriteAnim(sprite, type); +} + +static bool32 ShouldFlipTypeIcon(bool32 useDoubleBattleCoords, u32 position, u32 typeId) +{ + bool32 side = (useDoubleBattleCoords) ? B_SIDE_OPPONENT : B_SIDE_PLAYER; + + if (GetBattlerSide(GetBattlerAtPosition(position)) != side) + return FALSE; + + return !gTypesInfo[typeId].isSpecialCaseType; +} + +static void SpriteCB_TypeIcon(struct Sprite* sprite) +{ + u32 position = sprite->tMonPosition; + u32 battlerId = sprite->tBattlerId; + bool32 useDoubleBattleCoords = UseDoubleBattleCoords(GetBattlerAtPosition(position)); + + if (sprite->tHideIconTimer == NUM_FRAMES_HIDE_TYPE_ICON) + { + DestroyTypeIcon(sprite); + return; + } + + if (ShouldHideTypeIcon(battlerId)) + { + sprite->x += GetTypeIconHideMovement(useDoubleBattleCoords, position); + ++sprite->tHideIconTimer; + return; + } + + sprite->x += GetTypeIconSlideMovement(useDoubleBattleCoords,position, sprite->x); + sprite->y = GetTypeIconBounceMovement(sprite->tVerticalPosition,position); +} + +static void DestroyTypeIcon(struct Sprite* sprite) +{ + u32 i; + DestroySpriteAndFreeResources(sprite); + + for (i = 0; i < MAX_SPRITES; ++i) + { + if (!gSprites[i].inUse) + continue; + + if (gSprites[i].template->paletteTag == TYPE_ICON_TAG) + return; + } + + FreeSpritePaletteByTag(TYPE_ICON_TAG); + FreeSpritePaletteByTag(TYPE_ICON_TAG_2); +} + +static bool32 ShouldHideTypeIcon(u32 battlerId) +{ + return gBattlerControllerFuncs[battlerId] != PlayerHandleChooseMove + && gBattlerControllerFuncs[battlerId] != HandleInputChooseMove + && gBattlerControllerFuncs[battlerId] != HandleChooseMoveAfterDma3 + && gBattlerControllerFuncs[battlerId] != HandleInputChooseMove + && gBattlerControllerFuncs[battlerId] != HandleInputChooseTarget + && gBattlerControllerFuncs[battlerId] != HandleMoveSwitching + && gBattlerControllerFuncs[battlerId] != HandleInputChooseMove; +} + +static s32 GetTypeIconHideMovement(bool32 useDoubleBattleCoords, u32 position) +{ + if (useDoubleBattleCoords) + { + if (position == B_POSITION_PLAYER_LEFT || position == B_POSITION_PLAYER_RIGHT) + return 1; + else + return -1; + } + + if (position == B_POSITION_PLAYER_LEFT) + return -1; + else + return 1; +} + +static s32 GetTypeIconSlideMovement(bool32 useDoubleBattleCoords, u32 position, s32 xPos) +{ + if (useDoubleBattleCoords) + { + switch (position) + { + case B_POSITION_PLAYER_LEFT: + case B_POSITION_PLAYER_RIGHT: + if (xPos > sTypeIconPositions[position][useDoubleBattleCoords].x - 10) + return -1; + break; + default: + case B_POSITION_OPPONENT_LEFT: + case B_POSITION_OPPONENT_RIGHT: + if (xPos < sTypeIconPositions[position][useDoubleBattleCoords].x + 10) + return 1; + break; + } + return 0; + } + + if (position == B_POSITION_PLAYER_LEFT) + { + if (xPos < sTypeIconPositions[position][useDoubleBattleCoords].x + 10) + return 1; + } + else + { + if (xPos > sTypeIconPositions[position][useDoubleBattleCoords].x - 10) + return -1; + } + return 0; +} + +static s32 GetTypeIconBounceMovement(s32 originalY, u32 position) +{ + struct Sprite* healthbox = &gSprites[gHealthboxSpriteIds[GetBattlerAtPosition(position)]]; + return originalY + healthbox->y2; +} + From 779cedd16f7fe9a28b0d82cbe740ed6b171563e4 Mon Sep 17 00:00:00 2001 From: PhallenTree <168426989+PhallenTree@users.noreply.github.com> Date: Sun, 11 Aug 2024 17:13:46 +0100 Subject: [PATCH 09/64] Fixes Dancer, adds Revelation Dance interactions with Z-Move, Roost and typeless mons (#5133) * Add Revelation Dance interactions with typeless mons, Roost and Z-Move * Fixes Dancer-called moves not updating their type * Adds Revelation Dance tests * Make sure target isn't immune in Dancer test * Missing ... in message * Missing Assume * CI ends Dancer test too early? * Z-Revelation Dance is Breakneck Blitz (Test) * Fix test (Zoroark too strong?) * Replace H!Zoroark * Remove Ability specification * Remove HP_Bars * Fix Dancer checking for battlers that don't exist in single battles --- src/battle_main.c | 10 +- src/battle_script_commands.c | 6 +- src/battle_util.c | 6 +- test/battle/ability/dancer.c | 19 +++ test/battle/gimmick/zmove.c | 19 +++ test/battle/move_effect/revelation_dance.c | 149 +++++++++++++++++++++ 6 files changed, 202 insertions(+), 7 deletions(-) create mode 100644 test/battle/move_effect/revelation_dance.c diff --git a/src/battle_main.c b/src/battle_main.c index 6bbcc0e3bc..526c54d62f 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5824,16 +5824,20 @@ void SetTypeBeforeUsingMove(u32 move, u32 battlerAtk) { gBattleStruct->dynamicMoveType = ItemId_GetSecondaryId(gBattleMons[battlerAtk].item) | F_DYNAMIC_TYPE_SET; } - else if (gMovesInfo[move].effect == EFFECT_REVELATION_DANCE) + else if (gMovesInfo[move].effect == EFFECT_REVELATION_DANCE && GetActiveGimmick(battlerAtk) != GIMMICK_Z_MOVE) { if (GetActiveGimmick(battlerAtk) == GIMMICK_TERA && GetBattlerTeraType(battlerAtk) != TYPE_STELLAR) gBattleStruct->dynamicMoveType = GetBattlerTeraType(battlerAtk); - else if (gBattleMons[battlerAtk].types[0] != TYPE_MYSTERY) + else if (gBattleMons[battlerAtk].types[0] != TYPE_MYSTERY && !(gBattleResources->flags->flags[battlerAtk] & RESOURCE_FLAG_ROOST && gBattleMons[battlerAtk].types[0] == TYPE_FLYING)) gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].types[0] | F_DYNAMIC_TYPE_SET; - else if (gBattleMons[battlerAtk].types[1] != TYPE_MYSTERY) + else if (gBattleMons[battlerAtk].types[1] != TYPE_MYSTERY && !(gBattleResources->flags->flags[battlerAtk] & RESOURCE_FLAG_ROOST && gBattleMons[battlerAtk].types[1] == TYPE_FLYING)) gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].types[1] | F_DYNAMIC_TYPE_SET; + else if (gBattleResources->flags->flags[battlerAtk] & RESOURCE_FLAG_ROOST) + gBattleStruct->dynamicMoveType = (B_ROOST_PURE_FLYING >= GEN_5 ? TYPE_NORMAL : TYPE_MYSTERY) | F_DYNAMIC_TYPE_SET; else if (gBattleMons[battlerAtk].types[2] != TYPE_MYSTERY) gBattleStruct->dynamicMoveType = gBattleMons[battlerAtk].types[2] | F_DYNAMIC_TYPE_SET; + else + gBattleStruct->dynamicMoveType = TYPE_MYSTERY | F_DYNAMIC_TYPE_SET; } else if (gMovesInfo[move].effect == EFFECT_RAGING_BULL && (gBattleMons[battlerAtk].species == SPECIES_TAUROS_PALDEAN_COMBAT_BREED diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 9d10c87cf7..317613c479 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6257,7 +6257,7 @@ static void Cmd_moveend(void) u32 battler, nextDancer = 0; bool32 turnOnHitmarker = FALSE; - for (battler = 0; battler < MAX_BATTLERS_COUNT; battler++) + for (battler = 0; battler < gBattlersCount; battler++) { if (gSpecialStatuses[battler].dancerUsedMove) { @@ -6278,7 +6278,7 @@ static void Cmd_moveend(void) gBattleScripting.savedBattler |= (gBattlerAttacker << 4); gSpecialStatuses[gBattlerAttacker].dancerUsedMove = TRUE; } - for (battler = 0; battler < MAX_BATTLERS_COUNT; battler++) + for (battler = 0; battler < gBattlersCount; battler++) { if (GetBattlerAbility(battler) == ABILITY_DANCER && !gSpecialStatuses[battler].dancerUsedMove) { @@ -12898,7 +12898,7 @@ static void Cmd_settypetorandomresistance(void) { gBattlescriptCurrInstr = cmd->failInstr; } - else if (gLastHitByType[gBattlerAttacker] == TYPE_STELLAR) + else if (gLastHitByType[gBattlerAttacker] == TYPE_STELLAR || gLastHitByType[gBattlerAttacker] == TYPE_MYSTERY) { gBattlescriptCurrInstr = cmd->failInstr; } diff --git a/src/battle_util.c b/src/battle_util.c index 56701e2d99..e517a81605 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5565,6 +5565,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && TARGET_TURN_DAMAGED && !IS_BATTLER_OF_TYPE(battler, moveType) && moveType != TYPE_STELLAR + && moveType != TYPE_MYSTERY && IsBattlerAlive(battler)) { SET_BATTLER_TYPE(battler, moveType); @@ -6049,6 +6050,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 // Edge case for dance moves that hit multiply targets gHitMarker &= ~HITMARKER_NO_ATTACKSTRING; + SetTypeBeforeUsingMove(gCalledMove, battler); // Make sure that the target isn't an ally - if it is, target the original user if (GetBattlerSide(gBattlerTarget) == GetBattlerSide(gBattlerAttacker)) @@ -9860,7 +9862,9 @@ static inline uq4_12_t GetParentalBondModifier(u32 battlerAtk) static inline uq4_12_t GetSameTypeAttackBonusModifier(u32 battlerAtk, u32 moveType, u32 move, u32 abilityAtk) { - if (gBattleStruct->pledgeMove && IS_BATTLER_OF_TYPE(BATTLE_PARTNER(battlerAtk), moveType)) + if (moveType == TYPE_MYSTERY) + return UQ_4_12(1.0); + else if (gBattleStruct->pledgeMove && IS_BATTLER_OF_TYPE(BATTLE_PARTNER(battlerAtk), moveType)) return (abilityAtk == ABILITY_ADAPTABILITY) ? UQ_4_12(2.0) : UQ_4_12(1.5); else if (!IS_BATTLER_OF_TYPE(battlerAtk, moveType) || move == MOVE_STRUGGLE || move == MOVE_NONE) return UQ_4_12(1.0); diff --git a/test/battle/ability/dancer.c b/test/battle/ability/dancer.c index f54f7ab76a..660a719c69 100644 --- a/test/battle/ability/dancer.c +++ b/test/battle/ability/dancer.c @@ -126,3 +126,22 @@ DOUBLE_BATTLE_TEST("Dancer still triggers if another dancer flinches") ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); } } + +SINGLE_BATTLE_TEST("Dancer-called attacks have their type updated") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].danceMove == TRUE); + ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].effect == EFFECT_REVELATION_DANCE); + PLAYER(SPECIES_TANGROWTH); + OPPONENT(SPECIES_ORICORIO_BAILE); + } WHEN { + TURN { MOVE(player, MOVE_REVELATION_DANCE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player); + MESSAGE("It's not very effective…"); + ABILITY_POPUP(opponent, ABILITY_DANCER); + ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, opponent); + NOT MESSAGE("It's not very effective…"); + MESSAGE("It's super effective!"); + } +} diff --git a/test/battle/gimmick/zmove.c b/test/battle/gimmick/zmove.c index bde241bfd7..1eb2c7ae74 100644 --- a/test/battle/gimmick/zmove.c +++ b/test/battle/gimmick/zmove.c @@ -599,3 +599,22 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Searing Sunraze Smash ignores the target's abilitie MESSAGE("A critical hit!"); } } + +SINGLE_BATTLE_TEST("(Z-MOVE) Z-Revelation Dance always transforms into Breakneck Blitz") +{ + u16 species; + PARAMETRIZE { species = SPECIES_ORICORIO_BAILE; } + PARAMETRIZE { species = SPECIES_ORICORIO_PAU; } + PARAMETRIZE { species = SPECIES_ORICORIO_POM_POM; } + PARAMETRIZE { species = SPECIES_ORICORIO_SENSU; } + GIVEN { + ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].type == TYPE_NORMAL); + PLAYER(species) { Item(ITEM_NORMALIUM_Z); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_REVELATION_DANCE, gimmick: GIMMICK_Z_MOVE); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ZMOVE_ACTIVATE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BREAKNECK_BLITZ, player); + } +} diff --git a/test/battle/move_effect/revelation_dance.c b/test/battle/move_effect/revelation_dance.c new file mode 100644 index 0000000000..489dee1c87 --- /dev/null +++ b/test/battle/move_effect/revelation_dance.c @@ -0,0 +1,149 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].effect == EFFECT_REVELATION_DANCE); + ASSUME(gMovesInfo[MOVE_REVELATION_DANCE].danceMove == TRUE); + ASSUME(MoveHasAdditionalEffectSelfArg(MOVE_BURN_UP, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE)); + ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].effect == EFFECT_THIRD_TYPE); + ASSUME(gMovesInfo[MOVE_FORESTS_CURSE].argument == TYPE_GRASS); + ASSUME(gMovesInfo[MOVE_ROOST].effect == EFFECT_ROOST); +} + +SINGLE_BATTLE_TEST("Revelation Dance changes its type depending on the user's 1st Type") +{ + u16 speciesPlayer; + u16 speciesOpponent; + + PARAMETRIZE { speciesPlayer = SPECIES_ORICORIO_POM_POM; speciesOpponent = SPECIES_DUGTRIO; } + PARAMETRIZE { speciesPlayer = SPECIES_ORICORIO_BAILE; speciesOpponent = SPECIES_BLASTOISE; } + PARAMETRIZE { speciesPlayer = SPECIES_ORICORIO_PAU; speciesOpponent = SPECIES_LIEPARD; } + PARAMETRIZE { speciesPlayer = SPECIES_ORICORIO_SENSU; speciesOpponent = SPECIES_PERSIAN; } + + GIVEN { + PLAYER(speciesPlayer); + OPPONENT(speciesOpponent); + } WHEN { + TURN { MOVE(player, MOVE_REVELATION_DANCE); } + } SCENE { + if (speciesPlayer == SPECIES_ORICORIO_BAILE) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player); + HP_BAR(opponent); + MESSAGE("It's not very effective…"); + } + else { + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player); + HP_BAR(opponent); + MESSAGE("It's not very effective…"); + } + } + } +} + +SINGLE_BATTLE_TEST("Revelation Dance changes its type depending on the user's 2nd Type if it has no 1st type") +{ + GIVEN { + PLAYER(SPECIES_ORICORIO_BAILE); + OPPONENT(SPECIES_EMPOLEON); + } WHEN { + TURN { MOVE(player, MOVE_BURN_UP); } + TURN { MOVE(player, MOVE_REVELATION_DANCE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BURN_UP, player); + HP_BAR(opponent); + NONE_OF { + MESSAGE("It's not very effective…"); + MESSAGE("It's super effective!"); + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player); + HP_BAR(opponent); + MESSAGE("It's not very effective…"); + } +} + +SINGLE_BATTLE_TEST("Revelation Dance changes its type depending on the user's 3rd Type if it has no 1st or 2nd type") +{ + GIVEN { + PLAYER(SPECIES_GROWLITHE); + OPPONENT(SPECIES_TREVENANT); + } WHEN { + TURN { MOVE(player, MOVE_BURN_UP); MOVE(opponent, MOVE_FORESTS_CURSE); } + TURN { MOVE(player, MOVE_REVELATION_DANCE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BURN_UP, player); + HP_BAR(opponent); + MESSAGE("It's super effective!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FORESTS_CURSE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player); + HP_BAR(opponent); + MESSAGE("It's not very effective…"); + } +} + +SINGLE_BATTLE_TEST("Revelation Dance becomes Typeless if its user is Typeless") +{ + u16 speciesOpponent; + + PARAMETRIZE { speciesOpponent = SPECIES_BLISSEY; } + PARAMETRIZE { speciesOpponent = SPECIES_BLASTOISE; } + PARAMETRIZE { speciesOpponent = SPECIES_CHARIZARD; } + PARAMETRIZE { speciesOpponent = SPECIES_VENUSAUR; } + PARAMETRIZE { speciesOpponent = SPECIES_GOLEM; } + PARAMETRIZE { speciesOpponent = SPECIES_AEGISLASH; } + + GIVEN { + PLAYER(SPECIES_GROWLITHE); + OPPONENT(speciesOpponent); + } WHEN { + TURN { MOVE(player, MOVE_BURN_UP); } + TURN { MOVE(player, MOVE_REVELATION_DANCE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BURN_UP, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player); + HP_BAR(opponent); + NONE_OF { + MESSAGE("It's not very effective…"); + MESSAGE("It's super effective!"); + } + } +} + +SINGLE_BATTLE_TEST("Revelation Dance becomes Normal type if used by a Typeless Pokemon due to Roost") +{ + u16 speciesOpponent; + + PARAMETRIZE { speciesOpponent = SPECIES_SABLEYE; } + PARAMETRIZE { speciesOpponent = SPECIES_AGGRON; } + + ASSUME(B_ROOST_PURE_FLYING >= GEN_5); + + GIVEN { + PLAYER(SPECIES_ORICORIO_BAILE) { Ability(ABILITY_DANCER); } + OPPONENT(speciesOpponent); + } WHEN { + TURN { MOVE(player, MOVE_BURN_UP); MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_ROOST); MOVE(opponent, MOVE_REVELATION_DANCE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BURN_UP, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROOST, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, opponent); + HP_BAR(player); + ABILITY_POPUP(player, ABILITY_DANCER); + if (speciesOpponent == SPECIES_AGGRON) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player); + HP_BAR(opponent); + MESSAGE("It's not very effective…"); + } + else { + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player); + HP_BAR(opponent); + MESSAGE("It's not very effective…"); + } + } + } +} From 805bb2888cf5400ec1b031c5766f0115e9ace35d Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Sun, 11 Aug 2024 18:27:22 +0200 Subject: [PATCH 10/64] Fixes wrong padding in struct SpeciesInfo (#5139) Fixes wrong padding in struct SpeciesInfo that is if I counted correctly. After I opened #5138 I realized it might be an issue on master as well. --- include/pokemon.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/pokemon.h b/include/pokemon.h index d1484fe2ce..22c465214c 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -441,7 +441,7 @@ struct SpeciesInfo /*0xC4*/ u32 dexForceRequired:1; // This species will be taken into account for Pokédex ratings even if they have the "isMythical" flag set. u32 tmIlliterate:1; // This species will be unable to learn the universal moves. u32 isFrontierBanned:1; // This species is not allowed to participate in Battle Frontier facilities. - u32 padding4:14; + u32 padding4:13; // Move Data /* 0x80 */ const struct LevelUpMove *levelUpLearnset; /* 0x84 */ const u16 *teachableLearnset; From 25f7f431faae05621ea9d57be5150a98f6d01b55 Mon Sep 17 00:00:00 2001 From: Martin Griffin Date: Sun, 11 Aug 2024 21:06:33 +0100 Subject: [PATCH 11/64] Remove agbcc (#4994) --- .github/workflows/build.yml | 23 +- INSTALL.md | 52 - Makefile | 109 +- common_syms/AgbRfu_LinkManager.txt | 1 - common_syms/agb_flash.txt | 10 - common_syms/apprentice.txt | 3 - common_syms/battle_anim_throw.txt | 3 - common_syms/battle_controllers.txt | 3 - common_syms/battle_factory_screen.txt | 1 - common_syms/battle_main.txt | 7 - common_syms/battle_tower.txt | 1 - common_syms/berry_blender.txt | 1 - common_syms/bg.txt | 1 - common_syms/contest.txt | 1 - common_syms/contest_painting.txt | 4 - common_syms/ereader_screen.txt | 1 - common_syms/evolution_scene.txt | 1 - common_syms/faraway_island.txt | 3 - common_syms/field_camera.txt | 3 - common_syms/field_control_avatar.txt | 1 - common_syms/field_specials.txt | 1 - common_syms/fieldmap.txt | 1 - common_syms/image_processing_effects.txt | 10 - common_syms/intro.txt | 2 - common_syms/librfu_rfu.txt | 5 - common_syms/librfu_sio32id.txt | 1 - common_syms/librfu_stwi.txt | 1 - common_syms/link.txt | 35 - common_syms/link_rfu_2.txt | 2 - common_syms/list_menu.txt | 2 - common_syms/load_save.txt | 4 - common_syms/m4a.txt | 12 - common_syms/main.txt | 10 - common_syms/mauville_old_man.txt | 1 - common_syms/overworld.txt | 8 - common_syms/party_menu.txt | 1 - common_syms/pokedex.txt | 2 - common_syms/pokedex_cry_screen.txt | 1 - common_syms/random.txt | 2 - common_syms/rtc.txt | 1 - common_syms/save.txt | 13 - common_syms/sound.txt | 1 - common_syms/sprite.txt | 2 - common_syms/start_menu.txt | 1 - common_syms/task.txt | 1 - common_syms/text.txt | 4 - common_syms/trainer_see.txt | 5 - common_syms/tv.txt | 4 - common_syms/window.txt | 2 - ld_script.ld | 1391 ---------------------- sym_bss.txt | 63 - sym_common.txt | 83 -- sym_ewram.txt | 154 --- 53 files changed, 18 insertions(+), 2037 deletions(-) delete mode 100644 common_syms/AgbRfu_LinkManager.txt delete mode 100644 common_syms/agb_flash.txt delete mode 100644 common_syms/apprentice.txt delete mode 100755 common_syms/battle_anim_throw.txt delete mode 100644 common_syms/battle_controllers.txt delete mode 100644 common_syms/battle_factory_screen.txt delete mode 100644 common_syms/battle_main.txt delete mode 100644 common_syms/battle_tower.txt delete mode 100644 common_syms/berry_blender.txt delete mode 100644 common_syms/bg.txt delete mode 100644 common_syms/contest.txt delete mode 100644 common_syms/contest_painting.txt delete mode 100644 common_syms/ereader_screen.txt delete mode 100644 common_syms/evolution_scene.txt delete mode 100755 common_syms/faraway_island.txt delete mode 100644 common_syms/field_camera.txt delete mode 100644 common_syms/field_control_avatar.txt delete mode 100644 common_syms/field_specials.txt delete mode 100644 common_syms/fieldmap.txt delete mode 100644 common_syms/image_processing_effects.txt delete mode 100644 common_syms/intro.txt delete mode 100644 common_syms/librfu_rfu.txt delete mode 100644 common_syms/librfu_sio32id.txt delete mode 100644 common_syms/librfu_stwi.txt delete mode 100644 common_syms/link.txt delete mode 100644 common_syms/link_rfu_2.txt delete mode 100644 common_syms/list_menu.txt delete mode 100644 common_syms/load_save.txt delete mode 100644 common_syms/m4a.txt delete mode 100644 common_syms/main.txt delete mode 100644 common_syms/mauville_old_man.txt delete mode 100644 common_syms/overworld.txt delete mode 100644 common_syms/party_menu.txt delete mode 100644 common_syms/pokedex.txt delete mode 100644 common_syms/pokedex_cry_screen.txt delete mode 100644 common_syms/random.txt delete mode 100644 common_syms/rtc.txt delete mode 100644 common_syms/save.txt delete mode 100644 common_syms/sound.txt delete mode 100644 common_syms/sprite.txt delete mode 100644 common_syms/start_menu.txt delete mode 100644 common_syms/task.txt delete mode 100644 common_syms/text.txt delete mode 100644 common_syms/trainer_see.txt delete mode 100644 common_syms/tv.txt delete mode 100644 common_syms/window.txt delete mode 100644 ld_script.ld delete mode 100644 sym_bss.txt delete mode 100644 sym_common.txt delete mode 100644 sym_ewram.txt diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0322cbe11f..c84110d7dd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,19 +15,12 @@ jobs: GAME_VERSION: EMERALD GAME_REVISION: 0 GAME_LANGUAGE: ENGLISH - MODERN: 0 COMPARE: 0 UNUSED_ERROR: 1 steps: - name: Checkout uses: actions/checkout@v2 - - name: Checkout agbcc - uses: actions/checkout@v2 - with: - path: agbcc - repository: pret/agbcc - - name: Install binutils run: | sudo apt update @@ -36,27 +29,13 @@ jobs: # gcc-arm-none-eabi is only needed for the modern build # as an alternative to dkP - - name: Install agbcc - run: | - ./build.sh - ./install.sh ../ - working-directory: agbcc - - - name: Agbcc + - name: ROM env: - MODERN: 0 - COMPARE: 0 - run: make -j${nproc} -O all - - - name: Modern - env: - MODERN: 1 COMPARE: 0 run: make -j${nproc} -O all - name: Test env: - MODERN: 1 TEST: 1 run: | make -j${nproc} -O pokeemerald-test.elf diff --git a/INSTALL.md b/INSTALL.md index 6349d24fbb..49f11fce7c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -596,58 +596,6 @@ To build **pokeemerald.elf** with debug symbols under a modern toolchain: ```bash make DINFO=1 ``` -Note that this is not necessary for a non-modern (agbcc) build since those are built with debug symbols by default. - -### agbcc - -

- Deprecated; installing agbcc is optional since 1.7.0. - -1. Install agbcc into pokeemerald-expansion. The commands to run depend on certain conditions. **You should only follow one of the listed instructions**: -- If agbcc has **not been built before** in the folder where you chose to store pokeemerald Expansion, run the following commands to build and install it into pokeemerald-expansion: - - ```bash - git clone https://github.com/pret/agbcc - cd agbcc - ./build.sh - ./install.sh ../pokeemerald-expansion - ``` - -- **Otherwise**, if agbcc has been built before (e.g. if the git clone above fails), but was **last built on a different terminal** than the one currently used (only relevant to Windows, e.g. switching from msys2 to WSL1), then run the following commands to build and install it into pokeemerald-expansion: - - ```bash - cd agbcc - git clean -fX - ./build.sh - ./install.sh ../pokeemerald-expansion - ``` - -- **Otherwise**, if agbcc has been built before on the same terminal, run the following commands to install agbcc into pokeemerald-expansion: - - ```bash - cd agbcc - ./install.sh ../pokeemerald-expansion - ``` - -
- Note... - - > If building agbcc or pokeemerald results in an error, try deleting the agbcc folder and re-installing agbcc as if it has not been built before. -
- -2. Once agbcc is installed, change directory back to the base directory where pokeemerald-expansion and agbcc are stored: - - ```bash - cd .. - ``` - -3. To compile with agbcc: - - ```bash - make agbcc - ``` - -
# Useful additional tools diff --git a/Makefile b/Makefile index 6dacf8b1d3..6f8951d378 100644 --- a/Makefile +++ b/Makefile @@ -25,10 +25,8 @@ AS := $(PREFIX)as LD := $(PREFIX)ld -# note: the makefile must be set up so MODERNCC is never called -# if MODERN=0 -MODERNCC := $(PREFIX)gcc -PATH_MODERNCC := PATH="$(PATH)" $(MODERNCC) +ARMCC := $(PREFIX)gcc +PATH_ARMCC := PATH="$(PATH)" $(ARMCC) ifeq ($(OS),Windows_NT) EXE := .exe @@ -40,45 +38,20 @@ TITLE := POKEMON EMER GAME_CODE := BPEE MAKER_CODE := 01 REVISION := 0 -MODERN ?= 1 TEST ?= 0 ANALYZE ?= 0 UNUSED_ERROR ?= 0 -ifeq (agbcc,$(MAKECMDGOALS)) - MODERN := 0 -endif - ifeq (check,$(MAKECMDGOALS)) TEST := 1 endif -# use arm-none-eabi-cpp for macOS -# as macOS's default compiler is clang -# and clang's preprocessor will warn on \u -# when preprocessing asm files, expecting a unicode literal -# we can't unconditionally use arm-none-eabi-cpp -# as installations which install binutils-arm-none-eabi -# don't come with it -ifneq ($(MODERN),1) - ifeq ($(shell uname -s),Darwin) - CPP := $(PREFIX)cpp - else - CPP := $(CC) -E - endif -else - CPP := $(PREFIX)cpp -endif +CPP := $(PREFIX)cpp -ROM_NAME := pokeemerald_agbcc.gba +ROM_NAME := pokeemerald.gba ELF_NAME := $(ROM_NAME:.gba=.elf) MAP_NAME := $(ROM_NAME:.gba=.map) -OBJ_DIR_NAME := build/emerald - -MODERN_ROM_NAME := pokeemerald.gba -MODERN_ELF_NAME := $(MODERN_ROM_NAME:.gba=.elf) -MODERN_MAP_NAME := $(MODERN_ROM_NAME:.gba=.map) -MODERN_OBJ_DIR_NAME := build/modern +OBJ_DIR_NAME := build/modern SHELL := bash -o pipefail @@ -86,14 +59,8 @@ ELF = $(ROM:.gba=.elf) MAP = $(ROM:.gba=.map) SYM = $(ROM:.gba=.sym) -TEST_OBJ_DIR_NAME_MODERN := build/modern-test -TEST_OBJ_DIR_NAME_AGBCC := build/test +TEST_OBJ_DIR_NAME := build/modern-test -ifeq ($(MODERN),0) -TEST_OBJ_DIR_NAME := $(TEST_OBJ_DIR_NAME_AGBCC) -else -TEST_OBJ_DIR_NAME := $(TEST_OBJ_DIR_NAME_MODERN) -endif TESTELF = $(ROM:.gba=-test.elf) HEADLESSELF = $(ROM:.gba=-test-headless.elf) @@ -116,17 +83,9 @@ SONG_BUILDDIR = $(OBJ_DIR)/$(SONG_SUBDIR) MID_BUILDDIR = $(OBJ_DIR)/$(MID_SUBDIR) TEST_BUILDDIR = $(OBJ_DIR)/$(TEST_SUBDIR) -ASFLAGS := -mcpu=arm7tdmi --defsym MODERN=$(MODERN) +ASFLAGS := -mcpu=arm7tdmi --defsym MODERN=1 -ifeq ($(MODERN),0) -CC1 := tools/agbcc/bin/agbcc$(EXE) -override CFLAGS += -mthumb-interwork -Wimplicit -Wparentheses -Werror -O2 -fhex-asm -g -ROM := $(ROM_NAME) -OBJ_DIR := $(OBJ_DIR_NAME) -LIBPATH := -L ../../tools/agbcc/lib -LIB := $(LIBPATH) -lgcc -lc -L../../libagbsyscall -lagbsyscall -else -CC1 = $(shell $(PATH_MODERNCC) --print-prog-name=cc1) -quiet +CC1 = $(shell $(PATH_ARMCC) --print-prog-name=cc1) -quiet override CFLAGS += -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init ifeq ($(ANALYZE),1) override CFLAGS += -fanalyzer @@ -137,11 +96,10 @@ ifneq ($(GITHUB_REPOSITORY_OWNER),rh-hideout) override CFLAGS += -Wno-error=unused-variable -Wno-error=unused-const-variable -Wno-error=unused-parameter -Wno-error=unused-function -Wno-error=unused-but-set-parameter -Wno-error=unused-but-set-variable -Wno-error=unused-value -Wno-error=unused-local-typedefs endif endif -ROM := $(MODERN_ROM_NAME) -OBJ_DIR := $(MODERN_OBJ_DIR_NAME) -LIBPATH := -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libgcc.a))" -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libnosys.a))" -L "$(dir $(shell $(PATH_MODERNCC) -mthumb -print-file-name=libc.a))" +ROM := $(ROM_NAME) +OBJ_DIR := $(OBJ_DIR_NAME) +LIBPATH := -L "$(dir $(shell $(PATH_ARMCC) -mthumb -print-file-name=libgcc.a))" -L "$(dir $(shell $(PATH_ARMCC) -mthumb -print-file-name=libnosys.a))" -L "$(dir $(shell $(PATH_ARMCC) -mthumb -print-file-name=libc.a))" LIB := $(LIBPATH) -lc -lnosys -lgcc -L../../libagbsyscall -lagbsyscall -endif ifeq ($(TESTELF),$(MAKECMDGOALS)) TEST := 1 @@ -151,10 +109,7 @@ ifeq ($(TEST),1) OBJ_DIR := $(TEST_OBJ_DIR_NAME) endif -CPPFLAGS := -iquote include -iquote $(GFLIB_SUBDIR) -Wno-trigraphs -DMODERN=$(MODERN) -DTESTING=$(TEST) -ifneq ($(MODERN),1) -CPPFLAGS += -I tools/agbcc/include -I tools/agbcc -nostdinc -undef -endif +CPPFLAGS := -iquote include -iquote $(GFLIB_SUBDIR) -Wno-trigraphs -DMODERN=1 -DTESTING=$(TEST) SHA1 := $(shell { command -v sha1sum || command -v shasum; } 2>/dev/null) -c GFX := tools/gbagfx/gbagfx$(EXE) @@ -301,26 +256,17 @@ mostlyclean: tidynonmodern tidymodern tidycheck rm -f $(AUTO_GEN_TARGETS) @$(MAKE) clean -C libagbsyscall -tidy: tidynonmodern tidymodern tidycheck +tidy: tidymodern tidycheck -tidynonmodern: +tidymodern: rm -f $(ROM_NAME) $(ELF_NAME) $(MAP_NAME) rm -rf $(OBJ_DIR_NAME) -tidymodern: - rm -f $(MODERN_ROM_NAME) $(MODERN_ELF_NAME) $(MODERN_MAP_NAME) - rm -rf $(MODERN_OBJ_DIR_NAME) - tidycheck: rm -f $(TESTELF) $(HEADLESSELF) - rm -rf $(TEST_OBJ_DIR_NAME_MODERN) - rm -rf $(TEST_OBJ_DIR_NAME_AGBCC) + rm -rf $(TEST_OBJ_DIR_NAME) -ifneq ($(MODERN),0) -$(C_BUILDDIR)/berry_crush.o: override CFLAGS += -Wno-address-of-packed-member -endif - include graphics_file_rules.mk include map_data_rules.mk include spritesheet_rules.mk @@ -349,27 +295,11 @@ ifeq ($(COMPETITIVE_PARTY_SYNTAX),1) %.h: %.party tools ; $(CPP) $(CPPFLAGS) -traditional-cpp - < $< | $(TRAINERPROC) -o $@ -i $< - endif -ifeq ($(MODERN),0) -$(C_BUILDDIR)/libc.o: CC1 := tools/agbcc/bin/old_agbcc$(EXE) -$(C_BUILDDIR)/libc.o: CFLAGS := -O2 - -$(C_BUILDDIR)/siirtc.o: CFLAGS := -mthumb-interwork - -$(C_BUILDDIR)/agb_flash.o: CFLAGS := -O -mthumb-interwork -$(C_BUILDDIR)/agb_flash_1m.o: CFLAGS := -O -mthumb-interwork -$(C_BUILDDIR)/agb_flash_mx.o: CFLAGS := -O -mthumb-interwork - -$(C_BUILDDIR)/m4a.o: CC1 := tools/agbcc/bin/old_agbcc$(EXE) - -$(C_BUILDDIR)/record_mixing.o: CFLAGS += -ffreestanding -$(C_BUILDDIR)/librfu_intr.o: CC1 := tools/agbcc/bin/agbcc_arm$(EXE) -$(C_BUILDDIR)/librfu_intr.o: CFLAGS := -O2 -mthumb-interwork -quiet -else +$(C_BUILDDIR)/berry_crush.o: override CFLAGS += -Wno-address-of-packed-member $(C_BUILDDIR)/librfu_intr.o: CFLAGS := -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -fno-toplevel-reorder -Wno-pointer-to-int-cast $(C_BUILDDIR)/pokedex_plus_hgss.o: CFLAGS := -mthumb -mthumb-interwork -O2 -mabi=apcs-gnu -mtune=arm7tdmi -march=armv4t -Wno-pointer-to-int-cast -std=gnu17 -Werror -Wall -Wno-strict-aliasing -Wno-attribute-alias -Woverride-init # Annoyingly we can't turn this on just for src/data/trainers.h $(C_BUILDDIR)/data.o: CFLAGS += -fno-show-column -fno-diagnostics-show-caret -endif ifeq ($(DINFO),1) override CFLAGS += -g @@ -488,13 +418,8 @@ $1: $2 $$(shell $(SCANINC) -I include -I tools/agbcc/include -I gflib $2) endef $(foreach src, $(TEST_SRCS), $(eval $(call TEST_DEP,$(patsubst $(TEST_SUBDIR)/%.c,$(TEST_BUILDDIR)/%.o,$(src)),$(src),$(patsubst $(TEST_SUBDIR)/%.c,%,$(src))))) -ifeq ($(MODERN),0) -LD_SCRIPT := ld_script.ld -LD_SCRIPT_DEPS := $(OBJ_DIR)/sym_bss.ld $(OBJ_DIR)/sym_common.ld $(OBJ_DIR)/sym_ewram.ld -else LD_SCRIPT := ld_script_modern.ld LD_SCRIPT_DEPS := -endif $(OBJ_DIR)/ld_script.ld: $(LD_SCRIPT) $(LD_SCRIPT_DEPS) cd $(OBJ_DIR) && sed "s#tools/#../../tools/#g" ../../$(LD_SCRIPT) > ld_script.ld @@ -541,7 +466,7 @@ check: $(TESTELF) $(ROMTESTHYDRA) $(ROMTEST) $(OBJCOPY) $(HEADLESSELF) libagbsyscall: - @$(MAKE) -C libagbsyscall TOOLCHAIN=$(TOOLCHAIN) MODERN=$(MODERN) + @$(MAKE) -C libagbsyscall TOOLCHAIN=$(TOOLCHAIN) MODERN=1 ################### ### Symbol file ### diff --git a/common_syms/AgbRfu_LinkManager.txt b/common_syms/AgbRfu_LinkManager.txt deleted file mode 100644 index 7ff8cd53dd..0000000000 --- a/common_syms/AgbRfu_LinkManager.txt +++ /dev/null @@ -1 +0,0 @@ -lman diff --git a/common_syms/agb_flash.txt b/common_syms/agb_flash.txt deleted file mode 100644 index cb421ec80d..0000000000 --- a/common_syms/agb_flash.txt +++ /dev/null @@ -1,10 +0,0 @@ -gFlashTimeoutFlag -PollFlashStatus -WaitForFlashWrite -ProgramFlashSector -gFlash -ProgramFlashByte -gFlashNumRemainingBytes -EraseFlashChip -EraseFlashSector -gFlashMaxTime diff --git a/common_syms/apprentice.txt b/common_syms/apprentice.txt deleted file mode 100644 index 0d3569dcbb..0000000000 --- a/common_syms/apprentice.txt +++ /dev/null @@ -1,3 +0,0 @@ -gApprenticePartyMovesData -gApprenticeQuestionData -gApprenticeFunc diff --git a/common_syms/battle_anim_throw.txt b/common_syms/battle_anim_throw.txt deleted file mode 100755 index 5e2e8b3ff3..0000000000 --- a/common_syms/battle_anim_throw.txt +++ /dev/null @@ -1,3 +0,0 @@ -gMonShrinkDuration -gMonShrinkDelta -gMonShrinkDistance diff --git a/common_syms/battle_controllers.txt b/common_syms/battle_controllers.txt deleted file mode 100644 index 0b3c25266a..0000000000 --- a/common_syms/battle_controllers.txt +++ /dev/null @@ -1,3 +0,0 @@ -gBattlerControllerFuncs -gBattleControllerData -gBattlerControllerEndFuncs diff --git a/common_syms/battle_factory_screen.txt b/common_syms/battle_factory_screen.txt deleted file mode 100644 index 3ddeb6d3b1..0000000000 --- a/common_syms/battle_factory_screen.txt +++ /dev/null @@ -1 +0,0 @@ -gFactorySelect_CurrentOptionFunc diff --git a/common_syms/battle_main.txt b/common_syms/battle_main.txt deleted file mode 100644 index 7a9faa5a13..0000000000 --- a/common_syms/battle_main.txt +++ /dev/null @@ -1,7 +0,0 @@ -gPreBattleCallback1 -gBattleMainFunc -gBattleResults -gLeveledUpInBattle -gHealthboxSpriteIds -gMultiUsePlayerCursor -gNumberOfMovesToChoose diff --git a/common_syms/battle_tower.txt b/common_syms/battle_tower.txt deleted file mode 100644 index 7371109d51..0000000000 --- a/common_syms/battle_tower.txt +++ /dev/null @@ -1 +0,0 @@ -gFrontierTempParty diff --git a/common_syms/berry_blender.txt b/common_syms/berry_blender.txt deleted file mode 100644 index 1b15a33d61..0000000000 --- a/common_syms/berry_blender.txt +++ /dev/null @@ -1 +0,0 @@ -gInGameOpponentsNo diff --git a/common_syms/bg.txt b/common_syms/bg.txt deleted file mode 100644 index 0a3c3aecca..0000000000 --- a/common_syms/bg.txt +++ /dev/null @@ -1 +0,0 @@ -gWindowTileAutoAllocEnabled diff --git a/common_syms/contest.txt b/common_syms/contest.txt deleted file mode 100644 index 6a519fb463..0000000000 --- a/common_syms/contest.txt +++ /dev/null @@ -1 +0,0 @@ -gContestRngValue diff --git a/common_syms/contest_painting.txt b/common_syms/contest_painting.txt deleted file mode 100644 index 32bb8be161..0000000000 --- a/common_syms/contest_painting.txt +++ /dev/null @@ -1,4 +0,0 @@ -gContestMonPixels -gImageProcessingContext -gContestPaintingWinner -gContestPaintingMonPalette diff --git a/common_syms/ereader_screen.txt b/common_syms/ereader_screen.txt deleted file mode 100644 index 2189eedbc9..0000000000 --- a/common_syms/ereader_screen.txt +++ /dev/null @@ -1 +0,0 @@ -gEReaderData diff --git a/common_syms/evolution_scene.txt b/common_syms/evolution_scene.txt deleted file mode 100644 index 137cd3e05d..0000000000 --- a/common_syms/evolution_scene.txt +++ /dev/null @@ -1 +0,0 @@ -gCB2_AfterEvolution diff --git a/common_syms/faraway_island.txt b/common_syms/faraway_island.txt deleted file mode 100755 index e02ca2ec25..0000000000 --- a/common_syms/faraway_island.txt +++ /dev/null @@ -1,3 +0,0 @@ -sPlayerToMewDeltaX -sPlayerToMewDeltaY -sMewDirectionCandidates diff --git a/common_syms/field_camera.txt b/common_syms/field_camera.txt deleted file mode 100644 index 02301ce23c..0000000000 --- a/common_syms/field_camera.txt +++ /dev/null @@ -1,3 +0,0 @@ -gFieldCamera -gTotalCameraPixelOffsetY -gTotalCameraPixelOffsetX diff --git a/common_syms/field_control_avatar.txt b/common_syms/field_control_avatar.txt deleted file mode 100644 index 268f60c641..0000000000 --- a/common_syms/field_control_avatar.txt +++ /dev/null @@ -1 +0,0 @@ -gSelectedObjectEvent diff --git a/common_syms/field_specials.txt b/common_syms/field_specials.txt deleted file mode 100644 index 7adb3f6692..0000000000 --- a/common_syms/field_specials.txt +++ /dev/null @@ -1 +0,0 @@ -gScrollableMultichoice_ListMenuTemplate diff --git a/common_syms/fieldmap.txt b/common_syms/fieldmap.txt deleted file mode 100644 index 0ead758462..0000000000 --- a/common_syms/fieldmap.txt +++ /dev/null @@ -1 +0,0 @@ -gBackupMapLayout diff --git a/common_syms/image_processing_effects.txt b/common_syms/image_processing_effects.txt deleted file mode 100644 index 134f7e88b2..0000000000 --- a/common_syms/image_processing_effects.txt +++ /dev/null @@ -1,10 +0,0 @@ -gCanvasColumnStart -gCanvasPixels -gCanvasRowEnd -gCanvasHeight -gCanvasColumnEnd -gCanvasRowStart -gCanvasMonPersonality -gCanvasWidth -gCanvasPalette -gCanvasPaletteStart diff --git a/common_syms/intro.txt b/common_syms/intro.txt deleted file mode 100644 index d069b1014f..0000000000 --- a/common_syms/intro.txt +++ /dev/null @@ -1,2 +0,0 @@ -gIntroFrameCounter -gMultibootProgramStruct diff --git a/common_syms/librfu_rfu.txt b/common_syms/librfu_rfu.txt deleted file mode 100644 index 4b742dcd25..0000000000 --- a/common_syms/librfu_rfu.txt +++ /dev/null @@ -1,5 +0,0 @@ -gRfuSlotStatusUNI -gRfuSlotStatusNI -gRfuLinkStatus -gRfuStatic -gRfuFixed diff --git a/common_syms/librfu_sio32id.txt b/common_syms/librfu_sio32id.txt deleted file mode 100644 index 97395e84b3..0000000000 --- a/common_syms/librfu_sio32id.txt +++ /dev/null @@ -1 +0,0 @@ -gRfuSIO32Id diff --git a/common_syms/librfu_stwi.txt b/common_syms/librfu_stwi.txt deleted file mode 100644 index a1f7735535..0000000000 --- a/common_syms/librfu_stwi.txt +++ /dev/null @@ -1 +0,0 @@ -gSTWIStatus diff --git a/common_syms/link.txt b/common_syms/link.txt deleted file mode 100644 index 4118d1eb4b..0000000000 --- a/common_syms/link.txt +++ /dev/null @@ -1,35 +0,0 @@ -gLinkPartnersHeldKeys -gLinkDebugSeed -gLocalLinkPlayerBlock -gLinkErrorOccurred -gLinkDebugFlags -gLinkFiller1 -gRemoteLinkPlayersNotReceived -gBlockReceivedStatus -gLinkFiller2 -gLinkHeldKeys -gRecvCmds -gLinkStatus -gLinkDummy1 -gLinkDummy2 -gReadyToExitStandby -gReadyToCloseLink -gReadyCloseLinkType -gSuppressLinkErrorMessage -gWirelessCommType -gSavedLinkPlayerCount -gSendCmd -gSavedMultiplayerId -gReceivedRemoteLinkPlayers -gLinkTestBGInfo -gLinkCallback -gShouldAdvanceLinkState -gLinkTestBlockChecksums -gBlockRequestType -gLinkFiller3 -gLinkFiller4 -gLinkFiller5 -gLastSendQueueCount -gLink -gLastRecvQueueCount -gLinkSavedIme diff --git a/common_syms/link_rfu_2.txt b/common_syms/link_rfu_2.txt deleted file mode 100644 index 4b8f02bad8..0000000000 --- a/common_syms/link_rfu_2.txt +++ /dev/null @@ -1,2 +0,0 @@ -gRfuAPIBuffer -gRfu diff --git a/common_syms/list_menu.txt b/common_syms/list_menu.txt deleted file mode 100644 index ed5343618c..0000000000 --- a/common_syms/list_menu.txt +++ /dev/null @@ -1,2 +0,0 @@ -gListMenuOverride -gMultiuseListMenuTemplate diff --git a/common_syms/load_save.txt b/common_syms/load_save.txt deleted file mode 100644 index 2d3d9b802f..0000000000 --- a/common_syms/load_save.txt +++ /dev/null @@ -1,4 +0,0 @@ -gFlashMemoryPresent -gSaveBlock1Ptr -gSaveBlock2Ptr -gPokemonStoragePtr diff --git a/common_syms/m4a.txt b/common_syms/m4a.txt deleted file mode 100644 index 0d6b13a79b..0000000000 --- a/common_syms/m4a.txt +++ /dev/null @@ -1,12 +0,0 @@ -gSoundInfo -gPokemonCrySongs -gPokemonCryMusicPlayers -gMPlayInfo_BGM -gMPlayJumpTable -gCgbChans -gMPlayInfo_SE1 -gMPlayInfo_SE2 -gPokemonCryTracks -gPokemonCrySong -gMPlayMemAccArea -gMPlayInfo_SE3 diff --git a/common_syms/main.txt b/common_syms/main.txt deleted file mode 100644 index f1f8076adf..0000000000 --- a/common_syms/main.txt +++ /dev/null @@ -1,10 +0,0 @@ -gKeyRepeatStartDelay -gLinkTransferringData -gMain -gKeyRepeatContinueDelay -gSoftResetDisabled -gIntrTable -gLinkVSyncDisabled -IntrMain_Buffer -gPcmDmaCounter -gAgbMainLoop_sp diff --git a/common_syms/mauville_old_man.txt b/common_syms/mauville_old_man.txt deleted file mode 100644 index 9d77b8692b..0000000000 --- a/common_syms/mauville_old_man.txt +++ /dev/null @@ -1 +0,0 @@ -gBardSong diff --git a/common_syms/overworld.txt b/common_syms/overworld.txt deleted file mode 100644 index dcada0bbef..0000000000 --- a/common_syms/overworld.txt +++ /dev/null @@ -1,8 +0,0 @@ -gOverworldTilemapBuffer_Bg2 -gOverworldTilemapBuffer_Bg1 -gOverworldTilemapBuffer_Bg3 -gHeldKeyCodeToSend -gFieldCallback -gFieldCallback2 -gLocalLinkPlayerId -gFieldLinkPlayerCount diff --git a/common_syms/party_menu.txt b/common_syms/party_menu.txt deleted file mode 100644 index 6ed37392c2..0000000000 --- a/common_syms/party_menu.txt +++ /dev/null @@ -1 +0,0 @@ -gItemUseCB diff --git a/common_syms/pokedex.txt b/common_syms/pokedex.txt deleted file mode 100644 index c7a297b2af..0000000000 --- a/common_syms/pokedex.txt +++ /dev/null @@ -1,2 +0,0 @@ -gUnusedPokedexU8 -gPokedexVBlankCB diff --git a/common_syms/pokedex_cry_screen.txt b/common_syms/pokedex_cry_screen.txt deleted file mode 100644 index d16ec36d64..0000000000 --- a/common_syms/pokedex_cry_screen.txt +++ /dev/null @@ -1 +0,0 @@ -gDexCryScreenState diff --git a/common_syms/random.txt b/common_syms/random.txt deleted file mode 100644 index 8037c69586..0000000000 --- a/common_syms/random.txt +++ /dev/null @@ -1,2 +0,0 @@ -gRngValue -gRng2Value diff --git a/common_syms/rtc.txt b/common_syms/rtc.txt deleted file mode 100644 index fa00a34d51..0000000000 --- a/common_syms/rtc.txt +++ /dev/null @@ -1 +0,0 @@ -gLocalTime diff --git a/common_syms/save.txt b/common_syms/save.txt deleted file mode 100644 index 131031d506..0000000000 --- a/common_syms/save.txt +++ /dev/null @@ -1,13 +0,0 @@ -gLastWrittenSector -gLastSaveCounter -gLastKnownGoodSector -gDamagedSaveSectors -gSaveCounter -gReadWriteSector -gIncrementalSectorId -gSaveUnusedVar -gSaveFileStatus -gGameContinueCallback -gRamSaveSectorLocations -gSaveUnusedVar2 -gSaveAttemptStatus diff --git a/common_syms/sound.txt b/common_syms/sound.txt deleted file mode 100644 index 0f6f2fc758..0000000000 --- a/common_syms/sound.txt +++ /dev/null @@ -1 +0,0 @@ -gDisableMusic diff --git a/common_syms/sprite.txt b/common_syms/sprite.txt deleted file mode 100644 index 627c01c0d0..0000000000 --- a/common_syms/sprite.txt +++ /dev/null @@ -1,2 +0,0 @@ -gOamMatrixAllocBitmap -gReservedSpritePaletteCount diff --git a/common_syms/start_menu.txt b/common_syms/start_menu.txt deleted file mode 100644 index 05beaf57c2..0000000000 --- a/common_syms/start_menu.txt +++ /dev/null @@ -1 +0,0 @@ -gMenuCallback diff --git a/common_syms/task.txt b/common_syms/task.txt deleted file mode 100644 index 6601bd11bb..0000000000 --- a/common_syms/task.txt +++ /dev/null @@ -1 +0,0 @@ -gTasks diff --git a/common_syms/text.txt b/common_syms/text.txt deleted file mode 100644 index cd8886e5b1..0000000000 --- a/common_syms/text.txt +++ /dev/null @@ -1,4 +0,0 @@ -gFonts -gDisableTextPrinters -gCurGlyph -gTextFlags diff --git a/common_syms/trainer_see.txt b/common_syms/trainer_see.txt deleted file mode 100644 index 0b30a632a0..0000000000 --- a/common_syms/trainer_see.txt +++ /dev/null @@ -1,5 +0,0 @@ -gWhichTrainerToFaceAfterBattle -gPostBattleMovementScript -gApproachingTrainers -gNoOfApproachingTrainers -gTrainerApproachedPlayer diff --git a/common_syms/tv.txt b/common_syms/tv.txt deleted file mode 100644 index 0370f65e1f..0000000000 --- a/common_syms/tv.txt +++ /dev/null @@ -1,4 +0,0 @@ -sCurTVShowSlot -sTV_SecretBaseVisitMovesTemp -sTV_DecorationsBuffer -sTV_SecretBaseVisitMonsTemp diff --git a/common_syms/window.txt b/common_syms/window.txt deleted file mode 100644 index 24c093a226..0000000000 --- a/common_syms/window.txt +++ /dev/null @@ -1,2 +0,0 @@ -gTransparentTileNumber -gWindowBgTilemapBuffers diff --git a/ld_script.ld b/ld_script.ld deleted file mode 100644 index a0c069c965..0000000000 --- a/ld_script.ld +++ /dev/null @@ -1,1391 +0,0 @@ -ENTRY(Start) - -gNumMusicPlayers = 4; -gMaxLines = 0; -gInitialMainCB2 = CB2_InitCopyrightScreenAfterBootup; - -MEMORY -{ - EWRAM (rwx) : ORIGIN = 0x2000000, LENGTH = 256K - IWRAM (rwx) : ORIGIN = 0x3000000, LENGTH = 32K - ROM (rx) : ORIGIN = 0x8000000, LENGTH = 32M -} - -SECTIONS { - - .ewram ORIGIN(EWRAM) : AT (__ewram_lma) - ALIGN(4) - { - __ewram_start = .; - *(.ewram*) - __ewram_end = .; - } > EWRAM - - .ewram.sbss (NOLOAD) : - ALIGN(4) - { - INCLUDE "sym_ewram.ld" - src/*.o(.sbss); - gflib/*.o(.sbss); - - *libc.a:impure.o(.data); - *libc.a:locale.o(.data); - *libc.a:mallocr.o(.data); - } > EWRAM - - .iwram ORIGIN(IWRAM) : AT (__iwram_lma) - ALIGN(4) - { - __iwram_start = .; - *(.iwram*); - __iwram_end = .; - } > IWRAM - - .iwram.bss (NOLOAD) : - ALIGN(4) - { - /* .bss starts at 0x3000000 */ - INCLUDE "sym_bss.ld" - src/*.o(.bss); - gflib/*.o(.bss); - data/*.o(.bss); - - /* .bss.code starts at 0x3001AA8 */ - src/m4a.o(.bss.code); - - /* COMMON starts at 0x30022A8 */ - INCLUDE "sym_common.ld" - *libc.a:sbrkr.o(COMMON); - } > IWRAM - - /* BEGIN ROM DATA */ - . = 0x8000000; - - .text : - ALIGN(4) - { - src/rom_header.o(.text); - src/rom_header_gf.o(.text.*); - src/rom_header_rhh.o(.text.*); - src/crt0.o(.text); - src/main.o(.text); - gflib/malloc.o(.text); - gflib/dma3_manager.o(.text); - gflib/gpu_regs.o(.text); - gflib/bg.o(.text); - gflib/blit.o(.text); - gflib/window.o(.text); - gflib/text.o(.text); - gflib/sprite.o(.text); - gflib/string_util.o(.text); - src/link.o(.text); - src/AgbRfu_LinkManager.o(.text); - src/link_rfu_3.o(.text); - src/link_rfu_2.o(.text); - src/union_room.o(.text); - src/mystery_gift_menu.o(.text); - src/union_room_player_avatar.o(.text); - src/wireless_communication_status_screen.o(.text); - src/union_room_battle.o(.text); - src/mystery_gift.o(.text); - src/mystery_gift_view.o(.text); - src/mystery_gift_server.o(.text); - src/mystery_gift_client.o(.text); - src/mystery_gift_link.o(.text); - src/wonder_news.o(.text); - src/union_room_chat.o(.text); - src/berry_crush.o(.text); - src/berry_powder.o(.text); - src/dodrio_berry_picking.o(.text); - src/pokemon_jump.o(.text); - src/minigame_countdown.o(.text); - src/rtc.o(.text); - src/main_menu.o(.text); - src/battle_controllers.o(.text); - src/decompress.o(.text); - src/digit_obj_util.o(.text); - src/battle_bg.o(.text); - src/battle_main.o(.text); - src/battle_util.o(.text); - src/battle_z_move.o(.text); - src/battle_script_commands.o(.text); - src/battle_util2.o(.text); - src/battle_controller_player.o(.text); - src/battle_gfx_sfx_util.o(.text); - src/battle_controller_opponent.o(.text); - src/battle_ai_switch_items.o(.text); - src/battle_controller_link_opponent.o(.text); - src/battle_debug.o(.text); - src/pokemon.o(.text); - src/trig.o(.text); - src/random.o(.text); - src/util.o(.text); - src/daycare.o(.text); - src/egg_hatch.o(.text); - src/battle_interface.o(.text); - src/battle_anim_smokescreen.o(.text); - src/pokeball.o(.text); - src/load_save.o(.text); - src/trade.o(.text); - src/berry_blender.o(.text); - src/play_time.o(.text); - src/new_game.o(.text); - src/overworld.o(.text); - src/fieldmap.o(.text); - src/metatile_behavior.o(.text); - src/field_camera.o(.text); - src/field_door.o(.text); - src/field_player_avatar.o(.text); - src/event_object_movement.o(.text); - src/follower_helper.o(.text); - src/field_message_box.o(.text); - src/event_object_lock.o(.text); - src/text_window.o(.text); - src/script.o(.text); - src/scrcmd.o(.text); - src/field_control_avatar.o(.text); - src/event_data.o(.text); - src/coord_event_weather.o(.text); - src/field_tasks.o(.text); - src/clock.o(.text); - src/reset_rtc_screen.o(.text); - src/start_menu.o(.text); - src/tileset_anims.o(.text); - src/palette.o(.text); - src/sound.o(.text); - src/battle_anim.o(.text); - src/battle_anim_mons.o(.text); - src/task.o(.text); - src/reshow_battle_screen.o(.text); - src/battle_anim_status_effects.o(.text); - src/title_screen.o(.text); - src/field_weather.o(.text); - src/field_weather_effect.o(.text); - src/field_screen_effect.o(.text); - src/battle_setup.o(.text); - src/cable_club.o(.text); - src/trainer_see.o(.text); - src/wild_encounter.o(.text); - src/field_effect.o(.text); - src/scanline_effect.o(.text); - src/option_menu.o(.text); - src/pokedex.o(.text); - src/trainer_card.o(.text); - src/frontier_pass.o(.text); - src/pokemon_storage_system.o(.text); - src/pokemon_icon.o(.text); - src/script_movement.o(.text); - src/fldeff_cut.o(.text); - src/mail_data.o(.text); - src/map_name_popup.o(.text); - src/item_menu_icons.o(.text); - src/battle_anim_mon_movement.o(.text); - src/item.o(.text); - src/contest.o(.text); - src/shop.o(.text); - src/fldeff_escalator.o(.text); - src/berry.o(.text); - src/script_menu.o(.text); - src/naming_screen.o(.text); - src/money.o(.text); - src/contest_effect.o(.text); - src/record_mixing.o(.text); - src/secret_base.o(.text); - src/tv.o(.text); - src/contest_util.o(.text); - src/script_pokemon_util.o(.text); - src/field_poison.o(.text); - src/pokemon_size_record.o(.text); - src/fldeff_misc.o(.text); - src/field_special_scene.o(.text); - src/rotating_gate.o(.text); - src/safari_zone.o(.text); - src/contest_link.o(.text); - src/item_use.o(.text); - src/battle_anim_effects_1.o(.text); - src/battle_anim_effects_2.o(.text); - src/battle_anim_water.o(.text); - src/battle_anim_fire.o(.text); - src/battle_anim_electric.o(.text); - src/battle_anim_ice.o(.text); - src/battle_anim_fight.o(.text); - src/battle_anim_poison.o(.text); - src/battle_anim_flying.o(.text); - src/battle_anim_psychic.o(.text); - src/battle_anim_bug.o(.text); - src/battle_anim_rock.o(.text); - src/battle_anim_ghost.o(.text); - src/battle_anim_dragon.o(.text); - src/battle_anim_dark.o(.text); - src/battle_anim_ground.o(.text); - src/battle_anim_normal.o(.text); - src/battle_anim_utility_funcs.o(.text); - src/battle_anim_new.o(.text); - src/battle_intro.o(.text); - src/bike.o(.text); - src/easy_chat.o(.text); - src/mon_markings.o(.text); - src/mauville_old_man.o(.text); - src/mail.o(.text); - src/menu_helpers.o(.text); - src/dewford_trend.o(.text); - src/heal_location.o(.text); - src/region_map.o(.text); - src/image_processing_effects.o(.text); - src/decoration.o(.text); - src/slot_machine.o(.text); - src/contest_painting.o(.text); - src/battle_ai_main.o(.text); - src/battle_ai_util.o(.text); - src/trader.o(.text); - src/starter_choose.o(.text); - src/wallclock.o(.text); - src/fldeff_rocksmash.o(.text); - src/fldeff_dig.o(.text); - src/pokeblock.o(.text); - src/fldeff_flash.o(.text); - src/post_battle_event_funcs.o(.text); - src/time_events.o(.text); - src/birch_pc.o(.text); - src/hof_pc.o(.text); - src/field_specials.o(.text); - src/battle_records.o(.text); - src/pokedex_area_screen.o(.text); - src/evolution_scene.o(.text); - src/roulette.o(.text); - src/pokedex_cry_screen.o(.text); - src/coins.o(.text); - src/landmark.o(.text); - src/fldeff_strength.o(.text); - src/battle_transition.o(.text); - src/battle_controller_link_partner.o(.text); - src/battle_message.o(.text); - src/cable_car.o(.text); - src/math_util.o(.text); - src/palette_util.o(.text); - src/confetti_util.o(.text); - src/save.o(.text); - src/mystery_event_script.o(.text); - src/field_effect_helpers.o(.text); - src/contest_ai.o(.text); - src/battle_anim_sound_tasks.o(.text); - src/battle_controller_safari.o(.text); - src/fldeff_sweetscent.o(.text); - src/battle_anim_effects_3.o(.text); - src/move_relearner.o(.text); - src/fldeff_softboiled.o(.text); - src/decoration_inventory.o(.text); - src/roamer.o(.text); - src/battle_tower.o(.text); - src/use_pokeblock.o(.text); - src/battle_controller_wally.o(.text); - src/player_pc.o(.text); - src/intro.o(.text); - src/reload_save.o(.text); - src/field_region_map.o(.text); - src/battle_anim_throw.o(.text); - src/hall_of_fame.o(.text); - src/credits.o(.text); - src/lottery_corner.o(.text); - src/diploma.o(.text); - src/berry_tag_screen.o(.text); - src/mystery_event_menu.o(.text); - src/save_failed_screen.o(.text); - src/braille_puzzles.o(.text); - src/pokeblock_feed.o(.text); - src/clear_save_data_screen.o(.text); - src/intro_credits_graphics.o(.text); - src/evolution_graphics.o(.text); - src/bard_music.o(.text); - src/fldeff_teleport.o(.text); - src/battle_tv.o(.text); - src/pokemon_animation.o(.text); - src/recorded_battle.o(.text); - src/battle_controller_recorded_opponent.o(.text); - src/battle_controller_recorded_player.o(.text); - src/trainer_pokemon_sprites.o(.text); - src/lilycove_lady.o(.text); - src/battle_dome.o(.text); - src/battle_palace.o(.text); - src/match_call.o(.text); - src/menu.o(.text); - src/battle_factory_screen.o(.text); - src/apprentice.o(.text); - src/frontier_util.o(.text); - src/battle_arena.o(.text); - src/battle_factory.o(.text); - src/battle_pike.o(.text); - src/rotating_tile_puzzle.o(.text); - src/battle_pyramid.o(.text); - src/item_menu.o(.text); - src/list_menu.o(.text); - src/dynamic_placeholder_text_util.o(.text); - src/save_location.o(.text); - src/item_icon.o(.text); - src/party_menu.o(.text); - src/battle_tent.o(.text); - src/braille.o(.text); - src/multiboot.o(.text); - src/berry_fix_graphics.o(.text); - src/battle_controller_player_partner.o(.text); - src/mirage_tower.o(.text); - src/berry_fix_program.o(.text); - src/pokemon_summary_screen.o(.text); - src/pokedex_area_region_map.o(.text); - src/battle_pyramid_bag.o(.text); - src/pokenav.o(.text); - src/pokenav_main_menu.o(.text); - src/pokenav_list.o(.text); - src/pokenav_menu_handler.o(.text); - src/pokenav_menu_handler_gfx.o(.text); - src/pokenav_match_call_list.o(.text); - src/pokenav_match_call_gfx.o(.text); - src/pokenav_region_map.o(.text); - src/pokenav_conditions.o(.text); - src/pokenav_conditions_gfx.o(.text); - src/pokenav_conditions_search_results.o(.text); - src/pokenav_ribbons_list.o(.text); - src/pokenav_ribbons_summary.o(.text); - src/pokenav_match_call_data.o(.text); - src/menu_specialized.o(.text); - src/ereader_helpers.o(.text); - src/faraway_island.o(.text); - src/ereader_screen.o(.text); - src/trainer_hill.o(.text); - src/rayquaza_scene.o(.text); - src/walda_phrase.o(.text); - src/contest_link_util.o(.text); - src/gym_leader_rematch.o(.text); - src/battle_transition_frontier.o(.text); - src/international_string_util.o(.text); - src/pokemon_sprite_visualizer.o(.text); - src/expansion_intro.o(.text); - } > ROM =0 - - script_data : - ALIGN(4) - { - data/event_scripts.o(script_data); - data/battle_anim_scripts.o(script_data); - data/battle_scripts_1.o(script_data); - data/field_effect_scripts.o(script_data); - data/battle_scripts_2.o(script_data); - data/contest_ai_scripts.o(script_data); - data/mystery_event_script_cmd_table.o(script_data); - } > ROM =0 - - lib_text : - ALIGN(4) - { - src/libgcnmultiboot.o(.text); - src/m4a_1.o(.text); - src/m4a.o(.text); - src/agb_flash.o(.text); - src/agb_flash_1m.o(.text); - src/agb_flash_mx.o(.text); - src/siirtc.o(.text); - src/librfu_stwi.o(.text); - src/librfu_intr.o(.text); - src/librfu_rfu.o(.text); - src/librfu_sio32id.o(.text); - src/libisagbprn.o(.text); - *libagbsyscall.a:ArcTan2.o(.text); - *libagbsyscall.a:BgAffineSet.o(.text); - *libagbsyscall.a:CpuFastSet.o(.text); - *libagbsyscall.a:CpuSet.o(.text); - *libagbsyscall.a:Div.o(.text); - *libagbsyscall.a:LZ77UnCompVram.o(.text); - *libagbsyscall.a:LZ77UnCompWram.o(.text); - *libagbsyscall.a:MultiBoot.o(.text); - *libagbsyscall.a:ObjAffineSet.o(.text); - *libagbsyscall.a:RLUnCompVram.o(.text); - *libagbsyscall.a:RLUnCompWram.o(.text); - *libagbsyscall.a:RegisterRamReset.o(.text); - *libagbsyscall.a:SoftReset.o(.text); - *libagbsyscall.a:Sqrt.o(.text); - *libagbsyscall.a:VBlankIntrWait.o(.text); - *libgcc.a:_call_via_rX.o(.text); - *libgcc.a:_divdi3.o(.text); - *libgcc.a:_divsi3.o(.text); - *libgcc.a:_dvmd_tls.o(.text); - *libgcc.a:_fixunsdfsi.o(.text); - *libgcc.a:_fixunssfsi.o(.text); - *libgcc.a:_modsi3.o(.text); - *libgcc.a:_muldi3.o(.text); - *libgcc.a:_udivdi3.o(.text); - *libgcc.a:_udivsi3.o(.text); - *libgcc.a:_umodsi3.o(.text); - *libgcc.a:dp-bit.o(.text); - *libgcc.a:fp-bit.o(.text); - *libgcc.a:_lshrdi3.o(.text); - *libgcc.a:_negdi2.o(.text); - *libc.a:memcpy.o(.text); - *libc.a:memset.o(.text); - *libc.a:strcmp.o(.text); - *libc.a:strcpy.o(.text); - *libc.a:impure.o(.text); - *libc.a:vsprintf.o(.text); - *libc.a:vfprintf.o(.text); - *libc.a:wsetup.o(.text); - *libc.a:dtoa.o(.text); - *libc.a:fflush.o(.text); - *libc.a:findfp.o(.text); - *libc.a:freer.o(.text); - *libc.a:mtrim.o(.text); - *libc.a:fvwrite.o(.text); - *libc.a:fwalk.o(.text); - *libc.a:locale.o(.text); - *libc.a:makebuf.o(.text); - *libc.a:mallocr.o(.text); - *libc.a:mbtowc_r.o(.text); - *libc.a:memchr.o(.text); - *libc.a:memmove.o(.text); - *libc.a:mlock.o(.text); - *libc.a:mprec.o(.text); - *libc.a:s_isinf.o(.text); - *libc.a:s_isnan.o(.text); - *libc.a:sbrkr.o(.text); - *libc.a:stdio.o(.text); - *libc.a:strlen.o(.text); - *libc.a:syscalls.o(.text); - *libc.a:writer.o(.text); - *libc.a:callocr.o(.text); - *libc.a:closer.o(.text); - *libc.a:errno.o(.text); - *libc.a:fstatr.o(.text); - *libc.a:libcfunc.o(.text); - *libc.a:lseekr.o(.text); - *libc.a:readr.o(.text); - } > ROM =0 - - .rodata : - ALIGN(4) - { - src/rom_header.o(.rodata); - src/rom_header_gf.o(.rodata); - src/main.o(.rodata); - gflib/bg.o(.rodata); - gflib/window.o(.rodata); - gflib/text.o(.rodata); - gflib/sprite.o(.rodata); - gflib/io_reg.o(.rodata); - gflib/string_util.o(.rodata); - src/link.o(.rodata); - src/link.o(.rodata.str1.4); - src/AgbRfu_LinkManager.o(.rodata); - src/link_rfu_3.o(.rodata); - src/link_rfu_2.o(.rodata); - src/link_rfu_2.o(.rodata.str1.4); - src/union_room.o(.rodata); - src/mystery_gift_menu.o(.rodata); - src/union_room_player_avatar.o(.rodata); - src/wireless_communication_status_screen.o(.rodata); - src/union_room_battle.o(.rodata); - src/mystery_gift.o(.rodata); - src/mystery_gift_view.o(.rodata); - src/mystery_gift_server.o(.rodata); - src/mystery_gift_client.o(.rodata); - src/mystery_gift_scripts.o(.rodata); - src/wonder_news.o(.rodata); - src/union_room_chat.o(.rodata); - src/berry_crush.o(.rodata); - src/berry_powder.o(.rodata); - src/dodrio_berry_picking.o(.rodata); - src/pokemon_jump.o(.rodata); - src/minigame_countdown.o(.rodata); - src/rtc.o(.rodata); - src/main_menu.o(.rodata); - src/battle_controllers.o(.rodata); - src/digit_obj_util.o(.rodata); - src/data.o(.rodata); - src/battle_bg.o(.rodata); - src/battle_main.o(.rodata); - src/battle_util.o(.rodata); - src/battle_z_move.o(.rodata); - src/battle_script_commands.o(.rodata); - src/battle_controller_player.o(.rodata); - src/battle_anim_smokescreen.o(.rodata); - src/battle_controller_opponent.o(.rodata); - src/battle_ai_switch_items.o(.rodata); - src/battle_controller_link_opponent.o(.rodata); - src/battle_debug.o(.rodata); - src/pokemon.o(.rodata); - src/trig.o(.rodata); - src/util.o(.rodata); - src/daycare.o(.rodata); - src/egg_hatch.o(.rodata); - src/battle_gfx_sfx_util.o(.rodata); - src/battle_interface.o(.rodata); - src/pokeball.o(.rodata); - src/trade.o(.rodata); - src/berry_blender.o(.rodata); - src/new_game.o(.rodata); - src/overworld.o(.rodata); - src/tilesets.o(.rodata); - data/maps.o(.rodata); - src/fieldmap.o(.rodata); - src/metatile_behavior.o(.rodata); - src/field_door.o(.rodata); - src/field_player_avatar.o(.rodata); - src/event_object_movement.o(.rodata); - src/follower_helper.o(.rodata); - src/text_window.o(.rodata); - src/scrcmd.o(.rodata); - src/field_control_avatar.o(.rodata); - src/coord_event_weather.o(.rodata); - src/field_tasks.o(.rodata); - src/reset_rtc_screen.o(.rodata); - src/start_menu.o(.rodata); - src/tileset_anims.o(.rodata); - src/palette.o(.rodata); - src/sound.o(.rodata); - src/battle_anim.o(.rodata); - src/battle_anim_mons.o(.rodata); - data/map_events.o(.rodata); - src/reshow_battle_screen.o(.rodata); - src/battle_anim_status_effects.o(.rodata); - src/title_screen.o(.rodata); - src/field_weather.o(.rodata); - src/field_weather_effect.o(.rodata); - src/field_screen_effect.o(.rodata); - src/battle_setup.o(.rodata); - src/cable_club.o(.rodata); - src/trainer_see.o(.rodata); - src/wild_encounter.o(.rodata); - src/field_effect.o(.rodata); - src/scanline_effect.o(.rodata); - src/option_menu.o(.rodata); - src/pokedex.o(.rodata); - src/trainer_card.o(.rodata); - src/frontier_pass.o(.rodata); - src/pokemon_storage_system.o(.rodata); - src/pokemon_icon.o(.rodata); - src/fldeff_cut.o(.rodata); - src/map_name_popup.o(.rodata); - src/item_menu_icons.o(.rodata); - src/battle_anim_mon_movement.o(.rodata); - src/item.o(.rodata); - src/contest.o(.rodata); - src/shop.o(.rodata); - src/fldeff_escalator.o(.rodata); - src/berry.o(.rodata); - src/script_menu.o(.rodata); - src/naming_screen.o(.rodata); - src/money.o(.rodata); - src/contest_effect.o(.rodata); - src/record_mixing.o(.rodata); - src/secret_base.o(.rodata); - src/tv.o(.rodata); - src/contest_util.o(.rodata); - src/script_pokemon_util.o(.rodata); - src/pokemon_size_record.o(.rodata) - src/fldeff_misc.o(.rodata); - src/field_special_scene.o(.rodata); - src/rotating_gate.o(.rodata); - src/contest_link.o(.rodata); - src/item_use.o(.rodata); - src/battle_anim_effects_1.o(.rodata); - src/battle_anim_effects_2.o(.rodata); - src/battle_anim_water.o(.rodata); - src/battle_anim_fire.o(.rodata); - src/battle_anim_electric.o(.rodata); - src/battle_anim_ice.o(.rodata); - src/battle_anim_fight.o(.rodata); - src/battle_anim_poison.o(.rodata); - src/battle_anim_flying.o(.rodata); - src/battle_anim_psychic.o(.rodata); - src/battle_anim_bug.o(.rodata); - src/battle_anim_rock.o(.rodata); - src/battle_anim_ghost.o(.rodata); - src/battle_anim_dragon.o(.rodata); - src/battle_anim_dark.o(.rodata); - src/battle_anim_ground.o(.rodata); - src/battle_anim_normal.o(.rodata); - src/battle_anim_utility_funcs.o(.rodata); - src/battle_anim_new.o(.rodata); - src/battle_intro.o(.rodata); - src/bike.o(.rodata); - src/easy_chat.o(.rodata); - src/mon_markings.o(.rodata); - src/mauville_old_man.o(.rodata); - src/mail.o(.rodata); - src/menu_helpers.o(.rodata); - src/heal_location.o(.rodata); - src/region_map.o(.rodata); - src/image_processing_effects.o(.rodata); - src/decoration.o(.rodata); - src/slot_machine.o(.rodata); - src/contest_painting.o(.rodata); - src/battle_ai_main.o(.rodata); - src/battle_ai_util.o(.rodata); - src/trader.o(.rodata); - src/starter_choose.o(.rodata); - src/wallclock.o(.rodata); - src/pokeblock.o(.rodata); - src/fldeff_flash.o(.rodata); - src/time_events.o(.rodata); - src/field_specials.o(.rodata); - src/battle_records.o(.rodata); - src/pokedex_area_screen.o(.rodata); - src/evolution_scene.o(.rodata); - src/roulette.o(.rodata); - src/pokedex_cry_screen.o(.rodata); - src/landmark.o(.rodata); - src/battle_transition.o(.rodata); - src/battle_controller_link_partner.o(.rodata); - src/battle_message.o(.rodata); - src/cable_car.o(.rodata); - src/save.o(.rodata); - src/field_effect_helpers.o(.rodata); - src/contest_ai.o(.rodata); - src/battle_anim_sound_tasks.o(.rodata); - src/battle_controller_safari.o(.rodata); - src/battle_anim_effects_3.o(.rodata); - src/move_relearner.o(.rodata); - src/roamer.o(.rodata); - src/battle_tower.o(.rodata); - src/use_pokeblock.o(.rodata); - src/battle_controller_wally.o(.rodata); - src/player_pc.o(.rodata); - src/intro.o(.rodata); - src/field_region_map.o(.rodata); - src/battle_anim_throw.o(.rodata); - src/hall_of_fame.o(.rodata); - src/credits.o(.rodata); - src/lottery_corner.o(.rodata); - src/diploma.o(.rodata); - src/strings.o(.rodata); - src/berry_tag_screen.o(.rodata); - src/mystery_event_menu.o(.rodata); - src/save_failed_screen.o(.rodata); - src/braille_puzzles.o(.rodata); - src/pokeblock_feed.o(.rodata); - src/clear_save_data_screen.o(.rodata); - src/intro_credits_graphics.o(.rodata); - src/evolution_graphics.o(.rodata); - src/bard_music.o(.rodata); - src/battle_tv.o(.rodata); - src/pokemon_animation.o(.rodata); - src/battle_controller_recorded_opponent.o(.rodata); - src/battle_controller_recorded_player.o(.rodata); - src/trainer_pokemon_sprites.o(.rodata); - src/lilycove_lady.o(.rodata); - src/battle_dome.o(.rodata); - src/battle_palace.o(.rodata); - src/match_call.o(.rodata); - src/menu.o(.rodata); - src/battle_factory_screen.o(.rodata); - src/apprentice.o(.rodata); - src/frontier_util.o(.rodata); - src/battle_arena.o(.rodata); - src/battle_factory.o(.rodata); - src/battle_pike.o(.rodata); - src/rotating_tile_puzzle.o(.rodata); - src/battle_pyramid.o(.rodata); - src/item_menu.o(.rodata); - src/list_menu.o(.rodata); - src/save_location.o(.rodata); - src/item_icon.o(.rodata); - src/party_menu.o(.rodata); - src/battle_tent.o(.rodata); - src/braille.o(.rodata); - src/multiboot.o(.rodata); - src/berry_fix_graphics.o(.rodata); - src/battle_controller_player_partner.o(.rodata); - src/mirage_tower.o(.rodata); - src/berry_fix_program.o(.rodata); - src/pokemon_summary_screen.o(.rodata); - src/pokedex_area_region_map.o(.rodata); - src/battle_pyramid_bag.o(.rodata); - src/pokenav.o(.rodata); - src/pokenav_main_menu.o(.rodata); - src/pokenav_list.o(.rodata); - src/pokenav_menu_handler.o(.rodata); - src/pokenav_menu_handler_gfx.o(.rodata); - src/pokenav_match_call_list.o(.rodata); - src/pokenav_match_call_gfx.o(.rodata); - src/pokenav_region_map.o(.rodata); - src/pokenav_conditions_gfx.o(.rodata); - src/pokenav_conditions_search_results.o(.rodata); - src/pokenav_ribbons_list.o(.rodata); - src/pokenav_ribbons_summary.o(.rodata); - src/pokenav_match_call_data.o(.rodata); - src/menu_specialized.o(.rodata); - src/ereader_helpers.o(.rodata); - src/faraway_island.o(.rodata); - src/ereader_screen.o(.rodata); - src/trainer_hill.o(.rodata); - src/rayquaza_scene.o(.rodata); - src/walda_phrase.o(.rodata); - src/gym_leader_rematch.o(.rodata); - src/battle_transition_frontier.o(.rodata); - src/text_input_strings.o(.rodata); - src/fonts.o(.rodata); - src/international_string_util.o(.rodata); - src/mystery_event_msg.o(.rodata); - data/mystery_gift.o(.rodata); - src/m4a_tables.o(.rodata); - data/sound_data.o(.rodata); - src/pokemon_sprite_visualizer.o(.rodata); - src/expansion_intro.o(.rodata); - } > ROM =0 - - song_data : - ALIGN(4) - { - sound/songs/midi/mus_dummy.o(.rodata); - sound/songs/midi/se_use_item.o(.rodata); - sound/songs/midi/se_pc_login.o(.rodata); - sound/songs/midi/se_pc_off.o(.rodata); - sound/songs/midi/se_pc_on.o(.rodata); - sound/songs/midi/se_select.o(.rodata); - sound/songs/se_win_open.o(.rodata); - sound/songs/se_wall_hit.o(.rodata); - sound/songs/midi/se_door.o(.rodata); - sound/songs/midi/se_exit.o(.rodata); - sound/songs/midi/se_ledge.o(.rodata); - sound/songs/midi/se_bike_bell.o(.rodata); - sound/songs/midi/se_not_effective.o(.rodata); - sound/songs/midi/se_effective.o(.rodata); - sound/songs/midi/se_super_effective.o(.rodata); - sound/songs/midi/se_ball_open.o(.rodata); - sound/songs/midi/se_faint.o(.rodata); - sound/songs/midi/se_flee.o(.rodata); - sound/songs/midi/se_sliding_door.o(.rodata); - sound/songs/midi/se_ship.o(.rodata); - sound/songs/midi/se_bang.o(.rodata); - sound/songs/midi/se_pin.o(.rodata); - sound/songs/midi/se_boo.o(.rodata); - sound/songs/midi/se_ball.o(.rodata); - sound/songs/midi/se_contest_place.o(.rodata); - sound/songs/midi/se_a.o(.rodata); - sound/songs/midi/se_i.o(.rodata); - sound/songs/midi/se_u.o(.rodata); - sound/songs/midi/se_e.o(.rodata); - sound/songs/midi/se_o.o(.rodata); - sound/songs/midi/se_n.o(.rodata); - sound/songs/midi/se_success.o(.rodata); - sound/songs/midi/se_failure.o(.rodata); - sound/songs/midi/se_exp.o(.rodata); - sound/songs/midi/se_bike_hop.o(.rodata); - sound/songs/midi/se_switch.o(.rodata); - sound/songs/midi/se_click.o(.rodata); - sound/songs/midi/se_fu_zaku.o(.rodata); - sound/songs/midi/se_contest_condition_lose.o(.rodata); - sound/songs/midi/se_lavaridge_fall_warp.o(.rodata); - sound/songs/midi/se_ice_stairs.o(.rodata); - sound/songs/midi/se_ice_break.o(.rodata); - sound/songs/midi/se_ice_crack.o(.rodata); - sound/songs/midi/se_fall.o(.rodata); - sound/songs/midi/se_unlock.o(.rodata); - sound/songs/midi/se_warp_in.o(.rodata); - sound/songs/midi/se_warp_out.o(.rodata); - sound/songs/midi/se_repel.o(.rodata); - sound/songs/midi/se_rotating_gate.o(.rodata); - sound/songs/midi/se_truck_move.o(.rodata); - sound/songs/midi/se_truck_stop.o(.rodata); - sound/songs/midi/se_truck_unload.o(.rodata); - sound/songs/midi/se_truck_door.o(.rodata); - sound/songs/midi/se_berry_blender.o(.rodata); - sound/songs/midi/se_card.o(.rodata); - sound/songs/midi/se_save.o(.rodata); - sound/songs/midi/se_ball_bounce_1.o(.rodata); - sound/songs/midi/se_ball_bounce_2.o(.rodata); - sound/songs/midi/se_ball_bounce_3.o(.rodata); - sound/songs/midi/se_ball_bounce_4.o(.rodata); - sound/songs/midi/se_ball_trade.o(.rodata); - sound/songs/midi/se_ball_throw.o(.rodata); - sound/songs/midi/se_note_c.o(.rodata); - sound/songs/midi/se_note_d.o(.rodata); - sound/songs/midi/se_note_e.o(.rodata); - sound/songs/midi/se_note_f.o(.rodata); - sound/songs/midi/se_note_g.o(.rodata); - sound/songs/midi/se_note_a.o(.rodata); - sound/songs/midi/se_note_b.o(.rodata); - sound/songs/midi/se_note_c_high.o(.rodata); - sound/songs/midi/se_puddle.o(.rodata); - sound/songs/midi/se_bridge_walk.o(.rodata); - sound/songs/midi/se_itemfinder.o(.rodata); - sound/songs/midi/se_ding_dong.o(.rodata); - sound/songs/midi/se_balloon_red.o(.rodata); - sound/songs/midi/se_balloon_blue.o(.rodata); - sound/songs/midi/se_balloon_yellow.o(.rodata); - sound/songs/midi/se_breakable_door.o(.rodata); - sound/songs/midi/se_mud_ball.o(.rodata); - sound/songs/midi/se_field_poison.o(.rodata); - sound/songs/midi/se_escalator.o(.rodata); - sound/songs/midi/se_thunderstorm.o(.rodata); - sound/songs/midi/se_thunderstorm_stop.o(.rodata); - sound/songs/midi/se_downpour.o(.rodata); - sound/songs/midi/se_downpour_stop.o(.rodata); - sound/songs/midi/se_rain.o(.rodata); - sound/songs/midi/se_rain_stop.o(.rodata); - sound/songs/midi/se_thunder.o(.rodata); - sound/songs/midi/se_thunder2.o(.rodata); - sound/songs/midi/se_elevator.o(.rodata); - sound/songs/midi/se_low_health.o(.rodata); - sound/songs/midi/se_exp_max.o(.rodata); - sound/songs/midi/se_roulette_ball.o(.rodata); - sound/songs/midi/se_roulette_ball2.o(.rodata); - sound/songs/midi/se_taillow_wing_flap.o(.rodata); - sound/songs/midi/se_shop.o(.rodata); - sound/songs/midi/se_contest_heart.o(.rodata); - sound/songs/midi/se_contest_curtain_rise.o(.rodata); - sound/songs/midi/se_contest_curtain_fall.o(.rodata); - sound/songs/midi/se_contest_icon_change.o(.rodata); - sound/songs/midi/se_contest_icon_clear.o(.rodata); - sound/songs/midi/se_contest_mons_turn.o(.rodata); - sound/songs/midi/se_shiny.o(.rodata); - sound/songs/midi/se_intro_blast.o(.rodata); - sound/songs/midi/se_mugshot.o(.rodata); - sound/songs/midi/se_applause.o(.rodata); - sound/songs/midi/se_vend.o(.rodata); - sound/songs/midi/se_orb.o(.rodata); - sound/songs/se_dex_scroll.o(.rodata); - sound/songs/se_dex_page.o(.rodata); - sound/songs/midi/se_pokenav_on.o(.rodata); - sound/songs/midi/se_pokenav_off.o(.rodata); - sound/songs/midi/se_dex_search.o(.rodata); - sound/songs/midi/se_egg_hatch.o(.rodata); - sound/songs/midi/se_ball_tray_enter.o(.rodata); - sound/songs/midi/se_ball_tray_ball.o(.rodata); - sound/songs/midi/se_ball_tray_exit.o(.rodata); - sound/songs/midi/se_glass_flute.o(.rodata); - sound/songs/se_m_thunderbolt.o(.rodata); - sound/songs/se_m_thunderbolt2.o(.rodata); - sound/songs/se_m_harden.o(.rodata); - sound/songs/se_m_nightmare.o(.rodata); - sound/songs/se_m_vital_throw.o(.rodata); - sound/songs/se_m_vital_throw2.o(.rodata); - sound/songs/se_m_bubble.o(.rodata); - sound/songs/se_m_bubble2.o(.rodata); - sound/songs/se_m_bubble3.o(.rodata); - sound/songs/se_m_rain_dance.o(.rodata); - sound/songs/midi/se_m_cut.o(.rodata); - sound/songs/se_m_string_shot.o(.rodata); - sound/songs/se_m_string_shot2.o(.rodata); - sound/songs/se_m_rock_throw.o(.rodata); - sound/songs/midi/se_m_gust.o(.rodata); - sound/songs/midi/se_m_gust2.o(.rodata); - sound/songs/midi/se_m_double_slap.o(.rodata); - sound/songs/se_m_double_team.o(.rodata); - sound/songs/midi/se_m_razor_wind.o(.rodata); - sound/songs/se_m_icy_wind.o(.rodata); - sound/songs/se_m_thunder_wave.o(.rodata); - sound/songs/midi/se_m_comet_punch.o(.rodata); - sound/songs/midi/se_m_mega_kick.o(.rodata); - sound/songs/midi/se_m_mega_kick2.o(.rodata); - sound/songs/se_m_crabhammer.o(.rodata); - sound/songs/midi/se_m_jump_kick.o(.rodata); - sound/songs/se_m_flame_wheel.o(.rodata); - sound/songs/se_m_flame_wheel2.o(.rodata); - sound/songs/se_m_flamethrower.o(.rodata); - sound/songs/midi/se_m_fire_punch.o(.rodata); - sound/songs/se_m_toxic.o(.rodata); - sound/songs/se_m_sacred_fire.o(.rodata); - sound/songs/se_m_sacred_fire2.o(.rodata); - sound/songs/se_m_ember.o(.rodata); - sound/songs/midi/se_m_take_down.o(.rodata); - sound/songs/se_m_blizzard.o(.rodata); - sound/songs/se_m_blizzard2.o(.rodata); - sound/songs/midi/se_m_scratch.o(.rodata); - sound/songs/midi/se_m_vicegrip.o(.rodata); - sound/songs/midi/se_m_wing_attack.o(.rodata); - sound/songs/midi/se_m_fly.o(.rodata); - sound/songs/midi/se_m_sand_attack.o(.rodata); - sound/songs/midi/se_m_razor_wind2.o(.rodata); - sound/songs/se_m_bite.o(.rodata); - sound/songs/midi/se_m_headbutt.o(.rodata); - sound/songs/se_m_surf.o(.rodata); - sound/songs/se_m_hydro_pump.o(.rodata); - sound/songs/se_m_whirlpool.o(.rodata); - sound/songs/midi/se_m_horn_attack.o(.rodata); - sound/songs/midi/se_m_tail_whip.o(.rodata); - sound/songs/se_m_mist.o(.rodata); - sound/songs/se_m_poison_powder.o(.rodata); - sound/songs/midi/se_m_bind.o(.rodata); - sound/songs/se_m_dragon_rage.o(.rodata); - sound/songs/se_m_sing.o(.rodata); - sound/songs/se_m_perish_song.o(.rodata); - sound/songs/midi/se_m_pay_day.o(.rodata); - sound/songs/se_m_dig.o(.rodata); - sound/songs/se_m_dizzy_punch.o(.rodata); - sound/songs/se_m_self_destruct.o(.rodata); - sound/songs/se_m_explosion.o(.rodata); - sound/songs/se_m_absorb_2.o(.rodata); - sound/songs/se_m_absorb.o(.rodata); - sound/songs/se_m_screech.o(.rodata); - sound/songs/se_m_bubble_beam.o(.rodata); - sound/songs/se_m_bubble_beam2.o(.rodata); - sound/songs/se_m_supersonic.o(.rodata); - sound/songs/se_m_belly_drum.o(.rodata); - sound/songs/se_m_metronome.o(.rodata); - sound/songs/se_m_bonemerang.o(.rodata); - sound/songs/se_m_lick.o(.rodata); - sound/songs/se_m_psybeam.o(.rodata); - sound/songs/se_m_faint_attack.o(.rodata); - sound/songs/midi/se_m_swords_dance.o(.rodata); - sound/songs/midi/se_m_leer.o(.rodata); - sound/songs/se_m_swagger.o(.rodata); - sound/songs/se_m_swagger2.o(.rodata); - sound/songs/se_m_heal_bell.o(.rodata); - sound/songs/se_m_confuse_ray.o(.rodata); - sound/songs/se_m_snore.o(.rodata); - sound/songs/se_m_brick_break.o(.rodata); - sound/songs/se_m_giga_drain.o(.rodata); - sound/songs/se_m_psybeam2.o(.rodata); - sound/songs/se_m_solar_beam.o(.rodata); - sound/songs/se_m_petal_dance.o(.rodata); - sound/songs/se_m_teleport.o(.rodata); - sound/songs/se_m_minimize.o(.rodata); - sound/songs/se_m_sketch.o(.rodata); - sound/songs/se_m_swift.o(.rodata); - sound/songs/se_m_reflect.o(.rodata); - sound/songs/se_m_barrier.o(.rodata); - sound/songs/se_m_detect.o(.rodata); - sound/songs/se_m_lock_on.o(.rodata); - sound/songs/se_m_moonlight.o(.rodata); - sound/songs/se_m_charm.o(.rodata); - sound/songs/se_m_charge.o(.rodata); - sound/songs/se_m_strength.o(.rodata); - sound/songs/se_m_hyper_beam.o(.rodata); - sound/songs/se_m_waterfall.o(.rodata); - sound/songs/se_m_reversal.o(.rodata); - sound/songs/se_m_acid_armor.o(.rodata); - sound/songs/se_m_sandstorm.o(.rodata); - sound/songs/se_m_tri_attack.o(.rodata); - sound/songs/se_m_tri_attack2.o(.rodata); - sound/songs/se_m_encore.o(.rodata); - sound/songs/se_m_encore2.o(.rodata); - sound/songs/se_m_baton_pass.o(.rodata); - sound/songs/se_m_milk_drink.o(.rodata); - sound/songs/se_m_attract.o(.rodata); - sound/songs/se_m_attract2.o(.rodata); - sound/songs/se_m_morning_sun.o(.rodata); - sound/songs/se_m_flatter.o(.rodata); - sound/songs/se_m_sand_tomb.o(.rodata); - sound/songs/se_m_grasswhistle.o(.rodata); - sound/songs/se_m_spit_up.o(.rodata); - sound/songs/se_m_dive.o(.rodata); - sound/songs/se_m_earthquake.o(.rodata); - sound/songs/se_m_twister.o(.rodata); - sound/songs/se_m_sweet_scent.o(.rodata); - sound/songs/se_m_yawn.o(.rodata); - sound/songs/se_m_sky_uppercut.o(.rodata); - sound/songs/se_m_stat_increase.o(.rodata); - sound/songs/se_m_heat_wave.o(.rodata); - sound/songs/se_m_uproar.o(.rodata); - sound/songs/se_m_hail.o(.rodata); - sound/songs/se_m_cosmic_power.o(.rodata); - sound/songs/se_m_teeter_dance.o(.rodata); - sound/songs/se_m_stat_decrease.o(.rodata); - sound/songs/se_m_haze.o(.rodata); - sound/songs/se_m_hyper_beam2.o(.rodata); - sound/songs/midi/se_rg_door.o(.rodata); - sound/songs/midi/se_rg_card_flip.o(.rodata); - sound/songs/midi/se_rg_card_flipping.o(.rodata); - sound/songs/midi/se_rg_card_open.o(.rodata); - sound/songs/midi/se_rg_bag_cursor.o(.rodata); - sound/songs/midi/se_rg_bag_pocket.o(.rodata); - sound/songs/midi/se_rg_ball_click.o(.rodata); - sound/songs/midi/se_rg_shop.o(.rodata); - sound/songs/midi/se_rg_ss_anne_horn.o(.rodata); - sound/songs/midi/se_rg_help_open.o(.rodata); - sound/songs/midi/se_rg_help_close.o(.rodata); - sound/songs/midi/se_rg_help_error.o(.rodata); - sound/songs/midi/se_rg_deoxys_move.o(.rodata); - sound/songs/midi/se_rg_poke_jump_success.o(.rodata); - sound/songs/midi/se_rg_poke_jump_failure.o(.rodata); - sound/songs/midi/se_pokenav_call.o(.rodata); - sound/songs/midi/se_pokenav_hang_up.o(.rodata); - sound/songs/midi/se_arena_timeup1.o(.rodata); - sound/songs/midi/se_arena_timeup2.o(.rodata); - sound/songs/midi/se_pike_curtain_close.o(.rodata); - sound/songs/midi/se_pike_curtain_open.o(.rodata); - sound/songs/midi/se_sudowoodo_shake.o(.rodata); - sound/songs/midi/mus_littleroot_test.o(.rodata); - sound/songs/midi/mus_gsc_route38.o(.rodata); - sound/songs/midi/mus_caught.o(.rodata); - sound/songs/midi/mus_victory_wild.o(.rodata); - sound/songs/midi/mus_victory_gym_leader.o(.rodata); - sound/songs/midi/mus_victory_league.o(.rodata); - sound/songs/midi/mus_c_comm_center.o(.rodata); - sound/songs/midi/mus_gsc_pewter.o(.rodata); - sound/songs/midi/mus_c_vs_legend_beast.o(.rodata); - sound/songs/midi/mus_route101.o(.rodata); - sound/songs/midi/mus_route110.o(.rodata); - sound/songs/midi/mus_route120.o(.rodata); - sound/songs/midi/mus_petalburg.o(.rodata); - sound/songs/midi/mus_oldale.o(.rodata); - sound/songs/midi/mus_gym.o(.rodata); - sound/songs/midi/mus_surf.o(.rodata); - sound/songs/midi/mus_petalburg_woods.o(.rodata); - sound/songs/midi/mus_level_up.o(.rodata); - sound/songs/midi/mus_heal.o(.rodata); - sound/songs/midi/mus_obtain_badge.o(.rodata); - sound/songs/midi/mus_obtain_item.o(.rodata); - sound/songs/midi/mus_evolved.o(.rodata); - sound/songs/midi/mus_obtain_tmhm.o(.rodata); - sound/songs/midi/mus_lilycove_museum.o(.rodata); - sound/songs/midi/mus_route122.o(.rodata); - sound/songs/midi/mus_oceanic_museum.o(.rodata); - sound/songs/midi/mus_evolution_intro.o(.rodata); - sound/songs/midi/mus_evolution.o(.rodata); - sound/songs/midi/mus_move_deleted.o(.rodata); - sound/songs/midi/mus_encounter_girl.o(.rodata); - sound/songs/midi/mus_encounter_male.o(.rodata); - sound/songs/midi/mus_abandoned_ship.o(.rodata); - sound/songs/midi/mus_fortree.o(.rodata); - sound/songs/midi/mus_birch_lab.o(.rodata); - sound/songs/midi/mus_b_tower_rs.o(.rodata); - sound/songs/midi/mus_encounter_swimmer.o(.rodata); - sound/songs/midi/mus_cave_of_origin.o(.rodata); - sound/songs/midi/mus_obtain_berry.o(.rodata); - sound/songs/midi/mus_awaken_legend.o(.rodata); - sound/songs/midi/mus_slots_jackpot.o(.rodata); - sound/songs/midi/mus_slots_win.o(.rodata); - sound/songs/midi/mus_too_bad.o(.rodata); - sound/songs/midi/mus_roulette.o(.rodata); - sound/songs/midi/mus_link_contest_p1.o(.rodata); - sound/songs/midi/mus_link_contest_p2.o(.rodata); - sound/songs/midi/mus_link_contest_p3.o(.rodata); - sound/songs/midi/mus_link_contest_p4.o(.rodata); - sound/songs/midi/mus_encounter_rich.o(.rodata); - sound/songs/midi/mus_verdanturf.o(.rodata); - sound/songs/midi/mus_rustboro.o(.rodata); - sound/songs/midi/mus_poke_center.o(.rodata); - sound/songs/midi/mus_route104.o(.rodata); - sound/songs/midi/mus_route119.o(.rodata); - sound/songs/midi/mus_cycling.o(.rodata); - sound/songs/midi/mus_poke_mart.o(.rodata); - sound/songs/midi/mus_littleroot.o(.rodata); - sound/songs/midi/mus_mt_chimney.o(.rodata); - sound/songs/midi/mus_encounter_female.o(.rodata); - sound/songs/midi/mus_lilycove.o(.rodata); - sound/songs/midi/mus_route111.o(.rodata); - sound/songs/midi/mus_help.o(.rodata); - sound/songs/midi/mus_underwater.o(.rodata); - sound/songs/midi/mus_victory_trainer.o(.rodata); - sound/songs/midi/mus_title.o(.rodata); - sound/songs/midi/mus_intro.o(.rodata); - sound/songs/midi/mus_encounter_may.o(.rodata); - sound/songs/midi/mus_encounter_intense.o(.rodata); - sound/songs/midi/mus_encounter_cool.o(.rodata); - sound/songs/midi/mus_route113.o(.rodata); - sound/songs/midi/mus_encounter_aqua.o(.rodata); - sound/songs/midi/mus_follow_me.o(.rodata); - sound/songs/midi/mus_encounter_brendan.o(.rodata); - sound/songs/midi/mus_ever_grande.o(.rodata); - sound/songs/midi/mus_encounter_suspicious.o(.rodata); - sound/songs/midi/mus_victory_aqua_magma.o(.rodata); - sound/songs/midi/mus_cable_car.o(.rodata); - sound/songs/midi/mus_game_corner.o(.rodata); - sound/songs/midi/mus_dewford.o(.rodata); - sound/songs/midi/mus_safari_zone.o(.rodata); - sound/songs/midi/mus_victory_road.o(.rodata); - sound/songs/midi/mus_aqua_magma_hideout.o(.rodata); - sound/songs/midi/mus_sailing.o(.rodata); - sound/songs/midi/mus_mt_pyre.o(.rodata); - sound/songs/midi/mus_slateport.o(.rodata); - sound/songs/midi/mus_mt_pyre_exterior.o(.rodata); - sound/songs/midi/mus_school.o(.rodata); - sound/songs/midi/mus_hall_of_fame.o(.rodata); - sound/songs/midi/mus_fallarbor.o(.rodata); - sound/songs/midi/mus_sealed_chamber.o(.rodata); - sound/songs/midi/mus_contest_winner.o(.rodata); - sound/songs/midi/mus_contest.o(.rodata); - sound/songs/midi/mus_encounter_magma.o(.rodata); - sound/songs/midi/mus_intro_battle.o(.rodata); - sound/songs/midi/mus_abnormal_weather.o(.rodata); - sound/songs/midi/mus_weather_groudon.o(.rodata); - sound/songs/midi/mus_sootopolis.o(.rodata); - sound/songs/midi/mus_contest_results.o(.rodata); - sound/songs/midi/mus_hall_of_fame_room.o(.rodata); - sound/songs/midi/mus_trick_house.o(.rodata); - sound/songs/midi/mus_encounter_twins.o(.rodata); - sound/songs/midi/mus_encounter_elite_four.o(.rodata); - sound/songs/midi/mus_encounter_hiker.o(.rodata); - sound/songs/midi/mus_contest_lobby.o(.rodata); - sound/songs/midi/mus_encounter_interviewer.o(.rodata); - sound/songs/midi/mus_encounter_champion.o(.rodata); - sound/songs/midi/mus_credits.o(.rodata); - sound/songs/midi/mus_end.o(.rodata); - sound/songs/midi/mus_b_frontier.o(.rodata); - sound/songs/midi/mus_b_arena.o(.rodata); - sound/songs/midi/mus_obtain_b_points.o(.rodata); - sound/songs/midi/mus_register_match_call.o(.rodata); - sound/songs/midi/mus_b_pyramid.o(.rodata); - sound/songs/midi/mus_b_pyramid_top.o(.rodata); - sound/songs/midi/mus_b_palace.o(.rodata); - sound/songs/midi/mus_rayquaza_appears.o(.rodata); - sound/songs/midi/mus_b_tower.o(.rodata); - sound/songs/midi/mus_obtain_symbol.o(.rodata); - sound/songs/midi/mus_b_dome.o(.rodata); - sound/songs/midi/mus_b_pike.o(.rodata); - sound/songs/midi/mus_b_factory.o(.rodata); - sound/songs/midi/mus_vs_rayquaza.o(.rodata); - sound/songs/midi/mus_vs_frontier_brain.o(.rodata); - sound/songs/midi/mus_vs_mew.o(.rodata); - sound/songs/midi/mus_b_dome_lobby.o(.rodata); - sound/songs/midi/mus_vs_wild.o(.rodata); - sound/songs/midi/mus_vs_aqua_magma.o(.rodata); - sound/songs/midi/mus_vs_trainer.o(.rodata); - sound/songs/midi/mus_vs_gym_leader.o(.rodata); - sound/songs/midi/mus_vs_champion.o(.rodata); - sound/songs/midi/mus_vs_regi.o(.rodata); - sound/songs/midi/mus_vs_kyogre_groudon.o(.rodata); - sound/songs/midi/mus_vs_rival.o(.rodata); - sound/songs/midi/mus_vs_elite_four.o(.rodata); - sound/songs/midi/mus_vs_aqua_magma_leader.o(.rodata); - sound/songs/midi/mus_rg_follow_me.o(.rodata); - sound/songs/midi/mus_rg_game_corner.o(.rodata); - sound/songs/midi/mus_rg_rocket_hideout.o(.rodata); - sound/songs/midi/mus_rg_gym.o(.rodata); - sound/songs/midi/mus_rg_jigglypuff.o(.rodata); - sound/songs/midi/mus_rg_intro_fight.o(.rodata); - sound/songs/midi/mus_rg_title.o(.rodata); - sound/songs/midi/mus_rg_cinnabar.o(.rodata); - sound/songs/midi/mus_rg_lavender.o(.rodata); - sound/songs/midi/mus_rg_heal.o(.rodata); - sound/songs/midi/mus_rg_cycling.o(.rodata); - sound/songs/midi/mus_rg_encounter_rocket.o(.rodata); - sound/songs/midi/mus_rg_encounter_girl.o(.rodata); - sound/songs/midi/mus_rg_encounter_boy.o(.rodata); - sound/songs/midi/mus_rg_hall_of_fame.o(.rodata); - sound/songs/midi/mus_rg_viridian_forest.o(.rodata); - sound/songs/midi/mus_rg_mt_moon.o(.rodata); - sound/songs/midi/mus_rg_poke_mansion.o(.rodata); - sound/songs/midi/mus_rg_credits.o(.rodata); - sound/songs/midi/mus_rg_route1.o(.rodata); - sound/songs/midi/mus_rg_route24.o(.rodata); - sound/songs/midi/mus_rg_route3.o(.rodata); - sound/songs/midi/mus_rg_route11.o(.rodata); - sound/songs/midi/mus_rg_victory_road.o(.rodata); - sound/songs/midi/mus_rg_vs_gym_leader.o(.rodata); - sound/songs/midi/mus_rg_vs_trainer.o(.rodata); - sound/songs/midi/mus_rg_vs_wild.o(.rodata); - sound/songs/midi/mus_rg_vs_champion.o(.rodata); - sound/songs/midi/mus_rg_pallet.o(.rodata); - sound/songs/midi/mus_rg_oak_lab.o(.rodata); - sound/songs/midi/mus_rg_oak.o(.rodata); - sound/songs/midi/mus_rg_poke_center.o(.rodata); - sound/songs/midi/mus_rg_ss_anne.o(.rodata); - sound/songs/midi/mus_rg_surf.o(.rodata); - sound/songs/midi/mus_rg_poke_tower.o(.rodata); - sound/songs/midi/mus_rg_silph.o(.rodata); - sound/songs/midi/mus_rg_fuchsia.o(.rodata); - sound/songs/midi/mus_rg_celadon.o(.rodata); - sound/songs/midi/mus_rg_victory_trainer.o(.rodata); - sound/songs/midi/mus_rg_victory_wild.o(.rodata); - sound/songs/midi/mus_rg_victory_gym_leader.o(.rodata); - sound/songs/midi/mus_rg_vermillion.o(.rodata); - sound/songs/midi/mus_rg_pewter.o(.rodata); - sound/songs/midi/mus_rg_encounter_rival.o(.rodata); - sound/songs/midi/mus_rg_rival_exit.o(.rodata); - sound/songs/midi/mus_rg_dex_rating.o(.rodata); - sound/songs/midi/mus_rg_obtain_key_item.o(.rodata); - sound/songs/midi/mus_rg_caught_intro.o(.rodata); - sound/songs/midi/mus_rg_photo.o(.rodata); - sound/songs/midi/mus_rg_game_freak.o(.rodata); - sound/songs/midi/mus_rg_caught.o(.rodata); - sound/songs/midi/mus_rg_new_game_instruct.o(.rodata); - sound/songs/midi/mus_rg_new_game_intro.o(.rodata); - sound/songs/midi/mus_rg_new_game_exit.o(.rodata); - sound/songs/midi/mus_rg_poke_jump.o(.rodata); - sound/songs/midi/mus_rg_union_room.o(.rodata); - sound/songs/midi/mus_rg_net_center.o(.rodata); - sound/songs/midi/mus_rg_mystery_gift.o(.rodata); - sound/songs/midi/mus_rg_berry_pick.o(.rodata); - sound/songs/midi/mus_rg_sevii_cave.o(.rodata); - sound/songs/midi/mus_rg_teachy_tv_show.o(.rodata); - sound/songs/midi/mus_rg_sevii_route.o(.rodata); - sound/songs/midi/mus_rg_sevii_dungeon.o(.rodata); - sound/songs/midi/mus_rg_sevii_123.o(.rodata); - sound/songs/midi/mus_rg_sevii_45.o(.rodata); - sound/songs/midi/mus_rg_sevii_67.o(.rodata); - sound/songs/midi/mus_rg_poke_flute.o(.rodata); - sound/songs/midi/mus_rg_vs_deoxys.o(.rodata); - sound/songs/midi/mus_rg_vs_mewtwo.o(.rodata); - sound/songs/midi/mus_rg_vs_legend.o(.rodata); - sound/songs/midi/mus_rg_encounter_gym_leader.o(.rodata); - sound/songs/midi/mus_rg_encounter_deoxys.o(.rodata); - sound/songs/midi/mus_rg_trainer_tower.o(.rodata); - sound/songs/midi/mus_rg_slow_pallet.o(.rodata); - sound/songs/midi/mus_rg_teachy_tv_menu.o(.rodata); - sound/songs/midi/ph_trap_blend.o(.rodata); - sound/songs/midi/ph_trap_held.o(.rodata); - sound/songs/midi/ph_trap_solo.o(.rodata); - sound/songs/midi/ph_face_blend.o(.rodata); - sound/songs/midi/ph_face_held.o(.rodata); - sound/songs/midi/ph_face_solo.o(.rodata); - sound/songs/midi/ph_cloth_blend.o(.rodata); - sound/songs/midi/ph_cloth_held.o(.rodata); - sound/songs/midi/ph_cloth_solo.o(.rodata); - sound/songs/midi/ph_dress_blend.o(.rodata); - sound/songs/midi/ph_dress_held.o(.rodata); - sound/songs/midi/ph_dress_solo.o(.rodata); - sound/songs/midi/ph_fleece_blend.o(.rodata); - sound/songs/midi/ph_fleece_held.o(.rodata); - sound/songs/midi/ph_fleece_solo.o(.rodata); - sound/songs/midi/ph_kit_blend.o(.rodata); - sound/songs/midi/ph_kit_held.o(.rodata); - sound/songs/midi/ph_kit_solo.o(.rodata); - sound/songs/midi/ph_price_blend.o(.rodata); - sound/songs/midi/ph_price_held.o(.rodata); - sound/songs/midi/ph_price_solo.o(.rodata); - sound/songs/midi/ph_lot_blend.o(.rodata); - sound/songs/midi/ph_lot_held.o(.rodata); - sound/songs/midi/ph_lot_solo.o(.rodata); - sound/songs/midi/ph_goat_blend.o(.rodata); - sound/songs/midi/ph_goat_held.o(.rodata); - sound/songs/midi/ph_goat_solo.o(.rodata); - sound/songs/midi/ph_thought_blend.o(.rodata); - sound/songs/midi/ph_thought_held.o(.rodata); - sound/songs/midi/ph_thought_solo.o(.rodata); - sound/songs/midi/ph_choice_blend.o(.rodata); - sound/songs/midi/ph_choice_held.o(.rodata); - sound/songs/midi/ph_choice_solo.o(.rodata); - sound/songs/midi/ph_mouth_blend.o(.rodata); - sound/songs/midi/ph_mouth_held.o(.rodata); - sound/songs/midi/ph_mouth_solo.o(.rodata); - sound/songs/midi/ph_foot_blend.o(.rodata); - sound/songs/midi/ph_foot_held.o(.rodata); - sound/songs/midi/ph_foot_solo.o(.rodata); - sound/songs/midi/ph_goose_blend.o(.rodata); - sound/songs/midi/ph_goose_held.o(.rodata); - sound/songs/midi/ph_goose_solo.o(.rodata); - sound/songs/midi/ph_strut_blend.o(.rodata); - sound/songs/midi/ph_strut_held.o(.rodata); - sound/songs/midi/ph_strut_solo.o(.rodata); - sound/songs/midi/ph_cure_blend.o(.rodata); - sound/songs/midi/ph_cure_held.o(.rodata); - sound/songs/midi/ph_cure_solo.o(.rodata); - sound/songs/midi/ph_nurse_blend.o(.rodata); - sound/songs/midi/ph_nurse_held.o(.rodata); - sound/songs/midi/ph_nurse_solo.o(.rodata); - } > ROM =0 - - lib_rodata : - SUBALIGN(4) - { - src/m4a.o(.rodata); - src/agb_flash.o(.rodata); - src/agb_flash_1m.o(.rodata); - src/agb_flash_mx.o(.rodata); - src/agb_flash_le.o(.rodata); - src/siirtc.o(.rodata); - src/librfu_rfu.o(.rodata); - src/librfu_sio32id.o(.rodata); - *libgcc.a:_divdi3.o(.rodata); - *libgcc.a:_udivdi3.o(.rodata); - *libc.a:memcpy.o(.rodata); - *libc.a:memset.o(.rodata); - *libc.a:strcmp.o(.rodata); - *libc.a:strcpy.o(.rodata); - *libc.a:impure.o(.rodata); - *libc.a:vsprintf.o(.rodata); - *libc.a:vfprintf.o(.rodata); - *libc.a:wsetup.o(.rodata); - *libc.a:dtoa.o(.rodata); - *libc.a:fflush.o(.rodata); - *libc.a:findfp.o(.rodata); - *libc.a:freer.o(.rodata); - *libc.a:mtrim.o(.rodata); - *libc.a:fvwrite.o(.rodata); - *libc.a:fwalk.o(.rodata); - *libc.a:locale.o(.rodata); - *libc.a:makebuf.o(.rodata); - *libc.a:mallocr.o(.rodata); - *libc.a:mbtowc_r.o(.rodata); - *libc.a:memchr.o(.rodata); - *libc.a:memmove.o(.rodata); - *libc.a:mlock.o(.rodata); - *libc.a:mprec.o(.rodata); - *libc.a:s_isinf.o(.rodata); - *libc.a:s_isnan.o(.rodata); - *libc.a:sbrkr.o(.rodata); - *libc.a:stdio.o(.rodata); - *libc.a:strlen.o(.rodata); - *libc.a:syscalls.o(.rodata); - *libc.a:writer.o(.rodata); - *libc.a:callocr.o(.rodata); - *libc.a:closer.o(.rodata); - *libc.a:errno.o(.rodata); - *libc.a:fstatr.o(.rodata); - *libc.a:libcfunc.o(.rodata); - *libc.a:lseekr.o(.rodata); - *libc.a:readr.o(.rodata); - src/libisagbprn.o(.rodata); - } > ROM =0 - - multiboot_data : - ALIGN(4) - { - data/multiboot_ereader.o(.rodata); - data/multiboot_berry_glitch_fix.o(.rodata); - data/multiboot_pokemon_colosseum.o(.rodata); - } > ROM =0 - - gfx_data : - ALIGN(4) - { - src/graphics.o(.rodata); - } > ROM =0 - - extra : - ALIGN(4) - { - src/*.o(.text); - gflib/*.o(.text); - src/*.o(.rodata); - gflib/*.o(.rodata); - data/*.o(.rodata); - } > ROM = 0 - - .data.iwram : - ALIGN(4) - { - __iwram_lma = .; - . = . + (__iwram_end - __iwram_start); - } > ROM = 0 - - .data.ewram : - ALIGN(4) - { - __ewram_lma = .; - . = . + (__ewram_end - __ewram_start); - } > ROM = 0 - - __rom_end = .; - - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - - /* Discard everything not specifically mentioned above. */ - /DISCARD/ : - { - *(*); - } -} diff --git a/sym_bss.txt b/sym_bss.txt deleted file mode 100644 index 3a23e74789..0000000000 --- a/sym_bss.txt +++ /dev/null @@ -1,63 +0,0 @@ - .include "src/main.o" - .include "gflib/malloc.o" - .include "gflib/dma3_manager.o" - .include "gflib/gpu_regs.o" - .include "gflib/bg.o" - .include "gflib/text.o" - .include "gflib/sprite.o" - .include "src/link.o" - .include "src/AgbRfu_LinkManager.o" - .include "src/link_rfu_3.o" - .include "src/link_rfu_2.o" - .include "src/union_room.o" - .include "src/wireless_communication_status_screen.o" - .include "src/union_room_battle.o" - .include "src/dodrio_berry_picking.o" - .include "src/rtc.o" - .include "src/main_menu.o" - .include "src/digit_obj_util.o" - .include "src/egg_hatch.o" - .include "src/berry_blender.o" - .include "src/play_time.o" - .include "src/overworld.o" - .include "src/field_camera.o" - .include "src/script.o" - .include "src/scrcmd.o" - .include "src/tileset_anims.o" - .include "src/palette.o" - .include "src/sound.o" - .include "src/field_weather.o" - .include "src/field_effect.o" - .include "src/pokemon_storage_system.o" - .include "src/fldeff_cut.o" - .include "src/script_menu.o" - .include "src/record_mixing.o" - .include "src/tv.o" - .include "src/mauville_old_man.o" - .include "src/menu_helpers.o" - .include "src/region_map.o" - .include "src/slot_machine.o" - .include "src/contest_painting.o" - .include "src/starter_choose.o" - .include "src/pokedex_area_screen.o" - .include "src/battle_transition.o" - .include "src/pokemon_animation.o" - .include "src/recorded_battle.o" - .include "src/battle_factory_screen.o" - .include "src/battle_factory.o" - .include "src/battle_pike.o" - .include "src/battle_tent.o" - .include "src/multiboot.o" - .include "src/mirage_tower.o" - .include "src/berry_fix_program.o" - .include "src/pokenav_conditions_gfx.o" - .include "src/pokenav_ribbons_summary.o" - .include "src/ereader_helpers.o" - .include "src/faraway_island.o" - .include "src/m4a_1.o" - .include "data/sound_data.o" - .include "src/agb_flash.o" - .include "src/siirtc.o" - .include "*libgcc.a:dp-bit.o" - .include "*libgcc.a:fp-bit.o" - .include "*libc.a:syscalls.o" diff --git a/sym_common.txt b/sym_common.txt deleted file mode 100644 index 170aee2f42..0000000000 --- a/sym_common.txt +++ /dev/null @@ -1,83 +0,0 @@ - .space 0x8 - .include "main.o" - @ ../gflib/bg.o - .align 2 -gWindowTileAutoAllocEnabled: - .space 4 - @ ../gflib/window.o - .align 4 -gTransparentTileNumber: - .space 1 - .align 4 -gWindowBgTilemapBuffers: - .space 16 - @ ../gflib/text.o - .align 4 -gFonts: - .space 4 - .align 2 -gDisableTextPrinters: - .space 1 - .align 4 -gCurGlyph: - .space 132 - .align 2 -gTextFlags: - .space 4 - @ ../gflib/sprite.o - .align 2 -gOamMatrixAllocBitmap: - .space 4 - .align 2 -gReservedSpritePaletteCount: - .space 1 - .align 4 - .include "link.o" - .include "AgbRfu_LinkManager.o" - .include "link_rfu_2.o" - .include "rtc.o" - .include "battle_main.o" - .include "battle_controllers.o" - .include "random.o" - .include "load_save.o" - .include "berry_blender.o" - .include "overworld.o" - .include "fieldmap.o" - .include "field_camera.o" - .include "field_control_avatar.o" - .include "start_menu.o" - .include "sound.o" - .include "task.o" - .include "trainer_see.o" - .include "pokedex.o" - .include "contest.o" - .include "tv.o" - .include "mauville_old_man.o" - .include "image_processing_effects.o" - - .space 0x4 - - .include "contest_painting.o" - .include "field_specials.o" - .include "evolution_scene.o" - .include "pokedex_cry_screen.o" - .include "save.o" - .include "battle_tower.o" - .include "intro.o" - .include "battle_anim_throw.o" - .include "battle_factory_screen.o" - .include "apprentice.o" - - .space 0x8 - - .include "list_menu.o" - .include "party_menu.o" - - .space 0x44 - - .include "ereader_screen.o" - .include "m4a.o" - .include "agb_flash.o" - .include "librfu_stwi.o" - .include "librfu_rfu.o" - .include "librfu_sio32id.o" diff --git a/sym_ewram.txt b/sym_ewram.txt deleted file mode 100644 index 3123b3388a..0000000000 --- a/sym_ewram.txt +++ /dev/null @@ -1,154 +0,0 @@ - .include "gflib/malloc.o" - .include "src/decompress.o" - .include "src/main.o" - .include "gflib/window.o" - .include "gflib/text.o" - .include "gflib/sprite.o" - .include "gflib/string_util.o" - .include "src/link.o" - .include "src/AgbRfu_LinkManager.o" - .include "src/link_rfu_3.o" - .include "src/link_rfu_2.o" - .include "src/union_room.o" - .include "src/mystery_gift_menu.o" - .include "src/union_room_player_avatar.o" - .include "src/wireless_communication_status_screen.o" - .include "src/union_room_battle.o" - .include "src/mystery_gift.o" - .include "src/mystery_gift_view.o" - .include "src/mystery_gift_server.o" - .include "src/mystery_gift_client.o" - .include "src/union_room_chat.o" - .include "src/berry_crush.o" - .include "src/berry_powder.o" - .include "src/dodrio_berry_picking.o" - .include "src/pokemon_jump.o" - .include "src/main_menu.o" - .include "src/battle_controllers.o" - .include "src/digit_obj_util.o" - .include "src/battle_main.o" - .include "src/pokemon.o" - .include "src/random.o" - .include "src/daycare.o" - .include "src/load_save.o" - .include "src/trade.o" - .include "src/berry_blender.o" - .include "src/new_game.o" - .include "src/overworld.o" - .include "src/fieldmap.o" - .include "src/field_camera.o" - .include "src/field_player_avatar.o" - .include "src/event_object_movement.o" - .include "src/field_message_box.o" - .include "src/scrcmd.o" - .include "src/field_control_avatar.o" - .include "src/event_data.o" - .include "src/start_menu.o" - .include "src/tileset_anims.o" - .include "src/palette.o" - .include "src/sound.o" - .include "src/battle_anim.o" - .include "src/battle_anim_mons.o" - - .space 0xC - .include "src/field_weather.o" - .include "src/field_weather_effect.o" - .include "src/battle_setup.o" - .include "src/trainer_see.o" - .include "src/wild_encounter.o" - .include "src/field_effect.o" - .include "src/scanline_effect.o" - .include "src/option_menu.o" - .include "src/pokedex.o" - .include "src/trainer_card.o" - .include "src/frontier_pass.o" - .include "src/pokemon_storage_system.o" - .include "src/script_movement.o" - .include "src/fldeff_cut.o" - .include "src/map_name_popup.o" - .include "src/item.o" - .include "src/contest.o" - .include "src/shop.o" - .include "src/fldeff_escalator.o" - .include "src/script_menu.o" - .include "src/naming_screen.o" - .include "src/money.o" - .include "src/record_mixing.o" - .include "src/secret_base.o" - .include "src/tv.o" - .include "src/contest_util.o" - .include "src/rotating_gate.o" - .include "src/safari_zone.o" - .include "src/item_use.o" - .include "src/battle_anim_effects_1.o" - .include "src/battle_anim_dragon.o" - .include "src/battle_anim_utility_funcs.o" - .include "src/battle_intro.o" - .include "src/easy_chat.o" - .include "src/mon_markings.o" - .include "src/mauville_old_man.o" - .include "src/mail.o" - .include "src/menu_helpers.o" - .include "src/region_map.o" - .include "src/decoration.o" - .include "src/slot_machine.o" - .include "src/battle_ai_main.o" - .include "src/fldeff_misc.o" - .include "src/pokeblock.o" - .include "src/field_specials.o" - .include "src/battle_records.o" - .include "src/pokedex_area_screen.o" - .include "src/evolution_scene.o" - .include "src/roulette.o" - .include "src/pokedex_cry_screen.o" - .include "src/coins.o" - .include "src/battle_transition.o" - .include "src/battle_message.o" - .include "src/cable_car.o" - .include "src/confetti_util.o" - .include "src/save.o" - .include "src/mystery_event_script.o" - .include "src/move_relearner.o" - .include "src/decoration_inventory.o" - .include "src/roamer.o" - .include "src/battle_tower.o" - .include "src/use_pokeblock.o" - .include "src/player_pc.o" - .include "src/intro.o" - .include "src/field_region_map.o" - .include "src/hall_of_fame.o" - .include "src/credits.o" - .include "src/lottery_corner.o" - .include "src/diploma.o" - .include "src/berry_tag_screen.o" - .include "src/mystery_event_menu.o" - .include "src/save_failed_screen.o" - .include "src/braille_puzzles.o" - .include "src/pokeblock_feed.o" - .include "src/intro_credits_graphics.o" - .include "src/recorded_battle.o" - .include "src/trainer_pokemon_sprites.o" - .include "src/lilycove_lady.o" - .include "src/battle_dome.o" - .include "src/match_call.o" - .include "src/menu.o" - .include "src/battle_factory_screen.o" - .include "src/rotating_tile_puzzle.o" - .include "src/item_menu.o" - .include "src/list_menu.o" - .include "src/dynamic_placeholder_text_util.o" - .include "src/item_icon.o" - .include "src/party_menu.o" - .include "src/mirage_tower.o" - .include "src/pokemon_summary_screen.o" - .include "src/pokedex_area_region_map.o" - .include "src/battle_pyramid_bag.o" - .include "src/pokenav.o" - .include "src/pokenav_list.o" - .include "src/menu_specialized.o" - .include "src/faraway_island.o" - .include "src/trainer_hill.o" - .include "src/rayquaza_scene.o" - .include "src/debug.o" - .include "src/battle_controller_player.o" - .include "src/pokedex_plus_hgss.o" From 863b96f75964ccc35ee6545e48652ecd9872cec7 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Mon, 12 Aug 2024 01:05:38 +0200 Subject: [PATCH 12/64] Fixes Stomping Tantrum effect not doubling power in certain situations (#5140) * Fixes Stomping Tantrum effect not doubling power in certain situations * fix dancer test --- src/battle_script_commands.c | 14 +-- test/battle/move_effect/stomping_tantrum.c | 134 +++++++++++++++++++++ 2 files changed, 141 insertions(+), 7 deletions(-) create mode 100644 test/battle/move_effect/stomping_tantrum.c diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 317613c479..8056b3ddf2 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1364,9 +1364,8 @@ static void Cmd_attackcanceler(void) } // Z-moves and Max Moves bypass protection, but deal reduced damage (factored in AccumulateOtherModifiers) - if ((IsZMove(gCurrentMove) - || IsMaxMove(gCurrentMove)) - && IS_BATTLER_PROTECTED(gBattlerTarget)) + if ((IsZMove(gCurrentMove) || IsMaxMove(gCurrentMove)) + && IS_BATTLER_PROTECTED(gBattlerTarget)) { BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_CouldntFullyProtect; @@ -5825,7 +5824,9 @@ static void Cmd_moveend(void) gBattleScripting.moveendState++; break; case MOVEEND_UPDATE_LAST_MOVES: - if (gMoveResultFlags & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE)) + if ((gMoveResultFlags & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE)) + || (gBattleMons[gBattlerAttacker].status2 & (STATUS2_FLINCHED)) + || gProtectStructs[gBattlerAttacker].prlzImmobility) gBattleStruct->lastMoveFailed |= gBitTable[gBattlerAttacker]; else gBattleStruct->lastMoveFailed &= ~(gBitTable[gBattlerAttacker]); @@ -6267,9 +6268,8 @@ static void Cmd_moveend(void) } } - if (!(gBattleStruct->lastMoveFailed & gBitTable[gBattlerAttacker] - || (!gSpecialStatuses[gBattlerAttacker].dancerUsedMove - && gBattleStruct->bouncedMoveIsUsed))) + if (!(gMoveResultFlags & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE) + || (!gSpecialStatuses[gBattlerAttacker].dancerUsedMove && gBattleStruct->bouncedMoveIsUsed))) { // Dance move succeeds // Set target for other Dancer mons; set bit so that mon cannot activate Dancer off of its own move if (!gSpecialStatuses[gBattlerAttacker].dancerUsedMove) diff --git a/test/battle/move_effect/stomping_tantrum.c b/test/battle/move_effect/stomping_tantrum.c new file mode 100644 index 0000000000..1a5870fdd0 --- /dev/null +++ b/test/battle/move_effect/stomping_tantrum.c @@ -0,0 +1,134 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_STOMPING_TANTRUM].effect == EFFECT_STOMPING_TANTRUM); +} + +SINGLE_BATTLE_TEST("Stomping Tatrum will deal double damage if user flinched on the previous turn") +{ + s16 damage[3]; + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); SWITCH(opponent, 1); } + TURN { MOVE(opponent, MOVE_FAKE_OUT); MOVE(player, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); } + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[0]); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_FAKE_OUT, opponent); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[1]); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[2]); + } THEN { + EXPECT_MUL_EQ(damage[0], Q_4_12(2.0), damage[1]); + EXPECT_EQ(damage[0], damage[2]); + } +} + +SINGLE_BATTLE_TEST("Stomping Tatrum will deal double damage if user failed to attack due to paralysis") +{ + s16 damage[3]; + PASSES_RANDOMLY(25, 100, RNG_PARALYSIS); + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Speed(100); Item(ITEM_POTION); }; + OPPONENT(SPECIES_WOBBUFFET) { Speed(10); Item(ITEM_LUM_BERRY); }; + } WHEN { + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); MOVE(opponent, MOVE_THUNDER_WAVE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_TRICK); } + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); } + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[0]); + ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDER_WAVE, opponent); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_TRICK, opponent); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[1]); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[2]); + } THEN { + EXPECT_MUL_EQ(damage[0], Q_4_12(2.0), damage[1]); + EXPECT_EQ(damage[0], damage[2]); + } +} + +SINGLE_BATTLE_TEST("Stomping Tatrum will not deal double damage if target protects") +{ + s16 damage[2]; + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); } + TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_STOMPING_TANTRUM); } + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[0]); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponent); + MESSAGE("Foe Wobbuffet protected itself!"); + + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[1]); + } THEN { + EXPECT_EQ(damage[0], damage[1]); + } +} + +SINGLE_BATTLE_TEST("Stomping Tatrum will not deal double damage if it failed on the previous turn cause of Protect") +{ + s16 damage[2]; + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_BRIGHTPOWDER); }; + } WHEN { + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); } + TURN { MOVE(player, MOVE_STOMPING_TANTRUM, hit: FALSE); } + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[0]); + MESSAGE("Wobbuffet's attack missed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[1]); + } THEN { + EXPECT_EQ(damage[0], damage[1]); + } +} + +SINGLE_BATTLE_TEST("Stomping Tatrum will deal double damage if user was immune to previous move") +{ + s16 damage[2]; + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_PIDGEY); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); SWITCH(opponent, 1); } + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); SWITCH(opponent, 0); } + TURN { MOVE(player, MOVE_STOMPING_TANTRUM); SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[0]); + MESSAGE("It doesn't affect Foe Pidgey…"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_STOMPING_TANTRUM, player); + HP_BAR(opponent, captureDamage: &damage[1]); + } THEN { + EXPECT_MUL_EQ(damage[0], Q_4_12(2.0), damage[1]); + } +} From 5df53a5c1c1e67b8c333e15bfe5411f6fb722d36 Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Mon, 12 Aug 2024 21:39:11 +0200 Subject: [PATCH 13/64] Added fixed Unown follower sprites by Sarn (#5146) Co-authored-by: Hedara --- graphics/pokemon/unown/b/overworld.png | Bin 299 -> 419 bytes graphics/pokemon/unown/c/overworld.png | Bin 348 -> 462 bytes graphics/pokemon/unown/d/overworld.png | Bin 330 -> 443 bytes graphics/pokemon/unown/e/overworld.png | Bin 305 -> 422 bytes .../unown/exclamation_mark/overworld.png | Bin 2556 -> 360 bytes graphics/pokemon/unown/f/overworld.png | Bin 301 -> 419 bytes graphics/pokemon/unown/g/overworld.png | Bin 316 -> 426 bytes graphics/pokemon/unown/h/overworld.png | Bin 321 -> 433 bytes graphics/pokemon/unown/i/overworld.png | Bin 263 -> 377 bytes graphics/pokemon/unown/j/overworld.png | Bin 286 -> 399 bytes graphics/pokemon/unown/k/overworld.png | Bin 289 -> 402 bytes graphics/pokemon/unown/l/overworld.png | Bin 294 -> 404 bytes graphics/pokemon/unown/m/overworld.png | Bin 319 -> 428 bytes graphics/pokemon/unown/n/overworld.png | Bin 323 -> 438 bytes graphics/pokemon/unown/o/overworld.png | Bin 317 -> 428 bytes graphics/pokemon/unown/p/overworld.png | Bin 278 -> 392 bytes graphics/pokemon/unown/q/overworld.png | Bin 313 -> 430 bytes .../pokemon/unown/question_mark/overworld.png | Bin 2741 -> 405 bytes graphics/pokemon/unown/r/overworld.png | Bin 276 -> 391 bytes graphics/pokemon/unown/s/overworld.png | Bin 322 -> 436 bytes graphics/pokemon/unown/t/overworld.png | Bin 260 -> 369 bytes graphics/pokemon/unown/u/overworld.png | Bin 299 -> 409 bytes graphics/pokemon/unown/v/overworld.png | Bin 272 -> 387 bytes graphics/pokemon/unown/w/overworld.png | Bin 271 -> 385 bytes graphics/pokemon/unown/x/overworld.png | Bin 281 -> 398 bytes graphics/pokemon/unown/y/overworld.png | Bin 287 -> 402 bytes graphics/pokemon/unown/z/overworld.png | Bin 313 -> 419 bytes 27 files changed, 0 insertions(+), 0 deletions(-) diff --git a/graphics/pokemon/unown/b/overworld.png b/graphics/pokemon/unown/b/overworld.png index b2500cca0cd4b49f896564dd672d1c9c03929b08..1e8ab69c117e625fc102b25ca591dbbf8f8ccd85 100644 GIT binary patch delta 393 zcmZ3@w3vB`sf3l26xHjcEt2NyChFo>79MwA5SrR}8R%`D`i2xK!RdAqwXbg;^L06E7!T^vIy=DfXf zkoS-Q59@`B=3Om}36m8zGb~~*NcbD~VS zt?ViO)1@2&zHDE{%f?VEFX6!BGJ$Ew(}&8^tZm0d9^^Y5tJrz*_E(Fqj0-<1)Z}Vg Rw}3qB>FVdQ&WS0Z2>|ZEiopN? delta 272 zcmZ3?yqal(O1(jVPl)T;vupk{{D+`>_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z4BI?i978JRyq)69)oQ@gvisD@Cl3u{rUZO{Bq%3$`&U?6lkA~rPRRnpxd!p|2ZDlD zhG>0Ndig0{k7t7uqu8cBjqVHT<>IXwTXo7Ao-e<-CL!^%*_oT2OWw_vWLyv@#VE_L zCuHq+HU=&xnF-8qI0ZOb`8*h1m!Gda8XNhZS(^0*6U#3d8|E*CyOlL2XvfbhW_wY7 zYd>Sa7xT|NJo64PZWL&IXwDHI`DbGDJf`sf3l26xc12r}j2;FC2JsTth?3y^w370~qErTVAC~|>cZIUl zA_ZeTlfu>|4}nTJN(%hkfilKGHiK7#raX{hNq6*hWMJ6X&;2Kn705RT@Ck7}dv*wfo#SkZ+91l4pvzYAm@{(i(^Q|oVQZ~ z`I-y_Ty~qk5U^>u#}cfc@PwhR;=lHeBQE9X6PIp0r z{4bAXPx~&#JaJc1+eyw9ue2LZ|23@PlHkx>dSgz5al<@D3m$`378XX19c&9)`5rX# z90+rGb$oVY;(~Yjs_z+IEIfG4uwa$Tw)R(z+6@2JrX_fNnaiS3D|&Ep>Vq?KOxGBi z49_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z49`7X978JRyqyxrcgTRp`S;Yxz8%S5k~dW`91#>au9hRDa_-u?TjGnR{U`|foy$7$ z(gh&+@6izaoB8iP$ELOKW;@l#*;lu&-RrmNZ&Udll@$RcGgIr=Yn?L;kbm*>guy*# z)z@;@gbkSXv`=|C>#1?FLXczQO<{wNzg-U0?4QZRmbA0@G3O4(4{?k$KF(!T;BYvg z%%EGsz@NfU#mIU2sE@>skY~aSe=pU@GKMppC};fB(3su8cr`w-=X!&5I>!wrD-NeQ zuMf}nw>=p5;@pomq3^~USUn!G3o(`0F<3JmWM_CT{jdEi)0Y?Z)~CMQUI6qogQu&X J%Q~loCIDTgnLq#l diff --git a/graphics/pokemon/unown/d/overworld.png b/graphics/pokemon/unown/d/overworld.png index 426e517d5df4b06d05a19b2288a0f406a055e7e9..d8796d020083830aa2f931832747b577d60fac67 100644 GIT binary patch delta 417 zcmX@bw3~T?N`sf3l26x4wX~S8qP279MwA5SrR}8R%`D`i2xK!RdAqwXbg;^L06F(PT^vIy=DfXf zkoS-Q4{Jbr^A0WM18S~`j4tdC4*b)eaPQB5aZdsDB|p-9KEG1ic(X^+IPJ`j#Rd7( zCO`l7c_qKa(;aqay|u!J@&niYPL!6t z5#@D9k+tHo>UwtTc}gs=mmNBoUcm66x_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z3|Bo}978JRyuD(`cUXakHNbz4PFEFA+ly}I5L>6K$>L`J--~%zyB?bD{Gpj8XIs+I zE>Ueg5r=XM#qZCT8#0{SxsRcqQD+jnz_DNn7e5oJ0}L7WPFBkK>I{3?d0uS{DPX(c{#EPY?TEc6mcKvP9`_{vqQ*4= qGXv%fzx<41?gq2%iRF9!_Ar))=4_9Zeb55*B7>)^pUXO@geCyKqKF~@ diff --git a/graphics/pokemon/unown/e/overworld.png b/graphics/pokemon/unown/e/overworld.png index 741a5ef42e1427da054fe295f6bf44ff6257375a..34fd50f0040e92fcedfb2417da1470b5c77d5949 100644 GIT binary patch delta 396 zcmdnUw2XOzN`sf3l26xPMP2TIfWS*7{p6lBT9nv(@M${i&7cfeOv11JIm^)LpEW)^Z$1hN^EyxmZR_X4 z;MmgpCoEXn!hc(tgWZD$7KI56*IqWUHGVOEB~;Jwq;9h;i`zbCiwFNqWZBOB%J?Pd zaP4~a%4mkJRZ;Q>7$&4neI3**d!U9PYyN?A<{uoSUo?C)*Z7_0c4(sL)n_M!)~{V% zxRLS8KGtIlW)e4E|7Y0J`0hBD`y+-3UZJ;(;ux+^k1jiVxo&6c?XNb!82VG>k~yuV Rn?U~cboFC(S?83{1OP$si!%TK delta 278 zcmZ3+ypd^wO1(jVPl)T;vupk{{D+`>_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z40}9X978JRyq)66b=ZK1rS{Wlr9EbK!w_Et-rf<q-V@91VEv?qfpx*HZT5FJGDrA3ycf3E+05~!k#WWUM&15>!hJmQ zHhY=b1SD$XSXepI)tK}cjyY6rG+|hL@QThX)`FVWMDrNg_StjReZMHbq9-YRI=}vH R1E5bBJYD@<);T3K0RWj8d`$oV diff --git a/graphics/pokemon/unown/exclamation_mark/overworld.png b/graphics/pokemon/unown/exclamation_mark/overworld.png index 4271c7ab99a223d67cfe3431f957ca0a2ffc1213..96073167d0ab7a66365f64460cfef042896a1ed8 100644 GIT binary patch delta 334 zcmew({DNtMay>K`y~{$!fU_3=HBWt`Q}{`DrEPiAAXl?mjL7e(nlo zsYMFLdM1UfOCAE1aFi7IxdUa4fouk^22FV&#ggvm>&U>cv7h@-A}f$@5a1KydiLxZ zATuFjf`dndhJnM27e99F*Z~xQf_fMOPBRO+C;~Z*N#5=*3>~bp9zafyr;B4q#hkZO z4ssqg;BkG*t70yzaPNrg-35{h+TZMVI#>9xzQ;pxL4EbKr|ie3d8kc3nUXi9s4#Zb zqqdA#xx;N68?Q?KmoYefdOxdjyuLxNp>RaB>7kH-X!qa~|C-LQES+6?x_f@;gh@RL~E3(Nt<=?9}dyGzp2>fGzT(J1^S366F9XF+9)mFd#26D2etDnm{ Hr-UW|@49qP delta 2547 zcmVaB^>EX>4U6ba`-PAZ2)IW&i+q+O3ysmLsVV zM*p)4FM$XM0+z$`oY{ew?@LNmUDe(8%-B{+$`nZg5#J+F*#G?Fgn#goR&&VawX{+q zuiSFe&P9!{S9`uC=I8r)&G#*Se`^o=aYJcJoYU*4_jmtJyMO(7;A0LM-`hid-_iOW zNInOCUg^$!uh-W_(yp&|$?t*MeqEGS{p(W4d!YI5_$=l9$)C%5o$l}Ot-;CCGA2r@ zJ4uSqcYduPy*`~!;agLtpCo%)THutDz6T>A-@^Mi$M`it-;(@s6@JdX_TML8`@2W_ zDVOD)BQAb>Lx1e2_VhWwew{ddu1LS%sQqK8Uz2>!s^{!ibUha`THcI$k}V&@&~cFR z^gLELoR4ws&(Sz)>~RA5f|-M3N)rW@6C}%$E=Trro-$ct)~(K2b!vLrYI1El)5R&@ zLymfCX{8E&Q+EKfob+=o^32dHSkp(c6qS0feC} z2b-2UV1MOo@W*q7L*0^PGb`p+gEi|Vm0YZp;^mrL_vG2li@R5E-fOD4S}oOUt*!Q^ zE#ZOIO7m7*YrSjeOw<{x)4$U)bfl4ojWT@H(MF%pXXa_MOrLeO*_W=gu!&Wcue#dm zTf)XEcHXwj_FZ?|{lK-8PCjy=V=g$otlhWE zwh`-)Y`k-1A?a9IrO%TMKWXL21m#gJNPnFk(}1j}PJ^`g^(0o@+9qYS7;tagt_hrKlo@hC{5FSp)3r3$ zIeEV6ZW_eqMt1~v(>zxhi^s}BZ%;rmT3&gdotB=w;OB1exud4GAz zUi-N+lvZ@s-7}-38SSg4HA_aOV6<7fl?X|PZMZK>yFH&3c3C{Lt>k_6CK+C@xnXp5 z#_G)h{Dvf(V!5PQ9dqKxPzABo+gqrFfi$=?0);lmK6XA%nN4Fo)a$PZ4Y}VNbVo6Tq|q1mC!7+ z&4wUzTbtyq+@C2MQ$7TVg3XK)Mk?Nwx;cjvtl643V~LD0m9v|k4bFRCcH*tKTx z{iJ+|jZKYX)}ir`7m6<{?q1sEOioR1@VSyyLfFsBP~g$tVeHB?(pNNkkDOA zKREo_jnNbAqE|^e2h+~e3xBtt2zItIx+8ep0ljXYGMpalt*ix7N?kZQagNGPZNhOU&Pk>tt2xp}T4<|vG+}+ONE8}_^B~y=u1PZ%Ceynh*53)img@{?p z7zh7~y`5I$^)NJB^?xO3>SIq-LwhCimZLezDjA=cLR>aaMS1Mz*x=RG$!AqFaDY{C z2Ed^tUY@Y`M%t*el2=GnXC&CB=eud$gOa_mTPpDlaAhg$F?dhcqZ^fggy|S#AI~>J zBj3G;y#V55sT6;B%kJSimBvpyLVMs!^t}POPy`m{!rs6OgMX4oHVv~bwtlgL<2ZOa zo3%xy&$k9@*M?-|6P6DPcQ$TfBO6q+zNoXOj=aM#HXII_WHgi`x1)-Azo z=dTMUdq-rC#lF7#P0YZF;)}C^y%UmTTkaz3+Xw`wkEqWu{qOT zX0oed;1xZHAVlk^%q(M0l9KQoU-$6w{Vv9{yzBlP{eNoCVt`L1o@ItvCEg&O-mDs& z_ld)-D67Qh#A7C1kob}7ipy`D3l0lBGi;_)^Tc6dvCzRv2eYE75l<0ERZXXSA>*>j zd5g1FuCdlV`3r+NePx;JG>4GDB9w#001yhOn+2G&CRU;0RR60|Nj90-rnB-|NjsW z5TvA}b8~Z2Qd0i_|Nj90{{a900RR60|Nj90lMVIt00009a7bBm000XU000XU0RWnu z7ytkO2XskIMF->t7!wI1K`x$P0001WNkl1+cp%wvN=*BwH-#@H-Lk|bG(GI(y)`GPvP)A>R)kNkI_*D*VQ=>hm)Z;vY;25M_g z9hG_%DEJUO4jeeZTo2qAn5zN9wmWrzdK?H2$N~ACm)_rX9bVFrRju6ZN@4&2002ov JPDHLkV1nyS@;3kg diff --git a/graphics/pokemon/unown/f/overworld.png b/graphics/pokemon/unown/f/overworld.png index ea3332e941fec718005c262d0c32954bf0900999..789e65cc1de3569feefe0d28839ad5b68b3f9dc3 100644 GIT binary patch delta 393 zcmZ3>w3vB`sf3l26xZk{W3)n6GH7{p6lBT9nv(@M${i&7cfeOv11JIm^)LpEW)^Z$1hN^EyxmT z=4<_(T=oo!tD4Sz332z+Sj^6Rt&AvVc=G4gzU~$4jp`S4T#1^lJi&|QgfFw0O9Fd| z!_AqDnGVg9Dnu4+s=Jk4?;xhRb(Jdf2KJ1*lkFtLa!mI+a(rWW7s2E)L1F`c0QVEe zV|DNBJBs*c$TWUdaIR;Y5Sw+p{LBeE%h|^n3Z+gyww2)Bb7#@*uTCGCS)VBczGdP0 Q4f3p~tDnm{C#HlZ0JtcK-v9sr delta 274 zcmZ3?yq0N#O1(jVPl)T;vupk{{D+`>_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z3_Cns978JRyq#jm$E?W168kfCxyJbg4r2TrpIS7|pL=goRY84itsu~L=wY}?-Q8Cz_Kl)h%oP`UPe`^?*-3~yHp8ocsY9m?;Z zz+A^*&G1t>z~%t++80_5IlF(Va@ah&%f;r$_>IB7?ZDn=j68D~OU_SfaC*jnU_8VQzITG%ZSOq!_fju}8MuMo N@O1TaS?83{1OP*`sf3l26x9>%AA6Z;t$7{p6lBT9nv(@M${i&7cfeOv11JIm^)LpEW)^Z$1hN^EyxmmdKI;Vst0H_&-v;Y7A delta 289 zcmZ3*yoYImO1(jVPl)T;vupk{{D+`>_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z497iP978JRyq)66b=ZK1rS#Kjr`V%C1XeKaYn#vEz#>qvg^6h%>kR$rf4R2y zygO>Zuw0EPQhu(|WPfMhugna09<1zh;B4qV&$h!+<^jWjV`e?uU!4B=`{${mH62n~ dB0uGib0-O9@=vZc+Y0m)gQu&X%Q~loCIBbmhu;7I diff --git a/graphics/pokemon/unown/h/overworld.png b/graphics/pokemon/unown/h/overworld.png index 9abe3e40010435444e7dbc9a94ce90c5dc9e9f40..a5f030dbd6011979dd9f59efdf4dafb53f69dd14 100644 GIT binary patch delta 407 zcmX@ew2^s&N`sf3l26xUdBID7o1~YU=S~HjVKAuPb(=;EJ|f?_i+jEb5|%! zEmAPnGbwCc@(`$mqolyk9VlZAWHWd*XvzaAmUKs7M+SzC{oH>NS%G|m0G|-ovuD=; znF$#a96Ta43>;p(__1Th4xk7O)WaAsnpwz25y)mt@^*J&=wOxg0CKK+x;TbZ%y~QI zF7F`&o|d`1MWK=mW{fjg1!No8zr{C(cnHk*j=8ej%W@_EJI(JWe{S>$2ZHN$Q;f`h zPGXXlRBL2Xj!!w^tMKXfZ&8V#atW`eJb!wXi>v2P{USq#2PJD}Jv(qBp5ca+kGUr{Icg1P9tH-8s z-q&1rdLiSp0NsLv<_AO>%5{Acp0qQ3-w?3sN=3z+b_R2)XS+_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z3}-xD978JRyqyxr)odW(@?Bef@}=ZA?vX_emz1Z-?dEivJ@=~55q(AFx}0NYj4!S^ zaRmfQr(E&-IjJKzOOKIhX1)HTt=uND@Ao=9b8lEb`P$2~JRB+e5=0rlRhoAnb9k1| zz@T5bGy7L>V!}t=@*2Jk$6sguH)OfB>RR~$L5H2Q7+91TUOm?4IIx*vga#svmHf3VP>aiQszsN=O<9A{U{v%CFVdQ&MBb@0C6;o+5i9m diff --git a/graphics/pokemon/unown/i/overworld.png b/graphics/pokemon/unown/i/overworld.png index 39aa3b8572199448f2de292cce8c0766a7b9300b..b360c0faac3b951477fff43841dfdd94048a9ed0 100644 GIT binary patch delta 350 zcmZo?`pGmwrJlXS)7O>#1qYj;n&BFoTy6#i2JsTth?3y^w370~qErTVAC~|>cZIUl zA_ZeTlfu>|4}nTJN(%hkfilKGHiK7#raX{hNq6*hWMJ6X&;2Kn705RT@Ck7}dv*wfo#SkZ+91l4pvzYAZM{tWVwMTHS(=j#=cN2`~{iUJJaAhaUEe4$j2kzZr+4F8c`-A6Sw*B9j X=Ta@bJdf+S0>}%Vu6{1-oD!M<sJN_ zhDn|-jv*Cu-cH%bbwGi~#rS7x&@V|@l^c7%2z%M@?mNrMvxv_rZ}*&??R-KzWAvtH zE4H4re7bnwh1r)m*$WPy(p}G$5@jpRP$zHM$fO<4z}mBWMndAVn6tVL9^a3OCOlXq zb%CuQ>7l9sBiD^8X4W^X0>|Il2l|Koa=FJhftBNmWrc79^XdiC26xW0KX`6(OMeaj Y$>o8kJr2)J2Re_z)78&qol`;+0Faexw*UYD diff --git a/graphics/pokemon/unown/j/overworld.png b/graphics/pokemon/unown/j/overworld.png index af240eafd38ac6c7c4f941c00b56c9393bae28ac..e1c88938d7bbae3950aec4c44a287cf120d62234 100644 GIT binary patch delta 372 zcmbQo)XzLYrJlXS)7O>#1qYj;23r@?(=G-E2JsTth?3y^w370~qErTVAC~|>cZIUl zA_ZeTlfu>|4}nTJN(%hkfilKGHiK7#raX{hNq6*hWMJ6X&;2Kn705RT@Ck7}dv*wfo#SkZ+91l4pvzYAZN3ui(^Q|oVQmF zavnC|VGYP;KD~okMLMNLq_lAo&jsi2@e8lN;{Kx9>g4!eZOMS{k%6q)y`P ztdgbK=l6?m`?o8HQ{(ooJ=}sa0m>HVcF%SwxN(({!7Y~|Yp3nJYNoE4Kliam&*r&s z`dt>klE49mGd1jtf5b9A+uWJ>V50BlFDEn>yjsuNu<^YkpUIB09SU!Q9SXc7p4%VE wX4tTdS%ky=!$SsUm(R2K9$Y?fZ<+lmZsr#0-O_OuDj<(}y85}Sb4q9e05T|o_W%F@ delta 258 zcmeBYp2svnrQRUGC&cya*){(e{zK5cd-wkT|1TgQuw==S;^N|sJN_ zhLxT!jv*Cu-cGs5*^E$UF<*ttLZT(!i;rAvZV zhG>0VxFySA>MGN^xQPGzWElgh`)YR!+iYlbPmord?2r(Axxs;-LI3lv8KR5LhFN`sf3l26xO-9~Y#|#Dr2JsTth?3y^w370~qErTVAC~|>cZIUl zA_ZeTlfu>|4}nTJN(%hkfilKGHiK7#raX{hNq6*hWMJ6X&;2Kn705RT@Ck7}dv*wfo#SkZ+91l4pvzYAZMGWi(^Q|oVQaB z@*Xnaaed7DNQkY0*UD)^B*R5Uiw*y|4xIhBaE3$miYN8Ie{P(w`!qw^|Ewpyd za>aVRALjnnI~rKy-u+zWxL%*Hp}+miW?qf`pY$A<=M?DKoMXzAd9p<79)m2y-2CsW z`Wa3r1zjy=sAGOmYkH6AB$L1mdq$>>icEiHr@TCsb&^3vPifbpxeXt$E=V_9e}ZYg ycWUfKhFS(Wg$vI({xELX5ij2`|MI1}!&MBgJ!JR4ExfY}_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z3~M}H978JRyq#jrcgR4%CHCz}r6YzhE{iWH_cd5Jo|E=@Dk&`H9OQEA<*~7;T-sRsqe_Hb>fblSVb z+<`se@mnuvCYM0d*oONI22D21y^LIM?l&@RUC8v;`ar=VgTe~DWM4fa3p#d diff --git a/graphics/pokemon/unown/l/overworld.png b/graphics/pokemon/unown/l/overworld.png index b11096a1ab728da126eb4716749078ff2a215c94..dbbe738b8bb2ca7fefaa52ac05f16f66ce0dbbf9 100644 GIT binary patch delta 377 zcmZ3+G=+JBN`sf3l26xO2lJ4m1$iT3%pZiZDE0Avx;1l9{_UsxU zGa+MwgGYphfy0XzKX&Zc0Th9OdKd#nGYh#W0@;j7-tI089jvk*K+X8H&F zlf~9gQ2Qt?lrVF7_`yaae{YVm9}Xu6)hOVlPr+FpYoLZ^{&U^&8`oiHt>2 zzPXMpGA|kg-ydka&t$S~wj^g?&Wbi=Z$`oD9ELBo+|L*uZWO7R@TFLRt>0exUHVq` z1#S<5KkR(IAZ-T6wR{F124#VD-@=`X%>M?LU9FYgzf2)#2FQ1wu6{1-oD!M_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z3>!UN978JRyuEUe^RNLAYrtHaNDbM;?H@ies4BPkOsIUF{Kfu6A$M!jKi_SO(`D4t zX8Nd2KKVyy>7rxW0fOZc49_>#$FnjPzDegWyQR>aTWQtcko`fHC8gojrab-a%4`>f z8;`l`Fof;6)y%`8!Ep7`goF8vhd=G;J2CNVU0$8s2VRLQl^;x{8Eg!)J}?S2|2^ID z{5j()$r-G^aZ>lCzB61mZ*X!*RESx-zwO}um-9cd{r(V8yrbNZ73g{fPgg$|mUT`E FO#m^Hd_n*K diff --git a/graphics/pokemon/unown/m/overworld.png b/graphics/pokemon/unown/m/overworld.png index 0d5f60e297013c1b355d5085da527a88198dc32a..19524911541f4c12e51ba4c796a79f4a62e85aa0 100644 GIT binary patch delta 402 zcmdnbw1#`sf3l26xEw$#T11JIm^)LpEW)^Z$1hN^EyxmWO|B$^*$a*Z8yFTbe>nJ0dxC;X^70$4b&5~_z43m3G*e{JGBB9V#NO~> z^Ze;I8U#HbA9pzK|LO)yQ}wYuF6_JNcqf!5yxLiRXChz8pCtzwA8dI3$RlLIbA5&s z-dD@G+spmg)$Hf-+-Gn3{I+fmvx$J>F^yWr80G`(crG~b27LW49CBbSgVZu@Y2gb3 ziwjeBE@il|okPGrlu5jXF^2I3Z=tU1g6F#%(j&KBx~`LbyPUByDrd#(_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z45vI@978JRyq)66*KEMUQhVxjz}5604Pg)CzH)}fAE`sf3l26xZSm9dr|o87U=S~HjVKAuPb(=;EJ|f?_i+jEb5|%! zEmAPnGbwCc@(`$mqolyk9VlZAWHWd*XvzaAmUKs7M+SzC{oH>NS%G|m0G|-ovuD=; znF$#a96Ta43>;p(__1Th4xk7O)WaAsnpwz25y)mt@^*J&=wOxg0CH}5x;TbZ%z1m| zBIh9k0k#LH*>;-oEs*XI4!Oj7gzrJ~@AVHtUElxv=Hw#K@`t}M`&6y3r_+^7An<8* z%MZEhhqAszi8R*bGqSv2d-&iru{RH1>)a@QvO-F!USsW(-g~U!4AI38?wV;aIH=7` zm!Go4$l-2D5JQvE{QisV;SDU>68hHJS!AEFyBmGrfW z2AtaY;j|XRv>9y-r%JvY{3*!5b70Tg2vY`u?Ya%74Kgyk3_mIkvc6_0{WAZ->SL>w j89Yw!UQuKIH&iswYrEo8rLzpjK>^_D>gTe~DWM4fo2{8F delta 296 zcmdnSe3)s1O1(jVPl)T;vupk{{D+`>_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z4Cg#u978JRyuA|0b;y8+?SakL6lWVZdAE%FN0mF&1@^3++2#FDZ>h6D%OC#c64iL? zYeKF{6FpQutzNRnZu_BEFSov^XZo7P$TENJ<-6C!bT(LVhn<@f>ddlq>X{XKI~Z@w z5{}o8WMnWpS^e!`>I(jVnSERi0r!ee+JWRQ*VxSzHCu3m-JM}xDKm>;L)CvisSnW& z6;@Bq@p=3zwY$l|a9_fafkB30+WkD)Y==L&m+Kt(`q&t1d`Pt|FKf><0}t_ iplb22@0aaA#cchtl;3&fsaHV1F?hQAxvX`sf3l26x9pUE9M^YIW7{p6lBT9nv(@M${i&7cfeOv11JIm^)LpEW)^Z$1hN^Eyxm3>$W&tLy%xye+{MvJ$Yw;cCE$&*kSIaIlIJLPxh~dHMnL9r1GB{PvaLd@|b8|uL z=2pw;(aQad74dP`*B)S!bai>ob%XgqaBM=OSi+z8>IDZDGkAQSET!I{a_L7(!hg-z zpO+f0_P%;xZVaO}!@KPvt$}h(n{>~I9jIj8Y0uA?XCkuIt^MTR4aN6*#J1a?_`kw@ ZL%H(RKhw_oGH?UE=jrO_vd$@?2>@c&l!O2P delta 290 zcmZ3(yq9T$O1(jVPl)T;vupk{{D+`>_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z3@1EY978JRyq)6BcgTRpW$&kxT1O1`tXLz%P{?v*W1&M<^6ndsu^T>y#QM0;obE5$ z5VSHxYpR*z=an)BZ?E&d$eF=hZ^G5+Gyi*Z;7WLgSt32{s~XvNGWjvw$zRE}*@m^_?fE!`V3j97ZCH1#UfBJtxc;VP{yJ$f ebGwuOSBO6pZ8le&bKL^yD+W(jKbLh*2~7Y?$A{Jc diff --git a/graphics/pokemon/unown/p/overworld.png b/graphics/pokemon/unown/p/overworld.png index f3699ebdcdbaf109114d2873dd3c3bce8692e251..fc497afc096bb23b98d7a1153690247114024526 100644 GIT binary patch delta 365 zcmbQn)WJMKrJlXS)7O>#1qYj;E_1v5QwIhH2JsTth?3y^w370~qErTVAC~|>cZIUl zA_ZeTlfu>|4}nTJN(%hkfilKGHiK7#raX{hNq6*hWMJ6X&;2Kn705RT@Ck7}dv*wfo#SkZ+91l4pvzYAZLxIi(^Q|oVQmF zavnC|VGXEcKD~okMLMNLq_lAo&jsi2@e7wbeYN*!oyYad{N}Oqf_<)9Q@xf3RW2`m z`;qId)cXkxw|CWWvAo)qqiFGsJN_ zhJ~Ikjv*Cu-d;J#*| zn|w0m-IOk=^$xCg7Bb8H{wBgwd}N=j;*E@Eo^6Rm42{`sf3l26xJ+XuDgEANx7{p6lBT9nv(@M${i&7cfeOv11JIm^)LpEW)^Z$1hN^Eyxm+EE(Y$XU}ik97f zI^nf^)lG&OXF_v&LYXrb^qNN|um>g{Ug~`$y5Up3f$hA-5f;bi-4Q!G0xkQbAe(0&c^+Z)-gPOtP^&HcbZ$OHlqiV-6xUbSCs?K1hG^uWMbG` zTq5JpySjYJC+57F%Y_!qH&gih>uUE0+k{)ozl+S#V|4g_GXL1xnR)7eWfuIOcjx(c b_bNu&my%~_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z3`aa&978JRyq$88?~sCk%l9quZmZ^BbT&S8_Xlg+m(8yFcV&|@x61j49YZ!i2l;qC#~Yw0&4 zUd2Z+8dx&;O+ToUc;NCcHns`t{TdkCnOG7F;$N^hwaPPeUFox7eY|krho{o5PfoL| zaBJ{(`>Sr17W&5gBTKvIdGz~3XB(!PN|)s`zW8x2{PDY)?-c&Z9LV>7{qeWBvMob? XvR}31lm$^hA2E2k`njxgN@xNAt1FDM diff --git a/graphics/pokemon/unown/question_mark/overworld.png b/graphics/pokemon/unown/question_mark/overworld.png index e4d210288364040bd08298e5864d79e4640eac28..743b7edbfe9ddbb1eed54c6d3c880e4b17f192cd 100644 GIT binary patch delta 379 zcmdlgI+b~Xay>L4EGspZGs8FffRhxJHx&=ckpFCl;kLxcj&S__-^T zr4}g|>zNd`E_n!4!ckJ-=MI!H2C^Bv8Z_mB6id3JuOkD)#(wTUiL5}rL4Z$)>)Eqw zfXsx92@W0+8U_w8Ui{dxV+T+K3hH4DIL$2Nq6p+LCV9KNFm$lWdH^{)JzX3_D(1YM za*+410*`AVv(F{QLu@OA11zPtFn_u5H#}qgpOE{GUxH5l|CZCvE~LoPfBf;sKRSUz z@&blp1}r;sLL|Ija%-H~;3(1+vzt>yZ>zani-yBLosx^80Xq)Za2>YNaCmlCpXrIh zRIX&-CDm>X@e2fgY1kApiSTSvov>-Cq#3K^y1R{E-ELYX<|y@UTxGP4b$5)^9BYy|gdQ@0+Qek%>aB^>EX>4U6ba`-PAZ2)IW&i+q+O3ysk|Qe) zM*p*lSpo=zU^##w;_hIUKZmrdx~jWp?jy!ocDhJ15&9mI!~XXlC;W?-#9l*DYqi%J zd6ize48FAZdiCcs#qxYUul2sf|KG-gd|VKQGUxpI*T#GPV1HbH-0-nRn%~DmdtZ_E zeo*>+@bk)d<@?>g2FbX*##4DesPEU8+M9h1b-o|8-V>it-tY1m*6Vct58noiEV;5! z7TG!F_X$5agOn8g1#mB<6HPS`!ar?d>QW< z`KMggcaHe-+kXp5e;Uu9>&w@L^Jhfz{le)VkNP#q=Xg73zjilDC8PDts3+O!<1tK} zq&z>jRSx5=e7EQ594(HxfZSo`mk^OCSoa(#|A)y$gegg2qaZ;f|QbTm0;53uFXA`p1Gn@MWEL$Br+O4~k#Wv&zy{m#wz?8ZMq4oAB!9 z&AX4C!p13f*}Cht-FDyOz_pW4IeO}`(@sC*6MwZgs=pk61GV%SnC4snI1R%6r%wkKW$VKjA7P}w{6@t`@P4ILP1H!VC=t-a0{Xp(7;TE+0 zCEVoCkP8>O{|9mb=zhiRH>mk|s$+g|yDGdnjT!Zw(ucG#WHu~=ul&V-eh&Zi#sWY< z5r1ph88~Ms-lb?8x%RX$QVLe-l(MwVEp3@6$?hhLypLJ?I@RlB&ICXF6QT0wEu^lE zN1^>)zT2$$p7Sj;-?$SVX1eQ~aHut8-HgrePjLw>ZgwUD$3uyE$)Fe|LFeym+y!6h;| zVY_GiNV2!GlGT&9`_%-cYv6^Yqf2+g%QpcKf694^OIDkte5_O%)wX@@;HKF%&3}eW z&sw%o#-81<(A9@g>_ponA-(4{q4Xk(q_Wl_vyeFUg!`s&I!2i^i=wkPPbh1<&ZQt# ztH-n1{*0xry2oBQHHRolYP&{jdqa*HS~|)`)mAq14PuC^SMh4)bV+U2x(Vm3$vgS^M@hglnK%td+sgPNE zQiKOxR9Z8o-f55VaL0nzv2hgjW0GW)sZSOLQ*}-E)9_F~%TUaSjWRIlhPe6AIYF*4 z=dkL%Edx$y>inkY@P#@g;D22(M|hpjDZ08+e>$KdhBB@(4cK_amkM2NyADD5K>TUW ze4(NuY>j)FB=mb^v^8z#Ni9jp0XH+k!`$K~{yf-R7>5X(+c{7D^9&ku-=4EcozC9w zm4;03*%vw*6bN18GEY9k3Yxr9)2Iih)H$6xP^*&E)>hSS)VK~0U4Qqr*u2_s$dafp zI&iXeTCS7_4TqWo6LxD8PD~Wv)JGz_Mp>i@&%lsxu1}$6^xB*znby@N;dkz0KU6`q zwwkCqsR2r(7-QiTKTyk~?LtYL@yVxBi!fJ(oGY{ZKn->(PEHX$0lL%BcB~lG@Lc!S z5FFNl3!U4LmLNICS7eO$t#C6;P;g+=DcvCa|~N}|)# zMelGSqa84)!%Qc}vij^9?#EYw#C>SKNrLZq;3l16kp}_-gi;0i4a{S7<@d!^5(%RA z^U%S@@UcT9A5H`h0|k$Jk`>r-u8T#a%Z`Z!E0}{W2M$9z!GA0h&S3MVZE&(R7p>n% zCgC<74+I@V#zf+R#utgt3A?h+&lu_=O;d&62XEMA-i9plI|AMWIw7o?{w1XYt6Rp@ z+%h<#H#&^FLAn|ztr*3o_kj_Wo(8P#dg^ZMu+Bijx#^6irc>8il`64q^S0&zkU(1O*QVlUWcf8k3HBJ;)XY7)0004nX+uL$Nkc;*aB^>EX@6{G004NLeUUv#!$25@-==Cs zDh};X#34g<5DTIrj#`BxR0y>~s}3fY{y~$5q{YQia4k6avsiU-an{wrRS*P!K%5+% z6kVjm?~+1`7!U65;l1yDx%&k&SHR1B%Wo4StZ^ep5Ck)ocD>ttSGC*=fqx#>7 zoC^*MJTq*jQ}e`OVzJP{N(Zx|sS!^RM^#Oyd?Dkq%6W^kR<5zuJ^2fRIelfB>okXu zz#^6)L4<-DN+_d>80|VK7E*K`_wWxoeu-QPxqnJv0{s+H%Yvm^=+@xR} z=zg*7k6|FN3pDGt{e5iP%@e@?3|#4Lf29G;e3D*oYtbWMU>mr&ZfnXOaJd6So($QP z9m!8q$mfCgGy0}15V{5W*4)0e&T;wxq^VcQ8{ps&7%5Qpy2rbFJNx!;O{;%DT$FO2 zFMo9fZvX%QFi=cXMa|8u{{a900RR60|K8r-|Ns9G5D=uKq;qp~Qc_a?0RR60|Nj90 z{{a900RR60|C0^%^#A|>32;bRa{vGf6951U69E94oEQKA00(qQO+^Rf1{f0uIaSDd z0ssI2rb$FWR7l6|)JqD(Fbo7xuY9u7bAMY;EgAcANPJpq`QEcYd3W$?H*8p%a^m-ePF`|*5kly2kTLw;3x4E o+5y^qz}X-SgztG>{C)pXPGz%X>6?rePXGV_07*qoM6N<$f*8#1qYj;zS-kh&JP(F7{p6lBT9nv(@M${i&7cfeOv>405 zA!CArM}&rf!;2R`cI?;z6oG+y7z0K#3%Mu)*^Eiv?k)@+tg;?J&T3B=$B>FSZ?9bB zY!2XIy^zBExk7e9UXrJ{MrlJ`$$wF;e^c&USdt{jweyGYx+g1ExJ>n08nkkc^5K2+ zHvfHmGq0gF(w{et<#vs6`h!Eurf(=`I8#$=vz#F%GsJN_ zhWVZ@jv*Cu-d-`}I&8qh8sKXcsbSm3u3XYENx4OC_r0cl4qdMUG+yL8J+rSi3|tzt zGDItV$=bJ;uj}QvF>-CT)jU(k@#>q2`i214!+V(%p6%PO!Vu}EWKbB`sf3l26x1JzY^JPR2Z7{p6lBT9nv(@M${i&7cfeOv11JIm^)LpEW)^Z$1hN^EyxmUpI z75nSY_>5)7_czL>oDVoz6`ud$c(*jBI%y5F^S9HFYfjfU$1_b}_>?zud2(yQrpl;Q z3mAg-$M%aht<+E7@7k2bKK*y{+Qy|K_t{r4TCdgnuF%L(x2u`Ki{XFdiQ{jd^|iR0 zO$)L$;+*l*eDZ^P-}HOgO*e?ga4PH)yuzU0Cx5cr{R6K;jf~8RcdKWwW2ob`-1M(_ jAH$9Y=ACg*>}C9y3x~_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z3}-!E978JRyuD(`cUXbPA<%!0&Z;V&wi8O#SCw5X9nVF({gHim$uIO{n)DwgA;Fo3 z$;W!^xp;qRvi}Wiuw;DJTDzoPiYY>n@r335=B-nzwR5gBMsMT(Q*(CqU8V^PpGxGa zqZKu(-lU83Fle6MyH;SzqHkx!6U04Ue@@J6U9f7eX_MiC)wAw2vB+3dF|pTicj#^3 z_GsOjbH;xQ8KgOw6eO6pCU`Mi{F=b?qy6%;nhKWt40p~SY#1qYj;p~P$6!jB9L4B{oO5hcO-X(i=}MX3z#J}v=%?h0k8 zMGD4xCWWm_9s-qcloa^617(bXYzD6eO?e>2lJ4m1$iT3%pZiZDE0Avx;1l9{_UsxU zGa+MwgGYphfy0XzKX&Zc0Th9OdKd#nGYh#W0@;j7-tI089jvk*K+aT87srr_Id7*N zUv{lAn%J?gmZkQZ$dyMEbbhluah zTVq0X|0_-CyZY(lfft+~q!vvt>t42cmLGG4Vf9?LAMygnmpAV5{eOg6flJQ$vHadr PkkdU~{an^LB{Ts5b~SWm delta 232 zcmey!)WS4DrQRUGC&cya*){(e{zK5cd-wkT|1TgQuw==S;^N|sJN_ zhJH^M$B>FSZ>JpOY%maDd7ql8E_k^-P}k0{_n2}_ab<&u2=@;zj>nfB?k%%VWq09^ VIs2EP$Q`sf3l26xBc5BozWFmSFo>79MwA5SrR}8R%`D`i2xK!RdAqwXbg;^L06BX-T^vIy=DeM9 zkoS-QkLz3BM?!23z7A=OF6<8u{L`NB&FPQxV~?p5Cj6-`ivJxSwNdXJ1@OJK3C|-1ZW*Eqep00i_>zopr E09{&*t^fc4 delta 272 zcmbQqyqal(O1(jVPl)T;vupk{{D+`>_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z4BI?i978JRyq)66b=ZK1rS#Hir6^Sk_{U9_h}%qJn;M=;GKy~cu*P9S%&7-#Nwv-4VqD+;9$5H+yZjJmqprrR zo8oRZA~$x}wzn$svwE@L;*WS%sc}Qf#{K)$wmrX1TmCQme^OfGW!~|u=Ch1IFK{w= My85}Sb4q9e0A_ZC2mk;8 diff --git a/graphics/pokemon/unown/v/overworld.png b/graphics/pokemon/unown/v/overworld.png index 0bb8dba96c8ee604ff3aa40de9017de606116df2..c1fd90ff23d7ed51db049589440d237cca8d4bee 100644 GIT binary patch delta 360 zcmbQh)XY3VrJlXS)7O>#1qYj;k;QL6re6#U4B{oO5hcO-X(i=}MX3z#J}v=%?h0k8 zMGD4xCWWm_9s-qcloa^617(bXYzD6eO?e>2lJ4m1$iT3%pZiZDE0Avx;1l9{_UsxU zGa+MwgGYphfy0XzKX&Zc0Th9OdKd#nGYh#W0@;j7-tI089jvk*K+bYc7srr_Id7+& z=500*aJep9@l(XXiZNHJV?l$=rF!lIXM3j3Re931MOn{(@z>3%DHA-Jjx*HJefm^|2aAd#cx#^McP4DWaAiYFdmjnuy+*!b@L`xx#CA5Yvj z5?yk;pljuVNV%J-vt!blO6vEy^`AZSn4jfVzg%$Rqox0Tv$!bSHAp1?FgrQRUGC&cya*){(e{zK5cd-wkT|1TgQuw==S;^N|sJN_ zhS{Djjv*Cu-cB*(I-(%rveqUtqKK#4V20fr!9#M@zR%C8*Prm}Iv}4T*KFr%xYR>M zsMF=wlcIZ$=f!Lrrn2lU$gRzdk4}7gvn982zNgBQd97g%HE*`XH;9MSX16jN|1p2< z0R!2eTHcQT-Z<;9md@%vy+TjhG47tU%`@-m({orN9(>&K;F++B&-zE7UTE+7JM)z+ h$FuW(wRQZb#6wp_+5Z$5F$TJm!PC{xWt~$(699={bRqx% diff --git a/graphics/pokemon/unown/w/overworld.png b/graphics/pokemon/unown/w/overworld.png index d49a4cf96cb94452d43965c5f6cc87e14eefb037..8c424c88b9a1aa91f2fdce0459aa68d25c3b219d 100644 GIT binary patch delta 358 zcmeBYYGj_EQqNxE>Fdh=f`d)aSWm36?G*z9gLsK+L`iUdT1k0gQ7VJGk4u1`yFyuN zk%F##t%t9`TKsIBNx4R2N2dk_Hkh9d&#WAE}&f6)D ze9aCV3=i46Z?WH)f8znWRILO5-~ZxA;<#?7Ogu8fBr%V~G4!aj`_~Ti2ef7LjRA+LBm*MRC?_Xpe z9>2<%l(zZ4to5P`z_>|7cIHL%V;LZ?c)I$ztaD0e0sv`>fTI8a delta 243 zcmZoFSZ>Jb?H5l-?8b3`@l2dm6`9e?5(PrCKO}8AKE`=wSdzbx@xAG8SaTH*Y zKcxS=Gw$BkWJPXXrwi`QA!l;#I!On-maK^_C}Gn#e%cY(X8ZTz^X;l7OcUM&ZAwB($NJKd|hp)ElcJ9M=o5CNk*yw#Q gFWB?z{ulW$ecRaJ|K9z7fX-y_boFyt=akR{0G^0&f&c&j diff --git a/graphics/pokemon/unown/x/overworld.png b/graphics/pokemon/unown/x/overworld.png index e1621d278bd6be49e0b8f4b04d1f21761dbceecb..4de8713939353ce73e3fd8749c8713c802d9c594 100644 GIT binary patch delta 371 zcmbQq)W#1qYj;iONpVpT-Of4B{oO5hcO-X(i=}MX3z#J}v=%?h0k8 zMGD4xCWWm_9s-qcloa^617$$U8N3=a<$)ASx}&cn1H;CC?mvmFK)ykMPl)T;vul9N zgp3Ie9uXP_4liE(*s)^=Py`0*VGJ0}EaajHWHTmtySp%Su*!M>Ih#CP978JRyq$cI zx7mQlbuMp`2YZHj0*h8TV+h-e#=qeTJCE8=>b(`LYJcS6XJvcAlP-<|ERF&(ZLep4 z`d*uxdvK2B`MV4(cdDe|}?>likmw|3s;=I*JFMxlKRSJ^bt$%l%JeT%gSl#ZH%vQPow{$@M@^tlcS?83{1OUfefsJN_ zh9#aZjv*Cu-cB~;I&8q>YWg!p?Tdumnd3LT`vt0+=9s@q^HkXCIjt$~gu?#?>g+C4 zR6HlCoV?y}|I)eVbAB~#UAQ*5jQOs?sm``b+KD&s-+srj_zss(to-NBJP+o>XF2yR z_;Ou%oLhFN`sf3l26xQ_+tXPIxddFo>79MwA5SrR}8R%`D`i2xK!RdAqwXbg;^T9JI~T#WAE}&f6&m zd7BM*T<7v8d9Y`gC$MOhGlsCeX#5-Ap!{#zn`MFg9zTQl?#ut1Tw@Rz4g}Xzj~w^@ z`TdVa?SUDV{mYqjdWse?eqivq{MgR&fW~%)$Jd`0*c^0{dh+sFNR2~P?Y5iDT^;94 zFEDX2{V>yB-^gKbK!Tx_BZoC0@_v@;j!jCB*6FYqY@Wq%;hB^Kv&a8@uI%E+hxw!a v-e>IGd9t4I%H$|{<_Be0tBQS_UstKV?ah*RU)&Mw0P>rstDnm{r-UW|jCq3+ delta 259 zcmbQlJfCTTO1(jVPl)T;vupk{{D+`>_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z468g{978JRyq)66)oQ@wvia0W7aKQm)hm1dD4(!ze7^N`8B^!qU*b+|yJqm5X=Za0 z;c9hSc-`aG<1f{5!O|PlJhOvq8d~H0LKyfR?DqXmWY``sf3l26xGl5mp^H~@e7{p6lBT9nv(@M${i&7cfeOv11JIm^)LpEW)^Z$1hN^Eyxm(It?!vYD)f#zEIycxhCX8^OWDaV;)Vn@NHkX8VFv88`-bW zd{@fKI)n8>8Uw?IgG@|vmswbn&N;9wxGy$^)llt0{R)P6sjh;?414D|aCF4nb2x3Xw8+@1G&DMOUYp64uA80?oaF{m*7xT~(PfaSs53$nWXSBi6PN=*E8 zm!Z9#^T6AuPemE7Fcg0=33$%6p#R6x<+`cy%jFqgl=CqBcvaDS=>NvJHM8W{Z*?68 Qd62==)z4*}6H`JH0Oq5KIRF3v delta 286 zcmZ3?ypw5yO1(jVPl)T;vupk{{D+`>_wN1w|6f2rV9Amt#l^)zK|ydSIAb#J*RKo= z3`aa&978JRyq#jr$7IOkvi;M^u#V(_HEs*tWf%*aZ1pcZG}mC8#-@4s=j6&lq10Jz zAW*mT!osYHzxYHGbQ?A@)iWd9Zze#7#N(r)*ovyb?`P~xWLe1Kkq<8G~?uFcZ-kp z`TPvq&#=LsS-wwGYbP0l+XkKw1k5t From ba1512f864e17e8a623b1015f2a82afc239500ea Mon Sep 17 00:00:00 2001 From: cawtds <38510667+cawtds@users.noreply.github.com> Date: Mon, 12 Aug 2024 21:52:55 +0200 Subject: [PATCH 14/64] Fix specific tiles changing to pc tiles when using boxlink/debug pc (#5141) --- include/tilesets.h | 3 +++ src/field_specials.c | 22 ++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/include/tilesets.h b/include/tilesets.h index c7cc8edac9..b495b6c52c 100644 --- a/include/tilesets.h +++ b/include/tilesets.h @@ -7,4 +7,7 @@ extern const u16 gTilesetPalettes_General[][16]; extern const struct Tileset * const gTilesetPointer_SecretBase; extern const struct Tileset * const gTilesetPointer_SecretBaseRedCave; +extern const struct Tileset gTileset_Building; +extern const struct Tileset gTileset_BrendansMaysHouse; + #endif //GUARD_tilesets_H diff --git a/src/field_specials.c b/src/field_specials.c index b44c8327aa..d1b27e2df6 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -44,6 +44,7 @@ #include "strings.h" #include "task.h" #include "text.h" +#include "tilesets.h" #include "tv.h" #include "wallclock.h" #include "window.h" @@ -969,6 +970,20 @@ void FieldShowRegionMap(void) SetMainCallback2(CB2_FieldShowRegionMap); } +static bool32 IsBuildingPCTile(u32 tileId) +{ + return gMapHeader.mapLayout->primaryTileset == &gTileset_Building && (tileId == METATILE_Building_PC_On || tileId == METATILE_Building_PC_Off); +} + +static bool32 IsPlayerHousePCTile(u32 tileId) +{ + return gMapHeader.mapLayout->secondaryTileset == &gTileset_BrendansMaysHouse + && (tileId == METATILE_BrendansMaysHouse_BrendanPC_On + || tileId == METATILE_BrendansMaysHouse_BrendanPC_Off + || tileId == METATILE_BrendansMaysHouse_MayPC_On + || tileId == METATILE_BrendansMaysHouse_MayPC_Off); +} + static bool8 IsPlayerInFrontOfPC(void) { s16 x, y; @@ -977,12 +992,7 @@ static bool8 IsPlayerInFrontOfPC(void) GetXYCoordsOneStepInFrontOfPlayer(&x, &y); tileInFront = MapGridGetMetatileIdAt(x, y); - return (tileInFront == METATILE_BrendansMaysHouse_BrendanPC_On - || tileInFront == METATILE_BrendansMaysHouse_BrendanPC_Off - || tileInFront == METATILE_BrendansMaysHouse_MayPC_On - || tileInFront == METATILE_BrendansMaysHouse_MayPC_Off - || tileInFront == METATILE_Building_PC_On - || tileInFront == METATILE_Building_PC_Off); + return IsBuildingPCTile(tileInFront) || IsPlayerHousePCTile(tileInFront); } // Task data for Task_PCTurnOnEffect and Task_LotteryCornerComputerEffect From a8cd459370c5f512bab666435c29fb61573633e6 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Mon, 12 Aug 2024 21:54:24 +0200 Subject: [PATCH 15/64] Fixes Purifying Salt not halving dmg for dynamic move types (#5145) * Fixes Purifying Salt not halving dmg for dynamic move types * forgot to add --- src/battle_util.c | 11 +++++++---- test/battle/ability/purifying_salt.c | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index e517a81605..3be34d1afc 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8257,6 +8257,8 @@ u32 GetMoveTarget(u16 move, u8 setTarget) { u8 targetBattler = 0; u32 moveTarget, side; + u32 moveType; + GET_MOVE_TYPE(move, moveType); if (setTarget != NO_TARGET_OVERRIDE) moveTarget = setTarget - 1; @@ -8274,7 +8276,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget) else { targetBattler = SetRandomTarget(gBattlerAttacker); - if (gMovesInfo[move].type == TYPE_ELECTRIC + if (moveType == TYPE_ELECTRIC && IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_LIGHTNING_ROD) && GetBattlerAbility(targetBattler) != ABILITY_LIGHTNING_ROD) { @@ -8282,7 +8284,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget) RecordAbilityBattle(targetBattler, gBattleMons[targetBattler].ability); gSpecialStatuses[targetBattler].lightningRodRedirected = TRUE; } - else if (gMovesInfo[move].type == TYPE_WATER + else if (moveType == TYPE_WATER && IsAbilityOnOpposingSide(gBattlerAttacker, ABILITY_STORM_DRAIN) && GetBattlerAbility(targetBattler) != ABILITY_STORM_DRAIN) { @@ -9771,7 +9773,7 @@ static inline u32 CalcDefenseStat(u32 move, u32 battlerAtk, u32 battlerDef, u32 modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5)); break; case ABILITY_PURIFYING_SALT: - if (gMovesInfo[move].type == TYPE_GHOST) + if (moveType == TYPE_GHOST) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(2.0)); break; } @@ -10467,7 +10469,8 @@ uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef) { uq4_12_t modifier = UQ_4_12(1.0); - u8 moveType = gMovesInfo[move].type; + u32 moveType; + GET_MOVE_TYPE(move, moveType); if (move != MOVE_STRUGGLE && moveType != TYPE_MYSTERY) { diff --git a/test/battle/ability/purifying_salt.c b/test/battle/ability/purifying_salt.c index e188262497..4c25321e5f 100644 --- a/test/battle/ability/purifying_salt.c +++ b/test/battle/ability/purifying_salt.c @@ -19,6 +19,24 @@ SINGLE_BATTLE_TEST("Purifying Salt halves damage from Ghost-type moves", s16 dam } } +SINGLE_BATTLE_TEST("Purifying Salt halves damage from dynamic Ghost-type moves", s16 damage) +{ + u16 ability; + PARAMETRIZE { ability = ABILITY_STURDY; } + PARAMETRIZE { ability = ABILITY_PURIFYING_SALT; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TERA_BLAST].effect == EFFECT_TERA_BLAST); + PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_GHOST); } + OPPONENT(SPECIES_GARGANACL) { Ability(ability); } + } WHEN { + TURN { MOVE(player, MOVE_TERA_BLAST, gimmick: GIMMICK_TERA); } + } SCENE { + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[0].damage, UQ_4_12(0.5), results[1].damage); + } +} + SINGLE_BATTLE_TEST("Purifying Salt makes Rest fail") { GIVEN { From c74ad262cb5e6a2267e0115a3554e8b4181f2c8e Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Mon, 12 Aug 2024 16:32:11 -0400 Subject: [PATCH 16/64] Fixed incoming usage of GET_MOVE_TYPE from master --- src/battle_util.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index adcb745c7b..9da592b09f 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8256,8 +8256,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget) { u8 targetBattler = 0; u32 moveTarget, side; - u32 moveType; - GET_MOVE_TYPE(move, moveType); + u32 moveType = GetMoveType(move); if (setTarget != NO_TARGET_OVERRIDE) moveTarget = setTarget - 1; @@ -10468,8 +10467,7 @@ uq4_12_t CalcTypeEffectivenessMultiplier(u32 move, u32 moveType, u32 battlerAtk, uq4_12_t CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef) { uq4_12_t modifier = UQ_4_12(1.0); - u32 moveType; - GET_MOVE_TYPE(move, moveType); + u32 moveType = GetMoveType(move); if (move != MOVE_STRUGGLE && moveType != TYPE_MYSTERY) { From f18859ac331c5356ac8ad4895729640ac9fa2b11 Mon Sep 17 00:00:00 2001 From: Frank DeBlasio <35279583+fdeblasio@users.noreply.github.com> Date: Mon, 12 Aug 2024 23:07:12 -0400 Subject: [PATCH 17/64] Refactor Frontier Brains (#5027) * Created gFrontierBrainInfo with trainerId * Added objEventGfx and isFemale * Added win/loss texts * Added battleBit and streakAppearances * Added macro for texts * Added macro for sprites --- src/frontier_util.c | 218 ++++++++++++++++++++------------------------ 1 file changed, 97 insertions(+), 121 deletions(-) diff --git a/src/frontier_util.c b/src/frontier_util.c index ca8c76a0fd..7cadbf364b 100644 --- a/src/frontier_util.c +++ b/src/frontier_util.c @@ -49,6 +49,17 @@ struct FrontierBrainMon u16 moves[MAX_MON_MOVES]; }; +struct FrontierBrain +{ + u16 trainerId; + u8 objEventGfx; + u8 isFemale; + const u8 *lostTexts[2]; + const u8 *wonTexts[2]; + u16 battledBit[2]; + u8 streakAppearances[4]; +}; + // This file's functions. static void GetChallengeStatus(void); static void GetFrontierData(void); @@ -83,16 +94,74 @@ static void ShowPyramidResultsWindow(void); static void ShowLinkContestResultsWindow(void); static void CopyFrontierBrainText(bool8 playerWonText); -// const rom data -static const u8 sFrontierBrainStreakAppearances[NUM_FRONTIER_FACILITIES][4] = +#define FRONTIER_BRAIN_SPRITES(Brain) \ + .trainerId = TRAINER_##Brain, \ + .objEventGfx = OBJ_EVENT_GFX_##Brain + +#define FRONTIER_BRAIN_TEXTS(Brain) \ + .lostTexts = {gText_##Brain##DefeatSilver, gText_##Brain##DefeatGold}, \ + .wonTexts = {gText_##Brain##WonSilver, gText_##Brain##WonGold} + +// battledBit: Flags to change the conversation when the Frontier Brain is encountered for a battle +// First bit is has battled them before and not won yet, second bit is has battled them and won (obtained a Symbol) +const struct FrontierBrain gFrontierBrainInfo[NUM_FRONTIER_FACILITIES] = { - [FRONTIER_FACILITY_TOWER] = {35, 70, 35, 1}, - [FRONTIER_FACILITY_DOME] = { 4, 9, 5, 0}, - [FRONTIER_FACILITY_PALACE] = {21, 42, 21, 1}, - [FRONTIER_FACILITY_ARENA] = {28, 56, 28, 1}, - [FRONTIER_FACILITY_FACTORY] = {21, 42, 21, 1}, - [FRONTIER_FACILITY_PIKE] = {28, 140, 56, 1}, - [FRONTIER_FACILITY_PYRAMID] = {21, 70, 35, 0}, + [FRONTIER_FACILITY_TOWER] = + { + FRONTIER_BRAIN_SPRITES(ANABEL), + .isFemale = TRUE, + FRONTIER_BRAIN_TEXTS(Anabel), + .battledBit = {1 << 0, 1 << 1}, + .streakAppearances = {35, 70, 35, 1}, + }, + [FRONTIER_FACILITY_DOME] = + { + FRONTIER_BRAIN_SPRITES(TUCKER), + .isFemale = FALSE, + FRONTIER_BRAIN_TEXTS(Tucker), + .battledBit = {1 << 2, 1 << 3}, + .streakAppearances = {1, 2, 5, 0}, + }, + [FRONTIER_FACILITY_PALACE] = + { + FRONTIER_BRAIN_SPRITES(SPENSER), + .isFemale = FALSE, + FRONTIER_BRAIN_TEXTS(Spenser), + .battledBit = {1 << 4, 1 << 5}, + .streakAppearances = {21, 42, 21, 1}, + }, + [FRONTIER_FACILITY_ARENA] = + { + FRONTIER_BRAIN_SPRITES(GRETA), + .isFemale = TRUE, + FRONTIER_BRAIN_TEXTS(Greta), + .battledBit = {1 << 6, 1 << 7}, + .streakAppearances = {28, 56, 28, 1}, + }, + [FRONTIER_FACILITY_FACTORY] = + { + FRONTIER_BRAIN_SPRITES(NOLAND), + .isFemale = FALSE, + FRONTIER_BRAIN_TEXTS(Noland), + .battledBit = {1 << 8, 1 << 9}, + .streakAppearances = {21, 42, 21, 1}, + }, + [FRONTIER_FACILITY_PIKE] = + { + FRONTIER_BRAIN_SPRITES(LUCY), + .isFemale = TRUE, + FRONTIER_BRAIN_TEXTS(Lucy), + .battledBit = {1 << 10, 1 << 11}, + .streakAppearances = {28, 140, 56, 1}, + }, + [FRONTIER_FACILITY_PYRAMID] = + { + FRONTIER_BRAIN_SPRITES(BRANDON), + .isFemale = FALSE, + FRONTIER_BRAIN_TEXTS(Brandon), + .battledBit = {1 << 12, 1 << 13}, + .streakAppearances = {21, 70, 35, 0}, + }, }; static const struct FrontierBrainMon sFrontierBrainsMons[][2][FRONTIER_PARTY_SIZE] = @@ -537,20 +606,6 @@ static const u8 sBattlePointAwards[NUM_FRONTIER_FACILITIES][FRONTIER_MODE_COUNT] }, }; - -// Flags to change the conversation when the Frontier Brain is encountered for a battle -// First bit is has battled them before and not won yet, second bit is has battled them and won (obtained a Symbol) -static const u16 sBattledBrainBitFlags[NUM_FRONTIER_FACILITIES][2] = -{ - [FRONTIER_FACILITY_TOWER] = {1 << 0, 1 << 1}, - [FRONTIER_FACILITY_DOME] = {1 << 2, 1 << 3}, - [FRONTIER_FACILITY_PALACE] = {1 << 4, 1 << 5}, - [FRONTIER_FACILITY_ARENA] = {1 << 6, 1 << 7}, - [FRONTIER_FACILITY_FACTORY] = {1 << 8, 1 << 9}, - [FRONTIER_FACILITY_PIKE] = {1 << 10, 1 << 11}, - [FRONTIER_FACILITY_PYRAMID] = {1 << 12, 1 << 13}, -}; - static void (* const sFrontierUtilFuncs[])(void) = { [FRONTIER_UTIL_FUNC_GET_STATUS] = GetChallengeStatus, @@ -611,18 +666,6 @@ static const struct WindowTemplate sRankingHallRecordsWindowTemplate = .baseBlock = 1 }; -// Second field - whether the character is female. -static const u8 sFrontierBrainObjEventGfx[NUM_FRONTIER_FACILITIES][2] = -{ - [FRONTIER_FACILITY_TOWER] = {OBJ_EVENT_GFX_ANABEL, TRUE}, - [FRONTIER_FACILITY_DOME] = {OBJ_EVENT_GFX_TUCKER, FALSE}, - [FRONTIER_FACILITY_PALACE] = {OBJ_EVENT_GFX_SPENSER, FALSE}, - [FRONTIER_FACILITY_ARENA] = {OBJ_EVENT_GFX_GRETA, TRUE}, - [FRONTIER_FACILITY_FACTORY] = {OBJ_EVENT_GFX_NOLAND, FALSE}, - [FRONTIER_FACILITY_PIKE] = {OBJ_EVENT_GFX_LUCY, TRUE}, - [FRONTIER_FACILITY_PYRAMID] = {OBJ_EVENT_GFX_BRANDON, FALSE}, -}; - static const u8 *const sRecordsWindowChallengeTexts[][2] = { [RANKING_HALL_TOWER_SINGLES] = {gText_BattleTower2, gText_FacilitySingle}, @@ -657,73 +700,6 @@ static const u8 *const sHallFacilityToRecordsText[] = [RANKING_HALL_TOWER_LINK] = gText_FrontierFacilityWinStreak, }; -static const u16 sFrontierBrainTrainerIds[NUM_FRONTIER_FACILITIES] = -{ - [FRONTIER_FACILITY_TOWER] = TRAINER_ANABEL, - [FRONTIER_FACILITY_DOME] = TRAINER_TUCKER, - [FRONTIER_FACILITY_PALACE] = TRAINER_SPENSER, - [FRONTIER_FACILITY_ARENA] = TRAINER_GRETA, - [FRONTIER_FACILITY_FACTORY] = TRAINER_NOLAND, - [FRONTIER_FACILITY_PIKE] = TRAINER_LUCY, - [FRONTIER_FACILITY_PYRAMID] = TRAINER_BRANDON, -}; - -static const u8 *const sFrontierBrainPlayerLostSilverTexts[NUM_FRONTIER_FACILITIES] = -{ - [FRONTIER_FACILITY_TOWER] = gText_AnabelWonSilver, - [FRONTIER_FACILITY_DOME] = gText_TuckerWonSilver, - [FRONTIER_FACILITY_PALACE] = gText_SpenserWonSilver, - [FRONTIER_FACILITY_ARENA] = gText_GretaWonSilver, - [FRONTIER_FACILITY_FACTORY] = gText_NolandWonSilver, - [FRONTIER_FACILITY_PIKE] = gText_LucyWonSilver, - [FRONTIER_FACILITY_PYRAMID] = gText_BrandonWonSilver, -}; - -static const u8 *const sFrontierBrainPlayerWonSilverTexts[NUM_FRONTIER_FACILITIES] = -{ - [FRONTIER_FACILITY_TOWER] = gText_AnabelDefeatSilver, - [FRONTIER_FACILITY_DOME] = gText_TuckerDefeatSilver, - [FRONTIER_FACILITY_PALACE] = gText_SpenserDefeatSilver, - [FRONTIER_FACILITY_ARENA] = gText_GretaDefeatSilver, - [FRONTIER_FACILITY_FACTORY] = gText_NolandDefeatSilver, - [FRONTIER_FACILITY_PIKE] = gText_LucyDefeatSilver, - [FRONTIER_FACILITY_PYRAMID] = gText_BrandonDefeatSilver, -}; - -static const u8 *const sFrontierBrainPlayerLostGoldTexts[NUM_FRONTIER_FACILITIES] = -{ - [FRONTIER_FACILITY_TOWER] = gText_AnabelWonGold, - [FRONTIER_FACILITY_DOME] = gText_TuckerWonGold, - [FRONTIER_FACILITY_PALACE] = gText_SpenserWonGold, - [FRONTIER_FACILITY_ARENA] = gText_GretaWonGold, - [FRONTIER_FACILITY_FACTORY] = gText_NolandWonGold, - [FRONTIER_FACILITY_PIKE] = gText_LucyWonGold, - [FRONTIER_FACILITY_PYRAMID] = gText_BrandonWonGold, -}; - -static const u8 *const sFrontierBrainPlayerWonGoldTexts[NUM_FRONTIER_FACILITIES] = -{ - [FRONTIER_FACILITY_TOWER] = gText_AnabelDefeatGold, - [FRONTIER_FACILITY_DOME] = gText_TuckerDefeatGold, - [FRONTIER_FACILITY_PALACE] = gText_SpenserDefeatGold, - [FRONTIER_FACILITY_ARENA] = gText_GretaDefeatGold, - [FRONTIER_FACILITY_FACTORY] = gText_NolandDefeatGold, - [FRONTIER_FACILITY_PIKE] = gText_LucyDefeatGold, - [FRONTIER_FACILITY_PYRAMID] = gText_BrandonDefeatGold, -}; - -static const u8 *const *const sFrontierBrainPlayerLostTexts[] = -{ - sFrontierBrainPlayerLostSilverTexts, - sFrontierBrainPlayerLostGoldTexts, -}; - -static const u8 *const *const sFrontierBrainPlayerWonTexts[] = -{ - sFrontierBrainPlayerWonSilverTexts, - sFrontierBrainPlayerWonGoldTexts, -}; - // code void CallFrontierUtilFunc(void) { @@ -785,7 +761,7 @@ static void GetFrontierData(void) gSpecialVar_Result = gSaveBlock2Ptr->frontier.disableRecordBattle; break; case FRONTIER_DATA_HEARD_BRAIN_SPEECH: - gSpecialVar_Result = gSaveBlock2Ptr->frontier.battledBrainFlags & sBattledBrainBitFlags[facility][hasSymbol]; + gSpecialVar_Result = gSaveBlock2Ptr->frontier.battledBrainFlags & gFrontierBrainInfo[facility].battledBit[hasSymbol]; break; } } @@ -820,7 +796,7 @@ static void SetFrontierData(void) gSaveBlock2Ptr->frontier.disableRecordBattle = gSpecialVar_0x8006; break; case FRONTIER_DATA_HEARD_BRAIN_SPEECH: - gSaveBlock2Ptr->frontier.battledBrainFlags |= sBattledBrainBitFlags[facility][hasSymbol]; + gSaveBlock2Ptr->frontier.battledBrainFlags |= gFrontierBrainInfo[facility].battledBit[hasSymbol]; break; } } @@ -1600,7 +1576,7 @@ u8 GetFrontierBrainStatus(void) s32 facility = VarGet(VAR_FRONTIER_FACILITY); s32 battleMode = VarGet(VAR_FRONTIER_BATTLE_MODE); u16 winStreakNoModifier = GetCurrentFacilityWinStreak(); - s32 winStreak = winStreakNoModifier + sFrontierBrainStreakAppearances[facility][3]; + s32 winStreak = winStreakNoModifier + gFrontierBrainInfo[facility].streakAppearances[3]; s32 symbolsCount; if (battleMode != FRONTIER_MODE_SINGLES) @@ -1612,20 +1588,20 @@ u8 GetFrontierBrainStatus(void) // Missing a symbol case 0: case 1: - if (winStreak == sFrontierBrainStreakAppearances[facility][symbolsCount]) + if (winStreak == gFrontierBrainInfo[facility].streakAppearances[symbolsCount]) status = symbolsCount + 1; // FRONTIER_BRAIN_SILVER and FRONTIER_BRAIN_GOLD break; // Already received both symbols case 2: default: // Silver streak is reached - if (winStreak == sFrontierBrainStreakAppearances[facility][0]) + if (winStreak == gFrontierBrainInfo[facility].streakAppearances[0]) status = FRONTIER_BRAIN_STREAK; // Gold streak is reached - else if (winStreak == sFrontierBrainStreakAppearances[facility][1]) + else if (winStreak == gFrontierBrainInfo[facility].streakAppearances[1]) status = FRONTIER_BRAIN_STREAK_LONG; // Some increment of the gold streak is reached - else if (winStreak > sFrontierBrainStreakAppearances[facility][1] && (winStreak - sFrontierBrainStreakAppearances[facility][1]) % sFrontierBrainStreakAppearances[facility][2] == 0) + else if (winStreak > gFrontierBrainInfo[facility].streakAppearances[1] && (winStreak - gFrontierBrainInfo[facility].streakAppearances[1]) % gFrontierBrainInfo[facility].streakAppearances[2] == 0) status = FRONTIER_BRAIN_STREAK_LONG; break; } @@ -2396,7 +2372,7 @@ u8 GetFrontierBrainTrainerPicIndex(void) else facility = VarGet(VAR_FRONTIER_FACILITY); - return GetTrainerPicFromId(sFrontierBrainTrainerIds[facility]); + return GetTrainerPicFromId(gFrontierBrainInfo[facility].trainerId); } u8 GetFrontierBrainTrainerClass(void) @@ -2408,7 +2384,7 @@ u8 GetFrontierBrainTrainerClass(void) else facility = VarGet(VAR_FRONTIER_FACILITY); - return GetTrainerClassFromId(sFrontierBrainTrainerIds[facility]); + return GetTrainerClassFromId(gFrontierBrainInfo[facility].trainerId); } void CopyFrontierBrainTrainerName(u8 *dst) @@ -2422,7 +2398,7 @@ void CopyFrontierBrainTrainerName(u8 *dst) else facility = VarGet(VAR_FRONTIER_FACILITY); - trainerName = GetTrainerNameFromId(sFrontierBrainTrainerIds[facility]); + trainerName = GetTrainerNameFromId(gFrontierBrainInfo[facility].trainerId); for (i = 0; i < PLAYER_NAME_LENGTH; i++) dst[i] = trainerName[i]; @@ -2432,13 +2408,13 @@ void CopyFrontierBrainTrainerName(u8 *dst) bool8 IsFrontierBrainFemale(void) { s32 facility = VarGet(VAR_FRONTIER_FACILITY); - return sFrontierBrainObjEventGfx[facility][1]; + return gFrontierBrainInfo[facility].isFemale; } void SetFrontierBrainObjEventGfx_2(void) { s32 facility = VarGet(VAR_FRONTIER_FACILITY); - VarSet(VAR_OBJ_GFX_ID_0, sFrontierBrainObjEventGfx[facility][0]); + VarSet(VAR_OBJ_GFX_ID_0, gFrontierBrainInfo[facility].objEventGfx); } #define FRONTIER_BRAIN_OTID 61226 @@ -2505,7 +2481,7 @@ u16 GetFrontierBrainMonSpecies(u8 monId) void SetFrontierBrainObjEventGfx(u8 facility) { gTrainerBattleOpponent_A = TRAINER_FRONTIER_BRAIN; - VarSet(VAR_OBJ_GFX_ID_0, sFrontierBrainObjEventGfx[facility][0]); + VarSet(VAR_OBJ_GFX_ID_0, gFrontierBrainInfo[facility].objEventGfx); } u16 GetFrontierBrainMonMove(u8 monId, u8 moveSlotId) @@ -2540,12 +2516,12 @@ s32 GetFronterBrainSymbol(void) if (symbol == 2) { u16 winStreak = GetCurrentFacilityWinStreak(); - if (winStreak + sFrontierBrainStreakAppearances[facility][3] == sFrontierBrainStreakAppearances[facility][0]) + if (winStreak + gFrontierBrainInfo[facility].streakAppearances[3] == gFrontierBrainInfo[facility].streakAppearances[0]) symbol = 0; - else if (winStreak + sFrontierBrainStreakAppearances[facility][3] == sFrontierBrainStreakAppearances[facility][1]) + else if (winStreak + gFrontierBrainInfo[facility].streakAppearances[3] == gFrontierBrainInfo[facility].streakAppearances[1]) symbol = 1; - else if (winStreak + sFrontierBrainStreakAppearances[facility][3] > sFrontierBrainStreakAppearances[facility][1] - && (winStreak + sFrontierBrainStreakAppearances[facility][3] - sFrontierBrainStreakAppearances[facility][1]) % sFrontierBrainStreakAppearances[facility][2] == 0) + else if (winStreak + gFrontierBrainInfo[facility].streakAppearances[3] > gFrontierBrainInfo[facility].streakAppearances[1] + && (winStreak + gFrontierBrainInfo[facility].streakAppearances[3] - gFrontierBrainInfo[facility].streakAppearances[1]) % gFrontierBrainInfo[facility].streakAppearances[2] == 0) symbol = 1; } return symbol; @@ -2571,10 +2547,10 @@ static void CopyFrontierBrainText(bool8 playerWonText) switch (playerWonText) { case FALSE: - StringCopy(gStringVar4, sFrontierBrainPlayerLostTexts[symbol][facility]); + StringCopy(gStringVar4, gFrontierBrainInfo[facility].wonTexts[symbol]); break; case TRUE: - StringCopy(gStringVar4, sFrontierBrainPlayerWonTexts[symbol][facility]); + StringCopy(gStringVar4, gFrontierBrainInfo[facility].lostTexts[symbol]); break; } } From a3d5f54b7588d6b5b3125c6c61356dcc0123b544 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 1 Jul 2024 15:51:15 -0400 Subject: [PATCH 18/64] Fix type for offset in MapConnection --- include/global.fieldmap.h | 2 +- src/fieldmap.c | 2 +- src/item_use.c | 45 ++++++++++++++++++--------------------- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index 7461929c3a..c7a4133ea8 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -131,7 +131,7 @@ struct MapEvents struct MapConnection { u8 direction; - u32 offset; + s32 offset; u8 mapGroup; u8 mapNum; }; diff --git a/src/fieldmap.c b/src/fieldmap.c index d9c4fa371a..5fdc4cbfb7 100644 --- a/src/fieldmap.c +++ b/src/fieldmap.c @@ -144,7 +144,7 @@ static void InitBackupMapLayoutConnections(struct MapHeader *mapHeader) for (i = 0; i < count; i++, connection++) { struct MapHeader const *cMap = GetMapHeaderFromConnection(connection); - u32 offset = connection->offset; + s32 offset = connection->offset; switch (connection->direction) { case CONNECTION_SOUTH: diff --git a/src/item_use.c b/src/item_use.c index 60338e437a..abd80e0eae 100755 --- a/src/item_use.c +++ b/src/item_use.c @@ -393,46 +393,43 @@ static bool8 IsHiddenItemPresentAtCoords(const struct MapEvents *events, s16 x, static bool8 IsHiddenItemPresentInConnection(const struct MapConnection *connection, int x, int y) { + s16 connectionX, connectionY; + struct MapHeader const *const connectionHeader = GetMapHeaderFromConnection(connection); - u16 localX, localY; - u32 localOffset; - s32 localLength; - - struct MapHeader const *const mapHeader = GetMapHeaderFromConnection(connection); - +// To convert our x/y into coordinates that are relative to the connected map, we must: +// - Subtract the virtual offset used for the border buffer (MAP_OFFSET). +// - Subtract the horizontal offset between North/South connections, or the vertical offset for East/West +// - Account for map size. (0,0) is in the NW corner of our map, so when looking North/West we have to add the height/width of the connected map, +// and when looking South/East we have to subtract the height/width of our current map. +#define localX (x - MAP_OFFSET) +#define localY (y - MAP_OFFSET) switch (connection->direction) { - // same weird temp variable behavior seen in IsHiddenItemPresentAtCoords case CONNECTION_NORTH: - localOffset = connection->offset + MAP_OFFSET; - localX = x - localOffset; - localLength = mapHeader->mapLayout->height - MAP_OFFSET; - localY = localLength + y; // additions are reversed for some reason + connectionX = localX - connection->offset; + connectionY = connectionHeader->mapLayout->height + localY; break; case CONNECTION_SOUTH: - localOffset = connection->offset + MAP_OFFSET; - localX = x - localOffset; - localLength = gMapHeader.mapLayout->height + MAP_OFFSET; - localY = y - localLength; + connectionX = localX - connection->offset; + connectionY = localY - gMapHeader.mapLayout->height; break; case CONNECTION_WEST: - localLength = mapHeader->mapLayout->width - MAP_OFFSET; - localX = localLength + x; // additions are reversed for some reason - localOffset = connection->offset + MAP_OFFSET; - localY = y - localOffset; + connectionX = connectionHeader->mapLayout->width + localX; + connectionY = localY - connection->offset; break; case CONNECTION_EAST: - localLength = gMapHeader.mapLayout->width + MAP_OFFSET; - localX = x - localLength; - localOffset = connection->offset + MAP_OFFSET; - localY = y - localOffset; + connectionX = localX - gMapHeader.mapLayout->width; + connectionY = localY - connection->offset; break; default: return FALSE; } - return IsHiddenItemPresentAtCoords(mapHeader->events, localX, localY); + return IsHiddenItemPresentAtCoords(connectionHeader->events, connectionX, connectionY); } +#undef localX +#undef localY + static void CheckForHiddenItemsInMapConnection(u8 taskId) { s16 playerX, playerY; From cfa7316ea04f37a21833b3a0b5f5f1b38476cb9b Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Tue, 13 Aug 2024 22:08:24 +0200 Subject: [PATCH 19/64] Made the speed tie test use PASSES_RANDOMLY (#5092) * Made the speed tie test use PASSES_RANDOMLY * Hack to allow results with PASSES_RANDOMLY --------- Co-authored-by: Hedara Co-authored-by: Martin Griffin --- test/battle/move.c | 90 +++++++++++++++++++-------------------- test/test_runner_battle.c | 5 ++- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/test/battle/move.c b/test/battle/move.c index 228a09a7c6..081a91712d 100644 --- a/test/battle/move.c +++ b/test/battle/move.c @@ -80,57 +80,57 @@ SINGLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie } } -DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie [doubles]") +DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie [doubles]", u32 permutations) { - struct BattlePokemon *order[4] = { NULL, NULL, NULL, NULL }; - u32 a, b, c, d; - - // TODO: Test all of these in a single PASSES_RANDOMLY pass rather - // than 24 PARAMETRIZEd passes. - PARAMETRIZE { a = 0; b = 1; c = 2; d = 3; } - PARAMETRIZE { a = 0; b = 1; c = 3; d = 2; } - PARAMETRIZE { a = 0; b = 2; c = 1; d = 3; } - PARAMETRIZE { a = 0; b = 2; c = 3; d = 1; } - PARAMETRIZE { a = 0; b = 3; c = 1; d = 2; } - PARAMETRIZE { a = 0; b = 3; c = 2; d = 1; } - PARAMETRIZE { a = 1; b = 0; c = 2; d = 3; } - PARAMETRIZE { a = 1; b = 0; c = 3; d = 2; } - PARAMETRIZE { a = 1; b = 2; c = 0; d = 3; } - PARAMETRIZE { a = 1; b = 2; c = 3; d = 0; } - PARAMETRIZE { a = 1; b = 3; c = 0; d = 2; } - PARAMETRIZE { a = 1; b = 3; c = 2; d = 0; } - PARAMETRIZE { a = 2; b = 0; c = 1; d = 3; } - PARAMETRIZE { a = 2; b = 0; c = 3; d = 1; } - PARAMETRIZE { a = 2; b = 1; c = 0; d = 3; } - PARAMETRIZE { a = 2; b = 1; c = 3; d = 0; } - PARAMETRIZE { a = 2; b = 3; c = 0; d = 1; } - PARAMETRIZE { a = 2; b = 3; c = 1; d = 0; } - PARAMETRIZE { a = 3; b = 0; c = 1; d = 2; } - PARAMETRIZE { a = 3; b = 0; c = 2; d = 1; } - PARAMETRIZE { a = 3; b = 1; c = 0; d = 2; } - PARAMETRIZE { a = 3; b = 1; c = 2; d = 0; } - PARAMETRIZE { a = 3; b = 2; c = 0; d = 1; } - PARAMETRIZE { a = 3; b = 2; c = 1; d = 0; } - - order[a] = playerLeft; - order[b] = playerRight; - order[c] = opponentLeft; - order[d] = opponentRight; - - PASSES_RANDOMLY(1, 24, RNG_SPEED_TIE); + PARAMETRIZE {} // Hack to make permutations legal. + PASSES_RANDOMLY(24, 24, RNG_SPEED_TIE); + ASSUME(gMovesInfo[MOVE_ENDEAVOR].effect == EFFECT_ENDEAVOR); + ASSUME(gMovesInfo[MOVE_LIFE_DEW].effect == EFFECT_JUNGLE_HEALING); + ASSUME(gMovesInfo[MOVE_CRUSH_GRIP].effect == EFFECT_VARY_POWER_BASED_ON_HP); + ASSUME(gMovesInfo[MOVE_SUPER_FANG].effect == EFFECT_SUPER_FANG); GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(1); } + PLAYER(SPECIES_WOBBUFFET) { MaxHP(480); HP(360); Defense(100); Speed(1); } PLAYER(SPECIES_WYNAUT) { Speed(1); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(1); } + OPPONENT(SPECIES_WOBBUFFET) { Attack(100); Speed(1); } OPPONENT(SPECIES_WYNAUT) { Speed(1); } } WHEN { - TURN { MOVE(playerLeft, MOVE_SPLASH); MOVE(playerRight, MOVE_SPLASH); MOVE(opponentLeft, MOVE_SPLASH); MOVE(opponentRight, MOVE_SPLASH); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[0]); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[1]); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[2]); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[3]); + TURN { MOVE(playerLeft, MOVE_ENDEAVOR, target: opponentLeft); MOVE(playerRight, MOVE_LIFE_DEW); MOVE(opponentLeft, MOVE_CRUSH_GRIP, target: playerLeft, WITH_RNG(RNG_DAMAGE_MODIFIER, 0)); MOVE(opponentRight, MOVE_SUPER_FANG, target: playerLeft); } + } THEN { + // This tests for unique combinatins of HP values depending on which order the moves are executed in + // The unique outcomes arise from the specific attacks and HP, Def, and Atk values chosen + // The switch is then set up in such a way that the only way for this test to pass exactly one is for each HP combination to occur exactly once +#define HP_PAIR(a, b) ((a) * 1000 + (b)) + switch (HP_PAIR(playerLeft->hp, opponentLeft->hp)) + { + case HP_PAIR(188, 360): results[i].permutations += 1 << 0; break; + case HP_PAIR(189, 360): results[i].permutations += 1 << 1; break; + case HP_PAIR(261, 360): results[i].permutations += 1 << 2; break; + case HP_PAIR(235, 360): results[i].permutations += 1 << 3; break; + case HP_PAIR(262, 360): results[i].permutations += 1 << 4; break; + case HP_PAIR(202, 360): results[i].permutations += 1 << 5; break; + case HP_PAIR(189, 378): results[i].permutations += 1 << 6; break; + case HP_PAIR(189, 189): results[i].permutations += 1 << 7; break; + case HP_PAIR(189, 480): results[i].permutations += 1 << 8; break; + case HP_PAIR(188, 480): results[i].permutations += 1 << 9; break; + case HP_PAIR(188, 240): results[i].permutations += 1 << 10; break; + case HP_PAIR(188, 188): results[i].permutations += 1 << 11; break; + case HP_PAIR(262, 262): results[i].permutations += 1 << 12; break; + case HP_PAIR(262, 142): results[i].permutations += 1 << 13; break; + case HP_PAIR(202, 403): results[i].permutations += 1 << 14; break; + case HP_PAIR(202, 202): results[i].permutations += 1 << 15; break; + case HP_PAIR(262, 283): results[i].permutations += 1 << 16; break; + case HP_PAIR(202, 283): results[i].permutations += 1 << 17; break; + case HP_PAIR(235, 180): results[i].permutations += 1 << 18; break; + case HP_PAIR(261, 180): results[i].permutations += 1 << 19; break; + case HP_PAIR(235, 235): results[i].permutations += 1 << 20; break; + case HP_PAIR(235, 300): results[i].permutations += 1 << 21; break; + case HP_PAIR(261, 141): results[i].permutations += 1 << 22; break; + case HP_PAIR(261, 261): results[i].permutations += 1 << 23; break; + } +#undef HP_PAIR + } FINALLY { + EXPECT_EQ(results[i].permutations, (1 << 24) - 1); } } diff --git a/test/test_runner_battle.c b/test/test_runner_battle.c index 11432bd12b..92789710f7 100644 --- a/test/test_runner_battle.c +++ b/test/test_runner_battle.c @@ -1327,7 +1327,7 @@ void TestRunner_Battle_AfterLastTurn(void) } STATE->runThen = TRUE; - STATE->runFinally = STATE->runParameter + 1 == STATE->parameters; + STATE->runFinally = STATE->runParameter + 1 == STATE->parameters && STATE->runTrial + 1 >= STATE->trials; InvokeTestFunction(test); STATE->runThen = FALSE; STATE->runFinally = FALSE; @@ -1369,6 +1369,7 @@ static inline rng_value_t MakeRngValue(const u16 seed) return ISO_RANDOMIZE1(seed); #endif } + static void CB2_BattleTest_NextTrial(void) { ClearFlagAfterTest(); @@ -1452,7 +1453,7 @@ void Randomly(u32 sourceLine, u32 passes, u32 trials, struct RandomlyContext ctx { const struct BattleTest *test = GetBattleTest(); INVALID_IF(STATE->trials != 0, "PASSES_RANDOMLY can only be used once per test"); - INVALID_IF(test->resultsSize > 0, "PASSES_RANDOMLY is incompatible with results"); + INVALID_IF(test->resultsSize > 0 && STATE->parametersCount > 1, "PASSES_RANDOMLY is incompatible with results"); INVALID_IF(passes > trials, "%d passes specified, but only %d trials", passes, trials); STATE->rngTag = ctx.tag; STATE->rngTrialOffset = 0; From 38752b59b42235e020cd32624d36107a2588352a Mon Sep 17 00:00:00 2001 From: psf <77138753+pkmnsnfrn@users.noreply.github.com> Date: Tue, 13 Aug 2024 15:42:39 -0700 Subject: [PATCH 20/64] Fix a sprite issue with B_SHOW_TYPES (#5157) * Fixed issue where tiles were not freed * Updated to destroy first * Cleaned up returns * Added typeIconTags Added FreeAllTypeIconResources Fixed issue where typeIcons were not being properly handled when hidden --- src/type_icons.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/type_icons.c b/src/type_icons.c index a36c347775..2877d22071 100644 --- a/src/type_icons.c +++ b/src/type_icons.c @@ -28,6 +28,7 @@ static bool32 ShouldFlipTypeIcon(bool32, u32, u32); static void SpriteCB_TypeIcon(struct Sprite*); static void DestroyTypeIcon(struct Sprite*); +static void FreeAllTypeIconResources(void); static bool32 ShouldHideTypeIcon(u32); static s32 GetTypeIconHideMovement(bool32, u32); static s32 GetTypeIconSlideMovement(bool32, u32, s32); @@ -429,22 +430,45 @@ static void SpriteCB_TypeIcon(struct Sprite* sprite) sprite->y = GetTypeIconBounceMovement(sprite->tVerticalPosition,position); } +static const u32 typeIconTags[] = +{ + TYPE_ICON_TAG, + TYPE_ICON_TAG_2 +}; + static void DestroyTypeIcon(struct Sprite* sprite) { - u32 i; + u32 spriteId, tag; + DestroySpriteAndFreeResources(sprite); - for (i = 0; i < MAX_SPRITES; ++i) + for (spriteId = 0; spriteId < MAX_SPRITES; ++spriteId) { - if (!gSprites[i].inUse) + if (!gSprites[spriteId].inUse) continue; - if (gSprites[i].template->paletteTag == TYPE_ICON_TAG) - return; + for (tag = 0; tag < 2; tag++) + { + if (gSprites[spriteId].template->paletteTag == typeIconTags[tag]) + return; + + if (gSprites[spriteId].template->tileTag == typeIconTags[tag]) + return; + } } - FreeSpritePaletteByTag(TYPE_ICON_TAG); - FreeSpritePaletteByTag(TYPE_ICON_TAG_2); + FreeAllTypeIconResources(); +} + +static void FreeAllTypeIconResources(void) +{ + u32 tag; + + for (tag = 0; tag < 2; tag++) + { + FreeSpriteTilesByTag(typeIconTags[tag]); + FreeSpritePaletteByTag(typeIconTags[tag]); + } } static bool32 ShouldHideTypeIcon(u32 battlerId) From 7119d60a6748c3f6a899d602f3eed7b239ee8753 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:31:26 +0200 Subject: [PATCH 21/64] Set new anim particles by default to off (#5161) --- include/config/battle.h | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/include/config/battle.h b/include/config/battle.h index d867a223d9..1cb4a4a6ce 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -251,22 +251,22 @@ #define B_TRY_CATCH_TRAINER_BALL GEN_LATEST // In Gen4+, trying to catch a Trainer's Pokémon does not consume the Poké Ball. // Animation Settings -#define B_NEW_SWORD_PARTICLE TRUE // If set to TRUE, it updates Swords Dance's particle. -#define B_NEW_LEECH_SEED_PARTICLE TRUE // If set to TRUE, it updates Leech Seed's animation particle. -#define B_NEW_HORN_ATTACK_PARTICLE TRUE // If set to TRUE, it updates Horn Attack's horn particle. -#define B_NEW_ROCKS_PARTICLE TRUE // If set to TRUE, it updates rock particles. -#define B_NEW_LEAF_PARTICLE TRUE // If set to TRUE, it updates leaf particle. -#define B_NEW_EMBER_PARTICLES TRUE // If set to TRUE, it updates Ember's fire particle. -#define B_NEW_MEAN_LOOK_PARTICLE TRUE // If set to TRUE, it updates Mean Look's eye particle. -#define B_NEW_TEETH_PARTICLE TRUE // If set to TRUE, it updates Bite/Crunch teeth particle. -#define B_NEW_HANDS_FEET_PARTICLE TRUE // If set to TRUE, it updates chop/kick/punch particles. -#define B_NEW_SPIKES_PARTICLE TRUE // If set to TRUE, it updates Spikes particle. -#define B_NEW_FLY_BUBBLE_PARTICLE TRUE // If set to TRUE, it updates Fly's 'bubble' particle. -#define B_NEW_CURSE_NAIL_PARTICLE TRUE // If set to TRUE, it updates Curse's nail. -#define B_NEW_BATON_PASS_BALL_PARTICLE TRUE // If set to TRUE, it updates Baton Pass' Poké Ball sprite. -#define B_NEW_MORNING_SUN_STAR_PARTICLE TRUE // If set to TRUE, it updates Morning Sun's star particles. -#define B_NEW_IMPACT_PALETTE TRUE // If set to TRUE, it updates the basic 'hit' palette. -#define B_NEW_SURF_PARTICLE_PALETTE TRUE // If set to TRUE, it updates Surf's wave palette. +#define B_NEW_SWORD_PARTICLE FALSE // If set to TRUE, it updates Swords Dance's particle. +#define B_NEW_LEECH_SEED_PARTICLE FALSE // If set to TRUE, it updates Leech Seed's animation particle. +#define B_NEW_HORN_ATTACK_PARTICLE FALSE // If set to TRUE, it updates Horn Attack's horn particle. +#define B_NEW_ROCKS_PARTICLE FALSE // If set to TRUE, it updates rock particles. +#define B_NEW_LEAF_PARTICLE FALSE // If set to TRUE, it updates leaf particle. +#define B_NEW_EMBER_PARTICLES FALSE // If set to TRUE, it updates Ember's fire particle. +#define B_NEW_MEAN_LOOK_PARTICLE FALSE // If set to TRUE, it updates Mean Look's eye particle. +#define B_NEW_TEETH_PARTICLE FALSE // If set to TRUE, it updates Bite/Crunch teeth particle. +#define B_NEW_HANDS_FEET_PARTICLE FALSE // If set to TRUE, it updates chop/kick/punch particles. +#define B_NEW_SPIKES_PARTICLE FALSE // If set to TRUE, it updates Spikes particle. +#define B_NEW_FLY_BUBBLE_PARTICLE FALSE // If set to TRUE, it updates Fly's 'bubble' particle. +#define B_NEW_CURSE_NAIL_PARTICLE FALSE // If set to TRUE, it updates Curse's nail. +#define B_NEW_BATON_PASS_BALL_PARTICLE FALSE // If set to TRUE, it updates Baton Pass' Poké Ball sprite. +#define B_NEW_MORNING_SUN_STAR_PARTICLE FALSE // If set to TRUE, it updates Morning Sun's star particles. +#define B_NEW_IMPACT_PALETTE FALSE // If set to TRUE, it updates the basic 'hit' palette. +#define B_NEW_SURF_PARTICLE_PALETTE FALSE // If set to TRUE, it updates Surf's wave palette. // Poké Ball animation and sounds #define B_ENEMY_THROW_BALLS GEN_LATEST // In GEN_6+, enemy Trainers throw Poké Balls into battle instead of them just appearing on the ground and opening. From c625ac6d534fd08e7fc30b4c0bad060b7d213211 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 14 Aug 2024 09:43:18 -0400 Subject: [PATCH 22/64] Added multiple missing ability TODO tests (#5163) --- test/battle/ability/adaptability.c | 46 ++++++++ test/battle/ability/aerilate.c | 33 ++++++ test/battle/ability/aftermath.c | 4 + test/battle/ability/air_lock.c | 4 + test/battle/ability/analytic.c | 11 ++ test/battle/ability/anger_point.c | 4 +- test/battle/ability/anger_shell.c | 2 +- test/battle/ability/anticipation.c | 24 ++++ test/battle/ability/arena_trap.c | 11 ++ test/battle/ability/aroma_veil.c | 15 +++ test/battle/ability/as_one.c | 7 ++ test/battle/ability/aura_break.c | 6 + test/battle/ability/chilling_neigh.c | 4 + test/battle/ability/chlorophyll.c | 6 + test/battle/ability/cloud_nine.c | 31 ++++- test/battle/ability/damp.c | 2 +- test/battle/ability/drought.c | 5 + test/battle/ability/dry_skin.c | 4 + test/battle/ability/flower_gift.c | 4 + test/battle/ability/forecast.c | 9 +- .../ability/{ate_abilities.c => galvanize.c} | 70 +++-------- test/battle/ability/grim_neigh.c | 109 ++++++++++++++++++ test/battle/ability/harvest.c | 1 + test/battle/ability/hydration.c | 2 + test/battle/ability/ice_body.c | 2 + test/battle/ability/ice_face.c | 9 ++ test/battle/ability/leaf_guard.c | 6 + test/battle/ability/moxie.c | 76 ++++++++---- test/battle/ability/normalize.c | 16 +++ test/battle/ability/orichalcum_pulse.c | 5 + test/battle/ability/pixilate.c | 35 ++++++ test/battle/ability/protosynthesis.c | 4 + test/battle/ability/rain_dish.c | 2 + test/battle/ability/refrigerate.c | 34 ++++++ test/battle/ability/sand_force.c | 6 + test/battle/ability/sand_rush.c | 6 + test/battle/ability/sand_veil.c | 3 + test/battle/ability/slush_rush.c | 6 + test/battle/ability/snow_cloak.c | 3 + test/battle/ability/solar_power.c | 7 ++ test/battle/ability/swift_swim.c | 6 + test/battle/ability/unnerve.c | 6 + test/battle/gimmick/terastal.c | 40 ------- .../{ability => hold_effect}/booster_energy.c | 0 test/battle/hold_effect/utility_umbrella.c | 2 + test/battle/move_effect/weather_ball.c | 2 + 46 files changed, 566 insertions(+), 124 deletions(-) create mode 100644 test/battle/ability/adaptability.c create mode 100644 test/battle/ability/aerilate.c create mode 100644 test/battle/ability/aftermath.c create mode 100644 test/battle/ability/air_lock.c create mode 100644 test/battle/ability/analytic.c create mode 100644 test/battle/ability/anticipation.c create mode 100644 test/battle/ability/arena_trap.c create mode 100644 test/battle/ability/aroma_veil.c create mode 100644 test/battle/ability/as_one.c create mode 100644 test/battle/ability/aura_break.c create mode 100644 test/battle/ability/chilling_neigh.c create mode 100644 test/battle/ability/chlorophyll.c create mode 100644 test/battle/ability/drought.c rename test/battle/ability/{ate_abilities.c => galvanize.c} (50%) create mode 100644 test/battle/ability/grim_neigh.c create mode 100644 test/battle/ability/ice_face.c create mode 100644 test/battle/ability/normalize.c create mode 100644 test/battle/ability/orichalcum_pulse.c create mode 100644 test/battle/ability/pixilate.c create mode 100644 test/battle/ability/refrigerate.c create mode 100644 test/battle/ability/sand_force.c create mode 100644 test/battle/ability/sand_rush.c create mode 100644 test/battle/ability/slush_rush.c create mode 100644 test/battle/ability/solar_power.c create mode 100644 test/battle/ability/swift_swim.c create mode 100644 test/battle/ability/unnerve.c rename test/battle/{ability => hold_effect}/booster_energy.c (100%) diff --git a/test/battle/ability/adaptability.c b/test/battle/ability/adaptability.c new file mode 100644 index 0000000000..fecdc6b7e2 --- /dev/null +++ b/test/battle/ability/adaptability.c @@ -0,0 +1,46 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Adaptability increases same-type attack bonus from x1.5 to x2"); + +SINGLE_BATTLE_TEST("(TERA) Terastallizing into a different type with Adaptability gives 2.0x STAB", s16 damage) +{ + bool32 tera; + PARAMETRIZE { tera = GIMMICK_NONE; } + PARAMETRIZE { tera = GIMMICK_TERA; } + GIVEN { + PLAYER(SPECIES_CRAWDAUNT) { Ability(ABILITY_ADAPTABILITY); TeraType(TYPE_NORMAL); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_HEADBUTT, gimmick: tera); } + } SCENE { + MESSAGE("Crawdaunt used Headbutt!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_HEADBUTT, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + // The jump from no STAB to 2.0x STAB is a 2.0x boost. + EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage); + } +} + +SINGLE_BATTLE_TEST("(TERA) Terastallizing into the same type with Adaptability gives 2.25x STAB", s16 damage) +{ + bool32 tera; + PARAMETRIZE { tera = GIMMICK_NONE; } + PARAMETRIZE { tera = GIMMICK_TERA; } + GIVEN { + PLAYER(SPECIES_CRAWDAUNT) { Ability(ABILITY_ADAPTABILITY); TeraType(TYPE_WATER); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_WATER_PULSE, gimmick: tera); } + } SCENE { + MESSAGE("Crawdaunt used Water Pulse!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_PULSE, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + // The jump from 2x STAB to 2.25x STAB is a 1.125x boost. + EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.125), results[1].damage); + } +} + +TO_DO_BATTLE_TEST("Adaptability does not affect Stellar-type moves"); diff --git a/test/battle/ability/aerilate.c b/test/battle/ability/aerilate.c new file mode 100644 index 0000000000..8a5f889a66 --- /dev/null +++ b/test/battle/ability/aerilate.c @@ -0,0 +1,33 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); +} + +SINGLE_BATTLE_TEST("Aerilate turns a Normal-type move into Flying-type move") +{ + GIVEN { + PLAYER(SPECIES_MEGANIUM); + OPPONENT(SPECIES_SALAMENCE) { Item(ITEM_SALAMENCITE); } + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE, gimmick: GIMMICK_MEGA); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + MESSAGE("It's super effective!"); + } +} + +TO_DO_BATTLE_TEST("Aerilate can not turn certain moves into Flying type moves"); +TO_DO_BATTLE_TEST("Aerilate boosts power of affected moves by 20% (Gen7+)"); +TO_DO_BATTLE_TEST("Aerilate boosts power of affected moves by 30% (Gen6)"); + +// Gen 6-7 +TO_DO_BATTLE_TEST("Aerilate overrides Electrify (Gen6-7)"); +TO_DO_BATTLE_TEST("Aerilate overrides Ion Deluge (Gen6-7)"); +// Gen 8+ +//TO_DO_BATTLE_TEST("Aerilate doesn't override Electrify (Gen8+)"); // No mon with Aerilate exists in Gen8+, but probably behaves similar to Pixilate, which does. +//TO_DO_BATTLE_TEST("Aerilate doesn't override Ion Deluge (Gen8+)"); // Ion Deluge doesn't exist in Gen 8+, but we probably could assume it behaves similar to under Electrify. TODO: Test by hacking SV. diff --git a/test/battle/ability/aftermath.c b/test/battle/ability/aftermath.c new file mode 100644 index 0000000000..65c0be7dfd --- /dev/null +++ b/test/battle/ability/aftermath.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Aftermath damages the attacker by 1/4th of its max HP if they faint the target has this ability by a contact move"); diff --git a/test/battle/ability/air_lock.c b/test/battle/ability/air_lock.c new file mode 100644 index 0000000000..0201e86a20 --- /dev/null +++ b/test/battle/ability/air_lock.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +// Tests for Air Lock are handled in test/battle/ability/cloud_nine.c diff --git a/test/battle/ability/analytic.c b/test/battle/ability/analytic.c new file mode 100644 index 0000000000..44c42ae2d5 --- /dev/null +++ b/test/battle/ability/analytic.c @@ -0,0 +1,11 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Analytic increases the power of moves by 30% if it's the last one that uses its move"); +TO_DO_BATTLE_TEST("Analytic takes into account modifications to speeed an priority (Gen 5-8)"); //Eg. Paralysis, Power Weight, Stall +TO_DO_BATTLE_TEST("Analytic does not take into account modifications to speeed an priority (Gen 8)"); //Eg. Paralysis, Power Weight, Stall +TO_DO_BATTLE_TEST("Analytic takes into account the turn order of what fainted Pokémon would've moved"); + +// Triple Battles needed to test +//TO_DO_BATTLE_TEST("If the Pokémon with Analytic is targeting a Pokémon in a flank position that chooses to switch with its ally in the middle, its move's power will always be normal when it attacks the Pokémon that is shifted into the flank position"); +//TO_DO_BATTLE_TEST("If the Pokémon with Analytic targets a Pokémon in the middle whose ally on a flank chooses to shift into the middle position, its move's power still depends on whether the Pokémon that was in the middle (and is now on a flank) has acted when the Pokémon with Analytic uses its move"); diff --git a/test/battle/ability/anger_point.c b/test/battle/ability/anger_point.c index 0b13b9df4b..7cb283426a 100644 --- a/test/battle/ability/anger_point.c +++ b/test/battle/ability/anger_point.c @@ -47,7 +47,9 @@ SINGLE_BATTLE_TEST("Anger Point does not trigger when already at maximum Attack } } -SINGLE_BATTLE_TEST("Anger Point does not trigger when a substitute takes the hit") +TO_DO_BATTLE_TEST("Anger Point triggers when a substitute takes the hit (Gen4)"); + +SINGLE_BATTLE_TEST("Anger Point does not trigger when a substitute takes the hit (Gen5+)") { ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit); ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE); diff --git a/test/battle/ability/anger_shell.c b/test/battle/ability/anger_shell.c index f0d11d7576..c5b490216b 100644 --- a/test/battle/ability/anger_shell.c +++ b/test/battle/ability/anger_shell.c @@ -1,7 +1,7 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Anger Shell activates only if the target had more than 50% of its hp") +SINGLE_BATTLE_TEST("Anger Shell activates only if the target had more than 50% of its HP") { bool32 activates = FALSE; u16 maxHp = 500, hp = 0; diff --git a/test/battle/ability/anticipation.c b/test/battle/ability/anticipation.c new file mode 100644 index 0000000000..a15ff153d9 --- /dev/null +++ b/test/battle/ability/anticipation.c @@ -0,0 +1,24 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Anticipation causes notifies if an opponent has a super-effective move"); +TO_DO_BATTLE_TEST("Anticipation causes notifies if an opponent has a One-hit KO move"); +TO_DO_BATTLE_TEST("Anticipation causes notifies if an opponent has a Self-Destruct or Explosion (Gen4)"); +TO_DO_BATTLE_TEST("Anticipation treats Self-Destruct and Explosion like all other Normal types (Gen5+)"); + +TO_DO_BATTLE_TEST("Anticipation considers Scrappy and Normalize into their effectiveness (Gen4)"); +TO_DO_BATTLE_TEST("Anticipation doesn't consider Scrappy and Normalize into their effectiveness (Gen5+)"); +TO_DO_BATTLE_TEST("Anticipation considers Gravity into their effectiveness (Gen4)"); +TO_DO_BATTLE_TEST("Anticipation doesn't consider Gravity into their effectiveness (Gen5+)"); +TO_DO_BATTLE_TEST("Anticipation doesn't trigger from Counter, Metal Burst or Mirror Coat (Gen4)"); +TO_DO_BATTLE_TEST("Anticipation counts Counter, Metal Burst or Mirror Coat as attacking moves of their types (Gen5+)"); +TO_DO_BATTLE_TEST("Anticipation considers Synchronoise as an ordinary Psychic-type move"); +TO_DO_BATTLE_TEST("Anticipation considers Freeze-Dry as an ordinary Ice-type move"); +TO_DO_BATTLE_TEST("Anticipation considers Flying Press as an ordinary Fighting-type move"); +TO_DO_BATTLE_TEST("Anticipation considers Aura Wheel as an ordinary Electric-type move"); +TO_DO_BATTLE_TEST("Anticipation considers Inverse Battle types"); //Check with Normal-type moves +TO_DO_BATTLE_TEST("Anticipation treats dynamic move types as their base type (Normal)"); // Judgment, Weather Ball, Natural Gift, Techno Blast, Revelation Dance, Multi Attack +TO_DO_BATTLE_TEST("Anticipation treats Hidden Power as Normal Type (Gen4-5)"); +TO_DO_BATTLE_TEST("Anticipation treats Hidden Power as its dynamic type (Gen6+)"); +TO_DO_BATTLE_TEST("Anticipation does not consider Strong Winds on type matchups"); +TO_DO_BATTLE_TEST("Anticipation does not consider ate-abilities"); diff --git a/test/battle/ability/arena_trap.c b/test/battle/ability/arena_trap.c new file mode 100644 index 0000000000..ef0d5b7d8c --- /dev/null +++ b/test/battle/ability/arena_trap.c @@ -0,0 +1,11 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Arena Trap prevents grounded adjacent opponents from switching out"); +TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs if the Pokémon is switched in the same turn the opponent decided to switch out"); +TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs via moves that switch out"); // Baton Pass, U-Turn, Volt Switch, Flip Turn, Parting Shot +TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs via Shed Shell, but not via Teleport"); +TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs via Run Away"); +TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs via Smoke Ball"); +TO_DO_BATTLE_TEST("Arena Trap prevents switch outs from Ghost-type Pokémon (Gen3-5)"); +TO_DO_BATTLE_TEST("Arena Trap doesn't prevent switch outs from Ghost-type Pokémon (Gen6+)"); diff --git a/test/battle/ability/aroma_veil.c b/test/battle/ability/aroma_veil.c new file mode 100644 index 0000000000..dc53fa1492 --- /dev/null +++ b/test/battle/ability/aroma_veil.c @@ -0,0 +1,15 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Taunt"); +TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Torment"); +TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Encore"); +TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Disable"); +TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Cursed Body"); +TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Heal Block"); +TO_DO_BATTLE_TEST("Aroma Veil protects the Pokémon's side from Infatuation"); +TO_DO_BATTLE_TEST("Aroma Veil does not protect the Pokémon's side from Imprison"); + +// Marked in Bulbapedia as need of research +//TO_DO_BATTLE_TEST("Aroma Veil prevents G-Max Meltdown's effect"); +//TO_DO_BATTLE_TEST("Aroma Veil prevents Psychic Noise's effect"); diff --git a/test/battle/ability/as_one.c b/test/battle/ability/as_one.c new file mode 100644 index 0000000000..0d5367bf37 --- /dev/null +++ b/test/battle/ability/as_one.c @@ -0,0 +1,7 @@ +#include "global.h" +#include "test/battle.h" + +// Tests for the individual ability effects are handled in the following times: +// - Unnerve: test/battle/ability/unnerve.c +// - Chilling Neigh: test/battle/ability/chilling_neigh.c +// - Grim Neigh: test/battle/ability/grim_neigh.c diff --git a/test/battle/ability/aura_break.c b/test/battle/ability/aura_break.c new file mode 100644 index 0000000000..93b21421e4 --- /dev/null +++ b/test/battle/ability/aura_break.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Aura Break inverts Fairy Aura's effect"); +TO_DO_BATTLE_TEST("Aura Break inverts Dark Aura's effect"); +TO_DO_BATTLE_TEST("Aura Break ignores Mold Breaker abilities"); diff --git a/test/battle/ability/chilling_neigh.c b/test/battle/ability/chilling_neigh.c new file mode 100644 index 0000000000..03be77000b --- /dev/null +++ b/test/battle/ability/chilling_neigh.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +// Tests for Chilling Neigh are handled in test/battle/ability/moxie.c diff --git a/test/battle/ability/chlorophyll.c b/test/battle/ability/chlorophyll.c new file mode 100644 index 0000000000..493a197638 --- /dev/null +++ b/test/battle/ability/chlorophyll.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Chlorophyll doubles speed if it's sunny"); +TO_DO_BATTLE_TEST("Chlorophyll doesn't double speed if Cloud Nine/Air Lock is on the field"); +TO_DO_BATTLE_TEST("Chlorophyll doesn't double speed if they have an Utility Umbrella"); diff --git a/test/battle/ability/cloud_nine.c b/test/battle/ability/cloud_nine.c index dfe5611fc4..887769a5ec 100644 --- a/test/battle/ability/cloud_nine.c +++ b/test/battle/ability/cloud_nine.c @@ -1,16 +1,41 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Cloud Nine prevents weather effects") +SINGLE_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Sandstorm") { + u32 species = 0, ability = 0; + PARAMETRIZE { species = SPECIES_PSYDUCK; ability = ABILITY_CLOUD_NINE; } + PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; } GIVEN { ASSUME(gMovesInfo[MOVE_SANDSTORM].effect == EFFECT_SANDSTORM); - PLAYER(SPECIES_PSYDUCK) { Ability(ABILITY_CLOUD_NINE); } + PLAYER(species) { Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { TURN { MOVE(opponent, MOVE_SANDSTORM); } TURN {} } SCENE { - NONE_OF { HP_BAR(player); } + ABILITY_POPUP(player, ability); + MESSAGE("The effects of weather disappeared."); + MESSAGE("Foe Wobbuffet used Sandstorm!"); + MESSAGE("The sandstorm rages."); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SANDSTORM_CONTINUES); + NONE_OF { + HP_BAR(player); + HP_BAR(opponent); + MESSAGE("Foe Wobbuffet is buffeted by the sandstorm!"); + } + MESSAGE("The sandstorm rages."); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SANDSTORM_CONTINUES); } } + +TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Sun"); +TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Rain"); +TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Hail"); +TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Snow"); +TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Fog"); +TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Primal Sun"); +TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Primal Rain"); +TO_DO_BATTLE_TEST("Cloud Nine/Air Lock prevent basic weather effects, but without them disappearing - Strong Winds"); + +// Moves and abilities that are affected by weather should have new tests that check for Clould Nine/Air Lock, like Mold-Breaker Abilities diff --git a/test/battle/ability/damp.c b/test/battle/ability/damp.c index 9a3b795f2a..b567293aa0 100644 --- a/test/battle/ability/damp.c +++ b/test/battle/ability/damp.c @@ -57,7 +57,7 @@ SINGLE_BATTLE_TEST("Damp prevents explosion-like moves from self") } } -SINGLE_BATTLE_TEST("Damp prevents damage from aftermath") +SINGLE_BATTLE_TEST("Damp prevents damage from Aftermath") { GIVEN { ASSUME(gMovesInfo[MOVE_TACKLE].makesContact); diff --git a/test/battle/ability/drought.c b/test/battle/ability/drought.c new file mode 100644 index 0000000000..bbe4dbe853 --- /dev/null +++ b/test/battle/ability/drought.c @@ -0,0 +1,5 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Drought sets up sun for 5 turns (Gen6+)"); +TO_DO_BATTLE_TEST("Drought sets up permanent sun (Gen3-5)"); diff --git a/test/battle/ability/dry_skin.c b/test/battle/ability/dry_skin.c index 368e4b8047..5709a58a94 100644 --- a/test/battle/ability/dry_skin.c +++ b/test/battle/ability/dry_skin.c @@ -15,6 +15,8 @@ SINGLE_BATTLE_TEST("Dry Skin causes 1/8th Max HP damage in Sun") } } +TO_DO_BATTLE_TEST("Dry Skin doesn't get damaged in Sun if Cloud Nine/Air Lock is on the field"); + SINGLE_BATTLE_TEST("Dry Skin heals 1/8th Max HP in Rain") { GIVEN { @@ -29,6 +31,8 @@ SINGLE_BATTLE_TEST("Dry Skin heals 1/8th Max HP in Rain") } } +TO_DO_BATTLE_TEST("Dry Skin doesn't heal in Rain if Cloud Nine/Air Lock is on the field"); + SINGLE_BATTLE_TEST("Dry Skin increases damage taken from Fire-type moves by 25%", s16 damage) { u32 ability; diff --git a/test/battle/ability/flower_gift.c b/test/battle/ability/flower_gift.c index 69a76b8e81..68712641e0 100644 --- a/test/battle/ability/flower_gift.c +++ b/test/battle/ability/flower_gift.c @@ -17,6 +17,8 @@ SINGLE_BATTLE_TEST("Flower Gift transforms Cherrim in harsh sunlight") } } +TO_DO_BATTLE_TEST("Flower Gift doesn't transform Cherrim if Cloud Nine/Air Lock is on the field"); + SINGLE_BATTLE_TEST("Flower Gift transforms Cherrim back to normal when weather changes") { GIVEN { @@ -61,6 +63,8 @@ SINGLE_BATTLE_TEST("Flower Gift transforms Cherrim back to normal when its abili } } +TO_DO_BATTLE_TEST("Forecast transforms Castform back to normal under Cloud Nine/Air Lock"); + DOUBLE_BATTLE_TEST("Flower Gift increases the attack of Cherrim and its allies by 1.5x", s16 damageL, s16 damageR) { bool32 sunny; diff --git a/test/battle/ability/forecast.c b/test/battle/ability/forecast.c index 427a8e6807..296c123dbd 100644 --- a/test/battle/ability/forecast.c +++ b/test/battle/ability/forecast.c @@ -264,12 +264,15 @@ SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal when Sandstorm i } } -SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal under Air Lock") +SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal under Cloud Nine/Air Lock") { + u32 species = 0, ability = 0; + PARAMETRIZE { species = SPECIES_PSYDUCK; ability = ABILITY_CLOUD_NINE; } + PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; } GIVEN { PLAYER(SPECIES_CASTFORM_NORMAL) { Ability(ABILITY_FORECAST); } OPPONENT(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_RAYQUAZA); + OPPONENT(species) { Ability(ability); } } WHEN { TURN { MOVE(player, MOVE_RAIN_DANCE); } TURN { SWITCH(opponent, 1); } @@ -279,7 +282,7 @@ SINGLE_BATTLE_TEST("Forecast transforms Castform back to normal under Air Lock") ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); MESSAGE("Castform transformed!"); // back to normal - ABILITY_POPUP(opponent, ABILITY_AIR_LOCK); + ABILITY_POPUP(opponent, ability); ABILITY_POPUP(player, ABILITY_FORECAST); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FORM_CHANGE, player); MESSAGE("Castform transformed!"); diff --git a/test/battle/ability/ate_abilities.c b/test/battle/ability/galvanize.c similarity index 50% rename from test/battle/ability/ate_abilities.c rename to test/battle/ability/galvanize.c index 203452cc01..55dfd7287a 100644 --- a/test/battle/ability/ate_abilities.c +++ b/test/battle/ability/galvanize.c @@ -7,6 +7,19 @@ ASSUMPTIONS ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); } +SINGLE_BATTLE_TEST("Galvanize turns a normal type move into Electric") +{ + GIVEN { + PLAYER(SPECIES_KRABBY); + OPPONENT(SPECIES_GEODUDE_ALOLAN) { Ability(ABILITY_GALVANIZE); } + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + MESSAGE("It's super effective!"); + } +} + SINGLE_BATTLE_TEST("Galvanize can not turn certain moves into Electric type moves") { u32 move; @@ -29,56 +42,7 @@ SINGLE_BATTLE_TEST("Galvanize can not turn certain moves into Electric type move } } -SINGLE_BATTLE_TEST("Galvanize turns a normal type move into Electric") -{ - GIVEN { - PLAYER(SPECIES_KRABBY); - OPPONENT(SPECIES_GEODUDE_ALOLAN) { Ability(ABILITY_GALVANIZE); } - } WHEN { - TURN { MOVE(opponent, MOVE_TACKLE); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); - MESSAGE("It's super effective!"); - } -} - -SINGLE_BATTLE_TEST("Pixilate turns a normal type move into Fairy") -{ - GIVEN { - PLAYER(SPECIES_DRAGONITE); - OPPONENT(SPECIES_ALTARIA) { Item(ITEM_ALTARIANITE); } - } WHEN { - TURN { MOVE(opponent, MOVE_TACKLE, gimmick: GIMMICK_MEGA); } - } SCENE { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); - MESSAGE("It's super effective!"); - } -} - -SINGLE_BATTLE_TEST("Refrigerate turns a normal type move into Ice") -{ - GIVEN { - PLAYER(SPECIES_MEGANIUM); - OPPONENT(SPECIES_AMAURA) { Ability(ABILITY_REFRIGERATE); } - } WHEN { - TURN { MOVE(opponent, MOVE_TACKLE); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); - MESSAGE("It's super effective!"); - } -} - -SINGLE_BATTLE_TEST("Aerilate turns a normal type move into Flying") -{ - GIVEN { - PLAYER(SPECIES_MEGANIUM); - OPPONENT(SPECIES_SALAMENCE) { Item(ITEM_SALAMENCITE); } - } WHEN { - TURN { MOVE(opponent, MOVE_TACKLE, gimmick: GIMMICK_MEGA); } - } SCENE { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); - MESSAGE("It's super effective!"); - } -} +TO_DO_BATTLE_TEST("Galvanize boosts power of affected moves by 20% (Gen7+)"); +TO_DO_BATTLE_TEST("Galvanize boosts power of affected moves by 30% (Gen6)"); +TO_DO_BATTLE_TEST("(DYNAMAX) Galvanize turns Max Strike into Max Lightning when not used by Gigantamax Pikachu/Toxtricity"); +//TO_DO_BATTLE_TEST("(DYNAMAX) Galvanize doesn't turn Max Strike into Max Lightning when used by Gigantamax Pikachu/Toxtricity, instead becoming G-Max Volt Crash/Stun Shock"); // Marked in Bulbapedia as "needs research", so this assumes that it behaves like Pixilate. diff --git a/test/battle/ability/grim_neigh.c b/test/battle/ability/grim_neigh.c new file mode 100644 index 0000000000..b4d82487d8 --- /dev/null +++ b/test/battle/ability/grim_neigh.c @@ -0,0 +1,109 @@ +#include "global.h" +#include "test/battle.h" + +DOUBLE_BATTLE_TEST("Grim Neigh raises Sp. Attack by one stage after directly causing a Pokemon to faint") +{ + u32 species = 0, ability = 0, abilityPopUp = 0; + PARAMETRIZE { species = SPECIES_SPECTRIER; ability = ABILITY_GRIM_NEIGH; abilityPopUp = ABILITY_GRIM_NEIGH; } + PARAMETRIZE { species = SPECIES_CALYREX_SHADOW_RIDER; ability = ABILITY_AS_ONE_SHADOW_RIDER; abilityPopUp = ABILITY_GRIM_NEIGH; } + GIVEN { + ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY); + PLAYER(species) { Ability(ability); } + PLAYER(SPECIES_SNORUNT) { HP(1); } + OPPONENT(SPECIES_GLALIE) { HP(1); } + OPPONENT(SPECIES_ABRA) { HP(1); } + OPPONENT(SPECIES_ABRA); + } WHEN { + TURN { MOVE(playerLeft, MOVE_DISCHARGE); SEND_OUT(opponentLeft, 2); } + } SCENE { + int i; + + ANIMATION(ANIM_TYPE_MOVE, MOVE_DISCHARGE, playerLeft); + for (i = 0; i < 3; i++) { + ONE_OF { + MESSAGE("Snorunt fainted!"); + MESSAGE("Foe Glalie fainted!"); + MESSAGE("Foe Abra fainted!"); + } + ABILITY_POPUP(playerLeft, abilityPopUp); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + if (species == SPECIES_SPECTRIER) + MESSAGE("Spectrier's Grim Neigh raised its Sp. Atk!"); + else + MESSAGE("Calyrex's Grim Neigh raised its Sp. Atk!"); + } + } THEN { + EXPECT_EQ(playerLeft->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 3); + } +} + +DOUBLE_BATTLE_TEST("Grim Neigh does not trigger if Pokemon faint to indirect damage or damage from other Pokemon") +{ + u32 species = 0, ability = 0, abilityPopUp = 0; + PARAMETRIZE { species = SPECIES_SPECTRIER; ability = ABILITY_GRIM_NEIGH; abilityPopUp = ABILITY_GRIM_NEIGH; } + PARAMETRIZE { species = SPECIES_CALYREX_SHADOW_RIDER; ability = ABILITY_AS_ONE_SHADOW_RIDER; abilityPopUp = ABILITY_GRIM_NEIGH; } + GIVEN { + PLAYER(species) { Ability(ability); } + PLAYER(SPECIES_SNORUNT) { HP(1); Status1(STATUS1_POISON); } + OPPONENT(SPECIES_GLALIE) { HP(1); Status1(STATUS1_BURN); } + OPPONENT(SPECIES_ABRA) { HP(1); } + OPPONENT(SPECIES_ABRA); + } WHEN { + TURN { MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentRight); SEND_OUT(opponentLeft, 2); } + } SCENE { + int i; + + ANIMATION(ANIM_TYPE_MOVE, MOVE_QUICK_ATTACK, playerRight); + for (i = 0; i < 3; i++) { + ONE_OF { + MESSAGE("Snorunt fainted!"); + MESSAGE("Foe Glalie fainted!"); + MESSAGE("Foe Abra fainted!"); + } + NONE_OF { + ABILITY_POPUP(playerLeft, abilityPopUp); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + MESSAGE("Salamence's Moxie raised its Sp. Atk!"); + MESSAGE("Spectrier's Grim Neigh raised its Sp. Atk!"); + MESSAGE("Calyrex's Grim Neigh raised its Sp. Atk!"); + } + } + } THEN { + EXPECT_EQ(playerLeft->statStages[STAT_SPATK], DEFAULT_STAT_STAGE); + } +} + +DOUBLE_BATTLE_TEST("Grim Neigh does not increase damage done by the same move that causes another Pokemon to faint") +{ + s16 damage[2]; + u32 species = 0, ability = 0, abilityPopUp = 0; + PARAMETRIZE { species = SPECIES_SPECTRIER; ability = ABILITY_GRIM_NEIGH; abilityPopUp = ABILITY_GRIM_NEIGH; } + PARAMETRIZE { species = SPECIES_CALYREX_SHADOW_RIDER; ability = ABILITY_AS_ONE_SHADOW_RIDER; abilityPopUp = ABILITY_GRIM_NEIGH; } + + KNOWN_FAILING; // Requires simultaneous damage implementation + GIVEN { + ASSUME(gMovesInfo[MOVE_DISCHARGE].target == MOVE_TARGET_FOES_AND_ALLY); + PLAYER(species) { Ability(ability); } + PLAYER(SPECIES_ABRA) { HP(1); } + OPPONENT(SPECIES_GLALIE); + OPPONENT(SPECIES_GLALIE); + OPPONENT(SPECIES_ABRA); + } WHEN { + TURN { MOVE(playerLeft, MOVE_DISCHARGE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DISCHARGE, playerLeft); + HP_BAR(opponentLeft, captureDamage: &damage[0]); + HP_BAR(playerRight); + MESSAGE("Abra fainted!"); + ABILITY_POPUP(playerLeft, abilityPopUp); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + if (species == SPECIES_SPECTRIER) + MESSAGE("Spectrier's Grim Neigh raised its Sp. Atk!"); + else + MESSAGE("Calyrex's Grim Neigh raised its Sp. Atk!"); + HP_BAR(opponentRight, captureDamage: &damage[1]); + } THEN { + EXPECT_EQ(playerLeft->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1); + EXPECT_EQ(damage[0], damage[1]); + } +} diff --git a/test/battle/ability/harvest.c b/test/battle/ability/harvest.c index 9fb969b036..b4783c4542 100644 --- a/test/battle/ability/harvest.c +++ b/test/battle/ability/harvest.c @@ -3,6 +3,7 @@ TO_DO_BATTLE_TEST("Harvest has a 50% chance to restore a Berry at the end of the turn"); TO_DO_BATTLE_TEST("Harvest always restores a Berry in Sunlight"); +TO_DO_BATTLE_TEST("Harvest doesn't always restore a Berry if Cloud Nine/Air Lock is on the field"); TO_DO_BATTLE_TEST("Harvest restores a Berry even after being switched out and back in"); TO_DO_BATTLE_TEST("Harvest restores a Berry consumed by Fling"); TO_DO_BATTLE_TEST("Harvest restores a Berry consumed by Natural Gift"); diff --git a/test/battle/ability/hydration.c b/test/battle/ability/hydration.c index 2dca490c02..7d16ad04ae 100644 --- a/test/battle/ability/hydration.c +++ b/test/battle/ability/hydration.c @@ -14,3 +14,5 @@ SINGLE_BATTLE_TEST("Hydration cures non-volatile Status conditions if it is rain STATUS_ICON(player, none: TRUE); } } + +TO_DO_BATTLE_TEST("Hydration doesn't cure status conditions if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/ice_body.c b/test/battle/ability/ice_body.c index 1aa7c80a4d..304059a00e 100644 --- a/test/battle/ability/ice_body.c +++ b/test/battle/ability/ice_body.c @@ -26,3 +26,5 @@ SINGLE_BATTLE_TEST("Ice Body recovers 1/16th of Max HP in hail.") MESSAGE("Glalie's Ice Body healed it a little bit!"); } } + +TO_DO_BATTLE_TEST("Sand Rush doesn't recover HP if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/ice_face.c b/test/battle/ability/ice_face.c new file mode 100644 index 0000000000..53917b5623 --- /dev/null +++ b/test/battle/ability/ice_face.c @@ -0,0 +1,9 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Ice Face blocks physical moves, changing Eiscue into its Noice Face form"); // Include Special move in test +TO_DO_BATTLE_TEST("Ice Face is restored if hail or snow begins while Noice Face Eiscue is out"); +TO_DO_BATTLE_TEST("Ice Face is restored if Noice Face Eiscue is sent in while hail or snow is active"); +TO_DO_BATTLE_TEST("Ice Face is not restored if Eiscue changes into Noice Face form while there's already hail"); +TO_DO_BATTLE_TEST("Ice Face form change persists after switching out"); +TO_DO_BATTLE_TEST("Ice Face doesn't transform Eiscue if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/leaf_guard.c b/test/battle/ability/leaf_guard.c index 6c559ea48a..2c55236def 100644 --- a/test/battle/ability/leaf_guard.c +++ b/test/battle/ability/leaf_guard.c @@ -27,6 +27,8 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents non-volatile status conditions in sun") } } +TO_DO_BATTLE_TEST("Leaf Guard doesn't prevent non-volatile status conditions if Cloud Nine/Air Lock is on the field"); + SINGLE_BATTLE_TEST("Leaf Guard prevents status conditions from Flame Orb and Toxic Orb") { u32 item; @@ -49,6 +51,8 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents status conditions from Flame Orb and Tox } } +TO_DO_BATTLE_TEST("Leaf Guard doesn't prevent status conditions from Flame Orb and Toxic Orb if Cloud Nine/Air Lock is on the field"); + SINGLE_BATTLE_TEST("Leaf Guard prevents Rest during sun") { GIVEN { @@ -66,3 +70,5 @@ SINGLE_BATTLE_TEST("Leaf Guard prevents Rest during sun") } } } + +TO_DO_BATTLE_TEST("Leaf Guard doesn't prevent Rest if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/moxie.c b/test/battle/ability/moxie.c index b60a11507a..79b1fc989f 100644 --- a/test/battle/ability/moxie.c +++ b/test/battle/ability/moxie.c @@ -1,12 +1,15 @@ #include "global.h" #include "test/battle.h" -DOUBLE_BATTLE_TEST("Moxie raises Attack by one stage after directly causing a Pokemon to faint") +DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh raises Attack by one stage after directly causing a Pokemon to faint") { - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); - + u32 species = 0, ability = 0, abilityPopUp = 0; + PARAMETRIZE { species = SPECIES_SALAMENCE; ability = ABILITY_MOXIE; abilityPopUp = ABILITY_MOXIE; } + PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; } + PARAMETRIZE { species = SPECIES_CALYREX_ICE_RIDER; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; } GIVEN { - PLAYER(SPECIES_SALAMENCE) { Ability(ABILITY_MOXIE); } + ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); + PLAYER(species) { Ability(ability); } PLAYER(SPECIES_SNORUNT) { HP(1); } OPPONENT(SPECIES_GLALIE) { HP(1); } OPPONENT(SPECIES_ABRA) { HP(1); } @@ -23,19 +26,28 @@ DOUBLE_BATTLE_TEST("Moxie raises Attack by one stage after directly causing a Po MESSAGE("Foe Glalie fainted!"); MESSAGE("Foe Abra fainted!"); } - ABILITY_POPUP(playerLeft, ABILITY_MOXIE); + ABILITY_POPUP(playerLeft, abilityPopUp); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); - MESSAGE("Salamence's Moxie raised its Attack!"); + if (species == SPECIES_SALAMENCE) + MESSAGE("Salamence's Moxie raised its Attack!"); + else if (species == SPECIES_GLASTRIER) + MESSAGE("Glastrier's Chilling Neigh raised its Attack!"); + else + MESSAGE("Calyrex's Chilling Neigh raised its Attack!"); } } THEN { EXPECT_EQ(playerLeft->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 3); } } -DOUBLE_BATTLE_TEST("Moxie does not trigger if Pokemon faint to indirect damage or damage from other Pokemon") +DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh does not trigger if Pokemon faint to indirect damage or damage from other Pokemon") { + u32 species = 0, ability = 0, abilityPopUp = 0; + PARAMETRIZE { species = SPECIES_SALAMENCE; ability = ABILITY_MOXIE; abilityPopUp = ABILITY_MOXIE; } + PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; } + PARAMETRIZE { species = SPECIES_CALYREX_ICE_RIDER; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; } GIVEN { - PLAYER(SPECIES_SALAMENCE) { Ability(ABILITY_MOXIE); } + PLAYER(species) { Ability(ability); } PLAYER(SPECIES_SNORUNT) { HP(1); Status1(STATUS1_POISON); } OPPONENT(SPECIES_GLALIE) { HP(1); Status1(STATUS1_BURN); } OPPONENT(SPECIES_ABRA) { HP(1); } @@ -53,9 +65,11 @@ DOUBLE_BATTLE_TEST("Moxie does not trigger if Pokemon faint to indirect damage o MESSAGE("Foe Abra fainted!"); } NONE_OF { - ABILITY_POPUP(playerLeft, ABILITY_MOXIE); + ABILITY_POPUP(playerLeft, abilityPopUp); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); MESSAGE("Salamence's Moxie raised its Attack!"); + MESSAGE("Glastrier's Chilling Neigh raised its Attack!"); + MESSAGE("Calyrex's Chilling Neigh raised its Attack!"); } } } THEN { @@ -63,12 +77,15 @@ DOUBLE_BATTLE_TEST("Moxie does not trigger if Pokemon faint to indirect damage o } } -SINGLE_BATTLE_TEST("Moxie does not trigger when already at maximum Attack stage") +SINGLE_BATTLE_TEST("Moxie/Chilling Neigh does not trigger when already at maximum Attack stage") { - ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM); - + u32 species = 0, ability = 0, abilityPopUp = 0; + PARAMETRIZE { species = SPECIES_SALAMENCE; ability = ABILITY_MOXIE; abilityPopUp = ABILITY_MOXIE; } + PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; } + PARAMETRIZE { species = SPECIES_CALYREX_ICE_RIDER; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; } GIVEN { - PLAYER(SPECIES_SALAMENCE) { Ability(ABILITY_MOXIE); } + ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM); + PLAYER(species) { Ability(ability); } OPPONENT(SPECIES_SNORUNT) { HP(1); } OPPONENT(SPECIES_SNORUNT); } WHEN { @@ -77,28 +94,38 @@ SINGLE_BATTLE_TEST("Moxie does not trigger when already at maximum Attack stage" } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_BELLY_DRUM, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Salamence cut its own HP and maximized ATTACK!"); + if (species == SPECIES_SALAMENCE) + MESSAGE("Salamence cut its own HP and maximized ATTACK!"); + else if (species == SPECIES_GLASTRIER) + MESSAGE("Glastrier cut its own HP and maximized ATTACK!"); + else + MESSAGE("Calyrex cut its own HP and maximized ATTACK!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_QUICK_ATTACK, player); MESSAGE("Foe Snorunt fainted!"); - NONE_OF { - ABILITY_POPUP(player, ABILITY_MOXIE); + NONE_OF { + ABILITY_POPUP(player, abilityPopUp); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); MESSAGE("Salamence's Moxie raised its Attack!"); + MESSAGE("Glastrier's Chilling Neigh raised its Attack!"); + MESSAGE("Calyrex's Chilling Neigh raised its Attack!"); } } THEN { EXPECT_EQ(player->statStages[STAT_ATK], MAX_STAT_STAGE); } } -DOUBLE_BATTLE_TEST("Moxie does not increase damage done by the same move that causes another Pokemon to faint") +DOUBLE_BATTLE_TEST("Moxie/Chilling Neigh does not increase damage done by the same move that causes another Pokemon to faint") { s16 damage[2]; - - ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); + u32 species = 0, ability = 0, abilityPopUp = 0; + PARAMETRIZE { species = SPECIES_SALAMENCE; ability = ABILITY_MOXIE; abilityPopUp = ABILITY_MOXIE; } + PARAMETRIZE { species = SPECIES_GLASTRIER; ability = ABILITY_CHILLING_NEIGH; abilityPopUp = ABILITY_CHILLING_NEIGH; } + PARAMETRIZE { species = SPECIES_CALYREX_ICE_RIDER; ability = ABILITY_AS_ONE_ICE_RIDER; abilityPopUp = ABILITY_CHILLING_NEIGH; } KNOWN_FAILING; // Requires simultaneous damage implementation GIVEN { - PLAYER(SPECIES_SALAMENCE) { Ability(ABILITY_MOXIE); } + ASSUME(gMovesInfo[MOVE_EARTHQUAKE].target == MOVE_TARGET_FOES_AND_ALLY); + PLAYER(species) { Ability(ability); } PLAYER(SPECIES_ABRA) { HP(1); } OPPONENT(SPECIES_GLALIE); OPPONENT(SPECIES_GLALIE); @@ -110,9 +137,14 @@ DOUBLE_BATTLE_TEST("Moxie does not increase damage done by the same move that ca HP_BAR(opponentLeft, captureDamage: &damage[0]); HP_BAR(playerRight); MESSAGE("Abra fainted!"); - ABILITY_POPUP(playerLeft, ABILITY_MOXIE); + ABILITY_POPUP(playerLeft, abilityPopUp); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); - MESSAGE("Salamence's Moxie raised its Attack!"); + if (species == SPECIES_SALAMENCE) + MESSAGE("Salamence's Moxie raised its Attack!"); + else if (species == SPECIES_GLASTRIER) + MESSAGE("Glastrier's Chilling Neigh raised its Attack!"); + else + MESSAGE("Calyrex's Chilling Neigh raised its Attack!"); HP_BAR(opponentRight, captureDamage: &damage[1]); } THEN { EXPECT_EQ(playerLeft->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1); diff --git a/test/battle/ability/normalize.c b/test/battle/ability/normalize.c new file mode 100644 index 0000000000..d3e8df6bee --- /dev/null +++ b/test/battle/ability/normalize.c @@ -0,0 +1,16 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Normalize tuns a move into a Normal-type move"); +TO_DO_BATTLE_TEST("Normalize boosts power of both affected and originally Normal-type moves by 20% (Gen7+)"); +TO_DO_BATTLE_TEST("Normalize affects status moves"); // Eg. Thunder Wave can affect Ground types +TO_DO_BATTLE_TEST("Normalize makes Flying Press do Normal/Flying damage"); +TO_DO_BATTLE_TEST("Normalize still makes Freeze-Dry do super effective damage to Water-type Pokémon"); +TO_DO_BATTLE_TEST("Normalize-affected moves become Electric-type under Electrify's effect"); +TO_DO_BATTLE_TEST("Normalize-affected moves become Electric-type under Ion Deluge's effect"); +TO_DO_BATTLE_TEST("Normalize doesn't affect Hidden Power's type"); +TO_DO_BATTLE_TEST("Normalize doesn't affect Weather Ball's type"); +TO_DO_BATTLE_TEST("Normalize doesn't affect Natural Gift's type"); +TO_DO_BATTLE_TEST("Normalize doesn't affect Judgment/Techno Blast/Multi-Attack's type"); +TO_DO_BATTLE_TEST("Normalize doesn't affect Terrain Pulse's type"); +TO_DO_BATTLE_TEST("Normalize doesn't affect damaging Z-Move types"); diff --git a/test/battle/ability/orichalcum_pulse.c b/test/battle/ability/orichalcum_pulse.c new file mode 100644 index 0000000000..295e0db23c --- /dev/null +++ b/test/battle/ability/orichalcum_pulse.c @@ -0,0 +1,5 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Orichalcum Pulse sets up sun for 5 turns"); +TO_DO_BATTLE_TEST("Orichalcum Pulse boosts the Pokémon's Attack by 33% in sun, even if it's holding an Utility Umbrella"); diff --git a/test/battle/ability/pixilate.c b/test/battle/ability/pixilate.c new file mode 100644 index 0000000000..97c9c37a0c --- /dev/null +++ b/test/battle/ability/pixilate.c @@ -0,0 +1,35 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); +} + +SINGLE_BATTLE_TEST("Pixilate turns a Normal-type move into a Fairy-type move") +{ + GIVEN { + PLAYER(SPECIES_DRAGONITE); + OPPONENT(SPECIES_ALTARIA) { Item(ITEM_ALTARIANITE); } + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE, gimmick: GIMMICK_MEGA); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + MESSAGE("It's super effective!"); + } +} + +TO_DO_BATTLE_TEST("Pixilate can not turn certain moves into Fairy type moves"); +TO_DO_BATTLE_TEST("Pixilate boosts power of affected moves by 20% (Gen7+)"); +TO_DO_BATTLE_TEST("Pixilate boosts power of affected moves by 30% (Gen6)"); +TO_DO_BATTLE_TEST("(DYNAMAX) Pixilate turns Max Strike into Max Starfall when not used by Gigantamax Alcremie"); +TO_DO_BATTLE_TEST("(DYNAMAX) Pixilate doesn't turn Max Strike into Max Starfall when used by Gigantamax Alcremie, instead becoming G-Max Finale"); + +// Gen 6-7 +TO_DO_BATTLE_TEST("Pixilate overrides Electrify (Gen6-7)"); +TO_DO_BATTLE_TEST("Pixilate overrides Ion Deluge (Gen6-7)"); +// Gen 8+ +TO_DO_BATTLE_TEST("Pixilate doesn't override Electrify (Gen8+)"); +//TO_DO_BATTLE_TEST("Pixilate doesn't override Ion Deluge (Gen8+)"); // Ion Deluge doesn't exist in Gen 8+, but we probably could assume it behaves similar to under Electrify. TODO: Test by hacking SV. diff --git a/test/battle/ability/protosynthesis.c b/test/battle/ability/protosynthesis.c index 3cb35164ec..58f10b366f 100644 --- a/test/battle/ability/protosynthesis.c +++ b/test/battle/ability/protosynthesis.c @@ -99,3 +99,7 @@ SINGLE_BATTLE_TEST("Protosynthesis activates on switch-in") MESSAGE("Roaring Moon's Attack was heightened!"); } } + +TO_DO_BATTLE_TEST("Protosynthesis activates in sun before Booster Energy"); +TO_DO_BATTLE_TEST("Protosynthesis activates even if the Pokémon is holding an Utility Umbrella"); +TO_DO_BATTLE_TEST("Protosynthesis doesn't activate if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/rain_dish.c b/test/battle/ability/rain_dish.c index dd647f0eb9..ed71a67f92 100644 --- a/test/battle/ability/rain_dish.c +++ b/test/battle/ability/rain_dish.c @@ -14,3 +14,5 @@ SINGLE_BATTLE_TEST("Rain Dish recovers 1/16th of Max HP in Rain") HP_BAR(player, damage: -(100 / 16)); } } + +TO_DO_BATTLE_TEST("Rain Dish doesn't recover HP if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/refrigerate.c b/test/battle/ability/refrigerate.c new file mode 100644 index 0000000000..dbbaa30eb8 --- /dev/null +++ b/test/battle/ability/refrigerate.c @@ -0,0 +1,34 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_TACKLE].type == TYPE_NORMAL); + ASSUME(gMovesInfo[MOVE_TACKLE].power > 0); +} + +SINGLE_BATTLE_TEST("Refrigerate turns a Normal-type move into a Ice-type move") +{ + GIVEN { + PLAYER(SPECIES_MEGANIUM); + OPPONENT(SPECIES_AMAURA) { Ability(ABILITY_REFRIGERATE); } + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + MESSAGE("It's super effective!"); + } +} + +TO_DO_BATTLE_TEST("Refrigerate can not turn certain moves into Ice type moves"); +TO_DO_BATTLE_TEST("Refrigerate boosts power of affected moves by 20% (Gen7+)"); +TO_DO_BATTLE_TEST("Refrigerate boosts power of affected moves by 30% (Gen6)"); +TO_DO_BATTLE_TEST("(DYNAMAX) Refrigerate turns Max Strike into Max Hailstorm when not used by Gigantamax Lapras"); +//TO_DO_BATTLE_TEST("(DYNAMAX) Refrigerate doesn't turn Max Strike into Max Hailstorm when used by Gigantamax Lapras, instead becoming G-Max Resonance"); // Marked in Bulbapedia as "needs research", so this assumes that it behaves like Pixilate. + +// Gen 6-7 +TO_DO_BATTLE_TEST("Refrigerate overrides Electrify (Gen6-7)"); +TO_DO_BATTLE_TEST("Refrigerate overrides Ion Deluge (Gen6-7)"); +// Gen 8+ +//TO_DO_BATTLE_TEST("Refrigerate doesn't override Electrify (Gen8+)"); // Bulbapedia doesn't list this effect, so it assumes it behaves like Pixilate. +//TO_DO_BATTLE_TEST("Refrigerate doesn't override Ion Deluge (Gen8+)"); // Ion Deluge doesn't exist in Gen 8+, but we probably could assume it behaves similar to under Electrify. TODO: Test by hacking SV. diff --git a/test/battle/ability/sand_force.c b/test/battle/ability/sand_force.c new file mode 100644 index 0000000000..e17722a885 --- /dev/null +++ b/test/battle/ability/sand_force.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Sand Force prevents damage from sandstorm"); +TO_DO_BATTLE_TEST("Sand Force increases the power of Rock-, Ground- and Steel-type moves by 30% in sandstorm"); +TO_DO_BATTLE_TEST("Sand Force increases move power if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/sand_rush.c b/test/battle/ability/sand_rush.c new file mode 100644 index 0000000000..fa7695c129 --- /dev/null +++ b/test/battle/ability/sand_rush.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Sand Rush prevents damage from sandstorm"); +TO_DO_BATTLE_TEST("Sand Rush doubles speed from sandstorm"); +TO_DO_BATTLE_TEST("Sand Rush doesn't double speed if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/sand_veil.c b/test/battle/ability/sand_veil.c index 9e4a634de2..f42c267273 100644 --- a/test/battle/ability/sand_veil.c +++ b/test/battle/ability/sand_veil.c @@ -28,3 +28,6 @@ SINGLE_BATTLE_TEST("Sand Veil increases evasion during sandstorm") HP_BAR(player); } } + +TO_DO_BATTLE_TEST("Sand Veil doesn't prevent Sandstorm damage if Cloud Nine/Air Lock is on the field"); +TO_DO_BATTLE_TEST("Sand Veil doesn't increase evasion if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/slush_rush.c b/test/battle/ability/slush_rush.c new file mode 100644 index 0000000000..8ae62454bb --- /dev/null +++ b/test/battle/ability/slush_rush.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Slush Rush doubles speed from hail"); +TO_DO_BATTLE_TEST("Slush Rush doubles speed from snow"); +TO_DO_BATTLE_TEST("Slush Rush doesn't double speed if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/snow_cloak.c b/test/battle/ability/snow_cloak.c index f1bfbcb9b0..a4d1acadb7 100644 --- a/test/battle/ability/snow_cloak.c +++ b/test/battle/ability/snow_cloak.c @@ -27,3 +27,6 @@ SINGLE_BATTLE_TEST("Snow Cloak increases evasion during hail") HP_BAR(player); } } + +TO_DO_BATTLE_TEST("Snow Cloak doesn't prevent hail damage if Cloud Nine/Air Lock is on the field"); +TO_DO_BATTLE_TEST("Snow Cloak doesn't increase evasion if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/solar_power.c b/test/battle/ability/solar_power.c new file mode 100644 index 0000000000..f14ea11ee1 --- /dev/null +++ b/test/battle/ability/solar_power.c @@ -0,0 +1,7 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Solar Power increases a Sp. Attack by x1.5 in Sun"); +TO_DO_BATTLE_TEST("Solar Power doesn't increases a Sp. Attack if Cloud Nine/Air Lock is on the field"); +TO_DO_BATTLE_TEST("Solar Power causes the Pokémon to lose 1/8 max HP in Sun"); +TO_DO_BATTLE_TEST("Solar Power doesn't cause the Pokémon to lose 1/8 max HP if Cloud Nine/Air Lock is on the field"); diff --git a/test/battle/ability/swift_swim.c b/test/battle/ability/swift_swim.c new file mode 100644 index 0000000000..4282ac2741 --- /dev/null +++ b/test/battle/ability/swift_swim.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Swift Swim doubles speed if it's raining"); +TO_DO_BATTLE_TEST("Swift Swim doesn't double speed if Cloud Nine/Air Lock is on the field"); +TO_DO_BATTLE_TEST("Swift Swim doesn't double speed if they have an Utility Umbrella"); diff --git a/test/battle/ability/unnerve.c b/test/battle/ability/unnerve.c new file mode 100644 index 0000000000..9ad4ee7e5f --- /dev/null +++ b/test/battle/ability/unnerve.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "test/battle.h" + +// Remember to add a PARAMETRIZE for As One in the following tests: +TO_DO_BATTLE_TEST("Unnerve prevents opposing Pokémon from eating their own berries"); +TO_DO_BATTLE_TEST("Unnerve doesn't prevent opposing Pokémon from using Natural Gift"); diff --git a/test/battle/gimmick/terastal.c b/test/battle/gimmick/terastal.c index f14c398b64..7a70ba0de0 100644 --- a/test/battle/gimmick/terastal.c +++ b/test/battle/gimmick/terastal.c @@ -86,46 +86,6 @@ SINGLE_BATTLE_TEST("(TERA) Terastallizing into the same type gives that type 2x } } -SINGLE_BATTLE_TEST("(TERA) Terastallizing into a different type with Adaptability gives 2.0x STAB", s16 damage) -{ - bool32 tera; - PARAMETRIZE { tera = GIMMICK_NONE; } - PARAMETRIZE { tera = GIMMICK_TERA; } - GIVEN { - PLAYER(SPECIES_CRAWDAUNT) { Ability(ABILITY_ADAPTABILITY); TeraType(TYPE_NORMAL); } - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_HEADBUTT, gimmick: tera); } - } SCENE { - MESSAGE("Crawdaunt used Headbutt!"); - ANIMATION(ANIM_TYPE_MOVE, MOVE_HEADBUTT, player); - HP_BAR(opponent, captureDamage: &results[i].damage); - } FINALLY { - // The jump from no STAB to 2.0x STAB is a 2.0x boost. - EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage); - } -} - -SINGLE_BATTLE_TEST("(TERA) Terastallizing into the same type with Adaptability gives 2.25x STAB", s16 damage) -{ - bool32 tera; - PARAMETRIZE { tera = GIMMICK_NONE; } - PARAMETRIZE { tera = GIMMICK_TERA; } - GIVEN { - PLAYER(SPECIES_CRAWDAUNT) { Ability(ABILITY_ADAPTABILITY); TeraType(TYPE_WATER); } - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_WATER_PULSE, gimmick: tera); } - } SCENE { - MESSAGE("Crawdaunt used Water Pulse!"); - ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_PULSE, player); - HP_BAR(opponent, captureDamage: &results[i].damage); - } FINALLY { - // The jump from 2x STAB to 2.25x STAB is a 1.125x boost. - EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.125), results[1].damage); - } -} - SINGLE_BATTLE_TEST("(TERA) Terastallizing boosts moves of the same type to 60 BP", s16 damage) { bool32 tera; diff --git a/test/battle/ability/booster_energy.c b/test/battle/hold_effect/booster_energy.c similarity index 100% rename from test/battle/ability/booster_energy.c rename to test/battle/hold_effect/booster_energy.c diff --git a/test/battle/hold_effect/utility_umbrella.c b/test/battle/hold_effect/utility_umbrella.c index e02a4fdef3..f04a773789 100644 --- a/test/battle/hold_effect/utility_umbrella.c +++ b/test/battle/hold_effect/utility_umbrella.c @@ -52,3 +52,5 @@ SINGLE_BATTLE_TEST("Utility Umbrella blocks Rain damage modifiers", s16 damage) EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.5), results[3].damage); } } + +// Moves and abilities affected by Utility Umbrella have their tests in the respective files diff --git a/test/battle/move_effect/weather_ball.c b/test/battle/move_effect/weather_ball.c index 1656b60d87..432e5f79f7 100644 --- a/test/battle/move_effect/weather_ball.c +++ b/test/battle/move_effect/weather_ball.c @@ -78,3 +78,5 @@ SINGLE_BATTLE_TEST("Weather Ball doubles its power and turns to an Ice-type move EXPECT_MUL_EQ(results[0].damage, Q_4_12(4.0), results[1].damage); // double base power + type effectiveness. } } + +TO_DO_BATTLE_TEST("Weather Ball doesn't double its power or change type if Cloud Nine/Air Lock is on the field"); From 6f0004ec4ed7b052052f5bfb785ab4b63e3ce954 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 14 Aug 2024 09:51:34 -0400 Subject: [PATCH 23/64] Removed some hardcoding of move IDs + Gen4/5 Defog (#5156) * Removed some hardcoding of move IDs * Added Defog Gen6+ config (+ updated tests) --- include/config/battle.h | 2 +- src/battle_ai_main.c | 2 +- src/battle_ai_switch_items.c | 4 +- src/battle_script_commands.c | 21 +++++---- src/battle_util.c | 2 +- src/pokemon.c | 21 ++++----- test/battle/move_effect/defog.c | 77 ++++++++++++++++++++------------- 7 files changed, 75 insertions(+), 54 deletions(-) diff --git a/include/config/battle.h b/include/config/battle.h index 72fda7f76c..4bf84a1716 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -110,7 +110,7 @@ #define B_BURN_HIT_THAW GEN_LATEST // In Gen6+, damaging moves with a chance of burn will thaw the target, regardless if they're fire-type moves or not. #define B_HEALING_WISH_SWITCH GEN_LATEST // In Gen5+, the mon receiving Healing Wish is sent out at the end of the turn. // Additionally, in gen8+ the Healing Wish's effect will be stored until the user switches into a statused or hurt mon. -#define B_DEFOG_CLEARS_TERRAIN GEN_LATEST // In Gen8+, Defog also clears active Terrain. +#define B_DEFOG_EFFECT_CLEARING GEN_LATEST // In Gen6+, Defog clears Spikes, Toxic Spikes, Stealth Rock and Sticky Web from both sides. In Gen8+, Defog also clears active Terrain. #define B_STOCKPILE_RAISES_DEFS GEN_LATEST // In Gen4+, Stockpile also raises Defense and Sp. Defense stats. Once Spit Up / Swallow is used, these stat changes are lost. #define B_TRANSFORM_SHINY GEN_LATEST // In Gen4+, Transform will copy the shiny state of the opponent instead of maintaining its own shiny state. #define B_TRANSFORM_FORM_CHANGES GEN_LATEST // In Gen5+, Transformed Pokemon cannot change forms. diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index c814210766..b0229cd926 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -4056,7 +4056,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) ADJUST_SCORE(DECENT_EFFECT); // Force 'em out next turn break; default: - if (move != MOVE_BESTOW && aiData->items[battlerAtk] == ITEM_NONE) + if (gMovesInfo[gCurrentMove].effect != EFFECT_BESTOW && aiData->items[battlerAtk] == ITEM_NONE) { switch (aiData->holdEffects[battlerDef]) { diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 966082f32f..e1e25b5279 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -881,7 +881,9 @@ static bool32 CanMonSurviveHazardSwitchin(u32 battler) for (j = 0; j < MAX_MON_MOVES; j++) { aiMove = GetMonData(&party[i], MON_DATA_MOVE1 + j, NULL); - if (aiMove == MOVE_RAPID_SPIN || aiMove == MOVE_DEFOG || aiMove == MOVE_MORTAL_SPIN || aiMove == MOVE_TIDY_UP) + if (MoveHasAdditionalEffectSelf(aiMove, MOVE_EFFECT_RAPID_SPIN) + || (B_DEFOG_EFFECT_CLEARING >= GEN_6 && gMovesInfo[aiMove].effect == EFFECT_DEFOG) + || gMovesInfo[aiMove].effect == EFFECT_TIDY_UP) { // Have a mon that can clear the hazards, so switching out is okay return TRUE; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ecd6fc7ffb..befc8f95ca 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1491,14 +1491,14 @@ static bool32 AccuracyCalcHelper(u16 move) return TRUE; } // If the attacker has the ability No Guard and they aren't targeting a Pokemon involved in a Sky Drop with the move Sky Drop, move hits. - else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)) + else if (GetBattlerAbility(gBattlerAttacker) == ABILITY_NO_GUARD && (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)) { if (!JumpIfMoveFailed(7, move)) RecordAbilityBattle(gBattlerAttacker, ABILITY_NO_GUARD); return TRUE; } // If the target has the ability No Guard and they aren't involved in a Sky Drop or the current move isn't Sky Drop, move hits. - else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (move != MOVE_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)) + else if (GetBattlerAbility(gBattlerTarget) == ABILITY_NO_GUARD && (gMovesInfo[move].effect != EFFECT_SKY_DROP || gBattleStruct->skyDropTargets[gBattlerTarget] == 0xFF)) { if (!JumpIfMoveFailed(7, move)) RecordAbilityBattle(gBattlerTarget, ABILITY_NO_GUARD); @@ -2165,7 +2165,7 @@ static void Cmd_attackanimation(void) && gCurrentMove != MOVE_SUBSTITUTE && gCurrentMove != MOVE_ALLY_SWITCH // In a wild double battle gotta use the teleport animation if two wild pokemon are alive. - && !(gCurrentMove == MOVE_TELEPORT && WILD_DOUBLE_BATTLE && GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)))) + && !(gMovesInfo[gCurrentMove].effect == EFFECT_TELEPORT && WILD_DOUBLE_BATTLE && GetBattlerSide(gBattlerAttacker) == B_SIDE_OPPONENT && IsBattlerAlive(BATTLE_PARTNER(gBattlerAttacker)))) { BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_Pausex20; @@ -8605,11 +8605,14 @@ static bool32 TryDefogClear(u32 battlerAtk, bool32 clear) DEFOG_CLEAR(SIDE_STATUS_AURORA_VEIL, auroraVeilTimer, BattleScript_SideStatusWoreOffReturn, MOVE_AURORA_VEIL); DEFOG_CLEAR(SIDE_STATUS_SAFEGUARD, safeguardTimer, BattleScript_SideStatusWoreOffReturn, MOVE_SAFEGUARD); } - DEFOG_CLEAR(SIDE_STATUS_SPIKES, spikesAmount, BattleScript_SpikesDefog, 0); - DEFOG_CLEAR(SIDE_STATUS_STEALTH_ROCK, stealthRockAmount, BattleScript_StealthRockDefog, 0); - DEFOG_CLEAR(SIDE_STATUS_TOXIC_SPIKES, toxicSpikesAmount, BattleScript_ToxicSpikesDefog, 0); - DEFOG_CLEAR(SIDE_STATUS_STICKY_WEB, stickyWebAmount, BattleScript_StickyWebDefog, 0); - DEFOG_CLEAR(SIDE_STATUS_STEELSURGE, steelsurgeAmount, BattleScript_SteelsurgeDefog, 0); + if (B_DEFOG_EFFECT_CLEARING >= GEN_6) + { + DEFOG_CLEAR(SIDE_STATUS_SPIKES, spikesAmount, BattleScript_SpikesDefog, 0); + DEFOG_CLEAR(SIDE_STATUS_STEALTH_ROCK, stealthRockAmount, BattleScript_StealthRockDefog, 0); + DEFOG_CLEAR(SIDE_STATUS_TOXIC_SPIKES, toxicSpikesAmount, BattleScript_ToxicSpikesDefog, 0); + DEFOG_CLEAR(SIDE_STATUS_STICKY_WEB, stickyWebAmount, BattleScript_StickyWebDefog, 0); + DEFOG_CLEAR(SIDE_STATUS_STEELSURGE, steelsurgeAmount, BattleScript_SteelsurgeDefog, 0); + } if (gBattleWeather & B_WEATHER_FOG) { gBattleWeather &= ~B_WEATHER_FOG; @@ -8617,7 +8620,7 @@ static bool32 TryDefogClear(u32 battlerAtk, bool32 clear) gBattlescriptCurrInstr = BattleScript_FogEnded_Ret; return TRUE; } - if (B_DEFOG_CLEARS_TERRAIN >= GEN_8 && (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY)) + if (B_DEFOG_EFFECT_CLEARING >= GEN_8 && (gFieldStatuses & STATUS_FIELD_TERRAIN_ANY)) { RemoveAllTerrains(); BattleScriptPushCursor(); diff --git a/src/battle_util.c b/src/battle_util.c index 9da592b09f..7bcdf1ee08 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8391,7 +8391,7 @@ u8 IsMonDisobedient(void) // is not obedient if (gCurrentMove == MOVE_RAGE) gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RAGE; - if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (gCurrentMove == MOVE_SNORE || gCurrentMove == MOVE_SLEEP_TALK)) + if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (gMovesInfo[gCurrentMove].effect == EFFECT_SNORE || gMovesInfo[gCurrentMove].effect == EFFECT_SLEEP_TALK)) { gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep; return 1; diff --git a/src/pokemon.c b/src/pokemon.c index cfb2307126..306e310372 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -6957,8 +6957,9 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) u32 ability = GetMonAbility(mon); u32 type1 = gSpeciesInfo[species].types[0]; u32 type2 = gSpeciesInfo[species].types[1]; + u32 effect = gMovesInfo[move].effect; - if (move == MOVE_IVY_CUDGEL + if (effect == EFFECT_IVY_CUDGEL && (species == SPECIES_OGERPON_WELLSPRING_MASK || species == SPECIES_OGERPON_WELLSPRING_MASK_TERA || species == SPECIES_OGERPON_HEARTHFLAME_MASK || species == SPECIES_OGERPON_HEARTHFLAME_MASK_TERA || species == SPECIES_OGERPON_CORNERSTONE_MASK || species == SPECIES_OGERPON_CORNERSTONE_MASK_TERA)) @@ -6969,11 +6970,11 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) { return TYPE_NORMAL; } - else if (move == MOVE_TERA_BLAST && GetActiveGimmick(battler) == GIMMICK_TERA && gBattleMons[battler].species == species) + else if (effect == EFFECT_TERA_BLAST && GetActiveGimmick(battler) == GIMMICK_TERA && gBattleMons[battler].species == species) { return GetMonData(mon, MON_DATA_TERA_TYPE); } - else if (move == MOVE_TERA_STARSTORM && species == SPECIES_TERAPAGOS_STELLAR) + else if (effect == EFFECT_TERA_STARSTORM && species == SPECIES_TERAPAGOS_STELLAR) { return TYPE_STELLAR; } @@ -6981,32 +6982,32 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) { return CalculateHiddenPowerType(mon); } - else if (move == MOVE_AURA_WHEEL && species == SPECIES_MORPEKO_HANGRY) + else if (effect == EFFECT_AURA_WHEEL && species == SPECIES_MORPEKO_HANGRY) { type = TYPE_DARK; } - else if (gMovesInfo[move].effect == EFFECT_CHANGE_TYPE_ON_ITEM) + else if (effect == EFFECT_CHANGE_TYPE_ON_ITEM) { if (heldItemEffect == gMovesInfo[move].argument) return ItemId_GetSecondaryId(heldItem); else return TYPE_NORMAL; } - else if (move == MOVE_NATURAL_GIFT) + else if (effect == EFFECT_NATURAL_GIFT) { if (ItemId_GetPocket(heldItem) == POCKET_BERRIES) return gNaturalGiftTable[ITEM_TO_BERRY(heldItem)].type; else return TYPE_NORMAL; } - else if (move == MOVE_RAGING_BULL + else if (effect == EFFECT_RAGING_BULL && (species == SPECIES_TAUROS_PALDEAN_COMBAT_BREED || species == SPECIES_TAUROS_PALDEAN_BLAZE_BREED || species == SPECIES_TAUROS_PALDEAN_AQUA_BREED)) { return type2; } - else if (move == MOVE_REVELATION_DANCE) + else if (effect == EFFECT_REVELATION_DANCE) { if (gBattleMons[battler].species != species && type1 != TYPE_MYSTERY) type = type1; @@ -7021,7 +7022,7 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) else if (gBattleMons[battler].types[2] != TYPE_MYSTERY) type = gBattleMons[battler].types[2]; } - else if (gMovesInfo[move].effect == EFFECT_TERRAIN_PULSE + else if (effect == EFFECT_TERRAIN_PULSE && ((IsMonGrounded(heldItemEffect, ability, type1, type2) && gBattleMons[battler].species != species) || (IsBattlerTerrainAffected(battler, STATUS_FIELD_TERRAIN_ANY) && gBattleMons[battler].species == species))) { @@ -7037,7 +7038,7 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) type = TYPE_NORMAL; } - if (gMovesInfo[move].effect == EFFECT_WEATHER_BALL) + if (effect == EFFECT_WEATHER_BALL) { if (gMain.inBattle && WEATHER_HAS_EFFECT) { diff --git a/test/battle/move_effect/defog.c b/test/battle/move_effect/defog.c index 418d28d97b..80d500d2ee 100644 --- a/test/battle/move_effect/defog.c +++ b/test/battle/move_effect/defog.c @@ -131,7 +131,7 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Mist and Safeguard } } -DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and Sticky Web from player's side") +DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and Sticky Web from player's side (Gen 6+)") { u16 move; @@ -154,13 +154,15 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Stealth Rock and S if (move == MOVE_DEFOG) { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); MESSAGE("Foe Wobbuffet's evasiveness fell!"); - MESSAGE("The pointed stones disappeared from around your team!"); - MESSAGE("The sticky web has disappeared from the ground around your team!"); + if (B_DEFOG_EFFECT_CLEARING >= GEN_6) { + MESSAGE("The pointed stones disappeared from around your team!"); + MESSAGE("The sticky web has disappeared from the ground around your team!"); + } } // Switch happens SWITCH_OUT_MESSAGE("Wobbuffet"); SEND_IN_MESSAGE("Wobbuffet"); - if (move != MOVE_DEFOG) { + if (move != MOVE_DEFOG || B_DEFOG_EFFECT_CLEARING <= GEN_5) { HP_BAR(playerLeft); MESSAGE("Pointed stones dug into Wobbuffet!"); MESSAGE("Wobbuffet was caught in a Sticky Web!"); @@ -198,12 +200,13 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Spikes from player if (move == MOVE_DEFOG) { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); MESSAGE("Foe Wobbuffet's evasiveness fell!"); - MESSAGE("The spikes disappeared from the ground around your team!"); + if (B_DEFOG_EFFECT_CLEARING >= GEN_6) + MESSAGE("The spikes disappeared from the ground around your team!"); } // Switch happens SWITCH_OUT_MESSAGE("Wobbuffet"); SEND_IN_MESSAGE("Wobbuffet"); - if (move != MOVE_DEFOG) { + if (move != MOVE_DEFOG || B_DEFOG_EFFECT_CLEARING <= GEN_5) { HP_BAR(player); MESSAGE("Wobbuffet is hurt by spikes!"); } @@ -216,7 +219,7 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Spikes from player } } -SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain") +SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain (Gen 8+)") { u16 move; @@ -225,7 +228,6 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain") PARAMETRIZE { move = MOVE_MISTY_TERRAIN; } PARAMETRIZE { move = MOVE_GRASSY_TERRAIN; } GIVEN { - ASSUME(B_DEFOG_CLEARS_TERRAIN >= GEN_8); PLAYER(SPECIES_WOBBUFFET) { Speed(50); } OPPONENT(SPECIES_WOBBUFFET) { Speed(5); } } WHEN { @@ -235,19 +237,29 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes terrain") ANIMATION(ANIM_TYPE_MOVE, MOVE_DEFOG, opponent); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); MESSAGE("Wobbuffet's evasiveness fell!"); - if (move == MOVE_PSYCHIC_TERRAIN) { - MESSAGE("The weirdness disappeared from the battlefield."); + if (B_DEFOG_EFFECT_CLEARING >= GEN_8) { + if (move == MOVE_PSYCHIC_TERRAIN) { + MESSAGE("The weirdness disappeared from the battlefield."); + } + else if (move == MOVE_ELECTRIC_TERRAIN) { + MESSAGE("The electricity disappeared from the battlefield."); + } + else if (move == MOVE_MISTY_TERRAIN) { + MESSAGE("The mist disappeared from the battlefield."); + } + else if (move == MOVE_GRASSY_TERRAIN) { + MESSAGE("The grass disappeared from the battlefield."); + } + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_RESTORE_BG, player); + } else { + NONE_OF { + MESSAGE("The weirdness disappeared from the battlefield."); + MESSAGE("The electricity disappeared from the battlefield."); + MESSAGE("The mist disappeared from the battlefield."); + MESSAGE("The grass disappeared from the battlefield."); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_RESTORE_BG, player); + } } - else if (move == MOVE_ELECTRIC_TERRAIN) { - MESSAGE("The electricity disappeared from the battlefield."); - } - else if (move == MOVE_MISTY_TERRAIN) { - MESSAGE("The mist disappeared from the battlefield."); - } - else if (move == MOVE_GRASSY_TERRAIN) { - MESSAGE("The grass disappeared from the battlefield."); - } - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_RESTORE_BG, player); } } @@ -270,11 +282,12 @@ SINGLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes Toxic Spikes from if (move == MOVE_DEFOG) { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); MESSAGE("Wobbuffet's evasiveness fell!"); - MESSAGE("The poison spikes disappeared from the ground around the opposing team!"); + if (B_DEFOG_EFFECT_CLEARING >= GEN_6) + MESSAGE("The poison spikes disappeared from the ground around the opposing team!"); } // Switch happens MESSAGE("2 sent out Wobbuffet!"); - if (move != MOVE_DEFOG) { + if (move != MOVE_DEFOG || B_DEFOG_EFFECT_CLEARING <= GEN_5) { MESSAGE("Foe Wobbuffet was poisoned!"); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent); STATUS_ICON(opponent, poison: TRUE); @@ -356,15 +369,17 @@ DOUBLE_BATTLE_TEST("Defog lowers evasiveness by 1 and removes everything it can" MESSAGE("Ally's Aurora Veil wore off!"); MESSAGE("Ally's Safeguard wore off!"); - MESSAGE("The spikes disappeared from the ground around your team!"); - MESSAGE("The pointed stones disappeared from around your team!"); - MESSAGE("The poison spikes disappeared from the ground around your team!"); - MESSAGE("The sticky web has disappeared from the ground around your team!"); + if (B_DEFOG_EFFECT_CLEARING >= GEN_6) { + MESSAGE("The spikes disappeared from the ground around your team!"); + MESSAGE("The pointed stones disappeared from around your team!"); + MESSAGE("The poison spikes disappeared from the ground around your team!"); + MESSAGE("The sticky web has disappeared from the ground around your team!"); - // Opponent side - MESSAGE("The spikes disappeared from the ground around the opposing team!"); - MESSAGE("The pointed stones disappeared from around the opposing team!"); - MESSAGE("The poison spikes disappeared from the ground around the opposing team!"); - MESSAGE("The sticky web has disappeared from the ground around the opposing team!"); + // Opponent side + MESSAGE("The spikes disappeared from the ground around the opposing team!"); + MESSAGE("The pointed stones disappeared from around the opposing team!"); + MESSAGE("The poison spikes disappeared from the ground around the opposing team!"); + MESSAGE("The sticky web has disappeared from the ground around the opposing team!"); + } } } From 00f8a4db157494faa4a267cffc022452b00d0cc5 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 14 Aug 2024 10:10:58 -0400 Subject: [PATCH 24/64] Added guide to running documentation website locally (#5059) * Added guide to running documentation website locally * Added link to mdBook's official documentation. --------- Co-authored-by: psf <77138753+pkmnsnfrn@users.noreply.github.com> --- docs/SUMMARY.md | 2 ++ docs/local_mdbook/index.md | 2 ++ docs/local_mdbook/ubuntu_WSL.md | 51 +++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 docs/local_mdbook/index.md create mode 100644 docs/local_mdbook/ubuntu_WSL.md diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index fce328d858..0e065d018e 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -3,6 +3,8 @@ - [README](./README.md) - [Installation](./INSTALL.md) - [Setting up WSL1 (Legacy Portion)](./legacy_WSL1_INSTALL.md) +- [Run documentation site locally](local_mdbook/index.md) + - [Ubuntu WSL1/WSL2](local_mdbook/ubuntu_WSL.md) - [AI Flags](./ai_flags.md) - [Tutorials]() - [How to add new AI Flags](./ai_logic.md) diff --git a/docs/local_mdbook/index.md b/docs/local_mdbook/index.md new file mode 100644 index 0000000000..ef362dc45f --- /dev/null +++ b/docs/local_mdbook/index.md @@ -0,0 +1,2 @@ +## Running documentation website locally +- [Ubuntu WSL1/WSL2](/docs/local_mdbook/ubuntu_WSL.md) diff --git a/docs/local_mdbook/ubuntu_WSL.md b/docs/local_mdbook/ubuntu_WSL.md new file mode 100644 index 0000000000..88ee2468e6 --- /dev/null +++ b/docs/local_mdbook/ubuntu_WSL.md @@ -0,0 +1,51 @@ +Note: For further information beyond this very basic guide, please visit mdBook's [official documentation](https://rust-lang.github.io/mdBook/). + +## Running documentation website locally (Ubuntu WSL1/WSL2) +### Previous Requirements: +- Option 1: Install via Rust toolchain + - Install Rust toolchain if you don't have it via the `sudo apt install cargo` command. + - Install mdBook via the `cargo install mdbook` command. Once finished, this message will pop up, with {USER} being your Ubuntu + ``` + warning: be sure to add `/home/{USER}/.cargo/bin` to your PATH to be able to run the installed binaries + ``` + - Add `/home/{USER}/.cargo/bin` to your PATH (with {USER} being the Ubuntu username.) + - Run command `nano ~/.profile` to edit the file. + - Add the following lines, ***replacing {USER} with your Linux username.*** + ```diff + # set PATH so it includes user's private bin if it exists + if [ -d "$HOME/bin" ] ; then + PATH="$HOME/bin:$PATH" + fi + + # set PATH so it includes user's private bin if it exists + if [ -d "$HOME/.local/bin" ] ; then + PATH="$HOME/.local/bin:$PATH" + fi + + +# set PATH so it includes cargo bin if it exists + +if [ -d "/home/{USER}/.cargo/bin" ] ; then + + PATH="/home/{USER}/.cargo/bin:$PATH" + +fi + ``` + - Run the `source ~/.profile` command to refresh the path in the current session. +- Option 2: Install downloaded binaries directly + - TODO: Add documentation of this process. + +### Running the website +- Navigate to the `docs` folder on the repository. +- Run `mdbook serve`. Once started, you may now open the website on your browser by going to `http://127.0.0.1:3000`. +- Every change done to the `docs` folder will be reflected with an automatic refresh. +- To stop the server and go back to the terminal, press `Ctrl + C`. + +### Modifying the website +- The navigation menu on the left is handled by `docs/SUMMARY.md`. Every file added needs to be added somewhere here in order to become visible, otherwise you'll get a 404 error. +- Any Markdown files (.md extension) added to the `docs/` directory will automatically be read by mdBook. +- To add Markdown files that are not in the `docs/` directory, you may create an empty `.md` file and add the following ***without the "----"***: + ```md + {{ ----#include ../INSTALL.md}}` + ``` + This will include the `INSTALL.md` Markdown file from the root directory. + +Once you're set up, you can now check your changes before pushing them to your repo! :D + +We hope that this will make it easier for users to contribute to the documentation :) From fde85e9357bf30493ed81dda3c002006cc60ddc9 Mon Sep 17 00:00:00 2001 From: Sadfish the Sad Date: Wed, 14 Aug 2024 11:20:18 -0400 Subject: [PATCH 25/64] some gen 9 move anims + fickle beam rework (#5159) * new move anims + fickle beam rework * more fickle beam changes * removed the true for consistency * ficklebeamboosted gets cleared now * mortal spin and thunderclap changes * minor mortal spin pal change * removed hex numbers and made hard press quicker --- asm/macros/battle_script.inc | 4 + data/battle_anim_scripts.s | 632 +++++++++++++++++- data/battle_scripts_1.s | 13 + graphics/battle_anims/sprites/beam.png | Bin 0 -> 383 bytes graphics/battle_anims/sprites/blood_moon.png | Bin 0 -> 714 bytes .../battle_anims/sprites/purple_chain.png | Bin 0 -> 622 bytes .../battle_anims/sprites/red_explosion.png | Bin 0 -> 946 bytes include/battle.h | 1 + include/battle_anim.h | 1 + include/battle_scripts.h | 2 + include/constants/battle_anim.h | 4 + include/constants/battle_string_ids.h | 3 +- include/graphics.h | 8 + src/battle_anim_effects_1.c | 27 + src/battle_anim_new.c | 66 ++ src/battle_message.c | 2 + src/battle_script_commands.c | 17 + src/battle_util.c | 2 +- src/data/battle_anim.h | 8 + src/data/battle_move_effects.h | 2 +- src/graphics.c | 12 + 21 files changed, 786 insertions(+), 18 deletions(-) create mode 100644 graphics/battle_anims/sprites/beam.png create mode 100644 graphics/battle_anims/sprites/blood_moon.png create mode 100644 graphics/battle_anims/sprites/purple_chain.png create mode 100644 graphics/battle_anims/sprites/red_explosion.png diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 12439efc4a..9d61889b40 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -1670,6 +1670,10 @@ callnative BS_DamageToQuarterTargetHP .endm + .macro ficklebeamdamagecalculation + callnative BS_FickleBeamDamageCalculation + .endm + @ various command changed to more readable macros .macro cancelmultiturnmoves battler:req various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index f842b8c113..2f1a3cb73c 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -16219,6 +16219,12 @@ Move_RAGING_BULL:: loadspritegfx ANIM_TAG_IMPACT loadspritegfx ANIM_TAG_ANGER loadspritegfx ANIM_TAG_BREATH + loadspritegfx ANIM_TAG_BLUE_LIGHT_WALL + loadspritegfx ANIM_TAG_TORN_METAL + choosetwoturnanim RagingBullNormal, RagingBullShatteredWall +RagingBullNormal: + monbg ANIM_TARGET + setalpha 12, 8 createsprite gBreathPuffSpriteTemplate, ANIM_ATTACKER, 2 loopsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER, 4, 2 createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, -20, -28 @@ -16250,6 +16256,49 @@ Move_RAGING_BULL:: waitforvisualfinish restorebg waitbgfadein + clearmonbg ANIM_TARGET + end +RagingBullShatteredWall: + monbg ANIM_TARGET + setalpha 12, 8 + createsprite gBreathPuffSpriteTemplate, ANIM_ATTACKER, 2 + loopsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER, 4, 2 + createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, -20, -28 + delay 20 + createsprite gAngerMarkSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, -28 + waitforvisualfinish + createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 18, 6, 2, 4 + waitforvisualfinish + playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER + call SetImpactBackground + createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, 0, 0, 4 + delay 3 + waitforvisualfinish + createsprite gBrickBreakWallSpriteTemplate, ANIM_ATTACKER, 3, ANIM_TARGET, 0, 0, 90, 10 + playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, -10, 0, ANIM_TARGET, 0 + createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -32, 0, 0, 3 + delay 20 + createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_ATTACKER, 0 + createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_TARGET, 0 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 4, 0, 12, 1 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + delay 20 + createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_ATTACKER, 1 + createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_TARGET, 1 + waitforvisualfinish + createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0, -8, -12 + createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 1, 8, -12 + createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 2, -8, 12 + createsprite gBrickBreakWallShardSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 3, 8, 12 + playsewithpan SE_M_BRICK_BREAK, SOUND_PAN_TARGET + createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 5 + delay 3 + createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 7 + waitforvisualfinish + restorebg + waitbgfadein + clearmonbg ANIM_TARGET end @ Credits to Z-nogyroP. Simple anim that combines Force Palm + Fake Out @@ -17013,44 +17062,597 @@ Move_AXE_KICK:: createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 1, 4 end +Move_SPIN_OUT:: + loadspritegfx ANIM_TAG_IMPACT + loadspritegfx ANIM_TAG_RAPID_SPIN + loopsewithpan SE_M_HARDEN, SOUND_PAN_ATTACKER, 28, 2 + createvisualtask AnimTask_MetallicShine, 5, 0, 0, RGB_BLACK + waitforvisualfinish + call SetHighSpeedBg + loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 3 + waitforvisualfinish + monbg ANIM_ATTACKER + createsprite gRapidSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 32, -32, 40, -2 + createvisualtask AnimTask_RapinSpinMonElevation, 2, 0, 2, 0 + loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 4 + waitforvisualfinish + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 2 + createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 10, 1, 0 + playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET + waitforvisualfinish + delay 8 + createvisualtask AnimTask_RapinSpinMonElevation, 2, 0, 2, 1 + loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 4 + waitforvisualfinish + call UnsetHighSpeedBg + clearmonbg ANIM_ATTACKER + end + +Move_MORTAL_SPIN:: + loadspritegfx ANIM_TAG_IMPACT + loadspritegfx ANIM_TAG_RAPID_SPIN + loadspritegfx ANIM_TAG_POISON_BUBBLE + createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_RAPID_SPIN, 0, 6, 6, RGB(15, 0, 15) + monbg ANIM_ATTACKER + createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, 1, 0, 13, RGB(10, 2, 19) + delay 16 + createsprite gRapidSpinSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 32, -32, 40, -2 + createvisualtask AnimTask_RapinSpinMonElevation, 2, 0, 2, 0 + loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 4 + waitforvisualfinish + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, ANIM_TARGET, 2 + createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 10, 1, 0 + createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_ATTACKER, 1, 13, 0, RGB(10, 2, 19) + call PoisonBubblesEffect + waitforvisualfinish + delay 8 + createvisualtask AnimTask_RapinSpinMonElevation, 2, 0, 2, 1 + loopsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER, 8, 4 + waitforvisualfinish + clearmonbg ANIM_ATTACKER + blendoff + end + +Move_FILLET_AWAY:: + loadspritegfx ANIM_TAG_CUT + createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 40, -32, 0 + playsewithpan SE_M_CUT, SOUND_PAN_ATTACKER + delay 5 + createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 20, -27, 0 + playsewithpan SE_M_CUT, SOUND_PAN_ATTACKER + delay 5 + createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 60, -37, 0 + playsewithpan SE_M_CUT, SOUND_PAN_ATTACKER + waitforvisualfinish + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 2, 0, 9, 0x7FFF + waitforvisualfinish + createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 2, 4, 4 + waitforvisualfinish + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 2, 9, 0, 0x7FFF + waitforvisualfinish + blendoff + end + +Move_FLOWER_TRICK:: + loadspritegfx ANIM_TAG_SPOTLIGHT + loadspritegfx ANIM_TAG_LEAF @leaves + loadspritegfx ANIM_TAG_FLOWER @flowers + loadspritegfx ANIM_TAG_IMPACT + createvisualtask AnimTask_CreateSpotlight, 2 + createvisualtask AnimTask_HardwarePaletteFade, 2, (BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN), 3, 0, 10, FALSE + waitforvisualfinish + createsprite gSpotlightSpriteTemplate, ANIM_TARGET, 2, 0, -8 + delay 16 + createvisualtask SoundTask_PlaySE2WithPanning, 5, SE_M_ENCORE2, SOUND_PAN_TARGET + createvisualtask AnimTask_SwayMon, 5, 1, 8, 1536, 5, ANIM_TARGET + waitforvisualfinish + playsewithpan SE_M_DOUBLE_SLAP, SOUND_PAN_TARGET + createsprite gTropKickLeavesTemplate, ANIM_TARGET, 1, 0, 10, 192, 176, 40 + createsprite gTropKickLeavesTemplate, ANIM_TARGET, 1, 0, 10, -192, 240, 40 + createsprite gTropKickFlowerTemplate, ANIM_TARGET, 1, 0, 10, 192, -160, 40 + createsprite gTropKickFlowerTemplate, ANIM_TARGET, 1, 0, 10, -192, -112, 40 + createsprite gTropKickFlowerTemplate, ANIM_TARGET, 1, 0, 10, 160, 48, 40 + createsprite gTropKickLeavesTemplate, ANIM_TARGET, 1, 0, 10, -224, -32, 40 + createsprite gTropKickLeavesTemplate, ANIM_TARGET, 1, 0, 10, 112, -128, 40 + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, ANIM_TARGET, 2 + waitforvisualfinish + createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1 + waitforvisualfinish + createvisualtask AnimTask_HardwarePaletteFade, 2, (BLDCNT_TGT1_BG3 | BLDCNT_TGT1_OBJ | BLDCNT_TGT1_BD | BLDCNT_EFFECT_DARKEN), 3, 10, 0, TRUE + createvisualtask AnimTask_RemoveSpotlight, 2 + end + +Move_MAKE_IT_RAIN:: + loadspritegfx ANIM_TAG_COIN + loadspritegfx ANIM_TAG_IMPACT + monbg ANIM_ATTACKER + setalpha 12, 8 + playsewithpan SE_M_RAZOR_WIND2, SOUND_PAN_ATTACKER + createsprite gCoinThrowSpriteTemplate, ANIM_ATTACKER, 2, 20, 0, 0, 0, 1152 + waitforvisualfinish + playsewithpan SE_M_PAY_DAY, SOUND_PAN_TARGET + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 1, 0, 0, ANIM_TARGET, 2 + createsprite gFallingCoinSpriteTemplate, ANIM_ATTACKER, 2 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 1, 0, 6, 1 + waitforvisualfinish + delay 20 + createvisualtask AnimTask_IsTargetPlayerSide, 2 + jumpretfalse MakingItRainOnOpponent + jumprettrue MakingItRainOnPlayer +MakingItRainContinue: + waitbgfadeout + createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, 7, 1, 11, 1 + loopsewithpan SE_M_PAY_DAY, SOUND_PAN_TARGET, 8, 15 + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -5, 0, -5, 1 + delay 2 + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 5, 0, 6, 1 + delay 2 + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 19, 0, 10, 1 + delay 2 + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -23, 0, -10, 1 + createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 5, 50, 1 + createvisualtask AnimTask_ShakeMon, 2, ANIM_DEF_PARTNER, 0, 5, 50, 1 + call MakingItRain + call MakingItRain + call MakingItRain + restorebg + waitbgfadein + blendoff + waitforvisualfinish + clearmonbg ANIM_ATTACKER + end +MakingItRainOnOpponent: + fadetobg BG_IMPACT_OPPONENT + goto MakingItRainContinue +MakingItRainOnPlayer: + fadetobg BG_IMPACT_PLAYER + goto MakingItRainContinue +MakingItRain: + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -20, 0, -10, 1 + delay 2 + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 28, 0, 10, 1 + delay 2 + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -10, 0, -5, 1 + delay 2 + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 10, 0, 6, 1 + delay 2 + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 24, 0, 10, 1 + delay 2 + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -32, 0, -10, 1 + delay 2 + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, -20, 0, -10, 1 + delay 2 + createsprite gMakingItRainTemplate, ANIM_TARGET, 2, 30, 0, 10, 1 + delay 2 + return + +Move_SHED_TAIL:: + loopsewithpan SE_M_TAIL_WHIP, SOUND_PAN_ATTACKER, 24, 3 + createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 12, 4, 2, 3 + waitforvisualfinish + playsewithpan SE_M_ATTRACT, SOUND_PAN_ATTACKER + createvisualtask AnimTask_MonToSubstitute, 2 + end + +Move_HYPER_DRILL:: + loadspritegfx ANIM_TAG_IMPACT + loadspritegfx ANIM_TAG_HORN_HIT + fadetobgfromset BG_GUILLOTINE_OPPONENT, BG_GUILLOTINE_PLAYER, BG_GUILLOTINE_CONTESTS + waitbgfadein + createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 0 + playsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER + waitforvisualfinish + delay 2 + createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 1 + createsprite gHornHitSpriteTemplate, ANIM_TARGET, 4, 0, 0, 12 + waitforvisualfinish + playse 20 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 2, 0, 40, 1 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 10, 0, 40, 1 + createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, 1, 3 + playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET + delay 4 + createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 2, 1, 3 + playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET + delay 4 + createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -4, 3, 1, 3 + playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET + delay 4 + createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -8, -5, 1, 3 + playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET + delay 4 + createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 4, -12, 1, 3 + playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET + delay 4 + createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 16, 0, 1, 3 + playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET + delay 4 + createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 5, 18, 1, 3 + playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET + delay 4 + createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -17, 12, 1, 2 + playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET + delay 4 + createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, -21, -15, 1, 2 + playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET + delay 4 + createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 8, -27, 1, 2 + playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET + delay 4 + createsprite gFlashingHitSplatSpriteTemplate, ANIM_TARGET, 3, 32, 0, 1, 2 + playsewithpan SE_M_HORN_ATTACK, SOUND_PAN_TARGET + delay 4 + createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 2, 2 + createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_BLACK, 8, RGB_BLACK, 0 + playsewithpan SE_M_RAZOR_WIND, SOUND_PAN_TARGET + waitforvisualfinish + createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, F_PAL_BG | F_PAL_BATTLERS, 3, 1, RGB_BLACK, 8, RGB_BLACK, 0 + restorebg + waitbgfadein + blendoff + end + +Move_TWIN_BEAM:: + loadspritegfx ANIM_TAG_BLUE_RING + loadspritegfx ANIM_TAG_GOLD_RING + playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER + call SetPsychicBackground + createvisualtask AnimTask_StartSinAnimTimer, 5, 100 + createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_TELEPORT, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 2, 9, 0, 10 + call PsywaveRings + call PsybeamRings + call PsywaveRings + call PsybeamRings + createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 1, 4, 0, 12, RGB(31, 18, 31) + call PsywaveRings + call PsybeamRings + call PsywaveRings + call PsybeamRings + call PsywaveRings + call PsybeamRings + call PsywaveRings + call PsybeamRings + waitforvisualfinish + delay 1 + call UnsetPsychicBg + end + +Move_COMEUPPANCE:: + loadspritegfx ANIM_TAG_IMPACT + monbg ANIM_TARGET + fadetobg BG_DARK + waitbgfadein + delay 0 + playsewithpan SE_M_DRAGON_RAGE, SOUND_PAN_ATTACKER + createvisualtask AnimTask_ShakeMon2, 5, ANIM_ATTACKER, 1, 0, 15, 1 + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 3, 0, 9, RGB_RED + waitforvisualfinish + delay 10 + createvisualtask AnimTask_SwayMon, 5, 0, 16, 6144, 8, ANIM_ATTACKER + delay 5 + setalpha 12, 8 + createvisualtask AnimTask_ShakeMon2, 5, ANIM_TARGET, 4, 0, 30, 1 + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1, 0 + playsewithpan SE_M_COMET_PUNCH, +63 + delay 5 + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 24, 8, 1, 0 + playsewithpan SE_M_COMET_PUNCH, +63 + delay 5 + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -24, -16, 1, 0 + playsewithpan SE_M_COMET_PUNCH, +63 + delay 5 + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 8, 4, 1, 0 + playsewithpan SE_M_COMET_PUNCH, +63 + delay 5 + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -16, 19, 1, 0 + playsewithpan SE_M_COMET_PUNCH, +63 + delay 5 + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 18, -18, 1, 0 + playsewithpan SE_M_COMET_PUNCH, +63 + waitforvisualfinish + clearmonbg ANIM_TARGET + blendoff + restorebg + waitbgfadein + createvisualtask AnimTask_BlendBattleAnimPal, 10, F_PAL_ATTACKER, 3, 9, 0, RGB_RED + waitforvisualfinish + clearmonbg ANIM_DEF_PARTNER + end + +Move_BLOOD_MOON:: + loadspritegfx ANIM_TAG_BLOOD_MOON + loadspritegfx ANIM_TAG_BEAM + loadspritegfx ANIM_TAG_RED_EXPLOSION + createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_BG, 0, 16, 16, RGB_BLACK + createsprite gVerticalDipSpriteTemplate, ANIM_ATTACKER, 2, 8, 1, ANIM_ATTACKER + delay 8 + playsewithpan SE_M_BARRIER, SOUND_PAN_ATTACKER + createsprite gMoonUpSpriteTemplate, ANIM_ATTACKER, 2 + waitforvisualfinish + delay 15 + playsewithpan SE_M_DETECT, 0 + waitforvisualfinish + createvisualtask AnimTask_IsTargetPlayerSide, 2 + jumpargeq 7 ANIM_TARGET BloodMoonOnPlayer +BloodMoonOnOpponent: + createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_HYPER_BEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 1, 10, 0, 5 + call BloodMoonOnslaughtOpponent + call BloodMoonOnslaughtOpponent + call BloodMoonOnslaughtOpponent + call BloodMoonOnslaughtOpponent + call BloodMoonOnslaughtOpponent + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 6, 5, 1, 0 + delay 0 + waitforvisualfinish + goto BloodMoonFinish +BloodMoonOnPlayer: + createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_HYPER_BEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 1, 10, 0, 5 + call BloodMoonOnslaughtPlayer + call BloodMoonOnslaughtPlayer + call BloodMoonOnslaughtPlayer + call BloodMoonOnslaughtPlayer + call BloodMoonOnslaughtPlayer + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + delay 0 + waitforvisualfinish +BloodMoonFinish: + createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_BG, 0, 0, 0, RGB_BLACK + waitforvisualfinish + clearmonbg ANIM_ATTACKER + end +BloodMoonOnslaughtOpponent: + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 6, 5, 1, 0 + delay 0 + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, -16, -15, 1, 0 + delay 0 + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 16, -5, 1, 0 + delay 0 + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, -12, 18, 1, 0 + delay 0 + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 140, -16, 165, 40, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 0, 5, 1, 0 + delay 0 + return +BloodMoonOnslaughtPlayer: + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 6, 5, 1, 0 + delay 0 + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, -16, -15, 1, 0 + delay 0 + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 16, -5, 1, 0 + delay 0 + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, -12, 18, 1, 0 + delay 0 + createsprite gBloodMoonOnslaughtSpriteTemplate, ANIM_TARGET, 2, 40, -16, 75, 80, 4 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 + createsprite gRedExplosionSpriteTemplate, ANIM_TARGET, 4, 0, 5, 1, 0 + delay 0 + return + +Move_FICKLE_BEAM:: + createvisualtask AnimTask_IsPowerOver99, 2 + waitforvisualfinish + jumpreteq FALSE, FickleBeamRegular + jumpreteq TRUE, FickleBeamIntense +FickleBeamRegular: + loadspritegfx ANIM_TAG_GOLD_RING + playsewithpan SE_M_PSYBEAM, SOUND_PAN_ATTACKER + createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_PSYBEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 3, 4, 0, 15 + call PsybeamRings + call PsybeamRings + createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 4, 25, 1 + createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_TARGET, 2, 2, 0, 12, RGB(15, 8, 30) + call PsybeamRings + call PsybeamRings + call PsybeamRings + call PsybeamRings + call PsybeamRings + call PsybeamRings + call PsybeamRings + call PsybeamRings + call PsybeamRings + waitforvisualfinish + end +FickleBeamIntense: + loadspritegfx ANIM_TAG_ORBS + fadetobgfromset BG_SPACIAL_REND_ON_OPPONENT BG_SPACIAL_REND_ON_PLAYER BG_SPACIAL_REND_ON_OPPONENT + waitbgfadein + delay 10 + playsewithpan SE_M_HYPER_BEAM, SOUND_PAN_ATTACKER + createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATTACKER, 1, 0, 4, 1 + waitforvisualfinish + delay 30 + createsoundtask SoundTask_LoopSEAdjustPanning, SE_M_HYPER_BEAM2, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 1, 15, 0, 5 + createvisualtask AnimTask_ShakeMon, 2, ANIM_ATTACKER, 0, 4, 50, 1 + createvisualtask AnimTask_FlashAnimTagWithColor, 2, ANIM_TAG_ORBS, 1, 12, RGB_RED, 16, 0, 0 + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 50, 1 + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + call HyperBeamOrbs + waitforvisualfinish + restorebg + waitbgfadein + end + +Move_THUNDERCLAP:: + loadspritegfx ANIM_TAG_LIGHTNING + monbg ANIM_ATK_PARTNER + setalpha 12, 8 + createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 24, 6, 1, 5 + createvisualtask AnimTask_TraceMonBlended, 2, 0, 4, 7, 3 + playsewithpan SE_M_JUMP_KICK, SOUND_PAN_ATTACKER + delay 4 + playsewithpan SE_M_THUNDER_WAVE, SOUND_PAN_TARGET + delay 1 + createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, -32 + playsewithpan SE_M_TRI_ATTACK2, SOUND_PAN_TARGET + delay 1 + createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, -16 + delay 1 + createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, 0 + delay 1 + createsprite gLightningSpriteTemplate, ANIM_TARGET, 2, 0, 16 + delay 10 + createvisualtask AnimTask_ShakeTargetInPattern, 2, 30, 3, TRUE, 0 + delay 2 + createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_BG, 3, 16, 0, RGB_WHITE + createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_TARGET, 0, 16, 16, RGB_BLACK + delay 4 + createvisualtask AnimTask_BlendBattleAnimPal, 5, F_PAL_TARGET, 0, 0, 0, RGB_BLACK + waitforvisualfinish + clearmonbg ANIM_ATK_PARTNER + blendoff + waitforvisualfinish + end + +Move_HARD_PRESS:: + loadspritegfx ANIM_TAG_EXPLOSION + loadspritegfx ANIM_TAG_ACUPRESSURE + loadspritegfx ANIM_TAG_PURPLE_HAND_OUTLINE + setalpha 15, 0 + call SetSteelBeamBackground + createvisualtask AnimTask_CompressTargetHorizontallyFast, 2 + createsprite gCrushGripExplosionTemplate, ANIM_TARGET, 0, 0, 0, 1, 1 + delay 3 + playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER + createsprite gCrushGripExplosionTemplate, ANIM_TARGET, 0, 24, -24, 1, 1 + delay 3 + playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER + createsprite gCrushGripExplosionTemplate, ANIM_TARGET, 0, -16, 16, 1, 1 + delay 3 + playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER + createsprite gCrushGripExplosionTemplate, ANIM_TARGET, 0, -24, -12, 1, 1 + delay 3 + playsewithpan SE_M_EXPLOSION, SOUND_PAN_ATTACKER + createsprite gCrushGripExplosionTemplate, ANIM_TARGET, 0, 16, 16, 1, 1 + waitforvisualfinish + blendoff + call UnsetHighSpeedBg + end + +Move_DRAGON_CHEER:: + loadspritegfx ANIM_TAG_NOISE_LINE + loadspritegfx ANIM_TAG_CONFETTI + loadspritegfx ANIM_TAG_PINK_CLOUD + createvisualtask AnimTask_DeepInhale, 2, ANIM_ATTACKER + delay 12 + call RoarEffect + createvisualtask SoundTask_PlayCryHighPitch, 2, ANIM_ATTACKER, 3 + waitforvisualfinish + monbg ANIM_ATTACKER + playsewithpan SE_BALL_OPEN, SOUND_PAN_TARGET + createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 122, 3, -14, 18, 24 + createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 121, 3, 14, 6, 24 + createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 120, 3, -12, 12, 24 + createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 119, 3, 14, 18, 24 + createsprite gSmokeBallEscapeCloudSpriteTemplate, ANIM_ATTACKER, 118, 3, 0, 0, 24 + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + call CreateFlatterConfetti + waitforvisualfinish + clearmonbg ANIM_ATTACKER + delay 10 + end + +Move_MALIGNANT_CHAIN:: + loadspritegfx ANIM_TAG_PURPLE_CHAIN + loadspritegfx ANIM_TAG_POISON_BUBBLE + loopsewithpan SE_M_SCRATCH, SOUND_PAN_TARGET, 6, 2 + createsprite gChainBindingSpriteTemplate, ANIM_TARGET, 4, 0, 16, 0, 1 + delay 7 + createsprite gChainBindingSpriteTemplate, ANIM_TARGET, 2, 0, 8, 1, 1 + delay 3 + createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 2, 0, 8, 1 + delay 20 + setarg 7, -1 + playsewithpan SE_M_BIND, SOUND_PAN_TARGET + waitforvisualfinish + call PoisonBubblesEffect + waitforvisualfinish + end + Move_TERA_BLAST:: Move_ORDER_UP:: -Move_SPIN_OUT:: Move_POPULATION_BOMB:: Move_GLAIVE_RUSH:: Move_REVIVAL_BLESSING:: Move_SALT_CURE:: Move_TRIPLE_DIVE:: -Move_MORTAL_SPIN:: Move_DOODLE:: -Move_FILLET_AWAY:: -Move_FLOWER_TRICK:: -Move_MAKE_IT_RAIN:: Move_RUINATION:: Move_COLLISION_COURSE:: Move_ELECTRO_DRIFT:: -Move_SHED_TAIL:: -Move_HYPER_DRILL:: -Move_TWIN_BEAM:: Move_ARMOR_CANNON:: -Move_COMEUPPANCE:: Move_BLAZING_TORQUE:: Move_WICKED_TORQUE:: Move_NOXIOUS_TORQUE:: Move_COMBAT_TORQUE:: Move_MAGICAL_TORQUE:: Move_PSYBLADE:: -Move_BLOOD_MOON:: Move_MATCHA_GOTCHA:: Move_TERA_STARSTORM:: -Move_FICKLE_BEAM:: -Move_THUNDERCLAP:: Move_MIGHTY_CLEAVE:: Move_TACHYON_CUTTER:: -Move_HARD_PRESS:: -Move_DRAGON_CHEER:: Move_SUPERCELL_SLAM:: -Move_MALIGNANT_CHAIN:: end @to do @@@@@@@@@@@@@@@@@@@@@@@ GEN 1-3 @@@@@@@@@@@@@@@@@@@@@@@ diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index beb3bd5423..a366055658 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -30,6 +30,19 @@ BattleScript_DamageToQuarterTargetHP:: damagetoquartertargethp goto BattleScript_HitFromAtkAnimation +BattleScript_EffectFickleBeam:: + attackcanceler + attackstring + ppreduce + accuracycheck BattleScript_MoveMissedPause, ACC_CURR_MOVE + ficklebeamdamagecalculation + goto BattleScript_HitFromCritCalc +BattleScript_FickleBeamDoubled:: + pause B_WAIT_TIME_SHORTEST + printstring STRINGID_FICKLEBEAMDOUBLED + waitmessage B_WAIT_TIME_LONG + goto BattleScript_HitFromCritCalc + BattleScript_Terastallization:: @ TODO: no string prints in S/V, but right now this helps with clarity printstring STRINGID_PKMNSTORINGENERGY diff --git a/graphics/battle_anims/sprites/beam.png b/graphics/battle_anims/sprites/beam.png new file mode 100644 index 0000000000000000000000000000000000000000..cce0a23a4c2951b215346f396b1507507a15b1bf GIT binary patch literal 383 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0J3?w7mbKU|e_7YEDSN0bijKaDyQ(Rb*fI{LW zt`Q}{`DrEPiAAXl?mjL+V-(6#ixiCYObT0z;le!RLk zxyZZv*Y1P$ncuIQyl8N|z}&om-AKcMjkV(e%e~7FSo$Ib9C(=w7}XB2%wP~sVDf3; zG+>lwv}V+1}`-{yl(%&x`9K0QOSX&gF#S%iOrEeC7^+aOTdv;X$4U83P%Q* elnYE<1OJkYPN(I-ViM0_5DRAz|C${4tFacO8x{0q zF8T!&VNCLNclp1R{nJq(`<EQwELoyM)whc?AdYImMwNGGt{d`_@dRFMxWl60w+9T}0@`PntHC*N4+QhZ}^}>$} zUA~rjv!~t9`}SOM+UkYr&3y)LjI(~9{qUP7BI8+Dw6vz&+$DcDR-S24$Ul-Q=^9-1 zQIa9|sc+_Tmn)5tKZ_q6lh9AzaQjD~`#2D{M1rPkks_(7Pt=+oT3AAB|)swWlejMGPSdCo6WjMxJ&tP7oBydmNb4 zmFF(CiQ}k|hWAI)pA%Eoe(t%nxOC+~5p|{LR=w}tS_-O7YKkeUX$PFNrMEwteBxzf z`=Se78kbJq+jaGh{GOly|_W^~( zOI#yLg7ec#$`gxH8QgtbfW|14r4}g|>zNd`E_n!4!ckJ-=MI!H2C^Bv8Z_mB6id3J zuOkD)#(wTUiL5}rL4Z$)E0CVxJT1{6^1NsE9Gi+uh~=Qua?rf$T}1 zE{-7;bKXv`%{#2Xb2Rrm(~TI0nx+YN{^u1hS$OG);jJZkSHryjYWwql{#X~#Q2sY& zp&!f6sW%p6_VNlHZDQNlAhuuwd(@;Q0Sc#6W+@f+N0`bmvS`XBs&>grC2+FtoDz}X zE7q%`vPed6YL;%H^a`$zNw3}n%yhMA(X{yYZ{75j^-L2=jeO@asmL+rX-PT`c7Be>uGNp2^CJokY(FI)XYApu ze$wp3X4Ud$B7gPi_GR)v5)9jdFDuKxd9LzDyJp9oZRsB!@AS15rt^E2thD61^kgB& z>obYE8x=k;IcZaQ@Lu2-JXNj1Ie_Iq{0*X&hS3j3^P6Ix5ep^rs7ykeNw;N&Jv-(G1^&lK49K#VLV{6@ymTg8_T?CV)fbv{iZOEQr6<8Zh4pagJeI zWjyj@Oza6Mg!p8a}c_n=cbfOgCvX2DzvR_)^*b)HePr>?s7j7MbQ(; zRNR;4AwT*QMVUN+Xp@-OeXHbk#-_|U+@s%~8FluJd}mInfHfs_@j!^tusJqLs)N^) z^s6&SUZ<4;VF#X8LJd~f+iWZVMyWq=4uJhe16EF~y%>Tr%ygHWe5@-yH-Plh5R^^( zwRfjC3kw6SeP{#uH#x3X|tU887u(&=6Bbm; z)$i3f6#9NRAGj=>kM_7VBkg2aoz=lYlU?sP4)in3$3Ia&xtPO{3Rq*K5%@*k-CqEI zymIv%48U;7`564S$Z7{b&ByOlS^0>n`^1*@Nv*^EAS59rK=jh)LH-yF!}sIx11ZDd Ux%QAR^#A|>07*qoM6N<$g6eam;{X5v literal 0 HcmV?d00001 diff --git a/include/battle.h b/include/battle.h index fdc9575b24..1d60aacec1 100644 --- a/include/battle.h +++ b/include/battle.h @@ -800,6 +800,7 @@ struct BattleStruct u8 distortedTypeMatchups; u8 categoryOverride; // for Z-Moves and Max Moves u32 stellarBoostFlags[NUM_BATTLE_SIDES]; // stored as a bitfield of flags for all types for each side + u8 fickleBeamBoosted:1; }; // The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider, diff --git a/include/battle_anim.h b/include/battle_anim.h index ce9749685e..6ff7e9ff22 100644 --- a/include/battle_anim.h +++ b/include/battle_anim.h @@ -253,6 +253,7 @@ void AnimParticleBurst(struct Sprite *); void AnimPowerAbsorptionOrb(struct Sprite *sprite); void AnimNeedleArmSpike(struct Sprite *); void AnimTask_CompressTargetHorizontally(u8 taskId); +void AnimTask_CompressTargetHorizontallyFast(u8 taskId); void AnimSporeParticle(struct Sprite *sprite); void AnimAbsorptionOrb(struct Sprite *sprite); void AnimPetalDanceSmallFlower(struct Sprite *sprite); diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 0c9f72c276..6bdb88b28f 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -843,5 +843,7 @@ extern const u8 BattleScript_EffectUpperHand[]; extern const u8 BattleScript_EffectTidyUp[]; extern const u8 BattleScript_EffectSpicyExtract[]; extern const u8 BattleScript_DamageToQuarterTargetHP[]; +extern const u8 BattleScript_EffectFickleBeam[]; +extern const u8 BattleScript_FickleBeamDoubled[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/constants/battle_anim.h b/include/constants/battle_anim.h index 389cd7e127..54573a4868 100644 --- a/include/constants/battle_anim.h +++ b/include/constants/battle_anim.h @@ -412,6 +412,10 @@ #define ANIM_TAG_TERA_CRYSTAL (ANIM_SPRITES_START + 398) #define ANIM_TAG_TERA_SHATTER (ANIM_SPRITES_START + 399) #define ANIM_TAG_DREEPY_SHINY (ANIM_SPRITES_START + 400) +#define ANIM_TAG_BLOOD_MOON (ANIM_SPRITES_START + 401) +#define ANIM_TAG_BEAM (ANIM_SPRITES_START + 402) +#define ANIM_TAG_RED_EXPLOSION (ANIM_SPRITES_START + 403) +#define ANIM_TAG_PURPLE_CHAIN (ANIM_SPRITES_START + 404) // battlers #define ANIM_ATTACKER 0 diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index 1e6e2d86d7..9529e026c1 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -712,8 +712,9 @@ #define STRINGID_FOGISDEEP 710 #define STRINGID_FOGLIFTED 711 #define STRINGID_PKMNMADESHELLGLEAM 712 +#define STRINGID_FICKLEBEAMDOUBLED 713 -#define BATTLESTRINGS_COUNT 713 +#define BATTLESTRINGS_COUNT 714 // This is the string id that gBattleStringsTable starts with. // String ids before this (e.g. STRINGID_INTROMSG) are not in the table, diff --git a/include/graphics.h b/include/graphics.h index 01de060b79..4cb944af8a 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -2724,6 +2724,8 @@ extern const u32 gBattleAnimSpritePal_AuraSphere[]; extern const u32 gBattleAnimSpritePal_AvalancheRocks[]; extern const u32 gBattleAnimSpriteGfx_NewPokeball[]; extern const u32 gBattleAnimSpritePal_NewPokeball[]; +extern const u32 gBattleAnimSpriteGfx_Beam[]; +extern const u32 gBattleAnimSpritePal_Beam[]; extern const u32 gBattleAnimSpriteGfx_BerryEaten[]; extern const u32 gBattleAnimSpritePal_BerryEaten[]; extern const u32 gBattleAnimSpriteGfx_BerryNormal[]; @@ -2732,6 +2734,8 @@ extern const u32 gBattleAnimSpriteGfx_BigRock[]; extern const u32 gBattleAnimSpritePal_BigRock[]; extern const u32 gBattleAnimSpriteGfx_BlacephalonHead[]; extern const u32 gBattleAnimSpritePal_BlacephalonHead[]; +extern const u32 gBattleAnimSpriteGfx_BloodMoon[]; +extern const u32 gBattleAnimSpritePal_BloodMoon[]; extern const u32 gBattleAnimSpritePal_BlueFlare[]; extern const u32 gBattleAnimSpriteGfx_Branch[]; extern const u32 gBattleAnimSpritePal_Branch[]; @@ -2825,12 +2829,16 @@ extern const u32 gBattleAnimSpriteGfx_PoisonColumn[]; extern const u32 gBattleAnimSpritePal_PoisonColumn[]; extern const u32 gBattleAnimSpriteGfx_PowerTrick[]; extern const u32 gBattleAnimSpritePal_PowerTrick[]; +extern const u32 gBattleAnimSpriteGfx_PurpleChain[]; +extern const u32 gBattleAnimSpritePal_PurpleChain[]; extern const u32 gBattleAnimSpriteGfx_PurpleDrake[]; extern const u32 gBattleAnimSpritePal_PurpleDrake[]; extern const u32 gBattleAnimSpriteGfx_QuickGuard[]; extern const u32 gBattleAnimSpritePal_QuickGuard[]; extern const u32 gBattleAnimSpriteGfx_RazorShell[]; extern const u32 gBattleAnimSpritePal_RazorShell[]; +extern const u32 gBattleAnimSpriteGfx_RedExplosion[]; +extern const u32 gBattleAnimSpritePal_RedExplosion[]; extern const u32 gBattleAnimSpriteGfx_RocksSmall[]; extern const u32 gBattleAnimSpriteGfx_NewRocks[]; extern const u32 gBattleAnimSpritePal_NewRocks[]; diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index b917cdc9a5..d8283fc7dc 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -3101,6 +3101,17 @@ const struct SpriteTemplate gPsyshockSmokeSpriteTemplate = .callback = AnimSpriteOnMonPos, }; +const struct SpriteTemplate gChainBindingSpriteTemplate = +{ + .tileTag = ANIM_TAG_PURPLE_CHAIN, + .paletteTag = ANIM_TAG_PURPLE_CHAIN, + .oam = &gOamData_AffineNormal_ObjNormal_64x32, + .anims = sAnims_ConstrictBinding, + .images = NULL, + .affineAnims = sAffineAnims_ConstrictBinding, + .callback = AnimConstrictBinding, +}; + // functions static void AnimGrassKnot(struct Sprite *sprite) { @@ -7229,6 +7240,14 @@ static const union AffineAnimCmd sCompressTargetHorizontallyAffineAnimCmds[] = AFFINEANIMCMD_END, }; +static const union AffineAnimCmd sCompressTargetHorizontallyAffineAnimCmdsFast[] = +{ + AFFINEANIMCMD_FRAME(32, 0, 0, 16), //Compress + AFFINEANIMCMD_FRAME(0, 0, 0, 32), + AFFINEANIMCMD_FRAME(-32, 0, 0, 16), + AFFINEANIMCMD_END, +}; + static void AnimTask_CompressTargetStep(u8 taskId) { struct Task* task = &gTasks[taskId]; @@ -7245,6 +7264,14 @@ void AnimTask_CompressTargetHorizontally(u8 taskId) task->func = AnimTask_CompressTargetStep; } +void AnimTask_CompressTargetHorizontallyFast(u8 taskId) +{ + struct Task* task = &gTasks[taskId]; + u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET); + PrepareAffineAnimInTaskData(task, spriteId, sCompressTargetHorizontallyAffineAnimCmdsFast); + task->func = AnimTask_CompressTargetStep; +} + void AnimTask_CreateSmallSteelBeamOrbs(u8 taskId) { if (--gTasks[taskId].data[0] == -1) diff --git a/src/battle_anim_new.c b/src/battle_anim_new.c index f023859b59..cd89b6aab7 100644 --- a/src/battle_anim_new.c +++ b/src/battle_anim_new.c @@ -99,6 +99,7 @@ static void SpriteCB_GlacialLance_Step1(struct Sprite* sprite); static void SpriteCB_GlacialLance_Step2(struct Sprite* sprite); static void SpriteCB_GlacialLance(struct Sprite* sprite); static void SpriteCB_TripleArrowKick(struct Sprite* sprite); +static void AnimMakingItRain(struct Sprite *sprite); // const data // general @@ -7234,6 +7235,51 @@ const struct SpriteTemplate gBitterBladeImpactTemplate = .callback = AnimClawSlash }; +// Make It Rain +const struct SpriteTemplate gMakingItRainTemplate = +{ + .tileTag = ANIM_TAG_COIN, + .paletteTag = ANIM_TAG_COIN, + .oam = &gOamData_AffineNormal_ObjNormal_16x16, + .anims = gCoinAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimMakingItRain, +}; + +const struct SpriteTemplate gRedExplosionSpriteTemplate = +{ + .tileTag = ANIM_TAG_RED_EXPLOSION, + .paletteTag = ANIM_TAG_RED_EXPLOSION, + .oam = &gOamData_AffineOff_ObjNormal_32x32, + .anims = gExplosionAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimSpriteOnMonPos, +}; + +const struct SpriteTemplate gBloodMoonOnslaughtSpriteTemplate = +{ + .tileTag = ANIM_TAG_BEAM, + .paletteTag = ANIM_TAG_BEAM, + .oam = &gOamData_AffineNormal_ObjBlend_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = sArrowRaidOnslaughtAffineAnimTable, + .callback = AnimAssistPawprint +}; + +const struct SpriteTemplate gMoonUpSpriteTemplate = +{ + .tileTag = ANIM_TAG_BLOOD_MOON, + .paletteTag = ANIM_TAG_BLOOD_MOON, + .oam = &gOamData_AffineOff_ObjNormal_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = AnimWeatherBallUp, +}; + // functions //general void AnimTask_IsTargetPartner(u8 taskId) @@ -9219,3 +9265,23 @@ void AnimTask_StickySyrup(u8 taskId) gBattleAnimArgs[0] = gAnimDisableStructPtr->syrupBombIsShiny; DestroyAnimVisualTask(taskId); } + +static void AnimMakingItRain(struct Sprite *sprite) +{ + if (gBattleAnimArgs[3] != 0) + SetAverageBattlerPositions(gBattleAnimTarget, FALSE, &sprite->x, &sprite->y); //coin shower on target + + sprite->x += gBattleAnimArgs[0]; + sprite->y += 14; + StartSpriteAnim(sprite, gBattleAnimArgs[1]); + AnimateSprite(sprite); + sprite->data[0] = 0; + sprite->data[1] = 0; + sprite->data[2] = 4; + sprite->data[3] = 16; + sprite->data[4] = -70; + sprite->data[5] = gBattleAnimArgs[2]; + StoreSpriteCallbackInData6(sprite, AnimFallingRock_Step); + sprite->callback = TranslateSpriteInEllipse; + sprite->callback(sprite); +} diff --git a/src/battle_message.c b/src/battle_message.c index 87ac5326fb..497e617601 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -849,9 +849,11 @@ static const u8 sText_ShedItsTail[] = _("{B_ATK_NAME_WITH_PREFIX} shed its tail\ static const u8 sText_PkmnTerastallizedInto[] = _("{B_ATK_NAME_WITH_PREFIX} terastallized\ninto the {B_BUFF1} type!"); static const u8 sText_SupersweetAromaWafts[] = _("A supersweet aroma is wafting from\nthe syrup covering {B_ATK_NAME_WITH_PREFIX}!"); static const u8 sText_TidyingUpComplete[] = _("Tidying up complete!"); +static const u8 sText_FickleBeamDoubled[] = _("{B_ATK_NAME_WITH_PREFIX} is going all\nout for this attack!"); const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = { + [STRINGID_FICKLEBEAMDOUBLED - BATTLESTRINGS_TABLE_START] = sText_FickleBeamDoubled, [STRINGID_PKMNTERASTALLIZEDINTO - BATTLESTRINGS_TABLE_START] = sText_PkmnTerastallizedInto, [STRINGID_TIDYINGUPCOMPLETE - BATTLESTRINGS_TABLE_START] = sText_TidyingUpComplete, [STRINGID_SUPERSWEETAROMAWAFTS - BATTLESTRINGS_TABLE_START] = sText_SupersweetAromaWafts, diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 8056b3ddf2..afc63fed9b 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6402,6 +6402,7 @@ static void Cmd_moveend(void) gBattleStruct->enduredDamage = 0; gBattleStruct->additionalEffectsCounter = 0; gBattleStruct->poisonPuppeteerConfusion = FALSE; + gBattleStruct->fickleBeamBoosted = FALSE; if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE) SetActiveGimmick(gBattlerAttacker, GIMMICK_NONE); gBattleStruct->distortedTypeMatchups = 0; @@ -17132,3 +17133,19 @@ void BS_DamageToQuarterTargetHP(void) gBattlescriptCurrInstr = cmd->nextInstr; } + +void BS_FickleBeamDamageCalculation(void) +{ + NATIVE_ARGS(); + gBattleStruct->fickleBeamBoosted = FALSE; + + if (RandomPercentage(RNG_FICKLE_BEAM, 30)) + { + gBattleStruct->fickleBeamBoosted = TRUE; + gBattlescriptCurrInstr = BattleScript_FickleBeamDoubled; + } + else + { + gBattlescriptCurrInstr = cmd->nextInstr; + } +} diff --git a/src/battle_util.c b/src/battle_util.c index 3be34d1afc..71f6e3581b 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -9073,7 +9073,7 @@ static inline u32 CalcMoveBasePower(u32 move, u32 battlerAtk, u32 battlerDef, u3 basePower = (basePower > 350) ? 350 : basePower; break; case EFFECT_FICKLE_BEAM: - if (RandomPercentage(RNG_FICKLE_BEAM, 30)) + if (gBattleStruct->fickleBeamBoosted) basePower *= 2; break; case EFFECT_TERA_BLAST: diff --git a/src/data/battle_anim.h b/src/data/battle_anim.h index ec98ecd854..72a3c7121b 100644 --- a/src/data/battle_anim.h +++ b/src/data/battle_anim.h @@ -1461,6 +1461,10 @@ const struct CompressedSpriteSheet gBattleAnimPicTable[] = {gBattleAnimSpriteGfx_TeraCrystal, 0x800, ANIM_TAG_TERA_CRYSTAL}, {gBattleAnimSpriteGfx_TeraShatter, 0x0180, ANIM_TAG_TERA_SHATTER}, {gBattleAnimSpriteGfx_DreepyMissile, 0x200, ANIM_TAG_DREEPY_SHINY}, + {gBattleAnimSpriteGfx_BloodMoon, 0x0800, ANIM_TAG_BLOOD_MOON}, + {gBattleAnimSpriteGfx_RedExplosion, 0x0800, ANIM_TAG_RED_EXPLOSION}, + {gBattleAnimSpriteGfx_Beam, 0x0800, ANIM_TAG_BEAM}, + {gBattleAnimSpriteGfx_PurpleChain, 0x1000, ANIM_TAG_PURPLE_CHAIN}, }; const struct CompressedSpritePalette gBattleAnimPaletteTable[] = @@ -1923,6 +1927,10 @@ const struct CompressedSpritePalette gBattleAnimPaletteTable[] = {gBattleAnimSpritePal_TeraCrystal, ANIM_TAG_TERA_CRYSTAL}, {gBattleAnimSpritePal_TeraShatter, ANIM_TAG_TERA_SHATTER}, {gBattleAnimSpritePal_DreepyMissileShiny, ANIM_TAG_DREEPY_SHINY}, + {gBattleAnimSpritePal_BloodMoon, ANIM_TAG_BLOOD_MOON}, + {gBattleAnimSpritePal_RedExplosion, ANIM_TAG_RED_EXPLOSION}, + {gBattleAnimSpritePal_Beam, ANIM_TAG_BEAM}, + {gBattleAnimSpritePal_PurpleChain, ANIM_TAG_PURPLE_CHAIN}, }; const struct BattleAnimBackground gBattleAnimBackgroundTable[] = diff --git a/src/data/battle_move_effects.h b/src/data/battle_move_effects.h index f970f0e9f7..ead7cee6f1 100644 --- a/src/data/battle_move_effects.h +++ b/src/data/battle_move_effects.h @@ -2169,7 +2169,7 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = [EFFECT_FICKLE_BEAM] = { - .battleScript = BattleScript_EffectHit, + .battleScript = BattleScript_EffectFickleBeam, .battleTvScore = 0, // TODO: Assign points }, diff --git a/src/graphics.c b/src/graphics.c index c35cec3467..b1e1a91678 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -81,6 +81,9 @@ const u32 gBattleAnimSpritePal_AvalancheRocks[] = INCBIN_U32("graphics/battle_an const u32 gBattleAnimSpriteGfx_NewPokeball[] = INCBIN_U32("graphics/battle_anims/sprites/baton_pass_ball.4bpp.lz"); const u32 gBattleAnimSpritePal_NewPokeball[] = INCBIN_U32("graphics/battle_anims/sprites/baton_pass_ball.gbapal.lz"); +const u32 gBattleAnimSpriteGfx_Beam[] = INCBIN_U32("graphics/battle_anims/sprites/beam.4bpp.lz"); +const u32 gBattleAnimSpritePal_Beam[] = INCBIN_U32("graphics/battle_anims/sprites/beam.gbapal.lz"); + const u32 gBattleAnimSpriteGfx_BerryEaten[] = INCBIN_U32("graphics/battle_anims/sprites/berry_eaten.4bpp.lz"); const u32 gBattleAnimSpritePal_BerryEaten[] = INCBIN_U32("graphics/battle_anims/sprites/berry_eaten.gbapal.lz"); @@ -93,6 +96,9 @@ const u32 gBattleAnimSpritePal_BigRock[] = INCBIN_U32("graphics/battle_anims/spr const u32 gBattleAnimSpriteGfx_BlacephalonHead[] = INCBIN_U32("graphics/battle_anims/sprites/blacephalon_head.4bpp.lz"); const u32 gBattleAnimSpritePal_BlacephalonHead[] = INCBIN_U32("graphics/battle_anims/sprites/blacephalon_head.gbapal.lz"); +const u32 gBattleAnimSpriteGfx_BloodMoon[] = INCBIN_U32("graphics/battle_anims/sprites/blood_moon.4bpp.lz"); +const u32 gBattleAnimSpritePal_BloodMoon[] = INCBIN_U32("graphics/battle_anims/sprites/blood_moon.gbapal.lz"); + const u32 gBattleAnimSpritePal_BlueFlare[] = INCBIN_U32("graphics/battle_anims/sprites/blue_flare.gbapal.lz"); const u32 gBattleAnimSpriteGfx_Branch[] = INCBIN_U32("graphics/battle_anims/sprites/branch.4bpp.lz"); @@ -233,12 +239,18 @@ const u32 gBattleAnimSpritePal_PoisonColumn[] = INCBIN_U32("graphics/battle_anim const u32 gBattleAnimSpriteGfx_PowerTrick[] = INCBIN_U32("graphics/battle_anims/sprites/power_trick.4bpp.lz"); const u32 gBattleAnimSpritePal_PowerTrick[] = INCBIN_U32("graphics/battle_anims/sprites/power_trick.gbapal.lz"); +const u32 gBattleAnimSpriteGfx_PurpleChain[] = INCBIN_U32("graphics/battle_anims/sprites/purple_chain.4bpp.lz"); +const u32 gBattleAnimSpritePal_PurpleChain[] = INCBIN_U32("graphics/battle_anims/sprites/purple_chain.gbapal.lz"); + const u32 gBattleAnimSpriteGfx_PurpleDrake[] = INCBIN_U32("graphics/battle_anims/sprites/purple_drake.4bpp.lz"); const u32 gBattleAnimSpritePal_PurpleDrake[] = INCBIN_U32("graphics/battle_anims/sprites/purple_drake.gbapal.lz"); const u32 gBattleAnimSpriteGfx_RazorShell[] = INCBIN_U32("graphics/battle_anims/sprites/razor_shell.4bpp.lz"); const u32 gBattleAnimSpritePal_RazorShell[] = INCBIN_U32("graphics/battle_anims/sprites/razor_shell.gbapal.lz"); +const u32 gBattleAnimSpriteGfx_RedExplosion[] = INCBIN_U32("graphics/battle_anims/sprites/red_explosion.4bpp.lz"); +const u32 gBattleAnimSpritePal_RedExplosion[] = INCBIN_U32("graphics/battle_anims/sprites/red_explosion.gbapal.lz"); + const u32 gBattleAnimSpriteGfx_RocksSmall[] = INCBIN_U32("graphics/battle_anims/sprites/rock_small.4bpp.lz"); const u32 gBattleAnimSpriteGfx_NewRocks[] = INCBIN_U32("graphics/battle_anims/sprites/rocks_new.4bpp.lz"); From 4d78d5e5075ffe4a7765b6497a86b68ff1e4644b Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:07:01 +0200 Subject: [PATCH 26/64] Fixes Poltergeist missing accuracy check (#5168) --- data/battle_scripts_1.s | 1 + 1 file changed, 1 insertion(+) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index a366055658..c47127c651 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -878,6 +878,7 @@ BattleScript_OctlockTurnDmgEnd: BattleScript_EffectPoltergeist:: attackcanceler + accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE attackstring ppreduce checkpoltergeist BS_TARGET, BattleScript_ButItFailed From 9019fed264a4c2187ccf489c884cfe2b0222239f Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:26:52 +0200 Subject: [PATCH 27/64] Fixes booster energy not increasing speed (#5167) * Fixes booster energy not increasing speed * alternative solution * forgot else --- src/battle_main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index 526c54d62f..e164976e9d 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4717,7 +4717,6 @@ void SwapTurnOrder(u8 id1, u8 id2) u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect) { u32 speed = gBattleMons[battler].speed; - u32 highestStat = GetHighestStatId(battler); // weather abilities if (WEATHER_HAS_EFFECT) @@ -4739,10 +4738,10 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect) speed *= 2; else if (ability == ABILITY_SLOW_START && gDisableStructs[battler].slowStartTimer != 0) speed /= 2; - else if (ability == ABILITY_PROTOSYNTHESIS && gBattleWeather & B_WEATHER_SUN && highestStat == STAT_SPEED) - speed = (speed * 150) / 100; - else if (ability == ABILITY_QUARK_DRIVE && gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && highestStat == STAT_SPEED) - speed = (speed * 150) / 100; + else if (ability == ABILITY_PROTOSYNTHESIS && (gBattleWeather & B_WEATHER_SUN || gBattleStruct->boosterEnergyActivates & gBitTable[battler])) + speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed; + else if (ability == ABILITY_QUARK_DRIVE && (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & gBitTable[battler])) + speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed; // stat stages speed *= gStatStageRatios[gBattleMons[battler].statStages[STAT_SPEED]][0]; From e3d9bb643feac3885c5b2a4815162516161d4e30 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:27:40 +0200 Subject: [PATCH 28/64] #5120 Follow up (#5158) Consistency change --- src/battle_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index 71f6e3581b..ada7cb20a3 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -4096,7 +4096,7 @@ static void ChooseStatBoostAnimation(u32 battler) if (gBattleScripting.animArg1 != 0) // Already set in a different stat so now boosting multiple stats gBattleScripting.animArg1 = (statBuffMoreThan1 ? STAT_ANIM_MULTIPLE_PLUS2 : STAT_ANIM_MULTIPLE_PLUS1); else - gBattleScripting.animArg1 = GET_STAT_BUFF_ID((statsOrder[stat] + 1)) + (!statBuffMoreThan1 ? STAT_ANIM_PLUS1 : STAT_ANIM_PLUS2); + gBattleScripting.animArg1 = GET_STAT_BUFF_ID((statsOrder[stat] + 1)) + (statBuffMoreThan1 ? STAT_ANIM_PLUS2 : STAT_ANIM_PLUS1); } } #undef ANIM_STAT_HP From 18980b20a3128b22ab9ba23f2a466d076e95536d Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 14 Aug 2024 22:48:20 -0400 Subject: [PATCH 29/64] Remove trailing whitespace (master) (#5174) --- INSTALL.md | 4 +- data/battle_scripts_2.s | 2 +- .../followers/rename_to_graphics_pokemon.py | 2 +- docs/ai_flags.md | 16 +- docs/changelogs/1.5.x/1.5.2.md | 2 +- docs/changelogs/1.5.x/1.5.3.md | 4 +- docs/changelogs/1.7.x/1.7.2.md | 2 +- docs/how_to_new_pokemon_1_6_0.md | 10 +- docs/how_to_new_pokemon_1_7_0.md | 24 +-- docs/how_to_new_pokemon_1_8_0.md | 22 +-- docs/how_to_new_pokemon_1_9_0.md | 24 +-- docs/how_to_testing_system.md | 150 +++++++++--------- docs/how_to_trainer_class.md | 4 +- include/test/battle.h | 2 +- migration_scripts/1.8/item_ball_refactor.py | 2 +- .../1.9/battle_anim_moves_refactor.py | 2 +- spritesheet_rules.mk | 2 +- src/battle_anim.c | 2 +- src/battle_anim_dragon.c | 12 +- src/battle_anim_effects_1.c | 6 +- src/battle_anim_flying.c | 2 +- src/battle_anim_normal.c | 4 +- src/battle_controllers.c | 2 +- src/battle_dome.c | 8 +- src/battle_factory.c | 4 +- src/battle_factory_screen.c | 2 +- src/battle_setup.c | 2 +- src/clock.c | 2 +- src/data/gimmicks.h | 8 +- .../object_event_graphics_info_pointers.h | 2 +- src/event_object_movement.c | 10 +- src/field_specials.c | 4 +- src/load_save.c | 2 +- src/map_name_popup.c | 4 +- src/script_menu.c | 2 +- src/script_pokemon_util.c | 2 +- src/vs_seeker.c | 2 +- test/battle/ability/anger_point.c | 4 +- test/battle/ability/clear_body.c | 4 +- test/battle/ability/gulp_missile.c | 2 +- test/battle/ability/magic_guard.c | 2 +- test/battle/ai/ai_flag_risky.c | 8 +- test/battle/gimmick/terastal.c | 2 +- test/battle/gimmick/zmove.c | 4 +- test/battle/hold_effect/ability_shield.c | 2 +- test/battle/move_effect/heal_bell.c | 12 +- test/battle/move_effect/knock_off.c | 4 +- test/battle/move_effect/revelation_dance.c | 4 +- test/battle/move_effect/sleep_talk.c | 4 +- test/battle/move_effect/telekinesis.c | 2 +- tools/learnset_helpers/teachable.py | 4 +- tools/preproc/asm_file.cpp | 6 +- 52 files changed, 210 insertions(+), 210 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 6349d24fbb..5744adcb04 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -327,7 +327,7 @@ If this works, then proceed to [Installation](#installation). Otherwise, ask for libpng is now installed. Continue to [Installing pkg-config (macOS)](#installing-pkg-config-macos) if **pkg-config is not installed**. Otherwise, continue to [Installing devkitARM (macOS)](#installing-devkitarm-macos) if **devkitARM is not installed**. - + If both pkg-config and devkitARM are already installed, go to [Choosing where to store pokeemerald Expansion (macOS)](#choosing-where-to-store-pokeemerald-expansion-macos). ### Installing pkg-config (macOS) @@ -541,7 +541,7 @@ If this works, then proceed to [Installation](#installation). Otherwise, ask for > ``` > Where *\* is the path of the folder [where you chose to store pokeemerald Expansion](#Choosing-where-to-store-pokeemerald-expansion-WSL1). Then run the `git clone` command again. - + Now you're ready to build pokeemerald Expansion. ## Build pokeemerald Expansion diff --git a/data/battle_scripts_2.s b/data/battle_scripts_2.s index 6238afb36c..7fe22195c8 100644 --- a/data/battle_scripts_2.s +++ b/data/battle_scripts_2.s @@ -45,7 +45,7 @@ BattleScript_UseItemMessage: printfromtable gTrainerUsedItemStringIds waitmessage B_WAIT_TIME_LONG return - + BattleScript_ItemRestoreHPRet: bichalfword gMoveResultFlags, MOVE_RESULT_NO_EFFECT orword gHitMarker, HITMARKER_IGNORE_SUBSTITUTE diff --git a/dev_scripts/followers/rename_to_graphics_pokemon.py b/dev_scripts/followers/rename_to_graphics_pokemon.py index bad1758b0c..a89348ddb4 100644 --- a/dev_scripts/followers/rename_to_graphics_pokemon.py +++ b/dev_scripts/followers/rename_to_graphics_pokemon.py @@ -59,6 +59,6 @@ def rellocate_follower_graphics(): #os.popen('cp followers/' + name + '.png followers/' + name + '/follower.png') #os.remove('followers/' + name + '.png') #print(pth) - #subprocess.run(["tools/gbagfx/gbagfx " + name +".png " + name + "_normal.pal'" + str(count) + "'"]) + #subprocess.run(["tools/gbagfx/gbagfx " + name +".png " + name + "_normal.pal'" + str(count) + "'"]) rellocate_follower_graphics() diff --git a/docs/ai_flags.md b/docs/ai_flags.md index cc5c1631ff..bb7b1b7444 100644 --- a/docs/ai_flags.md +++ b/docs/ai_flags.md @@ -21,14 +21,14 @@ AI: Check Bad Move / Try to Faint / Check Viability. The name of each flag is ju * Sequence Switching ## `COMPETITIVE_PARTY_SYNTAX != TRUE` / Not Found -If you are not using competitive syntax parties, instead access the trainer data directly in [`src/data/trainers.h`](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/trainers.h), and add flags like so, typed exactly the same as the flag names themselves: +If you are not using competitive syntax parties, instead access the trainer data directly in [`src/data/trainers.h`](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/trainers.h), and add flags like so, typed exactly the same as the flag names themselves: `.aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY` # What AI Flags does pokeemerald-expansion have? This section lists all of expansion’s AI Flags and briefly describes the effect they have on the AI’s behaviour. In all cases, please check the corresponding function or surrounding code around their implementation for more details. Some of these functions are vanilla, some share a name with vanilla but have been modified to varying degrees, and some are completely new. ## `AI_FLAG_CHECK_BAD_MOVE` -The AI will avoid using moves that are likely to fail in the current situation. This flag helps prevent the AI from making ineffective choices, such as using moves into immunities, into invulnerable states, or when the moves are otherwise hindered by abilities, terrain, or status conditions. +The AI will avoid using moves that are likely to fail in the current situation. This flag helps prevent the AI from making ineffective choices, such as using moves into immunities, into invulnerable states, or when the moves are otherwise hindered by abilities, terrain, or status conditions. ## `AI_FLAG_TRY_TO_FAINT` AI will prioritize KOing the player if able rather than using status moves. Will prioritize using a move that can OHKO the player. If the player can KO the AI’s mon and the AI’s mon is slower, prioritize priority moves (this does not prevent the AI from switching out instead). @@ -58,12 +58,12 @@ AI will generally behave more recklessly. This AI enables the following behaviou * Prioritize Explosion moves ## `AI_FLAG_PREFER_STRONGEST_MOVE` -Adds score bonus to any move the AI has that either OHKOs or 2HKOs the player. +Adds score bonus to any move the AI has that either OHKOs or 2HKOs the player. Keep in mind that this is a weaker form of `AI_FLAG_TRY_TO_FAINT` at scoring OHKOs as it does not take into account who is attacking first, it does however handle 2HKOs. ## `AI_FLAG_PREFER_BATON_PASS` -AI prefers raising its own stats if it has >= 60% HP, as well as Ingrain, Aqua Ring, and Protect. Prioritizes Baton Bass if the mon is rooted (Ingrain) or has the Aqua Ring effect, and doesn’t if it has been Leech Seeded. +AI prefers raising its own stats if it has >= 60% HP, as well as Ingrain, Aqua Ring, and Protect. Prioritizes Baton Bass if the mon is rooted (Ingrain) or has the Aqua Ring effect, and doesn’t if it has been Leech Seeded. ## `AI_FLAG_DOUBLE_BATTLE` This flag is automatically set in double battles, and controls much of the doubles-specific scoring. I’ll summarize some of its scoring as follows: @@ -83,7 +83,7 @@ With respect to the AI’s mons, in doubles: In both singles and doubles: * Prioritizes not using moves that require the user fainting (Destiny Bond, Explosion etc.) and healing moves while on >= 70% HP. * Prioritize not using moves that require the user fainting or losing significant HP (Belly Drum etc) while between 30% and 70% HP -* Prioritize not using setup moves (Light Screen etc.) and Bide while on <= 30% HP +* Prioritize not using setup moves (Light Screen etc.) and Bide while on <= 30% HP With respect to the player’s mons: * Prioritize not using many status moves (stat buffs, Poison, Pain Split) if the player has between 30% and 70% HP @@ -96,7 +96,7 @@ AI prioritizes setting up field effects (Trick Room, Rain Dance, etc.) and side AI does not understand ability suppression (Mold Breaker etc., weather suppression (Air Lock etc.), redirection abilities (Lightningrod etc.) being temporarily removed due to move effects (Sky Drop etc.), or item suppression (Magic Room etc.) and will ignore them. This is a handicap flag. ## `AI_FLAG_WILL_SUICIDE` -AI prioritizes self destruction moves (Explosion, Memento). +AI prioritizes self destruction moves (Explosion, Memento). ## `AI_FLAG_PREFER_STATUS_MOVES` AI gets a score bonus for status moves. This should be combined with `AI_FLAG_CHECK_BAD_MOVE` to prevent using only status moves. @@ -127,7 +127,7 @@ Affects when the AI chooses to switch. AI will make smarter decisions about when Marks the last Pokemon in the party as the Ace Pokemon. It will not be used unless it is the last one remaining, or is forced to be switched in (Roar, U-Turn with 1 mon remaining, etc.) ## `AI_FLAG_OMNISCIENT` -AI has full knowledge of player moves, abilities, and hold items, and can use this knowledge when making decisions. +AI has full knowledge of player moves, abilities, and hold items, and can use this knowledge when making decisions. ## `AI_FLAG_SMART_MON_CHOICES` Affects what the AI chooses to send out after a switch. AI will make smarter decisions when choosing which mon to send out mid-battle and after a KO, which are handled separately. Automatically included when `AI_FLAG_SMART_SWITCHING` is enabled. @@ -148,7 +148,7 @@ And will choose mons after a mid-battle switch prioritizing the following criter * Has Baton Pass ## `AI_FLAG_CONSERVATIVE` -AI always assumes it will roll the lowest possible result when comparing damage in scoring. +AI always assumes it will roll the lowest possible result when comparing damage in scoring. ## `AI_FLAG_SEQUENCE_SWITCHING` AI will always switch out after a KO in exactly party order as defined in the trainer data (ie. slot 1, then 2, then 3, etc.). The AI will never switch out mid-battle unless forced to (Roar etc.). If the AI uses a move that requires a switch where it makes a decision about what to send in (U-Turn etc.), it will always switch out into the lowest available party index. diff --git a/docs/changelogs/1.5.x/1.5.2.md b/docs/changelogs/1.5.x/1.5.2.md index ab6735c7a3..69e0ecaabf 100644 --- a/docs/changelogs/1.5.x/1.5.2.md +++ b/docs/changelogs/1.5.x/1.5.2.md @@ -92,5 +92,5 @@ * Court Change by @DizzyEggg in https://github.com/rh-hideout/pokeemerald-expansion/pull/3160 * Item Effects * Utility Umbrella, by @AsparagusEduardo in https://github.com/rh-hideout/pokeemerald-expansion/pull/2835 - + **Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.5.1...expansion/1.5.2 \ No newline at end of file diff --git a/docs/changelogs/1.5.x/1.5.3.md b/docs/changelogs/1.5.x/1.5.3.md index 831814740a..85748b2375 100644 --- a/docs/changelogs/1.5.x/1.5.3.md +++ b/docs/changelogs/1.5.x/1.5.3.md @@ -9,8 +9,8 @@ ## CRITICAL FIX, please update to avoid the issues detailed down below: - Fixed memory corruption when handling trigger sprites by @SBird1337 in https://github.com/rh-hideout/pokeemerald-expansion/pull/3238 - This had the posibility of manifesting in weird ways, like camera and music changes, NPC duplication and more. If you've had this issue in the past, we ***heavily*** recommend you update to this version of the expansion. - - Thank you @Bassoonian for helping us pinpointing the issue. - + - Thank you @Bassoonian for helping us pinpointing the issue. + ![image](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/26b9b984-c5db-4dac-85f7-5fc4e95a32ce) ![image](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/d490eb30-ce54-4b90-bb2e-79c2e9bb50ac) diff --git a/docs/changelogs/1.7.x/1.7.2.md b/docs/changelogs/1.7.x/1.7.2.md index 34aa131e70..a92d778956 100644 --- a/docs/changelogs/1.7.x/1.7.2.md +++ b/docs/changelogs/1.7.x/1.7.2.md @@ -41,7 +41,7 @@ * Clodsire * Crocalor * Dolliv - * Dudunsparce + * Dudunsparce * Esparthra ### Fixed * Multiple Pokémon graphical fixes by @katykat5099 in https://github.com/rh-hideout/pokeemerald-expansion/pull/3805 diff --git a/docs/how_to_new_pokemon_1_6_0.md b/docs/how_to_new_pokemon_1_6_0.md index d965e48a5f..9bf3e2e61f 100644 --- a/docs/how_to_new_pokemon_1_6_0.md +++ b/docs/how_to_new_pokemon_1_6_0.md @@ -384,7 +384,7 @@ Edit [src/data/text/species_names.h](https://github.com/rh-hideout/pokeemerald-e const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1] = { [SPECIES_NONE] = _("??????????"), [SPECIES_BULBASAUR] = _("Bulbasaur"), - ... + ... [SPECIES_ENAMORUS] = _("Enamorus"), + [SPECIES_MEWTHREE] = _("Mewthree"), }; @@ -482,7 +482,7 @@ Append to [src/data/pokemon/pokedex_text.h](https://github.com/rh-hideout/pokeem "winter. According to legend, this\n" "Pokémon's love gives rise to the\n" "budding of fresh life across the land."); - + +const u8 gMewthreePokedexText[] = _( + "The rumors became true.\n" + "This is Mews final form.\n" @@ -509,7 +509,7 @@ Edit [src/data/pokemon/pokedex_entries.h](https://github.com/rh-hideout/pokeemer .trainerScale = 296, .trainerOffset = 1, }, - + + [NATIONAL_DEX_MEWTHREE] = + { + .categoryName = _("NEW SPECIES"), @@ -553,7 +553,7 @@ Edit [src/data/pokemon/pokedex_orders.h](https://github.com/rh-hideout/pokeemera NATIONAL_DEX_DUGTRIO, ... }; - + const u16 gPokedexOrder_Height[] = { ... @@ -598,7 +598,7 @@ Edit [src/data/pokemon/species_info.h](https://github.com/rh-hideout/pokeemerald }, + [SPECIES_MEWTHREE] = -+ { ++ { + .baseHP = 106, + .baseAttack = 150, + .baseDefense = 70, diff --git a/docs/how_to_new_pokemon_1_7_0.md b/docs/how_to_new_pokemon_1_7_0.md index 801ae8e549..30c1f82dbe 100644 --- a/docs/how_to_new_pokemon_1_7_0.md +++ b/docs/how_to_new_pokemon_1_7_0.md @@ -170,7 +170,7 @@ Edit [src/data/pokemon/species_info.h](https://github.com/rh-hideout/pokeemerald }, + [SPECIES_MEWTHREE] = -+ { ++ { + .baseHP = 106, + .baseAttack = 150, + .baseDefense = 70, @@ -234,7 +234,7 @@ That's all the basic fields present in vanilla emerald, so now let's take a look { ... [SPECIES_MEWTHREE] = - { + { ... .isLegendary = TRUE, .allPerfectIVs = TRUE, @@ -309,7 +309,7 @@ Lastly, we add the cry to our species entry { ... [SPECIES_MEWTHREE] = - { + { ... .isLegendary = TRUE, .allPerfectIVs = TRUE, @@ -388,7 +388,7 @@ Now we can add the number and entry to our Mewthree: { ... [SPECIES_MEWTHREE] = - { + { ... .cryId = CRY_MEWTHREE, + .natDexNum = NATIONAL_DEX_MEWTHREE, @@ -409,7 +409,7 @@ Now we can add the number and entry to our Mewthree: ``` ![image](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/3759dd4c-8da5-4b1c-9a50-b9e9d0815e7f) -The values `pokemonScale`, `pokemonOffset`, `trainerScale` and `trainerOffset` are used for the height comparison figure in the Pokédex. +The values `pokemonScale`, `pokemonOffset`, `trainerScale` and `trainerOffset` are used for the height comparison figure in the Pokédex. `height` and `weight` are specified in decimeters and hectograms respectively (which are meters and kilograms multiplied by 10, so 2.5 meters are 25 decimeters). @@ -443,7 +443,7 @@ Edit [src/data/pokemon/pokedex_orders.h](https://github.com/rh-hideout/pokeemera NATIONAL_DEX_DUGTRIO, ... }; - + const u16 gPokedexOrder_Height[] = { ... @@ -560,7 +560,7 @@ Now that we have all the external data ready, we just need to add it to `gSpecie { ... [SPECIES_MEWTHREE] = - { + { ... .pokemonScale = 256, .pokemonOffset = 0, @@ -612,7 +612,7 @@ Let's explain each of these: - Used to define what Y position of the back sprite. When working with the animation debug menu, we recommend aligning the back sprite to the white background, as it was designed to properyly align with the real battle layout. - `backAnimId`: - Like `frontAnimId` except for the back sprites and them being a single frame. The IDs listed [here](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/pokemon_animation.h) are used to represent 3 different animations that happen based on the the Pokémon's nature. -- `PALETTES` +- `PALETTES` - This macro was created to handle both regular and shiny palettes of a Pokémon. It just needs the species suffix to call the corresponding palette. ```c #define PALETTES(pal) \ @@ -650,7 +650,7 @@ We're almost there just a bit left! { ... [SPECIES_MEWTHREE] = - { + { ... .abilities = { ABILITY_INSOMNIA, ABILITY_NONE, ABILITY_NONE }, .bodyColor = BODY_COLOR_PURPLE, @@ -745,7 +745,7 @@ Again, we need to register the learnset in `gSpeciesInfo`: { ... [SPECIES_MEWTHREE] = - { + { ... PALETTES(Mewthree), ICON(Mewthree, 2), @@ -846,7 +846,7 @@ Once more, we need to register the learnset in `gSpeciesInfo`: { ... [SPECIES_MEWTHREE] = - { + { ... FOOTPRINT(Mewthree) .levelUpLearnset = sMewthreeLevelUpLearnset, @@ -869,7 +869,7 @@ Edit `gSpeciesInfo`: { ... [SPECIES_MEWTWO] = - { + { ... FOOTPRINT(Mewtwo) .isLegendary = TRUE, diff --git a/docs/how_to_new_pokemon_1_8_0.md b/docs/how_to_new_pokemon_1_8_0.md index c4c7ab621c..6dbb009fcf 100644 --- a/docs/how_to_new_pokemon_1_8_0.md +++ b/docs/how_to_new_pokemon_1_8_0.md @@ -181,7 +181,7 @@ Edit [src/data/pokemon/species_info.h](https://github.com/rh-hideout/pokeemerald }, + [SPECIES_MEWTHREE] = -+ { ++ { + .baseHP = 106, + .baseAttack = 150, + .baseDefense = 70, @@ -245,7 +245,7 @@ That's all the basic fields present in vanilla emerald, so now let's take a look { ... [SPECIES_MEWTHREE] = - { + { ... .isLegendary = TRUE, .allPerfectIVs = TRUE, @@ -320,7 +320,7 @@ Lastly, we add the cry to our species entry { ... [SPECIES_MEWTHREE] = - { + { ... .isLegendary = TRUE, .allPerfectIVs = TRUE, @@ -399,7 +399,7 @@ Now we can add the number and entry to our Mewthree: { ... [SPECIES_MEWTHREE] = - { + { ... .cryId = CRY_MEWTHREE, + .natDexNum = NATIONAL_DEX_MEWTHREE, @@ -420,7 +420,7 @@ Now we can add the number and entry to our Mewthree: ``` ![image](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/3759dd4c-8da5-4b1c-9a50-b9e9d0815e7f) -The values `pokemonScale`, `pokemonOffset`, `trainerScale` and `trainerOffset` are used for the height comparison figure in the Pokédex. +The values `pokemonScale`, `pokemonOffset`, `trainerScale` and `trainerOffset` are used for the height comparison figure in the Pokédex. `height` and `weight` are specified in decimeters and hectograms respectively (which are meters and kilograms multiplied by 10, so 2.5 meters are 25 decimeters). @@ -454,7 +454,7 @@ Edit [src/data/pokemon/pokedex_orders.h](https://github.com/rh-hideout/pokeemera NATIONAL_DEX_DUGTRIO, ... }; - + const u16 gPokedexOrder_Height[] = { ... @@ -571,7 +571,7 @@ Now that we have all the external data ready, we just need to add it to `gSpecie { ... [SPECIES_MEWTHREE] = - { + { ... .pokemonScale = 256, .pokemonOffset = 0, @@ -651,7 +651,7 @@ We're almost there just a bit left! { ... [SPECIES_MEWTHREE] = - { + { ... .abilities = { ABILITY_INSOMNIA, ABILITY_NONE, ABILITY_NONE }, .bodyColor = BODY_COLOR_PURPLE, @@ -746,7 +746,7 @@ Again, we need to register the learnset in `gSpeciesInfo`: { ... [SPECIES_MEWTHREE] = - { + { ... PALETTES(Mewthree), ICON(Mewthree, 2), @@ -847,7 +847,7 @@ Once more, we need to register the learnset in `gSpeciesInfo`: { ... [SPECIES_MEWTHREE] = - { + { ... FOOTPRINT(Mewthree) .levelUpLearnset = sMewthreeLevelUpLearnset, @@ -870,7 +870,7 @@ Edit `gSpeciesInfo`: { ... [SPECIES_MEWTWO] = - { + { ... FOOTPRINT(Mewtwo) .isLegendary = TRUE, diff --git a/docs/how_to_new_pokemon_1_9_0.md b/docs/how_to_new_pokemon_1_9_0.md index 84742c3a76..e64f8e6e66 100644 --- a/docs/how_to_new_pokemon_1_9_0.md +++ b/docs/how_to_new_pokemon_1_9_0.md @@ -176,7 +176,7 @@ Edit [src/data/pokemon/species_info.h](https://github.com/rh-hideout/pokeemerald }, + [SPECIES_MEWTHREE] = -+ { ++ { + .baseHP = 106, + .baseAttack = 150, + .baseDefense = 70, @@ -240,7 +240,7 @@ That's all the basic fields present in vanilla emerald, so now let's take a look { ... [SPECIES_MEWTHREE] = - { + { ... .isLegendary = TRUE, .allPerfectIVs = TRUE, @@ -315,7 +315,7 @@ Lastly, we add the cry to our species entry { ... [SPECIES_MEWTHREE] = - { + { ... .isLegendary = TRUE, .allPerfectIVs = TRUE, @@ -394,7 +394,7 @@ Now we can add the number and entry to our Mewthree: { ... [SPECIES_MEWTHREE] = - { + { ... .cryId = CRY_MEWTHREE, + .natDexNum = NATIONAL_DEX_MEWTHREE, @@ -415,7 +415,7 @@ Now we can add the number and entry to our Mewthree: ``` ![image](https://github.com/rh-hideout/pokeemerald-expansion/assets/2904965/3759dd4c-8da5-4b1c-9a50-b9e9d0815e7f) -The values `pokemonScale`, `pokemonOffset`, `trainerScale` and `trainerOffset` are used for the height comparison figure in the Pokédex. +The values `pokemonScale`, `pokemonOffset`, `trainerScale` and `trainerOffset` are used for the height comparison figure in the Pokédex. `height` and `weight` are specified in decimeters and hectograms respectively (which are meters and kilograms multiplied by 10, so 2.5 meters are 25 decimeters). @@ -449,7 +449,7 @@ Edit [src/data/pokemon/pokedex_orders.h](https://github.com/rh-hideout/pokeemera NATIONAL_DEX_DUGTRIO, ... }; - + const u16 gPokedexOrder_Height[] = { ... @@ -566,7 +566,7 @@ Now that we have all the external data ready, we just need to add it to `gSpecie { ... [SPECIES_MEWTHREE] = - { + { ... .pokemonScale = 256, .pokemonOffset = 0, @@ -646,7 +646,7 @@ We're almost there just a bit left! { ... [SPECIES_MEWTHREE] = - { + { ... .abilities = { ABILITY_INSOMNIA, ABILITY_NONE, ABILITY_NONE }, .bodyColor = BODY_COLOR_PURPLE, @@ -745,7 +745,7 @@ Again, we need to register the learnset in `gSpeciesInfo`: { ... [SPECIES_MEWTHREE] = - { + { ... PALETTES(Mewthree), ICON(Mewthree, 2), @@ -846,7 +846,7 @@ Once more, we need to register the learnset in `gSpeciesInfo`: { ... [SPECIES_MEWTHREE] = - { + { ... FOOTPRINT(Mewthree) .levelUpLearnset = sMewthreeLevelUpLearnset, @@ -869,7 +869,7 @@ Edit `gSpeciesInfo`: { ... [SPECIES_MEWTWO] = - { + { ... FOOTPRINT(Mewtwo) .isLegendary = TRUE, @@ -1097,7 +1097,7 @@ And finally, in `gSpeciesInfo`: { ... [SPECIES_MEWTHREE] = - { + { ... FOOTPRINT(Mewthree) + OVERWORLD( diff --git a/docs/how_to_testing_system.md b/docs/how_to_testing_system.md index 793465114c..1f25f9847e 100644 --- a/docs/how_to_testing_system.md +++ b/docs/how_to_testing_system.md @@ -1,11 +1,11 @@ # How to use the Testing System ## Running Tests -To run all the tests use: -`make check -j` -To run specific tests, e.g. Spikes ones, use: -`make check TESTS='Spikes'` -To build a ROM (pokemerald-test.elf) that can be opened in mgba to view specific tests, e.g. Spikes ones, use: +To run all the tests use: +`make check -j` +To run specific tests, e.g. Spikes ones, use: +`make check TESTS='Spikes'` +To build a ROM (pokemerald-test.elf) that can be opened in mgba to view specific tests, e.g. Spikes ones, use: `make pokeemerald-test.elf TESTS='Spikes'` ## How to Write Tests @@ -48,21 +48,21 @@ SINGLE_BATTLE_TEST("Stun Spore inflicts paralysis") STATUS_ICON(opponent, paralysis: TRUE); // 4. } } -``` +``` -The `ASSUMPTIONS` block documents that Stun Spore has `EFFECT_PARALYZE`. -If Stun Spore did not have that effect it would cause the tests in the file to be skipped. We write our tests like this so that hackers can change the effects of moves without causing tests to fail. +The `ASSUMPTIONS` block documents that Stun Spore has `EFFECT_PARALYZE`. +If Stun Spore did not have that effect it would cause the tests in the file to be skipped. We write our tests like this so that hackers can change the effects of moves without causing tests to fail. -`SINGLE_BATTLE_TEST` defines the name of the test. Related tests should start with the same prefix, e.g. Stun Spore tests should start with "Stun Spore", this allows just the Stun Spore-related tests to be run with: -`make check TESTS='Stun Spore'` +`SINGLE_BATTLE_TEST` defines the name of the test. Related tests should start with the same prefix, e.g. Stun Spore tests should start with "Stun Spore", this allows just the Stun Spore-related tests to be run with: +`make check TESTS='Stun Spore'` -`GIVEN` initializes the parties, `PLAYER` and `OPPONENT` add a Pokémon to their respective parties. They can both accept a block which further customizes the Pokémon's stats, moves, item, ability, etc. +`GIVEN` initializes the parties, `PLAYER` and `OPPONENT` add a Pokémon to their respective parties. They can both accept a block which further customizes the Pokémon's stats, moves, item, ability, etc. -`WHEN` describes the turns, and `TURN` describes the choices made in a single turn. `MOVE` causes the player to use Stun Spore and adds the move to the Pokémon's moveset if an explicit Moves was not specified. -Pokémon that are not mentioned in a `TURN` use Celebrate. -The test runner rigs the RNG so that unless otherwise specified, moves always hit, never critical hit, always activate their secondary effects, and always roll the same damage modifier. +`WHEN` describes the turns, and `TURN` describes the choices made in a single turn. `MOVE` causes the player to use Stun Spore and adds the move to the Pokémon's moveset if an explicit Moves was not specified. +Pokémon that are not mentioned in a `TURN` use Celebrate. +The test runner rigs the RNG so that unless otherwise specified, moves always hit, never critical hit, always activate their secondary effects, and always roll the same damage modifier. -`SCENE` describes the player-visible output of the battle. In this case `ANIMATION` checks that the Stun Spore animation played, `MESSAGE` checks the paralysis message was shown, and `STATUS_ICON` checks that the opponent's HP bar shows a PRZ icon. +`SCENE` describes the player-visible output of the battle. In this case `ANIMATION` checks that the Stun Spore animation played, `MESSAGE` checks the paralysis message was shown, and `STATUS_ICON` checks that the opponent's HP bar shows a PRZ icon. ### Example 2 As a second example, to manually test that Stun Spore does not effect Grass-types you might: @@ -90,8 +90,8 @@ SINGLE_BATTLE_TEST("Stun Spore does not affect Grass-types") } } ``` -The `ASSUME` commands are documenting the reasons why Stun Spore does not affect Oddish, namely that Stun Spore is a powder move, and Oddish is a Grass-type. These `ASSUME` statements function similarly to the ones in `ASSUMPTIONS` but apply only to the one test. -NOT inverts the meaning of a `SCENE` check, so applying it to `ANIMATION` requires that the Stun Spore animation does not play. `MESSAGE` checks that the message was shown. +The `ASSUME` commands are documenting the reasons why Stun Spore does not affect Oddish, namely that Stun Spore is a powder move, and Oddish is a Grass-type. These `ASSUME` statements function similarly to the ones in `ASSUMPTIONS` but apply only to the one test. +NOT inverts the meaning of a `SCENE` check, so applying it to `ANIMATION` requires that the Stun Spore animation does not play. `MESSAGE` checks that the message was shown. The checks in `SCENE` are ordered, so together this says "The doesn't affect message is shown, and the Stun Spore animation does not play at any time before that". Normally you would only test one or the other, or even better, just `NOT STATUS_ICON(opponent, paralysis: TRUE);` to say that Oddish was not paralyzed without specifying the exact outputs which led to that. ### Example 3 @@ -131,9 +131,9 @@ SINGLE_BATTLE_TEST("Meditate raises Attack", s16 damage) } ``` -`PARAMETRIZE` causes a test to run multiple times, once per `PARAMETRIZE` block (e.g. once with `raiseAttack = FALSE` and once with `raiseAttack = TRUE`). -The `HP_BAR` command's `captureDamage` causes the change in HP to be stored in a variable, and the variable chosen is `results[i].damage`. -`results[i]` contains all the variables defined at the end of `SINGLE_BATTLE_TEST`, `i` is the current `PARAMETRIZE` index. +`PARAMETRIZE` causes a test to run multiple times, once per `PARAMETRIZE` block (e.g. once with `raiseAttack = FALSE` and once with `raiseAttack = TRUE`). +The `HP_BAR` command's `captureDamage` causes the change in HP to be stored in a variable, and the variable chosen is `results[i].damage`. +`results[i]` contains all the variables defined at the end of `SINGLE_BATTLE_TEST`, `i` is the current `PARAMETRIZE` index. `FINALLY` runs after the last parameter has finished, and uses `EXPECT_MUL_EQ` to check that the second battle deals 1.5× the damage of the first battle (with a small tolerance to account for rounding). You might notice that all the tests check the outputs the player could see rather than the internal battle state. e.g. the Meditate test could have used `gBattleMons[B_POSITION_OPPONENT_LEFT].hp` instead of using `HP_BAR` to capture the damage. This is a deliberate choice, by checking what the player can observe the tests are more robust to refactoring, e.g. if `gBattleMons` got moved into `gBattleStruct` then any test that used it would need to be updated. @@ -144,8 +144,8 @@ The overworld is not available, so it is only possible to test commands which do ## REFERENCE ### `ASSUME` -`ASSUME(cond)` -Causes the test to be skipped if `cond` is false. Used to document any prerequisites of the test, e.g. to test Burn reducing the Attack of a Pokémon we can observe the damage of a physical attack with and without the burn. To document that this test assumes the attack is physical we can use: +`ASSUME(cond)` +Causes the test to be skipped if `cond` is false. Used to document any prerequisites of the test, e.g. to test Burn reducing the Attack of a Pokémon we can observe the damage of a physical attack with and without the burn. To document that this test assumes the attack is physical we can use: `ASSUME(gMovesInfo[MOVE_WHATEVER].category == DAMAGE_CATEGORY_PHYSICAL);` ### `ASSUMPTIONS` @@ -164,16 +164,16 @@ ASSUMPTIONS ``` ### `SINGLE_BATTLE_TEST` -`SINGLE_BATTLE_TEST(name, results...)` and `DOUBLE_BATTLE_TEST(name, results...)` -Define single- and double- battles. The names should start with the name of the mechanic being tested so that it is easier to run all the related tests. `results` contains variable declarations to be placed into the `results` array which is available in tests using `PARAMETRIZE` commands. +`SINGLE_BATTLE_TEST(name, results...)` and `DOUBLE_BATTLE_TEST(name, results...)` +Define single- and double- battles. The names should start with the name of the mechanic being tested so that it is easier to run all the related tests. `results` contains variable declarations to be placed into the `results` array which is available in tests using `PARAMETRIZE` commands. The main differences for doubles are: - Move targets sometimes need to be explicit. - Instead of `player` and `opponent` there is `playerLeft`, `playerRight`, `opponentLeft`, and `opponentRight`. ### `AI_SINGLE_BATTLE_TEST` -`AI_SINGLE_BATTLE_TEST(name, results...)` and `AI_DOUBLE_BATTLE_TEST(name, results...)` +`AI_SINGLE_BATTLE_TEST(name, results...)` and `AI_DOUBLE_BATTLE_TEST(name, results...)` Define battles where opponent mons are controlled by AI, the same that runs -when battling regular Trainers. The flags for AI should be specified by the `AI_FLAGS` command. +when battling regular Trainers. The flags for AI should be specified by the `AI_FLAGS` command. The rules remain the same as with the `SINGLE` and `DOUBLE` battle tests with some differences: - opponent's action is specified by the `EXPECT_MOVE` / `EXPECT_SEND_OUT` / `EXPECT_SWITCH` commands - we don't control what opponent actually does, instead we make sure the opponent does what we expect it to do @@ -182,7 +182,7 @@ The rules remain the same as with the `SINGLE` and `DOUBLE` battle tests with so ### `KNOWN_FAILING` `KNOWN_FAILING;` -Marks a test as not passing due to a bug. If there is an issue number associated with the bug it should be included in a comment. If the test passes the developer will be notified to remove `KNOWN_FAILING`. +Marks a test as not passing due to a bug. If there is an issue number associated with the bug it should be included in a comment. If the test passes the developer will be notified to remove `KNOWN_FAILING`. For example: ``` SINGLE_BATTLE_TEST("Jump Kick has no recoil if no target") @@ -192,7 +192,7 @@ SINGLE_BATTLE_TEST("Jump Kick has no recoil if no target") } ``` ### `PARAMETRIZE` -`PARAMETERIZE { parameter; }` +`PARAMETERIZE { parameter; }` Runs a test multiple times. `i` will be set to which parameter is running, and `results` will contain an entry for each parameter, e.g.: ``` SINGLE_BATTLE_TEST("Blaze boosts Fire-type moves in a pinch", s16 damage) @@ -246,7 +246,7 @@ Contains the initial state of the parties before the battle. ## `RNGSeed` `RNGSeed(seed)` -Explicitly sets the RNG seed. Try to avoid using this because it is a very fragile tool. +Explicitly sets the RNG seed. Try to avoid using this because it is a very fragile tool. Example: ``` GIVEN { @@ -256,10 +256,10 @@ GIVEN { ``` ### `FLAG_SET` -`FLAG_SET(flagId)` -Sets the specified flag. Can currently only set one flag at a time. -Cleared between parameters and at the end of the test. -Example: +`FLAG_SET(flagId)` +Sets the specified flag. Can currently only set one flag at a time. +Cleared between parameters and at the end of the test. +Example: ``` GIVEN { FLAG_SET(FLAG_SYS_EXAMPLE_FLAG); @@ -268,8 +268,8 @@ GIVEN { ``` ### `PLAYER` and `OPPONENT` -`PLAYER(species)` and `OPPONENT(species` -Adds the species to the player's or opponent's party respectively. +`PLAYER(species)` and `OPPONENT(species` +Adds the species to the player's or opponent's party respectively. The Pokémon can be further customized with the following functions: - `Gender(MON_MALE | MON_FEMALE)` - `Nature(nature)` @@ -280,14 +280,14 @@ The Pokémon can be further customized with the following functions: - `Moves(moves...)` - `Friendship(friendship)` - `Status1(status1)` -For example to create a level 42 Wobbuffet that is poisoned: -`PLAYER(SPECIES_WOBBUFFET) { Level(42); Status1(STATUS1_POISON); }` -**Note if Speed is specified for any Pokémon then it must be specified for all Pokémon.** +For example to create a level 42 Wobbuffet that is poisoned: +`PLAYER(SPECIES_WOBBUFFET) { Level(42); Status1(STATUS1_POISON); }` +**Note if Speed is specified for any Pokémon then it must be specified for all Pokémon.** **Note if Moves is specified then MOVE will not automatically add moves to the moveset.** ### `AI_FLAGS` -`AI_FLAGS(flags)` -Specifies which AI flags are run during the test. Has use only for AI tests. +`AI_FLAGS(flags)` +Specifies which AI flags are run during the test. Has use only for AI tests. The most common combination is `AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT)` which is the general 'smart' AI. ### `WHEN` @@ -300,8 +300,8 @@ The most common combination is `AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_ Contains the choices that battlers make during the battle. ### `TURN` -`TURN { ... }` -Groups the choices made by the battlers on a single turn. If Speeds have not been explicitly specified then the order of the `MOVE` commands in the `TURN` will be used to infer the Speeds of the Pokémon, e.g.: +`TURN { ... }` +Groups the choices made by the battlers on a single turn. If Speeds have not been explicitly specified then the order of the `MOVE` commands in the `TURN` will be used to infer the Speeds of the Pokémon, e.g.: ``` // player's speed will be greater than opponent's speed. TURN { MOVE(player, MOVE_SPLASH); MOVE(opponent, MOVE_SPLASH); } @@ -311,7 +311,7 @@ Groups the choices made by the battlers on a single turn. If Speeds have not bee The inference process is naive, if your test contains anything that modifies the speed of a battler you should specify them explicitly. ### `MOVE` -`MOVE(battler, move | moveSlot:, [megaEvolve:], [hit:], [criticalHit:], [target:], [allowed:], [WITH_RNG(tag, value])` +`MOVE(battler, move | moveSlot:, [megaEvolve:], [hit:], [criticalHit:], [target:], [allowed:], [WITH_RNG(tag, value])` Used when the battler chooses Fight. Either the move ID (e.g. `MOVE_TACKLE` or move slot must be specified. - `megaEvolve: TRUE` causes the battler to Mega Evolve if able - `hit: FALSE` causes the move to miss @@ -325,35 +325,35 @@ Used when the battler chooses Fight. Either the move ID (e.g. `MOVE_TACKLE` or m If the battler does not have an explicit Moves specified the moveset will be populated based on the `MOVE`s it uses. ### `FORCED_MOVE` -`FORCED_MOVE(battler)` +`FORCED_MOVE(battler)` Used when the battler chooses Fight and then their move is chosen for them, e.g. when affected by Encore. ``` FORCED_MOVE(player); ``` ### `SWITCH` -`SWITCH(battler, partyIndex)` +`SWITCH(battler, partyIndex)` Used when the battler chooses Switch. ``` SWITCH(player, 1); ``` ### `SKIP_TURN` -`SKIP_TURN(battler)` +`SKIP_TURN(battler)` Used when the battler cannot choose an action, e.g. when locked into Thrash. ``` SKIP_TURN(player); ``` ### `SEND_OUT` -`SEND_OUT(battler, partyIndex)` +`SEND_OUT(battler, partyIndex)` Used when the battler chooses to switch to another Pokémon but not via Switch, e.g. after fainting or due to a U-turn. ``` SEND_OUT(player, 1); ``` ### `USE_ITEM` -`USE_ITEM(battler, itemId, [partyIndex:], [move:])` +`USE_ITEM(battler, itemId, [partyIndex:], [move:])` Used when the battler chooses to use an item from the Bag. The item ID (e.g. ITEM_POTION) must be specified, and party index and move slot if applicable, e.g: ``` USE_ITEM(player, ITEM_X_ATTACK); @@ -378,15 +378,15 @@ Contains an abridged description of the UI during the `THEN`. The order of the d ``` ### `ABILITY_POPUP` -`ABILITY_POPUP(battler, [ability])` -Causes the test to fail if the battler's ability pop-up is not shown. +`ABILITY_POPUP(battler, [ability])` +Causes the test to fail if the battler's ability pop-up is not shown. If specified, ability is the ability shown in the pop-up. ``` ABILITY_POPUP(opponent, ABILITY_MOLD_BREAKER); ``` ### `ANIMATION` -`ANIMATION(type, animId, [battler], [target:])` +`ANIMATION(type, animId, [battler], [target:])` Causes the test to fail if the animation does not play. A common use of this command is to check if a move was successful, e.g.: ``` ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); @@ -394,7 +394,7 @@ Causes the test to fail if the animation does not play. A common use of this com `target` can only be specified for `ANIM_TYPE_MOVE`. ### `EXPERIENCE_BAR` -`EXPERIENCE_BAR(battler, [exp: | captureGainedExp:])` +`EXPERIENCE_BAR(battler, [exp: | captureGainedExp:])` If `exp:` is used, causes the test to fail if that amount of experience is not gained, e.g.: ``` EXPERIENCE_BAR(player, exp: 0); @@ -404,11 +404,11 @@ If `captureGainedExp:` is used, causes the test to fail if the Experience bar do u32 exp; EXPERIENCE_BAR(player, captureGainedExp: &exp); ``` -If none of the above are used, causes the test to fail if the Exp does not change at all. +If none of the above are used, causes the test to fail if the Exp does not change at all. **Please note that due to nature of tests, this command is only usable in `WILD_BATTLE_TEST` and will fail elsewhere.** ### `HP_BAR` -`HP_BAR(battler, [damage: | hp: | captureDamage: | captureHP:])` +`HP_BAR(battler, [damage: | hp: | captureDamage: | captureHP:])` If `hp:` or `damage:` are used, causes the test to fail if that amount of damage is not dealt, e.g.: ``` HP_BAR(player, hp: 0); @@ -422,9 +422,9 @@ If `captureDamage:` or `captureHP:` are used, causes the test to fail if the HP If none of the above are used, causes the test to fail if the HP does not change at all. ### MESSAGE -`MESSAGE(pattern)` -Causes the test to fail if the message in pattern is not displayed. -Spaces in pattern match newlines (\n, \l, and \p) in the message. +`MESSAGE(pattern)` +Causes the test to fail if the message in pattern is not displayed. +Spaces in pattern match newlines (\n, \l, and \p) in the message. Often used to check that a battler took its turn but it failed, e.g.: ``` MESSAGE("Wobbuffet used Dream Eater!"); @@ -432,7 +432,7 @@ Often used to check that a battler took its turn but it failed, e.g.: ``` ### `STATUS_ICON` -`STATUS_ICON(battler, status1 | none: | sleep: | poison: | burn: | freeze: | paralysis:, badPoison:)` +`STATUS_ICON(battler, status1 | none: | sleep: | poison: | burn: | freeze: | paralysis:, badPoison:)` Causes the test to fail if the battler's status is not changed to the specified status. ``` STATUS_ICON(player, badPoison: TRUE); @@ -447,7 +447,7 @@ If the expected status icon is parametrized the corresponding `STATUS1` constant ``` ### `NOT` -`NOT sceneCommand` +`NOT sceneCommand` Causes the test to fail if the `SCENE` command succeeds before the following command succeeds. ``` // Our Wobbuffet does not Celebrate before the foe's. @@ -519,27 +519,27 @@ Contains code to run after the battle has finished. If the test is using `PARAME Contains checks to run after all `PARAMETERIZE` commands have run. Prefer to write your checks in `THEN` where possible, because a failure in `THEN` will be tagged with which parameter it corresponds to. ### `EXPECT` -`EXPECT(cond)` +`EXPECT(cond)` Causes the test to fail if `cond` is false. ### `EXPECT_XX` -`EXPECT_EQ(a, b)` -`a == b` +`EXPECT_EQ(a, b)` +`a == b` -`EXPECT_NE(a, b)` -`a != b` +`EXPECT_NE(a, b)` +`a != b` -`EXPECT_LT(a, b)` -`a < b` +`EXPECT_LT(a, b)` +`a < b` -`EXPECT_LE(a, b)` -`a <= b` +`EXPECT_LE(a, b)` +`a <= b` -`EXPECT_GT(a, b)` -`a > b` +`EXPECT_GT(a, b)` +`a > b` -`EXPECT_GE(a, b)` -`a >= b` +`EXPECT_GE(a, b)` +`a >= b` Causes the test to fail if a and b compare incorrectly, e.g. ``` @@ -547,7 +547,7 @@ Causes the test to fail if a and b compare incorrectly, e.g. ``` ### `EXPECT_MUL_EQ` -`EXPECT_MUL_EQ(a, m, b)` +`EXPECT_MUL_EQ(a, m, b)` Causes the test to fail if `a*m != b` (within a threshold), e.g. ``` // Expect results[0].damage * 1.5 == results[1].damage. @@ -557,7 +557,7 @@ Causes the test to fail if a and b compare incorrectly, e.g. ## Overworld Command Reference ### `OVERWORLD_SCRIPT` -`OVERWORLD_SCRIPT(instructions...)` +`OVERWORLD_SCRIPT(instructions...)` Returns a pointer to a compiled overworld script. Cannot be used to initialize global `const` data, although the pointer **IS** to `const` data. Note that each script command must be followed by a ;, e.g.: ``` @@ -568,7 +568,7 @@ const u8 *myScript = OVERWORLD_SCRIPT( ``` ### `RUN_OVERWORLD_SCRIPT` -`RUN_OVERWORLD_SCRIPT(instructions...)` +`RUN_OVERWORLD_SCRIPT(instructions...)` Runs an overworld script in the immediate script context, which means that commands like `waitstate` are not supported. ``` RUN_OVERWORLD_SCRIPT( diff --git a/docs/how_to_trainer_class.md b/docs/how_to_trainer_class.md index a47cbe19c5..3ce0217c28 100644 --- a/docs/how_to_trainer_class.md +++ b/docs/how_to_trainer_class.md @@ -12,13 +12,13 @@ * [Usage](#usage) ## Quick Summary -(Page contains out of date information, [new instructions for Sprites here](https://github.com/rh-hideout/pokeemerald-expansion/pull/3597).) +(Page contains out of date information, [new instructions for Sprites here](https://github.com/rh-hideout/pokeemerald-expansion/pull/3597).) If you've done this before and just need a quick lookup, here's what files you need: 1. GFX into [graphics/trainers/front_pics](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/graphics/trainers/front_pics) 2. Palette into [graphics/trainers/palettes](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/graphics/trainers/palettes) 3. Register sprites to [include/graphics.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/graphics.h) 4. Point game to where graphic files are found: [src/data/graphics/trainers](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/graphics/trainers.h) -5. Add animation to: [src/data/trainer_graphics/front_pic_anims.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/trainer_graphics/front_pic_anims.h) +5. Add animation to: [src/data/trainer_graphics/front_pic_anims.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/trainer_graphics/front_pic_anims.h) 6. Add the trainer to all three structs in: [src/data/trainer_graphics/front_pic_table.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/src/data/trainer_graphics/front_pic_table.h) 7. Add trainer to [include/constants/trainers.h](https://github.com/rh-hideout/pokeemerald-expansion/blob/master/include/constants/trainers.h) diff --git a/include/test/battle.h b/include/test/battle.h index a44e813f82..865afe8e0b 100644 --- a/include/test/battle.h +++ b/include/test/battle.h @@ -328,7 +328,7 @@ * * MOVE(battler, move | moveSlot:, [gimmick:], [hit:], [criticalHit:], [target:], [allowed:], [WITH_RNG(tag, value]) * Used when the battler chooses Fight. Either the move ID or move slot - * must be specified. gimmick: GIMMICK_MEGA causes the battler to Mega + * must be specified. gimmick: GIMMICK_MEGA causes the battler to Mega * Evolve if able, hit: FALSE causes the move to miss, criticalHit: TRUE * causes the move to land a critical hit, target: is used in double * battles to choose the target (when necessary), and allowed: FALSE is diff --git a/migration_scripts/1.8/item_ball_refactor.py b/migration_scripts/1.8/item_ball_refactor.py index f121978ec8..83d6f9f167 100755 --- a/migration_scripts/1.8/item_ball_refactor.py +++ b/migration_scripts/1.8/item_ball_refactor.py @@ -81,5 +81,5 @@ for file in pories_to_check: raw = re.sub("script %s[ \n]*\{[ \n]*finditem\((.*)\)[ \n]*\}[ \n]*" % unused, "", raw) with open(file, "w") as f2: f2.write(raw) - + print("Done!") diff --git a/migration_scripts/1.9/battle_anim_moves_refactor.py b/migration_scripts/1.9/battle_anim_moves_refactor.py index 116d3964c0..a7adac98ff 100644 --- a/migration_scripts/1.9/battle_anim_moves_refactor.py +++ b/migration_scripts/1.9/battle_anim_moves_refactor.py @@ -37,7 +37,7 @@ for line in lines: comment_split = line.split('//') if move and IsCommaMissing(comment_split[0]): line = comment_split[0].removesuffix('\n') + ',' + line[len(comment_split[0]):-1] + '\n' - + moves_info_lines.append(line) diff --git a/spritesheet_rules.mk b/spritesheet_rules.mk index 03e6b8a3b1..c10c9081f4 100644 --- a/spritesheet_rules.mk +++ b/spritesheet_rules.mk @@ -731,7 +731,7 @@ $(FLDEFFGFXDIR)/secret_power_tree.4bpp: %.4bpp: %.png $(FLDEFFGFXDIR)/record_mix_lights.4bpp: %.4bpp: %.png $(GFX) $< $@ -mwidth 4 -mheight 1 - + $(POKEMONGFXDIR)/question_mark/overworld.4bpp: %.4bpp: %.png $(GFX) $< $@ -mwidth 4 -mheight 4 diff --git a/src/battle_anim.c b/src/battle_anim.c index 71813ddf46..df597560ec 100644 --- a/src/battle_anim.c +++ b/src/battle_anim.c @@ -798,7 +798,7 @@ static void Cmd_end(void) // Debugging - ensure no hanging mon bg tasks if (FuncIsActiveTask(Task_UpdateMonBg)) DebugPrintf("Move %d animation still has Task_UpdateMonBg active at the end!", gAnimMoveIndex); - + m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 256); if (!IsContest()) { diff --git a/src/battle_anim_dragon.c b/src/battle_anim_dragon.c index 4191c42585..862c0ad069 100644 --- a/src/battle_anim_dragon.c +++ b/src/battle_anim_dragon.c @@ -42,35 +42,35 @@ const struct SpriteTemplate gOutrageFlameSpriteTemplate = .callback = AnimOutrageFlame, }; -static const union AnimCmd sAnim_DreepyMissileOpponent_0[] = +static const union AnimCmd sAnim_DreepyMissileOpponent_0[] = { ANIMCMD_FRAME(0, 0, .hFlip = TRUE), ANIMCMD_END, }; -const union AnimCmd *const gAnims_DreepyMissileOpponent[] = +const union AnimCmd *const gAnims_DreepyMissileOpponent[] = { sAnim_DreepyMissileOpponent_0, }; -static const union AnimCmd sAnim_DreepyMissilePlayer_0[] = +static const union AnimCmd sAnim_DreepyMissilePlayer_0[] = { ANIMCMD_FRAME(0, 0), ANIMCMD_END, }; -const union AnimCmd *const gAnims_DreepyMissilePlayer[] = +const union AnimCmd *const gAnims_DreepyMissilePlayer[] = { sAnim_DreepyMissilePlayer_0, }; -static const union AnimCmd sAnim_DreepyMissileNotDrag_0[] = +static const union AnimCmd sAnim_DreepyMissileNotDrag_0[] = { ANIMCMD_FRAME(0, 0, .hFlip = TRUE, .vFlip = TRUE), ANIMCMD_END, }; -const union AnimCmd *const gAnims_DreepyMissileOpponentNotDrag[] = +const union AnimCmd *const gAnims_DreepyMissileOpponentNotDrag[] = { sAnim_DreepyMissileNotDrag_0, }; diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index d8283fc7dc..b29d9b2b94 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -6578,11 +6578,11 @@ void PrepareDoubleTeamAnim(u32 taskId, u32 animBattler, bool32 forAllySwitch) gSprites[spriteId].sBattlerFlank = (animBattler != ANIM_ATTACKER); else gSprites[spriteId].sBattlerFlank = (animBattler == ANIM_ATTACKER); - + // correct direction on opponent side if (GetBattlerSide(gBattleAnimAttacker) == B_SIDE_OPPONENT) gSprites[spriteId].sBattlerFlank ^= 1; - + gSprites[spriteId].callback = AnimDoubleTeam; task->tBlendSpritesCount++; } @@ -6614,7 +6614,7 @@ static void ReloadBattlerSprites(u32 battler, struct Pokemon *party) UpdateHealthboxAttribute(gHealthboxSpriteIds[battler], mon, HEALTHBOX_ALL); // If battler has an indicator for a gimmick, hide the sprite until the move animation finishes. UpdateIndicatorVisibilityAndType(gHealthboxSpriteIds[battler], TRUE); - + // Try to recreate shadow sprite if (gBattleSpritesDataPtr->healthBoxesData[battler].shadowSpriteId < MAX_SPRITES) { diff --git a/src/battle_anim_flying.c b/src/battle_anim_flying.c index f58aa97ee2..6afe1e9f36 100644 --- a/src/battle_anim_flying.c +++ b/src/battle_anim_flying.c @@ -33,7 +33,7 @@ static void AnimSkyAttackBird_Step(struct Sprite *); static void AnimTask_AnimateGustTornadoPalette_Step(u8); static void AnimTask_LoadWindstormBackground_Step(u8 taskId); -const struct SpriteTemplate gEllipticalGustCenteredSpriteTemplate = +const struct SpriteTemplate gEllipticalGustCenteredSpriteTemplate = { .tileTag = ANIM_TAG_GUST, .paletteTag = ANIM_TAG_GUST, diff --git a/src/battle_anim_normal.c b/src/battle_anim_normal.c index 6333cc8183..759c410946 100644 --- a/src/battle_anim_normal.c +++ b/src/battle_anim_normal.c @@ -414,7 +414,7 @@ u32 UnpackSelectedBattlePalettes(s16 selector) bool8 anim1 = (selector >> 5) & 1; bool8 anim2 = (selector >> 6) & 1; u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gAnimMoveIndex); - + switch (moveTarget) { case MOVE_TARGET_BOTH: @@ -431,7 +431,7 @@ u32 UnpackSelectedBattlePalettes(s16 selector) } break; } - + return GetBattlePalettesMask(battleBackground, attacker, target, attackerPartner, targetPartner, anim1, anim2); } diff --git a/src/battle_controllers.c b/src/battle_controllers.c index fae42939d0..d6b2fbdc3a 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -610,7 +610,7 @@ static void InitLinkBtlControllers(void) bool32 IsValidForBattle(struct Pokemon *mon) { u32 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG); - return (species != SPECIES_NONE + return (species != SPECIES_NONE && species != SPECIES_EGG && GetMonData(mon, MON_DATA_HP) != 0 && GetMonData(mon, MON_DATA_IS_EGG) == FALSE); diff --git a/src/battle_dome.c b/src/battle_dome.c index 67b9a1e293..06acf6e2f2 100644 --- a/src/battle_dome.c +++ b/src/battle_dome.c @@ -2136,7 +2136,7 @@ static void CalcDomeMonStats(const struct TrainerMon *fmon, int level, u8 ivs, i { int evs[NUM_STATS]; int i; - + for (i = 0; i < NUM_STATS; i++) { if (fmon->ev != NULL) @@ -2144,7 +2144,7 @@ static void CalcDomeMonStats(const struct TrainerMon *fmon, int level, u8 ivs, i else evs[i] = 0; } - + if (fmon->species == SPECIES_SHEDINJA) { stats[STAT_HP] = 1; @@ -2199,7 +2199,7 @@ static void CreateDomeOpponentMon(u8 monPartyId, u16 tournamentTrainerId, u8 tou u8 fixedIv = GetDomeTrainerMonIvs(tournamentTrainerId); // BUG: Using the wrong ID. As a result, all Pokémon have ivs of 3. #endif u8 level = SetFacilityPtrsGetLevel(); - + CreateFacilityMon(&gFacilityTrainerMons[DOME_MONS[tournamentTrainerId][tournamentMonId]], level, fixedIv, otId, 0, &gEnemyParty[monPartyId]); } @@ -4446,7 +4446,7 @@ static void DisplayTrainerInfoOnCard(u8 flags, u8 trainerTourneyId) else allocatedArray[j] = 0; } - + allocatedArray[NUM_STATS] += allocatedArray[STAT_HP]; for (j = 0; j < NUM_NATURE_STATS; j++) { diff --git a/src/battle_factory.c b/src/battle_factory.c index 7d7ec7b3af..b5645368c2 100644 --- a/src/battle_factory.c +++ b/src/battle_factory.c @@ -406,7 +406,7 @@ static void SetPlayerAndOpponentParties(void) u8 monLevel; u16 monId; u8 ivs; - + if (gSaveBlock2Ptr->frontier.lvlMode == FRONTIER_LVL_TENT) { gFacilityTrainerMons = gSlateportBattleTentMons; @@ -428,7 +428,7 @@ static void SetPlayerAndOpponentParties(void) { monId = gSaveBlock2Ptr->frontier.rentalMons[i].monId; ivs = gSaveBlock2Ptr->frontier.rentalMons[i].ivs; - + CreateFacilityMon(&gFacilityTrainerMons[monId], monLevel, ivs, OT_ID_PLAYER_ID, FLAG_FRONTIER_MON_FACTORY, &gPlayerParty[i]); SetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY, &gSaveBlock2Ptr->frontier.rentalMons[i].personality); diff --git a/src/battle_factory_screen.c b/src/battle_factory_screen.c index 5aa019c29f..f76c6a2fc8 100644 --- a/src/battle_factory_screen.c +++ b/src/battle_factory_screen.c @@ -1761,7 +1761,7 @@ static void CreateFrontierFactorySelectableMons(u8 firstMonId) ivs = GetFactoryMonFixedIV(challengeNum + 1, FALSE); else ivs = GetFactoryMonFixedIV(challengeNum, FALSE); - + CreateFacilityMon(&gFacilityTrainerMons[monId], level, ivs, otId, FLAG_FRONTIER_MON_FACTORY, &sFactorySelectScreen->mons[i + firstMonId].monData); diff --git a/src/battle_setup.c b/src/battle_setup.c index 41f2b9b502..54c4f99b92 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -1940,7 +1940,7 @@ void IncrementRematchStepCounter(void) #if FREE_MATCH_CALL == FALSE if (!HasAtLeastFiveBadges()) return; - + if (IsVsSeekerEnabled()) return; diff --git a/src/clock.c b/src/clock.c index 7061f96b7f..54c9422bbe 100644 --- a/src/clock.c +++ b/src/clock.c @@ -84,7 +84,7 @@ static void FormChangeTimeUpdate() { struct Pokemon *mon = &gPlayerParty[i]; u16 targetSpecies = GetFormChangeTargetSpecies(mon, FORM_CHANGE_TIME_OF_DAY, 0); - + if (targetSpecies != SPECIES_NONE) { SetMonData(mon, MON_DATA_SPECIES, &targetSpecies); diff --git a/src/data/gimmicks.h b/src/data/gimmicks.h index 95a233e3fe..5b06feddef 100644 --- a/src/data/gimmicks.h +++ b/src/data/gimmicks.h @@ -5,7 +5,7 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] = { [GIMMICK_NONE] = {0}, - [GIMMICK_MEGA] = + [GIMMICK_MEGA] = { .triggerSheet = &sSpriteSheet_MegaTrigger, .triggerPal = &sSpritePalette_MegaTrigger, @@ -15,7 +15,7 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] = .CanActivate = CanMegaEvolve, .ActivateGimmick = ActivateMegaEvolution, }, - [GIMMICK_Z_MOVE] = + [GIMMICK_Z_MOVE] = { .triggerSheet = &sSpriteSheet_ZMoveTrigger, .triggerPal = &sSpritePalette_ZMoveTrigger, @@ -23,7 +23,7 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] = .CanActivate = CanUseZMove, .ActivateGimmick = ActivateZMove, }, - [GIMMICK_ULTRA_BURST] = + [GIMMICK_ULTRA_BURST] = { .triggerSheet = &sSpriteSheet_BurstTrigger, .triggerPal = &sSpritePalette_BurstTrigger, @@ -31,7 +31,7 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] = .CanActivate = CanUltraBurst, .ActivateGimmick = ActivateUltraBurst, }, - [GIMMICK_DYNAMAX] = + [GIMMICK_DYNAMAX] = { .triggerSheet = &sSpriteSheet_DynamaxTrigger, .triggerPal = &sSpritePalette_DynamaxTrigger, diff --git a/src/data/object_events/object_event_graphics_info_pointers.h b/src/data/object_events/object_event_graphics_info_pointers.h index 7f487a5ae5..60dc6997db 100755 --- a/src/data/object_events/object_event_graphics_info_pointers.h +++ b/src/data/object_events/object_event_graphics_info_pointers.h @@ -239,7 +239,7 @@ extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_HoOh; // Begin pokemon event objects extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_PokeBall; extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Follower; - + extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Bard; extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Hipster; extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Trader; diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 5a6eb28fc3..1edc986c9b 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1493,7 +1493,7 @@ static s16 ReallocSpriteTiles(struct Sprite *sprite, u32 byteSize) { i = -1; } - + sprite->invisible = wasVisible; return i; } @@ -1510,7 +1510,7 @@ u16 LoadSheetGraphicsInfo(const struct ObjectEventGraphicsInfo *info, u16 uuid, bool32 oldInvisible; if (tag == TAG_NONE) tag = COMP_OW_TILE_TAG_BASE + uuid; - + if (sprite) { oldInvisible = sprite->invisible; @@ -1547,7 +1547,7 @@ u16 LoadSheetGraphicsInfo(const struct ObjectEventGraphicsInfo *info, u16 uuid, { FieldEffectFreeTilesIfUnused(oldTiles); } - + if (sprite) { sprite->sheetTileStart = tileStart; @@ -1566,7 +1566,7 @@ u16 LoadSheetGraphicsInfo(const struct ObjectEventGraphicsInfo *info, u16 uuid, { sprite->oam.tileNum = sprite->sheetTileStart; sprite->usingSheet = FALSE; - + } else if (sprite && !sprite->sheetTileStart && sprite->oam.size != info->oam->size) { @@ -1925,7 +1925,7 @@ static u8 LoadDynamicFollowerPalette(u16 species, u8 form, bool32 shiny) spritePalette.data = gSpeciesInfo[species].overworldShinyPalette; else spritePalette.data = gSpeciesInfo[species].overworldPalette; - + // Check if pal data must be decompressed if (IsLZ77Data(spritePalette.data, PLTT_SIZE_4BPP, PLTT_SIZE_4BPP)) { diff --git a/src/field_specials.c b/src/field_specials.c index d1b27e2df6..e00aa03803 100644 --- a/src/field_specials.c +++ b/src/field_specials.c @@ -977,8 +977,8 @@ static bool32 IsBuildingPCTile(u32 tileId) static bool32 IsPlayerHousePCTile(u32 tileId) { - return gMapHeader.mapLayout->secondaryTileset == &gTileset_BrendansMaysHouse - && (tileId == METATILE_BrendansMaysHouse_BrendanPC_On + return gMapHeader.mapLayout->secondaryTileset == &gTileset_BrendansMaysHouse + && (tileId == METATILE_BrendansMaysHouse_BrendanPC_On || tileId == METATILE_BrendansMaysHouse_BrendanPC_Off || tileId == METATILE_BrendansMaysHouse_MayPC_On || tileId == METATILE_BrendansMaysHouse_MayPC_Off); diff --git a/src/load_save.c b/src/load_save.c index ee8a6bd04c..a5f2693538 100644 --- a/src/load_save.c +++ b/src/load_save.c @@ -211,7 +211,7 @@ void SaveObjectEvents(void) gSaveBlock1Ptr->objectEvents[i].graphicsId = (graphicsId >> 8) | (graphicsId << 8); gSaveBlock1Ptr->objectEvents[i].spriteId = 127; // magic number // To avoid crash on vanilla, save follower as inactive - if (gObjectEvents[i].localId == OBJ_EVENT_ID_FOLLOWER) + if (gObjectEvents[i].localId == OBJ_EVENT_ID_FOLLOWER) gSaveBlock1Ptr->objectEvents[i].active = FALSE; } } diff --git a/src/map_name_popup.c b/src/map_name_popup.c index 67a0d6373f..5cc1f3cfd5 100644 --- a/src/map_name_popup.c +++ b/src/map_name_popup.c @@ -550,7 +550,7 @@ static void ShowMapNamePopUpWindow(void) if (OW_POPUP_GENERATION == GEN_5) { AddTextPrinterParameterized(mapNamePopUpWindowId, FONT_SHORT, mapDisplayHeader, 8, 2, TEXT_SKIP_DRAW, NULL); - + if (OW_POPUP_BW_TIME_MODE != OW_POPUP_BW_TIME_NONE) { RtcCalcLocalTime(); @@ -622,7 +622,7 @@ static void LoadMapNamePopUpWindowBg(void) if (OW_POPUP_GENERATION == GEN_5) { popUpThemeId = sRegionMapSectionId_To_PopUpThemeIdMapping_BW[regionMapSectionId]; - switch (popUpThemeId) + switch (popUpThemeId) { // add additional gen 5-style pop-up themes as cases here case MAPPOPUP_THEME_BW_DEFAULT: diff --git a/src/script_menu.c b/src/script_menu.c index b78f1ef112..706c4ac715 100644 --- a/src/script_menu.c +++ b/src/script_menu.c @@ -487,7 +487,7 @@ static void Task_HandleScrollingMultichoiceInput(u8 taskId) { bool32 done = FALSE; s32 input = ListMenu_ProcessInput(gTasks[taskId].data[0]); - + switch (input) { case LIST_HEADER: diff --git a/src/script_pokemon_util.c b/src/script_pokemon_util.c index e732dc7aa2..3d2c7d640c 100644 --- a/src/script_pokemon_util.c +++ b/src/script_pokemon_util.c @@ -466,7 +466,7 @@ u32 ScriptGiveMon(u16 species, u8 level, u16 item) #define PARSE_FLAG(n, default_) (flags & (1 << (n))) ? VarGet(ScriptReadHalfword(ctx)) : (default_) -/* Give or create a mon to either player or opponent +/* Give or create a mon to either player or opponent */ void ScrCmd_createmon(struct ScriptContext *ctx) { diff --git a/src/vs_seeker.c b/src/vs_seeker.c index 30dcb74ce0..771c01dc72 100644 --- a/src/vs_seeker.c +++ b/src/vs_seeker.c @@ -581,7 +581,7 @@ bool32 IsVsSeekerEnabled(void) { if (I_VS_SEEKER_CHARGING == 0) return FALSE; - + return (CheckBagHasItem(ITEM_VS_SEEKER, 1)); } diff --git a/test/battle/ability/anger_point.c b/test/battle/ability/anger_point.c index 7cb283426a..270d66f28e 100644 --- a/test/battle/ability/anger_point.c +++ b/test/battle/ability/anger_point.c @@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Anger Point does not trigger when already at maximum Attack MESSAGE("Primeape cut its own HP and maximized ATTACK!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_FROST_BREATH, opponent); MESSAGE("A critical hit!"); - NONE_OF { + NONE_OF { ABILITY_POPUP(player, ABILITY_ANGER_POINT); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); MESSAGE("Primeape's Anger Point maxed its Attack!"); @@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("Anger Point does not trigger when a substitute takes the hit MESSAGE("Primeape made a SUBSTITUTE!"); ANIMATION(ANIM_TYPE_MOVE, MOVE_FROST_BREATH, opponent); MESSAGE("A critical hit!"); - NONE_OF { + NONE_OF { ABILITY_POPUP(player, ABILITY_ANGER_POINT); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); MESSAGE("Primeape's Anger Point maxed its Attack!"); diff --git a/test/battle/ability/clear_body.c b/test/battle/ability/clear_body.c index 1379506a72..dc82be67b4 100644 --- a/test/battle/ability/clear_body.c +++ b/test/battle/ability/clear_body.c @@ -127,7 +127,7 @@ SINGLE_BATTLE_TEST("Clear Body, Full Metal Body, and White Smoke don't prevent s } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_SUPERPOWER, opponent); NONE_OF { - ABILITY_POPUP(opponent, ability); + ABILITY_POPUP(opponent, ability); MESSAGE("Foe Solgaleo's Full Metal Body prevents stat loss!"); MESSAGE("Foe Torkoal's White Smoke prevents stat loss!"); MESSAGE("Foe Metang's Clear Body prevents stat loss!"); @@ -186,7 +186,7 @@ SINGLE_BATTLE_TEST("Mold Breaker, Teravolt, and Turboblaze ignore Clear Body and else{ ANIMATION(ANIM_TYPE_MOVE, move, player); NONE_OF { - ABILITY_POPUP(opponent, ability); + ABILITY_POPUP(opponent, ability); MESSAGE("Foe Solgaleo's Full Metal Body prevents stat loss!"); MESSAGE("Foe Torkoal's White Smoke prevents stat loss!"); MESSAGE("Foe Metang's Clear Body prevents stat loss!"); diff --git a/test/battle/ability/gulp_missile.c b/test/battle/ability/gulp_missile.c index 2ec9acc61b..7ccf1063b5 100644 --- a/test/battle/ability/gulp_missile.c +++ b/test/battle/ability/gulp_missile.c @@ -116,7 +116,7 @@ SINGLE_BATTLE_TEST("(Gulp Missile) Cramorant in Gorging paralyzes the target if } SINGLE_BATTLE_TEST("(Gulp Missile) triggers even if the user is fainted by opposing mon") -{ +{ GIVEN { PLAYER(SPECIES_CRAMORANT) { HP(1); MaxHP(250); Ability(ABILITY_GULP_MISSILE); } PLAYER(SPECIES_WOBBUFFET); diff --git a/test/battle/ability/magic_guard.c b/test/battle/ability/magic_guard.c index 69e8bac9c7..5579652265 100644 --- a/test/battle/ability/magic_guard.c +++ b/test/battle/ability/magic_guard.c @@ -13,5 +13,5 @@ SINGLE_BATTLE_TEST("Magic Guard prevents recoil damage to the user") ANIMATION(ANIM_TYPE_MOVE, MOVE_DOUBLE_EDGE, player); HP_BAR(opponent); NOT HP_BAR(player); - } + } } diff --git a/test/battle/ai/ai_flag_risky.c b/test/battle/ai/ai_flag_risky.c index e6156de5a0..e1ceeb2161 100644 --- a/test/battle/ai/ai_flag_risky.c +++ b/test/battle/ai/ai_flag_risky.c @@ -13,7 +13,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_RISKY: AI will blindly Mirror Coat against specia ASSUME(gSpeciesInfo[SPECIES_GROVYLE].baseSpAttack == 85); ASSUME(gSpeciesInfo[SPECIES_GROVYLE].baseAttack == 65); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiRiskyFlag); - PLAYER(SPECIES_GROVYLE) { Level(20); Moves(MOVE_ENERGY_BALL); } + PLAYER(SPECIES_GROVYLE) { Level(20); Moves(MOVE_ENERGY_BALL); } OPPONENT(SPECIES_CASTFORM) { Level(20); Moves(MOVE_TACKLE, MOVE_MIRROR_COAT); } } WHEN { TURN { MOVE(player, MOVE_ENERGY_BALL) ; EXPECT_MOVE(opponent, aiRiskyFlag ? MOVE_MIRROR_COAT : MOVE_TACKLE); } @@ -32,7 +32,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_RISKY: AI will blindly Counter against physical a ASSUME(gSpeciesInfo[SPECIES_MARSHTOMP].baseAttack == 85); ASSUME(gSpeciesInfo[SPECIES_MARSHTOMP].baseSpAttack == 60); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiRiskyFlag); - PLAYER(SPECIES_MARSHTOMP) { Level(20); Moves(MOVE_WATERFALL); } + PLAYER(SPECIES_MARSHTOMP) { Level(20); Moves(MOVE_WATERFALL); } OPPONENT(SPECIES_CASTFORM) { Level(20); Moves(MOVE_TACKLE, MOVE_COUNTER); } } WHEN { TURN { MOVE(player, MOVE_WATERFALL) ; EXPECT_MOVE(opponent, aiRiskyFlag ? MOVE_COUNTER : MOVE_TACKLE); } @@ -49,7 +49,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_RISKY: AI will prioritize Revenge if slower") GIVEN { ASSUME(gMovesInfo[MOVE_REVENGE].effect == EFFECT_REVENGE); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiRiskyFlag); - PLAYER(SPECIES_GROVYLE) { Level(20); Speed(4); Moves(MOVE_ENERGY_BALL); } + PLAYER(SPECIES_GROVYLE) { Level(20); Speed(4); Moves(MOVE_ENERGY_BALL); } OPPONENT(SPECIES_CASTFORM) { Level(19); Speed(3); Moves(MOVE_TACKLE, MOVE_REVENGE); } } WHEN { TURN { MOVE(player, MOVE_ENERGY_BALL) ; EXPECT_MOVE(opponent, aiRiskyFlag ? MOVE_REVENGE : MOVE_TACKLE); } @@ -83,7 +83,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_RISKY: AI prefers high damage moves at the expens GIVEN { AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiRiskyFlag); - PLAYER(SPECIES_PSYDUCK) { Level(5); Moves(MOVE_TACKLE); } + PLAYER(SPECIES_PSYDUCK) { Level(5); Moves(MOVE_TACKLE); } OPPONENT(SPECIES_CASTFORM) { Level(20); Moves(MOVE_THUNDER, MOVE_THUNDERBOLT); } } WHEN { TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, aiRiskyFlag ? MOVE_THUNDER : MOVE_THUNDERBOLT); } diff --git a/test/battle/gimmick/terastal.c b/test/battle/gimmick/terastal.c index 7a70ba0de0..1b50bc4bcc 100644 --- a/test/battle/gimmick/terastal.c +++ b/test/battle/gimmick/terastal.c @@ -646,7 +646,7 @@ SINGLE_BATTLE_TEST("(TERA) Protean cannot change the type of a Terastallized Pok PLAYER(SPECIES_GRENINJA) { Ability(ABILITY_PROTEAN); TeraType(TYPE_GRASS); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(player, MOVE_BUBBLE, gimmick: GIMMICK_TERA); + TURN { MOVE(player, MOVE_BUBBLE, gimmick: GIMMICK_TERA); MOVE(opponent, MOVE_EMBER); } } SCENE { MESSAGE("Greninja used Bubble!"); diff --git a/test/battle/gimmick/zmove.c b/test/battle/gimmick/zmove.c index 1eb2c7ae74..51c6516106 100644 --- a/test/battle/gimmick/zmove.c +++ b/test/battle/gimmick/zmove.c @@ -10,7 +10,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Z-Moves do not retain priority") PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(opponent, MOVE_TACKLE); + TURN { MOVE(opponent, MOVE_TACKLE); MOVE(player, MOVE_QUICK_ATTACK, gimmick: GIMMICK_Z_MOVE); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); @@ -597,7 +597,7 @@ SINGLE_BATTLE_TEST("(Z-MOVE) Searing Sunraze Smash ignores the target's abilitie ANIMATION(ANIM_TYPE_MOVE, MOVE_SEARING_SUNRAZE_SMASH, player); HP_BAR(opponent); MESSAGE("A critical hit!"); - } + } } SINGLE_BATTLE_TEST("(Z-MOVE) Z-Revelation Dance always transforms into Breakneck Blitz") diff --git a/test/battle/hold_effect/ability_shield.c b/test/battle/hold_effect/ability_shield.c index ee84b2c5e0..e10c3e0887 100644 --- a/test/battle/hold_effect/ability_shield.c +++ b/test/battle/hold_effect/ability_shield.c @@ -69,7 +69,7 @@ SINGLE_BATTLE_TEST("Ability Shield protects against Mycelium Might") } WHEN { TURN { MOVE(opponent, MOVE_SPORE); MOVE(player, MOVE_SPORE); } } SCENE { - + if (item == ITEM_ABILITY_SHIELD) { NONE_OF { ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent); diff --git a/test/battle/move_effect/heal_bell.c b/test/battle/move_effect/heal_bell.c index 8bd6c1f456..743af905ce 100644 --- a/test/battle/move_effect/heal_bell.c +++ b/test/battle/move_effect/heal_bell.c @@ -10,7 +10,7 @@ ASSUMPTIONS DOUBLE_BATTLE_TEST("Heal Bell cures the entire party") { u32 move; - + PARAMETRIZE { move = MOVE_HEAL_BELL; } PARAMETRIZE { move = MOVE_AROMATHERAPY; } @@ -39,10 +39,10 @@ DOUBLE_BATTLE_TEST("Heal Bell cures the entire party") DOUBLE_BATTLE_TEST("Heal Bell does not cure soundproof partners") { u32 ability; - + PARAMETRIZE { ability = ABILITY_SCRAPPY; } PARAMETRIZE { ability = ABILITY_SOUNDPROOF; } - + ASSUME(B_HEAL_BELL_SOUNDPROOF != GEN_5); GIVEN { @@ -65,10 +65,10 @@ DOUBLE_BATTLE_TEST("Heal Bell does not cure soundproof partners") SINGLE_BATTLE_TEST("Heal Bell cures inactive soundproof Pokemon") { u32 ability; - + PARAMETRIZE { ability = ABILITY_SCRAPPY; } PARAMETRIZE { ability = ABILITY_SOUNDPROOF; } - + ASSUME(B_HEAL_BELL_SOUNDPROOF >= GEN_5); GIVEN { @@ -87,7 +87,7 @@ SINGLE_BATTLE_TEST("Heal Bell cures inactive soundproof Pokemon") SINGLE_BATTLE_TEST("Heal Bell cures a soundproof user") -{ +{ ASSUME(B_HEAL_BELL_SOUNDPROOF == GEN_5 || B_HEAL_BELL_SOUNDPROOF >= GEN_8); GIVEN { diff --git a/test/battle/move_effect/knock_off.c b/test/battle/move_effect/knock_off.c index ba6f9b6fe7..50d8aaa773 100644 --- a/test/battle/move_effect/knock_off.c +++ b/test/battle/move_effect/knock_off.c @@ -90,7 +90,7 @@ SINGLE_BATTLE_TEST("Knock Off does not remove items through Substitute") PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_LEFTOVERS); }; } WHEN { - TURN { MOVE(opponent, MOVE_SUBSTITUTE); + TURN { MOVE(opponent, MOVE_SUBSTITUTE); MOVE(player, MOVE_KNOCK_OFF); } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_KNOCK_OFF, player); @@ -112,7 +112,7 @@ SINGLE_BATTLE_TEST("Recycle cannot recover an item removed by Knock Off") ANIMATION(ANIM_TYPE_MOVE, MOVE_KNOCK_OFF, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_ITEM_KNOCKOFF); MESSAGE("Wobbuffet knocked off Foe Wobbuffet's Leftovers!"); - + MESSAGE("Foe Wobbuffet used Recycle!"); MESSAGE("But it failed!"); } THEN { diff --git a/test/battle/move_effect/revelation_dance.c b/test/battle/move_effect/revelation_dance.c index 489dee1c87..9ab5d4a8e2 100644 --- a/test/battle/move_effect/revelation_dance.c +++ b/test/battle/move_effect/revelation_dance.c @@ -37,7 +37,7 @@ SINGLE_BATTLE_TEST("Revelation Dance changes its type depending on the user's 1s ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player); HP_BAR(opponent); MESSAGE("It's not very effective…"); - } + } } } } @@ -142,7 +142,7 @@ SINGLE_BATTLE_TEST("Revelation Dance becomes Normal type if used by a Typeless P NONE_OF { ANIMATION(ANIM_TYPE_MOVE, MOVE_REVELATION_DANCE, player); HP_BAR(opponent); - MESSAGE("It's not very effective…"); + MESSAGE("It's not very effective…"); } } } diff --git a/test/battle/move_effect/sleep_talk.c b/test/battle/move_effect/sleep_talk.c index 0a42eb90e9..8ecd600f36 100644 --- a/test/battle/move_effect/sleep_talk.c +++ b/test/battle/move_effect/sleep_talk.c @@ -14,7 +14,7 @@ SINGLE_BATTLE_TEST("Sleep Talk fails if not asleep") u32 status; PARAMETRIZE { status = STATUS1_SLEEP; } PARAMETRIZE { status = STATUS1_NONE; } - + GIVEN { PLAYER(SPECIES_WOBBUFFET) { Status1(status); Moves(MOVE_SLEEP_TALK, MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH); } OPPONENT(SPECIES_WOBBUFFET); @@ -35,7 +35,7 @@ SINGLE_BATTLE_TEST("Sleep Talk fails if not asleep") SINGLE_BATTLE_TEST("Sleep Talk works if user has Comatose") { - + GIVEN { PLAYER(SPECIES_KOMALA) { Moves(MOVE_SLEEP_TALK, MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH); } OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/telekinesis.c b/test/battle/move_effect/telekinesis.c index 4210b1865b..3da96a08b9 100644 --- a/test/battle/move_effect/telekinesis.c +++ b/test/battle/move_effect/telekinesis.c @@ -71,4 +71,4 @@ SINGLE_BATTLE_TEST("Telekinesis makes the target immune to Ground-type attacks") TO_DO_BATTLE_TEST("Baton Pass passes Telekinesis' effect"); //Bulbapedia doesn't confirm what happens with Diglett, Dugtrio, Sandygast and Palossand, so it needs to be tested in-game. -TO_DO_BATTLE_TEST("Baton Pass removes Telekinesis' effect disappears if the switching-in mon is Mega Gengar"); +TO_DO_BATTLE_TEST("Baton Pass removes Telekinesis' effect disappears if the switching-in mon is Mega Gengar"); diff --git a/tools/learnset_helpers/teachable.py b/tools/learnset_helpers/teachable.py index 92ed8562d8..eb109e7a46 100644 --- a/tools/learnset_helpers/teachable.py +++ b/tools/learnset_helpers/teachable.py @@ -13,7 +13,7 @@ with open("./include/config/pokemon.h", "r") as file: def parse_mon_name(name): return re.sub(r'(?!^)([A-Z]+)', r'_\1', name).upper() - + tm_moves = [] tutor_moves = [] @@ -196,7 +196,7 @@ for move in tm_moves: header += "// " + longest_move_name * "*" + " //\n" header_print(tutor_title) tutor_moves.sort() # alphabetically sort tutor moves for easier referencing -for move in tutor_moves: +for move in tutor_moves: header_print("- " + move) header += "// " + longest_move_name * "*" + " //\n" header_print(universal_title) diff --git a/tools/preproc/asm_file.cpp b/tools/preproc/asm_file.cpp index ca8b8cc4ae..39d352bbd7 100644 --- a/tools/preproc/asm_file.cpp +++ b/tools/preproc/asm_file.cpp @@ -673,14 +673,14 @@ int AsmFile::FindLastLineNumber(std::string& filename) if (pos < 0) RaiseError("line indicator for header file not found before `enum`"); - + pos++; while (m_buffer[pos] == ' ' || m_buffer[pos] == '\t') pos++; if (!IsAsciiDigit(m_buffer[pos])) RaiseError("malformatted line indicator found before `enum`, expected line number"); - + unsigned n = 0; int digit = 0; while ((digit = ConvertDigit(m_buffer[pos++], 10)) != -1) @@ -715,7 +715,7 @@ int AsmFile::FindLastLineNumber(std::string& filename) filename += c; } - + return n + linebreaks - 1; } From fe275ef0629cf4560c774bbccba54fd5aeee1f8d Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Thu, 15 Aug 2024 07:45:01 -0400 Subject: [PATCH 30/64] Teatime animations use B_WAIT_TIME_LONG (#5173) --- data/battle_scripts_1.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index c47127c651..47436136ca 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -578,7 +578,7 @@ BattleScript_Teatimerod: statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_TeatimeBuffer jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_TeatimeBuffer printfromtable gStatUpStringIds - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG moveendto MOVEEND_NEXT_TARGET jumpifnexttargetvalid BattleScript_TeatimeLoop moveendcase MOVEEND_CLEAR_BITS @@ -590,7 +590,7 @@ BattleScript_Teatimemotor: statbuffchange STAT_CHANGE_ALLOW_PTR, BattleScript_TeatimeBuffer jumpifbyte CMP_EQUAL, cMULTISTRING_CHOOSER, 0x2, BattleScript_TeatimeBuffer printfromtable gStatUpStringIds - waitmessage 0x40 + waitmessage B_WAIT_TIME_LONG moveendto MOVEEND_NEXT_TARGET jumpifnexttargetvalid BattleScript_TeatimeLoop moveendcase MOVEEND_CLEAR_BITS From 45f10d734fde18c96fccdf2bf152c9e3e3aebae8 Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Thu, 15 Aug 2024 13:51:39 +0200 Subject: [PATCH 31/64] Fixed Ice Face, implemented tests (#5171) * Fixed Ice Face, implemented tests * Fixed agbcc and bad battle mon looping * Fixed the ShouldChangeFormInWeather function again * Cleaned up End of Turn weather form changes, simplified Ice Face --------- Co-authored-by: Hedara --- include/battle.h | 1 - src/battle_main.c | 2 - src/battle_util.c | 45 +++-------- test/battle/ability/ice_face.c | 140 +++++++++++++++++++++++++++++++-- 4 files changed, 146 insertions(+), 42 deletions(-) diff --git a/include/battle.h b/include/battle.h index 1d60aacec1..ace178c0e7 100644 --- a/include/battle.h +++ b/include/battle.h @@ -763,7 +763,6 @@ struct BattleStruct bool8 effectsBeforeUsingMoveDone:1; // Mega Evo and Focus Punch/Shell Trap effects. u8 targetsDone[MAX_BATTLERS_COUNT]; // Each battler as a bit. u16 overwrittenAbilities[MAX_BATTLERS_COUNT]; // abilities overwritten during battle (keep separate from battle history in case of switching) - bool8 allowedToChangeFormInWeather[PARTY_SIZE][NUM_BATTLE_SIDES]; // For each party member and side, used by Ice Face. u8 battleBondTransformed[NUM_BATTLE_SIDES]; // Bitfield for each party. u8 storedHealingWish:4; // Each battler as a bit. u8 storedLunarDance:4; // Each battler as a bit. diff --git a/src/battle_main.c b/src/battle_main.c index e164976e9d..55337a045e 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3114,8 +3114,6 @@ static void BattleStartClearSetData(void) gBattleStruct->itemLost[B_SIDE_PLAYER][i].originalItem = GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM); gBattleStruct->itemLost[B_SIDE_OPPONENT][i].originalItem = GetMonData(&gEnemyParty[i], MON_DATA_HELD_ITEM); gPartyCriticalHits[i] = 0; - gBattleStruct->allowedToChangeFormInWeather[i][B_SIDE_PLAYER] = FALSE; - gBattleStruct->allowedToChangeFormInWeather[i][B_SIDE_OPPONENT] = FALSE; } gBattleStruct->swapDamageCategory = FALSE; // Photon Geyser, Shell Side Arm, Light That Burns the Sky diff --git a/src/battle_util.c b/src/battle_util.c index ada7cb20a3..c18b0544a0 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1671,7 +1671,6 @@ enum ENDTURN_ION_DELUGE, ENDTURN_FAIRY_LOCK, ENDTURN_RETALIATE, - ENDTURN_WEATHER_FORM, ENDTURN_STATUS_HEAL, ENDTURN_RAINBOW, ENDTURN_SEA_OF_FIRE, @@ -2171,18 +2170,6 @@ u8 DoFieldEndTurnEffects(void) gSideTimers[B_SIDE_OPPONENT].retaliateTimer--; gBattleStruct->turnCountersTracker++; break; - case ENDTURN_WEATHER_FORM: - for (i = 0; i < gBattlersCount; i++) - { - if (AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, i, 0, 0, 0)) - { - effect++; - break; - } - } - if (effect == 0) - gBattleStruct->turnCountersTracker++; - break; case ENDTURN_STATUS_HEAL: for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++) { @@ -3894,21 +3881,6 @@ static const u16 sWeatherFlagsInfo[][3] = [ENUM_WEATHER_FOG] = {B_WEATHER_FOG_TEMPORARY, B_WEATHER_FOG_PERMANENT, HOLD_EFFECT_NONE}, }; -static void ShouldChangeFormInWeather(u32 battler) -{ - int i; - int side = GetBattlerSide(battler); - struct Pokemon *party = GetSideParty(side); - - for (i = 0; i < PARTY_SIZE; i++) - { - if (GetMonData(&party[i], MON_DATA_SPECIES) == SPECIES_EISCUE_NOICE_FACE) - gBattleStruct->allowedToChangeFormInWeather[i][side] = TRUE; - else - gBattleStruct->allowedToChangeFormInWeather[i][side] = FALSE; - } -} - bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility) { u16 battlerAbility = GetBattlerAbility(battler); @@ -3922,7 +3894,6 @@ bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility) else if (B_ABILITY_WEATHER < GEN_6 && viaAbility && !(gBattleWeather & sWeatherFlagsInfo[weatherEnumId][1])) { gBattleWeather = (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1]); - ShouldChangeFormInWeather(battler); return TRUE; } else if (!(gBattleWeather & (sWeatherFlagsInfo[weatherEnumId][0] | sWeatherFlagsInfo[weatherEnumId][1]))) @@ -3932,7 +3903,6 @@ bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility) gWishFutureKnock.weatherDuration = 8; else gWishFutureKnock.weatherDuration = 5; - ShouldChangeFormInWeather(battler); return TRUE; } return FALSE; @@ -4961,6 +4931,17 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 effect++; } break; + case ABILITY_ICE_FACE: + if (IsBattlerWeatherAffected(battler, B_WEATHER_HAIL | B_WEATHER_SNOW) + && gBattleMons[battler].species == SPECIES_EISCUE_NOICE_FACE + && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)) + { + // TODO: Convert this to a proper FORM_CHANGE type. + gBattleMons[battler].species = SPECIES_EISCUE_ICE_FACE; + BattleScriptPushCursorAndCallback(BattleScript_BattlerFormChangeWithStringEnd3); + effect++; + } + break; } break; case ABILITYEFFECT_ENDTURN: @@ -6285,11 +6266,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 case ABILITY_ICE_FACE: if (IsBattlerWeatherAffected(battler, B_WEATHER_HAIL | B_WEATHER_SNOW) && gBattleMons[battler].species == SPECIES_EISCUE_NOICE_FACE - && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED) - && gBattleStruct->allowedToChangeFormInWeather[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)]) + && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)) { // TODO: Convert this to a proper FORM_CHANGE type. - gBattleStruct->allowedToChangeFormInWeather[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)] = FALSE; gBattleMons[battler].species = SPECIES_EISCUE_ICE_FACE; BattleScriptPushCursorAndCallback(BattleScript_BattlerFormChangeWithStringEnd3); effect++; diff --git a/test/battle/ability/ice_face.c b/test/battle/ability/ice_face.c index 53917b5623..54a307754c 100644 --- a/test/battle/ability/ice_face.c +++ b/test/battle/ability/ice_face.c @@ -1,9 +1,137 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("Ice Face blocks physical moves, changing Eiscue into its Noice Face form"); // Include Special move in test -TO_DO_BATTLE_TEST("Ice Face is restored if hail or snow begins while Noice Face Eiscue is out"); -TO_DO_BATTLE_TEST("Ice Face is restored if Noice Face Eiscue is sent in while hail or snow is active"); -TO_DO_BATTLE_TEST("Ice Face is not restored if Eiscue changes into Noice Face form while there's already hail"); -TO_DO_BATTLE_TEST("Ice Face form change persists after switching out"); -TO_DO_BATTLE_TEST("Ice Face doesn't transform Eiscue if Cloud Nine/Air Lock is on the field"); +SINGLE_BATTLE_TEST("Ice Face blocks physical moves, changing Eiscue into its Noice Face form") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_EISCUE); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + } +} + +SINGLE_BATTLE_TEST("Ice Face does not block special moves, Eiscue stays in Ice Face form") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(gMovesInfo[MOVE_EMBER].category == DAMAGE_CATEGORY_SPECIAL); + PLAYER(SPECIES_EISCUE); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_EMBER); } + } SCENE { + NOT ABILITY_POPUP(player, ABILITY_ICE_FACE); + } +} + +SINGLE_BATTLE_TEST("Ice Face is restored if hail or snow begins while Noice Face Eiscue is out") +{ + u32 move; + PARAMETRIZE { move = MOVE_SNOWSCAPE; } + PARAMETRIZE { move = MOVE_HAIL; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); + ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + PLAYER(SPECIES_EISCUE); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(opponent, move); } + TURN { MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + } +} + +SINGLE_BATTLE_TEST("Ice Face is restored if Noice Face Eiscue is sent in while hail or snow is active") +{ + u32 move; + PARAMETRIZE { move = MOVE_SNOWSCAPE; } + PARAMETRIZE { move = MOVE_HAIL; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); + ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + PLAYER(SPECIES_EISCUE); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_TACKLE); } + TURN { SWITCH(player, 1); MOVE(opponent, move); } + TURN { SWITCH(player, 0); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + } +} + +SINGLE_BATTLE_TEST("Ice Face is not restored if Eiscue changes into Noice Face form while there's already hail or snow") +{ + u32 move; + PARAMETRIZE { move = MOVE_SNOWSCAPE; } + PARAMETRIZE { move = MOVE_HAIL; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); + ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + PLAYER(SPECIES_EISCUE) { HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, move); MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + MESSAGE("Eiscue used Celebrate!"); + MESSAGE("Eiscue fainted!"); + } +} + +SINGLE_BATTLE_TEST("Ice Face form change persists after switching out") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_EISCUE) { HP(1); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_CELEBRATE); } + TURN { SWITCH(player, 0); MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + MESSAGE("Eiscue fainted!"); + } +} + +SINGLE_BATTLE_TEST("Ice Face doesn't transform Eiscue if Cloud Nine/Air Lock is on the field") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_EISCUE) { HP(1); } + OPPONENT(SPECIES_RAYQUAZA) { Ability(ABILITY_AIR_LOCK); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_SNOWSCAPE); MOVE(opponent, MOVE_TACKLE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ICE_FACE); + MESSAGE("Eiscue transformed!"); + MESSAGE("Eiscue fainted!"); + } +} From 47356d181ac954897d92c2edcc1fa72400160a53 Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Thu, 15 Aug 2024 19:27:35 +0200 Subject: [PATCH 32/64] Fixed followers breaking for species IDs above 1535 (#5179) * Fixed followers breaking for species Ids above 1535 * Added reminder to increase follower species bits if needed in the future --------- Co-authored-by: Hedara --- include/constants/event_objects.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/constants/event_objects.h b/include/constants/event_objects.h index e2ac7f7920..fccc206638 100644 --- a/include/constants/event_objects.h +++ b/include/constants/event_objects.h @@ -271,7 +271,7 @@ #define OBJ_EVENT_GFX_VAR_F (OBJ_EVENT_GFX_VARS + 0xF) #define OBJ_EVENT_GFX_MON_BASE 0x200 // 512 -#define OBJ_EVENT_GFX_SPECIES_BITS 11 +#define OBJ_EVENT_GFX_SPECIES_BITS 12 // This will need to be updated when NUM_SPECIES is > ~3.5k #define OBJ_EVENT_GFX_SPECIES_MASK ((1 << OBJ_EVENT_GFX_SPECIES_BITS) - 1) // Used to call a specific species' follower graphics. Useful for static encounters. From ec3a86dd9a85c6dd6c85ff0826b576925ef0383e Mon Sep 17 00:00:00 2001 From: PhallenTree <168426989+PhallenTree@users.noreply.github.com> Date: Fri, 16 Aug 2024 14:37:23 +0100 Subject: [PATCH 33/64] Adds in-battle effect of Pickup, adds Harvest and Pickup tests (#5170) * Adds Harvest tests * Adds Pickup in-battle effect + tests * Fix G-Max Replenish test (Munchlax activates Pickup before G-Max Replenish) * Change canPickupItem to bit field * Make RandomUniformExcept inclusive (higher end) + convert bitfield * Use CantPickupItem in PickupHasValidTargetc check * Review --- data/battle_scripts_1.s | 9 ++ include/battle.h | 1 + include/battle_scripts.h | 1 + include/battle_util.h | 2 + include/random.h | 2 + src/battle_main.c | 2 + src/battle_script_commands.c | 6 +- src/battle_util.c | 32 +++- test/battle/ability/harvest.c | 274 +++++++++++++++++++++++++++++-- test/battle/ability/pickup.c | 295 ++++++++++++++++++++++++++++++++++ test/battle/gimmick/dynamax.c | 2 +- test/test_runner_battle.c | 2 +- 12 files changed, 610 insertions(+), 18 deletions(-) create mode 100644 test/battle/ability/pickup.c diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index c47127c651..95fffd0513 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -7754,6 +7754,15 @@ BattleScript_CheekPouchActivates:: copybyte gBattlerAttacker, sSAVED_BATTLER return +BattleScript_PickupActivates:: + pause 5 + tryrecycleitem BattleScript_PickupActivatesEnd + call BattleScript_AbilityPopUp + printstring STRINGID_XFOUNDONEY + waitmessage B_WAIT_TIME_LONG +BattleScript_PickupActivatesEnd: + end3 + BattleScript_HarvestActivates:: pause 5 tryrecycleitem BattleScript_HarvestActivatesEnd diff --git a/include/battle.h b/include/battle.h index ace178c0e7..0d54f2a614 100644 --- a/include/battle.h +++ b/include/battle.h @@ -676,6 +676,7 @@ struct BattleStruct u16 chosenItem[MAX_BATTLERS_COUNT]; u16 choicedMove[MAX_BATTLERS_COUNT]; u16 changedItems[MAX_BATTLERS_COUNT]; + u8 canPickupItem; u8 switchInBattlerCounter; u8 arenaTurnCounter; u8 turnSideTracker; diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 6bdb88b28f..cd35e1de82 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -295,6 +295,7 @@ extern const u8 BattleScript_WeakArmorActivates[]; extern const u8 BattleScript_FellStingerRaisesStat[]; extern const u8 BattleScript_SnowWarningActivatesHail[]; extern const u8 BattleScript_SnowWarningActivatesSnow[]; +extern const u8 BattleScript_PickupActivates[]; extern const u8 BattleScript_HarvestActivates[]; extern const u8 BattleScript_ImposterActivates[]; extern const u8 BattleScript_SelectingNotAllowedMoveAssaultVest[]; diff --git a/include/battle_util.h b/include/battle_util.h index 8eadf47c98..de05242902 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -231,6 +231,8 @@ bool32 TryRoomService(u32 battler); void BufferStatChange(u32 battler, u8 statId, u8 stringId); bool32 BlocksPrankster(u16 move, u32 battlerPrankster, u32 battlerDef, bool32 checkTarget); u16 GetUsedHeldItem(u32 battler); +bool32 PickupHasValidTarget(u32 battler); +bool32 CantPickupItem(u32 battler); bool32 IsBattlerWeatherAffected(u32 battler, u32 weatherFlags); u32 GetBattlerMoveTargetType(u32 battler, u32 move); bool32 CanTargetBattler(u32 battlerAtk, u32 battlerDef, u16 move); diff --git a/include/random.h b/include/random.h index cd7e26b589..d254a08f03 100644 --- a/include/random.h +++ b/include/random.h @@ -173,12 +173,14 @@ enum RandomTag RNG_G_MAX_BEFUDDLE, RNG_G_MAX_REPLENISH, RNG_G_MAX_SNOOZE, + RNG_HARVEST, RNG_HITS, RNG_HOLD_EFFECT_FLINCH, RNG_INFATUATION, RNG_LOADED_DICE, RNG_METRONOME, RNG_PARALYSIS, + RNG_PICKUP, RNG_POISON_POINT, RNG_POISON_TOUCH, RNG_RAMPAGE_TURNS, diff --git a/src/battle_main.c b/src/battle_main.c index 55337a045e..10f27e921f 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3219,6 +3219,7 @@ void SwitchInClearSetData(u32 battler) gBattleStruct->lastMoveFailed &= ~(gBitTable[battler]); gBattleStruct->palaceFlags &= ~(gBitTable[battler]); gBattleStruct->boosterEnergyActivates &= ~(gBitTable[battler]); + gBattleStruct->canPickupItem &= ~(1u << battler); for (i = 0; i < ARRAY_COUNT(gSideTimers); i++) { @@ -5112,6 +5113,7 @@ static void TurnValuesCleanUp(bool8 var0) if (gDisableStructs[i].rechargeTimer == 0) gBattleMons[i].status2 &= ~STATUS2_RECHARGE; } + gBattleStruct->canPickupItem &= ~(1u << i); } if (gDisableStructs[i].substituteHP == 0) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index afc63fed9b..6ba28f5027 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -8071,6 +8071,7 @@ static void Cmd_removeitem(void) gBattleStruct->usedHeldItems[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)] = itemId; // Remember if switched out gBattleMons[battler].item = ITEM_NONE; + gBattleStruct->canPickupItem |= (1u << battler); CheckSetUnburden(battler); BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_HELDITEM_BATTLE, 0, sizeof(gBattleMons[battler].item), &gBattleMons[battler].item); @@ -14853,7 +14854,10 @@ static void Cmd_tryrecycleitem(void) u16 *usedHeldItem; - usedHeldItem = &gBattleStruct->usedHeldItems[gBattlerPartyIndexes[gBattlerAttacker]][GetBattlerSide(gBattlerAttacker)]; + if (gCurrentMove == MOVE_NONE && GetBattlerAbility(gBattlerAttacker) == ABILITY_PICKUP) + usedHeldItem = &gBattleStruct->usedHeldItems[gBattlerPartyIndexes[gBattlerTarget]][GetBattlerSide(gBattlerTarget)]; + else + usedHeldItem = &gBattleStruct->usedHeldItems[gBattlerPartyIndexes[gBattlerAttacker]][GetBattlerSide(gBattlerAttacker)]; if (*usedHeldItem != ITEM_NONE && gBattleMons[gBattlerAttacker].item == ITEM_NONE) { gLastUsedItem = *usedHeldItem; diff --git a/src/battle_util.c b/src/battle_util.c index c18b0544a0..8729d0cf1a 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -4950,8 +4950,19 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 gBattlerAttacker = battler; switch (gLastUsedAbility) { + case ABILITY_PICKUP: + if (gBattleMons[battler].item == ITEM_NONE + && gBattleStruct->changedItems[battler] == ITEM_NONE // Will not inherit an item + && PickupHasValidTarget(battler)) + { + gBattlerTarget = RandomUniformExcept(RNG_PICKUP, 0, gBattlersCount - 1, CantPickupItem); + gLastUsedItem = GetUsedHeldItem(gBattlerTarget); + BattleScriptPushCursorAndCallback(BattleScript_PickupActivates); + effect++; + } + break; case ABILITY_HARVEST: - if ((IsBattlerWeatherAffected(battler, B_WEATHER_SUN) || Random() % 2 == 0) + if ((IsBattlerWeatherAffected(battler, B_WEATHER_SUN) || RandomPercentage(RNG_HARVEST, 50)) && gBattleMons[battler].item == ITEM_NONE && gBattleStruct->changedItems[battler] == ITEM_NONE // Will not inherit an item && ItemId_GetPocket(GetUsedHeldItem(battler)) == POCKET_BERRIES) @@ -11398,6 +11409,25 @@ u16 GetUsedHeldItem(u32 battler) return gBattleStruct->usedHeldItems[gBattlerPartyIndexes[battler]][GetBattlerSide(battler)]; } +bool32 CantPickupItem(u32 battler) +{ + // Used by RandomUniformExcept() for RNG_PICKUP + if (battler == gBattlerAttacker && gBattleTypeFlags & (BATTLE_TYPE_TRAINER | BATTLE_TYPE_LINK)) + return TRUE; + return !(IsBattlerAlive(battler) && GetUsedHeldItem(battler) && gBattleStruct->canPickupItem & (1u << battler)); +} + +bool32 PickupHasValidTarget(u32 battler) +{ + u32 i; + for (i = 0; i < gBattlersCount; i++) + { + if (!CantPickupItem(i)) + return TRUE; + } + return FALSE; +} + bool32 IsBattlerWeatherAffected(u32 battler, u32 weatherFlags) { if (gBattleWeather & weatherFlags && WEATHER_HAS_EFFECT) diff --git a/test/battle/ability/harvest.c b/test/battle/ability/harvest.c index b4783c4542..f19e0715de 100644 --- a/test/battle/ability/harvest.c +++ b/test/battle/ability/harvest.c @@ -1,18 +1,264 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("Harvest has a 50% chance to restore a Berry at the end of the turn"); -TO_DO_BATTLE_TEST("Harvest always restores a Berry in Sunlight"); -TO_DO_BATTLE_TEST("Harvest doesn't always restore a Berry if Cloud Nine/Air Lock is on the field"); -TO_DO_BATTLE_TEST("Harvest restores a Berry even after being switched out and back in"); -TO_DO_BATTLE_TEST("Harvest restores a Berry consumed by Fling"); -TO_DO_BATTLE_TEST("Harvest restores a Berry consumed by Natural Gift"); +ASSUMPTIONS +{ + ASSUME(gItemsInfo[ITEM_SITRUS_BERRY].holdEffect == HOLD_EFFECT_RESTORE_PCT_HP); + ASSUME(I_SITRUS_BERRY_HEAL >= GEN_4); + ASSUME(gMovesInfo[MOVE_SUNNY_DAY].effect == EFFECT_SUNNY_DAY); +} + +SINGLE_BATTLE_TEST("Harvest has a 50% chance to restore a Berry at the end of the turn") +{ + PASSES_RANDOMLY(1, 2, RNG_HARVEST); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); MaxHP(500); HP(251); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ABILITY_POPUP(opponent, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(opponent->item, ITEM_SITRUS_BERRY); + } +} + +SINGLE_BATTLE_TEST("Harvest always restores a Berry in Sunlight") +{ + PASSES_RANDOMLY(1, 1, RNG_HARVEST); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); MaxHP(500); HP(251); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_SUNNY_DAY); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, opponent); + ABILITY_POPUP(opponent, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(opponent->item, ITEM_SITRUS_BERRY); + } +} + +SINGLE_BATTLE_TEST("Harvest doesn't always restore a Berry if Cloud Nine/Air Lock is on the field") +{ + PASSES_RANDOMLY(1, 2, RNG_HARVEST); + GIVEN { + PLAYER(SPECIES_GOLDUCK) { Ability(ABILITY_CLOUD_NINE); } + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); MaxHP(500); HP(251); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_SUNNY_DAY); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, opponent); + NOT ABILITY_POPUP(opponent, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(opponent->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Harvest restores a Berry even after being switched out and back in") +{ + ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); MaxHP(500); HP(251); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_PARTING_SHOT); SEND_OUT(opponent, 1); } + TURN { MOVE(player, MOVE_SUNNY_DAY); MOVE(opponent, MOVE_PARTING_SHOT); SEND_OUT(opponent, 0); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player); + ABILITY_POPUP(opponent, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(opponent->item, ITEM_SITRUS_BERRY); + } +} + +SINGLE_BATTLE_TEST("Harvest restores a Berry consumed by Fling") +{ + ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_SUNNY_DAY); MOVE(opponent, MOVE_FLING); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, opponent); + ABILITY_POPUP(opponent, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(opponent->item, ITEM_SITRUS_BERRY); + } +} + +SINGLE_BATTLE_TEST("Harvest restores a Berry consumed by Natural Gift") +{ + ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_SUNNY_DAY); MOVE(opponent, MOVE_NATURAL_GIFT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_NATURAL_GIFT, opponent); + ABILITY_POPUP(opponent, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(opponent->item, ITEM_SITRUS_BERRY); + } +} + TO_DO_BATTLE_TEST("Harvest only works once per turn"); // Check for berries that are consumed immediately, like Pecha Berry -TO_DO_BATTLE_TEST("Harvest doesn't restore a Berry when destroyed by Incinerate"); -TO_DO_BATTLE_TEST("Harvest doesn't restore a Berry when knocked off by Knock Off"); -TO_DO_BATTLE_TEST("Harvest doesn't restore a Berry when eaten by Bug Bite/Pluck"); -TO_DO_BATTLE_TEST("Harvest doesn't restore a Berry that's collected via Pickup"); -TO_DO_BATTLE_TEST("Harvest order is affected by speed"); -TO_DO_BATTLE_TEST("Harvest doesn't restore a Berry when transfered to another Pokémon"); -TO_DO_BATTLE_TEST("Harvest can restore a Berry that was transferred from another Pokémon"); -TO_DO_BATTLE_TEST("Harvest can only restore the newest berry consumed that was transferred from another Pokémon instead of its original Berry"); + +SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when destroyed by Incinerate") +{ + PASSES_RANDOMLY(1, 1, RNG_HARVEST); + ASSUME(MoveHasAdditionalEffect(MOVE_INCINERATE, MOVE_EFFECT_INCINERATE)); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_INCINERATE); MOVE(opponent, MOVE_SUNNY_DAY); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INCINERATE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, opponent); + NOT ABILITY_POPUP(opponent, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(opponent->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when knocked off by Knock Off") +{ + PASSES_RANDOMLY(1, 1, RNG_HARVEST); + ASSUME(MoveHasAdditionalEffect(MOVE_KNOCK_OFF, MOVE_EFFECT_KNOCK_OFF)); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_KNOCK_OFF); MOVE(opponent, MOVE_SUNNY_DAY); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_KNOCK_OFF, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, opponent); + NOT ABILITY_POPUP(opponent, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(opponent->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when eaten by Bug Bite/Pluck") +{ + PASSES_RANDOMLY(1, 1, RNG_HARVEST); + ASSUME(MoveHasAdditionalEffect(MOVE_BUG_BITE, MOVE_EFFECT_BUG_BITE)); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_BUG_BITE); MOVE(opponent, MOVE_SUNNY_DAY); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BUG_BITE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, opponent); + NOT ABILITY_POPUP(opponent, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(opponent->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry that's collected via Pickup") +{ + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Speed(50); Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_EXEGGUTOR) { Speed(10); Ability(ABILITY_HARVEST); MaxHP(500); HP(251); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_SUNNY_DAY); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, opponent); + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + NOT ABILITY_POPUP(opponent, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(player->item, ITEM_SITRUS_BERRY); + EXPECT_EQ(opponent->item, ITEM_NONE); + } +} + +DOUBLE_BATTLE_TEST("Harvest order is affected by speed") +{ + GIVEN { + PLAYER(SPECIES_EXEGGUTOR) { Speed(2); Ability(ABILITY_HARVEST); MaxHP(500); HP(251); Item(ITEM_SITRUS_BERRY); } + PLAYER(SPECIES_WOBBUFFET) { Speed(5); } + OPPONENT(SPECIES_EXEGGUTOR) { Speed(10); Ability(ABILITY_HARVEST); MaxHP(500); HP(251); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(50); } + } WHEN { + TURN { MOVE(playerRight, MOVE_BULLDOZE); MOVE(playerLeft, MOVE_SUNNY_DAY); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BULLDOZE, playerRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, playerLeft); + ABILITY_POPUP(opponentLeft, ABILITY_HARVEST); + ABILITY_POPUP(playerLeft, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(opponentLeft->item, ITEM_SITRUS_BERRY); + EXPECT_EQ(playerLeft->item, ITEM_SITRUS_BERRY); + } +} + +SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when transfered to another Pokémon") +{ + ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_SUNNY_DAY); MOVE(opponent, MOVE_TRICK); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TRICK, opponent); + NOT ABILITY_POPUP(opponent, ABILITY_HARVEST); + } THEN { + EXPECT_EQ(opponent->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Harvest can restore a Berry that was transferred from another Pokémon") +{ + ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK); + GIVEN { + PLAYER(SPECIES_TORKOAL) { Ability(ABILITY_DROUGHT); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); HP(100); MaxHP(500); } + } WHEN { + TURN { MOVE(opponent, MOVE_TRICK); MOVE(player, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TRICK, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + ABILITY_POPUP(opponent, ABILITY_HARVEST); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + } THEN { + EXPECT_GT(opponent->hp, opponent->maxHP / 2); // eats 2 Sitrus + } +} + +SINGLE_BATTLE_TEST("Harvest can only restore the newest berry consumed that was transferred from another Pokémon instead of its original Berry") +{ + ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK); + ASSUME(gItemsInfo[ITEM_APICOT_BERRY].holdEffect == HOLD_EFFECT_SP_DEFENSE_UP); + GIVEN { + PLAYER(SPECIES_TORKOAL) { Ability(ABILITY_DROUGHT); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); HP(100); MaxHP(500); Item(ITEM_APICOT_BERRY); } + } WHEN { + TURN { MOVE(opponent, MOVE_TRICK); MOVE(player, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TRICK, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + ABILITY_POPUP(opponent, ABILITY_HARVEST); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + } THEN { + EXPECT_GT(opponent->hp, opponent->maxHP / 2); // eats 2 Sitrus + } +} diff --git a/test/battle/ability/pickup.c b/test/battle/ability/pickup.c new file mode 100644 index 0000000000..57f6429feb --- /dev/null +++ b/test/battle/ability/pickup.c @@ -0,0 +1,295 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gItemsInfo[ITEM_SITRUS_BERRY].holdEffect == HOLD_EFFECT_RESTORE_PCT_HP); + ASSUME(I_SITRUS_BERRY_HEAL >= GEN_4); +} + +SINGLE_BATTLE_TEST("Pickup grants an item used by another Pokémon") +{ + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + } THEN { + EXPECT_EQ(player->item, ITEM_SITRUS_BERRY); + } +} + +SINGLE_BATTLE_TEST("Pickup doesn't grant the user their item") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); MaxHP(500); HP(251); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + NONE_OF { + ABILITY_POPUP(opponent, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + } + } THEN { + EXPECT_EQ(opponent->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Pickup doesn't grant another Pokémon's popped Air Balloon") +{ + ASSUME(gItemsInfo[ITEM_AIR_BALLOON].holdEffect == HOLD_EFFECT_AIR_BALLOON); + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_AIR_BALLOON); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + NONE_OF { + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Air Balloon!"); + } + } THEN { + EXPECT_EQ(opponent->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Pickup doesn't grant an item not used that turn") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); } + TURN { SWITCH(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + NONE_OF { + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + } + } THEN { + EXPECT_EQ(player->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Pickup doesn't grant an item after its holder faints") +{ + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_MEMENTO); SEND_OUT(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + NONE_OF { + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + } + } THEN { + EXPECT_EQ(player->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if holder is replaced") +{ + ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_WOBBUFFET) { MaxHP(300); HP(151); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_WOBBUFFET) { MaxHP(300); HP(151); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_PARTING_SHOT); SEND_OUT(opponent, 1); } + TURN { MOVE(player, MOVE_U_TURN); SEND_OUT(player, 1); MOVE(opponent, MOVE_PARTING_SHOT); SEND_OUT(opponent, 0); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_PARTING_SHOT, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_U_TURN, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_PARTING_SHOT, opponent); + NONE_OF { + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + } + } THEN { + EXPECT_EQ(player->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Pickup doesn't grant an item if it destroyed the item with Incinerate") +{ + ASSUME(MoveHasAdditionalEffect(MOVE_INCINERATE, MOVE_EFFECT_INCINERATE)); + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_INCINERATE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INCINERATE, player); + NONE_OF { + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + } + } THEN { + EXPECT_EQ(player->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Pickup doesn't grant an item if it knocked off that item") +{ + ASSUME(MoveHasAdditionalEffect(MOVE_KNOCK_OFF, MOVE_EFFECT_KNOCK_OFF)); + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_KNOCK_OFF); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_KNOCK_OFF, player); + NONE_OF { + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + } + } THEN { + EXPECT_EQ(player->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Pickup doesn't grant an item if the user eats it with Bug Bite/Pluck") +{ + ASSUME(MoveHasAdditionalEffect(MOVE_BUG_BITE, MOVE_EFFECT_BUG_BITE)); + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_BUG_BITE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BUG_BITE, player); + NONE_OF { + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + } + } THEN { + EXPECT_EQ(player->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if its user already restored it") +{ + ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE); + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_RECYCLE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_RECYCLE, opponent); + NONE_OF { + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + } + } THEN { + EXPECT_EQ(player->item, ITEM_NONE); + } +} + +SINGLE_BATTLE_TEST("Pickup restores an item that has been Flinged") +{ + ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING); + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(opponent, MOVE_FLING); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, opponent); + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + } THEN { + EXPECT_EQ(player->item, ITEM_SITRUS_BERRY); + } +} + +SINGLE_BATTLE_TEST("Pickup restores an item that was used by Natural Gift") +{ + ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT); + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(opponent, MOVE_NATURAL_GIFT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_NATURAL_GIFT, opponent); + ABILITY_POPUP(player, ABILITY_PICKUP); + MESSAGE("Zigzagoon found one Sitrus Berry!"); + } THEN { + EXPECT_EQ(player->item, ITEM_SITRUS_BERRY); + } +} + +DOUBLE_BATTLE_TEST("Pickup triggers based on Speed order") +{ + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Speed(1); Ability(ABILITY_PICKUP); } + PLAYER(SPECIES_WOBBUFFET) { Speed(2); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(3); MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_ZIGZAGOON) { Speed(50); Ability(ABILITY_PICKUP); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_TACKLE, target: opponentLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerLeft); + ABILITY_POPUP(opponentRight, ABILITY_PICKUP); + NOT ABILITY_POPUP(playerLeft, ABILITY_PICKUP); + } THEN { + EXPECT_EQ(opponentRight->item, ITEM_SITRUS_BERRY); + EXPECT_EQ(playerLeft->item, ITEM_NONE); + } +} + +DOUBLE_BATTLE_TEST("Pickup grants a random item used by another Pokémon") +{ + PASSES_RANDOMLY(1, 3, RNG_PICKUP); + ASSUME(gItemsInfo[ITEM_WHITE_HERB].holdEffect == HOLD_EFFECT_RESTORE_STATS); + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); } + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); } + OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_BULLDOZE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BULLDOZE, playerLeft); + ABILITY_POPUP(playerLeft, ABILITY_PICKUP); + } THEN { + EXPECT_EQ(playerLeft->item, ITEM_SITRUS_BERRY); + } +} + +DOUBLE_BATTLE_TEST("Pickup doesn't trigger more than once per turn") +{ + GIVEN { + PLAYER(SPECIES_ZIGZAGOON) { HP(1); Ability(ABILITY_PICKUP); } + PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); } + OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_BULLDOZE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BULLDOZE, playerLeft); + ABILITY_POPUP(playerLeft, ABILITY_PICKUP); + NOT ABILITY_POPUP(playerLeft, ABILITY_PICKUP); + } THEN { + EXPECT_EQ(playerLeft->item, ITEM_NONE); + EXPECT_GT(playerLeft->hp, 1); + EXPECT_LT(playerLeft->hp, playerLeft->maxHP/2); + } +} diff --git a/test/battle/gimmick/dynamax.c b/test/battle/gimmick/dynamax.c index dca175c637..b865ef2f1c 100644 --- a/test/battle/gimmick/dynamax.c +++ b/test/battle/gimmick/dynamax.c @@ -1234,7 +1234,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max Replenish recycles allies' berries 50\% of t GIVEN { ASSUME(gMovesInfo[MOVE_G_MAX_REPLENISH].argument == MAX_EFFECT_RECYCLE_BERRIES); PLAYER(SPECIES_SNORLAX) { Item(ITEM_APICOT_BERRY); GigantamaxFactor(TRUE); } - PLAYER(SPECIES_MUNCHLAX) { Item(ITEM_APICOT_BERRY); } + PLAYER(SPECIES_MUNCHLAX) { Item(ITEM_APICOT_BERRY); Ability(ABILITY_THICK_FAT); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_APICOT_BERRY); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_APICOT_BERRY); } } WHEN { diff --git a/test/test_runner_battle.c b/test/test_runner_battle.c index 92789710f7..6f318bbead 100644 --- a/test/test_runner_battle.c +++ b/test/test_runner_battle.c @@ -410,7 +410,7 @@ u32 RandomUniformExcept(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reject)(u32 if (STATE->trials == 1) { u32 n = 0, i; - for (i = lo; i < hi; i++) + for (i = lo; i <= hi; i++) if (!reject(i)) n++; STATE->trials = n; From bd3d99d7d9031ef0e12de2c9d1ab31ecfca503b8 Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Fri, 16 Aug 2024 17:31:28 +0200 Subject: [PATCH 34/64] Fixed Retaliate not working correctly with passive damage (#5182) * Fixed Retaliate not working correctly when allies fainted from passive end of turn damage * Changed test parameters to use legal stats --------- Co-authored-by: Hedara --- src/battle_main.c | 5 + src/battle_script_commands.c | 2 +- src/battle_util.c | 8 -- test/battle/move_effect/retaliate.c | 137 ++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 9 deletions(-) create mode 100644 test/battle/move_effect/retaliate.c diff --git a/src/battle_main.c b/src/battle_main.c index 10f27e921f..cba22fa5ef 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4038,6 +4038,11 @@ void BattleTurnPassed(void) SetAiLogicDataForTurn(AI_DATA); // get assumed abilities, hold effects, etc of all battlers gBattleMainFunc = HandleTurnActionSelectionState; + if (gSideTimers[B_SIDE_PLAYER].retaliateTimer > 0) + gSideTimers[B_SIDE_PLAYER].retaliateTimer--; + if (gSideTimers[B_SIDE_OPPONENT].retaliateTimer > 0) + gSideTimers[B_SIDE_OPPONENT].retaliateTimer--; + if (gBattleTypeFlags & BATTLE_TYPE_PALACE) BattleScriptExecute(BattleScript_PalacePrintFlavorText); else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->arenaTurnCounter == 0) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 6ba28f5027..394a455b3a 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3502,7 +3502,7 @@ void SetMoveEffect(bool32 primary, bool32 certain) && GetBattlerAbility(BATTLE_PARTNER(gBattlerTarget)) != ABILITY_MAGIC_GUARD) { gBattleScripting.savedBattler = BATTLE_PARTNER(gBattlerTarget); - gBattleMoveDamage = gBattleMons[BATTLE_PARTNER(gBattlerTarget)].hp / 16; + gBattleMoveDamage = gBattleMons[BATTLE_PARTNER(gBattlerTarget)].maxHP / 16; if (gBattleMoveDamage == 0) gBattleMoveDamage = 1; gBattlescriptCurrInstr = BattleScript_MoveEffectFlameBurst; diff --git a/src/battle_util.c b/src/battle_util.c index 8729d0cf1a..0a680cc272 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -1670,7 +1670,6 @@ enum ENDTURN_PSYCHIC_TERRAIN, ENDTURN_ION_DELUGE, ENDTURN_FAIRY_LOCK, - ENDTURN_RETALIATE, ENDTURN_STATUS_HEAL, ENDTURN_RAINBOW, ENDTURN_SEA_OF_FIRE, @@ -2163,13 +2162,6 @@ u8 DoFieldEndTurnEffects(void) } gBattleStruct->turnCountersTracker++; break; - case ENDTURN_RETALIATE: - if (gSideTimers[B_SIDE_PLAYER].retaliateTimer > 0) - gSideTimers[B_SIDE_PLAYER].retaliateTimer--; - if (gSideTimers[B_SIDE_OPPONENT].retaliateTimer > 0) - gSideTimers[B_SIDE_OPPONENT].retaliateTimer--; - gBattleStruct->turnCountersTracker++; - break; case ENDTURN_STATUS_HEAL: for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++) { diff --git a/test/battle/move_effect/retaliate.c b/test/battle/move_effect/retaliate.c new file mode 100644 index 0000000000..581793e854 --- /dev/null +++ b/test/battle/move_effect/retaliate.c @@ -0,0 +1,137 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_RETALIATE].effect == EFFECT_RETALIATE); +} + +SINGLE_BATTLE_TEST("Retaliate doubles in base power the turn after an ally faints") +{ + s16 damage[2]; + GIVEN { + PLAYER(SPECIES_WYNAUT) { HP(1); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); } + TURN { MOVE(player, MOVE_RETALIATE); } + TURN { MOVE(player, MOVE_RETALIATE); } + } SCENE { + HP_BAR(opponent, captureDamage: &damage[0]); + HP_BAR(opponent, captureDamage: &damage[1]); + } THEN { + EXPECT_MUL_EQ(damage[1], Q_4_12(2), damage[0]); + } +} + +SINGLE_BATTLE_TEST("Retaliate doubles in base power the turn after an ally faints (opponent)") +{ + s16 damage[2]; + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT) { HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE); SEND_OUT(opponent, 1); } + TURN { MOVE(opponent, MOVE_RETALIATE); } + TURN { MOVE(opponent, MOVE_RETALIATE); } + } SCENE { + HP_BAR(player, captureDamage: &damage[0]); + HP_BAR(player, captureDamage: &damage[1]); + } THEN { + EXPECT_MUL_EQ(damage[1], Q_4_12(2), damage[0]); + } +} + +DOUBLE_BATTLE_TEST("Retaliate works with passive damage") +{ + s16 damage[2]; + u32 move; + u32 move2 = MOVE_CELEBRATE; + struct BattlePokemon *moveTarget = playerLeft; + PARAMETRIZE { move = MOVE_TOXIC; moveTarget = playerLeft; } + PARAMETRIZE { move = MOVE_POISON_POWDER; moveTarget = playerLeft; } + PARAMETRIZE { move = MOVE_WILL_O_WISP; moveTarget = playerLeft; } + #if B_USE_FROSTBITE == TRUE + PARAMETRIZE { move = MOVE_ICE_BEAM; moveTarget = playerLeft; } + #endif + PARAMETRIZE { move = MOVE_SANDSTORM; moveTarget = playerLeft; } + PARAMETRIZE { move = MOVE_HAIL; moveTarget = playerLeft; } + PARAMETRIZE { move = MOVE_LEECH_SEED; moveTarget = playerLeft; } + PARAMETRIZE { move = MOVE_MAGMA_STORM; moveTarget = playerLeft; } + PARAMETRIZE { move = MOVE_FLAME_BURST; moveTarget = playerRight; } + PARAMETRIZE { move = MOVE_FIRE_PLEDGE; moveTarget = playerRight; move2 = MOVE_GRASS_PLEDGE; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TOXIC].effect == EFFECT_TOXIC); + ASSUME(gMovesInfo[MOVE_POISON_POWDER].effect == EFFECT_POISON); + ASSUME(gMovesInfo[MOVE_WILL_O_WISP].effect == EFFECT_WILL_O_WISP); + #if B_USE_FROSTBITE == TRUE + ASSUME(gMovesInfo[MOVE_ICE_BEAM].additionalEffects[0].moveEffect == MOVE_EFFECT_FREEZE_OR_FROSTBITE); + #endif + ASSUME(gMovesInfo[MOVE_SANDSTORM].effect == EFFECT_SANDSTORM); + ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + ASSUME(gMovesInfo[MOVE_LEECH_SEED].effect == EFFECT_LEECH_SEED); + ASSUME(gMovesInfo[MOVE_MAGMA_STORM].additionalEffects[0].moveEffect == MOVE_EFFECT_WRAP); + ASSUME(gMovesInfo[MOVE_FLAME_BURST].additionalEffects[0].moveEffect == MOVE_EFFECT_FLAME_BURST); + PLAYER(SPECIES_WYNAUT) { Ability(ABILITY_SHADOW_TAG); HP(18); } + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_SHADOW_TAG); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_CLEFABLE) { Ability(ABILITY_MAGIC_GUARD); Level(1); } + OPPONENT(SPECIES_CLEFABLE) { Ability(ABILITY_MAGIC_GUARD); } + } WHEN { + TURN { MOVE(opponentRight, move2, target: moveTarget); MOVE(opponentLeft, move, target: moveTarget); MOVE(playerLeft, MOVE_CELEBRATE); SEND_OUT(playerLeft, 2); } + TURN { MOVE(opponentRight, MOVE_CELEBRATE, target: moveTarget); MOVE(playerLeft, MOVE_RETALIATE, target: opponentRight); } + TURN { MOVE(opponentRight, MOVE_CELEBRATE, target: moveTarget); MOVE(playerLeft, MOVE_RETALIATE, target: opponentRight); } + } SCENE { + if (move != MOVE_FLAME_BURST) + MESSAGE("Wynaut used Celebrate!"); + HP_BAR(opponentRight, captureDamage: &damage[0]); + HP_BAR(opponentRight, captureDamage: &damage[1]); + } THEN { + EXPECT_MUL_EQ(damage[1], Q_4_12(2), damage[0]); + } +} + +SINGLE_BATTLE_TEST("Retaliate works with Perish Song") +{ + s16 damage[2]; + GIVEN { + ASSUME(gMovesInfo[MOVE_PERISH_SONG].effect == EFFECT_PERISH_SONG); + PLAYER(SPECIES_WYNAUT); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_KOMMO_O) { Ability(ABILITY_SOUNDPROOF); } + } WHEN { + TURN { MOVE(opponent, MOVE_PERISH_SONG); } + TURN { MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(opponent, MOVE_CELEBRATE); SEND_OUT(player, 1); } + TURN { MOVE(player, MOVE_RETALIATE); } + TURN { MOVE(player, MOVE_RETALIATE); } + } SCENE { + HP_BAR(opponent, captureDamage: &damage[0]); + HP_BAR(opponent, captureDamage: &damage[1]); + } THEN { + EXPECT_MUL_EQ(damage[1], Q_4_12(2), damage[0]); + } +} + +SINGLE_BATTLE_TEST("Retaliate works with self-inflicted fainting") +{ + s16 damage[2]; + GIVEN { + ASSUME(gMovesInfo[MOVE_HEALING_WISH].effect == EFFECT_HEALING_WISH); + PLAYER(SPECIES_WYNAUT); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_HEALING_WISH); SEND_OUT(player, 1); } + TURN { MOVE(player, MOVE_RETALIATE); } + TURN { MOVE(player, MOVE_RETALIATE); } + } SCENE { + HP_BAR(opponent, captureDamage: &damage[0]); + HP_BAR(opponent, captureDamage: &damage[1]); + } THEN { + EXPECT_MUL_EQ(damage[1], Q_4_12(2), damage[0]); + } +} From bced2c97a1d3a9823c5aaf8a0c3729e0f7385601 Mon Sep 17 00:00:00 2001 From: Frank DeBlasio <35279583+fdeblasio@users.noreply.github.com> Date: Fri, 16 Aug 2024 16:41:26 -0400 Subject: [PATCH 35/64] Created PokeNav COMPOUND_STRINGS (#4983) * Converted Match Call names and descriptions to COMPOUND_STRINGs * Moved May/Brendan and Elite Four descriptions into pokenav_match_call_data.c * Moved Steven, Brendan, and May's Match Call text to pokenav_match_call_data.c * Cleaned up Steven's Match Call text * Added PokeNav option text to match_call_gfx * Moved PokeNav page descriptions to menu_handler_gfx * Moved help bar texts to pokenav_main_menu.c * Moved various PokeNav strings out of strings.c and into their relevant files * Removed unused PokeNav strings --- include/strings.h | 85 ------------------------- src/pokenav_conditions_gfx.c | 2 + src/pokenav_conditions_search_results.c | 2 + src/pokenav_list.c | 4 ++ src/pokenav_main_menu.c | 24 +++---- src/pokenav_match_call_data.c | 67 +++++++++++-------- src/pokenav_match_call_gfx.c | 11 +++- src/pokenav_match_call_list.c | 2 + src/pokenav_menu_handler_gfx.c | 30 +++++---- src/pokenav_ribbons_summary.c | 2 + src/strings.c | 84 ------------------------ 11 files changed, 90 insertions(+), 223 deletions(-) diff --git a/include/strings.h b/include/strings.h index 7ad99aad56..80df986993 100644 --- a/include/strings.h +++ b/include/strings.h @@ -986,23 +986,6 @@ extern const u8 gText_SomeonesPC[]; extern const u8 gText_PlayersPC[]; extern const u8 gText_WhichPCShouldBeAccessed[]; -extern const u8 gText_PokenavMatchCall_Strategy[]; -extern const u8 gText_PokenavMatchCall_TrainerPokemon[]; -extern const u8 gText_PokenavMatchCall_SelfIntroduction[]; -extern const u8 gText_Pokenav_ClearButtonList[]; -extern const u8 gText_PokenavMap_ZoomedOutButtons[]; -extern const u8 gText_PokenavMap_ZoomedInButtons[]; -extern const u8 gText_PokenavCondition_MonListButtons[]; -extern const u8 gText_PokenavCondition_MonStatusButtons[]; -extern const u8 gText_PokenavCondition_MarkingButtons[]; -extern const u8 gText_PokenavMatchCall_TrainerListButtons[]; -extern const u8 gText_PokenavMatchCall_CallMenuButtons[]; -extern const u8 gText_PokenavMatchCall_CheckTrainerButtons[]; -extern const u8 gText_PokenavRibbons_MonListButtons[]; -extern const u8 gText_PokenavRibbons_RibbonListButtons[]; -extern const u8 gText_PokenavRibbons_RibbonCheckButtons[]; -extern const u8 gText_Number2[]; - extern const u8 gText_Petalburg[]; extern const u8 gText_Slateport[]; extern const u8 gText_Enter2[]; @@ -2443,43 +2426,6 @@ extern const u8 MatchCall_Text_Phoebe[]; extern const u8 MatchCall_Text_Glacia[]; extern const u8 MatchCall_Text_Drake[]; extern const u8 MatchCall_Text_Wallace[]; -extern const u8 gText_MrStoneMatchCallDesc[]; -extern const u8 gText_MrStoneMatchCallName[]; -extern const u8 gText_StevenMatchCallDesc[]; -extern const u8 gText_StevenMatchCallName[]; -extern const u8 gText_MayBrendanMatchCallDesc[]; -extern const u8 gText_WallyMatchCallDesc[]; -extern const u8 gText_NormanMatchCallDesc[]; -extern const u8 gText_NormanMatchCallName[]; -extern const u8 gText_MomMatchCallDesc[]; -extern const u8 gText_MomMatchCallName[]; -extern const u8 gText_ScottMatchCallDesc[]; -extern const u8 gText_ScottMatchCallName[]; -extern const u8 gText_RoxanneMatchCallDesc[]; -extern const u8 gText_BrawlyMatchCallDesc[]; -extern const u8 gText_WattsonMatchCallDesc[]; -extern const u8 gText_FlanneryMatchCallDesc[]; -extern const u8 gText_WinonaMatchCallDesc[]; -extern const u8 gText_TateLizaMatchCallDesc[]; -extern const u8 gText_JuanMatchCallDesc[]; -extern const u8 gText_EliteFourMatchCallDesc[]; -extern const u8 gText_ChampionMatchCallDesc[]; -extern const u8 gText_ProfBirchMatchCallDesc[]; -extern const u8 gText_ProfBirchMatchCallName[]; -extern const u8 gText_MatchCallSteven_Strategy[]; -extern const u8 gText_MatchCallSteven_Pokemon[]; -extern const u8 gText_MatchCallSteven_Intro1_BeforeMeteorFallsBattle[]; -extern const u8 gText_MatchCallSteven_Intro2_BeforeMeteorFallsBattle[]; -extern const u8 gText_MatchCallSteven_Intro1_AfterMeteorFallsBattle[]; -extern const u8 gText_MatchCallSteven_Intro2_AfterMeteorFallsBattle[]; -extern const u8 gText_MatchCallBrendan_Strategy[]; -extern const u8 gText_MatchCallBrendan_Pokemon[]; -extern const u8 gText_MatchCallBrendan_Intro1[]; -extern const u8 gText_MatchCallBrendan_Intro2[]; -extern const u8 gText_MatchCallMay_Strategy[]; -extern const u8 gText_MatchCallMay_Pokemon[]; -extern const u8 gText_MatchCallMay_Intro1[]; -extern const u8 gText_MatchCallMay_Intro2[]; // Contest Link extern const u8 gText_ColorDarkGray[]; @@ -2897,37 +2843,6 @@ extern const u8 gText_CutenessContest[]; extern const u8 gText_SmartnessContest[]; extern const u8 gText_ToughnessContest[]; -// PokéNav Match Call -extern const u8 gText_CallCantBeMadeHere[]; -extern const u8 gText_NumberRegistered[]; -extern const u8 gText_NumberOfBattles[]; -extern const u8 gText_Unknown[]; -extern const u8 gText_TrainerCloseBy[]; -extern const u8 gText_Call[]; -extern const u8 gText_Check[]; -extern const u8 gText_Cancel6[]; - -// PokéNav Menu Handler -extern const u8 gText_CheckMapOfHoenn[]; -extern const u8 gText_CheckPokemonInDetail[]; -extern const u8 gText_CallRegisteredTrainer[]; -extern const u8 gText_CheckObtainedRibbons[]; -extern const u8 gText_PutAwayPokenav[]; -extern const u8 gText_CheckPartyPokemonInDetail[]; -extern const u8 gText_CheckAllPokemonInDetail[]; -extern const u8 gText_ReturnToPokenavMenu[]; -extern const u8 gText_FindCoolPokemon[]; -extern const u8 gText_FindBeautifulPokemon[]; -extern const u8 gText_FindCutePokemon[]; -extern const u8 gText_FindSmartPokemon[]; -extern const u8 gText_FindToughPokemon[]; -extern const u8 gText_ReturnToConditionMenu[]; -extern const u8 gText_NoRibbonWinners[]; - -// PokéNav -extern const u8 gText_NumberIndex[]; -extern const u8 gText_RibbonsF700[]; - // use_pokeblock extern const u8 gText_Coolness[]; extern const u8 gText_Toughness[]; diff --git a/src/pokenav_conditions_gfx.c b/src/pokenav_conditions_gfx.c index 26d8e99e06..8845307c0e 100644 --- a/src/pokenav_conditions_gfx.c +++ b/src/pokenav_conditions_gfx.c @@ -30,6 +30,8 @@ static const u32 sConditionGraphData_Gfx[] = INCBIN_U32("graphics/pokenav/condit static const u32 sConditionGraphData_Tilemap[] = INCBIN_U32("graphics/pokenav/condition/graph_data.bin.lz"); static const u16 sMonMarkings_Pal[] = INCBIN_U16("graphics/pokenav/condition/mon_markings.gbapal"); +static const u8 gText_Number2[] = _("No. "); + static const struct BgTemplate sMenuBgTemplates[3] = { { diff --git a/src/pokenav_conditions_search_results.c b/src/pokenav_conditions_search_results.c index 9afb2bb2d9..4889dd788c 100644 --- a/src/pokenav_conditions_search_results.c +++ b/src/pokenav_conditions_search_results.c @@ -22,6 +22,8 @@ enum CONDITION_SEARCH_FUNC_SELECT_MON, }; +static const u8 gText_NumberIndex[] = _("No. {DYNAMIC 0}"); + struct Pokenav_SearchResults { u32 (*callback)(struct Pokenav_SearchResults *); diff --git a/src/pokenav_list.c b/src/pokenav_list.c index ed3d40dee2..dbcf137331 100644 --- a/src/pokenav_list.c +++ b/src/pokenav_list.c @@ -96,6 +96,10 @@ static u32 LoopedTask_PrintCheckPageInfo(s32); static const u16 sListArrow_Pal[] = INCBIN_U16("graphics/pokenav/list_arrows.gbapal"); static const u32 sListArrow_Gfx[] = INCBIN_U32("graphics/pokenav/list_arrows.4bpp.lz"); +static const u8 gText_PokenavMatchCall_Strategy[] = _("STRATEGY"); +static const u8 gText_PokenavMatchCall_TrainerPokemon[] = _("TRAINER'S POKéMON"); +static const u8 gText_PokenavMatchCall_SelfIntroduction[] = _("SELF-INTRODUCTION"); + static EWRAM_DATA u32 sMoveWindowDownIndex = 0; // Read, but pointlessly bool32 CreatePokenavList(const struct BgTemplate *bgTemplate, struct PokenavListTemplate *listTemplate, s32 tileOffset) diff --git a/src/pokenav_main_menu.c b/src/pokenav_main_menu.c index 761f572d6b..dfd656833d 100644 --- a/src/pokenav_main_menu.c +++ b/src/pokenav_main_menu.c @@ -86,18 +86,18 @@ static const struct WindowTemplate sHelpBarWindowTemplate[] = static const u8 *const sHelpBarTexts[HELPBAR_COUNT] = { - [HELPBAR_NONE] = gText_Pokenav_ClearButtonList, - [HELPBAR_MAP_ZOOMED_OUT] = gText_PokenavMap_ZoomedOutButtons, - [HELPBAR_MAP_ZOOMED_IN] = gText_PokenavMap_ZoomedInButtons, - [HELPBAR_CONDITION_MON_LIST] = gText_PokenavCondition_MonListButtons, - [HELPBAR_CONDITION_MON_STATUS] = gText_PokenavCondition_MonStatusButtons, - [HELPBAR_CONDITION_MARKINGS] = gText_PokenavCondition_MarkingButtons, - [HELPBAR_MC_TRAINER_LIST] = gText_PokenavMatchCall_TrainerListButtons, - [HELPBAR_MC_CALL_MENU] = gText_PokenavMatchCall_CallMenuButtons, - [HELPBAR_MC_CHECK_PAGE] = gText_PokenavMatchCall_CheckTrainerButtons, - [HELPBAR_RIBBONS_MON_LIST] = gText_PokenavRibbons_MonListButtons, - [HELPBAR_RIBBONS_LIST] = gText_PokenavRibbons_RibbonListButtons, - [HELPBAR_RIBBONS_CHECK] = gText_PokenavRibbons_RibbonCheckButtons, + [HELPBAR_NONE] = COMPOUND_STRING("{CLEAR 0x80}"), + [HELPBAR_MAP_ZOOMED_OUT] = COMPOUND_STRING("{A_BUTTON}ZOOM {B_BUTTON}CANCEL"), + [HELPBAR_MAP_ZOOMED_IN] = COMPOUND_STRING("{A_BUTTON}FULL {B_BUTTON}CANCEL"), + [HELPBAR_CONDITION_MON_LIST] = COMPOUND_STRING("{A_BUTTON}CONDITION {B_BUTTON}CANCEL"), + [HELPBAR_CONDITION_MON_STATUS] = COMPOUND_STRING("{A_BUTTON}MARKINGS {B_BUTTON}CANCEL"), + [HELPBAR_CONDITION_MARKINGS] = COMPOUND_STRING("{A_BUTTON}SELECT MARK {B_BUTTON}CANCEL"), + [HELPBAR_MC_TRAINER_LIST] = COMPOUND_STRING("{A_BUTTON}MENU {B_BUTTON}CANCEL"), + [HELPBAR_MC_CALL_MENU] = COMPOUND_STRING("{A_BUTTON}OK {B_BUTTON}CANCEL"), + [HELPBAR_MC_CHECK_PAGE] = COMPOUND_STRING("{B_BUTTON}CANCEL"), + [HELPBAR_RIBBONS_MON_LIST] = COMPOUND_STRING("{A_BUTTON}RIBBONS {B_BUTTON}CANCEL"), + [HELPBAR_RIBBONS_LIST] = COMPOUND_STRING("{A_BUTTON}CHECK {B_BUTTON}CANCEL"), + [HELPBAR_RIBBONS_CHECK] = COMPOUND_STRING("{B_BUTTON}CANCEL"), }; static const u8 sHelpBarTextColors[3] = diff --git a/src/pokenav_match_call_data.c b/src/pokenav_match_call_data.c index ca027380d4..a2cf3f93c4 100644 --- a/src/pokenav_match_call_data.c +++ b/src/pokenav_match_call_data.c @@ -179,8 +179,8 @@ static const struct MatchCallStructNPC sMrStoneMatchCallHeader = .type = MC_TYPE_NPC, .mapSec = MAPSEC_RUSTBORO_CITY, .flag = 0xFFFF, - .desc = gText_MrStoneMatchCallDesc, - .name = gText_MrStoneMatchCallName, + .desc = COMPOUND_STRING("DEVON PRES"), + .name = COMPOUND_STRING("MR. STONE"), .textData = sMrStoneTextScripts }; @@ -203,8 +203,8 @@ static const struct MatchCallStructTrainer sNormanMatchCallHeader = .mapSec = MAPSEC_PETALBURG_CITY, .flag = FLAG_ENABLE_NORMAN_MATCH_CALL, .rematchTableIdx = REMATCH_NORMAN, - .desc = gText_NormanMatchCallDesc, - .name = gText_NormanMatchCallName, + .desc = COMPOUND_STRING("RELIABLE ONE"), + .name = COMPOUND_STRING("DAD"), .textData = sNormanTextScripts }; @@ -213,8 +213,8 @@ static const struct MatchCallBirch sProfBirchMatchCallHeader = .type = MC_TYPE_BIRCH, .mapSec = 0, .flag = FLAG_ENABLE_PROF_BIRCH_MATCH_CALL, - .desc = gText_ProfBirchMatchCallDesc, - .name = gText_ProfBirchMatchCallName + .desc = COMPOUND_STRING("{PKMN} PROF."), + .name = COMPOUND_STRING("PROF. BIRCH") }; static const match_call_text_data_t sMomTextScripts[] = { @@ -229,8 +229,8 @@ static const struct MatchCallStructNPC sMomMatchCallHeader = .type = MC_TYPE_NPC, .mapSec = MAPSEC_LITTLEROOT_TOWN, .flag = FLAG_ENABLE_MOM_MATCH_CALL, - .desc = gText_MomMatchCallDesc, - .name = gText_MomMatchCallName, + .desc = COMPOUND_STRING("CALM & KIND"), + .name = COMPOUND_STRING("MOM"), .textData = sMomTextScripts }; @@ -250,11 +250,13 @@ static const struct MatchCallStructNPC sStevenMatchCallHeader = .type = MC_TYPE_NPC, .mapSec = MAPSEC_NONE, .flag = FLAG_REGISTERED_STEVEN_POKENAV, - .desc = gText_StevenMatchCallDesc, - .name = gText_StevenMatchCallName, + .desc = COMPOUND_STRING("HARD AS ROCK"), + .name = COMPOUND_STRING("STEVEN"), .textData = sStevenTextScripts }; +static const u8 gText_MayBrendanMatchCallDesc[] = _("RAD NEIGHBOR"); + static const match_call_text_data_t sMayTextScripts[] = { { MatchCall_Text_May1, 0xFFFF, 0xFFFF }, { MatchCall_Text_May2, FLAG_DEFEATED_DEWFORD_GYM, 0xFFFF }, @@ -337,7 +339,7 @@ static const struct MatchCallWally sWallyMatchCallHeader = .mapSec = 0, .flag = FLAG_ENABLE_WALLY_MATCH_CALL, .rematchTableIdx = REMATCH_WALLY_VR, - .desc = gText_WallyMatchCallDesc, + .desc = COMPOUND_STRING("{PKMN} LOVER"), .textData = sWallyTextScripts, .locationData = sWallyLocationData }; @@ -359,8 +361,8 @@ static const struct MatchCallStructNPC sScottMatchCallHeader = .type = 0, .mapSec = MAPSEC_NONE, .flag = FLAG_ENABLE_SCOTT_MATCH_CALL, - .desc = gText_ScottMatchCallDesc, - .name = gText_ScottMatchCallName, + .desc = COMPOUND_STRING("ELUSIVE EYES"), + .name = COMPOUND_STRING("SCOTT"), .textData = sScottTextScripts }; @@ -378,7 +380,7 @@ static const struct MatchCallStructTrainer sRoxanneMatchCallHeader = .mapSec = MAPSEC_RUSTBORO_CITY, .flag = FLAG_ENABLE_ROXANNE_MATCH_CALL, .rematchTableIdx = REMATCH_ROXANNE, - .desc = gText_RoxanneMatchCallDesc, + .desc = COMPOUND_STRING("ROCKIN' WHIZ"), .name = NULL, .textData = sRoxanneTextScripts }; @@ -397,7 +399,7 @@ static const struct MatchCallStructTrainer sBrawlyMatchCallHeader = .mapSec = MAPSEC_DEWFORD_TOWN, .flag = FLAG_ENABLE_BRAWLY_MATCH_CALL, .rematchTableIdx = REMATCH_BRAWLY, - .desc = gText_BrawlyMatchCallDesc, + .desc = COMPOUND_STRING("THE BIG HIT"), .name = NULL, .textData = sBrawlyTextScripts }; @@ -416,7 +418,7 @@ static const struct MatchCallStructTrainer sWattsonMatchCallHeader = .mapSec = MAPSEC_MAUVILLE_CITY, .flag = FLAG_ENABLE_WATTSON_MATCH_CALL, .rematchTableIdx = REMATCH_WATTSON, - .desc = gText_WattsonMatchCallDesc, + .desc = COMPOUND_STRING("SWELL SHOCK"), .name = NULL, .textData = sWattsonTextScripts }; @@ -435,7 +437,7 @@ static const struct MatchCallStructTrainer sFlanneryMatchCallHeader = .mapSec = MAPSEC_LAVARIDGE_TOWN, .flag = FLAG_ENABLE_FLANNERY_MATCH_CALL, .rematchTableIdx = REMATCH_FLANNERY, - .desc = gText_FlanneryMatchCallDesc, + .desc = COMPOUND_STRING("PASSION BURN"), .name = NULL, .textData = sFlanneryTextScripts }; @@ -454,7 +456,7 @@ static const struct MatchCallStructTrainer sWinonaMatchCallHeader = .mapSec = MAPSEC_FORTREE_CITY, .flag = FLAG_ENABLE_WINONA_MATCH_CALL, .rematchTableIdx = REMATCH_WINONA, - .desc = gText_WinonaMatchCallDesc, + .desc = COMPOUND_STRING("SKY TAMER"), .name = NULL, .textData = sWinonaTextScripts }; @@ -473,7 +475,7 @@ static const struct MatchCallStructTrainer sTateLizaMatchCallHeader = .mapSec = MAPSEC_MOSSDEEP_CITY, .flag = FLAG_ENABLE_TATE_AND_LIZA_MATCH_CALL, .rematchTableIdx = REMATCH_TATE_AND_LIZA, - .desc = gText_TateLizaMatchCallDesc, + .desc = COMPOUND_STRING("MYSTIC DUO"), .name = NULL, .textData = sTateLizaTextScripts }; @@ -492,11 +494,13 @@ static const struct MatchCallStructTrainer sJuanMatchCallHeader = .mapSec = MAPSEC_SOOTOPOLIS_CITY, .flag = FLAG_ENABLE_JUAN_MATCH_CALL, .rematchTableIdx = REMATCH_JUAN, - .desc = gText_JuanMatchCallDesc, + .desc = COMPOUND_STRING("DANDY CHARM"), .name = NULL, .textData = sJuanTextScripts }; +static const u8 gText_EliteFourMatchCallDesc[] = _("ELITE FOUR"); + static const match_call_text_data_t sSidneyTextScripts[] = { { MatchCall_Text_Sidney, 0xFFFF, 0xFFFF }, { NULL, 0xFFFF, 0xFFFF } @@ -572,7 +576,7 @@ static const struct MatchCallStructTrainer sWallaceMatchCallHeader = .mapSec = MAPSEC_EVER_GRANDE_CITY, .flag = FLAG_REMATCH_WALLACE, .rematchTableIdx = REMATCH_WALLACE, - .desc = gText_ChampionMatchCallDesc, + .desc = COMPOUND_STRING("CHAMPION"), .name = NULL, .textData = sWallaceTextScripts }; @@ -657,6 +661,19 @@ static void (*const sMatchCall_GetNameAndDescFunctions[])(match_call_t, const u8 MatchCall_GetNameAndDesc_Birch }; +static const u8 gText_MatchCallSteven_Strategy[] = _("Attack the weak points!"); +static const u8 gText_MatchCallSteven_Pokemon[] = _("Ultimate STEEL POKéMON."); + +static const u8 gText_MatchCallBrendan_Strategy[] = _("Battle with knowledge!"); +static const u8 gText_MatchCallBrendan_Pokemon[] = _("I will use various POKéMON."); +static const u8 gText_MatchCallBrendan_Intro1[] = _("I'll be a better POKéMON"); +static const u8 gText_MatchCallBrendan_Intro2[] = _("prof than my father is!"); + +static const u8 gText_MatchCallMay_Strategy[] = _("I'm not so good at battles."); +static const u8 gText_MatchCallMay_Pokemon[] = _("I'll use any POKéMON!"); +static const u8 gText_MatchCallMay_Intro1[] = _("My POKéMON and I help"); +static const u8 gText_MatchCallMay_Intro2[] = _("my father's research."); + static const struct MatchCallCheckPageOverride sCheckPageOverrides[] = { { .idx = MC_HEADER_STEVEN, @@ -665,8 +682,8 @@ static const struct MatchCallCheckPageOverride sCheckPageOverrides[] = { .flavorTexts = { [CHECK_PAGE_STRATEGY] = gText_MatchCallSteven_Strategy, [CHECK_PAGE_POKEMON] = gText_MatchCallSteven_Pokemon, - [CHECK_PAGE_INTRO_1] = gText_MatchCallSteven_Intro1_BeforeMeteorFallsBattle, - [CHECK_PAGE_INTRO_2] = gText_MatchCallSteven_Intro2_BeforeMeteorFallsBattle + [CHECK_PAGE_INTRO_1] = COMPOUND_STRING("I'd climb even waterfalls"), + [CHECK_PAGE_INTRO_2] = COMPOUND_STRING("to find a rare stone!") } }, { @@ -676,8 +693,8 @@ static const struct MatchCallCheckPageOverride sCheckPageOverrides[] = { .flavorTexts = { [CHECK_PAGE_STRATEGY] = gText_MatchCallSteven_Strategy, [CHECK_PAGE_POKEMON] = gText_MatchCallSteven_Pokemon, - [CHECK_PAGE_INTRO_1] = gText_MatchCallSteven_Intro1_AfterMeteorFallsBattle, - [CHECK_PAGE_INTRO_2] = gText_MatchCallSteven_Intro2_AfterMeteorFallsBattle + [CHECK_PAGE_INTRO_1] = COMPOUND_STRING("I'm the strongest and most"), + [CHECK_PAGE_INTRO_2] = COMPOUND_STRING("energetic after all!") } }, { diff --git a/src/pokenav_match_call_gfx.c b/src/pokenav_match_call_gfx.c index 594b4d83d4..80e2709cf0 100755 --- a/src/pokenav_match_call_gfx.c +++ b/src/pokenav_match_call_gfx.c @@ -124,6 +124,11 @@ static const u16 sListWindow_Pal[] = INCBIN_U16("graphics/pokenav/match_call/lis static const u16 sPokeball_Pal[] = INCBIN_U16("graphics/pokenav/match_call/pokeball.gbapal"); static const u32 sPokeball_Gfx[] = INCBIN_U32("graphics/pokenav/match_call/pokeball.4bpp.lz"); +static const u8 gText_NumberRegistered[] = _("No. registered"); +static const u8 gText_NumberOfBattles[] = _("No. of battles"); +static const u8 gText_TrainerCloseBy[] = _("That TRAINER is close by.\nTalk to the TRAINER in person!"); +static const u8 gText_Unknown[] = _("UNKNOWN"); + static const struct BgTemplate sMatchCallBgTemplates[3] = { { @@ -199,9 +204,9 @@ static const struct WindowTemplate sMatchCallInfoBoxWindowTemplate = static const u8 *const sMatchCallOptionTexts[MATCH_CALL_OPTION_COUNT] = { - [MATCH_CALL_OPTION_CALL] = gText_Call, - [MATCH_CALL_OPTION_CHECK] = gText_Check, - [MATCH_CALL_OPTION_CANCEL] = gText_Cancel6 + [MATCH_CALL_OPTION_CALL] = COMPOUND_STRING("CALL"), + [MATCH_CALL_OPTION_CHECK] = COMPOUND_STRING("CHECK"), + [MATCH_CALL_OPTION_CANCEL] = COMPOUND_STRING("CANCEL") }; // The series of 5 dots that appear when someone is called with Match Call diff --git a/src/pokenav_match_call_list.c b/src/pokenav_match_call_list.c index 43cd5220dd..94a13031da 100755 --- a/src/pokenav_match_call_list.c +++ b/src/pokenav_match_call_list.c @@ -36,6 +36,8 @@ static u32 CB2_HandleCallExitInput(struct Pokenav_MatchCallMenu *); static u32 LoopedTask_BuildMatchCallList(s32); static bool32 ShouldDoNearbyMessage(void); +static const u8 gText_CallCantBeMadeHere[] = _("A call can't be made from here."); + #include "data/text/match_call_messages.h" static const u8 sMatchCallOptionsNoCheckPage[] = diff --git a/src/pokenav_menu_handler_gfx.c b/src/pokenav_menu_handler_gfx.c index b0128d385d..09fb96f3dc 100644 --- a/src/pokenav_menu_handler_gfx.c +++ b/src/pokenav_menu_handler_gfx.c @@ -108,6 +108,8 @@ static const u32 sPokenavDeviceBgTilemap[] = INCBIN_U32("graphics/pokenav/device static const u16 sMatchCallBlueLightPal[] = INCBIN_U16("graphics/pokenav/blue_light.gbapal"); static const u32 sMatchCallBlueLightTiles[] = INCBIN_U32("graphics/pokenav/blue_light.4bpp.lz"); +static const u8 gText_NoRibbonWinners[] = _("There are no RIBBON winners."); + static const struct BgTemplate sPokenavMainMenuBgTemplates[] = { { .bg = 1, @@ -267,20 +269,20 @@ static const struct WindowTemplate sOptionDescWindowTemplate = static const u8 *const sPageDescriptions[] = { - [POKENAV_MENUITEM_MAP] = gText_CheckMapOfHoenn, - [POKENAV_MENUITEM_CONDITION] = gText_CheckPokemonInDetail, - [POKENAV_MENUITEM_MATCH_CALL] = gText_CallRegisteredTrainer, - [POKENAV_MENUITEM_RIBBONS] = gText_CheckObtainedRibbons, - [POKENAV_MENUITEM_SWITCH_OFF] = gText_PutAwayPokenav, - [POKENAV_MENUITEM_CONDITION_PARTY] = gText_CheckPartyPokemonInDetail, - [POKENAV_MENUITEM_CONDITION_SEARCH] = gText_CheckAllPokemonInDetail, - [POKENAV_MENUITEM_CONDITION_CANCEL] = gText_ReturnToPokenavMenu, - [POKENAV_MENUITEM_CONDITION_SEARCH_COOL] = gText_FindCoolPokemon, - [POKENAV_MENUITEM_CONDITION_SEARCH_BEAUTY] = gText_FindBeautifulPokemon, - [POKENAV_MENUITEM_CONDITION_SEARCH_CUTE] = gText_FindCutePokemon, - [POKENAV_MENUITEM_CONDITION_SEARCH_SMART] = gText_FindSmartPokemon, - [POKENAV_MENUITEM_CONDITION_SEARCH_TOUGH] = gText_FindToughPokemon, - [POKENAV_MENUITEM_CONDITION_SEARCH_CANCEL] = gText_ReturnToConditionMenu + [POKENAV_MENUITEM_MAP] = COMPOUND_STRING("Check the map of the HOENN region"), + [POKENAV_MENUITEM_CONDITION] = COMPOUND_STRING("Check POKéMON in detail."), + [POKENAV_MENUITEM_MATCH_CALL] = COMPOUND_STRING("Call a registered TRAINER."), + [POKENAV_MENUITEM_RIBBONS] = COMPOUND_STRING("Check obtained RIBBONS."), + [POKENAV_MENUITEM_SWITCH_OFF] = COMPOUND_STRING("Put away the POKéNAV."), + [POKENAV_MENUITEM_CONDITION_PARTY] = COMPOUND_STRING("Check party POKéMON in detail."), + [POKENAV_MENUITEM_CONDITION_SEARCH] = COMPOUND_STRING("Check all POKéMON in detail."), + [POKENAV_MENUITEM_CONDITION_CANCEL] = COMPOUND_STRING("Return to the POKéNAV menu."), + [POKENAV_MENUITEM_CONDITION_SEARCH_COOL] = COMPOUND_STRING("Find cool POKéMON."), + [POKENAV_MENUITEM_CONDITION_SEARCH_BEAUTY] = COMPOUND_STRING("Find beautiful POKéMON."), + [POKENAV_MENUITEM_CONDITION_SEARCH_CUTE] = COMPOUND_STRING("Find cute POKéMON."), + [POKENAV_MENUITEM_CONDITION_SEARCH_SMART] = COMPOUND_STRING("Find smart POKéMON."), + [POKENAV_MENUITEM_CONDITION_SEARCH_TOUGH] = COMPOUND_STRING("Find tough POKéMON."), + [POKENAV_MENUITEM_CONDITION_SEARCH_CANCEL] = COMPOUND_STRING("Return to the CONDITION menu.") }; static const u8 sOptionDescTextColors[] = {TEXT_COLOR_GREEN, TEXT_COLOR_BLUE, TEXT_COLOR_LIGHT_GREEN}; diff --git a/src/pokenav_ribbons_summary.c b/src/pokenav_ribbons_summary.c index bba1c3600c..9a5eafeea5 100644 --- a/src/pokenav_ribbons_summary.c +++ b/src/pokenav_ribbons_summary.c @@ -40,6 +40,8 @@ enum #define MON_SPRITE_X_OFF -32 #define MON_SPRITE_Y 104 +static const u8 gText_RibbonsF700[] = _("RIBBONS {DYNAMIC 0}"); + struct Pokenav_RibbonsSummaryList { u8 unused1[8]; diff --git a/src/strings.c b/src/strings.c index a5533731ed..54a08f32e2 100644 --- a/src/strings.c +++ b/src/strings.c @@ -20,7 +20,6 @@ const u8 gText_ExpandedPlaceholder_Brendan[] = _("BRENDAN"); const u8 gText_ExpandedPlaceholder_May[] = _("MAY"); const u8 gText_EggNickname[] = _("EGG"); const u8 gText_Pokemon[] = _("POKéMON"); -const u8 gText_ProfBirchMatchCallName[] = _("PROF. BIRCH"); const u8 gText_Player[] = _("PLAYER"); // Unused const u8 gText_Pokedex[] = _("POKéDEX"); // Unused const u8 gText_Time[] = _("TIME"); @@ -897,57 +896,11 @@ const u8 gText_SeeYaDescription[] = _("Return to the previous menu."); const u8 gText_JustOnePkmn[] = _("There is just one POKéMON with you."); const u8 gText_PartyFull[] = _("Your party is full!"); const u8 gText_Box[] = _("BOX"); -const u8 gText_CheckMapOfHoenn[] = _("Check the map of the HOENN region."); -const u8 gText_CheckPokemonInDetail[] = _("Check POKéMON in detail."); -const u8 gText_CallRegisteredTrainer[] = _("Call a registered TRAINER."); -const u8 gText_CheckObtainedRibbons[] = _("Check obtained RIBBONS."); -const u8 gText_PutAwayPokenav[] = _("Put away the POKéNAV."); -const u8 gText_NoRibbonWinners[] = _("There are no RIBBON winners."); -const u8 gText_NoTrainersRegistered[] = _("No TRAINERS are registered."); // Unused -const u8 gText_CheckPartyPokemonInDetail[] = _("Check party POKéMON in detail."); -const u8 gText_CheckAllPokemonInDetail[] = _("Check all POKéMON in detail."); -const u8 gText_ReturnToPokenavMenu[] = _("Return to the POKéNAV menu."); -const u8 gText_FindCoolPokemon[] = _("Find cool POKéMON."); -const u8 gText_FindBeautifulPokemon[] = _("Find beautiful POKéMON."); -const u8 gText_FindCutePokemon[] = _("Find cute POKéMON."); -const u8 gText_FindSmartPokemon[] = _("Find smart POKéMON."); -const u8 gText_FindToughPokemon[] = _("Find tough POKéMON."); -const u8 gText_ReturnToConditionMenu[] = _("Return to the CONDITION menu."); -const u8 gText_NumberRegistered[] = _("No. registered"); -const u8 gText_NumberOfBattles[] = _("No. of battles"); -const u8 gText_Detail[] = _("DETAIL"); // Unused -const u8 gText_Call2[] = _("CALL"); // Unused -const u8 gText_UnusedExit[] = _("EXIT"); // Unused -const u8 gText_CantCallOpponentHere[] = _("Can't call opponent here."); // Unused -const u8 gText_PokenavMatchCall_Strategy[] = _("STRATEGY"); -const u8 gText_PokenavMatchCall_TrainerPokemon[] = _("TRAINER'S POKéMON"); -const u8 gText_PokenavMatchCall_SelfIntroduction[] = _("SELF-INTRODUCTION"); -const u8 gText_Pokenav_ClearButtonList[] = _("{CLEAR 0x80}"); -const u8 gText_PokenavMap_ZoomedOutButtons[] = _("{A_BUTTON}ZOOM {B_BUTTON}CANCEL"); -const u8 gText_PokenavMap_ZoomedInButtons[] = _("{A_BUTTON}FULL {B_BUTTON}CANCEL"); -const u8 gText_PokenavCondition_MonListButtons[] = _("{A_BUTTON}CONDITION {B_BUTTON}CANCEL"); -const u8 gText_PokenavCondition_MonStatusButtons[] = _("{A_BUTTON}MARKINGS {B_BUTTON}CANCEL"); -const u8 gText_PokenavCondition_MarkingButtons[] = _("{A_BUTTON}SELECT MARK {B_BUTTON}CANCEL"); -const u8 gText_PokenavMatchCall_TrainerListButtons[] = _("{A_BUTTON}MENU {B_BUTTON}CANCEL"); -const u8 gText_PokenavMatchCall_CallMenuButtons[] = _("{A_BUTTON}OK {B_BUTTON}CANCEL"); -const u8 gText_PokenavMatchCall_CheckTrainerButtons[] = _("{B_BUTTON}CANCEL"); -const u8 gText_PokenavRibbons_MonListButtons[] = _("{A_BUTTON}RIBBONS {B_BUTTON}CANCEL"); -const u8 gText_PokenavRibbons_RibbonListButtons[] = _("{A_BUTTON}CHECK {B_BUTTON}CANCEL"); -const u8 gText_PokenavRibbons_RibbonCheckButtons[] = _("{B_BUTTON}CANCEL"); const u8 gText_NatureSlash[] = _("NATURE/"); -const u8 gText_TrainerCloseBy[] = _("That TRAINER is close by.\nTalk to the TRAINER in person!"); const u8 gText_InParty[] = _("IN PARTY"); -const u8 gText_Number2[] = _("No. "); -const u8 gText_Ribbons[] = _("RIBBONS"); // Unused const u8 gText_PokemonMaleLv[] = _("{DYNAMIC 0}{COLOR_HIGHLIGHT_SHADOW LIGHT_RED WHITE GREEN}♂{COLOR_HIGHLIGHT_SHADOW DARK_GRAY WHITE LIGHT_GRAY}/{LV}{DYNAMIC 1}"); // Unused const u8 gText_PokemonFemaleLv[] = _("{DYNAMIC 0}{COLOR_HIGHLIGHT_SHADOW LIGHT_GREEN WHITE BLUE}♀{COLOR_HIGHLIGHT_SHADOW DARK_GRAY WHITE LIGHT_GRAY}/{LV}{DYNAMIC 1}"); // Unused const u8 gText_PokemonNoGenderLv[] = _("{DYNAMIC 0}/{LV}{DYNAMIC 1}"); // Unused -const u8 gText_Unknown[] = _("UNKNOWN"); -const u8 gText_Call[] = _("CALL"); -const u8 gText_Check[] = _("CHECK"); -const u8 gText_Cancel6[] = _("CANCEL"); -const u8 gText_NumberIndex[] = _("No. {DYNAMIC 0}"); -const u8 gText_RibbonsF700[] = _("RIBBONS {DYNAMIC 0}"); const u8 gText_PokemonMaleLv2[] = _("{DYNAMIC 0}{COLOR_HIGHLIGHT_SHADOW LIGHT_RED WHITE GREEN}♂{COLOR_HIGHLIGHT_SHADOW DARK_GRAY WHITE LIGHT_GRAY}/{LV}{DYNAMIC 1}{DYNAMIC 2}"); // Unused const u8 gText_PokemonFemaleLv2[] = _("{DYNAMIC 0}{COLOR_HIGHLIGHT_SHADOW LIGHT_GREEN WHITE BLUE}♀{COLOR_HIGHLIGHT_SHADOW DARK_GRAY WHITE LIGHT_GRAY}/{LV}{DYNAMIC 1}{DYNAMIC 2}"); // Unused const u8 gText_PokemonNoGenderLv2[] = _("{DYNAMIC 0}/{LV}{DYNAMIC 1}{DYNAMIC 2}"); // Unused @@ -1240,20 +1193,6 @@ const u8 gText_ThankYou[] = _("THANK YOU"); const u8 gText_ByeBye[] = _("BYE-BYE!"); const u8 gText_PlayerScurriedToCenter[] = _("{PLAYER} scurried to a POKéMON CENTER,\nprotecting the exhausted and fainted\nPOKéMON from further harm…\p"); const u8 gText_PlayerScurriedBackHome[] = _("{PLAYER} scurried back home, protecting\nthe exhausted and fainted POKéMON from\nfurther harm…\p"); -const u8 gText_MatchCallSteven_Strategy[] = _("Attack the weak points!"); -const u8 gText_MatchCallSteven_Pokemon[] = _("Ultimate STEEL POKéMON."); -const u8 gText_MatchCallSteven_Intro1_BeforeMeteorFallsBattle[] = _("I'd climb even waterfalls"); -const u8 gText_MatchCallSteven_Intro2_BeforeMeteorFallsBattle[] = _("to find a rare stone!"); -const u8 gText_MatchCallSteven_Intro1_AfterMeteorFallsBattle[] = _("I'm the strongest and most"); -const u8 gText_MatchCallSteven_Intro2_AfterMeteorFallsBattle[] = _("energetic after all!"); -const u8 gText_MatchCallBrendan_Strategy[] = _("Battle with knowledge!"); -const u8 gText_MatchCallBrendan_Pokemon[] = _("I will use various POKéMON."); -const u8 gText_MatchCallBrendan_Intro1[] = _("I'll be a better POKéMON"); -const u8 gText_MatchCallBrendan_Intro2[] = _("prof than my father is!"); -const u8 gText_MatchCallMay_Strategy[] = _("I'm not so good at battles."); -const u8 gText_MatchCallMay_Pokemon[] = _("I'll use any POKéMON!"); -const u8 gText_MatchCallMay_Intro1[] = _("My POKéMON and I help"); -const u8 gText_MatchCallMay_Intro2[] = _("my father's research."); const u8 gText_HatchedFromEgg[] = _("{STR_VAR_1} hatched from the EGG!"); const u8 gText_NicknameHatchPrompt[] = _("Would you like to nickname the newly\nhatched {STR_VAR_1}?"); ALIGNED(4) const u8 gText_ReadyPickBerry[] = _("Are you ready to BERRY-CRUSH?\nPlease pick a BERRY for use.\p"); @@ -1549,7 +1488,6 @@ const u8 gText_BoxName[] = _("BOX NAME?"); const u8 gText_PkmnsNickname[] = _("{STR_VAR_1}'s nickname?"); const u8 gText_TellHimTheWords[] = _("Tell him the words."); const u8 gText_MoveOkBack[] = _("{DPAD_NONE}MOVE {A_BUTTON}OK {B_BUTTON}BACK"); -const u8 gText_CallCantBeMadeHere[] = _("A call can't be made from here."); const u8 gText_RentalPkmn2[] = _("RENTAL POKéMON"); const u8 gText_SelectFirstPkmn[] = _("Select the first POKéMON."); const u8 gText_SelectSecondPkmn[] = _("Select the second POKéMON."); @@ -1720,28 +1658,6 @@ const u8 gText_ClearingData[] = _("Clearing data…\nPlease wait."); const u8 gText_IsThisTheCorrectTime[] = _("Is this the correct time?"); const u8 gText_Confirm3[] = _("CONFIRM"); const u8 gText_Cancel4[] = _("CANCEL"); -const u8 gText_MrStoneMatchCallDesc[] = _("DEVON PRES"); -const u8 gText_MrStoneMatchCallName[] = _("MR. STONE"); -const u8 gText_StevenMatchCallDesc[] = _("HARD AS ROCK"); -const u8 gText_StevenMatchCallName[] = _("STEVEN"); -const u8 gText_MayBrendanMatchCallDesc[] = _("RAD NEIGHBOR"); -const u8 gText_NormanMatchCallDesc[] = _("RELIABLE ONE"); -const u8 gText_MomMatchCallDesc[] = _("CALM & KIND"); -const u8 gText_WallyMatchCallDesc[] = _("{PKMN} LOVER"); -const u8 gText_NormanMatchCallName[] = _("DAD"); -const u8 gText_MomMatchCallName[] = _("MOM"); -const u8 gText_ScottMatchCallDesc[] = _("ELUSIVE EYES"); -const u8 gText_ScottMatchCallName[] = _("SCOTT"); -const u8 gText_RoxanneMatchCallDesc[] = _("ROCKIN' WHIZ"); -const u8 gText_BrawlyMatchCallDesc[] = _("THE BIG HIT"); -const u8 gText_WattsonMatchCallDesc[] = _("SWELL SHOCK"); -const u8 gText_FlanneryMatchCallDesc[] = _("PASSION BURN"); -const u8 gText_WinonaMatchCallDesc[] = _("SKY TAMER"); -const u8 gText_TateLizaMatchCallDesc[] = _("MYSTIC DUO"); -const u8 gText_JuanMatchCallDesc[] = _("DANDY CHARM"); -const u8 gText_EliteFourMatchCallDesc[] = _("ELITE FOUR"); -const u8 gText_ChampionMatchCallDesc[] = _("CHAMPION"); -const u8 gText_ProfBirchMatchCallDesc[] = _("{PKMN} PROF."); const u8 gText_CommStandbyAwaitingOtherPlayer[] = _("Communication standby…\nAwaiting another player to choose."); const u8 gText_BattleWasRefused[] = _("The battle was refused.{PAUSE 60}"); const u8 gText_RefusedBattle[] = _("Refused the battle.{PAUSE 60}"); From b641c6f4fa33127052b0a59f1088fc3192f5e011 Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Fri, 16 Aug 2024 23:02:49 +0200 Subject: [PATCH 36/64] Fixed incorrect weather damage rounding when maxHP <16 (#5183) Co-authored-by: Hedara --- src/battle_ai_switch_items.c | 2 +- src/battle_ai_util.c | 4 ++-- src/battle_util.c | 6 +++++- test/battle/ability/ice_body.c | 30 +++++++++++++++++++++++++++--- test/battle/ability/rain_dish.c | 18 ++++++++++++++++-- test/battle/weather/hail.c | 12 ++++++++++++ test/battle/weather/sandstorm.c | 12 ++++++++++++ 7 files changed, 75 insertions(+), 9 deletions(-) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 29642df9ff..e0359ff00f 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -1564,9 +1564,9 @@ static u32 GetSwitchinStatusDamage(u32 battler) if ((status & STATUS1_TOXIC_COUNTER) != STATUS1_TOXIC_TURN(15)) // not 16 turns AI_DATA->switchinCandidate.battleMon.status1 += STATUS1_TOXIC_TURN(1); statusDamage = maxHP / 16; - statusDamage *= AI_DATA->switchinCandidate.battleMon.status1 & STATUS1_TOXIC_COUNTER >> 8; if (statusDamage == 0) statusDamage = 1; + statusDamage *= AI_DATA->switchinCandidate.battleMon.status1 & STATUS1_TOXIC_COUNTER >> 8; } } diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index a094dfd694..30bce86c3d 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -2514,7 +2514,7 @@ u32 GetBattlerSecondaryDamage(u32 battlerId) bool32 BattlerWillFaintFromWeather(u32 battler, u32 ability) { if ((BattlerAffectedBySandstorm(battler, ability) || BattlerAffectedByHail(battler, ability)) - && gBattleMons[battler].hp <= gBattleMons[battler].maxHP / 16) + && gBattleMons[battler].hp <= max(1, gBattleMons[battler].maxHP / 16)) return TRUE; return FALSE; @@ -2523,7 +2523,7 @@ bool32 BattlerWillFaintFromWeather(u32 battler, u32 ability) bool32 BattlerWillFaintFromSecondaryDamage(u32 battler, u32 ability) { if (GetBattlerSecondaryDamage(battler) != 0 - && gBattleMons[battler].hp <= gBattleMons[battler].maxHP / 16) + && gBattleMons[battler].hp <= max(1, gBattleMons[battler].maxHP / 16)) return TRUE; return FALSE; } diff --git a/src/battle_util.c b/src/battle_util.c index 0a680cc272..aefce1f0a9 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2379,6 +2379,8 @@ u8 DoBattlerEndTurnEffects(void) { gBattleScripting.battler = battler; gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; BattleScriptExecute(BattleScript_DamagingWeather); effect++; } @@ -2389,7 +2391,7 @@ u8 DoBattlerEndTurnEffects(void) && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK)) { gBattleScripting.battler = battler; - gBattleMoveDamage = -1 * (GetNonDynamaxMaxHP(battler) / 16); + gBattleMoveDamage = -1 * max(1, GetNonDynamaxMaxHP(battler) / 16); BattleScriptExecute(BattleScript_IceBodyHeal); effect++; } @@ -2403,6 +2405,8 @@ u8 DoBattlerEndTurnEffects(void) { gBattleScripting.battler = battler; gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 16; + if (gBattleMoveDamage == 0) + gBattleMoveDamage = 1; BattleScriptExecute(BattleScript_DamagingWeather); effect++; } diff --git a/test/battle/ability/ice_body.c b/test/battle/ability/ice_body.c index 304059a00e..3f278a50cd 100644 --- a/test/battle/ability/ice_body.c +++ b/test/battle/ability/ice_body.c @@ -1,13 +1,21 @@ #include "global.h" #include "test/battle.h" +ASSUMPTIONS { + ASSUME(gMovesInfo[MOVE_HAIL].effect == EFFECT_HAIL); + ASSUME(gMovesInfo[MOVE_SNOWSCAPE].effect == EFFECT_SNOWSCAPE); +} + SINGLE_BATTLE_TEST("Ice Body prevents damage from hail") { + u32 move; + PARAMETRIZE { move = MOVE_HAIL; } + PARAMETRIZE { move = MOVE_SNOWSCAPE; } GIVEN { PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_GLALIE) { Ability(ABILITY_ICE_BODY); } } WHEN { - TURN { MOVE(player, MOVE_HAIL); MOVE(opponent, MOVE_SKILL_SWAP); } + TURN { MOVE(player, move); MOVE(opponent, MOVE_SKILL_SWAP); } } SCENE { NONE_OF { HP_BAR(player); } } @@ -15,11 +23,14 @@ SINGLE_BATTLE_TEST("Ice Body prevents damage from hail") SINGLE_BATTLE_TEST("Ice Body recovers 1/16th of Max HP in hail.") { + u32 move; + PARAMETRIZE { move = MOVE_HAIL; } + PARAMETRIZE { move = MOVE_SNOWSCAPE; } GIVEN { PLAYER(SPECIES_GLALIE) { Ability(ABILITY_ICE_BODY); HP(1); MaxHP(100); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(opponent, MOVE_HAIL); } + TURN { MOVE(opponent, move); } } SCENE { ABILITY_POPUP(player, ABILITY_ICE_BODY); HP_BAR(player, damage: -(100 / 16)); @@ -27,4 +38,17 @@ SINGLE_BATTLE_TEST("Ice Body recovers 1/16th of Max HP in hail.") } } -TO_DO_BATTLE_TEST("Sand Rush doesn't recover HP if Cloud Nine/Air Lock is on the field"); +SINGLE_BATTLE_TEST("Ice Body doesn't recover HP if Cloud Nine/Air Lock is on the field") +{ + u32 move; + PARAMETRIZE { move = MOVE_HAIL; } + PARAMETRIZE { move = MOVE_SNOWSCAPE; } + GIVEN { + PLAYER(SPECIES_GLALIE) { Ability(ABILITY_ICE_BODY); HP(1); MaxHP(100); } + OPPONENT(SPECIES_GOLDUCK) { Ability(ABILITY_CLOUD_NINE); } + } WHEN { + TURN { MOVE(opponent, move); } + } SCENE { + NOT ABILITY_POPUP(player, ABILITY_ICE_BODY); + } +} diff --git a/test/battle/ability/rain_dish.c b/test/battle/ability/rain_dish.c index ed71a67f92..93f642c633 100644 --- a/test/battle/ability/rain_dish.c +++ b/test/battle/ability/rain_dish.c @@ -1,6 +1,10 @@ #include "global.h" #include "test/battle.h" +ASSUMPTIONS { + ASSUME(gMovesInfo[MOVE_RAIN_DANCE].effect == EFFECT_RAIN_DANCE); +} + SINGLE_BATTLE_TEST("Rain Dish recovers 1/16th of Max HP in Rain") { GIVEN { @@ -11,8 +15,18 @@ SINGLE_BATTLE_TEST("Rain Dish recovers 1/16th of Max HP in Rain") } SCENE { ABILITY_POPUP(player, ABILITY_RAIN_DISH); MESSAGE("Ludicolo's Rain Dish restored its HP a little!"); - HP_BAR(player, damage: -(100 / 16)); + HP_BAR(player, damage: -(100 / 16)); } } -TO_DO_BATTLE_TEST("Rain Dish doesn't recover HP if Cloud Nine/Air Lock is on the field"); +SINGLE_BATTLE_TEST("Rain Dish doesn't recover HP if Cloud Nine/Air Lock is on the field") +{ + GIVEN { + PLAYER(SPECIES_LUDICOLO) { Ability(ABILITY_RAIN_DISH); HP(1); MaxHP(100); } + OPPONENT(SPECIES_GOLDUCK) { Ability(ABILITY_CLOUD_NINE); } + } WHEN { + TURN { MOVE(opponent, MOVE_RAIN_DANCE); } + } SCENE { + NOT ABILITY_POPUP(player, ABILITY_RAIN_DISH); + } +} diff --git a/test/battle/weather/hail.c b/test/battle/weather/hail.c index 5caeb84891..4210a22d9e 100644 --- a/test/battle/weather/hail.c +++ b/test/battle/weather/hail.c @@ -70,3 +70,15 @@ DOUBLE_BATTLE_TEST("Hail deals damage based on turn order") HP_BAR(playerRight); } } + +SINGLE_BATTLE_TEST("Hail damage rounds properly when maxHP < 16") +{ + GIVEN { + PLAYER(SPECIES_MAGIKARP) { Level(1); MaxHP(11); HP(11); } + OPPONENT(SPECIES_GLALIE); + } WHEN { + TURN { MOVE(opponent, MOVE_HAIL); } + } SCENE { + HP_BAR(player, damage: 1); + } +} diff --git a/test/battle/weather/sandstorm.c b/test/battle/weather/sandstorm.c index 63b24afd7e..1673c26f99 100644 --- a/test/battle/weather/sandstorm.c +++ b/test/battle/weather/sandstorm.c @@ -82,3 +82,15 @@ DOUBLE_BATTLE_TEST("Sandstorm deals damage based on turn order") HP_BAR(playerRight); } } + +SINGLE_BATTLE_TEST("Sandstorm damage rounds properly when maxHP < 16") +{ + GIVEN { + PLAYER(SPECIES_MAGIKARP) { Level(1); MaxHP(11); HP(11); } + OPPONENT(SPECIES_SANDSLASH); + } WHEN { + TURN { MOVE(opponent, MOVE_SANDSTORM); } + } SCENE { + HP_BAR(player, damage: 1); + } +} From 15348eae84b9480c832f43c48a36589cf34b58e0 Mon Sep 17 00:00:00 2001 From: Frank DeBlasio <35279583+fdeblasio@users.noreply.github.com> Date: Fri, 16 Aug 2024 17:31:19 -0400 Subject: [PATCH 37/64] Consolidated the values of Rotom's moves and added Gen9 base form effect (#5186) * Consolidated Rotom move values * Updated changing Rotom into its base form to its Gen9 effect * Fixed order of if statement --- include/config/item.h | 1 + src/data/party_menu.h | 17 ++++++++++++----- src/party_menu.c | 16 ++++++++-------- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/include/config/item.h b/include/config/item.h index 644a73ade6..2f60739335 100644 --- a/include/config/item.h +++ b/include/config/item.h @@ -19,6 +19,7 @@ #define I_BERRY_PRICE GEN_7 // Since Berries have become unplantable (Gen8+), their price has gone up. #define I_POWER_ITEM_BOOST GEN_LATEST // In Gen7+, Power Items grant 8 EVs instead of 4 EVs. #define I_PREMIER_BALL_BONUS GEN_LATEST // In LGPE onwards (Gen8+ here), you are given a Premier Ball for every 10 Poké Balls of any type and in the same purchase. Previously, it only applied to regular Poké Balls and only 1 could be obtained per purchase. +#define I_ROTOM_CATALOG_THUNDER_SHOCK GEN_LATEST // In Gen9+, reverting Rotom to its base form will teach it Thunder Shock even if it knows another move. // TM config #define I_REUSABLE_TMS FALSE // In Gen5-8, TMs are reusable. Setting this to TRUE will make all vanilla TMs reusable, though they can also be cherry-picked by setting their importance to 1. diff --git a/src/data/party_menu.h b/src/data/party_menu.h index 99488d4ebe..841cedca88 100644 --- a/src/data/party_menu.h +++ b/src/data/party_menu.h @@ -1140,11 +1140,18 @@ static const u8 *const sUnused_StatStrings[] = gText_Speed2 }; +#define ROTOM_BASE_MOVE MOVE_THUNDER_SHOCK +#define ROTOM_HEAT_MOVE MOVE_OVERHEAT +#define ROTOM_WASH_MOVE MOVE_HYDRO_PUMP +#define ROTOM_FROST_MOVE MOVE_BLIZZARD +#define ROTOM_FAN_MOVE MOVE_AIR_SLASH +#define ROTOM_MOW_MOVE MOVE_LEAF_STORM + static const u16 sRotomFormChangeMoves[5] = { - MOVE_HYDRO_PUMP, - MOVE_BLIZZARD, - MOVE_OVERHEAT, - MOVE_AIR_SLASH, - MOVE_LEAF_STORM, + ROTOM_HEAT_MOVE, + ROTOM_WASH_MOVE, + ROTOM_FROST_MOVE, + ROTOM_FAN_MOVE, + ROTOM_MOW_MOVE, }; diff --git a/src/party_menu.c b/src/party_menu.c index 15433854a5..5def34b3eb 100644 --- a/src/party_menu.c +++ b/src/party_menu.c @@ -6413,13 +6413,13 @@ static void Task_TryItemUseFormChange(u8 taskId) case 6: if (!IsPartyMenuTextPrinterActive()) { - if (gSpecialVar_ItemId == ITEM_ROTOM_CATALOG) //only for rotom currently + if (gSpecialVar_ItemId == ITEM_ROTOM_CATALOG) //only for Rotom currently { u32 i; for (i = 0; i < ARRAY_COUNT(sRotomFormChangeMoves); i++) DeleteMove(mon, sRotomFormChangeMoves[i]); - if (gSpecialVar_0x8000 == MOVE_THUNDER_SHOCK) + if (I_ROTOM_CATALOG_THUNDER_SHOCK < GEN_9 && gSpecialVar_0x8000 == ROTOM_BASE_MOVE) { if (!DoesMonHaveAnyMoves(mon)) FormChangeTeachMove(taskId, gSpecialVar_0x8000, gPartyMenu.slotId); @@ -6517,42 +6517,42 @@ bool32 TryMultichoiceFormChange(u8 taskId) static void CursorCb_CatalogBulb(u8 taskId) { gSpecialVar_Result = 0; - gSpecialVar_0x8000 = MOVE_THUNDER_SHOCK; + gSpecialVar_0x8000 = ROTOM_BASE_MOVE; TryMultichoiceFormChange(taskId); } static void CursorCb_CatalogOven(u8 taskId) { gSpecialVar_Result = 1; - gSpecialVar_0x8000 = MOVE_OVERHEAT; + gSpecialVar_0x8000 = ROTOM_HEAT_MOVE; TryMultichoiceFormChange(taskId); } static void CursorCb_CatalogWashing(u8 taskId) { gSpecialVar_Result = 2; - gSpecialVar_0x8000 = MOVE_HYDRO_PUMP; + gSpecialVar_0x8000 = ROTOM_WASH_MOVE; TryMultichoiceFormChange(taskId); } static void CursorCb_CatalogFridge(u8 taskId) { gSpecialVar_Result = 3; - gSpecialVar_0x8000 = MOVE_BLIZZARD; + gSpecialVar_0x8000 = ROTOM_FROST_MOVE; TryMultichoiceFormChange(taskId); } static void CursorCb_CatalogFan(u8 taskId) { gSpecialVar_Result = 4; - gSpecialVar_0x8000 = MOVE_AIR_SLASH; + gSpecialVar_0x8000 = ROTOM_FAN_MOVE; TryMultichoiceFormChange(taskId); } static void CursorCb_CatalogMower(u8 taskId) { gSpecialVar_Result = 5; - gSpecialVar_0x8000 = MOVE_LEAF_STORM; + gSpecialVar_0x8000 = ROTOM_MOW_MOVE; TryMultichoiceFormChange(taskId); } From e4c81ba6e0fb353589262869b09f7fac4bf87c5c Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Sat, 17 Aug 2024 17:28:09 +0200 Subject: [PATCH 38/64] Removed all instances of gBitTable[x] (#5123) * Replaced all the gBitTable[X] usages with 1 << X, and cleaned up script output * Fixed failed merge in online viewer --------- Co-authored-by: Hedara --- include/battle.h | 6 +- include/constants/battle.h | 6 +- include/util.h | 1 - src/battle_ai_main.c | 8 +- src/battle_ai_switch_items.c | 42 ++-- src/battle_ai_util.c | 18 +- src/battle_arena.c | 4 +- src/battle_controller_link_opponent.c | 4 +- src/battle_controller_link_partner.c | 4 +- src/battle_controller_opponent.c | 6 +- src/battle_controller_player.c | 20 +- src/battle_controller_player_partner.c | 6 +- src/battle_controller_recorded_opponent.c | 4 +- src/battle_controller_recorded_player.c | 4 +- src/battle_controller_safari.c | 4 +- src/battle_controller_wally.c | 4 +- src/battle_controllers.c | 6 +- src/battle_dome.c | 18 +- src/battle_gfx_sfx_util.c | 14 +- src/battle_gimmick.c | 4 +- src/battle_interface.c | 10 +- src/battle_main.c | 64 +++--- src/battle_pyramid.c | 10 +- src/battle_script_commands.c | 250 +++++++++++----------- src/battle_terastal.c | 4 +- src/battle_util.c | 154 ++++++------- src/battle_z_move.c | 4 +- src/pokemon.c | 14 +- src/recorded_battle.c | 2 +- src/script_movement.c | 6 +- src/trainer_hill.c | 6 +- src/util.c | 36 ---- test/test_runner_battle.c | 18 +- 33 files changed, 362 insertions(+), 399 deletions(-) diff --git a/include/battle.h b/include/battle.h index 28a6dd0f36..57242e4bd7 100644 --- a/include/battle.h +++ b/include/battle.h @@ -42,7 +42,7 @@ // Used to exclude moves learned temporarily by Transform or Mimic #define MOVE_IS_PERMANENT(battler, moveSlot) \ (!(gBattleMons[battler].status2 & STATUS2_TRANSFORMED) \ - && !(gDisableStructs[battler].mimickedMoves & gBitTable[moveSlot])) + && !(gDisableStructs[battler].mimickedMoves & (1u << moveSlot))) // Battle Actions // These determine what each battler will do in a turn @@ -819,8 +819,8 @@ STATIC_ASSERT(sizeof(((struct BattleStruct *)0)->palaceFlags) * 8 >= MAX_BATTLER #define IS_MOVE_RECOIL(move)(gMovesInfo[move].recoil > 0 || gMovesInfo[move].effect == EFFECT_RECOIL_IF_MISS) #define BATTLER_MAX_HP(battlerId)(gBattleMons[battlerId].hp == gBattleMons[battlerId].maxHP) -#define TARGET_TURN_DAMAGED ((gSpecialStatuses[gBattlerTarget].physicalDmg != 0 || gSpecialStatuses[gBattlerTarget].specialDmg != 0) || (gBattleStruct->enduredDamage & gBitTable[gBattlerTarget])) -#define BATTLER_TURN_DAMAGED(battlerId) ((gSpecialStatuses[battlerId].physicalDmg != 0 || gSpecialStatuses[battlerId].specialDmg != 0) || (gBattleStruct->enduredDamage & gBitTable[battler])) +#define TARGET_TURN_DAMAGED ((gSpecialStatuses[gBattlerTarget].physicalDmg != 0 || gSpecialStatuses[gBattlerTarget].specialDmg != 0) || (gBattleStruct->enduredDamage & (1u << gBattlerTarget))) +#define BATTLER_TURN_DAMAGED(battlerId) ((gSpecialStatuses[battlerId].physicalDmg != 0 || gSpecialStatuses[battlerId].specialDmg != 0) || (gBattleStruct->enduredDamage & (1u << battler))) #define IS_BATTLER_OF_TYPE(battlerId, type)((GetBattlerType(battlerId, 0, FALSE) == type || GetBattlerType(battlerId, 1, FALSE) == type || (GetBattlerType(battlerId, 2, FALSE) != TYPE_MYSTERY && GetBattlerType(battlerId, 2, FALSE) == type))) #define IS_BATTLER_OF_BASE_TYPE(battlerId, type)((GetBattlerType(battlerId, 0, TRUE) == type || GetBattlerType(battlerId, 1, TRUE) == type || (GetBattlerType(battlerId, 2, TRUE) != TYPE_MYSTERY && GetBattlerType(battlerId, 2, TRUE) == type))) diff --git a/include/constants/battle.h b/include/constants/battle.h index 39d52d3a45..f9800ef4b3 100644 --- a/include/constants/battle.h +++ b/include/constants/battle.h @@ -137,7 +137,7 @@ #define STATUS2_WRAPPED (1 << 13) #define STATUS2_POWDER (1 << 14) #define STATUS2_INFATUATION (1 << 16 | 1 << 17 | 1 << 18 | 1 << 19) // 4 bits, one for every battler -#define STATUS2_INFATUATED_WITH(battler) (gBitTable[battler] << 16) +#define STATUS2_INFATUATED_WITH(battler) (1u << (battler + 16)) #define STATUS2_DEFENSE_CURL (1 << 20) #define STATUS2_TRANSFORMED (1 << 21) #define STATUS2_RECHARGE (1 << 22) @@ -217,8 +217,8 @@ #define HITMARKER_OBEYS (1 << 25) #define HITMARKER_NEVER_SET (1 << 26) // Cleared as part of a large group. Never set or checked #define HITMARKER_CHARGING (1 << 27) -#define HITMARKER_FAINTED(battler) (gBitTable[battler] << 28) -#define HITMARKER_FAINTED2(battler) ((1 << 28) << battler) +#define HITMARKER_FAINTED(battler) (1u << (battler + 28)) +#define HITMARKER_FAINTED2(battler) HITMARKER_FAINTED(battler) #define HITMARKER_STRING_PRINTED (1 << 29) // Per-side statuses that affect an entire party diff --git a/include/util.h b/include/util.h index 3c90f136a6..fcc4e37bb1 100644 --- a/include/util.h +++ b/include/util.h @@ -4,7 +4,6 @@ #include "sprite.h" extern const u8 gMiscBlank_Gfx[]; // unused in Emerald -extern const u32 gBitTable[]; u8 CreateInvisibleSpriteWithCallback(void (*)(struct Sprite *)); void StoreWordInTwoHalfwords(u16 *, u32); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index b0229cd926..df055d62ba 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -262,7 +262,7 @@ void BattleAI_SetupAIData(u8 defaultScoreMoves, u32 battler) // Ignore moves that aren't possible to use. for (i = 0; i < MAX_MON_MOVES; i++) { - if (gBitTable[i] & moveLimitations) + if ((1u << i) & moveLimitations) SET_SCORE(battler, i, 0); } @@ -446,7 +446,7 @@ static void SetBattlerAiMovesData(struct AiLogicData *aiData, u32 battlerAtk, u3 if (move != 0 && move != 0xFFFF //&& gMovesInfo[move].power != 0 /* we want to get effectiveness and accuracy of status moves */ - && !(aiData->moveLimitations[battlerAtk] & gBitTable[i])) + && !(aiData->moveLimitations[battlerAtk] & (1u << i))) { if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_RISKY) dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, TRUE, weather, DMG_ROLL_HIGHEST); @@ -506,12 +506,12 @@ static bool32 AI_SwitchMonIfSuitable(u32 battler, bool32 doubleBattle) if (doubleBattle) { u32 partner = BATTLE_PARTNER(battler); - if (AI_DATA->shouldSwitchMon & gBitTable[partner] && AI_DATA->monToSwitchId[partner] == monToSwitchId) + if (AI_DATA->shouldSwitchMon & (1u << partner) && AI_DATA->monToSwitchId[partner] == monToSwitchId) { return FALSE; } } - AI_DATA->shouldSwitchMon |= gBitTable[battler]; + AI_DATA->shouldSwitchMon |= 1 << battler; AI_DATA->monToSwitchId[battler] = monToSwitchId; return TRUE; } diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index e1e25b5279..aca8687797 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -40,7 +40,7 @@ static void InitializeSwitchinCandidate(struct Pokemon *mon) static bool32 IsAceMon(u32 battler, u32 monPartyId) { if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_ACE_POKEMON - && !(gBattleStruct->forcedSwitch & gBitTable[battler]) + && !(gBattleStruct->forcedSwitch & (1u << battler)) && monPartyId == CalculateEnemyPartyCount()-1) return TRUE; return FALSE; @@ -218,9 +218,9 @@ static bool32 HasBadOdds(u32 battler, bool32 emitResult) static bool32 ShouldSwitchIfAllBadMoves(u32 battler, bool32 emitResult) { - if (AI_DATA->shouldSwitchMon & gBitTable[battler]) + if (AI_DATA->shouldSwitchMon & (1u << battler)) { - AI_DATA->shouldSwitchMon &= ~(gBitTable[battler]); + AI_DATA->shouldSwitchMon &= ~(1u << battler); gBattleStruct->AI_monToSwitchIntoId[battler] = AI_DATA->monToSwitchId[battler]; if (emitResult) BtlController_EmitTwoReturnValues(battler, BUFFER_B, B_ACTION_SWITCH, 0); @@ -321,7 +321,7 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler, bool32 emitResult) if (IsDoubleBattle()) { battlerIn1 = battler; - if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))]) + if (gAbsentBattlerFlags & (1u << GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))))) battlerIn2 = battler; else battlerIn2 = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))); @@ -690,7 +690,7 @@ static bool32 HasSuperEffectiveMoveAgainstOpponents(u32 battler, bool32 noRng) u32 opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(battler)); u32 opposingBattler = GetBattlerAtPosition(opposingPosition); - if (!(gAbsentBattlerFlags & gBitTable[opposingBattler])) + if (!(gAbsentBattlerFlags & (1u << opposingBattler))) { for (i = 0; i < MAX_MON_MOVES; i++) { @@ -712,7 +712,7 @@ static bool32 HasSuperEffectiveMoveAgainstOpponents(u32 battler, bool32 noRng) opposingBattler = GetBattlerAtPosition(BATTLE_PARTNER(opposingPosition)); - if (!(gAbsentBattlerFlags & gBitTable[opposingBattler])) + if (!(gAbsentBattlerFlags & (1u << opposingBattler))) { for (i = 0; i < MAX_MON_MOVES; i++) { @@ -768,7 +768,7 @@ static bool32 FindMonWithFlagsAndSuperEffective(u32 battler, u16 flags, u32 modu if (IsDoubleBattle()) { battlerIn1 = battler; - if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))]) + if (gAbsentBattlerFlags & (1u << GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))))) battlerIn2 = battler; else battlerIn2 = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))); @@ -849,7 +849,7 @@ static bool32 CanMonSurviveHazardSwitchin(u32 battler) if (IsDoubleBattle()) { battlerIn1 = battler; - if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))]) + if (gAbsentBattlerFlags & (1u << GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))))) battlerIn2 = battler; else battlerIn2 = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))); @@ -1028,7 +1028,7 @@ bool32 ShouldSwitch(u32 battler, bool32 emitResult) if (IsDoubleBattle()) { battlerIn1 = battler; - if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))]) + if (gAbsentBattlerFlags & (1u << GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))))) battlerIn2 = battler; else battlerIn2 = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))); @@ -1197,14 +1197,14 @@ static u32 GetBestMonBatonPass(struct Pokemon *party, int firstId, int lastId, u for (i = firstId; i < lastId; i++) { - if (invalidMons & gBitTable[i]) + if (invalidMons & (1u << i)) continue; for (j = 0; j < MAX_MON_MOVES; j++) { if (GetMonData(&party[i], MON_DATA_MOVE1 + j, NULL) == MOVE_BATON_PASS) { - bits |= gBitTable[i]; + bits |= 1u << i; break; } } @@ -1215,7 +1215,7 @@ static u32 GetBestMonBatonPass(struct Pokemon *party, int firstId, int lastId, u do { i = (Random() % (lastId - firstId)) + firstId; - } while (!(bits & gBitTable[i])); + } while (!(bits & (1 << i))); return i; } @@ -1233,7 +1233,7 @@ static u32 GetBestMonTypeMatchup(struct Pokemon *party, int firstId, int lastId, // Find the mon whose type is the most suitable defensively. for (i = firstId; i < lastId; i++) { - if (!(gBitTable[i] & invalidMons) && !(gBitTable[i] & bits)) + if (!((1u << i) & invalidMons) && !((1u << i) & bits)) { u16 species = GetMonData(&party[i], MON_DATA_SPECIES); uq4_12_t typeEffectiveness = UQ_4_12(1.0); @@ -1273,7 +1273,7 @@ static u32 GetBestMonTypeMatchup(struct Pokemon *party, int firstId, int lastId, if (i != MAX_MON_MOVES) return bestMonId; // Has both the typing and at least one super effective move. - bits |= gBitTable[bestMonId]; // Sorry buddy, we want something better. + bits |= (1u << bestMonId); // Sorry buddy, we want something better. } else { @@ -1295,7 +1295,7 @@ static u32 GetBestMonDmg(struct Pokemon *party, int firstId, int lastId, u8 inva // If we couldn't find the best mon in terms of typing, find the one that deals most damage. for (i = firstId; i < lastId; i++) { - if (gBitTable[i] & invalidMons) + if ((1 << (i)) & invalidMons) continue; InitializeSwitchinCandidate(&party[i]); for (j = 0; j < MAX_MON_MOVES; j++) @@ -1735,7 +1735,7 @@ static int GetRandomSwitchinWithBatonPass(int aliveCount, int bits, int firstId, do { return (Random() % (lastId - firstId)) + firstId; - } while (!(bits & gBitTable[currentMonId])); + } while (!(bits & (1 << (currentMonId)))); } // Catch any other cases (such as only one mon alive and it has Baton Pass) @@ -1875,7 +1875,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, // Check for Baton Pass; hitsToKO requirements mean mon can boost and BP without dying whether it's slower or not if (aiMove == MOVE_BATON_PASS && ((hitsToKOAI > hitsToKOAIThreshold + 1 && AI_DATA->switchinCandidate.battleMon.speed < playerMonSpeed) || (hitsToKOAI > hitsToKOAIThreshold && AI_DATA->switchinCandidate.battleMon.speed > playerMonSpeed))) - bits |= gBitTable[i]; + bits |= 1u << i; // Check for mon with resistance and super effective move for GetBestMonTypeMatchup if (aiMove != MOVE_NONE && gMovesInfo[aiMove].power != 0) @@ -2045,13 +2045,13 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd) if (IsDoubleBattle()) { battlerIn1 = battler; - if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler)))]) + if (gAbsentBattlerFlags & (1u << GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))))) battlerIn2 = battler; else battlerIn2 = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))); opposingBattler = BATTLE_OPPOSITE(battlerIn1); - if (gAbsentBattlerFlags & gBitTable[opposingBattler]) + if (gAbsentBattlerFlags & (1u << opposingBattler)) opposingBattler ^= BIT_FLANK; } else @@ -2097,12 +2097,12 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd) || i == gBattleStruct->monToSwitchIntoId[battlerIn2] || (GetMonAbility(&party[i]) == ABILITY_TRUANT && IsTruantMonVulnerable(battler, opposingBattler))) // While not really invalid per se, not really wise to switch into this mon.) { - invalidMons |= gBitTable[i]; + invalidMons |= 1u << i; } else if (IsAceMon(battler, i))// Save Ace Pokemon for last. { aceMonId = i; - invalidMons |= gBitTable[i]; + invalidMons |= 1u << i; } else { diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 03adcb1982..1cde7614ed 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -351,12 +351,12 @@ bool32 MovesWithCategoryUnusable(u32 attacker, u32 target, u32 category) if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && GetBattleMoveCategory(moves[i]) == category - && !(unusable & gBitTable[i])) + && !(unusable & (1u << i))) { SetTypeBeforeUsingMove(moves[i], attacker); moveType = GetMoveType(moves[i]); if (CalcTypeEffectivenessMultiplier(moves[i], moveType, attacker, target, AI_DATA->abilities[target], FALSE) != 0) - usable |= gBitTable[i]; + usable |= 1u << i; } } @@ -1105,7 +1105,7 @@ bool32 CanTargetFaintAi(u32 battlerDef, u32 battlerAtk) for (i = 0; i < MAX_MON_MOVES; i++) { - if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !(unusable & gBitTable[i]) + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !(unusable & (1u << i)) && AI_DATA->simulatedDmg[battlerDef][battlerAtk][i].expected >= gBattleMons[battlerAtk].hp) { return TRUE; @@ -1143,7 +1143,7 @@ u32 GetBestDmgMoveFromBattler(u32 battlerAtk, u32 battlerDef) for (i = 0; i < MAX_MON_MOVES; i++) { - if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !(unusable & gBitTable[i]) + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !(unusable & (1u << i)) && bestDmg < AI_DATA->simulatedDmg[battlerAtk][battlerDef][i].expected) { bestDmg = AI_DATA->simulatedDmg[battlerAtk][battlerDef][i].expected; @@ -1164,7 +1164,7 @@ u32 GetBestDmgFromBattler(u32 battler, u32 battlerTarget) { if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE - && !(unusable & gBitTable[i]) + && !(unusable & (1u << i)) && bestDmg < AI_DATA->simulatedDmg[battler][battlerTarget][i].expected) { bestDmg = AI_DATA->simulatedDmg[battler][battlerTarget][i].expected; @@ -1184,7 +1184,7 @@ bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u32 numHits) for (i = 0; i < MAX_MON_MOVES; i++) { - if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !(moveLimitations & gBitTable[i])) + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !(moveLimitations & (1u << i))) { // Use the pre-calculated value in simulatedDmg instead of re-calculating it dmg = AI_DATA->simulatedDmg[battlerAtk][battlerDef][i].expected; @@ -1229,7 +1229,7 @@ bool32 CanTargetFaintAiWithMod(u32 battlerDef, u32 battlerAtk, s32 hpMod, s32 dm if (dmgMod) dmg *= dmgMod; - if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !(unusable & gBitTable[i]) && dmg >= hpCheck) + if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !(unusable & (1u << i)) && dmg >= hpCheck) { return TRUE; } @@ -2091,7 +2091,7 @@ bool32 HasMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef, u32 accCheck, bool if (moves[i] == MOVE_NONE || moves[i] == MOVE_UNAVAILABLE) continue; - if (!(gBitTable[i] & moveLimitations)) + if (!((1u << i) & moveLimitations)) { if (ignoreStatus && IS_MOVE_STATUS(moves[i])) continue; @@ -2117,7 +2117,7 @@ bool32 HasSleepMoveWithLowAccuracy(u32 battlerAtk, u32 battlerDef) { if (moves[i] == MOVE_NONE) break; - if (!(gBitTable[i] & moveLimitations)) + if (!((1u << i) & moveLimitations)) { if (gMovesInfo[moves[i]].effect == EFFECT_SLEEP && AI_DATA->moveAccuracy[battlerAtk][battlerDef][i] < 85) diff --git a/src/battle_arena.c b/src/battle_arena.c index 26df519be0..f9a51ac652 100644 --- a/src/battle_arena.c +++ b/src/battle_arena.c @@ -386,9 +386,9 @@ void BattleArena_AddSkillPoints(u8 battler) if (gHitMarker & HITMARKER_OBEYS) { u8 *failedMoveBits = &gBattleStruct->alreadyStatusedMoveAttempt; - if (*failedMoveBits & gBitTable[battler]) + if (*failedMoveBits & (1u << battler)) { - *failedMoveBits &= ~(gBitTable[battler]); + *failedMoveBits &= ~((1u << battler)); skillPoints[battler] -= 2; } else if (gMoveResultFlags & MOVE_RESULT_NO_EFFECT) diff --git a/src/battle_controller_link_opponent.c b/src/battle_controller_link_opponent.c index 0c71d0a1da..7aeefa54b6 100644 --- a/src/battle_controller_link_opponent.c +++ b/src/battle_controller_link_opponent.c @@ -118,7 +118,7 @@ void SetControllerToLinkOpponent(u32 battler) static void LinkOpponentBufferRunCommand(u32 battler) { - if (gBattleControllerExecFlags & gBitTable[battler]) + if (gBattleControllerExecFlags & (1u << battler)) { if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkOpponentBufferCommands)) sLinkOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler); @@ -376,7 +376,7 @@ static void LinkOpponentBufferExecCompleted(u32 battler) } else { - gBattleControllerExecFlags &= ~gBitTable[battler]; + gBattleControllerExecFlags &= ~(1u << battler); } } diff --git a/src/battle_controller_link_partner.c b/src/battle_controller_link_partner.c index e5fb49bebf..283b492a91 100644 --- a/src/battle_controller_link_partner.c +++ b/src/battle_controller_link_partner.c @@ -117,7 +117,7 @@ void SetControllerToLinkPartner(u32 battler) static void LinkPartnerBufferRunCommand(u32 battler) { - if (gBattleControllerExecFlags & gBitTable[battler]) + if (gBattleControllerExecFlags & (1u << battler)) { if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sLinkPartnerBufferCommands)) sLinkPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler); @@ -202,7 +202,7 @@ static void LinkPartnerBufferExecCompleted(u32 battler) } else { - gBattleControllerExecFlags &= ~gBitTable[battler]; + gBattleControllerExecFlags &= ~(1u << battler); } } diff --git a/src/battle_controller_opponent.c b/src/battle_controller_opponent.c index b555711933..275aa623b6 100644 --- a/src/battle_controller_opponent.c +++ b/src/battle_controller_opponent.c @@ -132,7 +132,7 @@ void SetControllerToOpponent(u32 battler) static void OpponentBufferRunCommand(u32 battler) { - if (gBattleControllerExecFlags & gBitTable[battler]) + if (gBattleControllerExecFlags & (1u << battler)) { if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sOpponentBufferCommands)) sOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler); @@ -390,7 +390,7 @@ static void OpponentBufferExecCompleted(u32 battler) } else { - gBattleControllerExecFlags &= ~gBitTable[battler]; + gBattleControllerExecFlags &= ~(1u << battler); } } @@ -549,7 +549,7 @@ static void OpponentHandleChooseMove(u32 battler) if (GetBattlerMoveTargetType(battler, chosenMove) & MOVE_TARGET_BOTH) { gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) + if (gAbsentBattlerFlags & (1u << gBattlerTarget)) gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); } // If opponent can and should use a gimmick (considering trainer data), do it diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 8760252c67..61f2b8162d 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -180,13 +180,13 @@ static void PlayerBufferExecCompleted(u32 battler) } else { - gBattleControllerExecFlags &= ~gBitTable[battler]; + gBattleControllerExecFlags &= ~(1u << battler); } } static void PlayerBufferRunCommand(u32 battler) { - if (gBattleControllerExecFlags & gBitTable[battler]) + if (gBattleControllerExecFlags & (1u << battler)) { if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sPlayerBufferCommands)) sPlayerBufferCommands[gBattleResources->bufferA[battler][0]](battler); @@ -381,7 +381,7 @@ static void HandleInputChooseAction(u32 battler) { if (IsDoubleBattle() && GetBattlerPosition(battler) == B_POSITION_PLAYER_RIGHT - && !(gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)]) + && !(gAbsentBattlerFlags & (1u << GetBattlerAtPosition(B_POSITION_PLAYER_LEFT))) && !(gBattleTypeFlags & BATTLE_TYPE_MULTI)) { // Return item to bag if partner had selected one. @@ -507,7 +507,7 @@ void HandleInputChooseTarget(u32 battler) break; } - if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor] + if (gAbsentBattlerFlags & (1u << gMultiUsePlayerCursor) || !CanTargetBattler(battler, gMultiUsePlayerCursor, move)) i = 0; } while (i == 0); @@ -557,7 +557,7 @@ void HandleInputChooseTarget(u32 battler) break; } - if (gAbsentBattlerFlags & gBitTable[gMultiUsePlayerCursor] + if (gAbsentBattlerFlags & (1u << gMultiUsePlayerCursor) || !CanTargetBattler(battler, gMultiUsePlayerCursor, move)) i = 0; } while (i == 0); @@ -753,7 +753,7 @@ void HandleInputChooseMove(u32 battler) if (moveTarget & (MOVE_TARGET_USER | MOVE_TARGET_USER_OR_SELECTED)) gMultiUsePlayerCursor = battler; - else if (gAbsentBattlerFlags & gBitTable[GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)]) + else if (gAbsentBattlerFlags & (1u << GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT))) gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); else gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); @@ -994,10 +994,10 @@ void HandleMoveSwitching(u32 battler) moveInfo->maxPp[gMoveSelectionCursor[battler]] = moveInfo->maxPp[gMultiUsePlayerCursor]; moveInfo->maxPp[gMultiUsePlayerCursor] = i; - if (gDisableStructs[battler].mimickedMoves & gBitTable[gMoveSelectionCursor[battler]]) + if (gDisableStructs[battler].mimickedMoves & (1u << gMoveSelectionCursor[battler])) { - gDisableStructs[battler].mimickedMoves &= (~gBitTable[gMoveSelectionCursor[battler]]); - gDisableStructs[battler].mimickedMoves |= gBitTable[gMultiUsePlayerCursor]; + gDisableStructs[battler].mimickedMoves &= ~(1u << gMoveSelectionCursor[battler]); + gDisableStructs[battler].mimickedMoves |= 1u << gMultiUsePlayerCursor; } MoveSelectionDisplayMoveNames(battler); @@ -2109,7 +2109,7 @@ void PlayerHandleChooseMove(u32 battler) gBattleStruct->gimmick.playerSelect = FALSE; AssignUsableZMoves(battler, moveInfo->moves); - gBattleStruct->zmove.viable = (gBattleStruct->zmove.possibleZMoves[battler] & gBitTable[gMoveSelectionCursor[battler]]) != 0; + gBattleStruct->zmove.viable = (gBattleStruct->zmove.possibleZMoves[battler] & (1u << gMoveSelectionCursor[battler])) != 0; if (!IsGimmickTriggerSpriteActive()) gBattleStruct->gimmick.triggerSpriteId = 0xFF; diff --git a/src/battle_controller_player_partner.c b/src/battle_controller_player_partner.c index 2dffd4f702..47d71d87c6 100644 --- a/src/battle_controller_player_partner.c +++ b/src/battle_controller_player_partner.c @@ -121,7 +121,7 @@ void SetControllerToPlayerPartner(u32 battler) static void PlayerPartnerBufferRunCommand(u32 battler) { - if (gBattleControllerExecFlags & gBitTable[battler]) + if (gBattleControllerExecFlags & (1u << battler)) { if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sPlayerPartnerBufferCommands)) sPlayerPartnerBufferCommands[gBattleResources->bufferA[battler][0]](battler); @@ -274,7 +274,7 @@ static void PlayerPartnerBufferExecCompleted(u32 battler) } else { - gBattleControllerExecFlags &= ~gBitTable[battler]; + gBattleControllerExecFlags &= ~(1u << battler); } } @@ -365,7 +365,7 @@ static void PlayerPartnerHandleChooseMove(u32 battler) if (gMovesInfo[moveInfo->moves[chosenMoveId]].target & MOVE_TARGET_BOTH) { gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) + if (gAbsentBattlerFlags & (1u << gBattlerTarget)) gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); } // If partner can and should use a gimmick (considering trainer data), do it diff --git a/src/battle_controller_recorded_opponent.c b/src/battle_controller_recorded_opponent.c index abadcc231c..da977fab89 100644 --- a/src/battle_controller_recorded_opponent.c +++ b/src/battle_controller_recorded_opponent.c @@ -124,7 +124,7 @@ void SetControllerToRecordedOpponent(u32 battler) static void RecordedOpponentBufferRunCommand(u32 battler) { - if (gBattleControllerExecFlags & gBitTable[battler]) + if (gBattleControllerExecFlags & (1u << battler)) { if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sRecordedOpponentBufferCommands)) sRecordedOpponentBufferCommands[gBattleResources->bufferA[battler][0]](battler); @@ -145,7 +145,7 @@ static void RecordedOpponentBufferExecCompleted(u32 battler) } else { - gBattleControllerExecFlags &= ~gBitTable[battler]; + gBattleControllerExecFlags &= ~(1u << battler); } } diff --git a/src/battle_controller_recorded_player.c b/src/battle_controller_recorded_player.c index 3a9ca1ec00..2bb64f3066 100644 --- a/src/battle_controller_recorded_player.c +++ b/src/battle_controller_recorded_player.c @@ -121,7 +121,7 @@ void SetControllerToRecordedPlayer(u32 battler) static void RecordedPlayerBufferRunCommand(u32 battler) { - if (gBattleControllerExecFlags & gBitTable[battler]) + if (gBattleControllerExecFlags & (1u << battler)) { if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sRecordedPlayerBufferCommands)) sRecordedPlayerBufferCommands[gBattleResources->bufferA[battler][0]](battler); @@ -351,7 +351,7 @@ static void RecordedPlayerBufferExecCompleted(u32 battler) } else { - gBattleControllerExecFlags &= ~gBitTable[battler]; + gBattleControllerExecFlags &= ~(1u << battler); } } diff --git a/src/battle_controller_safari.c b/src/battle_controller_safari.c index 39fbc63ab6..b85157f246 100644 --- a/src/battle_controller_safari.c +++ b/src/battle_controller_safari.c @@ -112,7 +112,7 @@ void SetControllerToSafari(u32 battler) static void SafariBufferRunCommand(u32 battler) { - if (gBattleControllerExecFlags & gBitTable[battler]) + if (gBattleControllerExecFlags & (1u << battler)) { if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sSafariBufferCommands)) sSafariBufferCommands[gBattleResources->bufferA[battler][0]](battler); @@ -240,7 +240,7 @@ static void SafariBufferExecCompleted(u32 battler) } else { - gBattleControllerExecFlags &= ~gBitTable[battler]; + gBattleControllerExecFlags &= ~(1u << battler); } } diff --git a/src/battle_controller_wally.c b/src/battle_controller_wally.c index 7b0bb6f154..66d3932694 100644 --- a/src/battle_controller_wally.c +++ b/src/battle_controller_wally.c @@ -129,7 +129,7 @@ void SetControllerToWally(u32 battler) static void WallyBufferRunCommand(u32 battler) { - if (gBattleControllerExecFlags & gBitTable[battler]) + if (gBattleControllerExecFlags & (1u << battler)) { if (gBattleResources->bufferA[battler][0] < ARRAY_COUNT(sWallyBufferCommands)) sWallyBufferCommands[gBattleResources->bufferA[battler][0]](battler); @@ -288,7 +288,7 @@ static void WallyBufferExecCompleted(u32 battler) } else { - gBattleControllerExecFlags &= ~gBitTable[battler]; + gBattleControllerExecFlags &= ~(1u << battler); } } diff --git a/src/battle_controllers.c b/src/battle_controllers.c index e11406831b..9c9c1b50ba 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -851,7 +851,7 @@ void TryReceiveLinkBattleData(void) DestroyTask_RfuIdle(); for (i = 0; i < GetLinkPlayerCount(); i++) { - if (GetBlockReceivedStatus() & gBitTable[i]) + if (GetBlockReceivedStatus() & (1 << (i))) { ResetBlockReceivedFlag(i); recvBuffer = (u8 *)gBlockRecvBuffer[i]; @@ -898,7 +898,7 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId) switch (gLinkBattleRecvBuffer[gTasks[taskId].data[15] + 0]) { case 0: - if (gBattleControllerExecFlags & gBitTable[battler]) + if (gBattleControllerExecFlags & (1u << battler)) return; memcpy(gBattleResources->bufferA[battler], &gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA], blockSize); @@ -917,7 +917,7 @@ static void Task_HandleCopyReceivedLinkBuffersData(u8 taskId) break; case 2: var = gLinkBattleRecvBuffer[gTasks[taskId].data[15] + LINK_BUFF_DATA]; - gBattleControllerExecFlags &= ~(gBitTable[battler] << (var * 4)); + gBattleControllerExecFlags &= ~(1u << (battler + var * 4)); break; } diff --git a/src/battle_dome.c b/src/battle_dome.c index 67b9a1e293..6069f5439c 100644 --- a/src/battle_dome.c +++ b/src/battle_dome.c @@ -2030,8 +2030,8 @@ static void InitDomeTrainers(void) rankingScores[0] += GetMonData(&gPlayerParty[trainerId], MON_DATA_SPDEF, NULL); rankingScores[0] += GetMonData(&gPlayerParty[trainerId], MON_DATA_SPEED, NULL); rankingScores[0] += GetMonData(&gPlayerParty[trainerId], MON_DATA_MAX_HP, NULL); - monTypesBits |= gBitTable[gSpeciesInfo[GetMonData(&gPlayerParty[trainerId], MON_DATA_SPECIES, NULL)].types[0]]; - monTypesBits |= gBitTable[gSpeciesInfo[GetMonData(&gPlayerParty[trainerId], MON_DATA_SPECIES, NULL)].types[1]]; + monTypesBits |= 1u << gSpeciesInfo[GetMonData(&gPlayerParty[trainerId], MON_DATA_SPECIES, NULL)].types[0]; + monTypesBits |= 1u << gSpeciesInfo[GetMonData(&gPlayerParty[trainerId], MON_DATA_SPECIES, NULL)].types[1]; } // Count the number of types in the players party, to factor into the ranking @@ -2062,8 +2062,8 @@ static void InitDomeTrainers(void) rankingScores[i] += statValues[STAT_SPDEF]; rankingScores[i] += statValues[STAT_SPEED]; rankingScores[i] += statValues[STAT_HP]; - monTypesBits |= gBitTable[gSpeciesInfo[gFacilityTrainerMons[DOME_MONS[i][j]].species].types[0]]; - monTypesBits |= gBitTable[gSpeciesInfo[gFacilityTrainerMons[DOME_MONS[i][j]].species].types[1]]; + monTypesBits |= 1u << gSpeciesInfo[gFacilityTrainerMons[DOME_MONS[i][j]].species].types[0]; + monTypesBits |= 1u << gSpeciesInfo[gFacilityTrainerMons[DOME_MONS[i][j]].species].types[1]; } for (monTypesCount = 0, j = 0; j < 32; j++) @@ -2344,9 +2344,9 @@ static int SelectOpponentMonsFromParty(int *partyMovePoints, bool8 allowRandom) while (i != DOME_BATTLE_PARTY_SIZE) { u32 rand = Random() & FRONTIER_PARTY_SIZE; - if (rand != FRONTIER_PARTY_SIZE && !(selectedMonBits & gBitTable[rand])) + if (rand != FRONTIER_PARTY_SIZE && !(selectedMonBits & (1u << rand))) { - selectedMonBits |= gBitTable[rand]; + selectedMonBits |= 1u << rand; i++; } } @@ -2376,7 +2376,7 @@ static int SelectOpponentMonsFromParty(int *partyMovePoints, bool8 allowRandom) for (i = 0; i < DOME_BATTLE_PARTY_SIZE; i++) { - selectedMonBits |= gBitTable[partyPositions[i]]; + selectedMonBits |= 1u << partyPositions[i]; } } @@ -5802,8 +5802,8 @@ static void InitRandomTourneyTreeResults(void) statSums[i] += statValues[STAT_SPDEF]; statSums[i] += statValues[STAT_SPEED]; statSums[i] += statValues[STAT_HP]; - monTypesBits |= gBitTable[gSpeciesInfo[gFacilityTrainerMons[DOME_MONS[i][j]].species].types[0]]; - monTypesBits |= gBitTable[gSpeciesInfo[gFacilityTrainerMons[DOME_MONS[i][j]].species].types[1]]; + monTypesBits |= 1u << gSpeciesInfo[gFacilityTrainerMons[DOME_MONS[i][j]].species].types[0]; + monTypesBits |= 1u << gSpeciesInfo[gFacilityTrainerMons[DOME_MONS[i][j]].species].types[1]; } // Because GF hates temporary vars, trainerId acts like monTypesCount here. diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index b396f1d7b5..22736b7c2b 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -126,7 +126,7 @@ u16 ChooseMoveAndTargetInBattlePalace(u32 battler) // If battler is < 50% HP and not asleep, use second set of move group likelihoods // otherwise use first set - i = (gBattleStruct->palaceFlags & gBitTable[battler]) ? 2 : 0; + i = (gBattleStruct->palaceFlags & (1u << battler)) ? 2 : 0; minGroupNum = i; maxGroupNum = i + 2; // + 2 because there are two percentages per set of likelihoods @@ -150,7 +150,7 @@ u16 ChooseMoveAndTargetInBattlePalace(u32 battler) if (moveInfo->moves[i] == MOVE_NONE) break; if (selectedGroup == GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) && moveInfo->currentPp[i] != 0) - selectedMoves |= gBitTable[i]; + selectedMoves |= 1u << i; } // Pass selected moves to AI, pick one @@ -178,11 +178,11 @@ u16 ChooseMoveAndTargetInBattlePalace(u32 battler) { // Count the number of usable moves the battler has in each move group. // The totals will be stored separately in 3 groups of 4 bits each in numMovesPerGroup. - if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_ATTACK && !(gBitTable[i] & unusableMovesBits)) + if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_ATTACK && !((1u << i) & unusableMovesBits)) numMovesPerGroup += (1 << 0); - if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_DEFENSE && !(gBitTable[i] & unusableMovesBits)) + if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_DEFENSE && !((1u << i) & unusableMovesBits)) numMovesPerGroup += (1 << 4); - if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_SUPPORT && !(gBitTable[i] & unusableMovesBits)) + if (GetBattlePalaceMoveGroup(battler, moveInfo->moves[i]) == PALACE_MOVE_GROUP_SUPPORT && !((1u << i) & unusableMovesBits)) numMovesPerGroup += (1 << 8); } @@ -215,7 +215,7 @@ u16 ChooseMoveAndTargetInBattlePalace(u32 battler) do { i = Random() % MAX_MON_MOVES; - if (!(gBitTable[i] & unusableMovesBits)) + if (!((1u << i) & unusableMovesBits)) chosenMoveId = i; } while (chosenMoveId == -1); } @@ -241,7 +241,7 @@ u16 ChooseMoveAndTargetInBattlePalace(u32 battler) do { i = Random() % MAX_MON_MOVES; - if (!(gBitTable[i] & unusableMovesBits) && randSelectGroup == GetBattlePalaceMoveGroup(battler, moveInfo->moves[i])) + if (!((1u << i) & unusableMovesBits) && randSelectGroup == GetBattlePalaceMoveGroup(battler, moveInfo->moves[i])) chosenMoveId = i; } while (chosenMoveId == -1); } diff --git a/src/battle_gimmick.c b/src/battle_gimmick.c index 2595e4cbda..815fd5fc3e 100644 --- a/src/battle_gimmick.c +++ b/src/battle_gimmick.c @@ -45,7 +45,7 @@ bool32 IsGimmickSelected(u32 battler, enum Gimmick gimmick) { // There's no player select in tests, but some gimmicks need to test choice before they are fully activated. if (TESTING) - return (gBattleStruct->gimmick.toActivate & gBitTable[battler]) && gBattleStruct->gimmick.usableGimmick[battler] == gimmick; + return (gBattleStruct->gimmick.toActivate & (1u << battler)) && gBattleStruct->gimmick.usableGimmick[battler] == gimmick; else return gBattleStruct->gimmick.usableGimmick[battler] == gimmick && gBattleStruct->gimmick.playerSelect; } @@ -99,7 +99,7 @@ bool32 HasTrainerUsedGimmick(u32 battler, enum Gimmick gimmick) if (IsDoubleBattle() && IsPartnerMonFromSameTrainer(battler) && (gBattleStruct->gimmick.activated[BATTLE_PARTNER(battler)][gimmick] - || ((gBattleStruct->gimmick.toActivate & gBitTable[BATTLE_PARTNER(battler)] + || ((gBattleStruct->gimmick.toActivate & (1u << BATTLE_PARTNER(battler)) && gBattleStruct->gimmick.usableGimmick[BATTLE_PARTNER(battler)] == gimmick)))) { return TRUE; diff --git a/src/battle_interface.c b/src/battle_interface.c index 8d50bf95c3..4c17322b53 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -1377,7 +1377,7 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, // fainted mon gSprites[ballIconSpritesIds[i]].oam.tileNum += 3; } - else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->arenaLostPlayerMons & gBitTable[j]) + else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->arenaLostPlayerMons & (1u << j)) { // fainted arena mon gSprites[ballIconSpritesIds[i]].oam.tileNum += 3; @@ -1433,7 +1433,7 @@ u8 CreatePartyStatusSummarySprites(u8 battlerId, struct HpAndStatus *partyInfo, // fainted mon gSprites[ballIconSpritesIds[PARTY_SIZE - 1 - var]].oam.tileNum += 3; } - else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->arenaLostOpponentMons & gBitTable[j]) + else if (gBattleTypeFlags & BATTLE_TYPE_ARENA && gBattleStruct->arenaLostOpponentMons & (1u << j)) { // fainted arena mon gSprites[ballIconSpritesIds[PARTY_SIZE - 1 - var]].oam.tileNum += 3; @@ -2718,7 +2718,7 @@ void CreateAbilityPopUp(u8 battlerId, u32 ability, bool32 isDoubleBattle) LoadSpriteSheet(&sSpriteSheet_AbilityPopUp); LoadSpritePalette(&sSpritePalette_AbilityPopUp); } - gBattleStruct->activeAbilityPopUps |= gBitTable[battlerId]; + gBattleStruct->activeAbilityPopUps |= 1u << battlerId; battlerPosition = GetBattlerPosition(battlerId); if (isDoubleBattle) @@ -2809,7 +2809,7 @@ static void SpriteCb_AbilityPopUp(struct Sprite *sprite) ||(sprite->tRightToLeft && (sprite->x -= 4) <= sprite->tOriginalX - ABILITY_POP_UP_POS_X_SLIDE) ) { - gBattleStruct->activeAbilityPopUps &= ~(gBitTable[sprite->tBattlerId]); + gBattleStruct->activeAbilityPopUps &= ~(1u << sprite->tBattlerId); DestroySprite(sprite); } } @@ -2823,7 +2823,7 @@ static void SpriteCb_AbilityPopUp(struct Sprite *sprite) void DestroyAbilityPopUp(u8 battlerId) { - if (gBattleStruct->activeAbilityPopUps & gBitTable[battlerId]) + if (gBattleStruct->activeAbilityPopUps & (1u << battlerId)) { gSprites[gBattleStruct->abilityPopUpSpriteIds[battlerId][0]].tFrames = 0; gSprites[gBattleStruct->abilityPopUpSpriteIds[battlerId][1]].tFrames = 0; diff --git a/src/battle_main.c b/src/battle_main.c index b46feaf0f9..25cee6dfa9 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3218,9 +3218,9 @@ void SwitchInClearSetData(u32 battler) gBattleStruct->lastTakenMoveFrom[battler][1] = 0; gBattleStruct->lastTakenMoveFrom[battler][2] = 0; gBattleStruct->lastTakenMoveFrom[battler][3] = 0; - gBattleStruct->lastMoveFailed &= ~(gBitTable[battler]); - gBattleStruct->palaceFlags &= ~(gBitTable[battler]); - gBattleStruct->boosterEnergyActivates &= ~(gBitTable[battler]); + gBattleStruct->lastMoveFailed &= ~(1u << battler); + gBattleStruct->palaceFlags &= ~(1u << battler); + gBattleStruct->boosterEnergyActivates &= ~(1u << battler); for (i = 0; i < ARRAY_COUNT(gSideTimers); i++) { @@ -3245,7 +3245,7 @@ void SwitchInClearSetData(u32 battler) // Reset damage to prevent things like red card activating if the switched-in mon is holding it gSpecialStatuses[battler].physicalDmg = 0; gSpecialStatuses[battler].specialDmg = 0; - gBattleStruct->enduredDamage &= ~gBitTable[battler]; + gBattleStruct->enduredDamage &= ~(1u << battler); // Reset G-Max Chi Strike boosts. gBattleStruct->bonusCritStages[battler] = 0; @@ -3348,8 +3348,8 @@ const u8* FaintClearSetData(u32 battler) gBattleStruct->lastTakenMoveFrom[battler][2] = 0; gBattleStruct->lastTakenMoveFrom[battler][3] = 0; - gBattleStruct->palaceFlags &= ~(gBitTable[battler]); - gBattleStruct->boosterEnergyActivates &= ~(gBitTable[battler]); + gBattleStruct->palaceFlags &= ~(1u << battler); + gBattleStruct->boosterEnergyActivates &= ~(1u << battler); for (i = 0; i < ARRAY_COUNT(gSideTimers); i++) { @@ -3790,7 +3790,7 @@ static void TryDoEventsBeforeFirstTurn(void) struct Pokemon *party = GetBattlerParty(i); struct Pokemon *mon = &party[gBattlerPartyIndexes[i]]; if (!IsBattlerAlive(i) || gBattleMons[i].species == SPECIES_NONE || GetMonData(mon, MON_DATA_IS_EGG)) - gAbsentBattlerFlags |= gBitTable[i]; + gAbsentBattlerFlags |= 1u << i; } } @@ -3923,7 +3923,7 @@ static void TryDoEventsBeforeFirstTurn(void) gBattleMons[i].status2 &= ~STATUS2_FLINCHED; // Record party slots of player's mons that appeared in battle if (!BattlerHasAi(i)) - gBattleStruct->appearedInBattle |= gBitTable[gBattlerPartyIndexes[i]]; + gBattleStruct->appearedInBattle |= 1u << gBattlerPartyIndexes[i]; } *(&gBattleStruct->turnEffectsTracker) = 0; @@ -4195,10 +4195,10 @@ static void HandleTurnActionSelectionState(void) *(gBattleStruct->monToSwitchIntoId + battler) = PARTY_SIZE; if (gBattleTypeFlags & BATTLE_TYPE_MULTI || (position & BIT_FLANK) == B_FLANK_LEFT - || gBattleStruct->absentBattlerFlags & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(position))] + || gBattleStruct->absentBattlerFlags & (1u << GetBattlerAtPosition(BATTLE_PARTNER(position))) || gBattleCommunication[GetBattlerAtPosition(BATTLE_PARTNER(position))] == STATE_WAIT_ACTION_CONFIRMED) { - if (gBattleStruct->absentBattlerFlags & gBitTable[battler]) + if (gBattleStruct->absentBattlerFlags & (1u << battler)) { gChosenActionByBattler[battler] = B_ACTION_NOTHING_FAINTED; if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) @@ -4234,7 +4234,7 @@ static void HandleTurnActionSelectionState(void) } break; case STATE_WAIT_ACTION_CHOSEN: // Try to perform an action. - if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12)))) + if (!(gBattleControllerExecFlags & (((1u << battler)) | (0xF << 28) | ((1u << battler) << 4) | ((1u << battler) << 8) | ((1u << battler) << 12)))) { RecordedBattle_SetBattlerAction(battler, gBattleResources->bufferB[battler][1]); gChosenActionByBattler[battler] = gBattleResources->bufferB[battler][1]; @@ -4386,7 +4386,7 @@ static void HandleTurnActionSelectionState(void) RecordedBattle_ClearBattlerAction(GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(battler))), 3); } - gBattleStruct->gimmick.toActivate &= ~(gBitTable[BATTLE_PARTNER(GetBattlerPosition(battler))]); + gBattleStruct->gimmick.toActivate &= ~((1u << BATTLE_PARTNER(GetBattlerPosition(battler)))); BtlController_EmitEndBounceEffect(battler, BUFFER_A); MarkBattlerForControllerExec(battler); return; @@ -4429,7 +4429,7 @@ static void HandleTurnActionSelectionState(void) } break; case STATE_WAIT_ACTION_CASE_CHOSEN: - if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12)))) + if (!(gBattleControllerExecFlags & (((1u << battler)) | (0xF << 28) | ((1u << battler) << 4) | ((1u << battler) << 8) | ((1u << battler) << 12)))) { switch (gChosenActionByBattler[battler]) { @@ -4480,7 +4480,7 @@ static void HandleTurnActionSelectionState(void) // Check to see if any gimmicks need to be prepared. if (gBattleResources->bufferB[battler][2] & RET_GIMMICK) - gBattleStruct->gimmick.toActivate |= gBitTable[battler]; + gBattleStruct->gimmick.toActivate |= 1u << battler; // Max Move check if (GetActiveGimmick(battler) == GIMMICK_DYNAMAX || IsGimmickSelected(battler, GIMMICK_DYNAMAX)) @@ -4559,11 +4559,11 @@ static void HandleTurnActionSelectionState(void) } break; case STATE_WAIT_ACTION_CONFIRMED_STANDBY: - if (!(gBattleControllerExecFlags & ((gBitTable[battler]) + if (!(gBattleControllerExecFlags & ((1u << battler) | (0xF << 28) - | (gBitTable[battler] << 4) - | (gBitTable[battler] << 8) - | (gBitTable[battler] << 12)))) + | (1u << (battler + 4)) + | (1u << (battler + 8)) + | (1u << (battler + 12))))) { if (AllAtActionConfirmed()) i = TRUE; @@ -4572,7 +4572,7 @@ static void HandleTurnActionSelectionState(void) if (((gBattleTypeFlags & BATTLE_TYPE_MULTI) || !IsDoubleBattle()) || (position & BIT_FLANK) != B_FLANK_LEFT - || (*(&gBattleStruct->absentBattlerFlags) & gBitTable[GetBattlerAtPosition(BATTLE_PARTNER(position))])) + || (*(&gBattleStruct->absentBattlerFlags) & (1u << GetBattlerAtPosition(BATTLE_PARTNER(position))))) { BtlController_EmitLinkStandbyMsg(battler, BUFFER_A, LINK_STANDBY_MSG_STOP_BOUNCE, i); } @@ -4585,7 +4585,7 @@ static void HandleTurnActionSelectionState(void) } break; case STATE_WAIT_ACTION_CONFIRMED: - if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12)))) + if (!(gBattleControllerExecFlags & ((1u << battler) | (0xF << 28) | (1u << (battler + 4)) | (1u << (battler + 8)) | (1u << (battler + 12))))) { gBattleCommunication[ACTIONS_CONFIRMED_COUNT]++; } @@ -4599,7 +4599,7 @@ static void HandleTurnActionSelectionState(void) { gBattlerAttacker = battler; gBattlescriptCurrInstr = gSelectionBattleScripts[battler]; - if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12)))) + if (!(gBattleControllerExecFlags & ((1u << battler) | (0xF << 28) | (1u << (battler + 4)) | (1u << (battler + 8)) | (1u << (battler + 12))))) { gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); } @@ -4607,7 +4607,7 @@ static void HandleTurnActionSelectionState(void) } break; case STATE_WAIT_SET_BEFORE_ACTION: - if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12)))) + if (!(gBattleControllerExecFlags & ((1u << battler) | (0xF << 28) | (1u << (battler + 4)) | (1u << (battler + 8)) | (1u << (battler + 12))))) { gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN; } @@ -4631,7 +4631,7 @@ static void HandleTurnActionSelectionState(void) { gBattlerAttacker = battler; gBattlescriptCurrInstr = gSelectionBattleScripts[battler]; - if (!(gBattleControllerExecFlags & ((gBitTable[battler]) | (0xF << 28) | (gBitTable[battler] << 4) | (gBitTable[battler] << 8) | (gBitTable[battler] << 12)))) + if (!(gBattleControllerExecFlags & ((1u << battler) | (0xF << 28) | (1u << (battler + 4)) | (1u << (battler + 8)) | (1u << (battler + 12))))) { gBattleScriptingCommandsTable[gBattlescriptCurrInstr[0]](); } @@ -5154,10 +5154,10 @@ static bool32 TryDoGimmicksBeforeMoves(void) for (i = 0; i < gBattlersCount; i++) { // Search through each battler and activate their gimmick if they have one prepared. - if ((gBattleStruct->gimmick.toActivate & gBitTable[order[i]]) && !(gProtectStructs[order[i]].noValidMoves)) + if ((gBattleStruct->gimmick.toActivate & (1u << order[i])) && !(gProtectStructs[order[i]].noValidMoves)) { battler = gBattlerAttacker = gBattleScripting.battler = order[i]; - gBattleStruct->gimmick.toActivate &= ~(gBitTable[battler]); + gBattleStruct->gimmick.toActivate &= ~(1u << battler); if (gGimmicksInfo[gBattleStruct->gimmick.usableGimmick[battler]].ActivateGimmick != NULL) { gGimmicksInfo[gBattleStruct->gimmick.usableGimmick[battler]].ActivateGimmick(battler); @@ -5183,12 +5183,12 @@ static bool32 TryDoMoveEffectsBeforeMoves(void) SortBattlersBySpeed(battlers, FALSE); for (i = 0; i < gBattlersCount; i++) { - if (!(gBattleStruct->focusPunchBattlers & gBitTable[battlers[i]]) + if (!(gBattleStruct->focusPunchBattlers & (1u << battlers[i])) && !(gBattleMons[battlers[i]].status1 & STATUS1_SLEEP) && !(gDisableStructs[battlers[i]].truantCounter) && !(gProtectStructs[battlers[i]].noValidMoves)) { - gBattleStruct->focusPunchBattlers |= gBitTable[battlers[i]]; + gBattleStruct->focusPunchBattlers |= 1u << battlers[i]; gBattlerAttacker = battlers[i]; switch (gChosenMoveByBattler[gBattlerAttacker]) { @@ -5560,7 +5560,7 @@ static void HandleEndTurn_FinishBattle(void) bool8 changedForm = FALSE; // Appeared in battle and didn't faint - if ((gBattleStruct->appearedInBattle & gBitTable[i]) && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0) + if ((gBattleStruct->appearedInBattle & (1u << i)) && GetMonData(&gPlayerParty[i], MON_DATA_HP, NULL) != 0) changedForm = TryFormChange(i, B_SIDE_PLAYER, FORM_CHANGE_END_BATTLE_TERRAIN); if (!changedForm) @@ -5635,15 +5635,15 @@ static void TryEvolvePokemon(void) for (i = 0; i < PARTY_SIZE; i++) { - if (!(sTriedEvolving & gBitTable[i])) + if (!(sTriedEvolving & (1u << i))) { u16 species = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_BATTLE_SPECIAL, i, NULL); bool32 evoModeNormal = TRUE; - sTriedEvolving |= gBitTable[i]; + sTriedEvolving |= 1u << i; - if (species == SPECIES_NONE && (gLeveledUpInBattle & gBitTable[i])) + if (species == SPECIES_NONE && (gLeveledUpInBattle & (1u << i))) { - gLeveledUpInBattle &= ~(gBitTable[i]); + gLeveledUpInBattle &= ~(1u << i); species = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_BATTLE_ONLY, gLeveledUpInBattle, NULL); } diff --git a/src/battle_pyramid.c b/src/battle_pyramid.c index ce7a0526f2..aa3c63ef82 100644 --- a/src/battle_pyramid.c +++ b/src/battle_pyramid.c @@ -1081,7 +1081,7 @@ static void ShowPostBattleHintText(void) textIndex = sPyramidFloorTemplates[id].numTrainers; for (i = 0; i < MAX_PYRAMID_TRAINERS; i++) { - if (gBitTable[i] & gSaveBlock2Ptr->frontier.pyramidTrainerFlags) + if ((1u << i) & gSaveBlock2Ptr->frontier.pyramidTrainerFlags) textIndex--; } i = 1; @@ -1317,7 +1317,7 @@ u16 LocalIdToPyramidTrainerId(u8 localId) bool8 GetBattlePyramidTrainerFlag(u8 eventId) { - return gSaveBlock2Ptr->frontier.pyramidTrainerFlags & gBitTable[gObjectEvents[eventId].localId - 1]; + return gSaveBlock2Ptr->frontier.pyramidTrainerFlags & ((1u << gObjectEvents[eventId].localId) - 1); } void MarkApproachingPyramidTrainersAsBattled(void) @@ -1337,7 +1337,7 @@ static void MarkPyramidTrainerAsBattled(u16 trainerId) for (i = 0; i < MAX_PYRAMID_TRAINERS; i++) { if (gSaveBlock2Ptr->frontier.trainerIds[i] == trainerId) - gSaveBlock2Ptr->frontier.pyramidTrainerFlags |= gBitTable[i]; + gSaveBlock2Ptr->frontier.pyramidTrainerFlags |= 1u << i; } gObjectEvents[gSelectedObjectEvent].movementType = MOVEMENT_TYPE_WANDER_AROUND; @@ -1893,12 +1893,12 @@ static void SetPyramidObjectPositionsUniformly(u8 objType) { if (bits & 1) { - if (!(gBitTable[squareId] & gSaveBlock2Ptr->frontier.pyramidRandoms[3])) + if (!((1u << squareId) & gSaveBlock2Ptr->frontier.pyramidRandoms[3])) bits |= 2; } else { - if (gBitTable[squareId] & gSaveBlock2Ptr->frontier.pyramidRandoms[3]) + if ((1u << squareId) & gSaveBlock2Ptr->frontier.pyramidRandoms[3]) bits |= 2; } if (++squareId >= NUM_PYRAMID_FLOOR_SQUARES) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 44ad1868a8..2553794caa 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1173,7 +1173,7 @@ bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType) bool32 ShouldTeraShellDistortTypeMatchups(u32 move, u32 battlerDef) { - if (!(gBattleStruct->distortedTypeMatchups & gBitTable[battlerDef]) + if (!(gBattleStruct->distortedTypeMatchups & (1u << battlerDef)) && GetBattlerAbility(battlerDef) == ABILITY_TERA_SHELL && gBattleMons[battlerDef].species == SPECIES_TERAPAGOS_TERASTAL && !IS_MOVE_STATUS(move) @@ -1242,7 +1242,7 @@ static void Cmd_attackcanceler(void) if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_OFF && GetBattlerAbility(gBattlerAttacker) == ABILITY_PARENTAL_BOND && IsMoveAffectedByParentalBond(gCurrentMove, gBattlerAttacker) - && !(gAbsentBattlerFlags & gBitTable[gBattlerTarget]) + && !(gAbsentBattlerFlags & (1u << gBattlerTarget)) && GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE) { gSpecialStatuses[gBattlerAttacker].parentalBondState = PARENTAL_BOND_1ST_HIT; @@ -1847,7 +1847,7 @@ static void Cmd_ppreduce(void) if (ShouldTeraShellDistortTypeMatchups(gCurrentMove, gBattlerTarget)) { - gBattleStruct->distortedTypeMatchups |= gBitTable[gBattlerTarget]; + gBattleStruct->distortedTypeMatchups |= 1u << gBattlerTarget; gBattlerAbility = gBattlerTarget; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_TeraShellDistortingTypeMatchups; @@ -1987,7 +1987,7 @@ static void Cmd_adjustdamage(void) goto END; if (DoesDisguiseBlockMove(gBattlerTarget, gCurrentMove)) { - gBattleStruct->enduredDamage |= gBitTable[gBattlerTarget]; + gBattleStruct->enduredDamage |= 1u << gBattlerTarget; goto END; } if (GetBattlerAbility(gBattlerTarget) == ABILITY_ICE_FACE && IS_MOVE_PHYSICAL(gCurrentMove) && gBattleMons[gBattlerTarget].species == SPECIES_EISCUE) @@ -2041,7 +2041,7 @@ static void Cmd_adjustdamage(void) // Handle reducing the dmg to 1 hp. gBattleMoveDamage = gBattleMons[gBattlerTarget].hp - 1; - gBattleStruct->enduredDamage |= gBitTable[gBattlerTarget]; + gBattleStruct->enduredDamage |= 1u << gBattlerTarget; if (gProtectStructs[gBattlerTarget].endured) { @@ -2069,7 +2069,7 @@ END: gBattlescriptCurrInstr = cmd->nextInstr; if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && gBattleMoveDamage >= 1) - gSpecialStatuses[gBattlerAttacker].damagedMons |= gBitTable[gBattlerTarget]; + gSpecialStatuses[gBattlerAttacker].damagedMons |= (1 << (gBattlerTarget)); // Check gems and damage reducing berries. if (gSpecialStatuses[gBattlerTarget].berryReduced @@ -2144,7 +2144,7 @@ static void Cmd_multihitresultmessage(void) if (gSpecialStatuses[gBattlerTarget].berryReduced && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) { - gBattleStruct->ateBerry[gBattlerTarget & BIT_SIDE] |= gBitTable[gBattlerPartyIndexes[gBattlerTarget]]; + gBattleStruct->ateBerry[gBattlerTarget & BIT_SIDE] |= 1u << gBattlerPartyIndexes[gBattlerTarget]; gSpecialStatuses[gBattlerTarget].berryReduced = FALSE; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_PrintBerryReduceString; @@ -2605,7 +2605,7 @@ static void Cmd_resultmessage(void) if (gSpecialStatuses[gBattlerTarget].berryReduced && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) { - gBattleStruct->ateBerry[gBattlerTarget & BIT_SIDE] |= gBitTable[gBattlerPartyIndexes[gBattlerTarget]]; + gBattleStruct->ateBerry[gBattlerTarget & BIT_SIDE] |= 1u << gBattlerPartyIndexes[gBattlerTarget]; gSpecialStatuses[gBattlerTarget].berryReduced = FALSE; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_PrintBerryReduceString; @@ -3530,7 +3530,7 @@ void SetMoveEffect(bool32 primary, bool32 certain) { bool32 byTwo = FALSE; - gBattleStruct->stolenStats[0] |= gBitTable[i]; + gBattleStruct->stolenStats[0] |= (1 << (i)); // Store by how many stages to raise the stat. gBattleStruct->stolenStats[i] = gBattleMons[gBattlerTarget].statStages[i] - DEFAULT_STAT_STAGE; while (gBattleMons[gBattlerAttacker].statStages[i] + gBattleStruct->stolenStats[i] > MAX_STAT_STAGE) @@ -3945,7 +3945,7 @@ static void Cmd_tryfaintmon(void) destinyBondBattler = gBattlerAttacker; faintScript = BattleScript_FaintTarget; } - if (!(gAbsentBattlerFlags & gBitTable[battler]) + if (!(gAbsentBattlerFlags & (1u << battler)) && !IsBattlerAlive(battler)) { gHitMarker |= HITMARKER_FAINTED(battler); @@ -4243,7 +4243,7 @@ static void Cmd_getexp(void) else { gBattleScripting.getexpState++; - gBattleStruct->givenExpMons |= gBitTable[gBattlerPartyIndexes[gBattlerFainted]]; + gBattleStruct->givenExpMons |= (1u << gBattlerPartyIndexes[gBattlerFainted]); } break; case 1: // calculate experience points to redistribute @@ -4260,25 +4260,25 @@ static void Cmd_getexp(void) { if (!IsValidForBattle(&gPlayerParty[i])) continue; - if (gBitTable[i] & sentInBits) + if ((1u << i) & sentInBits) viaSentIn++; holdEffect = GetMonHoldEffect(&gPlayerParty[i]); if (holdEffect == HOLD_EFFECT_EXP_SHARE || IsGen6ExpShareEnabled()) { - expShareBits |= gBitTable[i]; + expShareBits |= 1u << i; viaExpShare++; } } // Get order of mons getting exp: 1. all mons via sent in, 2. all mons via exp share for (i = 0; i < PARTY_SIZE; i++) { - if (gBitTable[i] & sentInBits) + if ((1u << i) & sentInBits) gBattleStruct->expGettersOrder[orderId++] = i; } for (i = 0; i < PARTY_SIZE; i++) { - if (!(gBitTable[i] & sentInBits) && gBitTable[i] & expShareBits) + if (!((1u << i) & sentInBits) && (1u << i) & expShareBits) gBattleStruct->expGettersOrder[orderId++] = i; } if (orderId < PARTY_SIZE) @@ -4330,7 +4330,7 @@ static void Cmd_getexp(void) case 2: // set exp value to the poke in expgetter_id and print message if (gBattleControllerExecFlags == 0) { - bool32 wasSentOut = ((gBattleStruct->expSentInMons & gBitTable[*expMonId]) != 0); + bool32 wasSentOut = (gBattleStruct->expSentInMons & (1u << *expMonId)) != 0; holdEffect = GetMonHoldEffect(&gPlayerParty[*expMonId]); if ((holdEffect != HOLD_EFFECT_EXP_SHARE && !wasSentOut && !IsGen6ExpShareEnabled()) @@ -4404,11 +4404,11 @@ static void Cmd_getexp(void) // get exp getter battler if (IsDoubleBattle()) { - if (gBattlerPartyIndexes[2] == *expMonId && !(gAbsentBattlerFlags & gBitTable[2])) + if (gBattlerPartyIndexes[2] == *expMonId && !(gAbsentBattlerFlags & 4)) gBattleStruct->expGetterBattlerId = 2; else { - if (!(gAbsentBattlerFlags & gBitTable[0])) + if (!(gAbsentBattlerFlags & 1)) gBattleStruct->expGetterBattlerId = 0; else gBattleStruct->expGetterBattlerId = 2; @@ -4474,7 +4474,7 @@ static void Cmd_getexp(void) PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 3, GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL)); BattleScriptPushCursor(); - gLeveledUpInBattle |= gBitTable[*expMonId]; + gLeveledUpInBattle |= 1 << *expMonId; gBattlescriptCurrInstr = BattleScript_LevelUp; gBattleMoveDamage = T1_READ_32(&gBattleResources->bufferB[expBattler][2]); AdjustFriendship(&gPlayerParty[*expMonId], FRIENDSHIP_EVENT_GROW_LEVEL); @@ -4547,7 +4547,7 @@ bool32 NoAliveMonsForPlayer(void) for (i = 0; i < maxI; i++) { if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG) - && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->arenaLostPlayerMons & gBitTable[i]))) + && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->arenaLostPlayerMons & (1u << i)))) { HP_count += GetMonData(&gPlayerParty[i], MON_DATA_HP); } @@ -4565,7 +4565,7 @@ static bool32 NoAliveMonsForOpponent(void) for (i = 0; i < PARTY_SIZE; i++) { if (GetMonData(&gEnemyParty[i], MON_DATA_SPECIES) && !GetMonData(&gEnemyParty[i], MON_DATA_IS_EGG) - && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->arenaLostOpponentMons & gBitTable[i]))) + && (!(gBattleTypeFlags & BATTLE_TYPE_ARENA) || !(gBattleStruct->arenaLostOpponentMons & (1u << i)))) { HP_count += GetMonData(&gEnemyParty[i], MON_DATA_HP); } @@ -5338,7 +5338,7 @@ static bool32 TryKnockOffBattleScript(u32 battlerDef) } else { - gWishFutureKnock.knockedOffMons[side] |= gBitTable[gBattlerPartyIndexes[battlerDef]]; + gWishFutureKnock.knockedOffMons[side] |= 1u << gBattlerPartyIndexes[battlerDef]; } BattleScriptPushCursor(); @@ -5366,7 +5366,7 @@ static u32 GetNextTarget(u32 moveTarget, bool32 excludeCurrent) if (i != gBattlerAttacker && !(excludeCurrent && i == gBattlerTarget) && IsBattlerAlive(i) - && !(gBattleStruct->targetsDone[gBattlerAttacker] & gBitTable[i]) + && !(gBattleStruct->targetsDone[gBattlerAttacker] & (1u << i)) && (GetBattlerSide(i) != GetBattlerSide(gBattlerAttacker) || moveTarget == MOVE_TARGET_FOES_AND_ALLY)) break; } @@ -5816,9 +5816,9 @@ static void Cmd_moveend(void) if ((gMoveResultFlags & (MOVE_RESULT_FAILED | MOVE_RESULT_DOESNT_AFFECT_FOE)) || (gBattleMons[gBattlerAttacker].status2 & (STATUS2_FLINCHED)) || gProtectStructs[gBattlerAttacker].prlzImmobility) - gBattleStruct->lastMoveFailed |= gBitTable[gBattlerAttacker]; + gBattleStruct->lastMoveFailed |= 1u << gBattlerAttacker; else - gBattleStruct->lastMoveFailed &= ~(gBitTable[gBattlerAttacker]); + gBattleStruct->lastMoveFailed &= ~(1u << gBattlerAttacker); // Set ShellTrap to activate after the attacker's turn if target was hit by a physical move. if (gMovesInfo[gChosenMoveByBattler[gBattlerTarget]].effect == EFFECT_SHELL_TRAP @@ -5844,7 +5844,7 @@ static void Cmd_moveend(void) } if (!gSpecialStatuses[gBattlerAttacker].dancerUsedMove) { - gDisableStructs[gBattlerAttacker].usedMoves |= gBitTable[gCurrMovePos]; + gDisableStructs[gBattlerAttacker].usedMoves |= 1u << gCurrMovePos; gBattleStruct->lastMoveTarget[gBattlerAttacker] = gBattlerTarget; if (gHitMarker & HITMARKER_ATTACKSTRING_PRINTED) { @@ -5854,8 +5854,8 @@ static void Cmd_moveend(void) gBattleStruct->dynamax.lastUsedBaseMove = gBattleStruct->dynamax.baseMoves[gBattlerAttacker]; } } - if (!(gAbsentBattlerFlags & gBitTable[gBattlerAttacker]) - && !(gBattleStruct->absentBattlerFlags & gBitTable[gBattlerAttacker]) + if (!(gAbsentBattlerFlags & (1u << gBattlerAttacker)) + && !(gBattleStruct->absentBattlerFlags & (1u << gBattlerAttacker)) && gMovesInfo[originallyUsedMove].effect != EFFECT_BATON_PASS && gMovesInfo[originallyUsedMove].effect != EFFECT_HEALING_WISH) { @@ -5897,8 +5897,8 @@ static void Cmd_moveend(void) gBattleScripting.moveendState++; break; case MOVEEND_MIRROR_MOVE: // mirror move - if (!(gAbsentBattlerFlags & gBitTable[gBattlerAttacker]) - && !(gBattleStruct->absentBattlerFlags & gBitTable[gBattlerAttacker]) + if (!(gAbsentBattlerFlags & (1u << gBattlerAttacker)) + && !(gBattleStruct->absentBattlerFlags & (1u << gBattlerAttacker)) && !gMovesInfo[originallyUsedMove].mirrorMoveBanned && gHitMarker & HITMARKER_OBEYS && gBattlerAttacker != gBattlerTarget @@ -5918,7 +5918,7 @@ static void Cmd_moveend(void) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) gProtectStructs[gBattlerAttacker].targetAffected = TRUE; - gBattleStruct->targetsDone[gBattlerAttacker] |= gBitTable[gBattlerTarget]; + gBattleStruct->targetsDone[gBattlerAttacker] |= 1u << gBattlerTarget; if (!(gHitMarker & HITMARKER_UNABLE_TO_USE_MOVE) && IsDoubleBattle() && !gProtectStructs[gBattlerAttacker].chargingTurn @@ -5949,7 +5949,7 @@ static void Cmd_moveend(void) u8 originalBounceTarget = gBattlerAttacker; gBattleStruct->bouncedMoveIsUsed = FALSE; gBattlerAttacker = gBattleStruct->attackerBeforeBounce; - gBattleStruct->targetsDone[gBattlerAttacker] |= gBitTable[originalBounceTarget]; + gBattleStruct->targetsDone[gBattlerAttacker] |= 1u << originalBounceTarget; gBattleStruct->targetsDone[originalBounceTarget] = 0; nextTarget = GetNextTarget(moveTarget, FALSE); @@ -6052,7 +6052,7 @@ static void Cmd_moveend(void) && TARGET_TURN_DAMAGED && CanStealItem(gBattlerAttacker, gBattlerTarget, gBattleMons[gBattlerTarget].item) && !gSpecialStatuses[gBattlerAttacker].gemBoost // In base game, gems are consumed after magician would activate. - && !(gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerTarget)] & gBitTable[gBattlerPartyIndexes[gBattlerTarget]]) + && !(gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerTarget)] & (1u << gBattlerPartyIndexes[gBattlerTarget])) && !DoesSubstituteBlockMove(gBattlerAttacker, gBattlerTarget, gCurrentMove) && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) && (GetBattlerAbility(gBattlerTarget) != ABILITY_STICKY_HOLD || !IsBattlerAlive(gBattlerTarget))) @@ -6076,9 +6076,9 @@ static void Cmd_moveend(void) u32 holdEffect; holdEffect = GetBattlerHoldEffect(i, TRUE); if (holdEffect == HOLD_EFFECT_EJECT_BUTTON) - ejectButtonBattlers |= gBitTable[i]; + ejectButtonBattlers |= 1u << i; else if (holdEffect == HOLD_EFFECT_EJECT_PACK) - ejectPackBattlers |= gBitTable[i]; + ejectPackBattlers |= 1u << i; } if (ejectButtonBattlers || ejectPackBattlers) { @@ -6089,7 +6089,7 @@ static void Cmd_moveend(void) { u32 battler = battlers[i]; - if (battler != gBattlerAttacker && ejectButtonBattlers & gBitTable[battler]) + if (battler != gBattlerAttacker && ejectButtonBattlers & (1u << battler)) { if (TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)) // Apparently Sheer Force blocks Eject Button, but not Eject Pack continue; @@ -6098,7 +6098,7 @@ static void Cmd_moveend(void) if (!BATTLER_TURN_DAMAGED(battler)) continue; } - else if (ejectPackBattlers & gBitTable[battler]) + else if (ejectPackBattlers & (1u << battler)) { if (!gProtectStructs[battler].statFell || gProtectStructs[battler].disableEjectPack) continue; @@ -6120,7 +6120,7 @@ static void Cmd_moveend(void) gBattlescriptCurrInstr = BattleScript_MoveEnd; // Prevent user switch-in selection effect = TRUE; BattleScriptPushCursor(); - if (ejectButtonBattlers & gBitTable[battler]) + if (ejectButtonBattlers & (1u << battler)) { gBattlescriptCurrInstr = BattleScript_EjectButtonActivates; } @@ -6159,7 +6159,7 @@ static void Cmd_moveend(void) if (i == gBattlerAttacker) continue; if (GetBattlerHoldEffect(i, TRUE) == HOLD_EFFECT_RED_CARD) - redCardBattlers |= gBitTable[i]; + redCardBattlers |= (1u << i); } if (redCardBattlers && (gMovesInfo[gCurrentMove].effect != EFFECT_HIT_SWITCH_TARGET || gBattleStruct->hitSwitchTargetFailed) @@ -6176,7 +6176,7 @@ static void Cmd_moveend(void) u32 battler = battlers[i]; // Search for fastest hit pokemon with a red card // Attacker is the one to be switched out, battler is one with red card - if (redCardBattlers & gBitTable[battler] + if (redCardBattlers & (1u << battler) && IsBattlerAlive(battler) && !DoesSubstituteBlockMove(gBattlerAttacker, battler, gCurrentMove) && BATTLER_TURN_DAMAGED(battler) @@ -6207,7 +6207,7 @@ static void Cmd_moveend(void) case MOVEEND_PICKPOCKET: if (IsBattlerAlive(gBattlerAttacker) && gBattleMons[gBattlerAttacker].item != ITEM_NONE // Attacker must be holding an item - && !(gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerAttacker)] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]) // But not knocked off + && !(gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerAttacker)] & (1u << gBattlerPartyIndexes[gBattlerAttacker])) // But not knocked off && !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)) // Pickpocket doesn't activate for sheer force && IsMoveMakingContact(gCurrentMove, gBattlerAttacker) // Pickpocket requires contact && !(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)) // Obviously attack needs to have worked @@ -6451,7 +6451,7 @@ static void Cmd_getswitchedmondata(void) gBattlerPartyIndexes[battler] = gBattleStruct->monToSwitchIntoId[battler]; - BtlController_EmitGetMonData(battler, BUFFER_A, REQUEST_ALL_BATTLE, gBitTable[gBattlerPartyIndexes[battler]]); + BtlController_EmitGetMonData(battler, BUFFER_A, REQUEST_ALL_BATTLE, 1u << gBattlerPartyIndexes[battler]); MarkBattlerForControllerExec(battler); gBattlescriptCurrInstr = cmd->nextInstr; @@ -6497,7 +6497,7 @@ static void Cmd_switchindataupdate(void) if (i != PARTY_SIZE) { gBattlerPartyIndexes[battler] = gBattleStruct->monToSwitchIntoId[battler] = i; - BtlController_EmitGetMonData(battler, BUFFER_A, REQUEST_ALL_BATTLE, gBitTable[gBattlerPartyIndexes[battler]]); + BtlController_EmitGetMonData(battler, BUFFER_A, REQUEST_ALL_BATTLE, 1u << gBattlerPartyIndexes[battler]); MarkBattlerForControllerExec(battler); return; } @@ -6520,7 +6520,7 @@ static void Cmd_switchindataupdate(void) // check knocked off item i = GetBattlerSide(battler); - if (gWishFutureKnock.knockedOffMons[i] & gBitTable[gBattlerPartyIndexes[battler]]) + if (gWishFutureKnock.knockedOffMons[i] & (1u << gBattlerPartyIndexes[battler])) { gBattleMons[battler].item = ITEM_NONE; } @@ -6541,7 +6541,7 @@ static void Cmd_switchindataupdate(void) && IsBattlerAlive(battler) && !(gBattleMons[battler].status1 & STATUS1_SLEEP)) { - gBattleStruct->palaceFlags |= gBitTable[battler]; + gBattleStruct->palaceFlags |= 1u << battler; } gBattleScripting.battler = battler; @@ -6570,7 +6570,7 @@ static void Cmd_switchinanim(void) | BATTLE_TYPE_FRONTIER))) HandleSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[battler].species), FLAG_SET_SEEN, gBattleMons[battler].personality); - gAbsentBattlerFlags &= ~(gBitTable[battler]); + gAbsentBattlerFlags &= ~(1u << battler); BtlController_EmitSwitchInAnim(battler, BUFFER_A, gBattlerPartyIndexes[battler], cmd->dontClearSubstitute); MarkBattlerForControllerExec(battler); @@ -6749,7 +6749,7 @@ static void ChooseMonToSendOut(u32 battler, u8 slotId) { gBattleStruct->battlerPartyIndexes[battler] = gBattlerPartyIndexes[battler]; gBattleStruct->monToSwitchIntoId[battler] = PARTY_SIZE; - gBattleStruct->field_93 &= ~(gBitTable[battler]); + gBattleStruct->field_93 &= ~(1u << battler); BtlController_EmitChoosePokemon(battler, BUFFER_A, PARTY_ACTION_SEND_OUT, slotId, ABILITY_NONE, gBattleStruct->battlerPartyOrders[battler]); MarkBattlerForControllerExec(battler); @@ -6774,7 +6774,7 @@ static void Cmd_openpartyscreen(void) { if (HasNoMonsToSwitch(battler, PARTY_SIZE, PARTY_SIZE)) { - gAbsentBattlerFlags |= gBitTable[battler]; + gAbsentBattlerFlags |= 1u << battler; gHitMarker &= ~HITMARKER_FAINTED(battler); BtlController_EmitLinkStandbyMsg(battler, BUFFER_A, LINK_STANDBY_MSG_ONLY, FALSE); MarkBattlerForControllerExec(battler); @@ -6798,12 +6798,12 @@ static void Cmd_openpartyscreen(void) hitmarkerFaintBits = gHitMarker >> 28; - if (gBitTable[0] & hitmarkerFaintBits) + if (1u & hitmarkerFaintBits) { battler = 0; if (HasNoMonsToSwitch(battler, PARTY_SIZE, PARTY_SIZE)) { - gAbsentBattlerFlags |= gBitTable[battler]; + gAbsentBattlerFlags |= 1u << battler; gHitMarker &= ~HITMARKER_FAINTED(battler); BtlController_EmitCantSwitch(battler, BUFFER_A); MarkBattlerForControllerExec(battler); @@ -6820,12 +6820,12 @@ static void Cmd_openpartyscreen(void) flags |= 1; } } - if (gBitTable[2] & hitmarkerFaintBits && !(gBitTable[0] & hitmarkerFaintBits)) + if (4u & hitmarkerFaintBits && !(1u & hitmarkerFaintBits)) { battler = 2; if (HasNoMonsToSwitch(battler, PARTY_SIZE, PARTY_SIZE)) { - gAbsentBattlerFlags |= gBitTable[battler]; + gAbsentBattlerFlags |= 1u << battler; gHitMarker &= ~HITMARKER_FAINTED(battler); BtlController_EmitCantSwitch(battler, BUFFER_A); MarkBattlerForControllerExec(battler); @@ -6841,12 +6841,12 @@ static void Cmd_openpartyscreen(void) MarkBattlerForControllerExec(battler); } } - if (gBitTable[1] & hitmarkerFaintBits) + if (2 & hitmarkerFaintBits) { battler = 1; if (HasNoMonsToSwitch(battler, PARTY_SIZE, PARTY_SIZE)) { - gAbsentBattlerFlags |= gBitTable[battler]; + gAbsentBattlerFlags |= 1u << battler; gHitMarker &= ~HITMARKER_FAINTED(battler); BtlController_EmitCantSwitch(battler, BUFFER_A); MarkBattlerForControllerExec(battler); @@ -6863,12 +6863,12 @@ static void Cmd_openpartyscreen(void) flags |= 2; } } - if (gBitTable[3] & hitmarkerFaintBits && !(gBitTable[1] & hitmarkerFaintBits)) + if (8 & hitmarkerFaintBits && !(2 & hitmarkerFaintBits)) { battler = 3; if (HasNoMonsToSwitch(battler, PARTY_SIZE, PARTY_SIZE)) { - gAbsentBattlerFlags |= gBitTable[battler]; + gAbsentBattlerFlags |= 1u << battler; gHitMarker &= ~HITMARKER_FAINTED(battler); BtlController_EmitCantSwitch(battler, BUFFER_A); MarkBattlerForControllerExec(battler); @@ -6891,7 +6891,7 @@ static void Cmd_openpartyscreen(void) hasReplacement_2 = gSpecialStatuses[2].faintedHasReplacement; if (!hasReplacement_2 && hitmarkerFaintBits != 0) { - if (gAbsentBattlerFlags & gBitTable[0]) + if (gAbsentBattlerFlags & 1) battler = 2; else battler = 0; @@ -6907,7 +6907,7 @@ static void Cmd_openpartyscreen(void) hasReplacement_3 = gSpecialStatuses[3].faintedHasReplacement; if (!hasReplacement_3 && hitmarkerFaintBits != 0) { - if (gAbsentBattlerFlags & gBitTable[1]) + if (gAbsentBattlerFlags & 2) battler = 3; else battler = 1; @@ -6926,12 +6926,12 @@ static void Cmd_openpartyscreen(void) if (IsDoubleBattle()) { hitmarkerFaintBits = gHitMarker >> 28; - if (gBitTable[2] & hitmarkerFaintBits && gBitTable[0] & hitmarkerFaintBits) + if (4 & hitmarkerFaintBits && 1 & hitmarkerFaintBits) { battler = 2; if (HasNoMonsToSwitch(battler, gBattleResources->bufferB[0][1], PARTY_SIZE)) { - gAbsentBattlerFlags |= gBitTable[battler]; + gAbsentBattlerFlags |= 1u << battler; gHitMarker &= ~HITMARKER_FAINTED(battler); BtlController_EmitCantSwitch(battler, BUFFER_A); MarkBattlerForControllerExec(battler); @@ -6942,12 +6942,12 @@ static void Cmd_openpartyscreen(void) gSpecialStatuses[battler].faintedHasReplacement = TRUE; } } - if (gBitTable[3] & hitmarkerFaintBits && hitmarkerFaintBits & gBitTable[1]) + if (8u & hitmarkerFaintBits && hitmarkerFaintBits & 2u) { battler = 3; if (HasNoMonsToSwitch(battler, gBattleResources->bufferB[1][1], PARTY_SIZE)) { - gAbsentBattlerFlags |= gBitTable[battler]; + gAbsentBattlerFlags |= 1u << battler; gHitMarker &= ~HITMARKER_FAINTED(battler); BtlController_EmitCantSwitch(battler, BUFFER_A); MarkBattlerForControllerExec(battler); @@ -6975,7 +6975,7 @@ static void Cmd_openpartyscreen(void) hitmarkerFaintBits = gHitMarker >> 28; gBattlerFainted = 0; - while (!(gBitTable[gBattlerFainted] & hitmarkerFaintBits) + while (!((1u << gBattlerFainted) & hitmarkerFaintBits) && gBattlerFainted < gBattlersCount) gBattlerFainted++; @@ -6996,7 +6996,7 @@ static void Cmd_openpartyscreen(void) } else if (HasNoMonsToSwitch(battler, PARTY_SIZE, PARTY_SIZE)) { - gAbsentBattlerFlags |= gBitTable[battler]; + gAbsentBattlerFlags |= 1u << battler; gHitMarker &= ~HITMARKER_FAINTED(battler); gBattlescriptCurrInstr = failInstr; } @@ -7004,7 +7004,7 @@ static void Cmd_openpartyscreen(void) { *(gBattleStruct->battlerPartyIndexes + battler) = gBattlerPartyIndexes[battler]; *(gBattleStruct->monToSwitchIntoId + battler) = PARTY_SIZE; - gBattleStruct->field_93 &= ~(gBitTable[battler]); + gBattleStruct->field_93 &= ~(1u << battler); BtlController_EmitChoosePokemon(battler, BUFFER_A, hitmarkerFaintBits, *(gBattleStruct->monToSwitchIntoId + BATTLE_PARTNER(battler)), ABILITY_NONE, gBattleStruct->battlerPartyOrders[battler]); MarkBattlerForControllerExec(battler); @@ -7028,7 +7028,7 @@ static void Cmd_openpartyscreen(void) else { u32 battlerOpposite = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerPosition(battler))); - if (gAbsentBattlerFlags & gBitTable[battlerOpposite]) + if (gAbsentBattlerFlags & (1u << battlerOpposite)) battlerOpposite ^= BIT_FLANK; // Make sure we're checking a valid battler. In edge case scenarios - battler could be absent and battlerOpposite would become a non-existent one softlocking the game. @@ -7060,10 +7060,10 @@ static void Cmd_switchhandleorder(void) if (gBattleResources->bufferB[i][0] == CONTROLLER_CHOSENMONRETURNVALUE) { *(gBattleStruct->monToSwitchIntoId + i) = gBattleResources->bufferB[i][1]; - if (!(gBattleStruct->field_93 & gBitTable[i])) + if (!(gBattleStruct->field_93 & (1u << i))) { RecordedBattle_SetBattlerAction(i, gBattleResources->bufferB[i][1]); - gBattleStruct->field_93 |= gBitTable[i]; + gBattleStruct->field_93 |= 1u << i; } } } @@ -7073,10 +7073,10 @@ static void Cmd_switchhandleorder(void) SwitchPartyOrder(battler); break; case 2: - if (!(gBattleStruct->field_93 & gBitTable[battler])) + if (!(gBattleStruct->field_93 & (1u << battler))) { RecordedBattle_SetBattlerAction(battler, gBattleResources->bufferB[battler][1]); - gBattleStruct->field_93 |= gBitTable[battler]; + gBattleStruct->field_93 |= 1u << battler; } // fall through case 3: @@ -7144,7 +7144,7 @@ static void UpdateSentMonFlags(u32 battler) gSpecialStatuses[battler].faintedHasReplacement = FALSE; if (!BattlerHasAi(battler)) - gBattleStruct->appearedInBattle |= gBitTable[gBattlerPartyIndexes[battler]]; + gBattleStruct->appearedInBattle |= 1u << gBattlerPartyIndexes[battler]; } static bool32 DoSwitchInEffectsForBattler(u32 battler) @@ -7161,20 +7161,20 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler) } // Healing Wish activates before hazards. // Starting from Gen8 - it heals only pokemon which can be healed. In gens 5,6,7 the effect activates anyways. - else if (((gBattleStruct->storedHealingWish & gBitTable[battler]) || (gBattleStruct->storedLunarDance & gBitTable[battler])) + else if (((gBattleStruct->storedHealingWish & (1u << battler)) || (gBattleStruct->storedLunarDance & (1u << battler))) && (gBattleMons[battler].hp != gBattleMons[battler].maxHP || gBattleMons[battler].status1 != 0 || B_HEALING_WISH_SWITCH < GEN_8)) { - if (gBattleStruct->storedHealingWish & gBitTable[battler]) + if (gBattleStruct->storedHealingWish & (1u << battler)) { BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_HealingWishActivates; - gBattleStruct->storedHealingWish &= ~(gBitTable[battler]); + gBattleStruct->storedHealingWish &= ~(1u << battler); } else // Lunar Dance { BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_LunarDanceActivates; - gBattleStruct->storedLunarDance &= ~(gBitTable[battler]); + gBattleStruct->storedLunarDance &= ~(1u << battler); } } else if (!(gDisableStructs[battler].spikesDone) @@ -7308,7 +7308,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler) gBattleStruct->hpOnSwitchout[GetBattlerSide(i)] = gBattleMons[i].hp; } - gBattleStruct->forcedSwitch &= ~(gBitTable[battler]); + gBattleStruct->forcedSwitch &= ~(1u << battler); return FALSE; } @@ -7324,7 +7324,7 @@ static void Cmd_switchineffects(void) { // Multiple mons fainted and are being switched-in. Their abilities/hazards will play according to speed ties. case BS_FAINTED_MULTIPLE_1: // Saves the battlers. - gBattleStruct->multipleSwitchInBattlers |= gBitTable[battler]; + gBattleStruct->multipleSwitchInBattlers |= 1 << battler; UpdateSentMonFlags(battler); // Increment fainted battler. @@ -7333,7 +7333,7 @@ static void Cmd_switchineffects(void) gBattlerFainted++; if (gBattlerFainted >= gBattlersCount) break; - if (gHitMarker & HITMARKER_FAINTED(gBattlerFainted) && !(gAbsentBattlerFlags & gBitTable[gBattlerFainted])) + if (gHitMarker & HITMARKER_FAINTED(gBattlerFainted) && !(gAbsentBattlerFlags & (1u << gBattlerFainted))) break; } while (1); @@ -7353,7 +7353,7 @@ static void Cmd_switchineffects(void) for (; gBattleStruct->multipleSwitchInCursor < gBattlersCount; gBattleStruct->multipleSwitchInCursor++) { gBattlerFainted = gBattleStruct->multipleSwitchInSortedBattlers[gBattleStruct->multipleSwitchInCursor]; - if (gBattleStruct->multipleSwitchInBattlers & gBitTable[gBattlerFainted]) + if (gBattleStruct->multipleSwitchInBattlers & (1 << (gBattlerFainted))) { if (DoSwitchInEffectsForBattler(gBattlerFainted)) return; @@ -7982,7 +7982,7 @@ static bool32 TryCheekPouch(u32 battler, u32 itemId) if (ItemId_GetPocket(itemId) == POCKET_BERRIES && GetBattlerAbility(battler) == ABILITY_CHEEK_POUCH && !(gStatuses3[battler] & STATUS3_HEAL_BLOCK) - && gBattleStruct->ateBerry[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]] + && gBattleStruct->ateBerry[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler]) && !BATTLER_MAX_HP(battler)) { gBattleMoveDamage = GetNonDynamaxMaxHP(battler) / 3; @@ -8515,7 +8515,7 @@ bool32 CanUseLastResort(u8 battler) { if (gBattleMons[battler].moves[i] != MOVE_NONE) knownMovesCount++; - if (i != gCurrMovePos && gDisableStructs[battler].usedMoves & gBitTable[i]) // Increment used move count for all moves except current Last Resort. + if (i != gCurrMovePos && gDisableStructs[battler].usedMoves & (1u << i)) // Increment used move count for all moves except current Last Resort. usedMovesCount++; } @@ -8847,7 +8847,7 @@ static void HandleScriptMegaPrimalBurst(u32 caseId, u32 battler, u32 type) PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[battler].species); - BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_SPECIES_BATTLE, gBitTable[gBattlerPartyIndexes[battler]], sizeof(gBattleMons[battler].species), &gBattleMons[battler].species); + BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_SPECIES_BATTLE, 1u << gBattlerPartyIndexes[battler], sizeof(gBattleMons[battler].species), &gBattleMons[battler].species); MarkBattlerForControllerExec(battler); } // Update healthbox and elevation and play cry. @@ -9165,9 +9165,9 @@ static void Cmd_various(void) // Raise stats for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) { - if (gBattleStruct->stolenStats[0] & gBitTable[i]) + if (gBattleStruct->stolenStats[0] & (1u << i)) { - gBattleStruct->stolenStats[0] &= ~(gBitTable[i]); + gBattleStruct->stolenStats[0] &= ~(1u << i); SET_STATCHANGER(i, gBattleStruct->stolenStats[i], FALSE); if (ChangeStatBuffs(GET_STAT_BUFF_VALUE_WITH_SIGN(gBattleScripting.statChanger), i, MOVE_EFFECT_CERTAIN | MOVE_EFFECT_AFFECTS_USER, NULL) == STAT_CHANGE_WORKED) { @@ -9192,7 +9192,7 @@ static void Cmd_various(void) for (i = STAT_ATK; i < NUM_BATTLE_STATS; i++) { if (CompareStat(battler, i, MAX_STAT_STAGE, CMP_LESS_THAN)) - bits |= gBitTable[i]; + bits |= 1u << i; } if (bits) { @@ -9200,7 +9200,7 @@ static void Cmd_various(void) do { statId = (Random() % (NUM_BATTLE_STATS - 1)) + 1; - } while (!(bits & gBitTable[statId])); + } while (!(bits & (1u << statId))); SET_STATCHANGER(statId, 2, FALSE); gBattlescriptCurrInstr = cmd->nextInstr; @@ -9300,12 +9300,12 @@ static void Cmd_various(void) // Try and print end-of-turn Battle Palace flavor text (e.g. "A glint appears in mon's eyes") gBattleCommunication[0] = FALSE; // whether or not msg should be printed gBattleScripting.battler = battler = gBattleCommunication[1]; - if (!(gBattleStruct->palaceFlags & gBitTable[battler]) + if (!(gBattleStruct->palaceFlags & (1u << battler)) && gBattleMons[battler].maxHP / 2 >= gBattleMons[battler].hp && IsBattlerAlive(battler) && !(gBattleMons[battler].status1 & STATUS1_SLEEP)) { - gBattleStruct->palaceFlags |= gBitTable[battler]; + gBattleStruct->palaceFlags |= 1u << battler; gBattleCommunication[0] = TRUE; gBattleCommunication[MULTISTRING_CHOOSER] = gNaturesInfo[GetNatureFromPersonality(gBattleMons[battler].personality)].battlePalaceFlavorText; } @@ -9330,7 +9330,7 @@ static void Cmd_various(void) VARIOUS_ARGS(); gBattleMons[1].hp = 0; gHitMarker |= HITMARKER_FAINTED(1); - gBattleStruct->arenaLostOpponentMons |= gBitTable[gBattlerPartyIndexes[1]]; + gBattleStruct->arenaLostOpponentMons |= 1u << gBattlerPartyIndexes[1]; gDisableStructs[1].truantSwitchInHack = 1; break; } @@ -9340,7 +9340,7 @@ static void Cmd_various(void) gBattleMons[0].hp = 0; gHitMarker |= HITMARKER_FAINTED(0); gHitMarker |= HITMARKER_PLAYER_FAINTED; - gBattleStruct->arenaLostPlayerMons |= gBitTable[gBattlerPartyIndexes[0]]; + gBattleStruct->arenaLostPlayerMons |= 1u << gBattlerPartyIndexes[0]; gDisableStructs[0].truantSwitchInHack = 1; break; } @@ -9352,8 +9352,8 @@ static void Cmd_various(void) gHitMarker |= HITMARKER_FAINTED(0); gHitMarker |= HITMARKER_FAINTED(1); gHitMarker |= HITMARKER_PLAYER_FAINTED; - gBattleStruct->arenaLostPlayerMons |= gBitTable[gBattlerPartyIndexes[0]]; - gBattleStruct->arenaLostOpponentMons |= gBitTable[gBattlerPartyIndexes[1]]; + gBattleStruct->arenaLostPlayerMons |= 1u << gBattlerPartyIndexes[0]; + gBattleStruct->arenaLostOpponentMons |= 1u << gBattlerPartyIndexes[1]; gDisableStructs[0].truantSwitchInHack = 1; gDisableStructs[1].truantSwitchInHack = 1; break; @@ -9438,7 +9438,7 @@ static void Cmd_various(void) case VARIOUS_SET_ALREADY_STATUS_MOVE_ATTEMPT: { VARIOUS_ARGS(); - gBattleStruct->alreadyStatusedMoveAttempt |= gBitTable[battler]; + gBattleStruct->alreadyStatusedMoveAttempt |= 1u << battler; break; } case VARIOUS_PALACE_TRY_ESCAPE_STATUS: @@ -9455,7 +9455,7 @@ static void Cmd_various(void) // and its partner is still alive. if (GetBattlerSide(battler) == B_SIDE_OPPONENT && IsBattlerAlive(BATTLE_PARTNER(battler))) { - gAbsentBattlerFlags |= gBitTable[battler]; + gAbsentBattlerFlags |= 1u << battler; gHitMarker |= HITMARKER_FAINTED(battler); gBattleMons[battler].hp = 0; SetMonData(&gEnemyParty[gBattlerPartyIndexes[battler]], MON_DATA_HP, &gBattleMons[battler].hp); @@ -9830,7 +9830,7 @@ static void Cmd_various(void) if (!gBattleTextBuff1) PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[battler].species); */ - BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_SPECIES_BATTLE, gBitTable[gBattlerPartyIndexes[battler]], sizeof(gBattleMons[battler].species), &gBattleMons[battler].species); + BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_SPECIES_BATTLE, 1u << gBattlerPartyIndexes[battler], sizeof(gBattleMons[battler].species), &gBattleMons[battler].species); MarkBattlerForControllerExec(battler); } // Change stats. @@ -10034,7 +10034,7 @@ static void Cmd_various(void) || gBattleMons[gBattlerTarget].item != ITEM_NONE || !CanBattlerGetOrLoseItem(gBattlerAttacker, gBattleMons[gBattlerAttacker].item) || !CanBattlerGetOrLoseItem(gBattlerTarget, gBattleMons[gBattlerAttacker].item) - || gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerTarget)] & gBitTable[gBattlerPartyIndexes[gBattlerTarget]]) + || gWishFutureKnock.knockedOffMons[GetBattlerSide(gBattlerTarget)] & (1u << gBattlerPartyIndexes[gBattlerTarget])) { gBattlescriptCurrInstr = cmd->failInstr; } @@ -10279,7 +10279,7 @@ static void Cmd_various(void) ConvertIntToDecimalStringN(gBattleTextBuff2, ppToDeduct, STR_CONV_MODE_LEFT_ALIGN, 1); PREPARE_BYTE_NUMBER_BUFFER(gBattleTextBuff2, 1, ppToDeduct) gBattleMons[battler].pp[i] -= ppToDeduct; - if (!(gDisableStructs[battler].mimickedMoves & gBitTable[i]) + if (!(gDisableStructs[battler].mimickedMoves & (1u << i)) && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)) { BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[battler].pp[i]), &gBattleMons[battler].pp[i]); @@ -10518,9 +10518,9 @@ static void Cmd_various(void) if (gBattleMons[gBattlerAttacker].species == SPECIES_GRENINJA_BATTLE_BOND && HasAttackerFaintedTarget() && CalculateBattlerPartyCount(gBattlerTarget) > 1 - && !(gBattleStruct->battleBondTransformed[GetBattlerSide(gBattlerAttacker)] & gBitTable[gBattlerPartyIndexes[gBattlerAttacker]])) + && !(gBattleStruct->battleBondTransformed[GetBattlerSide(gBattlerAttacker)] & (1u << gBattlerPartyIndexes[gBattlerAttacker]))) { - gBattleStruct->battleBondTransformed[GetBattlerSide(gBattlerAttacker)] |= gBitTable[gBattlerPartyIndexes[gBattlerAttacker]]; + gBattleStruct->battleBondTransformed[GetBattlerSide(gBattlerAttacker)] |= 1u << gBattlerPartyIndexes[gBattlerAttacker]; PREPARE_SPECIES_BUFFER(gBattleTextBuff1, gBattleMons[gBattlerAttacker].species); gBattleStruct->changedSpecies[GetBattlerSide(gBattlerAttacker)][gBattlerPartyIndexes[gBattlerAttacker]] = gBattleMons[gBattlerAttacker].species; gBattleMons[gBattlerAttacker].species = SPECIES_GRENINJA_ASH; @@ -10542,7 +10542,7 @@ static void Cmd_various(void) if (cmd->fromBattler) gLastUsedItem = gBattleMons[battler].item; - gBattleStruct->ateBerry[battler & BIT_SIDE] |= gBitTable[gBattlerPartyIndexes[battler]]; + gBattleStruct->ateBerry[battler & BIT_SIDE] |= 1u << gBattlerPartyIndexes[battler]; gBattleScripting.battler = gEffectBattler = gBattlerTarget = battler; // Cover all berry effect battler cases. e.g. ChangeStatBuffs uses target ID if (ItemBattleEffects(ITEMEFFECT_USE_LAST_ITEM, battler, FALSE)) return; @@ -10882,9 +10882,9 @@ static void Cmd_various(void) { VARIOUS_ARGS(); if (gCurrentMove == MOVE_LUNAR_DANCE) - gBattleStruct->storedLunarDance |= gBitTable[battler]; + gBattleStruct->storedLunarDance |= 1u << battler; else - gBattleStruct->storedHealingWish |= gBitTable[battler]; + gBattleStruct->storedHealingWish |= 1u << battler; break; } case VARIOUS_HIT_SWITCH_TARGET_FAILED: @@ -10913,7 +10913,7 @@ static void Cmd_various(void) struct Pokemon *party = GetSideParty(side); u16 hp = GetMonData(&party[gSelectedMonPartyId], MON_DATA_MAX_HP) / 2; - BtlController_EmitSetMonData(gBattlerAttacker, BUFFER_A, REQUEST_HP_BATTLE, gBitTable[gSelectedMonPartyId], sizeof(hp), &hp); + BtlController_EmitSetMonData(gBattlerAttacker, BUFFER_A, REQUEST_HP_BATTLE, 1u << gSelectedMonPartyId, sizeof(hp), &hp); MarkBattlerForControllerExec(gBattlerAttacker); PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gSelectedMonPartyId], MON_DATA_SPECIES)); @@ -12136,7 +12136,7 @@ static void Cmd_forcerandomswitch(void) { *(gBattleStruct->battlerPartyIndexes + gBattlerTarget) = gBattlerPartyIndexes[gBattlerTarget]; gBattlescriptCurrInstr = BattleScript_RoarSuccessSwitch; - gBattleStruct->forcedSwitch |= gBitTable[gBattlerTarget]; + gBattleStruct->forcedSwitch |= 1u << gBattlerTarget; *(gBattleStruct->monToSwitchIntoId + gBattlerTarget) = validMons[RandomUniform(RNG_FORCE_RANDOM_SWITCH, 0, validMonsCount - 1)]; if (!IsMultiBattle()) @@ -12464,7 +12464,7 @@ static void Cmd_updatestatusicon(void) else { battler = gBattlerAttacker; - if (!(gAbsentBattlerFlags & gBitTable[battler])) + if (!(gAbsentBattlerFlags & (1u << battler))) { BtlController_EmitStatusIconUpdate(battler, BUFFER_A, gBattleMons[battler].status1, gBattleMons[battler].status2); MarkBattlerForControllerExec(battler); @@ -12472,7 +12472,7 @@ static void Cmd_updatestatusicon(void) if ((IsDoubleBattle())) { battler = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker))); - if (!(gAbsentBattlerFlags & gBitTable[battler])) + if (!(gAbsentBattlerFlags & (1u << battler))) { BtlController_EmitStatusIconUpdate(battler, BUFFER_A, gBattleMons[battler].status1, gBattleMons[battler].status2); MarkBattlerForControllerExec(battler); @@ -12506,8 +12506,8 @@ static void Cmd_setfocusenergy(void) CMD_ARGS(u8 battler); u8 battler = GetBattlerForBattleScript(cmd->battler); - if ((gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && (!(IsDoubleBattle()) || (gAbsentBattlerFlags & gBitTable[battler]))) - || gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY) + if ((gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_CHEER && (!(IsDoubleBattle()) || (gAbsentBattlerFlags & (1u << battler)))) + || gBattleMons[battler].status2 & STATUS2_FOCUS_ENERGY_ANY) { gMoveResultFlags |= MOVE_RESULT_FAILED; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FOCUS_ENERGY_FAILED; @@ -12650,7 +12650,7 @@ static void Cmd_mimicattackcopy(void) PREPARE_MOVE_BUFFER(gBattleTextBuff1, gLastMoves[gBattlerTarget]) - gDisableStructs[gBattlerAttacker].mimickedMoves |= gBitTable[gCurrMovePos]; + gDisableStructs[gBattlerAttacker].mimickedMoves |= 1u << gCurrMovePos; gBattlescriptCurrInstr = cmd->nextInstr; } else @@ -12906,7 +12906,7 @@ static void Cmd_settypetorandomresistance(void) { case UQ_4_12(0): case UQ_4_12(0.5): - resistTypes |= gBitTable[i]; + resistTypes |= 1u << i; break; } } @@ -12914,11 +12914,11 @@ static void Cmd_settypetorandomresistance(void) while (resistTypes != 0) { i = Random() % NUMBER_OF_MON_TYPES; - if (resistTypes & gBitTable[i]) + if (resistTypes & (1u << i)) { if (IS_BATTLER_OF_TYPE(gBattlerAttacker, i)) { - resistTypes &= ~(gBitTable[i]); // Type resists, but the user is already of this type. + resistTypes &= ~(1u << i); // Type resists, but the user is already of this type. } else { @@ -13008,7 +13008,7 @@ static void Cmd_trychoosesleeptalkmove(void) if (gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].sleepTalkBanned || gBattleMoveEffects[gMovesInfo[gBattleMons[gBattlerAttacker].moves[i]].effect].twoTurnEffect) { - unusableMovesBits |= gBitTable[i]; + unusableMovesBits |= (1 << (i)); } } @@ -13020,11 +13020,11 @@ static void Cmd_trychoosesleeptalkmove(void) else // at least one move can be chosen { // Set Sleep Talk as used move, so it works with Last Resort. - gDisableStructs[gBattlerAttacker].usedMoves |= gBitTable[gCurrMovePos]; + gDisableStructs[gBattlerAttacker].usedMoves |= 1u << gCurrMovePos; do { movePosition = MOD(Random(), MAX_MON_MOVES); - } while ((gBitTable[movePosition] & unusableMovesBits)); + } while ((1u << movePosition) & unusableMovesBits); if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE && !IS_MOVE_STATUS(gBattleMons[gBattlerAttacker].moves[movePosition])) { @@ -13135,7 +13135,7 @@ static void Cmd_tryspiteppreduce(void) gBattleMons[gBattlerTarget].pp[i] -= ppToDeduct; // if (MOVE_IS_PERMANENT(gBattlerTarget, i)), but backwards - if (!(gDisableStructs[gBattlerTarget].mimickedMoves & gBitTable[i]) + if (!(gDisableStructs[gBattlerTarget].mimickedMoves & (1u << i)) && !(gBattleMons[gBattlerTarget].status2 & STATUS2_TRANSFORMED)) { BtlController_EmitSetMonData(gBattlerTarget, BUFFER_A, REQUEST_PPMOVE1_BATTLE + i, 0, sizeof(gBattleMons[gBattlerTarget].pp[i]), &gBattleMons[gBattlerTarget].pp[i]); @@ -13250,7 +13250,7 @@ static void Cmd_healpartystatus(void) gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; if (IsDoubleBattle() - && !(gAbsentBattlerFlags & gBitTable[partner])) + && !(gAbsentBattlerFlags & (1u <failInstr; } @@ -14619,7 +14619,7 @@ static void Cmd_switchoutabilities(void) case ABILITY_NATURAL_CURE: gBattleMons[battler].status1 = 0; BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_STATUS_BATTLE, - gBitTable[*(gBattleStruct->battlerPartyIndexes + battler)], + 1u << *(gBattleStruct->battlerPartyIndexes + battler), sizeof(gBattleMons[battler].status1), &gBattleMons[battler].status1); MarkBattlerForControllerExec(battler); @@ -14630,7 +14630,7 @@ static void Cmd_switchoutabilities(void) if (gBattleMoveDamage > gBattleMons[battler].maxHP) gBattleMoveDamage = gBattleMons[battler].maxHP; BtlController_EmitSetMonData(battler, BUFFER_A, REQUEST_HP_BATTLE, - gBitTable[*(gBattleStruct->battlerPartyIndexes + battler)], + 1u << *(gBattleStruct->battlerPartyIndexes + battler), sizeof(gBattleMoveDamage), &gBattleMoveDamage); MarkBattlerForControllerExec(battler); @@ -14915,7 +14915,7 @@ static void Cmd_pursuitdoubles(void) u32 battler = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerAttacker))); if (IsDoubleBattle() - && !(gAbsentBattlerFlags & gBitTable[battler]) + && !(gAbsentBattlerFlags & (1u << battler)) && gChosenActionByBattler[battler] == B_ACTION_USE_MOVE && gMovesInfo[gChosenMoveByBattler[battler]].effect == EFFECT_PURSUIT) { @@ -16206,7 +16206,7 @@ void BS_ItemRestoreHP(void) // Revived battlers on the field need to be brought back. if (IsDoubleBattle() && battler != MAX_BATTLERS_COUNT) { - gAbsentBattlerFlags &= ~gBitTable[battler]; + gAbsentBattlerFlags &= ~(1u << battler); gBattleMons[battler].hp = hp; gBattleCommunication[MULTIUSE_STATE] = TRUE; } diff --git a/src/battle_terastal.c b/src/battle_terastal.c index f687150d39..2c140414db 100644 --- a/src/battle_terastal.c +++ b/src/battle_terastal.c @@ -114,14 +114,14 @@ u32 GetBattlerTeraType(u32 battler) void ExpendTypeStellarBoost(u32 battler, u32 type) { if (type < 32 && gBattleMons[battler].species != SPECIES_TERAPAGOS_STELLAR) // avoid OOB access - gBattleStruct->stellarBoostFlags[GetBattlerSide(battler)] |= gBitTable[type]; + gBattleStruct->stellarBoostFlags[GetBattlerSide(battler)] |= 1u << type; } // Checks whether a type's Stellar boost has been expended. bool32 IsTypeStellarBoosted(u32 battler, u32 type) { if (type < 32) // avoid OOB access - return !(gBattleStruct->stellarBoostFlags[GetBattlerSide(battler)] & gBitTable[type]); + return !(gBattleStruct->stellarBoostFlags[GetBattlerSide(battler)] & (1u << type)); else return FALSE; } diff --git a/src/battle_util.c b/src/battle_util.c index b16a33764b..7187c7cde8 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -130,7 +130,7 @@ void HandleAction_UseMove(void) u16 moveTarget; gBattlerAttacker = gBattlerByTurnOrder[gCurrentTurnActionNumber]; - if (gBattleStruct->absentBattlerFlags & gBitTable[gBattlerAttacker] || !IsBattlerAlive(gBattlerAttacker)) + if (gBattleStruct->absentBattlerFlags & (1u << gBattlerAttacker) || !IsBattlerAlive(gBattlerAttacker)) { gCurrentActionFuncId = B_ACTION_FINISHED; return; @@ -322,7 +322,7 @@ void HandleAction_UseMove(void) gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); } - if (gAbsentBattlerFlags & gBitTable[gBattlerTarget] + if (gAbsentBattlerFlags & (1u << gBattlerTarget) && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) { gBattlerTarget = GetBattlerAtPosition(BATTLE_PARTNER(GetBattlerPosition(gBattlerTarget))); @@ -964,29 +964,29 @@ static void UNUSED MarkAllBattlersForControllerExec(void) if (gBattleTypeFlags & BATTLE_TYPE_LINK) { for (i = 0; i < gBattlersCount; i++) - gBattleControllerExecFlags |= gBitTable[i] << (32 - MAX_BATTLERS_COUNT); + gBattleControllerExecFlags |= 1u << (i + 32 - MAX_BATTLERS_COUNT); } else { for (i = 0; i < gBattlersCount; i++) - gBattleControllerExecFlags |= gBitTable[i]; + gBattleControllerExecFlags |= 1 << i; } } bool32 IsBattlerMarkedForControllerExec(u32 battler) { if (gBattleTypeFlags & BATTLE_TYPE_LINK) - return (gBattleControllerExecFlags & (gBitTable[battler] << 0x1C)) != 0; + return (gBattleControllerExecFlags & (1 << (battler + 28))) != 0; else - return (gBattleControllerExecFlags & (gBitTable[battler])) != 0; + return (gBattleControllerExecFlags & (1 << battler)) != 0; } void MarkBattlerForControllerExec(u32 battler) { if (gBattleTypeFlags & BATTLE_TYPE_LINK) - gBattleControllerExecFlags |= gBitTable[battler] << (32 - MAX_BATTLERS_COUNT); + gBattleControllerExecFlags |= 1u << (32 - MAX_BATTLERS_COUNT); else - gBattleControllerExecFlags |= gBitTable[battler]; + gBattleControllerExecFlags |= 1u << battler; } void MarkBattlerReceivedLinkData(u32 battler) @@ -994,9 +994,9 @@ void MarkBattlerReceivedLinkData(u32 battler) s32 i; for (i = 0; i < GetLinkPlayerCount(); i++) - gBattleControllerExecFlags |= gBitTable[battler] << (i << 2); + gBattleControllerExecFlags |= 1u << (battler + (i << 2)); - gBattleControllerExecFlags &= ~((1 << 28) << battler); + gBattleControllerExecFlags &= ~(1u << (28 + battler)); } const u8* CancelMultiTurnMoves(u32 battler) @@ -1172,7 +1172,7 @@ void ResetSentPokesToOpponentValue(void) gSentPokesToOpponent[1] = 0; for (i = 0; i < gBattlersCount; i += 2) - bits |= gBitTable[gBattlerPartyIndexes[i]]; + bits |= 1u << gBattlerPartyIndexes[i]; for (i = 1; i < gBattlersCount; i += 2) gSentPokesToOpponent[(i & BIT_FLANK) >> 1] = bits; @@ -1190,8 +1190,8 @@ void OpponentSwitchInResetSentPokesToOpponentValue(u32 battler) for (i = 0; i < gBattlersCount; i += 2) { - if (!(gAbsentBattlerFlags & gBitTable[i])) - bits |= gBitTable[gBattlerPartyIndexes[i]]; + if (!(gAbsentBattlerFlags & (1u << i))) + bits |= 1u << gBattlerPartyIndexes[i]; } gSentPokesToOpponent[flank] = bits; } @@ -1207,7 +1207,7 @@ void UpdateSentPokesToOpponentValue(u32 battler) { s32 i; for (i = 1; i < gBattlersCount; i++) - gSentPokesToOpponent[(i & BIT_FLANK) >> 1] |= gBitTable[gBattlerPartyIndexes[battler]]; + gSentPokesToOpponent[(i & BIT_FLANK) >> 1] |= 1u << gBattlerPartyIndexes[battler]; } } @@ -1248,7 +1248,7 @@ bool32 IsBelchPreventingMove(u32 battler, u32 move) if (gMovesInfo[move].effect != EFFECT_BELCH) return FALSE; - return !(gBattleStruct->ateBerry[battler & BIT_SIDE] & gBitTable[gBattlerPartyIndexes[battler]]); + return !(gBattleStruct->ateBerry[battler & BIT_SIDE] & (1u << gBattlerPartyIndexes[battler])); } // Dynamax bypasses all selection prevention except Taunt and Assault Vest. @@ -1513,55 +1513,55 @@ u8 CheckMoveLimitations(u32 battler, u8 unusableMoves, u16 check) moveEffect = gMovesInfo[move].effect; // No move if (check & MOVE_LIMITATION_ZEROMOVE && move == MOVE_NONE) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // No PP else if (check & MOVE_LIMITATION_PP && gBattleMons[battler].pp[i] == 0) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Placeholder else if (check & MOVE_LIMITATION_PLACEHOLDER && moveEffect == EFFECT_PLACEHOLDER) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Disable else if (check & MOVE_LIMITATION_DISABLED && move == gDisableStructs[battler].disabledMove) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Torment else if (check & MOVE_LIMITATION_TORMENTED && move == gLastMoves[battler] && gBattleMons[battler].status2 & STATUS2_TORMENT) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Taunt else if (check & MOVE_LIMITATION_TAUNT && gDisableStructs[battler].tauntTimer && IS_MOVE_STATUS(move)) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Imprison else if (check & MOVE_LIMITATION_IMPRISON && GetImprisonedMovesCount(battler, move)) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Encore else if (check & MOVE_LIMITATION_ENCORE && gDisableStructs[battler].encoreTimer && gDisableStructs[battler].encoredMove != move) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Choice Items else if (check & MOVE_LIMITATION_CHOICE_ITEM && HOLD_EFFECT_CHOICE(holdEffect) && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != move) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Assault Vest else if (check & MOVE_LIMITATION_ASSAULT_VEST && holdEffect == HOLD_EFFECT_ASSAULT_VEST && IS_MOVE_STATUS(move) && gMovesInfo[move].effect != EFFECT_ME_FIRST) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Gravity else if (check & MOVE_LIMITATION_GRAVITY && IsGravityPreventingMove(move)) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Heal Block else if (check & MOVE_LIMITATION_HEAL_BLOCK && IsHealBlockPreventingMove(battler, move)) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Belch else if (check & MOVE_LIMITATION_BELCH && IsBelchPreventingMove(battler, move)) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Throat Chop else if (check & MOVE_LIMITATION_THROAT_CHOP && gDisableStructs[battler].throatChopTimer && gMovesInfo[move].soundMove) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Stuff Cheeks else if (check & MOVE_LIMITATION_STUFF_CHEEKS && moveEffect == EFFECT_STUFF_CHEEKS && ItemId_GetPocket(gBattleMons[battler].item) != POCKET_BERRIES) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Gorilla Tactics else if (check & MOVE_LIMITATION_CHOICE_ITEM && GetBattlerAbility(battler) == ABILITY_GORILLA_TACTICS && *choicedMove != MOVE_NONE && *choicedMove != MOVE_UNAVAILABLE && *choicedMove != move) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; // Can't Use Twice flag else if (check & MOVE_LIMITATION_CANT_USE_TWICE && gMovesInfo[move].cantUseTwice && move == gLastResultingMoves[battler]) - unusableMoves |= gBitTable[i]; + unusableMoves |= 1u << i; } return unusableMoves; } @@ -1703,10 +1703,10 @@ u8 DoFieldEndTurnEffects(void) { u8 effect = 0; - for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount && gAbsentBattlerFlags & gBitTable[gBattlerAttacker]; gBattlerAttacker++) + for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount && gAbsentBattlerFlags & (1u << gBattlerAttacker); gBattlerAttacker++) { } - for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount && gAbsentBattlerFlags & gBitTable[gBattlerTarget]; gBattlerTarget++) + for (gBattlerTarget = 0; gBattlerTarget < gBattlersCount && gAbsentBattlerFlags & (1u << gBattlerTarget); gBattlerTarget++) { } @@ -2370,7 +2370,7 @@ u8 DoBattlerEndTurnEffects(void) while (gBattleStruct->turnEffectsBattlerId < gBattlersCount && gBattleStruct->turnEffectsTracker <= ENDTURN_BATTLER_COUNT) { battler = gBattlerAttacker = gBattlerByTurnOrder[gBattleStruct->turnEffectsBattlerId]; - if (gAbsentBattlerFlags & gBitTable[battler]) + if (gAbsentBattlerFlags & (1u << battler)) { gBattleStruct->turnEffectsBattlerId++; continue; @@ -3032,7 +3032,7 @@ bool32 HandleWishPerishSongOnTurnEnd(void) if (gWishFutureKnock.futureSightCounter[battler] != 0 && --gWishFutureKnock.futureSightCounter[battler] == 0 - && !(gAbsentBattlerFlags & gBitTable[battler])) + && !(gAbsentBattlerFlags & (1u << battler))) { struct Pokemon *party; @@ -3073,7 +3073,7 @@ bool32 HandleWishPerishSongOnTurnEnd(void) while (gBattleStruct->wishPerishSongBattlerId < gBattlersCount) { battler = gBattlerAttacker = gBattlerByTurnOrder[gBattleStruct->wishPerishSongBattlerId]; - if (gAbsentBattlerFlags & gBitTable[battler]) + if (gAbsentBattlerFlags & (1u << battler)) { gBattleStruct->wishPerishSongBattlerId++; continue; @@ -3139,8 +3139,8 @@ bool32 HandleFaintedMonActions(void) gBattleStruct->faintedActionsState++; for (i = 0; i < gBattlersCount; i++) { - if (gAbsentBattlerFlags & gBitTable[i] && !HasNoMonsToSwitch(i, PARTY_SIZE, PARTY_SIZE)) - gAbsentBattlerFlags &= ~(gBitTable[i]); + if (gAbsentBattlerFlags & (1u << i) && !HasNoMonsToSwitch(i, PARTY_SIZE, PARTY_SIZE)) + gAbsentBattlerFlags &= ~(1u << i); } // fall through case 1: @@ -3148,8 +3148,8 @@ bool32 HandleFaintedMonActions(void) { gBattlerFainted = gBattlerTarget = gBattleStruct->faintedActionsBattlerId; if (gBattleMons[gBattleStruct->faintedActionsBattlerId].hp == 0 - && !(gBattleStruct->givenExpMons & gBitTable[gBattlerPartyIndexes[gBattleStruct->faintedActionsBattlerId]]) - && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->faintedActionsBattlerId])) + && !(gBattleStruct->givenExpMons & (1u << gBattlerPartyIndexes[gBattleStruct->faintedActionsBattlerId])) + && !(gAbsentBattlerFlags & (1u << gBattleStruct->faintedActionsBattlerId))) { BattleScriptExecute(BattleScript_GiveExp); gBattleStruct->faintedActionsState = 2; @@ -3170,7 +3170,7 @@ bool32 HandleFaintedMonActions(void) && !NoAliveMonsForEitherParty() && gCurrentTurnActionNumber != gBattlersCount) { - gAbsentBattlerFlags |= gBitTable[gBattlerFainted]; + gAbsentBattlerFlags |= 1u << gBattlerFainted; if (gBattleStruct->faintedActionsState != 1) return FALSE; } @@ -3192,7 +3192,7 @@ bool32 HandleFaintedMonActions(void) { gBattlerFainted = gBattlerTarget = gBattleStruct->faintedActionsBattlerId; if (gBattleMons[gBattleStruct->faintedActionsBattlerId].hp == 0 - && !(gAbsentBattlerFlags & gBitTable[gBattleStruct->faintedActionsBattlerId])) + && !(gAbsentBattlerFlags & (1u << gBattleStruct->faintedActionsBattlerId))) { BattleScriptExecute(BattleScript_HandleFaintedMon); gBattleStruct->faintedActionsState = 5; @@ -3498,7 +3498,7 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) gCurrentMove = MOVE_BIDE; gBattleScripting.bideDmg = gBideDmg[gBattlerAttacker] * 2; gBattlerTarget = gBideTarget[gBattlerAttacker]; - if (gAbsentBattlerFlags & gBitTable[gBattlerTarget]) + if (gAbsentBattlerFlags & (1u << gBattlerTarget)) gBattlerTarget = GetMoveTarget(MOVE_BIDE, MOVE_TARGET_SELECTED + 1); gBattlescriptCurrInstr = BattleScript_BideAttack; } @@ -4731,11 +4731,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 break; case ABILITY_SUPERSWEET_SYRUP: if (!gSpecialStatuses[battler].switchInAbilityDone - && !(gBattleStruct->supersweetSyrup[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]])) + && !(gBattleStruct->supersweetSyrup[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler]))) { gBattlerAttacker = battler; gSpecialStatuses[battler].switchInAbilityDone = TRUE; - gBattleStruct->supersweetSyrup[GetBattlerSide(battler)] |= gBitTable[gBattlerPartyIndexes[battler]]; + gBattleStruct->supersweetSyrup[GetBattlerSide(battler)] |= (1u << gBattlerPartyIndexes[battler]); BattleScriptPushCursorAndCallback(BattleScript_SupersweetSyrupActivates); effect++; } @@ -4772,12 +4772,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 break; case ABILITY_INTREPID_SWORD: if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN) - && !(gBattleStruct->intrepidSwordBoost[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]])) + && !(gBattleStruct->intrepidSwordBoost[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler]))) { gBattleScripting.savedBattler = gBattlerAttacker; gBattlerAttacker = battler; if (B_INTREPID_SWORD == GEN_9) - gBattleStruct->intrepidSwordBoost[GetBattlerSide(battler)] |= gBitTable[gBattlerPartyIndexes[battler]]; + gBattleStruct->intrepidSwordBoost[GetBattlerSide(battler)] |= 1u << gBattlerPartyIndexes[battler]; gSpecialStatuses[battler].switchInAbilityDone = TRUE; SET_STATCHANGER(STAT_ATK, 1, FALSE); BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn); @@ -4786,12 +4786,12 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 break; case ABILITY_DAUNTLESS_SHIELD: if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_DEF, MAX_STAT_STAGE, CMP_LESS_THAN) - && !(gBattleStruct->dauntlessShieldBoost[GetBattlerSide(battler)] & gBitTable[gBattlerPartyIndexes[battler]])) + && !(gBattleStruct->dauntlessShieldBoost[GetBattlerSide(battler)] & (1u << gBattlerPartyIndexes[battler]))) { gBattleScripting.savedBattler = gBattlerAttacker; gBattlerAttacker = battler; if (B_DAUNTLESS_SHIELD == GEN_9) - gBattleStruct->dauntlessShieldBoost[GetBattlerSide(battler)] |= gBitTable[gBattlerPartyIndexes[battler]]; + gBattleStruct->dauntlessShieldBoost[GetBattlerSide(battler)] |= 1u << gBattlerPartyIndexes[battler]; gSpecialStatuses[battler].switchInAbilityDone = TRUE; SET_STATCHANGER(STAT_DEF, 1, FALSE); BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn); @@ -4895,11 +4895,11 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (!gSpecialStatuses[battler].switchInAbilityDone && GetMonData(mon, MON_DATA_SPECIES) == SPECIES_PALAFIN_HERO - && !(gBattleStruct->transformZeroToHero[side] & gBitTable[gBattlerPartyIndexes[battler]])) + && !(gBattleStruct->transformZeroToHero[side] & (1u << gBattlerPartyIndexes[battler]))) { gSpecialStatuses[battler].switchInAbilityDone = TRUE; gBattlerAttacker = battler; - gBattleStruct->transformZeroToHero[side] |= gBitTable[gBattlerPartyIndexes[battler]]; + gBattleStruct->transformZeroToHero[side] |= 1u << gBattlerPartyIndexes[battler]; BattleScriptPushCursorAndCallback(BattleScript_ZeroToHeroActivates); effect++; } @@ -5046,9 +5046,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 for (i = STAT_ATK; i < statsNum; i++) { if (CompareStat(battler, i, MIN_STAT_STAGE, CMP_GREATER_THAN)) - validToLower |= gBitTable[i]; + validToLower |= 1u << i; if (CompareStat(battler, i, MAX_STAT_STAGE, CMP_LESS_THAN)) - validToRaise |= gBitTable[i]; + validToRaise |= 1u << i; } if (validToLower != 0 || validToRaise != 0) // Can lower one stat, or can raise one stat @@ -5059,16 +5059,16 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 do { i = (Random() % statsNum) + STAT_ATK; - } while (!(validToRaise & gBitTable[i])); + } while (!(validToRaise & (1u << i))); SET_STATCHANGER(i, 2, FALSE); - validToLower &= ~(gBitTable[i]); // Can't lower the same stat as raising. + validToLower &= ~(1u << i); // Can't lower the same stat as raising. } if (validToLower != 0) // Find stat to lower { do { i = (Random() % statsNum) + STAT_ATK; - } while (!(validToLower & gBitTable[i])); + } while (!(validToLower & (1u << i))); SET_STATCHANGER2(gBattleScripting.savedStatChanger, i, 1, TRUE); } BattleScriptPushCursorAndCallback(BattleScript_MoodyActivates); @@ -7560,13 +7560,13 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) effect = TryConsumeMirrorHerb(battler, TRUE); break; case HOLD_EFFECT_BOOSTER_ENERGY: - if (!(gBattleStruct->boosterEnergyActivates & gBitTable[battler]) + if (!(gBattleStruct->boosterEnergyActivates & (1u << battler)) && (((GetBattlerAbility(battler) == ABILITY_PROTOSYNTHESIS) && !(gBattleWeather & B_WEATHER_SUN)) || ((GetBattlerAbility(battler) == ABILITY_QUARK_DRIVE) && !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)))) { PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); gBattleScripting.battler = battler; - gBattleStruct->boosterEnergyActivates |= gBitTable[battler]; + gBattleStruct->boosterEnergyActivates |= 1u << battler; BattleScriptExecute(BattleScript_BoosterEnergyEnd2); effect = ITEM_EFFECT_OTHER; } @@ -7827,13 +7827,13 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) effect = TryConsumeMirrorHerb(battler, TRUE); break; case HOLD_EFFECT_BOOSTER_ENERGY: - if (!(gBattleStruct->boosterEnergyActivates & gBitTable[battler]) + if (!(gBattleStruct->boosterEnergyActivates & (1u << battler)) && (((GetBattlerAbility(battler) == ABILITY_PROTOSYNTHESIS) && !(gBattleWeather & B_WEATHER_SUN)) || ((GetBattlerAbility(battler) == ABILITY_QUARK_DRIVE) && !(gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN)))) { PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); gBattlerAbility = gBattleScripting.battler = battler; - gBattleStruct->boosterEnergyActivates |= gBitTable[battler]; + gBattleStruct->boosterEnergyActivates |= 1u << battler; BattleScriptExecute(BattleScript_BoosterEnergyEnd2); effect = ITEM_EFFECT_OTHER; } @@ -8210,7 +8210,7 @@ u8 ItemBattleEffects(u8 caseID, u32 battler, bool32 moveTurn) // Berry was successfully used on a Pokemon. if (effect && (gLastUsedItem >= FIRST_BERRY_INDEX && gLastUsedItem <= LAST_BERRY_INDEX)) - gBattleStruct->ateBerry[battler & BIT_SIDE] |= gBitTable[gBattlerPartyIndexes[battler]]; + gBattleStruct->ateBerry[battler & BIT_SIDE] |= 1u << gBattlerPartyIndexes[battler]; return effect; } @@ -8401,7 +8401,7 @@ u8 IsMonDisobedient(void) calc = (levelReferenced + obedienceLevel) * rnd >> 8; if (calc < obedienceLevel) { - calc = CheckMoveLimitations(gBattlerAttacker, gBitTable[gCurrMovePos], MOVE_LIMITATIONS_ALL); + calc = CheckMoveLimitations(gBattlerAttacker, 1u << gCurrMovePos, MOVE_LIMITATIONS_ALL); if (calc == ALL_MOVES_MASK) // all moves cannot be used { // Randomly select, then print a disobedient string @@ -8415,7 +8415,7 @@ u8 IsMonDisobedient(void) do { gCurrMovePos = gChosenMovePos = MOD(Random(), MAX_MON_MOVES); - } while (gBitTable[gCurrMovePos] & calc); + } while ((1u << gCurrMovePos) & calc); gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos]; SetAtkCancellerForCalledMove(); @@ -8630,7 +8630,7 @@ bool32 IsBattlerAlive(u32 battler) return FALSE; else if (battler >= gBattlersCount) return FALSE; - else if (gAbsentBattlerFlags & gBitTable[battler]) + else if (gAbsentBattlerFlags & (1u << battler)) return FALSE; else return TRUE; @@ -8703,12 +8703,12 @@ u32 GetMoveTargetCount(u32 move, u32 battlerAtk, u32 battlerDef) switch (GetBattlerMoveTargetType(gBattlerAttacker, move)) { case MOVE_TARGET_BOTH: - return !(gAbsentBattlerFlags & gBitTable[battlerDef]) - + !(gAbsentBattlerFlags & gBitTable[BATTLE_PARTNER(battlerDef)]); + return !(gAbsentBattlerFlags & (1u << battlerDef)) + + !(gAbsentBattlerFlags & (1u << BATTLE_PARTNER(battlerDef))); case MOVE_TARGET_FOES_AND_ALLY: - return !(gAbsentBattlerFlags & gBitTable[battlerDef]) - + !(gAbsentBattlerFlags & gBitTable[BATTLE_PARTNER(battlerDef)]) - + !(gAbsentBattlerFlags & gBitTable[BATTLE_PARTNER(battlerAtk)]); + return !(gAbsentBattlerFlags & (1u << battlerDef)) + + !(gAbsentBattlerFlags & (1u << BATTLE_PARTNER(battlerDef))) + + !(gAbsentBattlerFlags & (1u << BATTLE_PARTNER(battlerAtk))); case MOVE_TARGET_OPPONENTS_FIELD: return 1; case MOVE_TARGET_DEPENDS: @@ -9126,7 +9126,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32 modifier = uq4_12_multiply(modifier, UQ_4_12(0.5)); break; case EFFECT_STOMPING_TANTRUM: - if (gBattleStruct->lastMoveFailed & gBitTable[battlerAtk]) + if (gBattleStruct->lastMoveFailed & (1u << battlerAtk)) modifier = uq4_12_multiply(modifier, UQ_4_12(2.0)); break; case EFFECT_MAGNITUDE: @@ -9281,7 +9281,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32 case ABILITY_PROTOSYNTHESIS: { u8 atkHighestStat = GetHighestStatId(battlerAtk); - if ((weather & B_WEATHER_SUN || gBattleStruct->boosterEnergyActivates & gBitTable[battlerAtk]) + if ((weather & B_WEATHER_SUN || gBattleStruct->boosterEnergyActivates & (1u << battlerAtk)) && ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK))) modifier = uq4_12_multiply(modifier, UQ_4_12(1.3)); } @@ -9289,7 +9289,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32 case ABILITY_QUARK_DRIVE: { u8 atkHighestStat = GetHighestStatId(battlerAtk); - if ((gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & gBitTable[battlerAtk]) + if ((gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & (1u << battlerAtk)) && ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK))) modifier = uq4_12_multiply(modifier, UQ_4_12(1.3)); } @@ -9359,7 +9359,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32 case ABILITY_PROTOSYNTHESIS: { u8 defHighestStat = GetHighestStatId(battlerDef); - if ((weather & B_WEATHER_SUN || gBattleStruct->boosterEnergyActivates & gBitTable[battlerDef]) + if ((weather & B_WEATHER_SUN || gBattleStruct->boosterEnergyActivates & (1u << battlerDef)) && ((IS_MOVE_PHYSICAL(move) && defHighestStat == STAT_DEF) || (IS_MOVE_SPECIAL(move) && defHighestStat == STAT_SPDEF))) modifier = uq4_12_multiply(modifier, UQ_4_12(0.7)); } @@ -9367,7 +9367,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32 case ABILITY_QUARK_DRIVE: { u8 defHighestStat = GetHighestStatId(battlerDef); - if ((gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & gBitTable[battlerDef]) + if ((gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & (1u << battlerDef)) && ((IS_MOVE_PHYSICAL(move) && defHighestStat == STAT_DEF) || (IS_MOVE_SPECIAL(move) && defHighestStat == STAT_SPDEF))) modifier = uq4_12_multiply(modifier, UQ_4_12(0.7)); } @@ -10335,7 +10335,7 @@ static inline void MulByTypeEffectiveness(uq4_12_t *modifier, u32 move, u32 move mod = UQ_4_12(1.0); } - if (gBattleStruct->distortedTypeMatchups & gBitTable[battlerDef] || (gBattleStruct->aiCalcInProgress && ShouldTeraShellDistortTypeMatchups(move, battlerDef))) + if (gBattleStruct->distortedTypeMatchups & (1u << battlerDef) || (gBattleStruct->aiCalcInProgress && ShouldTeraShellDistortTypeMatchups(move, battlerDef))) { mod = UQ_4_12(0.5); if (recordAbilities) @@ -11245,7 +11245,7 @@ bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item) | BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_SECRET_BASE)) - && (gWishFutureKnock.knockedOffMons[stealerSide] & gBitTable[gBattlerPartyIndexes[battlerStealing]])) + && (gWishFutureKnock.knockedOffMons[stealerSide] & (1u << gBattlerPartyIndexes[battlerStealing]))) { return FALSE; } diff --git a/src/battle_z_move.c b/src/battle_z_move.c index 8113da48a9..5a5816142c 100644 --- a/src/battle_z_move.c +++ b/src/battle_z_move.c @@ -209,13 +209,13 @@ void AssignUsableZMoves(u32 battler, u16 *moves) for (i = 0; i < MAX_MON_MOVES; i++) { if (moves[i] != MOVE_NONE && IsViableZMove(battler, moves[i])) - gBattleStruct->zmove.possibleZMoves[battler] |= gBitTable[i]; + gBattleStruct->zmove.possibleZMoves[battler] |= 1u << i; } } bool32 TryChangeZTrigger(u32 battler, u32 moveIndex) { - bool32 viableZMove = (gBattleStruct->zmove.possibleZMoves[battler] & gBitTable[moveIndex]) != 0; + bool32 viableZMove = (gBattleStruct->zmove.possibleZMoves[battler] & (1u << moveIndex)) != 0; if (gBattleStruct->zmove.viable && !viableZMove) HideGimmickTriggerSprite(); // Was a viable z move, now is not -> slide out diff --git a/src/pokemon.c b/src/pokemon.c index 306e310372..1acaa3a2ed 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -2080,14 +2080,14 @@ u8 CountAliveMonsInBattle(u8 caseId, u32 battler) case BATTLE_ALIVE_EXCEPT_BATTLER: for (i = 0; i < MAX_BATTLERS_COUNT; i++) { - if (i != battler && !(gAbsentBattlerFlags & gBitTable[i])) + if (i != battler && !(gAbsentBattlerFlags & (1u << i))) retVal++; } break; case BATTLE_ALIVE_SIDE: for (i = 0; i < MAX_BATTLERS_COUNT; i++) { - if (GetBattlerSide(i) == GetBattlerSide(battler) && !(gAbsentBattlerFlags & gBitTable[i])) + if (GetBattlerSide(i) == GetBattlerSide(battler) && !(gAbsentBattlerFlags & (1u << i))) retVal++; } break; @@ -2115,7 +2115,7 @@ u8 GetDefaultMoveTarget(u8 battlerId) } else { - if ((gAbsentBattlerFlags & gBitTable[opposing])) + if ((gAbsentBattlerFlags & (1u << opposing))) return GetBattlerAtPosition(BATTLE_PARTNER(opposing)); else return GetBattlerAtPosition(opposing); @@ -2691,7 +2691,7 @@ u32 GetBoxMonData3(struct BoxPokemon *boxMon, s32 field, u8 *data) || substruct1->move2 == move || substruct1->move3 == move || substruct1->move4 == move) - retVal |= gBitTable[i]; + retVal |= (1u << i); i++; } } @@ -5316,7 +5316,7 @@ void RandomlyGivePartyPokerus(struct Pokemon *party) } while (!GetMonData(mon, MON_DATA_SPECIES, 0) || GetMonData(mon, MON_DATA_IS_EGG, 0)); - if (!(CheckPartyHasHadPokerus(party, gBitTable[rnd]))) + if (!(CheckPartyHasHadPokerus(party, 1u << rnd))) { u8 rnd2; @@ -6651,9 +6651,9 @@ void TrySpecialOverworldEvo(void) for (i = 0; i < PARTY_SIZE; i++) { u16 targetSpecies = GetEvolutionTargetSpecies(&gPlayerParty[i], EVO_MODE_OVERWORLD_SPECIAL, evoMethod, SPECIES_NONE); - if (targetSpecies != SPECIES_NONE && !(sTriedEvolving & gBitTable[i])) + if (targetSpecies != SPECIES_NONE && !(sTriedEvolving & (1u << i))) { - sTriedEvolving |= gBitTable[i]; + sTriedEvolving |= 1u << i; if(gMain.callback2 == TrySpecialOverworldEvo) // This fixes small graphics glitches. EvolutionScene(&gPlayerParty[i], targetSpecies, canStopEvo, i); else diff --git a/src/recorded_battle.c b/src/recorded_battle.c index 2ac33a08a0..c32e86b525 100644 --- a/src/recorded_battle.c +++ b/src/recorded_battle.c @@ -741,7 +741,7 @@ void RecordedBattle_CheckMovesetChanges(u8 mode) movePp.moves[j] = gBattleMons[battlerId].moves[moveSlots[j]]; movePp.currentPp[j] = gBattleMons[battlerId].pp[moveSlots[j]]; movePp.maxPp[j] = ppBonuses[moveSlots[j]]; - mimickedMoveSlots[j] = (gDisableStructs[battlerId].mimickedMoves & gBitTable[j]) >> j; + mimickedMoveSlots[j] = (gDisableStructs[battlerId].mimickedMoves & (1u << j)) >> j; } for (j = 0; j < MAX_MON_MOVES; j++) { diff --git a/src/script_movement.c b/src/script_movement.c index 10517dfc8e..d67afd9972 100644 --- a/src/script_movement.c +++ b/src/script_movement.c @@ -142,19 +142,19 @@ static void LoadObjectEventIdFromMovementScript(u8 taskId, u8 moveScrId, u8 *obj static void ClearMovementScriptFinished(u8 taskId, u8 moveScrId) { - u16 mask = ~gBitTable[moveScrId]; + u16 mask = ~(1u << moveScrId); gTasks[taskId].data[0] &= mask; } static void SetMovementScriptFinished(u8 taskId, u8 moveScrId) { - gTasks[taskId].data[0] |= gBitTable[moveScrId]; + gTasks[taskId].data[0] |= (1u << moveScrId); } static bool8 IsMovementScriptFinished(u8 taskId, u8 moveScrId) { - u16 moveScriptFinished = (u16)gTasks[taskId].data[0] & gBitTable[moveScrId]; + u16 moveScriptFinished = (u16)gTasks[taskId].data[0] & (1u << moveScrId); if (moveScriptFinished != 0) return TRUE; diff --git a/src/trainer_hill.c b/src/trainer_hill.c index aa7c8ee930..c89803ffb2 100644 --- a/src/trainer_hill.c +++ b/src/trainer_hill.c @@ -852,7 +852,7 @@ bool8 GetHillTrainerFlag(u8 objectEventId) u32 trainerIndexStart = GetFloorId() * HILL_TRAINERS_PER_FLOOR; u8 bitId = gObjectEvents[objectEventId].localId - 1 + trainerIndexStart; - return gSaveBlock2Ptr->frontier.trainerFlags & gBitTable[bitId]; + return gSaveBlock2Ptr->frontier.trainerFlags & (1u << bitId); } void SetHillTrainerFlag(void) @@ -864,7 +864,7 @@ void SetHillTrainerFlag(void) { if (gSaveBlock2Ptr->frontier.trainerIds[i] == gTrainerBattleOpponent_A) { - gSaveBlock2Ptr->frontier.trainerFlags |= gBitTable[trainerIndexStart + i]; + gSaveBlock2Ptr->frontier.trainerFlags |= 1u << (trainerIndexStart + i); break; } } @@ -875,7 +875,7 @@ void SetHillTrainerFlag(void) { if (gSaveBlock2Ptr->frontier.trainerIds[i] == gTrainerBattleOpponent_B) { - gSaveBlock2Ptr->frontier.trainerFlags |= gBitTable[trainerIndexStart + i]; + gSaveBlock2Ptr->frontier.trainerFlags |= 1u << (trainerIndexStart + i); break; } } diff --git a/src/util.c b/src/util.c index 77d9cde2f1..002b2fabf0 100644 --- a/src/util.c +++ b/src/util.c @@ -4,42 +4,6 @@ #include "palette.h" #include "constants/rgb.h" -const u32 gBitTable[] = -{ - 1 << 0, - 1 << 1, - 1 << 2, - 1 << 3, - 1 << 4, - 1 << 5, - 1 << 6, - 1 << 7, - 1 << 8, - 1 << 9, - 1 << 10, - 1 << 11, - 1 << 12, - 1 << 13, - 1 << 14, - 1 << 15, - 1 << 16, - 1 << 17, - 1 << 18, - 1 << 19, - 1 << 20, - 1 << 21, - 1 << 22, - 1 << 23, - 1 << 24, - 1 << 25, - 1 << 26, - 1 << 27, - 1 << 28, - 1 << 29, - 1 << 30, - 1 << 31, -}; - static const struct SpriteTemplate sInvisibleSpriteTemplate = { .tileTag = 0, diff --git a/test/test_runner_battle.c b/test/test_runner_battle.c index 92789710f7..53e63dc7cf 100644 --- a/test/test_runner_battle.c +++ b/test/test_runner_battle.c @@ -769,7 +769,7 @@ static u32 CountAiExpectMoves(struct ExpectedAIAction *expectedAction, u32 battl u32 i, countExpected = 0; for (i = 0; i < MAX_MON_MOVES; i++) { - if (gBitTable[i] & expectedAction->moveSlots) + if ((1u << i) & expectedAction->moveSlots) { if (printLog) PrintAiMoveLog(battlerId, i, gBattleMons[battlerId].moves[i], gBattleStruct->aiFinalScore[battlerId][expectedAction->target][i]); @@ -801,7 +801,7 @@ void TestRunner_Battle_CheckChosenMove(u32 battlerId, u32 moveId, u32 target) for (i = 0; i < MAX_MON_MOVES; i++) { - if (gBitTable[i] & expectedAction->moveSlots) + if ((1u << i) & expectedAction->moveSlots) { expectedMoveId = gBattleMons[battlerId].moves[i]; if (!expectedAction->notMove) @@ -917,8 +917,8 @@ static void CheckIfMaxScoreEqualExpectMove(u32 battlerId, s32 target, struct Exp // We expect move 'i', but it has the same best score as another move that we didn't expect. if (scores[i] == scores[bestScoreId] && !aiAction->notMove - && (aiAction->moveSlots & gBitTable[i]) - && !(aiAction->moveSlots & gBitTable[bestScoreId])) + && (aiAction->moveSlots & (1u << i)) + && !(aiAction->moveSlots & (1u << bestScoreId))) { Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: EXPECT_MOVE %S has the same best score(%d) as not expected MOVE %S", filename, aiAction->sourceLine, GetMoveName(moves[i]), scores[i], GetMoveName(moves[bestScoreId])); @@ -926,8 +926,8 @@ static void CheckIfMaxScoreEqualExpectMove(u32 battlerId, s32 target, struct Exp // We DO NOT expect move 'i', but it has the same best score as another move. if (scores[i] == scores[bestScoreId] && aiAction->notMove - && (aiAction->moveSlots & gBitTable[i]) - && !(aiAction->moveSlots & gBitTable[bestScoreId])) + && (aiAction->moveSlots & (1u << i)) + && !(aiAction->moveSlots & (1u << bestScoreId))) { Test_ExitWithResult(TEST_RESULT_FAIL, SourceLine(0), ":L%s:%d: NOT_EXPECT_MOVE %S has the same best score(%d) as MOVE %S", filename, aiAction->sourceLine, GetMoveName(moves[i]), scores[i], GetMoveName(moves[bestScoreId])); @@ -940,9 +940,9 @@ static void PrintAiMoveLog(u32 battlerId, u32 moveSlot, u32 moveId, s32 totalSco s32 i, scoreFromLogs = 0; if (!DATA.logAI) return; - if (DATA.aiLogPrintedForMove[battlerId] & gBitTable[moveSlot]) return; + if (DATA.aiLogPrintedForMove[battlerId] & (1u << moveSlot)) return; - DATA.aiLogPrintedForMove[battlerId] |= gBitTable[moveSlot]; + DATA.aiLogPrintedForMove[battlerId] |= 1u << moveSlot; Test_MgbaPrintf("Score Log for move %S:\n", GetMoveName(moveId)); for (i = 0; i < MAX_AI_LOG_LINES; i++) { @@ -2187,7 +2187,7 @@ static void TryMarkExpectMove(u32 sourceLine, struct BattlePokemon *battler, str id = DATA.expectedAiActionIndex[battlerId]; DATA.expectedAiActions[battlerId][id].type = B_ACTION_USE_MOVE; - DATA.expectedAiActions[battlerId][id].moveSlots |= gBitTable[moveSlot]; + DATA.expectedAiActions[battlerId][id].moveSlots |= 1 << moveSlot; DATA.expectedAiActions[battlerId][id].target = target; DATA.expectedAiActions[battlerId][id].explicitTarget = ctx->explicitTarget; DATA.expectedAiActions[battlerId][id].sourceLine = sourceLine; From 3a0c5c9c6cd284a7bbf6f6f49c558f7984098038 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Sat, 17 Aug 2024 18:18:03 +0200 Subject: [PATCH 39/64] Adds missing AI checks for poltergeist (#5189) Adds missing AI checks for poltergeist --- src/battle_ai_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 30bce86c3d..08e05e02c1 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -483,7 +483,7 @@ bool32 IsDamageMoveUnusable(u32 move, u32 battlerAtk, u32 battlerDef) return TRUE; break; case EFFECT_POLTERGEIST: - if (AI_DATA->items[battlerDef] == ITEM_NONE) + if (AI_DATA->items[battlerDef] == ITEM_NONE || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM || battlerDefAbility == ABILITY_KLUTZ) return TRUE; break; case EFFECT_FIRST_TURN_ONLY: From 8607a7fb338d81a3e5692d1aafd0951e7fd603c5 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Sat, 17 Aug 2024 18:19:22 +0200 Subject: [PATCH 40/64] Fixes UB in Cmd_averagestats (#5191) * Fixes UB in Cmd_averagestats * fix test and align default case --- src/battle_script_commands.c | 23 ++++++++++++++++------- test/battle/move_effect/guard_split.c | 22 ++++++++++++++++++++++ test/battle/move_effect/power_split.c | 22 ++++++++++++++++++++++ 3 files changed, 60 insertions(+), 7 deletions(-) create mode 100644 test/battle/move_effect/guard_split.c create mode 100644 test/battle/move_effect/power_split.c diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 394a455b3a..9165d7b7e4 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -15669,17 +15669,26 @@ static void Cmd_swapstatstages(void) gBattlescriptCurrInstr = cmd->nextInstr; } +static u16 *GetBattlerStat(struct BattlePokemon *battler, u32 stat) +{ + switch (stat) + { + case STAT_ATK: return &battler->attack; + case STAT_DEF: return &battler->defense; + case STAT_SPATK: return &battler->spAttack; + case STAT_SPDEF: return &battler->spDefense; + default: return NULL; + } +} + static void Cmd_averagestats(void) { CMD_ARGS(u8 stat); - u8 stat = cmd->stat; - u16 atkStat = *(u16 *)((&gBattleMons[gBattlerAttacker].attack) + (stat - 1)); - u16 defStat = *(u16 *)((&gBattleMons[gBattlerTarget].attack) + (stat - 1)); - u16 average = (atkStat + defStat) / 2; - - *(u16 *)((&gBattleMons[gBattlerAttacker].attack) + (stat - 1)) = average; - *(u16 *)((&gBattleMons[gBattlerTarget].attack) + (stat - 1)) = average; + u16 *stat1 = GetBattlerStat(&gBattleMons[gBattlerAttacker], cmd->stat); + u16 *stat2 = GetBattlerStat(&gBattleMons[gBattlerTarget], cmd->stat); + u16 avg = (*stat1 + *stat2) / 2; + *stat1 = *stat2 = avg; gBattlescriptCurrInstr = cmd->nextInstr; } diff --git a/test/battle/move_effect/guard_split.c b/test/battle/move_effect/guard_split.c new file mode 100644 index 0000000000..3f012ab6e2 --- /dev/null +++ b/test/battle/move_effect/guard_split.c @@ -0,0 +1,22 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_GUARD_SPLIT].effect == EFFECT_GUARD_SPLIT); +} + +SINGLE_BATTLE_TEST("Guard Split averages users and targets Def and Sp. Def stats") +{ + GIVEN { + PLAYER(SPECIES_BULBASAUR); + OPPONENT(SPECIES_IVYSAUR); + } WHEN { + TURN { MOVE(player, MOVE_GUARD_SPLIT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GUARD_SPLIT, player); + } THEN { + EXPECT_EQ(player->defense, opponent->defense); + EXPECT_EQ(player->spDefense, opponent->spDefense); + } +} diff --git a/test/battle/move_effect/power_split.c b/test/battle/move_effect/power_split.c new file mode 100644 index 0000000000..70d1bfd5ea --- /dev/null +++ b/test/battle/move_effect/power_split.c @@ -0,0 +1,22 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_POWER_SPLIT].effect == EFFECT_POWER_SPLIT); +} + +SINGLE_BATTLE_TEST("Power Split averages user and targets Atk and Sp. Atk stats") +{ + GIVEN { + PLAYER(SPECIES_BULBASAUR); + OPPONENT(SPECIES_IVYSAUR); + } WHEN { + TURN { MOVE(player, MOVE_POWER_SPLIT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_POWER_SPLIT, player); + } THEN { + EXPECT_EQ(player->attack, opponent->attack); + EXPECT_EQ(player->spAttack, opponent->spAttack); + } +} From 8ca234de7e1e18459989e59919de3881a3941274 Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Sat, 17 Aug 2024 19:38:55 +0200 Subject: [PATCH 41/64] Removed gBitTable usage again (#5193) Co-authored-by: Hedara --- src/battle_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index 25cee6dfa9..10b5f25e0c 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -4738,9 +4738,9 @@ u32 GetBattlerTotalSpeedStatArgs(u32 battler, u32 ability, u32 holdEffect) speed *= 2; else if (ability == ABILITY_SLOW_START && gDisableStructs[battler].slowStartTimer != 0) speed /= 2; - else if (ability == ABILITY_PROTOSYNTHESIS && (gBattleWeather & B_WEATHER_SUN || gBattleStruct->boosterEnergyActivates & gBitTable[battler])) + else if (ability == ABILITY_PROTOSYNTHESIS && (gBattleWeather & B_WEATHER_SUN || gBattleStruct->boosterEnergyActivates & (1u << battler))) speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed; - else if (ability == ABILITY_QUARK_DRIVE && (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & gBitTable[battler])) + else if (ability == ABILITY_QUARK_DRIVE && (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & (1u << battler))) speed = (GetHighestStatId(battler) == STAT_SPEED) ? (speed * 150) / 100 : speed; // stat stages From a958e6111017d7acb8632a013020fb75958cd5b9 Mon Sep 17 00:00:00 2001 From: kittenchilly Date: Sat, 17 Aug 2024 15:33:11 -0500 Subject: [PATCH 42/64] Fix using Population Dice with Loaded Dice printing garbage text (#5195) --- src/battle_util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/battle_util.c b/src/battle_util.c index aefce1f0a9..9412737fae 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3641,13 +3641,14 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) else { gMultiHitCounter = gMovesInfo[gCurrentMove].strikeCount; - PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 3, 0) if (gMovesInfo[gCurrentMove].effect == EFFECT_DRAGON_DARTS && CanTargetPartner(gBattlerAttacker, gBattlerTarget) && TargetFullyImmuneToCurrMove(gBattlerAttacker, gBattlerTarget)) gBattlerTarget = BATTLE_PARTNER(gBattlerTarget); } + + PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 3, 0) } else if (B_BEAT_UP >= GEN_5 && gMovesInfo[gCurrentMove].effect == EFFECT_BEAT_UP) { From bc5f40e5182e78ca05c0048b089d1fa75a86597a Mon Sep 17 00:00:00 2001 From: PhallenTree <168426989+PhallenTree@users.noreply.github.com> Date: Mon, 19 Aug 2024 14:25:44 +0100 Subject: [PATCH 43/64] Adds missing Wind Rider activation and tests (#5207) * Adds missing Wind Rider activation + tests * Adds test for opponent setting up Tailwind * Update src/battle_util.c Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> --------- Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> --- src/battle_util.c | 13 ++++ test/battle/ability/wind_rider.c | 127 +++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+) create mode 100644 test/battle/ability/wind_rider.c diff --git a/src/battle_util.c b/src/battle_util.c index 9412737fae..f489ea6258 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -4766,6 +4766,19 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 effect++; } break; + case ABILITY_WIND_RIDER: + if (!gSpecialStatuses[battler].switchInAbilityDone + && CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN) + && gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_TAILWIND) + { + gBattleScripting.savedBattler = gBattlerAttacker; + gBattlerAttacker = battler; + gSpecialStatuses[battler].switchInAbilityDone = TRUE; + SET_STATCHANGER(STAT_ATK, 1, FALSE); + BattleScriptPushCursorAndCallback(BattleScript_BattlerAbilityStatRaiseOnSwitchIn); + effect++; + } + break; case ABILITY_DESOLATE_LAND: if (TryChangeBattleWeather(battler, ENUM_WEATHER_SUN_PRIMAL, TRUE)) { diff --git a/test/battle/ability/wind_rider.c b/test/battle/ability/wind_rider.c new file mode 100644 index 0000000000..57e6f0d275 --- /dev/null +++ b/test/battle/ability/wind_rider.c @@ -0,0 +1,127 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_TAILWIND].effect == EFFECT_TAILWIND); + ASSUME(gMovesInfo[MOVE_TAILWIND].windMove == TRUE); +} + +SINGLE_BATTLE_TEST("Wind Rider raises Attack by one stage if it sets up Tailwind") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRAMBLIN) { Ability(ABILITY_WIND_RIDER); } + } WHEN { + TURN { MOVE(opponent, MOVE_TAILWIND); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TAILWIND, opponent); + ABILITY_POPUP(opponent, ABILITY_WIND_RIDER); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Bramblin's Attack rose!"); + } THEN { + EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1); + } +} + +DOUBLE_BATTLE_TEST("Wind Rider raises Attack by one stage if Tailwind is setup by its partner") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRAMBLIN) { Ability(ABILITY_WIND_RIDER); } + } WHEN { + TURN { MOVE(opponentLeft, MOVE_TAILWIND); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TAILWIND, opponentLeft); + ABILITY_POPUP(opponentRight, ABILITY_WIND_RIDER); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); + MESSAGE("Foe Bramblin's Attack rose!"); + } THEN { + EXPECT_EQ(opponentRight->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1); + } +} + +SINGLE_BATTLE_TEST("Wind Rider doesn't raise Attack if opponent sets up Tailwind") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRAMBLIN) { Ability(ABILITY_WIND_RIDER); } + } WHEN { + TURN { MOVE(player, MOVE_TAILWIND); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TAILWIND, player); + NONE_OF { + ABILITY_POPUP(opponent, ABILITY_WIND_RIDER); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Bramblin's Attack rose!"); + } + } THEN { + EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE); + } +} + +SINGLE_BATTLE_TEST("Wind Rider raises Attack by one stage if switched into Tailwind on its side of the field") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + OPPONENT(SPECIES_BRAMBLIN) { Ability(ABILITY_WIND_RIDER); } + } WHEN { + TURN { MOVE(opponent, MOVE_TAILWIND); } + TURN { SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TAILWIND, opponent); + ABILITY_POPUP(opponent, ABILITY_WIND_RIDER); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Bramblin's Wind Rider raised its Attack!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + } THEN { + EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1); + } +} + +SINGLE_BATTLE_TEST("Wind Rider activates when it's no longer effected by Neutralizing Gas") +{ + GIVEN { + PLAYER(SPECIES_WEEZING) { Ability(ABILITY_NEUTRALIZING_GAS); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRAMBLIN) { Ability(ABILITY_WIND_RIDER); } + } WHEN { + TURN { MOVE(opponent, MOVE_TAILWIND); } + TURN { SWITCH(player, 1); } + } SCENE { + ABILITY_POPUP(player, ABILITY_NEUTRALIZING_GAS); + MESSAGE("Neutralizing Gas filled the area!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TAILWIND, opponent); + SWITCH_OUT_MESSAGE("Weezing"); + MESSAGE("The effects of Neutralizing Gas wore off!"); + ABILITY_POPUP(opponent, ABILITY_WIND_RIDER); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Bramblin's Wind Rider raised its Attack!"); + } THEN { + EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1); + } +} + +SINGLE_BATTLE_TEST("Wind Rider absorbs Wind moves and raises Attack by one stage") +{ + ASSUME(gMovesInfo[MOVE_GUST].windMove == TRUE); + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BRAMBLIN) { Ability(ABILITY_WIND_RIDER); } + } WHEN { + TURN { MOVE(player, MOVE_GUST); } + } SCENE { + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GUST, player); + HP_BAR(opponent); + } + ABILITY_POPUP(opponent, ABILITY_WIND_RIDER); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Bramblin's Attack rose!"); + } THEN { + EXPECT_EQ(opponent->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1); + } +} From 3a6c3d580d2ac68a6f92588b5ede7c56b791a13e Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Mon, 19 Aug 2024 19:03:47 +0200 Subject: [PATCH 44/64] Round Tests (#5196) * Round Tests * Apply suggestions from code review Co-authored-by: Eduardo Quezada --------- Co-authored-by: Hedara Co-authored-by: Eduardo Quezada --- test/battle/move_effect/round.c | 115 ++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 test/battle/move_effect/round.c diff --git a/test/battle/move_effect/round.c b/test/battle/move_effect/round.c new file mode 100644 index 0000000000..c911c96b63 --- /dev/null +++ b/test/battle/move_effect/round.c @@ -0,0 +1,115 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_ROUND].effect == EFFECT_ROUND); +} + +DOUBLE_BATTLE_TEST("Round allows other battlers which also selected the moves to immediately use the move, ignoring turn order") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_LAGGING_TAIL].holdEffect == HOLD_EFFECT_LAGGING_TAIL); + ASSUME(gMovesInfo[MOVE_IRON_HEAD].additionalEffects[0].moveEffect == MOVE_EFFECT_FLINCH); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_LAGGING_TAIL); } + } WHEN { + TURN { + MOVE(playerRight, MOVE_CELEBRATE); + MOVE(opponentLeft, MOVE_ROUND, target: playerLeft); + MOVE(playerLeft, MOVE_IRON_HEAD, target: opponentRight); + MOVE(opponentRight, MOVE_ROUND, target: playerLeft); + } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponentLeft); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_IRON_HEAD, playerLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponentRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_IRON_HEAD, playerLeft); + } +} + +DOUBLE_BATTLE_TEST("Round usages beyond the first one has double base power") +{ + s16 damage[2]; + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { + MOVE(opponentLeft, MOVE_ROUND, target: playerLeft); + MOVE(opponentRight, MOVE_ROUND, target: playerLeft); + } + } SCENE { + HP_BAR(playerLeft, captureDamage: &damage[0]); + HP_BAR(playerLeft, captureDamage: &damage[1]); + } THEN { + EXPECT_MUL_EQ(damage[0], Q_4_12(2.0), damage[1]); + } +} + +DOUBLE_BATTLE_TEST("Round still preserves the turn order outside of the other Round users moving immediately") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { + MOVE(opponentLeft, MOVE_ROUND, target: playerLeft); + MOVE(playerRight, MOVE_CELEBRATE); + MOVE(playerLeft, MOVE_CELEBRATE); + MOVE(opponentRight, MOVE_ROUND, target: playerLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponentLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponentRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerLeft); + } +} +DOUBLE_BATTLE_TEST("Round still preserves the turn order outside of the other Round users moving immediately with switch") +{ + KNOWN_FAILING; // #5148 + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { + SWITCH(playerRight, 2); + MOVE(opponentLeft, MOVE_ROUND, target: playerLeft); + MOVE(playerLeft, MOVE_CELEBRATE); + MOVE(opponentRight, MOVE_ROUND, target: playerLeft); + } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponentLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponentRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerLeft); + } +} + +DOUBLE_BATTLE_TEST("Round causes opposing pokemon to use Round immediately") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_LAGGING_TAIL].holdEffect == HOLD_EFFECT_LAGGING_TAIL); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_LAGGING_TAIL); } + } WHEN { + TURN { MOVE(opponentLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_ROUND, target: opponentLeft); MOVE(playerLeft, MOVE_CELEBRATE, target: opponentRight); MOVE(opponentRight, MOVE_ROUND, target: playerLeft); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, playerRight); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROUND, opponentRight); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerLeft); + } +} From a11f03ed9d9cdf31b291144b7c2e16f0573bc049 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Mon, 19 Aug 2024 18:25:39 -0400 Subject: [PATCH 45/64] Version 1.9.1 (#5199) * Version 1.9.1 * Added 5195 * Apply suggestions from code review Co-authored-by: hedara90 <90hedara@gmail.com> * Added 5196 and 5207 --------- Co-authored-by: hedara90 <90hedara@gmail.com> --- .../ISSUE_TEMPLATE/01_battle_engine_bugs.yaml | 3 +- .../ISSUE_TEMPLATE/02_battle_ai_issues.yaml | 3 +- .github/ISSUE_TEMPLATE/04_other_errors.yaml | 3 +- CHANGELOG.md | 1 + README.md | 2 +- docs/SUMMARY.md | 8 +- docs/changelogs/1.9.x/1.9.1.md | 140 ++++++++++++++++++ docs/changelogs/template.md | 5 +- include/constants/expansion.h | 4 +- 9 files changed, 158 insertions(+), 11 deletions(-) create mode 100644 docs/changelogs/1.9.x/1.9.1.md diff --git a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml index 310f92c118..edebc1bbf0 100644 --- a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml +++ b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml @@ -23,9 +23,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.9.0 (Latest release) + - 1.9.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.9.0 - 1.8.6 - 1.8.5 - 1.8.4 diff --git a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml index 9fcb1595a2..dd3024230b 100644 --- a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml +++ b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml @@ -23,9 +23,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.9.0 (Latest release) + - 1.9.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.9.0 - 1.8.6 - 1.8.5 - 1.8.4 diff --git a/.github/ISSUE_TEMPLATE/04_other_errors.yaml b/.github/ISSUE_TEMPLATE/04_other_errors.yaml index 73d9fd11d3..29960c267b 100644 --- a/.github/ISSUE_TEMPLATE/04_other_errors.yaml +++ b/.github/ISSUE_TEMPLATE/04_other_errors.yaml @@ -23,9 +23,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.9.0 (Latest release) + - 1.9.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.9.0 - 1.8.6 - 1.8.5 - 1.8.4 diff --git a/CHANGELOG.md b/CHANGELOG.md index 0999ae5f7e..fb2f38af1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Pokeemerald-Expansion Changelogs ## 1.9.x +- **[Version 1.9.1](docs/changelogs/1.9.x/1.9.1.md) - 🧹 Bugfix Release** - **[Version 1.9.0](docs/changelogs/1.9.x/1.9.0.md) - ✨ Feature Release** ## 1.8.x diff --git a/README.md b/README.md index 3a87ac27f6..f09f5a7d90 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ pokeemerald-expansion is a decomp hack base project based off pret's [pokeemeral If you use pokeemerald-expansion in your hack, please add RHH (Rom Hacking Hideout) to your credits list. Optionally, you can list the version used, so it can help players know what features to expect. You can phrase it as the following: ``` -Based off RHH's pokeemerald-expansion 1.9.0 https://github.com/rh-hideout/pokeemerald-expansion/ +Based off RHH's pokeemerald-expansion 1.9.1 https://github.com/rh-hideout/pokeemerald-expansion/ ``` ## What features are included? diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 0e065d018e..603fa225db 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -12,10 +12,10 @@ - [How to add a new move](./how_to_new_move.md) - [How to add a new trainer class](./how_to_trainer_class.md) - [How to add a new Pokémon]() - - [v1.9.0](./how_to_new_pokemon_1_9_0.md) - - [v1.8.0](./how_to_new_pokemon_1_8_0.md) - - [v1.7.0](./how_to_new_pokemon_1_7_0.md) - - [v1.6.0](./how_to_new_pokemon_1_6_0.md) + - [v1.9.x](./how_to_new_pokemon_1_9_0.md) + - [v1.8.x](./how_to_new_pokemon_1_8_0.md) + - [v1.7.x](./how_to_new_pokemon_1_7_0.md) + - [v1.6.x](./how_to_new_pokemon_1_6_0.md) - [How to use the Testing System](./how_to_testing_system.md) - [Changelog](./CHANGELOG.md) - [1.9.x]() diff --git a/docs/changelogs/1.9.x/1.9.1.md b/docs/changelogs/1.9.x/1.9.1.md new file mode 100644 index 0000000000..8393727c2a --- /dev/null +++ b/docs/changelogs/1.9.x/1.9.1.md @@ -0,0 +1,140 @@ +# Version 1.9.1 + +```md +## How to update +- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`. +- Once you have your remote set up, run the command `git pull RHH expansion/1.9.1`. +``` + +## 🌋 *REFACTORS* 🌋 +* Removed `ENDTURN_RETALIATE` in [#5182](https://github.com/rh-hideout/pokeemerald-expansion/pull/5182) +* Removed `ENDTURN_WEATHER_FORM` and `allowedToChangeFormInWeather` in [#5171](https://github.com/rh-hideout/pokeemerald-expansion/pull/5171) + +## 🧬 General 🧬 +### Added +* Move Relearner UI now displays move category by @kittenchilly in [#5081](https://github.com/rh-hideout/pokeemerald-expansion/pull/5081) +### Fixed +* Fixes wrong padding field in `SpeciesInfo` struct by @AlexOn1ine in [#5139](https://github.com/rh-hideout/pokeemerald-expansion/pull/5139) +* Fixed specific tiles changing to PC tiles when using Box Link/Debug PC option by @cawtds in [#5141](https://github.com/rh-hideout/pokeemerald-expansion/pull/5141) + +## 🐉 Pokémon 🐉 +### Fixed +* Fixed stray transparent pixels in Urshifu sprites by @hedara90 in [#5071](https://github.com/rh-hideout/pokeemerald-expansion/pull/5071) +* Fixed `bufferspeciesname` not working for species IDs over 1023 by @SBird1337 in [#5088](https://github.com/rh-hideout/pokeemerald-expansion/pull/5088) +* Fixed overworld Pokémon breaking for species IDs above 1535 by @hedara90, @mrgriffin and +@SarnPoke in [#5179](https://github.com/rh-hideout/pokeemerald-expansion/pull/5179) +* Fixed overworld palettes for multiple species by @hedara90 in [#5107](https://github.com/rh-hideout/pokeemerald-expansion/pull/5107) + * Dialga Origin (Normal and Shiny) + * Palkia Origin (Normal and Shiny) + * Giratina Origin (shiny palette fixed by @hedara90 in [#5108](https://github.com/rh-hideout/pokeemerald-expansion/pull/5108)) + * Xerneas Neutral/Active (Normal and Shiny) + * Enamorus Incarnate/Therian (Normal and Shiny) +* Fixed/added missing Pokémon sprites and palettes by @Cafeei in [#5126](https://github.com/rh-hideout/pokeemerald-expansion/pull/5126) + * Overworld: + * Shiny Sneasler, Morelul, Bounsweet, Bruxish, Guzzlord, Regieleki, Zacian, Zamazenta + * Hisuian Zorua sprite + * Shiny Summer Sawsbuck + * Shiny Galarian Yamask, Darumaka, Zigzagoon, Zapdos, Ponyta, Rapidash, Slowpoke, Farfetch'd, Weezing, Mr. Mime, Articuno, Moltres, Slowking, Stunfisk, Darmanitan + * Shiny Hisuian Sneasel, Qwilfish, Samurott, + * Battle sprites: + * Shiny Sneasler, Cursola, Pincurchin, Runerigus + * Shiny Galarian Yamask, Darumaka +* Fixed Unown Overworld follower sprites by Sarn by @hedara90 in [#5146](https://github.com/rh-hideout/pokeemerald-expansion/pull/5146) + +## ⚔️ Battle General ⚔️ +### Changed +* Set new animation particles by default to off by @AlexOn1ine in [#5161](https://github.com/rh-hideout/pokeemerald-expansion/pull/5161) +### Fixed +* Fixed speed ties by @mrgriffin in [#4780](https://github.com/rh-hideout/pokeemerald-expansion/pull/4780) + * Cleanup by @hedara90 in [#5092](https://github.com/rh-hideout/pokeemerald-expansion/pull/5092) +* Fixed Defiant/Competitive not working after the battler enters the field with a Court Changed Sticky Web on its side of the field by @PhallenTree in [#5093](https://github.com/rh-hideout/pokeemerald-expansion/pull/5093) +* Fixed `trainerproc` not properly parsing line markers, which caused erroring lines to be offset by @mrgriffin in [#5122](https://github.com/rh-hideout/pokeemerald-expansion/pull/5122) +* Fixed initial Zigzagoon battle being able to use a Gimmick by @AlexOn1ine in [#5129](https://github.com/rh-hideout/pokeemerald-expansion/pull/5129) +* Fixed incorrect rounding when `maxHP` is lower than 16 by @hedara90 in [#5183](https://github.com/rh-hideout/pokeemerald-expansion/pull/5183) + * This caused these Pokémon to not be hurt by Sandstorm/Hail. +* Fixes UB in `Cmd_averagestats` by @mrgriffin and @AlexOn1ine in [#5191](https://github.com/rh-hideout/pokeemerald-expansion/pull/5191) + +## 🤹 Moves 🤹 +### Added +* Added move animations for multiple moves by @TheTrueSadfish in [#5159](https://github.com/rh-hideout/pokeemerald-expansion/pull/5159) + * Spin Out, Mortal Spin, Fillet Away, Flower Trick, Make It Rain, Shed Tail, Hyper Drill, Twin Beam, Comeuppance, Blood Moon, Fickle Beam, Thunder Clap, Hard Press, Dragon Cheer, Malignant Chain. + * Purple chains by ogwon on Discord, beam by @TheTrueSadfish and livra on Discord. +### Changed +* Adjusted Raging Bull's animation to include Brick Break's wall break effect by @TheTrueSadfish in [#5159](https://github.com/rh-hideout/pokeemerald-expansion/pull/5159) +### Fixed +* Fixed non-grass Ivy Cudgel breaking battle UI by @hedara90 in [#5117](https://github.com/rh-hideout/pokeemerald-expansion/pull/5117) +* Fixes Stomping Tantrum effect not doubling power in certain situations by @AlexOn1ine in [#5140](https://github.com/rh-hideout/pokeemerald-expansion/pull/5140) +* Fixed Fickle Beam's description by @PhallenTree in [#5093](https://github.com/rh-hideout/pokeemerald-expansion/pull/5093) +* Fixed Revelation Dance interactions with Z-Move, Roost and typeless mons by @PhallenTree in [#5133](https://github.com/rh-hideout/pokeemerald-expansion/pull/5133) +* Fixes Poltergeist missing its accuracy check by @AlexOn1ine in [#5168](https://github.com/rh-hideout/pokeemerald-expansion/pull/5168) +* Fixed Fickle Beam not showing its message by @TheTrueSadfish in [#5159](https://github.com/rh-hideout/pokeemerald-expansion/pull/5159) +* Fixed Retaliate not working correctly if the party member fainted via passive damage during end of turn by @hedara90 in [#5182](https://github.com/rh-hideout/pokeemerald-expansion/pull/5182) +* Fixed Flame Burst's passive damage being based off current HP rather than Max HP by @hedara90 in [#5182](https://github.com/rh-hideout/pokeemerald-expansion/pull/5182) +* Fixed using Population Bomb with Loaded Dice printing garbage text by @kittenchilly in [#5195](https://github.com/rh-hideout/pokeemerald-expansion/pull/5195) + +## 🎭 Abilities 🎭 +### Added +* Added in-battle effect of Pickup by @PhallenTree in [#5170](https://github.com/rh-hideout/pokeemerald-expansion/pull/5170) +### Fixed +* Fixes Purifying Salt not halving damage for dynamic move types by @AlexOn1ine in [#5145](https://github.com/rh-hideout/pokeemerald-expansion/pull/5145) +* Fixed Dancer-called moves not changing their type based on the new user by @PhallenTree in [#5133](https://github.com/rh-hideout/pokeemerald-expansion/pull/5133) +* Fixed Ice Face not regenerating after switching in during Hail/Snow by @hedara90 in [#5171](https://github.com/rh-hideout/pokeemerald-expansion/pull/5171) +* Fixed Wind Rider not activating when switched in while Tailwind is active on the user's side of the field activation and tests by @PhallenTree in https://github.com/rh-hideout/pokeemerald-expansion/pull/5207 + +## 🧶 Items 🧶 +### Added +* Added Dowsing Machine's expanded name by @kittenchilly in [#5134](https://github.com/rh-hideout/pokeemerald-expansion/pull/5134) +### Fixed +* Fixes Booster Energy not increasing speed by @AlexOn1ine in [#5167](https://github.com/rh-hideout/pokeemerald-expansion/pull/5167) + +## 🤖 Battle AI 🤖 +### Changed +* Adjusted AI calculation for Triple Kick Effect by @AlexOn1ine in [#5127](https://github.com/rh-hideout/pokeemerald-expansion/pull/5127) +### Fixed +* Fix Switch AI Bug: AI never switching out when it could be OHKO'd by @Pawkkie in [#5089](https://github.com/rh-hideout/pokeemerald-expansion/pull/5089) +* Adds missing AI checks for poltergeist by @AlexOn1ine in [#5189](https://github.com/rh-hideout/pokeemerald-expansion/pull/5189) + +## 🧹 Other Cleanup 🧹 +* `IsValidForBattle` function formatting by @AlexOn1ine in [#5085](https://github.com/rh-hideout/pokeemerald-expansion/pull/5085) +* Opportunist/Mirror Herb cleanup by @AlexOn1ine in [#5120](https://github.com/rh-hideout/pokeemerald-expansion/pull/5120) + * Cleanup by @AlexOn1ine in [#5158](https://github.com/rh-hideout/pokeemerald-expansion/pull/5158) +* Remove trailing whitespace (master) by @AsparagusEduardo in [#5174](https://github.com/rh-hideout/pokeemerald-expansion/pull/5174) + +## 🧪 Test Runner 🧪 +### Added +* Added missing Move Effect TODO tests - Volume C by @AsparagusEduardo in [#5094](https://github.com/rh-hideout/pokeemerald-expansion/pull/5094) +* Added multiple missing ability TODO tests by @AsparagusEduardo in [#5163](https://github.com/rh-hideout/pokeemerald-expansion/pull/5163) +* Added missing Guard/Power split tests by @mrgriffin and @AlexOn1ine in [#5191](https://github.com/rh-hideout/pokeemerald-expansion/pull/5191) +* Added missing Harvest and Pickup tests by @PhallenTree in [#5170](https://github.com/rh-hideout/pokeemerald-expansion/pull/5170) +* Added missing Round tests by @hedara90 in https://github.com/rh-hideout/pokeemerald-expansion/pull/5196 +* Added missing Wind Rider tests by @PhallenTree in https://github.com/rh-hideout/pokeemerald-expansion/pull/5207 +### Changed +* Fixed G-Max Replenish not considering Gen 5+ Pickup by @PhallenTree in [#5170](https://github.com/rh-hideout/pokeemerald-expansion/pull/5170) +### Fixed +* Fixed `RandomUniformExcept` not being exclusive on the higher boundary by @PhallenTree in [#5170](https://github.com/rh-hideout/pokeemerald-expansion/pull/5170) + + +## 📚 Documentation 📚 +* Added guide to running documentation website locally by @AsparagusEduardo in [#5059](https://github.com/rh-hideout/pokeemerald-expansion/pull/5059) +* How to docs and fixes to be added to the mdbook documentation site by @anrichtait in [#5070](https://github.com/rh-hideout/pokeemerald-expansion/pull/5070) +* Improved 1.8 ⇒ 1.9 non-Competitive syntax migration instructions by @mrgriffin in [#5079](https://github.com/rh-hideout/pokeemerald-expansion/pull/5079) + +## 📦 Branch Synchronisation 📦 +### pret +* 5th of August in [#5098](https://github.com/rh-hideout/pokeemerald-expansion/pull/5098) + * Fixed bottom half of Mt. Pyre not being labeled in PokeNav by @fdeblasio in [pret#2018](https://github.com/pret/pokeemerald/pull/2018) +* 7th of August in [#5116](https://github.com/rh-hideout/pokeemerald-expansion/pull/5116) + * Changed type1 and type2 to be consistent by @pkmnsnfrn in [pret#2021](https://github.com/pret/pokeemerald/pull/2021) +* 14th of August in [#5165](https://github.com/rh-hideout/pokeemerald-expansion/pull/5165) + * Fix type for offset in MapConnection by @GriffinRichards in [pret#2011](https://github.com/pret/pokeemerald/pull/2011) +### Followers +* 7th of August in [#5110](https://github.com/rh-hideout/pokeemerald-expansion/pull/5110) + * Fixed expanded OW IDs by @pkmnsnfrn in [aarant#38](https://github.com/aarant/pokeemerald/pull/38) + * Fix two small text errors in follower dialogue by @Bassoonian in [aarant#39](https://github.com/aarant/pokeemerald/pull/39) + +**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.9.0...expansion/1.9.1 + +## New Contributors +* @TheTrueSadfish made their first contribution in https://github.com/rh-hideout/pokeemerald-expansion/pull/5159 + + diff --git a/docs/changelogs/template.md b/docs/changelogs/template.md index 6641d612f3..a40afebad3 100644 --- a/docs/changelogs/template.md +++ b/docs/changelogs/template.md @@ -122,7 +122,10 @@ ### Fixed * N/A -## 📦 Pret merges 📦 +## 📦 Branch Synchronisation 📦 +### pret's base pokeemerald +* N/A +### merrp/aarant's followers * N/A diff --git a/include/constants/expansion.h b/include/constants/expansion.h index ad79d584cb..9fc3a6fe73 100644 --- a/include/constants/expansion.h +++ b/include/constants/expansion.h @@ -1,13 +1,13 @@ #ifndef GUARD_CONSTANTS_EXPANSION_H #define GUARD_CONSTANTS_EXPANSION_H -// 1.9.0 +// 1.9.1 #define EXPANSION_VERSION_MAJOR 1 #define EXPANSION_VERSION_MINOR 9 #define EXPANSION_VERSION_PATCH 1 // FALSE if this this version of Expansion is not a tagged commit, i.e. // it contains unreleased changes. -#define EXPANSION_TAGGED_RELEASE FALSE +#define EXPANSION_TAGGED_RELEASE TRUE #endif From becb2fcac839a36df868297a8945ec51f32123ad Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Mon, 19 Aug 2024 18:29:48 -0400 Subject: [PATCH 46/64] Start 1.9.2 cycle --- include/constants/expansion.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/constants/expansion.h b/include/constants/expansion.h index 9fc3a6fe73..caf7e4ddab 100644 --- a/include/constants/expansion.h +++ b/include/constants/expansion.h @@ -4,10 +4,10 @@ // 1.9.1 #define EXPANSION_VERSION_MAJOR 1 #define EXPANSION_VERSION_MINOR 9 -#define EXPANSION_VERSION_PATCH 1 +#define EXPANSION_VERSION_PATCH 2 // FALSE if this this version of Expansion is not a tagged commit, i.e. // it contains unreleased changes. -#define EXPANSION_TAGGED_RELEASE TRUE +#define EXPANSION_TAGGED_RELEASE FALSE #endif From a111ac496d08d580bcb83998a0e0a678acec53d6 Mon Sep 17 00:00:00 2001 From: Pawkkie <61265402+Pawkkie@users.noreply.github.com> Date: Tue, 20 Aug 2024 06:44:27 -0400 Subject: [PATCH 47/64] Fix typos (#5221) Fix typos in move description of Decorate, Collision Course and Electro Drift --- src/data/moves_info.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/data/moves_info.h b/src/data/moves_info.h index bec17632ec..08579f274f 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -17470,7 +17470,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .name = COMPOUND_STRING("Decorate"), .description = COMPOUND_STRING( "The user sharply raises\n" - "the target's Atk and Sp.Atk"), + "the target's Atk and Sp.Atk."), .effect = EFFECT_DECORATE, .power = 0, .type = TYPE_FAIRY, @@ -19739,7 +19739,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .name = HANDLE_EXPANDED_MOVE_NAME("ColisinCours", "Collision Course"), .description = COMPOUND_STRING( "Prehistoric explosion that's\n" - "stronger if supereffective."), + "stronger if super effective."), .effect = EFFECT_COLLISION_COURSE, .power = 100, .type = TYPE_FIGHTING, @@ -19758,7 +19758,7 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] = .name = HANDLE_EXPANDED_MOVE_NAME("ElectroDrift", "Electro Drift"), .description = COMPOUND_STRING( "Futuristic electricity. It's\n" - "stronger if supereffective."), + "stronger if super effective."), .effect = EFFECT_COLLISION_COURSE, .power = 100, .type = TYPE_ELECTRIC, From af12697845f83b2a9984556af436c9668a938c5a Mon Sep 17 00:00:00 2001 From: psf <77138753+pkmnsnfrn@users.noreply.github.com> Date: Tue, 20 Aug 2024 04:23:33 -0700 Subject: [PATCH 48/64] Adds OW_BERRY_IMMORTAL (#5187) * Added OW_BERRY_IMMORTAL Added cases for OW_BERRY_IMMORTAL * removed one preproc * removed other preproc * Fixed identation * Set config to FALSE * Update include/config/overworld.h per https://github.com/rh-hideout/pokeemerald-expansion/pull/5187#discussion_r1720747388 Co-authored-by: Bassoonian * Reordered condition per https://github.com/rh-hideout/pokeemerald-expansion/pull/5187\#discussion_r1720747652 * Update include/config/overworld.h --------- Co-authored-by: Bassoonian --- include/config/overworld.h | 1 + src/berry.c | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/config/overworld.h b/include/config/overworld.h index b47cef5c50..63479f1831 100644 --- a/include/config/overworld.h +++ b/include/config/overworld.h @@ -33,6 +33,7 @@ #define OW_BERRY_GROWTH_RATE GEN_3 // Presets for how long each Berry plant takes to grow. #define OW_BERRY_YIELD_RATE GEN_3 // Presets for how many Berries each plant can yield. #define OW_BERRY_DRAIN_RATE GEN_6_ORAS // If OW_BERRY_MOISTURE is enabled, this setting changes how fast the soil dries out. GEN_4 uses a Berry-dependent drain rate, GEN_6_XY dries out in 24 hours (4 hours with the relevant Mulch) and GEN_6_ORAS dries out in 4 hours. Other values are illegal. +#define OW_BERRY_IMMORTAL FALSE // If enabled, once a Berry tree has grown a Berry, the tree will not disappear until picked by the player. // Overworld Pokémon #define OW_POKEMON_OBJECT_EVENTS TRUE // Adds Object Event fields for every species. Can be used for NPCs using the OBJ_EVENT_GFX_SPECIES macro (eg. OBJ_EVENT_GFX_SPECIES(BULBASAUR)) diff --git a/src/berry.c b/src/berry.c index 9f187bd1e2..1a1c3b7f1f 100644 --- a/src/berry.c +++ b/src/berry.c @@ -1817,6 +1817,8 @@ bool32 BerryTreeGrow(struct BerryTree *tree) tree->stage = BERRY_STAGE_BERRIES; break; case BERRY_STAGE_BERRIES: + if (OW_BERRY_IMMORTAL) + break; tree->watered = 0; tree->berryYield = 0; tree->stage = BERRY_STAGE_SPROUTED; @@ -1842,16 +1844,16 @@ static u16 GetMulchAffectedGrowthRate(u16 berryDuration, u8 mulch, u8 stage) void BerryTreeTimeUpdate(s32 minutes) { int i; - u8 drainVal; + u32 drainVal; struct BerryTree *tree; for (i = 0; i < BERRY_TREES_COUNT; i++) { tree = &gSaveBlock1Ptr->berryTrees[i]; - if (tree->berry && tree->stage && !tree->stopGrowth) + if (tree->berry && tree->stage && !tree->stopGrowth && (!OW_BERRY_IMMORTAL || tree->stage != BERRY_STAGE_BERRIES)) { - if (minutes >= GetStageDurationByBerryType(tree->berry) * 71) + if ((!OW_BERRY_IMMORTAL) && (minutes >= GetStageDurationByBerryType(tree->berry) * 71)) { *tree = gBlankBerryTree; } From bde69828909cfe2edbda93a0065fc836e95b1cbf Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Tue, 20 Aug 2024 13:24:48 +0200 Subject: [PATCH 49/64] =?UTF-8?q?Fixes=20weather=20abilities=20not=20activ?= =?UTF-8?q?ating=20when=20Cloud=20Nine=20user=20leaves=20th=E2=80=A6=20(#5?= =?UTF-8?q?209)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixes weather abilities not activating when Cloud Nine user leaves the field * parametrize --- data/battle_scripts_1.s | 4 ++-- src/battle_script_commands.c | 29 +++++++++++++++++++++-------- src/battle_util.c | 13 +++++++------ test/battle/ability/forecast.c | 22 ++++++++++++++++++++++ 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 95fffd0513..083143bdf2 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -7150,7 +7150,7 @@ BattleScript_TargetFormChangeWithStringNoPopup:: BattleScript_BattlerFormChangeWithStringEnd3:: pause 5 - call BattleScript_AbilityPopUp + call BattleScript_AbilityPopUpScripting flushtextbox handleformchange BS_SCRIPTING, 0 handleformchange BS_SCRIPTING, 1 @@ -8010,7 +8010,7 @@ BattleScript_DeltaStreamActivates:: end3 BattleScript_ProtosynthesisActivates:: - call BattleScript_AbilityPopUp + call BattleScript_AbilityPopUpScripting printstring STRINGID_SUNLIGHTACTIVATEDABILITY waitmessage B_WAIT_TIME_MED printstring STRINGID_STATWASHEIGHTENED diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 9165d7b7e4..efa841a631 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7292,19 +7292,32 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler) gDisableStructs[battler].truantSwitchInHack = 0; - for (i = 0; i < gBattlersCount; i++) - { - if (i != battler - && GetBattlerAbility(i) == ABILITY_TRACE - && AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, i, 0, 0, 0)) - return TRUE; - } - if (DoSwitchInAbilities(battler) || ItemBattleEffects(ITEMEFFECT_ON_SWITCH_IN, battler, FALSE)) return TRUE; else if (AbilityBattleEffects(ABILITYEFFECT_OPPORTUNIST, battler, 0, 0, 0)) return TRUE; + for (i = 0; i < gBattlersCount; i++) + { + if (i == battler) + continue; + + switch (GetBattlerAbility(i)) + { + case ABILITY_TRACE: + if (AbilityBattleEffects(ABILITYEFFECT_ON_SWITCHIN, i, 0, 0, 0)) + return TRUE; + break; + case ABILITY_FORECAST: + case ABILITY_FLOWER_GIFT: + case ABILITY_ICE_FACE: + case ABILITY_PROTOSYNTHESIS: + if (AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, i, 0, 0, 0)) + return TRUE; + break; + } + } + gDisableStructs[battler].stickyWebDone = FALSE; gDisableStructs[battler].spikesDone = FALSE; gDisableStructs[battler].toxicSpikesDone = FALSE; diff --git a/src/battle_util.c b/src/battle_util.c index f489ea6258..b133b7c629 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -4767,7 +4767,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 } break; case ABILITY_WIND_RIDER: - if (!gSpecialStatuses[battler].switchInAbilityDone + if (!gSpecialStatuses[battler].switchInAbilityDone && CompareStat(battler, STAT_ATK, MAX_STAT_STAGE, CMP_LESS_THAN) && gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_TAILWIND) { @@ -6269,17 +6269,17 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 } break; case ABILITYEFFECT_ON_WEATHER: // For ability effects that activate when the battle weather changes. - battler = gBattlerAbility = gBattleScripting.battler; gLastUsedAbility = GetBattlerAbility(battler); switch (gLastUsedAbility) { case ABILITY_FORECAST: case ABILITY_FLOWER_GIFT: if ((IsBattlerWeatherAffected(battler, gBattleWeather) - || gBattleWeather == B_WEATHER_NONE - || !WEATHER_HAS_EFFECT) // Air Lock active - && TryBattleFormChange(battler, FORM_CHANGE_BATTLE_WEATHER)) + || gBattleWeather == B_WEATHER_NONE + || !WEATHER_HAS_EFFECT) // Air Lock active + && TryBattleFormChange(battler, FORM_CHANGE_BATTLE_WEATHER)) { + gBattleScripting.battler = battler; BattleScriptPushCursorAndCallback(BattleScript_BattlerFormChangeWithStringEnd3); effect++; } @@ -6290,6 +6290,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED)) { // TODO: Convert this to a proper FORM_CHANGE type. + gBattleScripting.battler = battler; gBattleMons[battler].species = SPECIES_EISCUE_ICE_FACE; BattleScriptPushCursorAndCallback(BattleScript_BattlerFormChangeWithStringEnd3); effect++; @@ -6300,7 +6301,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 { gDisableStructs[battler].weatherAbilityDone = TRUE; PREPARE_STAT_BUFFER(gBattleTextBuff1, GetHighestStatId(battler)); - gBattlerAbility = gBattleScripting.battler = battler; + gBattleScripting.battler = battler; BattleScriptPushCursorAndCallback(BattleScript_ProtosynthesisActivates); effect++; } diff --git a/test/battle/ability/forecast.c b/test/battle/ability/forecast.c index 296c123dbd..24a0eed957 100644 --- a/test/battle/ability/forecast.c +++ b/test/battle/ability/forecast.c @@ -397,3 +397,25 @@ SINGLE_BATTLE_TEST("Forecast transforms Castform back when it uses a move that f EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_CASTFORM); } } + +SINGLE_BATTLE_TEST("Forecast transforms Castform when Cloud Nine ability user leaves the field") +{ + u32 species = 0, ability = 0; + PARAMETRIZE { species = SPECIES_PSYDUCK; ability = ABILITY_CLOUD_NINE; } + PARAMETRIZE { species = SPECIES_RAYQUAZA; ability = ABILITY_AIR_LOCK; } + + GIVEN { + PLAYER(SPECIES_CASTFORM) { Ability(ABILITY_FORECAST); } + OPPONENT(species) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SUNNY_DAY); MOVE(opponent, MOVE_CELEBRATE); } + TURN { SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SUNNY_DAY, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); + MESSAGE("2 sent out Wobbuffet!"); + ABILITY_POPUP(player, ABILITY_FORECAST); + MESSAGE("Castform transformed!"); + } +} From d379ffef3e86f38739e95827cca3daa2cacac0bc Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Tue, 20 Aug 2024 14:24:42 +0200 Subject: [PATCH 50/64] Fixed Confide+Crafty Shield interaction (#5202) Co-authored-by: Hedara --- src/battle_util.c | 17 ++++---- test/battle/move_effect/protect.c | 65 +++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 8 deletions(-) diff --git a/src/battle_util.c b/src/battle_util.c index b133b7c629..c2e05cbd4e 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -8560,16 +8560,20 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move) // Protective Pads doesn't stop Unseen Fist from bypassing Protect effects, so IsMoveMakingContact() isn't used here. // This means extra logic is needed to handle Shell Side Arm. if (GetBattlerAbility(gBattlerAttacker) == ABILITY_UNSEEN_FIST - && (gMovesInfo[move].makesContact - || (gMovesInfo[move].effect == EFFECT_SHELL_SIDE_ARM && gBattleStruct->shellSideArmCategory[battlerAtk][battlerDef] == DAMAGE_CATEGORY_PHYSICAL)) - && !gProtectStructs[battlerDef].maxGuarded) // Max Guard cannot be bypassed by Unseen Fist + && (gMovesInfo[move].makesContact + || (gMovesInfo[move].effect == EFFECT_SHELL_SIDE_ARM + && gBattleStruct->shellSideArmCategory[battlerAtk][battlerDef] == DAMAGE_CATEGORY_PHYSICAL)) + && !gProtectStructs[battlerDef].maxGuarded) // Max Guard cannot be bypassed by Unseen Fist return FALSE; + else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_CRAFTY_SHIELD + && IS_MOVE_STATUS(move)) + return TRUE; else if (gMovesInfo[move].ignoresProtect) return FALSE; else if (gProtectStructs[battlerDef].protected) return TRUE; else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_WIDE_GUARD - && GetBattlerMoveTargetType(gBattlerAttacker, move) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) + && GetBattlerMoveTargetType(gBattlerAttacker, move) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY)) return TRUE; else if (gProtectStructs[battlerDef].banefulBunkered) return TRUE; @@ -8586,11 +8590,8 @@ bool32 IsBattlerProtected(u32 battlerAtk, u32 battlerDef, u32 move) else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_QUICK_GUARD && GetChosenMovePriority(gBattlerAttacker) > 0) return TRUE; - else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_CRAFTY_SHIELD - && IS_MOVE_STATUS(move)) - return TRUE; else if (gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_MAT_BLOCK - && !IS_MOVE_STATUS(move)) + && !IS_MOVE_STATUS(move)) return TRUE; else return FALSE; diff --git a/test/battle/move_effect/protect.c b/test/battle/move_effect/protect.c index 973033bc33..aca5ef859d 100644 --- a/test/battle/move_effect/protect.c +++ b/test/battle/move_effect/protect.c @@ -482,3 +482,68 @@ DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from status moves") } } } + +SINGLE_BATTLE_TEST("Protect does not block Confide") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_CONFIDE); } + } SCENE { + MESSAGE("Wobbuffet used Confide!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CONFIDE, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + NOT MESSAGE("Foe Wobbuffet protected itself!"); + } +} + +DOUBLE_BATTLE_TEST("Crafty Shield protects self and ally from Confide") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_CONFIDE].effect == EFFECT_SPECIAL_ATTACK_DOWN); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(opponentLeft, MOVE_CRAFTY_SHIELD); MOVE(playerLeft, MOVE_CONFIDE, target: opponentLeft); MOVE(playerRight, MOVE_CONFIDE, target: opponentRight); } + } SCENE { + MESSAGE("Wobbuffet used Confide!"); + MESSAGE("Foe Wobbuffet protected itself!"); + MESSAGE("Wynaut used Confide!"); + MESSAGE("Foe Wynaut protected itself!"); + } +} + +DOUBLE_BATTLE_TEST("Crafty Shield does not protect against moves that target all battlers") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_FLOWER_SHIELD].target == MOVE_TARGET_ALL_BATTLERS); + ASSUME(gSpeciesInfo[SPECIES_TANGELA].types[0] == TYPE_GRASS); + ASSUME(gSpeciesInfo[SPECIES_TANGROWTH].types[0] == TYPE_GRASS); + ASSUME(gSpeciesInfo[SPECIES_SUNKERN].types[0] == TYPE_GRASS); + ASSUME(gSpeciesInfo[SPECIES_SUNFLORA].types[0] == TYPE_GRASS); + PLAYER(SPECIES_TANGELA); + PLAYER(SPECIES_TANGROWTH); + OPPONENT(SPECIES_SUNKERN); + OPPONENT(SPECIES_SUNFLORA); + } WHEN { + TURN { MOVE(opponentLeft, MOVE_CRAFTY_SHIELD); MOVE(opponentRight, MOVE_CELEBRATE); MOVE(playerLeft, MOVE_FLOWER_SHIELD); MOVE(playerRight, MOVE_CELEBRATE); } + } SCENE { + MESSAGE("Tangela used Flower Shield!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerLeft); + MESSAGE("Tangela's Defense rose!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); + MESSAGE("Foe Sunkern's Defense rose!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, playerRight); + MESSAGE("Tangrowth's Defense rose!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLOWER_SHIELD, playerLeft); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight); + MESSAGE("Foe Sunflora's Defense rose!"); + } +} From bd38c64f298ea64c1b1051181f1aaa7ec1697cd8 Mon Sep 17 00:00:00 2001 From: kittenchilly Date: Tue, 20 Aug 2024 13:16:32 -0500 Subject: [PATCH 51/64] New Garganacl and Naclstack battle sprite + various battle sprite fixes (#5142) Garganacl, Spidops, Wattrel, Kilowattrel, Shroodle, Bombirdier, Orthworm, Veluza, Aerodactyl-Mega, Medicham-Mega, Latis-Mega, Diancie-Mega, Ponyta-Galar, Rapidash-Galar, Magearna, Landorus. --- graphics/pokemon/absol/mega/front.png | Bin 1028 -> 1001 bytes graphics/pokemon/aerodactyl/mega/front.png | Bin 1135 -> 1070 bytes graphics/pokemon/bombirdier/front.png | Bin 897 -> 877 bytes graphics/pokemon/diancie/mega/back.png | Bin 934 -> 856 bytes graphics/pokemon/diancie/mega/front.png | Bin 1171 -> 1118 bytes graphics/pokemon/diancie/mega/normal.pal | 30 ++++++++-------- graphics/pokemon/diancie/mega/shiny.pal | 30 ++++++++-------- graphics/pokemon/garganacl/back.png | Bin 526 -> 621 bytes graphics/pokemon/garganacl/front.png | Bin 837 -> 951 bytes graphics/pokemon/garganacl/normal.pal | 30 ++++++++-------- graphics/pokemon/garganacl/shiny.pal | 30 ++++++++-------- graphics/pokemon/kilowattrel/back.png | Bin 550 -> 535 bytes graphics/pokemon/kilowattrel/front.png | Bin 608 -> 593 bytes graphics/pokemon/kilowattrel/shiny.pal | 4 +-- graphics/pokemon/landorus/anim_front.png | Bin 1501 -> 1491 bytes graphics/pokemon/landorus/back.png | Bin 948 -> 885 bytes graphics/pokemon/landorus/normal.pal | 6 ++-- graphics/pokemon/landorus/shiny.pal | 32 +++++++++--------- graphics/pokemon/latias/mega/front.png | Bin 975 -> 897 bytes graphics/pokemon/latios/mega/front.png | Bin 975 -> 897 bytes graphics/pokemon/magearna/back.png | Bin 716 -> 646 bytes graphics/pokemon/magearna/shiny.pal | 20 +++++------ graphics/pokemon/medicham/mega/back.png | Bin 792 -> 909 bytes graphics/pokemon/medicham/mega/front.png | Bin 1002 -> 889 bytes graphics/pokemon/medicham/mega/normal.pal | 32 +++++++++--------- graphics/pokemon/medicham/mega/shiny.pal | 32 +++++++++--------- graphics/pokemon/naclstack/back.png | Bin 555 -> 389 bytes graphics/pokemon/naclstack/front.png | Bin 711 -> 551 bytes graphics/pokemon/naclstack/normal.pal | 30 ++++++++-------- graphics/pokemon/naclstack/shiny.pal | 32 ++++++++++-------- graphics/pokemon/orthworm/front.png | Bin 700 -> 698 bytes graphics/pokemon/ponyta/galarian/back.png | Bin 721 -> 661 bytes graphics/pokemon/ponyta/galarian/shiny.pal | 14 ++++---- graphics/pokemon/rapidash/galarian/back.png | Bin 738 -> 663 bytes graphics/pokemon/rapidash/galarian/shiny.pal | 6 ++-- graphics/pokemon/salamence/anim_front.png | Bin 1519 -> 1458 bytes graphics/pokemon/salamence/mega/front.png | Bin 1102 -> 984 bytes graphics/pokemon/shroodle/back.png | Bin 402 -> 387 bytes graphics/pokemon/shroodle/front.png | Bin 396 -> 381 bytes graphics/pokemon/shroodle/shiny.pal | 20 +++++------ graphics/pokemon/spidops/front.png | Bin 800 -> 766 bytes graphics/pokemon/veluza/front.png | Bin 698 -> 574 bytes graphics/pokemon/wattrel/back.png | Bin 554 -> 437 bytes graphics/pokemon/wattrel/front.png | Bin 625 -> 492 bytes .../pokemon/species_info/gen_9_families.h | 6 ++-- 45 files changed, 179 insertions(+), 175 deletions(-) diff --git a/graphics/pokemon/absol/mega/front.png b/graphics/pokemon/absol/mega/front.png index e7656154da2a58a0892486f637a9751924d2feff..bc89ac2de0f156fca489866bf0ac589db5cb6ebb 100644 GIT binary patch delta 933 zcmV;W16urq2c0004VQb$4nuFf3kkv=|u17}G@K~z|U&6bOf z;~)%0V?)4U=l{QV{o<7bT4}V>B2C*#xCh%9o8$N&27rDcemC#=JlKnPejxb72j^P= z1epkR`U4Qpb59Te7=c(}Mn~72OPl^1q_r0jfS!!MOehfSB9$AxwICmH3J3 z7X%KH$Yh#-zzpDjr+DrG!AF)qfHa0sURM1p0DRrbfc)^F=|@0IOqlgaU4Su)U4N1d z(N`Fl;ckCODT~qR6+q<6Fk%GQu=vTyc?v?;50+wer|VPI^O&;P0oSO105YreLkArX zz!l>NNR?2NPYiF%(-RO)pM<5p7I}(b8OVu{=0PZ<1EK+cvhStF5l?>9PS8#76CFV_ zAfoL=1z7Gj1plO4-WWg#NsPg|m;5C44eUmc1k8pJ6LF2^N_jjzK4^P zs8VctCa|nX48-oXye&2#7g>u!{4O76Q5h?GF1?}HNr;nIw}#vq6^lNt{mz`L^B08-X29y9_9P~tD~QCEE| zJ^L^NWNltOWzut=7oE++$UZQEuoE&b4N7p}4q!%bkXc`kWisd4`&yB<1W7pFHr;B| zE5NcRJMohNWQBvO1F7dfBU0G{B)()PuQ`zBQ~UvcAdC*U8PE&iwt-X2{qUkM0>EV^ zIiZAR08}5Kd4L93TOlO~Mguf~52&@6>tLkqWlB;Wh6sQra0e6y@W)aQDjc?et1oZP zLGA+yplkt3=vyEFYJgItloY_F69!1o0YF@Y4q~i&M-3o*HtN-^i!th&YQ$D(0g%NO!lQSM132H||z{U5EQP(X%(iSnH-Az8j!B@!nRXA0c(ikhph=3miXcwif=5w*u%I1 zRLBb;q5!yKZrb{e8c|P%RJCPW-<##7U>CvfNWawoVGd00Uh~L_t(Y$E}pVZ__{&$1f3s#~ddat5XOB zMcv$2IT2%UB?p+QS|X!s>1uVWA_}7u8*?+Xs2R&pMgC9tuXyk5SUwk+cuO4L$KUt+ z*nhCzfU(gZ-Zduh&&jX@xQy|C0m5b6Z2?bz!qYCmVZiucPj`VHxPTg<0WM&0(g6er zKn=GR=m5O|2_RAlu$~9UVHgfu83>5M1Bhw>;&BH6v=v<06~N&L&s%`-2!QFcI!~bm zDxg2qFEnrsQI%#-3xrCkl#Peva)qA*$SdKs0EOSo(h5MsAf@~iRWXr=4_ftz9ASEY z;Kd-(>W(3>%nV>E<7+%m*dAE=6%db4$pg0~okywx`~bW#jN$b-e2!HVwybP3(sMFC zL*Qc=o&s#nGHOE&Bp4hKRt?NC4+6mBL`3{cT^|Je%nSV&7)74Nl%uN!ZUQV0cG0>) z0Q@;<0I>bQ@mS@4iux339;i7SkpRqp-~fc=B#`?WAj`AtojxXjM#07uRj%@&1{}!V zAJs&5X-f(r@dIWB%>;_YuhWVs(0>e0A@j8IuT6>DaQUqQ;%N~n8$(Q6Gum^H!|hg= zySQ``navcl+JJD6Z!2J0$ml|4aK#LB*09)Y?`Vt)TiW>RngE8GFSY?5B+^lTHciyP z1UO`g!lCjKiEX&RhtvebESt)NJVaE)3%Kk6R+@n)$U{_hx(hI-fvNUD7O}?w_P{G@ z0eR0@*U4+QPEvc>^${>G70Y!g1O$>4-6Z|Vu5aEtYbkUHj$#_v?G6o~mq_6i2&^5; z!YtHoSDJtKnaD%~JY^iu%loneq($_w z!|)tTNfA*RBXccPkvur|#b>UE{h%zL8o*R4)L0j*nN!uJqkuI~IA;7SxM~kf+5&jz z$&@MXG?(LnDS*q8Fl*ER{llMa1-h1Sm#hg_D{zT;`8GdnHqXl6V5c#EPb*c_cAABk zY8y10@x{j}eW-6FoPC?pwC>VoGkhsm=po$$+DB_|o`gR}@=De(vd2r&KbzmaN@{`r zif+k?2?U$vWG~qN4%1iXp)rqEY6Z=U@lu{|&rcq0Me{hG%kzb~`ljU*rADdscYtEu i{QbE0$o{J__8Wj}Odt*qc?P%u0000c0004VQb$4nuFf3kkv=|u1FT6zK~z|U&6ewS zqdE+QkwoMKhV=d4_GnAOmp~|I&7V=bR-3^7tgG#5`fDR1{9(Q?8Q+z8HUvLz0Yb_T z9SA@?ZUS7&Twvk)G(De=xQ-&9nWH+Hb`IMKua}gWE~ChYzP4+{ZR!ab1?xG$oe#A+ zEU(vVsZR}H1Y%!*q6ct|Dt%9}n0{G0zPnJY7XIF_?v4N%j=OkRzIOrd4-wcmiC`uw zp*`voAQAyE53WaUgy!#h5CoMK*V?MBQ;cB0GMT;u91@*LAbGeAi8O*aPrkr62OtIXT>uyHO;)%|gah;v0R2{F^j64JR6rlWk+3+y>aD1`mgWHO0KEh_0?YaKqs@VA>W>th zcam#;`x*cqLq@QKeIan@A3|D4_HV)kM6g7hX87-r1g@LFy9I4Dh`e?pJ&v464b>n~r` zzTxi{hjwi1*aNJqU4JFFaR|4pBpwr=mxQ^78Ts?hJF)wfLzb)y&)A~ zVsAA$o}dH=wx4aqFe}@>IAcHq5VyHh?`QZ3pp~HBHa{5@N}mXCZn0y{jHvVmfOde@ zYOt=DeOrqIkPc8eJ0aw_d7c4cHXJ~CJJNCS zhyer|T*wP*PN%AOo#J*v2Yocg5ulmTf?YP#qhA2QXdk!&aH(mUsKFOPZ`^L`=)E3E zAo9NfVqLX|C%81+Aaqwu8T!VGd00YQLL_t(Y$F-C(Z`(!`$4?}{XbBLSYB_YV zpF?^jb&ePTMF86eb1n;JK1l(Y6wN@Nq1!tIR8|2+=qXbWX!Dez1^OWhbP1GxfFj5z zNZofwT9jp_oqCJz_Ivh2 zp#olCi<(7J0C?$RodS}eCpEB=J)2AWL7FDD%w$ivQmj=_+X$t209m~nyHaZ4=M~VM zHG6^*sv8n2?{Q=+i@2e@Iuti;Qa}=MbjT+f z=;`nMfGmDW$7z!H>y40J1GL@7V}=K<2JpV%E-w~~#k!SVlBQvQ?x+bi zr1xxrvdYEVcAt=>-@lV0KrexJ;vXV3m-1{^1HDrWzsyC;CUJW=}V>T l85Xzx9oRZD^1ls2{sDarVx+3^&WQj3002ovPDHLkV1f{G=mh`( diff --git a/graphics/pokemon/bombirdier/front.png b/graphics/pokemon/bombirdier/front.png index 97159715f25cfccdb4311cf70ae0b1a77afa006a..b8aa83644ba1f142ff37e0e980d17ef7b4ef173b 100644 GIT binary patch delta 796 zcmV+%1LORG2ki!sBnkm@Qb$4nuFf3kks&^R0_#acK~z|Uy_SK_s~`-8g{BB9`u=Zw zPYWtK6!tH$VLGbi#(

OMX+f)Yks{TF&?&RwWiF#*OmfH_=L z18QaP#{$siJ`w<4SXRsf#> z?=(!V!g~>R0203e#KfDvumDC;hQon>R>2seriDF=yFTxuH4lW+f@Z;Y19>C5l8|t8 zcOYZ*n8BUkd}>O2IxtS!=-I(AxKr=Fx87r|EiAP31Cb!C+}?Y}8-!~P<}HJSAR4Vd zLI5%g2#>#74ss<<087!7pkF&2DBvKlT*!HszxT)!phyA$=Y${$bm~3Y=mg+@w0Fru z^ZsZ)W)gh?kmkt_T6#Wuz-b?dM$QKXK%D_0;9WiZQv*(U6uk6(x)eR~Pm>s?Fobz} z089v}0T$W?AqbxVkQ<6bQ2j5LQi+%__bTxXHl72#J9vH@L)ZNLkF=>)_Oq<;HXI(&G%+(zqV zh-Dk`F7#4Wd+E}IK<_!c08j!Ie-A^s9z4R1U!Kt9Sh2imumGAZuzu6vrYW;-{f-UrY0LcM;pP!=+dAB}WKpMOi z!O-^tvEHFLr}ja9N30k5cj9bytRMGc;+j|mFQSqm{GdE5e0f1f?QG2ON4A8JBeXb#dKXlOu zM(ADhSLi)$yU?y;2K09TT3odBx~eyZoEE4a0P;7_FBZ&%P$zN*kk0^aY(WLkAW*p0 z_m%#thC4vt0C>ydf364{Knx%oAb1NZRk$z00zl#ifSS0|R~Epi%CI`HDiAS0T3E6; z>dQVlx**gREDJdrC>!xA2@TIj2RcTV85{{dPymnHJuwS&iT zQiLo9%mN4le{7^CAPtFCo{s`GAfj&onBIap4jK(W!q?H}(Tf4}SOP(U7uo<_G6zFb zpLm%%UTVsW9n1!-h+Rx60gxK{6xnZsi_d0e;-b%oAxfBdh(kPVWKy}!qKK~|Odu2k zwh-HZ3xMi$PBCizmRnwZ1YCaRX*a~Wjd)dht*YB~e`!Xb_dG5DjKI~;U01IMkFn#s z*3x6e$!sACc$}hXJojcM$PB>q6ua?EaI+5Qtbj*-$K#3M<}HO6fXODOp`YCweQy1c zSAwhb?*N(u`o8=hwaQ=Xiv^@1a}@&pTYyy|pCJVTJJWmpYGHvmJyE{VmnziponHHQ w+UxoGC?G!~rk(sdaWTPvkuQwzt^Ydy0Vbp-S0oA0vH$=807*qoM6N<$f{K5Ai2wiq diff --git a/graphics/pokemon/diancie/mega/back.png b/graphics/pokemon/diancie/mega/back.png index cb9a177a0d55682f96e4e8930397d5d47eea1a6a..3816c40d78e86db71540b37b03a0d07003f7ce32 100644 GIT binary patch delta 845 zcmV-T1G4<42iOLX7=H)@0001;w}I>c0004VQb$4nuFf3k0000mP)t-sn9!g;JV1;s zW2QQA=2dzBbm$L2SuL@Xr2zhXHJV?AtKjM zgd*or^$M_ZbblL0>doPm@S~Sm>9pT*B@kW-S3TBhTslVV`v%YuT76TEYs<+ED?%o? zJAGaRe|lELC7lkM1Adx7RQvf?@_#nw15}4*g+BKH)nT6?mC;tF zWQ9I=85YvT3~>YSF8M?H+yh!f&0;WFKI<8<4gi7>2GIo|%Ttm&T1N(yunM9{AR8j0 zm9l)D7!bg^67>LHTmh_>+f%&~N?5FIAy`q%nCi8X@-flZo^~{!6|MT4>lb}#aRViQ zocV|uL4S{WeJE`E^=m0XVvN2bo&fw*sA~gg2gYcKmjK`gNfIcacEei-05OsQE zBtRiZxL5iml|XiZw-2&h@4eGo0`K;HX9y(qgn!WMI{+h^yMqwDe$ORHfSzz?0lEb! z^>GF45T=ACVKR^sXb}Yh5N3cbKo2<2a}&nY!X=<4XaI_UFxiNUfs^tlJ_7^+VHlz} zK^``*7V+Wl9)@Oje8gmWKFANFL>o=;OW6TjY+D-^f9pP3V zKt`r69Y7wYEmyH3ZUF&6^;`MJDmCIJj16MAdng-y0G`Ngv|jb`q X;E7iUepH|4BqaRDVdv&6GcD+dvq`6-^m3 z_~al8=@6elZYT*z7jBoicz57}hb*?P_W`)N88l_L3!b`o z&)D})vaLV)06DPr=YD#g=Y8)a>)i~y)4qqQ_w1-eAW;KElh~7AYJg+hyrGLDr0aUV!&K~2`I+T)eB&8hHEPct?=x`{n2%N}BmcSm`0fKQ?Fm}#h zfPoYvouo)+BLKi-G$euz2{i(c5t5dGKpp^$cL^O5Lfis?`LY+byns{!BnXKK3G_VN z0&deRUtG#kVk00;kWF(uIWT~hC77}L(KPf%w}OMo^r>Xc9?Ayiipz!B{HN(9}BDTNLY1HefM99LFzN_7i72cr-G z$|6X@`jyp;Jq`5W=XABl6n=xp3P3{F*qfB_G{hByhsuuWX<`RNAV^OhtOgMpARts= zILec+)qg!@<8FvcKsX>Eotxt-VD)j=EG7x5qdb^bj}1WK62PJICRp9n9Kb{AU{d!h zRJgB{stZ^aMktVCLIQ-99=I`YAvbma2wZWc3EUKbB_&}jB6#We5WnGI*#tQNz<%X? z*nb1q_mB^OX~kO#`}0cxSOmp7z5Gr!inI>q{D1n7PgtZd{+Q>_Eg<2X=RRx%mE?Nd zH5~R~o?psy0KOUExgjv$0fj_1YYXt(*Z}t$;CWkMY{vqsz}f?@+5$7El11qgPBL@Z z7AS!9$y`=FN`cSN1`VVi%=Ne-aQz!gS^z&YUh_D}3Wpz1C4}syKa)C8I+Va-iI0-H zM}LuN1{nIE?LuZ{At}{{G9_z-;{j^Mp(^@LE$SB79%G zm|Y)$!|7|$%W*ZrdWmEG@zEBmb&_XWpm2Cztn327c)eJ`if1+8`hIzQraxceC{0&q y%Xw~y+14SyJ+spdkp9ARZixD(d9TB={uKjh@P;_$aK%^v0000c0004VQb$4nuFf3k0000mP)t-sn9!hEP+4|KGlD*=!e*A@y8!XIR|FEqOudx_`SSB3+krjw@cHnaOS6 zdq62UFG~?Ah6Y5=0{Llc?7`d+#!0}Bo^iK_Recwyd z+nPc=>mM8FRe#0G0U(l8wSTG)K+IZZ2!)GT33#d}LG*>yG{*eDk`vJDb3m6}UyI2& z3jPIPF-<=MiY3He8ldl|={dm`SARv|{(5=xve@(^AZY{+0xvB9PYG&EafdcBa{;km zEa-&symQKX&c7zN=N6Ru*tS(nxdTw15g?yvfB^BHD}UHsI=9urcS6Xg%w6D}jE-YS zuogxMz>+KBBcjRyfPnxANgJRnxpnw}Xm2OQaaf9XJuH-1jNZ2xWb1Q-IM9VTq~1B5 zAS7f0o3qF^$~6^wAPdJw?uBQWvn6b0>i0PR67=-Y`(CjS<~YP=ObC~i7dfR$uYmOt z4tH5zu*3T&$!}IL>G8@9d8BbIyiPw5#){l zwqdLU5$=!5(6a?y8X$HMmVg}q(2tP_ViT9QSHd4ay+fRMFVOk{;O}|nq+m^BI=n>z z)fGSl)5q|=0eCT^`5^JSy8v`qHao*Gtg)Zk9Di-_{bZ-=3gD>o2fz>vKLA$3(SbV+ z3hk4U)vp9zV5Ih^Jrtbi3dylNS*P(gQM#ooQl^QiTjH&Iz(#EAgZ6j2wTxY7pL2=WPl zx__t{;0NBKG_m-;G(vo_f!;Mc0C#yePzh0F>H(1PUhFSmyUS6L#f}LNag3>Mglx6i z0d%0J^%LX`x2xQ5|{(Ah8mox9!Z%de&cBIA{QXsIT_h@1HAR z-|4lB2O#RiYQ7c9h_G&^zXl@ywM!7pI>`6pHRDVdvebvv48dn?u@HYzC zITfGEuw|i)Pj@tJgdJZx^iT?0$GK=zuz_x;TG`_=g&x(S6Kx~E_adr1@(icQ&m zn)9TRZbk!-Rex=Vb35mhqVgub&umuZt#Z!8SbrZ_WymvDE7KCToe1zLbdZ43rd`n@ zK>T6V0pNH59z+che`xbIt9h2!d_W_=hRL}DBT}AC(TEOctE06z=VfZUK{^`}W*WyDc862uF?yMKdS_toxKzia}(eVzOnz~di= zk)U1pcw6-TxSOl_8$iCdEd)6=YQ7)U<3*K-V{vkPYE+&?0rl^iUJ$23oEq&X5k1s? z+tIh43vo=0RzwfA@3*pK|-56%qEKKFfbEAPLq0ni**g34$9 zx`4d@V}Hfgzdd($&hjzdcKd5W4L_xuTRWsm1|N2E&c0l_85B6^wEjKOXo--MXRQPh z{>`AE zsq8$w23-WdVP^l63%Kkb4KCs46-OPYJPdoNb$82+kYhj2k;5kQvsO0LAnfV+6qEZX+1KMFcIuVO^8Vpr@R$iizH5TdVuaC>L>5o=rln6kzs$a;IXLHmHPagnhG3E=paRo+_x zFn`J&R&Elb2}z5Pzr6e9R(Tz?8E+0pE+J>u`5WJ`Y|ExdWedQ%@k-UYHyl|hp7M$S zXbVatRzbDK@4XB(k6X~D4?S$lN*pdhJq{!IFM|<0ABrKMWtU$ARe~BViC`L}oiE{M zeB)<5%eA)I60jFuDZ^*eU}QsqU@8o1xqqav1ogu@$)-5{2)-qxgW20=mbzhYG(Q=t zP_Ra+Hk}5+=kjm>8UDo&=b{(_XEs3xMG2rU;s5DKzflMkShpfOT@!Tl#%~wDQ~4Vl^ZNCZDg29`4*N9E8mWo zsn0R=wAKL*=Ll~Iq$TE4tOYE}Il_=KEVCMNaZ%-eV_szwTU0?e%_0t;AB;CNz?%YUZqqS~)S4Vp@xH zV#Snu2nYy4F)3nFO74po_U0H`N;&4$%>V!Z=TjZ60005&NklP#jDd3ePysapWZ^$UJvLIJ4%JeR%nCIa) z1N@h&R>Q0g0e`zc_rO2(4x|efEgfPPz%5r0AyS>f)1b| z3;_UiNWr%?Yyr>?B#=%}*9D?4P`{op5?vig0J;XyMe&z`)LeHpZ3N&>W+1q2-?I`l zQHVbRX8s6>;h*^vzz(2}VFIi~>&pG&VIYqYC?Kh?pnu(V0N@lb@K->XMiATZ9R=#| zF(&}P@C<-0poK&JmO?#@W*N)?m{0WRUwmr9dI0Dh6n~#W0i=ZtpmRVN#TJ}fau?`% z7ovX&ht>Fg=e;X!4CjD>q95c`AFZqMS+Kdf)j7AN2QC+1U&Qgb{6M(8U+?qwZSx%< zG=8*z&`klheE&#l0c<{+CW4UOSRN!-2IQ4T@uvr=0&IF^0XBq3&7lH_YzgEa;sGE< ia6|(5=%bJRh<*Ut+#v*>`b^;f0000s}D=1x7P~5+>k%M~d=GqPb000nlQchF<|NsC0|NsC0|NsC0|NsBZA+nSJ00DhT zL_t(oh3%H>Zi6rkg=;%BMRJ<=f7{v4g-gO|}>(;GX*AS@& z{D6qyZoriRbRJ;iL*Ue}04h4jA~a(K*pG;ghJg%Tw5j4(bBv`3-;q=-#AFDf`a=cq9z{n|KTmFbn~lXXc>< zJPHUQ3rTOm{|XZC}JC23DS}GEkKK&0p^bpaxJ>?+5kls zhPeRbU?*IZ)f`j&etz!(MDlu8wE9;w;EJCzKpvuber*e4RZG^MDg4m_n9;T;HIMu-YP()S3!2pJ$((`5ds_=zgOMp6JVY6N@FJf{dy0kR+n q^_Kv+0MPm){#wQY82JMGD}4c|!x~iXThx&N0000V!ZRFMq)0009uNkl zh|VKY#S+8UTF^umA#m4uCs- z2(ZvOwg`S*O0QlAgx{9Z{PzgBe%h!J@t_pF!q0sh1qLGlPb2Bbv+^qUkybud6m zY3)F@8~(&Kb>vP9%&%RUw^{_1%pS!gF)oNe>g6ph>iD2!fpT2Tgs82)*Mcdu38JEp zM*yMQ9YCxWsDETPiE&@N3osFgzP>4bcL3c0xPnzRWd4QE7{QNPLII|JFUsLHpabA1 zElt3xpsH4q8y_sh*Lxh-sdW)4lthu#pUn0=RLnUb91Q_jBXc+zz0#6n9G_CGi^k=q zrMw30Jts#1-3IItkf@yjbRQ6cJfF||Daa5fX|?i`=zq{g)B!X9GXQt#ARGbl4PcNO z1t^-qb69TWo%w?>SSdcnQ6_dRAgg~$TPmewEM$Dw-~&=AzFdEmEN6Eefw*m3!Y7Y_ zKxe?Zt|I`=&Mp?*5yX-onMzB6s6W>TIj;EY1kg8thFF#aK(s)~`hE-nH9tpbT1P8F~RT&xBe%@oumQ>9F zg@WwIF0j3bJQHz%-o8IX)vG#a5;ilPpj(!gkbhc}z5>)7eCDX_?Yfs%KwHXIfS7IOd1 z0fPCn#^VWrePg-+!e+)*cCoj}31Dxt5zyWpx`Wv3_Z&ceFiioSAi7)5-c)R7jOWvb zD}XxSIDJ#E=eTCg)=E(uIBd-6wJQ~&h+uz$CNx~$K>&@k300000NkvXXu0mjf D0)nV% delta 814 zcmV+}1JV4q2gL@EB!4haOjJdg)1|Ysv)S3%^78VEii%A#CX{Ge0001HJuJhLd-ano z`|>s}D=1x7P~5+>k%M|SPY5*t000nlQchF<|NsC0|NsC0|NsC0|NsBZA+nSJ00Oj0 zL_t(oh3%H$-hJ zU;vr_fPVtmRO^}m>FYboLK_(X()VpTlnkIAFrP~gupa{KmwgYwyXO)>6I+Y8+@{Le zuLdB!xC=vUD2v-7~)1B_#R0&sEP_W@uu zh;9H_mKdi2i&Hgb&Ml~cd(p^WBmq||_Dwj!?0e)z#D8MP#}`>K+K6AWA5i=$&vZ;) zT9XmMS{ZtMm;L#Z$pESZl2z=pe+b6`L=J$hB=EEaTL7=Z);+-<;*OmY;D4T)OLXcV zOXf_#VjV&Jf#6@S0h}xV(4Saq=OUYlWlNyrCwnQ+04EetF098cJs>dv$mTJ&fK&u~Z0cVK&0!`01OV+hfHFTCLiW#ubj09q z2$ES${ypHNl*3V1#9MBYoW(e6;V)D14B+oPKmaUo?ExkMbeCZ$`AYQ#V7-Kt;@c9S z+)(&$z-df*EC~Q_3qY9)kOlSn-~%HO6+n5caDSY8weJA(L|t`65i-_xl0ylABjARt zeFR*5Ix@f+c)$hGXeH`kO9s?LfJek9J&LB4&q3>c)92mJs3{m+P^70^dZbHIZbNg( zQJTq6&t9XKB7TdVsX;&cmrJ$+>bQ;oou&cHJ)p#8hz5WQ-2iS0qYSQc_?rN}wsc^x sFDIn|ptt?;N*e-ZtVg=NK!3M>0S7xM&o0zD=>Px#07*qoM6N<$fkh>GZx^prwCo0M^H%m)TbQEQeijGnrg#0s;aFKQ1&hG<;bI;#R~cctj)^Sa>i_o$-}{fkB`o$S?Rm O8aS)CY0Ac|wTu9lG9|(Q diff --git a/graphics/pokemon/kilowattrel/front.png b/graphics/pokemon/kilowattrel/front.png index 3a8e971644638c9ae20a3a4330afc78b31bbe879..fdb1a38e482218abc0eac631f7dd8bb7b81fa5b2 100755 GIT binary patch delta 24 gcmaFBa*<_%3KwH>kh>GZx^prwCo0-)tbWP}0BvRoN&o-= delta 40 jcmcb}@_=Q6%0xqJDF%U(Aiv=MXyB~krYReY^Z$Q4dH@C+VVthJE}hjT ztv z78uDQ_l}{jj?~*mdI6C1ehAz>4t`xxhSDtuz`@_HBnjVGOM3Id2&X)&&(t^ALOs4k(`Vijl3~(<< zi-!O%j-nGk$uqz>>Kz})?qSP-UC+PB69FG(x%WJgq(?$WK85c$0eH_ZxM&UPy>|zo zm%J~v_Zr@qMxJo$ADf4y@6Mj+*VRIpCfIq!(%j(!N(rEmtZNs5o6mA5K%)SbZn1w( z1pZwi)Ou-uN$z?0@>(S@Ae;sXybm1#yfCZ+0QgD^8)md<(jl+6|Z7of;1{Y2068nC%&p0pt|m zJcddSNoVC7jp+Tp5Hf()K{x>3rPVG@5~ z5Bh?=vW|t1*!>gMr8>IK?h8sAjpcabiDhti!doz=xHga2O$%R=ZV=_Mt$#w0y2Q% zDS)X4P%;7+H1zQjOHBNMQK@J9nSh(jw3-HhP!lj)c*d|IgbJm6zR*TFkK#)~@SL0w z8lZs)K%ZB%%Wg*jGRYT2o|Ah51#wQrk<+1nL~=y~a0lpoN&^>I*Hj$(#dM1#DMPVX zIZp=|srR``>Xn&H06Do5h2NRwT<0nE4%P-sJUr7ODko_L*ts6n5cmL1Dg8VUQ0l2z z<_*#$fTST-<*9g+w^V-ta0zC3YqbfGtNIiKK$6Esy#o(JNd!a;j|0C8AyN;^(JLH( z1vBj_?U1Pp1AEHzc*>`N&B7!5eClkx@BgU%=>kD4{Evvj|3AJ!I4%zaaA*69mRDUm z3?5z})b>C5|M3fimi>R=|J(L|7@*q!u?qy<{tsOs?7ICo%fJPK^j_Nkc|Pp_zy-qD z{+2mB{0u6+kc!!&;Voh zzvuo(?Y{~bw*T7U{=ok0_XmT2_FoHO-2Q8XA^T4il%7bgO1k#{wn*jYI`;n_KsBCj z|C96X67KCkg`gKZknc`a`wx3`%?bo=>_6~-!0_hK2%y^kpMxMR z^sRfc|9fHoBbDm)A=AYNYgDFpG6~NNI9%QTU)ulf{;%yHo)dr&td~0tI{*Lx07*qo IM6N<$g1>V?n6km4hn^Oq zHSB49sGLI&@gW}fkV7f8z0gDV7i>32`?7(ataJBNFtH0g={NMfkz$QTa$GuxSmb|w zdNcDR=6%w%{1KWf0(WtGKM_)=(O4DS3d4|6hp}01n6WyA!9vz>bK_Ku8eJ?{9`H#V zuhRu%EN7X2pEM(61rQ#e9iC9?17PI=AwBjEU(%;tDt6IO0odH}%MSO4!vdvlBa>l^ z9-ka{dYyis7if)H8DLKBvnD^{{XTz8!5S88s0k?bzU_X|x%jM08C$q&p%7^Heti7f zj(yH>5M_o%ojyH({pRfswfh245{zNx&mJGx@KfrISf&c&0D`677=KL0P?;JbMg>@h<794@nU%iQ~)qeagK+a!~88kJWhgl zGO+8t62J%x;dw3IZ3pA!E(Cyu8jgCfMGt{dB}h^n7*VMo!u;@PV zqWgadK$}dHr-iG;Vvq5e{`x08aLgb9Wdyd(4Jbya{o?T1eFmlMm##v2k?|a`*XDDlboCFf+H+baGO%gHqfDK8tqSMQ+@_|c z&HAf$DB(kG-3i{xx^w2yG27?X2fjaDNcwEyRy=U;oVX!SCm*^n0j6u zB4(T{Km6av*6sb_aPHhgKp1-SVzwe2Vi=ouu3=#Pgg-zn7iKmd>jAtEPPR4UNc6zT zHbyO_2f2W(2X=oBkkSKGklW1ti5^g9sg?uHJ<@}V&ruKX?a2T_4_@!ss0WQ()wH1d zgC4vg(ETGlu#`fdXNKP&(eRQ?vDu+!N}-=Dj2zXAPI(~ z2U?;Bi9bkspf&IG00d)MC|M6$OFj5L5e!KWHY7ce{2|eU2Z{Ngz8;t|kf#R{kgo^wDsuFoR!=XJ6cjzk z9OVT?4>Ev7zm)Z$#@tyN&@+1ADs7h#MGxE=G;SHO6g{vSl!kI|*DYBO7=e%90!>Y# zlSB_NMcvWUA4@_ZszMLIF4%2eQzIsL0l^=r!-^#Ku1Ei`=6-d{Tu%P~IsOGpgZ%C* S>!daS0000c0004VQb$4nuFf3k0000mP)t-snar75b6OD* z5&!@Hq`jnbK{@VX2()t;|D-8WF&O{F04W#{N--d;QXpD$T53Tl3~|sn0008>Nkls{a1Chpyq?U|)QGI*2E?|v?SKC$gPI!5)QTdmiKiXa zbvI@&)wQMKrd=Dz+S;9ghL<)|mDXCbTNR8HV29)J27hBJi{^9;DvJ0HCk)gb+ODK7zcZ9vzAn11t8u(b=(@(gmLtyTb4L zbIgV{&xQ$)@pBy0FqQ&DcR|5i5a)^whSFFbUGtDE2s} zj*3E0DggJ*W9NlSJOmO!@uwD0x_lC(?!-7lOMySLp#9Bb z&C3S9WQKVuaHAl!1>*sqXPvS#iL~OYpsrTx8cr_1jR`sfxq;6sSa5QuO9DS8==Kwh zd>=pH9Dn$N4O~@*CZ)$E5@zj@$L%XDn6ybseY2=9&e09|XDidtM&W`TTXAO3*K(FPmrJ z*+AVsJAJvg`&CR4Xt+La_8fhf$1XrbZA_9X|;kc~?7zc;AmBc;+FX^v!4FRe;b+^O!mLl7d(DXTe(ldGk)+Dooo2 zPh-4(KS6;0tAtqwFhrGC2A|&_tAQ2*GL`3!Spn2|d0(R%f)9+5jaUtMk*p(-jxYe_ zz|&i2>R`rMAlm}8mqY2gWny$CY@585eEBR)aLUjP6A07*qoM6N<$g7V;` A@c;k- delta 938 zcmV;b16BO>2DAr|7=Hu<00013M{Ml?001yhOjJdf(4bgwSP&2p`1tsku%K8#DDYqi zpkNUApeRr<82G>dI3N&6Fd%qHD1d-~0001u4e{6j000SaNLh0L01m_e01m_fl`9S# z0009jNklKeI&ecn37(tjUN3ia5*gQ0ZOau$J% ziA5Kq4z8E}4M7AvNQGkXEK5FX zmZh79L5QuJCZ*V4yPy!3B5Aj$fu>6lL0z;g(ekeQ=L%>j!Ie+-pqKPK&mf~;`VVnI zy9&^+RH6W^qkn|g&_L7kyei^(mer)!1%QaFus(KxL$3@#^!sih9|K(1E5{*Fi5xKh z30&^=U+czz4%AfFWyfU|aP#FP%@UA5tws(QCLsBn3Lu1(_l!yEP zTLoaUlmTh^Y%)9BX1j_-YZ1Y_q`jE?EU>p(k|Ym%0DqY?j7b==PxdCsvg}7v(odL< zX&BMuYlaaQz?_wcS4z)@_MrhJ`KWb1{BQ(FmP+TG4@ZX?93G>*0-dkN4^_b7o0kZD zcMz~EfX{hH>O&$3U1eTE%442oJJ82A0I^<^g$6pSbPM^j;do>?Dd*ZC)EPD%zJ>D1 zcx0D>&wl^};?D!`*!bqfoe)Hk5;&PM3HT`j&U6|Y(t)VG03in2 zL7hw{({Lso99simpc2IF{(cgMhM9sxx-QLb43W0wicV(-fR7z- zA_?48ftv&?d^=i5i}8DNCpz9~AXUpd3L^3I_J3E{DF9fB8;%tW$E{#N;P>qx1-zES zoWmkX1I89@996glU?YK(xg!nMBd`x-&Cym&`ue9lG-Q*ADI%y5#-3nS#hzTPYQwop(nJ{m;D7lYVTJ;5;HbuWR|O0X zv47ZCe4_yqbZx+h9T}%Q+m(T`0TZ34TLf0e447R%H&Q%!Tpw)BH(EtDd diff --git a/graphics/pokemon/landorus/normal.pal b/graphics/pokemon/landorus/normal.pal index bbacdca837..36dd9dbac0 100644 --- a/graphics/pokemon/landorus/normal.pal +++ b/graphics/pokemon/landorus/normal.pal @@ -10,10 +10,10 @@ JASC-PAL 184 72 80 160 88 56 240 120 64 -51 51 34 +96 48 16 248 200 96 -51 51 51 +72 40 24 96 64 48 119 51 85 128 128 128 -0 0 0 +128 96 72 diff --git a/graphics/pokemon/landorus/shiny.pal b/graphics/pokemon/landorus/shiny.pal index 25f3ac5c93..c76bc2922b 100644 --- a/graphics/pokemon/landorus/shiny.pal +++ b/graphics/pokemon/landorus/shiny.pal @@ -1,19 +1,19 @@ JASC-PAL 0100 16 -152 208 160 -88 112 88 -16 16 16 -248 248 248 -152 176 160 -88 64 40 -240 96 8 -160 96 16 -248 160 40 -80 48 24 -248 192 0 -56 32 16 -72 48 32 -120 72 40 -128 128 128 -0 0 0 +153 204 153 +90 115 90 +17 17 17 +255 255 255 +164 189 164 +115 65 57 +238 98 8 +180 115 24 +255 164 41 +82 49 24 +255 197 0 +41 24 16 +74 49 32 +172 82 32 +90 115 90 +106 65 41 diff --git a/graphics/pokemon/latias/mega/front.png b/graphics/pokemon/latias/mega/front.png index bb513505645aa15202fcb87aa5b5376ac0d3d2c6..491f02fa4b45573254abdaf7dd1cf836755afc21 100644 GIT binary patch delta 828 zcmV-C1H=5!2Z0BW7#0Wv0001;w}I>c0004VQb$4nuFf3kkv=|u0{=-wK~z|UrI%Y` zt1t{iu`C&f{V(|H<+mZ>R{bbVm}6NU33?nB;iwVdcpo9c=JFLF0Q?Prt_!iT-sm|B z0OR`{1Q4`%9qM%ku>ivBb6^!B)&$RztvgLscWPqzEe*RY(eGgRG@&j3){w}f5>2heFBBA1tD zHS1eq08v{3MGs&-A(hdyMK(wp3ODN&0RjO3tpr&yn*LmWw_n0r6yU^-M^2g{0OrFtkOaJOEPK5~#4*^QE^W4Ve$wrghO*!UU+` zL_-Qf0ajIic|*Ve=xyS{7|?S8NMq=I)IB_43$TL_K$s9&5QJd`$XNioUJCP`SOGQobM^rBdfsA3@NJ16VOBdpXDC?-h_0)Dk7)qLvX!U`vkhj-O5nd_ zb`ZrY@NIn=b4vl(e@@8N1I5K|SGbtazex2d2*3z`n0gmxMfg(!=GU;6LOOMV)7(qR zT5)*LtN=Bx4FcXaq+ajMOlgm(eM%0HZM%uZ#yLBIa@r$m4s8@=cMqjDi>zbPhCqcN ztCYmufQ?XZS_xD~cLxxJFzl2-empjM+oaMPLDpA6A#9J}C?f%=rrIWmHLw%z^kpPi zA+%b5^8|P%)R6*>024q7H-I|RKulT_sSLSxzwZep0sEGXfc^l0q3E}SQLhO8_r(j^ z3vLLD{;*dDnLBgOSvBUz%Bn9nFRSg&0`__ZuODh&V`4UG_V;co<_En1Htya7tUe21 zdnc{++5-0*IBv?gCEP3oX|C5T;O2|_-OV=}-hcDG3jY9`Q!UyqF3U;)0000VGd00SsVL_t(Y$Ay)@Zrd;r#uWkDQ(M^$x>kj5 zHWj$&W{XJ*WJ#4U(%PU=w6=|Xp4HOj19Zw(pi^I^eW>1%k}Ua8%E7RGKYjP{?npVf zj_AYbIR{sNK-A%GpQr=N7bjBo zpGo1%2l&MK_)y%D00ivGASHczJOcQ*50IdVxaI)Mubj{K#I?RcUgiXs1DLp0%<%y3p5pN~VB-mlpwA-&ycA%8#${@M z;+j!|v4mJ8&V2+@{CZJH2`dvXO)_`LFaPv8!+v-$g~yAfmB&@Na@ply#)Oz7@C5`c z>UdfC^#yw=gau$4!9sTh9CYFuVt~No6d>yg*fa)kQnUcIM7J)!$$`71wJYE_O%7US zlVMlk2;=d51dT+wB|#>lXjbJ|Wjfq{VhNffV z)9)6@TN_OgUrRha*zD4Czd|^{wWj%bW8>3O7|Nme_22fHr`7_?*JxTVQ|!yRGh91e(wz1VB-pA=gTm zYTY7?1S9zp_kU}~3EOku03Jzyl#0|@p5NoP!&2MJqXHHU04&IHS7FE)+g#15rn8cz zW>W4LD|FeJSP!?Aku1fj&%xHfdUy^J1a#GBT^8M$r-{MZq4l5wf)3!(2oKy)A;V}6 z$^rIo(9M7kxTASUmky&2btKYie%+T7v}*U(mZ${iUl!=3`WGeYGI*_7s~~8;xtooI ztwZQ-gaa)HHJ}>6EgHZL>*qqck9Prd#A=|mqm1pomqOJ70=)~kW$TR_sALb&`oZ)b giOwsVZJBVKe_Q^CQem&%1^@s607*qoM6N<$g461yivR!s diff --git a/graphics/pokemon/latios/mega/front.png b/graphics/pokemon/latios/mega/front.png index cc20e9d1cb9fab62fd5937a24f5a695ef53206b3..ebca8034d8bd89e5f9e01e558aa8218dc97f1615 100644 GIT binary patch delta 828 zcmV-C1H=5!2Z0BW7#0Wv0001;w}I>c0004VQb$4nuFf3kkv=|u0{=-wK~z|UrI%Y` zt1t{iu`C&f{V(|H<+mZ>R{bbVm}6NU33?nB;iwVdcpo9c=JFLF0Q?Prt_!iT-sm|B z0OR`{1Q4`%9qM%ku>ivBb6^!B)&$RztvgLscWPqzEe*RY(eGgRG@&j3){w}f5>2heFBBA1tD zHS1eq08v{3MGs&-A(hdyMK(wp3ODN&0RjO3tpr&yn*LmWw_n0r6yU^-M^2g{0OrFtkOaJOEPK5~#4*^QE^W4Ve$wrghO*!UU+` zL_-Qf0ajIic|*Ve=xyS{7|?S8NMq=I)IB_43$TL_K$s9&5QJd`$XNioUJCP`SOGQobM^rBdfsA3@NJ16VOBdpXDC?-h_0)Dk7)qLvX!U`vkhj-O5nd_ zb`ZrY@NIn=b4vl(e@@8N1I5K|SGbtazex2d2*3z`n0gmxMfg(!=GU;6LOOMV)7(qR zT5)*LtN=Bx4FcXaq+ajMOlgm(eM%0HZM%uZ#yLBIa@r$m4s8@=cMqjDi>zbPhCqcN ztCYmufQ?XZS_xD~cLxxJFzl2-empjM+oaMPLDpA6A#9J}C?f%=rrIWmHLw%z^kpPi zA+%b5^8|P%)R6*>024q7H-I|RKulT_sSLSxzwZep0sEGXfc^l0q3E}SQLhO8_r(j^ z3vLLD{;*dDnLBgOSvBUz%Bn9nFRSg&0`__ZuODh&V`4UG_V;co<_En1Htya7tUe21 zdnc{++5-0*IBv?gCEP3oX|C5T;O2|_-OV=}-hcDG3jY9`Q!UyqF3U;)0000VGd00SsVL_t(Y$Ay)@Zrd;r#uWkDQ(M^$x>kj5 zHWj$&W{XJ*WJ#4U(%PU=w6=|Xp4HOj19Zw(pi^I^eW>1%k}Ua8%E7RGKYjP{?npVf zj_AYbIR{sNK-A%GpQr=N7bjBo zpGo1%2l&MK_)y%D00ivGASHczJOcQ*50IdVxaI)Mubj{K#I?RcUgiXs1DLp0%<%y3p5pN~VB-mlpwA-&ycA%8#${@M z;+j!|v4mJ8&V2+@{CZJH2`dvXO)_`LFaPv8!+v-$g~yAfmB&@Na@ply#)Oz7@C5`c z>UdfC^#yw=gau$4!9sTh9CYFuVt~No6d>yg*fa)kQnUcIM7J)!$$`71wJYE_O%7US zlVMlk2;=d51dT+wB|#>lXjbJ|Wjfq{VhNffV z)9)6@TN_OgUrRha*zD4Czd|^{wWj%bW8>3O7|Nme_22fHr`7_?*JxTVQ|!yRGh91e(wz1VB-pA=gTm zYTY7?1S9zp_kU}~3EOku03Jzyl#0|@p5NoP!&2MJqXHHU04&IHS7FE)+g#15rn8cz zW>W4LD|FeJSP!?Aku1fj&%xHfdUy^J1a#GBT^8M$r-{MZq4l5wf)3!(2oKy)A;V}6 z$^rIo(9M7kxTASUmky&2btKYie%+T7v}*U(mZ${iUl!=3`WGeYGI*_7s~~8;xtooI ztwZQ-gaa)HHJ}>6EgHZL>*qqck9Prd#A=|mqm1pomqOJ70=)~kW$TR_sALb&`oZ)b giOwsVZJBVKe_Q^CQem&%1^@s607*qoM6N<$g461yivR!s diff --git a/graphics/pokemon/magearna/back.png b/graphics/pokemon/magearna/back.png index 17568f8bb23011aa8a1964305d00bebfb33bc7c5..2e3a77c5121415d79935553c11fbb9109e445185 100644 GIT binary patch delta 633 zcmV-<0*3v}1%?HX7=H)@0001;w}I>c0004VQb$4nuFf3k0000mP)t-snbW0ba&qeI z?4G8k(b(9cu&{1|f)Ef8USwpy!orM`ll+>z_)>2SsL9>wwn9%7Cj_PgL~01NhJ)z z9P~wl9G$Rl+unzjyD%C=m*BQ-ZTt=DYg4Ce^$&4``!RAk?F(MTLa)LaPbl7Sr=`jYbKGbU?pb$cu1htc^ z2=hb0Y!^Qr-}wn3)&gKcus*~kT>UhQH-O+804?MTLVrpHul%`>jDV2D%U1xklY^;~ z@HmbT%kJ5{oj?H6?P72X1Q_@U5D(Hb0EU3lPKFA4K$(#h5d2>N^cHr2db9vYAiIaK zS^y6|`3ZoKb=E@<@%iQgsCHqTkH83M{e;K>qkl#)&tQ>_xhK3RfV!ba;JX53TW$!! z)B(z$l5!E%Y8rb;#2#T0gPRBW9Vz4Y1;~fdXM`^&`D^8$5LiBpl!@~D1Sj{AQ2%vO zYI^pcq;!7vBkgjx1gyJ=cli1IBqfAX|4{b;<@d;TMtD8$?O{2MskdP~d0)00J*bL_t(Y$K{l z$ms*rQiD!jBo~>yI6?!oXouiZZ=HG>J2dg>eLCh5nrA2}$&O_+T|1OO0+IUilc6X@ z(SK~C30ObSaVNJku*pprxNrT*Y|gJA1LT=Mi(FoSZ}TPt z7e#xT>m~=A{%C>Dz9&K;*mpz#^!B4j%K*rW!5GGC*?#~+XlhW$AYuWbH_x95U}KJ2 zt&G+iW6XCF0NZk2nJYky`z&P%5=BHxY+1q>ON=>^*J<;US%AGWU#TL;CS{NTpyd^y zW)9$@s-Fm;I;1uObaF)i<6X7o2;iA4%@FvoucRLp!G(F+?TY??tYtf#!aVQy1K@B0 zu$%Q&0Dsf0C}8_{Kx^p%Ndr+NWv=zw14lia8JWY4RaS^sk3=W!zEXHegrR`7@&o`i zH4m`|RLPel5b0K8^+*p)LzHBVIFp`uZ^#sIT!qF;bC_>R;)PNmqm|aNIpDgV0iFkZ z(|BetDieb?zzdXQamhu7YnEia1lVD=C{HK8z&U27Y|+bLUzOLV^ZAt8H!JM{r3F5o m!G5_l&j{cX0>4S%U)mojnPBNov#jy}0000c0004VQb$4nuFf3k0000mP)t-snbV~JdT^9d zAfuTWIby6@gU#jQB%HMW0KvYrdqK^dVi6G$|M`sOy@UVer26{$hgfNR0009ENklr+4^=-wuz!GLAmoQtUmXhoEx-_nN|z2$1qzrfAQ6a2U1orc*N09&1aNPJco70X z>=Ckom~x}v0hFMkj8K3YXfj^=cNVN(5J|7mLZcs9fB-FE0M)~+BJSCTYcf5N#ippC>YVzcdOyBa_tFk&O$v>;i9<1=Q5pdA3{QjYd) z2J8TrQL$T-jfKzwQc`dyHxC;NHhY@Rkh7Z}nwk#=VGLmDS}N4&t*tbt&}0Bjq*CM7 zfUR_zP=BnaBl-6WX!QW?ZW-Soa`^|*y>74hAKXneDMdNm{XqW3x=*OwmWLNZ2I$OA zaxjZda!~hFtnVGXlqlWsMJ`Ajr1~rn(9@mc_v>eOWzN&7Kro+{fbHaEA;^ko4s)^7 z=P6eUnx5%QrE({+w8x&%g_byrG`>*6#7SU&+J9RPEo8m?EY7(_hLHd=5R``piyBOL z36k{%K$+?e_M}`9`I`U>z$+lmD9P!`rUFo>vAmeL1qCR8IKysiNNuASPUq5NvBBs# zq$dAjr~z7jzu$ilq>IUuW4Ut-c_@!n69X<5@b`=mR(>3Q}Uhg3&nHEAyfr~R^Uf1;op$tIQr0R+IEA;cZ3rNwOI*{P&%mDs| zo9_&Pa`d<>kOb$*bF^^w9oYe#E7l9({6lmHSSZO0;2vRKDP{dt+Z^?G0V}m?(+1zd Yf8`ujB=CERy8r+H07*qoM6N<$f~;|#XaE2J delta 781 zcmV+o1M>Wh2bczs7=Hu<00013M{Ml?0004VQb$4nuFf3k00004XF*Lt006O%3;baP z0000mP)t-sn9!gQNLUaM5Qu$mrn6*rpHaY;l$RDVdv<&#~C+b|S`6?p^A zFe!N%@Z1<-LI+F)ex3x)0$Q34SRleIBL(ASbo?l?lF*mVd-u|Nb>&QcNCLd-*LV$8-a7xV30Gw7MK@%Y)GIlGKfkGoe^TK$IJWD2)Uo9GIMcHb4Fwn?4rcf><$47NC5CTHeV4*ArLM^Fe>jc;UVn8Shqq}GK&ju;10Mf; zN_X)63V+4y+cZyi@P6t0r~CC5#2DbAc=&B*Uq?EiZp`DIS&sp4Q)A4gFlLs>FnI?+ zi7N#>y_<*o0eDFO*c#)-S|c0004VQb$4nuFf3k0000mP)t-snbV~gOI=by zN~CisgF#BPN?Pu{TIO?$L!-TmgNv-BtPv3r_TGcV#l_y<-un9bF51|{0008_NklZiI$`w3`NTzXo%?l|Lwd4#C=?5(tWBL^<9z>BK`Z_S%2Hg#T|y-%71OwofDYH zab$X+@B9g%$Va+!1pt2nQ27|6={UnK5a$5Xo3Rb(h?qxh)^B}W^a&vlq%js+ePo(S zdPD&jPIS~KBHH`22Z$8?0^mhnE~Ep&6c`YtBx0ijfa(SKL1{~%tf0goWPJsc`E~_R z5xf8l$4GJM8I+3Ro>+Z$H+7lK6S<>y<>cBF)UXH}&YFv8C z$_XU0>$D2#FnxZK@_bwU8X@HIb3T1RSWhI%B}Szu6olR+?^$-!=e404FQYrw5~~c> zw+1tJhqP=eY!0;Uf-FR|%0jjm~$ zcK}5Y2Pe|ttk;S3{bPb?=8Zv4x~4ZmCocebewauHz)W}-08B(rsugf{WW5GRgAE@1{i2wiq delta 992 zcmV<610VeP2I>cp7=Hu<00013M{Ml?0004VQb$4nuFf3k00004XF*Lt006O%3;baP z0000mP)t-sn9!iGNLW}vNQi)l$XIaTaESQ$_|VA6sGz725D@6NSfFqy@YsMrpt#`R z;1Ebyj>Ydt00009a7bBm000id000id0mpBsWB>pILrFwIRDVdvg_JR9+dveC&r+At zq1ZG-)4}pNSWW`Q*q}H|pl&jBEJQ=05Qsnug)B1YLWd3=9EZ~27y?yOFzr-i58Xnn ztX*o&Z8L;`7N?7#Lxv0?eRr}PJC>X`NV@yK``_KWXQQ!5+@9cz`QhO`S-2S#ixg0m zVPa+V1}LfueSf8mVPa)jxX~;0n=e&;kVQ-$0KBT!XbMS%U=}<)W2&4wDP2 z8t6a}nu9Y`rK%KRrOq<2S3kf)L4YaM4FgsRECU%TDSv2?1272yjVcQx2FxN)F-Za4 z&oFGjEMV&*kt&4fvoyn~L0}=iIV4!r#|@~3p`grqyNl`CaRY=fAvmM9yY!SrNz(;1 zM(CLUP%|MqLK(GUygr0FifX8i(wdH;3OH?$TN~h6>mg(|HZjJ(vlugjV$iHST#rw1 zn}2E_et&KG{%|SEQ0MrB^wu-_2P~>VAJNVUnr_L%o~PfMl{6?n@$Gn5&ixhqv;-y% z+D99PMo2&u%H{e%Cx%wdBWYVDI>yAH1V+ox>U|w!Xx1$S71FG%ScEMV+}XyCNp&a* zYsEqu3h3V(M~InqE45tO%mm%Uk#(>O?hWHw?tfe_WpQb-5zL7O^m0&l?!CS1z02l$ zomR;V=0w=};9hKJ*Av90Ui+taUhmIwBX?qFU6iZz+RitO!h;hy&)sgfqI8H|uZQjL zk+N;)yq*xf+_sJnJ!3vne_+|&Zg1U+%y8^D#~owNirB-$>m&1Xw_C7ms}%}do$SkN zW`Cz(Th>u1(A<~htBZp<%d+iy7{JN$+Udp10~;(tfhhpa_GR;v6_En~`BIkmo?P1Y z(RCQ`$^k@9CC^N=c@~mn%5i?k@{3gR^k4GiG6aY@4p_uf@#bDK%mBrv+m0MhJdHn2 zC7PkfNLgRv6o7ahrX!9@GYpsw1rP=UcUcDXL<9hhpL20)+QLx)LM0bt%lcZ61o)jh z0Mx*^6LH-GV7@iM0NsawF%wM+)10iMk2{lfBv$SKIFi4Ez#~6Bg#H7)K}BAH5TAzt O0000O$ z%C~Y6ckBp7L^*|{DN;wG$OTpu>7k4eBD7dE7Dw>~as-Z(v41hk*b7EVmBO#H=JU?a zV9=*epFaO4TS-^_VIk>46{ye+@O=i0ufKqZroO(M(>MS&e)C{6hY214`wmNY41tXm z_&frw9+8<)6mnYVbL+GXe4Y7~=xI&1*<+#r17^j|A@l=j zMwx}otHECXpKno76oy_dt UhqWcelK=n!07*qoM6N<$f>6hucmMzZ delta 542 zcmV+(0^$9I1FHm(7=H)@0001;w}I>c001gbOjJdg)1{l7t`(MO#VIp^E#TcR~^n0d1zHcjI4Jh=2Ky5D|R69zA;W=+UEp zrmYjKTMF|>{9U(KMgSCRUc06HXQod^KD0@yaS;+{oB zEd==^VB7XyP!Ji*oKm{;k9G*2ge8U)<4qC+0CL^2kxYty0e~saTYtCakM>f6y9vxM1wHv`^oKTqeGh7ncF%YQsDAl>_5eb{atb g(ZDSq-WLk^0m^?aAL5C9SpWb407*qoM6N<$f=e9qIRF3v diff --git a/graphics/pokemon/naclstack/front.png b/graphics/pokemon/naclstack/front.png index 4055c46cf312d0de578b48afd80040358d2da981..646b29881c1cb6ce7e95847bd2562fef4d9673d7 100644 GIT binary patch delta 538 zcmV+#0_FY31*Zg%7=Hu<00013M{Ml?001yhOjJdj)ufbST4GX4dwYAulzZmY&Be66 z|Ns9|Qc^)NDT{Mr2nY!7ix~Fi7ytkO0002fcYsC!00FW|L_t(|0qv4IPXa*{g$Y}U z)!nQnBo;7&hS&*N3vFg|H6~U*HrB9YG|>vfPU|Z`Y3L@j{C@xojRn1xws!s(?~Jc~ z5r2T3Vv9ZB+&z2l~DP=%J_6*A6{&wb!p3n+J z8XGQ4T%xvszC5Y|9 zqRUvZHIRo@1I$OylP3KRdK##310*&@nx8m)SvSUQO1hcy^$PE;1gH6z3L`9?*IS*07*qoM6N<$f;<%Vc001gbOjJdg)1`57asU7Sw6wGm5)#ITZiiM; z_QRf6EGKJ0JpZ5o|Nj6&797H75INX-<^TWy4s=pZQ~&?}|NsC0|NsC0|NsAJ!ZSqx z00KTqL_t(oh3%H@cET_ShD}2#)q4N8J0Kq=X=2->JKGQ6vwyRx+540Pg4}Ljef7^3 zg4^qYJIpMBcrPTca&Xo@Z%QaZIDaaH%DyRvaU4R9UBsRWMkfGHos&^P@aIJ9k$>8$ z0lXx*jz8~0!}1uAMq#*)UCs?clK1=xs(OU(!@cnfA``lRR4k_K-)150dgwY9|Ks|m6r7yKoB{ARYacz z;@D08AP1(lp7B{zYGAxjlea_VZ@bNL&RFY(~%V%Nk1Thk&+6Z7a6}0CZQT z!JumYP5SLS075C-vO|YFSY7~dZl%>=Sy3ESfHdBu?98o~Ndh;&js+HQJgPIp07PWF h$)Udz(RI&X=m*iDEpX8XK&k)$002ovPDHLkV1is@I)(rM diff --git a/graphics/pokemon/naclstack/normal.pal b/graphics/pokemon/naclstack/normal.pal index 2fd0dd7abd..19fea0383f 100644 --- a/graphics/pokemon/naclstack/normal.pal +++ b/graphics/pokemon/naclstack/normal.pal @@ -1,17 +1,19 @@ JASC-PAL 0100 -14 -153 211 165 -113 113 113 +16 +156 213 164 +148 98 90 +98 82 74 +123 123 123 +197 148 123 +230 213 205 +197 180 189 255 255 255 -180 180 180 -18 18 18 -198 135 110 -135 86 81 -246 195 158 -87 44 39 -107 65 60 -255 160 0 -255 255 0 -66 22 28 -194 103 16 +82 82 82 +65 49 41 +139 115 98 +8 8 8 +238 139 24 +246 230 24 +0 0 0 +0 0 0 diff --git a/graphics/pokemon/naclstack/shiny.pal b/graphics/pokemon/naclstack/shiny.pal index a8f14a01b0..94d60d4731 100644 --- a/graphics/pokemon/naclstack/shiny.pal +++ b/graphics/pokemon/naclstack/shiny.pal @@ -1,17 +1,19 @@ JASC-PAL 0100 -14 -153 211 165 -164 70 47 -235 145 61 -211 94 44 -18 18 18 -198 135 110 -135 86 81 -246 195 158 -87 44 39 -107 65 60 -255 160 0 -255 255 0 -66 22 28 -194 103 16 +16 +156 213 164 +148 98 90 +98 82 74 +123 98 65 +197 148 123 +230 213 205 +197 131 106 +238 189 148 +90 57 49 +65 49 41 +139 115 98 +8 8 8 +238 139 24 +246 230 24 +0 0 0 +0 0 0 diff --git a/graphics/pokemon/orthworm/front.png b/graphics/pokemon/orthworm/front.png index 87535ce92cf1fa4ca5d318bc8f2a9a3f9f3d2a18..14884ce2c7d8946a5f68377bae92be15f1bc8d43 100755 GIT binary patch delta 600 zcmV-e0;m1F1-b>0ZGSjPL_t(oh3%H%a)TfYfEx%{O_le5+a&~4Y_-9EyKC;c?l!;A z5Fqe){NfjffEsscC*i$wHx!u`wtQhP@7&7DSFfS+nGGTEPml2y?}886;BkmnMZ+_! z0yaF2hIaw~0wS;(z=g3f8{Z+|n(O-kNa|M#sDi=J8n|k?7c!mauS|el@Q}jgfQ;7}%!PQ`np5e= zLy2bz?kYxsMt>YyLrlqQ=_nglXG-4Fozvay+;ZlnN2UY4cc)5HhvyWsj3!5vXT zcL$~956_DG@)l8dmI{`o73?k|XKUoC{!g{C`cHFVzlcAjGapiaa@zR-0000X(1b;+U; zfL$O4cgz4L0?fS0Ad032I89U%FbN28KbcW@%F`ek1@M}23#j~%lF7h=`8Ch45``DR zvRG3PoPW6a9p53~n$Hq10FwHZ0;*szYz&>CV&)(nmY<(GxGr7i(BDagZA!;gkxh*HCdou>>&?M4(l4hdcF zF(vzXR14PtWpn5?)NZf_^X}9s5QQdz%uhE2K)x(&=BFDe0FjqzDfl$;f%`7FzD4kk zD50x^Qu2p)#eI2;s4Gha%hC#V7m>3$b}0bMEdtI3uzx%LtSM0GZM}l62DyfO7U0x` z1Gj?t)GLN_L7RdIDyFT&c7UD;koE#7Z|CdBmII4U1#H+9gdzw5eAxAZX%82B1+Fs* zP{u8YVC{s=q%Q(qP&sP z{wKqd+fya4RiLt}C@l+U;wdFje8u+yPFFCJ#7Ry-G~h=AV=AC8wL3G=%G+8mhDMP) o(1WW2DxXKSkFE~9&Hjt{1B31#G%zjfmH+?%07*qoM6N<$f{9EIs{jB1 diff --git a/graphics/pokemon/ponyta/galarian/back.png b/graphics/pokemon/ponyta/galarian/back.png index fe45584312b7bc9a46be9e20725d43d503a84c52..f798d5cb45a3fe010810f1a0441e9d53c31fd7aa 100644 GIT binary patch delta 649 zcmV;40(Sk;1(gMm7=H)@0001;w}I>c0004VQb$4nuFf3k0000mP)t-sn9!g|$mlSb zsDR+u$E$ny^vm$uo=8|o5D*YRIHlWD#Ex2TG}{{Z{;6H2;&AC zfS2^J4g#2b4e)+0U+#YrNb?5)+Wm&G&~Sbd5Top(C!PmnNRqJfwtoj8W!ScL1aQ`% zl^|m~Cr)K{kRYrVoq~TKU9k;CR2hZ2e#gkT&wj1I-{|5#sYO0C+L> z0b>L~kU^LL=qMBfEC6GKdVO?IN`Qg)YdMRE&H>ymvV^Aj;5F1zZ51 z0Fi*8sc61#qlMFk_C!?I04HZ11&BN_M}vJ)Mdrd%1~?fPj_&N)Vyll&fNJXj`cEWW z`RM}nrn>|1S-^dzgXnE55GB+CyLB}4CEW8za~95*yoG4sWDPiX03M7EbtRakwA>kl zI6mgR7Jt`#K8jd!73%c}oIg1kmD;7K?o1itcH0~q(44j@Z70XZG+Ee=xP^~I3DSpru% jP<+Ju`s|;wzZoBc9W06z2s3m50000P)Jxv5D*YpAb9Bb@W9x}h@g;Icwhhk z00000`+h_X00009a7bBm000id000id0mpBsWB>pHDoI2^RDVdv&6PiE+dvq`uOfq% z3}=VpF}8!r>S)pEQbh=~>P*%O<;arnpafx5(xIcgD$pu6dJ>HU#( z=jbl9OX&^b;Qjf1p67iJjQ*#y7tGk#IkeVKNisvP##SICgd}L_<+cWt0a@VLfFR%i zA;HPWsIf;#cz@1;`CD^~Q(hA-G9TFhd4A;ijCd+fWg{7hHQd)b+ zU~K{dO6wLR{$x^EP<9C6bI9IX0V*b$EN@>1=JD#I(E~qX)N%F2m_i30UeuuL^7d;7 zC?vp>B(VH^Z;_BPG2E?wS{jHZF~BM}TaYcz{s6f9Yk$BEHJ|`^>cor`k;U-Tozzj= zAuD0?JS1{P2U^UiyKfg`B|*rn1EA|2AVCJAUbq!-snAH}MhzNugYj$eDBg@ZfE?w> z!(yL(uZJ9#<#-1OY1*G+;iB(N51j#Wd|e`Am22FaNWeRB2F`e(o8$m3h159%ysN=@ zssX6b*MB8|9>zMbvrh*2+)bqC&^l1oz!#UO6I34TdG#yJjlesM{rY;Lxui0PBpN)M zX+af04_ZgL9z*%OP&WlEsIpO*fGSjg=D5{x;j#T)R2qPNs2-IAWk)^X?dC@zgQ({x zhz7WU?R^>UI!Gs)$Uc04Z=rC|2&BV_7Q}@OR6cxot=DvjbpUOv?^Qhm%$Lnp!U2r) r*2E1g#1L5pi+WGoZGUqA@F4UXj2(QUp`Ej900000NkvXXu0mjfRYyZH diff --git a/graphics/pokemon/ponyta/galarian/shiny.pal b/graphics/pokemon/ponyta/galarian/shiny.pal index 707eb51faa..62925ea1a8 100644 --- a/graphics/pokemon/ponyta/galarian/shiny.pal +++ b/graphics/pokemon/ponyta/galarian/shiny.pal @@ -2,15 +2,15 @@ JASC-PAL 0100 16 152 208 160 -72 184 120 -16 144 64 -128 248 176 -200 144 48 -248 240 160 -240 200 80 +72 200 232 +48 152 168 +128 224 216 +199 171 123 +247 244 203 +240 219 158 72 88 72 16 16 16 -88 32 120 +64 56 165 232 248 240 192 216 200 136 160 144 diff --git a/graphics/pokemon/rapidash/galarian/back.png b/graphics/pokemon/rapidash/galarian/back.png index df065bf1f0e64a7e0bac64d93f3c115997c86a68..59816614d913fef37169edfa0a2db9adcb8fb1e4 100644 GIT binary patch delta 630 zcmV-+0*U?N1(yYo7#0Wv0001;w}I>c0004VQb$4nuFf3kkvdi~e0luPB64*;H}m&NbhjP3?G=wRCARq5sBOwS6^IlXthZ$hZXF>(cu0YE-O-!yJx8CQa0&KS(fSwl$ zw-X4E1e^lMbM!L-2+~>mq@FL@95K5YBu9sBu2u0TFIi z2bX{Zlzhzj-6esI9rj=gv>iarGXY!@$N-I?jZo$jyZ}H2933j3+pGaT zQYe6+1L(VeNe_?$HlS6|Rv`od2rVEll2Fk9FT(-22-iBn@o>(2lzvPBFaRzEG@dMQ zxT-^NhXOwu$a+VG^QdbR1_k#*0M%at)E->_qNZF`LjzF8=!f^!Q9uB!9zFw%t6&l! z+yf>G0N2B{{X!1wtfcv7h9MJ$&f&s{BIt9eT6~Z&XfBkuV0Wgs&aK0yye7$yV*00013M{Ml?0004VQb$4nuFf3k00004XF*Lt006O%3;baP zkuDg2kRb5z@Zi{h02pBS_|Rx*c*w}mprEh-0000000000TV7D300009a7bBm000id z000id0mpBsWB>pHJ4r-AR7l6w)IE>WFc=5$Af*dabG}>1)Z`0X;&y>0rxc~o8*U)- z2LRnrSRy5Q)QzFTiJ4PXrW;VjwHqo`Rj-|Y_*D2MPVA%wF`l=`zdq03c5Ulvj%SW@ zS$z!K^Uj$c21?kQ_B_UCo);)^XwIKwHbT$q%Fj{Mn70uQgy@|BF%A%~QI@c0%>o#U zc~&Ag3S!Yfln_0}(TM`8$92?PqAI|8Fks(B%_X23^jZ-*S170e_WVn0WP;aO-2r2N z-|PNf8~gYUv<|FC_+o1;!X^+`9WJ2o{pBZP9}~!s>X5=>QM|l8%rsyF$ zKhE^CP64tq!hk?Qrr+ppd@wpx8TmZS&*_hm_IK)#3Jd@UOs6ir+r7EbBdClC6aetm z-7|21Bx9c!V4Q)C2GR*CTR;)5g6F-w5?V^MZmnm`=|{P9sK-!5;y`ZwF;zQ0P%B>8AA^C zEA6l(=o?@=se%39z<OoKG7{GH|fFBkEg$A~N1Go_)DGb1_KLhkb4N?Jr1|@LV z)#ND;`Z99LG2V#DW4A?njoma z6-(K*^wE)^P8oV8NJ^0W8_0`=!s9|glTO*9~S o=-@3o6?J+0n; z<0ueCjYWcx-O~U6?c~P3Sgx9Rn25&RWrxi@B&)djc>G_A;qnXhlgrN-qTa9w<7+*s ztrmhT5ugP>ItMWVTb3T-eU@)p0Q?>xccMd7fE}c2l4EiE4qI-iCLp3A>=G`d5b&!& zpA(`X*oF{Nyn={-`T_wh0ZM`kA;d8Qjz6USSTh6+2m!D)Tq;0%Uku2Yu+;>Q%8mYS zmh_<<&<%zmY$d>OZ)v?b*82+ZnP4^-%*N|A4D`~A1pxIs1&>|e_5*;a0W^{wAQOxW z2(a*aIg&dqRR|+O1UQ`b-I$kq?Xd)&m8KK35ZvAr>H}fCs#Q{<-&`=kv{kFeFR?4}1e`9`(=nse~Q?&mNHG!Flh2^v8jOaR@5_>YW5| z9AF`aP@NDKwkg2Txbp~H3_y9?3GD75fH;pd0q^(wkLa;31L&xOD924Y1#tWDdS9%E zOmGUoFK8Km#U3a!1LP2f>$(p4!~_{fuu1<^HR!=t&w_B`tP+6$Opw_&@@&`u(!tjP z3KYW)ZwCda9w0ZzgfTz}CL{txeN~AFD}WN{Yo)JCnN$E=qtknzy~CqgL|PLAtnGiVECASZ%-;h_;_H_BYhCmLr*wkDS+yn ziwGTABxx9Kpx^01)wJ$Y6pkN+_(*3d1lQ|_B@?i9PlTPM_|dtG`dYxjdr*Sf2>E>}1iZcK3KXT)~Iy z@vTgHnLk}u-xStaPeR7OMnfz6Ig7qzaat~s!j&To2vjq;3F^idWZ6J zjjAQ7gpdfhc<{#Pb&Ha`+u;gN((5PyG|t}WXayLZ5K_(9BN6EDakvP8<1h-qYTZ_F ze7&Jx&g1ZhXb&tdh(3Tj(q`y)lJgmj2!C*YQGyn_Oe&$*U#HJ=3k->b1mK^jj_&|~ z122RWnf8Oc{r96g1l|>Y z?%RJL51s74Lig~|{ueQXXnB!gR1Y8Re~w@i51ovf+oLI8+y6{}=%Kglp&uiHoe%~d z`kwtyW#FOj+5e;;dFWgAKk8c#EpsvqVQ@*Ddgz;kg@^uN|5e}Iu1XL6!Tu*e@1gUm zx)DP3&?h|-)d45#c_)O2K99MmhtA%Ab#DLXgbJ{*|HUvsLY(5EOZWU4;A8+#(c5wm zKiU66ACrn!9Pk$aSKcnfr(f%n1B$1 z&F=e#{YOMjKokfu&kOsXp-?0s5+b_qsr|3=2Soy+WH4Z5|BL)VPC#UWG_hd{}00000NkvXXu0mjfylt*O delta 1455 zcmV;g1yK633-1e%7zqRe0000$E@3%FRo{z1YCPzEAw`pycvg_SYngkN>ZVNU! z#2y`en6>5u*aZdRQz(>vg3wa%cL;^#;FDu&O4RpeB<<+Wno=nA&<8fVJ3qboqbGm8 zpQimAQ8A3EtHzD%jm9nGit$FnG#ibHM5QrfLzsDjKxoxAX0Sypr9@whn-FBcG?j=~ zIv|>+aK8imBf17P5LCK441*tg>pL*IoQp7|+dKq1kLiH{{voc)b(@g<;UII1KXqX+!pGaVS zJjarlqq1=D$&4BJat4U098l}lEaL{{Y&ixNQ$WsfBd9sgyL{B?biNkA+*D=})d4k* zf1(ha$IBc8I7gSt@EKW=8O*s9uo2j&d_)Lktr6@;#m&XEPG{q||&)sf@FB4lA$UIyr~FHUDKkDOLA zhvj^v0#)Ar<=5ZBrVT(}gX6Xqr!zp0k)Qv(JR-KkVGhr<>?z&Cx;8Bd5LerXj$AnZ z7HqU>+KU>jacQ0)8{cr9;CX-8PK%G=4BZMm8S^eyVOkM_vh79A2>{nE+rb0UJxc{( z4ggrwUY?N$h;^C+?3+L=H*DL9fATC9fVBg_8O$=3{*(bsoWu8h(o6xH*Hdxg+ZZfd|o96upn4t_1GDv)ba1?W9oFqXt@Ogbb{4TmY z4#OUW-Q6cxJL$dLf^T)Q{zDjs_rqiO!rK~bfu(oy{SbGoll6ZvJeGh9KtBaG&VGl2 z$F%@KNKXLz&dyFU1$h^7SsFTY4J`(~fBQB8^o?_+bZ~aON%ziQri;|o;zi&PpG8-_ zDhmvE&L@n?e1|`toViyKP4M5O(@L=Qxy{ku#L zv`qgl(F0BC-(Hy>XxaW<&;u>szw>&a<@YxZv!Wh|lZ5{L?VAw#H!JFa2zY2A zpntQX9>^4L5P<&8ih3ZoL6CUu_@qP+FnS|+dAw*kat(iZJrModg;xXi?{c6gURSWR zY3>#EKok920ykS;K@XI=0s!t-UJr6WQ4hvZ$KLFf>46F~C+Y!I4FYVk9sq!TFj)_@ z8uo5ZCh9>YZtifP<$53i&;vG656r)<2TTF<&G>Uh50du<{TJ6aL_;dQj>QSv@HAhm0PS`hy#Y|NY^g#9vgYxo$K$5Q6{!002ov JPDHLkV1l}ju0;R< diff --git a/graphics/pokemon/salamence/mega/front.png b/graphics/pokemon/salamence/mega/front.png index bec9a9254923bbd63430a73dfdd70bfa90ed29da..44812fa0580a958ab66c00fd37441e1432d4ee08 100644 GIT binary patch delta 915 zcmV;E18n@x2-pXZ7#0Wv0001;w}I>c0004VQb$4nuFf3kkv=|u16D~yK~z|U)tBp* zs~`-8OEHP8R(=1so$Le%WPXSF|4LWnU=Y9A6Wg7uJley7R287HsnGyATR(**i?wA1~b0NTLpemme?a62uM}!i%K^O!N ziynx0hY%4RJ54=*1CBN6j3c6V;z)?nIB-Hx#697lKP9vSIHlAk!hk)2?g-GU={zEX z%&Hf~{hpuz39i=HV*))Qx&?HEV5xsTRc?Cmc)|z5KG74WFhM`1M&A=gKqaVtRv#h~ z0DYow0h|;N>GfjBIooGK1~3XYgcrZGsu@WzH!P9A0hqvltQC`c&=Rg3YdD03{3QT+6d~wiR6^%M48H)Vp4|ZjM4G<^ zAZkJ-YB2yntqU=hYI$BIk+GI-F_~T!1`u)mM}WPb-r)_sUR45TfD^)VjKBfDC!p-2 zUm1at5qunf-9}JSR5uqR0Fbzh)D&GhFq&6f@S^mQ;Z%PGa6(9xV6Em0ed~fv@VWd3 z;3bm*Hb+BOzt>|*3SqW`=&mESwqPo($2wrq2TD*oB2M+ovaaNMBaq&&lybl65N970 zkZ)CwvRYU5VBW1DG$J{bFRl;x9)TPWvNjb2Ok)#&=A5s5Ubd{)_Npz~^XP z2`$tB$xl`9FItZJLI}P<1%w$=7VHDrUG>L&1+MB#4xOzvt(%~`Fx$%kb3Fk5BJ)23 zQgwk%uWi#h7RtjvA~d74sBPL<;c4phbF*!zBs_z8MW(L=+O|!{C-PX0w+w)!JFtYD zB(HLRDIFjaaVGd00XBarjh&0{W&pcLutTH%e z!k1~Wr>pmxwdw=57SLV~ey*8Yd%_z7;B4Fgj6tss zfX&wdVZ2+fI$O4gd?^#8|Gh0f4Y~jVdI9t{j+lzZh{}2Ej*Z? zjG%@5h5HIl%I?fh<$x)|roUb1=a+_MlAX?Cwg>412ueNi_9Y}+@R==UZh(#;Kfjdk zAH(Me&L$ZF;l0%KD-eLS_97L3U@T(Ha_}#LjbNO{J_x%l&W2Y?0Q4D5`X)i1U>sgQ zh!^vvyLZfn3kh(kFk(kF#JwaD&?xOsr|cPXDdQh*7ia8C$Z9Rf%&77mx{8Kl4uj0sPFyitG#5>)s? zN${}*-lAuq@4dm<$aTLhX&lB+8{yfgtgvGe0J zD70`&)wdVQtNtsMv$Hzx*P>6SoeTJ90HOsc(bJ%XIL{mN12Lhra{)%}>1PSJ01Q?@ z=j;m%JZzaVYKIEY4-XGna|`<{9 diff --git a/graphics/pokemon/shroodle/back.png b/graphics/pokemon/shroodle/back.png index ffecfe183c738a176f30d48dacffa35e38eb815b..3bb3cb4a581cbcd32eb4acc66e0ebb92f172a360 100755 GIT binary patch delta 81 zcmV-X0IvU%1A_yQBt`*qQb$4nuFf3k0000mP)t-sn9!hod3NmU=nxPPtfrYyXmvp2R#sCDb6mC&YEeg#`%_5ij1H5D*a9u%g4kC&RwB$g^RH`$lZxy-8q?;6BX?@)(9{H0B36mOaK4? delta 39 hcmey%)WbYMWul>tq(DiKU+{l4a8_~Cl#N-!i~zUY7$g7y diff --git a/graphics/pokemon/shroodle/shiny.pal b/graphics/pokemon/shroodle/shiny.pal index bb3f9a6a7d..67046e31cf 100755 --- a/graphics/pokemon/shroodle/shiny.pal +++ b/graphics/pokemon/shroodle/shiny.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 152 208 160 -96 88 88 -232 236 200 +125 121 118 +236 235 232 16 16 16 -176 168 136 -64 76 104 -72 60 56 +172 166 153 +79 104 117 +72 68 65 48 36 40 -128 156 168 -168 168 224 -96 108 136 +187 210 227 +173 114 205 +128 149 168 248 252 248 -208 200 248 +225 171 233 184 176 184 -160 112 224 +225 52 239 0 0 0 diff --git a/graphics/pokemon/spidops/front.png b/graphics/pokemon/spidops/front.png index 944a9110703b59239fd9f6a4158f98c9ce3c0131..d6bfb05623f29b943304159461107219c224c0ef 100644 GIT binary patch delta 696 zcmV;p0!RIz2L1(*7#0Wv0001;w}I>c0004VQb$4nuFf3kks&^R0(?nCK~z|U?UvE9 z!XOMp8zhEatp5Ms-fVyZTH20%H8VP+u*XdZsnhg}UwjipbWQJW?h=8#^Zp{iU$)>p zUnQId5N#BlPFv7y5$_1p@f1Mi_xpVVan6DW6}^VM5sm>8$jx(>yAV2p0uBiZm^IvN z6a{pG6Baaq*Wa9f!Ud5qw+ay-w+PZ0)eK&*m&*TMPUcw}fZ{^j0+2eD27my>0Nlz$ z;4M9Jtq3dPngVrlkxx1Fj%+o-$=b+@sNa!5v?EV?7Kxf45a<>=LJtEznh=Xy=Cj_8 zhB<1me%6;F^i6MYd_02K!r=H;eL*mD0DyF*0%UahrmqcuuLw~Eu40S?K+YZ9p}y-a zR)FdVu1U)YK(rj9eAWHxRKK$7#s5jD*BS)Hhq^9E&fLk$**i+pWUX76hFHb;58jdk!z*JlmEcK~F)eW22L ziIlO>OZGRY9{KXLNEQ;|;K7E+ zcMHfC7PEkE*AcZ3z`-{=vW4Wps=N@GGw_zjugCQ$m~Fju3VM|%BgtE zrnyr`561RklKc45+t5*R0Un`e~)&ThJ)@pyi z52G~^G*|<~VX`KJya*sPt<58y7j#NUur*p@Y}ztJ~x z=(qSFmy-3SfFIMuI%FTi2%(rrS#|Gt#byR30p_wh)W?Y8T$WIsliNmmyC#1@>1ksa z?wu=Qn<aC)0azoE=F?o{ic1psa?95u6>A=NsyC#cPw z-E4fPdY$mXgf9Y~c?BDfry96_7$m?Me7j-%ozkQGhiVBh8L*OAcPbm$vBcCVBA2lvht`UqU8%n6A`m;{MVY7`E_MRbZdC%Xi4Z#aohXY^ z-NIs(ejI4q&33ze^qfFmsG*-db$e++sehlxwVR><6fFH_Y^b5e7zy*+R z4z)Q}>q*t*0zRDps)kXi0a}0lel+c000DMK}|sb0I`mI`%#mTdp>^wxk*GpR9J=W zmg|m#AP|Ke2WBj4-~VxUE`V-ZODsQ{?0S+Kn)W+$7!e$XOPBtIpqC#z9lmY=W52QZjftYTU+$#q; zroEPBc!F6%@PscDD7~xr;J`VUObpRF`W}CDU|al>&k6C{ldq{MbZG7vu}yI zb+ytfUxhB&P|8xKCKl~I6{|`ytOh4e7u-MSo5P7?VLw?6+2Pc&vY%{@@cHTJ5qeHn sjnMUq@_Oq#=g{?rGqjffrAvQDKaOA&h;chPo&W#<07*qoM6N<$f^S#r(*OVf delta 627 zcmV-(0*w8>1iA%~7-Iwj00013M{Ml?000McNliru=K~KD9|x5PZ3qAW02g#cSaefw zW^{L9a%BKVOhiylM<8}(av(DOV1ZP1_ zK>z@;j|==^1(7j6e*ghuOGiZir3doG0005rNkl!d5@h;6&-TT z)XC8uqC*!q_YK;^k;)22WkObbCqbu*_?W9oy|Jie%f!%usX~IqD=Qmg@)@|-5C~4- z286osZ1($mpZAaNjL?hzlROs?Hl7>sh!c48L?CnnZ5KeIf5%$@;E_Q9Xn5_1O#tY5 zq&NL0!Gab5=rmCXF5cWo7U;w+LU{KBxP)^+i*qi7;5;Us$l|qjeX*)EXduKV9t8m1 z3-@)A8e_DvOd*7=HXDbqGP(JwrxLt3n+~rEU2IOnYM|JigWun;GL_D+K`o1va^9%L zrxr?V4AdUGe+B$Lw3Vk-YOafQRV0#9%=k@>KBO044i(fGZlpRFYF+a}A)7`QxPrAHzB$i)~M<3sr?-sCe%IJLqe}s~Y$>cKA@3(`c@`TzI*9`ox zc000DMK}|sb0I`mI`%#mTdp>^wFiAu~R9J=W zmfNy}APhx~XdpEI|Gg)nwdLYypwovl!+zDZ3=xCNGBY#tUjmwM=v6c5z$d-F9R0jo z*KZ6N?YxK8KzK&^veEvlO2M z?_tJ72d_Kf)*u2bW-%X+e(j|jfv&y~a7K>{%I$n7_#9^nV1Y=h;PN%30$kq1W-3?& zE<2C<1v*DQd^-~^PX@&Lktc)Eu!2keN`N(UGFQj{b!KK}ew{yk1rVnz{m``l0000< KMNUMnLSTaMRGQcT delta 481 zcmV<70UrLf1F8g&7-Iwj00013M{Ml?000McNliru=K~HE7$LNEW#s?>02g#cSaefw zW^{L9a%BKVOhiylM<8}(av(DOV1ZP1_ zK>z@;j|==^1(7j6e*ghuOGiZir3doG0003_NklH%bibpKI$0Jgl|SJkH*0D@oDo5w-MD9bwwkoJ09yg%4N zrqKbg>S1)~u(RqrBe!j93lP>iW74jL6{w%h`Lz%)mKLEf21>_bY|%XFh>Z{eah!4* zuXKl686d94bHF_{9h8p65Qrq8_ANox01!7rfa`@$)Nwh=ArOE88pIs@K(2>90=h>B z@R*z17z`qVtTTXqCE_u_x<}&#c*K;!yub1JAVS9VcMcAqSAN%a7=a%ffafQ3s=r%5 XmjaK4oR^ph00000NkvXXu0mjfuk*q> diff --git a/graphics/pokemon/wattrel/front.png b/graphics/pokemon/wattrel/front.png index 72981aa44e918cfb83114d326639dbc6a7d22f26..c2527bab8b7ff61611573acdafce86c0c1a610f3 100755 GIT binary patch delta 419 zcmV;U0bKs^1ndKl7#Roy0001;w}I>c000DMK}|sb0I`mI`%#mTdp>^wXGugsR9J=W z)!S~vAP@x50QPW)|NqK&lssK@?K6s=!dB_|sIKi*ilP6F9b(G|Tx|Zw`%IF@m zB`AGmOXvd_!|yx5A;5VYr`ZA&7&xIwuy#YhVVu)ANI3n@2na4l*MOZ(K$JM(IMWt@ z5Q3vuN@?>p0FL9WmD_)@E+`8cWAwGAQI`5iQI}(Soj$G*$!bFtZ+gFBc3Mc*%dfcA z^XS{@KZO7zxpaWMNr3t#f7e^Tk25DQ&;+Uvpr0;N0DLXCz+XTU-W^gu0PpXBQpQY- zz|+eLvIyR^<3(}(?LrvfAu0*Abl?`u>_Qu&*0Bh`(r3XVkDY(W8Fyf&&;Le`QO|b) zbA2Ho-C9L}2=n!BR0%5;oLZLvA*9x)$+@f&aA+4MWHn_;2o4tm-U@a$0om7nnJiP} z+w_odYun#SkqNwlJR_C?K9nPm8=@n^tqW|lEA=tI^53N=PoDgJz5wfb6aE_8R;~a5 N002ovPDHLkV1j|XzXSjP delta 553 zcmV+^0@nTP1Mviq7-Iwj00013M{Ml?000McNliru=K~HE6*U_H&(#0`02g#cSaefw zW^{L9a%BKVOhiylM<8}(av(DOV1ZP1_ zK>z@;j|==^1(7j6e*ghuOGiZir3doG0004%NklpAZcc6DBsjG3U5X&h zU1pI!vi*N~@7*Pmw66bIs;Z{v7~?b{YXGvFVz7l-9g9H*f8N*et{4dTExCAQL`=#6k7K5H^m2#(IaP7KJr1&ZZq~Gg5jx;flh;84RTFN=M$yK`!S2cR! z=Nmhw2@UYbZ1RPdH5)p{2f&)#1`Vu3e&_+H^A-ib$_G%_c);ttv3zQpI{zeIX9jsN zjThyC>LOtEf8J&QZcAPr^8=iA4CKtw3P9aiFbe{|>fFPBqh=C+7V3sU=!XFSomD=$ z#MiiN07smS`^JE5h1k?J^(># zpU{VfB5_$p7BVJt8uD|+ij6TQl;2_rBt#^_TT`)ZJ0dA9OE4ayXWLR-cPIjg3`lu! r=eBs=mqp+i47uZf^+}J{^{49_v!|#+h#uE(00000NkvXXu0mjf=7s1r diff --git a/src/data/pokemon/species_info/gen_9_families.h b/src/data/pokemon/species_info/gen_9_families.h index 8880d3584d..a59dd88fe2 100644 --- a/src/data/pokemon/species_info/gen_9_families.h +++ b/src/data/pokemon/species_info/gen_9_families.h @@ -1765,7 +1765,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .trainerOffset = 0, .frontPic = gMonFrontPic_Naclstack, .frontPicSize = MON_COORDS_SIZE(64, 64), - .frontPicYOffset = 2, + .frontPicYOffset = 9, .frontAnimFrames = sAnims_Naclstack, //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, .backPic = gMonBackPic_Naclstack, @@ -1818,12 +1818,12 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .trainerOffset = 0, .frontPic = gMonFrontPic_Garganacl, .frontPicSize = MON_COORDS_SIZE(64, 64), - .frontPicYOffset = 1, + .frontPicYOffset = 5, .frontAnimFrames = sAnims_Garganacl, //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, .backPic = gMonBackPic_Garganacl, .backPicSize = MON_COORDS_SIZE(64, 64), - .backPicYOffset = 2, + .backPicYOffset = 14, //.backAnimId = BACK_ANIM_NONE, .palette = gMonPalette_Garganacl, .shinyPalette = gMonShinyPalette_Garganacl, From 77148f83a6b67c1874e80eb5793a52579a015da0 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 21 Aug 2024 09:57:28 -0400 Subject: [PATCH 52/64] DoBattleIntro state documentation (#5231) * DoBattleIntro state documentation * Removed unused state * Update src/battle_main.c Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> * Fixed state jumps * BattleStruct state uses enum * Renamed state enums --------- Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> --- include/battle.h | 26 ++++++++++++- src/battle_main.c | 95 +++++++++++++++++++++++------------------------ 2 files changed, 71 insertions(+), 50 deletions(-) diff --git a/include/battle.h b/include/battle.h index 6d81bc146e..084c09f789 100644 --- a/include/battle.h +++ b/include/battle.h @@ -607,6 +607,30 @@ struct BattleVideo { }; #endif +enum BattleIntroStates +{ + BATTLE_INTRO_STATE_GET_MON_DATA, + BATTLE_INTRO_STATE_LOOP_BATTLER_DATA, + BATTLE_INTRO_STATE_PREPARE_BG_SLIDE, + BATTLE_INTRO_STATE_WAIT_FOR_BG_SLIDE, + BATTLE_INTRO_STATE_DRAW_SPRITES, + BATTLE_INTRO_STATE_DRAW_PARTY_SUMMARY, + BATTLE_INTRO_STATE_WAIT_FOR_PARTY_SUMMARY, + BATTLE_INTRO_STATE_INTRO_TEXT, + BATTLE_INTRO_STATE_WAIT_FOR_INTRO_TEXT, + BATTLE_INTRO_STATE_TRAINER_SEND_OUT_TEXT, + BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_SEND_OUT_TEXT, + BATTLE_INTRO_STATE_TRAINER_1_SEND_OUT_ANIM, + BATTLE_INTRO_STATE_TRAINER_2_SEND_OUT_ANIM, + BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_2_SEND_OUT_ANIM, + BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT, + BATTLE_INTRO_STATE_PRINT_PLAYER_SEND_OUT_TEXT, + BATTLE_INTRO_STATE_WAIT_FOR_PLAYER_SEND_OUT_TEXT, + BATTLE_INTRO_STATE_PRINT_PLAYER_1_SEND_OUT_TEXT, + BATTLE_INTRO_STATE_PRINT_PLAYER_2_SEND_OUT_TEXT, + BATTLE_INTRO_STATE_SET_DEX_AND_BATTLE_VARS +}; + struct BattleStruct { u8 turnEffectsTracker; @@ -726,7 +750,7 @@ struct BattleStruct struct BattleGimmickData gimmick; const u8 *trainerSlideMsg; bool8 trainerSlideLowHpMsgDone; - u8 introState; + enum BattleIntroStates introState:8; u8 ateBerry[2]; // array id determined by side, each party pokemon as bit u8 stolenStats[NUM_BATTLE_STATS]; // hp byte is used for which stats to raise, other inform about by how many stages u8 lastMoveFailed; // as bits for each battler, for the sake of Stomping Tantrum diff --git a/src/battle_main.c b/src/battle_main.c index e0ab912e4f..72b2f0838a 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3425,26 +3425,25 @@ static void DoBattleIntro(void) { s32 i; u32 battler; - u8 *state = &gBattleStruct->introState; - switch (*state) + switch (gBattleStruct->introState) { - case 0: // Get Data of all battlers. + case BATTLE_INTRO_STATE_GET_MON_DATA: battler = gBattleCommunication[1]; BtlController_EmitGetMonData(battler, BUFFER_A, REQUEST_ALL_BATTLE, 0); MarkBattlerForControllerExec(battler); - (*state)++; + gBattleStruct->introState++; break; - case 1: // Loop through all battlers. + case BATTLE_INTRO_STATE_LOOP_BATTLER_DATA: if (!gBattleControllerExecFlags) { if (++gBattleCommunication[1] == gBattlersCount) - (*state)++; + gBattleStruct->introState++; else - *state = 0; + gBattleStruct->introState = BATTLE_INTRO_STATE_GET_MON_DATA; } break; - case 2: // Start graphical intro slide. + case BATTLE_INTRO_STATE_PREPARE_BG_SLIDE: if (!gBattleControllerExecFlags) { battler = GetBattlerAtPosition(0); @@ -3452,14 +3451,14 @@ static void DoBattleIntro(void) MarkBattlerForControllerExec(battler); gBattleCommunication[0] = 0; gBattleCommunication[1] = 0; - (*state)++; + gBattleStruct->introState++; } break; - case 3: // Wait for intro slide. + case BATTLE_INTRO_STATE_WAIT_FOR_BG_SLIDE: if (!gBattleControllerExecFlags) - (*state)++; + gBattleStruct->introState++; break; - case 4: // Copy battler data gotten in cases 0 and 1. Draw trainer/mon sprite. + case BATTLE_INTRO_STATE_DRAW_SPRITES: for (battler = 0; battler < gBattlersCount; battler++) { if ((gBattleTypeFlags & BATTLE_TYPE_SAFARI) && GetBattlerSide(battler) == B_SIDE_PLAYER) @@ -3539,17 +3538,17 @@ static void DoBattleIntro(void) if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) { - (*state)++; + gBattleStruct->introState++; } else // Skip party summary since it is a wild battle. { if (B_FAST_INTRO == TRUE) - *state = 7; // Don't wait for sprite, print message at the same time. + gBattleStruct->introState = BATTLE_INTRO_STATE_INTRO_TEXT; // Don't wait for sprite, print message at the same time. else - *state = 6; // Wait for sprite to load. + gBattleStruct->introState++; // Wait for sprite to load. } break; - case 5: // draw party summary in trainer battles + case BATTLE_INTRO_STATE_DRAW_PARTY_SUMMARY: if (!gBattleControllerExecFlags) { struct HpAndStatus hpStatus[PARTY_SIZE]; @@ -3592,48 +3591,48 @@ static void DoBattleIntro(void) BtlController_EmitDrawPartyStatusSummary(battler, BUFFER_A, hpStatus, PARTY_SUMM_SKIP_DRAW_DELAY); MarkBattlerForControllerExec(battler); - (*state)++; + gBattleStruct->introState++; } break; - case 6: // wait for previous action to complete + case BATTLE_INTRO_STATE_WAIT_FOR_PARTY_SUMMARY: if (!gBattleControllerExecFlags) - (*state)++; + gBattleStruct->introState++; break; - case 7: // print battle intro message + case BATTLE_INTRO_STATE_INTRO_TEXT: if (!IsBattlerMarkedForControllerExec(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT))) { PrepareStringBattle(STRINGID_INTROMSG, GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)); - (*state)++; + gBattleStruct->introState++; } break; - case 8: // wait for intro message to be printed + case BATTLE_INTRO_STATE_WAIT_FOR_INTRO_TEXT: if (!IsBattlerMarkedForControllerExec(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT))) { if (gBattleTypeFlags & BATTLE_TYPE_TRAINER) { - (*state)++; + gBattleStruct->introState++; } else { if (B_FAST_INTRO == TRUE) - *state = 15; // Wait for text to be printed. + gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT; else - *state = 14; // Wait for text and sprite. + gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_2_SEND_OUT_ANIM; } } break; - case 9: // print opponent sends out + case BATTLE_INTRO_STATE_TRAINER_SEND_OUT_TEXT: if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK && !(gBattleTypeFlags & BATTLE_TYPE_RECORDED_IS_MASTER)) PrepareStringBattle(STRINGID_INTROSENDOUT, GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)); else PrepareStringBattle(STRINGID_INTROSENDOUT, GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT)); - (*state)++; + gBattleStruct->introState++; break; - case 10: // wait for opponent sends out text + case BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_SEND_OUT_TEXT: if (!gBattleControllerExecFlags) - (*state)++; + gBattleStruct->introState++; break; - case 11: // first opponent's mon send out animation + case BATTLE_INTRO_STATE_TRAINER_1_SEND_OUT_ANIM: if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK && !(gBattleTypeFlags & BATTLE_TYPE_RECORDED_IS_MASTER)) battler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); else @@ -3641,11 +3640,9 @@ static void DoBattleIntro(void) BtlController_EmitIntroTrainerBallThrow(battler, BUFFER_A); MarkBattlerForControllerExec(battler); - (*state)++; + gBattleStruct->introState++; break; - case 12: // nothing - (*state)++; - case 13: // second opponent's mon send out + case BATTLE_INTRO_STATE_TRAINER_2_SEND_OUT_ANIM: if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_TWO_OPPONENTS) && !BATTLE_TWO_VS_ONE_OPPONENT) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK && !(gBattleTypeFlags & BATTLE_TYPE_RECORDED_IS_MASTER)) @@ -3658,19 +3655,19 @@ static void DoBattleIntro(void) } if (B_FAST_INTRO == TRUE && !(gBattleTypeFlags & (BATTLE_TYPE_RECORDED | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_RECORDED_IS_MASTER | BATTLE_TYPE_LINK))) - *state = 15; // Print at the same time as trainer sends out second mon. + gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT; // Print at the same time as trainer sends out second mon. else - (*state)++; + gBattleStruct->introState++; break; - case 14: // wait for opponent 2 send out + case BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_2_SEND_OUT_ANIM: if (!gBattleControllerExecFlags) - (*state)++; + gBattleStruct->introState++; break; - case 15: // wait for wild battle message + case BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT: if (!IsBattlerMarkedForControllerExec(GetBattlerAtPosition(B_POSITION_PLAYER_LEFT))) - (*state)++; + gBattleStruct->introState++; break; - case 16: // print player sends out + case BATTLE_INTRO_STATE_PRINT_PLAYER_SEND_OUT_TEXT: if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI)) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK && !(gBattleTypeFlags & BATTLE_TYPE_RECORDED_IS_MASTER)) @@ -3689,9 +3686,9 @@ static void DoBattleIntro(void) PrepareStringBattle(STRINGID_INTROSENDOUT, battler); } - (*state)++; + gBattleStruct->introState++; break; - case 17: // wait for player send out message + case BATTLE_INTRO_STATE_WAIT_FOR_PLAYER_SEND_OUT_TEXT: if (!(gBattleTypeFlags & BATTLE_TYPE_LINK && gBattleControllerExecFlags)) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK && !(gBattleTypeFlags & BATTLE_TYPE_RECORDED_IS_MASTER)) @@ -3700,10 +3697,10 @@ static void DoBattleIntro(void) battler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); if (!IsBattlerMarkedForControllerExec(battler)) - (*state)++; + gBattleStruct->introState++; } break; - case 18: // player 1 send out + case BATTLE_INTRO_STATE_PRINT_PLAYER_1_SEND_OUT_TEXT: if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK && !(gBattleTypeFlags & BATTLE_TYPE_RECORDED_IS_MASTER)) battler = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); else @@ -3711,9 +3708,9 @@ static void DoBattleIntro(void) BtlController_EmitIntroTrainerBallThrow(battler, BUFFER_A); MarkBattlerForControllerExec(battler); - (*state)++; + gBattleStruct->introState++; break; - case 19: // player 2 send out + case BATTLE_INTRO_STATE_PRINT_PLAYER_2_SEND_OUT_TEXT: if (gBattleTypeFlags & (BATTLE_TYPE_MULTI | BATTLE_TYPE_INGAME_PARTNER)) { if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_LINK && !(gBattleTypeFlags & BATTLE_TYPE_RECORDED_IS_MASTER)) @@ -3724,9 +3721,9 @@ static void DoBattleIntro(void) BtlController_EmitIntroTrainerBallThrow(battler, BUFFER_A); MarkBattlerForControllerExec(battler); } - (*state)++; + gBattleStruct->introState++; break; - case 20: // set dex and battle vars + case BATTLE_INTRO_STATE_SET_DEX_AND_BATTLE_VARS: if (!gBattleControllerExecFlags) { for (battler = 0; battler < gBattlersCount; battler++) From 5a320f94d247310b05c8278f54c49c4cf927ac3b Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Wed, 21 Aug 2024 17:43:57 +0200 Subject: [PATCH 53/64] Fixes Hyperspace Fury softlock (#5237) Fixes #5236 --- data/battle_scripts_1.s | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 083143bdf2..5bd91f8df5 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -928,19 +928,10 @@ BattleScript_BothCanNoLongerEscape:: return BattleScript_EffectHyperspaceFury:: - jumpifspecies BS_ATTACKER, SPECIES_HOOPA_UNBOUND, BattleScript_EffectHyperspaceFuryUnbound + jumpifspecies BS_ATTACKER, SPECIES_HOOPA_UNBOUND, BattleScript_EffectHit jumpifspecies BS_ATTACKER, SPECIES_HOOPA_CONFINED, BattleScript_ButHoopaCantUseIt goto BattleScript_PokemonCantUseTheMove -BattleScript_EffectHyperspaceFuryUnbound:: - attackcanceler - accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE - attackstring - pause B_WAIT_TIME_LONG - ppreduce - seteffectprimary MOVE_EFFECT_FEINT - goto BattleScript_HitFromCritCalc - BattleScript_ButHoopaCantUseIt: printstring STRINGID_BUTHOOPACANTUSEIT waitmessage B_WAIT_TIME_LONG From 4cc193ebf1e839f9a14aa36a2d6a8056adf8e1b0 Mon Sep 17 00:00:00 2001 From: Cafei <46283144+Cafeei@users.noreply.github.com> Date: Fri, 23 Aug 2024 12:38:09 +0400 Subject: [PATCH 54/64] A bunch of fixes for follower Pokemon sprites (#5241) --- graphics/pokemon/archen/overworld.png | Bin 737 -> 627 bytes graphics/pokemon/archeops/overworld.png | Bin 1063 -> 983 bytes .../basculin/blue_striped/overworld.png | Bin 682 -> 654 bytes graphics/pokemon/blitzle/overworld.png | Bin 623 -> 641 bytes graphics/pokemon/blitzle/overworld_normal.pal | 2 +- graphics/pokemon/blitzle/overworld_shiny.pal | 2 +- graphics/pokemon/crustle/overworld_normal.pal | 4 ++-- graphics/pokemon/crustle/overworld_shiny.pal | 6 +++--- graphics/pokemon/dwebble/overworld.png | Bin 526 -> 506 bytes graphics/pokemon/escavalier/overworld.png | Bin 1279 -> 1286 bytes .../pokemon/excadrill/overworld_shiny.pal | 2 +- graphics/pokemon/krokorok/overworld.png | Bin 885 -> 826 bytes graphics/pokemon/krookodile/overworld.png | Bin 985 -> 852 bytes .../pokemon/krookodile/overworld_normal.pal | 4 ++-- .../pokemon/krookodile/overworld_shiny.pal | 4 ++-- graphics/pokemon/lillipup/overworld_shiny.pal | 6 +++--- .../pokemon/sawsbuck/summer/overworld.png | Bin 677 -> 721 bytes graphics/pokemon/serperior/overworld.png | Bin 1101 -> 1076 bytes .../pokemon/serperior/overworld_normal.pal | 14 ++++++------ .../pokemon/serperior/overworld_shiny.pal | 12 +++++------ graphics/pokemon/servine/overworld.png | Bin 582 -> 621 bytes graphics/pokemon/servine/overworld_normal.pal | 6 +++--- graphics/pokemon/servine/overworld_shiny.pal | 12 +++++------ graphics/pokemon/sigilyph/overworld.png | Bin 786 -> 713 bytes .../pokemon/sigilyph/overworld_normal.pal | 10 ++++----- graphics/pokemon/sigilyph/overworld_shiny.pal | 20 +++++++++--------- graphics/pokemon/snivy/overworld.png | Bin 623 -> 562 bytes graphics/pokemon/swoobat/overworld.png | Bin 831 -> 830 bytes graphics/pokemon/swoobat/overworld_shiny.pal | 12 +++++------ graphics/pokemon/throh/overworld.png | Bin 1071 -> 871 bytes graphics/pokemon/throh/overworld_normal.pal | 2 +- graphics/pokemon/tranquill/overworld.png | Bin 768 -> 828 bytes .../pokemon/tranquill/overworld_normal.pal | 4 ++-- .../pokemon/tranquill/overworld_shiny.pal | 10 ++++----- graphics/pokemon/venipede/overworld.png | Bin 616 -> 645 bytes .../pokemon/venipede/overworld_normal.pal | 4 ++-- graphics/pokemon/venipede/overworld_shiny.pal | 18 ++++++++-------- graphics/pokemon/vulpix/overworld.png | Bin 818 -> 739 bytes graphics/pokemon/woobat/overworld.png | Bin 530 -> 565 bytes graphics/pokemon/woobat/overworld_shiny.pal | 4 ++-- .../zamazenta/crowned_shield/overworld.png | Bin 1166 -> 1166 bytes graphics/pokemon/zebstrika/overworld.png | Bin 983 -> 926 bytes .../pokemon/zebstrika/overworld_normal.pal | 6 +++--- .../pokemon/zebstrika/overworld_shiny.pal | 6 +++--- 44 files changed, 85 insertions(+), 85 deletions(-) diff --git a/graphics/pokemon/archen/overworld.png b/graphics/pokemon/archen/overworld.png index e25f19ba7f21e34f53caac0b73e23d7585997d05..6dce497d6d3a5830a522b00cdda7cdedc69019f6 100644 GIT binary patch delta 568 zcmV-80>}N~1@i=u7#0Wv0001UMu)cm0004VQb$4nuFf3kkv=ki0sTotK~z|U?Uuok z>>vn5MFRNn|NnQuBt1O|n5yo@+eoUiIUpBAlTwx~TefW3vSrJbEn8L!xP8Ihs=3sU z@mKMPn_H^ziSG%9PpaSnTaV^BCK!=;rtpcsCrEuB@L6D5;sg^j9SXzMpZH-?H?*Cq z@)0(NLtz%5Vsv?bOf3t3;;#%1nHgIqV2-~iKx|#p_s;RF&gq;P8fs_ zh2B8xQIx^;9XP1(j0c8!yg9`2u8>g4>kkDEPTnPqv1d^0p>z%QcudHF!w&8{=y#0K zcn3Y+9pW8-v>djyJ83Mi41pSq=dVKdv3H4QxEwg1VJpG!nJNkppCJGp4kh`c8NIOt z*{8~9Z{o0v9%n6Cpq!^OYl1f#JU+g~JRW9WQYC9+GG9CAxx=n<@}bJnsj|X69-`~} zjcZHhYsa=p6Nl69BXk%%#ZP}_r1Z%j^Z0_!9G3kT5BmXVuN1c}wVGd00KryL_t(Y$L&;2Z__{!UDraEe5#|6N<}PkKUW7Yd9CnLvYo zL9!*vgcz?U99^_#XXS^hvm`sM&a}`+Iqb@Pn^JmwvWD8uB_Ut}lZ{HH5;SNu8f_LX z!SJF}dWtGJymXlCwayw9`+Y%9U`51lSMy5;EpssPX&~u^`09~vkF7BKGN#T4alM|O zkXO3*uCO|3V?-%(Y@lC!ap}+Yiz@?v_ipMR58ZWv$)iyaz5Kpx*}VA{MC~9BSG?|d zyn+a diff --git a/graphics/pokemon/archeops/overworld.png b/graphics/pokemon/archeops/overworld.png index 8a8a23a4edf76796cc9f60309c83f8d5dafdbdb4..6d8faa6597a22dedaab3857e7c9e9db3e8232bfd 100644 GIT binary patch delta 922 zcmV;L17-ZD2-gRY7#0Wv0001UMu)cm0004VQb$4nuFf3kks&sJUP(kjR9J=WSnYD- zAPfx12yFTNpZ8YaU<{&Z&bf~tWjd2KuxNKBWYfpvXZ-u&+`AK>#oryyPYFzCK8e3Q zoTtT{SZE~RMpvB=Y~ne53vY6ICwVR=vKTO>*l*+3bsfHo!BoH@d<$JCJ6JH&k;R$$pDFF4;$>$A!Sm;k;3h*&X0EN?G{3Y?a z2aczxg)mUA9pS`Rhu^~Y0y6(De;|d-kjPwtgvQ|@Lwp~d91e;b<_`SR;R#+hP!?_| zuiCz_gi89Z^PrxRP_PA{?}7qVhe*R;Dgf~jUQlD(f={^w_%@!Do_qGH$I7~JkgEBZ5m^Zs*!+)qUOo(@(RMC*Z zV&T)_*gLH8wLg@>g@Nnv;c&RG|B62Z4EVE43Qze%K;D-VB)IV*@4Zxq#g8?PHbXE^ ze~5WJqux_>m?n7e)-o9IwM&Y1{5t{8p-54)<0)!?95%WPW5tGc8RCXnLxJNeV201t z6KKHKE~%-JXuL@j0im2NoHenQK)}B14;g(P@gw?^4<5ZLy7Hjv`uypzjgMIY=`S7r z*(DGA-B{zN0?dn*ff8un_p$ztC#~Z}8!;{H%qMN@u!+Y4#pjOM;cJ&X`p;P7MZq&~ z)_ie)ct0E-tnY?BngI>mIP(z@-vB^1a-Pmk= zb7O1q{f#ZxkP0ySd|5KSC3OVS_`cWPnVoNWa%d@cE-ye4!`qK{ojQ?)@0@kG^-VUGafHRqeYt&Ph092>KhHJ8m?XxQv+*)+Y zAJrp|_d`}<$Jv^1Ab5Po_ult?cSi#7{|{&z1LxuRy-~B@HF!V#eu1a@{?V!;aO8ho z&DA*iRz8Jq$wj>~ANAN*_rXt!Ao)e&RO8`5;!DW_+ji^i>a|^8JqyQj&WkMd@4(SC zdwq-l(SB3jE~TbAY`fAC8pt^)OQxrH;5%uO`Cu-F`>jYghtn-ny(AEh41uj=x^V|S zOp~))0>Sd;`OSDJbAOA|O4yZS&O5il&^!P|D zyAm%QD;zpEYt!Dv+*(1a(V!BrHZji6jS@|AH{QvD18-K%fb9m(j!C_#@xp(x!fT@( zACn7J(83ABq3Te6bJQ^eoYsUDj@WG6tO)klReHj5!LWeCc8(clWL6QvDc>`!OD9S( zAk;ImbJ~n?hiulA30xE6G)Sjn;5gxq@l5GcN=S!#72(oJ>RUX4NmB|SdiiM%fE@BF zldb79A}h=Z0?Z@yL{mB5=Z=462b}h`+u;ITDimRM_48{h;t8mxAU=1P!;$L36L#US zyd@LZbAwKw;z&}~mJ7%I3a?GBqmD;tHxxZV(;+_nQ?HOp!0BDKRSJ&_!`;dNC-9x$ z>EJiJV&Hfo;5telenM&AL4p&V;rJ}{X6h&^O2qqhLkvay=IejDswICe{Gs>7SKSfc zx#A^MI&k0CJI_$e~2*Jama`eIYy>XwT2Rr_F Z;y?5OTMg diff --git a/graphics/pokemon/basculin/blue_striped/overworld.png b/graphics/pokemon/basculin/blue_striped/overworld.png index b8f0a345838b41119688d4484ba889fa38f43ff5..b900662eaf1bb01d1d1b1c3062386a681999c7bf 100644 GIT binary patch delta 594 zcmV-Y0#V?!Ilty{Nl{ZEP)BS=4&xTAGMe0UYC zB2pjjgw9AkJqbMk!#zV|=K@;wQYXU!44Fo{71p>6FKuDl?5a>}3@! zQm|P(-q$B=kyZXBuluurz0P- z{ET5R?>QH)42Sq~o)U+@@~4!R`Cr`R$86R1HrT4!Ot^7>;C8RYycgnzM;V7qHe3C` z(P+ape|Z`#!~Ea4$-fmb*mf9%zb0P?1swQ!0l03eDu-n<1$^;_F=bnT7(|ocFN?up z0S9glD_G*ULAC}Rj`lTbdR6~tg9olM1;QX6QiHM)2l>}rTfk3)Y#ZQltS&FNzWkd4 zj(kuc)`u^D%!rH{=pg@^_gBn1<2-19%dxz8)D9%F20b3AR$0Hw`nB3$3XjV^mmCtt zW{sGzQLm1BY-|%bNhWq#D g{MM~oxBfBx0oE8CVDvQL=Kufz07*qoM6N<$f<444X#fBK delta 622 zcmV-!0+IcW1*!#*7zqRe0002CwraMKE;D~YNkl(J%niavB#KN^RzWuCb5qK^+6*Njl)6x=>69sEtzlSqXn? z7#MHT0iVBfP&}ke8(e571U?1#6hqW6h4sb#J zFcFyUXdz@*?%mwG_|4+I6~{K4cTp3{{N<%!@BEerjOXHjH#+43AHKx__<~*28|Ebe zOOE%^4rB8&ehy`xQ6d6PZk@XGdXAHT_fahp0l+(32xndfTWmUKQ~WL#E*XCz@g

    -BEFx%wx$T{vN0ruypI40#-Xu70D zn>{g4vrYQ^4i1Dc&7cxohF?i2*a%50Y|>%Oz$YXmy^h2*kk~+k1PF?MLz;m_!#)kE zI1hp_n1#VWutj|TOq!<|AcR`*zJ`N7VOJ$72!KI2uh8TwP&N@Wc*I+9ele*) z#+AXhfb0FT!lADjn-9q4JppkhDV+6UkrM>c0^hVQRmYO%iyZNupixwB2J1_ zpE}*<%uHHYWq+efBHoN@&bq{ubEPHDz~H>VwJxlTSPCQFeV`DZb>0eG;4LD~Jiw^7s zj)%i&F@Z|KwEFS3M*Q$%2sHMgD_j$ZxGiLH#_r6Ldz)Zd@huL+q*Xu0z@6p4!rKxp z^48e8y3jZ8(|}W!V@wzVhKa|?;WEakJ!gw6A>i7eG6c@I^HHFE zW}vp)TWvioottwW{Y?(fom=ts&eo%NTc=Nv@c!5s!wTFJfJ2pWR#Tn=?#F+dEXI-N zILetvx_(agrqJoNz=QbwRyj{s;rMkC8E5CC8&1$t0!vmP=LM<> zFBdG?;{O(y)r&`Z?V;Z2n*!-J^c(Z;J?>fk;oG2q3yfh!x@|4>8*|#ky==Vi$qMAm z7^Yiqi)_kilYdd0w7Fhi_TIXl6kx_UDEY3x;x;Nh>MUk!j)y%-$c^y~`UszKXRtnk ziCU@WJzaHf>2~=ca>z5&?UlIyScV4fS5?&(jJh1zy}dpsm>*dRnyev9>^bv}9;& ulLBV}tgXBw#g}~5F-ZT8;bwrX6@3Fg%n?ZrA3c-+0000VGd00DVPL_t(Y$L-XyZi6ro2H=Z4u#zTH)%8Mm zH;!r;L;M6)-ykoLmZ4^5uo){V!Q&P)#D?k;sp-&xoA?gBn84Q@_q6j3;x^%=uN(kAaniZVOGrn?44s%Tz)r|Q z9Dp)Y?ney|Ft)Di_wY(nLsS&nNO_{n)~c^Pr>w30%7ZIS4W-c97}1j6xxfQy-POW> zH7G+-bzNPjl5+Xx0w4TK+>#UpefQq|g`5Rj2Ab@pMR+YhDLuN%M8~?tA=mb76GtR+=;mHTG z;V8`KMHOci3kGP>FBdQl@PVwI1i-{6eDW&l8zO8J{qpIeO9B740KNeT?vmxkI=FBE O0000c)EJTlx70+S8lYb{dzUESLE^}7KmEs1_jSG2|2 z1>>Fm34q@H6CD6oWAAi3<5%?`1N=~rp4phR#gn)@{nr6+^a#9ETO2ZZr~fAd*E1X! z!y}@S=Ggair{4pA5QiY9O9*^XXSZwQYK=J`Me#-vg!H+74@i<(*Z}oC%Q@z^cOd{0 ziR7&R^hK1g&E=hb52$)3F#w_b4Fi@SzyBmb(e7h*LMepwv3?Jz*IGR{I$Z*`K_W;H zbbXhp|LDe9o0drCfLQuer&GXo490@0HP5`Mg5<)s1V!2Kn6f*44AH0Dt2zEg)mb?>UA6023y{Ub!_OW^e?wZbPx= zddc9f4=YW7`ScDnl=F1sxf6Up_R|00c4hWeb{mY zAomqE={3N1oe{8_bb}OVdpxw4$79pa)ga_kz#4#m4lw<%zi2P4plYyZ#K@}J|JDF* z8T2E7vYsxu0CE9jy>>V#X0~-j4%V%?<{8c>fO#(=oj#lWMh6HkQx6ybmD#t-ve^{X zHpX0aX#$8Be|{>UH3QTq_5L_Ag8>FH?*xOPF{snV%LKS6gHHfsPsWGsg@D&^sb{tF$HJKl-^ANzvA6!j|Aj7FQh;=TuMg`MV4eHEFjssxSxFSdRD+a8& z0d*Khz~{PB_6KQGK)yF%)wrI=0J3MZ0zNInPXKbW#M~hEdpCg9+ZgoeiXC8F>Y<2I zvcY--oYNjr0a;V1qr@ofF5^#GV}?Elkfeow2S8rZVW1e4T((KmyFJ9FfDb^{2}pw) zI^Cye23*%C;Yis6`lu)!&8+UCc?_@&#=$^rj+JhZy->@uyftVcQEfWmhV#0N-D}8U z0Ad}W1AOWd()mnH2VP)|ylKy>j{z7V8{mG{0AQCw5cCFOe{QA}vHSaTKr;~smF;!OWyoT zoqxR3fia&Xed9bPDD=N(sN*}ky+lxRN}p5I0S-l+$}=a{4=2Mk2{>tQ3>H8fxaRVx zWT3nVpb3z^q_@MIgVGd00dh}L_t(Y$EB4$Z{s!?fL{^NEnTeGNLQLR zDWJg>u${KEWA$c5jU@E85Fjv=?pq~U?X8$OYPp!XQ>oiJK|;HPjfh@yG$Fz*Y-(Nj2x%n>}q2Lywt z_v!5EtL@Jw-T!v^$--S8%=@$E7@QsE{~zejrX&bv6Zg+u-a7%s&j!&kBpbrVo`E-? zO^>CN!`T2I;(Z~j#5kg&-f%uPi@f=i6}3{be>y+J`$DGJXu-ly4lJ;rsiLkgXJ?0h zcwZP=R)&!oq2^|Us2#Cmd-O5*X(lUwbasf*T4>MrmE)?R90L<#w4g#_2xD_W9lKi` zfK*i$!w4VZoOVKUKJrV;Wz__;QjajaoD_P5sMc@5Ylb%QOsQG`9Kj*ZDR)9)0y&kT z5irBd1f;Y9J@`$ooG{PztV!07Ws^~V%`+!VWN88-Omh82ZJ?l1g>~~SLfHiTj@y7= zNkXXPt$&MAQD#=i62(n0&5}%ir6y24;U-Ag z3Cm6xB_=3IR7!zR#j8vsOTC~}e8fJ_~y%`HS%L866;7M=&C31WErOM3H{`AZASR6f7I z|CfnGX`vob$Ba86q*bLSrZfSmRBl*E(F88^qI`REqlKd=F~JzUWAztHFhL|P2s1)5 zPPH&3Rm-#tu@%Ojy{<~4gj+^`s`~wPRgthZ!SD0}Gq(i7>(~YcT z)e=7E+DBCaj!|A=C;a2*I#hNU7D^?B=2De*lCdJDKd|~l;N09&9b}~r)Yt?8ozBsR z)oQi$qNzqNJp;>tzCCY+FK^4sV>@edRjTmitzto8pAb8Zo$%soY=caH?}c^kg21l) zM)W@DX)FBxS2~^>pf?Ysg`j*bwL-fK|qsG>Um!b zEso|8Ho*dW3)~5xFV*aSxVfW#bIZb-e+;iD!Y$?YigSJ_2r$fRy|t)wx3_!+xe3Pp zbS)ID=63(qt6a0000B6AHXqKFxDGO;3fldG4L04+#bSEC1*DEAW{(KGF>eLV=h5RZ%0YrwR)k zQ0E4{rx`paFhQ<=FvJVk{4+Yq6qa~zZF?mf6a;C_6~@P0z(%0LG{pr@d0_ZwD4-xX z?iS$Zu*f1!O<<_7!fgYTm}OTr3E-R{{aa!W12}=v9?RUmRISR6Csg4yg+4Isqw5C* z?R`5Q*bzU46@4+!@a+*ER#*780Wyr}RHOZCf+^fB2_S=i)lWw)#9(!WJBctW3_3p| z=$Za=Snk@ViRBruCeAxB!#9>TS=cMdZ6{Ac>_CU>8zDiSa0KE@y;EP9oeHN-U9HLS ztBn93?MX<+0Q;Mr9$gf?MRqv7iVRP{Z#)TLEGRK_3Wg2-j07xWC*aRWKaOS@V-XD^ z;0?ON`K0H60c8SrJT0IG*LTHB#^~!oz}m;y2~mK&XA~SPMh(6@z;edraC(zHq)94} zIN+>=umkd|j|Yy}biUyxd?)BJKsbQ+!4xxs<;{WWO8pK?J1#dD1O1iPIMB{XpyM`< zPvsQYA9z?on3$A732}rvp$7rF#9_u_c_$$M?G?U%9X*Jyrck2}#0HLH1`I?RT;|x} z@dt);3dazi1UEvDI*qk$DOPN8>~ju5KLLpes1Q44$cr-UDMoXR&Yx(KAu0$&9i|Us z%?Ul8vz#x(-3J?R3V9D?3IyfZ%tM%AWXQE~ad^?Ji;byt4ybhy=Gd~Pce&^1P(a&q zn-7v%5pI0g$MP)0j1Z$PkVGd00PuWL_t(Y$L&&=ACS&LfK16B#Q#znh{=-zdoPf) zmv>Km@5tkkyv19*#X4w*b{dJm{OL@O-#}i0-j} zawwCH*k*K*iO3)W2zd&Ag<1(JZ?G~Hj_!U*u1_V8H(^3{^cldl8M%akYd8b#cx4@w za=cM?zsk|4v4oQI!%cW404xTD40ORGgAG=J3|8T2W5pB~8?g;ggG2#xG?^3{88!r8 z3?2R69PqS(g9f%i%ih%?nmroDzgU5P3@fE_kLiWgpL+=8JVf=iv5k*LN}b&}{6`Pv z32u4{5c;`bDuP1cdrkqGlM4_bxckF&kM+W}ogU3o8I}`=vtqJ{+$2&F_3EnoA!B1>?CkaI;WH;{J^iPz|w3APO7Jmsrr|E5Pd)wRI_RlPt z{T~0RrEC_i@W1&qiP=dmlIPi0@Lj&m(>V@P(0NXwf_*M&3vl)W_%`=fIO6cg&{*cP zTuM*zT>Jozc*i>eb~!ef@s+b&5}2Sqaw(q2F@FU3I!9%zYAuBUIuRc69$?A#6AIYp zTZAbR5OZuT=YRcBi*F3@h|@GR2mL^RdWL_oS2<57rma1`mw8{H6qX1ag8+{B4+NwZ zA(N9&@aAM8T6m{<5AS6zNt2kv#npern~!KQ)2NT%x!(q~w)m<$|2`KJr56eGAMt6r zS!uDtpfle*hcDc55QN800eMlIyYm`ergRAO?{ld&BY#b}XlDE>UJaKA&vgg^6C{<- zT0cdzcTq^m8&Bi#ZVM9>We`?Fz96xzGaOP1$YUeU<-t)5%M)HWabh_(K?4n|jPc0=>7ApB+&Wk&GCHF+ zNhuibj(-)MZnds7c*t{nc7F8kaKo)WOaR<=xQfa+UKibX)TS0z@x4YyCq-`Q5eUR< z@oEMquLMx~f6Ri{=tF>;WI5oB@1kqV5+BXuLDDNcQZ%0By)u6O5jima)pt;IfnFlk zg@z5p!P&Sv+iOFvtKCzn;8RC_y=vFzEFgShn16s22}mY@uS!oqrhreYAe__jGSQ8b z`mY(=y=(%!T?RK=Q$c>7TP3A41*-&2j^D3LKynqTP0bB%pRt1F3lECO1W0rj>bi25 zdxpjZc**k3x-S0kx>j7| TYDSIc00000NkvXXu0mjf<@Jto delta 975 zcmV;=12Fv52H6LY7=Hu<0002CwraKj0004VQb$4nuFf3k00004XF*Lt006O%3;baP z0000jP)t-sn9!hTP%w~qP)8vdsEAkq007{~SYu;j?Cka?B_^nlK)I~Ffr^2)zsI=1 z$VKS~p#T5?32;bRa{vGi!vFvd!vV){sAK>D12suRK~zY`?SEB0Z`42#HL@HjUDn1c zAeGmb>yXZC`IQb=)#&)Y+?g6fdufvuskbi(fw`94O_wCWk3igMj%y^#0wCiAOJ*YXgN8BoMOLP z$lt)W?+Nk<>042nq~tA9v_lC{;yFkFAPY54azc=vNdnQ9kk0CEj!p`tC zAb*siQyTsR7`?MZ&F4)f5f%tmr@viu=}ZZXq?C0^{U^sDWoq7<31@_&GqZ;00m(^_bc!;}2!&?CoJE-5dhtETNv@wa2|~O&F>dE;soq-?kon!b zOA~F7WkeBFe5dYVV-OrpM)9F;-NBxPTS&mF&dzyb46+p61iw|iOg;ISZvf3fbH422 x56GDr!&(ISXI=tFG-E__&XoT;$~(9$>n}^A+6sPVzUKe{002ovPDHLkV1g>Ix6}Xt diff --git a/graphics/pokemon/krookodile/overworld_normal.pal b/graphics/pokemon/krookodile/overworld_normal.pal index 04d2244669..e416936398 100644 --- a/graphics/pokemon/krookodile/overworld_normal.pal +++ b/graphics/pokemon/krookodile/overworld_normal.pal @@ -10,8 +10,8 @@ JASC-PAL 25 25 33 99 99 99 236 236 246 -99 99 99 -185 172 189 +35 35 35 +152 142 156 38 37 38 129 138 129 182 191 199 diff --git a/graphics/pokemon/krookodile/overworld_shiny.pal b/graphics/pokemon/krookodile/overworld_shiny.pal index 070a0a4e5d..c89ebe28de 100644 --- a/graphics/pokemon/krookodile/overworld_shiny.pal +++ b/graphics/pokemon/krookodile/overworld_shiny.pal @@ -8,10 +8,10 @@ JASC-PAL 168 136 88 0 0 0 224 200 88 -99 99 99 +48 48 48 236 236 246 168 144 64 -185 172 189 +122 94 0 38 37 38 129 138 129 182 191 199 diff --git a/graphics/pokemon/lillipup/overworld_shiny.pal b/graphics/pokemon/lillipup/overworld_shiny.pal index 63bbc81935..ffdd1a31f2 100644 --- a/graphics/pokemon/lillipup/overworld_shiny.pal +++ b/graphics/pokemon/lillipup/overworld_shiny.pal @@ -2,11 +2,11 @@ JASC-PAL 0100 16 152 208 160 -104 72 16 -96 72 24 +97 62 1 +171 105 39 184 128 72 -232 176 88 0 0 0 +224 169 81 240 216 152 88 88 88 232 232 248 diff --git a/graphics/pokemon/sawsbuck/summer/overworld.png b/graphics/pokemon/sawsbuck/summer/overworld.png index 7bb026e55df07b9ba2b6361942afc594924c0289..1926a5f07112089536c67e498745c2eee671d82e 100644 GIT binary patch delta 664 zcmV;J0%!fD1KVB8uc$R1tct|5Ik zMzL6T>weEa1&q(ulq8wSPeeH}C@Dt$i<)6&ilZUPmVXEse>zM65zY*1N!FrGDTSbP z-o3to7rqfN{^AgSAi|l!p%{(YByrX%Zy8R$6)?X1A;dW|I3`xg)|~WXGe=MU00PFB z34kteX3!L+NUe4S+r;2dz<3A+qbr;kwD!sEKg^MU@lb|9ugE^(%-}f7z|I2 zGOYUH7-4ScFoO;3F@%q3y{kjJ{*8yW41UkmU(X`FVE-;Z4IW*E2QI+p`iiDMxQ{?C zC0nS$$=)Xl<4bkSMSOrN8P~MU!r2HR*U?pfGU!+9idC!fR&=fDUk@vr3xv`wkM$=r%Rc)%=#363y zz*GGXh2rmyKVR=)JeKhT6EbYiHaGtQhLD#hJJ3yxX-&z zuhLI3qcMqL149EYjjN65wox%Jjb?w{mj+0zF;;b0xgDQxS?F|AA2k~n8sJ5}-_~Ew z?ll4YH>PgGB4#w7>*MZxGISI0{doVA1%!dHcLSqN?Rc~m_gbfG-L0elbV#e#~gRQhWy*QyC1Lg-F5C*!3Vk?N7M%I7I-KL5e zdb@8QM_zy*2<45v>2QBy?N^&p%x*(O{H+NCq1+|jTUAzG|9WQKM74++(5}~3uz)ad zo0@XNy)+}{{?y$QcGE%w9F}*SXlFAXh+9fWEAEuI`(&#-yNlWdq?07=H)@0001UMu)cm0004VQb$4nuFf3k0000mP)t-sfY9g+VkdKO zIT)Nu`1tq;5D=Wzob0U?bEIzdmt39tKk*Yk@wdboLa3)W zJO3Z!MD(Y>3jdinw|y6VVc)k~17ilo80Er=GqQjA09O)GIHnRG7$1Ej{ZqzA;y~a7 z>}1fe#+idh#<{J~7xs0af65SvLxFSnIM7&Abae5Ny{BtDbXS8zXLI7-DB-e{qW*AR9s;W##2f4^U>?^fP3gNOH?{8`np zKD);-?q>`rL>xG1Sr!~LfD{-7)$$Ee&$i4!>)0&#Pq2IMWp;S^XL=;;xa4z+@YoO?si-FuFF) z83wl6XRmj+OES*8=#XIy{uh}x@7nS}AhZJY7}&FB#Bw3zUIl1icA z7$$!iS${JC<*F}dUNL$VYnZs6ngD&ToOSD|I+Dgsn`Z9teP7{oOE_rV_f{X{n0L%5 z^%jZQV`Lml9>U19A+Uj5DsWxZeMlBJu;&~tYiYI@t*Ee0aH-Ik!H`H~fw?5u4Pgvr z2vwhx)%j7_v{{eqF2tDp5`C=B=@1;BLk1vJ34a3pQuNtH(7>`QD?-h$GfDln*$r;H zF!O-5O1-*@&lz5B7CescA14}^f6)UFSBPyZ16P~f;HC>DA>jE}NuizolduWn8}815 zf-M0V5qnDD)nyGHJ|mbeq?l!|fjs`C;8ZZqjnpuVzNH4=@OlFZrrv;$(UVsl(sbE{ zhkrGMqT6;MMW31Bar5BM)!d30&%R~oHMqnp814;R@WNTJ2A1d-&hF=1t9J9nmw+!M ztc}bJc-G?FL@!ASJWGcwhMu52T}VV>cKRCv21t6n0uP*Bd{^4p2Pr~}?*S4FE(&p@ zLw-D0t5B`OWEjc--=K17@%q5i6(Cjoj(@<9sw^#(7f-Qh0}UQxj|&OG$wPKP#*fuN zhM_aWTRhLg6(zfo1x8b$7Oyq#^jD*$LD+71V(1dHEAN9Sy!ksg zEQGw&3D-v_TXy#LPtAShux^!ub?m`5S+=K{a@;C~X$K6_Wf3$Le-qa+Ln lZbYb8N5(IFH1NL~{{atvHt$n(>Q(>%002ovPDHLkV1f&>^5p;k delta 1092 zcmV-K1iSmR2+atP7=Hu<0002CwraKj0004VQb$4nuFf3k00004XF*Lt006O%3;baP z0000aP)t-sfY9hDNN8trH$Zrp&)35T4i2d3Xt}R7V5V0nI55;902rJ~RHdGV00009 za7bBm000id000id0mpBsWB>pIvPnciR7l6|luvKlHWs zlFm2dD)ZVjlE6K~!<0jl#WAs^em(Ea#b1`j0EvT^U8fDj8h9Xai^x14)| zHn_{NZ%`ubF;wJ8&KuqK1hnaLwUkoLx9kgeIqk?rynoINwyx!TIpt{<=a9#6{`Yg) zNPJH~h(|=hs;2WT`vO*~qf(m2&OptT5;Uf;gv%E{-28rI`;~Y{u=hhhZ(tJnD~J@7 zNU4oIxUQIkLv?YI(778pO|ym&)S+@dhsa5t8)q#~=u{0=WEX&18s{k0h9XIpQ~O5J zLEI3q3x72z_%lfD7x!KT1#5YNH5lbP2Bk)E_Vedhm_xlt5Ed1?Py?QcKW~$DMYz-X?y0M#pOE6r8qYbzH z@N1Y<$7MpR8QW0HZ1dOqA(mgvZ1> zVt)#Lxt+M?6X6*C@8H3C*yZBb_Pax+5iF;a!WWo10}M!sV9sD5BXh)ch?);(kC|mq zCI#n%0e@pR9ZyQ41#6I2pGWyNBFxhEa#O}v_f6*=GCWl^YYh^S{in^-PY zVn?t&1=(p>@d;{NEQEb>x6F`ew5uO&UuZn{7s5Yx!O*{=5c&rz7E diff --git a/graphics/pokemon/serperior/overworld_normal.pal b/graphics/pokemon/serperior/overworld_normal.pal index 3733e903b2..6600b8af88 100644 --- a/graphics/pokemon/serperior/overworld_normal.pal +++ b/graphics/pokemon/serperior/overworld_normal.pal @@ -3,17 +3,17 @@ JASC-PAL 16 128 208 232 12 98 39 -106 115 57 +115 112 57 24 156 74 -236 173 21 +248 248 248 8 16 16 156 213 156 236 173 21 115 164 115 -12 98 39 -236 173 21 +5 59 26 +248 128 0 24 156 74 -0 0 0 -0 0 0 -0 0 0 +208 152 8 +12 98 39 +5 59 26 0 0 0 diff --git a/graphics/pokemon/serperior/overworld_shiny.pal b/graphics/pokemon/serperior/overworld_shiny.pal index eafc2d1fda..2a03f663f2 100644 --- a/graphics/pokemon/serperior/overworld_shiny.pal +++ b/graphics/pokemon/serperior/overworld_shiny.pal @@ -8,12 +8,12 @@ JASC-PAL 207 215 195 7 14 14 168 232 104 -185 175 53 +224 248 152 96 166 87 -40 56 48 -212 33 0 +40 48 56 +248 64 24 24 156 74 -0 0 0 -0 0 0 -0 0 0 +184 179 114 +43 99 64 +0 72 40 0 0 0 diff --git a/graphics/pokemon/servine/overworld.png b/graphics/pokemon/servine/overworld.png index b329b478379cf996f25e9d060fe5b6273b4e3b35..5c9caeec8c853772c2b0dea604a97cd6596b0fa1 100644 GIT binary patch delta 608 zcmV-m0-ycH1nmTn7=H)@0001UMu)cm0004VQb$4nuFf3k0000mP)t-sn9!gOQY78O zNh!rjACor#00516F#GezZa@^l!IM8(Ke$LB000000000000000#MCK|0005&NklC*2t{iJS)Bj>-@T~wvMbWM50h+4n`V+j@uEVV<9~SUvBw^J?6Lo3>C-%| zJwkr|k>@}1bL|lE&nAG`UFwUtc@WWJjbfg2-sNnNe1Q?S_>|4a^9gw-vU`iyybd1m zK0r5LK*+H|TfA0HtKboD#unUe;yrHh`{ORJ+VqJ!0weww$dokU=_L?x(+7q3c@;?{ z41t3szQxA?`hOBql9xIHB98ioKvepDZVF#ts$+H2&qa#(7y&CKs&zj81&$_Z*A8b9 zdFw;Fv^;O|?xbSoOz;KX>ui;P&zV)Vl!BiGzh57Wh#v-ujyAc?0Y++8?mr79;&3R8z_^;{WPgAQ+&UEPam%obF4^+D%a4NI z#L&l_j_DS-z;hz2uPx4}Rk$fkr2Jc7#M?nj89U88aD|+>ot4=6+y|VCWoKt4(pjH~ zxarG+kA=)C{0b+VV6rKmDvUTw>gP2_U&LE?ZGAq^|1?A#Tg#3*WPN5Tz8B51|5LnisD(4>!Ke67sAruENKB_O9_b uzO3HH>ygJ8WCLB|p;H)OzB?cLpnU@-FBBX$peQ{60000~gj delta 569 zcmV-90>=IA1jYoA7=Hu<0002CwraKj0004VQb$4nuFf3k00004XF*Lt006O%3;baP z0000RP)t-sn9!gOQY78ONh!rjACor#00516F#GezZa@@6rMO7|000SaNLh0L01m?d z01m?e$8V@)0005BNklilx5pSOw5sWOK&5<_Gj6vhRlD}Yrd1%$%B*sjv5w_7%OiV; zwFOPj1J~kMU4I=e^PE*Szx{nU$4ZBK-}310)o!TF>V1PpTS`g43~XIhk9LEk>VK_3ys{ZCQ7eUiaX2k<0006z0Br41}%e4dMNtcPF8;C`}^P-CstJNBD+mlD43i%YQe%F&-hjdh)Lf1|!5P z5$#Uk=o){=523^N`3)N!GCEm2-D1vVJ1jZJ+ituNJ3NL@8f->~;=BC0K%7ZAHNoYA z?`YWxK5lT=6?!hd%byA)X%G(p0o#j)UgqNly9CwZEKZ?ysQE(@=mZ}(xaU{&;w-*) zD6s$oq=Urc<9`NCR;yZ^&80($1r`2BiN`m=nxJl=@l`~zs>Rt{I+TcNtb|o|ka&C( zaDtYB#yL{WVEP1@oY_i~H#&UzHkLzg^0Zhs*2GfjZgRJ(h?=CIod_<&CF zCYU+Jc~%W{jv9G|O>nP4DZt>;m(8G%9G>7!5GqofF@j>C^EE+Kh4u!ufTDA05Tc^J za;NJx(BL9q>pHI^^b9P{67CF(x?8~J(hlP7#cviIm$1d}0(NgBbPZH42}bS_*QgW_ zi^<_HihmN-4%i&G8R@Q`fya4X&>r=doWmhlutXQbz~&IhZPGAsxa6m~%RFKg=y+N9 z89~d^*LYk~z=O)jz~gk>+mAd$pi;gVPioRM9!DhnR?I1>L%2M*zdeS)pdq%GWp54P z30#Bg4KFW49n0m0g;(IXL5O4}=oQG`WcYjejW!$LAG5Uu+ya9b82z#H`+$KL!7lKX j%Z>d0!QdO;_;~yPiccdgi)=zY00000NkvXXu0mjfXFx{9 delta 774 zcmV+h1Nr>P1(F7k7=Hu<0002CwraKj0016POjJdf(4Zl3fk;Lc2L}f~q~ohx8UMcp zC@3hvz{@Y2KeTfmzyJUOuSrBfRCt{2RZUYGK@jcD6yb_Q@1cmL$I$_2b0ijqqaVm0 zz+E{~PGWDaqU`Vs0{=F>eC+m&yH<`K>;voL^?R>-b|?Wp>VF+n(8&MXTYt3G8VJ>D zl<`4R$u&}^d;b^kBNz0t$Nn&$X3xjFVWW%>`WN@vvmW<*6@$`rJieO?)<&W=x}*je zUA0SjI6a5}B-Em&%nhYb-*|x5EZ!4zhH(U1*5bQisiEj!#FxUrDDI!<1DnUY8@`V2 z7V*A7G!NDRQGfGGDGw*KVur6;vIxlc-C*SLo`4J^fu@#s_=dFNrA9g0ZI})GJ7$PH zERXjEC#_pyXSKY;=V`?Z-)=X|Dtw6;qWdu5@tGjBg`hKx)bp&Hcld_1;*CZ%Vy~d{ z!cGL>^IY-xOb`wVfl#BlI-B1ps4!IB$yiMym5(?XcYoQ5(23c2!~>Ul#C$hz~QU5Y)}KL6}k=P=-g;a4hxq zn=NGXtnkmW7|0iBwQ1PteO?&7_=~Gl?JPEs1)yCmQ+6V*ppK}s292ha2Sk%BR@NYH zJvVU50)Oy(ifjW7=H)@0001UMu)cm0004VQb$4nuFf3k0000mP)t-sn9!gASO5Tz z2LJ#709XM3;xfgZ0AN5Mzqn_=xM%JDqUh-OxL6?n;xfgZ0PX&wIY+B$00057NklO>2@PlH2(?^M~ka3T;n}L;ZypG$Vo&&RDVdv?UcVt13?hR=hz}` zZVoIggq;wzlFJ=vOry`B1Y1ckwqlB?q{&%CEK?{cHHC3o!OAzVw6OIFYHuHs(+3Gf)DlrDsI?-fNg1qs94WnyFx5*_KC)PK*j2Y2Jf?x>ru5zd5=%1 z?^Cm$!9=LJUK6GPN2a@6E7*XKo6ec*W`n{pk0#vhQ~L%cvt6+hz;=`~SNApmwH_z7 zZz)XK)=ENMe#S0G_~i~T<;w7&7DBowWzNqEjBS;T8GmvEm$L&@`GodtZ)_O%dkdT) zw|Q!gw_q|qXevB%wkO8l+2kb3YqEH9jGzm^h!sngYT0)iPF{67egA)xfzlJQ>QbU~!lT zwhv#hZCh|IC(=*#Wgw_lD-lP~Z8iCL)X}lfm$cBURub@WSn2CfG@vpN21X96S4R$O wF9MGS;IQ*wgOU!hGwkvgy|Vz9|7-!g0b*Tq^;Z@+Gynhq07*qoM6N<$g7-)hp#T5? diff --git a/graphics/pokemon/swoobat/overworld.png b/graphics/pokemon/swoobat/overworld.png index ad665f8346656559d227e7c1987ad8a9f34e74a3..4648f80f6381e48b7362fe6e07fc1384f1b769a7 100644 GIT binary patch delta 765 zcmVY4})P0-hDjY_O`eEDs%4N;@>4Z@0U)W;sD>m zm*!x-IT`v8JbnWQvX}8sPcKd?NGV+##CUCRFRKI;Zt}ff^A$eicch0SPnHn^*y^R6 zD+fJ<(<$+4A4B1P6Fw!lXQsN1%=8lCvfgAr}z81I^(3gL4aef4s5A9$IsPG@=D}hs{8OYf2 z1s5NT=7gj%fw_S85u~$2xJOLB!l$tjv&;ZuBeg5V;|B+Sa3M(Kt!z2~@{a!OQJ=;p z{>MG6dH^KZQ8Hv(HTu#0#`^-4z~&540UJL}fJH8UQ z=HJi219y0TLI#I)0JQx^c{CwV81UT5o*;i3eo8%_M*fi>WoYvoyx}W>c?PgrD-m_6 zOPE8X4lVmOJSr%Kh*($(jNSIf)u!+~T$9ML=_6k@U*SFf6gct(<0!CJ5yl2Mf<%f< z*-@7n&sqw6<7q5_`9V~KFymkN$QOYfpAOmrA5Fr4H-(u!n*%xIINowny1Q|Q=7Wl2 zOD9bECvNgZ8#fjB7!C?EeH%n#)4L7~9(*g(Oeq|*^{PYTRkkJn#7+J~YMcq2>TvTx z%qqa_cy`?2AlEu-9MLL(rflDq{1Z3%d6e?u!md{*Jyjp zB&GD29iqJmu@1=~^TY`j;=ddaF>-mf*#2-mi%RsiE2p4G)rz|kg#uH5|s`hPD+uz+rI?@hXIRfs$|O`FSmQ zRUV-76H810WbvFBDu+zPO1`BBE<%4^HEe}6^)BB4YMKp#P&J6b9~*?RE4XI7WP5g% z(s-Z9fQKjR9x81DaQ;St7bY3|_S3gcS4GsurjgI|B6;f84t zNDj1r-S_?WqVbYbpC5mmpoNezbqDar!?;8#A?Y0e5-!pRht$e(>And*lR-Gj5N7i>IO zb+L6IJb)7Yt4tak5%Rz^Ad-m*IC}Rj>jfJRASv4YLPjHE4?z9^sTyjakzyKYpZ}Eg z32QG$t$-+ly!gjZPi-iMdRD_3US@p4(CPxMe>Z+cWGcWey;Qq_b4fBjVR%y)$QtAZ w1+1+k8&NfYS)Z`wZ(8IX6};h($ diff --git a/graphics/pokemon/swoobat/overworld_shiny.pal b/graphics/pokemon/swoobat/overworld_shiny.pal index 84b110886f..8a3678398f 100644 --- a/graphics/pokemon/swoobat/overworld_shiny.pal +++ b/graphics/pokemon/swoobat/overworld_shiny.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 104 48 152 -72 32 0 +87 48 2 248 192 48 232 144 16 1 1 1 198 217 180 -198 217 180 -72 32 0 +136 192 120 +41 18 0 96 48 16 -167 89 102 -198 217 180 -167 89 102 +144 72 112 198 217 180 +106 48 87 +248 160 232 198 217 180 1 1 1 0 0 0 diff --git a/graphics/pokemon/throh/overworld.png b/graphics/pokemon/throh/overworld.png index dabd0d8ebadc6f8e5cd8519f7449b8ef1a8feeea..69b2fef48608c0d6928889e742706597412a8410 100644 GIT binary patch delta 860 zcmV-i1Ec(}2?Ku4o;Upqr%zqniyz#~xZ@lrw8zm-* zYiuQMhClHK0W*;Jl{+_iiOIP!wu?;UyzTzWd`0gxS?k(PBsI| zQQd7{So55}5mfnihx4{T;@mD#rh@tR0f#9sT<-DLul~y&79BsdkO%Wq+u_4N;dy<; zvPSv_w10v<|KV`=Ph9~)3n=y*4zlZjY;(ATApa=)AlQ%{ST*g7cA%F%dm8kd|hhY_z_{)Sx$6R}IK z(N)QF)@br?855st+Z5H9y8>G6$cPW0n*tbL6d1ljxN2CoQ^7=Hu<0002CwraKj0004VQb$4nuFf3k00004XF*Lt006O%3;baP z0000mP)t-sn9!hC5)xoA7$G4U0002!a44WqATKX3*yzxBfM^Q~3n3vPxX7r#wxs3d z_a`SO8R=ZK00009a7bBm000id000id0mpBsWB>pIh)G02RDVdv?UXTSBS#d57tewr zDV!@VxD0kATq+)$9R-!M7fv=R z+&L+fq>+hivfwJ+wU@$a1S#$c!)120v$Jw?*CvG@2=veV^ZoA)%NRFxQ#W-}|D(Ef z>#e+;n3*wNr+O7xdUjvhSze$iN?Cm z^1x!(%xmqKzT71Go z4J;h>f3*6_Uva;zMA&U+#NO{Uo)38QXIf@D0I_{4C%7M`D}+Ch6VM}`o*+%k0oue@ z4TM1%fZ;(#=sqJn05uW9ZyeVc5ZF=!u>FlX{q%k~A|l40{6L+PBi>H)n-vDEMf`N6 zau}R(;D7x=+5y6y8WU|D;9yLI$N~@(`=9lCKW&CAA(T1q{MPIJdL%}GGWP+5oZ$=A zz<08L0g(D*AmOrMt~y?9Fa`mzG_fpLczpcJ@nOLCBmvDazH|BK<)zO>43OFf0gQt$ zMh%ECRszDrp8&bMAy8L}oCX&G0XDiqG|kG;d4G2D$5B8EHR)ap`2Ob`A8kTA0Z1)x zNcP;qssSu-Nb>rLKLN%!-pT?R4KDd`J_=Y|4G`=!I-7oginE3>|FA^D&Sv8fN(n&f ztC$CmhpK_8^H{Ts#Ge2GgA5p^SA;RPq~ZJ^QSUt{AsBSKhi3tL7z2tW(%R{En@~ys zQhz@uG0+;S2BzFt2fK-X1a##O53}#on2hzE(FAXorY>Ie-7|b)#P0{f#uaW^m4mBc z0+4#ii+ggbssYoAdESDNy*HCyT)BWm@1`G_VUmNFyMMug+FgP>&tJX>stT}zrQ5Ak zRRd<AE4bw~11o!*?g{BW7y7LdkL7}Rlna== zHo=yjAO=RK%galHZKao+3)|arQSUF<_Lx4k?WHI;fvjd!eWm{3!KpX74Un#w0Lxq6 zO7UYO)76BU3s9?Bnac19{EWTQ+W9go8%^z$0 gOZ}7ZACzJI4G1cPse3$UwEzGB07*qoM6N<$f&~xi>vz`u}RqO|Nn1&AuJaIm8w1*omlO* z%@~-O7?boko_OMk|0)1rm+(9Mj{_jA8DPNW1Ur1U{0~xAIfx+yoKrxACBYrOVYnG= z6D%D@#pekaHUc*I4h^_}xd$7EdH$dp<|}ZxC}4x5pR{7g>js$2USi`g(+_~tGB$qx z8shB-M=xj1Fb{@B0q-1!K%g}MG;w(@K)h`Pj7cz8U(X$;_Hh)4!MP0>V#qbXzd5sD zxMKu)AXPYxL<>XTVhHDX(p&*z9<2`BDs3L~k7bcqE4an>0%{X~7%QV?{K%qW=$Uh! zr{U-d(6uR2c9?$~jAQ{+1W+SD#9}7^u_+UgA3kLehg;Y%9Lp=EaK2NFy30oe7=&=^ zFbirDQKvpn`D$$tcR3ezX}!hr2gNprY=_!MH}}AB;D4obVHDj$&jbQsnVpN8SF8n) zUTawL;L}2KlZWuxWxOf5eRaQdVGuSbx9CjG6X_Q_} z|CI=93yc0J6hTG~`fUwR9OAGAwhXnyn=hKiose1qQUjI4P7R1VZ@k#3H?~E5S74NH z`*bR>#rrK#7@8Fw!<qlilhpAhLu9~ zie?WBx5LiV*-=dPqwjTk4!*>Ec)91G9P>9mIc~KFXpu}9-i>M3ha9R^q&`m z`RZA3g(H$}?j1QWCJd3Hf6zAyW_P#SP~H;w#q7Qo_AGF9*V#Nxj%|U>E7KBP$Nqh1 zjzd0#ywbl@>Iap-iQOCL66Z~{V1Hx*%Z%U0?wx=8KY{h&wZJEyc;a7-Z_u$2*%8`u QmH+?%07*qoM6N<$f_=}Az6z8MLxGjiKHnyahtJd4qD!keDCRa zIu*rR{I@|^o?%zvtAkZH>jV|oU>4-&GPQO@HMHwQBd)-lk=GXjnPbYTOtBJIV8%$G zSqpz&I_A3Jt34bbVp1=#d4ZAe3KICNW34wjHAMiRia^Yeo)c?ERIkfAd>QA(eH)SUcs1i+^}$fstWh0q|6!*#WP&a@Gc0PlUSO1qfPqmg8L^wDN%$AiY8=J}t7tpB2!LczmElq{##{E)S}e*v-n|#F@_v7I zY?K#};^VLB=_G>y3|6vI*-p(z@I=YV?dS`dG18*h8fC0)`XFFLJ3DTr7f|E=@UYi* zVW1L}RTdwRetm&nU}gk)W-Mrr%chs7rG(Jdbaq^{%S}=EL_a*7NU(?{F{L%7@kOD^ zNQ=+8QE1O#h>S(Cu?G56>+i^Y!p?tj9Y!93Q}O<>rk!sLoFh>7J>HXVc0D>6n#ctk zjEsy<5TL&)l5mbAAZV0+N1oVuZ1ZC{{$ydA5aD3*@ith*F=2FFo&7M-@fo-t#z&t| zkczQ%8mwVEj9}AYb~i%)zi^IYY}_}PL#p${I@&%sM=l}3 z+Y#ybB(T=|n;@LM49O;5ZxG1G^`9e-+Gko&Zy5f=X10cXAzrC=<`5% z%ItENmq?i$i#v|=V}fLg)FE~}too!vT`uQBHIwt@4VUzFEpb(&c08>5Btjj)=V-1< zKjl3~?6`a=2BR1>4D7h1Z}uK>IsD~1mWcbfYxp%j4Wi2;ddw`q<%|jL?P?uUtgfKT ze>rlVTZ~$V!N;>=$HTZ@l7x)EngO44jp#8LB+9WW>0K`Fcy2Meu1@^0N;^IWNb8hI zh5?sT#o|P|@QP7cBbSfFwXP1iE-Hmy;cI|=mtkPXJIpn_`pcZAL2-yOulDueZ^u7T z01lZh?%=Vj$Bf5uIwVe|L=m<2^>EkifA|V2oZv2TF$`=t_13Uc8+N%iK?NN!d4IZ& z@Q8w~c{eDb9xwWRhVSJ(THQ3T_*4GL3k=FZ`8@tTKMmfL9SnBkU;o s9~#!2hasB#z)2qV|143k4II6pZ$H%#R=XW?=l}o!07*qoM6N<$f(gbGH~;_u delta 576 zcmV-G0>Ax*1?U8j7&in10002CwraKj0004VQb$4nuFf3k00004XF*Lt006O%3;baP z0000dP)t-sn9!gL3k!TWNRdAte_FUJ`v3p{32;bRa{vGi!vFvd!vV){sAK>D0m?~4 zK~zY`?bN+$<3JDq;N2~*-nDLp2`TgwL9UdAAHXJg0If5m-k5WhMmFN=1Pm?{Lcnz@ zCv~_7xF^f#4y=`;Q3BVb@Dze??U~uxMPi3I#32sxb%F;h>@nXzy8Vd;eF6oV3c?9omUtyEzU_9EfD5oHXy1=+(+A2LE`Px+-Tju`{`y=M|&pgZA^uP9<_h@lEm>#lNwWaj8Ieow%=<5exhuB$`!~sL<70%)+8=kxS|z_`F!lz?LzsrcMHzSi O0000g7zqdi0001UMu)eNF&hyt008P=0026d000+od=1R9J=Wm)ml~APht;0e0g4|NnMZkhEh!O5)D+#cI=f=3ukBnk>s@mtA(*WtUxc z+25FmE-LadC&ZG^`8g9wIcv^oA~E7vkrRHL00jJ;Nz#TcUu}Bk3bnCZ>I2KS`;-r$}!(ZUYjCDs5CL7y4>*Y1h3~f-DA+UdJ+n`$_ z4t38dl}8EkIc6N?AvS7@Ouw|&UP68jjlS-TAS935WxyR`tzp++KJ z_b9hQH*aO)fX5}*uyD{a#(fWYToBwF^)-R5M&wog6nICH?v4Xfg^#@z zR`~KPkzd0);%yI17p^Ij_l1AYIpR}|j*JGS%h{aNheyL~3Hs!x&LZAct<;A_>%;+{ zTY1>adVJnUN$97B|pYB6Kmz_8Q*)lIEHu}e|yDn z(k%lKwggZ03zH)!oivL$B=Yjh6PW`M;s(Y|OYY1)c(hDp=9~s4^AnsJFTS-+yeT_j zi`bI0JpHevXZ}Cw&*b#3bba;R*YVtGs{7N}nqoem{Zo}`dVaRgE32#-zuW>%{w>~| zwz+d_Oj_;cXB`R~<~=glIcoUZ#CZY?oTH)7IP^;W>eiEVUjKuZgzHTUGDX zeARDq;p9adcjZORGc;XW5~G=1c%@~^{xIFVvggjewvl|>Pkrjq^x7`y_VT;Ddwo{? z{5v%}In!ijpYy-IP0x7UzO{Gz7HYn^Z5@95#y+`kn{Ki5CS6|2$jEB;c-htOZ;!Dr zs+6vJ75pIoyKpA$REi=Jl_$ zHa`1Ov#i;=Xrq72@dTz88>bod#dG(ax@6DL_;Bik7c*51x_0lhGw}R9!C8<`)MX5lF!N|bKNY}tn*U%`$$jHjr#LC1_+rYxgz<_yH iv>8wbLPKtTN@iLmZVg4pA9n#YFnGH9xvX?WedY;0_7Y;1fEEFE7AYaJahSphI(%{qa9 z<*j#)Ka(0E1e6&>C<)Ld0L5hwuT`M)FZ8+o1l55B3?Yat^8Y0Ps~D}kqObFB^sOt9 z4Um0wh@t^DhENlKNWc3?>HzuBNQ0?dy1J%8J7l8HN zx`Sh&FGKp2S;L3U0_IF}NIvJ?Sp*iyJe@9-5CI~UPAZpw+<=@PEl?a#UH&-FlVj*_ zLp}=|zMp`^r|c3?+AOTE5VwKI^>d@e2HXRdS}7Ya_VSSmjQ$$*xj<-m5DYM%G4e&f z@Z$Apm*m|E#b;F+urz#=7DSF=3<&ZrSa}!>Kojx6Kl+mf+&Q3JULG)-KDwP~ozeoh zJRKnDr&AhNzL!|>EB$H!l-GrnTpm!~6*L7J8yg!NAA=uEZ4OgYKQIRX00007xV6onmGLW}_-b*_op zH7Ii0mEfZ8!JZMpet@b{)wvAi5g04-27STWCh<>zqDpkjSYG zo0lPqZGdhpH3(DA@*L%JTGo$V9GEo;g0AEpyk_Y?u3s zq6xOp%<74P(FH;=Z5TjKBtMmAz{h_h!Hd0ZNH#X6)K&%}^1gc|VNIB>HS^knsUT8w zZf=Pb8$SU3&5W<@GgFOaUO-T7cbl(-;4+ujIn-2|>5<9y%;QF0000WFmsfh Stku@u&B8hEKJPuTY9s`pnixL- delta 60 zcmeC#te27bwNRz_38WVanV!SFhbW PFeAaX_(H(OEEN_2CR!VT diff --git a/graphics/pokemon/zebstrika/overworld.png b/graphics/pokemon/zebstrika/overworld.png index fbe6fa8f566437b23a8deed106413bd0e9586aef..36f7228a62b4417a79039b86c8b840a70cfa2360 100644 GIT binary patch delta 916 zcmV;F18e-(2c8Fz7=H)@0001UMu)cm0004VQb$4nuFf3k0000mP)t-sn9!g(K|viU zDfIRC%*@OO2L~7+AO{Brq@<)dK|yeEaCE3&_}~BlsMrSw2LJ#7t-w?z0009VNkl>5*PTXuV^3N^6wqcGF7<1e=TszRn5CVHyurxah0jUz`hc{ zZFul5(8iM&TuHfzV=esk8Hd2itV6%o_$iQX0x5A|&XouP4FV}~Am>_2)$27=xWIR_ zt5o|*7Tz`qh$b^UbXIw=&1f~&~;-f%w!pI$%a^;&qP8>+NMo?f$`7iK6AqfNu zWfK?NYhm;lE;UKPjB|rRVs&wkx&ZZyM3fz}0D>cE^kRf0f#W;K*>E>yZkktnir zqg&v^0_CFANG~N3u;Qrh0)eC{hXcjW90K(sP*_~Lynj;Kq2;9bZ6Cc}uHe^8ngVlf ziVQ)c{mRQKaF3O^VpM z1Fzgw8KEU<$nz#Q(*?F7MdVco&PYOvkSCXc1$PuD1PU7MFvo%;0%9i)g&G--(Tayb z<}-!HxPPAw(#{K@M-n<^Dqzlm;X(AgVUB?lEA;z`LsN*9P}m~b(RO+aG{eZB))fEQ zc>xFViGUeL^;X1K8S_RV>RhFbIRK*D1RV!cP^F=zo zpqiv$rS1R^IhWSA9@R>5b5kwH4b~mEj&sz8fJTO0H##7((isuMIgy2-8*c!ioW&+qA zpMPKQ2oFx1{Pm9mzGlYVyw<9Rf8ct&7u@C&hMFV z*Q|cnSRGwP)Z<%E?kUG-O$E$skNU(xkhjdZt@-k3A1$Q)+aY>i=2LQ?u%$QI$CPts qbaOu)ZKI#|!+H5u^Rs_!e*i&49Da->lnspl0000pIJV``BR7l6|mcMV>KorMqq<_P!pKWTyR68IlIvqAm zmCXSf$&-KJqNEF?YRE_uQb*ZPn^LKBQdOOt5Vh)7sg)w-pQ|AT-a#FyONXitB=qt5 zzTdldckkf-$N%_iA;zCnW}7(vj|Dg`L-}ed^A@Y6h^zWM<>`HVuK}T~nEx9CQq9yD zrab1LSIw-ya(_~|#Tt;hx}q<RlfwSf?Q=W>;aHAKad)PgyLL0MW93;%s7e8RVNovOR zbj)(@){+N~?{5SSzYsjHeP#?;&U$O+;d9IbLr?fL_xVQNv|4n-n2cG7wr_`KF;|zb z43J^gVSoQSz1c$oOHA}NQ)d>rXw3N7`w6yGX~Z$fkq|s~l}I1Q*p%yyWVN&F5UEd) z!4e;hie~txk9c5~6Fv?=g2H+jj+?>Mzy%Gi!tk`=5W}8z7`}dRfCZNLL_KI~dBjk% z!i0q|aIM0I1r?>?#B&Ib0|lVNON^}^uPR{8PW49M3nT*dCA{@i{q?BZ?O?S=dJWGl7y?nA_SFEAGd-lXmcn#$YB z-R6}iUmUv~ZjUJyoyntl@P=VA7oh@mV}8vD@6RSbCnH`=-YJi`lZT8!ufr7?0devO zu`M2A-t89}^Y?}JG#g}5OWJMjn90y2mPQ2FMrABAhP{q5o*NwAWkXmbrCsI@R}7W} v*hZdTuJEw Date: Fri, 23 Aug 2024 18:21:40 +0200 Subject: [PATCH 55/64] add missing break for poison puppeteer (#5243) --- src/battle_util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/battle_util.c b/src/battle_util.c index c2e05cbd4e..2935afc1ff 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6028,6 +6028,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 gBattlescriptCurrInstr = BattleScript_AbilityStatusEffect; effect++; } + break; } break; case ABILITYEFFECT_MOVE_END_OTHER: // Abilities that activate on *another* battler's moveend: Dancer, Soul-Heart, Receiver, Symbiosis From 85fe398b5080d584254104c49f177708d71a5171 Mon Sep 17 00:00:00 2001 From: PhallenTree <168426989+PhallenTree@users.noreply.github.com> Date: Sat, 24 Aug 2024 13:28:24 +0100 Subject: [PATCH 56/64] Fix Starting Status being passed on to future wild battles (#5248) --- src/battle_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/battle_main.c b/src/battle_main.c index cba22fa5ef..ad7f877fd9 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3755,7 +3755,7 @@ static void DoBattleIntro(void) gBattleStruct->startingStatus = GetTrainerStartingStatusFromId(gTrainerBattleOpponent_B); gBattleStruct->startingStatusTimer = 0; // infinite } - else if (GetTrainerStartingStatusFromId(gTrainerBattleOpponent_A)) + else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && GetTrainerStartingStatusFromId(gTrainerBattleOpponent_A)) { gBattleStruct->startingStatus = GetTrainerStartingStatusFromId(gTrainerBattleOpponent_A); gBattleStruct->startingStatusTimer = 0; // infinite From 2fed75f7c5a1d9744b5f7815f5cf6c6a014be4ac Mon Sep 17 00:00:00 2001 From: kittenchilly Date: Sat, 24 Aug 2024 09:53:19 -0500 Subject: [PATCH 57/64] Adaptability, Aerilate, Aftermath tests (#5242) * Adaptability, Aerilate, Aftermath tests * Update test/battle/ability/aerilate.c Co-authored-by: Eduardo Quezada --------- Co-authored-by: Eduardo Quezada --- src/battle_main.c | 4 +++- test/battle/ability/adaptability.c | 20 +++++++++++++++++++- test/battle/ability/aerilate.c | 25 ++++++++++++++++++++++++- test/battle/ability/aftermath.c | 20 +++++++++++++++++++- 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/battle_main.c b/src/battle_main.c index ad7f877fd9..4165dea20d 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -5746,8 +5746,10 @@ bool32 TrySetAteType(u32 move, u32 battlerAtk, u32 attackerAbility) break; case EFFECT_HIDDEN_POWER: case EFFECT_WEATHER_BALL: - case EFFECT_CHANGE_TYPE_ON_ITEM: case EFFECT_NATURAL_GIFT: + case EFFECT_CHANGE_TYPE_ON_ITEM: + case EFFECT_REVELATION_DANCE: + case EFFECT_TERRAIN_PULSE: return FALSE; } diff --git a/test/battle/ability/adaptability.c b/test/battle/ability/adaptability.c index fecdc6b7e2..4c1c8439b7 100644 --- a/test/battle/ability/adaptability.c +++ b/test/battle/ability/adaptability.c @@ -1,7 +1,25 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("Adaptability increases same-type attack bonus from x1.5 to x2"); +SINGLE_BATTLE_TEST("Adaptability increases same-type attack bonus from x1.5 to x2", s16 damage) +{ + u32 ability; + PARAMETRIZE { ability = ABILITY_HYPER_CUTTER; } + PARAMETRIZE { ability = ABILITY_ADAPTABILITY; } + GIVEN { + PLAYER(SPECIES_CRAWDAUNT) { Ability(ability); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_WATER_GUN); } + } SCENE { + MESSAGE("Crawdaunt used Water Gun!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + // The jump from 1.5x STAB to 2.0x STAB is a 1.33x boost. + EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.33), results[1].damage); + } +} SINGLE_BATTLE_TEST("(TERA) Terastallizing into a different type with Adaptability gives 2.0x STAB", s16 damage) { diff --git a/test/battle/ability/aerilate.c b/test/battle/ability/aerilate.c index 8a5f889a66..4386034a59 100644 --- a/test/battle/ability/aerilate.c +++ b/test/battle/ability/aerilate.c @@ -21,7 +21,30 @@ SINGLE_BATTLE_TEST("Aerilate turns a Normal-type move into Flying-type move") } } -TO_DO_BATTLE_TEST("Aerilate can not turn certain moves into Flying type moves"); +SINGLE_BATTLE_TEST("Aerilate can not turn certain moves into Flying type moves") +{ + u32 move; + PARAMETRIZE { move = MOVE_WEATHER_BALL; } + // PARAMETRIZE { move = MOVE_NATURAL_GIFT; } TODO: handle this case via Skill Swap + PARAMETRIZE { move = MOVE_JUDGMENT; } + PARAMETRIZE { move = MOVE_TECHNO_BLAST; } + PARAMETRIZE { move = MOVE_REVELATION_DANCE; } + PARAMETRIZE { move = MOVE_MULTI_ATTACK; } + PARAMETRIZE { move = MOVE_TERRAIN_PULSE; } + GIVEN { + PLAYER(SPECIES_MEGANIUM); + OPPONENT(SPECIES_SALAMENCE) { Item(ITEM_SALAMENCITE); } + } WHEN { + TURN { MOVE(opponent, move, gimmick: GIMMICK_MEGA); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_MEGA_EVOLUTION, opponent); + ANIMATION(ANIM_TYPE_MOVE, move, opponent); + NONE_OF { + MESSAGE("It's super effective!"); + } + } +} + TO_DO_BATTLE_TEST("Aerilate boosts power of affected moves by 20% (Gen7+)"); TO_DO_BATTLE_TEST("Aerilate boosts power of affected moves by 30% (Gen6)"); diff --git a/test/battle/ability/aftermath.c b/test/battle/ability/aftermath.c index 65c0be7dfd..5cfd5ef034 100644 --- a/test/battle/ability/aftermath.c +++ b/test/battle/ability/aftermath.c @@ -1,4 +1,22 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("Aftermath damages the attacker by 1/4th of its max HP if they faint the target has this ability by a contact move"); +SINGLE_BATTLE_TEST("Aftermath damages the attacker by 1/4th of its max HP if fainted by a contact move") +{ + s16 aftermathDamage; + + GIVEN { + PLAYER(SPECIES_VOLTORB) { HP(1); Ability(ABILITY_AFTERMATH); }; + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN {MOVE(opponent, MOVE_TACKLE);} + } SCENE { + MESSAGE("Foe Wobbuffet used Tackle!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent); + MESSAGE("Voltorb fainted!"); + ABILITY_POPUP(player, ABILITY_AFTERMATH); + HP_BAR(opponent, captureDamage: &aftermathDamage); + } THEN { + EXPECT_EQ(aftermathDamage, opponent->maxHP / 4); + } +} From 17f68563ebe4164d2e16a603a167a9efc92905d4 Mon Sep 17 00:00:00 2001 From: tertu Date: Sat, 24 Aug 2024 12:07:00 -0500 Subject: [PATCH 58/64] Remove support for the original LCG random number generator (#5078) --- include/battle.h | 7 ----- include/random.h | 56 +++++++------------------------------- src/battle_main.c | 6 ----- src/main.c | 57 +++++++++++++-------------------------- src/random.c | 34 ----------------------- test/random.c | 22 ++++----------- test/test_runner_battle.c | 24 +++++------------ 7 files changed, 38 insertions(+), 168 deletions(-) diff --git a/include/battle.h b/include/battle.h index 084c09f789..ab0d356d95 100644 --- a/include/battle.h +++ b/include/battle.h @@ -600,12 +600,10 @@ struct LostItem u16 stolen:1; }; -#if HQ_RANDOM == TRUE struct BattleVideo { u32 battleTypeFlags; rng_value_t rngSeed; }; -#endif enum BattleIntroStates { @@ -707,12 +705,7 @@ struct BattleStruct u16 lastTakenMoveFrom[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT]; // a 2-D array [target][attacker] union { struct LinkBattlerHeader linkBattlerHeader; - - #if HQ_RANDOM == FALSE - u32 battleVideo[2]; - #else struct BattleVideo battleVideo; - #endif } multiBuffer; u8 wishPerishSongState; u8 wishPerishSongBattlerId; diff --git a/include/random.h b/include/random.h index d254a08f03..b5ce987f39 100644 --- a/include/random.h +++ b/include/random.h @@ -6,25 +6,21 @@ #define ISO_RANDOMIZE1(val)(1103515245 * (val) + 24691) #define ISO_RANDOMIZE2(val)(1103515245 * (val) + 12345) -/* Some functions have been added to support HQ_RANDOM. +/* Some functions have been added to support Expansion's RNG implementation. * -* If using HQ_RANDOM, you cannot call Random() in interrupt handlers safely. -* AdvanceRandom() is provided to handle burning numbers in the VBlank handler -* if you choose to do that, and can be used regardless of HQ_RANDOM setting. +* LocalRandom(*val) provides a higher-quality replacement for uses of +* ISO_RANDOMIZE in vanilla Emerald. You can use LocalRandomSeed(u32) to +* create a local state. +* +* It is no longer possible to call Random() in interrupt handlers safely. +* AdvanceRandom() is provided to handle burning numbers in VBlank handlers. * If you need to use random numbers in the VBlank handler, a local state * should be used instead. * -* LocalRandom(*val) allows you to have local random states that are the same -* type as the global states regardless of HQ_RANDOM setting, which is useful -* if you want to be able to set them from or assign them to gRngValue. -* LocalRandomSeed(u32) returns a properly seeded rng_value_t. -* -* Random2_32() was added to HQ_RANDOM because the output of the generator is -* always 32 bits and Random()/Random2() are just wrappers in that mode. It is -* also available in non-HQ mode for consistency. +* Random2_32() was added, even though it is not used directly, because the +* underlying RNG always outputs 32 bits. */ -#if HQ_RANDOM == TRUE struct Sfc32State { u32 a; u32 b; @@ -70,40 +66,6 @@ static inline u16 Random2(void) } void AdvanceRandom(void); -#else -typedef u32 rng_value_t; - -#define RNG_VALUE_EMPTY 0 - -//Returns a 16-bit pseudorandom number -u16 Random(void); -u16 Random2(void); - -//Sets the initial seed value of the pseudorandom number generator -void SeedRng(u16 seed); -void SeedRng2(u16 seed); - -//Returns a 32-bit pseudorandom number -#define Random32() (Random() | (Random() << 16)) -#define Random2_32() (Random2() | (Random2() << 16)) - -static inline u16 LocalRandom(rng_value_t *val) -{ - *val = ISO_RANDOMIZE1(*val); - return *val >> 16; -} - -static inline void AdvanceRandom(void) -{ - Random(); -} - -static inline rng_value_t LocalRandomSeed(u32 seed) -{ - return seed; -} - -#endif extern rng_value_t gRngValue; extern rng_value_t gRng2Value; diff --git a/src/battle_main.c b/src/battle_main.c index 72b2f0838a..68296138ef 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -1692,15 +1692,9 @@ static void CB2_HandleStartMultiBattle(void) case 8: if (IsLinkTaskFinished()) { - #if HQ_RANDOM == TRUE struct BattleVideo *ptr = &gBattleStruct->multiBuffer.battleVideo; ptr->battleTypeFlags = gBattleTypeFlags; ptr->rngSeed = gRecordedBattleRngSeed; - #else - u32 *ptr = gBattleStruct->multiBuffer.battleVideo; - ptr[0] = gBattleTypeFlags; - ptr[1] = gRecordedBattleRngSeed; // UB: overwrites berry data - #endif SendBlock(BitmaskAllOtherLinkPlayers(), ptr, sizeof(gBattleStruct->multiBuffer.battleVideo)); gBattleCommunication[MULTIUSE_STATE]++; diff --git a/src/main.c b/src/main.c index b0bba2f3f3..47907a0111 100644 --- a/src/main.c +++ b/src/main.c @@ -205,12 +205,9 @@ void SetMainCallback2(MainCallback callback) void StartTimer1(void) { - if (HQ_RANDOM) - { - REG_TM2CNT_L = 0; - REG_TM2CNT_H = TIMER_ENABLE | TIMER_COUNTUP; - } + REG_TM2CNT_L = 0; + REG_TM2CNT_H = TIMER_ENABLE | TIMER_COUNTUP; REG_TM1CNT_H = TIMER_ENABLE; } @@ -218,24 +215,12 @@ void SeedRngAndSetTrainerId(void) { u32 val; - if (HQ_RANDOM) - { - REG_TM1CNT_H = 0; - REG_TM2CNT_H = 0; - val = ((u32)REG_TM2CNT_L) << 16; - val |= REG_TM1CNT_L; - SeedRng(val); - sTrainerId = Random(); - } - else - { - // Do it exactly like it was originally done, including not stopping - // the timer beforehand. - val = REG_TM1CNT_L; - SeedRng((u16)val); - REG_TM1CNT_H = 0; - sTrainerId = val; - } + REG_TM1CNT_H = 0; + REG_TM2CNT_H = 0; + val = ((u32)REG_TM2CNT_L) << 16; + val |= REG_TM1CNT_L; + SeedRng(val); + sTrainerId = Random(); } u16 GetGeneratedTrainerIdLower(void) @@ -254,22 +239,16 @@ void EnableVCountIntrAtLine150(void) #ifdef BUGFIX static void SeedRngWithRtc(void) { - #if HQ_RANDOM == FALSE - u32 seed = RtcGetMinuteCount(); - seed = (seed >> 16) ^ (seed & 0xFFFF); - SeedRng(seed); - #else - #define BCD8(x) ((((x) >> 4) & 0xF) * 10 + ((x) & 0xF)) - u32 seconds; - struct SiiRtcInfo rtc; - RtcGetInfo(&rtc); - seconds = - ((HOURS_PER_DAY * RtcGetDayCount(&rtc) + BCD8(rtc.hour)) - * MINUTES_PER_HOUR + BCD8(rtc.minute)) - * SECONDS_PER_MINUTE + BCD8(rtc.second); - SeedRng(seconds); - #undef BCD8 - #endif + #define BCD8(x) ((((x) >> 4) & 0xF) * 10 + ((x) & 0xF)) + u32 seconds; + struct SiiRtcInfo rtc; + RtcGetInfo(&rtc); + seconds = + ((HOURS_PER_DAY * RtcGetDayCount(&rtc) + BCD8(rtc.hour)) + * MINUTES_PER_HOUR + BCD8(rtc.minute)) + * SECONDS_PER_MINUTE + BCD8(rtc.second); + SeedRng(seconds); + #undef BCD8 } #endif diff --git a/src/random.c b/src/random.c index 9d43ae3740..969aa6d404 100644 --- a/src/random.c +++ b/src/random.c @@ -8,7 +8,6 @@ rng_value_t gRngValue; rng_value_t gRng2Value; -#if HQ_RANDOM == TRUE EWRAM_DATA static volatile bool8 sRngLoopUnlocked; @@ -112,39 +111,6 @@ void AdvanceRandom(void) #define LOOP_RANDOM ((u16)(_SFC32_Next(state) >> 16)) -#else -EWRAM_DATA static u32 sRandCount = 0; - -u16 Random(void) -{ - gRngValue = ISO_RANDOMIZE1(gRngValue); - sRandCount++; - return gRngValue >> 16; -} - -void SeedRng(u16 seed) -{ - gRngValue = seed; -} - -void SeedRng2(u16 seed) -{ - gRng2Value = seed; -} - -u16 Random2(void) -{ - gRng2Value = ISO_RANDOMIZE1(gRng2Value); - return gRng2Value >> 16; -} - -#define LOOP_RANDOM_START -#define LOOP_RANDOM_END - -#define LOOP_RANDOM (Random()) - -#endif - #define SHUFFLE_IMPL \ u32 tmp; \ LOOP_RANDOM_START; \ diff --git a/test/random.c b/test/random.c index 0232ff1547..238a76467e 100644 --- a/test/random.c +++ b/test/random.c @@ -196,13 +196,8 @@ TEST("RandomElement generates a uniform distribution") TEST("RandomUniform mul-based faster than mod-based (compile-time)") { - #if HQ_RANDOM == TRUE - const u32 expectedMulSum = 6; - const u32 expectedModSum = 4; - #else - const u32 expectedMulSum = 3; - const u32 expectedModSum = 4; - #endif + const u32 expectedMulSum = 6; + const u32 expectedModSum = 4; struct Benchmark mulBenchmark, modBenchmark; u32 mulSum = 0, modSum = 0; @@ -234,13 +229,8 @@ TEST("RandomUniform mul-based faster than mod-based (compile-time)") TEST("RandomUniform mul-based faster than mod-based (run-time)") { - #if HQ_RANDOM == TRUE - const u32 expectedMulSum = 289; - const u32 expectedModSum = 205; - #else - const u32 expectedMulSum = 232; - const u32 expectedModSum = 249; - #endif + const u32 expectedMulSum = 289; + const u32 expectedModSum = 205; u32 i; struct Benchmark mulBenchmark, modBenchmark; u32 mulSum = 0, modSum = 0; @@ -264,7 +254,6 @@ TEST("RandomUniform mul-based faster than mod-based (run-time)") EXPECT_EQ(modSum, expectedModSum); } -#if HQ_RANDOM == TRUE TEST("Thumb and C SFC32 implementations produce the same results") { u32 thumbSum; @@ -285,5 +274,4 @@ TEST("Thumb and C SFC32 implementations produce the same results") } EXPECT_EQ(thumbSum, cSum); -} -#endif \ No newline at end of file +} \ No newline at end of file diff --git a/test/test_runner_battle.c b/test/test_runner_battle.c index 11a6565663..9a1ad8d708 100644 --- a/test/test_runner_battle.c +++ b/test/test_runner_battle.c @@ -35,20 +35,12 @@ #define STATE gBattleTestRunnerState #define DATA gBattleTestRunnerState->data -#if HQ_RANDOM == TRUE #define RNG_SEED_DEFAULT {0, 0, 0, 0} static inline bool32 RngSeedNotDefault(const rng_value_t *seed) { return (seed->a | seed->b | seed->c | seed->ctr) != 0; } -#else -#define RNG_SEED_DEFAULT 0x00000000 -static inline bool32 RngSeedNotDefault(const rng_value_t *seed) -{ - return *seed != RNG_SEED_DEFAULT; -} -#endif #undef Q_4_12 #define Q_4_12(n) (s32)((n) * 4096) @@ -1357,17 +1349,13 @@ static void CB2_BattleTest_NextParameter(void) static inline rng_value_t MakeRngValue(const u16 seed) { - #if HQ_RANDOM == TRUE - int i; - rng_value_t result = {0, 0, seed, 1}; - for (i = 0; i < 16; i++) - { + int i; + rng_value_t result = {0, 0, seed, 1}; + for (i = 0; i < 16; i++) + { _SFC32_Next(&result); - } - return result; - #else - return ISO_RANDOMIZE1(seed); - #endif + } + return result; } static void CB2_BattleTest_NextTrial(void) From 572972235e5c72877f20b845ebcf4b92b9a544fb Mon Sep 17 00:00:00 2001 From: hedara90 <90hedara@gmail.com> Date: Sat, 24 Aug 2024 20:22:50 +0200 Subject: [PATCH 59/64] Disguise tests (#5249) * Start new Disguise tests * Finished disguise tests --------- Co-authored-by: Hedara --- test/battle/ability/disguise.c | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/battle/ability/disguise.c b/test/battle/ability/disguise.c index c4f79d8fe3..5ab2035325 100644 --- a/test/battle/ability/disguise.c +++ b/test/battle/ability/disguise.c @@ -134,3 +134,42 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu is ignored by Mold Breaker") NOT ABILITY_POPUP(player, ABILITY_DISGUISE); } } + +SINGLE_BATTLE_TEST("Disguised Mimikyu's types revert back to Ghost/Fairy when Disguise is broken") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_SHADOW_CLAW].type == TYPE_GHOST); + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_SOAK); } + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(opponent, MOVE_SHADOW_CLAW); } + } SCENE { + MESSAGE("Foe Wobbuffet used Soak!"); + MESSAGE("Mimikyu transformed into the Water type!"); + MESSAGE("Foe Wobbuffet used Tackle!"); + ABILITY_POPUP(player, ABILITY_DISGUISE); + MESSAGE("Foe Wobbuffet used Shadow Claw!"); + MESSAGE("It's super effective!"); + } +} + +SINGLE_BATTLE_TEST("Disguised Mimikyu blocks a move after getting Gastro Acid Batton Passed") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_GASTRO_ACID); MOVE(player, MOVE_BATON_PASS); SEND_OUT(player, 1); } + TURN { MOVE(opponent, MOVE_SHADOW_CLAW); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GASTRO_ACID, opponent); + MESSAGE("Wobbuffet's ability was suppressed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BATON_PASS, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SHADOW_CLAW, opponent); + ABILITY_POPUP(player, ABILITY_DISGUISE); + } +} From 68e470f84a44f52e36ad50f0928e46f550345a15 Mon Sep 17 00:00:00 2001 From: Galaxeeh <154106034+Galaxeeh@users.noreply.github.com> Date: Sat, 24 Aug 2024 13:51:18 -0500 Subject: [PATCH 60/64] Dynamic Move Display fixes (#5251) * Weatherball fire type check changed to WEATHER_DROUGHT, added overworld check for field terrain set by weather dependent on configs * Update src/pokemon.c FRICKIN INDENTS LMAO Co-authored-by: Eduardo Quezada <93919226+equezada-jej@users.noreply.github.com> --------- Co-authored-by: Eduardo Quezada <93919226+equezada-jej@users.noreply.github.com> --- src/pokemon.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/pokemon.c b/src/pokemon.c index 1acaa3a2ed..718ce00c65 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -7026,16 +7026,35 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) && ((IsMonGrounded(heldItemEffect, ability, type1, type2) && gBattleMons[battler].species != species) || (IsBattlerTerrainAffected(battler, STATUS_FIELD_TERRAIN_ANY) && gBattleMons[battler].species == species))) { - if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) - return TYPE_ELECTRIC; - else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) - return TYPE_GRASS; - else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) - return TYPE_FAIRY; - else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) - return TYPE_PSYCHIC; - else //failsafe - type = TYPE_NORMAL; + if (gMain.inBattle) + { + if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN) + return TYPE_ELECTRIC; + else if (gFieldStatuses & STATUS_FIELD_GRASSY_TERRAIN) + return TYPE_GRASS; + else if (gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN) + return TYPE_FAIRY; + else if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN) + return TYPE_PSYCHIC; + else //failsafe + type = TYPE_NORMAL; + } + else + { + switch (gWeatherPtr->currWeather) + { + case WEATHER_RAIN_THUNDERSTORM: + if (B_THUNDERSTORM_TERRAIN) + return TYPE_ELECTRIC; + break; + case WEATHER_FOG_HORIZONTAL: + case WEATHER_FOG_DIAGONAL: + if (B_OVERWORLD_FOG >= GEN_8) + return TYPE_FAIRY; + break; + } + return TYPE_NORMAL; + } } if (effect == EFFECT_WEATHER_BALL) @@ -7057,11 +7076,12 @@ u32 CheckDynamicMoveType(struct Pokemon *mon, u32 move, u32 battler) { switch (gWeatherPtr->currWeather) { - case WEATHER_SUNNY: + case WEATHER_DROUGHT: if (heldItem != ITEM_UTILITY_UMBRELLA) return TYPE_FIRE; break; case WEATHER_RAIN: + case WEATHER_RAIN_THUNDERSTORM: if (heldItem != ITEM_UTILITY_UMBRELLA) return TYPE_WATER; break; From 8d47db6160530855804c62bc449eaeeba5726638 Mon Sep 17 00:00:00 2001 From: kittenchilly Date: Sun, 25 Aug 2024 16:39:25 -0500 Subject: [PATCH 61/64] Add Population Bomb animation (#5194) * Population Bomb animation * Update battle_anim_new.c * Update battle_anim_new.c --- data/battle_anim_scripts.s | 23 ++++++++++++++++++++++- src/battle_anim_new.c | 10 ++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 2f1a3cb73c..fdc7a59e4e 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -17630,9 +17630,30 @@ Move_MALIGNANT_CHAIN:: waitforvisualfinish end +Move_POPULATION_BOMB:: + loadspritegfx ANIM_TAG_CUT + monbg ANIM_TARGET + setalpha 12, 8 + playsewithpan SE_M_CUT, SOUND_PAN_TARGET + createvisualtask AnimTask_RandomBool, 2 + jumpretfalse PopulationBombSliceRight + jumprettrue PopulationBombSliceLeft +PopulationBombSliceRight: + createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 40, -32, 0 + goto PopulationBombContinue +PopulationBombSliceLeft: + createsprite gCuttingSliceSpriteTemplate, ANIM_ATTACKER, 2, 40, -32, 1 +PopulationBombContinue: + delay 5 + createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 10, 1 + waitforvisualfinish + clearmonbg ANIM_TARGET + blendoff + waitforvisualfinish + end + Move_TERA_BLAST:: Move_ORDER_UP:: -Move_POPULATION_BOMB:: Move_GLAIVE_RUSH:: Move_REVIVAL_BLESSING:: Move_SALT_CURE:: diff --git a/src/battle_anim_new.c b/src/battle_anim_new.c index a704a73f40..fd821250fc 100644 --- a/src/battle_anim_new.c +++ b/src/battle_anim_new.c @@ -9285,3 +9285,13 @@ static void AnimMakingItRain(struct Sprite *sprite) sprite->callback = TranslateSpriteInEllipse; sprite->callback(sprite); } + +void AnimTask_RandomBool(u8 taskId) +{ + if (RandomPercentage(RNG_NONE, 50)) + gBattleAnimArgs[ARG_RET_ID] = TRUE; + else + gBattleAnimArgs[ARG_RET_ID] = FALSE; + + DestroyAnimVisualTask(taskId); +} From 03e0472cbe93e10b3ec6e9dca8c1b459b54ece24 Mon Sep 17 00:00:00 2001 From: kittenchilly Date: Mon, 26 Aug 2024 08:58:12 -0500 Subject: [PATCH 62/64] Add I_REPEL_INCLUDE_FAINTED config and behavior (#5239) * Add I_REPEL_INCLUDE_FAINTED config * Update src/wild_encounter.c Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> * Update wild_encounter.c * Update wild_encounter.c * Update src/wild_encounter.c --------- Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> --- include/config/item.h | 1 + src/wild_encounter.c | 10 +++------- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/include/config/item.h b/include/config/item.h index 2f60739335..272848e82e 100644 --- a/include/config/item.h +++ b/include/config/item.h @@ -20,6 +20,7 @@ #define I_POWER_ITEM_BOOST GEN_LATEST // In Gen7+, Power Items grant 8 EVs instead of 4 EVs. #define I_PREMIER_BALL_BONUS GEN_LATEST // In LGPE onwards (Gen8+ here), you are given a Premier Ball for every 10 Poké Balls of any type and in the same purchase. Previously, it only applied to regular Poké Balls and only 1 could be obtained per purchase. #define I_ROTOM_CATALOG_THUNDER_SHOCK GEN_LATEST // In Gen9+, reverting Rotom to its base form will teach it Thunder Shock even if it knows another move. +#define I_REPEL_INCLUDE_FAINTED GEN_LATEST // In Gen1 and Gen6+, Repels always use the level of the first member of the party to check which wild Pokémon to prevent encounters with, even if that member is fainted. In Gen2-5, it only uses the level of the first non-fainted Pokémon. // TM config #define I_REUSABLE_TMS FALSE // In Gen5-8, TMs are reusable. Setting this to TRUE will make all vanilla TMs reusable, though they can also be cherry-picked by setting their importance to 1. diff --git a/src/wild_encounter.c b/src/wild_encounter.c index ae7770aa3a..033eec56da 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -1002,14 +1002,10 @@ static bool8 IsWildLevelAllowedByRepel(u8 wildLevel) for (i = 0; i < PARTY_SIZE; i++) { - if (GetMonData(&gPlayerParty[i], MON_DATA_HP) && !GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) + if (I_REPEL_INCLUDE_FAINTED == GEN_1 || I_REPEL_INCLUDE_FAINTED >= GEN_6 || GetMonData(&gPlayerParty[i], MON_DATA_HP)) { - u8 ourLevel = GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); - - if (wildLevel < ourLevel) - return FALSE; - else - return TRUE; + if (!GetMonData(&gPlayerParty[i], MON_DATA_IS_EGG)) + return wildLevel >= GetMonData(&gPlayerParty[i], MON_DATA_LEVEL); } } From b6299ac4cef4a95bb50e982673ebe5a5201416a3 Mon Sep 17 00:00:00 2001 From: psf <77138753+pkmnsnfrn@users.noreply.github.com> Date: Mon, 26 Aug 2024 12:16:56 -0700 Subject: [PATCH 63/64] Fix a display issue with B_SHOW_TYPES (#5201) * Moved HandleInputChooseTarget and ShowEntireFieldTargets to non-static and added them as cases to ShouldHideTypeIcon * Made ShouldHideTypeIcon easier to parse * Made ShouldHideTypeIcon a for loop * Fixed identation * Made showTypesControllerFuncs a static const array per https://github.com/rh-hideout/pokeemerald-expansion/pull/5201\#discussion_r1730336265 --- include/battle_controllers.h | 2 ++ src/battle_controller_player.c | 4 ++-- src/type_icons.c | 26 +++++++++++++++++++------- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/battle_controllers.h b/include/battle_controllers.h index 50860a7285..5e92cac763 100644 --- a/include/battle_controllers.h +++ b/include/battle_controllers.h @@ -313,6 +313,8 @@ void MoveSelectionDestroyCursorAt(u8 cursorPosition); void PlayerHandleChooseMove(u32 battler); void HandleInputChooseMove(u32 battler); void HandleInputChooseTarget(u32 battler); +void HandleInputShowEntireFieldTargets(u32 battler); +void HandleInputShowTargets(u32 battler); void HandleMoveSwitching(u32 battler); void HandleChooseMoveAfterDma3(u32 battler); diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 61f2b8162d..52507157e7 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -593,7 +593,7 @@ static void HideShownTargets(u32 battler) } } -static void HandleInputShowEntireFieldTargets(u32 battler) +void HandleInputShowEntireFieldTargets(u32 battler) { if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A) gPlayerDpadHoldFrames++; @@ -621,7 +621,7 @@ static void HandleInputShowEntireFieldTargets(u32 battler) } } -static void HandleInputShowTargets(u32 battler) +void HandleInputShowTargets(u32 battler) { if (JOY_HELD(DPAD_ANY) && gSaveBlock2Ptr->optionsButtonMode == OPTIONS_BUTTON_MODE_L_EQUALS_A) gPlayerDpadHoldFrames++; diff --git a/src/type_icons.c b/src/type_icons.c index 2877d22071..361312ab91 100644 --- a/src/type_icons.c +++ b/src/type_icons.c @@ -471,15 +471,27 @@ static void FreeAllTypeIconResources(void) } } +static void (* const sShowTypesControllerFuncs[])(u32 battler) = +{ + PlayerHandleChooseMove, + HandleChooseMoveAfterDma3, + HandleInputChooseTarget, + HandleInputShowTargets, + HandleInputShowEntireFieldTargets, + HandleMoveSwitching, + HandleInputChooseMove, +}; + + static bool32 ShouldHideTypeIcon(u32 battlerId) { - return gBattlerControllerFuncs[battlerId] != PlayerHandleChooseMove - && gBattlerControllerFuncs[battlerId] != HandleInputChooseMove - && gBattlerControllerFuncs[battlerId] != HandleChooseMoveAfterDma3 - && gBattlerControllerFuncs[battlerId] != HandleInputChooseMove - && gBattlerControllerFuncs[battlerId] != HandleInputChooseTarget - && gBattlerControllerFuncs[battlerId] != HandleMoveSwitching - && gBattlerControllerFuncs[battlerId] != HandleInputChooseMove; + u32 funcIndex; + + for (funcIndex = 0; funcIndex < ARRAY_COUNT(sShowTypesControllerFuncs); funcIndex++) + if (gBattlerControllerFuncs[battlerId] == sShowTypesControllerFuncs[funcIndex]) + return FALSE; + + return TRUE; } static s32 GetTypeIconHideMovement(bool32 useDoubleBattleCoords, u32 position) From 74a790f09c60b29522dc4270339813447175a5bd Mon Sep 17 00:00:00 2001 From: kittenchilly Date: Mon, 26 Aug 2024 19:11:33 -0500 Subject: [PATCH 64/64] Chilly Reception AI --- src/battle_ai_main.c | 12 ++++++++++++ src/battle_ai_switch_items.c | 2 +- src/battle_ai_util.c | 3 ++- test/battle/ai/ai_flag_sequence_switching.c | 4 +++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index df055d62ba..55b38f7ad7 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -1739,6 +1739,14 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) break; case EFFECT_HIT_ESCAPE: break; + case EFFECT_CHILLY_RECEPTION: + if (CountUsablePartyMons(battlerAtk) == 0) + ADJUST_SCORE(-10); + else if (weather & (B_WEATHER_SNOW | B_WEATHER_PRIMAL_ANY) || IsMoveEffectWeather(aiData->partnerMove)) + ADJUST_SCORE(-8); + else if (weather & B_WEATHER_HAIL) + ADJUST_SCORE(-2); // mainly to prevent looping between hail and snow + break; case EFFECT_BELLY_DRUM: case EFFECT_FILLET_AWAY: if (aiData->abilities[battlerAtk] == ABILITY_CONTRARY) @@ -2773,6 +2781,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_SNOWSCAPE: case EFFECT_RAIN_DANCE: case EFFECT_SANDSTORM: + case EFFECT_CHILLY_RECEPTION: if (IsMoveEffectWeather(move)) ADJUST_SCORE(-10); break; @@ -2852,6 +2861,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) } break; case EFFECT_SNOWSCAPE: + case EFFECT_CHILLY_RECEPTION: if (IsBattlerAlive(battlerAtkPartner) && ShouldSetSnow(battlerAtkPartner, atkPartnerAbility, atkPartnerHoldEffect)) { @@ -3621,6 +3631,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move) //fallthrough case EFFECT_HIT_ESCAPE: case EFFECT_PARTING_SHOT: + case EFFECT_CHILLY_RECEPTION: if (!IsDoubleBattle()) { switch (ShouldPivot(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, movesetIndex)) @@ -4879,6 +4890,7 @@ static s32 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32 score case EFFECT_SANDSTORM: case EFFECT_HAIL: case EFFECT_SNOWSCAPE: + case EFFECT_CHILLY_RECEPTION: case EFFECT_GEOMANCY: case EFFECT_VICTORY_DANCE: ADJUST_SCORE(DECENT_EFFECT); diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index c31dab8936..e2d0d85a3c 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -2002,7 +2002,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, } // If ace mon is the last available Pokemon and U-Turn/Volt Switch was used - switch to the mon. if (aceMonId != PARTY_SIZE - && (gMovesInfo[gLastUsedMove].effect == EFFECT_HIT_ESCAPE || gMovesInfo[gLastUsedMove].effect == EFFECT_PARTING_SHOT || gMovesInfo[gLastUsedMove].effect == EFFECT_BATON_PASS)) + && (gMovesInfo[gLastUsedMove].effect == EFFECT_HIT_ESCAPE || gMovesInfo[gLastUsedMove].effect == EFFECT_PARTING_SHOT || gMovesInfo[gLastUsedMove].effect == EFFECT_BATON_PASS || gMovesInfo[gLastUsedMove].effect == EFFECT_CHILLY_RECEPTION)) return aceMonId; return PARTY_SIZE; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index f1509fdd80..8c1cb578ed 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -3262,7 +3262,8 @@ bool32 IsMoveEffectWeather(u32 move) || gMovesInfo[move].effect == EFFECT_RAIN_DANCE || gMovesInfo[move].effect == EFFECT_SANDSTORM || gMovesInfo[move].effect == EFFECT_HAIL - || gMovesInfo[move].effect == EFFECT_SNOWSCAPE)) + || gMovesInfo[move].effect == EFFECT_SNOWSCAPE + || gMovesInfo[move].effect == EFFECT_CHILLY_RECEPTION)) return TRUE; return FALSE; } diff --git a/test/battle/ai/ai_flag_sequence_switching.c b/test/battle/ai/ai_flag_sequence_switching.c index 1b4a264a24..7a0f3528bd 100644 --- a/test/battle/ai/ai_flag_sequence_switching.c +++ b/test/battle/ai/ai_flag_sequence_switching.c @@ -64,7 +64,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SEQUENCE_SWITCHING: Roar and Dragon Tail still fo } } -AI_SINGLE_BATTLE_TEST("AI_FLAG_SEQUENCE_SWITCHING: AI will always switch into lowest party index after U-Turn, Parting Shot, and Baton Pass") +AI_SINGLE_BATTLE_TEST("AI_FLAG_SEQUENCE_SWITCHING: AI will always switch into lowest party index after U-Turn, Parting Shot, Baton Pass, and Chilly Reception") { u32 j, aiSequenceSwitchingFlag = 0, move = MOVE_NONE; @@ -72,6 +72,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SEQUENCE_SWITCHING: AI will always switch into lo MOVE_U_TURN, MOVE_PARTING_SHOT, MOVE_BATON_PASS, + MOVE_CHILLY_RECEPTION, }; for (j = 0; j < ARRAY_COUNT(switchMoves); j++) @@ -84,6 +85,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SEQUENCE_SWITCHING: AI will always switch into lo ASSUME(gMovesInfo[MOVE_U_TURN].effect == EFFECT_HIT_ESCAPE); ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT); ASSUME(gMovesInfo[MOVE_BATON_PASS].effect == EFFECT_BATON_PASS); + ASSUME(gMovesInfo[MOVE_CHILLY_RECEPTION].effect == EFFECT_CHILLY_RECEPTION); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiSequenceSwitchingFlag); PLAYER(SPECIES_SWELLOW) { Level (50); } OPPONENT(SPECIES_MACHOP) { Level(1); Moves(move); }