I suspect the test is set up wrong, more than I have the logic wrong. Though that could also be true.

This commit is contained in:
surskitty 2025-07-11 00:31:47 -04:00
parent 3ee93c69ec
commit 026b1f25f2
4 changed files with 72 additions and 14 deletions

View File

@ -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, ...) \

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}
}
}