From 20a986519d0b46404e9eaf9e65f3f2c92c0a9631 Mon Sep 17 00:00:00 2001 From: GGbond Date: Tue, 10 Feb 2026 17:00:42 +0800 Subject: [PATCH] Fix Aqua Ring reuse failure check and add Aqua Ring/Ingrain tests (#9174) --- data/battle_scripts_1.s | 1 + test/battle/move_effect/aqua_ring.c | 61 ++++++++++++- test/battle/move_effect/ingrain.c | 128 +++++++++++++++++++++++++++- 3 files changed, 188 insertions(+), 2 deletions(-) diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 25262692d7..7abeade1da 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -2302,6 +2302,7 @@ BattleScript_EffectMagicRoom:: BattleScript_EffectAquaRing:: attackcanceler + jumpifvolatile BS_ATTACKER, VOLATILE_AQUA_RING, BattleScript_ButItFailed setvolatile BS_ATTACKER, VOLATILE_AQUA_RING attackanimation waitanimation diff --git a/test/battle/move_effect/aqua_ring.c b/test/battle/move_effect/aqua_ring.c index d137a35276..e800f76c6c 100644 --- a/test/battle/move_effect/aqua_ring.c +++ b/test/battle/move_effect/aqua_ring.c @@ -1,6 +1,27 @@ #include "global.h" #include "test/battle.h" +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_AQUA_RING) == EFFECT_AQUA_RING); +} + +SINGLE_BATTLE_TEST("Aqua Ring fails if already active") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_AQUA_RING); } + TURN { MOVE(player, MOVE_AQUA_RING); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AQUA_RING, player); + MESSAGE("Wobbuffet surrounded itself with a veil of water!"); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_AQUA_RING, player); + MESSAGE("But it failed!"); + } +} + SINGLE_BATTLE_TEST("Aqua Ring recovers 1/16th HP at end of turn") { GIVEN { @@ -15,9 +36,30 @@ SINGLE_BATTLE_TEST("Aqua Ring recovers 1/16th HP at end of turn") } } +SINGLE_BATTLE_TEST("Aqua Ring restores 30% more HP when holding Big Root") +{ + u32 item; + u16 expectedHp; + PARAMETRIZE { item = ITEM_NONE; expectedHp = 58; } + PARAMETRIZE { item = ITEM_BIG_ROOT; expectedHp = 60; } + + GIVEN { + ASSUME(gItemsInfo[ITEM_BIG_ROOT].holdEffect == HOLD_EFFECT_BIG_ROOT); + PLAYER(SPECIES_WOBBUFFET) { HP(50); MaxHP(128); Item(item); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_AQUA_RING); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AQUA_RING, player); + } THEN { + EXPECT_EQ(player->hp, expectedHp); + } +} + SINGLE_BATTLE_TEST("Aqua Ring can be used under Heal Block but will not heal the user") { GIVEN { + ASSUME(GetMoveEffect(MOVE_HEAL_BLOCK) == EFFECT_HEAL_BLOCK); PLAYER(SPECIES_WOBBUFFET) { HP(50); MaxHP(128); Speed(50); } OPPONENT(SPECIES_WOBBUFFET) { Speed(100); } } WHEN { @@ -29,4 +71,21 @@ SINGLE_BATTLE_TEST("Aqua Ring can be used under Heal Block but will not heal the } } -TO_DO_BATTLE_TEST("Baton Pass passes Aqua Ring's effect"); +SINGLE_BATTLE_TEST("Aqua Ring's effect is passed by Baton Pass") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT) { HP(50); MaxHP(128); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_AQUA_RING); } + TURN { MOVE(player, MOVE_BATON_PASS); SEND_OUT(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_AQUA_RING, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BATON_PASS, player); + SEND_IN_MESSAGE("Wynaut"); + } THEN { + EXPECT(player->hp == 58); + } +} diff --git a/test/battle/move_effect/ingrain.c b/test/battle/move_effect/ingrain.c index 19213f10d9..2d08a67744 100644 --- a/test/battle/move_effect/ingrain.c +++ b/test/battle/move_effect/ingrain.c @@ -1,4 +1,130 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("TODO: Write Ingrain (Move Effect) test titles") +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_INGRAIN) == EFFECT_INGRAIN); +} + +SINGLE_BATTLE_TEST("Ingrain fails if already rooted") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_INGRAIN); } + TURN { MOVE(player, MOVE_INGRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INGRAIN, player); + MESSAGE("Wobbuffet planted its roots!"); + NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_INGRAIN, player); + MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Ingrain restores 1/16th HP at the end of turn") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { HP(50); MaxHP(128); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_INGRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INGRAIN, player); + } THEN { + EXPECT_EQ(player->hp, 58); + } +} + +SINGLE_BATTLE_TEST("Ingrain restores 30% more HP when holding Big Root") +{ + u32 item; + u16 expectedHp; + PARAMETRIZE { item = ITEM_NONE; expectedHp = 58; } + PARAMETRIZE { item = ITEM_BIG_ROOT; expectedHp = 60; } + + GIVEN { + ASSUME(gItemsInfo[ITEM_BIG_ROOT].holdEffect == HOLD_EFFECT_BIG_ROOT); + PLAYER(SPECIES_WOBBUFFET) { HP(50); MaxHP(128); Item(item); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_INGRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INGRAIN, player); + } THEN { + EXPECT_EQ(player->hp, expectedHp); + } +} + +SINGLE_BATTLE_TEST("Ingrain can be used under Heal Block but will not heal the user") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_HEAL_BLOCK) == EFFECT_HEAL_BLOCK); + PLAYER(SPECIES_WOBBUFFET) { HP(50); MaxHP(128); Speed(50); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(100); } + } WHEN { + TURN { MOVE(opponent, MOVE_HEAL_BLOCK); MOVE(player, MOVE_INGRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INGRAIN, player); + } THEN { + EXPECT_EQ(player->hp, 50); + } +} + +SINGLE_BATTLE_TEST("Ingrain prevents regular switching out") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_INGRAIN); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INGRAIN, player); + } THEN { + u32 battler = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); + EXPECT_EQ(CanBattlerEscape(battler), FALSE); + } +} + +SINGLE_BATTLE_TEST("Ingrain does not prevent switching out with Flip Turn") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_FLIP_TURN) == EFFECT_HIT_ESCAPE); + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_INGRAIN, MOVE_FLIP_TURN); } + PLAYER(SPECIES_WYNAUT); + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_INGRAIN); } + TURN { MOVE(player, MOVE_FLIP_TURN); SEND_OUT(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INGRAIN, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_FLIP_TURN, player); + HP_BAR(opponent); + SEND_IN_MESSAGE("Wynaut"); + } THEN { + EXPECT_EQ(player->species, SPECIES_WYNAUT); + } +} + +SINGLE_BATTLE_TEST("Ingrain's effect is passed by Baton Pass") +{ + GIVEN { + ASSUME(GetMoveEffect(MOVE_BATON_PASS) == EFFECT_BATON_PASS); + PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_INGRAIN, MOVE_BATON_PASS); } + PLAYER(SPECIES_WYNAUT) { HP(50); MaxHP(128); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_INGRAIN); } + TURN { MOVE(player, MOVE_BATON_PASS); SEND_OUT(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_INGRAIN, player); + ANIMATION(ANIM_TYPE_MOVE, MOVE_BATON_PASS, player); + SEND_IN_MESSAGE("Wynaut"); + } THEN { + EXPECT_EQ(player->species, SPECIES_WYNAUT); + EXPECT_EQ(player->hp, 58); + } +} + +TO_DO_BATTLE_TEST("Red Card and forced switch moves (Roar/Whirlwind) cannot force out a rooted Pokémon");