diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 5f92d592d2..d30d084a66 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -829,7 +829,7 @@ .4byte \failInstr .endm - .macro damagetohalftargethp + .macro unused_0x94 .byte 0x94 .endm @@ -877,11 +877,11 @@ .byte 0x9e .endm - .macro dmgtolevel + .macro unused_0x9f .byte 0x9f .endm - .macro psywavedamageeffect + .macro unused_0xA0 .byte 0xa0 .endm @@ -2030,10 +2030,6 @@ .4byte \jumpInstr .endm - .macro setargtobattledamage - various BS_ATTACKER, VARIOUS_SET_ARG_TO_BATTLE_DAMAGE - .endm - .macro tryautotomize battler:req, failInstr:req various \battler, VARIOUS_TRY_AUTOTOMIZE .4byte \failInstr diff --git a/charmap.txt b/charmap.txt index a35709d652..34fb683d0c 100644 --- a/charmap.txt +++ b/charmap.txt @@ -1064,6 +1064,7 @@ ROUND_RIGHT_PAREN = F9 14 CIRCLE_DOT = F9 15 TRIANGLE = F9 16 BIG_MULT_X = F9 17 +CIRCLE_HOLLOW = F9 18 EMOJI_UNDERSCORE = F9 D0 EMOJI_PIPE = F9 D1 diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 46121757e6..b8fc5b7344 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -200,7 +200,7 @@ gBattleAnimMove_NaturalGift:: createvisualtask AnimTask_DragonDanceWaver, 5 playsewithpan SE_M_TELEPORT, -64 delay 8 - createvisualtask AnimTask_BlendPalInAndOutByTag, 5, 10249, 19456, 14, 0, 3 + createvisualtask AnimTask_BlendPalInAndOutByTag, 5, ANIM_TAG_HOLLOW_ORB, 19456, 14, 0, 3 createsprite gDragonDanceOrbSpriteTemplate, ANIM_ATTACKER, 2, 0 createsprite gDragonDanceOrbSpriteTemplate, ANIM_ATTACKER, 2, 43 createsprite gDragonDanceOrbSpriteTemplate, ANIM_ATTACKER, 2, 85 @@ -824,7 +824,7 @@ gBattleAnimMove_Punishment:: monbg ANIM_TARGET setalpha 12, 8 playsewithpan 155, SOUND_PAN_TARGET - createsprite gPunishmentSpriteTemplate, ANIM_TARGET, 2, 0, 0, 1, 0 + createsprite gPunishmentSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 1, 0 createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 6, 1 waitforvisualfinish clearmonbg ANIM_TARGET @@ -844,7 +844,7 @@ gBattleAnimMove_Punishment:: gBattleAnimMove_LastResort:: fadetobg BG_COSMIC waitbgfadeout - createvisualtask AnimTask_StartSlidingBg, 2, 4, 0, 128, 0, -1 + createvisualtask AnimTask_StartSlidingBg, 2, 0, 128, 0, -1 waitbgfadein loadspritegfx ANIM_TAG_IMPACT playsewithpan SE_M_SWIFT, SOUND_PAN_ATTACKER @@ -855,19 +855,19 @@ gBattleAnimMove_LastResort:: waitplaysewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER, 8 createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 18, 6, 2, 4 waitforvisualfinish - createsprite gSimplePaletteBlendSpriteTemplate, ANIM_TARGET, 2, 1, 0, 16, 16, RGB_WHITE - createsprite gSlideMonToOffsetSpriteTemplate, ANIM_TARGET, 2, 0, 20, 0, 0, 4 + createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 16, 16, RGB_WHITE + createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, 0, 0, 4 delay 3 waitforvisualfinish playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 132, -10, 0, 1, 0 createsprite gSlideMonToOffsetSpriteTemplate, ANIM_TARGET, 2, 1, -32, 0, 0, 3 waitforvisualfinish - createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_ATTACKER, 0 - createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_TARGET, 0 + createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_ATTACKER, 1 + createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_TARGET, 1 createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 4, 0, 12, 1 createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 - createsprite gSimplePaletteBlendSpriteTemplate, ANIM_TARGET, 2, 1, 2, 16, 0, RGB_WHITE + createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 2, 16, 0, RGB_WHITE waitforvisualfinish createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_ATTACKER, 1 createvisualtask AnimTask_RotateMonSpriteToSide, 2, 8, -256, ANIM_TARGET, 1 @@ -897,9 +897,9 @@ gBattleAnimMove_SuckerPunch:: loadspritegfx ANIM_TAG_POISON_JAB loadspritegfx ANIM_TAG_IMPACT createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, 0, 0, 4 - createsprite gSuckerPunchSpriteTemplate, ANIM_TARGET, 130, -18, 5, 40, 8, 160, 0 + createsprite gSuckerPunchSpriteTemplate, ANIM_TARGET, 2, -18, 5, 40, 8, 160, 0 delay 4 - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 130, -8, 8, 1, 2 + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, -8, 8, 1, 2 createvisualtask AnimTask_RotateMonSpriteToSide, 2, 6, 384, ANIM_TARGET, 2 playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET waitforvisualfinish @@ -1003,11 +1003,11 @@ gBattleAnimGeneral_AquaRingHeal:: createsprite gSmallBubblePairSpriteTemplate, ANIM_ATTACKER, 2, 12, 0, 25, 0 setalpha 8, 8 playsewithpan SE_M_MILK_DRINK, SOUND_PAN_ATTACKER - createsprite gGuardRingSpriteTemplate, 2, 0 + createsprite gGuardRingSpriteTemplate, ANIM_ATTACKER, 0 delay 4 - createsprite gGuardRingSpriteTemplate, 2, 0 + createsprite gGuardRingSpriteTemplate, ANIM_ATTACKER, 0 delay 4 - createsprite gGuardRingSpriteTemplate, 2, 0 + createsprite gGuardRingSpriteTemplate, ANIM_ATTACKER, 0 waitforvisualfinish playsewithpan SE_SHINY, SOUND_PAN_ATTACKER createvisualtask AnimTask_BlendColorCycle, 2, F_PAL_ATK_SIDE, 0, 2, 0, 10, RGB_WHITE @@ -1090,33 +1090,33 @@ gBattleAnimMove_FlareBlitz:: createvisualtask AnimTask_ShakeMon2, 2, ANIM_TARGET, 4, 0, 22, 1 createvisualtask AnimTask_BlendMonInAndOut, 3, ANIM_TARGET, RGB_RED, 12, 1, 1 createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1, 0 - createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 129, 0, 10, 192, 176, 40 + createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, 192, 176, 40 playsewithpan SE_M_COMET_PUNCH, +63 delay 5 createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 24, 8, 1, 0 createvisualtask AnimTask_BlendMonInAndOut, 3, ANIM_TARGET, RGB_RED, 12, 1, 1 - createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 129, 0, 10, -192, 240, 40 + createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, -192, 240, 40 playsewithpan SE_M_COMET_PUNCH, +63 delay 5 createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -24, -16, 1, 0 createvisualtask AnimTask_BlendMonInAndOut, 3, ANIM_TARGET, RGB_RED, 12, 1, 1 - createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 129, 0, 10, 192, -160, 40 + createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, 192, -160, 40 playsewithpan SE_M_COMET_PUNCH, +63 delay 5 createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 8, 4, 1, 0 createvisualtask AnimTask_BlendMonInAndOut, 3, ANIM_TARGET, RGB_RED, 12, 1, 1 - createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 129, 0, 10, -192, -112, 40 + createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, -192, -112, 40 playsewithpan SE_M_COMET_PUNCH, +63 delay 5 createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, -16, 19, 1, 0 createvisualtask AnimTask_BlendMonInAndOut, 3, ANIM_TARGET, RGB_RED, 12, 1, 1 - createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 129, 0, 10, 160, 48, 40 + createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, 160, 48, 40 playsewithpan SE_M_COMET_PUNCH, +63 delay 5 createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 18, -18, 1, 0 createvisualtask AnimTask_BlendMonInAndOut, 3, ANIM_TARGET, RGB_RED, 12, 1, 1 - createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 129, 0, 10, -224, -32, 40 - createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 129, 0, 10, 112, -128, 40 + createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, -224, -32, 40 + createsprite gFireSpreadSpriteTemplate, ANIM_TARGET, 1, 0, 10, 112, -128, 40 playsewithpan SE_M_COMET_PUNCH, +63 createvisualtask AnimTask_BlendBattleAnimPal, 10, 4, 2, 0, 0, RGB_BLACK playsewithpan SE_M_COMET_PUNCH, +63 @@ -1138,10 +1138,10 @@ gBattleAnimMove_ForcePalm:: splitbgprio ANIM_TARGET setalpha 12, 8 playsewithpan SE_M_DOUBLE_TEAM, SOUND_PAN_TARGET - createsprite gKarateChopSpriteTemplate, ANIM_TARGET, 2, -16, 0, 0, 0, 10, 1, 3, 0 + createsprite gKarateChopSpriteTemplate, ANIM_ATTACKER, 2, -16, 0, 0, 0, 10, 1, 3, 0 waitforvisualfinish playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET - createsprite gForcePalmSpriteTemplate, ANIM_TARGET 3, 0, 0, 1, 2 + createsprite gForcePalmSpriteTemplate, ANIM_ATTACKER 3, 0, 0, 1, 2 createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 4, 0, 6, 1 waitforvisualfinish clearmonbg ANIM_DEF_PARTNER @@ -1379,17 +1379,17 @@ gBattleAnimMove_AquaTail:: createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 6 delay 4 playsewithpan SE_M_VITAL_THROW, SOUND_PAN_TARGET - createsprite gAquaTailKnockOffSpriteTemplate, ANIM_ATTACKER, 130, -16, -16 + createsprite gAquaTailKnockOffSpriteTemplate, ANIM_ATTACKER, 2, -16, -16 delay 8 - createsprite gComplexPaletteBlendSpriteTemplate, ANIM_TARGET, 2, 31, 5, 1, RGB_WHITE, 10, 0, 0 - createsprite gAquaTailHitSpriteTemplate, ANIM_TARGET, 131, 0, 0, 1, 2 + createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 31, 5, 1, RGB_WHITE, 10, 0, 0 + createsprite gAquaTailHitSpriteTemplate, ANIM_TARGET, 3, 0, 0, 1, 2 playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET - createsprite gSlideMonToOffsetSpriteTemplate, ANIM_TARGET, 2, ANIM_TARGET, -12, 10, 0, 3 + createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, -12, 10, 0, 3 createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_ATTACKER, 0, 5 delay 3 createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 0, 3, 6, 1 delay 5 - createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_TARGET, 2, ANIM_TARGET, 0, 6 + createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, ANIM_TARGET, 0, 6 delay 10 waitforvisualfinish clearmonbg ANIM_DEF_PARTNER @@ -1532,7 +1532,7 @@ gBattleAnimMove_DragonPulse:: clearmonbg ANIM_TARGET end DragonPulseParticle: - createsprite gDragonPulseSpriteTemplate, ANIM_ATTACKER, 130, 16, 0, 0, 0, 13, 0 + createsprite gDragonPulseSpriteTemplate, ANIM_TARGET, 2, 16, 0, 0, 0, 13, 0 delay 4 return @@ -1544,21 +1544,21 @@ gBattleAnimMove_DragonRush:: createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 6 delay 4 playsewithpan SE_M_VITAL_THROW, SOUND_PAN_TARGET - createsprite gDragonRushSpriteTemplate, ANIM_ATTACKER, 131, -16, -16 + createsprite gDragonRushSpriteTemplate, ANIM_ATTACKER, 3, -16, -16 delay 8 - createsprite gComplexPaletteBlendSpriteTemplate, ANIM_TARGET, 2, 31, 5, 1, RGB_WHITE, 10, 0, 0 - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, 1, 1 + createsprite gComplexPaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 31, 5, 1, RGB_WHITE, 10, 0, 0 + createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 3, 0, 0, 1, 1 createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 5, 1 waitforvisualfinish playsewithpan 131, SOUND_PAN_TARGET - createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, 0, 0, 20, 24, 14, 2 - createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, 5, 0, -20, 24, 14, 1 - createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, 0, 5, 20, -24, 14, 2 - createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, -5, 0, 20, 24, 14, 2 - createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, 0, -5, 30, 18, 8, 2 - createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, 0, 0, 30, -18, 8, 2 - createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, 0, 0, -30, 18, 8, 2 - createsprite gRockFragmentSpriteTemplate, ANIM_TARGET, 2, 0, 0, -30, -18, 8, 2 + createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 20, 24, 14, 2 + createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 5, 0, -20, 24, 14, 1 + createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, 5, 20, -24, 14, 2 + createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, -5, 0, 20, 24, 14, 2 + createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, -5, 30, 18, 8, 2 + createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 30, -18, 8, 2 + createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, -30, 18, 8, 2 + createsprite gRockFragmentSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, -30, -18, 8, 2 createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 3, 7, 1 waitforvisualfinish clearmonbg ANIM_DEF_PARTNER @@ -1704,29 +1704,28 @@ gBattleAnimMove_BraveBird:: gBattleAnimMove_EarthPower:: loadspritegfx ANIM_TAG_SMALL_EMBER loadspritegfx ANIM_TAG_FIRE_PLUME - createvisualtask AnimTask_HorizontalShake, 3, ANIM_DEF_PARTNER, 10, 50 createvisualtask AnimTask_HorizontalShake, 3, ANIM_TARGET, 10, 50 playsewithpan SE_M_EARTHQUAKE, SOUND_PAN_TARGET delay 40 loopsewithpan 145, SOUND_PAN_TARGET 11, 3 createvisualtask AnimTask_ShakeMon, 5, ANIM_TARGET, 0, 3, 25, 1 - createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 194, 1, 5, 0 + createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 66, 1, 5, 0 delay 1 - createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 194, 1, -10, -15 + createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 66, 1, -10, -15 delay 1 - createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 130, 1, 0, 25 + createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 2, 1, 0, 25 delay 1 - createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 194, 1, 15, 5 + createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 66, 1, 15, 5 delay 1 - createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 194, 1, -25, 0 + createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 66, 1, -25, 0 delay 1 - createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 130, 1, 30, 30 + createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 2, 1, 30, 30 delay 1 - createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 130, 1, -27, 25 + createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 2, 1, -27, 25 delay 1 - createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 194, 1, 0, 8 + createsprite gDragonRageFirePlumeSpriteTemplate, ANIM_TARGET, 66, 1, 0, 8 waitforvisualfinish - createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_TARGET, 194, 0, 0, 4 + createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_TARGET, 66, 0, 0, 4 waitforvisualfinish end @@ -1790,7 +1789,7 @@ GigaImpactContinuity: createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 4, -10, 0, 1, 0 playsewithpan SE_M_MEGA_KICK2, SOUND_PAN_TARGET delay 1 - createsprite gSlideMonToOffsetSpriteTemplate, ANIM_TARGET, 2, 1, -16, 0, 0, 4 + createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 1, -16, 0, 0, 4 waitforvisualfinish createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 4, 0, 12, 1 waitforvisualfinish @@ -1879,17 +1878,17 @@ gBattleAnimMove_Avalanche:: loadspritegfx ANIM_TAG_ROCKS loadspritegfx ANIM_TAG_ICE_CHUNK monbg ANIM_DEF_PARTNER - createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_TARGET, 2, 7, 1, 11, 1 - createsprite gAvalancheSpriteTemplate, ANIM_TARGET, 130, -5, 1, -5, 1 + createsprite gShakeMonOrTerrainSpriteTemplate, ANIM_ATTACKER, 2, 7, 1, 11, 1 + createsprite gAvalancheSpriteTemplate, ANIM_TARGET, 2, -5, 1, -5, 1 playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET delay 2 - createsprite gAvalancheSpriteTemplate, ANIM_TARGET, 130, 5, 0, 6, 1 + createsprite gAvalancheSpriteTemplate, ANIM_TARGET, 2, 5, 0, 6, 1 playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET delay 2 - createsprite gAvalancheSpriteTemplate, ANIM_TARGET, 130, 19, 1, 10, 1 + createsprite gAvalancheSpriteTemplate, ANIM_TARGET, 2, 19, 1, 10, 1 playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET delay 2 - createsprite gAvalancheSpriteTemplate ANIM_TARGET, 130, -17, 2, -20, 1 + createsprite gAvalancheSpriteTemplate ANIM_TARGET, 2, -17, 2, -20, 1 playsewithpan SE_M_ROCK_THROW, SOUND_PAN_TARGET createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 0, 5, 50, 1 createvisualtask AnimTask_ShakeMon, 2, ANIM_DEF_PARTNER, 0, 5, 50, 1 @@ -2212,7 +2211,7 @@ gBattleAnimMove_ZenHeadbutt:: setalpha 12, 8 createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 2, 0, 4, 0 waitforvisualfinish - createsprite gZenHeadbuttSpriteTemplate, ANIM_ATTACKER, 66, 0 + createsprite gZenHeadbuttSpriteTemplate, ANIM_ATTACKER, 2, 0 delay 18 playsewithpan SE_M_MORNING_SUN, SOUND_PAN_ATTACKER waitforvisualfinish @@ -2228,7 +2227,7 @@ gBattleAnimMove_ZenHeadbutt:: createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 2, 0, 4, 1 createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 5, 0, 6, 1 createsprite gBowMonSpriteTemplate, ANIM_ATTACKER, 1, 2 - createsprite gAquaTailHitSpriteTemplate, ANIM_TARGET, 131, 0, 0, 1, 1 + createsprite gAquaTailHitSpriteTemplate, ANIM_TARGET, 3, 0, 0, 1, 1 playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET waitforvisualfinish createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 4, 4, 0, 0 @@ -2246,22 +2245,22 @@ gBattleAnimMove_MirrorShot:: createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 0, 10, RGB_WHITEALPHA createvisualtask AnimTask_BlendParticle, 5, ANIM_TAG_IMPACT, 0, 12, 12, RGB(21, 21, 21) waitforvisualfinish - createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 131, 1, 2 + createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, 1, 2 createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET delay 3 - createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 131, 1, 2 + createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, 1, 2 createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET delay 3 - createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 131, 1, 2 + createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, 1, 2 createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET delay 3 - createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 131, 1, 2 + createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, 1, 2 createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET delay 3 - createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 131, 1, 2 + createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, 1, 2 createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET delay 3 - createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 131, 1, 2 + createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, 1, 2 createvisualtask SoundTask_PlaySE1WithPanning, 5, SE_M_VITAL_THROW2, SOUND_PAN_TARGET waitforvisualfinish createvisualtask AnimTask_BlendBattleAnimPalExclude, 5, 5, 2, 10, 0, RGB_WHITEALPHA @@ -2318,27 +2317,27 @@ gBattleAnimMove_RockClimb:: monbg ANIM_DEF_PARTNER splitbgprio ANIM_TARGET setalpha 12, 8 - createvisualtask AnimTask_Rollout, 2, 0 + createvisualtask AnimTask_Rollout, 2, 1 waitforvisualfinish - createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, 0, 1, 30, 1, RGB(0, 16, 1) - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 131, -15, 8, 1, 1 + createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, 0, 1, 30, 1, 0 + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -15, 8, 1, 1 playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET delay 1 playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 131, -5, -12, 1, 1 + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -5, -12, 1, 1 delay 1 playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 131, 0, -32, 1, 1 + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, -32, 1, 1 delay 1 playsewithpan SE_M_VITAL_THROW2, SOUND_PAN_TARGET - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 131, 5, -52, 1, 1 + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 5, -52, 1, 1 createsprite gSlideMonToOffsetSpriteTemplate, ANIM_TARGET, 2, 1, -25, 16, 1, 4 delay 4 createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 0, 3, 6, 1 delay 30 createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 6 delay 4 - createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_TARGET, 2, 1, 0, 6 + createsprite gSlideMonToOriginalPosSpriteTemplate, ANIM_ATTACKER, 2, 1, 0, 6 clearmonbg ANIM_DEF_PARTNER blendoff end @@ -2435,32 +2434,32 @@ gBattleAnimMove_DracoMeteor:: blendoff end DracoMeteor1: - createsprite gDracoMeteorRocksSpriteTemplate, ANIM_ATTACKER, 131, -48, -64, 40, 32, 25 + createsprite gDracoMeteorRocksSpriteTemplate, ANIM_ATTACKER, 3, -48, -64, 40, 32, 25 delay 2 - createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 131, -48, -64, 40, 32, 25 + createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 3, -48, -64, 40, 32, 25 delay 2 - createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 131, -48, -64, 40, 32, 25 + createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 3, -48, -64, 40, 32, 25 return DracoMeteor2: - createsprite gDracoMeteorRocksSpriteTemplate, ANIM_ATTACKER, 131, -112, -64, -8, 32, 25 + createsprite gDracoMeteorRocksSpriteTemplate, ANIM_ATTACKER, 3, -112, -64, -8, 32, 25 delay 2 - createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 131, -112, -64, -8, 32, 25 + createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 3, -112, -64, -8, 32, 25 delay 2 - createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 131, -112, -64, -8, 32, 25 + createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 3, -112, -64, -8, 32, 25 return DracoMeteor3: - createsprite gDracoMeteorRocksSpriteTemplate, ANIM_ATTACKER, 131, -80, -64, 24, 32, 25 + createsprite gDracoMeteorRocksSpriteTemplate, ANIM_ATTACKER, 3, -80, -64, 24, 32, 25 delay 2 - createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 131, -80, -64, 24, 32, 25 + createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 3, -80, -64, 24, 32, 25 delay 2 - createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 131, -80, -64, 24, 32, 25 + createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 3, -80, -64, 24, 32, 25 return DracoMeteor4: - createsprite gDracoMeteorRocksSpriteTemplate, ANIM_ATTACKER, 131, -80, -64, -8, 32, 25 + createsprite gDracoMeteorRocksSpriteTemplate, ANIM_ATTACKER, 3, -80, -64, -8, 32, 25 delay 2 - createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 131, -80, -64, -8, 32, 25 + createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 3, -80, -64, -8, 32, 25 delay 2 - createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 131, -80, -64, -8, 32, 25 + createsprite gDracoMeteorTailSpriteTemplate, ANIM_ATTACKER, 3, -80, -64, -8, 32, 25 return gBattleAnimMove_Discharge:: @@ -2576,14 +2575,14 @@ gBattleAnimMove_LavaPlume:: createvisualtask AnimTask_ShakeMon2, 2, ANIM_DEF_PARTNER, 1, 0, 32, 1 createvisualtask AnimTask_ShakeMon2, 2, ANIM_ATK_PARTNER, 1, 0, 32, 1 waitforvisualfinish - createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 130, 0 - createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 130, 32 - createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 130, 64 - createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 130, 96 - createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 130, 128 - createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 130, 160 - createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 130, 192 - createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 130, 224 + createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 2, 0 + createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 2, 32 + createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 2, 64 + createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 2, 96 + createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 2, 128 + createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 2, 160 + createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 2, 192 + createsprite gLavaPlumeSpriteTemplate, ANIM_ATTACKER, 2, 224 playsewithpan SE_M_SACRED_FIRE, SOUND_PAN_ATTACKER waitforvisualfinish end @@ -2729,7 +2728,7 @@ RockWrecker_1: createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 6 delay 3 playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER - createsprite gRockBlastRockSpriteTemplate, ANIM_ATTACKER, 130, 16, 0, 0, 0, 25, 257 + createsprite gRockBlastRockSpriteTemplate, ANIM_ATTACKER, 130, 16, 0, 0, 0, 25, (1 << 8) | 1 waitforvisualfinish createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 131, 0, 0, 1, 1 playsewithpan SE_M_ROCK_THROW SOUND_PAN_TARGET @@ -2747,15 +2746,15 @@ RockWrecker_2: createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 6 delay 3 playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER - createsprite gRockBlastRockSpriteTemplate, ANIM_ATTACKER, 130, 16, 0, 0, 0, 25, 257 + createsprite gRockBlastRockSpriteTemplate, ANIM_ATTACKER, 2, 16, 0, 0, 0, 25, 257 waitforvisualfinish - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 131, 0, 0, 1, 1 + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 0, 0, 1, 1 playsewithpan SE_M_ROCK_THROW SOUND_PAN_TARGET - createsprite gRockFragmentSpriteTemplate ANIM_TARGET, 130, 0, 0, 20, 24, 14, 2 + createsprite gRockFragmentSpriteTemplate ANIM_TARGET, 2, 0, 0, 20, 24, 14, 2 createvisualtask AnimTask_ShakeMon, 2, ANIM_TARGET, 3, 0, 5, 1 - createsprite gRockFragmentSpriteTemplate ANIM_ATTACKER, 130, 5, 0, -20, 24, 14, 1 - createsprite gRockFragmentSpriteTemplate ANIM_ATTACKER, 130, 0, 5, 20, -18, 14, 2 - createsprite gRockFragmentSpriteTemplate ANIM_ATTACKER, 130, -5, 0, -20, -18, 14, 2 + createsprite gRockFragmentSpriteTemplate ANIM_ATTACKER, 2, 5, 0, -20, 24, 14, 1 + createsprite gRockFragmentSpriteTemplate ANIM_ATTACKER, 2, 0, 5, 20, -18, 14, 2 + createsprite gRockFragmentSpriteTemplate ANIM_ATTACKER, 2, -5, 0, -20, -18, 14, 2 waitforvisualfinish call UnsetPsychicBg end @@ -2788,7 +2787,7 @@ gBattleAnimMove_GunkShot:: createvisualtask AnimTask_ShakeMon, 5, ANIM_ATTACKER, 0, 2, 40, 1 delay 6 panse SE_M_HYDRO_PUMP, SOUND_PAN_ATTACKER, SOUND_PAN_TARGET, 2, 0 - createvisualtask AnimTask_StartSinAnimTimer, 5, 1, 100 + createvisualtask AnimTask_StartSinAnimTimer, 5, 100 call GunkShotParticles call GunkShotParticles call GunkShotParticles @@ -2860,7 +2859,7 @@ gBattleAnimMove_MagnetBomb:: loadspritegfx ANIM_TAG_SPARK_2 delay 0 playsewithpan 119, 192 - createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 32, 24, 190, 12, 0, 1, 0 + createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 32, 24, 190, 12, 0, 1, 0 delay 0 createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 80, 24, 22, 12, 0, 1, 0 createsprite gSparkElectricitySpriteTemplate, ANIM_ATTACKER, 0, 156, 24, 121, 13, 0, 1, 1 @@ -2901,22 +2900,22 @@ gBattleAnimMove_MagnetBomb:: loadspritegfx ANIM_TAG_GRAY_SMOKE loadspritegfx ANIM_TAG_BLACK_BALL playsewithpan 177, 63 - createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 130, 8, 8, 1, 0 + createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, 8, 8, 1, 0 delay 2 - createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 130, -8, -8, 1, 0 + createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, -8, -8, 1, 0 delay 2 - createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 130, 8, -8, 1, 0 + createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, 8, -8, 1, 0 delay 2 - createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 130, -8, 8, 1, 0 + createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, -8, 8, 1, 0 waitforvisualfinish playsewithpan 177, 63 - createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 130, 8, 8, 1, 0 + createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, 8, 8, 1, 0 delay 2 - createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 130, -8, -8, 1, 0 + createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, -8, -8, 1, 0 delay 2 - createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 130, 8, -8, 1, 0 + createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, 8, -8, 1, 0 delay 2 - createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 130, -8, 8, 1, 0 + createsprite gOctazookaSmokeSpriteTemplate, ANIM_TARGET, 2, -8, 8, 1, 0 waitforvisualfinish end @@ -2924,55 +2923,54 @@ gBattleAnimMove_StoneEdge:: loadspritegfx ANIM_TAG_STONE_EDGE loadspritegfx ANIM_TAG_IMPACT playsewithpan SE_M_ROCK_THROW SOUND_PAN_TARGET - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 28, 528, 30, 13, 50, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 28, 528, 30, 13, 50, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 32, 480, 20, 16, -46, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 32, 480, 20, 16, -46, 1 delay 2 loopsewithpan 131, SOUND_PAN_TARGET 24, 3 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 33, 576, 20, 8, 42, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 33, 576, 20, 8, 42, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 31, 400, 25, 11, -42, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 31, 400, 25, 11, -42, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 28, 512, 25, 16, 46, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 28, 512, 25, 16, 46, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 33, 464, 30, 15, 49, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 33, 464, 30, 15, 49, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 28, 528, 30, 13, 50, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 28, 528, 30, 13, 50, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 32, 480, 20, 16, -46, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 32, 480, 20, 16, -46, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 33, 576, 20, 8, 42, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 33, 576, 20, 8, 42, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 31, 400, 25, 11, -42, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 31, 400, 25, 11, -42, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 28, 512, 25, 16, 46, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 28, 512, 25, 16, 46, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 33, 464, 30, 15, 49, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 33, 464, 30, 15, 49, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 28, 528, 30, 13, 50, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 28, 528, 30, 13, 50, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 32, 480, 20, 16, -46, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 32, 480, 20, 16, -46, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 33, 576, 20, 8, 42, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 33, 576, 20, 8, 42, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 31, 400, 25, 11, -42, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 31, 400, 25, 11, -42, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 28, 512, 25, 16, 46, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 28, 512, 25, 16, 46, 1 delay 2 - createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 130, 0, 33, 464, 30, 15, 49, 1 + createsprite gStoneEdgeSpriteTemplate, ANIM_TARGET, 2, 0, 33, 464, 30, 15, 49, 1 delay 2 - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 131, -32, -16, 1, 3 + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -32, -16, 1, 3 playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 3, 0, 12, 1 - createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_DEF_PARTNER, 3, 0, 12, 1 delay 4 - createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 131, 1, 3 + createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, 1, 3 playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET delay 4 - createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 131, 1, 3 + createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, 1, 3 playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET delay 4 - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 131, 32, 20, 1, 3 + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 32, 20, 1, 3 playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET waitforvisualfinish clearmonbg ANIM_DEF_PARTNER @@ -3016,9 +3014,9 @@ gBattleAnimMove_GrassKnot:: loadspritegfx ANIM_TAG_RAZOR_LEAF loadspritegfx ANIM_TAG_IMPACT createsprite gSlideMonToOffsetSpriteTemplate, ANIM_ATTACKER, 2, 0, 20, 0, 0, 4 - createsprite gGrassKnotSpriteTemplate, ANIM_TARGET, 130, -18, 19, 40, 8, 160, 0 + createsprite gGrassKnotSpriteTemplate, ANIM_TARGET, 2, -18, 19, 40, 8, 160, 0 delay 4 - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 130, -8, 8, 1, 2 + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, -8, 8, 1, 2 createvisualtask AnimTask_RotateMonSpriteToSide, 2, 6, 384, ANIM_TARGET, 2 playsewithpan SE_M_VITAL_THROW2 SOUND_PAN_TARGET waitforvisualfinish @@ -3287,6 +3285,7 @@ gBattleAnimMove_AquaJet:: loadspritegfx ANIM_TAG_SPARKLE_6 loadspritegfx ANIM_TAG_ROUND_SHADOW loadspritegfx ANIM_TAG_SPLASH + loadspritegfx ANIM_TAG_SWEAT_BEAD playsewithpan SE_M_HEADBUTT, SOUND_PAN_ATTACKER createsprite gDiveBallSpriteTemplate, ANIM_ATTACKER, 2, 0, 0, 13, 336 waitforvisualfinish @@ -3302,7 +3301,7 @@ gBattleAnimMove_AquaJet:: monbg ANIM_DEF_PARTNER setalpha 12, 8 playsewithpan SE_M_EXPLOSION, SOUND_PAN_TARGET - createsprite gDiveWaterSplashSpriteTemplate, ANIM_TARGET, 131, 1 + createsprite gDiveWaterSplashSpriteTemplate, ANIM_TARGET, 3, 1 call DiveAttackWaterDroplets call DiveAttackWaterDroplets call DiveAttackWaterDroplets @@ -3323,39 +3322,39 @@ gBattleAnimMove_AttackOrder:: monbg ANIM_DEF_PARTNER splitbgprio ANIM_TARGET playsewithpan SE_M_SWEET_SCENT, SOUND_PAN_TARGET - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 120, 70, 5, 70, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 120, 70, 5, 70, 30 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 120, 55, 6, 60, 25 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 120, 55, 6, 60, 25 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 120, 60, 7, 60, 30 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 120, 55, 10, 60, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 120, 60, 7, 60, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 120, 55, 10, 60, 30 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 100, 50, 4, 50, 26 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 100, 50, 4, 50, 26 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 105, 25, 8, 60, 20 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 105, 25, 8, 60, 20 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 120, 40, 10, 48, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 120, 40, 10, 48, 30 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 120, 30, 6, 45, 25 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 120, 35, 10, 60, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 120, 30, 6, 45, 25 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 120, 35, 10, 60, 30 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 105, 20, 8, 40, 0 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 105, 20, 8, 40, 0 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 20, 255, 15, 32, 0 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 5, 110, 10, 8, 32, 20 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 20, 255, 15, 32, 0 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 110, 10, 8, 32, 20 waitforvisualfinish - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 131, -32, -16, 1, 3 + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, -32, -16, 1, 3 playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 3, 0, 12, 1 createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_TARGET, 3, 0, 12, 1 delay 4 - createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 131, 1, 3 + createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, 1, 3 playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET delay 4 - createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 131, 1, 3 + createsprite gRandomPosHitSplatSpriteTemplate, ANIM_TARGET, 3, 1, 3 playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET delay 4 - createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 131, 32, 20, 1, 3 + createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 3, 32, 20, 1, 3 playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET waitforvisualfinish clearmonbg ANIM_DEF_PARTNER @@ -3369,30 +3368,30 @@ gBattleAnimMove_DefendOrder:: monbg ANIM_DEF_PARTNER splitbgprio ANIM_TARGET playsewithpan SE_M_SWEET_SCENT, SOUND_PAN_TARGET - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 120, 70, 5, 70, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 120, 70, 5, 70, 30 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 115, 55, 6, 60, 25 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 115, 55, 6, 60, 25 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 115, 60, 7, 60, 30 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 115, 55, 10, 60, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 115, 60, 7, 60, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 115, 55, 10, 60, 30 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 100, 50, 4, 50, 26 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 100, 50, 4, 50, 26 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 105, 25, 8, 60, 20 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 105, 25, 8, 60, 20 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 115, 40, 10, 48, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 115, 40, 10, 48, 30 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 120, 30, 6, 45, 25 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 115, 35, 10, 60, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 120, 30, 6, 45, 25 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 115, 35, 10, 60, 30 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 105, 20, 8, 40, 0 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 105, 20, 8, 40, 0 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 20, 255, 15, 32, 0 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 110, 10, 8, 32, 20 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 20, 255, 15, 32, 0 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_TARGET, 2, 110, 10, 8, 32, 20 waitforvisualfinish loadspritegfx ANIM_TAG_BLUE_STAR waitforvisualfinish - clearmonbg ANIM_ATK_PARTNER + clearmonbg ANIM_DEF_PARTNER blendoff delay 1 call BideSetUp @@ -3406,30 +3405,30 @@ gBattleAnimMove_HealOrder:: monbg ANIM_DEF_PARTNER splitbgprio ANIM_TARGET playsewithpan SE_M_SWEET_SCENT, SOUND_PAN_TARGET - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 120, 70, 5, 70, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 120, 70, 5, 70, 30 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 115, 55, 6, 60, 25 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 115, 55, 6, 60, 25 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 115, 60, 7, 60, 30 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 115, 55, 10, 60, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 115, 60, 7, 60, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 115, 55, 10, 60, 30 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 100, 50, 4, 50, 26 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 100, 50, 4, 50, 26 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 105, 25, 8, 60, 20 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 105, 25, 8, 60, 20 delay 1 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 115, 40, 10, 48, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 115, 40, 10, 48, 30 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 120, 30, 6, 45, 25 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 115, 35, 10, 60, 30 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 120, 30, 6, 45, 25 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 115, 35, 10, 60, 30 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 105, 20, 8, 40, 0 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 105, 20, 8, 40, 0 delay 3 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 20, 255, 15, 32, 0 - createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 130, 110, 10, 8, 32, 20 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 20, 255, 15, 32, 0 + createsprite gAttackOrderParticleSpriteTemplate, ANIM_ATTACKER, 2, 110, 10, 8, 32, 20 waitforvisualfinish loadspritegfx ANIM_TAG_BLUE_STAR waitforvisualfinish - clearmonbg ANIM_ATK_PARTNER + clearmonbg ANIM_DEF_PARTNER blendoff delay 1 call HealingEffect @@ -3469,6 +3468,10 @@ gBattleAnimMove_DoubleHit:: playsewithpan SE_M_COMET_PUNCH, SOUND_PAN_TARGET delay 8 waitforvisualfinish + @ why does the anim hit twice? + @ that just means the anim plays 4 times + @ which doesn't make sense + @ I don't know, but I'm not gonna argue with it createsprite gHorizontalLungeSpriteTemplate, ANIM_ATTACKER, 2, 4, 4 delay 6 createsprite gBasicHitSplatSpriteTemplate, ANIM_TARGET, 2, 0, 0, 1, 2 @@ -3560,7 +3563,7 @@ gBattleAnimMove_LunarDance:: loadspritegfx ANIM_TAG_GREEN_SPARKLE loadspritegfx ANIM_TAG_HOLLOW_ORB setalpha 0, 16 - createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 1, 0, 16, 0 + createsprite gSimplePaletteBlendSpriteTemplate, ANIM_ATTACKER, 2, 1, 1, 0, 16, RGB_BLACK waitforvisualfinish createsprite gMoonSpriteTemplate, ANIM_ATTACKER, 2, 120, 56 createvisualtask AnimTask_AlphaFadeIn, 3, 0, 16, 16, 0, 1 @@ -3576,8 +3579,8 @@ gBattleAnimMove_LunarDance:: delay 30 createsprite gMoonlightSparkleSpriteTemplate, ANIM_ATTACKER, 40, 10, 0 delay 20 - createvisualtask AnimTask_MoonlightEndFade, 2, 0 - createvisualtask AnimTask_DragonDanceWaver, 5, 0 + createvisualtask AnimTask_MoonlightEndFade, 2 + createvisualtask AnimTask_DragonDanceWaver, 5 playsewithpan 203, SOUND_PAN_ATTACKER delay 8 createvisualtask AnimTask_BlendPalInAndOutByTag, 5, ANIM_TAG_HOLLOW_ORB, RGB(0, 0, 19), 14, 0, 3 @@ -3592,7 +3595,6 @@ gBattleAnimMove_LunarDance:: delay 30 playsewithpan 203, SOUND_PAN_ATTACKER waitforvisualfinish - clearmonbg ANIM_ATTACKER delay 1 end @@ -3640,7 +3642,7 @@ gBattleAnimMove_MagmaStorm:: call FireSpinEffect restorebg waitbgfadeout - setarg 7, 0xFFF + setarg 7, 0xFFFF waitbgfadein clearmonbg ANIM_DEF_PARTNER blendoff @@ -3769,7 +3771,7 @@ gBattleAnimMove_OminousWind:: delay 0 createvisualtask AnimTask_BlendBattleAnimPalExclude, 10, 1, 0, 0, 0, 0 delay 0 - createvisualtask AnimTask_GetAttackerSide, 2, 0 + createvisualtask AnimTask_GetAttackerSide, 2 jumpargeq 7, 1, OminousWindFadeToBg fadetobg BG_GHOST waitbgfadeout @@ -21118,7 +21120,7 @@ gBattleAnimMove_Rollout:: monbg ANIM_DEF_PARTNER splitbgprio ANIM_TARGET setalpha 12, 8 - createvisualtask AnimTask_Rollout, 2 + createvisualtask AnimTask_Rollout, 2, 0 waitforvisualfinish createvisualtask AnimTask_ShakeTargetBasedOnMovePowerOrDmg, 2, FALSE, 1, 30, 1, 0 createsprite gBasicHitSplatSpriteTemplate, ANIM_ATTACKER, 4, 0, 0, ANIM_TARGET, 2 @@ -28311,7 +28313,7 @@ Status_MagmaStorm: call FireSpinEffect restorebg waitbgfadeout - setarg 7, 0xFFF + setarg 7, 0xFFFF waitbgfadein stopsound clearmonbg ANIM_DEF_PARTNER diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 994ba7e6ee..f5f1d948a2 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3418,16 +3418,6 @@ BattleScript_KOFail:: waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd -BattleScript_EffectSuperFang:: - attackcanceler - accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE - attackstring - ppreduce - typecalc - clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE - damagetohalftargethp - goto BattleScript_HitFromAtkAnimation - BattleScript_RecoilIfMiss:: printstring STRINGID_PKMNCRASHED waitmessage B_WAIT_TIME_LONG @@ -3873,28 +3863,6 @@ BattleScript_EffectDisable:: waitmessage B_WAIT_TIME_LONG goto BattleScript_MoveEnd -BattleScript_EffectLevelDamage:: - attackcanceler - accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE - attackstring - ppreduce - typecalc - clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE - dmgtolevel - adjustdamage - goto BattleScript_HitFromAtkAnimation - -BattleScript_EffectPsywave:: - attackcanceler - accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE - attackstring - ppreduce - typecalc - clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE - psywavedamageeffect - adjustdamage - goto BattleScript_HitFromAtkAnimation - BattleScript_EffectCounter:: attackcanceler counterdamagecalculator BattleScript_FailedFromAtkString @@ -4380,17 +4348,6 @@ BattleScript_EffectBatonPass:: switchineffects BS_ATTACKER goto BattleScript_MoveEnd -BattleScript_EffectFixedDamageArg:: - attackcanceler - accuracycheck BattleScript_PrintMoveMissed, ACC_CURR_MOVE - attackstring - ppreduce - typecalc - clearmoveresultflags MOVE_RESULT_SUPER_EFFECTIVE | MOVE_RESULT_NOT_VERY_EFFECTIVE - setargtobattledamage - adjustdamage - goto BattleScript_HitFromAtkAnimation - BattleScript_EffectMorningSun:: BattleScript_EffectSynthesis:: BattleScript_EffectMoonlight:: @@ -10120,3 +10077,15 @@ BattleScript_SleepClausePreventsEnd:: printstring STRINGID_BLOCKEDBYSLEEPCLAUSE waitmessage B_WAIT_TIME_LONG end2 + +BattleScript_QuestionForfeitBattle:: + printselectionstring STRINGID_QUESTIONFORFEITBATTLE + forfeityesnobox BS_ATTACKER + endselectionscript + +BattleScript_ForfeitBattleGaveMoney:: + getmoneyreward + printstring STRINGID_FORFEITBATTLEGAVEMONEY + waitmessage B_WAIT_TIME_LONG + end2 + diff --git a/docs/team_procedures/merge_checklist.md b/docs/team_procedures/merge_checklist.md index 8af4247411..107f5a0f9f 100644 --- a/docs/team_procedures/merge_checklist.md +++ b/docs/team_procedures/merge_checklist.md @@ -37,18 +37,18 @@ If you're not sure if something CAN be tested, start a discussion. Some contribu If any new tests are `KNOWN_FAILING`, issues should be opened describing each of the `KNOWN_FAILING` tests and our understanding of why they fail. -## Does the branch meet our [config philosophy](docs/styleguide#config-philosophy)? +## Does the branch meet our [config philosophy](/docs/STYLEGUIDE.md#config-philosophy)? -## Does the branch meet our [saves philosophy](docs/styleguide#saves-philosophy)? +## Does the branch meet our [saves philosophy](/docs/STYLEGUIDE.md#saves-philosophy)? -## Does the submitted code follow the [styleguide](docs/styleguide)? +## Does the submitted code follow the [styleguide](/docs/STYLEGUIDE.md)? This applies to code that comes from other branches or games. ## Is the pull request appropriately labeled? Without labels, the CHANGELOG will not be properly formatted. For specifically the `bugfix` label, an additional label, detailing what area the bug exists in is required. ## Is `pokeemerald-expansion` free from a merge freeze? -Our [release schedule](docs/team_procedures/schedule.md) prevents us from merging Big Features and non-bugfixes within certain dates close to a release. Please use `/release` in the RHH Discord to clarify when these are occuring. +Our [release schedule](/docs/team_procedures/schedule.md) prevents us from merging Big Features and non-bugfixes within certain dates close to a release. Please use `/release` in the RHH Discord to clarify when these are occuring. # Merging diff --git a/docs/tutorials/how_to_new_pokemon.md b/docs/tutorials/how_to_new_pokemon.md index b8a99520ec..de2d41d57c 100644 --- a/docs/tutorials/how_to_new_pokemon.md +++ b/docs/tutorials/how_to_new_pokemon.md @@ -1278,3 +1278,26 @@ Gen 4-style shadows are defined by the `SHADOW` macro which takes the following - `SHADOW_SIZE_XL_BATTLE_ONLY` To make the Pokémon have no shadow, use the `NO_SHADOW` macro instead of `SHADOW`. + +## 6. Limiting species allowed as followers +You may use the following configs in `include/config/overworld.h` +```c +#define OW_FOLLOWERS_ALLOWED_SPECIES (0) +#define OW_FOLLOWERS_ALLOWED_MET_LVL (0) +#define OW_FOLLOWERS_ALLOWED_MET_LOC (0) +``` +Examples: +```c +// Yellow Pikachu: +#define OW_FOLLOWERS_ALLOWED_SPECIES (SPECIES_PIKACHU) +#define OW_FOLLOWERS_ALLOWED_MET_LVL (0) +#define OW_FOLLOWERS_ALLOWED_MET_LOC (MAPSEC_PALLET_TOWN) +// Hoenn Starter: +#define OW_FOLLOWERS_ALLOWED_SPECIES (0) +#define OW_FOLLOWERS_ALLOWED_MET_LVL (5) +#define OW_FOLLOWERS_ALLOWED_MET_LOC (MAPSEC_ROUTE_101) +// Species set in VAR_XXXX: +#define OW_FOLLOWERS_ALLOWED_SPECIES (VAR_XXXX) +#define OW_FOLLOWERS_ALLOWED_MET_LVL (0) +#define OW_FOLLOWERS_ALLOWED_MET_LOC (0) +``` diff --git a/graphics/fonts/latin_narrow.png b/graphics/fonts/latin_narrow.png index 434638ed17..bb9d0670d3 100644 Binary files a/graphics/fonts/latin_narrow.png and b/graphics/fonts/latin_narrow.png differ diff --git a/graphics/fonts/latin_narrower.png b/graphics/fonts/latin_narrower.png index 19a6a98fb6..ab4ce4322e 100644 Binary files a/graphics/fonts/latin_narrower.png and b/graphics/fonts/latin_narrower.png differ diff --git a/graphics/fonts/latin_normal.png b/graphics/fonts/latin_normal.png index d1de69d136..b3fa87b0e0 100644 Binary files a/graphics/fonts/latin_normal.png and b/graphics/fonts/latin_normal.png differ diff --git a/graphics/fonts/latin_short.png b/graphics/fonts/latin_short.png index 98ad3c5cc3..12aa01835d 100644 Binary files a/graphics/fonts/latin_short.png and b/graphics/fonts/latin_short.png differ diff --git a/graphics/fonts/latin_short_narrow.png b/graphics/fonts/latin_short_narrow.png index 6bf1bae0cf..b551f3215c 100644 Binary files a/graphics/fonts/latin_short_narrow.png and b/graphics/fonts/latin_short_narrow.png differ diff --git a/graphics/fonts/latin_short_narrower.png b/graphics/fonts/latin_short_narrower.png index 5c4f4c1d4d..920a88aa01 100644 Binary files a/graphics/fonts/latin_short_narrower.png and b/graphics/fonts/latin_short_narrower.png differ diff --git a/graphics/fonts/latin_small.png b/graphics/fonts/latin_small.png index 41bb38cff8..31c4444dc4 100644 Binary files a/graphics/fonts/latin_small.png and b/graphics/fonts/latin_small.png differ diff --git a/graphics/fonts/latin_small_narrow.png b/graphics/fonts/latin_small_narrow.png index ff07b857d7..4fbb13aad4 100644 Binary files a/graphics/fonts/latin_small_narrow.png and b/graphics/fonts/latin_small_narrow.png differ diff --git a/graphics/fonts/latin_small_narrower.png b/graphics/fonts/latin_small_narrower.png index c20fa4ae48..69bca4645a 100644 Binary files a/graphics/fonts/latin_small_narrower.png and b/graphics/fonts/latin_small_narrower.png differ diff --git a/include/battle.h b/include/battle.h index dbeb791867..9a627b16b0 100644 --- a/include/battle.h +++ b/include/battle.h @@ -396,6 +396,7 @@ struct BattleCallbacksStack struct StatsArray { u16 stats[NUM_STATS]; + u16 level; }; struct BattleResources diff --git a/include/battle_gimmick.h b/include/battle_gimmick.h index de1352a611..d0e975462a 100644 --- a/include/battle_gimmick.h +++ b/include/battle_gimmick.h @@ -17,8 +17,8 @@ struct GimmickInfo const struct SpritePalette *triggerPal; // trigger gfx data const struct SpriteSheet *triggerSheet; const struct SpriteTemplate *triggerTemplate; - const struct SpritePalette *indicatorPal; // indicator gfx data - const struct SpriteSheet *indicatorSheet; + const u32 indicatorPalTag; + const u8 *indicatorData; bool32 (*CanActivate)(u32 battler); void (*ActivateGimmick)(u32 battler); }; diff --git a/include/battle_main.h b/include/battle_main.h index 18f2210588..2d2483d84b 100644 --- a/include/battle_main.h +++ b/include/battle_main.h @@ -87,6 +87,8 @@ u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer void ModifyPersonalityForNature(u32 *personality, u32 newNature); u32 GeneratePersonalityForGender(u32 gender, u32 species); void CustomTrainerPartyAssignMoves(struct Pokemon *mon, const struct TrainerMon *partyEntry); +bool32 CanPlayerForfeitNormalTrainerBattle(void); +bool32 DidPlayerForfeitNormalTrainerBattle(void); extern struct MultiPartnerMenuPokemon gMultiPartnerParty[MULTI_PARTY_SIZE]; diff --git a/include/battle_scripts.h b/include/battle_scripts.h index e02a562be5..d67fa47be4 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -592,8 +592,6 @@ extern const u8 BattleScript_EffectToxic[]; extern const u8 BattleScript_EffectLightScreen[]; extern const u8 BattleScript_EffectRest[]; extern const u8 BattleScript_EffectOHKO[]; -extern const u8 BattleScript_EffectSuperFang[]; -extern const u8 BattleScript_EffectFixedDamageArg[]; extern const u8 BattleScript_EffectHealBlock[]; extern const u8 BattleScript_RecoilIfMiss[]; extern const u8 BattleScript_EffectMist[]; @@ -628,8 +626,6 @@ extern const u8 BattleScript_EffectHoldHands[]; extern const u8 BattleScript_EffectCelebrate[]; extern const u8 BattleScript_EffectHappyHour[]; extern const u8 BattleScript_EffectDisable[]; -extern const u8 BattleScript_EffectLevelDamage[]; -extern const u8 BattleScript_EffectPsywave[]; extern const u8 BattleScript_EffectCounter[]; extern const u8 BattleScript_EffectEncore[]; extern const u8 BattleScript_EffectPainSplit[]; @@ -856,5 +852,7 @@ extern const u8 BattleScript_EffectSpicyExtract[]; extern const u8 BattleScript_DamageToQuarterTargetHP[]; extern const u8 BattleScript_EffectFickleBeam[]; extern const u8 BattleScript_FickleBeamDoubled[]; +extern const u8 BattleScript_QuestionForfeitBattle[]; +extern const u8 BattleScript_ForfeitBattleGaveMoney[]; #endif // GUARD_BATTLE_SCRIPTS_H diff --git a/include/config/battle.h b/include/config/battle.h index 0aa37db354..a252edba92 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -16,6 +16,7 @@ #define B_SPLIT_EXP GEN_LATEST // In Gen6+, all participating mon get full experience. #define B_SCALED_EXP GEN_LATEST // In Gen5 and Gen7+, experience is weighted by level difference. #define B_UNEVOLVED_EXP_MULTIPLIER GEN_LATEST // In Gen6+, if the Pokémon is at or past the level where it would be able to evolve, but it has not, it gets a ~1.2 multiplier to EXP gain. Only applies to Pokémon with EVO_LEVEL method. +#define B_LEVEL_UP_NOTIFICATION GEN_LATEST // In Gen9+, if the Pokémon gets enough experience to level up multiple times, the message is only displayed once. // Stat settings #define B_BADGE_BOOST GEN_LATEST // In Gen4+, Gym Badges no longer boost a Pokémon's stats. @@ -256,6 +257,7 @@ #define B_HIDE_HEALTHBOX_IN_ANIMS TRUE // If set to TRUE, hides healthboxes during move animations. #define B_WAIT_TIME_MULTIPLIER 16 // This determines how long text pauses in battle last. Vanilla is 16. Lower values result in faster battles. #define B_QUICK_MOVE_CURSOR_TO_RUN FALSE // If set to TRUE, pushing B in the battle options against a wild encounter will move the cursor to the run option +#define B_RUN_TRAINER_BATTLE TRUE // If set to TRUE, players can run from Trainer battles. This is treated as a whiteout. #define B_MOVE_DESCRIPTION_BUTTON L_BUTTON // If set to a button other than B_LAST_USED_BALL_BUTTON, pressing this button will open the move description menu #define B_SHOW_USELESS_Z_MOVE_INFO FALSE // If set to TRUE, Z-moves without additional effects like newer gen status moves will say "no additional effect" #define B_ANIMATE_MON_AFTER_KO TRUE // If set to TRUE, if a Pokémon on the opposite site faints, the non-fainted Pokemon will display a victory animation. @@ -316,10 +318,17 @@ #define B_ENEMY_THROW_BALLS_SOUND GEN_LATEST // In GEN_5+, enemy Trainer's Poké Balls make a sound when thrown to send out a Pokémon. This can only be used when B_ENEMY_THROW_BALLS is set to GEN_6 or later. #define B_PLAYER_THROW_BALLS_SOUND GEN_LATEST // In GEN_5+, the player's Poké Balls make a sound when thrown to send out a Pokémon. -#define SHOW_TYPES_NEVER 0 -#define SHOW_TYPES_ALWAYS 1 -#define SHOW_TYPES_CAUGHT 2 -#define B_SHOW_TYPES SHOW_TYPES_NEVER // When defined as SHOW_TYPES_ALWAYS, after selecting "Fight" in battle, the types of all Pokemon are revealed. Whe defined as SHOW_TYPES_OWN, types are only revealed if the player owns the mon in question. +#define SHOW_TYPES_NEVER 0 // Never shows types in battle +#define SHOW_TYPES_ALWAYS 1 // Always show types in battle +#define SHOW_TYPES_CAUGHT 2 // Only show types if you've caught a species of the mon. +#define SHOW_TYPES_SEEN 3 // Only show types if you've seen a species of the mon. +#define B_SHOW_TYPES SHOW_TYPES_NEVER // When to show type indicators next to Pokémon health bars in battle, while choosing a move after selecting a target Pokémon. + +#define SHOW_EFFECTIVENESS_NEVER 0 // Never show effectiveness when selecting moves. +#define SHOW_EFFECTIVENESS_ALWAYS 1 // Always show effectiveness when selecting moves. +#define SHOW_EFFECTIVENESS_CAUGHT 2 // Only show effectiveness if you've caught a species of the mon. +#define SHOW_EFFECTIVENESS_SEEN 3 // Only show effectiveness if you've seen a species of the mon. +#define B_SHOW_EFFECTIVENESS SHOW_EFFECTIVENESS_SEEN // If not SHOW_EFFECTIVENESS_NEVER, the PP string is replaced by a type effectiveness indicator based off the moves and the opposing side. // Pokémon battle sprite settings #define B_ENEMY_MON_SHADOW_STYLE GEN_LATEST // In Gen4+, all enemy Pokemon will have a shadow drawn beneath them. diff --git a/include/constants/battle_script_commands.h b/include/constants/battle_script_commands.h index b0cccc2626..c59b0ee170 100644 --- a/include/constants/battle_script_commands.h +++ b/include/constants/battle_script_commands.h @@ -134,7 +134,6 @@ enum CmdVarious VARIOUS_TRY_ELECTRIFY, VARIOUS_TRY_SOAK, VARIOUS_TRY_LAST_RESORT, - VARIOUS_SET_ARG_TO_BATTLE_DAMAGE, VARIOUS_TRY_AUTOTOMIZE, VARIOUS_ABILITY_POPUP, VARIOUS_JUMP_IF_TARGET_ALLY, diff --git a/include/constants/battle_string_ids.h b/include/constants/battle_string_ids.h index db5ee7b16e..9eb09a2fb4 100644 --- a/include/constants/battle_string_ids.h +++ b/include/constants/battle_string_ids.h @@ -732,8 +732,10 @@ #define STRINGID_PKMNGIGANTAMAXED 730 #define STRINGID_TIMETODYNAMAX 731 #define STRINGID_TIMETOGIGANTAMAX 732 +#define STRINGID_QUESTIONFORFEITBATTLE 733 +#define STRINGID_FORFEITBATTLEGAVEMONEY 734 -#define BATTLESTRINGS_COUNT 733 +#define BATTLESTRINGS_COUNT 735 // 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/global.fieldmap.h b/include/global.fieldmap.h index 05610b0bd3..5f2a84017f 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -213,8 +213,11 @@ struct ObjectEvent /*0x14*/ struct Coords16 previousCoords; /*0x18*/ u16 facingDirection:4; // current direction? u16 movementDirection:4; - u16 rangeX:4; - u16 rangeY:4; + struct __attribute__((packed)) + { + u16 rangeX:4; + u16 rangeY:4; + } range; /*0x1A*/ u8 fieldEffectSpriteId; /*0x1B*/ u8 warpArrowSpriteId; /*0x1C*/ u8 movementActionId; diff --git a/include/pokemon.h b/include/pokemon.h index 0c3deb2f72..7e048ef015 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -658,6 +658,7 @@ void SetMonMoveSlot(struct Pokemon *mon, u16 move, u8 slot); void SetBattleMonMoveSlot(struct BattlePokemon *mon, u16 move, u8 slot); void GiveMonInitialMoveset(struct Pokemon *mon); void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon); +u16 MonTryLearningNewMoveAtLevel(struct Pokemon *mon, bool32 firstMove, u32 level); u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove); void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move); void DeleteFirstMoveAndGiveMoveToBoxMon(struct BoxPokemon *boxMon, u16 move); diff --git a/include/strings.h b/include/strings.h index 588d513d4b..2bc6b23563 100644 --- a/include/strings.h +++ b/include/strings.h @@ -2414,6 +2414,8 @@ extern const u8 gText_PM[]; // FRLG whiteout extern const u8 gText_PlayerScurriedToCenter[]; extern const u8 gText_PlayerScurriedBackHome[]; +extern const u8 gText_PlayerRegroupCenter[]; +extern const u8 gText_PlayerRegroupHome[]; extern const u8 gText_Relearn[]; // move relearner from summary screen extern const u8 gText_Rename[]; // change nickname from summary screen diff --git a/include/type_icons.h b/include/type_icons.h index 1d6a312f07..c84e44f53d 100644 --- a/include/type_icons.h +++ b/include/type_icons.h @@ -1,7 +1,7 @@ #ifndef GUARD_TYPE_ICONS_H #define GUARD_TYPE_ICONS_H -void LoadTypeIcons(u32); +void LoadTypeIcons(u32 battler); #define TYPE_ICON_TAG 0x2720 #define TYPE_ICON_TAG_2 0x2721 diff --git a/sound/music_player_table.inc b/sound/music_player_table.inc index 5981a4d037..955d4d556f 100644 --- a/sound/music_player_table.inc +++ b/sound/music_player_table.inc @@ -5,6 +5,7 @@ .equiv NUM_TRACKS_SE3, 1 .bss + .align 2 gMPlayTrack_BGM:: .space TRACK_SIZE * NUM_TRACKS_BGM diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 242c030838..3f742536fd 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -30,6 +30,7 @@ static bool32 AI_ShouldHeal(u32 battler, u32 healAmount); static bool32 AI_OpponentCanFaintAiWithMod(u32 battler, u32 healAmount); static u32 GetSwitchinHazardsDamage(u32 battler, struct BattlePokemon *battleMon); static bool32 CanAbilityTrapOpponent(u16 ability, u32 opponent); +static u32 GetHPHealAmount(u8 itemEffectParam, struct Pokemon *mon); static void InitializeSwitchinCandidate(struct Pokemon *mon) { @@ -2250,6 +2251,7 @@ static bool32 ShouldUseItem(u32 battler) s32 i; u8 validMons = 0; bool32 shouldUse = FALSE; + u32 healAmount = 0; if (IsAiVsAiBattle()) return FALSE; @@ -2291,10 +2293,12 @@ static bool32 ShouldUseItem(u32 battler) switch (ItemId_GetBattleUsage(item)) { case EFFECT_ITEM_HEAL_AND_CURE_STATUS: - shouldUse = AI_ShouldHeal(battler, 0); + healAmount = GetHPHealAmount(itemEffects[GetItemEffectParamOffset(battler, item, 4, ITEM4_HEAL_HP)], &gEnemyParty[gBattlerPartyIndexes[battler]]); + shouldUse = AI_ShouldHeal(battler, healAmount); break; case EFFECT_ITEM_RESTORE_HP: - shouldUse = AI_ShouldHeal(battler, itemEffects[GetItemEffectParamOffset(battler, item, 4, ITEM4_HEAL_HP)]); + healAmount = GetHPHealAmount(itemEffects[GetItemEffectParamOffset(battler, item, 4, ITEM4_HEAL_HP)], &gEnemyParty[gBattlerPartyIndexes[battler]]); + shouldUse = AI_ShouldHeal(battler, healAmount); break; case EFFECT_ITEM_CURE_STATUS: if (itemEffects[3] & ITEM3_SLEEP && gBattleMons[battler].status1 & STATUS1_SLEEP) @@ -2360,6 +2364,9 @@ static bool32 ShouldUseItem(u32 battler) static bool32 AI_ShouldHeal(u32 battler, u32 healAmount) { bool32 shouldHeal = FALSE; + u8 opponent; + u32 maxDamage = 0; + u32 dmg = 0; if (gBattleMons[battler].hp < gBattleMons[battler].maxHP / 4 || gBattleMons[battler].hp == 0 @@ -2369,6 +2376,30 @@ static bool32 AI_ShouldHeal(u32 battler, u32 healAmount) shouldHeal = !AI_OpponentCanFaintAiWithMod(battler, healAmount); // if target can kill us even after we heal, why bother } + //calculate max expected damage from the opponent + for (opponent = 0; opponent < gBattlersCount; opponent++) + { + if (GetBattlerSide(opponent) == B_SIDE_PLAYER) + { + dmg = GetBestDmgFromBattler(opponent, battler, AI_DEFENDING); + + if (dmg > maxDamage) + maxDamage = dmg; + } + } + + // also heal if a 2HKO is outhealed + if (AI_OpponentCanFaintAiWithMod(battler, 0) + && !AI_OpponentCanFaintAiWithMod(battler, healAmount) + && healAmount > 2*maxDamage) + return TRUE; + + // also heal, if the expected damage is outhealed and it's the last remaining mon + if (AI_OpponentCanFaintAiWithMod(battler, 0) + && !AI_OpponentCanFaintAiWithMod(battler, healAmount) + && CountUsablePartyMons(battler) == 0) + return TRUE; + return shouldHeal; } @@ -2386,3 +2417,28 @@ static bool32 AI_OpponentCanFaintAiWithMod(u32 battler, u32 healAmount) } return FALSE; } + +static u32 GetHPHealAmount(u8 itemEffectParam, struct Pokemon *mon) +{ + switch (itemEffectParam) + { + case ITEM6_HEAL_HP_FULL: + itemEffectParam = GetMonData(mon, MON_DATA_MAX_HP, NULL) - GetMonData(mon, MON_DATA_HP, NULL); + break; + case ITEM6_HEAL_HP_HALF: + itemEffectParam = GetMonData(mon, MON_DATA_MAX_HP, NULL) / 2; + if (itemEffectParam == 0) + itemEffectParam = 1; + break; + case ITEM6_HEAL_HP_LVL_UP: + itemEffectParam = gBattleScripting.levelUpHP; + break; + case ITEM6_HEAL_HP_QUARTER: + itemEffectParam = GetMonData(mon, MON_DATA_MAX_HP, NULL) / 4; + if (itemEffectParam == 0) + itemEffectParam = 1; + break; + } + + return itemEffectParam; +} diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index a15d8df6c6..d9a1713e32 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -174,6 +174,7 @@ void RecordKnownMove(u32 battlerId, u32 move) s32 i; for (i = 0; i < MAX_MON_MOVES; i++) { + if (BATTLE_HISTORY->usedMoves[battlerId][i] == move) break; if (BATTLE_HISTORY->usedMoves[battlerId][i] == MOVE_NONE) @@ -577,15 +578,6 @@ static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCal switch (effect) { - case EFFECT_LEVEL_DAMAGE: - median = maximum = minimum = gBattleMons[damageCalcData->battlerAtk].level; - break; - case EFFECT_PSYWAVE: - median = maximum = minimum = gBattleMons[damageCalcData->battlerAtk].level; - break; - case EFFECT_FIXED_DAMAGE_ARG: - median = maximum = minimum = GetMoveFixedDamage(move); - break; case EFFECT_MULTI_HIT: if (move == MOVE_WATER_SHURIKEN && gBattleMons[damageCalcData->battlerAtk].species == SPECIES_GRENINJA_ASH) { @@ -617,9 +609,6 @@ static inline void CalcDynamicMoveDamage(struct DamageCalculationData *damageCal // If target has less HP than user, Endeavor does no damage median = maximum = minimum = max(0, gBattleMons[damageCalcData->battlerDef].hp - gBattleMons[damageCalcData->battlerAtk].hp); break; - case EFFECT_SUPER_FANG: - median = maximum = minimum = max(1, gBattleMons[damageCalcData->battlerDef].hp / 2); - break; case EFFECT_FINAL_GAMBIT: median = maximum = minimum = gBattleMons[damageCalcData->battlerAtk].hp; break; @@ -1350,7 +1339,7 @@ bool32 CanTargetFaintAiWithMod(u32 battlerDef, u32 battlerAtk, s32 hpMod, s32 dm if (IsMoveUnusable(moveIndex, moves[moveIndex], moveLimitations)) continue; - dmg = AI_GetDamage(battlerAtk, battlerDef, moveIndex, AI_DEFENDING, aiData); + dmg = AI_GetDamage(battlerDef, battlerAtk, moveIndex, AI_DEFENDING, aiData); if (dmgMod) dmg *= dmgMod; @@ -3132,9 +3121,9 @@ static inline bool32 DoesBattlerBenefitFromAllVolatileStatus(u32 battler, u32 ab bool32 ShouldPoison(u32 battlerAtk, u32 battlerDef) { - u32 defAbility = GetBattlerAbility(battlerDef); + u32 defAbility = AI_DATA->abilities[battlerDef]; // Battler can be poisoned and has move/ability that synergizes with being poisoned - if (CanBePoisoned(battlerAtk, battlerDef, GetBattlerAbility(battlerDef)) && ( + if (CanBePoisoned(battlerAtk, battlerDef, defAbility) && ( DoesBattlerBenefitFromAllVolatileStatus(battlerDef, defAbility) || defAbility == ABILITY_POISON_HEAL || (defAbility == ABILITY_TOXIC_BOOST && HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_PHYSICAL)))) @@ -3152,7 +3141,7 @@ bool32 ShouldPoison(u32 battlerAtk, u32 battlerDef) bool32 ShouldBurn(u32 battlerAtk, u32 battlerDef) { - u32 defAbility = GetBattlerAbility(battlerDef); + u32 defAbility = AI_DATA->abilities[battlerDef]; // Battler can be burned and has move/ability that synergizes with being burned if (CanBeBurned(battlerDef, defAbility) && ( DoesBattlerBenefitFromAllVolatileStatus(battlerDef, defAbility) @@ -3186,7 +3175,7 @@ bool32 ShouldFreezeOrFrostbite(u32 battlerAtk, u32 battlerDef) } else { - u32 defAbility = GetBattlerAbility(battlerDef); + u32 defAbility = AI_DATA->abilities[battlerDef]; // Battler can be frostbitten and has move/ability that synergizes with being frostbitten if (CanBeFrozen(battlerDef) && DoesBattlerBenefitFromAllVolatileStatus(battlerDef, defAbility)) @@ -3206,7 +3195,7 @@ bool32 ShouldFreezeOrFrostbite(u32 battlerAtk, u32 battlerDef) bool32 ShouldParalyze(u32 battlerAtk, u32 battlerDef) { - u32 defAbility = GetBattlerAbility(battlerDef); + u32 defAbility = AI_DATA->abilities[battlerDef]; // Battler can be paralyzed and has move/ability that synergizes with being paralyzed if (CanBeParalyzed(battlerDef, defAbility) && ( DoesBattlerBenefitFromAllVolatileStatus(battlerDef, defAbility))) diff --git a/src/battle_anim_dragon.c b/src/battle_anim_dragon.c index 55ecd5d0c1..bf5c4d823c 100644 --- a/src/battle_anim_dragon.c +++ b/src/battle_anim_dragon.c @@ -9,6 +9,7 @@ static void AnimDragonDanceOrb_Step(struct Sprite *); static void AnimOverheatFlame_Step(struct Sprite *); static void AnimTask_DragonDanceWaver_Step(u8); static void UpdateDragonDanceScanlineEffect(struct Task *); +static void AnimDragonRush(struct Sprite *sprite); static void AnimDragonRushStep(struct Sprite *sprite); static void AnimSpinningDracoMeteor(struct Sprite *sprite); static void AnimSpinningDracoMeteorFinish(struct Sprite *sprite); @@ -304,7 +305,7 @@ const struct SpriteTemplate gDragonRushSpriteTemplate = .anims = gDragonRushAnimTable, .images = NULL, .affineAnims = gDragonRushAffineAnimTable, - .callback = AnimDragonRushStep, + .callback = AnimDragonRush, }; const struct SpriteTemplate gDracoMetorSpriteTemplate = @@ -329,6 +330,36 @@ const struct SpriteTemplate gDragonPulseSpriteTemplate = .callback = TranslateAnimSpriteToTargetMonLocation, }; +// Animates a strike that swipes downard at the target mon. +// arg 0: initial x pixel offset +// arg 1: initial y pixel offset +static void AnimDragonRush(struct Sprite *sprite) +{ + if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) + { + sprite->x -= gBattleAnimArgs[0]; + sprite->y += gBattleAnimArgs[1]; + sprite->data[0] = -11; + sprite->data[1] = 192; + StartSpriteAffineAnim(sprite, 1); + } + else + { + sprite->data[0] = 11; + sprite->data[1] = 192; + sprite->x += gBattleAnimArgs[0]; + sprite->y += gBattleAnimArgs[1]; + } + + sprite->callback = AnimDragonRushStep; +} + +// args[0] - initial x delta +// args[1] - initial y delta +// args[2] - x delta to end x +// args[3] - y delta to end y +// args[4] - num frames +// args[5] - sprite anim number static void AnimDragonRushStep(struct Sprite *sprite) { // These two cases are identical. @@ -422,6 +453,9 @@ static void StartDragonFireTranslation(struct Sprite *sprite) StoreSpriteCallbackInData6(sprite, DestroySpriteAndMatrix); } +// args[0] - attacker or target +// args[1] - initial x offset +// args[2] - initial y offset void AnimDragonRageFirePlume(struct Sprite *sprite) { if (gBattleAnimArgs[0] == 0) diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index 4162447094..8e1e39d629 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -3116,6 +3116,12 @@ const struct SpriteTemplate gChainBindingSpriteTemplate = }; // functions +// args[0] - initial x offset +// args[1] - initial y offset +// args[2] - some param to linear translation +// args[3] - some param to linear translation +// args[4] - offset that gets added to param for Sin +// args[5] - another param for Sin static void AnimGrassKnot(struct Sprite *sprite) { if (BATTLE_PARTNER(gBattleAnimAttacker) == gBattleAnimTarget && GetBattlerPosition(gBattleAnimTarget) < B_POSITION_PLAYER_RIGHT) @@ -5972,12 +5978,12 @@ static void AnimBowMon_Step1_Callback(struct Sprite *sprite) { sprite->data[3] = gBattlerSpriteIds[gBattleAnimAttacker]; PrepareBattlerSpriteForRotScale(sprite->data[3], ST_OAM_OBJ_NORMAL); - sprite->data[4] = (sprite->data[6] = GetBattlerSide(gBattleAnimAttacker)) ? 0x300 : 0xFFFFFD00; + sprite->data[4] = (sprite->data[6] = GetBattlerSide(gBattleAnimAttacker)) ? 768 : -768; sprite->data[5] = 0; } sprite->data[5] += sprite->data[4]; - SetSpriteRotScale(sprite->data[3], 0x100, 0x100, sprite->data[5]); + SetSpriteRotScale(sprite->data[3], 256, 256, sprite->data[5]); SetBattlerSpriteYOffsetFromRotation(sprite->data[3]); if (++sprite->data[0] > 3) { @@ -6463,6 +6469,8 @@ static void UNUSED AnimTask_ShowBattlersHealthbox(u8 taskId) DestroyAnimVisualTask(taskId); } +// args[0] - sprite x +// args[1] - sprite y static void AnimMoon(struct Sprite *sprite) { if (IsContest()) diff --git a/src/battle_anim_effects_2.c b/src/battle_anim_effects_2.c index e751a1ca51..c4d0a33fac 100755 --- a/src/battle_anim_effects_2.c +++ b/src/battle_anim_effects_2.c @@ -3133,6 +3133,8 @@ static void AnimHealBellMusicNote(struct Sprite *sprite) SetMusicNotePalette(sprite, gBattleAnimArgs[5], gBattleAnimArgs[6]); } +// args[0] - initial x offset +// args[1] - initial y offset void AnimMagentaHeart(struct Sprite *sprite) { if (++sprite->data[0] == 1) diff --git a/src/battle_anim_electric.c b/src/battle_anim_electric.c index 59cd017b9a..bd010797a1 100644 --- a/src/battle_anim_electric.c +++ b/src/battle_anim_electric.c @@ -657,13 +657,13 @@ static void AnimUnusedCirclingShock(struct Sprite *sprite) sprite->callback = TranslateSpriteInCircle; } -// arg 0: -// arg 1: -// arg 2: +// arg 0: index to sine table +// arg 1: something multiplied with +// arg 2: index to sine table // arg 3: duration // arg 4: target -// arg 5: -// arg 6: +// arg 5: 0 or non-0 determines which set of battler sprite coords to use +// arg 6: increase battler sprite priority by 1 void AnimSparkElectricity(struct Sprite *sprite) { u8 battler; diff --git a/src/battle_anim_fire.c b/src/battle_anim_fire.c index b67304e05e..7f89fb7d1d 100644 --- a/src/battle_anim_fire.c +++ b/src/battle_anim_fire.c @@ -572,6 +572,11 @@ static void AnimFireSpiralInward(struct Sprite *sprite) } // For the impact spread of fire sprites for moves like Blaze Kick or Fire Punch +// args[0] - delta to mon x offset +// args[1] - delta to mon y offset +// args[2] - x increment +// args[3] - y increment +// args[4] - duration void AnimFireSpread(struct Sprite *sprite) { SetAnimSpriteInitialXOffset(sprite, gBattleAnimArgs[0]); diff --git a/src/battle_anim_flying.c b/src/battle_anim_flying.c index 8b613ad677..a4b37389ed 100644 --- a/src/battle_anim_flying.c +++ b/src/battle_anim_flying.c @@ -1027,6 +1027,10 @@ void AnimBounceBallLand(struct Sprite *sprite) } } +// args[0] - initial x offset +// args[1] - initial y offset +// args[2] - initial delay before anim +// args[3] - quadratic delta to sprite y static void AnimDiveBall(struct Sprite *sprite) { InitSpritePosToAnimAttacker(sprite, TRUE); @@ -1066,6 +1070,7 @@ static void AnimDiveBall_Step2(struct Sprite *sprite) DestroyAnimSprite(sprite); } +// args[0] - attacker or target static void AnimDiveWaterSplash(struct Sprite *sprite) { u32 matrixNum; diff --git a/src/battle_anim_mon_movement.c b/src/battle_anim_mon_movement.c index 0bacd96219..e8ce92677c 100644 --- a/src/battle_anim_mon_movement.c +++ b/src/battle_anim_mon_movement.c @@ -1173,6 +1173,11 @@ void SetupShakeBattlerBasedOnMovePowerOrDmg(u8 taskId, u8 animBattlerId) gTasks[taskId].data[2] = gBattleAnimArgs[2]; } +// args[0] - 0 if scale on move power, 1 if scale on move damage +// args[1] - delay before starting anim +// args[2] - duration of anim (after anim starts from above counter) +// args[3] - 1 if do horizontal shake +// args[4] - 1 if do vertical shake void AnimTask_ShakeTargetPartnerBasedOnMovePowerOrDmg(u8 taskId) { SetupShakeBattlerBasedOnMovePowerOrDmg(taskId, ANIM_DEF_PARTNER); diff --git a/src/battle_anim_mons.c b/src/battle_anim_mons.c index 13b1cf834f..af38afc814 100644 --- a/src/battle_anim_mons.c +++ b/src/battle_anim_mons.c @@ -1429,6 +1429,9 @@ static u8 UNUSED GetSpritePalIdxByPosition(u8 position) return GetBattlerAtPosition(position); } +// gBattleAnimArgs 0-3 used +// 0, 1 used for position +// 2, 3 as some control variables void AnimSpriteOnMonPos(struct Sprite *sprite) { bool8 var; @@ -1698,6 +1701,11 @@ static void AnimTask_BlendMonInAndOut_Step(u8 taskId) } // See AnimTask_BlendMonInAndOut. Same, but ANIM_TAG_* instead of mon +// args[0] - tag +// arg 1: blend color +// arg 2: target blend coefficient +// arg 3: initial delay +// arg 4: number of times to blend in and out void AnimTask_BlendPalInAndOutByTag(u8 task) { u8 palette = IndexOfSpritePaletteTag(gBattleAnimArgs[0]); diff --git a/src/battle_anim_normal.c b/src/battle_anim_normal.c index d9fc8aa412..a8a6417d6e 100644 --- a/src/battle_anim_normal.c +++ b/src/battle_anim_normal.c @@ -1045,6 +1045,10 @@ static void AnimTask_ShakeBattleTerrain_Step(u8 taskId) #undef tTimer #undef tShakeDelay +// args[0] - initial pos x +// args[1] - initial pos y +// args[2] - which battler +// args[3] - affine anim number void AnimHitSplatBasic(struct Sprite *sprite) { StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]); diff --git a/src/battle_anim_poison.c b/src/battle_anim_poison.c index 301cdd4643..a75ce87087 100644 --- a/src/battle_anim_poison.c +++ b/src/battle_anim_poison.c @@ -415,11 +415,15 @@ const struct SpriteTemplate gSyrupBombYellowShellBSpriteTemplate = .callback = AnimAnimSyrupBomb, }; +// args[0] - initial x +// args[1] - initial y +// args[2] - attacker or target +// args[3] - affine anim number static void AnimGunkShotImpact(struct Sprite *sprite) { StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]); if (gBattleAnimArgs[2] == 0) - InitSpritePosToAnimAttacker(sprite, 1); + InitSpritePosToAnimAttacker(sprite, TRUE); else InitSpritePosToAnimTarget(sprite, TRUE); @@ -427,6 +431,10 @@ static void AnimGunkShotImpact(struct Sprite *sprite) StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); } +// args[0] - initial attacker x +// args[1] - initial attacker y +// args[2] - ??? +// args[3] - some param static void AnimGunkShotParticles(struct Sprite *sprite) { u16 retArg; diff --git a/src/battle_anim_rock.c b/src/battle_anim_rock.c index 0aaf5f1609..dcdb2a8965 100644 --- a/src/battle_anim_rock.c +++ b/src/battle_anim_rock.c @@ -476,6 +476,13 @@ void AnimRockFragment(struct Sprite *sprite) } // Swirls particle in vortex. Used for moves like Fire Spin or Sand Tomb +// args[0] - initial x offset +// args[1] - initial y offset +// args[2] - y increment +// args[3] - duration +// args[4] - increments some sin parameter +// args[5] - fixed sin parameter +// args[6] - attacker or target void AnimParticleInVortex(struct Sprite *sprite) { if (IsDoubleBattle() diff --git a/src/battle_anim_utility_funcs.c b/src/battle_anim_utility_funcs.c index 47642b9fce..f43f13b748 100644 --- a/src/battle_anim_utility_funcs.c +++ b/src/battle_anim_utility_funcs.c @@ -722,6 +722,10 @@ void AnimTask_BlendNonAttackerPalettes(u8 taskId) StartBlendAnimSpriteColor(taskId, selectedPalettes); } +// gBattleAnimArgs[0] - initial x +// gBattleAnimArgs[1] - initial y +// gBattleAnimArgs[2] - negative? +// gBattleAnimArgs[3] - sentinel value to compare to void AnimTask_StartSlidingBg(u8 taskId) { u8 newTaskId; diff --git a/src/battle_anim_water.c b/src/battle_anim_water.c index 57053ef043..39be71c6b5 100644 --- a/src/battle_anim_water.c +++ b/src/battle_anim_water.c @@ -606,6 +606,10 @@ const struct SpriteTemplate gSparkBeamSpriteTemplate = .callback = AnimToTargetInSinWave, }; +// args[0] - initial sprite x +// args[1] - initial sprite y +// args[2] - attacker or target +// args[3] - affine anim number static void AnimAquaTail(struct Sprite *sprite) { StartSpriteAffineAnim(sprite, gBattleAnimArgs[3]); @@ -618,6 +622,8 @@ static void AnimAquaTail(struct Sprite *sprite) StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); } +// args[0] - initial x delta +// args[1] - initial y delta static void AnimKnockOffAquaTail(struct Sprite *sprite) { if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER) @@ -885,6 +891,7 @@ static void AnimToTargetInSinWave_Step(struct Sprite *sprite) } } +// args[0] - duration void AnimTask_StartSinAnimTimer(u8 taskId) { gTasks[taskId].data[0] = gBattleAnimArgs[0]; @@ -975,6 +982,10 @@ static void AnimWaterGunDroplet(struct Sprite *sprite) StoreSpriteCallbackInData6(sprite, DestroyAnimSprite); } +// args[0] - initial sprite x +// args[1] - initial sprite y +// args[2] - counter +// args[3] - attacker or target void AnimSmallBubblePair(struct Sprite *sprite) { if (gBattleAnimArgs[3] != ANIM_ATTACKER) diff --git a/src/battle_controller_player.c b/src/battle_controller_player.c index 96f3e6b67d..cd69f2ab1a 100644 --- a/src/battle_controller_player.c +++ b/src/battle_controller_player.c @@ -46,6 +46,7 @@ #include "menu.h" #include "pokemon_summary_screen.h" #include "type_icons.h" +#include "pokedex.h" static void PlayerBufferExecCompleted(u32 battler); static void PlayerHandleLoadMonSprite(u32 battler); @@ -99,6 +100,9 @@ static void Task_UpdateLvlInHealthbox(u8); static void PrintLinkStandbyMsg(void); static void ReloadMoveNames(u32 battler); +static u32 CheckTypeEffectiveness(u32 targetId, u32 battler); +static u32 CheckTargetTypeEffectiveness(u32 battler); +static void MoveSelectionDisplayMoveEffectiveness(u32 foeEffectiveness, u32 battler); static void (*const sPlayerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) = { @@ -502,6 +506,8 @@ void HandleInputChooseTarget(u32 battler) i++; break; } + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTypeEffectiveness(GetBattlerPosition(gMultiUsePlayerCursor), battler), battler); if (gAbsentBattlerFlags & (1u << gMultiUsePlayerCursor) || !CanTargetBattler(battler, gMultiUsePlayerCursor, move) @@ -551,6 +557,8 @@ void HandleInputChooseTarget(u32 battler) i++; break; } + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTypeEffectiveness(GetBattlerPosition(gMultiUsePlayerCursor), battler), battler); if (gAbsentBattlerFlags & (1u << gMultiUsePlayerCursor) || !CanTargetBattler(battler, gMultiUsePlayerCursor, move) @@ -749,6 +757,8 @@ void HandleInputChooseMove(u32 battler) gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); else gMultiUsePlayerCursor = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTypeEffectiveness(GetBattlerPosition(gMultiUsePlayerCursor), battler), battler); gSprites[gBattlerSpriteIds[gMultiUsePlayerCursor]].callback = SpriteCB_ShowAsMoveTarget; break; @@ -785,6 +795,8 @@ void HandleInputChooseMove(u32 battler) gMoveSelectionCursor[battler] ^= 1; PlaySE(SE_SELECT); MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTargetTypeEffectiveness(battler), battler); MoveSelectionDisplayPpNumber(battler); MoveSelectionDisplayMoveType(battler); TryMoveSelectionDisplayMoveDescription(battler); @@ -800,6 +812,8 @@ void HandleInputChooseMove(u32 battler) gMoveSelectionCursor[battler] ^= 1; PlaySE(SE_SELECT); MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTargetTypeEffectiveness(battler), battler); MoveSelectionDisplayPpNumber(battler); MoveSelectionDisplayMoveType(battler); TryMoveSelectionDisplayMoveDescription(battler); @@ -814,6 +828,8 @@ void HandleInputChooseMove(u32 battler) gMoveSelectionCursor[battler] ^= 2; PlaySE(SE_SELECT); MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTargetTypeEffectiveness(battler), battler); MoveSelectionDisplayPpNumber(battler); MoveSelectionDisplayMoveType(battler); TryMoveSelectionDisplayMoveDescription(battler); @@ -829,6 +845,8 @@ void HandleInputChooseMove(u32 battler) gMoveSelectionCursor[battler] ^= 2; PlaySE(SE_SELECT); MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTargetTypeEffectiveness(battler), battler); MoveSelectionDisplayPpNumber(battler); MoveSelectionDisplayMoveType(battler); TryMoveSelectionDisplayMoveDescription(battler); @@ -866,6 +884,8 @@ void HandleInputChooseMove(u32 battler) ClearStdWindowAndFrame(B_WIN_MOVE_DESCRIPTION, FALSE); CopyWindowToVram(B_WIN_MOVE_DESCRIPTION, COPYWIN_GFX); PlaySE(SE_SELECT); + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTargetTypeEffectiveness(battler), battler); MoveSelectionDisplayPpNumber(battler); MoveSelectionDisplayMoveType(battler); } @@ -900,6 +920,8 @@ static void ReloadMoveNames(u32 battler) MoveSelectionDestroyCursorAt(battler); MoveSelectionDisplayMoveNames(battler); MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTargetTypeEffectiveness(battler), battler); MoveSelectionDisplayPpNumber(battler); MoveSelectionDisplayMoveType(battler); } @@ -1052,7 +1074,10 @@ void HandleMoveSwitching(u32 battler) gBattlerControllerFuncs[battler] = HandleInputChooseMove; gMoveSelectionCursor[battler] = gMultiUsePlayerCursor; MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); - MoveSelectionDisplayPpString(battler); + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTargetTypeEffectiveness(battler), battler); + else + MoveSelectionDisplayPpString(battler); MoveSelectionDisplayPpNumber(battler); MoveSelectionDisplayMoveType(battler); AssignUsableZMoves(battler, moveInfo->moves); @@ -1063,7 +1088,10 @@ void HandleMoveSwitching(u32 battler) MoveSelectionDestroyCursorAt(gMultiUsePlayerCursor); MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); gBattlerControllerFuncs[battler] = HandleInputChooseMove; - MoveSelectionDisplayPpString(battler); + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTargetTypeEffectiveness(battler), battler); + else + MoveSelectionDisplayPpString(battler); MoveSelectionDisplayPpNumber(battler); MoveSelectionDisplayMoveType(battler); } @@ -1425,11 +1453,13 @@ static void Task_GiveExpToMon(u8 taskId) u8 level = GetMonData(mon, MON_DATA_LEVEL); u32 currExp = GetMonData(mon, MON_DATA_EXP); u32 nextLvlExp = gExperienceTables[gSpeciesInfo[species].growthRate][level + 1]; + u32 expAfterGain = currExp + gainedExp; u32 oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP); - if (currExp + gainedExp >= nextLvlExp) + if (expAfterGain >= nextLvlExp) { - SetMonData(mon, MON_DATA_EXP, &nextLvlExp); + SetMonData(mon, MON_DATA_EXP, (B_LEVEL_UP_NOTIFICATION >= GEN_9) ? &expAfterGain : &nextLvlExp); + CalculateMonStats(mon); // Reapply Dynamax HP multiplier after stats are recalculated. @@ -1437,7 +1467,7 @@ static void Task_GiveExpToMon(u8 taskId) DynamaxModifyHPLevelUp(mon, battler, oldMaxHP); gainedExp -= nextLvlExp - currExp; - BtlController_EmitTwoReturnValues(battler, BUFFER_B, RET_VALUE_LEVELED_UP, gainedExp); + BtlController_EmitTwoReturnValues(battler, BUFFER_B, RET_VALUE_LEVELED_UP, (B_LEVEL_UP_NOTIFICATION >= GEN_9) ? 0 : gainedExp); if (IsDoubleBattle() == TRUE && (monId == gBattlerPartyIndexes[battler] || monId == gBattlerPartyIndexes[BATTLE_PARTNER(battler)])) @@ -1481,7 +1511,7 @@ static void Task_PrepareToGiveExpWithExpBar(u8 taskId) static void Task_GiveExpWithExpBar(u8 taskId) { - u8 level; + u32 level, expAfterGain; u16 species; u32 oldMaxHP; s32 currExp, expOnNextLvl, newExpPoints; @@ -1508,9 +1538,14 @@ static void Task_GiveExpWithExpBar(u8 taskId) oldMaxHP = GetMonData(mon, MON_DATA_MAX_HP); expOnNextLvl = gExperienceTables[gSpeciesInfo[species].growthRate][level + 1]; - if (currExp + gainedExp >= expOnNextLvl) + expAfterGain = currExp + gainedExp; + if (expAfterGain >= expOnNextLvl) { - SetMonData(mon, MON_DATA_EXP, &expOnNextLvl); + if (B_LEVEL_UP_NOTIFICATION >= GEN_9) + SetMonData(mon, MON_DATA_EXP, &expAfterGain); + else + SetMonData(mon, MON_DATA_EXP, &expOnNextLvl); + CalculateMonStats(mon); // Reapply Dynamax HP multiplier after stats are recalculated. @@ -1518,7 +1553,7 @@ static void Task_GiveExpWithExpBar(u8 taskId) DynamaxModifyHPLevelUp(mon, battler, oldMaxHP); gainedExp -= expOnNextLvl - currExp; - BtlController_EmitTwoReturnValues(battler, BUFFER_B, RET_VALUE_LEVELED_UP, gainedExp); + BtlController_EmitTwoReturnValues(battler, BUFFER_B, RET_VALUE_LEVELED_UP, (B_LEVEL_UP_NOTIFICATION >= GEN_9) ? 0 : gainedExp); gTasks[taskId].func = Task_LaunchLvlUpAnim; } else @@ -2152,7 +2187,10 @@ void InitMoveSelectionsVarsAndStrings(u32 battler) MoveSelectionDisplayMoveNames(battler); gMultiUsePlayerCursor = 0xFF; MoveSelectionCreateCursorAt(gMoveSelectionCursor[battler], 0); - MoveSelectionDisplayPpString(battler); + if (B_SHOW_EFFECTIVENESS) + MoveSelectionDisplayMoveEffectiveness(CheckTargetTypeEffectiveness(battler), battler); + else + MoveSelectionDisplayPpString(battler); MoveSelectionDisplayPpNumber(battler); MoveSelectionDisplayMoveType(battler); } @@ -2386,3 +2424,100 @@ static void PlayerHandleBattleDebug(u32 battler) SetMainCallback2(CB2_BattleDebugMenu); gBattlerControllerFuncs[battler] = Controller_WaitForDebug; } + +// Order based numerically, with EFFECTIVENESS_CANNOT_VIEW at 0 to always prioritize any other effectiveness during comparison +enum +{ + EFFECTIVENESS_CANNOT_VIEW, + EFFECTIVENESS_NO_EFFECT, + EFFECTIVENESS_NOT_VERY_EFFECTIVE, + EFFECTIVENESS_NORMAL, + EFFECTIVENESS_SUPER_EFFECTIVE, +}; + +static bool32 ShouldShowTypeEffectiveness(u32 targetId) +{ + if (B_SHOW_EFFECTIVENESS == SHOW_EFFECTIVENESS_CAUGHT) + return GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[targetId].species), FLAG_GET_CAUGHT); + + if (B_SHOW_EFFECTIVENESS == SHOW_EFFECTIVENESS_SEEN) + return GetSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[targetId].species), FLAG_GET_SEEN); + + return TRUE; +} + +static u32 CheckTypeEffectiveness(u32 targetId, u32 battler) +{ + struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); + struct Pokemon *mon = &gPlayerParty[gBattlerPartyIndexes[battler]]; + u32 move = moveInfo->moves[gMoveSelectionCursor[battler]]; + u32 moveType = CheckDynamicMoveType(mon, move, battler); + uq4_12_t modifier = CalcTypeEffectivenessMultiplier(move, moveType, battler, targetId, GetBattlerAbility(targetId), FALSE); + + if (!ShouldShowTypeEffectiveness(targetId)) + return EFFECTIVENESS_CANNOT_VIEW; + + if (modifier == UQ_4_12(0.0)) + return EFFECTIVENESS_NO_EFFECT; // No effect + else if (modifier <= UQ_4_12(0.5)) + return EFFECTIVENESS_NOT_VERY_EFFECTIVE; // Not very effective + else if (modifier >= UQ_4_12(2.0)) + return EFFECTIVENESS_SUPER_EFFECTIVE; // Super effective + return EFFECTIVENESS_NORMAL; // Normal effectiveness +} + +static u32 CheckTargetTypeEffectiveness(u32 battler) +{ + u32 battlerFoe = BATTLE_OPPOSITE(GetBattlerPosition(battler)); + u32 foeEffectiveness = CheckTypeEffectiveness(battlerFoe, battler); + + if (IsDoubleBattle()) + { + u32 partnerFoe = BATTLE_PARTNER(battlerFoe); + u32 partnerFoeEffectiveness = CheckTypeEffectiveness(partnerFoe, battler); + if (!IsBattlerAlive(battlerFoe)) + return partnerFoeEffectiveness; + if (IsBattlerAlive(battlerFoe) && IsBattlerAlive(partnerFoe) + && partnerFoeEffectiveness > foeEffectiveness) + return partnerFoeEffectiveness; + } + return foeEffectiveness; // fallthrough for any other circumstance +} + +static void MoveSelectionDisplayMoveEffectiveness(u32 foeEffectiveness, u32 battler) +{ + static const u8 noIcon[] = _(""); + static const u8 effectiveIcon[] = _("{CIRCLE_HOLLOW}"); + static const u8 superEffectiveIcon[] = _("{CIRCLE_DOT}"); + static const u8 notVeryEffectiveIcon[] = _("{TRIANGLE}"); + static const u8 immuneIcon[] = _("{BIG_MULT_X}"); + struct ChooseMoveStruct *moveInfo = (struct ChooseMoveStruct *)(&gBattleResources->bufferA[battler][4]); + u8 *txtPtr; + + txtPtr = StringCopy(gDisplayedStringBattle, gText_MoveInterfacePP); + + if (!IsBattleMoveStatus(moveInfo->moves[gMoveSelectionCursor[battler]])) + { + switch (foeEffectiveness) + { + case EFFECTIVENESS_SUPER_EFFECTIVE: + StringCopy(txtPtr, superEffectiveIcon); + break; + case EFFECTIVENESS_NOT_VERY_EFFECTIVE: + StringCopy(txtPtr, notVeryEffectiveIcon); + break; + case EFFECTIVENESS_NO_EFFECT: + StringCopy(txtPtr, immuneIcon); + break; + case EFFECTIVENESS_NORMAL: + StringCopy(txtPtr, effectiveIcon); + break; + default: + case EFFECTIVENESS_CANNOT_VIEW: + StringCopy(txtPtr, noIcon); + break; + } + } + + BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_PP); +} diff --git a/src/battle_gimmick.c b/src/battle_gimmick.c index 0b725811ee..4cdc754ea4 100644 --- a/src/battle_gimmick.c +++ b/src/battle_gimmick.c @@ -265,20 +265,9 @@ static void SpriteCb_GimmickTrigger(struct Sprite *sprite) void LoadIndicatorSpritesGfx(void) { - u32 gimmick; - for (gimmick = 0; gimmick < GIMMICKS_COUNT; ++gimmick) - { - if (gimmick == GIMMICK_TERA) // special case - LoadSpriteSheets(sTeraIndicatorSpriteSheets); - else if (gGimmicksInfo[gimmick].indicatorSheet != NULL) - LoadSpriteSheet(gGimmicksInfo[gimmick].indicatorSheet); - - if (gGimmicksInfo[gimmick].indicatorPal != NULL) - LoadSpritePalette(gGimmicksInfo[gimmick].indicatorPal); - } - // Primal reversion graphics aren't loaded as part of gimmick data - LoadSpriteSheet(&sSpriteSheet_AlphaIndicator); - LoadSpriteSheet(&sSpriteSheet_OmegaIndicator); + LoadSpritePalette(&sSpritePalette_MiscIndicator); + LoadSpritePalette(&sSpritePalette_MegaIndicator); + LoadSpritePalette(&sSpritePalette_TeraIndicator); } static void SpriteCb_GimmickIndicator(struct Sprite *sprite) @@ -295,28 +284,28 @@ static inline u32 GetIndicatorSpriteId(u32 healthboxId) return gBattleStruct->gimmick.indicatorSpriteId[gSprites[healthboxId].hMain_Battler]; } -u32 GetIndicatorTileTag(u32 battler) +const u32 *GetIndicatorSpriteSrc(u32 battler) { u32 gimmick = GetActiveGimmick(battler); if (IsBattlerPrimalReverted(battler)) { if (gBattleMons[battler].species == SPECIES_GROUDON_PRIMAL) - return TAG_OMEGA_INDICATOR_TILE; + return (u32 *)&sOmegaIndicatorGfx; else - return TAG_ALPHA_INDICATOR_TILE; + return (u32 *)&sAlphaIndicatorGfx; } else if (gimmick == GIMMICK_TERA) // special case { - return sTeraIndicatorSpriteSheets[GetBattlerTeraType(battler)].tag; + return (u32 *)sTeraIndicatorDataPtrs[GetBattlerTeraType(battler)]; } - else if (gGimmicksInfo[gimmick].indicatorSheet != NULL) + else if (gGimmicksInfo[gimmick].indicatorData != NULL) { - return gGimmicksInfo[gimmick].indicatorSheet->tag; + return (u32 *)gGimmicksInfo[gimmick].indicatorData; } else { - return TAG_NONE; + return NULL; } } @@ -325,27 +314,34 @@ u32 GetIndicatorPalTag(u32 battler) u32 gimmick = GetActiveGimmick(battler); if (IsBattlerPrimalReverted(battler)) return TAG_MISC_INDICATOR_PAL; - else if (gGimmicksInfo[gimmick].indicatorPal != NULL) - return gGimmicksInfo[gimmick].indicatorPal->tag; + else if (gGimmicksInfo[gimmick].indicatorPalTag != 0) + return gGimmicksInfo[gimmick].indicatorPalTag; else return TAG_NONE; } +#define INDICATOR_SIZE (8 * 16 / 2) + void UpdateIndicatorVisibilityAndType(u32 healthboxId, bool32 invisible) { u32 battler = gSprites[healthboxId].hMain_Battler; - u32 tileTag = GetIndicatorTileTag(battler); u32 palTag = GetIndicatorPalTag(battler); struct Sprite *sprite = &gSprites[GetIndicatorSpriteId(healthboxId)]; if (GetIndicatorSpriteId(healthboxId) == 0) // safari zone means the player doesn't have an indicator sprite id return; - if (tileTag != TAG_NONE && palTag != TAG_NONE) + if (palTag != TAG_NONE) { - sprite->oam.tileNum = GetSpriteTileStartByTag(tileTag); sprite->oam.paletteNum = IndexOfSpritePaletteTag(palTag); sprite->invisible = invisible; + + u32 *dst = (u32 *)(OBJ_VRAM0 + TILE_SIZE_4BPP * GetSpriteTileStartByTag(BATTLER_INDICATOR_TAG + battler)); + + const u32 *src = GetIndicatorSpriteSrc(battler); + + for (u32 i = 0; i < INDICATOR_SIZE / 4; i++) + dst[i] = src[i]; } else // in case of error { @@ -353,6 +349,8 @@ void UpdateIndicatorVisibilityAndType(u32 healthboxId, bool32 invisible) } } +#undef INDICATOR_SIZE + void UpdateIndicatorOamPriority(u32 healthboxId, u32 oamPriority) { gSprites[GetIndicatorSpriteId(healthboxId)].oam.priority = oamPriority; @@ -389,7 +387,8 @@ void CreateIndicatorSprite(u32 battler) x = sIndicatorPositions[position][0]; y += sIndicatorPositions[position][1]; - spriteId = CreateSpriteAtEnd(&sSpriteTemplate_GimmickIndicator, 0, y, 0); + LoadSpriteSheet(&sBattler_GimmickSpritesheets[battler]); + spriteId = CreateSprite(&(sSpriteTemplate_BattlerIndicators[battler]), 0, y, 0); gBattleStruct->gimmick.indicatorSpriteId[battler] = spriteId; gSprites[spriteId].tBattler = battler; gSprites[spriteId].tPosX = x; diff --git a/src/battle_interface.c b/src/battle_interface.c index d20848f321..1f85e68eea 100644 --- a/src/battle_interface.c +++ b/src/battle_interface.c @@ -922,7 +922,7 @@ static void UpdateLvlInHealthbox(u8 healthboxSpriteId, u8 lvl) u8 battler = gSprites[healthboxSpriteId].hMain_Battler; // Don't print Lv char if mon has a gimmick with an indicator active. - if (GetIndicatorTileTag(battler) != TAG_NONE) + if (GetIndicatorPalTag(battler) != TAG_NONE) { objVram = ConvertIntToDecimalStringN(text, lvl, STR_CONV_MODE_LEFT_ALIGN, 3); xPos = 5 * (3 - (objVram - (text + 2))) - 1; diff --git a/src/battle_main.c b/src/battle_main.c index d9e811014b..acc6e6f454 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3696,19 +3696,6 @@ static void DoBattleIntro(void) case BATTLE_INTRO_STATE_SET_DEX_AND_BATTLE_VARS: if (!gBattleControllerExecFlags) { - for (battler = 0; battler < gBattlersCount; battler++) - { - if (GetBattlerSide(battler) == B_SIDE_OPPONENT - && !(gBattleTypeFlags & (BATTLE_TYPE_EREADER_TRAINER - | BATTLE_TYPE_FRONTIER - | BATTLE_TYPE_LINK - | BATTLE_TYPE_RECORDED_LINK - | BATTLE_TYPE_TRAINER_HILL))) - { - HandleSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[battler].species), FLAG_SET_SEEN, gBattleMons[battler].personality); - } - } - gBattleStruct->eventsBeforeFirstTurnState = 0; gBattleStruct->switchInBattlerCounter = 0; gBattleStruct->overworldWeatherDone = FALSE; @@ -4230,6 +4217,15 @@ static void HandleTurnActionSelectionState(void) gChosenActionByBattler[battler] = B_ACTION_NOTHING_FAINTED; // Not fainted, but it cannot move, because of the throwing ball. gBattleCommunication[battler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY; } + else if (B_RUN_TRAINER_BATTLE + && gBattleTypeFlags & BATTLE_TYPE_DOUBLE + && position == B_POSITION_PLAYER_RIGHT + && gChosenActionByBattler[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)] == B_ACTION_RUN + && gChosenActionByBattler[GetBattlerAtPosition(B_POSITION_PLAYER_LEFT)] != B_ACTION_NOTHING_FAINTED) + { + gChosenActionByBattler[battler] = B_ACTION_USE_MOVE; + gBattleCommunication[battler] = STATE_WAIT_ACTION_CONFIRMED_STANDBY; + } else { gBattleStruct->itemPartyIndex[battler] = PARTY_SIZE; @@ -4413,9 +4409,17 @@ static void HandleTurnActionSelectionState(void) gBattleStruct->stateIdAfterSelScript[battler] = STATE_BEFORE_ACTION_CHOSEN; return; } + else if (CanPlayerForfeitNormalTrainerBattle() && gBattleResources->bufferB[battler][1] == B_ACTION_RUN) + { + gSelectionBattleScripts[battler] = BattleScript_QuestionForfeitBattle; + gBattleCommunication[battler] = STATE_SELECTION_SCRIPT_MAY_RUN; + gBattleStruct->selectionScriptFinished[battler] = FALSE; + gBattleStruct->stateIdAfterSelScript[battler] = STATE_BEFORE_ACTION_CHOSEN; + return; + } else if (gBattleTypeFlags & BATTLE_TYPE_TRAINER - && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK)) - && gBattleResources->bufferB[battler][1] == B_ACTION_RUN) + && !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK)) + && gBattleResources->bufferB[battler][1] == B_ACTION_RUN) { BattleScriptExecute(BattleScript_PrintCantRunFromTrainer); gBattleCommunication[battler] = STATE_BEFORE_ACTION_CHOSEN; @@ -5492,6 +5496,11 @@ static void HandleEndTurn_RanFromBattle(void) gBattlescriptCurrInstr = BattleScript_PrintPlayerForfeited; gBattleOutcome = B_OUTCOME_FORFEITED; } + else if (CanPlayerForfeitNormalTrainerBattle()) + { + gBattlescriptCurrInstr = BattleScript_ForfeitBattleGaveMoney; + gBattleOutcome = B_OUTCOME_FORFEITED; + } else { switch (gProtectStructs[gBattlerAttacker].fleeType) @@ -5550,6 +5559,10 @@ static void HandleEndTurn_FinishBattle(void) GetMonData(&gPlayerParty[gBattlerPartyIndexes[battler]], MON_DATA_NICKNAME, gBattleResults.playerMon2Name); } } + else if (GetBattlerSide(battler) == B_SIDE_OPPONENT) + { + HandleSetPokedexFlag(SpeciesToNationalPokedexNum(gBattleMons[battler].species), FLAG_SET_SEEN, gBattleMons[battler].personality); + } } TryPutPokemonTodayOnAir(); } @@ -6114,3 +6127,25 @@ static s32 Factorial(s32 n) f *= i; return f; } + +bool32 CanPlayerForfeitNormalTrainerBattle(void) +{ + if (!B_RUN_TRAINER_BATTLE) + return FALSE; + + if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER) + return FALSE; + + if (gBattleTypeFlags & BATTLE_TYPE_RECORDED_INVALID) + return FALSE; + + return (gBattleTypeFlags & BATTLE_TYPE_TRAINER); +} + +bool32 DidPlayerForfeitNormalTrainerBattle(void) +{ + if (!CanPlayerForfeitNormalTrainerBattle()) + return FALSE; + + return (gBattleOutcome == B_OUTCOME_FORFEITED); +} diff --git a/src/battle_message.c b/src/battle_message.c index ccc6ff8963..2887e1512e 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -896,6 +896,8 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] = [STRINGID_PKMNGIGANTAMAXED] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} grew huge\ninto its Gigantamax form!"), [STRINGID_TIMETODYNAMAX] = COMPOUND_STRING("Time to Dynamax!"), [STRINGID_TIMETOGIGANTAMAX] = COMPOUND_STRING("Time to Gigantamax!"), + [STRINGID_QUESTIONFORFEITBATTLE] = COMPOUND_STRING("Would you like to give up on this battle and quit now? Quitting the battle is the same as losing the battle."), + [STRINGID_FORFEITBATTLEGAVEMONEY] = COMPOUND_STRING("You gave ¥{B_BUFF1} to the winner…{PAUSE_UNTIL_PRESS}"), }; const u16 gTrainerUsedItemStringIds[] = @@ -1633,9 +1635,9 @@ static const struct BattleWindowText sTextOnWindowsInfo_Normal[] = .x = 0, .y = 1, .speed = 0, - .fgColor = 12, + .fgColor = B_SHOW_EFFECTIVENESS != SHOW_EFFECTIVENESS_NEVER ? 13 : 12, .bgColor = 14, - .shadowColor = 11, + .shadowColor = B_SHOW_EFFECTIVENESS != SHOW_EFFECTIVENESS_NEVER ? 15 : 11, }, [B_WIN_DUMMY] = { .fillValue = PIXEL_FILL(0xE), @@ -1885,9 +1887,9 @@ static const struct BattleWindowText sTextOnWindowsInfo_Arena[] = .x = 0, .y = 1, .speed = 0, - .fgColor = 12, + .fgColor = B_SHOW_EFFECTIVENESS != SHOW_EFFECTIVENESS_NEVER ? 13 : 12, .bgColor = 14, - .shadowColor = 11, + .shadowColor = B_SHOW_EFFECTIVENESS != SHOW_EFFECTIVENESS_NEVER ? 15 : 11, }, [B_WIN_DUMMY] = { .fillValue = PIXEL_FILL(0xE), diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d5c64a57ed..671203448b 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -494,7 +494,7 @@ static void Cmd_tryconversiontypechange(void); static void Cmd_givepaydaymoney(void); static void Cmd_setlightscreen(void); static void Cmd_tryKO(void); -static void Cmd_damagetohalftargethp(void); +static void Cmd_unused_0x94(void); static void Cmd_copybidedmg(void); static void Cmd_unused_96(void); static void Cmd_tryinfatuating(void); @@ -505,8 +505,8 @@ static void Cmd_transformdataexecution(void); static void Cmd_setsubstitute(void); static void Cmd_mimicattackcopy(void); static void Cmd_metronome(void); -static void Cmd_dmgtolevel(void); -static void Cmd_psywavedamageeffect(void); +static void Cmd_unused_0x9f(void); +static void Cmd_unused_0xA0(void); static void Cmd_counterdamagecalculator(void); static void Cmd_mirrorcoatdamagecalculator(void); static void Cmd_disablelastusedattack(void); @@ -753,7 +753,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = Cmd_givepaydaymoney, //0x91 Cmd_setlightscreen, //0x92 Cmd_tryKO, //0x93 - Cmd_damagetohalftargethp, //0x94 + Cmd_unused_0x94, //0x94 Cmd_copybidedmg, //0x95 Cmd_unused_96, //0x96 Cmd_tryinfatuating, //0x97 @@ -764,8 +764,8 @@ void (* const gBattleScriptingCommandsTable[])(void) = Cmd_setsubstitute, //0x9C Cmd_mimicattackcopy, //0x9D Cmd_metronome, //0x9E - Cmd_dmgtolevel, //0x9F - Cmd_psywavedamageeffect, //0xA0 + Cmd_unused_0x9f, //0x9F + Cmd_unused_0xA0, //0xA0 Cmd_counterdamagecalculator, //0xA1 Cmd_mirrorcoatdamagecalculator, //0xA2 Cmd_disablelastusedattack, //0xA3 @@ -5100,6 +5100,7 @@ static void Cmd_getexp(void) u32 holdEffect; s32 i; // also used as stringId u8 *expMonId = &gBattleStruct->expGetterMonId; + u32 currLvl; gBattlerFainted = GetBattlerForBattleScript(cmd->battler); @@ -5314,7 +5315,8 @@ static void Cmd_getexp(void) if (gBattleControllerExecFlags == 0) { gBattleResources->bufferB[gBattleStruct->expGetterBattlerId][0] = 0; - if (GetMonData(&gPlayerParty[*expMonId], MON_DATA_HP) && GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL) != MAX_LEVEL) + currLvl = GetMonData(&gPlayerParty[*expMonId], MON_DATA_LEVEL); + if (GetMonData(&gPlayerParty[*expMonId], MON_DATA_HP) && currLvl != MAX_LEVEL) { gBattleResources->beforeLvlUp->stats[STAT_HP] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_MAX_HP); gBattleResources->beforeLvlUp->stats[STAT_ATK] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_ATK); @@ -5322,6 +5324,7 @@ static void Cmd_getexp(void) gBattleResources->beforeLvlUp->stats[STAT_SPEED] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPEED); gBattleResources->beforeLvlUp->stats[STAT_SPATK] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPATK); gBattleResources->beforeLvlUp->stats[STAT_SPDEF] = GetMonData(&gPlayerParty[*expMonId], MON_DATA_SPDEF); + gBattleResources->beforeLvlUp->level = currLvl; BtlController_EmitExpUpdate(gBattleStruct->expGetterBattlerId, BUFFER_A, *expMonId, gBattleStruct->battlerExpReward); MarkBattlerForControllerExec(gBattleStruct->expGetterBattlerId); @@ -8643,10 +8646,32 @@ static void Cmd_handlelearnnewmove(void) { CMD_ARGS(const u8 *learnedMovePtr, const u8 *nothingToLearnPtr, bool8 isFirstMove); + u16 learnMove = MOVE_NONE; u32 monId = gBattleStruct->expGetterMonId; - u16 learnMove = MonTryLearningNewMove(&gPlayerParty[monId], cmd->isFirstMove); - while (learnMove == MON_ALREADY_KNOWS_MOVE) - learnMove = MonTryLearningNewMove(&gPlayerParty[monId], FALSE); + + if (B_LEVEL_UP_NOTIFICATION >= GEN_9) + { + u32 currLvl = GetMonData(&gPlayerParty[monId], MON_DATA_LEVEL); + + while (gBattleResources->beforeLvlUp->level <= currLvl) + { + learnMove = MonTryLearningNewMoveAtLevel(&gPlayerParty[monId], cmd->isFirstMove, gBattleResources->beforeLvlUp->level); + + while (learnMove == MON_ALREADY_KNOWS_MOVE) + learnMove = MonTryLearningNewMoveAtLevel(&gPlayerParty[monId], FALSE, gBattleResources->beforeLvlUp->level); + + if (learnMove != MOVE_NONE) + break; + + gBattleResources->beforeLvlUp->level++; + } + } + else + { + learnMove = MonTryLearningNewMove(&gPlayerParty[monId], cmd->isFirstMove); + while (learnMove == MON_ALREADY_KNOWS_MOVE) + learnMove = MonTryLearningNewMove(&gPlayerParty[monId], FALSE); + } if (learnMove == MOVE_NONE || RECORDED_WILD_BATTLE) { @@ -11021,12 +11046,6 @@ static void Cmd_various(void) gBattlescriptCurrInstr = cmd->failInstr; return; } - case VARIOUS_SET_ARG_TO_BATTLE_DAMAGE: - { - VARIOUS_ARGS(); - gBattleStruct->moveDamage[gBattlerTarget] = GetMoveFixedDamage(gCurrentMove); - break; - } case VARIOUS_TRY_AUTOTOMIZE: { VARIOUS_ARGS(const u8 *failInstr); @@ -13195,16 +13214,8 @@ static void Cmd_tryKO(void) #undef FOCUS_BANDED #undef AFFECTION_ENDURED -// Super Fang -static void Cmd_damagetohalftargethp(void) +static void Cmd_unused_0x94(void) { - CMD_ARGS(); - - gBattleStruct->moveDamage[gBattlerTarget] = GetNonDynamaxHP(gBattlerTarget) / 2; - if (gBattleStruct->moveDamage[gBattlerTarget] == 0) - gBattleStruct->moveDamage[gBattlerTarget] = 1; - - gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_copybidedmg(void) @@ -13515,21 +13526,12 @@ static void Cmd_metronome(void) ResetValuesForCalledMove(); } -static void Cmd_dmgtolevel(void) +static void Cmd_unused_0x9f(void) { - CMD_ARGS(); - - gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerAttacker].level; - gBattlescriptCurrInstr = cmd->nextInstr; } -static void Cmd_psywavedamageeffect(void) +static void Cmd_unused_0xA0(void) { - CMD_ARGS(); - - s32 randDamage = B_PSYWAVE_DMG >= GEN_6 ? (Random() % 101) : ((Random() % 11) * 10); - gBattleStruct->moveDamage[gBattlerTarget] = gBattleMons[gBattlerAttacker].level * (randDamage + 50) / 100; - gBattlescriptCurrInstr = cmd->nextInstr; } static void Cmd_counterdamagecalculator(void) diff --git a/src/battle_setup.c b/src/battle_setup.c index 96d23dc42a..5a96c0b9c3 100644 --- a/src/battle_setup.c +++ b/src/battle_setup.c @@ -1084,9 +1084,9 @@ void ConfigureTwoTrainersBattle(u8 trainerObjEventId, const u8 *trainerScript) gSelectedObjectEvent = trainerObjEventId; gSpecialVar_LastTalked = gObjectEvents[trainerObjEventId].localId; - if (gApproachingTrainerId == 0) + if (gApproachingTrainerId == 0) TrainerBattleLoadArgs(trainerScript + 1); - else + else TrainerBattleLoadArgsSecondTrainer(trainerScript + 1); BattleSetup_ConfigureTrainerBattle(trainerScript + 1); @@ -1264,6 +1264,10 @@ static void CB2_EndTrainerBattle(void) else SetMainCallback2(CB2_WhiteOut); } + else if (DidPlayerForfeitNormalTrainerBattle()) + { + SetMainCallback2(CB2_WhiteOut); + } else { SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic); diff --git a/src/battle_util.c b/src/battle_util.c index c308417191..bcb9c9ab98 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -562,6 +562,10 @@ bool32 TryRunFromBattle(u32 battler) { effect++; } + else if (CanPlayerForfeitNormalTrainerBattle()) + { + effect++; + } else { u8 runningFromBattler = BATTLE_OPPOSITE(battler); @@ -4796,16 +4800,21 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 } break; case ABILITY_IMPOSTER: - if (IsBattlerAlive(BATTLE_OPPOSITE(battler)) - && !(gBattleMons[BATTLE_OPPOSITE(battler)].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE)) - && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED) - && !(gBattleStruct->illusion[BATTLE_OPPOSITE(battler)].on) - && !(gStatuses3[BATTLE_OPPOSITE(battler)] & STATUS3_SEMI_INVULNERABLE_NO_COMMANDER)) { - gBattlerAttacker = battler; - gBattlerTarget = BATTLE_OPPOSITE(battler); - BattleScriptPushCursorAndCallback(BattleScript_ImposterActivates); - effect++; + u32 diagonalBattler = BATTLE_OPPOSITE(battler); + if (IsDoubleBattle()) + diagonalBattler = BATTLE_PARTNER(diagonalBattler); + if (IsBattlerAlive(diagonalBattler) + && !(gBattleMons[diagonalBattler].status2 & (STATUS2_TRANSFORMED | STATUS2_SUBSTITUTE)) + && !(gBattleMons[battler].status2 & STATUS2_TRANSFORMED) + && !(gBattleStruct->illusion[diagonalBattler].on) + && !(gStatuses3[diagonalBattler] & STATUS3_SEMI_INVULNERABLE_NO_COMMANDER)) + { + gBattlerAttacker = battler; + gBattlerTarget = diagonalBattler; + BattleScriptPushCursorAndCallback(BattleScript_ImposterActivates); + effect++; + } } break; case ABILITY_MOLD_BREAKER: @@ -10495,6 +10504,37 @@ s32 ApplyModifiersAfterDmgRoll(s32 dmg, struct DamageCalculationData *damageCalc return dmg; } +static inline s32 DoFixedDamageMoveCalc(struct DamageCalculationData *damageCalcData) +{ + s32 dmg = 0; + + switch (GetMoveEffect(damageCalcData->move)) + { + case EFFECT_LEVEL_DAMAGE: + dmg = gBattleMons[damageCalcData->battlerAtk].level; + break; + case EFFECT_PSYWAVE: + s32 randDamage = B_PSYWAVE_DMG >= GEN_6 ? (Random() % 101) : ((Random() % 11) * 10); + dmg = gBattleMons[damageCalcData->battlerAtk].level * (randDamage + 50) / 100; + break; + case EFFECT_FIXED_DAMAGE_ARG: + dmg = GetMoveFixedDamage(damageCalcData->move); + break; + case EFFECT_SUPER_FANG: + dmg = GetNonDynamaxHP(gBattlerTarget) / 2; + break; + default: + return INT32_MAX; + } + + gBattleStruct->moveResultFlags[damageCalcData->battlerDef] &= ~(MOVE_RESULT_NOT_VERY_EFFECTIVE | MOVE_RESULT_SUPER_EFFECTIVE); + + if (dmg == 0) + dmg = 1; + + return dmg; +} + static inline s32 DoMoveDamageCalc(struct DamageCalculationData *damageCalcData, u32 fixedBasePower, uq4_12_t typeEffectivenessModifier, u32 weather) { u32 holdEffectAtk, holdEffectDef, abilityAtk, abilityDef; @@ -10502,6 +10542,10 @@ static inline s32 DoMoveDamageCalc(struct DamageCalculationData *damageCalcData, if (typeEffectivenessModifier == UQ_4_12(0.0)) return 0; + s32 dmg = DoFixedDamageMoveCalc(damageCalcData); + if (dmg != INT32_MAX) + return dmg; + holdEffectAtk = GetBattlerHoldEffect(damageCalcData->battlerAtk, TRUE); holdEffectDef = GetBattlerHoldEffect(damageCalcData->battlerDef, TRUE); abilityAtk = GetBattlerAbility(damageCalcData->battlerAtk); @@ -10610,6 +10654,10 @@ s32 CalculateMoveDamage(struct DamageCalculationData *damageCalcData, u32 fixedB s32 CalculateMoveDamageVars(struct DamageCalculationData *damageCalcData, u32 fixedBasePower, uq4_12_t typeEffectivenessModifier, u32 weather, u32 holdEffectAtk, u32 holdEffectDef, u32 abilityAtk, u32 abilityDef) { + s32 dmg = DoFixedDamageMoveCalc(damageCalcData); + if (dmg != INT32_MAX) + return dmg; + return DoMoveDamageCalcVars(damageCalcData, fixedBasePower, typeEffectivenessModifier, weather, holdEffectAtk, holdEffectDef, abilityAtk, abilityDef); } diff --git a/src/data/battle_move_effects.h b/src/data/battle_move_effects.h index dc0413af2d..38928c4f4c 100644 --- a/src/data/battle_move_effects.h +++ b/src/data/battle_move_effects.h @@ -218,14 +218,14 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = [EFFECT_SUPER_FANG] = { - .battleScript = BattleScript_EffectSuperFang, + .battleScript = BattleScript_EffectHit, .battleTvScore = 5, .encourageEncore = TRUE, }, [EFFECT_FIXED_DAMAGE_ARG] = { - .battleScript = BattleScript_EffectFixedDamageArg, + .battleScript = BattleScript_EffectHit, .battleTvScore = 1, }, @@ -454,13 +454,13 @@ const struct BattleMoveEffect gBattleMoveEffects[NUM_BATTLE_MOVE_EFFECTS] = [EFFECT_LEVEL_DAMAGE] = { - .battleScript = BattleScript_EffectLevelDamage, + .battleScript = BattleScript_EffectHit, .battleTvScore = 2, }, [EFFECT_PSYWAVE] = { - .battleScript = BattleScript_EffectPsywave, + .battleScript = BattleScript_EffectHit, .battleTvScore = 1, }, diff --git a/src/data/gimmicks.h b/src/data/gimmicks.h index 5b06feddef..0ea19ea1e4 100644 --- a/src/data/gimmicks.h +++ b/src/data/gimmicks.h @@ -10,8 +10,8 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] = .triggerSheet = &sSpriteSheet_MegaTrigger, .triggerPal = &sSpritePalette_MegaTrigger, .triggerTemplate = &sSpriteTemplate_GimmickTrigger, - .indicatorSheet = &sSpriteSheet_MegaIndicator, - .indicatorPal = &sSpritePalette_MegaIndicator, + .indicatorData = sMegaIndicatorGfx, + .indicatorPalTag = TAG_MEGA_INDICATOR_PAL, .CanActivate = CanMegaEvolve, .ActivateGimmick = ActivateMegaEvolution, }, @@ -36,8 +36,8 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] = .triggerSheet = &sSpriteSheet_DynamaxTrigger, .triggerPal = &sSpritePalette_DynamaxTrigger, .triggerTemplate = &sSpriteTemplate_GimmickTrigger, - .indicatorSheet = &sSpriteSheet_DynamaxIndicator, - .indicatorPal = &sSpritePalette_MiscIndicator, + .indicatorData = sDynamaxIndicatorGfx, + .indicatorPalTag = TAG_MISC_INDICATOR_PAL, .CanActivate = CanDynamax, .ActivateGimmick = ActivateDynamax, }, @@ -46,8 +46,8 @@ const struct GimmickInfo gGimmicksInfo[GIMMICKS_COUNT] = .triggerSheet = &sSpriteSheet_TeraTrigger, .triggerPal = &sSpritePalette_TeraTrigger, .triggerTemplate = &sSpriteTemplate_GimmickTrigger, - .indicatorSheet = NULL, // handled separately - .indicatorPal = &sSpritePalette_TeraIndicator, + .indicatorData = NULL, // handled separately + .indicatorPalTag = TAG_TERA_INDICATOR_PAL, .CanActivate = CanTerastallize, .ActivateGimmick = ActivateTera, } diff --git a/src/data/graphics/gimmicks.h b/src/data/graphics/gimmicks.h index f16b2f83c0..483cf2218b 100644 --- a/src/data/graphics/gimmicks.h +++ b/src/data/graphics/gimmicks.h @@ -99,34 +99,29 @@ static const u16 sMiscIndicatorPal[] = INCBIN_U16("graphics/battle_interface/mis static const u16 sMegaIndicatorPal[] = INCBIN_U16("graphics/battle_interface/mega_indicator.gbapal"); static const u16 sTeraIndicatorPal[] = INCBIN_U16("graphics/battle_interface/tera_indicator.gbapal"); -static const struct SpriteSheet sSpriteSheet_MegaIndicator = {sMegaIndicatorGfx, sizeof(sMegaIndicatorGfx), TAG_MEGA_INDICATOR_TILE}; -static const struct SpriteSheet sSpriteSheet_AlphaIndicator = {sAlphaIndicatorGfx, sizeof(sAlphaIndicatorGfx), TAG_ALPHA_INDICATOR_TILE}; -static const struct SpriteSheet sSpriteSheet_OmegaIndicator = {sOmegaIndicatorGfx, sizeof(sOmegaIndicatorGfx), TAG_OMEGA_INDICATOR_TILE}; -static const struct SpriteSheet sSpriteSheet_DynamaxIndicator = {sDynamaxIndicatorGfx, sizeof(sDynamaxIndicatorGfx), TAG_DYNAMAX_INDICATOR_TILE}; -static const struct SpriteSheet sTeraIndicatorSpriteSheets[NUMBER_OF_MON_TYPES + 1] = +static const u8 *sTeraIndicatorDataPtrs[] = { - {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE}, // TYPE_NONE - {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE}, - {sFightingIndicatorGfx, sizeof(sFightingIndicatorGfx), TAG_FIGHTING_INDICATOR_TILE}, - {sFlyingIndicatorGfx, sizeof(sFlyingIndicatorGfx), TAG_FLYING_INDICATOR_TILE}, - {sPoisonIndicatorGfx, sizeof(sPoisonIndicatorGfx), TAG_POISON_INDICATOR_TILE}, - {sGroundIndicatorGfx, sizeof(sGroundIndicatorGfx), TAG_GROUND_INDICATOR_TILE}, - {sRockIndicatorGfx, sizeof(sRockIndicatorGfx), TAG_ROCK_INDICATOR_TILE}, - {sBugIndicatorGfx, sizeof(sBugIndicatorGfx), TAG_BUG_INDICATOR_TILE}, - {sGhostIndicatorGfx, sizeof(sGhostIndicatorGfx), TAG_GHOST_INDICATOR_TILE}, - {sSteelIndicatorGfx, sizeof(sSteelIndicatorGfx), TAG_STEEL_INDICATOR_TILE}, - {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), TAG_NORMAL_INDICATOR_TILE}, // TYPE_MYSTERY - {sFireIndicatorGfx, sizeof(sFireIndicatorGfx), TAG_FIRE_INDICATOR_TILE}, - {sWaterIndicatorGfx, sizeof(sWaterIndicatorGfx), TAG_WATER_INDICATOR_TILE}, - {sGrassIndicatorGfx, sizeof(sGrassIndicatorGfx), TAG_GRASS_INDICATOR_TILE}, - {sElectricIndicatorGfx, sizeof(sElectricIndicatorGfx), TAG_ELECTRIC_INDICATOR_TILE}, - {sPsychicIndicatorGfx, sizeof(sPsychicIndicatorGfx), TAG_PSYCHIC_INDICATOR_TILE}, - {sIceIndicatorGfx, sizeof(sIceIndicatorGfx), TAG_ICE_INDICATOR_TILE}, - {sDragonIndicatorGfx, sizeof(sDragonIndicatorGfx), TAG_DRAGON_INDICATOR_TILE}, - {sDarkIndicatorGfx, sizeof(sDarkIndicatorGfx), TAG_DARK_INDICATOR_TILE}, - {sFairyIndicatorGfx, sizeof(sFairyIndicatorGfx), TAG_FAIRY_INDICATOR_TILE}, - {sStellarIndicatorGfx, sizeof(sStellarIndicatorGfx), TAG_STELLAR_INDICATOR_TILE}, - {0} + sNormalIndicatorGfx, + sNormalIndicatorGfx, + sFightingIndicatorGfx, + sFlyingIndicatorGfx, + sPoisonIndicatorGfx, + sGroundIndicatorGfx, + sRockIndicatorGfx, + sBugIndicatorGfx, + sGhostIndicatorGfx, + sSteelIndicatorGfx, + sNormalIndicatorGfx, + sFireIndicatorGfx, + sWaterIndicatorGfx, + sGrassIndicatorGfx, + sElectricIndicatorGfx, + sPsychicIndicatorGfx, + sIceIndicatorGfx, + sDragonIndicatorGfx, + sDarkIndicatorGfx, + sFairyIndicatorGfx, + sStellarIndicatorGfx, }; static const struct SpritePalette sSpritePalette_MiscIndicator = {sMiscIndicatorPal, TAG_MISC_INDICATOR_PAL}; @@ -141,13 +136,56 @@ static const struct OamData sOamData_GimmickIndicator = }; static void SpriteCb_GimmickIndicator(struct Sprite *sprite); -static const struct SpriteTemplate sSpriteTemplate_GimmickIndicator = + +#define BATTLER_INDICATOR_TAG 0xDEDE +static const struct SpriteSheet sBattler_GimmickSpritesheets[] = { - .tileTag = TAG_NORMAL_INDICATOR_TILE, // updated dynamically - .paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically - .oam = &sOamData_GimmickIndicator, - .anims = gDummySpriteAnimTable, - .images = NULL, - .affineAnims = gDummySpriteAffineAnimTable, - .callback = SpriteCb_GimmickIndicator, + {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG}, + {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG+1}, + {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG+2}, + {sNormalIndicatorGfx, sizeof(sNormalIndicatorGfx), BATTLER_INDICATOR_TAG+3}, +}; + +static const struct SpriteTemplate sSpriteTemplate_BattlerIndicators[] = +{ + [0] = + { + .tileTag = BATTLER_INDICATOR_TAG, // updated dynamically + .paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically + .oam = &sOamData_GimmickIndicator, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCb_GimmickIndicator, + }, + [1] = + { + .tileTag = BATTLER_INDICATOR_TAG + 1, // updated dynamically + .paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically + .oam = &sOamData_GimmickIndicator, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCb_GimmickIndicator, + }, + [2] = + { + .tileTag = BATTLER_INDICATOR_TAG + 2, // updated dynamically + .paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically + .oam = &sOamData_GimmickIndicator, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCb_GimmickIndicator, + }, + [3] = + { + .tileTag = BATTLER_INDICATOR_TAG + 3, // updated dynamically + .paletteTag = TAG_TERA_INDICATOR_PAL, // updated dynamically + .oam = &sOamData_GimmickIndicator, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gDummySpriteAffineAnimTable, + .callback = SpriteCb_GimmickIndicator, + }, }; diff --git a/src/data/items.h b/src/data/items.h index 9df4265116..93d7dbdb90 100644 --- a/src/data/items.h +++ b/src/data/items.h @@ -13509,6 +13509,8 @@ const struct Item gItemsInfo[] = { .name = _("Adamant Crystal"), .price = 0, + .holdEffect = HOLD_EFFECT_ADAMANT_ORB, + .holdEffectParam = 20, .description = COMPOUND_STRING( "A large, glowing gem\n" "that lets Dialga\n" @@ -13525,6 +13527,8 @@ const struct Item gItemsInfo[] = { .name = _("Griseous Core"), .price = 0, + .holdEffect = HOLD_EFFECT_GRISEOUS_ORB, + .holdEffectParam = 20, .description = COMPOUND_STRING( "A large, glowing gem\n" "that lets Giratina\n" @@ -13541,6 +13545,8 @@ const struct Item gItemsInfo[] = { .name = _("Lustrous Globe"), .price = 0, + .holdEffect = HOLD_EFFECT_LUSTROUS_ORB, + .holdEffectParam = 20, .description = COMPOUND_STRING( "A large, glowing gem\n" "that lets Palkia\n" diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 7ccc71f575..6564ece843 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -1439,8 +1439,8 @@ static u8 InitObjectEventStateFromTemplate(const struct ObjectEventTemplate *tem objectEvent->previousCoords.y = y; objectEvent->currentElevation = template->elevation; objectEvent->previousElevation = template->elevation; - objectEvent->rangeX = template->movementRangeX; - objectEvent->rangeY = template->movementRangeY; + objectEvent->range.rangeX = template->movementRangeX; + objectEvent->range.rangeY = template->movementRangeY; objectEvent->trainerType = template->trainerType; objectEvent->mapNum = mapNum; objectEvent->trainerRange_berryTreeId = template->trainerRange_berryTreeId; @@ -1448,10 +1448,10 @@ static u8 InitObjectEventStateFromTemplate(const struct ObjectEventTemplate *tem SetObjectEventDirection(objectEvent, objectEvent->previousMovementDirection); if (sMovementTypeHasRange[objectEvent->movementType]) { - if (objectEvent->rangeX == 0) - objectEvent->rangeX++; - if (objectEvent->rangeY == 0) - objectEvent->rangeY++; + if (objectEvent->range.rangeX == 0) + objectEvent->range.rangeX++; + if (objectEvent->range.rangeY == 0) + objectEvent->range.rangeY++; } return objectEventId; } @@ -6384,18 +6384,18 @@ static bool8 IsCoordOutsideObjectEventMovementRange(struct ObjectEvent *objectEv s16 top; s16 bottom; - if (objectEvent->rangeX != 0) + if (objectEvent->range.rangeX != 0) { - left = objectEvent->initialCoords.x - objectEvent->rangeX; - right = objectEvent->initialCoords.x + objectEvent->rangeX; + left = objectEvent->initialCoords.x - objectEvent->range.rangeX; + right = objectEvent->initialCoords.x + objectEvent->range.rangeX; if (left > x || right < x) return TRUE; } - if (objectEvent->rangeY != 0) + if (objectEvent->range.rangeY != 0) { - top = objectEvent->initialCoords.y - objectEvent->rangeY; - bottom = objectEvent->initialCoords.y + objectEvent->rangeY; + top = objectEvent->initialCoords.y - objectEvent->range.rangeY; + bottom = objectEvent->initialCoords.y + objectEvent->range.rangeY; if (top > y || bottom < y) return TRUE; diff --git a/src/field_player_avatar.c b/src/field_player_avatar.c index 6452e99a9b..413c4acfc8 100644 --- a/src/field_player_avatar.c +++ b/src/field_player_avatar.c @@ -272,7 +272,7 @@ static bool8 (*const sArrowWarpMetatileBehaviorChecks[])(u8) = [DIR_EAST - 1] = MetatileBehavior_IsEastArrowWarp, }; -static const u8 sRivalAvatarGfxIds[][2] = +static const u8 sRivalAvatarGfxIds[][GENDER_COUNT] = { [PLAYER_AVATAR_STATE_NORMAL] = {OBJ_EVENT_GFX_RIVAL_BRENDAN_NORMAL, OBJ_EVENT_GFX_RIVAL_MAY_NORMAL}, [PLAYER_AVATAR_STATE_MACH_BIKE] = {OBJ_EVENT_GFX_RIVAL_BRENDAN_MACH_BIKE, OBJ_EVENT_GFX_RIVAL_MAY_MACH_BIKE}, @@ -285,7 +285,7 @@ static const u8 sRivalAvatarGfxIds[][2] = [PLAYER_AVATAR_STATE_VSSEEKER] = {OBJ_EVENT_GFX_RIVAL_BRENDAN_FIELD_MOVE, OBJ_EVENT_GFX_RIVAL_MAY_FIELD_MOVE}, }; -static const u8 sPlayerAvatarGfxIds[][2] = +static const u8 sPlayerAvatarGfxIds[][GENDER_COUNT] = { [PLAYER_AVATAR_STATE_NORMAL] = {OBJ_EVENT_GFX_BRENDAN_NORMAL, OBJ_EVENT_GFX_MAY_NORMAL}, [PLAYER_AVATAR_STATE_MACH_BIKE] = {OBJ_EVENT_GFX_BRENDAN_MACH_BIKE, OBJ_EVENT_GFX_MAY_MACH_BIKE}, diff --git a/src/field_screen_effect.c b/src/field_screen_effect.c index 77733d17b3..726f5539b7 100644 --- a/src/field_screen_effect.c +++ b/src/field_screen_effect.c @@ -39,6 +39,7 @@ #include "constants/rgb.h" #include "trainer_hill.h" #include "fldeff.h" +#include "battle.h" static void Task_ExitNonAnimDoor(u8); static void Task_ExitNonDoor(u8); @@ -1344,6 +1345,21 @@ enum { FRLG_WHITEOUT_HEAL_SCRIPT, }; +static const u8 *GenerateRecoveryMessage(u8 taskId) +{ + bool32 forfeitTrainer = DidPlayerForfeitNormalTrainerBattle(); + bool32 destinationIsPlayersHouse = (gTasks[taskId].tIsPlayerHouse == TRUE); + + if (forfeitTrainer && destinationIsPlayersHouse) + return gText_PlayerRegroupHome; + else if (forfeitTrainer && !destinationIsPlayersHouse) + return gText_PlayerRegroupCenter; + else if (!forfeitTrainer && destinationIsPlayersHouse) + return gText_PlayerScurriedBackHome; + else + return gText_PlayerScurriedToCenter; +} + static void Task_RushInjuredPokemonToCenter(u8 taskId) { u32 windowId; @@ -1363,7 +1379,8 @@ static void Task_RushInjuredPokemonToCenter(u8 taskId) break; case FRLG_WHITEOUT_PRINT_MSG: { - const u8 *recoveryMessage = gTasks[taskId].tIsPlayerHouse == TRUE ? gText_PlayerScurriedBackHome : gText_PlayerScurriedToCenter; + const u8 *recoveryMessage = GenerateRecoveryMessage(taskId); + if (PrintWhiteOutRecoveryMessage(taskId, recoveryMessage, 2, 8)) { ObjectEventTurn(&gObjectEvents[gPlayerAvatar.objectEventId], DIR_NORTH); diff --git a/src/fonts.c b/src/fonts.c index 853f6fbde2..46f3a335c4 100644 --- a/src/fonts.c +++ b/src/fonts.c @@ -19,7 +19,7 @@ ALIGNED(4) const u8 gFontSmallNarrowLatinGlyphWidths[] = { 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 3, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 8, 3, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -55,7 +55,7 @@ ALIGNED(4) const u8 gFontSmallLatinGlyphWidths[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 7, 5, 5, 5, 5, 5, 5, 9, 3, 3, 3, 8, 3, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -91,7 +91,7 @@ ALIGNED(4) const u8 gFontNarrowLatinGlyphWidths[] = { 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 3, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 8, 3, 3, 3, 3, 10, 10, 10, 10, 8, 8, 10, 8, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -127,7 +127,7 @@ ALIGNED(4) const u8 gFontShortLatinGlyphWidths[] = { 5, 6, 5, 6, 6, 6, 5, 5, 5, 6, 6, 6, 6, 6, 6, 8, 5, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 8, 3, 3, 3, 3, 12, 12, 12, 12, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -163,7 +163,7 @@ ALIGNED(4) const u8 gFontNormalLatinGlyphWidths[] = { 4, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 8, 3, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 8, 3, 3, 3, 3, 10, 10, 10, 10, 8, 10, 10, 8, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -199,7 +199,7 @@ ALIGNED(4) const u8 gFontNarrowerLatinGlyphWidths[] = { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 2, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 8, 3, 3, 3, 3, 10, 10, 10, 10, 8, 8, 10, 8, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -235,7 +235,7 @@ ALIGNED(4) const u8 gFontSmallNarrowerLatinGlyphWidths[] = { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 7, 2, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 8, 3, 3, 3, 3, 8, 8, 8, 8, 8, 7, 8, 7, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -271,7 +271,7 @@ ALIGNED(4) const u8 gFontShortNarrowLatinGlyphWidths[] = { 4, 6, 5, 5, 5, 5, 5, 5, 4, 5, 5, 6, 4, 5, 5, 8, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 8, 3, 3, 3, 3, 12, 12, 12, 12, 8, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, @@ -307,7 +307,7 @@ ALIGNED(4) const u8 gFontShortNarrowerLatinGlyphWidths[] = { 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 5, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 10, 10, 10, 10, 8, 8, 10, 8, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, diff --git a/src/main.c b/src/main.c index c2758ee227..c27d56bacd 100644 --- a/src/main.c +++ b/src/main.c @@ -124,7 +124,7 @@ void AgbMain() #if (LOG_HANDLER == LOG_HANDLER_MGBA_PRINT) (void) MgbaOpen(); #elif (LOG_HANDLER == LOG_HANDLER_AGB_PRINT) - AGBPrintfInit(); + AGBPrintInit(); #endif #endif gAgbMainLoop_sp = __builtin_frame_address(0); diff --git a/src/overworld.c b/src/overworld.c index e7273164ad..ae7d361cdc 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -3188,7 +3188,7 @@ static void ZeroObjectEvent(struct ObjectEvent *objEvent) // conflict with the usual Event Object struct, thus the definitions. #define linkGender(obj) obj->singleMovementActive // not even one can reference *byte* aligned bitfield members... -#define linkDirection(obj) ((u8 *)obj)[offsetof(typeof(*obj), fieldEffectSpriteId) - 1] // -> rangeX +#define linkDirection(obj) ((u8 *)obj)[offsetof(typeof(*obj), range)] // -> rangeX static void SpawnLinkPlayerObjectEvent(u8 linkPlayerId, s16 x, s16 y, u8 gender) { @@ -3524,7 +3524,7 @@ static u8 ReformatItemDescription(u16 item, u8 *dest) u8 count = 0; u8 numLines = 1; u8 maxChars = 32; - u8 *desc = (u8 *)gItemsInfo[item].description; + u8 *desc = (u8 *)ItemId_GetDescription(item); while (*desc != EOS) { diff --git a/src/pokemon.c b/src/pokemon.c index 0289ca180e..29407b8961 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -1982,11 +1982,10 @@ void GiveBoxMonInitialMoveset(struct BoxPokemon *boxMon) //Credit: AsparagusEdua } } -u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove) +u16 MonTryLearningNewMoveAtLevel(struct Pokemon *mon, bool32 firstMove, u32 level) { u32 retVal = MOVE_NONE; u16 species = GetMonData(mon, MON_DATA_SPECIES, NULL); - u8 level = GetMonData(mon, MON_DATA_LEVEL, NULL); const struct LevelUpMove *learnset = GetSpeciesLevelUpLearnset(species); // since you can learn more than one move per level @@ -2034,6 +2033,11 @@ u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove) return retVal; } +u16 MonTryLearningNewMove(struct Pokemon *mon, bool8 firstMove) +{ + return MonTryLearningNewMoveAtLevel(mon, firstMove, GetMonData(mon, MON_DATA_LEVEL, NULL)); +} + void DeleteFirstMoveAndGiveMoveToMon(struct Pokemon *mon, u16 move) { s32 i; diff --git a/src/strings.c b/src/strings.c index c112db4616..fee143ea68 100644 --- a/src/strings.c +++ b/src/strings.c @@ -806,6 +806,8 @@ 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_PlayerRegroupCenter[] = _("{PLAYER} went running back to a POKéMON CENTER\nto regroup and reconsider their battle\lstrategy…\p"); +const u8 gText_PlayerRegroupHome[] = _("{PLAYER} went running back home to regroup\nand reconsider their battle strategy…\p"); 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"); diff --git a/src/trainer_see.c b/src/trainer_see.c index 07eb46efdd..e8b9c4f5ae 100644 --- a/src/trainer_see.c +++ b/src/trainer_see.c @@ -590,15 +590,15 @@ static u8 CheckPathBetweenTrainerAndPlayer(struct ObjectEvent *trainerObj, u8 ap return 0; } - rangeX = trainerObj->rangeX; - rangeY = trainerObj->rangeY; - trainerObj->rangeX = 0; - trainerObj->rangeY = 0; + rangeX = trainerObj->range.rangeX; + rangeY = trainerObj->range.rangeY; + trainerObj->range.rangeX = 0; + trainerObj->range.rangeY = 0; collision = GetCollisionAtCoords(trainerObj, x, y, direction); - trainerObj->rangeX = rangeX; - trainerObj->rangeY = rangeY; + trainerObj->range.rangeX = rangeX; + trainerObj->range.rangeY = rangeY; if (collision == COLLISION_OBJECT_EVENT) return approachDistance; diff --git a/src/type_icons.c b/src/type_icons.c index 41fa102bb9..febf2346a4 100644 --- a/src/type_icons.c +++ b/src/type_icons.c @@ -15,7 +15,8 @@ static void LoadTypeIconsPerBattler(u32, u32); static bool32 UseDoubleBattleCoords(u32); static u32 GetMonPublicType(u32, u32); -static bool32 ShouldHideUncaughtType(u32); +static bool32 ShouldHideUncaughtType(u32 species); +static bool32 ShouldHideUnseenType(u32 species); static u32 GetMonDefensiveTeraType(struct Pokemon *, struct Pokemon*, u32, u32, u32, u32); static u32 IsIllusionActiveAndTypeUnchanged(struct Pokemon*, u32, u32); @@ -239,7 +240,11 @@ void LoadTypeIcons(u32 battler) { u32 position; - if (B_SHOW_TYPES == SHOW_TYPES_NEVER) + struct Pokemon* mon = GetPartyBattlerData(battler); + u32 species = GetMonData(mon, MON_DATA_SPECIES, NULL); + + if (B_SHOW_TYPES == SHOW_TYPES_NEVER + || (B_SHOW_TYPES == SHOW_TYPES_SEEN && !GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_SEEN))) return; LoadTypeSpritesAndPalettes(); @@ -296,7 +301,7 @@ static u32 GetMonPublicType(u32 battlerId, u32 typeNum) struct Pokemon* monIllusion; u32 illusionSpecies; - if (ShouldHideUncaughtType(monSpecies)) + if (ShouldHideUncaughtType(monSpecies) || ShouldHideUnseenType(monSpecies)) return TYPE_MYSTERY; monIllusion = GetIllusionMonPtr(battlerId); @@ -316,7 +321,18 @@ static bool32 ShouldHideUncaughtType(u32 species) if (B_SHOW_TYPES != SHOW_TYPES_CAUGHT) return FALSE; - if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species),FLAG_GET_CAUGHT)) + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_CAUGHT)) + return FALSE; + + return TRUE; +} + +static bool32 ShouldHideUnseenType(u32 species) +{ + if (B_SHOW_TYPES != SHOW_TYPES_SEEN) + return FALSE; + + if (GetSetPokedexFlag(SpeciesToNationalPokedexNum(species), FLAG_GET_SEEN)) return FALSE; return TRUE; diff --git a/src/wild_encounter.c b/src/wild_encounter.c index 3a3a7d8dc7..3db2402d2f 100644 --- a/src/wild_encounter.c +++ b/src/wild_encounter.c @@ -1182,6 +1182,7 @@ static u8 GetMaxLevelOfSpeciesInWildTable(const struct WildPokemon *wildMon, u16 default: case WILD_AREA_FISHING: case WILD_AREA_HIDDEN: + break; } for (i = 0; i < numMon; i++) diff --git a/test/battle/ability/commander.c b/test/battle/ability/commander.c index 2220fb9ec2..d4b31f23b8 100644 --- a/test/battle/ability/commander.c +++ b/test/battle/ability/commander.c @@ -245,11 +245,11 @@ DOUBLE_BATTLE_TEST("Commander doesn't prevent Imposter from working on a Command OPPONENT(SPECIES_DITTO) { Ability(ABILITY_IMPOSTER); } } WHEN { TURN { } - TURN { SWITCH(opponentRight, 2); } + TURN { SWITCH(opponentLeft, 2); } } SCENE { ABILITY_POPUP(playerRight, ABILITY_COMMANDER); MESSAGE("Tatsugiri was swallowed by Dondozo and became Dondozo's commander!"); - ABILITY_POPUP(opponentRight, ABILITY_IMPOSTER); + ABILITY_POPUP(opponentLeft, ABILITY_IMPOSTER); MESSAGE("The opposing Ditto transformed into Tatsugiri using Imposter!"); } } diff --git a/test/battle/move_effect/level_damage.c b/test/battle/move_effect/level_damage.c new file mode 100644 index 0000000000..2ccf1ae964 --- /dev/null +++ b/test/battle/move_effect/level_damage.c @@ -0,0 +1,23 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_SEISMIC_TOSS) == EFFECT_LEVEL_DAMAGE); +} + +SINGLE_BATTLE_TEST("Level Damage: Seismic Toss deals damage based on user's level") +{ + s16 dmg; + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Level(50); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SEISMIC_TOSS); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SEISMIC_TOSS, player); + HP_BAR(opponent, captureDamage: &dmg); + } THEN { + EXPECT(dmg == 50); + } +}