From 026b1f25f24072ee36f8d4c2e81c37a40bb38729 Mon Sep 17 00:00:00 2001 From: surskitty Date: Fri, 11 Jul 2025 00:31:47 -0400 Subject: [PATCH] I suspect the test is set up wrong, more than I have the logic wrong. Though that could also be true. --- include/random.h | 5 +++ src/battle_ai_main.c | 3 ++ src/battle_ai_util.c | 30 +++++++------- test/battle/ai/ai_assume_powerful_status.c | 48 ++++++++++++++++++++++ 4 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 test/battle/ai/ai_assume_powerful_status.c diff --git a/include/random.h b/include/random.h index f23ff2f184..df749312fd 100644 --- a/include/random.h +++ b/include/random.h @@ -202,6 +202,11 @@ enum RandomTag RNG_AI_BOOST_INTO_HAZE, RNG_HEALER, RNG_DEXNAV_ENCOUNTER_LEVEL, + RNG_AI_ASSUME_POWERFUL_STATUS_SLEEP, + RNG_AI_ASSUME_POWERFUL_STATUS_NONVOLATILE, + RNG_AI_ASSUME_POWERFUL_STATUS_HIGH_ODDS, + RNG_AI_ASSUME_POWERFUL_STATUS_MEDIUM_ODDS, + RNG_AI_ASSUME_POWERFUL_STATUS_LOW_ODDS, }; #define RandomWeighted(tag, ...) \ diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index a69edaa48f..a14ebd4c1a 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -570,6 +570,9 @@ void SetBattlerAiData(u32 battler, struct AiLogicData *aiData) if (IsAiBattlerAssumingStab()) RecordMovesBasedOnStab(battler); + + if (IsAiBattlerAssumingPowerfulStatus()) + RecordPowerfulStatusMoves(battler); } #define BYPASSES_ACCURACY_CALC 101 // 101 indicates for ai that the move will always hit diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index b6a208a9c7..f09fe2d132 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -141,6 +141,15 @@ bool32 IsAiBattlerAssumingStab() return FALSE; } +bool32 IsAiBattlerAssumingPowerfulStatus() +{ + if (gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_LEFT] & AI_FLAG_ASSUME_POWERFUL_STATUS + || gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_RIGHT] & AI_FLAG_ASSUME_POWERFUL_STATUS) + return TRUE; + + return FALSE; +} + bool32 IsAiBattlerPredictingAbility(u32 battlerId) { if (gAiThinkingStruct->aiFlags[B_POSITION_OPPONENT_LEFT] & AI_FLAG_WEIGH_ABILITY_PREDICTION @@ -251,18 +260,13 @@ void SaveBattlerData(u32 battlerId) bool32 ShouldRecordStatusMove(u32 move) { - u32 rand = Random() % 100; - - if (rand >= ASSUME_POWERFUL_STATUS_HIGH_ODDS) - return FALSE; - switch (GetMoveEffect(move)) { // variable odds by additional effect case EFFECT_NON_VOLATILE_STATUS: - if (GetMoveNonVolatileStatus(move) == MOVE_EFFECT_SLEEP) + if (GetMoveNonVolatileStatus(move) == MOVE_EFFECT_SLEEP && RandomPercentage(RNG_AI_ASSUME_POWERFUL_STATUS_SLEEP, ASSUME_POWERFUL_STATUS_HIGH_ODDS)) return TRUE; - else if (rand < ASSUME_POWERFUL_STATUS_MEDIUM_ODDS) + else if (RandomPercentage(RNG_AI_ASSUME_POWERFUL_STATUS_NONVOLATILE, ASSUME_POWERFUL_STATUS_MEDIUM_ODDS)) return TRUE; break; // High odds @@ -276,7 +280,7 @@ bool32 ShouldRecordStatusMove(u32 move) case EFFECT_REVIVAL_BLESSING: case EFFECT_SHED_TAIL: case EFFECT_STICKY_WEB: - return TRUE; + return RandomPercentage(RNG_AI_ASSUME_POWERFUL_STATUS_HIGH_ODDS, ASSUME_POWERFUL_STATUS_HIGH_ODDS); // Medium odds case EFFECT_AFTER_YOU: case EFFECT_DEFOG: @@ -288,8 +292,10 @@ bool32 ShouldRecordStatusMove(u32 move) case EFFECT_MEMENTO: case EFFECT_PARTING_SHOT: case EFFECT_PROTECT: + case EFFECT_REST: case EFFECT_RESTORE_HP: case EFFECT_ROAR: + case EFFECT_SLEEP_TALK: case EFFECT_TAUNT: case EFFECT_TAILWIND: case EFFECT_TELEPORT: @@ -311,9 +317,7 @@ bool32 ShouldRecordStatusMove(u32 move) case EFFECT_GRASSY_TERRAIN: case EFFECT_MISTY_TERRAIN: case EFFECT_PSYCHIC_TERRAIN: - if (rand < ASSUME_POWERFUL_STATUS_MEDIUM_ODDS) - return TRUE; - break; + return RandomPercentage(RNG_AI_ASSUME_POWERFUL_STATUS_MEDIUM_ODDS, ASSUME_POWERFUL_STATUS_MEDIUM_ODDS); // Low odds case EFFECT_COURT_CHANGE: case EFFECT_DOODLE: @@ -329,9 +333,7 @@ bool32 ShouldRecordStatusMove(u32 move) case EFFECT_SKILL_SWAP: case EFFECT_SPEED_SWAP: case EFFECT_WORRY_SEED: - if (rand < ASSUME_POWERFUL_STATUS_LOW_ODDS) - return TRUE; - break; + return RandomPercentage(RNG_AI_ASSUME_POWERFUL_STATUS_LOW_ODDS, ASSUME_POWERFUL_STATUS_LOW_ODDS); default: break; } diff --git a/test/battle/ai/ai_assume_powerful_status.c b/test/battle/ai/ai_assume_powerful_status.c new file mode 100644 index 0000000000..7c1f08f352 --- /dev/null +++ b/test/battle/ai/ai_assume_powerful_status.c @@ -0,0 +1,48 @@ +#include "global.h" +#include "test/battle.h" +#include "battle_ai_util.h" + +AI_DOUBLE_BATTLE_TEST("AI_FLAG_ASSUME_POWERFUL_STATUS correctly records assumed status moves") +{ + PASSES_RANDOMLY(ASSUME_POWERFUL_STATUS_HIGH_ODDS, 100, RNG_AI_ASSUME_POWERFUL_STATUS_HIGH_ODDS); + PASSES_RANDOMLY(ASSUME_POWERFUL_STATUS_MEDIUM_ODDS, 100, RNG_AI_ASSUME_POWERFUL_STATUS_MEDIUM_ODDS); + PASSES_RANDOMLY(ASSUME_POWERFUL_STATUS_LOW_ODDS, 100, RNG_AI_ASSUME_POWERFUL_STATUS_LOW_ODDS); + + u32 aiFlag = 0; + PARAMETRIZE { aiFlag = AI_FLAG_ASSUME_POWERFUL_STATUS; } + PARAMETRIZE { aiFlag = 0; } + GIVEN { + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | aiFlag); + PLAYER(SPECIES_TYPHLOSION) { Moves(MOVE_TACKLE, MOVE_COURT_CHANGE, MOVE_FAKE_OUT); } + PLAYER(SPECIES_ZIGZAGOON) { Moves(MOVE_HAIL, MOVE_SHED_TAIL, MOVE_THUNDERBOLT); } + OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); } + OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_TACKLE); } + } WHEN { + TURN { MOVE(playerLeft, MOVE_TACKLE, target:opponentLeft); MOVE(playerRight, MOVE_THUNDERBOLT, target:opponentRight); } + } THEN { + if (aiFlag == AI_FLAG_ASSUME_POWERFUL_STATUS) + { + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_LEFT][0], MOVE_TACKLE); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_LEFT][1], MOVE_COURT_CHANGE); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_LEFT][2], MOVE_FAKE_OUT); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_LEFT][3], MOVE_NONE); + + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_RIGHT][0], MOVE_HAIL); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_RIGHT][1], MOVE_SHED_TAIL); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_RIGHT][2], MOVE_THUNDERBOLT); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_RIGHT][3], MOVE_NONE); + } + else if (aiFlag == 0) + { + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_LEFT][0], MOVE_TACKLE); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_LEFT][1], MOVE_NONE); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_LEFT][2], MOVE_NONE); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_LEFT][3], MOVE_NONE); + + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_RIGHT][0], MOVE_NONE); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_RIGHT][1], MOVE_NONE); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_RIGHT][2], MOVE_THUNDERBOLT); + EXPECT_EQ(gBattleHistory->usedMoves[B_POSITION_PLAYER_RIGHT][3], MOVE_NONE); + } + } +}