Clean up follow up for AtkCanceller refactor (#7951)

This commit is contained in:
Alex 2025-10-14 19:07:56 +02:00 committed by GitHub
parent 2daa8f3c88
commit 3ad78d0079
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 50 additions and 46 deletions

View File

@ -173,8 +173,9 @@ struct BattleContext
u32 battlerAtk:3;
u32 battlerDef:3;
u32 currentMove:16;
enum BattleMoveEffects moveEffect:10;
enum Ability ability[MAX_BATTLERS_COUNT];
u32 padding:10;
enum Ability abilities[MAX_BATTLERS_COUNT];
enum HoldEffect holdEffects[MAX_BATTLERS_COUNT];
};
enum SleepClauseBlock

View File

@ -1065,7 +1065,7 @@ bool32 IsMovePowderBlocked(struct BattleContext *ctx)
if (IsPowderMove(ctx->currentMove) && (ctx->battlerAtk != ctx->battlerDef))
{
if (GetGenConfig(GEN_CONFIG_POWDER_GRASS) >= GEN_6
&& (IS_BATTLER_OF_TYPE(ctx->battlerDef, TYPE_GRASS) || ctx->ability[ctx->battlerDef] == ABILITY_OVERCOAT))
&& (IS_BATTLER_OF_TYPE(ctx->battlerDef, TYPE_GRASS) || ctx->abilities[ctx->battlerDef] == ABILITY_OVERCOAT))
{
gBattlerAbility = ctx->battlerDef;
RecordAbilityBattle(ctx->battlerDef, ABILITY_OVERCOAT);
@ -1125,11 +1125,12 @@ static void Cmd_attackcanceler(void)
ctx.battlerAtk = gBattlerAttacker;
ctx.battlerDef = gBattlerTarget;
ctx.currentMove = gCurrentMove;
ctx.moveEffect = GetMoveEffect(ctx.currentMove);
enum BattleMoveEffects moveEffect = GetMoveEffect(ctx.currentMove);
if (!IsBattlerAlive(gBattlerAttacker)
&& ctx.moveEffect != EFFECT_EXPLOSION
&& ctx.moveEffect != EFFECT_MISTY_EXPLOSION)
&& moveEffect != EFFECT_EXPLOSION
&& moveEffect != EFFECT_MISTY_EXPLOSION)
{
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
gBattlescriptCurrInstr = BattleScript_MoveEnd;
@ -1137,14 +1138,14 @@ static void Cmd_attackcanceler(void)
}
// With how attackcanceller works right now we only need attacker and target abilities. Might change in the future
ctx.ability[ctx.battlerAtk] = GetBattlerAbility(ctx.battlerAtk);
ctx.ability[ctx.battlerDef] = GetBattlerAbility(ctx.battlerDef);
ctx.abilities[ctx.battlerAtk] = GetBattlerAbility(ctx.battlerAtk);
ctx.abilities[ctx.battlerDef] = GetBattlerAbility(ctx.battlerDef);
if (AtkCanceller_MoveSuccessOrder(&ctx) != MOVE_STEP_SUCCESS)
return;
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_OFF
&& ctx.ability[ctx.battlerAtk] == ABILITY_PARENTAL_BOND
&& ctx.abilities[ctx.battlerAtk] == ABILITY_PARENTAL_BOND
&& IsMoveAffectedByParentalBond(gCurrentMove, gBattlerAttacker)
&& !(gAbsentBattlerFlags & (1u << gBattlerTarget))
&& GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE)
@ -1158,8 +1159,8 @@ static void Cmd_attackcanceler(void)
if (CanAbilityBlockMove(
ctx.battlerAtk,
ctx.battlerDef,
ctx.ability[ctx.battlerAtk],
ctx.ability[ctx.battlerDef],
ctx.abilities[ctx.battlerAtk],
ctx.abilities[ctx.battlerDef],
ctx.currentMove,
RUN_SCRIPT))
return;
@ -1169,7 +1170,7 @@ static void Cmd_attackcanceler(void)
if (CanAbilityAbsorbMove(
ctx.battlerAtk,
ctx.battlerDef,
ctx.ability[ctx.battlerDef],
ctx.abilities[ctx.battlerDef],
ctx.currentMove,
GetBattleMoveType(ctx.currentMove),
RUN_SCRIPT))
@ -1181,17 +1182,17 @@ static void Cmd_attackcanceler(void)
// Check if no available target present on the field or if Sky Battles ban the move
if ((NoTargetPresent(gBattlerAttacker, gCurrentMove)
&& (!gBattleMoveEffects[ctx.moveEffect].twoTurnEffect || (gBattleMons[gBattlerAttacker].volatiles.multipleTurns)))
&& (!gBattleMoveEffects[moveEffect].twoTurnEffect || (gBattleMons[gBattlerAttacker].volatiles.multipleTurns)))
|| (IsMoveNotAllowedInSkyBattles(gCurrentMove)))
{
gBattleStruct->noTargetPresent = TRUE;
if (ctx.moveEffect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling.
if (moveEffect == EFFECT_FLING) // Edge case for removing a mon's item when there is no target available after using Fling.
gBattlescriptCurrInstr = BattleScript_FlingFailConsumeItem;
else
gBattlescriptCurrInstr = BattleScript_ButItFailed;
if (!gBattleMoveEffects[ctx.moveEffect].twoTurnEffect || (gBattleMons[gBattlerAttacker].volatiles.multipleTurns))
if (!gBattleMoveEffects[moveEffect].twoTurnEffect || (gBattleMons[gBattlerAttacker].volatiles.multipleTurns))
CancelMultiTurnMoves(gBattlerAttacker, SKY_DROP_ATTACKCANCELLER_CHECK);
return;
}
@ -1222,7 +1223,7 @@ static void Cmd_attackcanceler(void)
{
u32 battler = gBattlerTarget;
if (ctx.ability[ctx.battlerDef] == ABILITY_MAGIC_BOUNCE)
if (ctx.abilities[ctx.battlerDef] == ABILITY_MAGIC_BOUNCE)
{
battler = gBattlerTarget;
gBattleStruct->bouncedMoveIsUsed = TRUE;
@ -1273,11 +1274,11 @@ static void Cmd_attackcanceler(void)
BattleScriptCall(BattleScript_TookAttack);
}
else if (IsBattlerProtected(gBattlerAttacker, gBattlerTarget, gCurrentMove)
&& (ctx.moveEffect != EFFECT_CURSE || IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
&& (!gBattleMoveEffects[ctx.moveEffect].twoTurnEffect || (gBattleMons[gBattlerAttacker].volatiles.multipleTurns))
&& ctx.moveEffect != EFFECT_SUCKER_PUNCH
&& ctx.moveEffect != EFFECT_COUNTER
&& ctx.moveEffect != EFFECT_UPPER_HAND)
&& (moveEffect != EFFECT_CURSE || IS_BATTLER_OF_TYPE(gBattlerAttacker, TYPE_GHOST))
&& (!gBattleMoveEffects[moveEffect].twoTurnEffect || (gBattleMons[gBattlerAttacker].volatiles.multipleTurns))
&& moveEffect != EFFECT_SUCKER_PUNCH
&& moveEffect != EFFECT_COUNTER
&& moveEffect != EFFECT_UPPER_HAND)
{
if (!CanBattlerAvoidContactEffects(gBattlerAttacker, gBattlerTarget, GetBattlerAbility(gBattlerAttacker), GetBattlerHoldEffect(gBattlerAttacker), gCurrentMove))
gProtectStructs[gBattlerAttacker].touchedProtectLike = TRUE;

View File

@ -2010,7 +2010,7 @@ static enum MoveCanceller CancellerAsleepOrFrozen(struct BattleContext *ctx)
else
{
u8 toSub;
if (IsAbilityAndRecord(ctx->battlerAtk, ctx->ability[ctx->battlerAtk], ABILITY_EARLY_BIRD))
if (IsAbilityAndRecord(ctx->battlerAtk, ctx->abilities[ctx->battlerAtk], ABILITY_EARLY_BIRD))
toSub = 2;
else
toSub = 1;
@ -2018,9 +2018,11 @@ static enum MoveCanceller CancellerAsleepOrFrozen(struct BattleContext *ctx)
gBattleMons[ctx->battlerAtk].status1 &= ~STATUS1_SLEEP;
else
gBattleMons[ctx->battlerAtk].status1 -= toSub;
enum BattleMoveEffects moveEffect = GetMoveEffect(ctx->currentMove);
if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_SLEEP)
{
if (ctx->moveEffect != EFFECT_SNORE && ctx->moveEffect != EFFECT_SLEEP_TALK)
if (moveEffect != EFFECT_SNORE && moveEffect != EFFECT_SLEEP_TALK)
{
gProtectStructs[ctx->battlerAtk].nonVolatileStatusImmobility = TRUE;
gBattlescriptCurrInstr = BattleScript_MoveUsedIsAsleep;
@ -2273,7 +2275,7 @@ static enum MoveCanceller CancellerConfused(struct BattleContext *ctx)
static enum MoveCanceller CancellerParalysed(struct BattleContext *ctx)
{
if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_PARALYSIS
&& !(B_MAGIC_GUARD == GEN_4 && IsAbilityAndRecord(ctx->battlerAtk, ctx->ability[ctx->battlerAtk], ABILITY_MAGIC_GUARD))
&& !(B_MAGIC_GUARD == GEN_4 && IsAbilityAndRecord(ctx->battlerAtk, ctx->abilities[ctx->battlerAtk], ABILITY_MAGIC_GUARD))
&& !RandomPercentage(RNG_PARALYSIS, 75))
{
gProtectStructs[ctx->battlerAtk].nonVolatileStatusImmobility = TRUE;
@ -2366,7 +2368,7 @@ static enum MoveCanceller CancellerChoiceLock(struct BattleContext *ctx)
if (gChosenMove != MOVE_STRUGGLE
&& (*choicedMoveAtk == MOVE_NONE || *choicedMoveAtk == MOVE_UNAVAILABLE)
&& (IsHoldEffectChoice(holdEffect) || ctx->ability[ctx->battlerAtk] == ABILITY_GORILLA_TACTICS))
&& (IsHoldEffectChoice(holdEffect) || ctx->abilities[ctx->battlerAtk] == ABILITY_GORILLA_TACTICS))
*choicedMoveAtk = gChosenMove;
u32 moveIndex;
@ -2389,7 +2391,7 @@ static enum MoveCanceller CancellerCallSubmove(struct BattleContext *ctx)
const u8 *battleScript = NULL;
battleScript = BattleScript_SubmoveAttackstring;
switch(ctx->moveEffect)
switch(GetMoveEffect(ctx->currentMove))
{
case EFFECT_MIRROR_MOVE:
calledMove = GetMirrorMoveMove();
@ -2430,7 +2432,7 @@ static enum MoveCanceller CancellerCallSubmove(struct BattleContext *ctx)
{
if (GetActiveGimmick(ctx->battlerAtk) == GIMMICK_Z_MOVE && !IsBattleMoveStatus(calledMove))
calledMove = GetTypeBasedZMove(calledMove);
if (ctx->moveEffect == EFFECT_COPYCAT && IsMaxMove(calledMove))
if (GetMoveEffect(ctx->currentMove) == EFFECT_COPYCAT && IsMaxMove(calledMove))
calledMove = gBattleStruct->dynamax.lastUsedBaseMove;
gBattleStruct->submoveAnnouncement = SUBMOVE_SUCCESS;
@ -2509,7 +2511,7 @@ static enum MoveCanceller CancellerPPDeduction(struct BattleContext *ctx)
}
else if (moveTarget != MOVE_TARGET_OPPONENTS_FIELD)
{
if (ctx->battlerAtk != ctx->battlerDef && ctx->ability[ctx->battlerDef] == ABILITY_PRESSURE)
if (ctx->battlerAtk != ctx->battlerDef && ctx->abilities[ctx->battlerDef] == ABILITY_PRESSURE)
ppToDeduct++;
}
@ -2597,7 +2599,7 @@ static enum MoveCanceller CancellerMoveFailure(struct BattleContext *ctx)
{
const u8 *battleScript = NULL;
switch (ctx->moveEffect)
switch (GetMoveEffect(ctx->currentMove))
{
case EFFECT_FAIL_IF_NOT_ARG_TYPE:
if (!IS_BATTLER_OF_TYPE(ctx->battlerAtk, GetMoveArgType(ctx->currentMove)))
@ -2656,7 +2658,7 @@ static enum MoveCanceller CancellerMoveFailure(struct BattleContext *ctx)
case EFFECT_POLTERGEIST:
if (gBattleMons[ctx->battlerDef].item == ITEM_NONE
|| gFieldStatuses & STATUS_FIELD_MAGIC_ROOM
|| ctx->ability[ctx->battlerDef] == ABILITY_KLUTZ)
|| ctx->abilities[ctx->battlerDef] == ABILITY_KLUTZ)
battleScript = BattleScript_ButItFailed;
break;
case EFFECT_PROTECT:
@ -2664,13 +2666,13 @@ static enum MoveCanceller CancellerMoveFailure(struct BattleContext *ctx)
break;
case EFFECT_REST:
if (gBattleMons[ctx->battlerAtk].status1 & STATUS1_SLEEP
|| ctx->ability[ctx->battlerAtk] == ABILITY_COMATOSE)
|| ctx->abilities[ctx->battlerAtk] == ABILITY_COMATOSE)
battleScript = BattleScript_RestIsAlreadyAsleep;
else if (gBattleMons[ctx->battlerAtk].hp == gBattleMons[ctx->battlerAtk].maxHP)
battleScript = BattleScript_AlreadyAtFullHp;
else if (ctx->ability[ctx->battlerAtk] == ABILITY_INSOMNIA
|| ctx->ability[ctx->battlerAtk] == ABILITY_VITAL_SPIRIT
|| ctx->ability[ctx->battlerAtk] == ABILITY_PURIFYING_SALT)
else if (ctx->abilities[ctx->battlerAtk] == ABILITY_INSOMNIA
|| ctx->abilities[ctx->battlerAtk] == ABILITY_VITAL_SPIRIT
|| ctx->abilities[ctx->battlerAtk] == ABILITY_PURIFYING_SALT)
battleScript = BattleScript_InsomniaProtects;
break;
case EFFECT_SUCKER_PUNCH:
@ -2680,7 +2682,7 @@ static enum MoveCanceller CancellerMoveFailure(struct BattleContext *ctx)
break;
case EFFECT_SNORE:
if (!(gBattleMons[ctx->battlerAtk].status1 & STATUS1_SLEEP)
&& ctx->ability[ctx->battlerAtk] != ABILITY_COMATOSE)
&& ctx->abilities[ctx->battlerAtk] != ABILITY_COMATOSE)
battleScript = BattleScript_ButItFailed;
break;
case EFFECT_STEEL_ROLLER:
@ -2726,7 +2728,7 @@ static enum MoveCanceller CancellerPowderStatus(struct BattleContext *ctx)
{
if (TryActivatePowderStatus(ctx->currentMove))
{
if (!IsAbilityAndRecord(ctx->battlerAtk, ctx->ability[ctx->battlerAtk], ABILITY_MAGIC_GUARD))
if (!IsAbilityAndRecord(ctx->battlerAtk, ctx->abilities[ctx->battlerAtk], ABILITY_MAGIC_GUARD))
gBattleStruct->moveDamage[ctx->battlerAtk] = GetNonDynamaxMaxHP(ctx->battlerAtk) / 4;
// This might be incorrect
@ -2754,16 +2756,16 @@ bool32 IsDazzlingAbility(enum Ability ability)
static enum MoveCanceller CancellerPriorityBlock(struct BattleContext *ctx)
{
bool32 effect = FALSE;
s32 priority = GetChosenMovePriority(ctx->battlerAtk, ctx->ability[ctx->battlerAtk]);
s32 priority = GetChosenMovePriority(ctx->battlerAtk, ctx->abilities[ctx->battlerAtk]);
u32 blockAbility = ABILITY_NONE; // ability of battler who is blocking
u32 blockedByBattler = ctx->battlerDef;
if (priority <= 0 || IsBattlerAlly(ctx->battlerAtk, ctx->battlerDef))
return MOVE_STEP_SUCCESS;
if (IsDazzlingAbility(ctx->ability[ctx->battlerDef]))
if (IsDazzlingAbility(ctx->abilities[ctx->battlerDef]))
{
blockAbility = ctx->ability[ctx->battlerDef];
blockAbility = ctx->abilities[ctx->battlerDef];
effect = TRUE;
}
else if (IsDoubleBattle() && IsBattlerAlive(BATTLE_PARTNER(ctx->battlerDef)))
@ -2793,7 +2795,7 @@ static enum MoveCanceller CancellerPriorityBlock(struct BattleContext *ctx)
static enum MoveCanceller CancellerProtean(struct BattleContext *ctx)
{
u32 moveType = GetBattleMoveType(ctx->currentMove);
if (ProteanTryChangeType(ctx->battlerAtk, ctx->ability[ctx->battlerAtk], ctx->currentMove, moveType))
if (ProteanTryChangeType(ctx->battlerAtk, ctx->abilities[ctx->battlerAtk], ctx->currentMove, moveType))
{
if (GetGenConfig(GEN_PROTEAN_LIBERO) >= GEN_9)
gDisableStructs[ctx->battlerAtk].usedProteanLibero = TRUE;
@ -2824,7 +2826,7 @@ static enum MoveCanceller CancellerMultihitMoves(struct BattleContext *ctx)
{
if (GetMoveEffect(ctx->currentMove) == EFFECT_MULTI_HIT)
{
enum Ability ability = ctx->ability[ctx->battlerAtk];
enum Ability ability = ctx->abilities[ctx->battlerAtk];
if (ability == ABILITY_SKILL_LINK)
{
@ -2845,7 +2847,7 @@ static enum MoveCanceller CancellerMultihitMoves(struct BattleContext *ctx)
}
else if (GetMoveStrikeCount(ctx->currentMove) > 1)
{
if (ctx->moveEffect == EFFECT_POPULATION_BOMB && GetBattlerHoldEffect(ctx->battlerAtk) == HOLD_EFFECT_LOADED_DICE)
if (GetMoveEffect(ctx->currentMove) == EFFECT_POPULATION_BOMB && GetBattlerHoldEffect(ctx->battlerAtk) == HOLD_EFFECT_LOADED_DICE)
{
gMultiHitCounter = RandomUniform(RNG_LOADED_DICE, 4, 10);
}
@ -2853,7 +2855,7 @@ static enum MoveCanceller CancellerMultihitMoves(struct BattleContext *ctx)
{
gMultiHitCounter = GetMoveStrikeCount(ctx->currentMove);
if (ctx->moveEffect == EFFECT_DRAGON_DARTS
if (GetMoveEffect(ctx->currentMove) == EFFECT_DRAGON_DARTS
&& !IsAffectedByFollowMe(ctx->battlerAtk, GetBattlerSide(ctx->battlerDef), ctx->currentMove)
&& CanTargetPartner(ctx->battlerAtk, ctx->battlerDef)
&& TargetFullyImmuneToCurrMove(ctx->battlerAtk, ctx->battlerDef))
@ -2862,7 +2864,7 @@ static enum MoveCanceller CancellerMultihitMoves(struct BattleContext *ctx)
PREPARE_BYTE_NUMBER_BUFFER(gBattleScripting.multihitString, 3, 0)
}
else if (B_BEAT_UP >= GEN_5 && ctx->moveEffect == EFFECT_BEAT_UP)
else if (B_BEAT_UP >= GEN_5 && GetMoveEffect(ctx->currentMove) == EFFECT_BEAT_UP)
{
struct Pokemon* party = GetBattlerParty(ctx->battlerAtk);
int i;
@ -2895,7 +2897,7 @@ static enum MoveCanceller CancellerMultihitMoves(struct BattleContext *ctx)
static enum MoveCanceller CancellerMultiTargetMoves(struct BattleContext *ctx)
{
u32 moveTarget = GetBattlerMoveTargetType(ctx->battlerAtk, ctx->currentMove);
enum Ability abilityAtk = ctx->ability[ctx->battlerAtk];
enum Ability abilityAtk = ctx->abilities[ctx->battlerAtk];
if (IsSpreadMove(moveTarget))
{
@ -2908,7 +2910,7 @@ static enum MoveCanceller CancellerMultiTargetMoves(struct BattleContext *ctx)
if (ctx->battlerAtk == battlerDef
|| !IsBattlerAlive(battlerDef)
|| (ctx->moveEffect == EFFECT_SYNCHRONOISE && !DoBattlersShareType(ctx->battlerAtk, battlerDef))
|| (GetMoveEffect(ctx->currentMove) == EFFECT_SYNCHRONOISE && !DoBattlersShareType(ctx->battlerAtk, battlerDef))
|| (moveTarget == MOVE_TARGET_BOTH && ctx->battlerAtk == BATTLE_PARTNER(battlerDef))
|| IsBattlerProtected(ctx->battlerAtk, battlerDef, ctx->currentMove)) // Missing Invulnerable check
{