Split ai function IsBattlerTrapped (#6438)
This commit is contained in:
parent
29fa249762
commit
6031bb2a78
@ -52,7 +52,8 @@ u32 GetTotalBaseStat(u32 species);
|
||||
bool32 IsTruantMonVulnerable(u32 battlerAI, u32 opposingBattler);
|
||||
bool32 AI_BattlerAtMaxHp(u32 battler);
|
||||
u32 GetHealthPercentage(u32 battler);
|
||||
bool32 IsBattlerTrapped(u32 battler, bool32 switching);
|
||||
bool32 AI_CanBattlerEscape(u32 battler);
|
||||
bool32 IsBattlerTrapped(u32 battlerAtk, u32 battlerDef);
|
||||
s32 AI_WhoStrikesFirst(u32 battlerAI, u32 battler2, u32 moveConsidered);
|
||||
bool32 CanTargetFaintAi(u32 battlerDef, u32 battlerAtk);
|
||||
u32 NoOfHitsForTargetToFaintAI(u32 battlerDef, u32 battlerAtk);
|
||||
|
||||
@ -1600,7 +1600,9 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
ADJUST_SCORE(-10); // if mon will wake up, is not asleep, or is not comatose
|
||||
break;
|
||||
case EFFECT_MEAN_LOOK:
|
||||
if (IsBattlerTrapped(battlerDef, TRUE) || DoesPartnerHaveSameMoveEffect(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove))
|
||||
if (AI_CanBattlerEscape(battlerDef)
|
||||
|| IsBattlerTrapped(battlerAtk, battlerDef)
|
||||
|| DoesPartnerHaveSameMoveEffect(BATTLE_PARTNER(battlerAtk), battlerDef, move, aiData->partnerMove))
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
case EFFECT_NIGHTMARE:
|
||||
@ -2713,7 +2715,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
else if (GetBattleMoveCategory(move) == DAMAGE_CATEGORY_STATUS
|
||||
&& (CountUsablePartyMons(battlerAtk) < 1
|
||||
|| AI_DATA->mostSuitableMonId[battlerAtk] == PARTY_SIZE
|
||||
|| IsBattlerTrapped(battlerAtk, TRUE)))
|
||||
|| (!AI_CanBattlerEscape(battlerAtk) && IsBattlerTrapped(battlerDef, battlerAtk))))
|
||||
ADJUST_SCORE(-30);
|
||||
}
|
||||
|
||||
@ -3666,7 +3668,8 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
|| aiData->abilities[battlerDef] == ABILITY_MAGIC_GUARD)
|
||||
break;
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
if (!HasDamagingMove(battlerDef) || IsBattlerTrapped(battlerDef, FALSE)
|
||||
if (!HasDamagingMove(battlerDef)
|
||||
|| (!AI_CanBattlerEscape(battlerDef) && IsBattlerTrapped(battlerAtk, battlerDef))
|
||||
|| aiData->holdEffects[battlerAtk] == HOLD_EFFECT_BIG_ROOT)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
@ -3761,7 +3764,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
case EFFECT_CURSE:
|
||||
if (IS_BATTLER_OF_TYPE(battlerAtk, TYPE_GHOST))
|
||||
{
|
||||
if (IsBattlerTrapped(battlerDef, TRUE))
|
||||
if (!AI_CanBattlerEscape(battlerDef) && IsBattlerTrapped(battlerAtk, battlerDef))
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
else
|
||||
ADJUST_SCORE(WEAK_EFFECT);
|
||||
@ -3854,7 +3857,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case EFFECT_PERISH_SONG:
|
||||
if (IsBattlerTrapped(battlerDef, TRUE))
|
||||
if (!AI_CanBattlerEscape(battlerDef) && IsBattlerTrapped(battlerAtk, battlerDef))
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
break;
|
||||
case EFFECT_SANDSTORM:
|
||||
@ -3995,7 +3998,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
break; // Don't use if the attract won't have a change to activate
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_ANY
|
||||
|| (gBattleMons[battlerDef].status2 & STATUS2_CONFUSION)
|
||||
|| IsBattlerTrapped(battlerDef, TRUE))
|
||||
|| (!AI_CanBattlerEscape(battlerDef) && IsBattlerTrapped(battlerAtk, battlerDef)))
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
else
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
@ -5091,7 +5094,7 @@ static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u32 move, s32 scor
|
||||
|| CountUsablePartyMons(battlerAtk) == 0
|
||||
|| !IsBattleMoveStatus(move)
|
||||
|| !HasMoveEffect(battlerAtk, EFFECT_BATON_PASS)
|
||||
|| IsBattlerTrapped(battlerAtk, TRUE))
|
||||
|| (!AI_CanBattlerEscape(battlerAtk) && IsBattlerTrapped(battlerDef, battlerAtk)))
|
||||
return score;
|
||||
|
||||
u32 effect = GetMoveEffect(move);
|
||||
@ -5582,7 +5585,16 @@ static void AI_Watch(void)
|
||||
// Roaming pokemon logic
|
||||
static s32 AI_Roaming(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
{
|
||||
if (IsBattlerTrapped(battlerAtk, FALSE))
|
||||
bool32 roamerCanFlee = FALSE;
|
||||
|
||||
if (AI_CanBattlerEscape(battlerAtk))
|
||||
roamerCanFlee = TRUE;
|
||||
else if (AI_DATA->abilities[battlerAtk] == ABILITY_RUN_AWAY)
|
||||
roamerCanFlee = TRUE;
|
||||
else if (AI_DATA->holdEffects[battlerAtk] == HOLD_EFFECT_CAN_ALWAYS_RUN)
|
||||
roamerCanFlee = TRUE;
|
||||
|
||||
if (!roamerCanFlee && IsBattlerTrapped(battlerDef, battlerAtk))
|
||||
return score;
|
||||
|
||||
AI_Flee();
|
||||
|
||||
@ -339,25 +339,35 @@ bool32 AI_BattlerAtMaxHp(u32 battlerId)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsBattlerTrapped(u32 battler, bool32 checkSwitch)
|
||||
|
||||
bool32 AI_CanBattlerEscape(u32 battler)
|
||||
{
|
||||
u32 holdEffect = AI_DATA->holdEffects[battler];
|
||||
|
||||
if (B_GHOSTS_ESCAPE >= GEN_6 && IS_BATTLER_OF_TYPE(battler, TYPE_GHOST))
|
||||
return FALSE;
|
||||
if (checkSwitch && holdEffect == HOLD_EFFECT_SHED_SHELL)
|
||||
return FALSE;
|
||||
else if (!checkSwitch && AI_DATA->abilities[battler] == ABILITY_RUN_AWAY)
|
||||
return FALSE;
|
||||
else if (!checkSwitch && holdEffect == HOLD_EFFECT_CAN_ALWAYS_RUN)
|
||||
return FALSE;
|
||||
else if (gBattleMons[battler].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED))
|
||||
return TRUE;
|
||||
else if (gStatuses3[battler] & (STATUS3_ROOTED | STATUS3_SKY_DROPPED))
|
||||
if (holdEffect == HOLD_EFFECT_SHED_SHELL)
|
||||
return TRUE;
|
||||
else if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK)
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsBattlerTrapped(u32 battlerAtk, u32 battlerDef)
|
||||
{
|
||||
if (gBattleMons[battlerDef].status2 & (STATUS2_ESCAPE_PREVENTION | STATUS2_WRAPPED))
|
||||
return TRUE;
|
||||
else if (IsAbilityPreventingEscape(battler))
|
||||
if (gStatuses3[battlerDef] & (STATUS3_ROOTED | STATUS3_SKY_DROPPED))
|
||||
return TRUE;
|
||||
if (gFieldStatuses & STATUS_FIELD_FAIRY_LOCK)
|
||||
return TRUE;
|
||||
if (AI_IsAbilityOnSide(battlerAtk, ABILITY_SHADOW_TAG)
|
||||
&& (B_SHADOW_TAG_ESCAPE >= GEN_4 && AI_DATA->abilities[battlerDef] != ABILITY_SHADOW_TAG))
|
||||
return TRUE;
|
||||
if (AI_IsAbilityOnSide(battlerAtk, ABILITY_ARENA_TRAP)
|
||||
&& IsBattlerGrounded(battlerAtk))
|
||||
return TRUE;
|
||||
if (AI_IsAbilityOnSide(battlerAtk, ABILITY_MAGNET_PULL)
|
||||
&& IS_BATTLER_OF_TYPE(battlerAtk, TYPE_STEEL))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
@ -3256,7 +3266,10 @@ u32 ShouldTryToFlinch(u32 battlerAtk, u32 battlerDef, u32 atkAbility, u32 defAbi
|
||||
|
||||
bool32 ShouldTrap(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
{
|
||||
if (IsBattlerTrapped(battlerDef, TRUE))
|
||||
if (AI_CanBattlerEscape(battlerDef))
|
||||
return FALSE;
|
||||
|
||||
if (IsBattlerTrapped(battlerAtk, battlerDef))
|
||||
return FALSE;
|
||||
|
||||
if (BattlerWillFaintFromSecondaryDamage(battlerDef, AI_DATA->abilities[battlerDef]))
|
||||
|
||||
@ -845,3 +845,15 @@ AI_SINGLE_BATTLE_TEST("AI won't use Sucker Punch if it expects a move of the sam
|
||||
TURN { MOVE(player, MOVE_QUICK_ATTACK); EXPECT_MOVE(opponent, MOVE_TACKLE); }
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI score for Mean Look will be decreased if target can escape")
|
||||
{
|
||||
GIVEN {
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT);
|
||||
PLAYER(SPECIES_BULBASAUR) { Item(ITEM_SHED_SHELL); }
|
||||
OPPONENT(SPECIES_BULBASAUR) { Moves(MOVE_TACKLE, MOVE_MEAN_LOOK); }
|
||||
} WHEN {
|
||||
TURN { SCORE_EQ_VAL(opponent, MOVE_MEAN_LOOK, 90); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user