mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-01-19 09:54:19 +01:00
Add AI_FLAG_OMNISCIENT (#2872)
This commit is contained in:
commit
e4656f3ab8
@ -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
|
||||
|
@ -9,7 +9,8 @@
|
||||
|
||||
bool32 AI_RandLessThan(u8 val);
|
||||
void RecordLastUsedMoveByTarget(void);
|
||||
bool32 IsBattlerAIControlled(u32 battlerId);
|
||||
bool32 BattlerHasAi(u32 battlerId);
|
||||
bool32 IsAiBattlerAware(u32 battlerId);
|
||||
void ClearBattlerMoveHistory(u8 battlerId);
|
||||
void RecordLastUsedMoveBy(u32 battlerId, u32 move);
|
||||
void RecordKnownMove(u8 battlerId, u32 move);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,7 +367,7 @@ void GetAiLogicData(void)
|
||||
for (battlerAtk = 0; battlerAtk < gBattlersCount; battlerAtk++)
|
||||
{
|
||||
if (!IsBattlerAlive(battlerAtk)
|
||||
|| !IsBattlerAIControlled(battlerAtk)) {
|
||||
|| !IsAiBattlerAware(battlerAtk)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -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 IsAiBattlerAware(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]));
|
||||
@ -529,7 +537,7 @@ void ClearBattlerItemEffectHistory(u8 battlerId)
|
||||
|
||||
void SaveBattlerData(u8 battlerId)
|
||||
{
|
||||
if (!IsBattlerAIControlled(battlerId))
|
||||
if (!BattlerHasAi(battlerId))
|
||||
{
|
||||
u32 i;
|
||||
|
||||
@ -580,7 +588,7 @@ static bool32 ShouldFailForIllusion(u16 illusionSpecies, u32 battlerId)
|
||||
|
||||
void SetBattlerData(u8 battlerId)
|
||||
{
|
||||
if (!IsBattlerAIControlled(battlerId))
|
||||
if (!BattlerHasAi(battlerId))
|
||||
{
|
||||
u32 i, species, illusionSpecies;
|
||||
|
||||
@ -623,7 +631,7 @@ void SetBattlerData(u8 battlerId)
|
||||
|
||||
void RestoreBattlerData(u8 battlerId)
|
||||
{
|
||||
if (!IsBattlerAIControlled(battlerId))
|
||||
if (!BattlerHasAi(battlerId))
|
||||
{
|
||||
u32 i;
|
||||
|
||||
@ -1223,15 +1231,15 @@ s32 AI_GetAbility(u32 battlerId)
|
||||
return gBattleStruct->overwrittenAbilities[battlerId];
|
||||
|
||||
// The AI knows its own ability.
|
||||
if (IsBattlerAIControlled(battlerId))
|
||||
if (IsAiBattlerAware(battlerId))
|
||||
return knownAbility;
|
||||
|
||||
// Check neutralizing gas, gastro acid
|
||||
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)
|
||||
@ -1256,8 +1264,8 @@ u16 AI_GetHoldEffect(u32 battlerId)
|
||||
{
|
||||
u32 holdEffect;
|
||||
|
||||
if (!IsBattlerAIControlled(battlerId))
|
||||
holdEffect = BATTLE_HISTORY->itemEffects[battlerId];
|
||||
if (!IsAiBattlerAware(battlerId))
|
||||
holdEffect = AI_PARTY->mons[GetBattlerSide(battlerId)][gBattlerPartyIndexes[battlerId]].heldEffect;
|
||||
else
|
||||
holdEffect = GetBattlerHoldEffect(battlerId, FALSE);
|
||||
|
||||
@ -1881,7 +1889,7 @@ bool32 CanIndexMoveFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index, u8 numHit
|
||||
|
||||
u16 *GetMovesArray(u32 battler)
|
||||
{
|
||||
if (IsBattlerAIControlled(battler) || IsBattlerAIControlled(BATTLE_PARTNER(battler)))
|
||||
if (IsAiBattlerAware(battler) || IsAiBattlerAware(BATTLE_PARTNER(battler)))
|
||||
return gBattleMons[battler].moves;
|
||||
else
|
||||
return gBattleResources->battleHistory->usedMoves[battler];
|
||||
@ -3136,7 +3144,7 @@ u16 GetAllyChosenMove(u8 battlerId)
|
||||
{
|
||||
u8 partnerBattler = BATTLE_PARTNER(battlerId);
|
||||
|
||||
if (!IsBattlerAlive(partnerBattler) || !IsBattlerAIControlled(partnerBattler))
|
||||
if (!IsBattlerAlive(partnerBattler) || !IsAiBattlerAware(partnerBattler))
|
||||
return MOVE_NONE;
|
||||
else if (partnerBattler > battlerId) // Battler with the lower id chooses the move first.
|
||||
return gLastMoves[partnerBattler];
|
||||
|
@ -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;
|
||||
|
@ -3882,7 +3882,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);
|
||||
@ -4119,7 +4119,8 @@ 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;
|
||||
|
@ -7037,7 +7037,7 @@ static void Cmd_switchineffects(void)
|
||||
gHitMarker &= ~HITMARKER_FAINTED(gActiveBattler);
|
||||
gSpecialStatuses[gActiveBattler].faintedHasReplacement = FALSE;
|
||||
|
||||
if (!IsBattlerAIControlled(gActiveBattler))
|
||||
if (!BattlerHasAi(gActiveBattler))
|
||||
gBattleStruct->appearedInBattle |= gBitTable[gBattlerPartyIndexes[gActiveBattler]];
|
||||
|
||||
// Neutralizing Gas announces itself before hazards
|
||||
|
Loading…
x
Reference in New Issue
Block a user