From 353915ef646ba7ddb27a92be060119da144cdb78 Mon Sep 17 00:00:00 2001 From: ghoulslash <41651341+ghoulslash@users.noreply.github.com> Date: Fri, 11 Oct 2024 17:47:46 -0400 Subject: [PATCH] Add various tests, add RNG_RANDOM_TARGET (#5438) * burn dmg test depends on config * burn and frostbite tests use B_BURN_DAMAGE config for denom val * update kings shield test with config * add RNG_RANDOM_TARGET, use SetRandomTarget in HandleAction_UseMove target acquisition, update uproar test to PASSES_RANDOMLY since test will fail if you target the soundproof voltorb. Slightly faster UproarWakeUpCheck * add sticky web+contrary test * add EXPECT_EQ to contrary+sticky web test * Update src/battle_script_commands.c Co-authored-by: Bassoonian * Update src/battle_util.c Co-authored-by: Bassoonian * Update test/battle/move_effect/uproar.c Co-authored-by: Bassoonian * fix test * syntax fix --------- Co-authored-by: ghoulslash Co-authored-by: Bassoonian --- include/random.h | 1 + src/battle_script_commands.c | 3 ++- src/battle_util.c | 39 +++++----------------------- test/battle/ability/contrary.c | 20 ++++++++++++++ test/battle/move_effect/belly_drum.c | 26 ++++++++++++++++++- test/battle/move_effect/protect.c | 6 ++++- test/battle/move_effect/uproar.c | 1 + test/battle/status1/burn.c | 5 ++-- test/battle/status1/frostbite.c | 4 +-- 9 files changed, 64 insertions(+), 41 deletions(-) diff --git a/include/random.h b/include/random.h index d41e4785435b..215472377e2f 100644 --- a/include/random.h +++ b/include/random.h @@ -168,6 +168,7 @@ enum RandomTag RNG_AI_SWITCH_NIGHTMARE, RNG_AI_SWITCH_SEEDED, RNG_SHELL_SIDE_ARM, + RNG_RANDOM_TARGET, }; #define RandomWeighted(tag, ...) \ diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 83f7bb4999ce..f55eff3b7b47 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -11405,10 +11405,11 @@ static void Cmd_setmiracleeye(void) bool8 UproarWakeUpCheck(u8 battler) { s32 i; + bool32 hasSoundproof = (B_UPROAR_IGNORE_SOUNDPROOF < GEN_5 && GetBattlerAbility(battler) == ABILITY_SOUNDPROOF); for (i = 0; i < gBattlersCount; i++) { - if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || (GetBattlerAbility(battler) == ABILITY_SOUNDPROOF && B_UPROAR_IGNORE_SOUNDPROOF < GEN_5)) + if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || hasSoundproof) continue; gBattleScripting.battler = i; diff --git a/src/battle_util.c b/src/battle_util.c index 03c375868496..2971b3684068 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -251,20 +251,7 @@ void HandleAction_UseMove(void) { if (moveTarget & MOVE_TARGET_RANDOM) { - if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) - { - if (Random() & 1) - gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - else - gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); - } - else - { - if (Random() & 1) - gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - else - gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); - } + gBattlerTarget = SetRandomTarget(gBattlerAttacker); } else if (moveTarget & MOVE_TARGET_FOES_AND_ALLY) { @@ -311,21 +298,7 @@ void HandleAction_UseMove(void) } else if (IsDoubleBattle() && moveTarget & MOVE_TARGET_RANDOM) { - if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER) - { - if (Random() & 1) - gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT); - else - gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT); - } - else - { - if (Random() & 1) - gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT); - else - gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT); - } - + gBattlerTarget = SetRandomTarget(gBattlerAttacker); if (gAbsentBattlerFlags & (1u << gBattlerTarget) && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) { @@ -2664,7 +2637,7 @@ u8 DoBattlerEndTurnEffects(void) for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++) { if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) - && GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF) + && (B_UPROAR_IGNORE_SOUNDPROOF >= GEN_5 || GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF)) { gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP; gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; @@ -8341,7 +8314,7 @@ void HandleAction_RunBattleScript(void) // identical to RunBattleScriptCommands gBattleScriptingCommandsTable[*gBattlescriptCurrInstr](); } -u32 SetRandomTarget(u32 battler) +u32 SetRandomTarget(u32 battlerAtk) { u32 target; static const u8 targets[2][2] = @@ -8352,13 +8325,13 @@ u32 SetRandomTarget(u32 battler) if (IsDoubleBattle()) { - target = GetBattlerAtPosition(targets[GetBattlerSide(battler)][Random() % 2]); + target = GetBattlerAtPosition(targets[GetBattlerSide(battlerAtk)][RandomUniform(RNG_RANDOM_TARGET, 0, 1)]); if (!IsBattlerAlive(target)) target ^= BIT_FLANK; } else { - target = GetBattlerAtPosition(targets[GetBattlerSide(battler)][0]); + target = GetBattlerAtPosition(targets[GetBattlerSide(battlerAtk)][0]); } return target; diff --git a/test/battle/ability/contrary.c b/test/battle/ability/contrary.c index d257a7a34430..824f2bf6c2f0 100644 --- a/test/battle/ability/contrary.c +++ b/test/battle/ability/contrary.c @@ -221,3 +221,23 @@ SINGLE_BATTLE_TEST("Contrary lowers a stat after using a move which would normal EXPECT_MUL_EQ(results[1].damageBefore, UQ_4_12(4.0), results[1].damageAfter); } } + +SINGLE_BATTLE_TEST("Sticky Web raises Speed by 1 for Contrary mon on switch-in") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_SNIVY) { Ability(ABILITY_CONTRARY); } + } WHEN { + TURN { MOVE(player, MOVE_STICKY_WEB); } + TURN { SWITCH(opponent, 1); } + TURN {} + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, player); + MESSAGE("A sticky web spreads out on the ground around the opposing team!"); + MESSAGE("2 sent out Snivy!"); + MESSAGE("Foe Snivy was caught in a Sticky Web!"); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent); + MESSAGE("Foe Snivy's Speed rose!"); + } +} diff --git a/test/battle/move_effect/belly_drum.c b/test/battle/move_effect/belly_drum.c index 82abaf30c455..612d4005c37c 100644 --- a/test/battle/move_effect/belly_drum.c +++ b/test/battle/move_effect/belly_drum.c @@ -105,7 +105,31 @@ SINGLE_BATTLE_TEST("Belly Drum's HP cost doesn't trigger effects that trigger on } } +SINGLE_BATTLE_TEST("Belly Drum minimizes the user's Attack stat with Contrary", s16 damage) +{ + bool32 raiseAttack; + PARAMETRIZE { raiseAttack = FALSE; } + PARAMETRIZE { raiseAttack = TRUE; } + GIVEN { + ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL); + PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_CONTRARY); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + if (raiseAttack) TURN { MOVE(player, MOVE_BELLY_DRUM); } + TURN { MOVE(player, MOVE_TACKLE); } + } SCENE { + if (raiseAttack) { + ANIMATION(ANIM_TYPE_MOVE, MOVE_BELLY_DRUM, player); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + MESSAGE("Wobbuffet cut its own HP and maximized ATTACK!"); // Message unaffected by Contrary + } + ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player); + HP_BAR(opponent, captureDamage: &results[i].damage); + } FINALLY { + EXPECT_MUL_EQ(results[1].damage, Q_4_12(4), results[0].damage); + } +} + TO_DO_BATTLE_TEST("Belly Drum maximizes the user's Attack stat, even when below 0"); -TO_DO_BATTLE_TEST("Belly Drum minimizes the user's Attack stat if it has Contrary"); // Should still say "maximized attack" TO_DO_BATTLE_TEST("Belly Drum fails if the user's Attack is already at +6, even with Contrary"); TO_DO_BATTLE_TEST("Belly Drum deducts HP if the user has contrary and is at -6"); diff --git a/test/battle/move_effect/protect.c b/test/battle/move_effect/protect.c index 60b55ebb7528..e5e75550e8c9 100644 --- a/test/battle/move_effect/protect.c +++ b/test/battle/move_effect/protect.c @@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("King's Shield, Silk Trap and Obstruct protect from damaging u32 j; static const u16 protectMoves[][3] = { // Move Stat Stages - {MOVE_KINGS_SHIELD, STAT_ATK, 1}, + {MOVE_KINGS_SHIELD, STAT_ATK, (B_KINGS_SHIELD_LOWER_ATK >= GEN_8) ? 1 : 2}, {MOVE_SILK_TRAP, STAT_SPEED, 1}, {MOVE_OBSTRUCT, STAT_DEF, 2}, }; @@ -99,7 +99,11 @@ SINGLE_BATTLE_TEST("King's Shield, Silk Trap and Obstruct protect from damaging NOT HP_BAR(opponent); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); if (statId == STAT_ATK) { + #if B_KINGS_SHIELD_LOWER_ATK >= GEN_8 MESSAGE("Wobbuffet's Attack fell!"); + #else + MESSAGE("Wobbuffet's Attack harshly fell!"); + #endif } else if (statId == STAT_SPEED) { MESSAGE("Wobbuffet's Speed fell!"); } else if (statId == STAT_DEF) { diff --git a/test/battle/move_effect/uproar.c b/test/battle/move_effect/uproar.c index fe6a4c9931f2..c463a8eaa114 100644 --- a/test/battle/move_effect/uproar.c +++ b/test/battle/move_effect/uproar.c @@ -8,6 +8,7 @@ ASSUMPTIONS DOUBLE_BATTLE_TEST("Uproar status causes sleeping pokemon to wake up during an attack") { + PASSES_RANDOMLY(1, 2, RNG_RANDOM_TARGET); // test fails if we target soundproof mon GIVEN { PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); } diff --git a/test/battle/status1/burn.c b/test/battle/status1/burn.c index 4da40589fb54..63d6506fb626 100644 --- a/test/battle/status1/burn.c +++ b/test/battle/status1/burn.c @@ -1,11 +1,10 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Burn deals 1/16th damage per turn") +SINGLE_BATTLE_TEST("Burn deals 1/16th (Gen7+) or 1/8th damage per turn") { u32 j; GIVEN { - ASSUME(B_BURN_DAMAGE >= GEN_LATEST); PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_BURN); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -14,7 +13,7 @@ SINGLE_BATTLE_TEST("Burn deals 1/16th damage per turn") } SCENE { s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); for (j = 0; j < 4; j++) - HP_BAR(player, damage: maxHP / 16); + HP_BAR(player, damage: maxHP / ((B_BURN_DAMAGE >= GEN_7) ? 16 : 8)); } } diff --git a/test/battle/status1/frostbite.c b/test/battle/status1/frostbite.c index bf4b1f7fcdd7..fc5fba69b1f4 100644 --- a/test/battle/status1/frostbite.c +++ b/test/battle/status1/frostbite.c @@ -23,7 +23,7 @@ SINGLE_BATTLE_TEST("Frostbite reduces the special attack by 50 percent") } THEN { EXPECT_EQ(reducedDamage * 2, normaleDamage); } } -SINGLE_BATTLE_TEST("Frostbite deals 1/16 damage to effected pokemon") +SINGLE_BATTLE_TEST("Frostbite deals 1/16th (Gen7+) or 1/8th damage to affected pokemon") { s16 frostbiteDamage; @@ -36,7 +36,7 @@ SINGLE_BATTLE_TEST("Frostbite deals 1/16 damage to effected pokemon") MESSAGE("Foe Wobbuffet is hurt by its frostbite!"); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_FRZ, opponent); HP_BAR(opponent, captureDamage: &frostbiteDamage); - } THEN { EXPECT_EQ(frostbiteDamage, opponent->maxHP / 16); } + } THEN { EXPECT_EQ(frostbiteDamage, opponent->maxHP / ((B_BURN_DAMAGE >= GEN_7) ? 16 : 8)); } } SINGLE_BATTLE_TEST("Frostbite is healed if hit with a thawing move")