From c252e2256b3e23677162c25164d9b7d0c35a4ec2 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Tue, 2 Sep 2025 15:44:01 +0200 Subject: [PATCH 1/8] Fix Rage Fist test name (#7681) --- test/battle/move_effect/rage_fist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/battle/move_effect/rage_fist.c b/test/battle/move_effect/rage_fist.c index ba8fcecc06..ed21a9097c 100644 --- a/test/battle/move_effect/rage_fist.c +++ b/test/battle/move_effect/rage_fist.c @@ -343,7 +343,7 @@ SINGLE_BATTLE_TEST("Rage Fist doesn't get increased power if Substitute is hit") } } -SINGLE_BATTLE_TEST("Rage Fist - X") +SINGLE_BATTLE_TEST("Rage Fist counter will be updated correctly after absorb move") { s16 timesGotHit[2]; From f39fdf57cfe758ece0177efb3189dfb15602418a Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Tue, 2 Sep 2025 09:46:48 -0400 Subject: [PATCH 2/8] Fixed disabled cross-evolutions still being possible (#7678) --- .../pokemon/species_info/gen_1_families.h | 94 +++++++++++++++---- .../pokemon/species_info/gen_2_families.h | 30 +++++- .../pokemon/species_info/gen_3_families.h | 20 +++- .../pokemon/species_info/gen_5_families.h | 2 + .../pokemon/species_info/gen_8_families.h | 9 +- 5 files changed, 127 insertions(+), 28 deletions(-) diff --git a/src/data/pokemon/species_info/gen_1_families.h b/src/data/pokemon/species_info/gen_1_families.h index 70165414ba..1b0e94aa13 100644 --- a/src/data/pokemon/species_info/gen_1_families.h +++ b/src/data/pokemon/species_info/gen_1_families.h @@ -5730,7 +5730,9 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sGolbatLevelUpLearnset, .teachableLearnset = sGolbatTeachableLearnset, + #if P_GEN_2_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_CROBAT, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), + #endif }, #if P_GEN_2_CROSS_EVOS @@ -5979,8 +5981,11 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sGloomLevelUpLearnset, .teachableLearnset = sGloomTeachableLearnset, - .evolutions = EVOLUTION({EVO_ITEM, ITEM_LEAF_STONE, SPECIES_VILEPLUME}, - {EVO_ITEM, ITEM_SUN_STONE, SPECIES_BELLOSSOM}), + .evolutions = EVOLUTION({EVO_ITEM, ITEM_LEAF_STONE, SPECIES_VILEPLUME} + #if P_GEN_2_CROSS_EVOS + ,{EVO_ITEM, ITEM_SUN_STONE, SPECIES_BELLOSSOM} + #endif + ), }, [SPECIES_VILEPLUME] = @@ -7577,7 +7582,9 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sPrimeapeLevelUpLearnset, .teachableLearnset = sPrimeapeTeachableLearnset, + #if P_GEN_9_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_ANNIHILAPE, CONDITIONS({IF_USED_MOVE_X_TIMES, MOVE_RAGE_FIST, 20})}), + #endif }, #if P_GEN_9_CROSS_EVOS @@ -8064,9 +8071,12 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sPoliwhirlLevelUpLearnset, .teachableLearnset = sPoliwhirlTeachableLearnset, - .evolutions = EVOLUTION({EVO_ITEM, ITEM_WATER_STONE, SPECIES_POLIWRATH}, - {EVO_TRADE, 0, SPECIES_POLITOED, CONDITIONS({IF_HOLD_ITEM, ITEM_KINGS_ROCK})}, - {EVO_ITEM, ITEM_KINGS_ROCK, SPECIES_POLITOED}), + .evolutions = EVOLUTION({EVO_ITEM, ITEM_WATER_STONE, SPECIES_POLIWRATH} + #if P_GEN_2_CROSS_EVOS + ,{EVO_TRADE, 0, SPECIES_POLITOED, CONDITIONS({IF_HOLD_ITEM, ITEM_KINGS_ROCK})}, + {EVO_ITEM, ITEM_KINGS_ROCK, SPECIES_POLITOED} + #endif + ), }, [SPECIES_POLIWRATH] = @@ -10045,9 +10055,12 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .teachableLearnset = sSlowpokeTeachableLearnset, .eggMoveLearnset = sSlowpokeEggMoveLearnset, .formSpeciesIdTable = sSlowpokeFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_LEVEL, 37, SPECIES_SLOWBRO}, - {EVO_TRADE, 0, SPECIES_SLOWKING, CONDITIONS({IF_HOLD_ITEM, ITEM_KINGS_ROCK})}, - {EVO_ITEM, ITEM_KINGS_ROCK, SPECIES_SLOWKING}), + .evolutions = EVOLUTION({EVO_LEVEL, 37, SPECIES_SLOWBRO} + #if P_GEN_2_CROSS_EVOS + ,{EVO_TRADE, 0, SPECIES_SLOWKING, CONDITIONS({IF_HOLD_ITEM, ITEM_KINGS_ROCK})}, + {EVO_ITEM, ITEM_KINGS_ROCK, SPECIES_SLOWKING} + #endif + ), }, [SPECIES_SLOWBRO] = @@ -10326,8 +10339,11 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .teachableLearnset = sSlowpokeGalarTeachableLearnset, .eggMoveLearnset = sSlowpokeGalarEggMoveLearnset, .formSpeciesIdTable = sSlowpokeFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_ITEM, ITEM_GALARICA_CUFF, SPECIES_SLOWBRO_GALAR}, - {EVO_ITEM, ITEM_GALARICA_WREATH, SPECIES_SLOWKING_GALAR}), + .evolutions = EVOLUTION({EVO_ITEM, ITEM_GALARICA_CUFF, SPECIES_SLOWBRO_GALAR} + #if P_GEN_2_CROSS_EVOS + ,{EVO_ITEM, ITEM_GALARICA_WREATH, SPECIES_SLOWKING_GALAR} + #endif + ), }, [SPECIES_SLOWBRO_GALAR] = @@ -10609,8 +10625,10 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sMagnetonLevelUpLearnset, .teachableLearnset = sMagnetonTeachableLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_MAGNEZONE, CONDITIONS({IF_IN_MAPSEC, MAPSEC_NEW_MAUVILLE})}, {EVO_ITEM, ITEM_THUNDER_STONE, SPECIES_MAGNEZONE}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -12107,8 +12125,10 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sOnixLevelUpLearnset, .teachableLearnset = sOnixTeachableLearnset, .eggMoveLearnset = sOnixEggMoveLearnset, + #if P_GEN_2_CROSS_EVOS .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_STEELIX, CONDITIONS({IF_HOLD_ITEM, ITEM_METAL_COAT})}, {EVO_ITEM, ITEM_METAL_COAT, SPECIES_STEELIX}), + #endif }, #if P_GEN_2_CROSS_EVOS @@ -13805,7 +13825,9 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sLickitungLevelUpLearnset, .teachableLearnset = sLickitungTeachableLearnset, .eggMoveLearnset = sLickitungEggMoveLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_LICKILICKY, CONDITIONS({IF_KNOWS_MOVE, MOVE_ROLLOUT})}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -14274,8 +14296,10 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sRhydonLevelUpLearnset, .teachableLearnset = sRhydonTeachableLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_RHYPERIOR, CONDITIONS({IF_HOLD_ITEM, ITEM_PROTECTOR})}, {EVO_ITEM, ITEM_PROTECTOR, SPECIES_RHYPERIOR}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -14510,7 +14534,9 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sChanseyLevelUpLearnset, .teachableLearnset = sChanseyTeachableLearnset, .eggMoveLearnset = sChanseyEggMoveLearnset, + #if P_GEN_2_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_BLISSEY, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD})}), + #endif }, #if P_GEN_2_CROSS_EVOS @@ -14655,7 +14681,9 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sTangelaLevelUpLearnset, .teachableLearnset = sTangelaTeachableLearnset, .eggMoveLearnset = sTangelaEggMoveLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_TANGROWTH, CONDITIONS({IF_KNOWS_MOVE, MOVE_ANCIENT_POWER})}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -15037,8 +15065,10 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sSeadraLevelUpLearnset, .teachableLearnset = sSeadraTeachableLearnset, + #if P_GEN_2_CROSS_EVOS .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_KINGDRA, CONDITIONS({IF_HOLD_ITEM, ITEM_DRAGON_SCALE})}, {EVO_ITEM, ITEM_DRAGON_SCALE, SPECIES_KINGDRA}), + #endif }, #if P_GEN_2_CROSS_EVOS @@ -15826,9 +15856,20 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .levelUpLearnset = sScytherLevelUpLearnset, .teachableLearnset = sScytherTeachableLearnset, .eggMoveLearnset = sScytherEggMoveLearnset, - .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_SCIZOR, CONDITIONS({IF_HOLD_ITEM, ITEM_METAL_COAT})}, - {EVO_ITEM, ITEM_BLACK_AUGURITE, SPECIES_KLEAVOR}, - {EVO_ITEM, ITEM_METAL_COAT, SPECIES_SCIZOR}), + #if P_GEN_2_CROSS_EVOS || P_GEN_8_CROSS_EVOS + .evolutions = EVOLUTION( + #if P_GEN_2_CROSS_EVOS + {EVO_TRADE, 0, SPECIES_SCIZOR, CONDITIONS({IF_HOLD_ITEM, ITEM_METAL_COAT})}, + {EVO_ITEM, ITEM_METAL_COAT, SPECIES_SCIZOR} + #if P_GEN_8_CROSS_EVOS + , + #endif + #endif + #if P_GEN_8_CROSS_EVOS + {EVO_ITEM, ITEM_BLACK_AUGURITE, SPECIES_KLEAVOR} + #endif + ), + #endif }, #if P_GEN_2_CROSS_EVOS @@ -16346,8 +16387,10 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sElectabuzzLevelUpLearnset, .teachableLearnset = sElectabuzzTeachableLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_ELECTIVIRE, CONDITIONS({IF_HOLD_ITEM, ITEM_ELECTIRIZER})}, {EVO_ITEM, ITEM_ELECTIRIZER, SPECIES_ELECTIVIRE}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -16567,8 +16610,10 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sMagmarLevelUpLearnset, .teachableLearnset = sMagmarTeachableLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_MAGMORTAR, CONDITIONS({IF_HOLD_ITEM, ITEM_MAGMARIZER})}, {EVO_ITEM, ITEM_MAGMARIZER, SPECIES_MAGMORTAR}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -17609,14 +17654,21 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = .formChangeTable = sEeveeFormChangeTable, .evolutions = EVOLUTION({EVO_ITEM, ITEM_THUNDER_STONE, SPECIES_JOLTEON}, {EVO_ITEM, ITEM_WATER_STONE, SPECIES_VAPOREON}, - {EVO_ITEM, ITEM_FIRE_STONE, SPECIES_FLAREON}, - {EVO_LEVEL, 0, SPECIES_SYLVEON, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_KNOWS_MOVE_TYPE, TYPE_FAIRY})}, - {EVO_LEVEL, 0, SPECIES_ESPEON, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_NOT_TIME, TIME_NIGHT})}, - {EVO_LEVEL, 0, SPECIES_UMBREON, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_TIME, TIME_NIGHT})}, - {EVO_LEVEL, 0, SPECIES_LEAFEON, CONDITIONS({IF_IN_MAP, MAP_PETALBURG_WOODS})}, + {EVO_ITEM, ITEM_FIRE_STONE, SPECIES_FLAREON} + #if P_GEN_6_CROSS_EVOS + ,{EVO_LEVEL, 0, SPECIES_SYLVEON, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_KNOWS_MOVE_TYPE, TYPE_FAIRY})} + #endif + #if P_GEN_2_CROSS_EVOS + ,{EVO_LEVEL, 0, SPECIES_ESPEON, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_NOT_TIME, TIME_NIGHT})}, + {EVO_LEVEL, 0, SPECIES_UMBREON, CONDITIONS({IF_MIN_FRIENDSHIP, FRIENDSHIP_EVO_THRESHOLD}, {IF_TIME, TIME_NIGHT})} + #endif + #if P_GEN_4_CROSS_EVOS + ,{EVO_LEVEL, 0, SPECIES_LEAFEON, CONDITIONS({IF_IN_MAP, MAP_PETALBURG_WOODS})}, {EVO_ITEM, ITEM_LEAF_STONE, SPECIES_LEAFEON}, {EVO_LEVEL, 0, SPECIES_GLACEON, CONDITIONS({IF_IN_MAP, MAP_SHOAL_CAVE_LOW_TIDE_ICE_ROOM})}, - {EVO_ITEM, ITEM_ICE_STONE, SPECIES_GLACEON}), + {EVO_ITEM, ITEM_ICE_STONE, SPECIES_GLACEON} + #endif + ), }, #if P_GIGANTAMAX_FORMS @@ -18366,8 +18418,10 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sPorygonLevelUpLearnset, .teachableLearnset = sPorygonTeachableLearnset, + #if P_GEN_2_CROSS_EVOS .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_PORYGON2, CONDITIONS({IF_HOLD_ITEM, ITEM_UPGRADE})}, {EVO_ITEM, ITEM_UPGRADE, SPECIES_PORYGON2}), + #endif }, #if P_GEN_2_CROSS_EVOS @@ -18443,8 +18497,10 @@ const struct SpeciesInfo gSpeciesInfoGen1[] = ) .levelUpLearnset = sPorygon2LevelUpLearnset, .teachableLearnset = sPorygon2TeachableLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_PORYGON_Z, CONDITIONS({IF_HOLD_ITEM, ITEM_DUBIOUS_DISC})}, {EVO_ITEM, ITEM_DUBIOUS_DISC, SPECIES_PORYGON_Z}), + #endif }, #if P_GEN_4_CROSS_EVOS diff --git a/src/data/pokemon/species_info/gen_2_families.h b/src/data/pokemon/species_info/gen_2_families.h index c8143d02f0..f95197332a 100644 --- a/src/data/pokemon/species_info/gen_2_families.h +++ b/src/data/pokemon/species_info/gen_2_families.h @@ -1619,7 +1619,9 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = ) .levelUpLearnset = sTogeticLevelUpLearnset, .teachableLearnset = sTogeticTeachableLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_ITEM, ITEM_SHINY_STONE, SPECIES_TOGEKISS}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -2868,7 +2870,9 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sAipomLevelUpLearnset, .teachableLearnset = sAipomTeachableLearnset, .eggMoveLearnset = sAipomEggMoveLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_AMBIPOM, CONDITIONS({IF_KNOWS_MOVE, MOVE_DOUBLE_HIT})}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -3191,7 +3195,9 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sYanmaLevelUpLearnset, .teachableLearnset = sYanmaTeachableLearnset, .eggMoveLearnset = sYanmaEggMoveLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_YANMEGA, CONDITIONS({IF_KNOWS_MOVE, MOVE_ANCIENT_POWER})}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -3669,7 +3675,9 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sMurkrowLevelUpLearnset, .teachableLearnset = sMurkrowTeachableLearnset, .eggMoveLearnset = sMurkrowEggMoveLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_ITEM, ITEM_DUSK_STONE, SPECIES_HONCHKROW}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -3819,7 +3827,9 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sMisdreavusLevelUpLearnset, .teachableLearnset = sMisdreavusTeachableLearnset, .eggMoveLearnset = sMisdreavusEggMoveLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_ITEM, ITEM_DUSK_STONE, SPECIES_MISMAGIUS}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -4239,7 +4249,9 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sGirafarigLevelUpLearnset, .teachableLearnset = sGirafarigTeachableLearnset, .eggMoveLearnset = sGirafarigEggMoveLearnset, + #if P_GEN_9_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_FARIGIRAF, CONDITIONS({IF_KNOWS_MOVE, MOVE_TWIN_BEAM})}), + #endif }, #if P_GEN_9_CROSS_EVOS @@ -4527,8 +4539,10 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sDunsparceLevelUpLearnset, .teachableLearnset = sDunsparceTeachableLearnset, .eggMoveLearnset = sDunsparceEggMoveLearnset, + #if P_GEN_9_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_DUDUNSPARCE_TWO_SEGMENT, CONDITIONS({IF_KNOWS_MOVE, MOVE_HYPER_DRILL}, {IF_PID_MODULO_100_GT, 0})}, {EVO_LEVEL, 0, SPECIES_DUDUNSPARCE_THREE_SEGMENT, CONDITIONS({IF_KNOWS_MOVE, MOVE_HYPER_DRILL}, {IF_PID_MODULO_100_EQ, 0})}), + #endif }, #if P_GEN_9_CROSS_EVOS @@ -4742,8 +4756,10 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sGligarLevelUpLearnset, .teachableLearnset = sGligarTeachableLearnset, .eggMoveLearnset = sGligarEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_GLISCOR, CONDITIONS({IF_TIME, TIME_NIGHT}, {IF_HOLD_ITEM, ITEM_RAZOR_FANG})}, + #if P_GEN_4_CROSS_EVOS + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_GLISCOR, CONDITIONS({IF_TIME, TIME_NIGHT}, {IF_HOLD_ITEM, ITEM_RAZOR_FANG})}, {EVO_ITEM, ITEM_RAZOR_FANG, SPECIES_GLISCOR, CONDITIONS({IF_TIME, TIME_NIGHT})}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -5506,8 +5522,10 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .teachableLearnset = sSneaselTeachableLearnset, .eggMoveLearnset = sSneaselEggMoveLearnset, .formSpeciesIdTable = sSneaselFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_WEAVILE, CONDITIONS({IF_TIME, TIME_NIGHT}, {IF_HOLD_ITEM, ITEM_RAZOR_CLAW})}, + #if P_GEN_4_CROSS_EVOS + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_WEAVILE, CONDITIONS({IF_TIME, TIME_NIGHT}, {IF_HOLD_ITEM, ITEM_RAZOR_CLAW})}, {EVO_ITEM, ITEM_RAZOR_CLAW, SPECIES_WEAVILE, CONDITIONS({IF_TIME, TIME_NIGHT})}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -5672,7 +5690,7 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sSneaselHisuiLevelUpLearnset, .teachableLearnset = sSneaselHisuiTeachableLearnset, .formSpeciesIdTable = sSneaselFormSpeciesIdTable, - .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_SNEASLER, CONDITIONS({IF_NOT_TIME, TIME_NIGHT}, {IF_HOLD_ITEM, ITEM_RAZOR_CLAW})}, + .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_SNEASLER, CONDITIONS({IF_NOT_TIME, TIME_NIGHT}, {IF_HOLD_ITEM, ITEM_RAZOR_CLAW})}, {EVO_ITEM, ITEM_RAZOR_CLAW, SPECIES_SNEASLER, CONDITIONS({IF_NOT_TIME, TIME_NIGHT})}), }, @@ -5897,8 +5915,10 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = ) .levelUpLearnset = sUrsaringLevelUpLearnset, .teachableLearnset = sUrsaringTeachableLearnset, + #if P_GEN_8_CROSS_EVOS .evolutions = EVOLUTION({EVO_ITEM, ITEM_PEAT_BLOCK, SPECIES_URSALUNA, CONDITIONS({IF_TIME, TIME_NIGHT})}, {EVO_NONE, 0, SPECIES_URSALUNA_BLOODMOON}), + #endif }, #if P_GEN_8_CROSS_EVOS @@ -6330,7 +6350,9 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = ) .levelUpLearnset = sPiloswineLevelUpLearnset, .teachableLearnset = sPiloswineTeachableLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_MAMOSWINE, CONDITIONS({IF_KNOWS_MOVE, MOVE_ANCIENT_POWER})}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -7534,7 +7556,9 @@ const struct SpeciesInfo gSpeciesInfoGen2[] = .levelUpLearnset = sStantlerLevelUpLearnset, .teachableLearnset = sStantlerTeachableLearnset, .eggMoveLearnset = sStantlerEggMoveLearnset, + #if P_GEN_8_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_WYRDEER, CONDITIONS({IF_USED_MOVE_X_TIMES, MOVE_PSYSHIELD_BASH, 20})}), + #endif }, #if P_GEN_8_CROSS_EVOS diff --git a/src/data/pokemon/species_info/gen_3_families.h b/src/data/pokemon/species_info/gen_3_families.h index 272c57668e..6ad30646cf 100644 --- a/src/data/pokemon/species_info/gen_3_families.h +++ b/src/data/pokemon/species_info/gen_3_families.h @@ -2801,8 +2801,11 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = ) .levelUpLearnset = sKirliaLevelUpLearnset, .teachableLearnset = sKirliaTeachableLearnset, - .evolutions = EVOLUTION({EVO_LEVEL, 30, SPECIES_GARDEVOIR}, - {EVO_ITEM, ITEM_DAWN_STONE, SPECIES_GALLADE, CONDITIONS({IF_GENDER, MON_MALE})}), + .evolutions = EVOLUTION({EVO_LEVEL, 30, SPECIES_GARDEVOIR} + #if P_GEN_4_CROSS_EVOS + ,{EVO_ITEM, ITEM_DAWN_STONE, SPECIES_GALLADE, CONDITIONS({IF_GENDER, MON_MALE})} + #endif + ), }, [SPECIES_GARDEVOIR] = @@ -4314,8 +4317,10 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .levelUpLearnset = sNosepassLevelUpLearnset, .teachableLearnset = sNosepassTeachableLearnset, .eggMoveLearnset = sNosepassEggMoveLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_PROBOPASS, CONDITIONS({IF_IN_MAPSEC, MAPSEC_NEW_MAUVILLE})}, {EVO_ITEM, ITEM_THUNDER_STONE, SPECIES_PROBOPASS}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -6069,7 +6074,9 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .levelUpLearnset = sRoseliaLevelUpLearnset, .teachableLearnset = sRoseliaTeachableLearnset, .eggMoveLearnset = sRoseliaEggMoveLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_ITEM, ITEM_SHINY_STONE, SPECIES_ROSERADE}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -9900,8 +9907,10 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = ) .levelUpLearnset = sDusclopsLevelUpLearnset, .teachableLearnset = sDusclopsTeachableLearnset, + #if P_GEN_4_CROSS_EVOS .evolutions = EVOLUTION({EVO_TRADE, 0, SPECIES_DUSKNOIR, CONDITIONS({IF_HOLD_ITEM, ITEM_REAPER_CLOTH})}, {EVO_ITEM, ITEM_REAPER_CLOTH, SPECIES_DUSKNOIR}), + #endif }, #if P_GEN_4_CROSS_EVOS @@ -10459,8 +10468,11 @@ const struct SpeciesInfo gSpeciesInfoGen3[] = .levelUpLearnset = sSnoruntLevelUpLearnset, .teachableLearnset = sSnoruntTeachableLearnset, .eggMoveLearnset = sSnoruntEggMoveLearnset, - .evolutions = EVOLUTION({EVO_LEVEL, 42, SPECIES_GLALIE}, - {EVO_ITEM, ITEM_DAWN_STONE, SPECIES_FROSLASS, CONDITIONS({IF_GENDER, MON_FEMALE})}), + .evolutions = EVOLUTION({EVO_LEVEL, 42, SPECIES_GLALIE} + #if P_GEN_4_CROSS_EVOS + ,{EVO_ITEM, ITEM_DAWN_STONE, SPECIES_FROSLASS, CONDITIONS({IF_GENDER, MON_FEMALE})} + #endif + ), }, [SPECIES_GLALIE] = diff --git a/src/data/pokemon/species_info/gen_5_families.h b/src/data/pokemon/species_info/gen_5_families.h index 9e906e8f85..6b46006a58 100644 --- a/src/data/pokemon/species_info/gen_5_families.h +++ b/src/data/pokemon/species_info/gen_5_families.h @@ -11107,7 +11107,9 @@ const struct SpeciesInfo gSpeciesInfoGen5[] = ) .levelUpLearnset = sBisharpLevelUpLearnset, .teachableLearnset = sBisharpTeachableLearnset, + #if P_GEN_9_CROSS_EVOS .evolutions = EVOLUTION({EVO_LEVEL, 0, SPECIES_KINGAMBIT, CONDITIONS({IF_DEFEAT_X_WITH_ITEMS, SPECIES_BISHARP, ITEM_LEADERS_CREST, 3})}), + #endif }, #if P_GEN_9_CROSS_EVOS diff --git a/src/data/pokemon/species_info/gen_8_families.h b/src/data/pokemon/species_info/gen_8_families.h index 8495287bf7..6ba7fed676 100644 --- a/src/data/pokemon/species_info/gen_8_families.h +++ b/src/data/pokemon/species_info/gen_8_families.h @@ -2466,8 +2466,11 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = .teachableLearnset = sApplinTeachableLearnset, .eggMoveLearnset = sApplinEggMoveLearnset, .evolutions = EVOLUTION({EVO_ITEM, ITEM_TART_APPLE, SPECIES_FLAPPLE}, - {EVO_ITEM, ITEM_SWEET_APPLE, SPECIES_APPLETUN}, - {EVO_ITEM, ITEM_SYRUPY_APPLE, SPECIES_DIPPLIN}), + {EVO_ITEM, ITEM_SWEET_APPLE, SPECIES_APPLETUN} + #if P_GEN_9_CROSS_EVOS + ,{EVO_ITEM, ITEM_SYRUPY_APPLE, SPECIES_DIPPLIN} + #endif + ), }, [SPECIES_FLAPPLE] = @@ -6405,7 +6408,9 @@ const struct SpeciesInfo gSpeciesInfoGen8[] = .eggMoveLearnset = sDuraludonEggMoveLearnset, .formSpeciesIdTable = sDuraludonFormSpeciesIdTable, .formChangeTable = sDuraludonFormChangeTable, + #if P_GEN_9_CROSS_EVOS .evolutions = EVOLUTION({EVO_ITEM, ITEM_METAL_ALLOY, SPECIES_ARCHALUDON}), + #endif }, #if P_GIGANTAMAX_FORMS From c1b1fb4cdc19bc7b6bb685229074020a86f6ef55 Mon Sep 17 00:00:00 2001 From: Hedara Date: Tue, 2 Sep 2025 16:17:05 +0200 Subject: [PATCH 3/8] 1.13.1 Release version --- .../ISSUE_TEMPLATE/01_battle_engine_bugs.yaml | 3 +- .../ISSUE_TEMPLATE/02_battle_ai_issues.yaml | 3 +- .github/ISSUE_TEMPLATE/04_other_errors.yaml | 3 +- README.md | 2 +- docs/SUMMARY.md | 1 + docs/changelogs/1.13.x/1.13.1.md | 44 +++++++++++++++++++ include/constants/expansion.h | 4 +- 7 files changed, 54 insertions(+), 6 deletions(-) create mode 100644 docs/changelogs/1.13.x/1.13.1.md diff --git a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml index 0d323435b4..a06bfb5247 100644 --- a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml +++ b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml @@ -43,9 +43,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using? options: - - 1.13.0 (Latest release) + - 1.13.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.13.0 - 1.12.3 - 1.12.2 - 1.12.1 diff --git a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml index a00d5f4d2c..505cd5e6c4 100644 --- a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml +++ b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml @@ -43,9 +43,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using? options: - - 1.13.0 (Latest release) + - 1.13.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.13.0 - 1.12.3 - 1.12.2 - 1.12.1 diff --git a/.github/ISSUE_TEMPLATE/04_other_errors.yaml b/.github/ISSUE_TEMPLATE/04_other_errors.yaml index 53bf274899..4abed5dbb5 100644 --- a/.github/ISSUE_TEMPLATE/04_other_errors.yaml +++ b/.github/ISSUE_TEMPLATE/04_other_errors.yaml @@ -43,9 +43,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using? options: - - 1.13.0 (Latest release) + - 1.13.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.13.0 - 1.12.3 - 1.12.2 - 1.12.1 diff --git a/README.md b/README.md index 93c6b3a913..21de8f622d 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ If you use **`pokeemerald-expansion`**, please credit **RHH (Rom Hacking Hideout)**. Optionally, include the version number for clarity. ``` -Based off RHH's pokeemerald-expansion 1.13.0 https://github.com/rh-hideout/pokeemerald-expansion/ +Based off RHH's pokeemerald-expansion 1.13.1 https://github.com/rh-hideout/pokeemerald-expansion/ ``` Please consider [crediting all contributors](CREDITS.md) involved in the project! diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 667fcce2a4..8fd400844d 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -20,6 +20,7 @@ - [Day/Night System FAQ](tutorials/dns.md) - [Changelog](./CHANGELOG.md) - [1.13.x]() + - [Version 1.13.1](changelogs/1.13.x/1.13.1.md) - [Version 1.13.0](changelogs/1.13.x/1.13.0.md) - [1.12.x]() - [Version 1.12.3](changelogs/1.12.x/1.12.3.md) diff --git a/docs/changelogs/1.13.x/1.13.1.md b/docs/changelogs/1.13.x/1.13.1.md new file mode 100644 index 0000000000..97b33e931d --- /dev/null +++ b/docs/changelogs/1.13.x/1.13.1.md @@ -0,0 +1,44 @@ +```md +## How to update +- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`. +- Once you have your remote set up, run the command `git pull RHH expansion/1.13.1 +`. +``` + + +## 🧬 General 🧬 +### Fixed +* Added sortType to Douse Drive by @fdeblasio in [#7664](https://github.com/rh-hideout/pokeemerald-expansion/pull/7664) + +## 🐉 Pokémon 🐉 +### Fixed +* Fixed disabled cross-evolutions still being possible by @AsparagusEduardo in [#7678](https://github.com/rh-hideout/pokeemerald-expansion/pull/7678) + +## ⚔️ Battle General ⚔️ +### Changed +* Replace boolean multiplications with ternaries by @hedara90 in [#7653](https://github.com/rh-hideout/pokeemerald-expansion/pull/7653) + +## 🤖 Battle AI 🤖 +### Fixed +* Helping Hand bugfix; used FOE instead of BATTLE_OPPOSITE. by @surskitty in [#7659](https://github.com/rh-hideout/pokeemerald-expansion/pull/7659) + +## 🧹 Other Cleanup 🧹 +* Replace boolean multiplications with ternaries by @hedara90 in [#7653](https://github.com/rh-hideout/pokeemerald-expansion/pull/7653) +* Fix Rage Fist test name by @AlexOn1ine in [#7681](https://github.com/rh-hideout/pokeemerald-expansion/pull/7681) + +## 🧪 Test Runner 🧪 +### Changed +* Fix Rage Fist test name by @AlexOn1ine in [#7681](https://github.com/rh-hideout/pokeemerald-expansion/pull/7681) + +### Fixed +* Fix crashing tests duplicating tests from another thread by @hedara90 in [#7683](https://github.com/rh-hideout/pokeemerald-expansion/pull/7683) + +## 📚 Documentation 📚 +* Update README.md by @Bassoonian in [#7639](https://github.com/rh-hideout/pokeemerald-expansion/pull/7639) + + +**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.13.0...expansion/1.13.1 + + + + diff --git a/include/constants/expansion.h b/include/constants/expansion.h index e4468a82b4..27845d8e5e 100644 --- a/include/constants/expansion.h +++ b/include/constants/expansion.h @@ -1,13 +1,13 @@ #ifndef GUARD_CONSTANTS_EXPANSION_H #define GUARD_CONSTANTS_EXPANSION_H -// Last version: 1.13.0 +// Last version: 1.13.1 #define EXPANSION_VERSION_MAJOR 1 #define EXPANSION_VERSION_MINOR 13 #define EXPANSION_VERSION_PATCH 1 // FALSE if this this version of Expansion is not a tagged commit, i.e. // it contains unreleased changes. -#define EXPANSION_TAGGED_RELEASE FALSE +#define EXPANSION_TAGGED_RELEASE TRUE #endif From ef001df00689196ec2e141fdb4ae69b22726c84f Mon Sep 17 00:00:00 2001 From: Hedara Date: Tue, 2 Sep 2025 16:18:32 +0200 Subject: [PATCH 4/8] Start of 1.13.2 cycle --- include/constants/expansion.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/constants/expansion.h b/include/constants/expansion.h index 27845d8e5e..02234f603c 100644 --- a/include/constants/expansion.h +++ b/include/constants/expansion.h @@ -4,10 +4,10 @@ // Last version: 1.13.1 #define EXPANSION_VERSION_MAJOR 1 #define EXPANSION_VERSION_MINOR 13 -#define EXPANSION_VERSION_PATCH 1 +#define EXPANSION_VERSION_PATCH 2 // FALSE if this this version of Expansion is not a tagged commit, i.e. // it contains unreleased changes. -#define EXPANSION_TAGGED_RELEASE TRUE +#define EXPANSION_TAGGED_RELEASE FALSE #endif From 1e6a533131b97e20bb06c7541d1732db6e954a74 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 3 Sep 2025 13:23:23 -0400 Subject: [PATCH 5/8] Fix most failed tests with `GEN_LATEST` = `GEN_7` (#7688) --- asm/macros/battle_script.inc | 7 ++++ data/battle_scripts_1.s | 23 +++++++------ include/constants/generational_changes.h | 5 +++ include/generational_changes.h | 5 +++ src/battle_ai_util.c | 2 +- src/battle_script_commands.c | 17 +++++++--- src/battle_util.c | 6 ++-- test/battle/ability/disguise.c | 21 +++++++++++- test/battle/ability/inner_focus.c | 33 ++++++++++++++++-- test/battle/ability/oblivious.c | 24 +++++++++++-- test/battle/ability/own_tempo.c | 22 ++++++++++-- test/battle/ability/rattled.c | 24 +++++++++++-- test/battle/ability/scrappy.c | 34 +++++++++++++++++-- test/battle/ability/sheer_force.c | 3 +- test/battle/ability/shield_dust.c | 6 ++-- test/battle/ai/ai_calc_best_move_score.c | 9 +++-- test/battle/ai/ai_switching.c | 3 +- test/battle/hold_effect/covert_cloak.c | 6 ++-- test/battle/move_effect/after_you.c | 27 ++++++++++++++- test/battle/move_effect/attack_up_user_ally.c | 9 +++-- test/battle/move_effect/healing_wish.c | 26 +++++++++++--- test/battle/move_effect/pursuit.c | 1 + test/battle/move_effect/quash.c | 4 +-- test/battle/move_effect/rage_fist.c | 31 ++++++++++++++++- test/battle/move_effect/tailwind.c | 22 ++++++++++-- test/battle/move_effect/teleport.c | 29 ++++++++++++++-- 26 files changed, 339 insertions(+), 60 deletions(-) diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index 4a332f5b43..a689c8a94d 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -2524,3 +2524,10 @@ callnative BS_TryBoosterEnergy .byte \onFieldStatus .endm + + .macro jumpifgenconfiglowerthan tag:req, gen:req, jumpInstr:req + callnative BS_JumpIfGenConfigLowerThan + .2byte \tag + .byte \gen + .4byte \jumpInstr + .endm diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index f066f52ae8..8851a6a8c7 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -14,6 +14,7 @@ #include "constants/game_stat.h" #include "constants/trainers.h" #include "constants/species.h" +#include "constants/generational_changes.h" .include "asm/macros.inc" .include "asm/macros/battle_script.inc" .include "constants/constants.inc" @@ -2278,7 +2279,11 @@ BattleScript_EffectHealingWish:: setatkhptozero tryfaintmon BS_ATTACKER storehealingwish BS_ATTACKER -.if B_HEALING_WISH_SWITCH <= GEN_4 + jumpifgenconfiglowerthan GEN_CONFIG_HEALING_WISH_SWITCH, GEN_5, BattleScript_EffectHealingWishGen4 +BattleScript_EffectHealingWishEnd: + moveendall + end +BattleScript_EffectHealingWishGen4: openpartyscreen BS_ATTACKER, BattleScript_EffectHealingWishEnd waitstate switchhandleorder BS_ATTACKER, 2 @@ -2292,10 +2297,7 @@ BattleScript_EffectHealingWish:: switchinanim BS_ATTACKER, FALSE, TRUE waitstate switchineffects BS_ATTACKER -.endif -BattleScript_EffectHealingWishEnd: - moveendall - end + goto BattleScript_EffectHealingWishEnd BattleScript_HealingWishActivates:: setbyte cMULTISTRING_CHOOSER, 0 @@ -4222,12 +4224,13 @@ BattleScript_EffectFutureSight:: goto BattleScript_MoveEnd BattleScript_EffectTeleport:: -.if B_TELEPORT_BEHAVIOR >= GEN_8 + jumpifgenconfiglowerthan GEN_CONFIG_TELEPORT_BEHAVIOR, GEN_8, BattleScript_EffectTeleportGen7 jumpifbattletype BATTLE_TYPE_TRAINER, BattleScript_EffectBatonPass jumpifside BS_ATTACKER, B_SIDE_PLAYER, BattleScript_EffectBatonPass -.else + goto BattleScript_DoEffectTeleport +BattleScript_EffectTeleportGen7:: jumpifbattletype BATTLE_TYPE_TRAINER, BattleScript_FailedFromAtkCanceler -.endif +BattleScript_DoEffectTeleport:: attackcanceler attackstring ppreduce @@ -6573,10 +6576,10 @@ BattleScript_CudChewActivates:: end3 BattleScript_ApplyDisguiseFormChangeHPLoss:: -.if B_DISGUISE_HP_LOSS >= GEN_8 + jumpifgenconfiglowerthan GEN_CONFIG_DISGUISE_HP_LOSS, GEN_8, BattleScript_ApplyDisguiseFormChangeHPLossReturn healthbarupdate BS_SCRIPTING datahpupdate BS_SCRIPTING -.endif +BattleScript_ApplyDisguiseFormChangeHPLossReturn: return BattleScript_TargetFormChangeNoPopup: diff --git a/include/constants/generational_changes.h b/include/constants/generational_changes.h index 83c9caa203..0478240320 100644 --- a/include/constants/generational_changes.h +++ b/include/constants/generational_changes.h @@ -30,6 +30,11 @@ enum GenConfigTag GEN_ALLY_SWITCH_FAIL_CHANCE, GEN_DREAM_EATER_LIQUID_OOZE, GEN_CONFIG_TRANSISTOR_BOOST, + GEN_CONFIG_RECALC_TURN_AFTER_ACTIONS, + GEN_CONFIG_UPDATED_INTIMIDATE, + GEN_CONFIG_DISGUISE_HP_LOSS, + GEN_CONFIG_AFTER_YOU_TURN_ORDER, + GEN_CONFIG_HEALING_WISH_SWITCH, GEN_CONFIG_COUNT }; diff --git a/include/generational_changes.h b/include/generational_changes.h index a6f3a56ef7..c3667d1af5 100644 --- a/include/generational_changes.h +++ b/include/generational_changes.h @@ -33,6 +33,11 @@ static const u8 sGenerationalChanges[GEN_CONFIG_COUNT] = [GEN_ALLY_SWITCH_FAIL_CHANCE] = B_ALLY_SWITCH_FAIL_CHANCE, [GEN_DREAM_EATER_LIQUID_OOZE] = B_DREAM_EATER_LIQUID_OOZE, [GEN_CONFIG_TRANSISTOR_BOOST] = B_TRANSISTOR_BOOST, + [GEN_CONFIG_RECALC_TURN_AFTER_ACTIONS] = B_RECALC_TURN_AFTER_ACTIONS, + [GEN_CONFIG_UPDATED_INTIMIDATE] = B_UPDATED_INTIMIDATE, + [GEN_CONFIG_DISGUISE_HP_LOSS] = B_DISGUISE_HP_LOSS, + [GEN_CONFIG_AFTER_YOU_TURN_ORDER] = B_AFTER_YOU_TURN_ORDER, + [GEN_CONFIG_HEALING_WISH_SWITCH] = B_HEALING_WISH_SWITCH, }; #if TESTING diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 84d247a617..6bf1245922 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -2769,7 +2769,7 @@ bool32 IsSwitchOutEffect(enum BattleMoveEffects effect) switch (effect) { case EFFECT_TELEPORT: - if (B_TELEPORT_BEHAVIOR >= GEN_8) + if (GetGenConfig(GEN_CONFIG_TELEPORT_BEHAVIOR) >= GEN_8) return TRUE; case EFFECT_HIT_ESCAPE: case EFFECT_PARTING_SHOT: diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 6845e760f4..f271bc4c28 100755 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2358,7 +2358,7 @@ static void Cmd_datahpupdate(void) gBattleMons[battler].species = SPECIES_MIMIKYU_BUSTED_TOTEM; else gBattleMons[battler].species = SPECIES_MIMIKYU_BUSTED; - if (B_DISGUISE_HP_LOSS >= GEN_8) + if (GetGenConfig(GEN_CONFIG_DISGUISE_HP_LOSS) >= GEN_8) gBattleStruct->moveDamage[battler] = GetNonDynamaxMaxHP(battler) / 8; BattleScriptPush(cmd->nextInstr); gBattlescriptCurrInstr = BattleScript_TargetFormChange; @@ -7756,7 +7756,7 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler) // Healing Wish activates before hazards. // Starting from Gen8 - it heals only pokemon which can be healed. In gens 5,6,7 the effect activates anyways. else if ((gBattleStruct->battlerState[battler].storedHealingWish || gBattleStruct->battlerState[battler].storedLunarDance) - && (gBattleMons[battler].hp != gBattleMons[battler].maxHP || gBattleMons[battler].status1 != 0 || B_HEALING_WISH_SWITCH < GEN_8)) + && (gBattleMons[battler].hp != gBattleMons[battler].maxHP || gBattleMons[battler].status1 != 0 || GetGenConfig(GEN_CONFIG_HEALING_WISH_SWITCH) < GEN_8)) { gBattlerAttacker = battler; if (gBattleStruct->battlerState[battler].storedHealingWish) @@ -9453,7 +9453,7 @@ static bool32 ChangeOrderTargetAfterAttacker(void) if (GetBattlerTurnOrderNum(gBattlerAttacker) > GetBattlerTurnOrderNum(gBattlerTarget)) return FALSE; if (GetBattlerTurnOrderNum(gBattlerAttacker) + 1 == GetBattlerTurnOrderNum(gBattlerTarget)) - return B_AFTER_YOU_TURN_ORDER >= GEN_8; + return GetGenConfig(GEN_CONFIG_AFTER_YOU_TURN_ORDER) >= GEN_8; for (i = 0; i < MAX_BATTLERS_COUNT; i++) { @@ -16562,7 +16562,7 @@ void BS_JumpIfIntimidateAbilityPrevented(void) case ABILITY_SCRAPPY: case ABILITY_OWN_TEMPO: case ABILITY_OBLIVIOUS: - if (B_UPDATED_INTIMIDATE >= GEN_8) + if (GetGenConfig(GEN_CONFIG_UPDATED_INTIMIDATE) >= GEN_8) { hasAbility = TRUE; gBattlescriptCurrInstr = BattleScript_IntimidatePrevented; @@ -18347,3 +18347,12 @@ void BS_BattlerItemToLastUsedItem(void) gBattleMons[gBattlerTarget].item = gLastUsedItem; gBattlescriptCurrInstr = cmd->nextInstr; } + +void BS_JumpIfGenConfigLowerThan(void) +{ + NATIVE_ARGS(u16 tag, u8 gen, const u8 *jumpInstr); + if (GetGenConfig(cmd->tag) < cmd->gen) + gBattlescriptCurrInstr = cmd->jumpInstr; + else + gBattlescriptCurrInstr = cmd->nextInstr; +} diff --git a/src/battle_util.c b/src/battle_util.c index de7cec8d58..16b335e701 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -919,7 +919,7 @@ void HandleAction_ActionFinished(void) gBattleResources->battleScriptsStack->size = 0; gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_NONE; - if (B_RECALC_TURN_AFTER_ACTIONS >= GEN_8 && !afterYouActive && !gBattleStruct->pledgeMove && !IsPursuitTargetSet()) + if (GetGenConfig(GEN_CONFIG_RECALC_TURN_AFTER_ACTIONS) >= GEN_8 && !afterYouActive && !gBattleStruct->pledgeMove && !IsPursuitTargetSet()) { // i starts at `gCurrentTurnActionNumber` because we don't want to recalculate turn order for mon that have already // taken action. It's been previously increased, which we want in order to not recalculate the turn of the mon that just finished its action @@ -1201,7 +1201,9 @@ void PrepareStringBattle(enum StringID stringId, u32 battler) else SET_STATCHANGER(STAT_SPATK, 2, FALSE); } - else if (B_UPDATED_INTIMIDATE >= GEN_8 && stringId == STRINGID_PKMNCUTSATTACKWITH && targetAbility == ABILITY_RATTLED + else if (GetGenConfig(GEN_CONFIG_UPDATED_INTIMIDATE) >= GEN_8 + && stringId == STRINGID_PKMNCUTSATTACKWITH + && targetAbility == ABILITY_RATTLED && CompareStat(gBattlerTarget, STAT_SPEED, MAX_STAT_STAGE, CMP_LESS_THAN)) { gBattlerAbility = gBattlerTarget; diff --git a/test/battle/ability/disguise.c b/test/battle/ability/disguise.c index ef00c1fe93..0d73fdf9ae 100644 --- a/test/battle/ability/disguise.c +++ b/test/battle/ability/disguise.c @@ -6,11 +6,30 @@ ASSUMPTIONS ASSUME(GetMoveCategory(MOVE_AERIAL_ACE) == DAMAGE_CATEGORY_PHYSICAL); } -SINGLE_BATTLE_TEST("Disguised Mimikyu will lose 1/8 of its max HP upon changing to its busted form") +SINGLE_BATTLE_TEST("Disguised Mimikyu doesn't lose 1/8 of its max HP upon changing to its busted form (Gen7)") +{ + GIVEN { + WITH_CONFIG(GEN_CONFIG_DISGUISE_HP_LOSS, GEN_7); + PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_AERIAL_ACE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AERIAL_ACE, opponent); + NOT HP_BAR(player); + ABILITY_POPUP(player, ABILITY_DISGUISE); + } THEN { + EXPECT_EQ(player->species, SPECIES_MIMIKYU_BUSTED); + EXPECT_EQ(player->hp, player->maxHP); + } +} + +SINGLE_BATTLE_TEST("Disguised Mimikyu will lose 1/8 of its max HP upon changing to its busted form (Gen8+)") { s16 disguiseDamage; GIVEN { + WITH_CONFIG(GEN_CONFIG_DISGUISE_HP_LOSS, GEN_8); PLAYER(SPECIES_MIMIKYU_DISGUISED) { Ability(ABILITY_DISGUISE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { diff --git a/test/battle/ability/inner_focus.c b/test/battle/ability/inner_focus.c index e6370f019a..75c7c113d0 100644 --- a/test/battle/ability/inner_focus.c +++ b/test/battle/ability/inner_focus.c @@ -1,13 +1,40 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Inner Focus prevents intimidate") +SINGLE_BATTLE_TEST("Inner Focus doesn't prevent intimidate (Gen3-7)") { s16 turnOneHit; s16 turnTwoHit; GIVEN { - ASSUME(B_UPDATED_INTIMIDATE >= GEN_8); + WITH_CONFIG(GEN_CONFIG_UPDATED_INTIMIDATE, GEN_7); + PLAYER(SPECIES_EKANS) { Ability(ABILITY_SHED_SKIN); }; + PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }; + OPPONENT(SPECIES_ZUBAT) { Ability(ABILITY_INNER_FOCUS); }; + } WHEN { + TURN { MOVE(opponent, MOVE_SCRATCH); } + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_SCRATCH); } + + } SCENE { + // Turn 1 + HP_BAR(player, captureDamage: &turnOneHit); + ABILITY_POPUP(player, ABILITY_INTIMIDATE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Ekans's Intimidate cuts the opposing Zubat's Attack!"); + // Turn 2 + HP_BAR(player, captureDamage: &turnTwoHit); + } THEN { + EXPECT_GT(turnOneHit, turnTwoHit); + } +} + +SINGLE_BATTLE_TEST("Inner Focus prevents intimidate (Gen8+)") +{ + s16 turnOneHit; + s16 turnTwoHit; + + GIVEN { + WITH_CONFIG(GEN_CONFIG_UPDATED_INTIMIDATE, GEN_8); PLAYER(SPECIES_EKANS) { Ability(ABILITY_SHED_SKIN); }; PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }; OPPONENT(SPECIES_ZUBAT) { Ability(ABILITY_INNER_FOCUS); }; @@ -18,7 +45,7 @@ SINGLE_BATTLE_TEST("Inner Focus prevents intimidate") } SCENE { HP_BAR(player, captureDamage: &turnOneHit); ABILITY_POPUP(player, ABILITY_INTIMIDATE); - NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); } + NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); } ABILITY_POPUP(opponent, ABILITY_INNER_FOCUS); MESSAGE("The opposing Zubat's Inner Focus prevents stat loss!"); HP_BAR(player, captureDamage: &turnTwoHit); diff --git a/test/battle/ability/oblivious.c b/test/battle/ability/oblivious.c index a787ec6578..40506e1967 100644 --- a/test/battle/ability/oblivious.c +++ b/test/battle/ability/oblivious.c @@ -50,10 +50,30 @@ SINGLE_BATTLE_TEST("Oblivious prevents Taunt") } } -SINGLE_BATTLE_TEST("Oblivious prevents Intimidate") +SINGLE_BATTLE_TEST("Oblivious doesn't prevent Intimidate (Gen3-7)") { GIVEN { - ASSUME(B_UPDATED_INTIMIDATE >= GEN_8); + WITH_CONFIG(GEN_CONFIG_UPDATED_INTIMIDATE, GEN_7); + PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); } + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); } + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + ABILITY_POPUP(opponent, ABILITY_INTIMIDATE); + NONE_OF { + ABILITY_POPUP(player, ABILITY_OBLIVIOUS); + MESSAGE("Slowpoke's Oblivious prevents stat loss!"); + } + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("The opposing Ekans's Intimidate cuts Slowpoke's Attack!"); + } +} + +SINGLE_BATTLE_TEST("Oblivious prevents Intimidate (Gen8+)") +{ + GIVEN { + WITH_CONFIG(GEN_CONFIG_UPDATED_INTIMIDATE, GEN_8); PLAYER(SPECIES_SLOWPOKE) { Ability(ABILITY_OBLIVIOUS); } OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); } diff --git a/test/battle/ability/own_tempo.c b/test/battle/ability/own_tempo.c index ef358a172e..bbd709c57b 100644 --- a/test/battle/ability/own_tempo.c +++ b/test/battle/ability/own_tempo.c @@ -1,10 +1,28 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Own Tempo prevents Intimidate but no other stat down changes") +SINGLE_BATTLE_TEST("Own Tempo doesn't prevent Intimidate (Gen3-7)") { GIVEN { - ASSUME(B_UPDATED_INTIMIDATE >= GEN_8); + WITH_CONFIG(GEN_CONFIG_UPDATED_INTIMIDATE, GEN_7); + ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE); + PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }; + OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); }; + } WHEN { + TURN { } + } SCENE { + ABILITY_POPUP(player, ABILITY_INTIMIDATE); + NONE_OF { + ABILITY_POPUP(opponent, ABILITY_OWN_TEMPO); + MESSAGE("The opposing Slowpoke's Own Tempo prevents stat loss!"); + } + } +} + +SINGLE_BATTLE_TEST("Own Tempo prevents Intimidate but no other stat down changes (Gen8+)") +{ + GIVEN { + WITH_CONFIG(GEN_CONFIG_UPDATED_INTIMIDATE, GEN_8); ASSUME(GetMoveEffect(MOVE_CONFUSE_RAY) == EFFECT_CONFUSE); PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }; OPPONENT(SPECIES_SLOWPOKE) { Ability(ABILITY_OWN_TEMPO); }; diff --git a/test/battle/ability/rattled.c b/test/battle/ability/rattled.c index d957dec66a..a2cc61536e 100644 --- a/test/battle/ability/rattled.c +++ b/test/battle/ability/rattled.c @@ -52,10 +52,30 @@ SINGLE_BATTLE_TEST("Rattled boosts speed by 1 when hit by Bug, Dark or Ghost typ } } -SINGLE_BATTLE_TEST("Rattled boosts speed by 1 when affected by Intimidate") +SINGLE_BATTLE_TEST("Rattled does not boost speed by 1 when affected by Intimidate (Gen5-7)") { GIVEN { - ASSUME(B_UPDATED_INTIMIDATE >= GEN_8); + WITH_CONFIG(GEN_CONFIG_UPDATED_INTIMIDATE, GEN_7); + PLAYER(SPECIES_GYARADOS) {Ability(ABILITY_INTIMIDATE); } + OPPONENT(SPECIES_SUDOWOODO) {Ability(ABILITY_RATTLED); } + } WHEN { + TURN {} + } SCENE { + ABILITY_POPUP(player, ABILITY_INTIMIDATE); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Gyarados's Intimidate cuts the opposing Sudowoodo's Attack!"); + NONE_OF { + ABILITY_POPUP(opponent, ABILITY_RATTLED); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("The opposing Sudowoodo's Speed rose!"); + } + } +} + +SINGLE_BATTLE_TEST("Rattled boosts speed by 1 when affected by Intimidate (Gen8+)") +{ + GIVEN { + WITH_CONFIG(GEN_CONFIG_UPDATED_INTIMIDATE, GEN_8); PLAYER(SPECIES_GYARADOS) {Ability(ABILITY_INTIMIDATE); } OPPONENT(SPECIES_SUDOWOODO) {Ability(ABILITY_RATTLED); } } WHEN { diff --git a/test/battle/ability/scrappy.c b/test/battle/ability/scrappy.c index 919ee486b9..9476f93926 100644 --- a/test/battle/ability/scrappy.c +++ b/test/battle/ability/scrappy.c @@ -1,13 +1,13 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Scrappy prevents intimidate") +SINGLE_BATTLE_TEST("Scrappy doesn't prevent Intimidate (Gen4-7)") { s16 turnOneHit; s16 turnTwoHit; GIVEN { - ASSUME(B_UPDATED_INTIMIDATE >= GEN_8); + WITH_CONFIG(GEN_CONFIG_UPDATED_INTIMIDATE, GEN_7); PLAYER(SPECIES_EKANS) { Ability(ABILITY_SHED_SKIN); }; PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }; OPPONENT(SPECIES_KANGASKHAN) { Ability(ABILITY_SCRAPPY); }; @@ -18,7 +18,35 @@ SINGLE_BATTLE_TEST("Scrappy prevents intimidate") } SCENE { HP_BAR(player, captureDamage: &turnOneHit); ABILITY_POPUP(player, ABILITY_INTIMIDATE); - NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); } + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + NONE_OF { + ABILITY_POPUP(opponent, ABILITY_SCRAPPY); + MESSAGE("The opposing Kangaskhan's Scrappy prevents stat loss!"); + } + HP_BAR(player, captureDamage: &turnTwoHit); + } THEN { + EXPECT_GT(turnOneHit, turnTwoHit); + } +} + +SINGLE_BATTLE_TEST("Scrappy prevents Intimidate (Gen8+)") +{ + s16 turnOneHit; + s16 turnTwoHit; + + GIVEN { + WITH_CONFIG(GEN_CONFIG_UPDATED_INTIMIDATE, GEN_8); + PLAYER(SPECIES_EKANS) { Ability(ABILITY_SHED_SKIN); }; + PLAYER(SPECIES_EKANS) { Ability(ABILITY_INTIMIDATE); }; + OPPONENT(SPECIES_KANGASKHAN) { Ability(ABILITY_SCRAPPY); }; + } WHEN { + TURN { MOVE(opponent, MOVE_SCRATCH); } + TURN { SWITCH(player, 1); MOVE(opponent, MOVE_SCRATCH); } + + } SCENE { + HP_BAR(player, captureDamage: &turnOneHit); + ABILITY_POPUP(player, ABILITY_INTIMIDATE); + NONE_OF { ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); } ABILITY_POPUP(opponent, ABILITY_SCRAPPY); MESSAGE("The opposing Kangaskhan's Scrappy prevents stat loss!"); HP_BAR(player, captureDamage: &turnTwoHit); diff --git a/test/battle/ability/sheer_force.c b/test/battle/ability/sheer_force.c index 8e99361296..d14d53571d 100644 --- a/test/battle/ability/sheer_force.c +++ b/test/battle/ability/sheer_force.c @@ -567,7 +567,6 @@ static inline bool32 IsMoveSheerForceBoosted(u32 move) case MOVE_POWDER_SNOW: case MOVE_PSYSHIELD_BASH: case MOVE_PYRO_BALL: - case MOVE_RAPID_SPIN: case MOVE_RELIC_SONG: case MOVE_ROLLING_KICK: case MOVE_SACRED_FIRE: @@ -605,6 +604,8 @@ static inline bool32 IsMoveSheerForceBoosted(u32 move) case MOVE_ELECTRO_SHOT: case MOVE_PSYCHIC_NOISE: return TRUE; + case MOVE_RAPID_SPIN: + return B_SPEED_BUFFING_RAPID_SPIN >= GEN_8; } return FALSE; } diff --git a/test/battle/ability/shield_dust.c b/test/battle/ability/shield_dust.c index 828e596525..2d7358335d 100644 --- a/test/battle/ability/shield_dust.c +++ b/test/battle/ability/shield_dust.c @@ -88,12 +88,12 @@ SINGLE_BATTLE_TEST("Shield Dust does not block self-targeting effects, primary o { u16 move; PARAMETRIZE { move = MOVE_POWER_UP_PUNCH; } - PARAMETRIZE { move = MOVE_RAPID_SPIN; } + PARAMETRIZE { move = MOVE_FLAME_CHARGE; } PARAMETRIZE { move = MOVE_LEAF_STORM; } PARAMETRIZE { move = MOVE_METEOR_ASSAULT; } GIVEN { - ASSUME(GetMoveEffect(MOVE_RAPID_SPIN) == EFFECT_RAPID_SPIN); + ASSUME(MoveHasAdditionalEffectSelf(MOVE_FLAME_CHARGE, MOVE_EFFECT_SPD_PLUS_1) == TRUE); ASSUME(MoveHasAdditionalEffectSelf(MOVE_POWER_UP_PUNCH, MOVE_EFFECT_ATK_PLUS_1) == TRUE); ASSUME(MoveHasAdditionalEffectSelf(MOVE_LEAF_STORM, MOVE_EFFECT_SP_ATK_MINUS_2) == TRUE); ASSUME(MoveHasAdditionalEffectSelf(MOVE_METEOR_ASSAULT, MOVE_EFFECT_RECHARGE) == TRUE); @@ -110,7 +110,7 @@ SINGLE_BATTLE_TEST("Shield Dust does not block self-targeting effects, primary o switch (move) { case MOVE_POWER_UP_PUNCH: - case MOVE_RAPID_SPIN: + case MOVE_FLAME_CHARGE: case MOVE_LEAF_STORM: ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); break; diff --git a/test/battle/ai/ai_calc_best_move_score.c b/test/battle/ai/ai_calc_best_move_score.c index a4a13c283f..cfad45a0aa 100644 --- a/test/battle/ai/ai_calc_best_move_score.c +++ b/test/battle/ai/ai_calc_best_move_score.c @@ -11,7 +11,8 @@ AI_SINGLE_BATTLE_TEST("AI will not further increase Attack / Sp. Atk stat if it GIVEN { ASSUME(GetMovePower(MOVE_SKY_UPPERCUT) == 85); - ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); + ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP + || GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); ASSUME(GetMoveEffect(MOVE_CALM_MIND) == EFFECT_CALM_MIND); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_COMBUSKEN) { Speed(15); Moves(MOVE_SKY_UPPERCUT, MOVE_CELEBRATE); }; @@ -31,7 +32,8 @@ AI_SINGLE_BATTLE_TEST("AI will not further increase Attack / Sp. Atk stat if it GIVEN { ASSUME(GetMovePower(MOVE_SKY_UPPERCUT) == 85); - ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); + ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP + || GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); ASSUME(GetMoveEffect(MOVE_CALM_MIND) == EFFECT_CALM_MIND); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); PLAYER(SPECIES_COMBUSKEN) { Speed(20); Moves(MOVE_DOUBLE_KICK, MOVE_CELEBRATE); }; @@ -63,7 +65,8 @@ AI_SINGLE_BATTLE_TEST("AI will not waste a turn setting up if it knows target ca GIVEN { ASSUME(GetMovePower(MOVE_SKY_UPPERCUT) == 85); - ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); + ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP + || GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); ASSUME(GetMoveEffect(MOVE_CALM_MIND) == EFFECT_CALM_MIND); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT); PLAYER(SPECIES_COMBUSKEN) { Speed(15); Moves(MOVE_SKY_UPPERCUT, MOVE_DOUBLE_KICK, MOVE_FLAME_WHEEL, MOVE_CELEBRATE); }; diff --git a/test/battle/ai/ai_switching.c b/test/battle/ai/ai_switching.c index 8db6fa9479..a0532a5df3 100644 --- a/test/battle/ai/ai_switching.c +++ b/test/battle/ai/ai_switching.c @@ -839,10 +839,9 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has an PARAMETRIZE { aiMon = SPECIES_BRONZONG; absorbingAbility = ABILITY_LEVITATE; move = MOVE_EARTHQUAKE;} PARAMETRIZE { aiMon = SPECIES_ELECTRODE; absorbingAbility = ABILITY_SOUNDPROOF; move = MOVE_HYPER_VOICE;} PARAMETRIZE { aiMon = SPECIES_CHESNAUGHT; absorbingAbility = ABILITY_BULLETPROOF; move = MOVE_SLUDGE_BOMB;} - PARAMETRIZE { aiMon = SPECIES_SHIFTRY; absorbingAbility = ABILITY_WIND_RIDER; move = MOVE_HURRICANE;} + PARAMETRIZE { aiMon = SPECIES_BRAMBLEGHAST; absorbingAbility = ABILITY_WIND_RIDER; move = MOVE_HURRICANE;} GIVEN { ASSUME(B_REDIRECT_ABILITY_IMMUNITY >= GEN_5); - ASSUME(P_UPDATED_ABILITIES >= GEN_9); //For the predicted ability for Shiftry AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_ZIGZAGOON) { Moves(move); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SCRATCH); } diff --git a/test/battle/hold_effect/covert_cloak.c b/test/battle/hold_effect/covert_cloak.c index 0b3d0c2ed6..64f75703cc 100644 --- a/test/battle/hold_effect/covert_cloak.c +++ b/test/battle/hold_effect/covert_cloak.c @@ -92,12 +92,12 @@ SINGLE_BATTLE_TEST("Covert Cloak does not block self-targeting effects, primary { u16 move; PARAMETRIZE { move = MOVE_POWER_UP_PUNCH; } - PARAMETRIZE { move = MOVE_RAPID_SPIN; } + PARAMETRIZE { move = MOVE_FLAME_CHARGE; } PARAMETRIZE { move = MOVE_LEAF_STORM; } PARAMETRIZE { move = MOVE_METEOR_ASSAULT; } GIVEN { - ASSUME(GetMoveEffect(MOVE_RAPID_SPIN) == EFFECT_RAPID_SPIN); + ASSUME(MoveHasAdditionalEffectSelf(MOVE_FLAME_CHARGE, MOVE_EFFECT_SPD_PLUS_1) == TRUE); ASSUME(MoveHasAdditionalEffectSelf(MOVE_POWER_UP_PUNCH, MOVE_EFFECT_ATK_PLUS_1) == TRUE); ASSUME(MoveHasAdditionalEffectSelf(MOVE_LEAF_STORM, MOVE_EFFECT_SP_ATK_MINUS_2) == TRUE); ASSUME(MoveHasAdditionalEffectSelf(MOVE_METEOR_ASSAULT, MOVE_EFFECT_RECHARGE) == TRUE); @@ -113,7 +113,7 @@ SINGLE_BATTLE_TEST("Covert Cloak does not block self-targeting effects, primary HP_BAR(opponent); switch (move) { case MOVE_POWER_UP_PUNCH: - case MOVE_RAPID_SPIN: + case MOVE_FLAME_CHARGE: case MOVE_LEAF_STORM: ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); break; diff --git a/test/battle/move_effect/after_you.c b/test/battle/move_effect/after_you.c index 222b94c7b6..9d0464f72a 100644 --- a/test/battle/move_effect/after_you.c +++ b/test/battle/move_effect/after_you.c @@ -86,10 +86,35 @@ DOUBLE_BATTLE_TEST("After You calculates correct turn order if only one Pokémon } } +DOUBLE_BATTLE_TEST("After You fails if the turn order remains the same after After You (Gen5-7)") +{ + GIVEN { + WITH_CONFIG(GEN_CONFIG_AFTER_YOU_TURN_ORDER, GEN_7); + PLAYER(SPECIES_WOBBUFFET) { Speed(4); } + PLAYER(SPECIES_WYNAUT) { Speed(1); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } + OPPONENT(SPECIES_WYNAUT) { Speed(3); } + } WHEN { + TURN { + MOVE(playerLeft, MOVE_CELEBRATE); + MOVE(playerRight, MOVE_CELEBRATE); + MOVE(opponentLeft, MOVE_CELEBRATE); + MOVE(opponentRight, MOVE_AFTER_YOU, target: opponentLeft); + } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerLeft); + MESSAGE("The opposing Wynaut used After You!"); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_AFTER_YOU, opponentRight); + MESSAGE("But it failed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponentLeft); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, playerRight); + } +} + DOUBLE_BATTLE_TEST("After You doesn't fail if the turn order remains the same after After You (Gen8+)") { GIVEN { - ASSUME(B_AFTER_YOU_TURN_ORDER >= GEN_8); + WITH_CONFIG(GEN_CONFIG_AFTER_YOU_TURN_ORDER, GEN_8); PLAYER(SPECIES_WOBBUFFET) { Speed(4); } PLAYER(SPECIES_WYNAUT) { Speed(1); } OPPONENT(SPECIES_WOBBUFFET) { Speed(2); } diff --git a/test/battle/move_effect/attack_up_user_ally.c b/test/battle/move_effect/attack_up_user_ally.c index ed3fedb261..767e9fdef7 100644 --- a/test/battle/move_effect/attack_up_user_ally.c +++ b/test/battle/move_effect/attack_up_user_ally.c @@ -1,17 +1,14 @@ #include "global.h" #include "test/battle.h" -ASSUMPTIONS -{ - ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); -} - SINGLE_BATTLE_TEST("Howl raises user's Attack by 1 stage", s16 damage) { bool32 raiseAttack; PARAMETRIZE { raiseAttack = FALSE; } PARAMETRIZE { raiseAttack = TRUE; } GIVEN { + ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP + || GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); @@ -37,6 +34,7 @@ DOUBLE_BATTLE_TEST("Howl raises user's and partner's Attack by 1 stage", s16 dam PARAMETRIZE { raiseAttack = FALSE; } PARAMETRIZE { raiseAttack = TRUE; } GIVEN { + ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) { Speed(15); } PLAYER(SPECIES_WYNAUT) { Speed(10); } @@ -69,6 +67,7 @@ DOUBLE_BATTLE_TEST("Howl does not work on partner if it has Soundproof") s16 damage[2]; GIVEN { + ASSUME(GetMoveEffect(MOVE_HOWL) == EFFECT_ATTACK_UP_USER_ALLY); ASSUME(GetMoveCategory(MOVE_SCRATCH) == DAMAGE_CATEGORY_PHYSICAL); PLAYER(SPECIES_WOBBUFFET) { Speed(15); } PLAYER(SPECIES_VOLTORB) { Speed(10); Ability(ABILITY_SOUNDPROOF); } diff --git a/test/battle/move_effect/healing_wish.c b/test/battle/move_effect/healing_wish.c index f303456a38..31dfebb342 100644 --- a/test/battle/move_effect/healing_wish.c +++ b/test/battle/move_effect/healing_wish.c @@ -49,10 +49,28 @@ DOUBLE_BATTLE_TEST("Lunar Dance causes the user to faint and fully heals the rep } } -SINGLE_BATTLE_TEST("Healing Wish effect activates only if the switched Pokémon can be healed") +SINGLE_BATTLE_TEST("Healing Wish effect activates even if the the switched Pokémon can't be healed (Gen4-7)") { GIVEN { - ASSUME(B_HEALING_WISH_SWITCH >= GEN_8); + WITH_CONFIG(GEN_CONFIG_HEALING_WISH_SWITCH, GEN_7); + PLAYER(SPECIES_GARDEVOIR) { Speed(300); } + PLAYER(SPECIES_NINJASK) { Speed(400); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(50); } + } WHEN { + TURN { MOVE(player, MOVE_HEALING_WISH); SEND_OUT(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_HEALING_WISH, player); + HP_BAR(player, hp: 0); + MESSAGE("Gardevoir fainted!"); + MESSAGE("The healing wish came true for Ninjask!"); + MESSAGE("Ninjask regained health!"); + } +} + +SINGLE_BATTLE_TEST("Healing Wish effect activates only if the switched Pokémon can be healed (Gen8+)") +{ + GIVEN { + WITH_CONFIG(GEN_CONFIG_HEALING_WISH_SWITCH, GEN_8); PLAYER(SPECIES_GARDEVOIR) { Speed(300); } PLAYER(SPECIES_NINJASK) { Speed(400); } PLAYER(SPECIES_WYNAUT) { HP(50); MaxHP(100); Status1(STATUS1_PARALYSIS); Speed(50); } @@ -65,8 +83,8 @@ SINGLE_BATTLE_TEST("Healing Wish effect activates only if the switched Pokémon HP_BAR(player, hp: 0); MESSAGE("Gardevoir fainted!"); NONE_OF { - MESSAGE("The healing wish came true for Wynaut!"); - MESSAGE("Wynaut's HP was restored."); + MESSAGE("The healing wish came true for Ninjask!"); + MESSAGE("Ninjask regained health!"); } ANIMATION(ANIM_TYPE_MOVE, MOVE_U_TURN, player); MESSAGE("The healing wish came true for Wynaut!"); diff --git a/test/battle/move_effect/pursuit.c b/test/battle/move_effect/pursuit.c index b18aa74b09..27303d95ce 100644 --- a/test/battle/move_effect/pursuit.c +++ b/test/battle/move_effect/pursuit.c @@ -51,6 +51,7 @@ DOUBLE_BATTLE_TEST("Pursuit doesn't attack a foe using Teleport / Baton Pass to PARAMETRIZE { move = MOVE_TELEPORT; } PARAMETRIZE { move = MOVE_BATON_PASS; } GIVEN { + WITH_CONFIG(GEN_CONFIG_TELEPORT_BEHAVIOR, GEN_8); ASSUME(GetMoveEffect(MOVE_QUASH) == EFFECT_QUASH); ASSUME(GetMoveEffect(MOVE_TELEPORT) == EFFECT_TELEPORT); ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); diff --git a/test/battle/move_effect/quash.c b/test/battle/move_effect/quash.c index 0869b45aeb..a6032b43c4 100644 --- a/test/battle/move_effect/quash.c +++ b/test/battle/move_effect/quash.c @@ -26,7 +26,7 @@ DOUBLE_BATTLE_TEST("Quash-affected target will move last in the priority bracket DOUBLE_BATTLE_TEST("Quash is not affected by dynamic speed") { GIVEN { - ASSUME(B_RECALC_TURN_AFTER_ACTIONS >= GEN_8); + WITH_CONFIG(GEN_CONFIG_RECALC_TURN_AFTER_ACTIONS, GEN_8); ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND); PLAYER(SPECIES_VOLBEAT) { Speed(10); Ability(ABILITY_PRANKSTER); } PLAYER(SPECIES_WOBBUFFET) { Speed(30); } @@ -112,7 +112,7 @@ DOUBLE_BATTLE_TEST("Quash-affected targets move from fastest to slowest (Gen 8+) DOUBLE_BATTLE_TEST("Quash-affected mon that acted early via After You is not affected by dynamic speed") { GIVEN { - ASSUME(B_RECALC_TURN_AFTER_ACTIONS >= GEN_8); + WITH_CONFIG(GEN_CONFIG_RECALC_TURN_AFTER_ACTIONS, GEN_8); ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND); ASSUME(GetMoveEffect(MOVE_AFTER_YOU) == EFFECT_AFTER_YOU); PLAYER(SPECIES_VOLBEAT) { Speed(20); Ability(ABILITY_PRANKSTER); } diff --git a/test/battle/move_effect/rage_fist.c b/test/battle/move_effect/rage_fist.c index ed21a9097c..5d92544e53 100644 --- a/test/battle/move_effect/rage_fist.c +++ b/test/battle/move_effect/rage_fist.c @@ -249,7 +249,35 @@ SINGLE_BATTLE_TEST("Rage Fist base power is not increased if move had no affect" } } -SINGLE_BATTLE_TEST("Rage Fist base power is increased if Disguise breaks") +SINGLE_BATTLE_TEST("Rage Fist base power is increased if Disguise breaks (Gen7)") +{ + KNOWN_FAILING; + s16 timesGotHit[2]; + u16 species = SPECIES_NONE; + + PARAMETRIZE { species = SPECIES_MIMIKYU_DISGUISED; } + PARAMETRIZE { species = SPECIES_MIMIKYU_TOTEM_DISGUISED; } + + GIVEN { + WITH_CONFIG(GEN_CONFIG_DISGUISE_HP_LOSS, GEN_7); + PLAYER(species) { Ability(ABILITY_DISGUISE); } + OPPONENT(SPECIES_REGIROCK); + } WHEN { + TURN { MOVE(player, MOVE_RAGE_FIST); MOVE(opponent, MOVE_ROCK_THROW); } + TURN { MOVE(player, MOVE_RAGE_FIST); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_RAGE_FIST, player); + HP_BAR(opponent, captureDamage: ×GotHit[0]); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ROCK_THROW, opponent); + ABILITY_POPUP(player, ABILITY_DISGUISE); + ANIMATION(ANIM_TYPE_MOVE, MOVE_RAGE_FIST, player); + HP_BAR(opponent, captureDamage: ×GotHit[1]); + } THEN { + EXPECT_MUL_EQ(timesGotHit[0], Q_4_12(2.0), timesGotHit[1]); + } +} + +SINGLE_BATTLE_TEST("Rage Fist base power is increased if Disguise breaks (Gen8+)") { s16 timesGotHit[2]; u16 species = SPECIES_NONE; @@ -258,6 +286,7 @@ SINGLE_BATTLE_TEST("Rage Fist base power is increased if Disguise breaks") PARAMETRIZE { species = SPECIES_MIMIKYU_TOTEM_DISGUISED; } GIVEN { + WITH_CONFIG(GEN_CONFIG_DISGUISE_HP_LOSS, GEN_8); PLAYER(species) { Ability(ABILITY_DISGUISE); } OPPONENT(SPECIES_REGIROCK); } WHEN { diff --git a/test/battle/move_effect/tailwind.c b/test/battle/move_effect/tailwind.c index f105c9612a..7968bc25ef 100644 --- a/test/battle/move_effect/tailwind.c +++ b/test/battle/move_effect/tailwind.c @@ -36,10 +36,28 @@ SINGLE_BATTLE_TEST("Tailwind applies for 4 turns") } } -DOUBLE_BATTLE_TEST("Tailwind affects partner on first turn") +DOUBLE_BATTLE_TEST("Tailwind doesn't affect the partner on the same turn it's used (Gen4-7)") { GIVEN { - ASSUME(B_RECALC_TURN_AFTER_ACTIONS); + WITH_CONFIG(GEN_CONFIG_RECALC_TURN_AFTER_ACTIONS, GEN_7); + PLAYER(SPECIES_WOBBUFFET) { Speed(20); } + PLAYER(SPECIES_WYNAUT) { Speed(10); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(15); } + OPPONENT(SPECIES_WYNAUT) { Speed(14); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_TAILWIND); } + } SCENE { + MESSAGE("Wobbuffet used Tailwind!"); + MESSAGE("The opposing Wobbuffet used Celebrate!"); + MESSAGE("The opposing Wynaut used Celebrate!"); + MESSAGE("Wynaut used Celebrate!"); + } +} + +DOUBLE_BATTLE_TEST("Tailwind affects the partner on the same turn it's used (Gen8+)") +{ + GIVEN { + WITH_CONFIG(GEN_CONFIG_RECALC_TURN_AFTER_ACTIONS, GEN_8); PLAYER(SPECIES_WOBBUFFET) { Speed(20); } PLAYER(SPECIES_WYNAUT) { Speed(10); } OPPONENT(SPECIES_WOBBUFFET) { Speed(15); } diff --git a/test/battle/move_effect/teleport.c b/test/battle/move_effect/teleport.c index 76fb499722..83d2142e67 100644 --- a/test/battle/move_effect/teleport.c +++ b/test/battle/move_effect/teleport.c @@ -6,9 +6,10 @@ ASSUMPTIONS ASSUME(GetMoveEffect(MOVE_TELEPORT) == EFFECT_TELEPORT); } -SINGLE_BATTLE_TEST("Teleport fails when there is no Pokémon to switch in") +SINGLE_BATTLE_TEST("Teleport fails to switch out when there is no Pokémon to switch in (Gen 8+)") { GIVEN { + WITH_CONFIG(GEN_CONFIG_TELEPORT_BEHAVIOR, GEN_8); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -18,9 +19,10 @@ SINGLE_BATTLE_TEST("Teleport fails when there is no Pokémon to switch in") } } -SINGLE_BATTLE_TEST("Teleport fails when there no alive Pokémon left") +SINGLE_BATTLE_TEST("Teleport fails to switch out the user when there no alive Pokémon left (Gen 8+)") { GIVEN { + WITH_CONFIG(GEN_CONFIG_TELEPORT_BEHAVIOR, GEN_8); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT) { HP(0); } @@ -31,9 +33,29 @@ SINGLE_BATTLE_TEST("Teleport fails when there no alive Pokémon left") } } -SINGLE_BATTLE_TEST("Teleport forces the Pokémon to switch out") +SINGLE_BATTLE_TEST("Teleport fails in Trainer Battles (Gen 1-7)") { GIVEN { + WITH_CONFIG(GEN_CONFIG_TELEPORT_BEHAVIOR, GEN_7); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WYNAUT); + } WHEN { + TURN { MOVE(opponent, MOVE_TELEPORT); } + } SCENE { + MESSAGE("The opposing Wobbuffet used Teleport!"); + NONE_OF { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TELEPORT, opponent); + MESSAGE("2 sent out Wynaut!"); + } + MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Teleport forces the Pokémon to switch out in Trainer Battles (Gen 8+)") +{ + GIVEN { + WITH_CONFIG(GEN_CONFIG_TELEPORT_BEHAVIOR, GEN_8); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT); @@ -48,6 +70,7 @@ SINGLE_BATTLE_TEST("Teleport forces the Pokémon to switch out") SINGLE_BATTLE_TEST("Teleport does not fail if the user is trapped") { GIVEN { + WITH_CONFIG(GEN_CONFIG_TELEPORT_BEHAVIOR, GEN_8); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WYNAUT); From 6e18c2f06e89a6bd8f099cd205c06a84ed721e6b Mon Sep 17 00:00:00 2001 From: grintoul <166724814+grintoul1@users.noreply.github.com> Date: Thu, 4 Sep 2025 14:18:51 +0100 Subject: [PATCH 6/8] Tidy up CanTargetFaintAiWithMod and CanTargetMoveFaintAi (#7693) Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> --- src/battle_ai_util.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 6bf1245922..f92112063d 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1559,7 +1559,8 @@ bool32 CanTargetMoveFaintAi(u32 move, u32 battlerDef, u32 battlerAtk, u32 nHits) u32 indexSlot = GetMoveSlot(GetMovesArray(battlerDef), move); if (indexSlot < MAX_MON_MOVES) { - if (GetNoOfHitsToKO(AI_GetDamage(battlerDef, battlerAtk, indexSlot, AI_DEFENDING, gAiLogicData), gBattleMons[battlerAtk].hp) <= nHits) + u32 hitsToKO = GetNoOfHitsToKO(AI_GetDamage(battlerDef, battlerAtk, indexSlot, AI_DEFENDING, gAiLogicData), gBattleMons[battlerAtk].hp); + if (hitsToKO <= nHits && hitsToKO != 0 && !(CanEndureHit(battlerDef, battlerAtk, move) && hitsToKO == 1)) return TRUE; } return FALSE; @@ -1588,8 +1589,15 @@ bool32 CanTargetFaintAiWithMod(u32 battlerDef, u32 battlerAtk, s32 hpMod, s32 dm if (dmgMod) dmg *= dmgMod; - if (dmg >= hpCheck) + // Applies modified HP percent to AI data for consideration when running CanEndureHit + gAiLogicData->hpPercents[battlerAtk] = (hpCheck/gBattleMons[battlerAtk].maxHP)*100; + + if (dmg >= hpCheck && !(CanEndureHit(battlerDef, battlerAtk, moves[moveIndex]) && (dmgMod <= 1))) + { + gAiLogicData->hpPercents[battlerAtk] = (gBattleMons[battlerAtk].hp / gBattleMons[battlerAtk].maxHP) * 100; return TRUE; + } + gAiLogicData->hpPercents[battlerAtk] = (gBattleMons[battlerAtk].hp / gBattleMons[battlerAtk].maxHP) * 100; } return FALSE; From c5fff74ec454506054b7cb64df77dd15347147bd Mon Sep 17 00:00:00 2001 From: surskitty Date: Fri, 5 Sep 2025 16:41:40 -0400 Subject: [PATCH 7/8] Toxic thread uses light screen's scoring.... (#7674) --- src/battle_ai_main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 0623faf864..ad573604e0 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -1702,7 +1702,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case EFFECT_TOXIC_THREAD: if (!CanLowerStat(battlerAtk, battlerDef, aiData, STAT_SPEED)) ADJUST_SCORE(-1); // may still want to just poison - //fallthrough + if (!AI_CanPoison(battlerAtk, battlerDef, aiData->abilities[battlerDef], move, aiData->partnerMove)) + ADJUST_SCORE(-10); + break; case EFFECT_LIGHT_SCREEN: if (gSideStatuses[GetBattlerSide(battlerAtk)] & (SIDE_STATUS_LIGHTSCREEN | SIDE_STATUS_AURORA_VEIL) || (HasPartner(battlerAtk) && AreMovesEquivalent(battlerAtk, BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))) From 912f553cf779b2cfdbabfe9e42e49615be6846d3 Mon Sep 17 00:00:00 2001 From: Hedara Date: Sat, 6 Sep 2025 16:56:48 +0200 Subject: [PATCH 8/8] Fix EWRAM_INIT in tests and add a default state to test runner main loop --- ld_script_test.ld | 1 + test/test_runner.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/ld_script_test.ld b/ld_script_test.ld index f6b9659a19..a40329ff1c 100644 --- a/ld_script_test.ld +++ b/ld_script_test.ld @@ -19,6 +19,7 @@ SECTIONS { { __ewram_start = .; *(.ewram*) + . = ALIGN(4); __ewram_end = .; } > EWRAM diff --git a/test/test_runner.c b/test/test_runner.c index 218061d63f..450283ab58 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -446,6 +446,11 @@ top: case STATE_EXIT: MgbaExit_(gTestRunnerState.exitCode); break; + default: + MgbaOpen_(); + Test_MgbaPrintf("\e[31mInvalid TestRunner state, exiting\e[0m"); + gTestRunnerState.exitCode = 1; + gTestRunnerState.state = STATE_EXIT; } if (gMain.callback2 == CB2_TestRunner)