From 6b8665d08f357e995939b15cd911e721f21402c9 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 1 Jan 2025 06:24:23 -0300 Subject: [PATCH 1/8] Speed up tests in headless mode (#5889) --- include/battle_gfx_sfx_util.h | 1 + include/config/battle.h | 3 +- src/battle_controllers.c | 5 ++- src/battle_gfx_sfx_util.c | 12 +++++++ src/battle_intro.c | 56 +++++++++++++++++++++++++++++ src/battle_main.c | 66 +++++++++++++++++++++-------------- src/battle_script_commands.c | 4 +++ src/pokemon.c | 5 +-- src/pokemon_animation.c | 6 +++- test/test_runner.c | 2 +- 10 files changed, 128 insertions(+), 32 deletions(-) diff --git a/include/battle_gfx_sfx_util.h b/include/battle_gfx_sfx_util.h index 968f8d48dc..dd85b2658c 100644 --- a/include/battle_gfx_sfx_util.h +++ b/include/battle_gfx_sfx_util.h @@ -6,6 +6,7 @@ void FreeBattleSpritesData(void); u16 ChooseMoveAndTargetInBattlePalace(u32 battler); void SpriteCB_WaitForBattlerBallReleaseAnim(struct Sprite *sprite); void SpriteCB_TrainerSlideIn(struct Sprite *sprite); +void SpriteCB_TrainerSpawn(struct Sprite *sprite); void InitAndLaunchChosenStatusAnimation(u32 battler, bool32 isStatus2, u32 status); bool8 TryHandleLaunchBattleTableAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId, u16 argument); void InitAndLaunchSpecialAnimation(u8 activeBattlerId, u8 attacker, u8 target, u8 tableId); diff --git a/include/config/battle.h b/include/config/battle.h index f1ba1944dc..cdb0caacfe 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -226,7 +226,8 @@ // Interface settings #define B_ABILITY_POP_UP TRUE // In Gen5+, the Pokémon abilities are displayed in a pop-up, when they activate in battle. -#define B_FAST_INTRO TRUE // If set to TRUE, battle intro texts print at the same time as animation of a Pokémon, as opposing to waiting for the animation to end. +#define B_FAST_INTRO_PKMN_TEXT TRUE // If set to TRUE, battle intro texts print at the same time as animation of a Pokémon, as opposing to waiting for the animation to end. +#define B_FAST_INTRO_NO_SLIDE FALSE // If set to TRUE, the slide animation that happens at the beginning of the battle is skipped. #define B_FAST_HP_DRAIN TRUE // If set to TRUE, HP bars will move faster. #define B_FAST_EXP_GROW TRUE // If set to TRUE, EXP bars will move faster. #define B_SHOW_TARGETS TRUE // If set to TRUE, all available targets, for moves hitting 2 or 3 Pokémon, will be shown before selecting a move. diff --git a/src/battle_controllers.c b/src/battle_controllers.c index 553eb7a85c..a5581cf735 100644 --- a/src/battle_controllers.c +++ b/src/battle_controllers.c @@ -2542,7 +2542,10 @@ void BtlController_HandleDrawTrainerPic(u32 battler, u32 trainerPicId, bool32 is gSprites[gBattlerSpriteIds[battler]].x2 = DISPLAY_WIDTH; gSprites[gBattlerSpriteIds[battler]].sSpeedX = -2; } - gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn; + if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless) + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSpawn; + else + gSprites[gBattlerSpriteIds[battler]].callback = SpriteCB_TrainerSlideIn; gBattlerControllerFuncs[battler] = Controller_WaitForTrainerPic; } diff --git a/src/battle_gfx_sfx_util.c b/src/battle_gfx_sfx_util.c index 1f768274aa..620ef57d94 100644 --- a/src/battle_gfx_sfx_util.c +++ b/src/battle_gfx_sfx_util.c @@ -435,6 +435,18 @@ void SpriteCB_TrainerSlideIn(struct Sprite *sprite) } } +void SpriteCB_TrainerSpawn(struct Sprite *sprite) +{ + if (!(gIntroSlideFlags & 1)) + { + sprite->x2 = 0; + if (sprite->y2 != 0) + sprite->callback = SpriteCB_TrainerSlideVertical; + else + sprite->callback = SpriteCallbackDummy; + } +} + // Slide up to 0 if necessary (used by multi battle intro) static void SpriteCB_TrainerSlideVertical(struct Sprite *sprite) { diff --git a/src/battle_intro.c b/src/battle_intro.c index a6b1607285..b951c163c8 100644 --- a/src/battle_intro.c +++ b/src/battle_intro.c @@ -8,6 +8,7 @@ #include "main.h" #include "scanline_effect.h" #include "task.h" +#include "test_runner.h" #include "trig.h" #include "constants/battle_partner.h" #include "constants/trainers.h" @@ -17,6 +18,7 @@ static void BattleIntroSlide2(u8); static void BattleIntroSlide3(u8); static void BattleIntroSlideLink(u8); static void BattleIntroSlidePartner(u8); +static void BattleIntroNoSlide(u8); static const u8 sBattleAnimBgCnts[] = {REG_OFFSET_BG0CNT, REG_OFFSET_BG1CNT, REG_OFFSET_BG2CNT, REG_OFFSET_BG3CNT}; @@ -149,9 +151,59 @@ static void BattleIntroSlideEnd(u8 taskId) SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG_ALL | WINOUT_WIN01_OBJ | WINOUT_WIN01_CLR | WINOUT_WINOBJ_BG_ALL | WINOUT_WINOBJ_OBJ | WINOUT_WINOBJ_CLR); } +static void BattleIntroNoSlide(u8 taskId) +{ + switch (gTasks[taskId].tState) + { + case 0: + if (gBattleTypeFlags & BATTLE_TYPE_LINK) + { + gTasks[taskId].data[2] = 16; + gTasks[taskId].tState++; + gIntroSlideFlags &= ~1; + } + else + { + gTasks[taskId].data[2] = 1; + gTasks[taskId].tState++; + gIntroSlideFlags &= ~1; + } + break; + case 1: + gTasks[taskId].data[2]--; + if (gTasks[taskId].data[2] == 0) + { + gTasks[taskId].tState++; + SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR); + gScanlineEffect.state = 3; + } + break; + case 2: + gBattle_WIN0V -= 0xFF * 2; + if ((gBattle_WIN0V & 0xFF00) == 0) + { + gTasks[taskId].tState++; + } + break; + case 3: + gTasks[taskId].tState++; + CpuFill32(0, (void *)BG_SCREEN_ADDR(28), BG_SCREEN_SIZE); + SetBgAttribute(1, BG_ATTR_CHARBASEINDEX, 0); + SetBgAttribute(2, BG_ATTR_CHARBASEINDEX, 0); + SetGpuReg(REG_OFFSET_BG1CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(28) | BGCNT_TXT256x512); + SetGpuReg(REG_OFFSET_BG2CNT, BGCNT_PRIORITY(0) | BGCNT_CHARBASE(0) | BGCNT_16COLOR | BGCNT_SCREENBASE(30) | BGCNT_TXT512x256); + break; + case 4: + BattleIntroSlideEnd(taskId); + break; + } +} + static void BattleIntroSlide1(u8 taskId) { int i; + if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless) + return BattleIntroNoSlide(taskId); gBattle_BG1_X += 6; switch (gTasks[taskId].tState) @@ -237,6 +289,8 @@ static void BattleIntroSlide1(u8 taskId) static void BattleIntroSlide2(u8 taskId) { int i; + if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless) + return BattleIntroNoSlide(taskId); switch (gTasks[taskId].tTerrain) { @@ -349,6 +403,8 @@ static void BattleIntroSlide2(u8 taskId) static void BattleIntroSlide3(u8 taskId) { int i; + if (B_FAST_INTRO_NO_SLIDE || gTestRunnerHeadless) + return BattleIntroNoSlide(taskId); gBattle_BG1_X += 8; switch (gTasks[taskId].tState) diff --git a/src/battle_main.c b/src/battle_main.c index 3dad2c67d6..2391b4f370 100644 --- a/src/battle_main.c +++ b/src/battle_main.c @@ -487,21 +487,24 @@ static void CB2_InitBattleInternal(void) else { gBattle_WIN0V = WIN_RANGE(DISPLAY_HEIGHT / 2, DISPLAY_HEIGHT / 2 + 1); - ScanlineEffect_Clear(); - - for (i = 0; i < DISPLAY_HEIGHT / 2; i++) + if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless) { - gScanlineEffectRegBuffers[0][i] = 0xF0; - gScanlineEffectRegBuffers[1][i] = 0xF0; - } + ScanlineEffect_Clear(); - for (; i < DISPLAY_HEIGHT; i++) - { - gScanlineEffectRegBuffers[0][i] = 0xFF10; - gScanlineEffectRegBuffers[1][i] = 0xFF10; - } + for (i = 0; i < DISPLAY_HEIGHT / 2; i++) + { + gScanlineEffectRegBuffers[0][i] = 0xF0; + gScanlineEffectRegBuffers[1][i] = 0xF0; + } - ScanlineEffect_SetParams(sIntroScanlineParams16Bit); + for (; i < DISPLAY_HEIGHT; i++) + { + gScanlineEffectRegBuffers[0][i] = 0xFF10; + gScanlineEffectRegBuffers[1][i] = 0xFF10; + } + + ScanlineEffect_SetParams(sIntroScanlineParams16Bit); + } } ResetPaletteFade(); @@ -532,7 +535,8 @@ static void CB2_InitBattleInternal(void) LoadBattleTextboxAndBackground(); ResetSpriteData(); ResetTasks(); - DrawBattleEntryBackground(); + if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless) + DrawBattleEntryBackground(); FreeAllSpritePalettes(); gReservedSpritePaletteCount = MAX_BATTLERS_COUNT; SetVBlankCallback(VBlankCB_Battle); @@ -2650,17 +2654,24 @@ void SpriteCB_WildMon(struct Sprite *sprite) { sprite->callback = SpriteCB_MoveWildMonToRight; StartSpriteAnimIfDifferent(sprite, 0); - if (WILD_DOUBLE_BATTLE) - BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 10, RGB(8, 8, 8)); - else - BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 10, RGB(8, 8, 8)); + if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless) + { + if (WILD_DOUBLE_BATTLE) + BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 10, RGB(8, 8, 8)); + else + BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 10, RGB(8, 8, 8)); + } } static void SpriteCB_MoveWildMonToRight(struct Sprite *sprite) { if ((gIntroSlideFlags & 1) == 0) { - sprite->x2 += 2; + if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless) + sprite->x2 += 2; + else + sprite->x2 = 0; + if (sprite->x2 == 0) { sprite->callback = SpriteCB_WildMonShowHealthbox; @@ -2676,10 +2687,13 @@ static void SpriteCB_WildMonShowHealthbox(struct Sprite *sprite) SetHealthboxSpriteVisible(gHealthboxSpriteIds[sprite->sBattler]); sprite->callback = SpriteCB_WildMonAnimate; StartSpriteAnimIfDifferent(sprite, 0); - if (WILD_DOUBLE_BATTLE) - BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 0, RGB(8, 8, 8)); - else - BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 0, RGB(8, 8, 8)); + if (B_FAST_INTRO_NO_SLIDE == FALSE && !gTestRunnerHeadless) + { + if (WILD_DOUBLE_BATTLE) + BeginNormalPaletteFade((0x10000 << sprite->sBattler) | (0x10000 << BATTLE_PARTNER(sprite->sBattler)), 0, 10, 0, RGB(8, 8, 8)); + else + BeginNormalPaletteFade((0x10000 << sprite->sBattler), 0, 10, 0, RGB(8, 8, 8)); + } } } @@ -3561,7 +3575,7 @@ static void DoBattleIntro(void) } else // Skip party summary since it is a wild battle. { - if (B_FAST_INTRO == TRUE) + if (B_FAST_INTRO_PKMN_TEXT == TRUE) gBattleStruct->introState = BATTLE_INTRO_STATE_INTRO_TEXT; // Don't wait for sprite, print message at the same time. else gBattleStruct->introState++; // Wait for sprite to load. @@ -3633,7 +3647,7 @@ static void DoBattleIntro(void) } else { - if (B_FAST_INTRO == TRUE) + if (B_FAST_INTRO_PKMN_TEXT == TRUE) gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT; else gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_TRAINER_2_SEND_OUT_ANIM; @@ -3672,7 +3686,7 @@ static void DoBattleIntro(void) BtlController_EmitIntroTrainerBallThrow(battler, BUFFER_A); MarkBattlerForControllerExec(battler); } - if (B_FAST_INTRO == TRUE + if (B_FAST_INTRO_PKMN_TEXT == TRUE && !(gBattleTypeFlags & (BATTLE_TYPE_RECORDED | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_RECORDED_IS_MASTER | BATTLE_TYPE_LINK))) gBattleStruct->introState = BATTLE_INTRO_STATE_WAIT_FOR_WILD_BATTLE_TEXT; // Print at the same time as trainer sends out second mon. else @@ -3695,7 +3709,7 @@ static void DoBattleIntro(void) battler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); // A hack that makes fast intro work in trainer battles too. - if (B_FAST_INTRO == TRUE + if (B_FAST_INTRO_PKMN_TEXT == TRUE && gBattleTypeFlags & BATTLE_TYPE_TRAINER && !(gBattleTypeFlags & (BATTLE_TYPE_RECORDED | BATTLE_TYPE_RECORDED_LINK | BATTLE_TYPE_RECORDED_IS_MASTER | BATTLE_TYPE_LINK)) && gSprites[gHealthboxSpriteIds[battler ^ BIT_SIDE]].callback == SpriteCallbackDummy) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 055f9e9c3b..3c719049a6 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -2773,6 +2773,8 @@ static void Cmd_waitmessage(void) else { u16 toWait = cmd->time; + if (gTestRunnerHeadless) + gPauseCounterBattle = toWait; if (++gPauseCounterBattle >= toWait) { gPauseCounterBattle = 0; @@ -5273,6 +5275,8 @@ static void Cmd_pause(void) if (gBattleControllerExecFlags == 0) { u16 value = cmd->frames; + if (gTestRunnerHeadless) + gPauseCounterBattle = value; if (++gPauseCounterBattle >= value) { gPauseCounterBattle = 0; diff --git a/src/pokemon.c b/src/pokemon.c index c60e95cc6a..c5162ecfd0 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -39,6 +39,7 @@ #include "string_util.h" #include "strings.h" #include "task.h" +#include "test_runner.h" #include "text.h" #include "trainer_hill.h" #include "util.h" @@ -6277,7 +6278,7 @@ void HandleSetPokedexFlag(u16 nationalNum, u8 caseId, u32 personality) bool8 HasTwoFramesAnimation(u16 species) { - return P_TWO_FRAME_FRONT_SPRITES && species != SPECIES_UNOWN; + return P_TWO_FRAME_FRONT_SPRITES && species != SPECIES_UNOWN && !gTestRunnerHeadless; } static bool8 ShouldSkipFriendshipChange(void) @@ -6896,7 +6897,7 @@ void HealBoxPokemon(struct BoxPokemon *boxMon) u16 GetCryIdBySpecies(u16 species) { species = SanitizeSpeciesId(species); - if (P_CRIES_ENABLED == FALSE || gSpeciesInfo[species].cryId >= CRY_COUNT) + if (P_CRIES_ENABLED == FALSE || gSpeciesInfo[species].cryId >= CRY_COUNT || gTestRunnerHeadless) return CRY_NONE; return gSpeciesInfo[species].cryId; } diff --git a/src/pokemon_animation.c b/src/pokemon_animation.c index d7c0bb343c..6bd32ee514 100644 --- a/src/pokemon_animation.c +++ b/src/pokemon_animation.c @@ -5,6 +5,7 @@ #include "pokemon_animation.h" #include "sprite.h" #include "task.h" +#include "test_runner.h" #include "trig.h" #include "util.h" #include "data.h" @@ -508,7 +509,10 @@ static void Task_HandleMonAnimation(u8 taskId) for (i = 2; i < ARRAY_COUNT(sprite->data); i++) sprite->data[i] = 0; - sprite->callback = sMonAnimFunctions[gTasks[taskId].tAnimId]; + if (gTestRunnerHeadless) + sprite->callback = WaitAnimEnd; + else + sprite->callback = sMonAnimFunctions[gTasks[taskId].tAnimId]; sIsSummaryAnim = FALSE; gTasks[taskId].tState++; diff --git a/test/test_runner.c b/test/test_runner.c index 4715c19189..7a81d1dc9f 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -10,7 +10,7 @@ #include "test_runner.h" #include "test/test.h" -#define TIMEOUT_SECONDS 55 +#define TIMEOUT_SECONDS 60 void CB2_TestRunner(void); From 55f0d3aad5a420d2903b51ffc3655bc30bb0d7e8 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 1 Jan 2025 12:06:20 -0300 Subject: [PATCH 2/8] Added missing Move Effect TODO tests - Volume E (#5915) Co-authored-by: Bassoonian --- test/battle/ability/electric_surge.c | 4 + test/battle/ability/grassy_surge.c | 4 + test/battle/ability/mimicry.c | 72 +++++++++ test/battle/ability/misty_surge.c | 4 + test/battle/ability/psychic_surge.c | 4 + test/battle/gimmick/dynamax.c | 35 ---- test/battle/hold_effect/seeds.c | 62 +++++++ test/battle/move_effect/beak_blast.c | 1 + test/battle/move_effect/echoed_voice.c | 7 + .../electric_terrain.c} | 19 --- test/battle/move_effect/electrify.c | 5 + test/battle/move_effect/electro_ball.c | 5 + test/battle/move_effect/encore.c | 152 +++++++++--------- test/battle/move_effect/endeavor.c | 6 + test/battle/move_effect/endure.c | 35 ++++ test/battle/move_effect/entrainment.c | 6 + test/battle/move_effect/evasion_down.c | 4 + test/battle/move_effect/evasion_down_2.c | 4 + test/battle/move_effect/evasion_up.c | 2 +- test/battle/move_effect/evasion_up_2.c | 28 ++++ test/battle/move_effect/expanding_force.c | 4 + test/battle/move_effect/extreme_evoboost.c | 4 + .../grassy.c => move_effect/grassy_terrain.c} | 19 --- .../move_effect/hit_set_remove_terrain.c | 36 +---- .../misty.c => move_effect/misty_terrain.c} | 19 --- test/battle/move_effect/multi_hit.c | 24 --- .../psychic_terrain.c} | 19 --- .../terrain.c} | 0 28 files changed, 341 insertions(+), 243 deletions(-) create mode 100644 test/battle/ability/electric_surge.c create mode 100644 test/battle/ability/grassy_surge.c create mode 100644 test/battle/ability/mimicry.c create mode 100644 test/battle/ability/misty_surge.c create mode 100644 test/battle/ability/psychic_surge.c create mode 100644 test/battle/hold_effect/seeds.c create mode 100644 test/battle/move_effect/echoed_voice.c rename test/battle/{terrain/electric.c => move_effect/electric_terrain.c} (74%) create mode 100644 test/battle/move_effect/electrify.c create mode 100644 test/battle/move_effect/electro_ball.c create mode 100644 test/battle/move_effect/endeavor.c create mode 100644 test/battle/move_effect/endure.c create mode 100644 test/battle/move_effect/entrainment.c create mode 100644 test/battle/move_effect/evasion_down.c create mode 100644 test/battle/move_effect/evasion_down_2.c create mode 100644 test/battle/move_effect/evasion_up_2.c create mode 100644 test/battle/move_effect/expanding_force.c create mode 100644 test/battle/move_effect/extreme_evoboost.c rename test/battle/{terrain/grassy.c => move_effect/grassy_terrain.c} (80%) rename test/battle/{terrain/misty.c => move_effect/misty_terrain.c} (78%) rename test/battle/{terrain/psychic.c => move_effect/psychic_terrain.c} (84%) rename test/battle/{terrain/starting_terrain.c => starting_status/terrain.c} (100%) diff --git a/test/battle/ability/electric_surge.c b/test/battle/ability/electric_surge.c new file mode 100644 index 0000000000..3509f1c687 --- /dev/null +++ b/test/battle/ability/electric_surge.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Electric Surge creates Electric Terrain when entering the battle"); diff --git a/test/battle/ability/grassy_surge.c b/test/battle/ability/grassy_surge.c new file mode 100644 index 0000000000..ccdb471d9f --- /dev/null +++ b/test/battle/ability/grassy_surge.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Grassy Surge creates Grassy Terrain when entering the battle"); diff --git a/test/battle/ability/mimicry.c b/test/battle/ability/mimicry.c new file mode 100644 index 0000000000..fbdb5cf98a --- /dev/null +++ b/test/battle/ability/mimicry.c @@ -0,0 +1,72 @@ +#include "global.h" +#include "test/battle.h" + +static const u16 terrainData[][2] = +{ + { MOVE_ELECTRIC_TERRAIN, TYPE_ELECTRIC, }, + { MOVE_PSYCHIC_TERRAIN, TYPE_PSYCHIC, }, + { MOVE_GRASSY_TERRAIN, TYPE_GRASS, }, + { MOVE_MISTY_TERRAIN, TYPE_FAIRY, }, +}; + +SINGLE_BATTLE_TEST("Mimicry changes the battler's type based on Terrain") +{ + u32 j; + u32 terrainMove = MOVE_NONE; + u32 terrainType = TYPE_NONE; + + for (j = 0; j < ARRAY_COUNT(terrainData); j++) + PARAMETRIZE { terrainMove = terrainData[j][0]; terrainType = terrainData[j][1]; } + + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } + } WHEN { + TURN { MOVE(player, terrainMove); } + } SCENE { + ABILITY_POPUP(opponent); + switch (terrainMove) + { + case MOVE_ELECTRIC_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Electric!"); break; + case MOVE_PSYCHIC_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Psychic!"); break; + case MOVE_GRASSY_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Grass!"); break; + case MOVE_MISTY_TERRAIN: MESSAGE("The opposing Stunfisk's type changed to Fairy!"); break; + } + } THEN { + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], terrainType); + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[1], terrainType); + } +} + +SINGLE_BATTLE_TEST("Mimicry restores the battler's types when terrain is removed by Steel Roller and Ice Spinner") +{ + u32 j; + u32 terrainMove = MOVE_NONE; + u32 removeTerrainMove = MOVE_NONE; + + for (j = 0; j < ARRAY_COUNT(terrainData); j++) + { + PARAMETRIZE { removeTerrainMove = MOVE_STEEL_ROLLER; terrainMove = terrainData[j][0]; } + PARAMETRIZE { removeTerrainMove = MOVE_ICE_SPINNER; terrainMove = terrainData[j][0]; } + } + + GIVEN { + ASSUME(gSpeciesInfo[SPECIES_STUNFISK_GALAR].types[0] == TYPE_GROUND); + ASSUME(gSpeciesInfo[SPECIES_STUNFISK_GALAR].types[1] == TYPE_STEEL); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } + } WHEN { + TURN { MOVE(opponent, terrainMove); MOVE(player, removeTerrainMove); } + } SCENE { + switch (terrainMove) + { + case MOVE_ELECTRIC_TERRAIN: MESSAGE("The electricity disappeared from the battlefield."); break; + case MOVE_PSYCHIC_TERRAIN: MESSAGE("The weirdness disappeared from the battlefield!"); break; + case MOVE_GRASSY_TERRAIN: MESSAGE("The grass disappeared from the battlefield."); break; + case MOVE_MISTY_TERRAIN: MESSAGE("The mist disappeared from the battlefield."); break; + } + } THEN { + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_GROUND); + EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[1], TYPE_STEEL); + } +} diff --git a/test/battle/ability/misty_surge.c b/test/battle/ability/misty_surge.c new file mode 100644 index 0000000000..229d26c3ba --- /dev/null +++ b/test/battle/ability/misty_surge.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Misty Surge creates Misty Terrain when entering the battle"); diff --git a/test/battle/ability/psychic_surge.c b/test/battle/ability/psychic_surge.c new file mode 100644 index 0000000000..d840e8d440 --- /dev/null +++ b/test/battle/ability/psychic_surge.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Psychic Surge creates Psychic Terrain when entering the battle"); diff --git a/test/battle/gimmick/dynamax.c b/test/battle/gimmick/dynamax.c index 33199a77fe..f910f551a4 100644 --- a/test/battle/gimmick/dynamax.c +++ b/test/battle/gimmick/dynamax.c @@ -227,41 +227,6 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can have their ability changed o } } -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Encore") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); MOVE(opponent, MOVE_ENCORE); } - TURN { MOVE(player, MOVE_EMBER); } - } SCENE { - MESSAGE("Wobbuffet used Max Strike!"); - MESSAGE("The opposing Wobbuffet used Encore!"); - MESSAGE("But it failed!"); - MESSAGE("Wobbuffet used Max Flare!"); - } -} - -SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can be encored immediately after reverting") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(50); }; // yes, this speed is necessary - OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }; - } WHEN { - TURN { MOVE(player, MOVE_ARM_THRUST, gimmick: GIMMICK_DYNAMAX); } - TURN { MOVE(player, MOVE_ARM_THRUST); } - TURN { MOVE(player, MOVE_ARM_THRUST); } - TURN { MOVE(opponent, MOVE_ENCORE); MOVE(player, MOVE_TACKLE); } - } SCENE { - MESSAGE("Wobbuffet used Max Knuckle!"); - MESSAGE("Wobbuffet used Max Knuckle!"); - MESSAGE("Wobbuffet used Max Knuckle!"); - MESSAGE("The opposing Wobbuffet used Encore!"); - MESSAGE("Wobbuffet used Arm Thrust!"); - } -} - // Max Moves don't make contact, so Cursed Body doesn't need to be tested, but it is coded for. SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon's Max Moves cannot be disabled") { diff --git a/test/battle/hold_effect/seeds.c b/test/battle/hold_effect/seeds.c new file mode 100644 index 0000000000..10a415bd63 --- /dev/null +++ b/test/battle/hold_effect/seeds.c @@ -0,0 +1,62 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Electric Seed raises the holder's Defense on Electric Terrain") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffect == HOLD_EFFECT_SEEDS); + ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_ELECTRIC_SEED); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_ELECTRIC_TERRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Electric Seed, the Defense of Wobbuffet rose!"); + } +} + +SINGLE_BATTLE_TEST("Grassy Seed raises the holder's Defense on Grassy Terrain") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffect == HOLD_EFFECT_SEEDS); + ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_GRASSY_TERRAIN); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GRASSY_SEED); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_GRASSY_TERRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Grassy Seed, the Defense of Wobbuffet rose!"); + } +} + +SINGLE_BATTLE_TEST("Misty Seed raises the holder's Sp. Defense on Misty Terrain") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffect == HOLD_EFFECT_SEEDS); + ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_MISTY_TERRAIN); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_MISTY_SEED); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_MISTY_TERRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Misty Seed, the Sp. Def of Wobbuffet rose!"); + } +} + +SINGLE_BATTLE_TEST("Psychic Seed raises the holder's Sp. Defense on Psychic Terrain") +{ + GIVEN { + ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffect == HOLD_EFFECT_SEEDS); + ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN); + PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_PSYCHIC_SEED); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_PSYCHIC_TERRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Using Psychic Seed, the Sp. Def of Wobbuffet rose!"); + } +} diff --git a/test/battle/move_effect/beak_blast.c b/test/battle/move_effect/beak_blast.c index e716b7717f..a07b28f992 100644 --- a/test/battle/move_effect/beak_blast.c +++ b/test/battle/move_effect/beak_blast.c @@ -113,4 +113,5 @@ SINGLE_BATTLE_TEST("Beak Blast burns only when contact moves are used") } TO_DO_BATTLE_TEST("Beak Blast's charging message is shown regardless if it would've missed"); +TO_DO_BATTLE_TEST("Beak Blast fails if it's forced by Encore after choosing a different move"); TO_DO_BATTLE_TEST("Bulletproof is immune to Beak Blast but not to the burn it causes"); diff --git a/test/battle/move_effect/echoed_voice.c b/test/battle/move_effect/echoed_voice.c new file mode 100644 index 0000000000..3c36270454 --- /dev/null +++ b/test/battle/move_effect/echoed_voice.c @@ -0,0 +1,7 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Echoed Voice's power is multiplied for every consecutive turn used, capped at 5"); +TO_DO_BATTLE_TEST("Echoed Voice's power is reset when using a different move"); +TO_DO_BATTLE_TEST("Echoed Voice's power is increased even if it misses"); +TO_DO_BATTLE_TEST("Echoed Voice's power is increased even if it's blocked by Protect"); diff --git a/test/battle/terrain/electric.c b/test/battle/move_effect/electric_terrain.c similarity index 74% rename from test/battle/terrain/electric.c rename to test/battle/move_effect/electric_terrain.c index b3811d056c..bf6d2536e6 100644 --- a/test/battle/terrain/electric.c +++ b/test/battle/move_effect/electric_terrain.c @@ -19,25 +19,6 @@ SINGLE_BATTLE_TEST("Electric Terrain protects grounded battlers from falling asl } } -SINGLE_BATTLE_TEST("Electric Terrain activates Electric Seed and Mimicry") -{ - GIVEN { - ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffect == HOLD_EFFECT_SEEDS); - ASSUME(gItemsInfo[ITEM_ELECTRIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_ELECTRIC_TERRAIN); - PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_ELECTRIC_SEED); } - OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } - } WHEN { - TURN { MOVE(player, MOVE_ELECTRIC_TERRAIN); } - } SCENE { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Electric Seed, the Defense of Wobbuffet rose!"); - ABILITY_POPUP(opponent); - MESSAGE("The opposing Stunfisk's type changed to Electric!"); - } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_ELECTRIC); - } -} - SINGLE_BATTLE_TEST("Electric Terrain increases power of Electric-type moves by 30/50 percent", s16 damage) { bool32 terrain; diff --git a/test/battle/move_effect/electrify.c b/test/battle/move_effect/electrify.c new file mode 100644 index 0000000000..71373cdd58 --- /dev/null +++ b/test/battle/move_effect/electrify.c @@ -0,0 +1,5 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Electrify makes the target's move Electric-type for the remainder of the turn"); +TO_DO_BATTLE_TEST("Electrify can change status moves to Electric-type"); // Test type immunity diff --git a/test/battle/move_effect/electro_ball.c b/test/battle/move_effect/electro_ball.c new file mode 100644 index 0000000000..a74445c00c --- /dev/null +++ b/test/battle/move_effect/electro_ball.c @@ -0,0 +1,5 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Electro Ball inflicts more damage the faster the user is compared to the target"); +TO_DO_BATTLE_TEST("Electro Ball considers speed modifiers"); // Stat modifiers, paralysis, Iron Ball, Abilities diff --git a/test/battle/move_effect/encore.c b/test/battle/move_effect/encore.c index ec68297ca0..dc7968b2a5 100644 --- a/test/battle/move_effect/encore.c +++ b/test/battle/move_effect/encore.c @@ -6,91 +6,56 @@ ASSUMPTIONS ASSUME(gMovesInfo[MOVE_ENCORE].effect == EFFECT_ENCORE); } -SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for player: Encore used before move") +SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns: Encore used before move") { + struct BattlePokemon *encoreUser = NULL; + struct BattlePokemon *encoreTarget = NULL; + u32 speedPlayer, speedOpponent; + PARAMETRIZE { encoreUser = opponent; encoreTarget = player; speedPlayer = 10; speedOpponent = 20; } + PARAMETRIZE { encoreUser = player; encoreTarget = opponent; speedPlayer = 20; speedOpponent = 10; } GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(10); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(20); } + PLAYER(SPECIES_WOBBUFFET) { Speed(speedPlayer); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(speedOpponent); } } WHEN { - TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_CELEBRATE); } - TURN { MOVE(opponent, MOVE_ENCORE); MOVE(player, MOVE_CELEBRATE); } - // TURN { FORCED_MOVE(player); } - TURN { FORCED_MOVE(player); } - TURN { FORCED_MOVE(player); } - TURN { MOVE(player, MOVE_SPLASH); } + TURN { MOVE(encoreUser, MOVE_CELEBRATE); MOVE(encoreTarget, MOVE_CELEBRATE); } + TURN { MOVE(encoreUser, MOVE_ENCORE); MOVE(encoreTarget, MOVE_CELEBRATE); } + TURN { FORCED_MOVE(encoreTarget); } + TURN { FORCED_MOVE(encoreTarget); } + TURN { MOVE(encoreTarget, MOVE_SPLASH); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreUser); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, encoreUser); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, encoreTarget); } } SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for player: Encore used after move") { + struct BattlePokemon *encoreUser = NULL; + struct BattlePokemon *encoreTarget = NULL; + u32 speedPlayer, speedOpponent; + PARAMETRIZE { encoreUser = opponent; encoreTarget = player; speedPlayer = 20; speedOpponent = 10; } + PARAMETRIZE { encoreUser = player; encoreTarget = opponent; speedPlayer = 10; speedOpponent = 20; } GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(20); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(10); } + PLAYER(SPECIES_WOBBUFFET) { Speed(speedPlayer); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(speedOpponent); } } WHEN { - TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_ENCORE); } - TURN { FORCED_MOVE(player); } - TURN { FORCED_MOVE(player); } - TURN { FORCED_MOVE(player); } - TURN { MOVE(player, MOVE_SPLASH); } + TURN { MOVE(encoreTarget, MOVE_CELEBRATE); MOVE(encoreUser, MOVE_ENCORE); } + TURN { FORCED_MOVE(encoreTarget); } + TURN { FORCED_MOVE(encoreTarget); } + TURN { FORCED_MOVE(encoreTarget); } + TURN { MOVE(encoreTarget, MOVE_SPLASH); } } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, player); - } -} - -SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for opponent: Encore used before move") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(20); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(10); } - } WHEN { - TURN { MOVE(player, MOVE_CELEBRATE); MOVE(opponent, MOVE_CELEBRATE); } - TURN { MOVE(player, MOVE_ENCORE); MOVE(opponent, MOVE_CELEBRATE); } - // TURN { FORCED_MOVE(opponent); } - TURN { FORCED_MOVE(opponent); } - TURN { FORCED_MOVE(opponent); } - TURN { MOVE(opponent, MOVE_SPLASH); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, opponent); - } -} - -SINGLE_BATTLE_TEST("Encore forces consecutive move uses for 3 turns for opponent: Encore used after move") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { Speed(10); } - OPPONENT(SPECIES_WOBBUFFET) { Speed(20); } - } WHEN { - TURN { MOVE(opponent, MOVE_CELEBRATE); MOVE(player, MOVE_ENCORE); } - TURN { FORCED_MOVE(opponent); } - TURN { FORCED_MOVE(opponent); } - TURN { FORCED_MOVE(opponent); } - TURN { MOVE(opponent, MOVE_SPLASH); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_ENCORE, encoreUser); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, encoreTarget); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, encoreTarget); } } @@ -121,3 +86,44 @@ SINGLE_BATTLE_TEST("Encore overrides the chosen move if it occurs first") ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); } } + +SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon are immune to Encore") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); MOVE(opponent, MOVE_ENCORE); } + TURN { MOVE(player, MOVE_EMBER); } + } SCENE { + MESSAGE("Wobbuffet used Max Strike!"); + MESSAGE("The opposing Wobbuffet used Encore!"); + MESSAGE("But it failed!"); + MESSAGE("Wobbuffet used Max Flare!"); + } +} + +SINGLE_BATTLE_TEST("(DYNAMAX) Dynamaxed Pokemon can be encored immediately after reverting") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { Speed(50); }; // yes, this speed is necessary + OPPONENT(SPECIES_WOBBUFFET) { Speed(100); }; + } WHEN { + TURN { MOVE(player, MOVE_ARM_THRUST, gimmick: GIMMICK_DYNAMAX); } + TURN { MOVE(player, MOVE_ARM_THRUST); } + TURN { MOVE(player, MOVE_ARM_THRUST); } + TURN { MOVE(opponent, MOVE_ENCORE); MOVE(player, MOVE_TACKLE); } + } SCENE { + MESSAGE("Wobbuffet used Max Knuckle!"); + MESSAGE("Wobbuffet used Max Knuckle!"); + MESSAGE("Wobbuffet used Max Knuckle!"); + MESSAGE("The opposing Wobbuffet used Encore!"); + MESSAGE("Wobbuffet used Arm Thrust!"); + } +} + +TO_DO_BATTLE_TEST("Encore's effect ends if the encored move runs out of PP"); +TO_DO_BATTLE_TEST("Encore lasts for 2-6 turns (Gen 2-3)"); +TO_DO_BATTLE_TEST("Encore lasts for 4-8 turns (Gen 4)"); +TO_DO_BATTLE_TEST("Encore lasts for 3 turns (Gen 5+)"); +TO_DO_BATTLE_TEST("Encore randomly chooses an opponent target"); diff --git a/test/battle/move_effect/endeavor.c b/test/battle/move_effect/endeavor.c new file mode 100644 index 0000000000..72eeaccdaf --- /dev/null +++ b/test/battle/move_effect/endeavor.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Endeavor sets the the target's HP to the user's current HP"); +TO_DO_BATTLE_TEST("Endeavor doesn't fail if the user's HP is greater or equal than the target, but it doesn't heal the target"); +TO_DO_BATTLE_TEST("Endeavor fails on Ghost-type Pokémon"); diff --git a/test/battle/move_effect/endure.c b/test/battle/move_effect/endure.c new file mode 100644 index 0000000000..04f150d3ce --- /dev/null +++ b/test/battle/move_effect/endure.c @@ -0,0 +1,35 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Endure allows the user to survive any attack with 1 HP left"); + +SINGLE_BATTLE_TEST("Endure does not prevent multiple hits and stat changes occur at the end of the turn") +{ + GIVEN { + ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT); + ASSUME(gMovesInfo[MOVE_ENDURE].effect == EFFECT_ENDURE); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { HP(1); } + } WHEN { + TURN { MOVE(opponent, MOVE_ENDURE); MOVE(player, MOVE_SCALE_SHOT); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_ENDURE, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); + MESSAGE("The Pokémon was hit 5 time(s)!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Defense fell!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's Speed rose!"); + } +} + +TO_DO_BATTLE_TEST("Endure's success rate decreases for every consecutively used turn"); +TO_DO_BATTLE_TEST("Endure uses the same counter as Protect"); +TO_DO_BATTLE_TEST("Endure doesn't trigger effects that require damage to be done to the Pokémon (Gen 2-4)"); // Eg. Rough Skin +TO_DO_BATTLE_TEST("Endure triggers effects that require damage to be done to the Pokémon (Gen 5+)"); // Eg. Rough Skin +TO_DO_BATTLE_TEST("Endure doesn't protect against Future Sight (Gen 2-4)"); +TO_DO_BATTLE_TEST("Endure protects against Future Sight (Gen 5+)"); diff --git a/test/battle/move_effect/entrainment.c b/test/battle/move_effect/entrainment.c new file mode 100644 index 0000000000..b43f6dcbc1 --- /dev/null +++ b/test/battle/move_effect/entrainment.c @@ -0,0 +1,6 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Entrainment changes the target's Ability to match the user's"); +TO_DO_BATTLE_TEST("Entrainment fails if the user's ability has cantBeCopied flag"); +TO_DO_BATTLE_TEST("Entrainment fails if the targets's ability has cantBeOverwritten flag"); diff --git a/test/battle/move_effect/evasion_down.c b/test/battle/move_effect/evasion_down.c new file mode 100644 index 0000000000..ecc0db135b --- /dev/null +++ b/test/battle/move_effect/evasion_down.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Sweet Scent lowers evasion by 1 stage (Gen 2-5)"); diff --git a/test/battle/move_effect/evasion_down_2.c b/test/battle/move_effect/evasion_down_2.c new file mode 100644 index 0000000000..7584406e4c --- /dev/null +++ b/test/battle/move_effect/evasion_down_2.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Sweet Scent lowers evasion by 1 stage (Gen 6+)"); diff --git a/test/battle/move_effect/evasion_up.c b/test/battle/move_effect/evasion_up.c index 7058694e9d..48722a7596 100644 --- a/test/battle/move_effect/evasion_up.c +++ b/test/battle/move_effect/evasion_up.c @@ -6,7 +6,7 @@ ASSUMPTIONS ASSUME(gMovesInfo[MOVE_DOUBLE_TEAM].effect == EFFECT_EVASION_UP); } -SINGLE_BATTLE_TEST("Double Team raises Evasion") +SINGLE_BATTLE_TEST("Double Team raises Evasion by 1 stage") { PASSES_RANDOMLY(gMovesInfo[MOVE_SCRATCH].accuracy * 3 / 4, 100, RNG_ACCURACY); GIVEN { diff --git a/test/battle/move_effect/evasion_up_2.c b/test/battle/move_effect/evasion_up_2.c new file mode 100644 index 0000000000..cd5cb543a9 --- /dev/null +++ b/test/battle/move_effect/evasion_up_2.c @@ -0,0 +1,28 @@ +#include "global.h" +#include "test/battle.h" + +// There's no move with EFFECT_EVASION_UP_2 effect. Below is a theoretical test. + +/* +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_X].effect == EFFECT_EVASION_UP_2); +} + +SINGLE_BATTLE_TEST("Double Team raises Evasion by 1 stage") +{ + PASSES_RANDOMLY(gMovesInfo[MOVE_SCRATCH].accuracy * 3 / 5, 100, RNG_ACCURACY); + GIVEN { + ASSUME(gMovesInfo[MOVE_SCRATCH].accuracy == 100); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_X); MOVE(opponent, MOVE_SCRATCH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_X, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet's evasiveness sharply rose!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, opponent); + } +} +*/ diff --git a/test/battle/move_effect/expanding_force.c b/test/battle/move_effect/expanding_force.c new file mode 100644 index 0000000000..74b78fdd86 --- /dev/null +++ b/test/battle/move_effect/expanding_force.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Expanding Force's power increases by 50% if the user is affected by Psychic Terrain"); diff --git a/test/battle/move_effect/extreme_evoboost.c b/test/battle/move_effect/extreme_evoboost.c new file mode 100644 index 0000000000..c43a6f7374 --- /dev/null +++ b/test/battle/move_effect/extreme_evoboost.c @@ -0,0 +1,4 @@ +#include "global.h" +#include "test/battle.h" + +TO_DO_BATTLE_TEST("Extreme Evoboost increases the user's Attack, Defense, Special Attack, Special Defense, and Speed stats by 2 stages each"); diff --git a/test/battle/terrain/grassy.c b/test/battle/move_effect/grassy_terrain.c similarity index 80% rename from test/battle/terrain/grassy.c rename to test/battle/move_effect/grassy_terrain.c index b247933dd2..90e878b6dd 100644 --- a/test/battle/terrain/grassy.c +++ b/test/battle/move_effect/grassy_terrain.c @@ -18,25 +18,6 @@ SINGLE_BATTLE_TEST("Grassy Terrain recovers 1/16th HP at end of turn") } } -SINGLE_BATTLE_TEST("Grassy Terrain activates Grassy Seed and Mimicry") -{ - GIVEN { - ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffect == HOLD_EFFECT_SEEDS); - ASSUME(gItemsInfo[ITEM_GRASSY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_GRASSY_TERRAIN); - PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GRASSY_SEED); } - OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } - } WHEN { - TURN { MOVE(player, MOVE_GRASSY_TERRAIN); } - } SCENE { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Grassy Seed, the Defense of Wobbuffet rose!"); - ABILITY_POPUP(opponent); - MESSAGE("The opposing Stunfisk's type changed to Grass!"); - } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_GRASS); - } -} - SINGLE_BATTLE_TEST("Grassy Terrain increases power of Grass-type moves by 30/50 percent", s16 damage) { bool32 terrain; diff --git a/test/battle/move_effect/hit_set_remove_terrain.c b/test/battle/move_effect/hit_set_remove_terrain.c index a48d316d3f..feeca62560 100644 --- a/test/battle/move_effect/hit_set_remove_terrain.c +++ b/test/battle/move_effect/hit_set_remove_terrain.c @@ -83,7 +83,7 @@ SINGLE_BATTLE_TEST("Ice Spinner doesn't fail if there is no terrain on the field } } -AI_SINGLE_BATTLE_TEST("Steel Roller will not be chosen by the AI if it might fail") +AI_SINGLE_BATTLE_TEST("AI will not choose Steel Roller if it might fail") { u32 move; @@ -104,7 +104,7 @@ AI_SINGLE_BATTLE_TEST("Steel Roller will not be chosen by the AI if it might fai } } -AI_SINGLE_BATTLE_TEST("Ice Spinner can be chosen by the AI regardless if there is a terrain or not") +AI_SINGLE_BATTLE_TEST("AI will can choose Ice Spinner regardless if there is a terrain or not") { u32 move; @@ -124,35 +124,3 @@ AI_SINGLE_BATTLE_TEST("Ice Spinner can be chosen by the AI regardless if there i } } } - -SINGLE_BATTLE_TEST("Steel Roller and Ice Spinner reverts typing on Mimicry users") -{ - u32 j; - static const u16 terrainMoves[] = - { - MOVE_ELECTRIC_TERRAIN, - MOVE_PSYCHIC_TERRAIN, - MOVE_GRASSY_TERRAIN, - MOVE_MISTY_TERRAIN, - }; - - u16 terrainMove = MOVE_NONE; - u16 removeTerrainMove = MOVE_NONE; - - for (j = 0; j < ARRAY_COUNT(terrainMoves); j++) - { - PARAMETRIZE { removeTerrainMove = MOVE_STEEL_ROLLER; terrainMove = terrainMoves[j]; } - PARAMETRIZE { removeTerrainMove = MOVE_ICE_SPINNER; terrainMove = terrainMoves[j]; } - } - - GIVEN { - ASSUME(gSpeciesInfo[SPECIES_STUNFISK_GALAR].types[1] == TYPE_STEEL); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } - } WHEN { - TURN { MOVE(opponent, terrainMove); MOVE(player, removeTerrainMove); } - TURN { MOVE(player, MOVE_TOXIC); } - } SCENE { - MESSAGE("It doesn't affect the opposing Stunfisk…"); - } -} diff --git a/test/battle/terrain/misty.c b/test/battle/move_effect/misty_terrain.c similarity index 78% rename from test/battle/terrain/misty.c rename to test/battle/move_effect/misty_terrain.c index e43cf4a253..b96f0c650d 100644 --- a/test/battle/terrain/misty.c +++ b/test/battle/move_effect/misty_terrain.c @@ -19,25 +19,6 @@ SINGLE_BATTLE_TEST("Misty Terrain protects grounded battlers from non-volatile s } } -SINGLE_BATTLE_TEST("Misty Terrain activates Misty Seed and Mimicry") -{ - GIVEN { - ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffect == HOLD_EFFECT_SEEDS); - ASSUME(gItemsInfo[ITEM_MISTY_SEED].holdEffectParam == HOLD_EFFECT_PARAM_MISTY_TERRAIN); - PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_MISTY_SEED); } - OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } - } WHEN { - TURN { MOVE(player, MOVE_MISTY_TERRAIN); } - } SCENE { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Misty Seed, the Sp. Def of Wobbuffet rose!"); - ABILITY_POPUP(opponent); - MESSAGE("The opposing Stunfisk's type changed to Fairy!"); - } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_FAIRY); - } -} - SINGLE_BATTLE_TEST("Misty Terrain does not increase the power of Fairy-type moves", s16 damage) { bool32 terrain; diff --git a/test/battle/move_effect/multi_hit.c b/test/battle/move_effect/multi_hit.c index e2331efbf7..802c4f455e 100644 --- a/test/battle/move_effect/multi_hit.c +++ b/test/battle/move_effect/multi_hit.c @@ -200,30 +200,6 @@ DOUBLE_BATTLE_TEST("Scale Shot does not corrupt the next turn move used") } } -SINGLE_BATTLE_TEST("Endure does not prevent multiple hits and stat changes occur at the end of the turn") -{ - GIVEN { - ASSUME(gMovesInfo[MOVE_SCALE_SHOT].effect == EFFECT_MULTI_HIT); - ASSUME(gMovesInfo[MOVE_ENDURE].effect == EFFECT_ENDURE); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET) { HP(1); } - } WHEN { - TURN { MOVE(opponent, MOVE_ENDURE); MOVE(player, MOVE_SCALE_SHOT); } - } SCENE { - ANIMATION(ANIM_TYPE_MOVE, MOVE_ENDURE, opponent); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); - ANIMATION(ANIM_TYPE_MOVE, MOVE_SCALE_SHOT, player); - MESSAGE("The Pokémon was hit 5 time(s)!"); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Wobbuffet's Defense fell!"); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Wobbuffet's Speed rose!"); - } -} - SINGLE_BATTLE_TEST("Scale Shot decreases defense and increases speed after the 4th hit of Loaded Dice") { PASSES_RANDOMLY(50, 100, RNG_LOADED_DICE); diff --git a/test/battle/terrain/psychic.c b/test/battle/move_effect/psychic_terrain.c similarity index 84% rename from test/battle/terrain/psychic.c rename to test/battle/move_effect/psychic_terrain.c index 9ac88f29da..b85653a0be 100644 --- a/test/battle/terrain/psychic.c +++ b/test/battle/move_effect/psychic_terrain.c @@ -18,25 +18,6 @@ SINGLE_BATTLE_TEST("Psychic Terrain protects grounded battlers from priority mov } } -SINGLE_BATTLE_TEST("Psychic Terrain activates Psychic Seed and Mimicry") -{ - GIVEN { - ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffect == HOLD_EFFECT_SEEDS); - ASSUME(gItemsInfo[ITEM_PSYCHIC_SEED].holdEffectParam == HOLD_EFFECT_PARAM_PSYCHIC_TERRAIN); - PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_PSYCHIC_SEED); } - OPPONENT(SPECIES_STUNFISK_GALAR) { Ability(ABILITY_MIMICRY); } - } WHEN { - TURN { MOVE(player, MOVE_PSYCHIC_TERRAIN); } - } SCENE { - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - MESSAGE("Using Psychic Seed, the Sp. Def of Wobbuffet rose!"); - ABILITY_POPUP(opponent); - MESSAGE("The opposing Stunfisk's type changed to Psychic!"); - } THEN { - EXPECT_EQ(gBattleMons[B_POSITION_OPPONENT_LEFT].types[0], TYPE_PSYCHIC); - } -} - SINGLE_BATTLE_TEST("Psychic Terrain increases power of Psychic-type moves by 30/50 percent", s16 damage) { bool32 terrain; diff --git a/test/battle/terrain/starting_terrain.c b/test/battle/starting_status/terrain.c similarity index 100% rename from test/battle/terrain/starting_terrain.c rename to test/battle/starting_status/terrain.c From 8d818445d29a820829e28d04579f492b0d35233c Mon Sep 17 00:00:00 2001 From: Pawkkie <61265402+Pawkkie@users.noreply.github.com> Date: Wed, 1 Jan 2025 13:29:45 -0500 Subject: [PATCH 3/8] Fixed ace switching bugs (#5922) --- src/battle_ai_switch_items.c | 19 +++++------- test/battle/ai/ai_switching.c | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index b41daa741b..f6e0facb12 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -917,7 +917,6 @@ bool32 ShouldSwitch(u32 battler) struct Pokemon *party; s32 i; s32 availableToSwitch; - bool32 hasAceMon = FALSE; if (gBattleMons[battler].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION)) return FALSE; @@ -966,7 +965,6 @@ bool32 ShouldSwitch(u32 battler) continue; if (IsAceMon(battler, i)) { - hasAceMon = TRUE; continue; } @@ -974,12 +972,7 @@ bool32 ShouldSwitch(u32 battler) } if (availableToSwitch == 0) - { - if (hasAceMon) // If the ace mon is the only available mon, use it - availableToSwitch++; - else return FALSE; - } // NOTE: The sequence of the below functions matter! Do not change unless you have carefully considered the outcome. // Since the order is sequencial, and some of these functions prompt switch to specific party members. @@ -1771,7 +1764,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, { int revengeKillerId = PARTY_SIZE, slowRevengeKillerId = PARTY_SIZE, fastThreatenId = PARTY_SIZE, slowThreatenId = PARTY_SIZE, damageMonId = PARTY_SIZE; int batonPassId = PARTY_SIZE, typeMatchupId = PARTY_SIZE, typeMatchupEffectiveId = PARTY_SIZE, defensiveMonId = PARTY_SIZE, aceMonId = PARTY_SIZE, trapperId = PARTY_SIZE; - int i, j, aliveCount = 0, bits = 0; + int i, j, aliveCount = 0, bits = 0, aceMonCount = 0; s32 defensiveMonHitKOThreshold = 3; // 3HKO threshold that candidate defensive mons must exceed s32 playerMonHP = gBattleMons[opposingBattler].hp, maxDamageDealt = 0, damageDealt = 0; u32 aiMove, hitsToKOAI, maxHitsToKO = 0; @@ -1794,6 +1787,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, else if (IsAceMon(battler, i)) { aceMonId = i; + aceMonCount++; continue; } else @@ -1940,7 +1934,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId, else if (batonPassId != PARTY_SIZE) return batonPassId; } // If ace mon is the last available Pokemon and U-Turn/Volt Switch was used - switch to the mon. - if (aceMonId != PARTY_SIZE && IsSwitchOutEffect(gMovesInfo[gLastUsedMove].effect)) + if (aceMonId != PARTY_SIZE && CountUsablePartyMons(battler) <= aceMonCount && IsSwitchOutEffect(gMovesInfo[gLastUsedMove].effect)) return aceMonId; return PARTY_SIZE; @@ -2018,7 +2012,7 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd) // This all handled by the GetBestMonIntegrated function if the AI_FLAG_SMART_MON_CHOICES flag is set else { - s32 i, aliveCount = 0; + s32 i, aliveCount = 0, aceMonCount = 0; u32 invalidMons = 0, aceMonId = PARTY_SIZE; // Get invalid slots ids. for (i = firstId; i < lastId; i++) @@ -2035,6 +2029,7 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd) else if (IsAceMon(battler, i)) // Save Ace Pokemon for last. { aceMonId = i; + aceMonCount++; invalidMons |= 1u << i; } else @@ -2054,8 +2049,8 @@ u32 GetMostSuitableMonToSwitchInto(u32 battler, bool32 switchAfterMonKOd) if (bestMonId != PARTY_SIZE) return bestMonId; - // If ace mon is the last available Pokemon and switch move was used - switch to the mon. - if (aceMonId != PARTY_SIZE) + // If ace mon is the last available Pokemon and U-Turn/Volt Switch was used - switch to the mon. + if (aceMonId != PARTY_SIZE && CountUsablePartyMons(battler) <= aceMonCount && IsSwitchOutEffect(gMovesInfo[gLastUsedMove].effect)) return aceMonId; return PARTY_SIZE; diff --git a/test/battle/ai/ai_switching.c b/test/battle/ai/ai_switching.c index 7f2368261d..45210efea6 100644 --- a/test/battle/ai/ai_switching.c +++ b/test/battle/ai/ai_switching.c @@ -909,3 +909,61 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_MON_CHOICES: AI correctly handles abilities TURN { MOVE(player, MOVE_WATER_GUN); EXPECT_MOVE(opponent, MOVE_ABSORB); } } } + +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI won't switch out if Yawn'd with only Ace mon remaining") +{ + u32 aceFlag; + PARAMETRIZE{ aceFlag = 0; } + PARAMETRIZE{ aceFlag = AI_FLAG_ACE_POKEMON; } + GIVEN { + ASSUME(gMovesInfo[MOVE_YAWN].effect == EFFECT_YAWN); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | aceFlag | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_SMART_SWITCHING); + PLAYER(SPECIES_SLOWKING) { Moves(MOVE_YAWN, MOVE_CONFUSION, MOVE_POWER_GEM, MOVE_WATER_PULSE); Item(ITEM_LEFTOVERS); } + OPPONENT(SPECIES_SCOLIPEDE) { Moves(MOVE_POISON_TAIL); } + OPPONENT(SPECIES_ABSOL) { Moves(MOVE_KNOCK_OFF, MOVE_CRUNCH); } + } WHEN { + TURN { MOVE(player, MOVE_YAWN); EXPECT_MOVE(opponent, MOVE_POISON_TAIL); } + if (aceFlag) + TURN { MOVE(player, MOVE_POWER_GEM); EXPECT_MOVE(opponent, MOVE_POISON_TAIL); } + else + TURN { MOVE(player, MOVE_POWER_GEM); EXPECT_SWITCH(opponent, 1); } + } +} + +AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI won't switch in ace mon after U-Turn if other options available") +{ + u32 aceFlag; + PARAMETRIZE{ aceFlag = 0; } + PARAMETRIZE{ aceFlag = AI_FLAG_ACE_POKEMON; } + GIVEN { + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | aceFlag | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_SMART_SWITCHING); + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_SURF); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_U_TURN); } + OPPONENT(SPECIES_NUMEL) { Level(5); Moves(MOVE_SPLASH); } + OPPONENT(SPECIES_SCIZOR) { Moves(MOVE_BUG_BITE); } + } WHEN { + if (aceFlag) + TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 1); MOVE(player, MOVE_SURF); } + else + TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 2); MOVE(player, MOVE_SURF); } + } +} + +AI_SINGLE_BATTLE_TEST("Switch AI: AI won't switch in ace mon after U-Turn if other options available") +{ + u32 aceFlag; + PARAMETRIZE{ aceFlag = 0; } + PARAMETRIZE{ aceFlag = AI_FLAG_ACE_POKEMON; } + GIVEN { + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | aceFlag | AI_FLAG_CHECK_VIABILITY | AI_FLAG_OMNISCIENT); + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_SURF); } + OPPONENT(SPECIES_WOBBUFFET) { Moves(MOVE_U_TURN); } + OPPONENT(SPECIES_NUMEL) { Level(5); Moves(MOVE_SPLASH); } + OPPONENT(SPECIES_SCIZOR) { Moves(MOVE_BUG_BITE); } + } WHEN { + if (aceFlag) + TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 1); MOVE(player, MOVE_SURF); } + else + TURN { EXPECT_MOVE(opponent, MOVE_U_TURN); EXPECT_SEND_OUT(opponent, 2); MOVE(player, MOVE_SURF); } + } +} From 89699939de8998c67611122175f75cc7255ec097 Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 1 Jan 2025 16:17:49 -0300 Subject: [PATCH 4/8] Version 1.10.1 --- .../ISSUE_TEMPLATE/01_battle_engine_bugs.yaml | 3 +- .../ISSUE_TEMPLATE/02_battle_ai_issues.yaml | 3 +- .github/ISSUE_TEMPLATE/04_other_errors.yaml | 3 +- CHANGELOG.md | 1 + README.md | 2 +- docs/SUMMARY.md | 1 + docs/changelogs/1.10.x/1.10.1.md | 140 ++++++++++++++++++ include/constants/expansion.h | 4 +- 8 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 docs/changelogs/1.10.x/1.10.1.md diff --git a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml index 0a3eff0e43..88c5cabd28 100644 --- a/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml +++ b/.github/ISSUE_TEMPLATE/01_battle_engine_bugs.yaml @@ -23,9 +23,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.10.0 (Latest release) + - 1.10.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.10.0 - 1.9.4 - 1.9.3 - 1.9.2 diff --git a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml index 4b8eec3a43..e49c54e756 100644 --- a/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml +++ b/.github/ISSUE_TEMPLATE/02_battle_ai_issues.yaml @@ -23,9 +23,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.10.0 (Latest release) + - 1.10.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.10.0 - 1.9.4 - 1.9.3 - 1.9.2 diff --git a/.github/ISSUE_TEMPLATE/04_other_errors.yaml b/.github/ISSUE_TEMPLATE/04_other_errors.yaml index 54335ca5e4..02bc0399b1 100644 --- a/.github/ISSUE_TEMPLATE/04_other_errors.yaml +++ b/.github/ISSUE_TEMPLATE/04_other_errors.yaml @@ -23,9 +23,10 @@ body: label: Version description: What version of pokeemerald-expansion are you using as a base? options: - - 1.10.0 (Latest release) + - 1.10.1 (Latest release) - master (default, unreleased bugfixes) - upcoming (Edge) + - 1.10.0 - 1.9.4 - 1.9.3 - 1.9.2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 13d6e4f4eb..963e05d7bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Pokeemerald-Expansion Changelogs ## 1.10.x +- **[Version 1.10.1](docs/changelogs/1.10.x/1.10.1.md) - 🧹 Bugfix Release** - **[Version 1.10.0](docs/changelogs/1.10.x/1.10.0.md) - ✨ Feature Release** ## 1.9.x diff --git a/README.md b/README.md index 4c6dff9fdd..70317fac5c 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ The main advantage of using vanilla pokeemerald as a base is being able to link If you use pokeemerald-expansion in your hack, please add RHH (Rom Hacking Hideout) to your credits list. Optionally, you can list the version used, so it can help players know what features to expect. You can phrase it as the following: ``` -Based off RHH's pokeemerald-expansion 1.10.0 https://github.com/rh-hideout/pokeemerald-expansion/ +Based off RHH's pokeemerald-expansion 1.10.1 https://github.com/rh-hideout/pokeemerald-expansion/ ``` #### Important: DO NOT use GitHub's "Download Zip" option. Using this option will not download the commit history required to update your expansion version or merge other feature branches. Instead, please read [this guide](https://github.com/Pawkkie/Team-Aquas-Asset-Repo/wiki/The-Basics-of-GitHub) to learn how to fork the repository and clone locally from there. diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 21584f3ad7..fe13ea72ee 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -20,6 +20,7 @@ - [How to use the Testing System](tutorials/how_to_testing_system.md) - [Changelog](./CHANGELOG.md) - [1.10.x]() + - [Version 1.10.1](changelogs/1.10.x/1.10.1.md) - [Version 1.10.0](changelogs/1.10.x/1.10.0.md) - [1.9.x]() - [Version 1.9.4](changelogs/1.9.x/1.9.4.md) diff --git a/docs/changelogs/1.10.x/1.10.1.md b/docs/changelogs/1.10.x/1.10.1.md new file mode 100644 index 0000000000..4eb4ea8e0d --- /dev/null +++ b/docs/changelogs/1.10.x/1.10.1.md @@ -0,0 +1,140 @@ +# Version 1.10.1 + +```md +## How to update +- If you haven't set up a remote, run the command `git remote add RHH https://github.com/rh-hideout/pokeemerald-expansion`. +- Once you have your remote set up, run the command `git pull RHH expansion/1.10.1`. +``` + +## 🧬 General 🧬 +### Added +* Added `FONT_SHORT_NARROWER` by @AsparagusEduardo (commit originally by @agsmgmaster64) in [#5101](https://github.com/rh-hideout/pokeemerald-expansion/pull/5101) + * Narrower font tweaks and font fitting fixes by @kittenchilly in [#5782](https://github.com/rh-hideout/pokeemerald-expansion/pull/5782) + +### Changed +* Adds Thief/Covet config to send stolen item to bag and Pickup config to pickup user's item in wild battles by @PhallenTree in [#5829](https://github.com/rh-hideout/pokeemerald-expansion/pull/5829) + +### Fixed +* trainerproc: Fix showing incorrect error context by @mrgriffin in [#5769](https://github.com/rh-hideout/pokeemerald-expansion/pull/5769) +* Fixes UB in caps.c by @AlexOn1ine in [#5878](https://github.com/rh-hideout/pokeemerald-expansion/pull/5878) + +## 🗺️ Overworld 🗺️ +### Fixed +* Fix Off-by-One Error in Move Relearner by @iriv24 and @luckytyphlosion in [#5778](https://github.com/rh-hideout/pokeemerald-expansion/pull/5778) +* Fix HGSS dex sort orders working incorrectly by @ravepossum in [#5790](https://github.com/rh-hideout/pokeemerald-expansion/pull/5790) +* Egg cycle length fix by @hedara90 and @/BolaDeQueijo on discord discovered the issue. in [#5828](https://github.com/rh-hideout/pokeemerald-expansion/pull/5828) +* Fixed givemon not respecting perfect IVs for species by @AsparagusEduardo in [#5873](https://github.com/rh-hideout/pokeemerald-expansion/pull/5873) + - Also removed redundant `RemoveIVIndexFromList` function in `src/daycare.c`, so it uses `src/pokemon.c`'s instead +* Fix Script Scrollable Multichoice Arrow Positions by @ghoulslash in [#5884](https://github.com/rh-hideout/pokeemerald-expansion/pull/5884) + +## 🐉 Pokémon 🐉 +### Changed +* Updated Ogerpon, Enamorus and Sinistcha sprites by @kittenchilly in [#5793](https://github.com/rh-hideout/pokeemerald-expansion/pull/5793) +* New Enamorus-Incarnate sprite by @kittenchilly in [#5797](https://github.com/rh-hideout/pokeemerald-expansion/pull/5797) + +### Fixed +* Fixes Wormadam define for teachable learnset script by @AlexOn1ine in [#5783](https://github.com/rh-hideout/pokeemerald-expansion/pull/5783) +* Fix "PlantCloak" references by @AsparagusEduardo in [#5821](https://github.com/rh-hideout/pokeemerald-expansion/pull/5821) +* Misc pokemon sprite fixes by @Cafeei in [#5846](https://github.com/rh-hideout/pokeemerald-expansion/pull/5846) + +## ⚔️ Battle General ⚔️ +### Changed +* Adds Thief/Covet config to send stolen item to bag and Pickup config to pickup user's item in wild battles by @PhallenTree in [#5829](https://github.com/rh-hideout/pokeemerald-expansion/pull/5829) + +### Fixed +* Fixes items preventing other switch in effects by @AlexOn1ine in [#5732](https://github.com/rh-hideout/pokeemerald-expansion/pull/5732) +* Fix Pokemon with No Guard failing OHKO Moves into Semi-Invulnerable Pokemon by @iriv24 and @Cafeei in [#5779](https://github.com/rh-hideout/pokeemerald-expansion/pull/5779) +* Fix move category and category icon when PSS is off by @ravepossum in [#5786](https://github.com/rh-hideout/pokeemerald-expansion/pull/5786) +* Added the missing config to use new terrains by @hedara90 in [#5792](https://github.com/rh-hideout/pokeemerald-expansion/pull/5792) +* Fixes Shed Tail substitute health by @AlexOn1ine in [#5826](https://github.com/rh-hideout/pokeemerald-expansion/pull/5826) +* `B_LAST_USED_BALL` and `.importance` by @AERDU in [#5834](https://github.com/rh-hideout/pokeemerald-expansion/pull/5834) + - prevents `B_LAST_USED_BALL` from removing balls with `.importance = 1` +* Fixes Quash-affected battlers having the wrong order for End Turn effects by @PhallenTree in [#5838](https://github.com/rh-hideout/pokeemerald-expansion/pull/5838) +* Fixes Cotton Down and Gulp Missile not interacting correctly with stat reduction prevention effects by @PhallenTree in [#5841](https://github.com/rh-hideout/pokeemerald-expansion/pull/5841) +* Fix Hit Escape moves giving Exp to the mon that switches in by @kittenchilly in [#5844](https://github.com/rh-hideout/pokeemerald-expansion/pull/5844) +* Fixed Wish triggering Disguise by @AsparagusEduardo in [#5860](https://github.com/rh-hideout/pokeemerald-expansion/pull/5860) +* Fixed `MOVE_EFFECT_FREEZE_OR_FROSTBITE` not being usable in battle scripts by @AsparagusEduardo in [#5859](https://github.com/rh-hideout/pokeemerald-expansion/pull/5859) +* Fixed Ally Switch breaking Illusion by @AsparagusEduardo in [#5879](https://github.com/rh-hideout/pokeemerald-expansion/pull/5879) +* Fixes gen3 Style Shadows out of place by @AlexOn1ine in [#5880](https://github.com/rh-hideout/pokeemerald-expansion/pull/5880) +* Fix Salt Cure script by @ghoulslash in [#5895](https://github.com/rh-hideout/pokeemerald-expansion/pull/5895) +* Fixes Eject Pack / Intimidate issue by @AlexOn1ine in [#5902](https://github.com/rh-hideout/pokeemerald-expansion/pull/5902) +* Adds Generational config for Magic Guard (Fix for Gen4+) by @AlexOn1ine in [#5893](https://github.com/rh-hideout/pokeemerald-expansion/pull/5893) +* Fixes Stance Change, Sleep Talk interaction by @AlexOn1ine in [#5909](https://github.com/rh-hideout/pokeemerald-expansion/pull/5909) +* Fixes Round doubling it's BP if previous Round failed by @AlexOn1ine in [#5907](https://github.com/rh-hideout/pokeemerald-expansion/pull/5907) + +## 🤹 Moves 🤹 +### Fixed +* Fixes absorb still draining HP when flinched by @AlexOn1ine in [#5814](https://github.com/rh-hideout/pokeemerald-expansion/pull/5814) +* Fixes Tidy Up by @AlexOn1ine in [#5819](https://github.com/rh-hideout/pokeemerald-expansion/pull/5819) +* Ally Switch extra battlerId tracking by @ghoulslash in [#5823](https://github.com/rh-hideout/pokeemerald-expansion/pull/5823) +* Sheer Force fix and move effect cleanup by @AlexOn1ine in [#5812](https://github.com/rh-hideout/pokeemerald-expansion/pull/5812) +* New U-turn animation to fix visibility by @AlexOn1ine in [#5910](https://github.com/rh-hideout/pokeemerald-expansion/pull/5910) + +## 🧶 Items 🧶 +### Fixed +* Prevent Key Items that open other menus from causing a crash if registered and used from the field by @iriv24 in [#5810](https://github.com/rh-hideout/pokeemerald-expansion/pull/5810) +* Fixes Clear Amulet displaying the wrong battler and Starting Status displaying the wrong message by @PhallenTree in [#5831](https://github.com/rh-hideout/pokeemerald-expansion/pull/5831) +* Fixes Room Service lowering the opposite mon in specific scenario by @AlexOn1ine in [#5827](https://github.com/rh-hideout/pokeemerald-expansion/pull/5827) + +## 🤖 Battle AI 🤖 +### Fixed +* Fixed ace switching bugs by @Pawkkie and @iriv24 for their diligent testing and debugging support in [#5922](https://github.com/rh-hideout/pokeemerald-expansion/pull/5922) + +## 🧹 Other Cleanup 🧹 +* Converted Stance Change to proper Form Change + Tests by @AsparagusEduardo in [#5749](https://github.com/rh-hideout/pokeemerald-expansion/pull/5749) +* Removed testing strings for automatic line breaks by @hedara90 in [#5757](https://github.com/rh-hideout/pokeemerald-expansion/pull/5757) +* Added NBSP and up+down arrows to all fonts by @hedara90 in [#5767](https://github.com/rh-hideout/pokeemerald-expansion/pull/5767) + - Use `~` or `{NBSP}` to insert a non-breaking space into a string. +* Palette cleanup by @hedara90 in [#5661](https://github.com/rh-hideout/pokeemerald-expansion/pull/5661) + - Resized some move anim palettes from 256 to 16 +* Replace power checks with IS_MOVE_STATUS by @Bassoonian and @AsparagusEduardo in [#5820](https://github.com/rh-hideout/pokeemerald-expansion/pull/5820) +* Changes Various defines to an Enum by @AsparagusEduardo in [#5840](https://github.com/rh-hideout/pokeemerald-expansion/pull/5840) +* Fix `IS_MOVE_STATUS` regression by @Bassoonian in [#5848](https://github.com/rh-hideout/pokeemerald-expansion/pull/5848) +* Remove unused various by @Bassoonian in [#5851](https://github.com/rh-hideout/pokeemerald-expansion/pull/5851) +* Removed redundant call to FillPalBufferBlack in FRLG whiteout sequence by @AsparagusEduardo in [#5854](https://github.com/rh-hideout/pokeemerald-expansion/pull/5854) +* Improve README.md by @AsparagusEduardo in [#5640](https://github.com/rh-hideout/pokeemerald-expansion/pull/5640) +* Fix wrong value for NUM_MOVE_EFFECTS by @Bassoonian in [#5913](https://github.com/rh-hideout/pokeemerald-expansion/pull/5913) +* Renamed OW type effectiveness function for clarity by @AsparagusEduardo in [#5917](https://github.com/rh-hideout/pokeemerald-expansion/pull/5917) + - Renamed `GetTypeEffectiveness` to `GetOverworldTypeEffectiveness`. + +## 🧪 Test Runner 🧪 +### Changed +* Gravity fix + Sky Drop Test by @ghoulslash in [#5780](https://github.com/rh-hideout/pokeemerald-expansion/pull/5780) +* Added missing Belch tests by @AsparagusEduardo in [#5881](https://github.com/rh-hideout/pokeemerald-expansion/pull/5881) +* Added missing Move Effect TODO tests - Volume D by @AsparagusEduardo in [#5887](https://github.com/rh-hideout/pokeemerald-expansion/pull/5887) +* Comment out Ally Switch Illusion test by @AsparagusEduardo in [#5901](https://github.com/rh-hideout/pokeemerald-expansion/pull/5901) +* Fixed leaking tasks not showing up in summary by @AsparagusEduardo in [#5890](https://github.com/rh-hideout/pokeemerald-expansion/pull/5890) +* Setting Battle configs during tests by @AsparagusEduardo and @SBird1337, @mrgriffin in [#5803](https://github.com/rh-hideout/pokeemerald-expansion/pull/5803) +* Speed up tests in headless mode by @AsparagusEduardo and @SBird1337 for the original fast intro code. in [#5889](https://github.com/rh-hideout/pokeemerald-expansion/pull/5889) + - This introduced the config option `B_FAST_INTRO_NO_SLIDE` which removes the sliding into for battles. +* Added missing Move Effect TODO tests - Volume E by @AsparagusEduardo in [#5915](https://github.com/rh-hideout/pokeemerald-expansion/pull/5915) + +### Fixed +* Fix test `TIMEOUT` messaging in summary by @AsparagusEduardo in [#5772](https://github.com/rh-hideout/pokeemerald-expansion/pull/5772) +* Fix octolock + defiant by @ghoulslash in [#5781](https://github.com/rh-hideout/pokeemerald-expansion/pull/5781) +* Added missing tests + Fix Coaching/Crafty Shield interaction by @AsparagusEduardo in [#5796](https://github.com/rh-hideout/pokeemerald-expansion/pull/5796) +* Fixed TODO tests not showing up when filtering by name by @AsparagusEduardo in [#5894](https://github.com/rh-hideout/pokeemerald-expansion/pull/5894) + +## 📚 Documentation 📚 +* Fixed changelog links to changelog 1.10 by @AsparagusEduardo in [#5758](https://github.com/rh-hideout/pokeemerald-expansion/pull/5758) +* Added scope document and made changes to pull request template by @pkmnsnfrn and @Pawkkie and arguably the entire senate in [#5706](https://github.com/rh-hideout/pokeemerald-expansion/pull/5706) +* Added instructions in PR template to make crediting people more clear by @pkmnsnfrn and @AsparagusEduardo made changes to my text in [#5755](https://github.com/rh-hideout/pokeemerald-expansion/pull/5755) +* Fix website not showing the "How to add mon" 1.10 tutorial by @AsparagusEduardo in [#5813](https://github.com/rh-hideout/pokeemerald-expansion/pull/5813) +* Install instructions by @hedara90 in [#5876](https://github.com/rh-hideout/pokeemerald-expansion/pull/5876) +* Change install.md to mention make debug instead of DINFO=1 by @ravepossum in [#5882](https://github.com/rh-hideout/pokeemerald-expansion/pull/5882) +* Backport changes from the wiki by @AsparagusEduardo in [#5900](https://github.com/rh-hideout/pokeemerald-expansion/pull/5900) +* Improve README.md by @AsparagusEduardo in [#5640](https://github.com/rh-hideout/pokeemerald-expansion/pull/5640) + +## 📦 Branch Synchronisation 📦 +### pret +* 20th of December in [#5845](https://github.com/rh-hideout/pokeemerald-expansion/pull/5845) + * Fix recorded battle link player loops by @AsparagusEduardo in [pret#2071](https://github.com/pret/pokeemerald/pull/2071) + * Added `POKEMART_LIST_END` to avoid users accidentally removing it by @AsparagusEduardo in [pret#1947](https://github.com/pret/pokeemerald/pull/1947) + * Fixed brace style inconsistencies by @AsparagusEduardo in [pret#2072](https://github.com/pret/pokeemerald/pull/2072) + * remove `sBirchSpeechPlatformBlackPal` by @DizzyEggg in [pret#2075](https://github.com/pret/pokeemerald/pull/2075) + + +**Full Changelog**: https://github.com/rh-hideout/pokeemerald-expansion/compare/expansion/1.10.0...expansion/1.10.1 + + + diff --git a/include/constants/expansion.h b/include/constants/expansion.h index 24d5ed3853..b127c99ecc 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.10.0 +// Last version: 1.10.1 #define EXPANSION_VERSION_MAJOR 1 #define EXPANSION_VERSION_MINOR 10 #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 e040dcb0b4be4706289d5fd4ac210c68a9c2903e Mon Sep 17 00:00:00 2001 From: Eduardo Quezada Date: Wed, 1 Jan 2025 16:20:40 -0300 Subject: [PATCH 5/8] Begin 1.10.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 b127c99ecc..1a3ba19065 100644 --- a/include/constants/expansion.h +++ b/include/constants/expansion.h @@ -4,10 +4,10 @@ // Last version: 1.10.1 #define EXPANSION_VERSION_MAJOR 1 #define EXPANSION_VERSION_MINOR 10 -#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 92c0039a238735e254f1610edee1ba33b64596b3 Mon Sep 17 00:00:00 2001 From: Pawkkie <61265402+Pawkkie@users.noreply.github.com> Date: Wed, 1 Jan 2025 15:40:29 -0500 Subject: [PATCH 6/8] Cleanup fix from 5922 (#5927) --- src/battle_ai_switch_items.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index f6e0facb12..db0070da8e 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -964,9 +964,7 @@ bool32 ShouldSwitch(u32 battler) if (i == gBattleStruct->monToSwitchIntoId[battlerIn2]) continue; if (IsAceMon(battler, i)) - { continue; - } availableToSwitch++; } From b7e945fbfb7a12f9dadfb0a6fd7fea672c4703ee Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Wed, 1 Jan 2025 21:41:42 +0100 Subject: [PATCH 7/8] Reverts wrongly done partial Eject Pack fix (#5928) --- data/battle_scripts_1.s | 7 ------- include/battle_scripts.h | 1 - src/battle_script_commands.c | 10 ++-------- test/battle/hold_effect/eject_pack.c | 7 ++++--- 4 files changed, 6 insertions(+), 19 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index dba914924d..bc2f4dea3c 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -9634,13 +9634,6 @@ BattleScript_EjectPackActivates:: jumpifcantswitch BS_SCRIPTING, BattleScript_EjectButtonEnd goto BattleScript_EjectPackActivate_Ret -BattleScript_EjectPackMissesTiming:: - playanimation BS_SCRIPTING, B_ANIM_HELD_ITEM_EFFECT - printstring STRINGID_EJECTBUTTONACTIVATE - waitmessage B_WAIT_TIME_LONG - removeitem BS_SCRIPTING - return - BattleScript_DarkTypePreventsPrankster:: attackstring ppreduce diff --git a/include/battle_scripts.h b/include/battle_scripts.h index 158dfb5dc3..1404a40718 100644 --- a/include/battle_scripts.h +++ b/include/battle_scripts.h @@ -421,7 +421,6 @@ extern const u8 BattleScript_EjectButtonActivates[]; extern const u8 BattleScript_EjectPackActivate_Ret[]; extern const u8 BattleScript_EjectPackActivate_End2[]; extern const u8 BattleScript_EjectPackActivates[]; -extern const u8 BattleScript_EjectPackMissesTiming[]; extern const u8 BattleScript_MentalHerbCureRet[]; extern const u8 BattleScript_MentalHerbCureEnd2[]; extern const u8 BattleScript_TerrainPreventsEnd2[]; diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 3c719049a6..82d941bbda 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -6471,19 +6471,13 @@ static void Cmd_moveend(void) } else // Eject Pack { - if (gBattleResources->flags->flags[gBattlerTarget] & RESOURCE_FLAG_EMERGENCY_EXIT) - { - gBattlescriptCurrInstr = BattleScript_EjectPackMissesTiming; - gProtectStructs[battler].statFell = FALSE; - } - else + if (!(gBattleResources->flags->flags[gBattlerTarget] & RESOURCE_FLAG_EMERGENCY_EXIT)) { gBattlescriptCurrInstr = BattleScript_EjectPackActivates; AI_DATA->ejectPackSwitch = TRUE; - // Are these 2 lines below needed? - gProtectStructs[battler].statFell = FALSE; gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE; } + gProtectStructs[battler].statFell = FALSE; } break; // Only the fastest Eject item activates } diff --git a/test/battle/hold_effect/eject_pack.c b/test/battle/hold_effect/eject_pack.c index b3a2d34b63..0d2696392f 100644 --- a/test/battle/hold_effect/eject_pack.c +++ b/test/battle/hold_effect/eject_pack.c @@ -76,12 +76,13 @@ SINGLE_BATTLE_TEST("Eject Pack will miss timing to switch out user if Emergency } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_OVERHEAT, player); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); - ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); - MESSAGE("Wobbuffet is switched out with the Eject Pack!"); + NONE_OF { + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_HELD_ITEM_EFFECT, player); + MESSAGE("Wobbuffet is switched out with the Eject Pack!"); + } ABILITY_POPUP(opponent, ABILITY_EMERGENCY_EXIT); } THEN { EXPECT(player->species == SPECIES_WOBBUFFET); - EXPECT(player->item == ITEM_NONE); EXPECT(opponent->species == SPECIES_WYNAUT); } } From 875f0f7436773ee7ef0690a661f522ffda562848 Mon Sep 17 00:00:00 2001 From: Alex <93446519+AlexOn1ine@users.noreply.github.com> Date: Wed, 1 Jan 2025 21:46:42 +0100 Subject: [PATCH 8/8] Fixes Trainer Slide messages causing corruption for recoil damage (#5926) --- src/battle_script_commands.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 82d941bbda..2f31b230ae 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -10369,6 +10369,7 @@ static void Cmd_various(void) { gBattlerSpriteIds[BATTLE_PARTNER(battler)] = gBattleScripting.savedDmg >> 8; gBattlerSpriteIds[battler] = gBattleScripting.savedDmg & 0xFF; + gBattleScripting.savedDmg = 0; if (IsBattlerAlive(battler)) { SetBattlerShadowSpriteCallback(battler, gBattleMons[battler].species);