diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5c91461fcd..dd214035d2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,11 +32,11 @@ jobs: env: COMPARE: 0 run: make -j${nproc} -O all - - - name: LTO + + - name: Release run: | make tidy - make -j${nproc} LTO=1 + make -j${nproc} release # make tidy to purge previous build - name: Test diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 88ef358dbb..e877940643 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -122,21 +122,20 @@ Once all items on the merge checklist are true, the branch will be merged in. ## Maintainers -This list was last updated 2025 April 1. +This list was last updated 2025 Dec 23. | Name | Discord | Currently Active | Areas of Expertise | | --- | --- | --- | --- | | [Alex](https://github.com/AlexOn1ine) | rainonline | ✅ | Battle Engine, Battle AI | [Egg](https://github.com/DizzyEggg) | egg9255 | ✅ | Battle Engine, Battle AI -| [ghoulslash](https://github.com/ghoulslash) | ghoulslash | ✅ | Dexnav, Overworld, Battle Engine | [Jasper](https://github.com/Bassoonian) | bassoonian | ✅ | Berries, Day / Night System, Followers, Feature Branches | [MGriffin](https://github.com/mrgriffin) | mgriffin | ✅ | Tests, Trainer Control | [psf](https://github.com/pkmnsnfrn) | pkmnsnfrn | ✅ | Rematches, Difficulty, Trainer Slides, Fake RTC, Fishing Minigames, Imperial / Metric, OW Item Balls, Sky Battles | [Hedara](https://github.com/hedara90) | hedara | ✅ | Compression, Sprites | [Pawkkie](https://github.com/Pawkkie) | pawkkie | ✅ | Battle AI | [SBird](https://github.com/SBird1337) | karathan | ✅ | Dynamic Multichoice, Damage Calculation, Animations, Trainer Control, Tests -| [Agustin](https://github.com/AgustinGDLV) | agustingdlv | Inactive | Gimmicks, Battle Engine, Tests, Items -| [tertu](https://github.com/tertu-m) | tertu | Inactive | Randomizer +| [Jamie](https://github.com/FosterProgramming) | foster_harmony | ✅ | Overworld, Tests, Day / Night System, Dexnav, Battle Frontier, HGSS Dex, Pokerus, Learnsets, Mon Generation, Vs Seeker +| [grintoul](https://github.com/grintoul1) | grintoul | ✅ | Tests, Battle AI, Battle Engine, Overworld, Trainer Slides, Follower NPCs, Multi Battles ## Attribution This guide is based on the [contributing.md](https://contributing.md/generator)! diff --git a/INSTALL.md b/INSTALL.md index 47f00cf78f..ebdb12e58c 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -140,7 +140,7 @@ git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion 2. Pull your desired branch There are three different options to pull from. ```console -git pull RHH master # if you've chosen to use the upcoming branch, replace the word master with upcoming. +git pull RHH master # if you've chosen to use the upcoming branch, replace the word master with upcoming. # If you've chosen the latest patch, replace the word master with expansion # If you've chosen Latest Patch, replace the word master with expansion/1.11.0 where 1.11.0 is replaced with whatever the latest released version is. ``` @@ -173,7 +173,7 @@ For example, if your version is 1.7.0, you should update to 1.7.4. git pull RHH expansion/X.Y.Z # Replace X, Y and Z with the target version, such as `1.9.3`, `master`, or `upcoming`. ``` -You may have merge conflicts that you need to resolve. +You may have merge conflicts that you need to resolve. If you targeted a specific version that is not the latest version listed on the [tags](https://github.com/rh-hideout/pokeemerald-expansion/tags) page, you should repeat steps 3 and 4 until you are. diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index a311d9a1f5..95eb2a8c19 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -2451,3 +2451,8 @@ .byte \gen .4byte \jumpInstr .endm + + @ Absorbs Toxic Spikes when a grounded Poison-type faints to entry hazards. + .macro tryabsorbtoxicspikesonfaint + callnative BS_TryAbsorbToxicSpikesOnFaint + .endm diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 9fa9fa669e..4f1e6424df 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -1534,10 +1534,10 @@ BattleScript_EffectInstruct:: tryinstruct BattleScript_ButItFailed attackanimation waitanimation - copybyte gBattlerAttacker, gBattlerTarget - copybyte gBattlerTarget, gEffectBattler printstring STRINGID_USEDINSTRUCTEDMOVE waitmessage B_WAIT_TIME_LONG + copybyte gBattlerAttacker, gBattlerTarget + copybyte gBattlerTarget, gEffectBattler jumptocalledmove TRUE BattleScript_EffectAutotomize:: diff --git a/docs/tutorials/how_to_testing_system.md b/docs/tutorials/how_to_testing_system.md index c2b9912898..70ee6c4033 100644 --- a/docs/tutorials/how_to_testing_system.md +++ b/docs/tutorials/how_to_testing_system.md @@ -497,10 +497,10 @@ Causes the test to fail if the `SCENE` command succeeds before the following com ``` Causes the test to fail unless one of the `SCENE` commands succeeds. ``` - ONE_OF { - MESSAGE("Wobbuffet used Celebrate!"); - MESSAGE("Wobbuffet couldn't move because it's paralyzed!"); - } + ONE_OF { + MESSAGE("Wobbuffet used Celebrate!"); + MESSAGE("Wobbuffet couldn't move because it's paralyzed!"); + } ``` ### `NONE_OF` @@ -511,12 +511,12 @@ Causes the test to fail unless one of the `SCENE` commands succeeds. ``` Causes the test to fail if one of the `SCENE` commands succeeds before the command after the `NONE_OF` succeeds. ``` - // Our Wobbuffet does not move before the foe's. - NONE_OF { - MESSAGE("Wobbuffet used Celebrate!"); - MESSAGE("Wobbuffet couldn't move because it's paralyzed!"); - } - MESSAGE("The opposing Wobbuffet used Celebrate!"); + // Our Wobbuffet does not move before the foe's. + NONE_OF { + MESSAGE("Wobbuffet used Celebrate!"); + MESSAGE("Wobbuffet couldn't move because it's paralyzed!"); + } + MESSAGE("The opposing Wobbuffet used Celebrate!"); ``` ### `PLAYER_PARTY` diff --git a/graphics/pokemon/conkeldurr/overworld.png b/graphics/pokemon/conkeldurr/overworld.png index fa83edbdc5..e1233f5ddc 100644 Binary files a/graphics/pokemon/conkeldurr/overworld.png and b/graphics/pokemon/conkeldurr/overworld.png differ diff --git a/graphics/pokemon/conkeldurr/overworld_normal.pal b/graphics/pokemon/conkeldurr/overworld_normal.pal index 6e4935354a..cbe2d171d5 100644 --- a/graphics/pokemon/conkeldurr/overworld_normal.pal +++ b/graphics/pokemon/conkeldurr/overworld_normal.pal @@ -12,7 +12,7 @@ JASC-PAL 101 101 94 144 144 137 172 41 65 -0 0 0 +255 255 255 0 0 0 0 0 0 0 0 0 diff --git a/graphics/pokemon/conkeldurr/overworld_shiny.pal b/graphics/pokemon/conkeldurr/overworld_shiny.pal index 4ed16e43f9..5fe0a295bb 100644 --- a/graphics/pokemon/conkeldurr/overworld_shiny.pal +++ b/graphics/pokemon/conkeldurr/overworld_shiny.pal @@ -12,7 +12,7 @@ JASC-PAL 103 92 90 144 144 137 214 66 61 -0 0 0 +255 255 255 0 0 0 0 0 0 0 0 0 diff --git a/graphics/pokemon/gurdurr/overworld.png b/graphics/pokemon/gurdurr/overworld.png index a2b8aabbfa..38ffe3798c 100644 Binary files a/graphics/pokemon/gurdurr/overworld.png and b/graphics/pokemon/gurdurr/overworld.png differ diff --git a/graphics/pokemon/gurdurr/overworld_normal.pal b/graphics/pokemon/gurdurr/overworld_normal.pal index 1219c452c4..25acc57714 100644 --- a/graphics/pokemon/gurdurr/overworld_normal.pal +++ b/graphics/pokemon/gurdurr/overworld_normal.pal @@ -9,11 +9,11 @@ JASC-PAL 146 129 121 47 47 40 147 63 121 -104 40 71 +88 56 64 200 95 172 229 229 247 -0 0 0 -0 0 0 -0 0 0 -0 0 0 +84 21 43 +131 41 57 +222 82 90 +161 48 74 0 0 0 diff --git a/graphics/pokemon/gurdurr/overworld_shiny.pal b/graphics/pokemon/gurdurr/overworld_shiny.pal index 09b2dfe70c..25db2209b8 100644 --- a/graphics/pokemon/gurdurr/overworld_shiny.pal +++ b/graphics/pokemon/gurdurr/overworld_shiny.pal @@ -1,19 +1,19 @@ JASC-PAL 0100 16 -153 210 164 -82 32 47 -136 40 51 -180 68 48 +152 208 160 +93 41 57 +238 98 16 7 7 7 -208 192 128 -174 151 96 +216 201 140 +175 152 96 47 47 40 -224 80 69 -104 40 71 +173 74 69 +96 88 62 +224 107 96 229 229 247 -0 0 0 -0 0 0 -0 0 0 -0 0 0 +84 21 43 +131 41 57 +222 82 90 +178 81 60 0 0 0 diff --git a/graphics/pokemon/seismitoad/overworld.png b/graphics/pokemon/seismitoad/overworld.png index 780b69f641..4da0d45298 100644 Binary files a/graphics/pokemon/seismitoad/overworld.png and b/graphics/pokemon/seismitoad/overworld.png differ diff --git a/graphics/pokemon/seismitoad/overworld_shiny.pal b/graphics/pokemon/seismitoad/overworld_shiny.pal index 6f97a5d2f4..41e3d1c57d 100644 --- a/graphics/pokemon/seismitoad/overworld_shiny.pal +++ b/graphics/pokemon/seismitoad/overworld_shiny.pal @@ -5,14 +5,14 @@ JASC-PAL 55 55 55 87 87 87 0 0 0 -24 56 64 +31 72 64 232 128 56 11 55 112 24 112 104 32 160 136 176 104 32 -236 79 47 -172 47 25 +236 204 110 +153 115 64 33 33 33 0 0 0 0 0 0 diff --git a/graphics/pokemon/sewaddle/overworld.png b/graphics/pokemon/sewaddle/overworld.png index 4ea3161e9d..eeb47aa54f 100644 Binary files a/graphics/pokemon/sewaddle/overworld.png and b/graphics/pokemon/sewaddle/overworld.png differ diff --git a/graphics/pokemon/sewaddle/overworld_normal.pal b/graphics/pokemon/sewaddle/overworld_normal.pal index c7d5351998..97d516fc1d 100644 --- a/graphics/pokemon/sewaddle/overworld_normal.pal +++ b/graphics/pokemon/sewaddle/overworld_normal.pal @@ -1,11 +1,11 @@ JASC-PAL 0100 16 -152 208 160 -0 0 0 +115 202 202 +52 19 21 88 152 48 144 200 8 -88 152 48 +36 86 26 152 120 8 248 208 64 192 152 64 @@ -14,6 +14,6 @@ JASC-PAL 80 80 80 224 128 8 152 120 8 -0 0 0 +192 185 180 0 0 0 0 0 0 diff --git a/graphics/pokemon/sewaddle/overworld_shiny.pal b/graphics/pokemon/sewaddle/overworld_shiny.pal index 7b83b61961..35807a8de2 100644 --- a/graphics/pokemon/sewaddle/overworld_shiny.pal +++ b/graphics/pokemon/sewaddle/overworld_shiny.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 152 208 160 -0 0 0 +24 52 31 64 152 104 104 184 144 -88 152 48 +60 96 48 120 64 72 -240 248 168 -200 232 48 +206 252 139 +168 211 48 112 128 16 252 252 252 80 80 80 248 88 64 152 120 8 -0 0 0 +192 185 180 0 0 0 0 0 0 diff --git a/graphics/pokemon/timburr/overworld.png b/graphics/pokemon/timburr/overworld.png index 4cdec74ce5..b2a5b6cb1b 100644 Binary files a/graphics/pokemon/timburr/overworld.png and b/graphics/pokemon/timburr/overworld.png differ diff --git a/graphics/pokemon/timburr/overworld_normal.pal b/graphics/pokemon/timburr/overworld_normal.pal index 48c26d4786..54d8267232 100644 --- a/graphics/pokemon/timburr/overworld_normal.pal +++ b/graphics/pokemon/timburr/overworld_normal.pal @@ -10,9 +10,9 @@ JASC-PAL 121 40 55 191 79 104 236 112 129 -95 47 40 +55 47 40 229 229 247 -138 87 79 +105 96 91 79 47 5 164 104 5 112 71 5 diff --git a/graphics/pokemon/timburr/overworld_shiny.pal b/graphics/pokemon/timburr/overworld_shiny.pal index d3ac821ecb..44f9579568 100644 --- a/graphics/pokemon/timburr/overworld_shiny.pal +++ b/graphics/pokemon/timburr/overworld_shiny.pal @@ -2,18 +2,18 @@ JASC-PAL 0100 16 152 208 160 -80 61 60 +96 88 62 208 192 128 2 2 2 175 151 96 2 2 2 -186 71 45 -186 71 45 -236 112 129 -80 61 60 +139 55 62 +173 74 69 +224 107 96 +93 41 57 213 210 213 186 71 45 79 47 5 -186 71 45 +164 104 5 112 71 5 218 172 87 diff --git a/graphics/pokemon/whirlipede/overworld.png b/graphics/pokemon/whirlipede/overworld.png index d6cc3e73d1..725b92fd63 100644 Binary files a/graphics/pokemon/whirlipede/overworld.png and b/graphics/pokemon/whirlipede/overworld.png differ diff --git a/graphics/pokemon/whirlipede/overworld_shiny.pal b/graphics/pokemon/whirlipede/overworld_shiny.pal index 18192596b3..5f3a68caa8 100644 --- a/graphics/pokemon/whirlipede/overworld_shiny.pal +++ b/graphics/pokemon/whirlipede/overworld_shiny.pal @@ -6,12 +6,12 @@ JASC-PAL 64 56 72 100 85 143 128 104 160 -88 152 136 +88 163 136 0 0 0 64 64 80 40 40 40 -168 128 64 -208 176 96 +209 128 175 +208 176 185 96 80 128 0 0 0 0 0 0 diff --git a/include/battle_util.h b/include/battle_util.h index e8a6cece03..4de7c32c2a 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -154,7 +154,6 @@ enum MoveCanceler MOVE_STEP_SUCCESS, MOVE_STEP_BREAK, // Breaks out of the function to run a script MOVE_STEP_FAILURE, // Same as break but breaks out of it due to move failure and jumps to script that handles the failure - MOVE_STEP_REMOVES_STATUS, }; extern const struct TypePower gNaturalGiftTable[]; @@ -356,7 +355,7 @@ bool32 IsPartnerMonFromSameTrainer(u32 battler); enum DamageCategory GetCategoryBasedOnStats(u32 battler); void SetShellSideArmCategory(void); bool32 MoveIsAffectedBySheerForce(u32 move); -bool32 TestIfSheerForceAffected(u32 battler, u16 move); +bool32 IsSheerForceAffected(u16 move, enum Ability ability); void TryRestoreHeldItems(void); bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item); void TrySaveExchangedItem(u32 battler, u16 stolenItem); diff --git a/include/constants/generational_changes.h b/include/constants/generational_changes.h index d75e78810b..192d388224 100644 --- a/include/constants/generational_changes.h +++ b/include/constants/generational_changes.h @@ -32,7 +32,7 @@ F(HIDDEN_POWER_DMG, hiddenPowerDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(ROUGH_SKIN_DMG, roughSkinDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(KNOCK_OFF_DMG, knockOffDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ - F(SPORT_DMG_REDUCTION, sportDmgReduction, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(SPORT_DMG_REDUCTION, sportDmgReduction, (u32, GEN_COUNT - 1)) \ F(EXPLOSION_DEFENSE, explosionDefense, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(PARENTAL_BOND_DMG, parentalBondDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(MULTIPLE_TARGETS_DMG, multipleTargetsDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ @@ -47,11 +47,11 @@ F(ROOST_PURE_FLYING, roostPureFlying, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(STATUS_TYPE_IMMUNITY, statusTypeImmunity, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ /* Turn settings */ \ - F(BINDING_TURNS, bindingTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(BINDING_TURNS, bindingTurns, (u32, GEN_COUNT - 1)) \ F(UPROAR_TURNS, uproarTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(UPROAR_IGNORE_SOUNDPROOF, uproarIgnoreSoundproof, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(DISABLE_TURNS, disableTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ - F(TAILWIND_TURNS, tailwindTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(TAILWIND_TURNS, tailwindTurns, (u32, GEN_COUNT - 1)) \ F(SLEEP_TURNS, sleepTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(TAUNT_TURNS, tauntTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(SPORT_TURNS, sportTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ @@ -66,7 +66,7 @@ F(RECOIL_IF_MISS_DMG, recoilIfMissDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(KLUTZ_FLING_INTERACTION, klutzFlingInteraction, (u32, GEN_COUNT - 1)) \ F(UPDATED_CONVERSION, updatedConversion, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ - F(UPDATED_CONVERSION_2, updatedConversion2, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(UPDATED_CONVERSION_2, updatedConversion2, (u32, GEN_COUNT - 1)) \ F(PP_REDUCED_BY_SPITE, ppReducedBySpite, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(EXTRAPOLATED_MOVE_FLAGS, extrapolatedMoveFlags, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ /* Ability data settings */ \ diff --git a/include/test/battle.h b/include/test/battle.h index 5c53e3e97f..bdedf679e1 100644 --- a/include/test/battle.h +++ b/include/test/battle.h @@ -772,7 +772,7 @@ struct BattleTestData u8 gender; u8 nature; bool8 isShiny; - enum Ability forcedAbilities[NUM_BATTLE_SIDES][PARTY_SIZE]; + enum Ability forcedAbilities[MAX_BATTLERS_COUNT][PARTY_SIZE]; u8 chosenGimmick[MAX_BATTLERS_COUNT][PARTY_SIZE]; u8 forcedEnvironment; diff --git a/include/test_runner.h b/include/test_runner.h index 8eac376c53..319aaf042b 100644 --- a/include/test_runner.h +++ b/include/test_runner.h @@ -30,7 +30,7 @@ void TestRunner_CheckMemory(void); void TestRunner_Battle_CheckBattleRecordActionType(u32 battlerId, u32 recordIndex, u32 actionType); -u32 TestRunner_Battle_GetForcedAbility(u32 side, u32 partyIndex); +u32 TestRunner_Battle_GetForcedAbility(u32 array, u32 partyIndex); u32 TestRunner_Battle_GetChosenGimmick(u32 battler, u32 partyIndex); u32 TestRunner_Battle_GetForcedEnvironment(void); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 8942950751..22f318d467 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -5687,7 +5687,7 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, stru ADJUST_SCORE(GOOD_EFFECT); break; case EFFECT_MAGNET_RISE: - if (AI_IsBattlerGrounded(battlerAtk) && HasDamagingMoveOfType(battlerDef, TYPE_ELECTRIC) + if (AI_IsBattlerGrounded(battlerAtk) && HasDamagingMoveOfType(battlerDef, TYPE_GROUND) && !(effectiveness == UQ_4_12(0.0))) // Doesn't resist ground move { if (AI_IsFaster(battlerAtk, battlerDef, move, predictedMoveSpeedCheck, CONSIDER_PRIORITY)) // Attacker goes first @@ -5698,8 +5698,7 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, stru } else // Opponent Goes First { - if (HasDamagingMoveOfType(battlerDef, TYPE_GROUND)) - ADJUST_SCORE(DECENT_EFFECT); + ADJUST_SCORE(DECENT_EFFECT); break; } } @@ -5877,17 +5876,14 @@ static s32 AI_CalcAdditionalEffectScore(u32 battlerAtk, u32 battlerDef, u32 move // Set battlerDef best dmg moves GetBestDmgMovesFromBattler(battlerDef, battlerAtk, AI_DEFENDING, defBestMoves); + if (IsSheerForceAffected(move, aiData->abilities[battlerAtk])) + return score; + // check move additional effects that are likely to happen for (u32 effectId = 0; effectId < additionalEffectCount; effectId++) { const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, effectId); - if (aiData->abilities[battlerAtk] == ABILITY_SHEER_FORCE) - { - if ((additionalEffect->chance > 0) != additionalEffect->sheerForceOverride) - continue; - } - // Only consider effects with a guaranteed chance to happen if (!MoveEffectIsGuaranteed(battlerAtk, aiData->abilities[battlerAtk], additionalEffect)) continue; diff --git a/src/battle_ai_switch.c b/src/battle_ai_switch.c index 2a645262e5..2dc5f7ca19 100644 --- a/src/battle_ai_switch.c +++ b/src/battle_ai_switch.c @@ -1173,14 +1173,8 @@ bool32 ShouldSwitchDynFuncExample(u32 battler) return FALSE; } -bool32 ShouldSwitch(u32 battler) +static bool32 CanBattlerConsiderSwitch(u32 battler) { - u32 battlerIn1, battlerIn2; - s32 firstId; - s32 lastId; // + 1 - struct Pokemon *party; - s32 availableToSwitch; - if (gBattleMons[battler].volatiles.wrapped) return FALSE; if (gBattleMons[battler].volatiles.escapePrevention) @@ -1189,8 +1183,23 @@ bool32 ShouldSwitch(u32 battler) return FALSE; if (IsAbilityPreventingEscape(battler)) return FALSE; + if (gBattleStruct->battlerState[battler].commanderSpecies) + return FALSE; if (gBattleTypeFlags & BATTLE_TYPE_ARENA) return FALSE; + return TRUE; +} + +bool32 ShouldSwitch(u32 battler) +{ + u32 battlerIn1, battlerIn2; + s32 firstId; + s32 lastId; // + 1 + struct Pokemon *party; + s32 availableToSwitch; + + if (!CanBattlerConsiderSwitch(battler)) + return FALSE; // Sequence Switching AI never switches mid-battle if (gAiThinkingStruct->aiFlags[battler] & AI_FLAG_SEQUENCE_SWITCHING) @@ -1324,15 +1333,7 @@ void ModifySwitchAfterMoveScoring(u32 battler) struct Pokemon *party; s32 availableToSwitch; - if (gBattleMons[battler].volatiles.wrapped) - return; - if (gBattleMons[battler].volatiles.escapePrevention) - return; - if (gBattleMons[battler].volatiles.root) - return; - if (IsAbilityPreventingEscape(battler)) - return; - if (gBattleTypeFlags & BATTLE_TYPE_ARENA) + if (!CanBattlerConsiderSwitch(battler)) return; // Sequence Switching AI never switches mid-battle diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 133a7027ad..7a7d6a87e2 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -896,6 +896,10 @@ struct SimulatedDamage AI_CalcDamage(u32 move, u32 battlerAtk, u32 battlerDef, u struct AiLogicData *aiData = gAiLogicData; gAiLogicData->aiCalcInProgress = TRUE; + if (moveEffect == EFFECT_HIT_ENEMY_HEAL_ALLY + && battlerDef == BATTLE_PARTNER(battlerAtk)) + return simDamage; + if (moveEffect == EFFECT_NATURE_POWER) move = GetNaturePowerMove(battlerAtk); @@ -1027,6 +1031,9 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3 u32 predictedMoveSpeedCheck = GetIncomingMoveSpeedCheck(battlerAtk, battlerDef, gAiLogicData); bool32 aiIsFaster = AI_IsFaster(battlerAtk, battlerDef, move, predictedMoveSpeedCheck, CONSIDER_PRIORITY); + if (IsSheerForceAffected(move, abilityAtk)) + return FALSE; + switch (GetMoveEffect(move)) { case EFFECT_ABSORB: diff --git a/src/battle_controller_recorded_partner.c b/src/battle_controller_recorded_partner.c index 08e9eb95a3..fb1952b386 100644 --- a/src/battle_controller_recorded_partner.c +++ b/src/battle_controller_recorded_partner.c @@ -45,6 +45,7 @@ static void RecordedPartnerHandleIntroTrainerBallThrow(u32 battler); static void RecordedPartnerHandleDrawPartyStatusSummary(u32 battler); static void RecordedPartnerHandleEndLinkBattle(u32 battler); static void RecordedPartnerBufferRunCommand(u32 battler); +static void RecordedPartnerHandleStatusIconUpdate(u32 battler); static void (*const sRecordedPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 battler) = { @@ -73,7 +74,7 @@ static void (*const sRecordedPartnerBufferCommands[CONTROLLER_CMDS_COUNT])(u32 b [CONTROLLER_23] = BtlController_Empty, [CONTROLLER_HEALTHBARUPDATE] = BtlController_HandleHealthBarUpdate, [CONTROLLER_EXPUPDATE] = PlayerHandleExpUpdate, // Partner's player gets experience the same way as the player. - [CONTROLLER_STATUSICONUPDATE] = BtlController_HandleStatusIconUpdate, + [CONTROLLER_STATUSICONUPDATE] = RecordedPartnerHandleStatusIconUpdate, [CONTROLLER_STATUSANIMATION] = BtlController_HandleStatusAnimation, [CONTROLLER_STATUSXOR] = BtlController_Empty, [CONTROLLER_DATATRANSFER] = BtlController_Empty, @@ -288,3 +289,13 @@ static void RecordedPartnerHandleEndLinkBattle(u32 battler) BtlController_Complete(battler); gBattlerControllerFuncs[battler] = SetBattleEndCallbacks; } + +static void RecordedPartnerHandleStatusIconUpdate(u32 battler) +{ + if (!IsBattleSEPlaying(battler)) + { + DoStatusIconUpdate(battler); + if (gTestRunnerEnabled) + TestRunner_Battle_RecordStatus1(battler, GetMonData(GetBattlerMon(battler), MON_DATA_STATUS)); + } +} diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 929014fba2..d175d33d9f 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -1486,10 +1486,10 @@ static u32 GetBattlerMonData(u32 battler, struct Pokemon *party, u32 monId, u8 * #if TESTING if (gTestRunnerEnabled) { - u32 side = GetBattlerSide(battler); + u32 array = (!IsPartnerMonFromSameTrainer(battler)) ? battler : GetBattlerSide(battler); u32 partyIndex = gBattlerPartyIndexes[battler]; - if (TestRunner_Battle_GetForcedAbility(side, partyIndex)) - gBattleMons[battler].ability = TestRunner_Battle_GetForcedAbility(side, partyIndex); + if (TestRunner_Battle_GetForcedAbility(array, partyIndex)) + gBattleMons[battler].ability = TestRunner_Battle_GetForcedAbility(array, partyIndex); } #endif break; diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 72e7eb8512..aab9aa1c13 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -955,8 +955,8 @@ void HandleSpeciesGfxDataChange(u8 battlerAtk, u8 battlerDef, u8 changeType) if (changeType == SPECIES_GFX_CHANGE_TRANSFORM) { - personalityValue = gBattleMons[battlerAtk].volatiles.transformedMonPID; - isShiny = gBattleMons[battlerAtk].volatiles.isTransformedMonShiny; + personalityValue = gTransformedPersonalities[battlerAtk]; + isShiny = gTransformedShininess[battlerAtk]; } else { diff --git a/src/battle_main.c b/src/battle_main.c index 3c34d966ac..1b7f1242b5 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -3254,10 +3254,10 @@ void SwitchInClearSetData(u32 battler, struct Volatiles *volatilesCopy) #if TESTING if (gTestRunnerEnabled) { - u32 side = GetBattlerSide(battler); + u32 array = (!IsPartnerMonFromSameTrainer(battler)) ? battler : GetBattlerSide(battler); u32 partyIndex = gBattlerPartyIndexes[battler]; - if (TestRunner_Battle_GetForcedAbility(side, partyIndex)) - gBattleMons[i].ability = TestRunner_Battle_GetForcedAbility(side, partyIndex); + if (TestRunner_Battle_GetForcedAbility(array, partyIndex)) + gBattleMons[i].ability = TestRunner_Battle_GetForcedAbility(array, partyIndex); } #endif // TESTING @@ -3460,10 +3460,10 @@ static void DoBattleIntro(void) #if TESTING if (gTestRunnerEnabled) { - u32 side = GetBattlerSide(battler); + u32 array = (!IsPartnerMonFromSameTrainer(battler)) ? battler : GetBattlerSide(battler); u32 partyIndex = gBattlerPartyIndexes[battler]; - if (TestRunner_Battle_GetForcedAbility(side, partyIndex)) - gBattleMons[battler].ability = TestRunner_Battle_GetForcedAbility(side, partyIndex); + if (TestRunner_Battle_GetForcedAbility(array, partyIndex)) + gBattleMons[battler].ability = TestRunner_Battle_GetForcedAbility(array, partyIndex); } #endif } @@ -3755,10 +3755,10 @@ static void TryDoEventsBeforeFirstTurn(void) { for (i = 0; i < gBattlersCount; ++i) { - u32 side = GetBattlerSide(i); + u32 array = (!IsPartnerMonFromSameTrainer(i)) ? i : GetBattlerSide(i); u32 partyIndex = gBattlerPartyIndexes[i]; - if (TestRunner_Battle_GetForcedAbility(side, partyIndex)) - gBattleMons[i].ability = TestRunner_Battle_GetForcedAbility(side, partyIndex); + if (TestRunner_Battle_GetForcedAbility(array, partyIndex)) + gBattleMons[i].ability = TestRunner_Battle_GetForcedAbility(array, partyIndex); } } #endif // TESTING diff --git a/src/battle_message.c b/src/battle_message.c index 74e56ccde4..e03830b451 100644 --- a/src/battle_message.c +++ b/src/battle_message.c @@ -679,7 +679,7 @@ const u8 *const gBattleStringsTable[STRINGID_COUNT] = [STRINGID_SWEETVEILPROTECTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} can't fall asleep due to a veil of sweetness!"), [STRINGID_AROMAVEILPROTECTED] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} is protected by an aromatic veil!"), [STRINGID_CELEBRATEMESSAGE] = COMPOUND_STRING("Congratulations, {B_PLAYER_NAME}!"), - [STRINGID_USEDINSTRUCTEDMOVE] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} followed {B_SCR_NAME_WITH_PREFIX2}'s instructions!"), + [STRINGID_USEDINSTRUCTEDMOVE] = COMPOUND_STRING("{B_DEF_NAME_WITH_PREFIX} followed {B_ATK_NAME_WITH_PREFIX2}'s instructions!"), [STRINGID_THROATCHOPENDS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} can use sound-based moves again!"), [STRINGID_PKMNCANTUSEMOVETHROATCHOP] = COMPOUND_STRING("The effects of Throat Chop prevent {B_ATK_NAME_WITH_PREFIX2} from using certain moves!\p"), [STRINGID_LASERFOCUS] = COMPOUND_STRING("{B_ATK_NAME_WITH_PREFIX} concentrated intensely!"), diff --git a/src/battle_move_resolution.c b/src/battle_move_resolution.c index 7299ad03fa..91432df6ad 100644 --- a/src/battle_move_resolution.c +++ b/src/battle_move_resolution.c @@ -67,7 +67,7 @@ static enum MoveEndResult MoveEnd_ProtectLikeEffect(void) result = MOVEEND_STEP_RUN_SCRIPT; break; case PROTECT_BANEFUL_BUNKER: - if (CanBePoisoned(gBattlerTarget, gBattlerAttacker, gLastUsedAbility, GetBattlerAbility(gBattlerAttacker))) + if (CanBePoisoned(gBattlerTarget, gBattlerAttacker, GetBattlerAbility(gBattlerTarget), GetBattlerAbility(gBattlerAttacker))) { gBattleScripting.moveEffect = MOVE_EFFECT_POISON; BattleScriptCall(BattleScript_BanefulBunkerEffect); @@ -446,7 +446,8 @@ static enum MoveEndResult MoveEnd_FaintBlock(void) && IsBattlerAlive(gBattlerAttacker) && !IsBattlerAlly(gBattlerAttacker, gBattlerTarget) && !IsZMove(gCurrentMove) - && gCurrentMove != MOVE_STRUGGLE) + && gCurrentMove != MOVE_STRUGGLE + && GetMoveEffect(gCurrentMove) != EFFECT_FUTURE_SIGHT) { gBattleStruct->tryGrudge = TRUE; } @@ -570,7 +571,7 @@ static enum MoveEndResult MoveEnd_UpdateLastMoves(void) && gBattlerTarget != gBattlerAttacker && !IsBattlerAlly(gBattlerTarget, gBattlerAttacker) && gProtectStructs[gBattlerTarget].physicalBattlerId == gBattlerAttacker - && !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)) + && !IsSheerForceAffected(gCurrentMove, GetBattlerAbility(gBattlerAttacker))) { gProtectStructs[gBattlerTarget].shellTrap = TRUE; // Change move order in double battles, so the hit mon with shell trap moves immediately after being hit. @@ -1098,7 +1099,7 @@ static enum MoveEndResult MoveEnd_AbilityEffectFoesFainted(void) static enum MoveEndResult MoveEnd_SheerForce(void) { - if (TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)) + if (IsSheerForceAffected(gCurrentMove, GetBattlerAbility(gBattlerAttacker))) gBattleScripting.moveendState = MOVEEND_EJECT_PACK; else gBattleScripting.moveendState++; @@ -1272,7 +1273,6 @@ static enum MoveEndResult MoveEnd_LifeOrbShellBell(void) if (ItemBattleEffects(gBattlerAttacker, 0, GetBattlerHoldEffect(gBattlerAttacker), IsLifeOrbShellBellActivation)) result = MOVEEND_STEP_RUN_SCRIPT; - // DebugPrintf("[11]"); gBattleScripting.moveendState++; return result; } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 5657770a6a..db2d04f7a5 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2744,6 +2744,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, enum MoveEffect moveEffect, c case MOVE_EFFECT_STEALTH_ROCK: case MOVE_EFFECT_PAYDAY: case MOVE_EFFECT_BUG_BITE: + case MOVE_EFFECT_FLAME_BURST: activateAfterFaint = TRUE; break; default: @@ -2757,7 +2758,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, enum MoveEffect moveEffect, c if (!primary && !affectsUser && IsMoveEffectBlockedByTarget(battlerAbility)) moveEffect = MOVE_EFFECT_NONE; else if (!primary - && TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove) + && IsSheerForceAffected(gCurrentMove, GetBattlerAbility(battler)) && !(moveEffect == MOVE_EFFECT_ORDER_UP && gBattleStruct->battlerState[gBattlerAttacker].commanderSpecies != SPECIES_NONE)) moveEffect = MOVE_EFFECT_NONE; else if (!IsBattlerAlive(gEffectBattler) && !activateAfterFaint) @@ -5376,10 +5377,10 @@ static void Cmd_switchindataupdate(void) #if TESTING if (gTestRunnerEnabled) { - u32 side = GetBattlerSide(battler); + u32 array = (!IsPartnerMonFromSameTrainer(battler)) ? battler : GetBattlerSide(battler); u32 partyIndex = gBattlerPartyIndexes[battler]; - if (TestRunner_Battle_GetForcedAbility(side, partyIndex)) - gBattleMons[battler].ability = TestRunner_Battle_GetForcedAbility(side, partyIndex); + if (TestRunner_Battle_GetForcedAbility(array, partyIndex)) + gBattleMons[battler].ability = TestRunner_Battle_GetForcedAbility(array, partyIndex); } #endif @@ -9028,10 +9029,10 @@ static void Cmd_mimicattackcopy(void) { CMD_ARGS(const u8 *failInstr); - if ((IsMoveMimicBanned(gLastMoves[gBattlerTarget])) - || (gBattleMons[gBattlerAttacker].volatiles.transformed) - || gLastMoves[gBattlerTarget] == MOVE_NONE - || gLastMoves[gBattlerTarget] == MOVE_UNAVAILABLE) + if (gLastMoves[gBattlerTarget] == MOVE_UNAVAILABLE + || gLastMoves[gBattlerTarget] == MOVE_NONE + || gBattleMons[gBattlerAttacker].volatiles.transformed + || IsMoveMimicBanned(gLastMoves[gBattlerTarget])) { gBattlescriptCurrInstr = cmd->failInstr; } @@ -9200,120 +9201,75 @@ static void Cmd_settypetorandomresistance(void) // Before Gen 5 Conversion 2 only worked on a move the attacker was actually hit by. // This changed later to the last move used by the selected target. - if (B_UPDATED_CONVERSION_2 < GEN_5) + u32 moveToCheck; + u32 typeToCheck; + + if (GetConfig(CONFIG_UPDATED_CONVERSION_2) < GEN_5) { - if (gLastLandedMoves[gBattlerAttacker] == MOVE_NONE - || gLastLandedMoves[gBattlerAttacker] == MOVE_UNAVAILABLE) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (gBattleMoveEffects[GetMoveEffect(gLastLandedMoves[gBattlerAttacker])].twoTurnEffect - && gBattleMons[gLastHitBy[gBattlerAttacker]].volatiles.multipleTurns) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (gLastHitByType[gBattlerAttacker] == TYPE_STELLAR || gLastHitByType[gBattlerAttacker] == TYPE_MYSTERY) - { - gBattlescriptCurrInstr = cmd->failInstr; - } + moveToCheck = gLastLandedMoves[gBattlerAttacker]; + if (GetMoveEffect(moveToCheck) == EFFECT_STRUGGLE) + typeToCheck = TYPE_NORMAL; else - { - u32 i, resistTypes = 0; - u32 hitByType = gLastHitByType[gBattlerAttacker]; - - for (i = 0; i < NUMBER_OF_MON_TYPES; i++) // Find all types that resist. - { - switch (GetTypeModifier(hitByType, i)) - { - case UQ_4_12(0): - case UQ_4_12(0.5): - resistTypes |= 1u << i; - break; - } - } - - while (resistTypes != 0) - { - i = Random() % NUMBER_OF_MON_TYPES; - if (resistTypes & 1u << i) - { - if (IS_BATTLER_OF_TYPE(gBattlerAttacker, i)) - { - resistTypes &= ~(1u << i); // Type resists, but the user is already of this type. - } - else - { - SET_BATTLER_TYPE(gBattlerAttacker, i); - PREPARE_TYPE_BUFFER(gBattleTextBuff1, i); - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - } - } - - gBattlescriptCurrInstr = cmd->failInstr; - } + typeToCheck = gLastHitByType[gBattlerAttacker]; } else { - if (gLastResultingMoves[gBattlerTarget] == MOVE_NONE - || gLastResultingMoves[gBattlerTarget] == MOVE_UNAVAILABLE - || gLastResultingMoves[gBattlerTarget] == MOVE_STRUGGLE) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (!BreaksThroughSemiInvulnerablity(gBattlerTarget, gCurrentMove)) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (gLastUsedMoveType[gBattlerTarget] == TYPE_NONE || gLastUsedMoveType[gBattlerTarget] == TYPE_STELLAR || gLastUsedMoveType[gBattlerTarget] == TYPE_MYSTERY) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - u32 i, resistTypes = 0; + moveToCheck = gLastResultingMoves[gBattlerTarget]; + typeToCheck = gLastUsedMoveType[gBattlerTarget]; + } - for (i = 0; i < NUMBER_OF_MON_TYPES; i++) // Find all types that resist. + if (moveToCheck == MOVE_NONE + || moveToCheck == MOVE_UNAVAILABLE) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else if (!BreaksThroughSemiInvulnerablity(gBattlerTarget, moveToCheck)) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else if (typeToCheck == TYPE_NONE || typeToCheck == TYPE_STELLAR || typeToCheck == TYPE_MYSTERY) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + u32 i, resistTypes = 0; + + for (i = 0; i < NUMBER_OF_MON_TYPES; i++) // Find all types that resist. + { + switch (GetTypeModifier(typeToCheck, i)) { - switch (GetTypeModifier(gLastUsedMoveType[gBattlerTarget], i)) + case UQ_4_12(0): + case UQ_4_12(0.5): + resistTypes |= 1u << i; + break; + } + } + + while (resistTypes != 0) + { + i = Random() % NUMBER_OF_MON_TYPES; + if (resistTypes & 1u << i) + { + if (IS_BATTLER_OF_TYPE(gBattlerAttacker, i)) { - case UQ_4_12(0): - case UQ_4_12(0.5): - resistTypes |= 1u << i; - break; + resistTypes &= ~(1u << i); // Type resists, but the user is already of this type. + } + else + { + SET_BATTLER_TYPE(gBattlerAttacker, i); + PREPARE_TYPE_BUFFER(gBattleTextBuff1, i); + gBattlescriptCurrInstr = cmd->nextInstr; + return; } } - - while (resistTypes != 0) - { - i = Random() % NUMBER_OF_MON_TYPES; - if (resistTypes & 1u << i) - { - if (IS_BATTLER_OF_TYPE(gBattlerAttacker, i)) - { - resistTypes &= ~(1u << i); // Type resists, but the user is already of this type. - } - else - { - SET_BATTLER_TYPE(gBattlerAttacker, i); - PREPARE_TYPE_BUFFER(gBattleTextBuff1, i); - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - } - } - - gBattlescriptCurrInstr = cmd->failInstr; } + + gBattlescriptCurrInstr = cmd->failInstr; } } @@ -9413,7 +9369,7 @@ static void Cmd_settailwind(void) if (!(gSideStatuses[side] & SIDE_STATUS_TAILWIND)) { gSideStatuses[side] |= SIDE_STATUS_TAILWIND; - gSideTimers[side].tailwindTimer = (B_TAILWIND_TURNS >= GEN_5 ? 4 : 3); + gSideTimers[side].tailwindTimer = (GetConfig(CONFIG_TAILWIND_TURNS) >= GEN_5 ? 4 : 3); gBattlescriptCurrInstr = cmd->nextInstr; } else @@ -9565,9 +9521,9 @@ static void Cmd_healpartystatus(void) #if TESTING if (gTestRunnerEnabled) { - u32 side = GetBattlerSide(gBattlerAttacker); - if (TestRunner_Battle_GetForcedAbility(side, i)) - ability = TestRunner_Battle_GetForcedAbility(side, i); + u32 array = (!IsPartnerMonFromSameTrainer(gBattlerAttacker)) ? gBattlerAttacker : GetBattlerSide(gBattlerAttacker); + if (TestRunner_Battle_GetForcedAbility(array, i)) + ability = TestRunner_Battle_GetForcedAbility(array, i); } #endif } @@ -10375,7 +10331,7 @@ static void Cmd_tryswapitems(void) if (GetBattlerAbility(gBattlerTarget) != ABILITY_GORILLA_TACTICS) gBattleStruct->choicedMove[gBattlerTarget] = MOVE_NONE; - if (GetBattlerAbility(gBattlerTarget) != ABILITY_GORILLA_TACTICS) + if (GetBattlerAbility(gBattlerAttacker) != ABILITY_GORILLA_TACTICS) gBattleStruct->choicedMove[gBattlerAttacker] = MOVE_NONE; gBattlescriptCurrInstr = cmd->nextInstr; @@ -10909,47 +10865,50 @@ static void Cmd_settypebasedhalvers(void) bool8 worked = FALSE; - if (GetMoveEffect(gCurrentMove) == EFFECT_MUD_SPORT) + if (!gBattleStruct->isSkyBattle) { - if (B_SPORT_TURNS >= GEN_6) + if (GetMoveEffect(gCurrentMove) == EFFECT_MUD_SPORT) { - if (!(gFieldStatuses & STATUS_FIELD_MUDSPORT)) + if (B_SPORT_TURNS >= GEN_6) { - gFieldStatuses |= STATUS_FIELD_MUDSPORT; - gFieldTimers.mudSportTimer = 5; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_ELECTRIC; - worked = TRUE; + if (!(gFieldStatuses & STATUS_FIELD_MUDSPORT)) + { + gFieldStatuses |= STATUS_FIELD_MUDSPORT; + gFieldTimers.mudSportTimer = 5; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_ELECTRIC; + worked = TRUE; + } + } + else + { + if (!gBattleMons[gBattlerAttacker].volatiles.mudSport) + { + gBattleMons[gBattlerAttacker].volatiles.mudSport = TRUE; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_ELECTRIC; + worked = TRUE; + } } } - else + else // Water Sport { - if (!gBattleMons[gBattlerAttacker].volatiles.waterSport) + if (B_SPORT_TURNS >= GEN_6) { - gBattleMons[gBattlerAttacker].volatiles.waterSport = TRUE; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_ELECTRIC; - worked = TRUE; + if (!(gFieldStatuses & STATUS_FIELD_WATERSPORT)) + { + gFieldStatuses |= STATUS_FIELD_WATERSPORT; + gFieldTimers.waterSportTimer = 5; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_FIRE; + worked = TRUE; + } } - } - } - else // Water Sport - { - if (B_SPORT_TURNS >= GEN_6) - { - if (!(gFieldStatuses & STATUS_FIELD_WATERSPORT)) + else { - gFieldStatuses |= STATUS_FIELD_WATERSPORT; - gFieldTimers.waterSportTimer = 5; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_FIRE; - worked = TRUE; - } - } - else - { - if (!gBattleMons[gBattlerAttacker].volatiles.mudSport) - { - gBattleMons[gBattlerAttacker].volatiles.mudSport = TRUE; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_FIRE; - worked = TRUE; + if (!gBattleMons[gBattlerAttacker].volatiles.waterSport) + { + gBattleMons[gBattlerAttacker].volatiles.waterSport = TRUE; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_FIRE; + worked = TRUE; + } } } } @@ -14196,7 +14155,27 @@ void BS_GetStatValue(void) { NATIVE_ARGS(u8 stat); u32 stat = cmd->stat; - gBattleStruct->passiveHpUpdate[gBattlerAttacker] = *(u16 *)(&gBattleMons[gBattlerTarget].attack) + (stat - 1); + switch (stat) + { + case STAT_ATK: + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = gBattleMons[gBattlerTarget].attack; + break; + case STAT_DEF: + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = gBattleMons[gBattlerTarget].defense; + break; + case STAT_SPATK: + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = gBattleMons[gBattlerTarget].spAttack; + break; + case STAT_SPDEF: + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = gBattleMons[gBattlerTarget].spDefense; + break; + case STAT_SPEED: + gBattleStruct->passiveHpUpdate[gBattlerAttacker] = gBattleMons[gBattlerTarget].speed; + break; + default: + // Add errorf here on upcoming + return; + } gBattleStruct->passiveHpUpdate[gBattlerAttacker] *= gStatStageRatios[gBattleMons[gBattlerTarget].statStages[stat]][0]; gBattleStruct->passiveHpUpdate[gBattlerAttacker] /= gStatStageRatios[gBattleMons[gBattlerTarget].statStages[stat]][1]; gBattlescriptCurrInstr = cmd->nextInstr; @@ -15626,3 +15605,29 @@ void BS_JumpIfGenConfigLowerThan(void) else gBattlescriptCurrInstr = cmd->nextInstr; } + +// Used when the Pokemon faints before Toxic Spikes would normally be processed in the hazards queue. +void BS_TryAbsorbToxicSpikesOnFaint(void) +{ + NATIVE_ARGS(); + u32 battler = gBattlerFainted; + u32 side = GetBattlerSide(battler); + + if (gSideTimers[side].toxicSpikesAmount == 0) + { + gBattlescriptCurrInstr = cmd->nextInstr; + return; + } + + if (IsBattlerGrounded(battler, GetBattlerAbility(battler), GetBattlerHoldEffect(battler)) + && IS_BATTLER_OF_TYPE(battler, TYPE_POISON)) + { + gSideTimers[side].toxicSpikesAmount = 0; + RemoveHazardFromField(side, HAZARDS_TOXIC_SPIKES); + gEffectBattler = battler; + BattleScriptCall(BattleScript_ToxicSpikesAbsorbed); + return; + } + + gBattlescriptCurrInstr = cmd->nextInstr; +} diff --git a/src/battle_util.c b/src/battle_util.c index eeba8339b3..cfb40612f3 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2023,6 +2023,18 @@ static inline bool32 TryActivatePowderStatus(u32 move) return FALSE; } +static void RequestNonVolatileChangee(u32 battlerAtk) +{ + BtlController_EmitSetMonData( + battlerAtk, + B_COMM_TO_CONTROLLER, + REQUEST_STATUS_BATTLE, + 0, + 4, + &gBattleMons[battlerAtk].status1); + MarkBattlerForControllerExec(battlerAtk); +} + static enum MoveCanceler CancelerClearFlags(struct BattleContext *ctx) { gBattleMons[ctx->battlerAtk].volatiles.grudge = FALSE; @@ -2061,6 +2073,8 @@ static enum MoveCanceler CancelerRecharge(struct BattleContext *ctx) static enum MoveCanceler CancelerAsleepOrFrozen(struct BattleContext *ctx) { + enum MoveCanceler effect = MOVE_STEP_BREAK; + if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_SLEEP) { if (UproarWakeUpCheck(ctx->battlerAtk)) @@ -2070,16 +2084,17 @@ static enum MoveCanceler CancelerAsleepOrFrozen(struct BattleContext *ctx) gBattleMons[ctx->battlerAtk].volatiles.nightmare = FALSE; gEffectBattler = ctx->battlerAtk; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP_UPROAR; + effect = MOVE_STEP_BREAK; BattleScriptCall(BattleScript_MoveUsedWokeUp); - return MOVE_STEP_REMOVES_STATUS; } else { - u8 toSub; + u32 toSub; if (IsAbilityAndRecord(ctx->battlerAtk, ctx->abilityAtk, ABILITY_EARLY_BIRD)) toSub = 2; else toSub = 1; + if ((gBattleMons[ctx->battlerAtk].status1 & STATUS1_SLEEP) < toSub) gBattleMons[ctx->battlerAtk].status1 &= ~STATUS1_SLEEP; else @@ -2090,8 +2105,12 @@ static enum MoveCanceler CancelerAsleepOrFrozen(struct BattleContext *ctx) { if (!IsUsableWhileAsleepEffect(moveEffect)) { + effect = MOVE_STEP_FAILURE; gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep; - return MOVE_STEP_FAILURE; + } + else + { + effect = MOVE_STEP_BREAK; } } else @@ -2099,27 +2118,30 @@ static enum MoveCanceler CancelerAsleepOrFrozen(struct BattleContext *ctx) TryDeactivateSleepClause(GetBattlerSide(ctx->battlerAtk), gBattlerPartyIndexes[ctx->battlerAtk]); gBattleMons[ctx->battlerAtk].volatiles.nightmare = FALSE; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP; + effect = MOVE_STEP_BREAK; BattleScriptCall(BattleScript_MoveUsedWokeUp); - return MOVE_STEP_REMOVES_STATUS; } } + RequestNonVolatileChangee(ctx->battlerAtk); } else if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_FREEZE && !MoveThawsUser(ctx->move)) { if (!RandomPercentage(RNG_FROZEN, 20)) { + effect = MOVE_STEP_FAILURE; gBattlescriptCurrInstr = BattleScript_MoveUsedIsFrozen; - return MOVE_STEP_FAILURE; } else // unfreeze { gBattleMons[ctx->battlerAtk].status1 &= ~STATUS1_FREEZE; + effect = MOVE_STEP_BREAK; BattleScriptCall(BattleScript_MoveUsedUnfroze); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED; - return MOVE_STEP_REMOVES_STATUS; } + RequestNonVolatileChangee(ctx->battlerAtk); } - return MOVE_STEP_SUCCESS; + + return effect; } static enum MoveCanceler CancelerObedience(struct BattleContext *ctx) @@ -2521,27 +2543,39 @@ static enum MoveCanceler CancelerCallSubmove(struct BattleContext *ctx) static enum MoveCanceler CancelerThaw(struct BattleContext *ctx) { + enum MoveCanceler effect = MOVE_STEP_BREAK; + if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_FREEZE) { if (!(IsMoveEffectRemoveSpeciesType(ctx->move, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(ctx->battlerAtk, TYPE_FIRE))) { gBattleMons[ctx->battlerAtk].status1 &= ~STATUS1_FREEZE; + effect = MOVE_STEP_BREAK; BattleScriptCall(BattleScript_MoveUsedUnfroze); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED_BY_MOVE; } - return MOVE_STEP_REMOVES_STATUS; + else + { + effect = MOVE_STEP_FAILURE; + } + RequestNonVolatileChangee(ctx->battlerAtk); } - if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_FROSTBITE && MoveThawsUser(ctx->move)) + else if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_FROSTBITE && MoveThawsUser(ctx->move)) { if (!(IsMoveEffectRemoveSpeciesType(ctx->move, MOVE_EFFECT_REMOVE_ARG_TYPE, TYPE_FIRE) && !IS_BATTLER_OF_TYPE(ctx->battlerAtk, TYPE_FIRE))) { gBattleMons[ctx->battlerAtk].status1 &= ~STATUS1_FROSTBITE; + effect = MOVE_STEP_BREAK; BattleScriptCall(BattleScript_MoveUsedUnfrostbite); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FROSTBITE_HEALED_BY_MOVE; } - return MOVE_STEP_REMOVES_STATUS; + else + { + effect = MOVE_STEP_FAILURE; + } + RequestNonVolatileChangee(ctx->battlerAtk); } - return MOVE_STEP_SUCCESS; + return effect; } static enum MoveCanceler CancelerStanceChangeTwo(struct BattleContext *ctx) @@ -3101,18 +3135,6 @@ enum MoveCanceler AtkCanceler_MoveSuccessOrder(struct BattleContext *ctx) gBattleStruct->eventState.atkCanceler++; } - if (effect == MOVE_STEP_REMOVES_STATUS) - { - BtlController_EmitSetMonData( - ctx->battlerAtk, - B_COMM_TO_CONTROLLER, - REQUEST_STATUS_BATTLE, - 0, - 4, - &gBattleMons[gBattlerAttacker].status1); - MarkBattlerForControllerExec(ctx->battlerAtk); - } - return effect; } @@ -4984,7 +5006,8 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, u32 battler, enum Ability ab } break; case ABILITY_BALL_FETCH: - if (gBattleMons[battler].item == ITEM_NONE + if (!(gBattleTypeFlags & BATTLE_TYPE_RAID) + && gBattleMons[battler].item == ITEM_NONE && gBattleResults.catchAttempts[ItemIdToBallId(gLastUsedBall)] >= 1 && !gHasFetchedBall) { @@ -6309,6 +6332,7 @@ bool32 IsBattlerTerrainAffected(u32 battler, enum Ability ability, enum HoldEffe u32 GetHighestStatId(u32 battler) { u32 highestId = STAT_ATK; + bool32 wonderRoom = (gFieldStatuses & STATUS_FIELD_WONDER_ROOM) != 0; u32 highestStat = gBattleMons[battler].attack; for (u32 stat = STAT_DEF; stat < NUM_STATS; stat++) @@ -6316,10 +6340,28 @@ u32 GetHighestStatId(u32 battler) if (stat == STAT_SPEED) continue; - u16 *statVal = &gBattleMons[battler].attack + (stat - 1); - if (*statVal > highestStat) + u32 statVal; + switch (stat) { - highestStat = *statVal; + case STAT_ATK: + statVal = gBattleMons[battler].attack; + break; + case STAT_DEF: + statVal = wonderRoom ? gBattleMons[battler].spDefense : gBattleMons[battler].defense; + break; + case STAT_SPATK: + statVal = gBattleMons[battler].spAttack; + break; + case STAT_SPDEF: + statVal = wonderRoom ? gBattleMons[battler].defense : gBattleMons[battler].spDefense; + break; + default: + continue; + } + + if (statVal > highestStat) + { + highestStat = statVal; highestId = stat; } } @@ -7408,7 +7450,10 @@ static inline u32 CalcTerrainBoostedPower(struct BattleContext *ctx, u32 basePow static inline u32 IsFieldMudSportAffected(enum Type moveType) { - if (moveType == TYPE_ELECTRIC && (gFieldStatuses & STATUS_FIELD_MUDSPORT)) + if (moveType != TYPE_ELECTRIC) + return FALSE; + + if (gFieldStatuses & STATUS_FIELD_MUDSPORT) return TRUE; if (B_SPORT_TURNS < GEN_6) @@ -7425,7 +7470,10 @@ static inline u32 IsFieldMudSportAffected(enum Type moveType) static inline u32 IsFieldWaterSportAffected(enum Type moveType) { - if (moveType == TYPE_FIRE && (gFieldStatuses & STATUS_FIELD_WATERSPORT)) + if (moveType != TYPE_FIRE) + return FALSE; + + if (gFieldStatuses & STATUS_FIELD_WATERSPORT) return TRUE; if (B_SPORT_TURNS < GEN_6) @@ -7764,9 +7812,9 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct BattleContext *ctx) if (IsPsychicTerrainAffected(battlerAtk, ctx->abilityAtk, ctx->holdEffectAtk, ctx->fieldStatuses) && moveType == TYPE_PSYCHIC) modifier = uq4_12_multiply(modifier, (B_TERRAIN_TYPE_BOOST >= GEN_8 ? UQ_4_12(1.3) : UQ_4_12(1.5))); if (IsFieldMudSportAffected(ctx->moveType)) - modifier = uq4_12_multiply(modifier, UQ_4_12(B_SPORT_DMG_REDUCTION >= GEN_5 ? 0.33 : 0.5)); + modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(CONFIG_SPORT_DMG_REDUCTION) >= GEN_5 ? 0.33 : 0.5)); if (IsFieldWaterSportAffected(ctx->moveType)) - modifier = uq4_12_multiply(modifier, UQ_4_12(B_SPORT_DMG_REDUCTION >= GEN_5 ? 0.33 : 0.5)); + modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(CONFIG_SPORT_DMG_REDUCTION) >= GEN_5 ? 0.33 : 0.5)); // attacker's abilities switch (ctx->abilityAtk) @@ -8238,7 +8286,8 @@ static inline u32 CalcAttackStat(struct BattleContext *ctx) } break; case ABILITY_ORICHALCUM_PULSE: - if (ctx->weather & B_WEATHER_SUN && IsBattleMovePhysical(move)) + if (ctx->weather & B_WEATHER_SUN && IsBattleMovePhysical(move) + && ctx->holdEffectAtk != HOLD_EFFECT_UTILITY_UMBRELLA) modifier = uq4_12_multiply(modifier, UQ_4_12(1.3333)); break; case ABILITY_HADRON_ENGINE: @@ -10511,9 +10560,9 @@ bool32 IsBattlerAffectedByHazards(u32 battler, enum HoldEffect holdEffect, bool3 return ret; } -bool32 TestIfSheerForceAffected(u32 battler, u16 move) +bool32 IsSheerForceAffected(u16 move, enum Ability ability) { - return GetBattlerAbility(battler) == ABILITY_SHEER_FORCE && MoveIsAffectedBySheerForce(move); + return ability == ABILITY_SHEER_FORCE && MoveIsAffectedBySheerForce(move); } // This function is the body of "jumpifstat", but can be used dynamically in a function @@ -12055,9 +12104,9 @@ void SetWrapTurns(u32 battler, enum HoldEffect holdEffect) { u32 normalWrapTurns = B_WRAP_TURNS - 2; // 5 turns if (holdEffect == HOLD_EFFECT_GRIP_CLAW) - gBattleMons[battler].volatiles.wrapTurns = B_BINDING_TURNS >= GEN_5 ? B_WRAP_TURNS : normalWrapTurns; + gBattleMons[battler].volatiles.wrapTurns = GetConfig(CONFIG_BINDING_TURNS) >= GEN_5 ? B_WRAP_TURNS : normalWrapTurns; else - gBattleMons[battler].volatiles.wrapTurns = B_BINDING_TURNS >= GEN_5 ? RandomUniform(RNG_WRAP, 4, normalWrapTurns) : RandomUniform(RNG_WRAP, 2, normalWrapTurns); + gBattleMons[battler].volatiles.wrapTurns = GetConfig(CONFIG_BINDING_TURNS) >= GEN_5 ? RandomUniform(RNG_WRAP, 4, normalWrapTurns) : RandomUniform(RNG_WRAP, 2, normalWrapTurns); } // Return True if the order was changed, and false if the order was not changed(for example because the target would move after the attacker anyway). @@ -12110,11 +12159,12 @@ void TryUpdateEvolutionTracker(u32 evolutionCondition, u32 upAmount, u16 usedMov u32 i, j; if (IsOnPlayerSide(gBattlerAttacker) - && !(gBattleTypeFlags & (BATTLE_TYPE_LINK + && ((TESTING && IsDoubleBattle()) // To be removed when Wild Double Battles are added to tests + || !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_TRAINER_HILL - | BATTLE_TYPE_FRONTIER))) + | BATTLE_TYPE_FRONTIER)))) { const struct Evolution *evolutions = GetSpeciesEvolutions(gBattleMons[gBattlerAttacker].species); if (evolutions == NULL) diff --git a/src/crt0.s b/src/crt0.s index bd0eb9426c..341f14c379 100644 --- a/src/crt0.s +++ b/src/crt0.s @@ -37,7 +37,7 @@ sp_irq: .word IWRAM_END - 0x60 .pool .arm - .section .iwram.code + .section .iwram.code, "ax", %progbits .align 2, 0 IntrMain:: mov r3, #REG_BASE diff --git a/src/data/moves_info.h b/src/data/moves_info.h index e1471b6585..38db2baf86 100644 --- a/src/data/moves_info.h +++ b/src/data/moves_info.h @@ -12580,7 +12580,6 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_ALL] = .category = DAMAGE_CATEGORY_SPECIAL, .additionalEffects = ADDITIONAL_EFFECTS({ .moveEffect = MOVE_EFFECT_FLAME_BURST, - .self = TRUE, }), .contestEffect = CONTEST_EFFECT_SHIFT_JUDGE_ATTENTION, .contestCategory = CONTEST_CATEGORY_BEAUTY, diff --git a/src/data/pokemon/species_info/gen_1_families.h b/src/data/pokemon/species_info/gen_1_families.h index aca0a78eb6..0f02ec39be 100644 --- a/src/data/pokemon/species_info/gen_1_families.h +++ b/src/data/pokemon/species_info/gen_1_families.h @@ -5048,41 +5048,22 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = "It flies by using the power of\n" "moonlight to control gravity within\n" "a radius of over 32 feet around it."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Clefable) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sClefableLevelUpLearnset, .teachableLearnset = sClefableTeachableLearnset, @@ -9252,41 +9233,22 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = "has increased due to Mega Evolution,\n" "filling its mouth. If not careful,\n" "the acid will overflow and spill out."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Victreebel) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sVictreebelLevelUpLearnset, .teachableLearnset = sVictreebelTeachableLearnset, @@ -15682,41 +15644,22 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = "humanlike. Whether it's simply\n" "trying to communicate or wants to\n" "supplant humanity is unclear."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Starmie) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sStarmieLevelUpLearnset, .teachableLearnset = sStarmieTeachableLearnset, @@ -20228,41 +20171,22 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = "powered up this Pokémon's feelings\n" "of kindness. It finishes off its\n" "opponents with mercy in its heart."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Dragonite) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sDragoniteLevelUpLearnset, .teachableLearnset = sDragoniteTeachableLearnset, diff --git a/src/data/pokemon/species_info/gen_2_families.h b/src/data/pokemon/species_info/gen_2_families.h index b014adf82a..da83fa1cef 100644 --- a/src/data/pokemon/species_info/gen_2_families.h +++ b/src/data/pokemon/species_info/gen_2_families.h @@ -267,41 +267,22 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = "powerful Solar Beam from its four\n" "flowers. Another name for this is\n" "Mega Sol Cannon."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Meganium) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sMeganiumLevelUpLearnset, .teachableLearnset = sMeganiumTeachableLearnset, @@ -853,41 +834,22 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = "Pokémon forms a gigantic set of jaws\n" "with a bite 10 times as powerful\n" "as Mega Feraligatr's actual jaws."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Feraligatr) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sFeraligatrLevelUpLearnset, .teachableLearnset = sFeraligatrTeachableLearnset, @@ -7309,41 +7271,22 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = "its pincers have taken a more\n" "diabolical form, ripping anything\n" "they pierce to shreds."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Skarmory) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sSkarmoryLevelUpLearnset, .teachableLearnset = sSkarmoryTeachableLearnset, diff --git a/src/data/pokemon/species_info/gen_3_families.h b/src/data/pokemon/species_info/gen_3_families.h index 4c156bc548..028027a3ec 100644 --- a/src/data/pokemon/species_info/gen_3_families.h +++ b/src/data/pokemon/species_info/gen_3_families.h @@ -10743,41 +10743,22 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = "air imbued with ghost energy to\n" "freeze even insubstantial things,\n" "such as flames or the wind."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Froslass) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sFroslassLevelUpLearnset, .teachableLearnset = sFroslassTeachableLearnset, diff --git a/src/data/pokemon/species_info/gen_5_families.h b/src/data/pokemon/species_info/gen_5_families.h index 52f91884d9..11885cb232 100644 --- a/src/data/pokemon/species_info/gen_5_families.h +++ b/src/data/pokemon/species_info/gen_5_families.h @@ -548,41 +548,22 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = "shaped like a serpentine spear,\n" "it rushes in to save its\n" "imperiled allies."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Emboar) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sEmboarLevelUpLearnset, .teachableLearnset = sEmboarTeachableLearnset, @@ -2879,41 +2860,22 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = "head together to form a streamlined\n" "shape and spins at high speeds,\n" "it can destroy anything."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Excadrill) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sExcadrillLevelUpLearnset, .teachableLearnset = sExcadrillTeachableLearnset, @@ -4127,41 +4089,22 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = "Its deadly venom gives off a faint\n" "glow. The venom affects Scolipede's\n" "mind, honing its viciousness."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Scolipede) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sScolipedeLevelUpLearnset, .teachableLearnset = sScolipedeTeachableLearnset, @@ -5882,41 +5825,22 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = "shed skin to turn white, growing\n" "tough and supple. Of course, this\n" "Pokémon is still as feisty as ever."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Scrafty) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sScraftyLevelUpLearnset, .teachableLearnset = sScraftyTeachableLearnset, @@ -9889,41 +9813,22 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = "electricity it did before Mega\n" "Evolving. It discharges this energy\n" "from its false Eelektrik made of mucus."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Eelektross) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sEelektrossLevelUpLearnset, .teachableLearnset = sEelektrossTeachableLearnset, @@ -10330,41 +10235,22 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = "our world with the afterlife.\n" "This Pokémon draws in hatred and\n" "converts it into power."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Chandelure) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sChandelureLevelUpLearnset, .teachableLearnset = sChandelureTeachableLearnset, diff --git a/src/data/pokemon/species_info/gen_6_families.h b/src/data/pokemon/species_info/gen_6_families.h index d8811dcb2d..b6a0bed22c 100644 --- a/src/data/pokemon/species_info/gen_6_families.h +++ b/src/data/pokemon/species_info/gen_6_families.h @@ -244,41 +244,22 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = "It has fortified armor and a\n" "will to defend at all costs.\n" "Both are absurdly strong."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Chesnaught) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sChesnaughtLevelUpLearnset, .teachableLearnset = sChesnaughtTeachableLearnset, @@ -534,41 +515,22 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = "dazzle its opponents before\n" "incinerating them with a\n" "huge fireball."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Delphox) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sDelphoxLevelUpLearnset, .teachableLearnset = sDelphoxTeachableLearnset, @@ -945,41 +907,22 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = "shuriken at high speed to make it\n" "float, then clings to it upside\n" "down to catch opponents unawares."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Greninja) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sGreninjaLevelUpLearnset, .teachableLearnset = sGreninjaTeachableLearnset, @@ -1934,41 +1877,22 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = "than 18,000 degrees Fahrenheit.\n" "It swings around its grand, blazing\n" "mane as it protects its allies."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Pyroar) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sPyroarLevelUpLearnset, .teachableLearnset = sPyroarTeachableLearnset, @@ -2354,41 +2278,22 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = "all the energy from Mega\n" "Evolution. The flower now attacks\n" "enemies on its own."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Floette) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sFloetteEternalLevelUpLearnset, .teachableLearnset = sFloetteEternalTeachableLearnset, @@ -3708,41 +3613,22 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = "overwrite the personality and\n" "memories of others-and to\n" "control them."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Malamar) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sMalamarLevelUpLearnset, .teachableLearnset = sMalamarTeachableLearnset, @@ -3925,41 +3811,22 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = "It uses its many arms to toy\n" "with its opponents. This\n" "keeps the head extremely busy."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Barbaracle) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sBarbaracleLevelUpLearnset, .teachableLearnset = sBarbaracleTeachableLearnset, @@ -4145,41 +4012,22 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = "regenerative power of cells to run\n" "wild. The liquid is deadly poison\n" "to everything other than itself."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Dragalge) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sDragalgeLevelUpLearnset, .teachableLearnset = sDragalgeTeachableLearnset, @@ -4864,41 +4712,22 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = "Mega Evolution has pumped up all\n" "its muscles. Hawlucha flexes to\n" "show off its strength."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Hawlucha) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sHawluchaLevelUpLearnset, .teachableLearnset = sHawluchaTeachableLearnset, @@ -7087,41 +6916,22 @@ const struct SpeciesInfo gSpeciesInfoGen6[] = "during an unprecedented crisis,\n" "Zygarde Mega Evolves and calms the\n" "situation with its unmatched power."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Zygarde) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .isRestrictedLegendary = TRUE, .levelUpLearnset = sZygardeLevelUpLearnset, diff --git a/src/data/pokemon/species_info/gen_7_families.h b/src/data/pokemon/species_info/gen_7_families.h index bea5fff6db..60d0bd16f7 100644 --- a/src/data/pokemon/species_info/gen_7_families.h +++ b/src/data/pokemon/species_info/gen_7_families.h @@ -5240,41 +5240,22 @@ const struct SpeciesInfo gSpeciesInfoGen7[] = "invigorated, allowing it to regain\n" "its youth. It manipulates the\n" "atmosphere to summon storms."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Drampa) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sDrampaLevelUpLearnset, .teachableLearnset = sDrampaTeachableLearnset, diff --git a/src/data/pokemon/species_info/gen_8_families.h b/src/data/pokemon/species_info/gen_8_families.h index 37b94de02f..6dcbf0c2d7 100644 --- a/src/data/pokemon/species_info/gen_8_families.h +++ b/src/data/pokemon/species_info/gen_8_families.h @@ -5277,41 +5277,22 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = "ultimate battle formation, which\n" "can be achieved only if the troopers\n" "and brass have the strongest of bonds."), - .frontPic = gMonFrontPic_CircledQuestionMark, - .frontPicSize = MON_COORDS_SIZE(40, 40), - .frontPicYOffset = 12, - .frontAnimFrames = sAnims_TwoFramePlaceHolder, - .frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, - .backPic = gMonBackPic_CircledQuestionMark, - .backPicSize = MON_COORDS_SIZE(40, 40), - .backPicYOffset = 12, - .backAnimId = BACK_ANIM_NONE, - .palette = gMonPalette_CircledQuestionMark, - .shinyPalette = gMonShinyPalette_CircledQuestionMark, - .iconSprite = gMonIcon_QuestionMark, - .iconPalIndex = 0, + //.frontPic = gMonFrontPic_CircledQuestionMark, + //.frontPicSize = MON_COORDS_SIZE(40, 40), + //.frontPicYOffset = 12, + //.frontAnimFrames = sAnims_TwoFramePlaceHolder, + //.frontAnimId = ANIM_V_SQUISH_AND_BOUNCE, + //.backPic = gMonBackPic_CircledQuestionMark, + //.backPicSize = MON_COORDS_SIZE(40, 40), + //.backPicYOffset = 12, + //.backAnimId = BACK_ANIM_NONE, + //.palette = gMonPalette_CircledQuestionMark, + //.shinyPalette = gMonShinyPalette_CircledQuestionMark, + //.iconSprite = gMonIcon_QuestionMark, + //.iconPalIndex = 0, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - FOOTPRINT(QuestionMark) - SHADOW(-1, 0, SHADOW_SIZE_M) - #if OW_BATTLE_ONLY_FORMS - .overworldData = { - .tileTag = TAG_NONE, - .paletteTag = OBJ_EVENT_PAL_TAG_SUBSTITUTE, - .reflectionPaletteTag = OBJ_EVENT_PAL_TAG_NONE, - .size = 512, - .width = 32, - .height = 32, - .paletteSlot = PALSLOT_NPC_1, - .shadowSize = SHADOW_SIZE_M, - .inanimate = FALSE, - .compressed = COMP, - .tracks = TRACKS_FOOT, - .oam = &gObjectEventBaseOam_32x32, - .subspriteTables = sOamTables_32x32, - .anims = sAnimTable_Following, - .images = sPicTable_Substitute, - }, - #endif //OW_BATTLE_ONLY_FORMS + FOOTPRINT(Falinks) + //SHADOW(-1, 0, SHADOW_SIZE_M) .isMegaEvolution = TRUE, .levelUpLearnset = sFalinksLevelUpLearnset, .teachableLearnset = sFalinksTeachableLearnset, diff --git a/src/data/pokemon/species_info/gen_9_families.h b/src/data/pokemon/species_info/gen_9_families.h index d45c918594..7ddd646b7d 100644 --- a/src/data/pokemon/species_info/gen_9_families.h +++ b/src/data/pokemon/species_info/gen_9_families.h @@ -2129,7 +2129,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .iconSprite = gMonIcon_Naclstack, .iconPalIndex = 2, .pokemonJumpType = PKMN_JUMP_TYPE_SLOW, - SHADOW(0, 5, SHADOW_SIZE_L) + SHADOW(0, 2, SHADOW_SIZE_L) FOOTPRINT(Naclstack) OVERWORLD( sPicTable_Naclstack, @@ -2193,7 +2193,7 @@ const struct SpeciesInfo gSpeciesInfoGen9[] = .iconSprite = gMonIcon_Garganacl, .iconPalIndex = 2, .pokemonJumpType = PKMN_JUMP_TYPE_NONE, - SHADOW(0, 13, SHADOW_SIZE_L) + SHADOW(0, 9, SHADOW_SIZE_L) FOOTPRINT(Garganacl) OVERWORLD( sPicTable_Garganacl, diff --git a/src/decompress_asm.s b/src/decompress_asm.s index bfe690ef60..9704d83a6a 100644 --- a/src/decompress_asm.s +++ b/src/decompress_asm.s @@ -1,7 +1,7 @@ .syntax unified .arm - .section .iwram.code + .section .iwram.code, "ax", %progbits .align 2 .global FastUnsafeCopy32 diff --git a/src/m4a_1.s b/src/m4a_1.s index 4c0c8f7f89..cc335f0d4c 100644 --- a/src/m4a_1.s +++ b/src/m4a_1.s @@ -85,7 +85,7 @@ lt_o_SoundInfo_pcmBuffer: .word o_SoundInfo_pcmBuffer lt_PCM_DMA_BUF_SIZE: .word PCM_DMA_BUF_SIZE thumb_func_end SoundMain - .section .iwram.code + .section .iwram.code, "ax", %progbits thumb_func_start SoundMainRAM SoundMainRAM: ldrb r3, [r0, o_SoundInfo_reverb] diff --git a/src/overworld.c b/src/overworld.c index ec995cc76a..5388284f6b 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -1707,11 +1707,12 @@ static void OverworldBasic(void) gTimeUpdateCounter = (SECONDS_PER_MINUTE * 60 / FakeRtc_GetSecondsRatio()); UpdateTimeOfDay(); FormChangeTimeUpdate(); - if (bld0[0] != bld1[0] + if (MapHasNaturalLight(gMapHeader.mapType) && + (bld0[0] != bld1[0] || bld0[1] != bld1[1] - || bld0[2] != bld1[2]) + || bld0[2] != bld1[2])) { - ApplyWeatherColorMapIfIdle(gWeatherPtr->colorMapIndex); + ApplyWeatherColorMapIfIdle(gWeatherPtr->colorMapIndex); } } } diff --git a/src/pokemon_sprite_visualizer.c b/src/pokemon_sprite_visualizer.c index a5f36a0db6..cc51b2dfc7 100644 --- a/src/pokemon_sprite_visualizer.c +++ b/src/pokemon_sprite_visualizer.c @@ -58,37 +58,6 @@ static struct PokemonSpriteVisualizer *GetStructPtr(u8 taskId) return (struct PokemonSpriteVisualizer*)(T1_READ_PTR(taskDataPtr)); } -static const union AnimCmd sAnim_Follower_1[] = -{ - ANIMCMD_FRAME(0, 30), - ANIMCMD_FRAME(1, 30), - ANIMCMD_FRAME(0, 30), - ANIMCMD_FRAME(1, 30), - ANIMCMD_FRAME(0, 10), - ANIMCMD_FRAME(2, 30), - ANIMCMD_FRAME(3, 30), - ANIMCMD_FRAME(2, 30), - ANIMCMD_FRAME(3, 30), - ANIMCMD_FRAME(2, 10), - ANIMCMD_FRAME(4, 30), - ANIMCMD_FRAME(5, 30), - ANIMCMD_FRAME(4, 30), - ANIMCMD_FRAME(5, 30), - ANIMCMD_FRAME(4, 10), - ANIMCMD_FRAME(4, 30, .hFlip = TRUE), - ANIMCMD_FRAME(5, 30, .hFlip = TRUE), - ANIMCMD_FRAME(4, 30, .hFlip = TRUE), - ANIMCMD_FRAME(5, 30, .hFlip = TRUE), - ANIMCMD_FRAME(4, 10, .hFlip = TRUE), - ANIMCMD_END, -}; - -static const union AnimCmd *const sAnims_Follower[] = -{ - sAnim_GeneralFrame0, - sAnim_Follower_1, -}; - //BgTemplates static const struct BgTemplate sBgTemplates[] = { @@ -842,32 +811,32 @@ static void SpriteCB_EnemyShadowCustom(struct Sprite *shadowSprite) static void SpriteCB_Follower(struct Sprite *sprite) { - if (sprite->animDelayCounter == 0) + if (sprite->data[3] == 0) { - sprite->animDelayCounter = 60; + sprite->data[3] = 120; switch (sprite->animNum) { - default: - case 0: - case 1: - StartSpriteAnim(sprite, GetFaceDirectionAnimNum(DIR_NORTH)); - break; - case 2: - StartSpriteAnim(sprite, GetFaceDirectionAnimNum(DIR_WEST)); - break; - case 3: - StartSpriteAnim(sprite, GetFaceDirectionAnimNum(DIR_EAST)); - break; case 4: - StartSpriteAnim(sprite, GetFaceDirectionAnimNum(DIR_SOUTH)); + StartSpriteAnim(sprite, GetMoveDirectionAnimNum(DIR_NORTH)); + break; + case 5: + StartSpriteAnim(sprite, GetMoveDirectionAnimNum(DIR_WEST)); + break; + case 6: + StartSpriteAnim(sprite, GetMoveDirectionAnimNum(DIR_EAST)); + break; + default: + case 7: + StartSpriteAnim(sprite, GetMoveDirectionAnimNum(DIR_SOUTH)); break; } } else { - sprite->animDelayCounter--; + sprite->data[3]--; } } + static void LoadAndCreateEnemyShadowSpriteCustom(struct PokemonSpriteVisualizer *data, u16 species) { bool8 invisible = FALSE; @@ -1315,9 +1284,26 @@ void CB2_Pokemon_Sprite_Visualizer(void) gSprites[data->iconspriteId].oam.priority = 0; //Follower Sprite - data->followerspriteId = CreateObjectGraphicsSprite(OBJ_EVENT_MON + species, SpriteCB_Follower, VISUALIZER_FOLLOWER_X, VISUALIZER_FOLLOWER_Y, 0); + u16 graphicsId = species + OBJ_EVENT_MON; + if (data->isShiny) + graphicsId += OBJ_EVENT_MON_SHINY; + if (data->isFemale) + graphicsId += OBJ_EVENT_MON_FEMALE; + data->followerspriteId = CreateObjectGraphicsSprite(graphicsId, + SpriteCB_Follower, + VISUALIZER_FOLLOWER_X, + VISUALIZER_FOLLOWER_Y, + 0); gSprites[data->followerspriteId].oam.priority = 0; - gSprites[data->followerspriteId].anims = sAnims_Follower; + const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, data->isShiny, data->isFemale); + if (graphicsInfo != NULL) + { + gSprites[data->followerspriteId].oam.shape = graphicsInfo->oam->shape; + gSprites[data->followerspriteId].oam.size = graphicsInfo->oam->size; + gSprites[data->followerspriteId].images = graphicsInfo->images; + gSprites[data->followerspriteId].anims = graphicsInfo->anims; + gSprites[data->followerspriteId].subspriteTables = graphicsInfo->subspriteTables; + } //Modify Arrows SetUpModifyArrows(data); @@ -2017,7 +2003,15 @@ static void ReloadPokemonSprites(struct PokemonSpriteVisualizer *data) VISUALIZER_FOLLOWER_Y, 0); gSprites[data->followerspriteId].oam.priority = 0; - gSprites[data->followerspriteId].anims = sAnims_Follower; + const struct ObjectEventGraphicsInfo *graphicsInfo = SpeciesToGraphicsInfo(species, data->isShiny, data->isFemale); + if (graphicsInfo != NULL) + { + gSprites[data->followerspriteId].oam.shape = graphicsInfo->oam->shape; + gSprites[data->followerspriteId].oam.size = graphicsInfo->oam->size; + gSprites[data->followerspriteId].images = graphicsInfo->images; + gSprites[data->followerspriteId].anims = graphicsInfo->anims; + gSprites[data->followerspriteId].subspriteTables = graphicsInfo->subspriteTables; + } //Modify Arrows LoadSpritePalette(&gSpritePalette_Arrow); diff --git a/test/battle/ability/beast_boost.c b/test/battle/ability/beast_boost.c index d6691c2f8f..ce7df9135b 100644 --- a/test/battle/ability/beast_boost.c +++ b/test/battle/ability/beast_boost.c @@ -17,23 +17,26 @@ SINGLE_BATTLE_TEST("Beast Boost boosts the most proficient stat when knocking ou TURN { MOVE(player, MOVE_SCRATCH); SEND_OUT(opponent, 1); } } SCENE { ABILITY_POPUP(player, ABILITY_BEAST_BOOST); - switch(i) { - case 0: - MESSAGE("Nihilego's Attack rose!"); - break; - case 1: - MESSAGE("Nihilego's Defense rose!"); - break; - case 2: - MESSAGE("Nihilego's Sp. Atk rose!"); - break; - case 3: - MESSAGE("Nihilego's Sp. Def rose!"); - break; - case 4: - MESSAGE("Nihilego's Speed rose!"); - break; + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + u32 expectedStat = STAT_ATK; + + switch (i) { + case 1: + expectedStat = STAT_DEF; + break; + case 2: + expectedStat = STAT_SPATK; + break; + case 3: + expectedStat = STAT_SPDEF; + break; + case 4: + expectedStat = STAT_SPEED; + break; } + + EXPECT_EQ(player->statStages[expectedStat], DEFAULT_STAT_STAGE + 1); } } @@ -73,28 +76,180 @@ SINGLE_BATTLE_TEST("Beast Boost prioritizes stats in the case of a tie in the fo TURN { MOVE(player, MOVE_SCRATCH); SEND_OUT(opponent, 1); } } SCENE { ABILITY_POPUP(player, ABILITY_BEAST_BOOST); - switch(i) { - case 0: - MESSAGE("Nihilego's Attack rose!"); - break; - case 1: - MESSAGE("Nihilego's Defense rose!"); - break; - case 2: - MESSAGE("Nihilego's Sp. Atk rose!"); - break; - case 3: - MESSAGE("Nihilego's Sp. Def rose!"); - break; + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + u32 expectedStat = STAT_ATK; + + switch (i) { + case 1: + expectedStat = STAT_DEF; + break; + case 2: + expectedStat = STAT_SPATK; + break; + case 3: + expectedStat = STAT_SPDEF; + break; } + + EXPECT_EQ(player->statStages[expectedStat], DEFAULT_STAT_STAGE + 1); } } -TO_DO_BATTLE_TEST("Beast Boost considers Power Split"); -TO_DO_BATTLE_TEST("Beast Boost considers Guard Split"); -TO_DO_BATTLE_TEST("Beast Boost considers Power Trick"); -TO_DO_BATTLE_TEST("Beast Boost considers Wonder Room"); -TO_DO_BATTLE_TEST("Beast Boost considers Speed Swap"); -TO_DO_BATTLE_TEST("Beast Boost doesn't consider stat stages"); -TO_DO_BATTLE_TEST("Beast Boost doesn't consider held items"); -TO_DO_BATTLE_TEST("Beast Boost doesn't consider status condition reductions"); +SINGLE_BATTLE_TEST("Beast Boost considers Power Split") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_POWER_SPLIT) == EFFECT_POWER_SPLIT); + PLAYER(SPECIES_NIHILEGO) { Ability(ABILITY_BEAST_BOOST); Attack(200); Defense(30); SpAttack(50); SpDefense(30); } + OPPONENT(SPECIES_WOBBUFFET) { HP(1); Attack(10); SpAttack(250); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_POWER_SPLIT); } + TURN { MOVE(player, MOVE_SCRATCH); SEND_OUT(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_POWER_SPLIT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); + ABILITY_POPUP(player, ABILITY_BEAST_BOOST); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + EXPECT_EQ(player->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1); + } +} + +SINGLE_BATTLE_TEST("Beast Boost considers Guard Split") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_GUARD_SPLIT) == EFFECT_GUARD_SPLIT); + PLAYER(SPECIES_NIHILEGO) { Ability(ABILITY_BEAST_BOOST); Attack(80); Defense(20); SpAttack(70); SpDefense(10); } + OPPONENT(SPECIES_WOBBUFFET) { HP(1); Defense(200); SpDefense(30); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_GUARD_SPLIT); } + TURN { MOVE(player, MOVE_SCRATCH); SEND_OUT(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GUARD_SPLIT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); + ABILITY_POPUP(player, ABILITY_BEAST_BOOST); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 1); + } +} + +SINGLE_BATTLE_TEST("Beast Boost considers Power Trick") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_POWER_TRICK) == EFFECT_POWER_TRICK); + PLAYER(SPECIES_NIHILEGO) { Ability(ABILITY_BEAST_BOOST); Attack(40); Defense(200); SpAttack(60); SpDefense(50); } + OPPONENT(SPECIES_WOBBUFFET) { HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_POWER_TRICK); } + TURN { MOVE(player, MOVE_SCRATCH); SEND_OUT(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_POWER_TRICK, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); + ABILITY_POPUP(player, ABILITY_BEAST_BOOST); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1); + } +} + +SINGLE_BATTLE_TEST("Beast Boost considers Wonder Room") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_WONDER_ROOM) == EFFECT_WONDER_ROOM); + ASSUME(GetMovePower(MOVE_SCRATCH) > 0); + PLAYER(SPECIES_NIHILEGO) { Ability(ABILITY_BEAST_BOOST); Attack(100); Defense(50); SpAttack(70); SpDefense(200); Speed(120); Moves(MOVE_SPLASH, MOVE_EXTREME_SPEED); } + OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(200); Moves(MOVE_WONDER_ROOM, MOVE_SPLASH); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(30); } + } WHEN { + TURN { MOVE(opponent, MOVE_WONDER_ROOM); MOVE(player, MOVE_SPLASH); } + TURN { MOVE(player, MOVE_EXTREME_SPEED); MOVE(opponent, MOVE_SPLASH); SEND_OUT(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_WONDER_ROOM, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_EXTREME_SPEED, player); + ABILITY_POPUP(player, ABILITY_BEAST_BOOST); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + EXPECT_EQ(player->statStages[STAT_DEF], DEFAULT_STAT_STAGE + 1); + } +} + +SINGLE_BATTLE_TEST("Beast Boost considers Speed Swap") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_SPEED_SWAP) == EFFECT_SPEED_SWAP); + PLAYER(SPECIES_NIHILEGO) { Ability(ABILITY_BEAST_BOOST); Attack(60); Defense(60); SpAttack(70); SpDefense(60); Speed(30); } + OPPONENT(SPECIES_WOBBUFFET) { HP(1); Speed(200); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(50); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_SPEED_SWAP); } + TURN { MOVE(player, MOVE_SCRATCH); SEND_OUT(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPEED_SWAP, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); + ABILITY_POPUP(player, ABILITY_BEAST_BOOST); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + EXPECT_EQ(player->statStages[STAT_SPEED], DEFAULT_STAT_STAGE + 1); + } +} + +SINGLE_BATTLE_TEST("Beast Boost doesn't consider stat stages") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); + PLAYER(SPECIES_NIHILEGO) { Ability(ABILITY_BEAST_BOOST); Attack(100); Defense(60); SpAttack(150); SpDefense(60); } + OPPONENT(SPECIES_WOBBUFFET) { HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SWORDS_DANCE); } + TURN { MOVE(player, MOVE_SCRATCH); SEND_OUT(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SWORDS_DANCE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); + ABILITY_POPUP(player, ABILITY_BEAST_BOOST); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + EXPECT_EQ(player->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1); + } +} + +SINGLE_BATTLE_TEST("Beast Boost doesn't consider held items") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_CHOICE_BAND].holdEffect == HOLD_EFFECT_CHOICE_BAND); + PLAYER(SPECIES_NIHILEGO) { Ability(ABILITY_BEAST_BOOST); Item(ITEM_CHOICE_BAND); Attack(120); Defense(60); SpAttack(150); SpDefense(60); } + OPPONENT(SPECIES_WOBBUFFET) { HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH); SEND_OUT(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); + ABILITY_POPUP(player, ABILITY_BEAST_BOOST); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + EXPECT_EQ(player->statStages[STAT_SPATK], DEFAULT_STAT_STAGE + 1); + } +} + +SINGLE_BATTLE_TEST("Beast Boost doesn't consider status condition reductions") +{ + GIVEN { + PLAYER(SPECIES_NIHILEGO) { Ability(ABILITY_BEAST_BOOST); Status1(STATUS1_BURN); Attack(150); Defense(60); SpAttack(100); SpDefense(60); } + OPPONENT(SPECIES_WOBBUFFET) { HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH); SEND_OUT(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); + ABILITY_POPUP(player, ABILITY_BEAST_BOOST); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } THEN { + EXPECT_EQ(player->statStages[STAT_ATK], DEFAULT_STAT_STAGE + 1); + } +} diff --git a/test/battle/ability/corrosion.c b/test/battle/ability/corrosion.c index ca6b602002..f46ad72a72 100644 --- a/test/battle/ability/corrosion.c +++ b/test/battle/ability/corrosion.c @@ -239,9 +239,115 @@ SINGLE_BATTLE_TEST("Corrosion's effect is lost if the move used by the Pokémon } } -TO_DO_BATTLE_TEST("Corrosion can poison Poison/Steel types if the Pokémon uses Baneful Bunker") -TO_DO_BATTLE_TEST("Corrosion can poison Poison/Steel types if the Pokémon uses Psycho Shift while poisoned") -TO_DO_BATTLE_TEST("Corrosion can poison Poison/Steel types if the Pokémon uses Fling while holding a Toxic Orb") -TO_DO_BATTLE_TEST("Corrosion can poison Poison/Steel types if the Pokémon uses Fling while holding a Poison Barb") +SINGLE_BATTLE_TEST("Corrosion can poison Poison/Steel types if the Pokémon uses Baneful Bunker") +{ + u16 species; + + PARAMETRIZE { species = SPECIES_ODDISH; } + PARAMETRIZE { species = SPECIES_BELDUM; } + + GIVEN { + ASSUME(GetMoveEffect(MOVE_BANEFUL_BUNKER) == EFFECT_PROTECT); + ASSUME(MoveMakesContact(MOVE_SCRATCH)); + PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); } + OPPONENT(species); + } WHEN { + TURN { MOVE(player, MOVE_BANEFUL_BUNKER); MOVE(opponent, MOVE_SCRATCH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BANEFUL_BUNKER, player); + MESSAGE("Salandit protected itself!"); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent); + MESSAGE("Salandit protected itself!"); + STATUS_ICON(opponent, poison: TRUE); + } +} + +SINGLE_BATTLE_TEST("Corrosion can poison Poison/Steel types if the Pokémon uses Psycho Shift while poisoned") +{ + u16 species; + + PARAMETRIZE { species = SPECIES_ODDISH; } + PARAMETRIZE { species = SPECIES_BELDUM; } + + GIVEN { + ASSUME(GetMoveEffect(MOVE_PSYCHO_SHIFT) == EFFECT_PSYCHO_SHIFT); + PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); Status1(STATUS1_POISON); } + OPPONENT(species); + } WHEN { + TURN { MOVE(player, MOVE_PSYCHO_SHIFT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_PSYCHO_SHIFT, player); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent); + STATUS_ICON(opponent, poison: TRUE); + STATUS_ICON(player, none: TRUE); + } +} + +SINGLE_BATTLE_TEST("Corrosion can poison Poison/Steel types if the Pokémon uses Fling while holding a Toxic Orb") +{ + u16 species; + + PARAMETRIZE { species = SPECIES_ODDISH; } + PARAMETRIZE { species = SPECIES_BELDUM; } + + GIVEN { + ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING); + ASSUME(gItemsInfo[ITEM_TOXIC_ORB].holdEffect == HOLD_EFFECT_TOXIC_ORB); + PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); Item(ITEM_TOXIC_ORB); } + OPPONENT(species); + } WHEN { + TURN { MOVE(player, MOVE_FLING); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent); + STATUS_ICON(opponent, badPoison: TRUE); + } +} + +SINGLE_BATTLE_TEST("Corrosion can poison Poison/Steel types if the Pokémon uses Fling while holding a Poison Barb") +{ + u16 species; + + PARAMETRIZE { species = SPECIES_ODDISH; } + PARAMETRIZE { species = SPECIES_BELDUM; } + + GIVEN { + ASSUME(GetMoveEffect(MOVE_FLING) == EFFECT_FLING); + ASSUME(gItemsInfo[ITEM_POISON_BARB].holdEffect == HOLD_EFFECT_TYPE_POWER); + ASSUME(gItemsInfo[ITEM_POISON_BARB].secondaryId == TYPE_POISON); + PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); Item(ITEM_POISON_BARB); } + OPPONENT(species); + } WHEN { + TURN { MOVE(player, MOVE_FLING); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player); + HP_BAR(opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent); + STATUS_ICON(opponent, poison: TRUE); + } +} + +SINGLE_BATTLE_TEST("Corrosion does not affect Poison Spikes") +{ + u16 species; + + PARAMETRIZE { species = SPECIES_ODDISH; } + PARAMETRIZE { species = SPECIES_BELDUM; } + + GIVEN { + ASSUME(GetMoveEffect(MOVE_TOXIC_SPIKES) == EFFECT_TOXIC_SPIKES); + PLAYER(SPECIES_SALANDIT) { Ability(ABILITY_CORROSION); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(species); + } WHEN { + TURN { MOVE(player, MOVE_TOXIC_SPIKES); } + TURN { SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TOXIC_SPIKES, player); + } THEN { + EXPECT_EQ(opponent->status1, STATUS1_NONE); + } +} + TO_DO_BATTLE_TEST("Dynamax: Corrosion can poison Poison/Steel types if the Pokémon uses G-Max Malodor") -TO_DO_BATTLE_TEST("Corrosion does not affect Poison Spikes") diff --git a/test/battle/ability/delta_stream.c b/test/battle/ability/delta_stream.c index a2202d64c0..0ea7429ff4 100644 --- a/test/battle/ability/delta_stream.c +++ b/test/battle/ability/delta_stream.c @@ -5,5 +5,45 @@ //TO_DO_BATTLE_TEST("Delta Stream doesn't activate if is sent-out in a rotated-out position (Rotation)") //TO_DO_BATTLE_TEST("Delta Stream doesn't activate if is rotated-in (Rotation)") -TO_DO_BATTLE_TEST("Delta Stream doesn't activate if there's already strong winds") -TO_DO_BATTLE_TEST("Strong winds continue as long as there's a Pokémon with Delta Stream on the field") // Doesn't need to be the original mon +DOUBLE_BATTLE_TEST("Delta Stream doesn't activate if there's already strong winds") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + OPPONENT(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { SWITCH(playerLeft, 2); } + } SCENE { + ABILITY_POPUP(opponentLeft, ABILITY_DELTA_STREAM); + MESSAGE("Mysterious strong winds are protecting Flying-type Pokémon!"); + SWITCH_OUT_MESSAGE("Wobbuffet"); + SEND_IN_MESSAGE("Rayquaza"); + NONE_OF { + ABILITY_POPUP(playerLeft, ABILITY_DELTA_STREAM); + MESSAGE("Mysterious strong winds are protecting Flying-type Pokémon!"); + } + } +} + +DOUBLE_BATTLE_TEST("Strong winds continue as long as there's a Pokémon with Delta Stream on the field") +{ + GIVEN { + PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); HP(1); } + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponentLeft, MOVE_SCRATCH, target: playerLeft); SEND_OUT(playerLeft, 2); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponentLeft); + HP_BAR(playerLeft, hp: 0); + MESSAGE("Rayquaza fainted!"); + SEND_IN_MESSAGE("Wobbuffet"); + NOT MESSAGE("The mysterious strong winds have dissipated!"); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_STRONG_WINDS); + } +} diff --git a/test/battle/ability/desolate_land.c b/test/battle/ability/desolate_land.c index e588129b6a..bcf7f519c7 100644 --- a/test/battle/ability/desolate_land.c +++ b/test/battle/ability/desolate_land.c @@ -99,14 +99,81 @@ SINGLE_BATTLE_TEST("Desolate Land is removed immediately if user faints") } } -TO_DO_BATTLE_TEST("Desolate Land makes Sunny Day fail") -TO_DO_BATTLE_TEST("Desolate Land makes Rain Dance fail") -TO_DO_BATTLE_TEST("Desolate Land makes Sandstorm fail") -TO_DO_BATTLE_TEST("Desolate Land makes Hail fail") -TO_DO_BATTLE_TEST("Desolate Land makes Snowscape fail") // Extrapolation -TO_DO_BATTLE_TEST("Desolate Land makes Drought fail to activate") -TO_DO_BATTLE_TEST("Desolate Land makes Drizzle fail to activate") -TO_DO_BATTLE_TEST("Desolate Land makes Sand Stream fail to activate") -TO_DO_BATTLE_TEST("Desolate Land makes Snow Warning fail to activate") -TO_DO_BATTLE_TEST("Desolate Land can be replaced by Delta Stream") -TO_DO_BATTLE_TEST("Desolate Land can be replaced by Primordial Sea") +SINGLE_BATTLE_TEST("Desolate Land blocks weather-setting moves") +{ + u16 move; + PARAMETRIZE { move = MOVE_SUNNY_DAY; } + PARAMETRIZE { move = MOVE_RAIN_DANCE; } + PARAMETRIZE { move = MOVE_SANDSTORM; } + PARAMETRIZE { move = MOVE_HAIL; } + PARAMETRIZE { move = MOVE_SNOWSCAPE; } + + GIVEN { + ASSUME(GetMoveEffect(MOVE_SUNNY_DAY) == EFFECT_SUNNY_DAY); + ASSUME(GetMoveEffect(MOVE_RAIN_DANCE) == EFFECT_RAIN_DANCE); + ASSUME(GetMoveEffect(MOVE_SANDSTORM) == EFFECT_SANDSTORM); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); + ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE); + PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, move); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, move, opponent); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_SUN_PRIMAL); + } +} + +SINGLE_BATTLE_TEST("Desolate Land prevents other weather abilities") +{ + u16 ability, species; + PARAMETRIZE { ability = ABILITY_DROUGHT; species = SPECIES_NINETALES; } + PARAMETRIZE { ability = ABILITY_DRIZZLE; species = SPECIES_POLITOED; } + PARAMETRIZE { ability = ABILITY_SAND_STREAM; species = SPECIES_HIPPOWDON; } + PARAMETRIZE { ability = ABILITY_SNOW_WARNING; species = SPECIES_ABOMASNOW; } + + GIVEN { + PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ability); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_SUN_PRIMAL); + } +} + +SINGLE_BATTLE_TEST("Desolate Land can be replaced by Delta Stream") +{ + GIVEN { + PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_DELTA_STREAM); + MESSAGE("Mysterious strong winds are protecting Flying-type Pokémon!"); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_STRONG_WINDS); + } +} + +SINGLE_BATTLE_TEST("Desolate Land can be replaced by Primordial Sea") +{ + GIVEN { + PLAYER(SPECIES_GROUDON) { Item(ITEM_RED_ORB); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); } + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_PRIMORDIAL_SEA); + MESSAGE("A heavy rain began to fall!"); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_RAIN_PRIMAL); + } +} diff --git a/test/battle/ability/drizzle.c b/test/battle/ability/drizzle.c index fd56704830..8e6f7876c9 100644 --- a/test/battle/ability/drizzle.c +++ b/test/battle/ability/drizzle.c @@ -22,3 +22,84 @@ SINGLE_BATTLE_TEST("Drizzle summons rain", s16 damage) EXPECT_MUL_EQ(results[1].damage, Q_4_12(1.5), results[0].damage); } } + +SINGLE_BATTLE_TEST("Drizzle sets up rain for 5 turns (Gen6+)") +{ + GIVEN { + WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6); + PLAYER(SPECIES_POLITOED) { Moves(MOVE_CELEBRATE); Ability(ABILITY_DRIZZLE); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_DRIZZLE); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("The rain stopped."); + } +} + +SINGLE_BATTLE_TEST("Drizzle sets up rain for 8 turns with Damp Rock (Gen6+)") +{ + GIVEN { + WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6); + PLAYER(SPECIES_POLITOED) { Moves(MOVE_CELEBRATE); Ability(ABILITY_DRIZZLE); Item(ITEM_DAMP_ROCK); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_DRIZZLE); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("The rain stopped."); + } +} + +SINGLE_BATTLE_TEST("Drizzle sets up permanent rain (Gen3-5)") +{ + GIVEN { + WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_3); + PLAYER(SPECIES_POLITOED) { Moves(MOVE_CELEBRATE); Ability(ABILITY_DRIZZLE); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_DRIZZLE); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + MESSAGE("Rain continues to fall."); + NOT MESSAGE("The rain stopped."); + } +} diff --git a/test/battle/ability/heatproof.c b/test/battle/ability/heatproof.c index 7f1d772bb7..154569fd2a 100644 --- a/test/battle/ability/heatproof.c +++ b/test/battle/ability/heatproof.c @@ -1,4 +1,52 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("TODO: Write Heatproof (Ability) test titles") +ASSUMPTIONS +{ + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); + ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_OVERWRITE_ABILITY); +} + +SINGLE_BATTLE_TEST("Heatproof halves damage from fire type moves") +{ + s16 damage[2]; + GIVEN { + PLAYER (SPECIES_WOBBUFFET); + OPPONENT (SPECIES_BRONZONG) { Ability(ABILITY_HEATPROOF); } + } + WHEN { + TURN { MOVE(player, MOVE_EMBER); } + TURN { MOVE(player, MOVE_WORRY_SEED); } + TURN { MOVE(player, MOVE_EMBER); } + } + SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player); + HP_BAR(opponent, captureDamage: &damage[0]); + ANIMATION(ANIM_TYPE_MOVE, MOVE_WORRY_SEED, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_EMBER, player); + HP_BAR(opponent, captureDamage: &damage[1]); + EXPECT_MUL_EQ(damage[0], Q_4_12(2), damage[1]); + } +} + +SINGLE_BATTLE_TEST("Heatproof halves the damage done by burn from 1/8th to 1/16th (Gen1-6) or 1/16th to 1/32nd (Gen 7+)") +{ + u32 config, burnRate; + + PARAMETRIZE { config = GEN_7; burnRate = 32; } + PARAMETRIZE { config = GEN_6; burnRate = 16; } + + GIVEN { + WITH_CONFIG(CONFIG_BURN_DAMAGE, config); + PLAYER (SPECIES_BRONZONG) { Ability(ABILITY_HEATPROOF); Status1(STATUS1_BURN); } + OPPONENT (SPECIES_WOBBUFFET); + } + WHEN { + TURN {} + } + SCENE { + s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); + HP_BAR(player, damage: maxHP / burnRate); + } +} + diff --git a/test/battle/ability/intrepid_sword.c b/test/battle/ability/intrepid_sword.c index 1fc461ebcd..f7c3705d44 100644 --- a/test/battle/ability/intrepid_sword.c +++ b/test/battle/ability/intrepid_sword.c @@ -112,3 +112,47 @@ SINGLE_BATTLE_TEST("Intrepid Sword and Dauntless Shield both can be Skill Swappe MESSAGE("Wobbuffet's Dauntless Shield raised its Defense!"); } } + +SINGLE_BATTLE_TEST("Intrepid Sword and Dauntless Shield do not proc at max stage (Skill Swap)") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_SKILL_SWAP) == EFFECT_SKILL_SWAP); + ASSUME(GetMoveEffect(MOVE_IRON_DEFENSE) == EFFECT_DEFENSE_UP_2); + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); + PLAYER(SPECIES_ZACIAN) { Ability(ABILITY_INTREPID_SWORD); } + OPPONENT(SPECIES_ZAMAZENTA) { Ability(ABILITY_DAUNTLESS_SHIELD); } + } WHEN { + TURN { MOVE(player, MOVE_IRON_DEFENSE); MOVE(opponent, MOVE_SWORDS_DANCE);} + TURN { MOVE(player, MOVE_IRON_DEFENSE); MOVE(opponent, MOVE_SWORDS_DANCE);} + TURN { MOVE(player, MOVE_IRON_DEFENSE); MOVE(opponent, MOVE_SWORDS_DANCE);} + TURN { MOVE(player, MOVE_SKILL_SWAP); } + } SCENE { + NONE_OF { + ABILITY_POPUP(player, ABILITY_DAUNTLESS_SHIELD); + ABILITY_POPUP(opponent, ABILITY_INTREPID_SWORD); + } + } +} + +SINGLE_BATTLE_TEST("Intrepid Sword and Dauntless Shield do not proc at max stage (Baton Pass)") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); + ASSUME(GetMoveEffect(MOVE_IRON_DEFENSE) == EFFECT_DEFENSE_UP_2); + ASSUME(GetMoveEffect(MOVE_SWORDS_DANCE) == EFFECT_ATTACK_UP_2); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_ZAMAZENTA) { Ability(ABILITY_DAUNTLESS_SHIELD); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_ZACIAN) { Ability(ABILITY_INTREPID_SWORD); } + } WHEN { + TURN { MOVE(player, MOVE_IRON_DEFENSE); MOVE(opponent, MOVE_SWORDS_DANCE);} + TURN { MOVE(player, MOVE_IRON_DEFENSE); MOVE(opponent, MOVE_SWORDS_DANCE);} + TURN { MOVE(player, MOVE_IRON_DEFENSE); MOVE(opponent, MOVE_SWORDS_DANCE);} + TURN { MOVE(player, MOVE_BATON_PASS); MOVE(opponent, MOVE_BATON_PASS); SEND_OUT(player, 1); SEND_OUT(opponent, 1);} + } SCENE { + NONE_OF { + ABILITY_POPUP(player, ABILITY_DAUNTLESS_SHIELD); + ABILITY_POPUP(opponent, ABILITY_INTREPID_SWORD); + } + } +} diff --git a/test/battle/ability/liquid_ooze.c b/test/battle/ability/liquid_ooze.c index 38b1428df1..437f8e4c7a 100644 --- a/test/battle/ability/liquid_ooze.c +++ b/test/battle/ability/liquid_ooze.c @@ -163,7 +163,7 @@ SINGLE_BATTLE_TEST("Liquid Ooze causes Dream Eater users to lose HP instead of h } } -SINGLE_BATTLE_TEST("Liquid Ooze does not cause Dream Eater users to lose HP instead of heal (Gen 3-4") +SINGLE_BATTLE_TEST("Liquid Ooze does not cause Dream Eater users to lose HP instead of heal (Gen 3-4)") { s16 damage; GIVEN { diff --git a/test/battle/ability/orichalcum_pulse.c b/test/battle/ability/orichalcum_pulse.c index 295e0db23c..62509ce0c6 100644 --- a/test/battle/ability/orichalcum_pulse.c +++ b/test/battle/ability/orichalcum_pulse.c @@ -1,5 +1,112 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("Orichalcum Pulse sets up sun for 5 turns"); -TO_DO_BATTLE_TEST("Orichalcum Pulse boosts the Pokémon's Attack by 33% in sun, even if it's holding an Utility Umbrella"); +SINGLE_BATTLE_TEST("Orichalcum Pulse sets up sun for 5 turns") +{ + GIVEN { + PLAYER(SPECIES_KORAIDON) { Moves(MOVE_CELEBRATE); Ability(ABILITY_ORICHALCUM_PULSE); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ORICHALCUM_PULSE); + MESSAGE("The sunlight is strong."); + MESSAGE("The sunlight is strong."); + MESSAGE("The sunlight is strong."); + MESSAGE("The sunlight is strong."); + MESSAGE("The sunlight faded."); + } +} + +SINGLE_BATTLE_TEST("Orichalcum Pulse sets up sun for 8 turns with Heat Rock") +{ + GIVEN { + PLAYER(SPECIES_KORAIDON) { Moves(MOVE_CELEBRATE); Ability(ABILITY_ORICHALCUM_PULSE); Item(ITEM_HEAT_ROCK); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ORICHALCUM_PULSE); + MESSAGE("The sunlight is strong."); + MESSAGE("The sunlight is strong."); + MESSAGE("The sunlight is strong."); + MESSAGE("The sunlight is strong."); + MESSAGE("The sunlight is strong."); + MESSAGE("The sunlight is strong."); + MESSAGE("The sunlight is strong."); + MESSAGE("The sunlight faded."); + } +} + +SINGLE_BATTLE_TEST("Orichalcum Pulse boosts physical moves by 33% in sun", s16 damage) +{ + u16 setupMove; + PARAMETRIZE { setupMove = MOVE_CELEBRATE; } + PARAMETRIZE { setupMove = MOVE_RAIN_DANCE; } + + GIVEN { + ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_KORAIDON) { Ability(ABILITY_ORICHALCUM_PULSE); Moves(MOVE_SCRATCH); Speed(5); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_RAIN_DANCE, MOVE_CELEBRATE); Speed(10); } + } WHEN { + TURN { MOVE(opponent, setupMove); MOVE(player, MOVE_SCRATCH); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ORICHALCUM_PULSE); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[1].damage, Q_4_12(1.3333), results[0].damage); + } +} + +SINGLE_BATTLE_TEST("Orichalcum Pulse boost applies even if the target holds Utility Umbrella", s16 damage) +{ + u16 targetItem; + PARAMETRIZE { targetItem = ITEM_NONE; } + PARAMETRIZE { targetItem = ITEM_UTILITY_UMBRELLA; } + + GIVEN { + ASSUME(gItemsInfo[ITEM_UTILITY_UMBRELLA].holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA); + ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_KORAIDON) { Ability(ABILITY_ORICHALCUM_PULSE); Moves(MOVE_SCRATCH); Speed(5); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); Speed(10); Item(targetItem); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_SCRATCH); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ORICHALCUM_PULSE); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_EQ(results[0].damage, results[1].damage); + } +} + +SINGLE_BATTLE_TEST("Orichalcum Pulse does not boost physical moves if holder has Utility Umbrella", s16 damage) +{ + u16 holdItem; + PARAMETRIZE { holdItem = ITEM_NONE; } + PARAMETRIZE { holdItem = ITEM_UTILITY_UMBRELLA; } + + GIVEN { + ASSUME(gItemsInfo[ITEM_UTILITY_UMBRELLA].holdEffect == HOLD_EFFECT_UTILITY_UMBRELLA); + ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_KORAIDON) { Ability(ABILITY_ORICHALCUM_PULSE); Moves(MOVE_SCRATCH); Speed(5); Item(holdItem); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); Speed(10); } + } WHEN { + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_SCRATCH); } + } SCENE { + ABILITY_POPUP(player, ABILITY_ORICHALCUM_PULSE); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[1].damage, Q_4_12(1.3333), results[0].damage); + } +} diff --git a/test/battle/ability/primordial_sea.c b/test/battle/ability/primordial_sea.c index 4a550d1d3e..ec6e30c643 100644 --- a/test/battle/ability/primordial_sea.c +++ b/test/battle/ability/primordial_sea.c @@ -65,14 +65,81 @@ SINGLE_BATTLE_TEST("Primordial Sea does not block a move if Pokémon is asleep a } } -TO_DO_BATTLE_TEST("Primordial Sea makes Sunny Day fail") -TO_DO_BATTLE_TEST("Primordial Sea makes Rain Dance fail") -TO_DO_BATTLE_TEST("Primordial Sea makes Sandstorm fail") -TO_DO_BATTLE_TEST("Primordial Sea makes Hail fail") -TO_DO_BATTLE_TEST("Primordial Sea makes Snowscape fail") // Extrapolation -TO_DO_BATTLE_TEST("Primordial Sea makes Drought fail to activate") -TO_DO_BATTLE_TEST("Primordial Sea makes Drizzle fail to activate") -TO_DO_BATTLE_TEST("Primordial Sea makes Sand Stream fail to activate") -TO_DO_BATTLE_TEST("Primordial Sea makes Snow Warning fail to activate") -TO_DO_BATTLE_TEST("Primordial Sea can be replaced by Delta Stream") -TO_DO_BATTLE_TEST("Primordial Sea can be replaced by Desolate Land") +SINGLE_BATTLE_TEST("Primordial Sea blocks weather-setting moves") +{ + u16 move; + PARAMETRIZE { move = MOVE_SUNNY_DAY; } + PARAMETRIZE { move = MOVE_RAIN_DANCE; } + PARAMETRIZE { move = MOVE_SANDSTORM; } + PARAMETRIZE { move = MOVE_HAIL; } + PARAMETRIZE { move = MOVE_SNOWSCAPE; } + + GIVEN { + ASSUME(GetMoveEffect(MOVE_SUNNY_DAY) == EFFECT_SUNNY_DAY); + ASSUME(GetMoveEffect(MOVE_RAIN_DANCE) == EFFECT_RAIN_DANCE); + ASSUME(GetMoveEffect(MOVE_SANDSTORM) == EFFECT_SANDSTORM); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); + ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE); + PLAYER(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, move); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, move, opponent); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_RAIN_PRIMAL); + } +} + +SINGLE_BATTLE_TEST("Primordial Sea prevents other weather abilities") +{ + u16 ability, species; + PARAMETRIZE { ability = ABILITY_DROUGHT; species = SPECIES_NINETALES; } + PARAMETRIZE { ability = ABILITY_DRIZZLE; species = SPECIES_POLITOED; } + PARAMETRIZE { ability = ABILITY_SAND_STREAM; species = SPECIES_HIPPOWDON; } + PARAMETRIZE { ability = ABILITY_SNOW_WARNING; species = SPECIES_ABOMASNOW; } + + GIVEN { + PLAYER(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ability); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_RAIN_PRIMAL); + } +} + +SINGLE_BATTLE_TEST("Primordial Sea can be replaced by Delta Stream") +{ + GIVEN { + PLAYER(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_DELTA_STREAM); + MESSAGE("Mysterious strong winds are protecting Flying-type Pokémon!"); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_STRONG_WINDS); + } +} + +SINGLE_BATTLE_TEST("Primordial Sea can be replaced by Desolate Land") +{ + GIVEN { + PLAYER(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_GROUDON) { Item(ITEM_RED_ORB); } + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_DESOLATE_LAND); + MESSAGE("The sunlight turned extremely harsh!"); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_SUN_PRIMAL); + } +} diff --git a/test/battle/ability/sand_spit.c b/test/battle/ability/sand_spit.c index c2128f65de..cb97179443 100644 --- a/test/battle/ability/sand_spit.c +++ b/test/battle/ability/sand_spit.c @@ -1,4 +1,77 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("TODO: Write Sand Spit (Ability) test titles") +SINGLE_BATTLE_TEST("Sand Spit sets up sandstorm for 5 turns when hit") +{ + GIVEN { + PLAYER(SPECIES_SANDSLASH) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SAND_SPIT); } + OPPONENT(SPECIES_LANDORUS) { Moves(MOVE_TACKLE, MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + MESSAGE("The opposing Landorus used Tackle!"); + HP_BAR(player); + ABILITY_POPUP(player, ABILITY_SAND_SPIT); + MESSAGE("A sandstorm kicked up!"); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm subsided."); + } +} + +SINGLE_BATTLE_TEST("Sand Spit sets up sandstorm for 8 turns when hit with Smooth Rock") +{ + GIVEN { + PLAYER(SPECIES_SANDSLASH) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SAND_SPIT); Item(ITEM_SMOOTH_ROCK); } + OPPONENT(SPECIES_LANDORUS) { Moves(MOVE_TACKLE, MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + MESSAGE("The opposing Landorus used Tackle!"); + HP_BAR(player); + ABILITY_POPUP(player, ABILITY_SAND_SPIT); + MESSAGE("A sandstorm kicked up!"); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm subsided."); + } +} + +SINGLE_BATTLE_TEST("Sand Spit triggers even if the user is knocked out by the hit") +{ + GIVEN { + PLAYER(SPECIES_SANDSLASH) { Ability(ABILITY_SAND_SPIT); HP(1); Speed(1); } + PLAYER(SPECIES_LANDORUS) { Moves(MOVE_CELEBRATE); Speed(5); } + OPPONENT(SPECIES_LANDORUS) { Moves(MOVE_TACKLE, MOVE_CELEBRATE); Speed(10); } + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); SEND_OUT(player, 1); } + TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_CELEBRATE); } + } SCENE { + MESSAGE("The opposing Landorus used Tackle!"); + HP_BAR(player); + ABILITY_POPUP(player, ABILITY_SAND_SPIT); + MESSAGE("A sandstorm kicked up!"); + MESSAGE("The sandstorm is raging."); + MESSAGE("The opposing Landorus used Celebrate!"); + MESSAGE("Landorus used Celebrate!"); + MESSAGE("The sandstorm is raging."); + } +} diff --git a/test/battle/ability/sand_stream.c b/test/battle/ability/sand_stream.c index 6cd1b06eb4..a1b9464c2a 100644 --- a/test/battle/ability/sand_stream.c +++ b/test/battle/ability/sand_stream.c @@ -1,4 +1,83 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("TODO: Write Sand Stream (Ability) test titles") +SINGLE_BATTLE_TEST("Sand Stream sets up sandstorm for 5 turns (Gen6+)") +{ + GIVEN { + WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6); + PLAYER(SPECIES_HIPPOWDON) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SAND_STREAM); } + OPPONENT(SPECIES_SANDSLASH) { Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_SAND_STREAM); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm subsided."); + } +} + +SINGLE_BATTLE_TEST("Sand Stream sets up sandstorm for 8 turns with Smooth Rock (Gen6+)") +{ + GIVEN { + WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6); + PLAYER(SPECIES_HIPPOWDON) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SAND_STREAM); Item(ITEM_SMOOTH_ROCK); } + OPPONENT(SPECIES_SANDSLASH) { Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_SAND_STREAM); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm subsided."); + } +} + +SINGLE_BATTLE_TEST("Sand Stream sets up permanent sandstorm (Gen3-5)") +{ + GIVEN { + WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_3); + PLAYER(SPECIES_HIPPOWDON) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SAND_STREAM); } + OPPONENT(SPECIES_SANDSLASH) { Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_SAND_STREAM); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + MESSAGE("The sandstorm is raging."); + NOT MESSAGE("The sandstorm subsided."); + } +} diff --git a/test/battle/ability/snow_warning.c b/test/battle/ability/snow_warning.c index bffee14e49..bfb27c5f49 100644 --- a/test/battle/ability/snow_warning.c +++ b/test/battle/ability/snow_warning.c @@ -1,30 +1,138 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Snow Warning summons hail (Gen4-8)") +SINGLE_BATTLE_TEST("Snow Warning sets up hail for 5 turns (Gen6-8)") { GIVEN { WITH_CONFIG(CONFIG_SNOW_WARNING, GEN_8); - PLAYER(SPECIES_ABOMASNOW) { Ability(ABILITY_SNOW_WARNING); } - OPPONENT(SPECIES_WOBBUFFET); + WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6); + PLAYER(SPECIES_ABOMASNOW) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SNOW_WARNING); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); } } WHEN { - TURN {} + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } } SCENE { - MESSAGE("It started to hail!"); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HAIL_CONTINUES); + ABILITY_POPUP(player, ABILITY_SNOW_WARNING); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail stopped."); } } -SINGLE_BATTLE_TEST("Snow Warning summons snow (Gen9+)") +SINGLE_BATTLE_TEST("Snow Warning sets up hail for 8 turns with Icy Rock (Gen6-8)") +{ + GIVEN { + WITH_CONFIG(CONFIG_SNOW_WARNING, GEN_8); + WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_6); + PLAYER(SPECIES_ABOMASNOW) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SNOW_WARNING); Item(ITEM_ICY_ROCK); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_SNOW_WARNING); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail stopped."); + } +} + +SINGLE_BATTLE_TEST("Snow Warning sets up permanent hail (Gen4-5)") +{ + GIVEN { + WITH_CONFIG(CONFIG_SNOW_WARNING, GEN_8); + WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_5); + PLAYER(SPECIES_ABOMASNOW) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SNOW_WARNING); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_SNOW_WARNING); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + MESSAGE("The hail is crashing down."); + NOT MESSAGE("The hail stopped."); + } +} + +SINGLE_BATTLE_TEST("Snow Warning sets up snow for 5 turns (Gen9+)") { GIVEN { WITH_CONFIG(CONFIG_SNOW_WARNING, GEN_9); - PLAYER(SPECIES_ABOMASNOW) { Ability(ABILITY_SNOW_WARNING); } - OPPONENT(SPECIES_WOBBUFFET); + WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_9); + PLAYER(SPECIES_ABOMASNOW) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SNOW_WARNING); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); } } WHEN { - TURN {} + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } } SCENE { - MESSAGE("It started to snow!"); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SNOW_CONTINUES); + ABILITY_POPUP(player, ABILITY_SNOW_WARNING); + MESSAGE("Snow continues to fall."); + MESSAGE("Snow continues to fall."); + MESSAGE("Snow continues to fall."); + MESSAGE("Snow continues to fall."); + MESSAGE("The snow stopped."); + } +} + +SINGLE_BATTLE_TEST("Snow Warning sets up snow for 8 turns with Icy Rock (Gen9+)") +{ + GIVEN { + WITH_CONFIG(CONFIG_SNOW_WARNING, GEN_9); + WITH_CONFIG(CONFIG_ABILITY_WEATHER, GEN_9); + PLAYER(SPECIES_ABOMASNOW) { Moves(MOVE_CELEBRATE); Ability(ABILITY_SNOW_WARNING); Item(ITEM_ICY_ROCK); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(player, ABILITY_SNOW_WARNING); + MESSAGE("Snow continues to fall."); + MESSAGE("Snow continues to fall."); + MESSAGE("Snow continues to fall."); + MESSAGE("Snow continues to fall."); + MESSAGE("Snow continues to fall."); + MESSAGE("Snow continues to fall."); + MESSAGE("Snow continues to fall."); + MESSAGE("The snow stopped."); } } diff --git a/test/battle/ability/thick_fat.c b/test/battle/ability/thick_fat.c index bcc4c9487c..ce13d12982 100644 --- a/test/battle/ability/thick_fat.c +++ b/test/battle/ability/thick_fat.c @@ -1,4 +1,39 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("TODO: Write Thick Fat (Ability) test titles") +ASSUMPTIONS +{ + ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); + ASSUME(GetMoveType(MOVE_POWDER_SNOW) == TYPE_ICE); + ASSUME(GetMoveEffect(MOVE_WORRY_SEED) == EFFECT_OVERWRITE_ABILITY); +} + +SINGLE_BATTLE_TEST("Thick Fat halves damage from fire and ice type moves", s16 damage[2]) +{ + u16 move; + + PARAMETRIZE { move = MOVE_POWDER_SNOW; } + PARAMETRIZE { move = MOVE_EMBER; } + + GIVEN { + PLAYER (SPECIES_WOBBUFFET); + OPPONENT (SPECIES_SNORLAX) { Ability(ABILITY_THICK_FAT); } + } + WHEN { + TURN { MOVE(player, move); } + TURN { MOVE(player, MOVE_WORRY_SEED); } + TURN { MOVE(player, move); } + } + SCENE { + ANIMATION(ANIM_TYPE_MOVE, move, player); + HP_BAR(opponent, captureDamage: &results[i].damage[0]); + ANIMATION(ANIM_TYPE_MOVE, MOVE_WORRY_SEED, player); + ANIMATION(ANIM_TYPE_MOVE, move, player); + HP_BAR(opponent, captureDamage: &results[i].damage[1]); + } + FINALLY { + EXPECT_MUL_EQ(results[0].damage[0], Q_4_12(2), results[0].damage[1]); + EXPECT_MUL_EQ(results[1].damage[0], Q_4_12(2), results[1].damage[1]); + } +} + diff --git a/test/battle/ai/ai_calc_best_move_score.c b/test/battle/ai/ai_calc_best_move_score.c index 8a3b123da8..cb1e1239de 100644 --- a/test/battle/ai/ai_calc_best_move_score.c +++ b/test/battle/ai/ai_calc_best_move_score.c @@ -259,6 +259,19 @@ AI_SINGLE_BATTLE_TEST("HasMoveThatChangesKOThreshold - AI should not see self-ta } } +AI_SINGLE_BATTLE_TEST("AI_IsMoveEffectInPlus - AI should not see secondary effect of Sheer Force boosted moves as beneficial") +{ + GIVEN { + ASSUME(GetMovePower(MOVE_PSYCHIC) == 90); + ASSUME(MoveHasAdditionalEffect(MOVE_PSYCHIC, MOVE_EFFECT_SP_DEF_MINUS_1) == TRUE); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_OMNISCIENT); + PLAYER(SPECIES_STEELIX) { Level(100); Nature(NATURE_SASSY); Item(ITEM_STEELIXITE); Ability(ABILITY_STURDY); Speed(58); Moves(MOVE_GYRO_BALL); } + OPPONENT(SPECIES_BRAVIARY_HISUI) { Level(100); Nature(NATURE_TIMID); Ability(ABILITY_SHEER_FORCE); Speed(251); Moves(MOVE_PSYCHIC, MOVE_NIGHT_SHADE); } + } WHEN { + TURN { MOVE(player, MOVE_GYRO_BALL); SCORE_EQ_VAL(opponent, MOVE_PSYCHIC, 101); SCORE_EQ_VAL(opponent, MOVE_NIGHT_SHADE, 101); } + } +} + AI_SINGLE_BATTLE_TEST("Fillet Away AI handling") { u16 move; diff --git a/test/battle/ai/ai_multi.c b/test/battle/ai/ai_multi.c index 6810badcec..d7e5755eab 100644 --- a/test/battle/ai/ai_multi.c +++ b/test/battle/ai/ai_multi.c @@ -222,3 +222,31 @@ AI_MULTI_BATTLE_TEST("AI opponents do not steal their partner pokemon in multi b EXPECT_EQ(SPECIES_VENUSAUR, opponentLeft->species); } } + +AI_MULTI_BATTLE_TEST("Pollen Puff: AI correctly scores moves with EFFECT_HIT_ENEMY_HEAL_ALLY as damaging opponents but not allies") +{ + GIVEN { + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT); + ASSUME(GetMoveEffect(MOVE_POLLEN_PUFF) == EFFECT_HIT_ENEMY_HEAL_ALLY); + // Speed tie so all think they are faster + MULTI_PLAYER(SPECIES_WOBBUFFET) { Speed(1); HP(50); Moves(MOVE_POLLEN_PUFF, MOVE_CELEBRATE); } + MULTI_PARTNER(SPECIES_WOBBUFFET) { Speed(1); HP(50); Moves(MOVE_POLLEN_PUFF); } + MULTI_OPPONENT_A(SPECIES_WOBBUFFET) { Speed(1); HP(50); Moves(MOVE_POLLEN_PUFF); } + MULTI_OPPONENT_B(SPECIES_WOBBUFFET) { Speed(1); HP(50); Moves(MOVE_POLLEN_PUFF); } + } WHEN { + TURN { + // Targeting ally + SCORE_EQ_VAL(opponentLeft, MOVE_POLLEN_PUFF, AI_SCORE_DEFAULT + WEAK_EFFECT, target:opponentRight); + SCORE_EQ_VAL(playerRight, MOVE_POLLEN_PUFF, AI_SCORE_DEFAULT + WEAK_EFFECT, target:playerLeft); + SCORE_EQ_VAL(opponentRight, MOVE_POLLEN_PUFF, AI_SCORE_DEFAULT + WEAK_EFFECT, target:opponentLeft); + + // Targeting opponent + SCORE_EQ_VAL(opponentLeft, MOVE_POLLEN_PUFF, AI_SCORE_DEFAULT + BEST_DAMAGE_MOVE + FAST_KILL, target:playerLeft); + SCORE_EQ_VAL(opponentLeft, MOVE_POLLEN_PUFF, AI_SCORE_DEFAULT + BEST_DAMAGE_MOVE + FAST_KILL, target:playerRight); + SCORE_EQ_VAL(playerRight, MOVE_POLLEN_PUFF, AI_SCORE_DEFAULT + BEST_DAMAGE_MOVE + FAST_KILL, target:opponentLeft); + SCORE_EQ_VAL(playerRight, MOVE_POLLEN_PUFF, AI_SCORE_DEFAULT + BEST_DAMAGE_MOVE + FAST_KILL, target:opponentRight); + SCORE_EQ_VAL(opponentRight, MOVE_POLLEN_PUFF, AI_SCORE_DEFAULT + BEST_DAMAGE_MOVE + FAST_KILL, target:playerLeft); + SCORE_EQ_VAL(opponentRight, MOVE_POLLEN_PUFF, AI_SCORE_DEFAULT + BEST_DAMAGE_MOVE + FAST_KILL, target:playerRight); + } + } +} diff --git a/test/battle/ai/ai_switching.c b/test/battle/ai/ai_switching.c index 653ebb1712..0692ffad5c 100644 --- a/test/battle/ai/ai_switching.c +++ b/test/battle/ai/ai_switching.c @@ -1949,6 +1949,27 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI considers both meeting and } } +AI_DOUBLE_BATTLE_TEST("AI will not choose to switch out Dondozo with Commander Tatsugiri") +{ + PASSES_RANDOMLY(100, 100); + GIVEN { + ASSUME(GetMoveEffect(MOVE_PERISH_SONG) == EFFECT_PERISH_SONG); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES); + OPPONENT(SPECIES_DONDOZO) { Level(50); Moves(MOVE_WATER_GUN); } + OPPONENT(SPECIES_TATSUGIRI) { Moves(MOVE_WATER_GUN); Ability(ABILITY_COMMANDER); } + OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_HEADBUTT); } + PLAYER(SPECIES_ZIGZAGOON) { Moves(MOVE_CELEBRATE, MOVE_SCRATCH); } + PLAYER(SPECIES_ZIGZAGOON) { Moves(MOVE_CELEBRATE, MOVE_PERISH_SONG); } + PLAYER(SPECIES_ZIGZAGOON) { Moves(MOVE_CELEBRATE); } + PLAYER(SPECIES_ZIGZAGOON) { Moves (MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_PERISH_SONG); } + TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); } + TURN { SWITCH(playerLeft, 2); SWITCH(playerRight, 3); } + TURN { MOVE(playerLeft, MOVE_CELEBRATE); MOVE(playerRight, MOVE_CELEBRATE); EXPECT_MOVE(opponentLeft, MOVE_WATER_GUN); } + } +} + AI_SINGLE_BATTLE_TEST("AI_FLAG_RANDOMIZE_SWITCHIN: AI will randomly choose between eligible switchin candidates of the same category") { u32 trials; // Two trial counts to ensure randomization is scalable diff --git a/test/battle/evolution_tracker.c b/test/battle/evolution_tracker.c new file mode 100644 index 0000000000..58aa835fbd --- /dev/null +++ b/test/battle/evolution_tracker.c @@ -0,0 +1,137 @@ +#include "global.h" +#include "test/battle.h" + +ASSUMPTIONS +{ + ASSUME(gSpeciesInfo[SPECIES_BISHARP].evolutions[0].params->condition == IF_DEFEAT_X_WITH_ITEMS); + ASSUME(gSpeciesInfo[SPECIES_BISHARP].evolutions[0].params->arg1 == SPECIES_BISHARP); + ASSUME(gSpeciesInfo[SPECIES_BISHARP].evolutions[0].params->arg2 == ITEM_LEADERS_CREST); +} + +WILD_BATTLE_TEST("Evolution Tracker: Bisharp KO-ing a Bisharp that holds Leader's Crest increases tracker") +{ + GIVEN { + PLAYER(SPECIES_BISHARP); + OPPONENT(SPECIES_BISHARP) { Item(ITEM_LEADERS_CREST); HP(1); } + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH); } + } SCENE { + HP_BAR(opponent, hp: 0); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_EVOLUTION_TRACKER), 1); + } +} + +// To be replaced with WILD_DOUBLE_BATTLE_TEST when that is made possible (also see TryUpdateEvolutionTracker) +DOUBLE_BATTLE_TEST("Evolution Tracker: Bisharp KO-ing multiple Bisharps holding Leader's Crest increases tracker multiple times") +{ + GIVEN { + ASSUME(GetMoveTarget(MOVE_LAVA_PLUME) == TARGET_FOES_AND_ALLY); + PLAYER(SPECIES_BISHARP); + PLAYER(SPECIES_BISHARP) { Item(ITEM_LEADERS_CREST); HP(1); } + OPPONENT(SPECIES_BISHARP) { Item(ITEM_LEADERS_CREST); HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_LAVA_PLUME); } + } SCENE { + HP_BAR(opponentLeft, hp: 0); + HP_BAR(playerRight, hp: 0); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_EVOLUTION_TRACKER), 2); + } +} + +WILD_BATTLE_TEST("Evolution Tracker: Bisharp KO-ing a Bisharp that doesn't hold Leader's Crest doesn't increase tracker") +{ + GIVEN { + PLAYER(SPECIES_BISHARP); + OPPONENT(SPECIES_BISHARP) { HP(1); } + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH); } + } SCENE { + HP_BAR(opponent, hp: 0); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_EVOLUTION_TRACKER), 0); + } +} + +WILD_BATTLE_TEST("Evolution Tracker: Bisharp KO-ing a non-Bisharp that holds Leader's Crest doesn't increase tracker") +{ + u32 species; + + PARAMETRIZE { species = SPECIES_WOBBUFFET; } + PARAMETRIZE { species = SPECIES_PAWNIARD; } + GIVEN { + PLAYER(SPECIES_BISHARP); + OPPONENT(species) { Item(ITEM_LEADERS_CREST); HP(1); } + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH); } + } SCENE { + HP_BAR(opponent, hp: 0); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_EVOLUTION_TRACKER), 0); + } +} + +WILD_BATTLE_TEST("Evolution Tracker: Pawniard KO-ing a Bisharp that holds Leader's Crest doesn't increase tracker") +{ + GIVEN { + PLAYER(SPECIES_PAWNIARD); + OPPONENT(SPECIES_BISHARP) { Item(ITEM_LEADERS_CREST); HP(1); } + } WHEN { + TURN { MOVE(player, MOVE_SCRATCH); } + } SCENE { + HP_BAR(opponent, hp: 0); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_EVOLUTION_TRACKER), 0); + } +} + +WILD_BATTLE_TEST("Evolution Tracker: Bisharp KO-ing eligible battler from contact effects doesn't increase tracker") +{ + GIVEN { + ASSUME(GetItemHoldEffect(ITEM_ROCKY_HELMET) == HOLD_EFFECT_ROCKY_HELMET); + ASSUME(MoveMakesContact(MOVE_SCRATCH)); + PLAYER(SPECIES_BISHARP) { Item(ITEM_ROCKY_HELMET); } + OPPONENT(SPECIES_BISHARP) { Item(ITEM_LEADERS_CREST); HP(1); } + } WHEN { + TURN { MOVE(opponent, MOVE_SCRATCH); } + } SCENE { + HP_BAR(opponent, hp: 0); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_EVOLUTION_TRACKER), 0); + } +} + +WILD_BATTLE_TEST("Evolution Tracker: Bisharp KO-ing eligible battler with passive damage doesn't increase tracker") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_LEECH_SEED) == EFFECT_LEECH_SEED); + PLAYER(SPECIES_BISHARP); + OPPONENT(SPECIES_BISHARP) { Item(ITEM_LEADERS_CREST); HP(1); } + } WHEN { + TURN { MOVE(player, MOVE_LEECH_SEED); } + } SCENE { + HP_BAR(opponent, hp: 0); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_EVOLUTION_TRACKER), 0); + } +} + +// To be replaced with WILD_DOUBLE_BATTLE_TEST when that is made possible (also see TryUpdateEvolutionTracker) +DOUBLE_BATTLE_TEST("Evolution Tracker: Bisharp KO-ing eligible battler with bursting flames doesn't increase tracker") +{ + GIVEN { + ASSUME(MoveHasAdditionalEffect(MOVE_FLAME_BURST, MOVE_EFFECT_FLAME_BURST)); + PLAYER(SPECIES_BISHARP); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_BISHARP) { Item(ITEM_LEADERS_CREST); HP(1); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_FLAME_BURST, target: opponentRight); } + } SCENE { + HP_BAR(opponentLeft, hp: 0); + } THEN { + EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_EVOLUTION_TRACKER), 0); + } +} diff --git a/test/battle/gimmick/terastal.c b/test/battle/gimmick/terastal.c index d78a68dc53..2379df58dc 100644 --- a/test/battle/gimmick/terastal.c +++ b/test/battle/gimmick/terastal.c @@ -327,33 +327,6 @@ SINGLE_BATTLE_TEST("(TERA) Reflect Type fails if used by a Terastallized Pokemon } } -SINGLE_BATTLE_TEST("(TERA) Conversion fails if used by a Terastallized Pokemon") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_PSYCHIC); } - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_CONVERSION, gimmick: GIMMICK_TERA); } - } SCENE { - MESSAGE("Wobbuffet used Conversion!"); - MESSAGE("But it failed!"); - } -} - -SINGLE_BATTLE_TEST("(TERA) Conversion2 fails if used by a Terastallized Pokemon") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_PSYCHIC); } - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(opponent, MOVE_SCRATCH); } - TURN { MOVE(player, MOVE_CONVERSION_2, gimmick: GIMMICK_TERA); } - } SCENE { - MESSAGE("Wobbuffet used Conversion 2!"); - MESSAGE("But it failed!"); - } -} - SINGLE_BATTLE_TEST("(TERA) Reflect Type copies a Terastallized Pokemon's Tera Type") { GIVEN { @@ -506,26 +479,6 @@ SINGLE_BATTLE_TEST("(TERA) Revelation Dance uses a Stellar-type Pokemon's base t } } -#if B_UPDATED_CONVERSION_2 < GEN_5 -SINGLE_BATTLE_TEST("(TERA) Conversion2 fails if last hit by a Stellar-type move") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_STELLAR); } - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_TERA_BLAST, gimmick: GIMMICK_TERA); } - TURN { MOVE(opponent, MOVE_CONVERSION_2); } - } SCENE { - // turn 1 - MESSAGE("Wobbuffet used Tera Blast!"); - ANIMATION(ANIM_TYPE_MOVE, MOVE_TERA_BLAST, player); - // turn 2 - MESSAGE("The opposing Wobbuffet used Conversion 2!"); - MESSAGE("But it failed!"); - } -} -#endif - SINGLE_BATTLE_TEST("(TERA) Roost does not remove Flying-type ground immunity when Terastallized into the Stellar type") { GIVEN { diff --git a/test/battle/hold_effect/white_herb.c b/test/battle/hold_effect/white_herb.c index 4a8f020023..8423c29fdb 100644 --- a/test/battle/hold_effect/white_herb.c +++ b/test/battle/hold_effect/white_herb.c @@ -151,7 +151,7 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if it is knocked off o } NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); - MESSAGE("Wobbuffet returned its stats to normal using its White Herb!"); + MESSAGE("Slugma returned its stats to normal using its White Herb!"); } } THEN { EXPECT(player->statStages[STAT_DEF] = DEFAULT_STAT_STAGE - 1); @@ -176,7 +176,7 @@ SINGLE_BATTLE_TEST("White Herb wont have time to activate if Magician steals it" MESSAGE("The opposing Fennekin stole Slugma's White Herb!"); NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); - MESSAGE("Wobbuffet returned its stats to normal using its White Herb!"); + MESSAGE("Slugma returned its stats to normal using its White Herb!"); } } THEN { EXPECT(player->statStages[STAT_DEF] = DEFAULT_STAT_STAGE - 1); diff --git a/test/battle/move_effect/conversion.c b/test/battle/move_effect/conversion.c index ac863cf2b2..165d274a50 100644 --- a/test/battle/move_effect/conversion.c +++ b/test/battle/move_effect/conversion.c @@ -8,3 +8,16 @@ TO_DO_BATTLE_TEST("Conversion fails if all the user's moves share types with the TO_DO_BATTLE_TEST("Conversion changes the user's types to the one in the user's first slot (Gen 6+)"); TO_DO_BATTLE_TEST("Conversion can read the user's first move slot even if that move cannot be selected (Gen 6+)"); //Eg. Disable TO_DO_BATTLE_TEST("Conversion can change the user's types to Conversion's type"); + +SINGLE_BATTLE_TEST("(TERA) Conversion fails if used by a Terastallized Pokemon") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_PSYCHIC); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CONVERSION, gimmick: GIMMICK_TERA); } + } SCENE { + MESSAGE("Wobbuffet used Conversion!"); + MESSAGE("But it failed!"); + } +} diff --git a/test/battle/move_effect/conversion_2.c b/test/battle/move_effect/conversion_2.c index acd21125c3..169243019b 100644 --- a/test/battle/move_effect/conversion_2.c +++ b/test/battle/move_effect/conversion_2.c @@ -3,10 +3,10 @@ TO_DO_BATTLE_TEST("Conversion 2's type change considers Inverse Battles"); -#if B_UPDATED_CONVERSION_2 < GEN_5 -SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type that resists the last move that hit the user (Gen 3-4)") +SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type that resists the last move that hit the user (Gen 1-4)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_4); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -16,15 +16,16 @@ SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type MESSAGE("Wobbuffet used Ominous Wind!"); // turn 1 ONE_OF { - MESSAGE("The opposing Wobbuffet transformed into the Normal type!"); - MESSAGE("The opposing Wobbuffet transformed into the Dark type!"); + MESSAGE("The opposing Wobbuffet transformed into the Normal type!"); + MESSAGE("The opposing Wobbuffet transformed into the Dark type!"); } } } -SINGLE_BATTLE_TEST("Conversion 2's type change considers Struggle to be Normal type (Gen 3-4)") +SINGLE_BATTLE_TEST("Conversion 2's type change considers Struggle to be Normal type (Gen 1-4)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_4); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -35,18 +36,17 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers Struggle to be Normal t MESSAGE("The opposing Wobbuffet used Struggle!"); // turn 2 ONE_OF { - MESSAGE("Wobbuffet transformed into the Steel type!"); - MESSAGE("Wobbuffet transformed into the Rock type!"); - MESSAGE("Wobbuffet transformed into the Ghost type!"); + MESSAGE("Wobbuffet transformed into the Steel type!"); + MESSAGE("Wobbuffet transformed into the Rock type!"); + MESSAGE("Wobbuffet transformed into the Ghost type!"); } } } -#endif -#if B_UPDATED_CONVERSION_2 >= GEN_5 SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type that resists the last used target's move (Gen 5+)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -56,8 +56,8 @@ SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type MESSAGE("Wobbuffet used Ominous Wind!"); // turn 1 ONE_OF { - MESSAGE("The opposing Wobbuffet transformed into the Normal type!"); - MESSAGE("The opposing Wobbuffet transformed into the Dark type!"); + MESSAGE("The opposing Wobbuffet transformed into the Normal type!"); + MESSAGE("The opposing Wobbuffet transformed into the Dark type!"); } } } @@ -65,6 +65,7 @@ SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type SINGLE_BATTLE_TEST("Conversion 2's type change considers status moves (Gen 5+)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -75,8 +76,8 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers status moves (Gen 5+)") MESSAGE("The opposing Wobbuffet used Curse!"); // turn 2 ONE_OF { - MESSAGE("Wobbuffet transformed into the Normal type!"); - MESSAGE("Wobbuffet transformed into the Dark type!"); + MESSAGE("Wobbuffet transformed into the Normal type!"); + MESSAGE("Wobbuffet transformed into the Dark type!"); } } } @@ -84,6 +85,7 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers status moves (Gen 5+)") SINGLE_BATTLE_TEST("Conversion 2's type change considers the type of moves called by other moves") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -94,8 +96,8 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers the type of moves calle MESSAGE("The opposing Wobbuffet used Mirror Move!"); // turn 2 ONE_OF { - MESSAGE("Wobbuffet transformed into the Normal type!"); - MESSAGE("Wobbuffet transformed into the Dark type!"); + MESSAGE("Wobbuffet transformed into the Normal type!"); + MESSAGE("Wobbuffet transformed into the Dark type!"); } } } @@ -103,6 +105,7 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers the type of moves calle SINGLE_BATTLE_TEST("Conversion 2's type change considers dynamic type moves") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -113,10 +116,10 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers dynamic type moves") MESSAGE("The opposing Wobbuffet used Weather Ball!"); // turn 2 ONE_OF { - MESSAGE("Wobbuffet transformed into the Steel type!"); - MESSAGE("Wobbuffet transformed into the Fire type!"); - MESSAGE("Wobbuffet transformed into the Water type!"); - MESSAGE("Wobbuffet transformed into the Ice type!"); + MESSAGE("Wobbuffet transformed into the Steel type!"); + MESSAGE("Wobbuffet transformed into the Fire type!"); + MESSAGE("Wobbuffet transformed into the Water type!"); + MESSAGE("Wobbuffet transformed into the Ice type!"); } } } @@ -124,6 +127,7 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers dynamic type moves") SINGLE_BATTLE_TEST("Conversion 2's type change considers move types changed by Normalize and Electrify") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_NORMALIZE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -136,17 +140,17 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers move types changed by N MESSAGE("The opposing Wobbuffet used Pound!"); // turn 2 ONE_OF { - MESSAGE("Wobbuffet transformed into the Ground type!"); - MESSAGE("Wobbuffet transformed into the Dragon type!"); - MESSAGE("Wobbuffet transformed into the Grass type!"); - MESSAGE("Wobbuffet transformed into the Electric type!"); + MESSAGE("Wobbuffet transformed into the Ground type!"); + MESSAGE("Wobbuffet transformed into the Dragon type!"); + MESSAGE("Wobbuffet transformed into the Grass type!"); + MESSAGE("Wobbuffet transformed into the Electric type!"); } // turn 3 MESSAGE("Wobbuffet used Water Gun!"); ONE_OF { - MESSAGE("The opposing Wobbuffet transformed into the Steel type!"); - MESSAGE("The opposing Wobbuffet transformed into the Rock type!"); - MESSAGE("The opposing Wobbuffet transformed into the Ghost type!"); + MESSAGE("The opposing Wobbuffet transformed into the Steel type!"); + MESSAGE("The opposing Wobbuffet transformed into the Rock type!"); + MESSAGE("The opposing Wobbuffet transformed into the Ghost type!"); } } } @@ -154,6 +158,7 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers move types changed by N SINGLE_BATTLE_TEST("Conversion 2's type change fails targeting Struggle (Gen 5+)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -171,6 +176,7 @@ SINGLE_BATTLE_TEST("Conversion 2's type change fails targeting Struggle (Gen 5+) SINGLE_BATTLE_TEST("Conversion 2 fails if the move used is of typeless damage (Gen 5+)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_ENTEI); } WHEN { @@ -187,7 +193,6 @@ SINGLE_BATTLE_TEST("Conversion 2 fails if the move used is of typeless damage (G MESSAGE("But it failed!"); } } -#endif SINGLE_BATTLE_TEST("Conversion 2 fails if the targeted move is Stellar Type") { @@ -205,3 +210,35 @@ SINGLE_BATTLE_TEST("Conversion 2 fails if the targeted move is Stellar Type") MESSAGE("But it failed!"); } } + +SINGLE_BATTLE_TEST("Conversion 2 fails if used by a Terastallized Pokemon") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_PSYCHIC); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_CONVERSION_2, gimmick: GIMMICK_TERA); } + } SCENE { + MESSAGE("Wobbuffet used Conversion 2!"); + MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Conversion 2 fails if last hit by a Stellar-type move (Gen 1-4)") +{ + GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_4); + PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_STELLAR); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TERA_BLAST, gimmick: GIMMICK_TERA); MOVE(opponent, MOVE_CONVERSION_2); } + } SCENE { + // turn 1 + MESSAGE("Wobbuffet used Tera Blast!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TERA_BLAST, player); + // turn 2 + MESSAGE("The opposing Wobbuffet used Conversion 2!"); + MESSAGE("But it failed!"); + } +} diff --git a/test/battle/move_effect/court_change.c b/test/battle/move_effect/court_change.c index c5a44635eb..353811ee28 100644 --- a/test/battle/move_effect/court_change.c +++ b/test/battle/move_effect/court_change.c @@ -81,6 +81,7 @@ DOUBLE_BATTLE_TEST("Court Change swaps entry hazards used by the player") DOUBLE_BATTLE_TEST("Court Change used by the player swaps Mist, Safeguard, Aurora Veil, Reflect, Light Screen, Tailwind") { GIVEN { + WITH_CONFIG(CONFIG_TAILWIND_TURNS, GEN_5); PLAYER(SPECIES_WYNAUT); PLAYER(SPECIES_WYNAUT); PLAYER(SPECIES_WYNAUT); @@ -119,6 +120,7 @@ DOUBLE_BATTLE_TEST("Court Change used by the player swaps Mist, Safeguard, Auror DOUBLE_BATTLE_TEST("Court Change used by the opponent swaps Mist, Safeguard, Aurora Veil, Reflect, Light Screen, Tailwind") { GIVEN { + WITH_CONFIG(CONFIG_TAILWIND_TURNS, GEN_5); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -246,4 +248,3 @@ AI_SINGLE_BATTLE_TEST("AI uses Court Change") TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_COURT_CHANGE); } } } - diff --git a/test/battle/move_effect/grudge.c b/test/battle/move_effect/grudge.c index 2b74a3b05a..9d381ad833 100644 --- a/test/battle/move_effect/grudge.c +++ b/test/battle/move_effect/grudge.c @@ -50,12 +50,258 @@ SINGLE_BATTLE_TEST("Grudge does not deplete PP of a Z-Move") } } -TO_DO_BATTLE_TEST("Grudge depletes all PP from a Max Move's base move") -TO_DO_BATTLE_TEST("Grudge does not activate for Struggle") -TO_DO_BATTLE_TEST("Grudge's effect disappears if the user takes a new turn - Move"); -TO_DO_BATTLE_TEST("Grudge's effect disappears if the user takes a new turn - Sleep"); -TO_DO_BATTLE_TEST("Grudge's effect disappears if the user takes a new turn - Paralysis"); -TO_DO_BATTLE_TEST("Grudge's effect disappears if the user takes a new turn - Flinching"); -TO_DO_BATTLE_TEST("Grudge's effect doesn't trigger on indirect damage - Sandstorm"); -TO_DO_BATTLE_TEST("Grudge's effect doesn't trigger on indirect damage - Leech Seed"); -TO_DO_BATTLE_TEST("Grudge's effect doesn't trigger on indirect damage - Future Sight"); +SINGLE_BATTLE_TEST("Grudge depletes all PP from a Max Move's base move") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { HP(1); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_SCRATCH, MOVE_POUND, MOVE_SURF); Item(ITEM_LAGGING_TAIL); } + } WHEN { + TURN { MOVE(player, MOVE_GRUDGE); MOVE(opponent, MOVE_SCRATCH, gimmick: GIMMICK_DYNAMAX); SEND_OUT(player, 1); } + } SCENE { + MESSAGE("Wobbuffet used Grudge!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_GRUDGE, player); + MESSAGE("The opposing Wobbuffet used Max Strike!"); + MESSAGE("Wobbuffet fainted!"); + MESSAGE("The opposing Wobbuffet's Scratch lost all its PP due to the grudge!"); + } THEN { + EXPECT_GT(opponent->pp[0], 0); + EXPECT_EQ(opponent->pp[1], 0); + EXPECT_GT(opponent->pp[2], 0); + EXPECT_GT(opponent->pp[3], 0); + } +} + +SINGLE_BATTLE_TEST("Grudge does not activate for Struggle") +{ + GIVEN { + PLAYER (SPECIES_WOBBUFFET) { HP(1); } + PLAYER (SPECIES_WOBBUFFET); + OPPONENT (SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_STRUGGLE, MOVE_POUND, MOVE_SURF); }; + } + WHEN { + TURN { MOVE(player, MOVE_GRUDGE); MOVE(opponent, MOVE_STRUGGLE); SEND_OUT(player, 1); } + } + SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GRUDGE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_STRUGGLE, opponent); + MESSAGE("Wobbuffet fainted!"); + NOT MESSAGE("The opposing Wobbuffet's Struggle lost all its PP due to the grudge!"); + } + THEN { + EXPECT_GT(opponent->pp[0], 0); + EXPECT_GT(opponent->pp[1], 0); + EXPECT_GT(opponent->pp[2], 0); + EXPECT_GT(opponent->pp[3], 0); + } +} + +SINGLE_BATTLE_TEST("Grudge's effect disappears if the user takes a new turn - Move") +{ + GIVEN { + PLAYER (SPECIES_WOBBUFFET) { HP(1); } + PLAYER (SPECIES_WOBBUFFET); + OPPONENT (SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_SCRATCH, MOVE_POUND, MOVE_SURF); }; + } + WHEN { + TURN { MOVE(player, MOVE_GRUDGE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_SCRATCH); SEND_OUT(player, 1); } + } + SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GRUDGE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent); + MESSAGE("Wobbuffet fainted!"); + NOT MESSAGE("The opposing Wobbuffet's Scratch lost all its PP due to the grudge!"); + } + THEN { + EXPECT_GT(opponent->pp[0], 0); + EXPECT_GT(opponent->pp[1], 0); + EXPECT_GT(opponent->pp[2], 0); + EXPECT_GT(opponent->pp[3], 0); + } +} + +SINGLE_BATTLE_TEST("Grudge's effect disappears if the user takes a new turn - Sleep") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_SPORE) == EFFECT_NON_VOLATILE_STATUS); + ASSUME(gMovesInfo[SanitizeMoveId(MOVE_SPORE)].argument.nonVolatileStatus == MOVE_EFFECT_SLEEP); + PLAYER (SPECIES_WOBBUFFET) { HP(1);} + PLAYER (SPECIES_WOBBUFFET); + OPPONENT (SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_VITAL_THROW, MOVE_SPORE, MOVE_SURF); } + } + WHEN { + TURN { MOVE(player, MOVE_GRUDGE); MOVE(opponent, MOVE_SPORE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_VITAL_THROW); SEND_OUT(player, 1); } + } + SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GRUDGE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponent); + ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_SLP, player); + MESSAGE("Wobbuffet fell asleep!"); + STATUS_ICON(player, sleep: TRUE); + MESSAGE("Wobbuffet is fast asleep."); + ANIMATION(ANIM_TYPE_MOVE, MOVE_VITAL_THROW, opponent); + MESSAGE("Wobbuffet fainted!"); + NOT MESSAGE("The opposing Wobbuffet's Scratch lost all its PP due to the grudge!"); + } + THEN { + EXPECT_GT(opponent->pp[0], 0); + EXPECT_GT(opponent->pp[1], 0); + EXPECT_GT(opponent->pp[2], 0); + EXPECT_GT(opponent->pp[3], 0); + } +} + +SINGLE_BATTLE_TEST("Grudge's effect disappears if the user takes a new turn - Paralysis") +{ + PASSES_RANDOMLY(25, 100, RNG_PARALYSIS); + GIVEN { + ASSUME(GetMoveEffect(MOVE_STUN_SPORE) == EFFECT_NON_VOLATILE_STATUS); + ASSUME(gMovesInfo[SanitizeMoveId(MOVE_STUN_SPORE)].argument.nonVolatileStatus == MOVE_EFFECT_PARALYSIS); + ASSUME(GetMovePriority(MOVE_VITAL_THROW) == -1); + PLAYER (SPECIES_WOBBUFFET) { HP(1);} + PLAYER (SPECIES_WOBBUFFET); + OPPONENT (SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_VITAL_THROW, MOVE_STUN_SPORE, MOVE_SURF); };\ + } + WHEN { + TURN { MOVE(player, MOVE_GRUDGE); MOVE(opponent, MOVE_STUN_SPORE); } + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_VITAL_THROW); SEND_OUT(player, 1); } + } + SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GRUDGE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_STUN_SPORE, opponent); + MESSAGE("Wobbuffet is paralyzed, so it may be unable to move!"); + STATUS_ICON(player, paralysis: TRUE); + MESSAGE("Wobbuffet couldn't move because it's paralyzed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_VITAL_THROW, opponent); + MESSAGE("Wobbuffet fainted!"); + NOT MESSAGE("The opposing Wobbuffet's Scratch lost all its PP due to the grudge!"); + } + THEN { + EXPECT_GT(opponent->pp[0], 0); + EXPECT_GT(opponent->pp[1], 0); + EXPECT_GT(opponent->pp[2], 0); + EXPECT_GT(opponent->pp[3], 0); + } +} + +SINGLE_BATTLE_TEST("Grudge's effect disappears if the user takes a new turn - Flinching") +{ + PASSES_RANDOMLY(10, 100, RNG_HOLD_EFFECT_FLINCH); + GIVEN { + ASSUME(GetMoveEffect(MOVE_FALSE_SWIPE) == EFFECT_FALSE_SWIPE); + PLAYER (SPECIES_WOBBUFFET) { HP(1); } + PLAYER (SPECIES_WOBBUFFET); + OPPONENT (SPECIES_WOBBUFFET); + OPPONENT (SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_SCRATCH, MOVE_FALSE_SWIPE, MOVE_SURF); Item(ITEM_KINGS_ROCK); } + } + WHEN { + TURN { SWITCH(opponent, 1); MOVE(player, MOVE_GRUDGE); } + TURN { MOVE(opponent, MOVE_FALSE_SWIPE); MOVE(player, MOVE_CELEBRATE); } + TURN { MOVE(opponent, MOVE_SCRATCH); MOVE(player, MOVE_CELEBRATE); SEND_OUT(player, 1); } + } + SCENE { + SEND_IN_MESSAGE("Wobbuffet"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_GRUDGE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FALSE_SWIPE, opponent); + MESSAGE("Wobbuffet flinched and couldn't move!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent); + MESSAGE("Wobbuffet fainted!"); + NOT MESSAGE("The opposing Wobbuffet's Scratch lost all its PP due to the grudge!"); + } + THEN { + EXPECT_GT(opponent->pp[0], 0); + EXPECT_GT(opponent->pp[1], 0); + EXPECT_GT(opponent->pp[2], 0); + EXPECT_GT(opponent->pp[3], 0); + } +} + +SINGLE_BATTLE_TEST("Grudge's effect doesn't trigger on indirect damage - Sandstorm") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_SANDSTORM) == EFFECT_SANDSTORM); + PLAYER (SPECIES_WOBBUFFET) { HP(1); } + PLAYER (SPECIES_WOBBUFFET); + OPPONENT (SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_SCRATCH, MOVE_SANDSTORM, MOVE_SURF); } + } + WHEN { + TURN { MOVE(player, MOVE_GRUDGE); MOVE(opponent, MOVE_SANDSTORM); SEND_OUT(player, 1); } + } + SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GRUDGE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SANDSTORM, opponent); + MESSAGE("The sandstorm is raging."); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SANDSTORM_CONTINUES); + MESSAGE("Wobbuffet is buffeted by the sandstorm!"); + MESSAGE("Wobbuffet fainted!"); + NOT MESSAGE("The opposing Wobbuffet's Sandstorm lost all its PP due to the grudge!"); + } + THEN { + EXPECT_GT(opponent->pp[0], 0); + EXPECT_GT(opponent->pp[1], 0); + EXPECT_GT(opponent->pp[2], 0); + EXPECT_GT(opponent->pp[3], 0); + } +} + +SINGLE_BATTLE_TEST("Grudge's effect doesn't trigger on indirect damage - Leech Seed") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_LEECH_SEED) == EFFECT_LEECH_SEED); + PLAYER (SPECIES_WOBBUFFET) { HP(1); } + PLAYER (SPECIES_WOBBUFFET); + OPPONENT (SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_SCRATCH, MOVE_LEECH_SEED, MOVE_SURF); } + } + WHEN { + TURN { MOVE(player, MOVE_GRUDGE); MOVE(opponent, MOVE_LEECH_SEED); SEND_OUT(player, 1); } + } + SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_GRUDGE, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_LEECH_SEED, opponent); + MESSAGE("Wobbuffet was seeded!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_LEECH_SEED_DRAIN, player); + MESSAGE("Wobbuffet fainted!"); + NOT MESSAGE("The opposing Wobbuffet's Leech Seed lost all its PP due to the grudge!"); + } + THEN { + EXPECT_GT(opponent->pp[0], 0); + EXPECT_GT(opponent->pp[1], 0); + EXPECT_GT(opponent->pp[2], 0); + EXPECT_GT(opponent->pp[3], 0); + } +} + +SINGLE_BATTLE_TEST("Grudge's effect doesn't trigger on indirect damage - Future Sight") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_FUTURE_SIGHT) == EFFECT_FUTURE_SIGHT); + PLAYER (SPECIES_WOBBUFFET) { HP(1); } + PLAYER (SPECIES_WOBBUFFET); + OPPONENT (SPECIES_WOBBUFFET) { Moves(MOVE_CELEBRATE, MOVE_SCRATCH, MOVE_FUTURE_SIGHT, MOVE_SURF); } + } + WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_FUTURE_SIGHT); } + TURN {} + TURN { MOVE(player, MOVE_GRUDGE); SEND_OUT(player, 1); } + } + SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_FUTURE_SIGHT, opponent); + MESSAGE("The opposing Wobbuffet foresaw an attack!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_GRUDGE, player); + MESSAGE("Wobbuffet took the Future Sight attack!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_FUTURE_SIGHT_HIT); + MESSAGE("Wobbuffet fainted!"); + NOT MESSAGE("The opposing Wobbuffet's Future Sight lost all its PP due to the grudge!"); + } + THEN { + EXPECT_GT(opponent->pp[0], 0); + EXPECT_GT(opponent->pp[1], 0); + EXPECT_GT(opponent->pp[2], 0); + EXPECT_GT(opponent->pp[3], 0); + } +} + diff --git a/test/battle/move_effect/instruct.c b/test/battle/move_effect/instruct.c index be6e557990..04f5558155 100644 --- a/test/battle/move_effect/instruct.c +++ b/test/battle/move_effect/instruct.c @@ -322,3 +322,28 @@ DOUBLE_BATTLE_TEST("Instructed move will be redirected by Rage Powder after inst HP_BAR(opponentLeft); } } + +DOUBLE_BATTLE_TEST("Instruct message references the correct battlers") +{ + GIVEN { + PLAYER(SPECIES_TREECKO); + PLAYER(SPECIES_SCEPTILE); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { + MOVE(playerLeft, MOVE_CELEBRATE); + MOVE(playerRight, MOVE_SCRATCH, target: opponentLeft); + MOVE(opponentLeft, MOVE_DRAGON_DARTS, target:playerLeft); + MOVE(opponentRight, MOVE_INSTRUCT, target: playerRight); + } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, playerRight); + MESSAGE("The opposing Wynaut used Instruct!"); + NONE_OF { + MESSAGE("Sceptile followed the opposing Wobbuffet's instructions!"); + } + MESSAGE("Sceptile followed the opposing Wynaut's instructions!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, playerRight); + } +} diff --git a/test/battle/move_effect/mimic.c b/test/battle/move_effect/mimic.c index 4a51a4b79e..6ea6e3f1f8 100644 --- a/test/battle/move_effect/mimic.c +++ b/test/battle/move_effect/mimic.c @@ -1,4 +1,20 @@ #include "global.h" #include "test/battle.h" +SINGLE_BATTLE_TEST("Mimic doesn't error when the last move used by the target resolves to MOVE_UNAVAILABLE") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN {MOVE(opponent, MOVE_TRANSFORM); MOVE(player, MOVE_MIMIC); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TRANSFORM, opponent); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_MIMIC, player); + } THEN { + EXPECT_EQ(gLastMoves[1], MOVE_UNAVAILABLE); // This test depends on the current implementation of Transform, if this changes, the test should be changed + } +} + TO_DO_BATTLE_TEST("TODO: Write Mimic (Move Effect) test titles") diff --git a/test/battle/move_effect/mud_sport.c b/test/battle/move_effect/mud_sport.c index ff483699b4..31e0ea18ff 100644 --- a/test/battle/move_effect/mud_sport.c +++ b/test/battle/move_effect/mud_sport.c @@ -3,11 +3,15 @@ TO_DO_BATTLE_TEST("TODO: Write Mud Sport (Move Effect) test titles") -SINGLE_BATTLE_TEST("Mud Sport reduces the damage of Electric Type moves by 67% (Gen5+)") +SINGLE_BATTLE_TEST("Mud Sport reduces the damage of Electric Type moves by 50% (Gen3-4) or 67% (Gen5+)") { + u32 config; s16 playerDmg[2]; s16 opponentDmg[2]; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_SPORT_DMG_REDUCTION, config); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -28,7 +32,13 @@ SINGLE_BATTLE_TEST("Mud Sport reduces the damage of Electric Type moves by 67% ( HP_BAR(player, captureDamage: &playerDmg[1]); } THEN { - EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.33), opponentDmg[1]); - EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.33), playerDmg[1]); + if (config >= GEN_5) { + EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.33), opponentDmg[1]); + EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.33), playerDmg[1]); + } + else { + EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.5), opponentDmg[1]); + EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.5), playerDmg[1]); + } } } diff --git a/test/battle/move_effect/tailwind.c b/test/battle/move_effect/tailwind.c index 9ed101301d..d22f36d285 100644 --- a/test/battle/move_effect/tailwind.c +++ b/test/battle/move_effect/tailwind.c @@ -6,10 +6,13 @@ ASSUMPTIONS ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND); } -SINGLE_BATTLE_TEST("Tailwind applies for 4 turns") +SINGLE_BATTLE_TEST("Tailwind applies for 3 turns (Gen4) or 4 turns (Gen5+)") { + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { - ASSUME(B_TAILWIND_TURNS >= GEN_5); + WITH_CONFIG(CONFIG_TAILWIND_TURNS, config); PLAYER(SPECIES_WOBBUFFET) { Speed(10); } OPPONENT(SPECIES_WOBBUFFET) { Speed(15); } } WHEN { @@ -28,8 +31,10 @@ SINGLE_BATTLE_TEST("Tailwind applies for 4 turns") MESSAGE("Wobbuffet used Celebrate!"); MESSAGE("The opposing Wobbuffet used Celebrate!"); - MESSAGE("Wobbuffet used Celebrate!"); - MESSAGE("The opposing Wobbuffet used Celebrate!"); + if (config >= GEN_5) { + MESSAGE("Wobbuffet used Celebrate!"); + MESSAGE("The opposing Wobbuffet used Celebrate!"); + } MESSAGE("The opposing Wobbuffet used Celebrate!"); MESSAGE("Wobbuffet used Celebrate!"); diff --git a/test/battle/move_effect/water_sport.c b/test/battle/move_effect/water_sport.c index cf4ec929c3..5cf52ed1c2 100644 --- a/test/battle/move_effect/water_sport.c +++ b/test/battle/move_effect/water_sport.c @@ -3,11 +3,15 @@ TO_DO_BATTLE_TEST("TODO: Write Water Sport (Move Effect) test titles") -SINGLE_BATTLE_TEST("Water Sport reduces the damage of Fire Type moves by 67% (Gen5+)") +SINGLE_BATTLE_TEST("Water Sport reduces the damage of Fire Type moves by 50% (Gen3-4) or 67% (Gen5+)") { + u32 config; s16 playerDmg[2]; s16 opponentDmg[2]; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_SPORT_DMG_REDUCTION, config); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -28,7 +32,13 @@ SINGLE_BATTLE_TEST("Water Sport reduces the damage of Fire Type moves by 67% (Ge HP_BAR(player, captureDamage: &playerDmg[1]); } THEN { - EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.33), opponentDmg[1]); - EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.33), playerDmg[1]); + if (config >= GEN_5) { + EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.33), opponentDmg[1]); + EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.33), playerDmg[1]); + } + else { + EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.5), opponentDmg[1]); + EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.5), playerDmg[1]); + } } } diff --git a/test/battle/move_effect_secondary/wrap.c b/test/battle/move_effect_secondary/wrap.c index dc05bbe288..2e430871fd 100644 --- a/test/battle/move_effect_secondary/wrap.c +++ b/test/battle/move_effect_secondary/wrap.c @@ -6,10 +6,14 @@ ASSUMPTIONS ASSUME(MoveHasAdditionalEffect(MOVE_WRAP, MOVE_EFFECT_WRAP)); } -SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 5 turns 50% of the time") +SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 5 turns 25% (Gen3-4) or 50% (Gen5+) of the time") { - PASSES_RANDOMLY(50, 100, RNG_WRAP); + u32 config, passes, trials; + PARAMETRIZE { config = GEN_4; passes = 25; trials = 100; } + PARAMETRIZE { config = GEN_5; passes = 50; trials = 100; } + PASSES_RANDOMLY(passes, trials, RNG_WRAP); GIVEN { + WITH_CONFIG(CONFIG_BINDING_TURNS, config); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -32,10 +36,14 @@ SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 5 turns 50% of the time" } } -SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 4 turns 50% of the time") +SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 4 turns 25% (Gen3-4) or 50% (Gen5+) of the time") { - PASSES_RANDOMLY(50, 100, RNG_WRAP); + u32 config, passes, trials; + PARAMETRIZE { config = GEN_4; passes = 25; trials = 100; } + PARAMETRIZE { config = GEN_5; passes = 50; trials = 100; } + PASSES_RANDOMLY(passes, trials, RNG_WRAP); GIVEN { + WITH_CONFIG(CONFIG_BINDING_TURNS, config); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -56,9 +64,13 @@ SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 4 turns 50% of the time" } } -SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon 7 turns while holding a Grip Claw") +SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon 5 turns (Gen4) or 7 turns (Gen5+) while holding a Grip Claw") { + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_BINDING_TURNS, config); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GRIP_CLAW); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -79,8 +91,10 @@ SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon 7 turns while holding a Grip HP_BAR(opponent); // Residual Damage HP_BAR(opponent); // Residual Damage HP_BAR(opponent); // Residual Damage - HP_BAR(opponent); // Residual Damage - HP_BAR(opponent); // Residual Damage + if (config >= GEN_5) { + HP_BAR(opponent); // Residual Damage + HP_BAR(opponent); // Residual Damage + } NOT HP_BAR(opponent); // Residual Damage } } diff --git a/test/battle/test_runner_features.c b/test/battle/test_runner_features.c index 2c6d73abcc..25a75f9ce5 100644 --- a/test/battle/test_runner_features.c +++ b/test/battle/test_runner_features.c @@ -80,3 +80,17 @@ SINGLE_BATTLE_TEST("Changing forms doesn't overwrite set stats (HP)") EXPECT_EQ(player->maxHP, 10); } } + +MULTI_BATTLE_TEST("Multi Battle Tests register partner's status1") +{ + GIVEN { + MULTI_PLAYER(SPECIES_WOBBUFFET); + MULTI_PARTNER(SPECIES_WOBBUFFET); + MULTI_OPPONENT_A(SPECIES_WOBBUFFET); + MULTI_OPPONENT_B(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(playerLeft, MOVE_WILL_O_WISP, target: playerRight); } + } SCENE { + STATUS_ICON(playerRight, STATUS1_BURN); + } +} diff --git a/test/battle/weather/strong_winds.c b/test/battle/weather/strong_winds.c index 26b0a51d0d..f319a7a229 100644 --- a/test/battle/weather/strong_winds.c +++ b/test/battle/weather/strong_winds.c @@ -1,17 +1,249 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("Strong winds remove Flying-type weaknesses of all battlers") // Electric, Ice, Rock -TO_DO_BATTLE_TEST("Strong winds remove Flying-type weaknesses of all battlers - Inverse Battle") // Bug, Fighting, Grass -TO_DO_BATTLE_TEST("Strong winds don't affect Stealth Rock's damage") -TO_DO_BATTLE_TEST("Strong winds makes Sunny Day fail") -TO_DO_BATTLE_TEST("Strong winds makes Rain Dance fail") -TO_DO_BATTLE_TEST("Strong winds makes Sandstorm fail") -TO_DO_BATTLE_TEST("Strong winds makes Hail fail") -TO_DO_BATTLE_TEST("Strong winds makes Snowscape fail") // Extrapolation -TO_DO_BATTLE_TEST("Strong winds makes Drought fail to activate") -TO_DO_BATTLE_TEST("Strong winds makes Drizzle fail to activate") -TO_DO_BATTLE_TEST("Strong winds makes Sand Stream fail to activate") -TO_DO_BATTLE_TEST("Strong winds makes Snow Warning fail to activate") -TO_DO_BATTLE_TEST("Strong winds can be replaced by Desolate Land") -TO_DO_BATTLE_TEST("Strong winds can be replaced by Primordial Sea") +DOUBLE_BATTLE_TEST("Strong winds remove Flying-type weaknesses of all battlers") // Electric, Ice, Rock +{ + u16 move; + bool32 targetPlayer; + + PARAMETRIZE { move = MOVE_THUNDER_SHOCK; targetPlayer = TRUE; } + PARAMETRIZE { move = MOVE_ICE_BEAM; targetPlayer = TRUE; } + PARAMETRIZE { move = MOVE_ROCK_THROW; targetPlayer = TRUE; } + PARAMETRIZE { move = MOVE_THUNDER_SHOCK; targetPlayer = FALSE; } + PARAMETRIZE { move = MOVE_ICE_BEAM; targetPlayer = FALSE; } + PARAMETRIZE { move = MOVE_ROCK_THROW; targetPlayer = FALSE; } + + GIVEN { + ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC); + ASSUME(GetMoveType(MOVE_ICE_BEAM) == TYPE_ICE); + ASSUME(GetMoveType(MOVE_ROCK_THROW) == TYPE_ROCK); + ASSUME(GetSpeciesType(SPECIES_PIDGEY, 0) == TYPE_NORMAL); + ASSUME(GetSpeciesType(SPECIES_PIDGEY, 1) == TYPE_FLYING); + PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + PLAYER(SPECIES_PIDGEY); + OPPONENT(SPECIES_PIDGEY); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + if (targetPlayer) + TURN { MOVE(opponentLeft, move, target: playerRight); } + else + TURN { MOVE(playerRight, move, target: opponentLeft); } + } SCENE { + if (targetPlayer) { + if (move == MOVE_THUNDER_SHOCK) + MESSAGE("The opposing Pidgey used Thunder Shock!"); + else if (move == MOVE_ICE_BEAM) + MESSAGE("The opposing Pidgey used Ice Beam!"); + else + MESSAGE("The opposing Pidgey used Rock Throw!"); + MESSAGE("The mysterious strong winds weakened the attack!"); + ANIMATION(ANIM_TYPE_MOVE, move, opponentLeft); + } else { + if (move == MOVE_THUNDER_SHOCK) + MESSAGE("Pidgey used Thunder Shock!"); + else if (move == MOVE_ICE_BEAM) + MESSAGE("Pidgey used Ice Beam!"); + else + MESSAGE("Pidgey used Rock Throw!"); + MESSAGE("The mysterious strong winds weakened the attack!"); + ANIMATION(ANIM_TYPE_MOVE, move, playerRight); + } + } +} + +DOUBLE_BATTLE_TEST("Strong winds remove Flying-type weaknesses of all battlers - Inverse Battle", s16 damagePlayer, s16 damageOpponent) // Bug, Fighting, Grass +{ + u16 move; + bool32 strongWinds; + + PARAMETRIZE { move = MOVE_BUG_BITE; strongWinds = FALSE; } + PARAMETRIZE { move = MOVE_BUG_BITE; strongWinds = TRUE; } + PARAMETRIZE { move = MOVE_KARATE_CHOP; strongWinds = FALSE; } + PARAMETRIZE { move = MOVE_KARATE_CHOP; strongWinds = TRUE; } + PARAMETRIZE { move = MOVE_VINE_WHIP; strongWinds = FALSE; } + PARAMETRIZE { move = MOVE_VINE_WHIP; strongWinds = TRUE; } + + GIVEN { + FLAG_SET(B_FLAG_INVERSE_BATTLE); + ASSUME(GetMoveType(MOVE_BUG_BITE) == TYPE_BUG); + ASSUME(GetMoveType(MOVE_KARATE_CHOP) == TYPE_FIGHTING); + ASSUME(GetMoveType(MOVE_VINE_WHIP) == TYPE_GRASS); + ASSUME(GetSpeciesType(SPECIES_TORNADUS, 0) == TYPE_FLYING); + ASSUME(GetSpeciesType(SPECIES_TORNADUS, 1) == TYPE_FLYING); + if (strongWinds) + PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + else + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_TORNADUS); + OPPONENT(SPECIES_TORNADUS); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { + MOVE(opponentLeft, move, target: playerRight); + MOVE(playerRight, move, target: opponentLeft); + } + } SCENE { + HP_BAR(playerRight, captureDamage: &results[i].damagePlayer); + HP_BAR(opponentLeft, captureDamage: &results[i].damageOpponent); + } FINALLY { + EXPECT_GT(results[0].damagePlayer, results[1].damagePlayer); + EXPECT_GT(results[0].damageOpponent, results[1].damageOpponent); + EXPECT_GT(results[2].damagePlayer, results[3].damagePlayer); + EXPECT_GT(results[2].damageOpponent, results[3].damageOpponent); + EXPECT_GT(results[4].damagePlayer, results[5].damagePlayer); + EXPECT_GT(results[4].damageOpponent, results[5].damageOpponent); + } +} + +SINGLE_BATTLE_TEST("Strong winds prevent Weakness Policy from activating on Flying-type weaknesses") +{ + GIVEN { + ASSUME(GetItemHoldEffect(ITEM_WEAKNESS_POLICY) == HOLD_EFFECT_WEAKNESS_POLICY); + ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC); + ASSUME(GetSpeciesType(SPECIES_PIDGEY, 0) == TYPE_NORMAL); + ASSUME(GetSpeciesType(SPECIES_PIDGEY, 1) == TYPE_FLYING); + PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); Moves(MOVE_THUNDER_SHOCK); } + OPPONENT(SPECIES_PIDGEY) { Item(ITEM_WEAKNESS_POLICY); } + } WHEN { + TURN { MOVE(player, MOVE_THUNDER_SHOCK); } + } SCENE { + MESSAGE("Rayquaza used Thunder Shock!"); + MESSAGE("The mysterious strong winds weakened the attack!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDER_SHOCK, player); + HP_BAR(opponent); + NOT ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, opponent); + } +} + +SINGLE_BATTLE_TEST("Anticipation still triggers with Strong Winds active") +{ + GIVEN { + ASSUME(GetMoveType(MOVE_THUNDER_SHOCK) == TYPE_ELECTRIC); + ASSUME(GetSpeciesType(SPECIES_PIDGEY, 0) == TYPE_NORMAL); + ASSUME(GetSpeciesType(SPECIES_PIDGEY, 1) == TYPE_FLYING); + PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); Moves(MOVE_THUNDER_SHOCK, MOVE_CELEBRATE); } + OPPONENT(SPECIES_PIDGEY) { Ability(ABILITY_ANTICIPATION); Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_ANTICIPATION); + MESSAGE("Rayquaza used Celebrate!"); + MESSAGE("The opposing Pidgey used Celebrate!"); + } +} + +SINGLE_BATTLE_TEST("Anticipation still triggers with Strong Winds active in Inverse Battle") +{ + GIVEN { + FLAG_SET(B_FLAG_INVERSE_BATTLE); + ASSUME(GetMoveType(MOVE_VINE_WHIP) == TYPE_GRASS); + ASSUME(GetSpeciesType(SPECIES_TORNADUS, 0) == TYPE_FLYING); + ASSUME(GetSpeciesType(SPECIES_TORNADUS, 1) == TYPE_FLYING); + PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); Moves(MOVE_VINE_WHIP, MOVE_CELEBRATE); } + OPPONENT(SPECIES_TORNADUS) { Ability(ABILITY_ANTICIPATION); Moves(MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_ANTICIPATION); + MESSAGE("Rayquaza used Celebrate!"); + MESSAGE("The opposing Tornadus used Celebrate!"); + } +} + +SINGLE_BATTLE_TEST("Strong winds don't affect Stealth Rock's damage") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_STEALTH_ROCK) == EFFECT_STEALTH_ROCK); + ASSUME(GetSpeciesType(SPECIES_PIDGEY, 0) == TYPE_NORMAL); + ASSUME(GetSpeciesType(SPECIES_PIDGEY, 1) == TYPE_FLYING); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_PIDGEY); + OPPONENT(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + } WHEN { + TURN { MOVE(opponent, MOVE_STEALTH_ROCK); } + TURN { SWITCH(player, 1); } + } SCENE { + s32 maxHP = GetMonData(&PLAYER_PARTY[1], MON_DATA_MAX_HP); + ANIMATION(ANIM_TYPE_MOVE, MOVE_STEALTH_ROCK, opponent); + HP_BAR(player, damage: maxHP / 4); + } +} + +SINGLE_BATTLE_TEST("Strong winds block weather-setting moves") +{ + u16 move; + PARAMETRIZE { move = MOVE_SUNNY_DAY; } + PARAMETRIZE { move = MOVE_RAIN_DANCE; } + PARAMETRIZE { move = MOVE_SANDSTORM; } + PARAMETRIZE { move = MOVE_HAIL; } + PARAMETRIZE { move = MOVE_SNOWSCAPE; } + + GIVEN { + ASSUME(GetMoveEffect(MOVE_SUNNY_DAY) == EFFECT_SUNNY_DAY); + ASSUME(GetMoveEffect(MOVE_RAIN_DANCE) == EFFECT_RAIN_DANCE); + ASSUME(GetMoveEffect(MOVE_SANDSTORM) == EFFECT_SANDSTORM); + ASSUME(GetMoveEffect(MOVE_HAIL) == EFFECT_HAIL); + ASSUME(GetMoveEffect(MOVE_SNOWSCAPE) == EFFECT_SNOWSCAPE); + PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, move); } + } SCENE { + NOT ANIMATION(ANIM_TYPE_MOVE, move, opponent); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_STRONG_WINDS); + } +} + +SINGLE_BATTLE_TEST("Strong winds prevent other weather abilities") +{ + u16 ability, species; + PARAMETRIZE { ability = ABILITY_DROUGHT; species = SPECIES_NINETALES; } + PARAMETRIZE { ability = ABILITY_DRIZZLE; species = SPECIES_POLITOED; } + PARAMETRIZE { ability = ABILITY_SAND_STREAM; species = SPECIES_HIPPOWDON; } + PARAMETRIZE { ability = ABILITY_SNOW_WARNING; species = SPECIES_ABOMASNOW; } + + GIVEN { + PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(species) { Ability(ability); } + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ability); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_STRONG_WINDS); + } +} + +SINGLE_BATTLE_TEST("Strong winds can be replaced by Desolate Land") +{ + GIVEN { + PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_GROUDON) { Item(ITEM_RED_ORB); } + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_DESOLATE_LAND); + MESSAGE("The sunlight turned extremely harsh!"); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_SUN_PRIMAL); + } +} + +SINGLE_BATTLE_TEST("Strong winds can be replaced by Primordial Sea") +{ + GIVEN { + PLAYER(SPECIES_RAYQUAZA) { Ability(ABILITY_DELTA_STREAM); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_KYOGRE) { Item(ITEM_BLUE_ORB); } + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_PRIMORDIAL_SEA); + MESSAGE("A heavy rain began to fall!"); + } THEN { + EXPECT(gBattleWeather & B_WEATHER_RAIN_PRIMAL); + } +} diff --git a/test/test_runner_battle.c b/test/test_runner_battle.c index 5331a7294b..1a9624df61 100644 --- a/test/test_runner_battle.c +++ b/test/test_runner_battle.c @@ -3376,9 +3376,9 @@ void ValidateFinally(u32 sourceLine) INVALID_IF(STATE->parametersCount == 0, "FINALLY without PARAMETRIZE"); } -u32 TestRunner_Battle_GetForcedAbility(u32 side, u32 partyIndex) +u32 TestRunner_Battle_GetForcedAbility(u32 array, u32 partyIndex) { - return DATA.forcedAbilities[side][partyIndex]; + return DATA.forcedAbilities[array][partyIndex]; } u32 TestRunner_Battle_GetForcedEnvironment(void) diff --git a/test/test_test_runner.c b/test/test_test_runner.c index 32742afb16..b94bdf1628 100644 --- a/test/test_test_runner.c +++ b/test/test_test_runner.c @@ -1,6 +1,7 @@ #include "global.h" #include "test/battle.h" #include "test/test.h" +#include "test/battle.h" TEST("Tests resume after CRASH") { @@ -9,6 +10,25 @@ TEST("Tests resume after CRASH") f(); } +MULTI_BATTLE_TEST("Forced Abilities are set correctly in multi battle tests") +{ + GIVEN { + MULTI_PLAYER(SPECIES_WOBBUFFET); + MULTI_PARTNER(SPECIES_WOBBUFFET); + MULTI_PARTNER(SPECIES_NINETALES_ALOLA) { Ability(ABILITY_DRIZZLE); } + MULTI_OPPONENT_A(SPECIES_WOBBUFFET); + MULTI_OPPONENT_A(SPECIES_NINETALES_ALOLA) { Ability(ABILITY_SAND_STREAM); } + MULTI_OPPONENT_B(SPECIES_WYNAUT); + MULTI_OPPONENT_B(SPECIES_NINETALES_ALOLA) { Ability(ABILITY_DROUGHT); } + } WHEN { + TURN { SWITCH(opponentLeft, 1); SWITCH(playerRight, 4); SWITCH(opponentRight, 4); } + } SCENE { + ABILITY_POPUP(opponentLeft, ABILITY_SAND_STREAM); + ABILITY_POPUP(playerRight, ABILITY_DRIZZLE); + ABILITY_POPUP(opponentRight, ABILITY_DROUGHT); + } +} + SINGLE_BATTLE_TEST("Substitute hits are detected by SUB_HIT") { GIVEN {