add AI_FLAG_OMNISCIENT

This commit is contained in:
ghoulslash 2023-03-28 10:38:48 -04:00
parent dd99cb6da8
commit 00d695ac2b
7 changed files with 35 additions and 11 deletions

View File

@ -272,8 +272,8 @@ struct AiPartyMon
struct AIPartyData // Opposing battlers - party mons.
{
struct AiPartyMon mons[2][PARTY_SIZE]; // 2 parties(player, opponent). Used to save information on opposing party.
u8 count[2];
struct AiPartyMon mons[NUM_BATTLE_SIDES][PARTY_SIZE]; // 2 parties(player, opponent). Used to save information on opposing party.
u8 count[NUM_BATTLE_SIDES];
};
struct AiLogicData

View File

@ -9,6 +9,7 @@
bool32 AI_RandLessThan(u8 val);
void RecordLastUsedMoveByTarget(void);
bool32 BattlerHasAi(u32 battlerId);
bool32 IsBattlerAIControlled(u32 battlerId);
void ClearBattlerMoveHistory(u8 battlerId);
void RecordLastUsedMoveBy(u32 battlerId, u32 move);

View File

@ -57,6 +57,7 @@
#define AI_FLAG_SCREENER (1 << 14) // AI prefers screening effects like reflect, mist, etc. TODO unfinished
#define AI_FLAG_SMART_SWITCHING (1 << 15) // AI includes a lot more switching checks
#define AI_FLAG_ACE_POKEMON (1 << 16) // AI has an Ace Pokemon. The last Pokemon in the party will not be used until it's the last one remaining.
#define AI_FLAG_OMNISCIENT (1 << 17) // AI has full knowledge of player moves, abilities, hold items
// 'other' ai logic flags
#define AI_FLAG_ROAMING (1 << 29)

View File

@ -257,6 +257,8 @@ static void CopyBattlerDataToAIParty(u32 bPosition, u32 side)
void Ai_InitPartyStruct(void)
{
u32 i;
bool32 isOmniscient = (AI_THINKING_STRUCT->aiFlags & AI_FLAG_OMNISCIENT);
struct Pokemon *mon;
AI_PARTY->count[B_SIDE_PLAYER] = gPlayerPartyCount;
AI_PARTY->count[B_SIDE_OPPONENT] = gEnemyPartyCount;
@ -278,6 +280,17 @@ void Ai_InitPartyStruct(void)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_HP) == 0)
AI_PARTY->mons[B_SIDE_PLAYER][i].isFainted = TRUE;
if (isOmniscient)
{
u32 j;
mon = &gPlayerParty[i];
AI_PARTY->mons[B_SIDE_PLAYER][i].item = GetMonData(mon, MON_DATA_HELD_ITEM);
AI_PARTY->mons[B_SIDE_PLAYER][i].heldEffect = ItemId_GetHoldEffect(AI_PARTY->mons[B_SIDE_PLAYER][i].item);
AI_PARTY->mons[B_SIDE_PLAYER][i].ability = GetMonAbility(mon);
for (j = 0; j < MAX_MON_MOVES; j++)
AI_PARTY->mons[B_SIDE_PLAYER][i].moves[j] = GetMonData(mon, MON_DATA_MOVE1 + j);
}
}
}

View File

@ -457,7 +457,7 @@ void RecordLastUsedMoveByTarget(void)
RecordKnownMove(gBattlerTarget, gLastMoves[gBattlerTarget]);
}
bool32 IsBattlerAIControlled(u32 battlerId)
bool32 BattlerHasAi(u32 battlerId)
{
switch (GetBattlerPosition(battlerId))
{
@ -473,6 +473,14 @@ bool32 IsBattlerAIControlled(u32 battlerId)
}
}
bool32 IsBattlerAIControlled(u32 battlerId)
{
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_OMNISCIENT)
return TRUE;
return BattlerHasAi(battlerId);
}
void ClearBattlerMoveHistory(u8 battlerId)
{
memset(BATTLE_HISTORY->usedMoves[battlerId], 0, sizeof(BATTLE_HISTORY->usedMoves[battlerId]));
@ -1230,8 +1238,9 @@ s32 AI_GetAbility(u32 battlerId)
if (knownAbility == ABILITY_NONE)
return knownAbility;
if (BATTLE_HISTORY->abilities[battlerId] != ABILITY_NONE)
return BATTLE_HISTORY->abilities[battlerId];
if (AI_PARTY->mons[GetBattlerSide(battlerId)][gBattlerPartyIndexes[battlerId]].ability != ABILITY_NONE) {
return AI_PARTY->mons[GetBattlerSide(battlerId)][gBattlerPartyIndexes[battlerId]].ability;
}
// Abilities that prevent fleeing - treat as always known
if (knownAbility == ABILITY_SHADOW_TAG || knownAbility == ABILITY_MAGNET_PULL || knownAbility == ABILITY_ARENA_TRAP)
@ -1257,10 +1266,10 @@ u16 AI_GetHoldEffect(u32 battlerId)
u32 holdEffect;
if (!IsBattlerAIControlled(battlerId))
holdEffect = BATTLE_HISTORY->itemEffects[battlerId];
holdEffect = AI_PARTY->mons[GetBattlerSide(battlerId)][gBattlerPartyIndexes[battlerId]].heldEffect;
else
holdEffect = GetBattlerHoldEffect(battlerId, FALSE);
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_NEGATE_UNAWARE)
return holdEffect;

View File

@ -774,7 +774,7 @@ static void Task_ShowAiPoints(u8 taskId)
// Swap battler if it's player mon
data->aiBattlerId = data->battlerId;
while (!IsBattlerAIControlled(data->aiBattlerId))
while (!BattlerHasAi(data->aiBattlerId))
{
if (++data->aiBattlerId >= gBattlersCount)
data->aiBattlerId = 0;
@ -931,7 +931,7 @@ static void Task_ShowAiKnowledge(u8 taskId)
// Swap battler if it's player mon
data->aiBattlerId = data->battlerId;
while (!IsBattlerAIControlled(data->aiBattlerId))
while (!BattlerHasAi(data->aiBattlerId))
{
if (++data->aiBattlerId >= gBattlersCount)
data->aiBattlerId = 0;

View File

@ -3859,7 +3859,7 @@ static void TryDoEventsBeforeFirstTurn(void)
gChosenActionByBattler[i] = B_ACTION_NONE;
gChosenMoveByBattler[i] = MOVE_NONE;
// Record party slots of player's mons that appeared in battle
if (!IsBattlerAIControlled(i))
if (!BattlerHasAi(i))
gBattleStruct->appearedInBattle |= gBitTable[gBattlerPartyIndexes[i]];
}
TurnValuesCleanUp(FALSE);
@ -4096,7 +4096,7 @@ static void HandleTurnActionSelectionState(void)
// Do AI score computations here so we can use them in AI_TrySwitchOrUseItem
if ((gBattleTypeFlags & BATTLE_TYPE_HAS_AI || IsWildMonSmart())
&& (IsBattlerAIControlled(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_PALACE))) {
&& (BattlerHasAi(gActiveBattler) && !(gBattleTypeFlags & BATTLE_TYPE_PALACE))) {
gBattleStruct->aiMoveOrAction[gActiveBattler] = ComputeBattleAiScores(gActiveBattler);
}
break;