Gen. 9 Move Effects, 2nd batch (#2870)

This commit is contained in:
Eduardo Quezada D'Ottone 2023-06-19 14:00:03 -04:00 committed by GitHub
commit 0d86ab0945
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 357 additions and 19 deletions

View File

@ -430,6 +430,32 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectRevivalBlessing @ EFFECT_REVIVAL_BLESSING
.4byte BattleScript_EffectFrostbiteHit @ EFFECT_FROSTBITE_HIT
.4byte BattleScript_EffectSnow @ EFFECT_SNOWSCAPE
.4byte BattleScript_EffectTripleArrows @ EFFECT_TRIPLE_ARROWS
.4byte BattleScript_EffectInfernalParade @ EFFECT_INFERNAL_PARADE
.4byte BattleScript_EffectTakeHeart @ EFFECT_TAKE_HEART
.4byte BattleScript_EffectAxeKick @ EFFECT_AXE_KICK
BattleScript_EffectAxeKick::
setmoveeffect MOVE_EFFECT_CONFUSION
goto BattleScript_EffectRecoilIfMiss
BattleScript_EffectTakeHeart::
attackcanceler
attackstring
ppreduce
cureifburnedparalysedorpoisoned BattleScript_CalmMindTryToRaiseStats
attackanimation
waitanimation
updatestatusicon BS_ATTACKER
printstring STRINGID_PKMNSTATUSNORMAL
waitmessage B_WAIT_TIME_LONG
jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPATK, MAX_STAT_STAGE, BattleScript_CalmMindStatRaise
jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPDEF, MAX_STAT_STAGE, BattleScript_CalmMindStatRaise
goto BattleScript_CantRaiseMultipleStats
BattleScript_EffectTripleArrows::
setmoveeffect MOVE_EFFECT_TRIPLE_ARROWS
goto BattleScript_EffectHit
BattleScript_EffectRevivalBlessing::
attackcanceler
@ -1482,6 +1508,11 @@ BattleScript_DoubleShockRemoveType::
waitmessage B_WAIT_TIME_LONG
return
BattleScript_DefDown::
modifybattlerstatstage BS_TARGET, STAT_DEF, DECREASE, 1, BattleScript_DefDown_Ret, ANIM_ON
BattleScript_DefDown_Ret:
return
BattleScript_EffectPurify:
attackcanceler
attackstring
@ -3476,6 +3507,7 @@ BattleScript_AbsorbHealBlock::
tryfaintmon BS_TARGET
goto BattleScript_MoveEnd
BattleScript_EffectInfernalParade::
BattleScript_EffectBurnHit::
setmoveeffect MOVE_EFFECT_BURN
goto BattleScript_EffectHit
@ -6344,11 +6376,13 @@ BattleScript_EffectCalmMind::
attackcanceler
attackstring
ppreduce
BattleScript_CalmMindTryToRaiseStats::
jumpifstat BS_ATTACKER, CMP_LESS_THAN, STAT_SPATK, MAX_STAT_STAGE, BattleScript_CalmMindDoMoveAnim
jumpifstat BS_ATTACKER, CMP_EQUAL, STAT_SPDEF, MAX_STAT_STAGE, BattleScript_CantRaiseMultipleStats
BattleScript_CalmMindDoMoveAnim::
attackanimation
waitanimation
BattleScript_CalmMindStatRaise::
setbyte sSTAT_ANIM_PLAYED, FALSE
playstatchangeanimation BS_ATTACKER, BIT_SPATK | BIT_SPDEF, 0
setstatchanger STAT_SPATK, 1, FALSE

View File

@ -470,6 +470,7 @@ extern const u8 BattleScript_StealthRockActivates[];
extern const u8 BattleScript_SpikesActivates[];
extern const u8 BattleScript_BerserkGeneRet[];
extern const u8 BattleScript_TargetFormChangeWithStringNoPopup[];
extern const u8 BattleScript_DefDown[];
// zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[];

View File

@ -236,5 +236,6 @@ bool8 ChangeTypeBasedOnTerrain(u8 battlerId);
void RemoveConfusionStatus(u8 battlerId);
u8 GetBattlerGender(u8 battlerId);
bool8 AreBattlersOfOppositeGender(u8 battler1, u8 battler2);
u32 CalcSecondaryEffectChance(u8 battlerId, u8 secondaryEffectChance);
#endif // GUARD_BATTLE_UTIL_H

View File

@ -384,8 +384,9 @@
#define MOVE_EFFECT_DIRE_CLAW 75
#define MOVE_EFFECT_STEALTH_ROCK 76
#define MOVE_EFFECT_SPIKES 77
#define MOVE_EFFECT_TRIPLE_ARROWS 78
#define NUM_MOVE_EFFECTS 78
#define NUM_MOVE_EFFECTS 79
#define MOVE_EFFECT_AFFECTS_USER 0x4000
#define MOVE_EFFECT_CERTAIN 0x8000

View File

@ -407,7 +407,11 @@
#define EFFECT_REVIVAL_BLESSING 401
#define EFFECT_FROSTBITE_HIT 402
#define EFFECT_SNOWSCAPE 403
#define EFFECT_TRIPLE_ARROWS 404
#define EFFECT_INFERNAL_PARADE 405
#define EFFECT_TAKE_HEART 406
#define EFFECT_AXE_KICK 407
#define NUM_BATTLE_MOVE_EFFECTS 404
#define NUM_BATTLE_MOVE_EFFECTS 408
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H

View File

@ -67,6 +67,8 @@ enum RandomTag
RNG_STATIC,
RNG_STENCH,
RNG_TRI_ATTACK,
RNG_TRIPLE_ARROWS_DEFENSE_DOWN,
RNG_TRIPLE_ARROWS_FLINCH,
};
#define RandomWeighted(tag, ...) \

