mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-27 20:24:18 +01:00
fix up some negative checks, organize some effects in AI_CheckBadMove
This commit is contained in:
parent
5ae1e3c25b
commit
1ae57f26a3
@ -7,6 +7,19 @@
|
|||||||
#define AI_CHOICE_WATCH 5
|
#define AI_CHOICE_WATCH 5
|
||||||
#define AI_CHOICE_SWITCH 7
|
#define AI_CHOICE_SWITCH 7
|
||||||
|
|
||||||
|
#define RETURN_SCORE_PLUS(val) \
|
||||||
|
{ \
|
||||||
|
score += val; \
|
||||||
|
return score; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RETURN_SCORE_MINUS(val) \
|
||||||
|
{ \
|
||||||
|
score -= val; \
|
||||||
|
return score; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void BattleAI_SetupItems(void);
|
void BattleAI_SetupItems(void);
|
||||||
void BattleAI_SetupFlags(void);
|
void BattleAI_SetupFlags(void);
|
||||||
void BattleAI_SetupAIData(u8 defaultScoreMoves);
|
void BattleAI_SetupAIData(u8 defaultScoreMoves);
|
||||||
|
@ -55,13 +55,12 @@ s8 GetAbilityRating(u16 ability);
|
|||||||
|
|
||||||
// stat stage checks
|
// stat stage checks
|
||||||
bool32 AnyStatIsRaised(u8 battlerId);
|
bool32 AnyStatIsRaised(u8 battlerId);
|
||||||
bool32 BattlerStatCanFall(u8 battler, u16 battlerAbility, u8 stat);
|
bool32 ShouldLowerStat(u8 battler, u16 battlerAbility, u8 stat);
|
||||||
bool32 BattlerStatCanRise(u8 battler, u16 battlerAbility, u8 stat);
|
bool32 BattlerStatCanRise(u8 battler, u16 battlerAbility, u8 stat);
|
||||||
bool32 AreBattlersStatsMaxed(u8 battler);
|
bool32 AreBattlersStatsMaxed(u8 battler);
|
||||||
bool32 BattlerHasAnyStatRaised(u8 battlerId);
|
bool32 BattlerHasAnyStatRaised(u8 battlerId);
|
||||||
u32 CountPositiveStatStages(u8 battlerId);
|
u32 CountPositiveStatStages(u8 battlerId);
|
||||||
u32 CountNegativeStatStages(u8 battlerId);
|
u32 CountNegativeStatStages(u8 battlerId);
|
||||||
bool32 BattlerShouldRaiseAttacks(u8 battlerId, u16 ability);
|
|
||||||
bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
|
bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
|
||||||
bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
|
bool32 ShouldLowerDefense(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
|
||||||
bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
|
bool32 ShouldLowerSpeed(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
|
||||||
|
1650
src/battle_ai_main.c
1650
src/battle_ai_main.c
File diff suppressed because it is too large
Load Diff
@ -859,23 +859,36 @@ u8 GetMoveDamageResult(u16 move)
|
|||||||
|
|
||||||
u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef)
|
u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||||
{
|
{
|
||||||
u16 typeEffectiveness, moveType;
|
u8 damageVar;
|
||||||
|
u32 effectivenessMultiplier;
|
||||||
|
|
||||||
SaveBattlerData(battlerAtk);
|
gMoveResultFlags = 0;
|
||||||
SaveBattlerData(battlerDef);
|
gCurrentMove = AI_THINKING_STRUCT->moveConsidered;
|
||||||
|
effectivenessMultiplier = AI_GetTypeEffectiveness(gCurrentMove, sBattler_AI, gBattlerTarget);
|
||||||
|
switch (effectivenessMultiplier)
|
||||||
|
{
|
||||||
|
case UQ_4_12(0.0):
|
||||||
|
default:
|
||||||
|
damageVar = AI_EFFECTIVENESS_x0;
|
||||||
|
break;
|
||||||
|
case UQ_4_12(0.25):
|
||||||
|
damageVar = AI_EFFECTIVENESS_x0_25;
|
||||||
|
break;
|
||||||
|
case UQ_4_12(0.5):
|
||||||
|
damageVar = AI_EFFECTIVENESS_x0_5;
|
||||||
|
break;
|
||||||
|
case UQ_4_12(1.0):
|
||||||
|
damageVar = AI_EFFECTIVENESS_x1;
|
||||||
|
break;
|
||||||
|
case UQ_4_12(2.0):
|
||||||
|
damageVar = AI_EFFECTIVENESS_x2;
|
||||||
|
break;
|
||||||
|
case UQ_4_12(4.0):
|
||||||
|
damageVar = AI_EFFECTIVENESS_x4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
SetBattlerData(battlerAtk);
|
return damageVar;
|
||||||
SetBattlerData(battlerDef);
|
|
||||||
|
|
||||||
gBattleStruct->dynamicMoveType = 0;
|
|
||||||
SetTypeBeforeUsingMove(move, battlerAtk);
|
|
||||||
GET_MOVE_TYPE(move, moveType);
|
|
||||||
typeEffectiveness = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, FALSE);
|
|
||||||
|
|
||||||
RestoreBattlerData(battlerAtk);
|
|
||||||
RestoreBattlerData(battlerDef);
|
|
||||||
|
|
||||||
return typeEffectiveness;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 AI_GetMoveEffectiveness(u16 move)
|
u8 AI_GetMoveEffectiveness(u16 move)
|
||||||
@ -1096,7 +1109,7 @@ bool32 DoesBattlerIgnoreAbilityChecks(u16 atkAbility, u16 move)
|
|||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_NEGATE_UNAWARE)
|
if (AI_THINKING_STRUCT->aiFlags & AI_FLAG_NEGATE_UNAWARE)
|
||||||
return FALSE; // AI doesn't understand ability suppression concept
|
return FALSE; // AI handicap flag: doesn't understand ability suppression concept
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_COUNT(sIgnoreMoldBreakerMoves); i++)
|
for (i = 0; i < ARRAY_COUNT(sIgnoreMoldBreakerMoves); i++)
|
||||||
{
|
{
|
||||||
@ -1331,7 +1344,7 @@ bool32 IsMoveEncouragedToHit(u8 battlerAtk, u8 battlerDef, u16 move)
|
|||||||
bool32 ShouldTryOHKO(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u32 accuracy, u16 move)
|
bool32 ShouldTryOHKO(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbility, u32 accuracy, u16 move)
|
||||||
{
|
{
|
||||||
u32 holdEffect = AI_GetHoldEffect(battlerDef);
|
u32 holdEffect = AI_GetHoldEffect(battlerDef);
|
||||||
|
|
||||||
gPotentialItemEffectBattler = battlerDef;
|
gPotentialItemEffectBattler = battlerDef;
|
||||||
if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < GetBattlerHoldEffectParam(battlerDef))
|
if (holdEffect == HOLD_EFFECT_FOCUS_BAND && (Random() % 100) < GetBattlerHoldEffectParam(battlerDef))
|
||||||
return FALSE; //probabilistically speaking, focus band should activate so dont OHKO
|
return FALSE; //probabilistically speaking, focus band should activate so dont OHKO
|
||||||
@ -1499,11 +1512,19 @@ void ProtectChecks(u8 battlerAtk, u8 battlerDef, u16 move, u16 predictedMove, s1
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stat stages
|
// stat stages
|
||||||
bool32 BattlerStatCanFall(u8 battler, u16 battlerAbility, u8 stat)
|
bool32 ShouldLowerStat(u8 battler, u16 battlerAbility, u8 stat)
|
||||||
{
|
{
|
||||||
if ((gBattleMons[battler].statStages[stat] > MIN_STAT_STAGE && battlerAbility != ABILITY_CONTRARY)
|
if ((gBattleMons[battler].statStages[stat] > MIN_STAT_STAGE && battlerAbility != ABILITY_CONTRARY)
|
||||||
|| (battlerAbility == ABILITY_CONTRARY && gBattleMons[battler].statStages[stat] < MAX_STAT_STAGE))
|
|| (battlerAbility == ABILITY_CONTRARY && gBattleMons[battler].statStages[stat] < MAX_STAT_STAGE))
|
||||||
|
{
|
||||||
|
if (battlerAbility == ABILITY_CLEAR_BODY
|
||||||
|
|| battlerAbility == ABILITY_WHITE_SMOKE
|
||||||
|
|| battlerAbility == ABILITY_FULL_METAL_BODY)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1562,18 +1583,6 @@ u32 CountNegativeStatStages(u8 battlerId)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks for growth, gear up, work up
|
|
||||||
bool32 BattlerShouldRaiseAttacks(u8 battlerId, u16 ability)
|
|
||||||
{
|
|
||||||
if (((!BattlerStatCanRise(battlerId, ability, STAT_ATK)|| !HasMoveWithSplit(battlerId, SPLIT_PHYSICAL))
|
|
||||||
&& (!BattlerStatCanRise(battlerId, ability, STAT_SPATK) || !HasMoveWithSplit(battlerId, SPLIT_SPECIAL)))
|
|
||||||
|| ability == ABILITY_CONTRARY)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex)
|
bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex)
|
||||||
{
|
{
|
||||||
if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0))
|
if (IsAiFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex, 0))
|
||||||
@ -2521,7 +2530,7 @@ bool32 ShouldPoisonSelf(u8 battler, u16 ability)
|
|||||||
|| (ability == ABILITY_GUTS && HasMoveWithSplit(battler, SPLIT_PHYSICAL))
|
|| (ability == ABILITY_GUTS && HasMoveWithSplit(battler, SPLIT_PHYSICAL))
|
||||||
|| HasMoveEffect(battler, EFFECT_FACADE)
|
|| HasMoveEffect(battler, EFFECT_FACADE)
|
||||||
|| HasMoveEffect(battler, EFFECT_PSYCHO_SHIFT)))
|
|| HasMoveEffect(battler, EFFECT_PSYCHO_SHIFT)))
|
||||||
return TRUE;
|
return TRUE; // battler can be poisoned and has move/ability that synergizes with being poisoned
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2539,12 +2548,19 @@ bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
static bool32 CanBeParayzed(battlerDef, defAbility)
|
||||||
{
|
{
|
||||||
if (defAbility == ABILITY_LIMBER
|
if (defAbility == ABILITY_LIMBER
|
||||||
|| IS_BATTLER_OF_TYPE(battlerDef, TYPE_ELECTRIC)
|
|| IS_BATTLER_OF_TYPE(battlerDef, TYPE_ELECTRIC)
|
||||||
|| gBattleMons[battlerDef].status1 & STATUS1_ANY
|
|| gBattleMons[battlerDef].status1 & STATUS1_ANY
|
||||||
|| IsAbilityStatusProtected(battlerDef)
|
|| IsAbilityStatusProtected(battlerDef))
|
||||||
|
return FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
||||||
|
{
|
||||||
|
if (!CanBeParayzed(battlerDef, defAbility)
|
||||||
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
||||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||||
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove))
|
|| PartnerMoveEffectIsStatusSameTarget(BATTLE_PARTNER(battlerAtk), battlerDef, partnerMove))
|
||||||
@ -2563,7 +2579,7 @@ bool32 CanBeConfused(u8 battler, u16 ability)
|
|||||||
|
|
||||||
bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove)
|
bool32 AI_CanConfuse(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPartner, u16 move, u16 partnerMove)
|
||||||
{
|
{
|
||||||
if (CanBeConfused(battlerDef, defAbility)
|
if (!CanBeConfused(battlerDef, defAbility)
|
||||||
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
||||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||||
|| DoesPartnerHaveSameMoveEffect(battlerAtkPartner, battlerDef, move, partnerMove))
|
|| DoesPartnerHaveSameMoveEffect(battlerAtkPartner, battlerDef, move, partnerMove))
|
||||||
@ -2613,13 +2629,12 @@ bool32 AI_CanBurn(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 battlerAtkPar
|
|||||||
|
|
||||||
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender)
|
bool32 AI_CanBeInfatuated(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 atkGender, u8 defGender)
|
||||||
{
|
{
|
||||||
if (IsBattlerAlive(battlerDef)
|
if ((gBattleMons[battlerDef].status2 & STATUS2_INFATUATION)
|
||||||
&& !(gBattleMons[battlerDef].status2 & STATUS2_INFATUATION)
|
|| defAbility == ABILITY_OBLIVIOUS
|
||||||
&& defAbility != ABILITY_OBLIVIOUS
|
|| atkGender == defGender
|
||||||
&& atkGender != defGender
|
|| atkGender == MON_GENDERLESS
|
||||||
&& atkGender != MON_GENDERLESS
|
|| defGender == MON_GENDERLESS
|
||||||
&& defGender != MON_GENDERLESS
|
|| !IsAbilityOnSide(battlerDef, ABILITY_AROMA_VEIL))
|
||||||
&& !IsAbilityOnSide(battlerDef, ABILITY_AROMA_VEIL))
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -2628,7 +2643,7 @@ u32 ShouldTryToFlinch(u8 battlerAtk, u8 battlerDef, u16 atkAbility, u16 defAbili
|
|||||||
{
|
{
|
||||||
if (defAbility == ABILITY_INNER_FOCUS
|
if (defAbility == ABILITY_INNER_FOCUS
|
||||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||||
|| GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1)
|
|| GetWhoStrikesFirst(battlerAtk, battlerDef, TRUE) == 1) // opponent goes first
|
||||||
{
|
{
|
||||||
return 0; // don't try to flinch
|
return 0; // don't try to flinch
|
||||||
}
|
}
|
||||||
@ -2863,7 +2878,7 @@ bool32 IsTargetingPartner(u8 battlerAtk, u8 battlerDef)
|
|||||||
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
|
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (battlerDef == BATTLE_PARTNER(battlerAtk))
|
if ((battlerAtk & BIT_SIDE) == (battlerDef & BIT_SIDE))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
Loading…
Reference in New Issue
Block a user