mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-11-16 19:47:35 +01:00
move common ai params to preloaded struct
This commit is contained in:
parent
916d0416e3
commit
8a544665e4
@ -235,8 +235,29 @@ struct AI_SavedBattleMon
|
||||
u16 species;
|
||||
};
|
||||
|
||||
struct AiLogicData
|
||||
{
|
||||
//attacker data
|
||||
u16 atkAbility;
|
||||
u16 atkHoldEffect;
|
||||
u8 atkParam;
|
||||
// target data
|
||||
u16 defAbility;
|
||||
u16 defHoldEffect;
|
||||
u8 defParam;
|
||||
// attacker partner data
|
||||
u8 battlerAtkPartner;
|
||||
u16 partnerMove;
|
||||
u16 atkPartnerAbility;
|
||||
bool32 targetSameSide;
|
||||
// target partner data
|
||||
u8 battlerDefPartner;
|
||||
u16 defPartnerAbility;
|
||||
};
|
||||
|
||||
struct AI_ThinkingStruct
|
||||
{
|
||||
struct AiLogicData *data;
|
||||
u8 aiState;
|
||||
u8 movesetIndex;
|
||||
u16 moveConsidered;
|
||||
@ -295,6 +316,7 @@ struct BattleResources
|
||||
};
|
||||
|
||||
#define AI_THINKING_STRUCT ((struct AI_ThinkingStruct *)(gBattleResources->ai))
|
||||
#define AI_DATA ((struct AiLogicData *)(gBattleResources->ai->data))
|
||||
#define BATTLE_HISTORY ((struct BattleHistory *)(gBattleResources->battleHistory))
|
||||
|
||||
struct BattleResults
|
||||
|
@ -49,8 +49,10 @@ bool32 BattlerHasAnyStatRaised(u8 battlerId);
|
||||
u32 CountPositiveStatStages(u8 battlerId);
|
||||
u32 CountNegativeStatStages(u8 battlerId);
|
||||
bool32 BattlerShouldRaiseAttacks(u8 battlerId, u16 ability);
|
||||
bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex);
|
||||
|
||||
// move checks
|
||||
bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split);
|
||||
s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef);
|
||||
u8 GetMoveDamageResult(u16 move);
|
||||
u16 AI_GetTypeEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef);
|
||||
@ -60,6 +62,7 @@ bool32 IsConfusionMoveEffect(u16 moveEffect);
|
||||
bool32 HasMoveWithSplit(u32 battler, u32 split);
|
||||
bool32 HasMoveWithType(u32 battler, u8 type);
|
||||
bool32 HasMoveEffect(u32 battlerId, u16 moveEffect);
|
||||
bool32 HasMoveWithLowAccuracy(u8, u8, u8, bool32, u16, u16, u16, u16, u16);
|
||||
bool32 TestMoveFlagsInMoveset(u8 battler, u32 flags);
|
||||
bool32 IsAromaVeilProtectedMove(u16 move);
|
||||
bool32 IsNonVolatileStatusMoveEffect(u16 moveEffect);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -267,6 +267,32 @@ bool32 IsBattlerTrapped(u8 battler, bool8 checkSwitch)
|
||||
}
|
||||
|
||||
// move checks
|
||||
// This function checks if all physical/special moves are either unusable or unreasonable to use.
|
||||
// Consider a pokemon boosting their attack against a ghost pokemon having only normal-type physical attacks.
|
||||
bool32 MovesWithSplitUnusable(u32 attacker, u32 target, u32 split)
|
||||
{
|
||||
s32 i, moveType;
|
||||
u32 usable = 0;
|
||||
u32 unusable = CheckMoveLimitations(attacker, 0, 0xFF);
|
||||
u16 *moves = GetMovesArray(attacker);
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (moves[i] != MOVE_NONE
|
||||
&& moves[i] != 0xFFFF
|
||||
&& GetBattleMoveSplit(moves[i]) == split
|
||||
&& !(unusable & gBitTable[i]))
|
||||
{
|
||||
SetTypeBeforeUsingMove(moves[i], attacker);
|
||||
GET_MOVE_TYPE(moves[i], moveType);
|
||||
if (CalcTypeEffectivenessMultiplier(moves[i], moveType, attacker, target, FALSE) != 0)
|
||||
usable |= gBitTable[i];
|
||||
}
|
||||
}
|
||||
|
||||
return (usable == 0);
|
||||
}
|
||||
|
||||
static bool32 AI_GetIfCrit(u32 move, u8 battlerAtk, u8 battlerDef)
|
||||
{
|
||||
bool32 isCrit;
|
||||
@ -1022,6 +1048,21 @@ bool32 BattlerShouldRaiseAttacks(u8 battlerId, u16 ability)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool32 ShouldLowerAttack(u8 battlerAtk, u8 battlerDef, u16 defAbility, u8 moveIndex)
|
||||
{
|
||||
if (IsBattlerFaster(AI_CHECK_FASTER) && CanAttackerFaintTarget(battlerAtk, battlerDef, moveIndex))
|
||||
return FALSE; //Don't bother lowering stats if can kill enemy.
|
||||
|
||||
if (gBattleMons[battlerDef].statStages[STAT_ATK] > 4 && HasMoveWithSplit(battlerDef, SPLIT_PHYSICAL)
|
||||
&& defAbility != ABILITY_CONTRARY
|
||||
&& defAbility != ABILITY_CLEAR_BODY
|
||||
&& defAbility != ABILITY_WHITE_SMOKE
|
||||
//&& defAbility != ABILITY_FULLMETALBODY
|
||||
&& defAbility != ABILITY_HYPER_CUTTER)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 CanAttackerFaintTarget(u8 battlerAtk, u8 battlerDef, u8 index)
|
||||
{
|
||||
s32 dmg = AI_THINKING_STRUCT->simulatedDmg[battlerAtk][battlerDef][index];
|
||||
@ -1081,6 +1122,33 @@ bool32 HasMoveEffect(u32 battlerId, u16 moveEffect)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 HasMoveWithLowAccuracy(u8 battlerAtk, u8 battlerDef, u8 accCheck, bool32 ignoreStatus, u16 atkAbility, u16 defAbility, u16 atkHoldEffect, u16 defHoldEffect, u16 move)
|
||||
{
|
||||
s32 i;
|
||||
u16 *moves = GetMovesArray(battlerAtk);
|
||||
u8 moveLimitations = CheckMoveLimitations(battlerAtk, 0, 0xFF);
|
||||
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (moves[i] == MOVE_NONE || moves[i] == 0xFFFF)
|
||||
continue;
|
||||
|
||||
if (!(gBitTable[i] & moveLimitations))
|
||||
{
|
||||
if (ignoreStatus && IS_MOVE_STATUS(moves[i]))
|
||||
continue;
|
||||
else if ((!IS_MOVE_STATUS(moves[i]) && gBattleMoves[move].accuracy == 0)
|
||||
|| gBattleMoves[move].target & (MOVE_TARGET_USER | MOVE_TARGET_OPPONENTS_FIELD))
|
||||
continue;
|
||||
|
||||
if (AI_GetMoveAccuracy(battlerAtk, battlerDef, atkAbility, defAbility, atkHoldEffect, defHoldEffect, move) <= accCheck)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool32 IsInstructBannedMove(u16 move)
|
||||
{
|
||||
u32 i;
|
||||
|
Loading…
Reference in New Issue
Block a user