Throw out unnecessary functions
This commit is contained in:
parent
83b7732fae
commit
b48d0c387d
@ -333,7 +333,7 @@ struct AiLogicData
|
|||||||
u8 ejectPackSwitch:1; // Tracks whether current switch out was from Eject Pack
|
u8 ejectPackSwitch:1; // Tracks whether current switch out was from Eject Pack
|
||||||
u8 predictingSwitch:1; // Determines whether AI will use switch predictions this turn or not
|
u8 predictingSwitch:1; // Determines whether AI will use switch predictions this turn or not
|
||||||
u8 predictingMove:1; // Determines whether AI will use move predictions this turn or not
|
u8 predictingMove:1; // Determines whether AI will use move predictions this turn or not
|
||||||
u8 aiSwitchPredictionInProgress:1; // Tracks whether the AI is in the middle of running prediction calculations
|
u8 aiPredictionInProgress:1; // Tracks whether the AI is in the middle of running prediction calculations
|
||||||
u8 padding:2;
|
u8 padding:2;
|
||||||
u8 shouldSwitch; // Stores result of ShouldSwitch, which decides whether a mon should be switched out
|
u8 shouldSwitch; // Stores result of ShouldSwitch, which decides whether a mon should be switched out
|
||||||
u8 aiCalcInProgress:1;
|
u8 aiCalcInProgress:1;
|
||||||
|
|||||||
@ -240,5 +240,6 @@ bool32 IsBattlerItemEnabled(u32 battler);
|
|||||||
bool32 IsBattlerPredictedToSwitch(u32 battler);
|
bool32 IsBattlerPredictedToSwitch(u32 battler);
|
||||||
bool32 HasLowAccuracyMove(u32 battlerAtk, u32 battlerDef);
|
bool32 HasLowAccuracyMove(u32 battlerAtk, u32 battlerDef);
|
||||||
bool32 HasBattlerSideAbility(u32 battlerDef, u32 ability, struct AiLogicData *aiData);
|
bool32 HasBattlerSideAbility(u32 battlerDef, u32 ability, struct AiLogicData *aiData);
|
||||||
|
u32 GetThinkingBattler(u32 battler);
|
||||||
|
|
||||||
#endif //GUARD_BATTLE_AI_UTIL_H
|
#endif //GUARD_BATTLE_AI_UTIL_H
|
||||||
|
|||||||
@ -32,11 +32,10 @@
|
|||||||
#define AI_ACTION_WATCH (1 << 2)
|
#define AI_ACTION_WATCH (1 << 2)
|
||||||
#define AI_ACTION_DO_NOT_ATTACK (1 << 3)
|
#define AI_ACTION_DO_NOT_ATTACK (1 << 3)
|
||||||
|
|
||||||
static u32 ChooseMoveOrAction_Singles(u32 battlerAi);
|
static u32 ChooseMoveOrAction_Singles(u32 battler);
|
||||||
static u32 ChooseMoveOrAction_Doubles(u32 battlerAi);
|
static u32 ChooseMoveOrAction_Doubles(u32 battler);
|
||||||
static inline void BattleAI_DoAIProcessing(struct AI_ThinkingStruct *aiThink, u32 battlerAi, u32 battlerDef);
|
static inline void BattleAI_DoAIProcessing(struct AI_ThinkingStruct *aiThink, u32 battler, u32 battlerDef);
|
||||||
static inline void BattleAI_DoAIProcessing_PredictMove(struct AI_ThinkingStruct *aiThink, u32 battler, u32 opposingBattler);
|
static inline void BattleAI_DoAIProcessing_PredictedSwitchin(struct AI_ThinkingStruct *aiThink, struct AiLogicData *aiData, u32 battlerAtk, u32 battlerDef);
|
||||||
static inline void BattleAI_DoAIProcessing_PredictedSwitchin(struct AI_ThinkingStruct *aiThink, struct AiLogicData *aiData, u32 battlerAi, u32 battlerDef);
|
|
||||||
static bool32 IsPinchBerryItemEffect(enum ItemHoldEffect holdEffect);
|
static bool32 IsPinchBerryItemEffect(enum ItemHoldEffect holdEffect);
|
||||||
|
|
||||||
// ewram
|
// ewram
|
||||||
@ -308,16 +307,15 @@ bool32 BattlerChoseNonMoveAction(void)
|
|||||||
void SetupAIPredictionData(u32 battler, enum SwitchType switchType)
|
void SetupAIPredictionData(u32 battler, enum SwitchType switchType)
|
||||||
{
|
{
|
||||||
s32 opposingBattler = GetOppositeBattler(battler);
|
s32 opposingBattler = GetOppositeBattler(battler);
|
||||||
|
AI_DATA->aiPredictionInProgress = TRUE;
|
||||||
|
AI_DATA->battlerDoingPrediction = battler;
|
||||||
|
|
||||||
// Switch prediction
|
// Switch prediction
|
||||||
if ((AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_PREDICT_SWITCH))
|
if ((AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_PREDICT_SWITCH))
|
||||||
{
|
{
|
||||||
AI_DATA->aiSwitchPredictionInProgress = TRUE;
|
|
||||||
AI_DATA->battlerDoingPrediction = battler;
|
|
||||||
AI_DATA->mostSuitableMonId[opposingBattler] = GetMostSuitableMonToSwitchInto(opposingBattler, switchType);
|
AI_DATA->mostSuitableMonId[opposingBattler] = GetMostSuitableMonToSwitchInto(opposingBattler, switchType);
|
||||||
if (ShouldSwitch(opposingBattler))
|
if (ShouldSwitch(opposingBattler))
|
||||||
AI_DATA->shouldSwitch |= (1u << opposingBattler);
|
AI_DATA->shouldSwitch |= (1u << opposingBattler);
|
||||||
AI_DATA->aiSwitchPredictionInProgress = FALSE;
|
|
||||||
gBattleStruct->prevTurnSpecies[opposingBattler] = gBattleMons[opposingBattler].species;
|
gBattleStruct->prevTurnSpecies[opposingBattler] = gBattleMons[opposingBattler].species;
|
||||||
|
|
||||||
// Determine whether AI will use predictions this turn
|
// Determine whether AI will use predictions this turn
|
||||||
@ -327,13 +325,14 @@ void SetupAIPredictionData(u32 battler, enum SwitchType switchType)
|
|||||||
// Move prediction
|
// Move prediction
|
||||||
if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_PREDICT_MOVES)
|
if (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_PREDICT_MOVES)
|
||||||
{
|
{
|
||||||
AI_DATA->predictedMove[opposingBattler] = gBattleMons[opposingBattler].moves[BattleAI_PredictMove(battler, opposingBattler)];
|
AI_DATA->predictedMove[opposingBattler] = gBattleMons[opposingBattler].moves[BattleAI_ChooseMoveIndex(opposingBattler)];
|
||||||
DebugPrintf("Predicted move: %d", AI_DATA->predictedMove[opposingBattler]);
|
DebugPrintf("Predicted move: %d", AI_DATA->predictedMove[opposingBattler]);
|
||||||
ModifySwitchAfterMoveScoring(opposingBattler);
|
ModifySwitchAfterMoveScoring(opposingBattler);
|
||||||
|
|
||||||
// Determine whether AI will use predictions this turn
|
// Determine whether AI will use predictions this turn
|
||||||
AI_DATA->predictingMove = RandomPercentage(RNG_AI_PREDICT_MOVE, PREDICT_MOVE_CHANCE);
|
AI_DATA->predictingMove = RandomPercentage(RNG_AI_PREDICT_MOVE, PREDICT_MOVE_CHANCE);
|
||||||
}
|
}
|
||||||
|
AI_DATA->aiPredictionInProgress = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeBattlerDecisions(u32 battler)
|
void ComputeBattlerDecisions(u32 battler)
|
||||||
@ -640,77 +639,23 @@ static u32 PpStallReduction(u32 move, u32 battlerAtk)
|
|||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 BattleAI_PredictMove(u32 battler, u32 opposingBattler)
|
static u32 ChooseMoveOrAction_Singles(u32 battler)
|
||||||
{
|
{
|
||||||
u8 currentMoveArray[MAX_MON_MOVES];
|
u8 currentMoveArray[MAX_MON_MOVES];
|
||||||
u8 consideredMoveArray[MAX_MON_MOVES];
|
u8 consideredMoveArray[MAX_MON_MOVES];
|
||||||
u32 numOfBestMoves;
|
u32 numOfBestMoves;
|
||||||
s32 i;
|
s32 i;
|
||||||
u32 flags = AI_THINKING_STRUCT->aiFlags[battler];
|
u64 flags = AI_THINKING_STRUCT->aiFlags[GetThinkingBattler(battler)];
|
||||||
|
|
||||||
AI_DATA->partnerMove = 0; // no ally
|
AI_DATA->partnerMove = 0; // no ally
|
||||||
while (flags != 0)
|
while (flags != 0)
|
||||||
{
|
{
|
||||||
if (flags & 1)
|
if (flags & 1)
|
||||||
{
|
{
|
||||||
BattleAI_DoAIProcessing_PredictMove(AI_THINKING_STRUCT, battler, opposingBattler);
|
if (IsBattlerPredictedToSwitch(gBattlerTarget) && (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_PREDICT_INCOMING_MON))
|
||||||
}
|
BattleAI_DoAIProcessing_PredictedSwitchin(AI_THINKING_STRUCT, AI_DATA, battler, gBattlerTarget);
|
||||||
flags >>= 1;
|
|
||||||
AI_THINKING_STRUCT->aiLogicId++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
|
||||||
{
|
|
||||||
gAiBattleData->finalScore[opposingBattler][battler][i] = AI_THINKING_STRUCT->score[i];
|
|
||||||
DebugPrintf("Final score: %d", gAiBattleData->finalScore[opposingBattler][battler][i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
numOfBestMoves = 1;
|
|
||||||
currentMoveArray[0] = AI_THINKING_STRUCT->score[0];
|
|
||||||
consideredMoveArray[0] = 0;
|
|
||||||
|
|
||||||
for (i = 1; i < MAX_MON_MOVES; i++)
|
|
||||||
{
|
|
||||||
if (gBattleMons[opposingBattler].moves[i] != MOVE_NONE)
|
|
||||||
{
|
|
||||||
// In ruby, the order of these if statements is reversed.
|
|
||||||
if (currentMoveArray[0] == AI_THINKING_STRUCT->score[i])
|
|
||||||
{
|
|
||||||
currentMoveArray[numOfBestMoves] = AI_THINKING_STRUCT->score[i];
|
|
||||||
consideredMoveArray[numOfBestMoves++] = i;
|
|
||||||
}
|
|
||||||
if (currentMoveArray[0] < AI_THINKING_STRUCT->score[i])
|
|
||||||
{
|
|
||||||
numOfBestMoves = 1;
|
|
||||||
currentMoveArray[0] = AI_THINKING_STRUCT->score[i];
|
|
||||||
consideredMoveArray[0] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DebugPrintf("Number of best moves: %d", numOfBestMoves);
|
|
||||||
DebugPrintf("Random best move: %d", consideredMoveArray[Random() % numOfBestMoves]);
|
|
||||||
DebugPrintf("Random best move: %d", consideredMoveArray[Random() % numOfBestMoves]);
|
|
||||||
DebugPrintf("Random best move: %d", consideredMoveArray[Random() % numOfBestMoves]);
|
|
||||||
return consideredMoveArray[Random() % numOfBestMoves];
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 ChooseMoveOrAction_Singles(u32 battlerAi)
|
|
||||||
{
|
|
||||||
u8 currentMoveArray[MAX_MON_MOVES];
|
|
||||||
u8 consideredMoveArray[MAX_MON_MOVES];
|
|
||||||
u32 numOfBestMoves;
|
|
||||||
s32 i;
|
|
||||||
u64 flags = AI_THINKING_STRUCT->aiFlags[battlerAi];
|
|
||||||
|
|
||||||
AI_DATA->partnerMove = 0; // no ally
|
|
||||||
while (flags != 0)
|
|
||||||
{
|
|
||||||
if (flags & 1)
|
|
||||||
{
|
|
||||||
if (IsBattlerPredictedToSwitch(gBattlerTarget) && (AI_THINKING_STRUCT->aiFlags[battlerAi] & AI_FLAG_PREDICT_INCOMING_MON))
|
|
||||||
BattleAI_DoAIProcessing_PredictedSwitchin(AI_THINKING_STRUCT, AI_DATA, battlerAi, gBattlerTarget);
|
|
||||||
else
|
else
|
||||||
BattleAI_DoAIProcessing(AI_THINKING_STRUCT, battlerAi, gBattlerTarget);
|
BattleAI_DoAIProcessing(AI_THINKING_STRUCT, battler, gBattlerTarget);
|
||||||
}
|
}
|
||||||
flags >>= (u64)1;
|
flags >>= (u64)1;
|
||||||
AI_THINKING_STRUCT->aiLogicId++;
|
AI_THINKING_STRUCT->aiLogicId++;
|
||||||
@ -718,7 +663,7 @@ static u32 ChooseMoveOrAction_Singles(u32 battlerAi)
|
|||||||
|
|
||||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||||
{
|
{
|
||||||
gAiBattleData->finalScore[battlerAi][gBattlerTarget][i] = AI_THINKING_STRUCT->score[i];
|
gAiBattleData->finalScore[battler][gBattlerTarget][i] = AI_THINKING_STRUCT->score[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
numOfBestMoves = 1;
|
numOfBestMoves = 1;
|
||||||
@ -727,7 +672,7 @@ static u32 ChooseMoveOrAction_Singles(u32 battlerAi)
|
|||||||
|
|
||||||
for (i = 1; i < MAX_MON_MOVES; i++)
|
for (i = 1; i < MAX_MON_MOVES; i++)
|
||||||
{
|
{
|
||||||
if (gBattleMons[battlerAi].moves[i] != MOVE_NONE)
|
if (gBattleMons[battler].moves[i] != MOVE_NONE)
|
||||||
{
|
{
|
||||||
// In ruby, the order of these if statements is reversed.
|
// In ruby, the order of these if statements is reversed.
|
||||||
if (currentMoveArray[0] == AI_THINKING_STRUCT->score[i])
|
if (currentMoveArray[0] == AI_THINKING_STRUCT->score[i])
|
||||||
@ -746,7 +691,7 @@ static u32 ChooseMoveOrAction_Singles(u32 battlerAi)
|
|||||||
return consideredMoveArray[Random() % numOfBestMoves];
|
return consideredMoveArray[Random() % numOfBestMoves];
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 ChooseMoveOrAction_Doubles(u32 battlerAi)
|
static u32 ChooseMoveOrAction_Doubles(u32 battler)
|
||||||
{
|
{
|
||||||
s32 i, j;
|
s32 i, j;
|
||||||
u64 flags;
|
u64 flags;
|
||||||
@ -761,7 +706,7 @@ static u32 ChooseMoveOrAction_Doubles(u32 battlerAi)
|
|||||||
|
|
||||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
||||||
{
|
{
|
||||||
if (i == battlerAi || gBattleMons[i].hp == 0)
|
if (i == battler || gBattleMons[i].hp == 0)
|
||||||
{
|
{
|
||||||
actionOrMoveIndex[i] = 0xFF;
|
actionOrMoveIndex[i] = 0xFF;
|
||||||
bestMovePointsForTarget[i] = -1;
|
bestMovePointsForTarget[i] = -1;
|
||||||
@ -769,25 +714,25 @@ static u32 ChooseMoveOrAction_Doubles(u32 battlerAi)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
if (gBattleTypeFlags & BATTLE_TYPE_PALACE)
|
||||||
BattleAI_SetupAIData(gBattleStruct->palaceFlags >> 4, battlerAi);
|
BattleAI_SetupAIData(gBattleStruct->palaceFlags >> 4, battler);
|
||||||
else
|
else
|
||||||
BattleAI_SetupAIData(0xF, battlerAi);
|
BattleAI_SetupAIData(0xF, battler);
|
||||||
|
|
||||||
gBattlerTarget = i;
|
gBattlerTarget = i;
|
||||||
|
|
||||||
AI_DATA->partnerMove = GetAllyChosenMove(battlerAi);
|
AI_DATA->partnerMove = GetAllyChosenMove(battler);
|
||||||
AI_THINKING_STRUCT->aiLogicId = 0;
|
AI_THINKING_STRUCT->aiLogicId = 0;
|
||||||
AI_THINKING_STRUCT->movesetIndex = 0;
|
AI_THINKING_STRUCT->movesetIndex = 0;
|
||||||
flags = AI_THINKING_STRUCT->aiFlags[battlerAi];
|
flags = AI_THINKING_STRUCT->aiFlags[GetThinkingBattler(battler)];
|
||||||
|
|
||||||
while (flags != 0)
|
while (flags != 0)
|
||||||
{
|
{
|
||||||
if (flags & 1)
|
if (flags & 1)
|
||||||
{
|
{
|
||||||
if (IsBattlerPredictedToSwitch(gBattlerTarget) && (AI_THINKING_STRUCT->aiFlags[battlerAi] & AI_FLAG_PREDICT_INCOMING_MON))
|
if (IsBattlerPredictedToSwitch(gBattlerTarget) && (AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_PREDICT_INCOMING_MON))
|
||||||
BattleAI_DoAIProcessing_PredictedSwitchin(AI_THINKING_STRUCT, AI_DATA, battlerAi, gBattlerTarget);
|
BattleAI_DoAIProcessing_PredictedSwitchin(AI_THINKING_STRUCT, AI_DATA, battler, gBattlerTarget);
|
||||||
else
|
else
|
||||||
BattleAI_DoAIProcessing(AI_THINKING_STRUCT, battlerAi, gBattlerTarget);
|
BattleAI_DoAIProcessing(AI_THINKING_STRUCT, battler, gBattlerTarget);
|
||||||
}
|
}
|
||||||
flags >>= (u64)1;
|
flags >>= (u64)1;
|
||||||
AI_THINKING_STRUCT->aiLogicId++;
|
AI_THINKING_STRUCT->aiLogicId++;
|
||||||
@ -798,9 +743,9 @@ static u32 ChooseMoveOrAction_Doubles(u32 battlerAi)
|
|||||||
mostViableMovesNo = 1;
|
mostViableMovesNo = 1;
|
||||||
for (j = 1; j < MAX_MON_MOVES; j++)
|
for (j = 1; j < MAX_MON_MOVES; j++)
|
||||||
{
|
{
|
||||||
if (gBattleMons[battlerAi].moves[j] != 0)
|
if (gBattleMons[battler].moves[j] != 0)
|
||||||
{
|
{
|
||||||
if (!CanTargetBattler(battlerAi, i, gBattleMons[battlerAi].moves[j]))
|
if (!CanTargetBattler(battler, i, gBattleMons[battler].moves[j]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (mostViableMovesScores[0] == AI_THINKING_STRUCT->score[j])
|
if (mostViableMovesScores[0] == AI_THINKING_STRUCT->score[j])
|
||||||
@ -821,14 +766,14 @@ static u32 ChooseMoveOrAction_Doubles(u32 battlerAi)
|
|||||||
bestMovePointsForTarget[i] = mostViableMovesScores[0];
|
bestMovePointsForTarget[i] = mostViableMovesScores[0];
|
||||||
|
|
||||||
// Don't use a move against ally if it has less than 100 points.
|
// Don't use a move against ally if it has less than 100 points.
|
||||||
if (i == BATTLE_PARTNER(battlerAi) && bestMovePointsForTarget[i] < AI_SCORE_DEFAULT)
|
if (i == BATTLE_PARTNER(battler) && bestMovePointsForTarget[i] < AI_SCORE_DEFAULT)
|
||||||
{
|
{
|
||||||
bestMovePointsForTarget[i] = -1;
|
bestMovePointsForTarget[i] = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||||
{
|
{
|
||||||
gAiBattleData->finalScore[battlerAi][gBattlerTarget][j] = AI_THINKING_STRUCT->score[j];
|
gAiBattleData->finalScore[battler][gBattlerTarget][j] = AI_THINKING_STRUCT->score[j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -853,7 +798,7 @@ static u32 ChooseMoveOrAction_Doubles(u32 battlerAi)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gBattlerTarget = mostViableTargetsArray[Random() % mostViableTargetsNo];
|
gBattlerTarget = mostViableTargetsArray[Random() % mostViableTargetsNo];
|
||||||
gAiBattleData->chosenTarget[battlerAi] = gBattlerTarget;
|
gAiBattleData->chosenTarget[battler] = gBattlerTarget;
|
||||||
return actionOrMoveIndex[gBattlerTarget];
|
return actionOrMoveIndex[gBattlerTarget];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -868,64 +813,26 @@ static inline bool32 ShouldConsiderMoveForBattler(u32 battlerAi, u32 battlerDef,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void BattleAI_DoAIProcessing_PredictMove(struct AI_ThinkingStruct *aiThink, u32 battler, u32 opposingBattler)
|
static inline void BattleAI_DoAIProcessing(struct AI_ThinkingStruct *aiThink, u32 battler, u32 battlerDef)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (gBattleMons[opposingBattler].pp[aiThink->movesetIndex] == 0)
|
if (gBattleMons[battler].pp[aiThink->movesetIndex] == 0)
|
||||||
aiThink->moveConsidered = MOVE_NONE;
|
aiThink->moveConsidered = MOVE_NONE;
|
||||||
else
|
else
|
||||||
aiThink->moveConsidered = gBattleMons[opposingBattler].moves[aiThink->movesetIndex];
|
aiThink->moveConsidered = gBattleMons[battler].moves[aiThink->movesetIndex];
|
||||||
|
|
||||||
DebugPrintf("Move considered: %d", aiThink->moveConsidered);
|
|
||||||
|
|
||||||
// There is no point in calculating scores for all 3 battlers(2 opponents + 1 ally) with certain moves.
|
// There is no point in calculating scores for all 3 battlers(2 opponents + 1 ally) with certain moves.
|
||||||
if (aiThink->moveConsidered != MOVE_NONE
|
if (aiThink->moveConsidered != MOVE_NONE
|
||||||
&& aiThink->score[aiThink->movesetIndex] > 0
|
&& aiThink->score[aiThink->movesetIndex] > 0
|
||||||
&& ShouldConsiderMoveForBattler(opposingBattler, battler, aiThink->moveConsidered))
|
&& ShouldConsiderMoveForBattler(battler, battlerDef, aiThink->moveConsidered))
|
||||||
{
|
{
|
||||||
if (aiThink->aiLogicId < ARRAY_COUNT(sBattleAiFuncTable)
|
if (aiThink->aiLogicId < ARRAY_COUNT(sBattleAiFuncTable)
|
||||||
&& sBattleAiFuncTable[aiThink->aiLogicId] != NULL)
|
&& sBattleAiFuncTable[aiThink->aiLogicId] != NULL)
|
||||||
{
|
{
|
||||||
// Call AI function
|
// Call AI function
|
||||||
aiThink->score[aiThink->movesetIndex] =
|
aiThink->score[aiThink->movesetIndex] =
|
||||||
sBattleAiFuncTable[aiThink->aiLogicId](opposingBattler,
|
sBattleAiFuncTable[aiThink->aiLogicId](battler,
|
||||||
battler,
|
|
||||||
aiThink->moveConsidered,
|
|
||||||
aiThink->score[aiThink->movesetIndex]);
|
|
||||||
DebugPrintf("Current score: %d", aiThink->score[aiThink->movesetIndex]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aiThink->score[aiThink->movesetIndex] = 0;
|
|
||||||
}
|
|
||||||
aiThink->movesetIndex++;
|
|
||||||
} while (aiThink->movesetIndex < MAX_MON_MOVES);
|
|
||||||
|
|
||||||
aiThink->movesetIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void BattleAI_DoAIProcessing(struct AI_ThinkingStruct *aiThink, u32 battlerAi, u32 battlerDef)
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (gBattleMons[battlerAi].pp[aiThink->movesetIndex] == 0)
|
|
||||||
aiThink->moveConsidered = MOVE_NONE;
|
|
||||||
else
|
|
||||||
aiThink->moveConsidered = gBattleMons[battlerAi].moves[aiThink->movesetIndex];
|
|
||||||
|
|
||||||
// There is no point in calculating scores for all 3 battlers(2 opponents + 1 ally) with certain moves.
|
|
||||||
if (aiThink->moveConsidered != MOVE_NONE
|
|
||||||
&& aiThink->score[aiThink->movesetIndex] > 0
|
|
||||||
&& ShouldConsiderMoveForBattler(battlerAi, battlerDef, aiThink->moveConsidered))
|
|
||||||
{
|
|
||||||
if (aiThink->aiLogicId < ARRAY_COUNT(sBattleAiFuncTable)
|
|
||||||
&& sBattleAiFuncTable[aiThink->aiLogicId] != NULL)
|
|
||||||
{
|
|
||||||
// Call AI function
|
|
||||||
aiThink->score[aiThink->movesetIndex] =
|
|
||||||
sBattleAiFuncTable[aiThink->aiLogicId](battlerAi,
|
|
||||||
battlerDef,
|
battlerDef,
|
||||||
aiThink->moveConsidered,
|
aiThink->moveConsidered,
|
||||||
aiThink->score[aiThink->movesetIndex]);
|
aiThink->score[aiThink->movesetIndex]);
|
||||||
|
|||||||
@ -108,13 +108,6 @@ u32 GetSwitchChance(enum ShouldSwitchScenario shouldSwitchScenario)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 GetThinkingBattler(u32 battler)
|
|
||||||
{
|
|
||||||
if (AI_DATA->aiSwitchPredictionInProgress)
|
|
||||||
return AI_DATA->battlerDoingPrediction;
|
|
||||||
return battler;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool32 IsAceMon(u32 battler, u32 monPartyId)
|
static bool32 IsAceMon(u32 battler, u32 monPartyId)
|
||||||
{
|
{
|
||||||
if (AI_THINKING_STRUCT->aiFlags[GetThinkingBattler(battler)] & AI_FLAG_ACE_POKEMON
|
if (AI_THINKING_STRUCT->aiFlags[GetThinkingBattler(battler)] & AI_FLAG_ACE_POKEMON
|
||||||
@ -295,7 +288,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
|
|||||||
&& gBattleMons[battler].hp >= gBattleMons[battler].maxHP / 4)))
|
&& gBattleMons[battler].hp >= gBattleMons[battler].maxHP / 4)))
|
||||||
{
|
{
|
||||||
// 50% chance to stay in regardless
|
// 50% chance to stay in regardless
|
||||||
if (RandomPercentage(RNG_AI_SWITCH_HASBADODDS, (100 - GetSwitchChance(SHOULD_SWITCH_HASBADODDS))) && !AI_DATA->aiSwitchPredictionInProgress)
|
if (RandomPercentage(RNG_AI_SWITCH_HASBADODDS, (100 - GetSwitchChance(SHOULD_SWITCH_HASBADODDS))) && !AI_DATA->aiPredictionInProgress)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// Switch mon out
|
// Switch mon out
|
||||||
@ -315,7 +308,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// 50% chance to stay in regardless
|
// 50% chance to stay in regardless
|
||||||
if (RandomPercentage(RNG_AI_SWITCH_HASBADODDS, (100 - GetSwitchChance(SHOULD_SWITCH_HASBADODDS))) && !AI_DATA->aiSwitchPredictionInProgress)
|
if (RandomPercentage(RNG_AI_SWITCH_HASBADODDS, (100 - GetSwitchChance(SHOULD_SWITCH_HASBADODDS))) && !AI_DATA->aiPredictionInProgress)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// Switch mon out
|
// Switch mon out
|
||||||
@ -465,7 +458,7 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
if (gBattleStruct->prevTurnSpecies[battler] != gBattleMons[battler].species && !(AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_PREDICT_MOVES)) // AI mon has changed, player's behaviour no longer reliable; note to override this if using AI_FLAG_PREDICT_MOVE
|
if (gBattleStruct->prevTurnSpecies[battler] != gBattleMons[battler].species && !(AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_PREDICT_MOVES)) // AI mon has changed, player's behaviour no longer reliable; note to override this if using AI_FLAG_PREDICT_MOVE
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (HasSuperEffectiveMoveAgainstOpponents(battler, TRUE) && (RandomPercentage(RNG_AI_SWITCH_ABSORBING_STAY_IN, STAY_IN_ABSORBING_PERCENTAGE) || AI_DATA->aiSwitchPredictionInProgress))
|
if (HasSuperEffectiveMoveAgainstOpponents(battler, TRUE) && (RandomPercentage(RNG_AI_SWITCH_ABSORBING_STAY_IN, STAY_IN_ABSORBING_PERCENTAGE) || AI_DATA->aiPredictionInProgress))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (AreStatsRaised(battler))
|
if (AreStatsRaised(battler))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -898,7 +891,7 @@ static bool32 FindMonWithFlagsAndSuperEffective(u32 battler, u16 flags, u32 perc
|
|||||||
if (move == 0)
|
if (move == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (AI_GetMoveEffectiveness(move, battler, battlerIn1) >= UQ_4_12(2.0) && (RandomPercentage(RNG_AI_SWITCH_SE_DEFENSIVE, percentChance) || AI_DATA->aiSwitchPredictionInProgress))
|
if (AI_GetMoveEffectiveness(move, battler, battlerIn1) >= UQ_4_12(2.0) && (RandomPercentage(RNG_AI_SWITCH_SE_DEFENSIVE, percentChance) || AI_DATA->aiPredictionInProgress))
|
||||||
return SetSwitchinAndSwitch(battler, i);
|
return SetSwitchinAndSwitch(battler, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -990,7 +983,7 @@ static bool32 ShouldSwitchIfEncored(u32 battler)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// Switch out 50% of the time otherwise
|
// Switch out 50% of the time otherwise
|
||||||
else if ((RandomPercentage(RNG_AI_SWITCH_ENCORE, GetSwitchChance(SHOULD_SWITCH_ENCORE_DAMAGE)) || AI_DATA->aiSwitchPredictionInProgress) && AI_DATA->mostSuitableMonId[battler] != PARTY_SIZE)
|
else if ((RandomPercentage(RNG_AI_SWITCH_ENCORE, GetSwitchChance(SHOULD_SWITCH_ENCORE_DAMAGE)) || AI_DATA->aiPredictionInProgress) && AI_DATA->mostSuitableMonId[battler] != PARTY_SIZE)
|
||||||
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
|
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -1036,7 +1029,7 @@ static bool32 ShouldSwitchIfAttackingStatsLowered(u32 battler)
|
|||||||
// 50% chance if attack at -2 and have a good candidate mon
|
// 50% chance if attack at -2 and have a good candidate mon
|
||||||
else if (attackingStage == DEFAULT_STAT_STAGE - 2)
|
else if (attackingStage == DEFAULT_STAT_STAGE - 2)
|
||||||
{
|
{
|
||||||
if (AI_DATA->mostSuitableMonId[battler] != PARTY_SIZE && (RandomPercentage(RNG_AI_SWITCH_STATS_LOWERED, GetSwitchChance(SHOULD_SWITCH_ATTACKING_STAT_MINUS_TWO)) || AI_DATA->aiSwitchPredictionInProgress))
|
if (AI_DATA->mostSuitableMonId[battler] != PARTY_SIZE && (RandomPercentage(RNG_AI_SWITCH_STATS_LOWERED, GetSwitchChance(SHOULD_SWITCH_ATTACKING_STAT_MINUS_TWO)) || AI_DATA->aiPredictionInProgress))
|
||||||
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
|
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
|
||||||
}
|
}
|
||||||
// If at -3 or worse, switch out regardless
|
// If at -3 or worse, switch out regardless
|
||||||
@ -1053,7 +1046,7 @@ static bool32 ShouldSwitchIfAttackingStatsLowered(u32 battler)
|
|||||||
// 50% chance if attack at -2 and have a good candidate mon
|
// 50% chance if attack at -2 and have a good candidate mon
|
||||||
else if (spAttackingStage == DEFAULT_STAT_STAGE - 2)
|
else if (spAttackingStage == DEFAULT_STAT_STAGE - 2)
|
||||||
{
|
{
|
||||||
if (AI_DATA->mostSuitableMonId[battler] != PARTY_SIZE && (RandomPercentage(RNG_AI_SWITCH_STATS_LOWERED, GetSwitchChance(SHOULD_SWITCH_ATTACKING_STAT_MINUS_TWO)) || AI_DATA->aiSwitchPredictionInProgress))
|
if (AI_DATA->mostSuitableMonId[battler] != PARTY_SIZE && (RandomPercentage(RNG_AI_SWITCH_STATS_LOWERED, GetSwitchChance(SHOULD_SWITCH_ATTACKING_STAT_MINUS_TWO)) || AI_DATA->aiPredictionInProgress))
|
||||||
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
|
return SetSwitchinAndSwitch(battler, PARTY_SIZE);
|
||||||
}
|
}
|
||||||
// If at -3 or worse, switch out regardless
|
// If at -3 or worse, switch out regardless
|
||||||
|
|||||||
@ -4517,3 +4517,10 @@ bool32 HasBattlerSideAbility(u32 battler, u32 ability, struct AiLogicData *aiDat
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 GetThinkingBattler(u32 battler)
|
||||||
|
{
|
||||||
|
if (AI_DATA->aiPredictionInProgress)
|
||||||
|
return AI_DATA->battlerDoingPrediction;
|
||||||
|
return battler;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user