From 0ff2db4d6a7dcceb9661de489a066157fc82609e Mon Sep 17 00:00:00 2001 From: AlexOn1ine Date: Fri, 27 Dec 2024 10:47:08 +0100 Subject: [PATCH] Minor Canceller reorder / clean up --- include/battle_util.h | 12 ++- src/battle_script_commands.c | 59 ----------- src/battle_util.c | 147 +++++++++++++++++++--------- test/battle/ability/stance_change.c | 1 - test/battle/gimmick/dynamax.c | 1 + 5 files changed, 109 insertions(+), 111 deletions(-) diff --git a/include/battle_util.h b/include/battle_util.h index adeb850061eb..e7dc47bcb1b1 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -100,6 +100,7 @@ struct TypePower enum { CANCELLER_FLAGS, + CANCELLER_STANCE_CHANGE_1, CANCELLER_SKY_DROP, CANCELLER_ASLEEP, CANCELLER_FROZEN, @@ -109,6 +110,7 @@ enum CANCELLER_FLINCH, CANCELLER_DISABLED, CANCELLER_GRAVITY, + CANCELLER_THROAT_CHOP, CANCELLER_HEAL_BLOCKED, CANCELLER_TAUNTED, CANCELLER_IMPRISONED, @@ -117,16 +119,19 @@ enum CANCELLER_IN_LOVE, CANCELLER_BIDE, CANCELLER_THAW, + CANCELLER_STANCE_CHANGE_2, + CANCELLER_SET_MOVE_TYPE, + CANCELLER_WEATHER_PRIMAL, + CANCELLER_DYNAMAX_BLOCKED, + CANCELLER_PROTEAN, + CANCELLER_PSYCHIC_TERRAIN, CANCELLER_POWDER_MOVE, CANCELLER_POWDER_STATUS, - CANCELLER_THROAT_CHOP, CANCELLER_EXPLODING_DAMP, CANCELLER_MULTIHIT_MOVES, CANCELLER_Z_MOVES, CANCELLER_MULTI_TARGET_MOVES, CANCELLER_END, - CANCELLER_PSYCHIC_TERRAIN, - CANCELLER_END2, }; enum { @@ -199,7 +204,6 @@ bool32 HandleFaintedMonActions(void); void TryClearRageAndFuryCutter(void); u8 AtkCanceller_UnableToUseMove(u32 moveType); void SetAtkCancellerForCalledMove(void); -u8 AtkCanceller_UnableToUseMove2(void); bool32 HasNoMonsToSwitch(u32 battler, u8 r1, u8 r2); bool32 TryChangeBattleWeather(u32 battler, u32 weatherEnumId, bool32 viaAbility); u32 CanAbilityBlockMove(u32 battlerAtk, u32 battlerDef, u32 move, u32 abilityDef); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 76a59fa9dc32..ad77765db0c7 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1126,19 +1126,6 @@ static bool32 NoTargetPresent(u8 battler, u32 move) return FALSE; } -static bool32 TryFormChangeBeforeMove(void) -{ - bool32 result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE); - if (!result) - result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY); - if (!result) - return FALSE; - - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_AttackerFormChange; - return TRUE; -} - bool32 ProteanTryChangeType(u32 battler, u32 ability, u32 move, u32 moveType) { if ((ability == ABILITY_PROTEAN || ability == ABILITY_LIBERO) @@ -1187,14 +1174,6 @@ static void Cmd_attackcanceler(void) return; } - // Weight-based moves are blocked by Dynamax. - if ((GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) && IsMoveBlockedByDynamax(gCurrentMove)) - { - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_MoveBlockedByDynamax; - return; - } - if (gBattleOutcome != 0) { gCurrentActionFuncId = B_ACTION_FINISHED; @@ -1207,29 +1186,9 @@ static void Cmd_attackcanceler(void) gBattlescriptCurrInstr = BattleScript_MoveEnd; return; } - if (B_STANCE_CHANGE_FAIL < GEN_7 && TryFormChangeBeforeMove()) - return; if (AtkCanceller_UnableToUseMove(moveType)) return; - if (WEATHER_HAS_EFFECT && gMovesInfo[gCurrentMove].power) - { - if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove; - return; - } - else if (moveType == TYPE_WATER && (gBattleWeather & B_WEATHER_SUN_PRIMAL)) - { - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_EVAPORATED_IN_SUN; - BattleScriptPushCursor(); - gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove; - return; - } - } - if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_OFF && GetBattlerAbility(gBattlerAttacker) == ABILITY_PARENTAL_BOND && IsMoveAffectedByParentalBond(gCurrentMove, gBattlerAttacker) @@ -1242,22 +1201,6 @@ static void Cmd_attackcanceler(void) return; } - // Check Protean activation. - if (ProteanTryChangeType(gBattlerAttacker, attackerAbility, gCurrentMove, moveType)) - { - if (B_PROTEAN_LIBERO == GEN_9) - gDisableStructs[gBattlerAttacker].usedProteanLibero = TRUE; - PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType); - gBattlerAbility = gBattlerAttacker; - BattleScriptPushCursor(); - PrepareStringBattle(STRINGID_EMPTYSTRING3, gBattlerAttacker); - gBattleCommunication[MSG_DISPLAY] = 1; - gBattlescriptCurrInstr = BattleScript_ProteanActivates; - return; - } - - if (AtkCanceller_UnableToUseMove2()) - return; if (AbilityBattleEffects(ABILITYEFFECT_MOVES_BLOCK, gBattlerTarget, 0, 0, 0)) return; if (!gBattleMons[gBattlerAttacker].pp[gCurrMovePos] && gCurrentMove != MOVE_STRUGGLE @@ -1268,8 +1211,6 @@ static void Cmd_attackcanceler(void) gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; return; } - if (B_STANCE_CHANGE_FAIL >= GEN_7 && TryFormChangeBeforeMove()) - return; gHitMarker &= ~HITMARKER_ALLOW_NO_PP; diff --git a/src/battle_util.c b/src/battle_util.c index 900ebf2d6e10..34f33f39f6ba 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3116,6 +3116,19 @@ void TryClearRageAndFuryCutter(void) } } +static inline bool32 TryFormChangeBeforeMove(void) +{ + bool32 result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE); + if (!result) + result = TryBattleFormChange(gBattlerAttacker, FORM_CHANGE_BATTLE_BEFORE_MOVE_CATEGORY); + if (!result) + return FALSE; + + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_AttackerFormChange; + return TRUE; +} + void SetAtkCancellerForCalledMove(void) { gBattleStruct->atkCancellerTracker = CANCELLER_HEAL_BLOCKED; @@ -3136,6 +3149,11 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) gStatuses4[gBattlerAttacker] &= ~STATUS4_GLAIVE_RUSH; gBattleStruct->atkCancellerTracker++; break; + case CANCELLER_STANCE_CHANGE_1: + if (B_STANCE_CHANGE_FAIL < GEN_7 && TryFormChangeBeforeMove()) + effect = 1; + gBattleStruct->atkCancellerTracker++; + break; case CANCELLER_SKY_DROP: // If Pokemon is being held in Sky Drop if (gStatuses3[gBattlerAttacker] & STATUS3_SKY_DROPPED) @@ -3339,6 +3357,17 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) } gBattleStruct->atkCancellerTracker++; break; + case CANCELLER_THROAT_CHOP: + if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].throatChopTimer && gMovesInfo[gCurrentMove].soundMove) + { + gProtectStructs[gBattlerAttacker].usedThroatChopPreventedMove = TRUE; + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsThroatChopPrevented; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; case CANCELLER_TAUNTED: // taunt if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].tauntTimer && IS_MOVE_STATUS(gCurrentMove)) { @@ -3486,6 +3515,76 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) } gBattleStruct->atkCancellerTracker++; break; + case CANCELLER_STANCE_CHANGE_2: + if (B_STANCE_CHANGE_FAIL >= GEN_7 && TryFormChangeBeforeMove()) + effect = 1; + gBattleStruct->atkCancellerTracker++; + break; + case CANCELLER_SET_MOVE_TYPE: + gBattleStruct->atkCancellerTracker++; + break; + case CANCELLER_WEATHER_PRIMAL: + if (WEATHER_HAS_EFFECT && gMovesInfo[gCurrentMove].power) + { + if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN; + effect = 1; + } + else if (moveType == TYPE_WATER && (gBattleWeather & B_WEATHER_SUN_PRIMAL)) + { + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_EVAPORATED_IN_SUN; + effect = 1; + } + if (effect) + { + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_PrimalWeatherBlocksMove; + } + } + gBattleStruct->atkCancellerTracker++; + break; + case CANCELLER_DYNAMAX_BLOCKED: + if ((GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) && IsMoveBlockedByDynamax(gCurrentMove)) + { + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + BattleScriptPushCursor(); + gBattlescriptCurrInstr = BattleScript_MoveBlockedByDynamax; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case CANCELLER_PROTEAN: + if (ProteanTryChangeType(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), gCurrentMove, moveType)) + { + if (B_PROTEAN_LIBERO == GEN_9) + gDisableStructs[gBattlerAttacker].usedProteanLibero = TRUE; + PREPARE_TYPE_BUFFER(gBattleTextBuff1, moveType); + gBattlerAbility = gBattlerAttacker; + BattleScriptPushCursor(); + PrepareStringBattle(STRINGID_EMPTYSTRING3, gBattlerAttacker); + gBattleCommunication[MSG_DISPLAY] = 1; + gBattlescriptCurrInstr = BattleScript_ProteanActivates; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; + case CANCELLER_PSYCHIC_TERRAIN: + if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN + && IsBattlerGrounded(gBattlerTarget) + && GetChosenMovePriority(gBattlerAttacker) > 0 + && gMovesInfo[gCurrentMove].target != MOVE_TARGET_ALL_BATTLERS + && gMovesInfo[gCurrentMove].target != MOVE_TARGET_OPPONENTS_FIELD + && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) + { + CancelMultiTurnMoves(gBattlerAttacker); + gBattlescriptCurrInstr = BattleScript_MoveUsedPsychicTerrainPrevents; + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + effect = 1; + } + gBattleStruct->atkCancellerTracker++; + break; case CANCELLER_POWDER_MOVE: if ((gMovesInfo[gCurrentMove].powderMove) && (gBattlerAttacker != gBattlerTarget)) { @@ -3529,17 +3628,6 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) } gBattleStruct->atkCancellerTracker++; break; - case CANCELLER_THROAT_CHOP: - if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].throatChopTimer && gMovesInfo[gCurrentMove].soundMove) - { - gProtectStructs[gBattlerAttacker].usedThroatChopPreventedMove = TRUE; - CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsThroatChopPrevented; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; case CANCELLER_Z_MOVES: if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE) { @@ -3707,7 +3795,7 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) break; } - } while (gBattleStruct->atkCancellerTracker != CANCELLER_END && gBattleStruct->atkCancellerTracker != CANCELLER_END2 && effect == 0); + } while (gBattleStruct->atkCancellerTracker != CANCELLER_END && effect == 0); if (effect == 2) { @@ -3717,41 +3805,6 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType) return effect; } -// After Protean Activation. -u8 AtkCanceller_UnableToUseMove2(void) -{ - u8 effect = 0; - - do - { - switch (gBattleStruct->atkCancellerTracker) - { - case CANCELLER_END: - gBattleStruct->atkCancellerTracker++; - case CANCELLER_PSYCHIC_TERRAIN: - if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN - && IsBattlerGrounded(gBattlerTarget) - && GetChosenMovePriority(gBattlerAttacker) > 0 - && gMovesInfo[gCurrentMove].target != MOVE_TARGET_ALL_BATTLERS - && gMovesInfo[gCurrentMove].target != MOVE_TARGET_OPPONENTS_FIELD - && GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget)) - { - CancelMultiTurnMoves(gBattlerAttacker); - gBattlescriptCurrInstr = BattleScript_MoveUsedPsychicTerrainPrevents; - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - effect = 1; - } - gBattleStruct->atkCancellerTracker++; - break; - case CANCELLER_END2: - break; - } - - } while (gBattleStruct->atkCancellerTracker != CANCELLER_END2 && effect == 0); - - return effect; -} - bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2) { u32 i, side, playerId, flankId; diff --git a/test/battle/ability/stance_change.c b/test/battle/ability/stance_change.c index 8221e16385b4..f8a0c70b3e48 100644 --- a/test/battle/ability/stance_change.c +++ b/test/battle/ability/stance_change.c @@ -63,7 +63,6 @@ SINGLE_BATTLE_TEST("Stance Change changes Aegislash from Blade to Shield when us SINGLE_BATTLE_TEST("Stance Change doesn't change Aegislash to Shield if King's Shield is called by a different move - Sleep Talk") { - KNOWN_FAILING; // Currently does change form GIVEN { ASSUME(gMovesInfo[MOVE_SLEEP_TALK].effect == EFFECT_SLEEP_TALK); PLAYER(SPECIES_AEGISLASH_BLADE) { Moves(MOVE_KINGS_SHIELD, MOVE_SLEEP_TALK); Status1(STATUS1_SLEEP_TURN(3)); } diff --git a/test/battle/gimmick/dynamax.c b/test/battle/gimmick/dynamax.c index 97b099d0463c..d76febbd0a9f 100644 --- a/test/battle/gimmick/dynamax.c +++ b/test/battle/gimmick/dynamax.c @@ -1431,6 +1431,7 @@ DOUBLE_BATTLE_TEST("(DYNAMAX) G-Max One Blow bypasses Max Guard for full damage" } // Bug Testing +// This test will fail if it's the first test a thread runs DOUBLE_BATTLE_TEST("(DYNAMAX) Max Flare doesn't softlock the game when fainting player partner") { GIVEN {