View File

@ -2638,6 +2638,22 @@ static s16 AI_CheckBadMove(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
&& AI_WhoStrikesFirst(battlerAtk, battlerDef, move) == AI_IS_SLOWER)
score -= 10;
break;
case EFFECT_JUNGLE_HEALING:
if (AtMaxHp(battlerAtk)
&& AtMaxHp(BATTLE_PARTNER(battlerAtk))
&& !(gBattleMons[battlerAtk].status1 & STATUS1_ANY)
&& !(gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & STATUS1_ANY))
score -= 10;
break;
case EFFECT_TAKE_HEART:
if ((!(gBattleMons[battlerAtk].status1 & STATUS1_ANY)
|| PartnerMoveIs(BATTLE_PARTNER(battlerAtk), AI_DATA->partnerMove, MOVE_JUNGLE_HEALING)
|| PartnerMoveIs(BATTLE_PARTNER(battlerAtk), AI_DATA->partnerMove, MOVE_HEAL_BELL)
|| PartnerMoveIs(BATTLE_PARTNER(battlerAtk), AI_DATA->partnerMove, MOVE_AROMATHERAPY))
&& !BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPATK)
&& !BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPDEF))
score -= 10;
break;
case EFFECT_PLACEHOLDER:
return 0; // cannot even select
} // move effect checks
@ -3772,7 +3788,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_WISH:
case EFFECT_HEAL_BELL:
if (ShouldUseWishAromatherapy(battlerAtk, battlerDef, move))
score += 7;
score += 3;
break;
case EFFECT_THIEF:
{
@ -4424,6 +4440,12 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
if (gBattleMons[battlerAtk].status1 & STATUS1_ANY)
score += 2;
break;
case EFFECT_TAKE_HEART:
if (gBattleMons[battlerAtk].status1 & STATUS1_ANY
|| BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPATK)
|| BattlerStatCanRise(battlerAtk, AI_DATA->abilities[battlerAtk], STAT_SPDEF))
score += 2;
break;
case EFFECT_PSYCHO_SHIFT:
if (gBattleMons[battlerAtk].status1 & STATUS1_PSN_ANY)
IncreasePoisonScore(battlerAtk, battlerDef, move, &score);
@ -4871,6 +4893,13 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
//break;
//case EFFECT_SKY_DROP
//break;
case EFFECT_JUNGLE_HEALING:
if (ShouldRecover(battlerAtk, battlerDef, move, 25)
|| ShouldRecover(BATTLE_PARTNER(battlerAtk), battlerDef, move, 25)
|| gBattleMons[battlerAtk].status1 & STATUS1_ANY
|| gBattleMons[BATTLE_PARTNER(battlerAtk)].status1 & STATUS1_ANY)
score += 3;
break;
} // move effect checks
return score;

