diff --git a/include/random.h b/include/random.h index af3d7c75e5..4500d77403 100644 --- a/include/random.h +++ b/include/random.h @@ -93,6 +93,7 @@ enum RandomTag RNG_TRIPLE_ARROWS_DEFENSE_DOWN, RNG_TRIPLE_ARROWS_FLINCH, RNG_QUICK_DRAW, + RNG_TRACE, }; #define RandomWeighted(tag, ...) \ diff --git a/src/battle_util.c b/src/battle_util.c index bdce8fbc9d..0a89e7e70e 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -5955,7 +5955,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 { if (!sAbilitiesNotTraced[gBattleMons[target1].ability] && gBattleMons[target1].hp != 0 && !sAbilitiesNotTraced[gBattleMons[target2].ability] && gBattleMons[target2].hp != 0) - chosenTarget = GetBattlerAtPosition(((Random() & 1) * 2) | side), effect++; + chosenTarget = GetBattlerAtPosition((RandomPercentage(RNG_TRACE, 50) * 2) | side), effect++; else if (!sAbilitiesNotTraced[gBattleMons[target1].ability] && gBattleMons[target1].hp != 0) chosenTarget = target1, effect++; else if (!sAbilitiesNotTraced[gBattleMons[target2].ability] && gBattleMons[target2].hp != 0) @@ -5969,15 +5969,7 @@ u32 AbilityBattleEffects(u32 caseID, u32 battler, u32 ability, u32 special, u32 if (effect != 0) { - if (caseID == ABILITYEFFECT_TRACE1) - { - BattleScriptPushCursorAndCallback(BattleScript_TraceActivatesEnd3); - } - else - { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_TraceActivates; - } + BattleScriptPushCursorAndCallback(BattleScript_TraceActivatesEnd3); gBattleResources->flags->flags[i] &= ~RESOURCE_FLAG_TRACED; gBattleStruct->tracedAbility[i] = gLastUsedAbility = gBattleMons[chosenTarget].ability; RecordAbilityBattle(chosenTarget, gLastUsedAbility); // Record the opposing battler has this ability diff --git a/test/battle/ability/trace.c b/test/battle/ability/trace.c new file mode 100644 index 0000000000..0e4448424b --- /dev/null +++ b/test/battle/ability/trace.c @@ -0,0 +1,82 @@ +#include "global.h" +#include "test/battle.h" + +SINGLE_BATTLE_TEST("Trace copies opponents ability") +{ + GIVEN { + PLAYER(SPECIES_RALTS) { Ability(ABILITY_TRACE); } + OPPONENT(SPECIES_TORCHIC) { Ability(ABILITY_BLAZE); } + } WHEN { + TURN { } + } SCENE { + ABILITY_POPUP(player, ABILITY_TRACE); + MESSAGE("Ralts TRACED Foe Torchic's Blaze!"); + } +} + +SINGLE_BATTLE_TEST("Trace copies opponents ability on switch-in") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) + PLAYER(SPECIES_RALTS) { Ability(ABILITY_TRACE); } + OPPONENT(SPECIES_TORCHIC) { Ability(ABILITY_BLAZE); } + } WHEN { + TURN { SWITCH(player, 1); } + } SCENE { + ABILITY_POPUP(player, ABILITY_TRACE); + MESSAGE("Ralts TRACED Foe Torchic's Blaze!"); + } +} + +SINGLE_BATTLE_TEST("Trace copies opponents ability on switch-in even if opponent switched in at the same time") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) + PLAYER(SPECIES_RALTS) { Ability(ABILITY_TRACE); } + OPPONENT(SPECIES_TREECKO) { HP(1); } + OPPONENT(SPECIES_TORCHIC) { Ability(ABILITY_BLAZE); } + } WHEN { + TURN { MOVE(player, MOVE_MISTY_EXPLOSION); SEND_OUT(opponent, 1); SEND_OUT(player, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_MISTY_EXPLOSION); + ABILITY_POPUP(player, ABILITY_TRACE); + MESSAGE("Ralts TRACED Foe Torchic's Blaze!"); + } +} + +DOUBLE_BATTLE_TEST("Trace copies opponents ability randomly") +{ + u16 ability1, ability2; + + PARAMETRIZE { ability1 = ABILITY_SPEED_BOOST; ability2 = ABILITY_BLAZE;} + PARAMETRIZE { ability1 = ABILITY_BLAZE; ability2 = ABILITY_SPEED_BOOST; } + + PASSES_RANDOMLY(1, 2, RNG_TRACE); + GIVEN { + PLAYER(SPECIES_RALTS) { Ability(ABILITY_TRACE); } + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_TORCHIC) { Ability(ability1); } + OPPONENT(SPECIES_TORCHIC) { Ability(ability2); } + } WHEN { + TURN { } + } SCENE { + ABILITY_POPUP(playerLeft, ABILITY_TRACE); + MESSAGE("Ralts TRACED Foe Torchic's Blaze!"); + } +} + +SINGLE_BATTLE_TEST("Trace will copy an opponent's ability whenever it has the chance but only once") +{ + GIVEN { + ASSUME(P_GEN_4_POKEMON == TRUE); + PLAYER(SPECIES_RALTS) { Ability(ABILITY_TRACE); } + OPPONENT(SPECIES_CHERRIM) { Ability(ABILITY_FLOWER_GIFT); } + OPPONENT(SPECIES_TORCHIC) { Ability(ABILITY_BLAZE); } + } WHEN { + TURN { SWITCH(opponent, 1); } + } SCENE { + // TURN 2 + ABILITY_POPUP(player, ABILITY_TRACE); + MESSAGE("Ralts TRACED Foe Torchic's Blaze!"); + } +}