diff --git a/include/battle_util.h b/include/battle_util.h index f198857994..9b3d8a4b5a 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -113,26 +113,23 @@ struct TypePower u16 effect; }; -enum +enum MoveSuccessOrder { CANCELLER_FLAGS, CANCELLER_STANCE_CHANGE_1, CANCELLER_SKY_DROP, CANCELLER_RECHARGE, - CANCELLER_ASLEEP, - CANCELLER_FROZEN, + CANCELLER_ASLEEP_OR_FROZEN, CANCELLER_OBEDIENCE, CANCELLER_TRUANT, CANCELLER_FLINCH, - CANCELLER_IN_LOVE, CANCELLER_DISABLED, - CANCELLER_HEAL_BLOCKED, - CANCELLER_GRAVITY, - CANCELLER_THROAT_CHOP, + CANCELLER_VOLATILE_BLOCKED, CANCELLER_TAUNTED, CANCELLER_IMPRISONED, CANCELLER_CONFUSED, CANCELLER_PARALYSED, + CANCELLER_INFATUATION, CANCELLER_BIDE, CANCELLER_THAW, CANCELLER_STANCE_CHANGE_2, @@ -148,7 +145,8 @@ enum CANCELLER_END, }; -enum { +enum Obedience +{ OBEYS, DISOBEYS_LOAFS, DISOBEYS_HITS_SELF, @@ -157,6 +155,13 @@ enum { DISOBEYS_RANDOM_MOVE, }; +enum MoveCanceller +{ + MOVE_STEP_SUCCESS, + MOVE_STEP_BREAK, + MOVE_STEP_REMOVES_STATUS, +}; + extern const struct TypePower gNaturalGiftTable[]; struct DamageContext @@ -241,7 +246,7 @@ bool32 IsAbilityAndRecord(u32 battler, u32 battlerAbility, u32 abilityToCheck); u32 DoEndTurnEffects(void); bool32 HandleFaintedMonActions(void); void TryClearRageAndFuryCutter(void); -u32 AtkCanceller_MoveSuccessOrder(void); +enum MoveCanceller AtkCanceller_MoveSuccessOrder(void); void SetAtkCancellerForCalledMove(void); bool32 HasNoMonsToSwitch(u32 battler, u8 partyIdBattlerOn1, u8 partyIdBattlerOn2); bool32 TryChangeBattleWeather(u32 battler, u32 battleWeatherId, bool32 viaAbility); diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 240ed0367b..7bc8d0664c 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1222,7 +1222,7 @@ static void Cmd_attackcanceler(void) gBattlescriptCurrInstr = BattleScript_MoveEnd; return; } - if (AtkCanceller_MoveSuccessOrder()) + if (AtkCanceller_MoveSuccessOrder() != MOVE_STEP_SUCCESS) return; if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_OFF diff --git a/src/battle_util.c b/src/battle_util.c index 1580e2addc..903f6ab3b9 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -58,7 +58,6 @@ match the ROM; this is also why sSoundMovesTable's declaration is in the middle functions instead of at the top of the file with the other declarations. */ -typedef void (*MoveSuccessOrderCancellers)(u32 *effect); static bool32 TryRemoveScreens(u32 battler); static bool32 IsUnnerveAbilityOnOpposingSide(u32 battler); static u32 GetFlingPowerFromItemId(u32 itemId); @@ -1885,35 +1884,38 @@ static inline bool32 TryActivatePowderStatus(u32 move) void SetAtkCancellerForCalledMove(void) { - gBattleStruct->atkCancellerTracker = CANCELLER_HEAL_BLOCKED; + gBattleStruct->atkCancellerTracker = CANCELLER_VOLATILE_BLOCKED; gBattleStruct->isAtkCancelerForCalledMove = TRUE; } -static void CancellerFlags(u32 *effect) +static enum MoveCanceller CancellerFlags(void) { gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_DESTINY_BOND; gStatuses3[gBattlerAttacker] &= ~STATUS3_GRUDGE; gStatuses4[gBattlerAttacker] &= ~STATUS4_GLAIVE_RUSH; + return MOVE_STEP_SUCCESS; } -static void CancellerStanceChangeOne(u32 *effect) +static enum MoveCanceller CancellerStanceChangeOne(void) { if (B_STANCE_CHANGE_FAIL < GEN_7 && TryFormChangeBeforeMove()) - *effect = 1; + return MOVE_STEP_BREAK; + return MOVE_STEP_SUCCESS; } -static void CancellerSkyDrop(u32 *effect) +static enum MoveCanceller CancellerSkyDrop(void) { // If Pokemon is being held in Sky Drop if (gStatuses3[gBattlerAttacker] & STATUS3_SKY_DROPPED) { gBattlescriptCurrInstr = BattleScript_MoveEnd; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerRecharge(u32 *effect) +static enum MoveCanceller CancellerRecharge(void) { if (gBattleMons[gBattlerAttacker].status2 & STATUS2_RECHARGE) { @@ -1922,11 +1924,12 @@ static void CancellerRecharge(u32 *effect) CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); gBattlescriptCurrInstr = BattleScript_MoveUsedMustRecharge; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerAsleep(u32 *effect) +static enum MoveCanceller CancellerAsleepOrFrozen(void) { if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP) { @@ -1937,7 +1940,7 @@ static void CancellerAsleep(u32 *effect) gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP_UPROAR; BattleScriptCall(BattleScript_MoveUsedWokeUp); - *effect = 2; + return MOVE_STEP_REMOVES_STATUS; } else { @@ -1958,7 +1961,7 @@ static void CancellerAsleep(u32 *effect) gProtectStructs[gBattlerAttacker].nonVolatileStatusImmobility = TRUE; gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 2; + return MOVE_STEP_REMOVES_STATUS; } } else @@ -1967,15 +1970,11 @@ static void CancellerAsleep(u32 *effect) gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE; gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WOKE_UP; BattleScriptCall(BattleScript_MoveUsedWokeUp); - *effect = 2; + return MOVE_STEP_REMOVES_STATUS; } } } -} - -static void CancellerFrozen(u32 *effect) -{ - if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE && !MoveThawsUser(gCurrentMove)) + else if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE && !MoveThawsUser(gCurrentMove)) { if (!RandomPercentage(RNG_FROZEN, 20)) { @@ -1989,19 +1988,22 @@ static void CancellerFrozen(u32 *effect) BattleScriptCall(BattleScript_MoveUsedUnfroze); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED; } - *effect = 2; + return MOVE_STEP_REMOVES_STATUS; } + return MOVE_STEP_SUCCESS; } -static void CancellerObedience(u32 *effect) +static enum MoveCanceller CancellerObedience(void) { - u32 obedienceResult = GetAttackerObedienceForAction(); - if (obedienceResult != OBEYS - && !(gHitMarker & HITMARKER_NO_PPDEDUCT) // Don't check obedience after first hit of multi target move or multi hit moves - && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS)) + enum Obedience obedienceResult = GetAttackerObedienceForAction(); + if (!(gHitMarker & HITMARKER_NO_PPDEDUCT) // Don't check obedience after first hit of multi target move or multi hit moves + && !gBattleMons[gBattlerAttacker].volatiles.multipleTurns) { switch (obedienceResult) { + case OBEYS: + gHitMarker |= HITMARKER_OBEYS; + break; case DISOBEYS_LOAFS: // Randomly select, then print a disobedient string // B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE @@ -2042,15 +2044,13 @@ static void CancellerObedience(u32 *effect) gHitMarker |= HITMARKER_OBEYS; break; } - *effect = 1; - } - else - { - gHitMarker |= HITMARKER_OBEYS; + return MOVE_STEP_BREAK; } + gHitMarker |= HITMARKER_OBEYS; + return MOVE_STEP_SUCCESS; } -static void CancellerTruant(u32 *effect) +static enum MoveCanceller CancellerTruant(void) { if (GetBattlerAbility(gBattlerAttacker) == ABILITY_TRUANT && gDisableStructs[gBattlerAttacker].truantCounter) { @@ -2060,11 +2060,12 @@ static void CancellerTruant(u32 *effect) gBattlerAbility = gBattlerAttacker; gBattlescriptCurrInstr = BattleScript_TruantLoafingAround; gBattleStruct->moveResultFlags[gBattlerTarget] |= MOVE_RESULT_MISSED; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerFlinch(u32 *effect) +static enum MoveCanceller CancellerFlinch(void) { if (gBattleMons[gBattlerAttacker].status2 & STATUS2_FLINCHED) { @@ -2072,32 +2073,12 @@ static void CancellerFlinch(u32 *effect) CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); gBattlescriptCurrInstr = BattleScript_MoveUsedFlinched; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerInLove(u32 *effect) -{ - if (!gBattleStruct->isAtkCancelerForCalledMove && gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) - { - gBattleScripting.battler = CountTrailingZeroBits((gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) >> 0x10); - if (!RandomPercentage(RNG_INFATUATION, 50)) - { - BattleScriptCall(BattleScript_MoveUsedIsInLove); - } - else - { - BattleScriptPush(BattleScript_MoveUsedIsInLoveCantAttack); - gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE; - CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); - gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove; - } - *effect = 1; - } -} - -static void CancellerDisabled(u32 *effect) +static enum MoveCanceller CancellerDisabled(void) { if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].disabledMove == gCurrentMove && gDisableStructs[gBattlerAttacker].disabledMove != MOVE_NONE) { @@ -2106,11 +2087,12 @@ static void CancellerDisabled(u32 *effect) CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); gBattlescriptCurrInstr = BattleScript_MoveUsedIsDisabled; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerHealBlocked(u32 *effect) +static enum MoveCanceller CancellerVolatileBlocked(void) { if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gStatuses3[gBattlerAttacker] & STATUS3_HEAL_BLOCK && IsHealBlockPreventingMove(gBattlerAttacker, gCurrentMove)) { @@ -2119,36 +2101,29 @@ static void CancellerHealBlocked(u32 *effect) CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); gBattlescriptCurrInstr = BattleScript_MoveUsedHealBlockPrevents; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } -} - -static void CancellerGravity(u32 *effect) -{ - if (gFieldStatuses & STATUS_FIELD_GRAVITY && IsGravityPreventingMove(gCurrentMove)) + else if (gFieldStatuses & STATUS_FIELD_GRAVITY && IsGravityPreventingMove(gCurrentMove)) { gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE; gBattleScripting.battler = gBattlerAttacker; CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); gBattlescriptCurrInstr = BattleScript_MoveUsedGravityPrevents; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } -} - -static void CancellerThroatChop(u32 *effect) -{ - if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].throatChopTimer > gBattleTurnCounter && IsSoundMove(gCurrentMove)) + else if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].throatChopTimer > gBattleTurnCounter && IsSoundMove(gCurrentMove)) { gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE; CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); gBattlescriptCurrInstr = BattleScript_MoveUsedIsThroatChopPrevented; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerTaunted(u32 *effect) +static enum MoveCanceller CancellerTaunted(void) { if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && gDisableStructs[gBattlerAttacker].tauntTimer && IsBattleMoveStatus(gCurrentMove)) { @@ -2156,11 +2131,12 @@ static void CancellerTaunted(u32 *effect) CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); gBattlescriptCurrInstr = BattleScript_MoveUsedIsTaunted; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerImprisoned(u32 *effect) +static enum MoveCanceller CancellerImprisoned(void) { if (GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE && GetImprisonedMovesCount(gBattlerAttacker, gCurrentMove)) { @@ -2168,14 +2144,15 @@ static void CancellerImprisoned(u32 *effect) CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); gBattlescriptCurrInstr = BattleScript_MoveUsedIsImprisoned; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerConfused(u32 *effect) +static enum MoveCanceller CancellerConfused(void) { if (gBattleStruct->isAtkCancelerForCalledMove) - return; + return MOVE_STEP_SUCCESS; if (gBattleMons[gBattlerAttacker].status2 & STATUS2_CONFUSION) { @@ -2211,11 +2188,12 @@ static void CancellerConfused(u32 *effect) { BattleScriptCall(BattleScript_MoveUsedIsConfusedNoMore); } - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerParalysed(u32 *effect) +static enum MoveCanceller CancellerParalysed(void) { if (!gBattleStruct->isAtkCancelerForCalledMove && (gBattleMons[gBattlerAttacker].status1 & STATUS1_PARALYSIS) @@ -2227,11 +2205,34 @@ static void CancellerParalysed(u32 *effect) //CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); gBattlescriptCurrInstr = BattleScript_MoveUsedIsParalyzed; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerBide(u32 *effect) +static enum MoveCanceller CancellerInfatuation(void) +{ + if (!gBattleStruct->isAtkCancelerForCalledMove && gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) + { + gBattleScripting.battler = CountTrailingZeroBits((gBattleMons[gBattlerAttacker].status2 & STATUS2_INFATUATION) >> 0x10); + if (!RandomPercentage(RNG_INFATUATION, 50)) + { + BattleScriptCall(BattleScript_MoveUsedIsInLove); + } + else + { + BattleScriptPush(BattleScript_MoveUsedIsInLoveCantAttack); + gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; + gProtectStructs[gBattlerAttacker].unableToUseMove = TRUE; + CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); + gBattlescriptCurrInstr = BattleScript_MoveUsedIsInLove; + } + return MOVE_STEP_BREAK; + } + return MOVE_STEP_SUCCESS; +} + +static enum MoveCanceller CancellerBide(void) { if (gBattleMons[gBattlerAttacker].status2 & STATUS2_BIDE) { @@ -2257,11 +2258,12 @@ static void CancellerBide(u32 *effect) gBattlescriptCurrInstr = BattleScript_BideNoEnergyToAttack; } } - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerThaw(u32 *effect) +static enum MoveCanceller CancellerThaw(void) { if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE) { @@ -2271,7 +2273,7 @@ static void CancellerThaw(u32 *effect) BattleScriptCall(BattleScript_MoveUsedUnfroze); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_DEFROSTED_BY_MOVE; } - *effect = 2; + return MOVE_STEP_REMOVES_STATUS; } if (gBattleMons[gBattlerAttacker].status1 & STATUS1_FROSTBITE && MoveThawsUser(gCurrentMove)) { @@ -2281,32 +2283,35 @@ static void CancellerThaw(u32 *effect) BattleScriptCall(BattleScript_MoveUsedUnfrostbite); gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_FROSTBITE_HEALED_BY_MOVE; } - *effect = 2; + return MOVE_STEP_REMOVES_STATUS; } + return MOVE_STEP_SUCCESS; } -static void CancellerStanceChangeTwo(u32 *effect) +static enum MoveCanceller CancellerStanceChangeTwo(void) { if (B_STANCE_CHANGE_FAIL >= GEN_7 && !gBattleStruct->isAtkCancelerForCalledMove && TryFormChangeBeforeMove()) - *effect = 1; + return MOVE_STEP_BREAK; + return MOVE_STEP_SUCCESS; } -static void CancellerWeatherPrimal(u32 *effect) +static enum MoveCanceller CancellerWeatherPrimal(void) { + enum MoveCanceller effect = MOVE_STEP_SUCCESS; if (HasWeatherEffect() && GetMovePower(gCurrentMove) > 0) { u32 moveType = GetBattleMoveType(gCurrentMove); if (moveType == TYPE_FIRE && (gBattleWeather & B_WEATHER_RAIN_PRIMAL) && (B_POWDER_RAIN >= GEN_7 || !TryActivatePowderStatus(gCurrentMove))) { gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_FIZZLED_BY_RAIN; - *effect = 1; + effect = MOVE_STEP_BREAK; } else if (moveType == TYPE_WATER && (gBattleWeather & B_WEATHER_SUN_PRIMAL)) { gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_PRIMAL_WEATHER_EVAPORATED_IN_SUN; - *effect = 1; + effect = MOVE_STEP_BREAK; } - if (*effect == 1) + if (effect == MOVE_STEP_BREAK) { gBattleScripting.moveEffect = MOVE_EFFECT_NONE; gProtectStructs[gBattlerAttacker].chargingTurn = FALSE; @@ -2315,19 +2320,21 @@ static void CancellerWeatherPrimal(u32 *effect) BattleScriptCall(BattleScript_PrimalWeatherBlocksMove); } } + return effect; } -static void CancellerDynamaxBlocked(u32 *effect) +static enum MoveCanceller CancellerDynamaxBlocked(void) { if ((GetActiveGimmick(gBattlerTarget) == GIMMICK_DYNAMAX) && IsMoveBlockedByDynamax(gCurrentMove)) { gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; BattleScriptCall(BattleScript_MoveBlockedByDynamax); - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerPowderStatus(u32 *effect) +static enum MoveCanceller CancellerPowderStatus(void) { if (TryActivatePowderStatus(gCurrentMove)) { @@ -2339,11 +2346,12 @@ static void CancellerPowderStatus(u32 *effect) || HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE)) gBattlescriptCurrInstr = BattleScript_MoveUsedPowder; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerProtean(u32 *effect) +static enum MoveCanceller CancellerProtean(void) { u32 moveType = GetBattleMoveType(gCurrentMove); if (ProteanTryChangeType(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker), gCurrentMove, moveType)) @@ -2355,11 +2363,12 @@ static void CancellerProtean(u32 *effect) PrepareStringBattle(STRINGID_EMPTYSTRING3, gBattlerAttacker); gBattleCommunication[MSG_DISPLAY] = 1; BattleScriptCall(BattleScript_ProteanActivates); - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerPsychicTerrain(u32 *effect) +static enum MoveCanceller CancellerPsychicTerrain(void) { if (gFieldStatuses & STATUS_FIELD_PSYCHIC_TERRAIN && IsBattlerGrounded(gBattlerTarget) @@ -2371,11 +2380,12 @@ static void CancellerPsychicTerrain(u32 *effect) CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK); gBattlescriptCurrInstr = BattleScript_MoveUsedPsychicTerrainPrevents; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerExplodingDamp(u32 *effect) +static enum MoveCanceller CancellerExplodingDamp(void) { u32 dampBattler = IsAbilityOnField(ABILITY_DAMP); if (dampBattler && IsMoveDampBanned(gCurrentMove)) @@ -2383,11 +2393,12 @@ static void CancellerExplodingDamp(u32 *effect) gBattleScripting.battler = dampBattler - 1; gBattlescriptCurrInstr = BattleScript_DampStopsExplosion; gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE; - *effect = 1; + return MOVE_STEP_BREAK; } + return MOVE_STEP_SUCCESS; } -static void CancellerMultihitMoves(u32 *effect) +static enum MoveCanceller CancellerMultihitMoves(void) { if (GetMoveEffect(gCurrentMove) == EFFECT_MULTI_HIT) { @@ -2450,9 +2461,11 @@ static void CancellerMultihitMoves(u32 *effect) { gMultiHitCounter = 0; } + + return MOVE_STEP_SUCCESS; } -static void CancellerZMoves(u32 *effect) +static enum MoveCanceller CancellerZMoves(void) { if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE) { @@ -2479,11 +2492,12 @@ static void CancellerZMoves(u32 *effect) if (!alreadyUsed) BattleScriptCall(BattleScript_ZMoveActivateDamaging); } - *effect = 1; + return MOVE_STEP_BREAK; // The original move is cancelled, not the z move } + return MOVE_STEP_SUCCESS; } -static void CancellerMultiTargetMoves(u32 *effect) +static enum MoveCanceller CancellerMultiTargetMoves(void) { u32 moveTarget = GetBattlerMoveTargetType(gBattlerAttacker, gCurrentMove); u32 abilityAtk = GetBattlerAbility(gBattlerAttacker); @@ -2526,24 +2540,22 @@ static void CancellerMultiTargetMoves(u32 *effect) else gBattleStruct->numSpreadTargets = CountAliveMonsInBattle(BATTLE_ALIVE_EXCEPT_BATTLER, gBattlerAttacker); } + return MOVE_STEP_SUCCESS; } -static const MoveSuccessOrderCancellers sMoveSuccessOrderCancellers[] = +static enum MoveCanceller (*const sMoveSuccessOrderCancellers[])(void) = { [CANCELLER_FLAGS] = CancellerFlags, [CANCELLER_STANCE_CHANGE_1] = CancellerStanceChangeOne, [CANCELLER_SKY_DROP] = CancellerSkyDrop, [CANCELLER_RECHARGE] = CancellerRecharge, - [CANCELLER_ASLEEP] = CancellerAsleep, - [CANCELLER_FROZEN] = CancellerFrozen, + [CANCELLER_ASLEEP_OR_FROZEN] = CancellerAsleepOrFrozen, [CANCELLER_OBEDIENCE] = CancellerObedience, [CANCELLER_TRUANT] = CancellerTruant, [CANCELLER_FLINCH] = CancellerFlinch, - [CANCELLER_IN_LOVE] = CancellerInLove, + [CANCELLER_INFATUATION] = CancellerInfatuation, [CANCELLER_DISABLED] = CancellerDisabled, - [CANCELLER_HEAL_BLOCKED] = CancellerHealBlocked, - [CANCELLER_GRAVITY] = CancellerGravity, - [CANCELLER_THROAT_CHOP] = CancellerThroatChop, + [CANCELLER_VOLATILE_BLOCKED] = CancellerVolatileBlocked, [CANCELLER_TAUNTED] = CancellerTaunted, [CANCELLER_IMPRISONED] = CancellerImprisoned, [CANCELLER_CONFUSED] = CancellerConfused, @@ -2562,17 +2574,17 @@ static const MoveSuccessOrderCancellers sMoveSuccessOrderCancellers[] = [CANCELLER_MULTI_TARGET_MOVES] = CancellerMultiTargetMoves, }; -u32 AtkCanceller_MoveSuccessOrder(void) +enum MoveCanceller AtkCanceller_MoveSuccessOrder(void) { - u32 effect = 0; + enum MoveCanceller effect = MOVE_STEP_SUCCESS; - while (gBattleStruct->atkCancellerTracker < CANCELLER_END && effect == 0) + while (gBattleStruct->atkCancellerTracker < CANCELLER_END && effect == MOVE_STEP_SUCCESS) { - sMoveSuccessOrderCancellers[gBattleStruct->atkCancellerTracker](&effect); + effect = sMoveSuccessOrderCancellers[gBattleStruct->atkCancellerTracker](); gBattleStruct->atkCancellerTracker++; } - if (effect == 2) + if (effect == MOVE_STEP_REMOVES_STATUS) { BtlController_EmitSetMonData(gBattlerAttacker, B_COMM_TO_CONTROLLER, REQUEST_STATUS_BATTLE, 0, 4, &gBattleMons[gBattlerAttacker].status1); MarkBattlerForControllerExec(gBattlerAttacker);