Fix Roullout Fury Cutter AI power calc

This commit is contained in:
DizzyEggg 2023-07-06 13:41:16 +02:00
parent f3be4e1ac5
commit 9a09f1e3b9
3 changed files with 42 additions and 12 deletions

View File

@ -165,8 +165,10 @@ bool32 IsBattlerGrounded(u8 battlerId);
bool32 IsBattlerAlive(u8 battlerId); bool32 IsBattlerAlive(u8 battlerId);
u8 GetBattleMonMoveSlot(struct BattlePokemon *battleMon, u16 move); u8 GetBattleMonMoveSlot(struct BattlePokemon *battleMon, u16 move);
u32 GetBattlerWeight(u8 battlerId); u32 GetBattlerWeight(u8 battlerId);
u32 CalcRolloutBasePower(u32 battlerAtk, u32 basePower, u32 rolloutTimer);
u32 CalcFuryCutterBasePower(u32 basePower, u32 furyCutterCounter);
s32 CalculateMoveDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32 fixedBasePower, bool32 isCrit, bool32 randomFactor, bool32 updateFlags); s32 CalculateMoveDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32 fixedBasePower, bool32 isCrit, bool32 randomFactor, bool32 updateFlags);
s32 CalculateMoveDamageAndEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, u16 *typeEffectivenessModifier); s32 CalculateMoveDamageAndEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32 fixedBasePower, u16 *typeEffectivenessModifier);
u16 CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 battlerDef, bool32 recordAbilities); u16 CalcTypeEffectivenessMultiplier(u16 move, u8 moveType, u8 battlerAtk, u8 battlerDef, bool32 recordAbilities);
u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef); u16 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef);
u16 GetTypeModifier(u8 atkType, u8 defType); u16 GetTypeModifier(u8 atkType, u8 defType);

View File

@ -785,7 +785,7 @@ static bool32 AI_GetIfCrit(u32 move, u8 battlerAtk, u8 battlerDef)
s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *typeEffectiveness, bool32 considerZPower) s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *typeEffectiveness, bool32 considerZPower)
{ {
s32 dmg, moveType, critDmg, normalDmg; s32 dmg, moveType, critDmg, normalDmg, fixedBasePower, n;
s8 critChance; s8 critChance;
u16 effectivenessMultiplier; u16 effectivenessMultiplier;
@ -814,8 +814,22 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *typeEffectiveness,
{ {
ProteanTryChangeType(battlerAtk, AI_DATA->abilities[battlerAtk], move, moveType); ProteanTryChangeType(battlerAtk, AI_DATA->abilities[battlerAtk], move, moveType);
critChance = GetInverseCritChance(battlerAtk, battlerDef, move); critChance = GetInverseCritChance(battlerAtk, battlerDef, move);
normalDmg = CalculateMoveDamageAndEffectiveness(move, battlerAtk, battlerDef, moveType, &effectivenessMultiplier); // Certain moves like Rollout calculate damage based on values which change during the move execution, but before calling dmg calc.
critDmg = CalculateMoveDamage(move, battlerAtk, battlerDef, moveType, 0, TRUE, FALSE, FALSE); switch (gBattleMoves[move].effect)
{
case EFFECT_ROLLOUT:
n = gDisableStructs[battlerAtk].rolloutTimer - 1;
fixedBasePower = CalcRolloutBasePower(battlerAtk, gBattleMoves[move].power, n < 0 ? 5 : n);
break;
case EFFECT_FURY_CUTTER:
fixedBasePower = CalcFuryCutterBasePower(gBattleMoves[move].power, min(gDisableStructs[battlerAtk].furyCutterCounter + 1, 5));
break;
default:
fixedBasePower = 0;
break;
}
normalDmg = CalculateMoveDamageAndEffectiveness(move, battlerAtk, battlerDef, moveType, fixedBasePower, &effectivenessMultiplier);
critDmg = CalculateMoveDamage(move, battlerAtk, battlerDef, moveType, fixedBasePower, TRUE, FALSE, FALSE);
if (critChance == -1) if (critChance == -1)
dmg = normalDmg; dmg = normalDmg;

View File

@ -8447,6 +8447,24 @@ const struct TypePower gNaturalGiftTable[] =
[ITEM_TO_BERRY(ITEM_MARANGA_BERRY)] = {TYPE_DARK, 100}, [ITEM_TO_BERRY(ITEM_MARANGA_BERRY)] = {TYPE_DARK, 100},
}; };
u32 CalcRolloutBasePower(u32 battlerAtk, u32 basePower, u32 rolloutTimer)
{
u32 i;
for (i = 1; i < (5 - rolloutTimer); i++)
basePower *= 2;
if (gBattleMons[battlerAtk].status2 & STATUS2_DEFENSE_CURL)
basePower *= 2;
return basePower;
}
u32 CalcFuryCutterBasePower(u32 basePower, u32 furyCutterCounter)
{
u32 i;
for (i = 1; i < furyCutterCounter; i++)
basePower *= 2;
return basePower;
}
static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef) static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
{ {
u32 i; u32 i;
@ -8483,14 +8501,10 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
basePower = 10 * (MAX_FRIENDSHIP - gBattleMons[battlerAtk].friendship) / 25; basePower = 10 * (MAX_FRIENDSHIP - gBattleMons[battlerAtk].friendship) / 25;
break; break;
case EFFECT_FURY_CUTTER: case EFFECT_FURY_CUTTER:
for (i = 1; i < gDisableStructs[battlerAtk].furyCutterCounter; i++) basePower = CalcFuryCutterBasePower(basePower, gDisableStructs[battlerAtk].furyCutterCounter);
basePower *= 2;
break; break;
case EFFECT_ROLLOUT: case EFFECT_ROLLOUT:
for (i = 1; i < (5 - gDisableStructs[battlerAtk].rolloutTimer); i++) basePower = CalcRolloutBasePower(battlerAtk, basePower, gDisableStructs[battlerAtk].rolloutTimer);
basePower *= 2;
if (gBattleMons[battlerAtk].status2 & STATUS2_DEFENSE_CURL)
basePower *= 2;
break; break;
case EFFECT_MAGNITUDE: case EFFECT_MAGNITUDE:
basePower = gBattleStruct->magnitudeBasePower; basePower = gBattleStruct->magnitudeBasePower;
@ -9694,10 +9708,10 @@ s32 CalculateMoveDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32
} }
// for AI - get move damage and effectiveness with one function call // for AI - get move damage and effectiveness with one function call
s32 CalculateMoveDamageAndEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, u16 *typeEffectivenessModifier) s32 CalculateMoveDamageAndEffectiveness(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32 fixedBasePower, u16 *typeEffectivenessModifier)
{ {
*typeEffectivenessModifier = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, FALSE); *typeEffectivenessModifier = CalcTypeEffectivenessMultiplier(move, moveType, battlerAtk, battlerDef, FALSE);
return DoMoveDamageCalc(move, battlerAtk, battlerDef, moveType, 0, FALSE, FALSE, FALSE, *typeEffectivenessModifier); return DoMoveDamageCalc(move, battlerAtk, battlerDef, moveType, fixedBasePower, FALSE, FALSE, FALSE, *typeEffectivenessModifier);
} }
static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 battlerDef, u8 defType, u8 battlerAtk, bool32 recordAbilities) static void MulByTypeEffectiveness(u16 *modifier, u16 move, u8 moveType, u8 battlerDef, u8 defType, u8 battlerAtk, bool32 recordAbilities)