Add AI_GetBattlerMoveTargetType()

Add AI version of the function that handles move target selection, as it needs to have ability and item info that it may not have access to.
This commit is contained in:
BuffelSaft 2022-04-27 22:23:20 +12:00
parent af6242f2e0
commit 746d9ea6c5
3 changed files with 21 additions and 10 deletions

View File

@ -60,6 +60,7 @@ bool32 IsAbilityOfRating(u16 ability, s8 rating);
s8 GetAbilityRating(u16 ability); s8 GetAbilityRating(u16 ability);
bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability); bool32 AI_IsAbilityOnSide(u32 battlerId, u32 ability);
bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move); bool32 AI_MoveMakesContact(u32 ability, u32 holdEffect, u16 move);
u32 AI_GetBattlerMoveTargetType(u8 battlerId, u16 move);
// stat stage checks // stat stage checks
bool32 AnyStatIsRaised(u8 battlerId); bool32 AnyStatIsRaised(u8 battlerId);

View File

@ -550,7 +550,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
u8 atkPriority = GetMovePriority(battlerAtk, move); u8 atkPriority = GetMovePriority(battlerAtk, move);
u16 moveEffect = gBattleMoves[move].effect; u16 moveEffect = gBattleMoves[move].effect;
s32 moveType; s32 moveType;
u16 moveTarget = GetBattlerMoveTargetType(battlerAtk, move); u16 moveTarget = AI_GetBattlerMoveTargetType(battlerAtk, move);
u16 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect, move); u16 accuracy = AI_GetMoveAccuracy(battlerAtk, battlerDef, AI_DATA->atkAbility, AI_DATA->defAbility, AI_DATA->atkHoldEffect, AI_DATA->defHoldEffect, move);
u8 effectiveness = AI_GetMoveEffectiveness(move, battlerAtk, battlerDef); u8 effectiveness = AI_GetMoveEffectiveness(move, battlerAtk, battlerDef);
bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk); bool32 isDoubleBattle = IsValidDoubleBattle(battlerAtk);
@ -2371,7 +2371,7 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
} }
else else
{ {
if (GetBattlerMoveTargetType(battlerDef, instructedMove) & (MOVE_TARGET_SELECTED if (AI_GetBattlerMoveTargetType(battlerDef, instructedMove) & (MOVE_TARGET_SELECTED
| MOVE_TARGET_DEPENDS | MOVE_TARGET_DEPENDS
| MOVE_TARGET_RANDOM | MOVE_TARGET_RANDOM
| MOVE_TARGET_BOTH | MOVE_TARGET_BOTH
@ -2568,7 +2568,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
// move data // move data
u8 moveType = gBattleMoves[move].type; u8 moveType = gBattleMoves[move].type;
u16 effect = gBattleMoves[move].effect; u16 effect = gBattleMoves[move].effect;
u16 moveTarget = GetBattlerMoveTargetType(battlerAtk, move); u16 moveTarget = AI_GetBattlerMoveTargetType(battlerAtk, move);
// ally data // ally data
u8 battlerAtkPartner = AI_DATA->battlerAtkPartner; u8 battlerAtkPartner = AI_DATA->battlerAtkPartner;
u16 atkPartnerAbility = AI_DATA->atkPartnerAbility; u16 atkPartnerAbility = AI_DATA->atkPartnerAbility;
@ -2875,7 +2875,7 @@ static s16 AI_DoubleBattle(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (instructedMove != MOVE_NONE if (instructedMove != MOVE_NONE
&& !IS_MOVE_STATUS(instructedMove) && !IS_MOVE_STATUS(instructedMove)
&& (GetBattlerMoveTargetType(battlerAtkPartner, instructedMove) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) // Use instruct on multi-target moves && (AI_GetBattlerMoveTargetType(battlerAtkPartner, instructedMove) & (MOVE_TARGET_BOTH | MOVE_TARGET_FOES_AND_ALLY))) // Use instruct on multi-target moves
{ {
RETURN_SCORE_PLUS(1); RETURN_SCORE_PLUS(1);
} }
@ -3698,24 +3698,24 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
break; break;
case MOVE_WIDE_GUARD: case MOVE_WIDE_GUARD:
if (predictedMove != MOVE_NONE && GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_BOTH)) if (predictedMove != MOVE_NONE && AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_FOES_AND_ALLY | MOVE_TARGET_BOTH))
{ {
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
} }
else if (isDoubleBattle && GetBattlerMoveTargetType(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove) & MOVE_TARGET_FOES_AND_ALLY) else if (isDoubleBattle && AI_GetBattlerMoveTargetType(AI_DATA->battlerAtkPartner, AI_DATA->partnerMove) & MOVE_TARGET_FOES_AND_ALLY)
{ {
if (AI_DATA->atkAbility != ABILITY_TELEPATHY) if (AI_DATA->atkAbility != ABILITY_TELEPATHY)
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
} }
break; break;
case MOVE_CRAFTY_SHIELD: case MOVE_CRAFTY_SHIELD:
if (predictedMove != MOVE_NONE && IS_MOVE_STATUS(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER)) if (predictedMove != MOVE_NONE && IS_MOVE_STATUS(predictedMove) && !(AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER))
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
break; break;
case MOVE_MAT_BLOCK: case MOVE_MAT_BLOCK:
if (gDisableStructs[battlerAtk].isFirstTurn && predictedMove != MOVE_NONE if (gDisableStructs[battlerAtk].isFirstTurn && predictedMove != MOVE_NONE
&& !IS_MOVE_STATUS(predictedMove) && !(GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER)) && !IS_MOVE_STATUS(predictedMove) && !(AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & MOVE_TARGET_USER))
ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score); ProtectChecks(battlerAtk, battlerDef, move, predictedMove, &score);
break; break;
case MOVE_KINGS_SHIELD: case MOVE_KINGS_SHIELD:
@ -4160,7 +4160,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
score += 10; score += 10;
break; break;
case EFFECT_MAGIC_COAT: case EFFECT_MAGIC_COAT:
if (IS_MOVE_STATUS(predictedMove) && GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_SELECTED | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH)) if (IS_MOVE_STATUS(predictedMove) && AI_GetBattlerMoveTargetType(battlerDef, predictedMove) & (MOVE_TARGET_SELECTED | MOVE_TARGET_OPPONENTS_FIELD | MOVE_TARGET_BOTH))
score += 3; score += 3;
break; break;
case EFFECT_RECYCLE: case EFFECT_RECYCLE:

View File

@ -1251,6 +1251,16 @@ bool32 AI_WeatherHasEffect(void)
return TRUE; return TRUE;
} }
u32 AI_GetBattlerMoveTargetType(u8 battlerId, u16 move)
{
u32 target;
if (gBattleMoves[move].effect == EFFECT_EXPANDING_FORCE && AI_IsTerrainAffected(battlerId, STATUS_FIELD_PSYCHIC_TERRAIN))
return MOVE_TARGET_BOTH;
else
return gBattleMoves[move].target;
}
bool32 IsAromaVeilProtectedMove(u16 move) bool32 IsAromaVeilProtectedMove(u16 move)
{ {
u32 i; u32 i;
@ -1919,7 +1929,7 @@ bool32 HasMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef, u8 accCheck, bool32
if (ignoreStatus && IS_MOVE_STATUS(moves[i])) if (ignoreStatus && IS_MOVE_STATUS(moves[i]))
continue; continue;
else if ((!IS_MOVE_STATUS(moves[i]) && gBattleMoves[moves[i]].accuracy == 0) else if ((!IS_MOVE_STATUS(moves[i]) && gBattleMoves[moves[i]].accuracy == 0)
|| GetBattlerMoveTargetType(battlerAtk, moves[i]) & (MOVE_TARGET_USER | MOVE_TARGET_OPPONENTS_FIELD)) || AI_GetBattlerMoveTargetType(battlerAtk, moves[i]) & (MOVE_TARGET_USER | MOVE_TARGET_OPPONENTS_FIELD))
continue; continue;
if (AI_GetMoveAccuracy(battlerAtk, battlerDef, atkAbility, defAbility, atkHoldEffect, defHoldEffect, moves[i]) <= accCheck) if (AI_GetMoveAccuracy(battlerAtk, battlerDef, atkAbility, defAbility, atkHoldEffect, defHoldEffect, moves[i]) <= accCheck)
return TRUE; return TRUE;