View File

@ -2051,6 +2051,7 @@ bool32 IsHealingMoveEffect(u16 effect)
case EFFECT_HEALING_WISH:
case EFFECT_HEAL_PULSE:
case EFFECT_REST:
case EFFECT_JUNGLE_HEALING:
return TRUE;
default:
return FALSE;

View File

@ -4770,6 +4770,7 @@ s8 GetMovePriority(u32 battlerId, u16 move)
case EFFECT_SOFTBOILED:
case EFFECT_ABSORB:
case EFFECT_ROOST:
case EFFECT_JUNGLE_HEALING:
priority += 3;
break;
}

View File

@ -3862,6 +3862,25 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattlescriptCurrInstr = BattleScript_SpikesActivates;
}
break;
case MOVE_EFFECT_TRIPLE_ARROWS:
{
u8 randomLowerDefenseChance = RandomPercentage(RNG_TRIPLE_ARROWS_DEFENSE_DOWN, CalcSecondaryEffectChance(gBattlerAttacker, 50));
u8 randomFlinchChance = RandomPercentage(RNG_TRIPLE_ARROWS_FLINCH, CalcSecondaryEffectChance(gBattlerAttacker, 30));
if (randomFlinchChance && battlerAbility != ABILITY_INNER_FOCUS && GetBattlerTurnOrderNum(gEffectBattler) > gCurrentTurnActionNumber)
gBattleMons[gEffectBattler].status2 |= sStatusFlagsForMoveEffects[MOVE_EFFECT_FLINCH];
if (randomLowerDefenseChance)
{
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_DefDown;
}
else
{
gBattlescriptCurrInstr++;
}
}
break;
}
}
}
@ -3873,12 +3892,7 @@ static void Cmd_seteffectwithchance(void)
{
CMD_ARGS();
u32 percentChance;
if (GetBattlerAbility(gBattlerAttacker) == ABILITY_SERENE_GRACE)
percentChance = gBattleMoves[gCurrentMove].secondaryEffectChance * 2;
else
percentChance = gBattleMoves[gCurrentMove].secondaryEffectChance;
u32 percentChance = CalcSecondaryEffectChance(gBattlerAttacker, gBattleMoves[gCurrentMove].secondaryEffectChance);
if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT)
&& gBattleScripting.moveEffect)

View File

@ -8537,6 +8537,7 @@ static u16 CalcMoveBasePower(u16 move, u8 battlerAtk, u8 battlerDef)
basePower = 120 * gBattleMons[battlerDef].hp / gBattleMons[battlerDef].maxHP;
break;
case EFFECT_HEX:
case EFFECT_INFERNAL_PARADE:
if (gBattleMons[battlerDef].status1 & STATUS1_ANY || GetBattlerAbility(battlerDef) == ABILITY_COMATOSE)
basePower *= 2;
break;
@ -10928,3 +10929,11 @@ bool8 AreBattlersOfOppositeGender(u8 battler1, u8 battler2)
return (gender1 != MON_GENDERLESS && gender2 != MON_GENDERLESS && gender1 != gender2);
}
u32 CalcSecondaryEffectChance(u8 battlerId, u8 secondaryEffectChance)
{
if (GetBattlerAbility(battlerId) == ABILITY_SERENE_GRACE)
secondaryEffectChance *= 2;
return secondaryEffectChance;
}

View File

