mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-02-20 11:13:35 +01:00
AI handles multi-strike and fixed dmg moves
Does not account for Parental Bond or Beat Up yet as those require some functions from #1676.
This commit is contained in:
parent
bbe2eccf62
commit
4310868bee
@ -156,7 +156,7 @@ void BufferStatChange(u8 battlerId, u8 statId, u8 stringId);
|
||||
void DoBurmyFormChange(u32 monId);
|
||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget);
|
||||
|
||||
// ability checks
|
||||
// Ability checks
|
||||
bool32 IsRolePlayBannedAbilityAtk(u16 ability);
|
||||
bool32 IsRolePlayBannedAbility(u16 ability);
|
||||
bool32 IsSkillSwapBannedAbility(u16 ability);
|
||||
@ -173,4 +173,7 @@ bool32 CanBeFrozen(u8 battlerId);
|
||||
bool32 CanBeConfused(u8 battlerId);
|
||||
bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag);
|
||||
|
||||
// Move checks
|
||||
bool8 IsTwoStrikesMove(u16 move);
|
||||
|
||||
#endif // GUARD_BATTLE_UTIL_H
|
||||
|
@ -733,20 +733,85 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
else
|
||||
dmg = (critDmg + normalDmg * (critChance - 1)) / critChance;
|
||||
|
||||
// handle dynamic move damage
|
||||
// Handle dynamic move damage
|
||||
switch (gBattleMoves[move].effect)
|
||||
{
|
||||
case EFFECT_LEVEL_DAMAGE:
|
||||
case EFFECT_PSYWAVE:
|
||||
//psywave's expected damage is equal to the user's level
|
||||
dmg = gBattleMons[battlerAtk].level;
|
||||
{
|
||||
// Psywave's expected damage is equal to the user's level
|
||||
if (AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0)
|
||||
dmg = 0;
|
||||
else if (AI_DATA->atkAbility == ABILITY_PARENTAL_BOND)
|
||||
dmg = 2 * gBattleMons[battlerAtk].level;
|
||||
else
|
||||
dmg = gBattleMons[battlerAtk].level;
|
||||
break;
|
||||
}
|
||||
case EFFECT_DRAGON_RAGE:
|
||||
dmg = 40;
|
||||
{
|
||||
if (AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0)
|
||||
dmg = 0;
|
||||
else if (AI_DATA->atkAbility == ABILITY_PARENTAL_BOND)
|
||||
dmg = 80;
|
||||
else
|
||||
dmg = 40;
|
||||
break;
|
||||
}
|
||||
case EFFECT_SONICBOOM:
|
||||
dmg = 20;
|
||||
{
|
||||
if (AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0)
|
||||
dmg = 0;
|
||||
else if (AI_DATA->atkAbility == ABILITY_PARENTAL_BOND)
|
||||
dmg = 40;
|
||||
else
|
||||
dmg = 20;
|
||||
break;
|
||||
}
|
||||
case EFFECT_MULTI_HIT:
|
||||
{
|
||||
if (AI_DATA->atkAbility == ABILITY_SKILL_LINK)
|
||||
dmg *= 5;
|
||||
else
|
||||
dmg *= 3; // Average number of hits is three
|
||||
break;
|
||||
}
|
||||
case EFFECT_TRIPLE_KICK:
|
||||
{
|
||||
if (AI_DATA->atkAbility == ABILITY_SKILL_LINK)
|
||||
dmg *= 6; // Skill Link ensures the 2nd and 3rd hits will connect if the first does
|
||||
else
|
||||
dmg *= 5; // Triple Kick/Triple Axel's average power is almost 5x its base power
|
||||
break;
|
||||
}
|
||||
case EFFECT_ENDEAVOR:
|
||||
{
|
||||
if (AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0)
|
||||
dmg = 0;
|
||||
else
|
||||
// If target has less HP than user, Endeavor does no damage
|
||||
dmg = max(0, gBattleMons[battlerDef].hp - gBattleMons[battlerAtk].hp);
|
||||
break;
|
||||
}
|
||||
case EFFECT_SUPER_FANG:
|
||||
{
|
||||
if (AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0)
|
||||
dmg = 0;
|
||||
// Two hits of Super Fang halves HP twice, leaving target with 25% HP
|
||||
else if (AI_DATA->atkAbility == ABILITY_PARENTAL_BOND)
|
||||
dmg = gBattleMons[battlerDef].hp * 3 / 4;
|
||||
else
|
||||
dmg = gBattleMons[battlerDef].hp / 2;
|
||||
break;
|
||||
}
|
||||
case EFFECT_FINAL_GAMBIT:
|
||||
{
|
||||
if (AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0)
|
||||
dmg = 0;
|
||||
else
|
||||
dmg = gBattleMons[battlerAtk].hp;
|
||||
break;
|
||||
}
|
||||
//case EFFECT_METAL_BURST:
|
||||
//case EFFECT_COUNTER:
|
||||
default:
|
||||
@ -755,6 +820,17 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef)
|
||||
break;
|
||||
}
|
||||
|
||||
// Handle other multi-strike moves
|
||||
if (IsTwoStrikesMove(move))
|
||||
{
|
||||
dmg *= 2;
|
||||
}
|
||||
else if (move == MOVE_SURGING_STRIKES
|
||||
|| (move == MOVE_WATER_SHURIKEN && gBattleMons[battlerAtk].species == SPECIES_GRENINJA_ASH))
|
||||
{
|
||||
dmg *= 3;
|
||||
}
|
||||
|
||||
RestoreBattlerData(battlerAtk);
|
||||
RestoreBattlerData(battlerDef);
|
||||
|
||||
@ -2653,7 +2729,7 @@ bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool32 CanBeParalyzed(u8 battler, u16 ability)
|
||||
static bool32 AI_CanBeParalyzed(u8 battler, u16 ability)
|
||||
{
|
||||
if (ability == ABILITY_LIMBER
|
||||
|| IS_BATTLER_OF_TYPE(battler, TYPE_ELECTRIC)
|
||||
@ -2665,7 +2741,7 @@ static bool32 CanBeParalyzed(u8 battler, u16 ability)
|
||||
|
||||
bool32 AI_CanParalyze(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16 partnerMove)
|
||||
{
|
||||
if (!CanBeParalyzed(battlerDef, defAbility)
|
||||
if (!AI_CanBeParalyzed(battlerDef, defAbility)
|
||||
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|
||||
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||
|
@ -217,6 +217,20 @@ static const u16 sEntrainmentTargetSimpleBeamBannedAbilities[] =
|
||||
ABILITY_GULP_MISSILE,
|
||||
};
|
||||
|
||||
static const u16 sTwoStrikeMoves[] =
|
||||
{
|
||||
MOVE_BONEMERANG,
|
||||
MOVE_DOUBLE_HIT,
|
||||
MOVE_DOUBLE_IRON_BASH,
|
||||
MOVE_DOUBLE_KICK,
|
||||
MOVE_DRAGON_DARTS,
|
||||
MOVE_DUAL_CHOP,
|
||||
MOVE_DUAL_WINGBEAT,
|
||||
MOVE_GEAR_GRIND,
|
||||
MOVE_TWINEEDLE,
|
||||
0xFFFF
|
||||
};
|
||||
|
||||
bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move)
|
||||
{
|
||||
u32 ability = GetBattlerAbility(battlerAtk);
|
||||
@ -9509,3 +9523,15 @@ bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 chec
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool8 IsTwoStrikesMove(u16 move)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(sTwoStrikeMoves); i++)
|
||||
{
|
||||
if (move == sTwoStrikeMoves[i])
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user