Fix roll handling in AI party damage calcs (#6733)

This commit is contained in:
Pawkkie 2025-05-01 04:15:19 -04:00 committed by GitHub
parent 4b1789ab1e
commit 1a2cd5645a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 14 deletions

View File

@ -228,7 +228,7 @@ void IncreaseSleepScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
void IncreaseConfusionScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
void IncreaseFrostbiteScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
s32 AI_CalcPartyMonDamage(u32 move, u32 battlerAtk, u32 battlerDef, struct BattlePokemon switchinCandidate, bool32 isPartyMonAttacker);
s32 AI_CalcPartyMonDamage(u32 move, u32 battlerAtk, u32 battlerDef, struct BattlePokemon switchinCandidate, enum DamageCalcContext calcContext);
u32 AI_WhoStrikesFirstPartyMon(u32 battlerAtk, u32 battlerDef, struct BattlePokemon switchinCandidate, u32 moveConsidered);
s32 AI_TryToClearStats(u32 battlerAtk, u32 battlerDef, bool32 isDoubleBattle);
bool32 AI_ShouldCopyStatChanges(u32 battlerAtk, u32 battlerDef);

View File

@ -1404,7 +1404,7 @@ static u32 GetBestMonDmg(struct Pokemon *party, int firstId, int lastId, u8 inva
if (aiMove != MOVE_NONE && !IsBattleMoveStatus(aiMove))
{
aiMove = GetMonData(&party[i], MON_DATA_MOVE1 + j);
dmg = AI_CalcPartyMonDamage(aiMove, battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, TRUE);
dmg = AI_CalcPartyMonDamage(aiMove, battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, AI_ATTACKING);
if (bestDmg < dmg)
{
bestDmg = dmg;
@ -1859,7 +1859,7 @@ static s32 GetMaxDamagePlayerCouldDealToSwitchin(u32 battler, u32 opposingBattle
playerMove = gBattleMons[opposingBattler].moves[i];
if (playerMove != MOVE_NONE && !IsBattleMoveStatus(playerMove) && GetMoveEffect(playerMove) != EFFECT_FOCUS_PUNCH)
{
damageTaken = AI_CalcPartyMonDamage(playerMove, opposingBattler, battler, battleMon, FALSE);
damageTaken = AI_CalcPartyMonDamage(playerMove, opposingBattler, battler, battleMon, AI_DEFENDING);
if (playerMove == gBattleStruct->choicedMove[opposingBattler]) // If player is choiced, only care about the choice locked move
return damageTaken;
if (damageTaken > maxDamageTaken)
@ -1990,12 +1990,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
aiMove = AI_DATA->switchinCandidate.battleMon.moves[j];
if (aiMove != MOVE_NONE && !IsBattleMoveStatus(aiMove))
{
if (AI_THINKING_STRUCT->aiFlags[GetThinkingBattler(battler)] & AI_FLAG_CONSERVATIVE)
damageDealt = AI_CalcPartyMonDamage(aiMove, battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, TRUE);
else
damageDealt = AI_CalcPartyMonDamage(aiMove, battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, TRUE);
}
damageDealt = AI_CalcPartyMonDamage(aiMove, battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, AI_ATTACKING);
// Offensive switchin decisions are based on which whether switchin moves first and whether it can win a 1v1
isSwitchinFirst = AI_WhoStrikesFirstPartyMon(battler, opposingBattler, AI_DATA->switchinCandidate.battleMon, aiMove);

View File

@ -3765,20 +3765,20 @@ void FreeRestoreBattleMons(struct BattlePokemon *savedBattleMons)
}
// party logic
s32 AI_CalcPartyMonDamage(u32 move, u32 battlerAtk, u32 battlerDef, struct BattlePokemon switchinCandidate, bool32 isPartyMonAttacker)
s32 AI_CalcPartyMonDamage(u32 move, u32 battlerAtk, u32 battlerDef, struct BattlePokemon switchinCandidate, enum DamageCalcContext calcContext)
{
struct SimulatedDamage dmg;
uq4_12_t effectiveness;
struct BattlePokemon *savedBattleMons = AllocSaveBattleMons();
if (isPartyMonAttacker)
if (calcContext == AI_ATTACKING)
{
gBattleMons[battlerAtk] = switchinCandidate;
AI_THINKING_STRUCT->saved[battlerDef].saved = TRUE;
SetBattlerAiData(battlerAtk, AI_DATA); // set known opposing battler data
AI_THINKING_STRUCT->saved[battlerDef].saved = FALSE;
}
else
else if (calcContext == AI_DEFENDING)
{
gBattleMons[battlerDef] = switchinCandidate;
AI_THINKING_STRUCT->saved[battlerAtk].saved = TRUE;
@ -3787,13 +3787,31 @@ s32 AI_CalcPartyMonDamage(u32 move, u32 battlerAtk, u32 battlerDef, struct Battl
}
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, FALSE, AI_GetWeather());
// restores original gBattleMon struct
FreeRestoreBattleMons(savedBattleMons);
if (isPartyMonAttacker)
if (calcContext == AI_ATTACKING)
{
SetBattlerAiData(battlerAtk, AI_DATA);
else
if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_RISKY && !(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_CONSERVATIVE))
return dmg.maximum;
else if (AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_CONSERVATIVE && !(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_RISKY))
return dmg.minimum;
else
return dmg.median;
}
else if (calcContext == AI_DEFENDING)
{
SetBattlerAiData(battlerDef, AI_DATA);
if (AI_THINKING_STRUCT->aiFlags[battlerDef] & AI_FLAG_RISKY && !(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_CONSERVATIVE))
return dmg.minimum;
else if (AI_THINKING_STRUCT->aiFlags[battlerDef] & AI_FLAG_CONSERVATIVE && !(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_RISKY))
return dmg.maximum;
else
return dmg.median;
}
return dmg.median;
}