@ -12753,29 +12753,30 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
{
#if B_UPDATED_MOVE_DATA >= GEN_9
.power = 90,
.pp = 10,
#else
.power = 50,
.pp = 15,
#endif
.effect = EFFECT_PLACEHOLDER, // EFFECT_TRIPLE_ARROWS,
.effect = EFFECT_TRIPLE_ARROWS,
.type = TYPE_FIGHTING,
.accuracy = 100,
.pp = 15,
.secondaryEffectChance = 100,
.secondaryEffectChance = 100, // 50% Defense down, 30% Flinch. Can be modified in 'SetMoveEffect'
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST,
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_HIGH_CRIT,
.split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE,
},
[MOVE_INFERNAL_PARADE] =
{
.effect = EFFECT_PLACEHOLDER, // EFFECT_INFERNAL_PARADE,
.effect = EFFECT_INFERNAL_PARADE,
.power = 60,
.type = TYPE_GHOST,
.accuracy = 100,
.pp = 15,
.secondaryEffectChance = 0,
.secondaryEffectChance = 30,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST,
@ -12861,7 +12862,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_LUNAR_BLESSING] =
{
.effect = EFFECT_PLACEHOLDER, // EFFECT_LUNAR_BLESSING,
.effect = EFFECT_JUNGLE_HEALING,
.power = 0,
.type = TYPE_PSYCHIC,
.accuracy = 0,
@ -12876,7 +12877,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_TAKE_HEART] =
{
.effect = EFFECT_PLACEHOLDER, // EFFECT_TAKE_HEART,
.effect = EFFECT_TAKE_HEART,
.power = 0,
.type = TYPE_PSYCHIC,
.accuracy = 0,
@ -12921,12 +12922,12 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_Z] =
[MOVE_AXE_KICK] =
{
.effect = EFFECT_PLACEHOLDER, // EFFECT_RECOIL_IF_MISS + 30% chance to confuse
.effect = EFFECT_AXE_KICK,
.power = 120,
.type = TYPE_FIGHTING,
.accuracy = 90,
.pp = 10,
.secondaryEffectChance = 0,
.secondaryEffectChance = 30,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST,

View File

@ -0,0 +1,54 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_AXE_KICK].effect == EFFECT_AXE_KICK);
}
SINGLE_BATTLE_TEST("Axe Kick confuses the target")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_AXE_KICK); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_AXE_KICK, player);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_CONFUSION, opponent);
MESSAGE("Foe Wobbuffet became confused!");
}
}
SINGLE_BATTLE_TEST("Axe Kick deals damage half the hp to user if def battler protected")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(opponent, MOVE_PROTECT); MOVE(player, MOVE_AXE_KICK); }
} SCENE {
s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
ANIMATION(ANIM_TYPE_MOVE, MOVE_PROTECT, opponent);
MESSAGE("Foe Wobbuffet protected itself!");
MESSAGE("Foe Wobbuffet protected itself!");
MESSAGE("Wobbuffet kept going and crashed!");
HP_BAR(player, hp: maxHP / 2);
}
}
SINGLE_BATTLE_TEST("Axe Kick deals damage half the hp to user if it fails")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_AXE_KICK, hit: FALSE); }
} SCENE {
s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
MESSAGE("Wobbuffet used Axe Kick!");
MESSAGE("Wobbuffet's attack missed!");
MESSAGE("Wobbuffet kept going and crashed!");
HP_BAR(player, hp: maxHP / 2);
}
}

View File

@ -0,0 +1,48 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_INFERNAL_PARADE].effect == EFFECT_INFERNAL_PARADE);
}
SINGLE_BATTLE_TEST("Infernal Parade inflicts poison")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_INFERNAL_PARADE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_INFERNAL_PARADE, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_BRN, opponent);
STATUS_ICON(opponent, burn: TRUE);
}
}
SINGLE_BATTLE_TEST("Infernal Parade's power doubles if the target has a status condition", s16 damage)
{
u32 status1;
PARAMETRIZE { status1 = STATUS1_NONE; }
PARAMETRIZE { status1 = STATUS1_SLEEP; }
PARAMETRIZE { status1 = STATUS1_POISON; }
PARAMETRIZE { status1 = STATUS1_BURN; }
PARAMETRIZE { status1 = STATUS1_FREEZE; }
PARAMETRIZE { status1 = STATUS1_PARALYSIS; }
PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) { Status1(status1); };
} WHEN {
TURN { MOVE(player, MOVE_INFERNAL_PARADE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_INFERNAL_PARADE, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
} THEN {
if (i > 0)
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[i].damage);
if (i > 1)
EXPECT_EQ(results[i-1].damage, results[i].damage);
}
}

