diff --git a/src/battle_move_resolution.c b/src/battle_move_resolution.c index 48e17fce11..69a5d4bb22 100644 --- a/src/battle_move_resolution.c +++ b/src/battle_move_resolution.c @@ -2061,15 +2061,25 @@ static enum MoveEndResult MoveEndProtectLikeEffect(void) { enum MoveEndResult result = MOVEEND_RESULT_CONTINUE; u32 temp = 0; + enum Ability abilityAtk = GetBattlerAbility(gBattlerAttacker); + enum HoldEffect holdEffectAtk = GetBattlerHoldEffect(gBattlerAttacker); + enum ProtectMethod method = gProtectStructs[gBattlerTarget].protected; if (gProtectStructs[gBattlerAttacker].chargingTurn - || CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker), gCurrentMove)) + || CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, abilityAtk, holdEffectAtk, gCurrentMove)) + { + gBattleScripting.moveendState++; + return result; + } + + if (method != PROTECT_MAX_GUARD + && abilityAtk == ABILITY_UNSEEN_FIST + && IsMoveMakingContact(gBattlerAttacker, gBattlerTarget, abilityAtk, holdEffectAtk, gCurrentMove)) { gBattleScripting.moveendState++; return result; } - enum ProtectMethod method = gProtectStructs[gBattlerTarget].protected; switch (method) { case PROTECT_SPIKY_SHIELD: diff --git a/test/battle/ability/unseen_fist.c b/test/battle/ability/unseen_fist.c index da5880c042..d72ade2c50 100644 --- a/test/battle/ability/unseen_fist.c +++ b/test/battle/ability/unseen_fist.c @@ -5,6 +5,12 @@ ASSUMPTIONS { ASSUME(MoveMakesContact(MOVE_SCRATCH)); ASSUME(GetMoveEffect(MOVE_PROTECT) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_KINGS_SHIELD) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_SPIKY_SHIELD) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_BANEFUL_BUNKER) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_BURNING_BULWARK) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_OBSTRUCT) == EFFECT_PROTECT); + ASSUME(GetMoveEffect(MOVE_SILK_TRAP) == EFFECT_PROTECT); } TO_DO_BATTLE_TEST("TODO: Write Unseen Fist (Ability) test titles") @@ -33,3 +39,38 @@ SINGLE_BATTLE_TEST("Unseen Fist ignores Protect when user has Protective Pads, b NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_MACH_PUNCH, player); } } + +SINGLE_BATTLE_TEST("Unseen Fist bypasses protect effects without triggering their contact effects") +{ + enum Move protectMove = MOVE_NONE; + u8 loweredStat = 0; + + PARAMETRIZE { protectMove = MOVE_SPIKY_SHIELD; loweredStat = 0; } + PARAMETRIZE { protectMove = MOVE_KINGS_SHIELD; loweredStat = STAT_ATK; } + PARAMETRIZE { protectMove = MOVE_BANEFUL_BUNKER; loweredStat = 0; } + PARAMETRIZE { protectMove = MOVE_BURNING_BULWARK; loweredStat = 0; } + PARAMETRIZE { protectMove = MOVE_OBSTRUCT; loweredStat = STAT_DEF; } + PARAMETRIZE { protectMove = MOVE_SILK_TRAP; loweredStat = STAT_SPEED; } + + GIVEN { + PLAYER(SPECIES_URSHIFU) { Ability(ABILITY_UNSEEN_FIST); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, protectMove); MOVE(player, MOVE_SCRATCH); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, protectMove, opponent); + ANIMATION(ANIM_TYPE_MOVE, MOVE_SCRATCH, player); + HP_BAR(opponent); + NONE_OF { + HP_BAR(player); + STATUS_ICON(player, STATUS1_POISON); + STATUS_ICON(player, STATUS1_BURN); + ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player); + } + } THEN { + EXPECT_EQ(player->hp, player->maxHP); + EXPECT_EQ(player->status1, STATUS1_NONE); + if (loweredStat != 0) + EXPECT_EQ(player->statStages[loweredStat], DEFAULT_STAT_STAGE); + } +}