diff --git a/asm/macros/battle_script.inc b/asm/macros/battle_script.inc index c9c95515f0..118aebab8f 100644 --- a/asm/macros/battle_script.inc +++ b/asm/macros/battle_script.inc @@ -928,8 +928,9 @@ .4byte \failInstr .endm - .macro setdestinybond + .macro trysetdestinybond failInstr:req .byte 0xaa + .4byte \failInstr .endm .macro trysetdestinybondtohappen diff --git a/data/battle_scripts_1.s b/data/battle_scripts_1.s index 2c9bd46f52..c7d9a35bb7 100644 --- a/data/battle_scripts_1.s +++ b/data/battle_scripts_1.s @@ -4063,7 +4063,7 @@ BattleScript_EffectDestinyBond:: attackcanceler attackstring ppreduce - setdestinybond + trysetdestinybond BattleScript_ButItFailed attackanimation waitanimation printstring STRINGID_PKMNTRYINGTOTAKEFOE diff --git a/include/battle_util.h b/include/battle_util.h index 2b0192aa71..20a228eef6 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -331,5 +331,6 @@ void TryDeactivateSleepClause(u32 battlerSide, u32 indexInParty); bool32 IsSleepClauseActiveForSide(u32 battlerSide); bool32 IsSleepClauseEnabled(); void ClearDamageCalcResults(void); +u32 DoesDestinyBondFail(u32 battler); #endif // GUARD_BATTLE_UTIL_H diff --git a/include/config/battle.h b/include/config/battle.h index 861e3e3fad..781df413a0 100644 --- a/include/config/battle.h +++ b/include/config/battle.h @@ -125,6 +125,7 @@ #define B_POWDER_RAIN GEN_LATEST // In Gen7+, Powder doesn't damage the user of a Fire type move in heavy rain. #define B_AFTER_YOU_TURN_ORDER GEN_LATEST // In Gen8+, After You doesn't fail if the turn order wouldn't change after use. #define B_QUASH_TURN_ORDER GEN_LATEST // In Gen8+, Quash-affected battlers move according to speed order. Before Gen8, Quash-affected battlers move in the order they were affected by Quash. +#define B_DESTINY_BOND_FAIL GEN_LATEST // In Gen7+, Destiny Bond fails if used repeatedly. // Ability settings #define B_ABILITY_WEATHER GEN_LATEST // In Gen6+, ability-induced weather lasts 5 turns. Before, it lasted until the battle ended or until it was changed by a move or a different weather-affecting ability. diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index a7e462ff97..d988142beb 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -1875,6 +1875,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) ADJUST_SCORE(-10); break; case EFFECT_DESTINY_BOND: + if (DoesDestinyBondFail(battlerAtk)) + ADJUST_SCORE(-10); if (gBattleMons[battlerDef].status2 & STATUS2_DESTINY_BOND) ADJUST_SCORE(-10); else if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 469f9f7eb2..791ea1f68f 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -508,7 +508,7 @@ static void Cmd_settypetorandomresistance(void); static void Cmd_setalwayshitflag(void); static void Cmd_copymovepermanently(void); static void Cmd_trychoosesleeptalkmove(void); -static void Cmd_setdestinybond(void); +static void Cmd_trysetdestinybond(void); static void Cmd_trysetdestinybondtohappen(void); static void Cmd_settailwind(void); static void Cmd_tryspiteppreduce(void); @@ -767,7 +767,7 @@ void (* const gBattleScriptingCommandsTable[])(void) = Cmd_setalwayshitflag, //0xA7 Cmd_copymovepermanently, //0xA8 Cmd_trychoosesleeptalkmove, //0xA9 - Cmd_setdestinybond, //0xAA + Cmd_trysetdestinybond, //0xAA Cmd_trysetdestinybondtohappen, //0xAB Cmd_settailwind, //0xAC Cmd_tryspiteppreduce, //0xAD @@ -13446,12 +13446,18 @@ static void Cmd_trychoosesleeptalkmove(void) } } -static void Cmd_setdestinybond(void) +static void Cmd_trysetdestinybond(void) { - CMD_ARGS(); - - gBattleMons[gBattlerAttacker].status2 |= STATUS2_DESTINY_BOND; - gBattlescriptCurrInstr = cmd->nextInstr; + CMD_ARGS(const u8 *failInstr); + if (DoesDestinyBondFail(gBattlerAttacker)) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + gBattleMons[gBattlerAttacker].status2 |= STATUS2_DESTINY_BOND; + gBattlescriptCurrInstr = cmd->nextInstr; + } } static void TrySetDestinyBondToHappen(void) diff --git a/src/battle_util.c b/src/battle_util.c index c00598eb14..aa2f36882c 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -12010,3 +12010,12 @@ void ClearDamageCalcResults(void) gBattleStruct->printedStrongWindsWeakenedAttack = FALSE; gBattleStruct->numSpreadTargets = 0; } + +bool32 DoesDestinyBondFail(u32 battler) +{ + if (B_DESTINY_BOND_FAIL >= GEN_7 + && gMovesInfo[gLastResultingMoves[battler]].effect == EFFECT_DESTINY_BOND + && !(gBattleStruct->lastMoveFailed & (1u << battler))) + return TRUE; + return FALSE; +} diff --git a/test/battle/move_effect/destiny_bond.c b/test/battle/move_effect/destiny_bond.c index ba49e0ec43..7291fe7fb3 100644 --- a/test/battle/move_effect/destiny_bond.c +++ b/test/battle/move_effect/destiny_bond.c @@ -1,6 +1,11 @@ #include "global.h" #include "test/battle.h" +ASSUMPTIONS +{ + ASSUME(gMovesInfo[MOVE_DESTINY_BOND].effect == EFFECT_DESTINY_BOND); +} + SINGLE_BATTLE_TEST("Destiny Bond faints the opposing mon if it fainted from the attack") { GIVEN { @@ -15,3 +20,60 @@ SINGLE_BATTLE_TEST("Destiny Bond faints the opposing mon if it fainted from the MESSAGE("The opposing Wobbuffet fainted!"); } } + +SINGLE_BATTLE_TEST("Destiny Bond fails if used sequentially in Gen 7+") +{ + GIVEN { + ASSUME(B_DESTINY_BOND_FAIL >= GEN_7); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_DESTINY_BOND); } + TURN { MOVE(player, MOVE_DESTINY_BOND); SWITCH(opponent, 1); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player); + MESSAGE("2 sent out Zigzagoon!"); + NOT { ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player); } + MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Destiny Bond does not fail if used repeatedly separated by other moves in Gen 7+") +{ + GIVEN { + ASSUME(B_DESTINY_BOND_FAIL >= GEN_7); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_DESTINY_BOND); } + TURN { MOVE(player, MOVE_GROWL); SWITCH(opponent, 1); } + TURN { MOVE(player, MOVE_DESTINY_BOND); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player); + MESSAGE("2 sent out Zigzagoon!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player); + NOT { MESSAGE("But it failed!"); } + } +} + +SINGLE_BATTLE_TEST("Destiny Bond does not fail if used after failing in Gen 7+") +{ + GIVEN { + ASSUME(B_DESTINY_BOND_FAIL >= GEN_7); + PLAYER(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + OPPONENT(SPECIES_ZIGZAGOON); + } WHEN { + TURN { MOVE(player, MOVE_DESTINY_BOND); } + TURN { MOVE(player, MOVE_DESTINY_BOND); SWITCH(opponent, 1); } + TURN { MOVE(player, MOVE_DESTINY_BOND); } + } SCENE { + ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player); + MESSAGE("2 sent out Zigzagoon!"); + NOT { ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player); } + MESSAGE("But it failed!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_DESTINY_BOND, player); + } +}