View File

@ -0,0 +1,47 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_TAKE_HEART].effect == EFFECT_TAKE_HEART);
}
SINGLE_BATTLE_TEST("Take Heart increases Sp. Atk and Sp. Def by one stage")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_TAKE_HEART); }
} SCENE {
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
}
}
SINGLE_BATTLE_TEST("Take Heart cures the user of all status conditions")
{
u32 status1;
PARAMETRIZE { status1 = STATUS1_SLEEP; }
PARAMETRIZE { status1 = STATUS1_POISON; }
PARAMETRIZE { status1 = STATUS1_FREEZE; }
PARAMETRIZE { status1 = STATUS1_BURN; }
PARAMETRIZE { status1 = STATUS1_PARALYSIS; }
PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Status1(status1); };
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_TAKE_HEART); }
} SCENE {
if (status1 == STATUS1_SLEEP) {
MESSAGE("Wobbuffet is fast asleep.");
} else if (status1 == STATUS1_FREEZE) {
PASSES_RANDOMLY(20, 100, RNG_FROZEN);
STATUS_ICON(player, none: TRUE);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
} else {
MESSAGE("Wobbuffet's status returned to normal!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
}
}
}

View File

@ -0,0 +1,91 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_TRIPLE_ARROWS].effect == EFFECT_TRIPLE_ARROWS);
}
SINGLE_BATTLE_TEST("Triple Arrows may lower Defense by one stage")
{
u32 ability;
u32 chance;
PARAMETRIZE { ability = ABILITY_HUSTLE; chance = 50; }
PARAMETRIZE { ability = ABILITY_SERENE_GRACE; chance = 100; }
PASSES_RANDOMLY(chance, 100, RNG_TRIPLE_ARROWS_DEFENSE_DOWN);
GIVEN {
PLAYER(SPECIES_TOGEPI) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_TRIPLE_ARROWS); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRIPLE_ARROWS, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
MESSAGE("Foe Wobbuffet's Defense fell!");
}
}
SINGLE_BATTLE_TEST("Triple Arrows makes the foe flinch 30% of the time")
{
u32 ability;
u32 chance;
PARAMETRIZE { ability = ABILITY_HUSTLE; chance = 30; }
PARAMETRIZE { ability = ABILITY_SERENE_GRACE; chance = 60; }
PASSES_RANDOMLY(chance, 100, RNG_TRIPLE_ARROWS_FLINCH);
GIVEN {
PLAYER(SPECIES_TOGEPI) { Ability(ability); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_TRIPLE_ARROWS); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRIPLE_ARROWS, player);
MESSAGE("Foe Wobbuffet flinched!");
}
}
SINGLE_BATTLE_TEST("Triple Arrows lands a critical hit")
{
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gBattleMoves[MOVE_TRIPLE_ARROWS].flags & FLAG_HIGH_CRIT);
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_TRIPLE_ARROWS); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRIPLE_ARROWS, player);
MESSAGE("A critical hit!");
}
}
SINGLE_BATTLE_TEST("Triple Arrows can lower Defense and cause flinch at the time")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_TRIPLE_ARROWS); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRIPLE_ARROWS, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
MESSAGE("Foe Wobbuffet's Defense fell!");
MESSAGE("Foe Wobbuffet flinched!");
}
}
SINGLE_BATTLE_TEST("Triple Arrows's flinching is prevented by Inner Focus")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_RIOLU) { Ability(ABILITY_INNER_FOCUS); }
} WHEN {
TURN { MOVE(player, MOVE_TRIPLE_ARROWS);
MOVE(opponent, MOVE_TACKLE);
}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRIPLE_ARROWS, player);
NONE_OF { MESSAGE("Foe Wobbuffet flinched!"); }
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, opponent);
}
}