Avoid doubling up on status moves in double battles. (#7452)

This commit is contained in:
surskitty 2025-08-01 12:10:44 -04:00 committed by GitHub
parent d060d547b6
commit a16d6e3bfe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 71 additions and 3 deletions

View File

@ -1720,7 +1720,17 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
if (gBattleMons[battlerAtk].volatiles.dragonCheer || gBattleMons[battlerAtk].volatiles.focusEnergy)
ADJUST_SCORE(-10);
break;
case EFFECT_NON_VOLATILE_STATUS:
if (GetBattlerMoveTargetType(battlerAtk, move) & MOVE_TARGET_FOES_AND_ALLY
&& PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
ADJUST_SCORE(-10);
if (DoesPartnerHaveSameMoveEffect(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove))
ADJUST_SCORE(-10);
break;
case EFFECT_CONFUSE:
if (GetBattlerMoveTargetType(battlerAtk, move) & MOVE_TARGET_FOES_AND_ALLY
&& PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
ADJUST_SCORE(-10);
case EFFECT_SWAGGER:
case EFFECT_FLATTER:
if (!AI_CanConfuse(battlerAtk, battlerDef, aiData->abilities[battlerDef], BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
@ -1853,7 +1863,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
case EFFECT_STICKY_WEB:
if (IsHazardOnSide(GetBattlerSide(battlerDef), HAZARDS_STICKY_WEB))
ADJUST_SCORE(-10);
else if (PartnerMoveIsSameNoTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove) && IsHazardOnSide(GetBattlerSide(battlerDef), HAZARDS_STICKY_WEB))
if (PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
ADJUST_SCORE(-10); // only one mon needs to set up Sticky Web
break;
case EFFECT_FORESIGHT:
@ -1881,7 +1891,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
{
ADJUST_SCORE(-10); //Both enemies are perish songed
}
else if (DoesPartnerHaveSameMoveEffect(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove))
else if (PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
{
ADJUST_SCORE(-10);
}
@ -2547,7 +2557,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
{
// This only happens if the ally already rolled on double trick room on final turn.
// Both Pokemon use Trick Room on the final turn of Trick Room to anticipate both opponents Protecting to stall out.
if (gFieldTimers.trickRoomTimer == gBattleTurnCounter)
if (gFieldStatuses & STATUS_FIELD_TRICK_ROOM && gFieldTimers.trickRoomTimer == gBattleTurnCounter)
ADJUST_SCORE(PERFECT_EFFECT);
else
ADJUST_SCORE(-10);
@ -2854,6 +2864,11 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
ADJUST_SCORE(-10);
}
break;
case EFFECT_COURT_CHANGE:
case EFFECT_TEATIME:
if (PartnerHasSameMoveEffectWithoutTarget(BATTLE_PARTNER(battlerAtk), move, aiData->partnerMove))
ADJUST_SCORE(-10);
break;
case EFFECT_PLACEHOLDER:
return 0; // cannot even select
} // move effect checks

View File

@ -85,6 +85,59 @@ AI_DOUBLE_BATTLE_TEST("AI will not use a status move if partner already chose He
}
}
TO_DO_BATTLE_TEST("AI understands Instruct")
TO_DO_BATTLE_TEST("AI understands Quick Guard")
TO_DO_BATTLE_TEST("AI understands Wide Guard")
AI_DOUBLE_BATTLE_TEST("AI will not use the same nondamaging move as its partner for no reason")
{
u32 move;
PARAMETRIZE { move = MOVE_AROMATHERAPY; }
PARAMETRIZE { move = MOVE_ELECTRIC_TERRAIN; }
PARAMETRIZE { move = MOVE_FOLLOW_ME; }
PARAMETRIZE { move = MOVE_GRASSY_TERRAIN; }
PARAMETRIZE { move = MOVE_GRAVITY; }
PARAMETRIZE { move = MOVE_HAIL; }
PARAMETRIZE { move = MOVE_HEAL_BELL; }
PARAMETRIZE { move = MOVE_LIGHT_SCREEN; }
PARAMETRIZE { move = MOVE_LUCKY_CHANT; }
PARAMETRIZE { move = MOVE_MAGIC_ROOM; }
PARAMETRIZE { move = MOVE_MISTY_TERRAIN; }
PARAMETRIZE { move = MOVE_MUD_SPORT; }
PARAMETRIZE { move = MOVE_PSYCHIC_TERRAIN; }
PARAMETRIZE { move = MOVE_RAIN_DANCE; }
PARAMETRIZE { move = MOVE_REFLECT; }
PARAMETRIZE { move = MOVE_SAFEGUARD; }
PARAMETRIZE { move = MOVE_SANDSTORM; }
PARAMETRIZE { move = MOVE_SNOWSCAPE; }
PARAMETRIZE { move = MOVE_SPOTLIGHT; }
PARAMETRIZE { move = MOVE_STEALTH_ROCK; }
PARAMETRIZE { move = MOVE_SUNNY_DAY; }
PARAMETRIZE { move = MOVE_TAILWIND; }
PARAMETRIZE { move = MOVE_TEETER_DANCE; }
PARAMETRIZE { move = MOVE_TRICK_ROOM; }
PARAMETRIZE { move = MOVE_WATER_SPORT; }
PARAMETRIZE { move = MOVE_COURT_CHANGE; }
PARAMETRIZE { move = MOVE_PERISH_SONG; }
PARAMETRIZE { move = MOVE_STICKY_WEB; }
PARAMETRIZE { move = MOVE_TEATIME; }
PARAMETRIZE { move = MOVE_WONDER_ROOM; }
GIVEN {
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Moves(move, MOVE_TACKLE); Status1(STATUS1_BURN); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(move, MOVE_TACKLE); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(move, MOVE_TACKLE); }
OPPONENT(SPECIES_WOBBUFFET) { Moves(move, MOVE_TACKLE); }
} WHEN {
TURN { EXPECT_MOVE(opponentLeft, move); EXPECT_MOVE(opponentRight, MOVE_TACKLE); }
}
}
AI_DOUBLE_BATTLE_TEST("AI will not choose Earthquake if it damages the partner without a positive effect")
{
ASSUME(GetMoveTarget(MOVE_EARTHQUAKE) == MOVE_TARGET_FOES_AND_ALLY);