From 474d586452daac1a33f700a5c81e144755d63d11 Mon Sep 17 00:00:00 2001 From: GGbond Date: Mon, 2 Mar 2026 20:30:52 +0800 Subject: [PATCH] Add tests for Taunt (#9386) --- include/constants/generational_changes.h | 2 +- include/random.h | 2 +- src/battle_script_commands.c | 6 +- test/battle/move_effect/taunt.c | 81 +++++++++++++++++++++++- 4 files changed, 85 insertions(+), 6 deletions(-) diff --git a/include/constants/generational_changes.h b/include/constants/generational_changes.h index 5b6d7cb76f..9b44f10b8a 100644 --- a/include/constants/generational_changes.h +++ b/include/constants/generational_changes.h @@ -54,7 +54,7 @@ F(B_DISABLE_TURNS, disableTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(B_TAILWIND_TURNS, tailwindTurns, (u32, GEN_COUNT - 1)) \ F(B_SLEEP_TURNS, sleepTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ - F(B_TAUNT_TURNS, tauntTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(B_TAUNT_TURNS, tauntTurns, (u32, GEN_COUNT - 1)) \ F(B_SPORT_TURNS, sportTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(B_MEGA_EVO_TURN_ORDER, megaEvoTurnOrder, (u32, GEN_COUNT - 1)) \ F(B_RECALC_TURN_AFTER_ACTIONS, recalcTurnAfterActions, (u32, GEN_COUNT - 1)) \ diff --git a/include/random.h b/include/random.h index a472644108..17a700ee1b 100644 --- a/include/random.h +++ b/include/random.h @@ -160,6 +160,7 @@ enum RandomTag RNG_SECONDARY_EFFECT_3, RNG_SHED_SKIN, RNG_SLEEP_TURNS, + RNG_TAUNT_TURNS, RNG_SPEED_TIE, RNG_STATIC, RNG_STENCH, @@ -241,7 +242,6 @@ enum RandomTag RNG_FISHING_BITE, RNG_FISHING_GEN3_STICKY, RNG_WILD_MON_TARGET, - RNG_TAUNT, }; #define RandomWeighted(tag, ...) \ diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index d8d6df5662..0fd5f4103d 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -9642,15 +9642,15 @@ static void Cmd_settaunt(void) else if (gBattleMons[gBattlerTarget].volatiles.tauntTimer == 0) { u8 turns; - if (B_TAUNT_TURNS >= GEN_5) + if (GetConfig(B_TAUNT_TURNS) >= GEN_5) { turns = B_TAUNT_TIMER - 1; // 4 turns if (!HasBattlerActedThisTurn(gBattlerTarget)) turns--; // If the target hasn't yet moved this turn, Taunt lasts for only three turns (source: Bulbapedia) } - else if (B_TAUNT_TURNS >= GEN_4) + else if (GetConfig(B_TAUNT_TURNS) >= GEN_4) { - turns = RandomUniform(RNG_TAUNT, 3, B_TAUNT_TIMER); + turns = RandomUniform(RNG_TAUNT_TURNS, 3, B_TAUNT_TIMER); } else { diff --git a/test/battle/move_effect/taunt.c b/test/battle/move_effect/taunt.c index 91fe13364d..491aa3a50b 100644 --- a/test/battle/move_effect/taunt.c +++ b/test/battle/move_effect/taunt.c @@ -1,4 +1,83 @@ #include "global.h" #include "test/battle.h" -TO_DO_BATTLE_TEST("TODO: Write Taunt (Move Effect) test titles") +ASSUMPTIONS +{ + ASSUME(GetMoveEffect(MOVE_TAUNT) == EFFECT_TAUNT); +} + +SINGLE_BATTLE_TEST("Taunt lasts for 2 turns (Gen 3)") +{ + GIVEN { + WITH_CONFIG(B_TAUNT_TURNS, GEN_3); + PLAYER(SPECIES_WOBBUFFET) { Speed(2); Moves(MOVE_GROWL, MOVE_TACKLE); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(1); Moves(MOVE_TAUNT, MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_GROWL); MOVE(opponent, MOVE_TAUNT); } + TURN { MOVE(player, MOVE_GROWL, allowed: FALSE); MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_GROWL); MOVE(opponent, MOVE_CELEBRATE); } + } +} + +// NOTE: AI test is required to validate RNG range without MOVE/FORCED_MOVE invalids; there may be a better approach. +AI_SINGLE_BATTLE_TEST("Taunt lasts for 3-5 turns (Gen 4)") +{ + u32 count, turns; + + PARAMETRIZE { turns = 3; } + PARAMETRIZE { turns = 4; } + PARAMETRIZE { turns = 5; } + PASSES_RANDOMLY(1, 3, RNG_TAUNT_TURNS); + GIVEN { + WITH_CONFIG(B_TAUNT_TURNS, GEN_4); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT); + PLAYER(SPECIES_WOBBUFFET) { Speed(1); Moves(MOVE_TAUNT, MOVE_CELEBRATE); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(2); Moves(MOVE_GROWL, MOVE_TACKLE); } + } WHEN { + TURN { MOVE(player, MOVE_TAUNT); } + for (count = 0; count < turns - 1; ++count) + TURN { MOVE(player, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_CELEBRATE); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_TAUNT, player); + for (count = 0; count < turns - 1; ++count) + { + NOT MESSAGE("The opposing Wobbuffet's Taunt wore off!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + } + MESSAGE("The opposing Wobbuffet's Taunt wore off!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, player); + } +} + +SINGLE_BATTLE_TEST("Taunt lasts for 3 turns if target hasn't moved (Gen 5+)") +{ + u32 count; + + GIVEN { + WITH_CONFIG(B_TAUNT_TURNS, GEN_5); + PLAYER(SPECIES_WOBBUFFET) { Speed(1); Moves(MOVE_GROWL, MOVE_TACKLE); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(2); Moves(MOVE_TAUNT, MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(opponent, MOVE_TAUNT); MOVE(player, MOVE_GROWL); } + for (count = 0; count < 2; ++count) + TURN { MOVE(player, MOVE_GROWL, allowed: FALSE); MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_GROWL); MOVE(opponent, MOVE_CELEBRATE); } + } +} + +SINGLE_BATTLE_TEST("Taunt lasts for 4 turns if target already moved (Gen 5+)") +{ + u32 count; + + GIVEN { + WITH_CONFIG(B_TAUNT_TURNS, GEN_5); + PLAYER(SPECIES_WOBBUFFET) { Speed(2); Moves(MOVE_GROWL, MOVE_TACKLE); } + OPPONENT(SPECIES_WOBBUFFET) { Speed(1); Moves(MOVE_TAUNT, MOVE_CELEBRATE); } + } WHEN { + TURN { MOVE(player, MOVE_GROWL); MOVE(opponent, MOVE_TAUNT); } + for (count = 0; count < 3; ++count) + TURN { MOVE(player, MOVE_GROWL, allowed: FALSE); MOVE(player, MOVE_TACKLE); MOVE(opponent, MOVE_CELEBRATE); } + TURN { MOVE(player, MOVE_GROWL); MOVE(opponent, MOVE_CELEBRATE); } + } +}