diff --git a/INSTALL.md b/INSTALL.md index cc6eba97ef..6349d24fbb 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -33,27 +33,23 @@ WSL1 is the preferred terminal to build **pokeemerald Expansion**. The following - Otherwise, **open WSL** and go to [Choosing where to store pokeemerald Expansion (WSL1)](#Choosing-where-to-store-pokeemerald-expansion-WSL1). ### Installing WSL1 -1. Open [Windows Powershell **as Administrator**](https://i.imgur.com/QKmVbP9.png), and run the following command (Right Click or Shift+Insert is paste in the Powershell). +1. Open [Windows Powershell **as Administrator**](https://i.imgur.com/QKmVbP9.png), and run the following commands (Right Click or Shift+Insert is paste in the Powershell). ```powershell - dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart + wsl --install -d Ubuntu --enable-wsl1 ``` 2. Once the process finishes, restart your machine. -3. The next step is to choose and install a Linux distribution from the Microsoft Store. The following instructions will assume Ubuntu as the Linux distribution of choice. +3. Open Windows Powershell **as Administrator** again (after restarting), and run the following command to configure Ubuntu to use WSL1. + + ```powershell + wsl --set-version Ubuntu 1 + ```
- Note for advanced users... + Note... - > You can pick a preferred Linux distribution, but setup instructions may differ. Debian should work with the given instructions, but has not been tested. -
- -4. Open the [Microsoft Store Linux Selection](https://aka.ms/wslstore), click Ubuntu, then click Get, which will install the Ubuntu distribution. -
- Notes... - - > Note 1: If a dialog pops up asking for you to sign into a Microsoft Account, then just close the dialog. - > Note 2: If the link does not work, then open the Microsoft Store manually, and search for the Ubuntu app (choose the one with no version number). + > WSL may open automatically after restarting, but you can ignore it for now.
### Setting up WSL1 diff --git a/asm/macros/battle_anim_script.inc b/asm/macros/battle_anim_script.inc index 742cdb2f26..367428eb50 100644 --- a/asm/macros/battle_anim_script.inc +++ b/asm/macros/battle_anim_script.inc @@ -315,6 +315,12 @@ .Lsprite_\@_2: .endm + .macro jumpifmovetypeequal type:req, jumpInstr:req + .byte 0x33 + .byte \type + .4byte \jumpInstr + .endm + @ useful macros .macro jumpreteq value:req, ptr:req jumpargeq ARG_RET_ID, \value, \ptr diff --git a/data/battle_anim_scripts.s b/data/battle_anim_scripts.s index 6bcf1271ec..0947c39d1c 100644 --- a/data/battle_anim_scripts.s +++ b/data/battle_anim_scripts.s @@ -17844,6 +17844,59 @@ ElectroShotUnleash: blendoff end +Move_IVY_CUDGEL:: + loadspritegfx ANIM_TAG_IVY_CUDGEL_GRASS + loadspritegfx ANIM_TAG_WOOD_HAMMER + loadspritegfx ANIM_TAG_WOOD_HAMMER_HAMMER + loadspritegfx ANIM_TAG_IMPACT + playsewithpan SE_M_SWAGGER, SOUND_PAN_ATTACKER + createvisualtask AnimTask_TranslateMonEllipticalRespectSide, 2, ANIM_ATTACKER, 12, 4, 2, 4 + jumpifmovetypeequal TYPE_FIRE, IvyCudgelFire + jumpifmovetypeequal TYPE_ROCK, IvyCudgelRock + jumpifmovetypeequal TYPE_WATER, IvyCudgelWater + createsprite gIvyCudgelSpriteTemplate, ANIM_TARGET, 2 + delay 60 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 3, 0, 12, 4 + delay 18 + createvisualtask AnimTask_SquishTarget, 0x2 + delay 6 + call WoodHammerImpact + waitforvisualfinish + end +IvyCudgelFire: + loadspritegfx ANIM_TAG_IVY_CUDGEL_FIRE + createsprite gIvyCudgelFireSpriteTemplate, ANIM_TARGET, 2 + delay 60 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 3, 0, 12, 4 + delay 18 + createvisualtask AnimTask_SquishTarget, 0x2 + delay 6 + call WoodHammerImpact + waitforvisualfinish + end +IvyCudgelRock: + loadspritegfx ANIM_TAG_IVY_CUDGEL_ROCK + createsprite gIvyCudgelRockSpriteTemplate, ANIM_TARGET, 2 + delay 60 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 3, 0, 12, 4 + delay 18 + createvisualtask AnimTask_SquishTarget, 0x2 + delay 6 + call WoodHammerImpact + waitforvisualfinish + end +IvyCudgelWater: + loadspritegfx ANIM_TAG_IVY_CUDGEL_WATER + createsprite gIvyCudgelWaterSpriteTemplate, ANIM_TARGET, 2 + delay 60 + createvisualtask AnimTask_ShakeMonInPlace, 2, ANIM_ATTACKER, 3, 0, 12, 4 + delay 18 + createvisualtask AnimTask_SquishTarget, 0x2 + delay 6 + call WoodHammerImpact + waitforvisualfinish + end + Move_AXE_KICK:: loadspritegfx ANIM_TAG_HANDS_AND_FEET loadspritegfx ANIM_TAG_IMPACT @@ -17889,7 +17942,6 @@ Move_MAGICAL_TORQUE:: Move_PSYBLADE:: Move_BLOOD_MOON:: Move_MATCHA_GOTCHA:: -Move_IVY_CUDGEL:: Move_TERA_STARSTORM:: Move_FICKLE_BEAM:: Move_THUNDERCLAP:: diff --git a/graphics/battle_anims/sprites/cudgel.png b/graphics/battle_anims/sprites/cudgel.png new file mode 100644 index 0000000000..a43b450adc Binary files /dev/null and b/graphics/battle_anims/sprites/cudgel.png differ diff --git a/graphics/pokemon/ogerpon/back.png b/graphics/pokemon/ogerpon/back.png index 29ad3c09b2..75f309fd67 100644 Binary files a/graphics/pokemon/ogerpon/back.png and b/graphics/pokemon/ogerpon/back.png differ diff --git a/graphics/pokemon/ogerpon/cornerstone/back.png b/graphics/pokemon/ogerpon/cornerstone/back.png index 39170fd757..7e40fee557 100644 Binary files a/graphics/pokemon/ogerpon/cornerstone/back.png and b/graphics/pokemon/ogerpon/cornerstone/back.png differ diff --git a/graphics/pokemon/ogerpon/cornerstone/front.png b/graphics/pokemon/ogerpon/cornerstone/front.png index 6bca5e915c..8e96be70e7 100644 Binary files a/graphics/pokemon/ogerpon/cornerstone/front.png and b/graphics/pokemon/ogerpon/cornerstone/front.png differ diff --git a/graphics/pokemon/ogerpon/cornerstone/normal.pal b/graphics/pokemon/ogerpon/cornerstone/normal.pal index 057bd48dcc..852898a6b7 100644 --- a/graphics/pokemon/ogerpon/cornerstone/normal.pal +++ b/graphics/pokemon/ogerpon/cornerstone/normal.pal @@ -2,12 +2,12 @@ JASC-PAL 0100 15 148 209 161 +0 0 0 42 44 41 21 158 7 -0 0 0 74 76 73 -25 27 24 61 113 53 +25 27 24 109 99 108 133 139 139 53 134 168 diff --git a/graphics/pokemon/ogerpon/cornerstone/shiny.pal b/graphics/pokemon/ogerpon/cornerstone/shiny.pal index b4d7d15195..c4956ce774 100644 --- a/graphics/pokemon/ogerpon/cornerstone/shiny.pal +++ b/graphics/pokemon/ogerpon/cornerstone/shiny.pal @@ -2,12 +2,12 @@ JASC-PAL 0100 15 148 209 161 +0 0 0 42 44 41 21 158 7 -0 0 0 74 76 73 -25 27 24 61 113 53 +25 27 24 109 99 108 133 139 139 53 134 168 diff --git a/graphics/pokemon/ogerpon/front.png b/graphics/pokemon/ogerpon/front.png index 5fa971f873..dec38ef0b8 100644 Binary files a/graphics/pokemon/ogerpon/front.png and b/graphics/pokemon/ogerpon/front.png differ diff --git a/graphics/pokemon/ogerpon/hearthflame/back.png b/graphics/pokemon/ogerpon/hearthflame/back.png index 19d6656870..d6d927f19d 100644 Binary files a/graphics/pokemon/ogerpon/hearthflame/back.png and b/graphics/pokemon/ogerpon/hearthflame/back.png differ diff --git a/graphics/pokemon/ogerpon/hearthflame/front.png b/graphics/pokemon/ogerpon/hearthflame/front.png index 036ea37f32..d8b9cb7b23 100644 Binary files a/graphics/pokemon/ogerpon/hearthflame/front.png and b/graphics/pokemon/ogerpon/hearthflame/front.png differ diff --git a/graphics/pokemon/ogerpon/hearthflame/normal.pal b/graphics/pokemon/ogerpon/hearthflame/normal.pal index 637556660a..3f478af8aa 100644 --- a/graphics/pokemon/ogerpon/hearthflame/normal.pal +++ b/graphics/pokemon/ogerpon/hearthflame/normal.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 148 210 164 -156 153 172 -131 28 24 -49 133 172 -213 230 246 +0 0 0 41 44 41 +16 157 0 +230 60 49 +57 113 49 +49 133 172 +131 28 24 +213 230 246 255 198 74 172 105 32 -16 157 0 -57 113 49 +156 153 172 49 190 230 -0 0 0 164 52 49 74 76 74 189 137 90 -230 60 49 diff --git a/graphics/pokemon/ogerpon/hearthflame/shiny.pal b/graphics/pokemon/ogerpon/hearthflame/shiny.pal index f874367b4b..fee0f8de7b 100644 --- a/graphics/pokemon/ogerpon/hearthflame/shiny.pal +++ b/graphics/pokemon/ogerpon/hearthflame/shiny.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 148 210 164 -156 153 172 -131 28 24 -49 133 172 -213 230 246 +0 0 0 41 44 41 +16 157 0 +230 60 49 +57 113 49 +49 133 172 +131 28 24 +213 230 246 255 198 74 124 162 56 -16 157 0 -57 113 49 +156 153 172 49 190 230 -0 0 0 164 52 49 74 76 74 189 137 90 -230 60 49 diff --git a/graphics/pokemon/ogerpon/normal.pal b/graphics/pokemon/ogerpon/normal.pal index 8f715fd815..a1ac4baf96 100644 --- a/graphics/pokemon/ogerpon/normal.pal +++ b/graphics/pokemon/ogerpon/normal.pal @@ -2,17 +2,17 @@ JASC-PAL 0100 15 148 209 161 -42 44 41 0 1 0 -27 70 15 -0 164 153 -17 106 68 +42 44 41 21 158 7 +27 70 15 +61 113 53 +17 106 68 +83 133 90 74 76 73 -61 97 53 175 216 159 251 253 250 139 99 57 +0 164 153 120 81 39 219 157 92 -83 133 90 diff --git a/graphics/pokemon/ogerpon/shiny.pal b/graphics/pokemon/ogerpon/shiny.pal index a96c55d35d..08c751ebda 100644 --- a/graphics/pokemon/ogerpon/shiny.pal +++ b/graphics/pokemon/ogerpon/shiny.pal @@ -2,17 +2,17 @@ JASC-PAL 0100 15 148 209 161 -42 44 41 0 1 0 -27 70 15 -0 164 153 -17 106 68 +42 44 41 21 158 7 +27 70 15 +61 113 53 +17 106 68 +83 133 90 74 76 73 -61 97 53 175 216 159 251 253 250 139 99 57 +0 164 153 124 162 56 219 157 92 -83 133 90 diff --git a/graphics/pokemon/ogerpon/wellspring/back.png b/graphics/pokemon/ogerpon/wellspring/back.png index f1d5276baa..87d82032f4 100644 Binary files a/graphics/pokemon/ogerpon/wellspring/back.png and b/graphics/pokemon/ogerpon/wellspring/back.png differ diff --git a/graphics/pokemon/ogerpon/wellspring/front.png b/graphics/pokemon/ogerpon/wellspring/front.png index 5263ce2f1e..77ffb489a5 100644 Binary files a/graphics/pokemon/ogerpon/wellspring/front.png and b/graphics/pokemon/ogerpon/wellspring/front.png differ diff --git a/graphics/pokemon/ogerpon/wellspring/normal.pal b/graphics/pokemon/ogerpon/wellspring/normal.pal index 4b22619be4..db40508a52 100644 --- a/graphics/pokemon/ogerpon/wellspring/normal.pal +++ b/graphics/pokemon/ogerpon/wellspring/normal.pal @@ -2,12 +2,12 @@ JASC-PAL 0100 16 148 209 161 +0 0 0 42 44 41 21 158 7 -74 76 73 -0 0 0 -61 113 53 11 64 121 +61 113 53 +74 76 73 15 90 170 0 126 229 53 134 168 diff --git a/graphics/pokemon/ogerpon/wellspring/shiny.pal b/graphics/pokemon/ogerpon/wellspring/shiny.pal index bca722c95d..7c44d3352d 100644 --- a/graphics/pokemon/ogerpon/wellspring/shiny.pal +++ b/graphics/pokemon/ogerpon/wellspring/shiny.pal @@ -2,12 +2,12 @@ JASC-PAL 0100 16 148 209 161 +0 0 0 42 44 41 21 158 7 -74 76 73 -0 0 0 -61 113 53 11 64 121 +61 113 53 +74 76 73 15 90 170 0 126 229 53 134 168 diff --git a/graphics/pokemon/sandile/anim_front.png b/graphics/pokemon/sandile/anim_front.png index 24d3545a42..ccf8146b3b 100644 Binary files a/graphics/pokemon/sandile/anim_front.png and b/graphics/pokemon/sandile/anim_front.png differ diff --git a/graphics/pokemon/sandile/back.png b/graphics/pokemon/sandile/back.png index 1680947040..0bf5c9e3f4 100644 Binary files a/graphics/pokemon/sandile/back.png and b/graphics/pokemon/sandile/back.png differ diff --git a/graphics/pokemon/sandile/normal.pal b/graphics/pokemon/sandile/normal.pal index b079c8061a..f428787e3c 100644 --- a/graphics/pokemon/sandile/normal.pal +++ b/graphics/pokemon/sandile/normal.pal @@ -1,6 +1,6 @@ JASC-PAL 0100 -16 +13 152 208 160 139 115 49 32 32 32 @@ -12,8 +12,5 @@ JASC-PAL 180 180 189 82 82 98 205 115 123 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 +205 115 123 +169 92 99 diff --git a/graphics/pokemon/sandile/shiny.pal b/graphics/pokemon/sandile/shiny.pal index f92d5f6bd0..b1a758254b 100644 --- a/graphics/pokemon/sandile/shiny.pal +++ b/graphics/pokemon/sandile/shiny.pal @@ -1,6 +1,6 @@ JASC-PAL 0100 -16 +13 152 208 160 120 136 56 32 32 32 @@ -12,8 +12,5 @@ JASC-PAL 176 168 168 80 80 96 64 144 160 -0 0 0 -0 0 0 -0 0 0 -0 0 0 -0 0 0 +205 115 123 +169 92 99 diff --git a/include/battle_util.h b/include/battle_util.h index 644a112d7d..118ef8c6b3 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -146,7 +146,7 @@ bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility) u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 moveArg); bool32 TryPrimalReversion(u32 battler); bool32 IsNeutralizingGasOnField(void); -bool32 IsMoldBreakerTypeAbility(u32 ability); +bool32 IsMoldBreakerTypeAbility(u32 battler, u32 ability); u32 GetBattlerAbility(u32 battler); u32 IsAbilityOnSide(u32 battler, u32 ability); u32 IsAbilityOnOpposingSide(u32 battler, u32 ability); diff --git a/include/constants/battle_anim.h b/include/constants/battle_anim.h index 8bc09ba530..8e225e2bc8 100644 --- a/include/constants/battle_anim.h +++ b/include/constants/battle_anim.h @@ -405,6 +405,10 @@ #define ANIM_TAG_SYRUP_SHELL_YELLOW (ANIM_SPRITES_START + 391) #define ANIM_TAG_SYRUP_SPLAT_RED (ANIM_SPRITES_START + 392) #define ANIM_TAG_SYRUP_SPLAT_YELLOW (ANIM_SPRITES_START + 393) +#define ANIM_TAG_IVY_CUDGEL_GRASS (ANIM_SPRITES_START + 394) +#define ANIM_TAG_IVY_CUDGEL_FIRE (ANIM_SPRITES_START + 395) +#define ANIM_TAG_IVY_CUDGEL_ROCK (ANIM_SPRITES_START + 396) +#define ANIM_TAG_IVY_CUDGEL_WATER (ANIM_SPRITES_START + 397) // battlers #define ANIM_ATTACKER 0 diff --git a/include/constants/field_weather.h b/include/constants/field_weather.h index e84dbc48c4..fe7eb6a1ae 100644 --- a/include/constants/field_weather.h +++ b/include/constants/field_weather.h @@ -8,6 +8,7 @@ #define NUM_FOG_DIAGONAL_SPRITES 20 #define NUM_SANDSTORM_SPRITES 20 #define NUM_SWIRL_SANDSTORM_SPRITES 5 +#define NUM_SNOWFLAKE_SPRITES 16 // Controls how the weather should be changing the screen palettes. #define WEATHER_PAL_STATE_CHANGING_WEATHER 0 diff --git a/include/graphics.h b/include/graphics.h index 2ec513bf91..db91f253cc 100644 --- a/include/graphics.h +++ b/include/graphics.h @@ -2865,6 +2865,11 @@ extern const u32 gBattleAnimSpriteGfx_SyrupShell[]; extern const u32 gBattleAnimSpriteGfx_SyrupSplat[]; extern const u32 gBattleAnimSpritePal_SyrupRed[]; extern const u32 gBattleAnimSpritePal_SyrupYellow[]; +extern const u32 gBattleAnimSpriteGfx_IvyCudgel[]; +extern const u32 gBattleAnimSpritePal_IvyCudgelGrass[]; +extern const u32 gBattleAnimSpritePal_IvyCudgelFire[]; +extern const u32 gBattleAnimSpritePal_IvyCudgelRock[]; +extern const u32 gBattleAnimSpritePal_IvyCudgelWater[]; extern const u32 gBattleAnimBgImage_Dark[]; extern const u32 gBattleAnimBgImage_Ghost[]; diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index b9770ba950..1498d8936c 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1188,7 +1188,7 @@ bool32 DoesBattlerIgnoreAbilityChecks(u32 atkAbility, u32 move) if (AI_THINKING_STRUCT->aiFlags[sBattler_AI] & AI_FLAG_NEGATE_UNAWARE) return FALSE; // AI handicap flag: doesn't understand ability suppression concept - if (IsMoldBreakerTypeAbility(atkAbility) || gMovesInfo[move].ignoresTargetAbility) + if (IsMoldBreakerTypeAbility(sBattler_AI, atkAbility) || gMovesInfo[move].ignoresTargetAbility) return TRUE; return FALSE; @@ -2766,7 +2766,7 @@ bool32 AI_CanBeInfatuated(u32 battlerAtk, u32 battlerDef, u32 defAbility) u32 ShouldTryToFlinch(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbility, u32 move) { - if (((!IsMoldBreakerTypeAbility(AI_DATA->abilities[battlerAtk]) && (defAbility == ABILITY_SHIELD_DUST || defAbility == ABILITY_INNER_FOCUS)) + if (((!IsMoldBreakerTypeAbility(battlerAtk, AI_DATA->abilities[battlerAtk]) && (defAbility == ABILITY_SHIELD_DUST || defAbility == ABILITY_INNER_FOCUS)) || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_COVERT_CLOAK || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) || AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_SLOWER)) // Opponent goes first @@ -2809,7 +2809,7 @@ bool32 ShouldFakeOut(u32 battlerAtk, u32 battlerDef, u32 move) || AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_CHOICE_BAND || AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_COVERT_CLOAK || DoesSubstituteBlockMove(battlerAtk, battlerDef, move) - || (!IsMoldBreakerTypeAbility(AI_DATA->abilities[battlerAtk]) + || (!IsMoldBreakerTypeAbility(battlerAtk, AI_DATA->abilities[battlerAtk]) && (AI_DATA->abilities[battlerDef] == ABILITY_SHIELD_DUST || AI_DATA->abilities[battlerDef] == ABILITY_INNER_FOCUS))) return FALSE; diff --git a/src/battle_anim.c b/src/battle_anim.c index 77f16cd3d7..f869dc1eae 100644 --- a/src/battle_anim.c +++ b/src/battle_anim.c @@ -86,6 +86,7 @@ static void Cmd_stopsound(void); static void Cmd_createvisualtaskontargets(void); static void Cmd_createspriteontargets(void); static void Cmd_createspriteontargets_onpos(void); +static void Cmd_jumpifmovetypeequal(void); static void RunAnimScriptCommand(void); static void Task_UpdateMonBg(u8 taskId); static void FlipBattlerBgTiles(void); @@ -177,6 +178,7 @@ static void (* const sScriptCmdTable[])(void) = Cmd_createvisualtaskontargets, // 0x30 Cmd_createspriteontargets, // 0x31 Cmd_createspriteontargets_onpos, // 0x32 + Cmd_jumpifmovetypeequal, // 0x33 }; void ClearBattleAnimationVars(void) @@ -2136,3 +2138,16 @@ static void Cmd_stopsound(void) m4aMPlayStop(&gMPlayInfo_SE2); sBattleAnimScriptPtr++; } + +static void Cmd_jumpifmovetypeequal(void) +{ + u8 moveType; + const u8 *type = sBattleAnimScriptPtr + 1; + sBattleAnimScriptPtr += 2; + GET_MOVE_TYPE(gCurrentMove, moveType); + + if (*type != moveType) + sBattleAnimScriptPtr += 4; + else + sBattleAnimScriptPtr = T2_READ_PTR(sBattleAnimScriptPtr); +} diff --git a/src/battle_anim_effects_1.c b/src/battle_anim_effects_1.c index abcdd44c35..f3cb387dd2 100644 --- a/src/battle_anim_effects_1.c +++ b/src/battle_anim_effects_1.c @@ -2958,6 +2958,50 @@ const struct SpriteTemplate gWoodHammerHammerSpriteTemplate = .callback = AnimWoodHammerHammer, }; +const struct SpriteTemplate gIvyCudgelSpriteTemplate = +{ + .tileTag = ANIM_TAG_IVY_CUDGEL_GRASS, + .paletteTag = ANIM_TAG_IVY_CUDGEL_GRASS, + .oam = &gOamData_AffineDouble_ObjNormal_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gWoodHammerHammerAffineAnims, + .callback = AnimWoodHammerHammer, +}; + +const struct SpriteTemplate gIvyCudgelFireSpriteTemplate = +{ + .tileTag = ANIM_TAG_IVY_CUDGEL_GRASS, + .paletteTag = ANIM_TAG_IVY_CUDGEL_FIRE, + .oam = &gOamData_AffineDouble_ObjNormal_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gWoodHammerHammerAffineAnims, + .callback = AnimWoodHammerHammer, +}; + +const struct SpriteTemplate gIvyCudgelRockSpriteTemplate = +{ + .tileTag = ANIM_TAG_IVY_CUDGEL_GRASS, + .paletteTag = ANIM_TAG_IVY_CUDGEL_ROCK, + .oam = &gOamData_AffineDouble_ObjNormal_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gWoodHammerHammerAffineAnims, + .callback = AnimWoodHammerHammer, +}; + +const struct SpriteTemplate gIvyCudgelWaterSpriteTemplate = +{ + .tileTag = ANIM_TAG_IVY_CUDGEL_GRASS, + .paletteTag = ANIM_TAG_IVY_CUDGEL_WATER, + .oam = &gOamData_AffineDouble_ObjNormal_64x64, + .anims = gDummySpriteAnimTable, + .images = NULL, + .affineAnims = gWoodHammerHammerAffineAnims, + .callback = AnimWoodHammerHammer, +}; + const struct SpriteTemplate gJudgmentGrayOutwardSpikesTemplate = { .tileTag = ANIM_TAG_GREEN_SPIKE, diff --git a/src/battle_debug.c b/src/battle_debug.c index 4e9d5ecf29..671a9057ef 100644 --- a/src/battle_debug.c +++ b/src/battle_debug.c @@ -116,6 +116,136 @@ enum LIST_ITEM_COUNT }; +enum +{ + LIST_STAT_HP_CURRENT, + LIST_STAT_HP_MAX, + LIST_STAT_ATTACK, + LIST_STAT_DEFENSE, + LIST_STAT_SPEED, + LIST_STAT_SP_ATK, + LIST_STAT_SP_DEF, +}; + +enum +{ + LIST_STATUS1_SLEEP, + LIST_STATUS1_POISON, + LIST_STATUS1_BURN, + LIST_STATUS1_FREEZE, + LIST_STATUS1_PARALYSIS, + LIST_STATUS1_TOXIC_POISON, + LIST_STATUS1_TOXIC_COUNTER, + LIST_STATUS1_FROSTBITE, +}; + +enum +{ + LIST_STATUS2_CONFUSION, + LIST_STATUS2_FLINCHED, + LIST_STATUS2_TORMENT, + LIST_STATUS2_POWDER, + LIST_STATUS2_DEFENSE_CURL, + LIST_STATUS2_RECHARGE, + LIST_STATUS2_RAGE, + LIST_STATUS2_DESTINY_BOND, + LIST_STATUS2_ESCAPE_PREVENTION, + LIST_STATUS2_CURSED, + LIST_STATUS2_FORESIGHT, + LIST_STATUS2_DRAGON_CHEER, + LIST_STATUS2_FOCUS_ENERGY +}; + +enum +{ + LIST_STATUS3_LEECH_SEED_HEALER, + LIST_STATUS3_LEECH_SEEDED, + LIST_STATUS3_ALWAYS_HITS, + LIST_STATUS3_PERISH_SONG, + LIST_STATUS3_ON_AIR, + LIST_STATUS3_UNDERGROUND, + LIST_STATUS3_MINIMIZED, + LIST_STATUS3_CHARGED_UP, + LIST_STATUS3_ROOTED, + LIST_STATUS3_YAWN, + LIST_STATUS3_IMPRISONED_OTHERS, + LIST_STATUS3_GRUDGE, + LIST_STATUS3_GASTRO_ACID, + LIST_STATUS3_EMBARGO, + LIST_STATUS3_UNDERWATER, + LIST_STATUS3_SMACKED_DOWN, + LIST_STATUS3_TELEKINESIS, + LIST_STATUS3_MIRACLE_EYED, + LIST_STATUS3_MAGNET_RISE, + LIST_STATUS3_HEAL_BLOCK, + LIST_STATUS3_AQUA_RING, + LIST_STATUS3_LASER_FOCUS, + LIST_STATUS3_POWER_TRICK, +}; + +enum +{ + LIST_STATUS4_ELECTRIFIED, + LIST_STATUS4_MUD_SPORT, + LIST_STATUS4_WATER_SPORT, + LIST_STATUS4_SALT_CURE, + LIST_STATUS4_SYRUP_BOMB, + LIST_STATUS4_GLAIVE_RUSH, +}; + +enum +{ + LIST_SIDE_REFLECT, + LIST_SIDE_LIGHTSCREEN, + LIST_SIDE_STICKY_WEB, + LIST_SIDE_SPIKES, + LIST_SIDE_SAFEGUARD, + LIST_SIDE_MIST, + LIST_SIDE_TAILWIND, + LIST_SIDE_AURORA_VEIL, + LIST_SIDE_LUCKY_CHANT, + LIST_SIDE_TOXIC_SPIKES, + LIST_SIDE_STEALTH_ROCK, + LIST_SIDE_STEELSURGE, + LIST_SIDE_DAMAGE_NON_TYPES, + LIST_SIDE_RAINBOW, + LIST_SIDE_SEA_OF_FIRE, + LIST_SIDE_SWAMP, +}; + +enum +{ + LIST_AI_CHECK_BAD_MOVE, + LIST_AI_TRY_TO_FAINT, + LIST_AI_CHECK_VIABILITY, + LIST_AI_SETUP_FIRST_TURN, + LIST_AI_RISKY, + LIST_AI_PREFER_STRONGEST_MOVE, + LIST_AI_PREFER_BATON_PASS, + LIST_AI_DOUBLE_BATTLE, + LIST_AI_HP_AWARE, + LIST_AI_POWERFUL_STATUS, + LIST_AI_NEGATE_UNAWARE, + LIST_AI_WILL_SUICIDE, + LIST_AI_HELP_PARTNER, + LIST_AI_PREFER_STATUS_MOVES, + LIST_AI_STALL, + LIST_AI_SMART_SWITCHING, + LIST_AI_ACE_POKEMON, + LIST_AI_OMNISCIENT, + LIST_AI_SMART_MON_CHOICES, + LIST_AI_ROAMING, + LIST_AI_SAFARI, + LIST_AI_FIRST_BATTLE, +}; + +enum +{ + VARIOUS_SHOW_HP, + VARIOUS_SUBSTITUTE_HP, + VARIOUS_IN_LOVE, +}; + enum { ACTIVE_WIN_MAIN, @@ -140,114 +270,142 @@ enum VAL_ALL_STAT_STAGES, }; -enum -{ - LIST_SIDE_REFLECT, - LIST_SIDE_LIGHTSCREEN, - LIST_SIDE_SPIKES, - LIST_SIDE_SAFEGUARD, - LIST_SIDE_MIST, - LIST_SIDE_AURORA_VEIL, - LIST_SIDE_LUCKY_CHANT, - LIST_SIDE_TAILWIND, - LIST_SIDE_STEALTH_ROCK, - LIST_SIDE_TOXIC_SPIKES, - LIST_SIDE_STICKY_WEB, - LIST_SIDE_STEELSURGE, -}; - -enum -{ - VARIOUS_SHOW_HP, - VARIOUS_SUBSTITUTE_HP, - VARIOUS_IN_LOVE, -}; - // Static Declarations static const u8 *GetHoldEffectName(u16 holdEffect); // const rom data -static const u8 sText_HoldEffect[] = _("Hold Effect"); -static const u8 sText_Ability[] = _("Ability"); static const u8 sText_Moves[] = _("Moves"); +static const u8 sText_Ability[] = _("Ability"); +static const u8 sText_HeldItem[] = _("Held Item"); +static const u8 sText_HoldEffect[] = _("Hold Effect"); +static const u8 sText_PP[] = _("PP"); +static const u8 sText_Types[] = _("Types"); static const u8 sText_Stats[] = _("Stats"); static const u8 sText_StatStages[] = _("Stat Stages"); static const u8 sText_Status1[] = _("Status1"); static const u8 sText_Status2[] = _("Status2"); static const u8 sText_Status3[] = _("Status3"); static const u8 sText_Status4[] = _("Status4"); -static const u8 sText_HeldItem[] = _("Held Item"); static const u8 sText_SideStatus[] = _("Side Status"); -static const u8 sText_MaxHp[] = _("HP Max"); +static const u8 sText_AI[] = _("AI"); +static const u8 sText_AIMovePts[] = _("AI Pts/Dmg"); +static const u8 sText_AiKnowledge[] = _("AI Info"); +static const u8 sText_AiParty[] = _("AI Party"); +static const u8 sText_Various[] = _("Various"); static const u8 sText_CurrHp[] = _("HP Current"); +static const u8 sText_MaxHp[] = _("HP Max"); +static const u8 sText_Attack[] = _("Attack"); +static const u8 sText_Defense[] = _("Defense"); +static const u8 sText_Speed[] = _("Speed"); +static const u8 sText_SpAtk[] = _("Sp. Atk"); +static const u8 sText_SpDef[] = _("Sp. Def"); +static const u8 sText_Sleep[] = _("Sleep"); +static const u8 sText_Poison[] = _("Poison"); +static const u8 sText_Burn[] = _("Burn"); static const u8 sText_Freeze[] = _("Freeze"); -static const u8 sText_Frostbite[] = _("Frostbite"); +static const u8 sText_Paralysis[] = _("Paralysis"); static const u8 sText_ToxicPoison[] = _("Toxic Poison"); static const u8 sText_ToxicCounter[] = _("Toxic Counter"); -static const u8 sText_Flinch[] = _("Flinch"); +static const u8 sText_Frostbite[] = _("Frostbite"); +static const u8 sText_Confusion[] = _("Confusion"); +static const u8 sText_Flinched[] = _("Flinched"); static const u8 sText_Uproar[] = _("Uproar"); +static const u8 sText_Torment[] = _("Torment"); static const u8 sText_Bide[] = _("Bide"); static const u8 sText_LockConfuse[] = _("Lock Confuse"); -static const u8 sText_MultipleTurns[] = _("MultipleTurns"); -static const u8 sText_FocusEnergy[] = _("Focus Energy"); +static const u8 sText_MultipleTurns[] = _("Multiple Turns"); +static const u8 sText_Wrapped[] = _("Wrapped"); +static const u8 sText_Powder[] = _("Powder"); +static const u8 sText_Infatuation[] = _("Infatuation"); +static const u8 sText_DefenseCurl[] = _("Defense Curl"); static const u8 sText_Transformed[] = _("Transformed"); static const u8 sText_Recharge[] = _("Recharge"); static const u8 sText_Rage[] = _("Rage"); static const u8 sText_Substitute[] = _("Substitute"); -static const u8 sText_SubstituteHp[] = _("Substitute HP"); static const u8 sText_DestinyBond[] = _("Destiny Bond"); -static const u8 sText_CantEscape[] = _("Cant Escape"); +static const u8 sText_EscapePrevention[] = _("Escape Prevention"); static const u8 sText_Nightmare[] = _("Nightmare"); static const u8 sText_Cursed[] = _("Cursed"); -static const u8 sText_Foresight[] = _("Foresighted"); -static const u8 sText_DefenseCurl[] = _("Def Curled"); -static const u8 sText_Tormented[] = _("Tormented"); -static const u8 sText_AlwaysHits[] = _("Sure Hit"); +static const u8 sText_Foresight[] = _("Foresight"); +static const u8 sText_DragonCheer[] = _("Dragon Cheer"); +static const u8 sText_FocusEnergy[] = _("Focus Energy"); +static const u8 sText_LeechSeedHealer[] = _("Leech Seed Healer"); +static const u8 sText_LeechSeeded[] = _("Leech Seeded"); +static const u8 sText_AlwaysHits[] = _("Always Hits"); +static const u8 sText_PerishSong[] = _("Perish Song"); +static const u8 sText_OnAir[] = _("On Air"); +static const u8 sText_Underground[] = _("Underground"); +static const u8 sText_Minimized[] = _("Minimized"); static const u8 sText_ChargedUp[] = _("Charged Up"); static const u8 sText_Rooted[] = _("Rooted"); -static const u8 sText_Yawned[] = _("Yawned"); -static const u8 sText_Minimized[] = _("Minimized"); -static const u8 sText_NoCrit[] = _("No Crit"); -static const u8 sText_Imprisoned[] = _("Imprison"); +static const u8 sText_Yawn[] = _("Yawn"); +static const u8 sText_ImprisonedOthers[] = _("Imprisoned Others"); +static const u8 sText_Grudge[] = _("Grudge"); +static const u8 sText_GastroAcid[] = _("Gastro Acid"); +static const u8 sText_Embargo[] = _("Embargo"); +static const u8 sText_Underwater[] = _("Underwater"); +static const u8 sText_Trace[] = _("Trace"); +static const u8 sText_SmackedDown[] = _("Smacked Down"); +static const u8 sText_MeFirst[] = _("Me First"); +static const u8 sText_Telekinesis[] = _("Telekinesis"); +static const u8 sText_PhantomForce[] = _("Phantom Force"); +static const u8 sText_MiracleEyed[] = _("Miracle Eyed"); +static const u8 sText_MagnetRise[] = _("Magnet Rise"); +static const u8 sText_HealBlock[] = _("Heal Block"); +static const u8 sText_AquaRing[] = _("Aqua Ring"); +static const u8 sText_LaserFocus[] = _("Laser Focus"); +static const u8 sText_PowerTrick[] = _("Power Trick"); +static const u8 sText_SkyDropped[] = _("Sky Dropped"); +static const u8 sText_Electrified[] = _("Electrified"); +static const u8 sText_MudSport[] = _("Mud Sport"); +static const u8 sText_WaterSport[] = _("Water Sport"); +static const u8 sText_InfiniteConfusion[] = _("Infinite Confusion"); +static const u8 sText_SaltCure[] = _("Salt Cure"); +static const u8 sText_SyrupBomb[] = _("Syrup Bomb"); +static const u8 sText_GlaiveRush[] = _("Glaive Rush"); static const u8 sText_Reflect[] = _("Reflect"); static const u8 sText_LightScreen[] = _("Light Screen"); +static const u8 sText_StickyWeb[] = _("Sticky Web"); static const u8 sText_Spikes[] = _("Spikes"); static const u8 sText_Safeguard[] = _("Safeguard"); +static const u8 sText_FutureAttack[] = _("Future Attack"); static const u8 sText_Mist[] = _("Mist"); -static const u8 sText_ShowOpponentHP[] = _("Opponent Hp"); -static const u8 sText_Types[] = _("Types"); -static const u8 sText_GastroAcid[] = _("Gastro Acid"); -static const u8 sText_SmackDown[] = _("Smacked Down"); -static const u8 sText_MiracleEye[] = _("Miracle Eye"); -static const u8 sText_AquaRing[] = _("Aqua Ring"); -static const u8 sText_LaserFocus[] = _("Laser Focused"); -static const u8 sText_Electrified[] = _("Electrified"); +static const u8 sText_Tailwind[] = _("Tailwind"); static const u8 sText_AuroraVeil[] = _("Aurora Veil"); static const u8 sText_LuckyChant[] = _("Lucky Chant"); -static const u8 sText_Tailwind[] = _("Tailwind"); -static const u8 sText_PP[] = _("PP"); -static const u8 sText_StealthRock[] = _("Stealth Rock"); static const u8 sText_ToxicSpikes[] = _("Toxic Spikes"); -static const u8 sText_StickyWeb[] = _("Sticky Web"); +static const u8 sText_StealthRock[] = _("Stealth Rock"); static const u8 sText_Steelsurge[] = _("Steelsurge"); -static const u8 sText_AI[] = _("AI"); -static const u8 sText_NoBadMoves[] = _("No Bad Moves"); -static const u8 sText_Viability[] = _("Viability"); -static const u8 sText_TryFaint[] = _("Try Faint"); -static const u8 sText_SetUpFirstTurn[] = _("Setup 1 turn"); +static const u8 sText_DamageNonTypes[] = _("Damage Non-Types"); +static const u8 sText_Rainbow[] = _("Rainbow"); +static const u8 sText_SeaOfFire[] = _("Sea of Fire"); +static const u8 sText_Swamp[] = _("Swamp"); +static const u8 sText_CheckBadMove[] = _("Check Bad Move"); +static const u8 sText_TryToFaint[] = _("Try to Faint"); +static const u8 sText_CheckViability[] = _("Check Viability"); +static const u8 sText_SetUpFirstTurn[] = _("Setup First Turn"); static const u8 sText_Risky[] = _("Risky"); -static const u8 sText_StrongestMove[] = _("Most dmg move"); -static const u8 sText_Various[] = _("Various"); +static const u8 sText_PreferStrongestMove[] = _("Prefer Strongest Move"); +static const u8 sText_PreferBatonPass[] = _("Prefer Baton Pass"); +static const u8 sText_DoubleBattle[] = _("Double Battle"); +static const u8 sText_HpAware[] = _("HP Aware"); +static const u8 sText_PowerfulStatus[] = _("Powerful Status"); +static const u8 sText_NegateUnaware[] = _("Negate Unaware"); +static const u8 sText_WillSuicide[] = _("Will Suicide"); +static const u8 sText_HelpPartner[] = _("Help Partner"); +static const u8 sText_PreferStatusMoves[] = _("Prefer Status Moves"); +static const u8 sText_Stall[] = _("Stall"); +static const u8 sText_SmartSwitching[] = _("Smart Switching"); +static const u8 sText_AcePokemon[] = _("Ace Pokemon"); +static const u8 sText_Omniscient[] = _("Omniscient"); +static const u8 sText_SmartMonChoices[] = _("Smart Mon Choices"); +static const u8 sText_Roaming[] = _("Roaming"); +static const u8 sText_Safari[] = _("Safari"); +static const u8 sText_FirstBattle[] = _("First Battle"); static const u8 sText_ShowHP[] = _("Show HP"); -static const u8 sText_PreferBatonPass[] = _("Baton Pass"); -static const u8 sText_InDoubles[] = _("In Doubles"); -static const u8 sText_HpAware[] = _("HP aware"); -static const u8 sText_Unknown[] = _("Unknown"); +static const u8 sText_SubstituteHp[] = _("Substitute HP"); static const u8 sText_InLove[] = _("In Love"); -static const u8 sText_AIMovePts[] = _("AI Pts/Dmg"); -static const u8 sText_AiKnowledge[] = _("AI Info"); -static const u8 sText_AiParty[] = _("AI Party"); - +static const u8 sText_Unknown[] = _("Unknown"); static const u8 sText_EmptyString[] = _(""); static const struct BitfieldInfo sStatus1Bitfield[] = @@ -265,78 +423,86 @@ static const struct BitfieldInfo sStatus1Bitfield[] = static const struct BitfieldInfo sStatus2Bitfield[] = { {/*Confusion*/ 3, 0}, - {/*Flinch*/ 1, 3}, - {/*Uproar*/ 3, 4}, - // Bit 7 is unused. - {/*Bide*/ 2, 8}, - {/*Lock Confuse*/ 2, 10}, - {/*Multiple Turns*/ 1, 12}, - // Wrap bits are omitted. Done in various. - // In Love bits are omitted. Done in various. - {/*(Focus Energy*/ 1, 20}, - {/*Transformed*/ 1, 21}, + {/*Flinched*/ 1, 3}, + {/*Torment*/ 1, 7}, + {/*Powder*/ 1, 14}, + {/*Defense Curl*/ 1, 20}, {/*Recharge*/ 1, 22}, {/*Rage*/ 1, 23}, - {/*Substitute*/ 1, 24}, - {/*Destiny bond*/ 1, 25}, - {/*Can't escape*/ 1, 26}, - {/*Nightmares*/ 1, 27}, + {/*Destiny Bond*/ 1, 25}, + {/*Escape Prevention*/ 1, 26}, {/*Cursed*/ 1, 28}, - {/*Foresighted*/ 1, 29}, - {/*Defense Curled*/ 1, 30}, - {/*Tormented*/ 1, 31}, + {/*Foresight*/ 1, 29}, + {/*Dragon Cheer*/ 1, 30}, + {/*Focus Energy*/ 1, 31}, }; static const struct BitfieldInfo sStatus3Bitfield[] = { - {/*Always hits*/ 2, 4}, - //*Perish Song*/ 1, 5}, - // On Air 1, 6, - // Underground 1, 7, + {/*Leech Seed Battler*/ 2, 0}, + {/*Leech Seed*/ 1, 2}, + {/*Always Hits*/ 2, 3}, + {/*Perish Song*/ 1, 5}, + {/*On Air*/ 1, 6}, + {/*Underground*/ 1, 7}, {/*Minimized*/ 1, 8}, {/*Charged Up*/ 1, 9}, {/*Rooted*/ 1, 10}, {/*Yawn*/ 2, 11}, - {/*Imprison*/ 1, 13}, - // Grudge 1, 14, - {/*No Crit*/ 1, 15}, + {/*Imprisoned Others*/ 1, 13}, + {/*Grudge*/ 1, 14}, {/*Gastro Acid*/ 1, 16}, - // Embargo 1, 17, - // Underwater 1, 18, - // Intimidated Mons 1, 19, - // Traced 1, 20, + {/*Embargo*/ 1, 17}, + {/*Underwater*/ 1, 18}, {/*Smacked Down*/ 1, 21}, - // Me First 1, 22, - // Telekinesis 1, 23, - // Phantom Force 1, 24}, + {/*Telekinesis*/ 1, 23}, {/*Miracle Eyed*/ 1, 25}, - // Magnet Rise 1, 26, - // Heal Block 1, 27, + {/*Magnet Rise*/ 1, 26}, + {/*Heal Blocked*/ 1, 27}, {/*Aqua Ring*/ 1, 28}, {/*Laser Focus*/ 1, 29}, - // Power Trick 1, 30, + {/*Power Trick*/ 1, 30}, }; static const struct BitfieldInfo sStatus4Bitfield[] = { - {/*Electrified*/ 1, 0,} + {/*Electrified*/ 1, 0}, + {/*Mud Sport*/ 1, 1}, + {/*Water Sport*/ 1, 2}, + {/*Salt Cure*/ 1, 4}, + {/*Syrup Bomb*/ 1, 5}, + {/*Glaive Rush*/ 1, 6}, }; static const struct BitfieldInfo sAIBitfield[] = { - {/*Check bad move*/ 1, 0}, - {/*Try To Faint*/ 1, 1}, - {/*Viability*/ 1, 2}, - {/*Set up first turn*/ 1, 3}, + {/*Check Bad Move*/ 1, 0}, + {/*Try to Faint*/ 1, 1}, + {/*Check Viability*/ 1, 2}, + {/*Setup First Turn*/ 1, 3}, {/*Risky*/ 1, 4}, {/*Prefer Strongest Move*/ 1, 5}, {/*Prefer Baton Pass*/ 1, 6}, - {/*In Doubles*/ 1, 7}, - {/*Hp aware*/ 1, 8}, - {/*Unknown*/ 1, 9}, + {/*Double Battle*/ 1, 7}, + {/*HP Aware*/ 1, 8}, + {/*Powerful Status*/ 1, 9}, + {/*Negate Unaware*/ 1, 10}, + {/*Will Suicide*/ 1, 11}, + {/*Help Partner*/ 1, 12}, + {/*Prefer Status Moves*/ 1, 13}, + {/*Stall*/ 1, 14}, + {/*Smart Switching*/ 1, 15}, + {/*Ace Pokemon*/ 1, 16}, + {/*Omniscient*/ 1, 17}, + {/*Smart Mon Choices*/ 1, 18}, + {/*Ace Pokemon*/ 1, 16}, + {/*Omniscient*/ 1, 17}, + {/*Smart Mon Choices*/ 1, 18}, + {/*Roaming*/ 1, 29}, + {/*Safari*/ 1, 30}, + {/*First Battle*/ 1, 31}, }; - static const struct ListMenuItem sMainListItems[] = { {sText_Moves, LIST_ITEM_MOVES}, @@ -358,106 +524,134 @@ static const struct ListMenuItem sMainListItems[] = {sText_Various, LIST_ITEM_VARIOUS}, }; -static const struct ListMenuItem sVariousListItems[] = -{ - {sText_ShowHP, VARIOUS_SHOW_HP}, - {sText_SubstituteHp, VARIOUS_SUBSTITUTE_HP}, - {sText_InLove, VARIOUS_IN_LOVE}, -}; - -static const struct ListMenuItem sAIListItems[] = -{ - {sText_NoBadMoves, 0}, - {sText_TryFaint, 1}, - {sText_Viability, 2}, - {sText_SetUpFirstTurn, 3}, - {sText_Risky, 4}, - {sText_StrongestMove, 5}, - {sText_PreferBatonPass, 6}, - {sText_InDoubles, 7}, - {sText_HpAware, 8}, - // {sText_Unknown, 9}, -}; - static const struct ListMenuItem sStatsListItems[] = { - {sText_CurrHp, 0}, - {sText_MaxHp, 1}, - {gText_Attack, 2}, - {gText_Defense, 3}, - {gText_Speed, 4}, - {gText_SpAtk, 5}, - {gText_SpDef, 6}, + {sText_CurrHp, LIST_STAT_HP_CURRENT}, + {sText_MaxHp, LIST_STAT_HP_MAX}, + {sText_Attack, LIST_STAT_ATTACK}, + {sText_Defense, LIST_STAT_DEFENSE}, + {sText_Speed, LIST_STAT_SPEED}, + {sText_SpAtk, LIST_STAT_SP_ATK}, + {sText_SpDef, LIST_STAT_SP_DEF}, }; static const struct ListMenuItem sStatus1ListItems[] = { - {gText_Sleep, 0}, - {gText_Poison, 1}, - {gText_Burn, 2}, - {sText_Freeze, 3}, - {gText_Paralysis, 4}, - {sText_ToxicPoison, 5}, - {sText_ToxicCounter, 6}, - {sText_Frostbite, 7}, + {sText_Sleep, LIST_STATUS1_SLEEP}, + {sText_Poison, LIST_STATUS1_POISON}, + {sText_Burn, LIST_STATUS1_BURN}, + {sText_Freeze, LIST_STATUS1_FREEZE}, + {sText_Paralysis, LIST_STATUS1_PARALYSIS}, + {sText_ToxicPoison, LIST_STATUS1_TOXIC_POISON}, + {sText_ToxicCounter, LIST_STATUS1_TOXIC_COUNTER}, + {sText_Frostbite, LIST_STATUS1_FROSTBITE}, }; static const struct ListMenuItem sStatus2ListItems[] = { - {gText_Confusion, 0}, - {sText_Flinch, 1}, - {sText_Uproar, 2}, - {sText_Bide, 3}, - {sText_LockConfuse, 4}, - {sText_MultipleTurns, 5}, - {sText_FocusEnergy, 6}, - {sText_Recharge, 7}, - {sText_Rage, 8}, - {sText_Substitute, 9}, - {sText_DestinyBond, 10}, - {sText_CantEscape, 11}, - {sText_Nightmare, 12}, - {sText_Cursed, 13}, - {sText_Foresight, 14}, - {sText_DefenseCurl, 15}, - {sText_Tormented, 16}, + {sText_Confusion, LIST_STATUS2_CONFUSION}, + {sText_Flinched, LIST_STATUS2_FLINCHED}, + {sText_Torment, LIST_STATUS2_TORMENT}, + {sText_Powder, LIST_STATUS2_POWDER}, + {sText_DefenseCurl, LIST_STATUS2_DEFENSE_CURL}, + {sText_Recharge, LIST_STATUS2_RECHARGE}, + {sText_Rage, LIST_STATUS2_RAGE}, + {sText_DestinyBond, LIST_STATUS2_DESTINY_BOND}, + {sText_EscapePrevention, LIST_STATUS2_ESCAPE_PREVENTION}, + {sText_Cursed, LIST_STATUS2_CURSED}, + {sText_Foresight, LIST_STATUS2_FORESIGHT}, + {sText_DragonCheer, LIST_STATUS2_DRAGON_CHEER}, + {sText_FocusEnergy, LIST_STATUS2_FOCUS_ENERGY}, }; static const struct ListMenuItem sStatus3ListItems[] = { - {sText_AlwaysHits, 0}, - {sText_Minimized, 1}, - {sText_ChargedUp, 2}, - {sText_Rooted, 3}, - {sText_Yawned, 4}, - {sText_Imprisoned, 5}, - {sText_NoCrit, 6}, - {sText_GastroAcid, 7}, - {sText_SmackDown, 8}, - {sText_MiracleEye, 9}, - {sText_AquaRing, 10}, - {sText_LaserFocus, 11}, + {sText_LeechSeedHealer, LIST_STATUS3_LEECH_SEED_HEALER}, + {sText_LeechSeeded, LIST_STATUS3_LEECH_SEEDED}, + {sText_AlwaysHits, LIST_STATUS3_ALWAYS_HITS}, + {sText_PerishSong, LIST_STATUS3_PERISH_SONG}, + {sText_OnAir, LIST_STATUS3_ON_AIR}, + {sText_Underground, LIST_STATUS3_UNDERGROUND}, + {sText_Minimized, LIST_STATUS3_MINIMIZED}, + {sText_ChargedUp, LIST_STATUS3_CHARGED_UP}, + {sText_Rooted, LIST_STATUS3_ROOTED}, + {sText_Yawn, LIST_STATUS3_YAWN}, + {sText_ImprisonedOthers, LIST_STATUS3_IMPRISONED_OTHERS}, + {sText_Grudge, LIST_STATUS3_GRUDGE}, + {sText_GastroAcid, LIST_STATUS3_GASTRO_ACID}, + {sText_Embargo, LIST_STATUS3_EMBARGO}, + {sText_Underwater, LIST_STATUS3_UNDERWATER}, + {sText_SmackedDown, LIST_STATUS3_SMACKED_DOWN}, + {sText_Telekinesis, LIST_STATUS3_TELEKINESIS}, + {sText_MiracleEyed, LIST_STATUS3_MIRACLE_EYED}, + {sText_MagnetRise, LIST_STATUS3_MAGNET_RISE}, + {sText_HealBlock, LIST_STATUS3_HEAL_BLOCK}, + {sText_AquaRing, LIST_STATUS3_AQUA_RING}, + {sText_LaserFocus, LIST_STATUS3_LASER_FOCUS}, + {sText_PowerTrick, LIST_STATUS3_POWER_TRICK}, }; static const struct ListMenuItem sStatus4ListItems[] = { - {sText_Electrified, 0}, + {sText_Electrified, LIST_STATUS4_ELECTRIFIED}, + {sText_MudSport, LIST_STATUS4_MUD_SPORT}, + {sText_WaterSport, LIST_STATUS4_WATER_SPORT}, + {sText_SaltCure, LIST_STATUS4_SALT_CURE}, + {sText_SyrupBomb, LIST_STATUS4_SYRUP_BOMB}, + {sText_GlaiveRush, LIST_STATUS4_GLAIVE_RUSH}, }; static const struct ListMenuItem sSideStatusListItems[] = { {sText_Reflect, LIST_SIDE_REFLECT}, {sText_LightScreen, LIST_SIDE_LIGHTSCREEN}, + {sText_StickyWeb, LIST_SIDE_STICKY_WEB}, {sText_Spikes, LIST_SIDE_SPIKES}, {sText_Safeguard, LIST_SIDE_SAFEGUARD}, {sText_Mist, LIST_SIDE_MIST}, + {sText_Tailwind, LIST_SIDE_TAILWIND}, {sText_AuroraVeil, LIST_SIDE_AURORA_VEIL}, {sText_LuckyChant, LIST_SIDE_LUCKY_CHANT}, - {sText_Tailwind, LIST_SIDE_TAILWIND}, - {sText_StealthRock, LIST_SIDE_STEALTH_ROCK}, {sText_ToxicSpikes, LIST_SIDE_TOXIC_SPIKES}, - {sText_StickyWeb, LIST_SIDE_STICKY_WEB}, + {sText_StealthRock, LIST_SIDE_STEALTH_ROCK}, {sText_Steelsurge, LIST_SIDE_STEELSURGE}, + {sText_DamageNonTypes, LIST_SIDE_DAMAGE_NON_TYPES}, + {sText_Rainbow, LIST_SIDE_RAINBOW}, + {sText_SeaOfFire, LIST_SIDE_SEA_OF_FIRE}, + {sText_Swamp, LIST_SIDE_SWAMP}, +}; + +static const struct ListMenuItem sAIListItems[] = +{ + {sText_CheckBadMove, LIST_AI_CHECK_BAD_MOVE}, + {sText_TryToFaint, LIST_AI_TRY_TO_FAINT}, + {sText_CheckViability, LIST_AI_CHECK_VIABILITY}, + {sText_SetUpFirstTurn, LIST_AI_SETUP_FIRST_TURN}, + {sText_Risky, LIST_AI_RISKY}, + {sText_PreferStrongestMove, LIST_AI_PREFER_STRONGEST_MOVE}, + {sText_PreferBatonPass, LIST_AI_PREFER_BATON_PASS}, + {sText_DoubleBattle, LIST_AI_DOUBLE_BATTLE}, + {sText_HpAware, LIST_AI_HP_AWARE}, + {sText_PowerfulStatus, LIST_AI_POWERFUL_STATUS}, + {sText_NegateUnaware, LIST_AI_NEGATE_UNAWARE}, + {sText_WillSuicide, LIST_AI_WILL_SUICIDE}, + {sText_HelpPartner, LIST_AI_HELP_PARTNER}, + {sText_PreferStatusMoves, LIST_AI_PREFER_STATUS_MOVES}, + {sText_Stall, LIST_AI_STALL}, + {sText_SmartSwitching, LIST_AI_SMART_SWITCHING}, + {sText_AcePokemon, LIST_AI_ACE_POKEMON}, + {sText_Omniscient, LIST_AI_OMNISCIENT}, + {sText_SmartMonChoices, LIST_AI_SMART_MON_CHOICES}, + {sText_Roaming, LIST_AI_ROAMING}, + {sText_Safari, LIST_AI_SAFARI}, + {sText_FirstBattle, LIST_AI_FIRST_BATTLE}, +}; + +static const struct ListMenuItem sVariousListItems[] = +{ + {sText_ShowHP, VARIOUS_SHOW_HP}, + {sText_SubstituteHp, VARIOUS_SUBSTITUTE_HP}, + {sText_InLove, VARIOUS_IN_LOVE}, }; static const struct ListMenuItem sSecondaryListItems[] = @@ -527,7 +721,7 @@ static const struct WindowTemplate sMainListWindowTemplate = .width = 9, .height = 12, .paletteNum = 0xF, - .baseBlock = 0x2 + .baseBlock = 0x1 }; static const struct WindowTemplate sSecondaryListWindowTemplate = @@ -535,10 +729,10 @@ static const struct WindowTemplate sSecondaryListWindowTemplate = .bg = 0, .tilemapLeft = 12, .tilemapTop = 3, - .width = 10, - .height = 2, + .width = 20, + .height = 16, .paletteNum = 0xF, - .baseBlock = 0xA0 + .baseBlock = 0x6D }; static const struct WindowTemplate sModifyWindowTemplate = @@ -549,7 +743,7 @@ static const struct WindowTemplate sModifyWindowTemplate = .width = 4, .height = 2, .paletteNum = 0xF, - .baseBlock = 0x200 + .baseBlock = 0x1AD }; static const struct WindowTemplate sBattlerWindowTemplate = @@ -560,7 +754,7 @@ static const struct WindowTemplate sBattlerWindowTemplate = .width = 14, .height = 2, .paletteNum = 0xF, - .baseBlock = 0x300 + .baseBlock = 0x1B5 }; static const struct BgTemplate sBgTemplates[] = @@ -1363,7 +1557,6 @@ static void CreateSecondaryListMenu(struct BattleDebugMenu *data) listTemplate.items = sStatus2ListItems; itemsCount = ARRAY_COUNT(sStatus2ListItems); data->bitfield = sStatus2Bitfield; - winTemplate.height = 1; break; case LIST_ITEM_STATUS3: listTemplate.items = sStatus3ListItems; @@ -1394,7 +1587,6 @@ static void CreateSecondaryListMenu(struct BattleDebugMenu *data) } data->secondaryListItemCount = itemsCount; - winTemplate.height *= itemsCount; data->secondaryListWindowId = AddWindow(&winTemplate); listTemplate.totalItems = itemsCount; @@ -1411,10 +1603,10 @@ static void PadString(const u8 *src, u8 *dst) { u32 i; - for (i = 0; i < 17 && src[i] != EOS; i++) + for (i = 0; i < 19 && src[i] != EOS; i++) dst[i] = src[i]; - for (; i < 17; i++) + for (; i < 19; i++) dst[i] = CHAR_SPACE; dst[i] = EOS; @@ -1516,11 +1708,10 @@ static void PrintSecondaryEntries(struct BattleDebugMenu *data) static void DestroyModifyArrows(struct BattleDebugMenu *data) { - FreeSpritePaletteByTag(gSpritePalette_Arrow.tag); if (data->modifyArrows.arrowSpriteId[0] != 0xFF) - DestroySprite(&gSprites[data->modifyArrows.arrowSpriteId[0]]); + DestroySpriteAndFreeResources(&gSprites[data->modifyArrows.arrowSpriteId[0]]); if (data->modifyArrows.arrowSpriteId[1] != 0xFF) - DestroySprite(&gSprites[data->modifyArrows.arrowSpriteId[1]]); + DestroySpriteAndFreeResources(&gSprites[data->modifyArrows.arrowSpriteId[1]]); } static void PrintDigitChars(struct BattleDebugMenu *data) @@ -1533,6 +1724,7 @@ static void PrintDigitChars(struct BattleDebugMenu *data) text[i] = EOS; + FillWindowPixelBuffer(data->modifyWindowId, 0x11); AddTextPrinterParameterized(data->modifyWindowId, FONT_NORMAL, text, 3, 0, 0, NULL); } @@ -1686,6 +1878,17 @@ static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, sideTimer->lightscreenBattlerId = data->battlerId; } return &sideTimer->lightscreenTimer; + case LIST_SIDE_STICKY_WEB: + if (changeStatus) + { + if (statusTrue) + *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_STICKY_WEB; + else + *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_STICKY_WEB; + sideTimer->stickyWebBattlerId = data->battlerId; + sideTimer->stickyWebBattlerSide = GetBattlerSide(data->battlerId); + } + return &sideTimer->stickyWebAmount; case LIST_SIDE_SPIKES: if (changeStatus) { @@ -1715,6 +1918,16 @@ static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, sideTimer->mistBattlerId = data->battlerId; } return &sideTimer->mistTimer; + case LIST_SIDE_TAILWIND: + if (changeStatus) + { + if (statusTrue) + *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_TAILWIND; + else + *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_TAILWIND; + sideTimer->tailwindBattlerId = data->battlerId; + } + return &sideTimer->tailwindTimer; case LIST_SIDE_AURORA_VEIL: if (changeStatus) { @@ -1735,25 +1948,6 @@ static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, sideTimer->luckyChantBattlerId = data->battlerId; } return &sideTimer->luckyChantTimer; - case LIST_SIDE_TAILWIND: - if (changeStatus) - { - if (statusTrue) - *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_TAILWIND; - else - *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_TAILWIND; - sideTimer->tailwindBattlerId = data->battlerId; - } - return &sideTimer->tailwindTimer; - case LIST_SIDE_STEALTH_ROCK: - if (changeStatus) - { - if (statusTrue) - *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_STEALTH_ROCK; - else - *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_STEALTH_ROCK; - } - return &sideTimer->stealthRockAmount; case LIST_SIDE_TOXIC_SPIKES: if (changeStatus) { @@ -1763,15 +1957,15 @@ static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_TOXIC_SPIKES; } return &sideTimer->toxicSpikesAmount; - case LIST_SIDE_STICKY_WEB: + case LIST_SIDE_STEALTH_ROCK: if (changeStatus) { if (statusTrue) - *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_STICKY_WEB; + *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_STEALTH_ROCK; else - *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_STICKY_WEB; + *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_STEALTH_ROCK; } - return &sideTimer->stickyWebAmount; + return &sideTimer->stealthRockAmount; case LIST_SIDE_STEELSURGE: if (changeStatus) { @@ -1781,6 +1975,43 @@ static u8 *GetSideStatusValue(struct BattleDebugMenu *data, bool32 changeStatus, *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_STEELSURGE; } return &sideTimer->steelsurgeAmount; + case LIST_SIDE_DAMAGE_NON_TYPES: + if (changeStatus) + { + if (statusTrue) + *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_DAMAGE_NON_TYPES; + else + *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_DAMAGE_NON_TYPES; + sideTimer->damageNonTypesType = gMovesInfo[gCurrentMove].type; + } + return &sideTimer->damageNonTypesTimer; + case LIST_SIDE_RAINBOW: + if (changeStatus) + { + if (statusTrue) + *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_RAINBOW; + else + *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_RAINBOW; + } + return &sideTimer->rainbowTimer; + case LIST_SIDE_SEA_OF_FIRE: + if (changeStatus) + { + if (statusTrue) + *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_SEA_OF_FIRE; + else + *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_SEA_OF_FIRE; + } + return &sideTimer->seaOfFireTimer; + case LIST_SIDE_SWAMP: + if (changeStatus) + { + if (statusTrue) + *(u32 *)(data->modifyArrows.modifiedValPtr) |= SIDE_STATUS_SWAMP; + else + *(u32 *)(data->modifyArrows.modifiedValPtr) &= ~SIDE_STATUS_SWAMP; + } + return &sideTimer->swampTimer; default: return NULL; } @@ -1847,14 +2078,15 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data) data->modifyArrows.minValue = 0; data->modifyArrows.maxValue = 9999; data->modifyArrows.maxDigits = 4; - if (data->currentSecondaryListItemId == 0) + data->modifyArrows.typeOfVal = VAL_U16; + if (data->currentSecondaryListItemId == LIST_STAT_HP_CURRENT) { data->modifyArrows.modifiedValPtr = &gBattleMons[data->battlerId].hp; data->modifyArrows.currValue = gBattleMons[data->battlerId].hp; data->modifyArrows.minValue = 1; data->modifyArrows.maxValue = gBattleMons[data->battlerId].maxHP; } - else if (data->currentSecondaryListItemId == 1) + else if (data->currentSecondaryListItemId == LIST_STAT_HP_MAX) { data->modifyArrows.modifiedValPtr = &gBattleMons[data->battlerId].maxHP; data->modifyArrows.minValue = gBattleMons[data->battlerId].hp; @@ -1865,7 +2097,6 @@ static void SetUpModifyArrows(struct BattleDebugMenu *data) data->modifyArrows.modifiedValPtr = (u16 *)((&gBattleMons[data->battlerId].attack) + (data->currentSecondaryListItemId - 2)); data->modifyArrows.currValue = *(u16 *)((&gBattleMons[data->battlerId].attack) + (data->currentSecondaryListItemId - 2)); } - data->modifyArrows.typeOfVal = VAL_U16; break; case LIST_ITEM_STAT_STAGES: data->modifyArrows.minValue = 0; @@ -2196,6 +2427,14 @@ static const u8 sText_HoldEffectRoomService[] = _("Room Service"); static const u8 sText_HoldEffectBlunderPolicy[] = _("Blunder Policy"); static const u8 sText_HoldEffectHeavyDutyBoots[] = _("Heavy Duty Boots"); static const u8 sText_HoldEffectThroatSpray[] = _("Throat Spray"); +static const u8 sText_HoldEffectAbilityShield[] = _("Ability Shield"); +static const u8 sText_HoldEffectClearAmulet[] = _("Clear Amulet"); +static const u8 sText_HoldEffectMirrorHerb[] = _("Mirror Herb"); +static const u8 sText_HoldEffectPunchingGlove[] = _("Punching Glove"); +static const u8 sText_HoldEffectCovertCloak[] = _("Covert Cloak"); +static const u8 sText_HoldEffectLoadedDice[] = _("Loaded Dice"); +static const u8 sText_HoldEffectBoosterEnergy[] = _("Booster Energy"); +static const u8 sText_HoldEffectBerserkGene[] = _("Berserk Gene"); static const u8 *const sHoldEffectNames[] = { [HOLD_EFFECT_NONE] = sText_HoldEffectNone, @@ -2338,6 +2577,14 @@ static const u8 *const sHoldEffectNames[] = [HOLD_EFFECT_BLUNDER_POLICY] = sText_HoldEffectBlunderPolicy, [HOLD_EFFECT_HEAVY_DUTY_BOOTS] = sText_HoldEffectHeavyDutyBoots, [HOLD_EFFECT_THROAT_SPRAY] = sText_HoldEffectThroatSpray, + [HOLD_EFFECT_ABILITY_SHIELD] = sText_HoldEffectAbilityShield, + [HOLD_EFFECT_CLEAR_AMULET] = sText_HoldEffectClearAmulet, + [HOLD_EFFECT_MIRROR_HERB] = sText_HoldEffectMirrorHerb, + [HOLD_EFFECT_PUNCHING_GLOVE] = sText_HoldEffectPunchingGlove, + [HOLD_EFFECT_COVERT_CLOAK] = sText_HoldEffectCovertCloak, + [HOLD_EFFECT_LOADED_DICE] = sText_HoldEffectLoadedDice, + [HOLD_EFFECT_BOOSTER_ENERGY] = sText_HoldEffectBoosterEnergy, + [HOLD_EFFECT_BERSERK_GENE] = sText_HoldEffectBerserkGene, }; static const u8 *GetHoldEffectName(u16 holdEffect) { diff --git a/src/battle_util.c b/src/battle_util.c index 9ea7a453cb..e87fa9f368 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6207,23 +6207,41 @@ bool32 IsNeutralizingGasOnField(void) return FALSE; } -bool32 IsMoldBreakerTypeAbility(u32 ability) +bool32 IsMoldBreakerTypeAbility(u32 battler, u32 ability) { + if (gStatuses3[battler] & STATUS3_GASTRO_ACID) + return FALSE; + return (ability == ABILITY_MOLD_BREAKER || ability == ABILITY_TERAVOLT || ability == ABILITY_TURBOBLAZE || (ability == ABILITY_MYCELIUM_MIGHT && IS_MOVE_STATUS(gCurrentMove))); } +static inline bool32 CanBreakThroughAbility(u32 battlerAtk, u32 battlerDef, u32 ability) +{ + return ((IsMoldBreakerTypeAbility(battlerAtk, ability) || gMovesInfo[gCurrentMove].ignoresTargetAbility) + && battlerDef != battlerAtk + && gAbilitiesInfo[gBattleMons[battlerDef].ability].breakable + && gBattlerByTurnOrder[gCurrentTurnActionNumber] == battlerAtk + && gActionsByTurnOrder[gCurrentTurnActionNumber] == B_ACTION_USE_MOVE + && gCurrentTurnActionNumber < gBattlersCount); +} + u32 GetBattlerAbility(u32 battler) { bool32 noAbilityShield = GetBattlerHoldEffectIgnoreAbility(battler, TRUE) != HOLD_EFFECT_ABILITY_SHIELD; + bool32 abilityCantBeSuppressed = gAbilitiesInfo[gBattleMons[battler].ability].cantBeSuppressed; - if (gAbilitiesInfo[gBattleMons[battler].ability].cantBeSuppressed) + if (abilityCantBeSuppressed) { // Edge case: pokemon under the effect of gastro acid transforms into a pokemon with Comatose (Todo: verify how other unsuppressable abilities behave) if (gBattleMons[battler].status2 & STATUS2_TRANSFORMED && gStatuses3[battler] & STATUS3_GASTRO_ACID && gBattleMons[battler].ability == ABILITY_COMATOSE) return ABILITY_NONE; + + if (noAbilityShield && CanBreakThroughAbility(gBattlerAttacker, battler, gBattleMons[gBattlerAttacker].ability)) + return ABILITY_NONE; + return gBattleMons[battler].ability; } @@ -6235,15 +6253,7 @@ u32 GetBattlerAbility(u32 battler) && noAbilityShield) return ABILITY_NONE; - if (((IsMoldBreakerTypeAbility(gBattleMons[gBattlerAttacker].ability) - && !(gStatuses3[gBattlerAttacker] & STATUS3_GASTRO_ACID)) - || gMovesInfo[gCurrentMove].ignoresTargetAbility) - && battler != gBattlerAttacker - && gAbilitiesInfo[gBattleMons[battler].ability].breakable - && noAbilityShield - && gBattlerByTurnOrder[gCurrentTurnActionNumber] == gBattlerAttacker - && gActionsByTurnOrder[gCurrentTurnActionNumber] == B_ACTION_USE_MOVE - && gCurrentTurnActionNumber < gBattlersCount) + if (noAbilityShield && CanBreakThroughAbility(gBattlerAttacker, battler, gBattleMons[gBattlerAttacker].ability)) return ABILITY_NONE; return gBattleMons[battler].ability; diff --git a/src/data/battle_anim.h b/src/data/battle_anim.h index 77b61584ca..af46c1983e 100644 --- a/src/data/battle_anim.h +++ b/src/data/battle_anim.h @@ -1454,6 +1454,7 @@ const struct CompressedSpriteSheet gBattleAnimPicTable[] = {gBattleAnimSpriteGfx_SyrupShell, 0x2000, ANIM_TAG_SYRUP_SHELL_YELLOW}, {gBattleAnimSpriteGfx_SyrupSplat, 0x400, ANIM_TAG_SYRUP_SPLAT_RED}, {gBattleAnimSpriteGfx_SyrupSplat, 0x400, ANIM_TAG_SYRUP_SPLAT_YELLOW}, + {gBattleAnimSpriteGfx_IvyCudgel, 0x800, ANIM_TAG_IVY_CUDGEL_GRASS}, }; const struct CompressedSpritePalette gBattleAnimPaletteTable[] = @@ -1909,6 +1910,10 @@ const struct CompressedSpritePalette gBattleAnimPaletteTable[] = {gBattleAnimSpritePal_SyrupYellow, ANIM_TAG_SYRUP_SHELL_YELLOW}, {gBattleAnimSpritePal_SyrupRed, ANIM_TAG_SYRUP_SPLAT_RED}, {gBattleAnimSpritePal_SyrupYellow, ANIM_TAG_SYRUP_SPLAT_YELLOW}, + {gBattleAnimSpritePal_IvyCudgelGrass, ANIM_TAG_IVY_CUDGEL_GRASS}, + {gBattleAnimSpritePal_IvyCudgelFire, ANIM_TAG_IVY_CUDGEL_FIRE}, + {gBattleAnimSpritePal_IvyCudgelRock, ANIM_TAG_IVY_CUDGEL_ROCK}, + {gBattleAnimSpritePal_IvyCudgelWater, ANIM_TAG_IVY_CUDGEL_WATER}, }; const struct BattleAnimBackground gBattleAnimBackgroundTable[] = diff --git a/src/field_weather_effect.c b/src/field_weather_effect.c index 325979f86a..2cf8f6fb78 100644 --- a/src/field_weather_effect.c +++ b/src/field_weather_effect.c @@ -770,7 +770,7 @@ void Snow_InitVars(void) gWeatherPtr->weatherGfxLoaded = FALSE; gWeatherPtr->targetColorMapIndex = 0; gWeatherPtr->colorMapStepDelay = 20; - gWeatherPtr->targetSnowflakeSpriteCount = 16; + gWeatherPtr->targetSnowflakeSpriteCount = NUM_SNOWFLAKE_SPRITES; gWeatherPtr->snowflakeVisibleCounter = 0; } diff --git a/src/graphics.c b/src/graphics.c index fee3ead0c8..bd9c73e864 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -457,6 +457,12 @@ const u32 gBattleAnimSpriteGfx_SyrupSplat[] = INCBIN_U32("graphics/battle_anims/ const u32 gBattleAnimSpritePal_SyrupRed[] = INCBIN_U32("graphics/battle_anims/sprites/syrup_red.gbapal.lz"); const u32 gBattleAnimSpritePal_SyrupYellow[] = INCBIN_U32("graphics/battle_anims/sprites/syrup_yellow.gbapal.lz"); +const u32 gBattleAnimSpriteGfx_IvyCudgel[] = INCBIN_U32("graphics/battle_anims/sprites/cudgel.4bpp.lz"); +const u32 gBattleAnimSpritePal_IvyCudgelGrass[] = INCBIN_U32("graphics/pokemon/ogerpon/normal.gbapal.lz"); +const u32 gBattleAnimSpritePal_IvyCudgelFire[] = INCBIN_U32("graphics/pokemon/ogerpon/hearthflame/normal.gbapal.lz"); +const u32 gBattleAnimSpritePal_IvyCudgelRock[] = INCBIN_U32("graphics/pokemon/ogerpon/cornerstone/normal.gbapal.lz"); +const u32 gBattleAnimSpritePal_IvyCudgelWater[] = INCBIN_U32("graphics/pokemon/ogerpon/wellspring/normal.gbapal.lz"); + // old battle interface data, unused const u32 gOldBattleInterfaceGfx[] = INCBIN_U32("graphics/unused/obi1.4bpp.lz"); diff --git a/test/battle/ability/disguise.c b/test/battle/ability/disguise.c index 7d3e36bf78..c4f79d8fe3 100644 --- a/test/battle/ability/disguise.c +++ b/test/battle/ability/disguise.c @@ -121,3 +121,16 @@ SINGLE_BATTLE_TEST("Disguised Mimikyu takes damage from Rough Skin without break EXPECT_EQ(player->species, SPECIES_MIMIKYU_DISGUISED); } } + +SINGLE_BATTLE_TEST("Disguised Mimikyu is ignored by Mold Breaker") +{ + GIVEN { + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_PINSIR) { Ability(ABILITY_MOLD_BREAKER); } + } WHEN { + TURN { MOVE(opponent, MOVE_AERIAL_ACE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AERIAL_ACE, opponent); + NOT ABILITY_POPUP(player, ABILITY_DISGUISE); + } +}