diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index a4f13be0b9..c6d6075ad5 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -3202,7 +3202,7 @@ BattleScript_StatDownEnd:: BattleScript_MirrorArmorReflect:: pause B_WAIT_TIME_SHORT call BattleScript_AbilityPopUp - jumpifsubstituteblocks BattleScript_AbilityNoSpecificStatLoss + jumpifstatus2 BS_ATTACKER, STATUS2_SUBSTITUTE, BattleScript_MirrorArmorDoesntAffect BattleScript_MirrorArmorReflectStatLoss: statbuffchange MOVE_EFFECT_AFFECTS_USER | STAT_CHANGE_MIRROR_ARMOR | STAT_CHANGE_NOT_PROTECT_AFFECTED | STAT_CHANGE_ALLOW_PTR, BattleScript_MirrorArmorReflectEnd jumpifbyte CMP_LESS_THAN, cMULTISTRING_CHOOSER, B_MSG_STAT_WONT_DECREASE, BattleScript_MirrorArmorReflectAnim @@ -3216,6 +3216,13 @@ BattleScript_MirrorArmorReflectPrintString: BattleScript_MirrorArmorReflectEnd: return +BattleScript_MirrorArmorDoesntAffect: + swapattackerwithtarget + printstring STRINGID_ITDOESNTAFFECT + waitmessage B_WAIT_TIME_LONG + swapattackerwithtarget + return + BattleScript_MirrorArmorReflectWontFall: copybyte gBattlerTarget, gBattlerAttacker @ STRINGID_STATSWONTDECREASE uses target goto BattleScript_MirrorArmorReflectPrintString diff --git a/include/battle.h b/include/battle.h index 1189ada4ea..185e565ed2 100644 --- a/include/battle.h +++ b/include/battle.h @@ -228,13 +228,11 @@ struct SpecialStatus // End of byte u8 dancerUsedMove:1; u8 dancerOriginalTarget:3; - u8 preventLifeOrbDamage:1; // So that Life Orb doesn't activate various effects. u8 distortedTypeMatchups:1; u8 teraShellAbilityDone:1; u8 criticalHit:1; - // End of byte u8 enduredDamage:1; - u8 padding:7; + // End of byte }; struct SideTimer diff --git a/include/battle_util.h b/include/battle_util.h index 5fef1b4f60..e4a54990c0 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -351,5 +351,6 @@ bool32 HasWeatherEffect(void); bool32 IsMovePowderBlocked(u32 battlerAtk, u32 battlerDef, u32 move); bool32 EmergencyExitCanBeTriggered(u32 battler); u32 RestoreWhiteHerbStats(u32 battler); +bool32 IsFutureSightAttackerInParty(u32 battlerAtk, u32 battlerDef); #endif // GUARD_BATTLE_UTIL_H diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 225646ee29..c812df97c8 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -7064,7 +7064,6 @@ static void Cmd_moveend(void) gEffectBattler = gBattlerTarget; BattleScriptPushCursor(); gBattlescriptCurrInstr = BattleScript_MagicianActivates; - gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = TRUE; effect = TRUE; } gBattleScripting.moveendState++; @@ -7404,7 +7403,6 @@ static void Cmd_moveend(void) gBattleStruct->ateBoost[gBattlerAttacker] = FALSE; gStatuses3[gBattlerAttacker] &= ~STATUS3_ME_FIRST; gSpecialStatuses[gBattlerAttacker].gemBoost = FALSE; - gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage = 0; gSpecialStatuses[gBattlerTarget].berryReduced = FALSE; gSpecialStatuses[gBattlerTarget].distortedTypeMatchups = FALSE; gBattleScripting.moveEffect = 0; diff --git a/src/battle_util.c b/src/battle_util.c index d9e64c969c..0093550a47 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -2930,8 +2930,6 @@ bool32 HandleWishPerishSongOnTurnEnd(void) if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter && !(gAbsentBattlerFlags & (1u << battler))) { - struct Pokemon *party; - if (gWishFutureKnock.futureSightCounter[battler] == gBattleTurnCounter && gWishFutureKnock.futureSightCounter[BATTLE_PARTNER(battler)] <= gBattleTurnCounter) { @@ -2952,8 +2950,7 @@ bool32 HandleWishPerishSongOnTurnEnd(void) gBattlerAttacker = gWishFutureKnock.futureSightBattlerIndex[battler]; gCurrentMove = gWishFutureKnock.futureSightMove[battler]; - party = GetSideParty(GetBattlerSide(gBattlerAttacker)); - if (&party[gWishFutureKnock.futureSightPartyIndex[gBattlerTarget]] == &party[gBattlerPartyIndexes[gBattlerAttacker]]) + if (!IsFutureSightAttackerInParty(gBattlerAttacker, gBattlerTarget)) SetTypeBeforeUsingMove(gCurrentMove, gBattlerAttacker); BattleScriptExecute(BattleScript_MonTookFutureAttack); @@ -5879,12 +5876,9 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 && IsBattlerAlive(gBattlerAttacker)) { // Prevent Innards Out effect if Future Sight user is currently not on field - if (GetMoveEffect(gCurrentMove) == EFFECT_FUTURE_SIGHT) - { - if (gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] != gBattlerPartyIndexes[gBattlerAttacker] - && gWishFutureKnock.futureSightPartyIndex[gBattlerTarget] != BATTLE_PARTNER(gBattlerPartyIndexes[gBattlerAttacker])) - break; - } + if (GetMoveEffect(gCurrentMove) == EFFECT_FUTURE_SIGHT + && IsFutureSightAttackerInParty(gBattlerAttacker, gBattlerTarget)) + break; gBattleScripting.battler = gBattlerTarget; gBattleStruct->moveDamage[gBattlerAttacker] = gBattleStruct->moveDamage[gBattlerTarget]; @@ -8202,7 +8196,7 @@ u32 ItemBattleEffects(enum ItemCaseId caseID, u32 battler, bool32 moveTurn) && !(TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)) && GetBattlerAbility(gBattlerAttacker) != ABILITY_MAGIC_GUARD && !gProtectStructs[gBattlerAttacker].confusionSelfDmg - && !gSpecialStatuses[gBattlerAttacker].preventLifeOrbDamage) + && !IsFutureSightAttackerInParty(gBattlerAttacker, gBattlerTarget)) { gBattleStruct->moveDamage[gBattlerAttacker] = GetNonDynamaxMaxHP(gBattlerAttacker) / 10; if (gBattleStruct->moveDamage[gBattlerAttacker] == 0) @@ -10510,8 +10504,6 @@ static inline s32 DoFutureSightAttackDamageCalcVars(struct DamageCalculationData if (dmg == 0) dmg = 1; - gSpecialStatuses[battlerAtk].preventLifeOrbDamage = TRUE; - return dmg; } @@ -10538,14 +10530,11 @@ static u32 GetWeather(void) return gBattleWeather; } -static inline bool32 IsFutureSightAttackerInParty(struct DamageCalculationData *damageCalcData) +bool32 IsFutureSightAttackerInParty(u32 battlerAtk, u32 battlerDef) { - if (GetMoveEffect(damageCalcData->move) != EFFECT_FUTURE_SIGHT) - return FALSE; - - struct Pokemon *party = GetSideParty(GetBattlerSide(damageCalcData->battlerAtk)); - return &party[gWishFutureKnock.futureSightPartyIndex[damageCalcData->battlerDef]] - != &party[gBattlerPartyIndexes[damageCalcData->battlerAtk]]; + struct Pokemon *party = GetSideParty(GetBattlerSide(battlerAtk)); + return &party[gWishFutureKnock.futureSightPartyIndex[battlerDef]] != &party[gBattlerPartyIndexes[battlerAtk]] + && &party[gWishFutureKnock.futureSightPartyIndex[battlerDef]] != &party[BATTLE_PARTNER(gBattlerPartyIndexes[battlerAtk])]; } s32 CalculateMoveDamage(struct DamageCalculationData *damageCalcData, u32 fixedBasePower) @@ -10557,7 +10546,8 @@ s32 CalculateMoveDamage(struct DamageCalculationData *damageCalcData, u32 fixedB GetBattlerAbility(damageCalcData->battlerDef), damageCalcData->updateFlags); - if (IsFutureSightAttackerInParty(damageCalcData)) + if (GetMoveEffect(damageCalcData->move) == EFFECT_FUTURE_SIGHT + && IsFutureSightAttackerInParty(damageCalcData->battlerAtk, damageCalcData->battlerDef)) return DoFutureSightAttackDamageCalc(damageCalcData, typeEffectivenessMultiplier, GetWeather()); return DoMoveDamageCalc(damageCalcData, fixedBasePower, typeEffectivenessMultiplier, GetWeather()); diff --git a/test/battle/ability/magician.c b/test/battle/ability/magician.c index f622ac07df..d12fe920b8 100644 --- a/test/battle/ability/magician.c +++ b/test/battle/ability/magician.c @@ -1,7 +1,7 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Magician does not get self-damage recoil after stealing Life Orb") +SINGLE_BATTLE_TEST("Magician gets self-damage recoil after stealing Life Orb") { GIVEN { ASSUME(gItemsInfo[ITEM_LIFE_ORB].holdEffect == HOLD_EFFECT_LIFE_ORB); @@ -16,10 +16,8 @@ SINGLE_BATTLE_TEST("Magician does not get self-damage recoil after stealing Life MESSAGE("Delphox used Tackle!"); ABILITY_POPUP(player, ABILITY_MAGICIAN); MESSAGE("Delphox stole the opposing Wobbuffet's Life Orb!"); - NONE_OF { - HP_BAR(player); - MESSAGE("Delphox was hurt by the Life Orb!"); - } + HP_BAR(player); + MESSAGE("Delphox was hurt by the Life Orb!"); // 2nd turn - Life Orb recoil happens now MESSAGE("Delphox used Tackle!"); HP_BAR(player); diff --git a/test/battle/ability/mirror_armor.c b/test/battle/ability/mirror_armor.c index 0918682d76..97e7616c94 100644 --- a/test/battle/ability/mirror_armor.c +++ b/test/battle/ability/mirror_armor.c @@ -102,10 +102,8 @@ SINGLE_BATTLE_TEST("Mirror Armor lowers the Attack of Pokemon with Intimidate") } } -// Unsure whether this should or should not fail, as Showdown has conflicting information. Needs testing in gen8 games. SINGLE_BATTLE_TEST("Mirror Armor doesn't lower the stats of an attacking Pokemon behind Substitute") { - KNOWN_FAILING; GIVEN { PLAYER(SPECIES_CORVIKNIGHT) { Ability(ABILITY_MIRROR_ARMOR); } OPPONENT(SPECIES_WYNAUT);