diff --git a/include/battle_util.h b/include/battle_util.h index c88f4723dd..c91078db2b 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -166,7 +166,7 @@ struct DamageContext u32 randomFactor:1; u32 updateFlags:1; u32 isAnticipation:1; - u32 padding1:1; + u32 isSelfInflicted:1; u32 weather:16; u32 fixedBasePower:8; u32 padding2:8; diff --git a/src/battle_tv.c b/src/battle_tv.c index 6504a3cc43..2fc8fad7b7 100644 --- a/src/battle_tv.c +++ b/src/battle_tv.c @@ -1267,6 +1267,7 @@ static void TrySetBattleSeminarShow(void) ctx.isCrit = FALSE; ctx.randomFactor = FALSE; ctx.updateFlags = FALSE; + ctx.isSelfInflicted = FALSE; ctx.fixedBasePower = powerOverride; gBattleStruct->moveDamage[gBattlerTarget] = CalculateMoveDamage(&ctx); dmgByMove[i] = gBattleStruct->moveDamage[gBattlerTarget]; diff --git a/src/battle_util.c b/src/battle_util.c index d4fb0d38a6..f98b83d9a6 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2029,6 +2029,7 @@ static enum MoveCanceler CancelerObedience(void) ctx.isCrit = FALSE; ctx.randomFactor = FALSE; ctx.updateFlags = TRUE; + ctx.isSelfInflicted = TRUE; ctx.fixedBasePower = 40; gBattleStruct->moveDamage[gBattlerAttacker] = CalculateMoveDamage(&ctx); gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself; @@ -2181,6 +2182,7 @@ static enum MoveCanceler CancelerConfused(void) ctx.isCrit = FALSE; ctx.randomFactor = FALSE; ctx.updateFlags = TRUE; + ctx.isSelfInflicted = TRUE; ctx.fixedBasePower = 40; gBattleStruct->moveDamage[gBattlerAttacker] = CalculateMoveDamage(&ctx); gProtectStructs[gBattlerAttacker].confusionSelfDmg = TRUE; @@ -8499,6 +8501,24 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageContext *ctx) return uq4_12_multiply_by_int_half_down(modifier, basePower); } +static inline uq4_12_t ApplyOffensiveBadgeBoost(uq4_12_t modifier, u32 battler, u32 move) +{ + if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_ATTACK, battler) && IsBattleMovePhysical(move)) + modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier()); + if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPATK, battler) && IsBattleMoveSpecial(move)) + modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier()); + return modifier; +} + +static inline uq4_12_t ApplyDefensiveBadgeBoost(uq4_12_t modifier, u32 battler, u32 move) +{ + if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_DEFENSE, battler) && IsBattleMovePhysical(move)) + modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier()); + if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPDEF, battler) && IsBattleMoveSpecial(move)) + modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier()); + return modifier; +} + static inline u32 CalcAttackStat(struct DamageContext *ctx) { u8 atkStage; @@ -8570,6 +8590,9 @@ static inline u32 CalcAttackStat(struct DamageContext *ctx) // apply attack stat modifiers modifier = UQ_4_12(1.0); + if (ctx->isSelfInflicted) + return uq4_12_multiply_by_int_half_down(ApplyOffensiveBadgeBoost(modifier, battlerAtk, move), atkStat); + // attacker's abilities switch (ctx->abilityAtk) { @@ -8764,11 +8787,7 @@ static inline u32 CalcAttackStat(struct DamageContext *ctx) break; } - // The offensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the corresponding flags set (eg. Badges) - if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_ATTACK, battlerAtk) && IsBattleMovePhysical(move)) - modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier()); - if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPATK, battlerAtk) && IsBattleMoveSpecial(move)) - modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier()); + modifier = ApplyOffensiveBadgeBoost(modifier, battlerAtk, move); return uq4_12_multiply_by_int_half_down(modifier, atkStat); } @@ -8853,6 +8872,9 @@ static inline u32 CalcDefenseStat(struct DamageContext *ctx) // apply defense stat modifiers modifier = UQ_4_12(1.0); + if (ctx->isSelfInflicted) + return uq4_12_multiply_by_int_half_down(ApplyDefensiveBadgeBoost(modifier, battlerDef, move), defStat); + // target's abilities switch (ctx->abilityDef) { @@ -8942,11 +8964,7 @@ static inline u32 CalcDefenseStat(struct DamageContext *ctx) if (IS_BATTLER_OF_TYPE(battlerDef, TYPE_ICE) && IsBattlerWeatherAffected(battlerDef, B_WEATHER_SNOW) && usesDefStat) modifier = uq4_12_multiply_half_down(modifier, UQ_4_12(1.5)); - // The defensive stats of a Player's Pokémon are boosted by x1.1 (+10%) if they have the corresponding flags set (eg. Badges) - if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_DEFENSE, battlerDef) && IsBattleMovePhysical(move)) - modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier()); - if (ShouldGetStatBadgeBoost(B_FLAG_BADGE_BOOST_SPDEF, battlerDef) && IsBattleMoveSpecial(move)) - modifier = uq4_12_multiply_half_down(modifier, GetBadgeBoostModifier()); + modifier = ApplyDefensiveBadgeBoost(modifier, battlerDef, move); return uq4_12_multiply_by_int_half_down(modifier, defStat); } diff --git a/test/battle/ability/fur_coat.c b/test/battle/ability/fur_coat.c index 84b8549e42..2ad6a3d5a2 100644 --- a/test/battle/ability/fur_coat.c +++ b/test/battle/ability/fur_coat.c @@ -26,7 +26,6 @@ SINGLE_BATTLE_TEST("Fur Coat doubles Defense", s16 damage) SINGLE_BATTLE_TEST("Fur Coat has no effect on self-inflicted confusion damage", s16 damage) { - KNOWN_FAILING; u32 ability; PARAMETRIZE { ability = ABILITY_FUR_COAT; } PARAMETRIZE { ability = ABILITY_RATTLED; }