Fix damage calc modifiers (#5604)

Co-authored-by: Eduardo Quezada <eduardo602002@gmail.com>
This commit is contained in:
Alex 2024-10-27 22:47:02 +01:00 committed by GitHub
parent 13d3245204
commit e9ab070e7d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 88 additions and 56 deletions

View file

@ -9255,53 +9255,6 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32
if (moveType == TYPE_STEEL)
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_TRANSISTOR:
if (moveType == TYPE_ELECTRIC)
{
if (B_TRANSISTOR_BOOST >= GEN_9)
modifier = uq4_12_multiply(modifier, UQ_4_12(5325 / 4096));
else
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
}
break;
case ABILITY_DRAGONS_MAW:
if (moveType == TYPE_DRAGON)
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_GORILLA_TACTICS:
if (IS_MOVE_PHYSICAL(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_ROCKY_PAYLOAD:
if (moveType == TYPE_ROCK)
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_PROTOSYNTHESIS:
{
u8 atkHighestStat = GetHighestStatId(battlerAtk);
if (((weather & B_WEATHER_SUN && WEATHER_HAS_EFFECT) || gBattleStruct->boosterEnergyActivates & (1u << battlerAtk))
&& ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK))
&& !(gBattleMons[battlerAtk].status2 & STATUS2_TRANSFORMED))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
}
break;
case ABILITY_QUARK_DRIVE:
{
u8 atkHighestStat = GetHighestStatId(battlerAtk);
if ((gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & (1u << battlerAtk))
&& ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK))
&& !(gBattleMons[battlerAtk].status2 & STATUS2_TRANSFORMED))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
}
break;
case ABILITY_ORICHALCUM_PULSE:
if (weather & B_WEATHER_SUN && WEATHER_HAS_EFFECT && IS_MOVE_PHYSICAL(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
break;
case ABILITY_HADRON_ENGINE:
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && IS_MOVE_SPECIAL(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
break;
case ABILITY_SHARPNESS:
if (gMovesInfo[move].slicingMove)
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
@ -9468,7 +9421,7 @@ static inline u32 CalcMoveBasePowerAfterModifiers(u32 move, u32 battlerAtk, u32
return uq4_12_multiply_by_int_half_down(modifier, basePower);
}
static inline u32 CalcAttackStat(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, bool32 isCrit, bool32 updateFlags, u32 atkAbility, u32 defAbility, u32 holdEffectAtk)
static inline u32 CalcAttackStat(u32 move, u32 battlerAtk, u32 battlerDef, u32 moveType, bool32 isCrit, bool32 updateFlags, u32 atkAbility, u32 defAbility, u32 holdEffectAtk, u32 weather)
{
u8 atkStage;
u32 atkStat;
@ -9608,6 +9561,57 @@ static inline u32 CalcAttackStat(u32 move, u32 battlerAtk, u32 battlerDef, u32 m
if (gBattleMons[battlerAtk].status1 & STATUS1_ANY && IS_MOVE_PHYSICAL(move))
modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5));
break;
case ABILITY_TRANSISTOR:
if (moveType == TYPE_ELECTRIC)
{
if (B_TRANSISTOR_BOOST >= GEN_9)
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
else
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
}
break;
case ABILITY_DRAGONS_MAW:
if (moveType == TYPE_DRAGON)
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_GORILLA_TACTICS:
if (IS_MOVE_PHYSICAL(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_ROCKY_PAYLOAD:
if (moveType == TYPE_ROCK)
modifier = uq4_12_multiply(modifier, UQ_4_12(1.5));
break;
case ABILITY_PROTOSYNTHESIS:
if (!(gBattleMons[battlerAtk].status2 & STATUS2_TRANSFORMED))
{
u32 atkHighestStat = GetHighestStatId(battlerAtk);
if (((weather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT) || gBattleStruct->boosterEnergyActivates & (1u << battlerAtk))
{
if ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
}
}
break;
case ABILITY_QUARK_DRIVE:
if (!(gBattleMons[battlerAtk].status2 & STATUS2_TRANSFORMED))
{
u32 atkHighestStat = GetHighestStatId(battlerAtk);
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN || gBattleStruct->boosterEnergyActivates & (1u << battlerAtk))
{
if ((IS_MOVE_PHYSICAL(move) && atkHighestStat == STAT_ATK) || (IS_MOVE_SPECIAL(move) && atkHighestStat == STAT_SPATK))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.3));
}
}
break;
case ABILITY_ORICHALCUM_PULSE:
if ((weather & B_WEATHER_SUN) && WEATHER_HAS_EFFECT && IS_MOVE_PHYSICAL(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.33));
break;
case ABILITY_HADRON_ENGINE:
if (gFieldStatuses & STATUS_FIELD_ELECTRIC_TERRAIN && IS_MOVE_SPECIAL(move))
modifier = uq4_12_multiply(modifier, UQ_4_12(1.33));
break;
}
// target's abilities
@ -10157,7 +10161,7 @@ static inline s32 DoMoveDamageCalcVars(u32 move, u32 battlerAtk, u32 battlerDef,
else
gBattleMovePower = CalcMoveBasePowerAfterModifiers(move, battlerAtk, battlerDef, moveType, updateFlags, abilityAtk, abilityDef, holdEffectAtk, weather);
userFinalAttack = CalcAttackStat(move, battlerAtk, battlerDef, moveType, isCrit, updateFlags, abilityAtk, abilityDef, holdEffectAtk);
userFinalAttack = CalcAttackStat(move, battlerAtk, battlerDef, moveType, isCrit, updateFlags, abilityAtk, abilityDef, holdEffectAtk, weather);
targetFinalDefense = CalcDefenseStat(move, battlerAtk, battlerDef, moveType, isCrit, updateFlags, abilityAtk, abilityDef, holdEffectDef, weather);
dmg = CalculateBaseDamage(gBattleMovePower, userFinalAttack, gBattleMons[battlerAtk].level, targetFinalDefense);

View file

@ -1,6 +1,9 @@
#include "global.h"
#include "test/battle.h"
#include "global.h"
#include "test/battle.h"
SINGLE_BATTLE_TEST("Transistor increases Electric-type move damage", s16 damage)
{
u32 move;
@ -27,12 +30,37 @@ SINGLE_BATTLE_TEST("Transistor increases Electric-type move damage", s16 damage)
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_EQ(results[0].damage, results[1].damage); // Tackle should be unaffected
#if B_TRANSISTOR_BOOST >= GEN_9
EXPECT_MUL_EQ(results[2].damage, Q_4_12(5325 / 4096), results[3].damage); // Wild Charge should be affected
EXPECT_MUL_EQ(results[4].damage, Q_4_12(5325 / 4096), results[5].damage); // Thunder Shock should be affected
#else
EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.5), results[3].damage); // Wild Charge should be affected
EXPECT_MUL_EQ(results[4].damage, Q_4_12(1.5), results[5].damage); // Thunder Shock should be affected
#endif
if (B_TRANSISTOR_BOOST >= GEN_9)
{
EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.3), results[3].damage); // Wild Charge should be affected
EXPECT_MUL_EQ(results[4].damage, Q_4_12(1.3), results[5].damage); // Thunder Shock should be affected
}
else
{
EXPECT_MUL_EQ(results[2].damage, Q_4_12(1.5), results[3].damage); // Wild Charge should be affected
EXPECT_MUL_EQ(results[4].damage, Q_4_12(1.5), results[5].damage); // Thunder Shock should be affected
}
}
}
SINGLE_BATTLE_TEST("Transistor boosts Electric type moves by 1.5 in Gen8 and 1.3 in Gen9+", s16 damage)
{
u16 ability;
PARAMETRIZE { ability = ABILITY_NEUTRALIZING_GAS; }
PARAMETRIZE { ability = ABILITY_LEVITATE; }
GIVEN {
ASSUME(gMovesInfo[MOVE_THUNDER_SHOCK].type == TYPE_ELECTRIC);
PLAYER(SPECIES_REGIELEKI) { Ability(ABILITY_TRANSISTOR); }
OPPONENT(SPECIES_KOFFING) { Ability(ability); }
} WHEN {
TURN { MOVE(player, MOVE_THUNDER_SHOCK); }
} SCENE {
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
if (B_TRANSISTOR_BOOST >= GEN_9)
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.3), results[1].damage);
else
EXPECT_MUL_EQ(results[0].damage, Q_4_12(1.5), results[1].damage);
}
}