mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2025-02-21 11:43:37 +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);
|
void DoBurmyFormChange(u32 monId);
|
||||||
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget);
|
bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 checkTarget);
|
||||||
|
|
||||||
// ability checks
|
// Ability checks
|
||||||
bool32 IsRolePlayBannedAbilityAtk(u16 ability);
|
bool32 IsRolePlayBannedAbilityAtk(u16 ability);
|
||||||
bool32 IsRolePlayBannedAbility(u16 ability);
|
bool32 IsRolePlayBannedAbility(u16 ability);
|
||||||
bool32 IsSkillSwapBannedAbility(u16 ability);
|
bool32 IsSkillSwapBannedAbility(u16 ability);
|
||||||
@ -173,4 +173,7 @@ bool32 CanBeFrozen(u8 battlerId);
|
|||||||
bool32 CanBeConfused(u8 battlerId);
|
bool32 CanBeConfused(u8 battlerId);
|
||||||
bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag);
|
bool32 IsBattlerTerrainAffected(u8 battlerId, u32 terrainFlag);
|
||||||
|
|
||||||
|
// Move checks
|
||||||
|
bool8 IsTwoStrikesMove(u16 move);
|
||||||
|
|
||||||
#endif // GUARD_BATTLE_UTIL_H
|
#endif // GUARD_BATTLE_UTIL_H
|
||||||
|
@ -733,20 +733,85 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef)
|
|||||||
else
|
else
|
||||||
dmg = (critDmg + normalDmg * (critChance - 1)) / critChance;
|
dmg = (critDmg + normalDmg * (critChance - 1)) / critChance;
|
||||||
|
|
||||||
// handle dynamic move damage
|
// Handle dynamic move damage
|
||||||
switch (gBattleMoves[move].effect)
|
switch (gBattleMoves[move].effect)
|
||||||
{
|
{
|
||||||
case EFFECT_LEVEL_DAMAGE:
|
case EFFECT_LEVEL_DAMAGE:
|
||||||
case EFFECT_PSYWAVE:
|
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;
|
break;
|
||||||
|
}
|
||||||
case EFFECT_DRAGON_RAGE:
|
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;
|
break;
|
||||||
|
}
|
||||||
case EFFECT_SONICBOOM:
|
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;
|
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_METAL_BURST:
|
||||||
//case EFFECT_COUNTER:
|
//case EFFECT_COUNTER:
|
||||||
default:
|
default:
|
||||||
@ -755,6 +820,17 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef)
|
|||||||
break;
|
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(battlerAtk);
|
||||||
RestoreBattlerData(battlerDef);
|
RestoreBattlerData(battlerDef);
|
||||||
|
|
||||||
@ -2653,7 +2729,7 @@ bool32 AI_CanPoison(u8 battlerAtk, u8 battlerDef, u16 defAbility, u16 move, u16
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool32 CanBeParalyzed(u8 battler, u16 ability)
|
static bool32 AI_CanBeParalyzed(u8 battler, u16 ability)
|
||||||
{
|
{
|
||||||
if (ability == ABILITY_LIMBER
|
if (ability == ABILITY_LIMBER
|
||||||
|| IS_BATTLER_OF_TYPE(battler, TYPE_ELECTRIC)
|
|| 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)
|
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
|
|| AI_GetMoveEffectiveness(move, battlerAtk, battlerDef) == AI_EFFECTIVENESS_x0
|
||||||
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
|| gSideStatuses[GetBattlerSide(battlerDef)] & SIDE_STATUS_SAFEGUARD
|
||||||
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
|| DoesSubstituteBlockMove(battlerAtk, battlerDef, move)
|
||||||
|
@ -217,6 +217,20 @@ static const u16 sEntrainmentTargetSimpleBeamBannedAbilities[] =
|
|||||||
ABILITY_GULP_MISSILE,
|
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)
|
bool32 IsAffectedByFollowMe(u32 battlerAtk, u32 defSide, u32 move)
|
||||||
{
|
{
|
||||||
u32 ability = GetBattlerAbility(battlerAtk);
|
u32 ability = GetBattlerAbility(battlerAtk);
|
||||||
@ -9509,3 +9523,15 @@ bool32 BlocksPrankster(u16 move, u8 battlerPrankster, u8 battlerDef, bool32 chec
|
|||||||
#endif
|
#endif
|
||||||
return FALSE;
|
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