Skip to content

Commit

Permalink
Fix Roullout Fury Cutter AI power calc (#3110)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrgriffin committed Jul 16, 2023
2 parents c4057cb + 9a09f1e commit 58ede15
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 12 deletions.
4 changes: 3 additions & 1 deletion include/battle_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,10 @@ bool32 IsBattlerGrounded(u8 battlerId);
bool32 IsBattlerAlive(u8 battlerId);
u8 GetBattleMonMoveSlot(struct BattlePokemon *battleMon, u16 move);
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 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 CalcPartyMonTypeEffectivenessMultiplier(u16 move, u16 speciesDef, u16 abilityDef);
u16 GetTypeModifier(u8 atkType, u8 defType);
Expand Down
20 changes: 17 additions & 3 deletions src/battle_ai_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 dmg, moveType, critDmg, normalDmg;
s32 dmg, moveType, critDmg, normalDmg, fixedBasePower, n;
s8 critChance;
u16 effectivenessMultiplier;

Expand Down Expand Up @@ -814,8 +814,22 @@ s32 AI_CalcDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 *typeEffectiveness,
{
ProteanTryChangeType(battlerAtk, AI_DATA->abilities[battlerAtk], move, moveType);
critChance = GetInverseCritChance(battlerAtk, battlerDef, move);
normalDmg = CalculateMoveDamageAndEffectiveness(move, battlerAtk, battlerDef, moveType, &effectivenessMultiplier);
critDmg = CalculateMoveDamage(move, battlerAtk, battlerDef, moveType, 0, TRUE, FALSE, FALSE);
// Certain moves like Rollout calculate damage based on values which change during the move execution, but before calling dmg calc.
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)
dmg = normalDmg;
Expand Down
30 changes: 22 additions & 8 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -8453,6 +8453,24 @@ const struct TypePower gNaturalGiftTable[] =
[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)
{
u32 i;
Expand Down Expand Up @@ -8489,14 +8507,10 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
basePower = 10 * (MAX_FRIENDSHIP - gBattleMons[battlerAtk].friendship) / 25;
break;
case EFFECT_FURY_CUTTER:
for (i = 1; i < gDisableStructs[battlerAtk].furyCutterCounter; i++)
basePower *= 2;
basePower = CalcFuryCutterBasePower(basePower, gDisableStructs[battlerAtk].furyCutterCounter);
break;
case EFFECT_ROLLOUT:
for (i = 1; i < (5 - gDisableStructs[battlerAtk].rolloutTimer); i++)
basePower *= 2;
if (gBattleMons[battlerAtk].status2 & STATUS2_DEFENSE_CURL)
basePower *= 2;
basePower = CalcRolloutBasePower(battlerAtk, basePower, gDisableStructs[battlerAtk].rolloutTimer);
break;
case EFFECT_MAGNITUDE:
basePower = gBattleStruct->magnitudeBasePower;
Expand Down Expand Up @@ -9700,10 +9714,10 @@ s32 CalculateMoveDamage(u16 move, u8 battlerAtk, u8 battlerDef, u8 moveType, s32
}

// 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);
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)
Expand Down

0 comments on commit 58ede15

Please sign in to comment.