AI sees dynamic moves and Nature Power as correct types for weather, terrain (#7759)

This commit is contained in:
surskitty 2025-09-19 14:50:13 -04:00 committed by GitHub
parent e92598e9e8
commit a55d603502
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 47 additions and 10 deletions

View File

@ -121,8 +121,8 @@ u32 AI_GetSwitchinWeather(struct BattlePokemon battleMon);
enum WeatherState IsWeatherActive(u32 flags);
bool32 CanAIFaintTarget(u32 battlerAtk, u32 battlerDef, u32 numHits);
bool32 CanIndexMoveFaintTarget(u32 battlerAtk, u32 battlerDef, u32 index, enum DamageCalcContext calcContext);
bool32 HasDamagingMove(u32 battlerId);
bool32 HasDamagingMoveOfType(u32 battlerId, u32 type);
bool32 HasDamagingMove(u32 battler);
bool32 HasDamagingMoveOfType(u32 battler, u32 type);
u32 GetBattlerSecondaryDamage(u32 battlerId);
bool32 BattlerWillFaintFromWeather(u32 battler, u32 ability);
bool32 BattlerWillFaintFromSecondaryDamage(u32 battler, u32 ability);

View File

@ -2929,30 +2929,38 @@ static inline bool32 IsMoveSleepClauseTrigger(u32 move)
return FALSE;
}
bool32 HasDamagingMove(u32 battlerId)
bool32 HasDamagingMove(u32 battler)
{
u32 i;
u16 *moves = GetMovesArray(battlerId);
u16 *moves = GetMovesArray(battler);
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && !IsBattleMoveStatus(moves[i]))
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && GetMovePower(moves[i]) > 0)
return TRUE;
}
return FALSE;
}
bool32 HasDamagingMoveOfType(u32 battlerId, u32 type)
bool32 HasDamagingMoveOfType(u32 battler, u32 type)
{
s32 i;
u16 *moves = GetMovesArray(battlerId);
u16 *moves = GetMovesArray(battler);
for (i = 0; i < MAX_MON_MOVES; i++)
{
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE
&& GetMoveType(moves[i]) == type && !IsBattleMoveStatus(moves[i]))
return TRUE;
if (moves[i] != MOVE_NONE && moves[i] != MOVE_UNAVAILABLE && GetMovePower(moves[i]) > 0)
{
u32 moveType = GetDynamicMoveType(GetBattlerMon(battler), moves[i], battler, MON_IN_BATTLE);
if (moveType != TYPE_NONE && type == moveType)
return TRUE;
if (GetMoveType(moves[i]) == type)
return TRUE;
if (GetMoveEffect(moves[i]) == EFFECT_NATURE_POWER && GetMoveType(GetNaturePowerMove(moves[i])) == type)
return TRUE;
}
}
return FALSE;

View File

@ -409,3 +409,32 @@ AI_SINGLE_BATTLE_TEST("AI sees Shield Dust immunity to additional effects")
TURN { EXPECT_MOVE(opponent, MOVE_CHILLING_WATER); }
}
}
AI_DOUBLE_BATTLE_TEST("AI sees type-changing moves as the correct type")
{
u32 species, fieldStatus, ability;
u64 aiFlags = AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT;
PARAMETRIZE { fieldStatus = MOVE_RAIN_DANCE; species = SPECIES_PRIMARINA; ability = ABILITY_NONE; }
PARAMETRIZE { fieldStatus = MOVE_RAIN_DANCE; species = SPECIES_PRIMARINA; ability = ABILITY_LIQUID_VOICE; }
PARAMETRIZE { fieldStatus = MOVE_ELECTRIC_TERRAIN; species = SPECIES_GEODUDE_ALOLA; ability = ABILITY_GALVANIZE; }
PARAMETRIZE { aiFlags |= AI_FLAG_OMNISCIENT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_PP_STALL_PREVENTION;
fieldStatus = MOVE_RAIN_DANCE; species = SPECIES_PRIMARINA; ability = ABILITY_NONE; }
PARAMETRIZE { aiFlags |= AI_FLAG_OMNISCIENT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_PP_STALL_PREVENTION;
fieldStatus = MOVE_RAIN_DANCE; species = SPECIES_PRIMARINA; ability = ABILITY_LIQUID_VOICE; }
PARAMETRIZE { aiFlags |= AI_FLAG_OMNISCIENT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_PP_STALL_PREVENTION;
fieldStatus = MOVE_ELECTRIC_TERRAIN; species = SPECIES_GEODUDE_ALOLA; ability = ABILITY_GALVANIZE; }
GIVEN {
AI_FLAGS(aiFlags);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Moves(fieldStatus, MOVE_RETURN, MOVE_TAUNT); }
OPPONENT(species) { Ability(ability); Moves(MOVE_HYPER_VOICE); }
} WHEN {
if (ability != ABILITY_NONE)
TURN { EXPECT_MOVE(opponentLeft, fieldStatus); }
else
TURN { NOT_EXPECT_MOVE(opponentLeft, fieldStatus); }
}
}