mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-16 19:47:35 +01:00
Improve AI switching, so it doesn't get killed on switch-in (#3146)
This commit is contained in:
commit
a0dd77dd41
@ -168,7 +168,9 @@ bool32 PartnerMoveIsSameNoTarget(u8 battlerAtkPartner, u16 move, u16 partnerMove
|
|||||||
bool32 ShouldUseWishAromatherapy(u8 battlerAtk, u8 battlerDef, u16 move);
|
bool32 ShouldUseWishAromatherapy(u8 battlerAtk, u8 battlerDef, u16 move);
|
||||||
|
|
||||||
// party logic
|
// party logic
|
||||||
s32 AI_CalcPartyMonDamage(u16 move, u8 battlerAtk, u8 battlerDef, struct Pokemon *mon);
|
struct BattlePokemon *AllocSaveBattleMons(void);
|
||||||
|
void FreeRestoreBattleMons(struct BattlePokemon *savedBattleMons);
|
||||||
|
s32 AI_CalcPartyMonBestMoveDamage(u32 battlerAtk, u32 battlerDef, struct Pokemon *attackerMon, struct Pokemon *targetMon);
|
||||||
s32 CountUsablePartyMons(u8 battlerId);
|
s32 CountUsablePartyMons(u8 battlerId);
|
||||||
bool32 IsPartyFullyHealedExceptBattler(u8 battler);
|
bool32 IsPartyFullyHealedExceptBattler(u8 battler);
|
||||||
bool32 PartyHasMoveSplit(u8 battlerId, u8 split);
|
bool32 PartyHasMoveSplit(u8 battlerId, u8 split);
|
||||||
|
@ -28,6 +28,7 @@ static bool8 ShouldUseItem(void);
|
|||||||
static bool32 AiExpectsToFaintPlayer(void);
|
static bool32 AiExpectsToFaintPlayer(void);
|
||||||
static bool32 AI_ShouldHeal(u32 healAmount);
|
static bool32 AI_ShouldHeal(u32 healAmount);
|
||||||
static bool32 AI_OpponentCanFaintAiWithMod(u32 healAmount);
|
static bool32 AI_OpponentCanFaintAiWithMod(u32 healAmount);
|
||||||
|
static bool32 IsAiPartyMonOHKOBy(u32 battlerAtk, struct Pokemon *aiMon);
|
||||||
|
|
||||||
static bool32 IsAceMon(u32 battlerId, u32 monPartyId)
|
static bool32 IsAceMon(u32 battlerId, u32 monPartyId)
|
||||||
{
|
{
|
||||||
@ -112,11 +113,7 @@ static bool8 ShouldSwitchIfWonderGuard(void)
|
|||||||
// Find a Pokemon in the party that has a super effective move.
|
// Find a Pokemon in the party that has a super effective move.
|
||||||
for (i = firstId; i < lastId; i++)
|
for (i = firstId; i < lastId; i++)
|
||||||
{
|
{
|
||||||
if (GetMonData(&party[i], MON_DATA_HP) == 0)
|
if (!IsValidForBattle(&party[i]))
|
||||||
continue;
|
|
||||||
if (GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG) == SPECIES_NONE)
|
|
||||||
continue;
|
|
||||||
if (GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG) == SPECIES_EGG)
|
|
||||||
continue;
|
continue;
|
||||||
if (i == gBattlerPartyIndexes[gActiveBattler])
|
if (i == gBattlerPartyIndexes[gActiveBattler])
|
||||||
continue;
|
continue;
|
||||||
@ -195,13 +192,9 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
|
|||||||
|
|
||||||
for (i = firstId; i < lastId; i++)
|
for (i = firstId; i < lastId; i++)
|
||||||
{
|
{
|
||||||
u16 species;
|
|
||||||
u16 monAbility;
|
u16 monAbility;
|
||||||
|
|
||||||
if (GetMonData(&party[i], MON_DATA_HP) == 0)
|
if (!IsValidForBattle(&party[i]))
|
||||||
continue;
|
|
||||||
species = GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG);
|
|
||||||
if (species == SPECIES_NONE || species == SPECIES_EGG)
|
|
||||||
continue;
|
continue;
|
||||||
if (i == gBattlerPartyIndexes[battlerIn1])
|
if (i == gBattlerPartyIndexes[battlerIn1])
|
||||||
continue;
|
continue;
|
||||||
@ -215,7 +208,6 @@ static bool8 FindMonThatAbsorbsOpponentsMove(void)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
monAbility = GetMonAbility(&party[i]);
|
monAbility = GetMonAbility(&party[i]);
|
||||||
|
|
||||||
if (absorbingTypeAbility == monAbility && Random() & 1)
|
if (absorbingTypeAbility == monAbility && Random() & 1)
|
||||||
{
|
{
|
||||||
// we found a mon.
|
// we found a mon.
|
||||||
@ -290,9 +282,7 @@ static bool8 ShouldSwitchIfGameStatePrompt(void)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
//Look for mon in party that is able to be switched into and has ability that sets terrain
|
//Look for mon in party that is able to be switched into and has ability that sets terrain
|
||||||
if (GetMonData(&party[i], MON_DATA_HP) != 0
|
if (IsValidForBattle(&party[i])
|
||||||
&& GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG) != SPECIES_NONE
|
|
||||||
&& GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG) != SPECIES_EGG
|
|
||||||
&& i != gBattlerPartyIndexes[gActiveBattler]
|
&& i != gBattlerPartyIndexes[gActiveBattler]
|
||||||
&& i != gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]
|
&& i != gBattlerPartyIndexes[BATTLE_PARTNER(gActiveBattler)]
|
||||||
&& IsBattlerGrounded(gActiveBattler)
|
&& IsBattlerGrounded(gActiveBattler)
|
||||||
@ -561,13 +551,9 @@ static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent)
|
|||||||
|
|
||||||
for (i = firstId; i < lastId; i++)
|
for (i = firstId; i < lastId; i++)
|
||||||
{
|
{
|
||||||
u16 species;
|
u16 species, monAbility;
|
||||||
u16 monAbility;
|
|
||||||
|
|
||||||
if (GetMonData(&party[i], MON_DATA_HP) == 0)
|
if (!IsValidForBattle(&party[i]))
|
||||||
continue;
|
|
||||||
species = GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG);
|
|
||||||
if (species == SPECIES_NONE || species == SPECIES_EGG)
|
|
||||||
continue;
|
continue;
|
||||||
if (i == gBattlerPartyIndexes[battlerIn1])
|
if (i == gBattlerPartyIndexes[battlerIn1])
|
||||||
continue;
|
continue;
|
||||||
@ -580,8 +566,8 @@ static bool8 FindMonWithFlagsAndSuperEffective(u16 flags, u8 moduloPercent)
|
|||||||
if (IsAceMon(gActiveBattler, i))
|
if (IsAceMon(gActiveBattler, i))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
species = GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG);
|
||||||
monAbility = GetMonAbility(&party[i]);
|
monAbility = GetMonAbility(&party[i]);
|
||||||
|
|
||||||
CalcPartyMonTypeEffectivenessMultiplier(gLastLandedMoves[gActiveBattler], species, monAbility);
|
CalcPartyMonTypeEffectivenessMultiplier(gLastLandedMoves[gActiveBattler], species, monAbility);
|
||||||
if (gMoveResultFlags & flags)
|
if (gMoveResultFlags & flags)
|
||||||
{
|
{
|
||||||
@ -650,11 +636,7 @@ bool32 ShouldSwitch(void)
|
|||||||
|
|
||||||
for (i = firstId; i < lastId; i++)
|
for (i = firstId; i < lastId; i++)
|
||||||
{
|
{
|
||||||
if (GetMonData(&party[i], MON_DATA_HP) == 0)
|
if (!IsValidForBattle(&party[i]))
|
||||||
continue;
|
|
||||||
if (GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG) == SPECIES_NONE)
|
|
||||||
continue;
|
|
||||||
if (GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG) == SPECIES_EGG)
|
|
||||||
continue;
|
continue;
|
||||||
if (i == gBattlerPartyIndexes[battlerIn1])
|
if (i == gBattlerPartyIndexes[battlerIn1])
|
||||||
continue;
|
continue;
|
||||||
@ -751,7 +733,7 @@ void AI_TrySwitchOrUseItem(void)
|
|||||||
|
|
||||||
for (monToSwitchId = (lastId-1); monToSwitchId >= firstId; monToSwitchId--)
|
for (monToSwitchId = (lastId-1); monToSwitchId >= firstId; monToSwitchId--)
|
||||||
{
|
{
|
||||||
if (GetMonData(&party[monToSwitchId], MON_DATA_HP) == 0)
|
if (!IsValidForBattle(&party[monToSwitchId]))
|
||||||
continue;
|
continue;
|
||||||
if (monToSwitchId == gBattlerPartyIndexes[battlerIn1])
|
if (monToSwitchId == gBattlerPartyIndexes[battlerIn1])
|
||||||
continue;
|
continue;
|
||||||
@ -785,7 +767,7 @@ void AI_TrySwitchOrUseItem(void)
|
|||||||
|
|
||||||
// If there are two(or more) mons to choose from, always choose one that has baton pass
|
// If there are two(or more) mons to choose from, always choose one that has baton pass
|
||||||
// as most often it can't do much on its own.
|
// as most often it can't do much on its own.
|
||||||
static u32 GetBestMonBatonPass(struct Pokemon *party, int firstId, int lastId, u8 invalidMons, int aliveCount)
|
static u32 GetBestMonBatonPass(struct Pokemon *party, int firstId, int lastId, u8 invalidMons, int aliveCount, u32 opposingBattler)
|
||||||
{
|
{
|
||||||
int i, j, bits = 0;
|
int i, j, bits = 0;
|
||||||
|
|
||||||
@ -793,6 +775,8 @@ static u32 GetBestMonBatonPass(struct Pokemon *party, int firstId, int lastId, u
|
|||||||
{
|
{
|
||||||
if (invalidMons & gBitTable[i])
|
if (invalidMons & gBitTable[i])
|
||||||
continue;
|
continue;
|
||||||
|
if (IsAiPartyMonOHKOBy(opposingBattler, &party[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
for (j = 0; j < MAX_MON_MOVES; j++)
|
||||||
{
|
{
|
||||||
@ -837,6 +821,9 @@ static u32 GetBestMonTypeMatchup(struct Pokemon *party, int firstId, int lastId,
|
|||||||
u8 defType1 = gSpeciesInfo[species].types[0];
|
u8 defType1 = gSpeciesInfo[species].types[0];
|
||||||
u8 defType2 = gSpeciesInfo[species].types[1];
|
u8 defType2 = gSpeciesInfo[species].types[1];
|
||||||
|
|
||||||
|
if (IsAiPartyMonOHKOBy(opposingBattler, &party[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
typeEffectiveness = uq4_12_multiply(typeEffectiveness, (GetTypeModifier(atkType1, defType1)));
|
typeEffectiveness = uq4_12_multiply(typeEffectiveness, (GetTypeModifier(atkType1, defType1)));
|
||||||
if (atkType2 != atkType1)
|
if (atkType2 != atkType1)
|
||||||
typeEffectiveness = uq4_12_multiply(typeEffectiveness, (GetTypeModifier(atkType2, defType1)));
|
typeEffectiveness = uq4_12_multiply(typeEffectiveness, (GetTypeModifier(atkType2, defType1)));
|
||||||
@ -881,7 +868,7 @@ static u32 GetBestMonTypeMatchup(struct Pokemon *party, int firstId, int lastId,
|
|||||||
static u32 GetBestMonDmg(struct Pokemon *party, int firstId, int lastId, u8 invalidMons, u32 opposingBattler)
|
static u32 GetBestMonDmg(struct Pokemon *party, int firstId, int lastId, u8 invalidMons, u32 opposingBattler)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
int bestDmg = 0;
|
int dmg, bestDmg = 0;
|
||||||
int bestMonId = PARTY_SIZE;
|
int bestMonId = PARTY_SIZE;
|
||||||
|
|
||||||
gMoveResultFlags = 0;
|
gMoveResultFlags = 0;
|
||||||
@ -890,19 +877,14 @@ static u32 GetBestMonDmg(struct Pokemon *party, int firstId, int lastId, u8 inva
|
|||||||
{
|
{
|
||||||
if (gBitTable[i] & invalidMons)
|
if (gBitTable[i] & invalidMons)
|
||||||
continue;
|
continue;
|
||||||
|
if (IsAiPartyMonOHKOBy(opposingBattler, &party[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
for (j = 0; j < MAX_MON_MOVES; j++)
|
dmg = AI_CalcPartyMonBestMoveDamage(gActiveBattler, opposingBattler, &party[i], NULL);
|
||||||
|
if (bestDmg < dmg)
|
||||||
{
|
{
|
||||||
u32 move = GetMonData(&party[i], MON_DATA_MOVE1 + j);
|
bestDmg = dmg;
|
||||||
if (move != MOVE_NONE && gBattleMoves[move].power != 0)
|
bestMonId = i;
|
||||||
{
|
|
||||||
s32 dmg = AI_CalcPartyMonDamage(move, gActiveBattler, opposingBattler, &party[i]);
|
|
||||||
if (bestDmg < dmg)
|
|
||||||
{
|
|
||||||
bestDmg = dmg;
|
|
||||||
bestMonId = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -912,7 +894,7 @@ static u32 GetBestMonDmg(struct Pokemon *party, int firstId, int lastId, u8 inva
|
|||||||
u8 GetMostSuitableMonToSwitchInto(void)
|
u8 GetMostSuitableMonToSwitchInto(void)
|
||||||
{
|
{
|
||||||
u32 opposingBattler = 0;
|
u32 opposingBattler = 0;
|
||||||
u32 bestMonId = 0;
|
u32 bestMonId = PARTY_SIZE;
|
||||||
u8 battlerIn1 = 0, battlerIn2 = 0;
|
u8 battlerIn1 = 0, battlerIn2 = 0;
|
||||||
s32 firstId = 0;
|
s32 firstId = 0;
|
||||||
s32 lastId = 0; // + 1
|
s32 lastId = 0; // + 1
|
||||||
@ -954,10 +936,7 @@ u8 GetMostSuitableMonToSwitchInto(void)
|
|||||||
// Get invalid slots ids.
|
// Get invalid slots ids.
|
||||||
for (i = firstId; i < lastId; i++)
|
for (i = firstId; i < lastId; i++)
|
||||||
{
|
{
|
||||||
u16 species = GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG);
|
if (!IsValidForBattle(&party[i])
|
||||||
if (species == SPECIES_NONE
|
|
||||||
|| species == SPECIES_EGG
|
|
||||||
|| GetMonData(&party[i], MON_DATA_HP) == 0
|
|
||||||
|| gBattlerPartyIndexes[battlerIn1] == i
|
|| gBattlerPartyIndexes[battlerIn1] == i
|
||||||
|| gBattlerPartyIndexes[battlerIn2] == i
|
|| gBattlerPartyIndexes[battlerIn2] == i
|
||||||
|| i == *(gBattleStruct->monToSwitchIntoId + battlerIn1)
|
|| i == *(gBattleStruct->monToSwitchIntoId + battlerIn1)
|
||||||
@ -977,7 +956,7 @@ u8 GetMostSuitableMonToSwitchInto(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bestMonId = GetBestMonBatonPass(party, firstId, lastId, invalidMons, aliveCount);
|
bestMonId = GetBestMonBatonPass(party, firstId, lastId, invalidMons, aliveCount, opposingBattler);
|
||||||
if (bestMonId != PARTY_SIZE)
|
if (bestMonId != PARTY_SIZE)
|
||||||
return bestMonId;
|
return bestMonId;
|
||||||
|
|
||||||
@ -1040,9 +1019,7 @@ static bool8 ShouldUseItem(void)
|
|||||||
|
|
||||||
for (i = 0; i < PARTY_SIZE; i++)
|
for (i = 0; i < PARTY_SIZE; i++)
|
||||||
{
|
{
|
||||||
if (GetMonData(&party[i], MON_DATA_HP) != 0
|
if (IsValidForBattle(&party[i]))
|
||||||
&& GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG) != SPECIES_NONE
|
|
||||||
&& GetMonData(&party[i], MON_DATA_SPECIES_OR_EGG) != SPECIES_EGG)
|
|
||||||
{
|
{
|
||||||
validMons++;
|
validMons++;
|
||||||
}
|
}
|
||||||
@ -1155,3 +1132,29 @@ static bool32 AI_OpponentCanFaintAiWithMod(u32 healAmount)
|
|||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool32 IsAiPartyMonOHKOBy(u32 battlerAtk, struct Pokemon *aiMon)
|
||||||
|
{
|
||||||
|
bool32 ret = FALSE;
|
||||||
|
struct BattlePokemon *savedBattleMons;
|
||||||
|
s32 hp = GetMonData(aiMon, MON_DATA_HP);
|
||||||
|
s32 bestDmg = AI_CalcPartyMonBestMoveDamage(battlerAtk, gActiveBattler, NULL, aiMon);
|
||||||
|
|
||||||
|
switch (GetNoOfHitsToKO(bestDmg, hp))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
ret = TRUE;
|
||||||
|
break;
|
||||||
|
case 2: // if AI mon is faster allow 2 turns
|
||||||
|
savedBattleMons = AllocSaveBattleMons();
|
||||||
|
PokemonToBattleMon(aiMon, &gBattleMons[gActiveBattler]);
|
||||||
|
if (AI_WhoStrikesFirst(gActiveBattler, battlerAtk, 0) == AI_IS_SLOWER)
|
||||||
|
ret = TRUE;
|
||||||
|
else
|
||||||
|
ret = FALSE;
|
||||||
|
FreeRestoreBattleMons(savedBattleMons);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -3369,25 +3369,49 @@ bool32 ShouldUseWishAromatherapy(u8 battlerAtk, u8 battlerDef, u16 move)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// party logic
|
#define SIZE_G_BATTLE_MONS (sizeof(struct BattlePokemon) * MAX_BATTLERS_COUNT)
|
||||||
s32 AI_CalcPartyMonDamage(u16 move, u8 battlerAtk, u8 battlerDef, struct Pokemon *mon)
|
|
||||||
|
struct BattlePokemon *AllocSaveBattleMons(void)
|
||||||
{
|
{
|
||||||
s32 dmg;
|
struct BattlePokemon *savedBattleMons = Alloc(SIZE_G_BATTLE_MONS);
|
||||||
u32 i;
|
memcpy(savedBattleMons, gBattleMons, SIZE_G_BATTLE_MONS);
|
||||||
|
return savedBattleMons;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeRestoreBattleMons(struct BattlePokemon *savedBattleMons)
|
||||||
|
{
|
||||||
|
memcpy(gBattleMons, savedBattleMons, SIZE_G_BATTLE_MONS);
|
||||||
|
Free(savedBattleMons);
|
||||||
|
}
|
||||||
|
|
||||||
|
// party logic
|
||||||
|
s32 AI_CalcPartyMonBestMoveDamage(u32 battlerAtk, u32 battlerDef, struct Pokemon *attackerMon, struct Pokemon *targetMon)
|
||||||
|
{
|
||||||
|
s32 i, move, bestDmg, dmg;
|
||||||
u8 effectiveness;
|
u8 effectiveness;
|
||||||
struct BattlePokemon *battleMons = Alloc(sizeof(struct BattlePokemon) * MAX_BATTLERS_COUNT);
|
struct BattlePokemon *savedBattleMons = AllocSaveBattleMons();
|
||||||
|
|
||||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
if (attackerMon != NULL)
|
||||||
battleMons[i] = gBattleMons[i];
|
PokemonToBattleMon(attackerMon, &gBattleMons[battlerAtk]);
|
||||||
|
if (targetMon != NULL)
|
||||||
|
PokemonToBattleMon(targetMon, &gBattleMons[battlerDef]);
|
||||||
|
|
||||||
PokemonToBattleMon(mon, &gBattleMons[battlerAtk]);
|
for (bestDmg = 0, i = 0; i < MAX_MON_MOVES; i++)
|
||||||
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, FALSE);
|
{
|
||||||
|
if (BattlerHasAi(battlerAtk))
|
||||||
|
move = GetMonData(attackerMon, MON_DATA_MOVE1 + i);
|
||||||
|
else
|
||||||
|
move = AI_PARTY->mons[GET_BATTLER_SIDE2(battlerAtk)][gBattlerPartyIndexes[battlerAtk]].moves[i];
|
||||||
|
|
||||||
for (i = 0; i < MAX_BATTLERS_COUNT; i++)
|
if (move != MOVE_NONE && gBattleMoves[move].power != 0)
|
||||||
gBattleMons[i] = battleMons[i];
|
{
|
||||||
|
dmg = AI_CalcDamage(move, battlerAtk, battlerDef, &effectiveness, FALSE);
|
||||||
Free(battleMons);
|
if (dmg > bestDmg)
|
||||||
|
bestDmg = dmg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeRestoreBattleMons(savedBattleMons);
|
||||||
return dmg;
|
return dmg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1688,7 +1688,6 @@ static void OpponentHandleChoosePokemon(void)
|
|||||||
else if (*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) == PARTY_SIZE)
|
else if (*(gBattleStruct->AI_monToSwitchIntoId + gActiveBattler) == PARTY_SIZE)
|
||||||
{
|
{
|
||||||
chosenMonId = GetMostSuitableMonToSwitchInto();
|
chosenMonId = GetMostSuitableMonToSwitchInto();
|
||||||
|
|
||||||
if (chosenMonId == PARTY_SIZE)
|
if (chosenMonId == PARTY_SIZE)
|
||||||
{
|
{
|
||||||
s32 battler1, battler2, firstId, lastId;
|
s32 battler1, battler2, firstId, lastId;
|
||||||
@ -1702,14 +1701,13 @@ static void OpponentHandleChoosePokemon(void)
|
|||||||
battler1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
battler1 = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
|
||||||
battler2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
battler2 = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
|
||||||
pokemonInBattle = 2;
|
pokemonInBattle = 2;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
GetAIPartyIndexes(gActiveBattler, &firstId, &lastId);
|
||||||
|
|
||||||
for (chosenMonId = (lastId-1); chosenMonId >= firstId; chosenMonId--)
|
for (chosenMonId = (lastId-1); chosenMonId >= firstId; chosenMonId--)
|
||||||
{
|
{
|
||||||
if (GetMonData(&gEnemyParty[chosenMonId], MON_DATA_HP) != 0
|
if (IsValidForBattle(&gEnemyParty[chosenMonId])
|
||||||
&& chosenMonId != gBattlerPartyIndexes[battler1]
|
&& chosenMonId != gBattlerPartyIndexes[battler1]
|
||||||
&& chosenMonId != gBattlerPartyIndexes[battler2]
|
&& chosenMonId != gBattlerPartyIndexes[battler2]
|
||||||
&& (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_ACE_POKEMON)
|
&& (!(AI_THINKING_STRUCT->aiFlags & AI_FLAG_ACE_POKEMON)
|
||||||
|
Loading…
Reference in New Issue
Block a user