Skip to content

Commit

Permalink
Minor Canceller reorder / clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexOn1ine committed Dec 27, 2024
1 parent b0b1f44 commit 0ff2db4
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 111 deletions.
12 changes: 8 additions & 4 deletions include/battle_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ struct TypePower
enum
{
CANCELLER_FLAGS,
CANCELLER_STANCE_CHANGE_1,
CANCELLER_SKY_DROP,
CANCELLER_ASLEEP,
CANCELLER_FROZEN,
Expand All @@ -109,6 +110,7 @@ enum
CANCELLER_FLINCH,
CANCELLER_DISABLED,
CANCELLER_GRAVITY,
CANCELLER_THROAT_CHOP,
CANCELLER_HEAL_BLOCKED,
CANCELLER_TAUNTED,
CANCELLER_IMPRISONED,
Expand All @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down
59 changes: 0 additions & 59 deletions src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand All @@ -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
Expand All @@ -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;

Expand Down
147 changes: 100 additions & 47 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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))
{
Expand Down Expand Up @@ -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))
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand Down
1 change: 0 additions & 1 deletion test/battle/ability/stance_change.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)); }
Expand Down
1 change: 1 addition & 0 deletions test/battle/gimmick/dynamax.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit 0ff2db4

Please sign in to comment.