Add ShouldSwitch result to AiLogicData (#5440)
* Add ShouldSwitch to AiLogicData * Convert shouldSwitch to bitfield * Update include/battle.h Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com> * Update include/battle.h --------- Co-authored-by: Alex <93446519+AlexOn1ine@users.noreply.github.com>
This commit is contained in:
parent
5130ea9da3
commit
5e027754c7
5 changed files with 12 additions and 11 deletions
|
@ -366,11 +366,12 @@ struct AiLogicData
|
|||
u8 effectiveness[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // attacker, target, moveIndex
|
||||
u8 moveAccuracy[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT][MAX_MON_MOVES]; // attacker, target, moveIndex
|
||||
u8 moveLimitations[MAX_BATTLERS_COUNT];
|
||||
bool8 shouldSwitchMon; // Because all available moves have no/little effect. Each bit per battler.
|
||||
u8 shouldSwitchIfBadMoves; // Because all available moves have no/little effect. Each bit per battler.
|
||||
u8 monToSwitchId[MAX_BATTLERS_COUNT]; // ID of the mon to switch.
|
||||
bool8 weatherHasEffect; // The same as WEATHER_HAS_EFFECT. Stored here, so it's called only once.
|
||||
u8 mostSuitableMonId[MAX_BATTLERS_COUNT]; // Stores result of GetMostSuitableMonToSwitchInto, which decides which generic mon the AI would switch into if they decide to switch. This can be overruled by specific mons found in ShouldSwitch; the final resulting mon is stored in AI_monToSwitchIntoId.
|
||||
struct SwitchinCandidate switchinCandidate; // Struct used for deciding which mon to switch to in battle_ai_switch_items.c
|
||||
u8 shouldSwitch; // Stores result of ShouldSwitch, which decides whether a mon should be switched out
|
||||
};
|
||||
|
||||
struct AI_ThinkingStruct
|
||||
|
|
|
@ -504,12 +504,12 @@ static bool32 AI_SwitchMonIfSuitable(u32 battler, bool32 doubleBattle)
|
|||
if (doubleBattle)
|
||||
{
|
||||
u32 partner = BATTLE_PARTNER(battler);
|
||||
if (AI_DATA->shouldSwitchMon & (1u << partner) && AI_DATA->monToSwitchId[partner] == monToSwitchId)
|
||||
if (AI_DATA->shouldSwitchIfBadMoves & (1u << partner) && AI_DATA->monToSwitchId[partner] == monToSwitchId)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
AI_DATA->shouldSwitchMon |= 1 << battler;
|
||||
AI_DATA->shouldSwitchIfBadMoves |= 1 << battler;
|
||||
AI_DATA->monToSwitchId[battler] = monToSwitchId;
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -3679,7 +3679,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
|||
}
|
||||
break;
|
||||
case EFFECT_BATON_PASS:
|
||||
if (ShouldSwitch(battlerAtk, FALSE) && (gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE
|
||||
if ((AI_DATA->shouldSwitch & (1u << battlerAtk)) && (gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE
|
||||
|| (gStatuses3[battlerAtk] & (STATUS3_ROOTED | STATUS3_AQUA_RING | STATUS3_MAGNET_RISE | STATUS3_POWER_TRICK))
|
||||
|| AnyStatIsRaised(battlerAtk)))
|
||||
ADJUST_SCORE(BEST_EFFECT);
|
||||
|
|
|
@ -218,9 +218,9 @@ static bool32 HasBadOdds(u32 battler, bool32 emitResult)
|
|||
|
||||
static bool32 ShouldSwitchIfAllBadMoves(u32 battler, bool32 emitResult)
|
||||
{
|
||||
if (AI_DATA->shouldSwitchMon & (1u << battler))
|
||||
if (AI_DATA->shouldSwitchIfBadMoves & (1u << battler))
|
||||
{
|
||||
AI_DATA->shouldSwitchMon &= ~(1u << battler);
|
||||
AI_DATA->shouldSwitchIfBadMoves &= ~(1u << battler);
|
||||
gBattleStruct->AI_monToSwitchIntoId[battler] = AI_DATA->monToSwitchId[battler];
|
||||
if (emitResult)
|
||||
BtlController_EmitTwoReturnValues(battler, BUFFER_B, B_ACTION_SWITCH, 0);
|
||||
|
|
|
@ -2699,10 +2699,8 @@ enum {
|
|||
bool32 ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32 moveIndex)
|
||||
{
|
||||
bool32 hasStatBoost = AnyUsefulStatIsRaised(battlerAtk) || gBattleMons[battlerDef].statStages[STAT_EVASION] >= 9; //Significant boost in evasion for any class
|
||||
bool32 shouldSwitch;
|
||||
u32 battlerToSwitch;
|
||||
|
||||
shouldSwitch = ShouldSwitch(battlerAtk, FALSE);
|
||||
battlerToSwitch = gBattleStruct->AI_monToSwitchIntoId[battlerAtk];
|
||||
|
||||
if (PartyBattlerShouldAvoidHazards(battlerAtk, battlerToSwitch))
|
||||
|
@ -2727,7 +2725,7 @@ bool32 ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32
|
|||
if (CanTargetFaintAi(battlerDef, battlerAtk))
|
||||
return PIVOT; // Won't get the two turns, pivot
|
||||
|
||||
if (!IS_MOVE_STATUS(move) && (shouldSwitch
|
||||
if (!IS_MOVE_STATUS(move) && ((AI_DATA->shouldSwitch & (1u << battlerAtk))
|
||||
|| (AtMaxHp(battlerDef) && (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH
|
||||
|| (B_STURDY >= GEN_5 && defAbility == ABILITY_STURDY)
|
||||
|| defAbility == ABILITY_MULTISCALE
|
||||
|
@ -2742,7 +2740,7 @@ bool32 ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32
|
|||
|| defAbility == ABILITY_SHADOW_SHIELD)))
|
||||
return PIVOT; // pivot to break sash/sturdy/multiscale
|
||||
|
||||
if (shouldSwitch)
|
||||
if (AI_DATA->shouldSwitch & (1u << battlerAtk))
|
||||
return PIVOT;
|
||||
|
||||
/* TODO - check if switchable mon unafffected by/will remove hazards
|
||||
|
@ -2813,7 +2811,7 @@ bool32 ShouldPivot(u32 battlerAtk, u32 battlerDef, u32 defAbility, u32 move, u32
|
|||
else if (CanAIFaintTarget(battlerAtk, battlerDef, 2))
|
||||
{
|
||||
// can knock out foe in 2 hits
|
||||
if (IS_MOVE_STATUS(move) && (shouldSwitch //Damaging move
|
||||
if (IS_MOVE_STATUS(move) && ((AI_DATA->shouldSwitch & (1u << battlerAtk)) //Damaging move
|
||||
//&& (switchScore >= SWITCHING_INCREASE_RESIST_ALL_MOVES + SWITCHING_INCREASE_KO_FOE //remove hazards
|
||||
|| (AI_DATA->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH && AtMaxHp(battlerDef))))
|
||||
return DONT_PIVOT; // Pivot to break the sash
|
||||
|
|
|
@ -4178,6 +4178,8 @@ static void HandleTurnActionSelectionState(void)
|
|||
if ((gBattleTypeFlags & BATTLE_TYPE_HAS_AI || IsWildMonSmart())
|
||||
&& (BattlerHasAi(battler) && !(gBattleTypeFlags & BATTLE_TYPE_PALACE)))
|
||||
{
|
||||
if (ShouldSwitch(battler, FALSE))
|
||||
AI_DATA->shouldSwitch |= (1u << battler);
|
||||
if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_RISKY) // Risky AI switches aggressively even mid battle
|
||||
AI_DATA->mostSuitableMonId[battler] = GetMostSuitableMonToSwitchInto(battler, TRUE);
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue