diff --git a/include/battle/common.h b/include/battle/common.h index cd8a46d427..271fe1c61e 100644 --- a/include/battle/common.h +++ b/include/battle/common.h @@ -51,9 +51,9 @@ #define MON_HAS_TYPE(mon, type) (BattleMon_Get(battleCtx, mon, BATTLEMON_TYPE_1, NULL) == type || BattleMon_Get(battleCtx, mon, BATTLEMON_TYPE_2, NULL) == type) #define MON_IS_NOT_TYPE(mon, type) (BattleMon_Get(battleCtx, mon, BATTLEMON_TYPE_1, NULL) != type && BattleMon_Get(battleCtx, mon, BATTLEMON_TYPE_2, NULL) != type) -#define NO_TARGET_SINGLE_TURN (battleCtx->defender == BATTLER_NONE && BattleMove_IsMultiTurn(battleCtx, battleCtx->moveCur) == FALSE) +#define NO_TARGET_SINGLE_TURN (battleCtx->defender == BATTLER_NONE && Move_IsMultiTurn(battleCtx, battleCtx->moveCur) == FALSE) #define NO_TARGET_MULTI_TURN (battleCtx->defender == BATTLER_NONE \ - && BattleMove_IsMultiTurn(battleCtx, battleCtx->moveCur) == TRUE \ + && Move_IsMultiTurn(battleCtx, battleCtx->moveCur) == TRUE \ && ( \ (ATTACKING_MON.statusVolatile & VOLATILE_CONDITION_MOVE_LOCKED) \ || (battleCtx->battleStatusMask & SYSCTL_LAST_OF_MULTI_TURN) \ diff --git a/include/overlay016/ov16_0225177C.h b/include/overlay016/ov16_0225177C.h index b60946f385..57719f079a 100644 --- a/include/overlay016/ov16_0225177C.h +++ b/include/overlay016/ov16_0225177C.h @@ -568,7 +568,16 @@ u16 Battler_SelectedMove(BattleContext * param0, int param1); * be a mask of the battlers matching the criteria. */ int BattleSystem_CountAbility(BattleSystem *battleSys, BattleContext *battleCtx, enum CountAbilityMode mode, int battler, int ability); -BOOL BattleMove_IsMultiTurn(BattleContext * param0, int param1); + +/** + * @brief Determine if a given move is a multi-turn move. + * + * @param battleCtx + * @param move + * @return TRUE if the move is a multi-turn move (one which has a charging + * turn); FALSE if not + */ +BOOL Move_IsMultiTurn(BattleContext *battleCtx, int move); /** * @brief Access a particular entry in the type-matchup table. @@ -616,7 +625,17 @@ int BattleSystem_TypeMatchupMultiplier(u8 attackingType, u8 defendingType1, u8 d * @return TRUE if the move is invoker-class, FALSE if not. */ BOOL Move_IsInvoker(u16 move); -BOOL BattleSystem_IsGhostCurse(BattleContext * param0, u16 param1, int param2); + +/** + * @brief Check if a given move is Curse being used by a Ghost-type Pokemon. + * + * @param battleCtx + * @param move + * @param battler + * @return TRUE if the move is Curse and the battler has the Ghost typing; + * FALSE otherwise + */ +BOOL Move_IsGhostCurse(BattleContext *battleCtx, u16 move, int battler); /** * @brief Determine if a battler's item can be stolen. @@ -645,7 +664,16 @@ BOOL BattleSystem_NotHoldingMail(BattleContext * param0, int param1); * @return TRUE if Whirlwind should succeed, FALSE if it should fail. */ BOOL BattleSystem_CanWhirlwind(BattleSystem *battleSys, BattleContext *battleCtx); -u8 Battler_Ability(BattleContext * param0, int param1); + +/** + * @brief Get the battler's ability, accounting for disrupting effects on itself, + * e.g. Gastro Acid, Gravity, and Ingrain. + * + * @param battleCtx + * @param battler + * @return The battler's ability + */ +u8 Battler_Ability(BattleContext *battleCtx, int battler); /** * @brief Check if the given defender has the specified ability, treating it as diff --git a/src/overlay014/ov14_0221FC20.c b/src/overlay014/ov14_0221FC20.c index 908a0c3a28..858bf5e73a 100644 --- a/src/overlay014/ov14_0221FC20.c +++ b/src/overlay014/ov14_0221FC20.c @@ -541,7 +541,7 @@ static u8 ov14_0221FE38 (BattleSystem * param0, BattleContext * param1) } if (v7 == 174) { - if (BattleSystem_IsGhostCurse(param1, v7, param1->aiContext.attacker) == 0) { + if (Move_IsGhostCurse(param1, v7, param1->aiContext.attacker) == 0) { param1->aiContext.selectedTarget[param1->aiContext.attacker] = param1->aiContext.attacker; } } diff --git a/src/overlay016/battle_controller.c b/src/overlay016/battle_controller.c index b3c3b9c860..184286492a 100644 --- a/src/overlay016/battle_controller.c +++ b/src/overlay016/battle_controller.c @@ -2325,7 +2325,7 @@ static BOOL BattleController_HasNoTarget(BattleSystem *battleSys, BattleContext // Don't alter the target for charge-turn moves that are just charging up this turn if (battleCtx->defender == BATTLER_NONE - && BattleMove_IsMultiTurn(battleCtx, battleCtx->moveCur) == TRUE + && Move_IsMultiTurn(battleCtx, battleCtx->moveCur) == TRUE && result == FALSE && solarMove == FALSE && Battler_HeldItemEffect(battleCtx, battleCtx->attacker) != HOLD_EFFECT_CHARGE_SKIP @@ -3007,8 +3007,8 @@ static int BattleController_CheckMoveHitOverrides(BattleSystem *battleSys, Battl if (battleCtx->turnFlags[defender].protecting && (MOVE_DATA(move).flags & MOVE_FLAG_CAN_PROTECT) - && (move != MOVE_CURSE || BattleSystem_IsGhostCurse(battleCtx, move, attacker) == TRUE) // Ghost-Curse can be Protected - && (BattleMove_IsMultiTurn(battleCtx, move) == FALSE || (battleCtx->battleStatusMask & SYSCTL_LAST_OF_MULTI_TURN))) { + && (move != MOVE_CURSE || Move_IsGhostCurse(battleCtx, move, attacker) == TRUE) // Ghost-Curse can be Protected + && (Move_IsMultiTurn(battleCtx, move) == FALSE || (battleCtx->battleStatusMask & SYSCTL_LAST_OF_MULTI_TURN))) { Battler_UnlockMoveChoice(battleSys, battleCtx, attacker); battleCtx->moveStatusFlags |= MOVE_STATUS_PROTECTED; return 0; @@ -4348,7 +4348,7 @@ static BOOL BattleController_CheckBattleOver(BattleSystem * battleSys, BattleCon static BOOL BattleController_MustSelectTarget(BattleSystem *battleSys, BattleContext *battleCtx, u8 battler, u32 battleType, int *range, int moveSlot, u32 *target) { if (battleCtx->battleMons[battler].moves[moveSlot] == MOVE_CURSE - && BattleSystem_IsGhostCurse(battleCtx, battleCtx->battleMons[battler].moves[moveSlot], battler) == FALSE) { + && Move_IsGhostCurse(battleCtx, battleCtx->battleMons[battler].moves[moveSlot], battler) == FALSE) { *range = RANGE_USER; } else { *range = MOVE_DATA(battleCtx->battleMons[battler].moves[moveSlot]).range; diff --git a/src/overlay016/battle_script.c b/src/overlay016/battle_script.c index 7ddefe6e19..b0532a0475 100644 --- a/src/overlay016/battle_script.c +++ b/src/overlay016/battle_script.c @@ -5011,7 +5011,7 @@ static BOOL BtlCmd_TryConversion2(BattleSystem *battleSys, BattleContext *battle if (battleCtx->conversion2Move[battleCtx->attacker] && battleCtx->conversion2Battler[battleCtx->attacker] != BATTLER_NONE) { // Fail to execute if the source move's owner is locked into the first turn of a multi-turn move - if (BattleMove_IsMultiTurn(battleCtx, battleCtx->conversion2Move[battleCtx->attacker]) + if (Move_IsMultiTurn(battleCtx, battleCtx->conversion2Move[battleCtx->attacker]) && (battleCtx->battleMons[battleCtx->conversion2Battler[battleCtx->attacker]].statusVolatile & VOLATILE_CONDITION_MOVE_LOCKED)) { BattleScript_Iter(battleCtx, jumpOnFail); return FALSE; @@ -5154,7 +5154,7 @@ static BOOL BtlCmd_TrySleepTalk(BattleSystem *battleSys, BattleContext *battleCt || ATTACKING_MON.moves[i] == MOVE_FOCUS_PUNCH || ATTACKING_MON.moves[i] == MOVE_UPROAR || ATTACKING_MON.moves[i] == MOVE_CHATTER - || BattleMove_IsMultiTurn(battleCtx, ATTACKING_MON.moves[i])) { + || Move_IsMultiTurn(battleCtx, ATTACKING_MON.moves[i])) { invalidMovesMask |= FlagIndex(i); } } diff --git a/src/overlay016/ov16_0225177C.c b/src/overlay016/ov16_0225177C.c index 8ac8f2b1b5..77ac97843e 100644 --- a/src/overlay016/ov16_0225177C.c +++ b/src/overlay016/ov16_0225177C.c @@ -2981,24 +2981,23 @@ int BattleSystem_CountAbility(BattleSystem *battleSys, BattleContext *battleCtx, return result; } -BOOL BattleMove_IsMultiTurn (BattleContext * param0, int param1) +BOOL Move_IsMultiTurn(BattleContext *battleCtx, int move) { - switch (param0->aiContext.moveTable[param1].effect) { - case 26: - case 39: - case 75: - case 145: - case 151: - case 155: - case 255: - case 256: - case 263: - case 272: - return 1; - break; + switch (MOVE_DATA(move).effect) { + case BATTLE_EFFECT_BIDE: + case BATTLE_EFFECT_CHARGE_TURN_HIGH_CRIT: + case BATTLE_EFFECT_CHARGE_TURN_HIGH_CRIT_FLINCH: + case BATTLE_EFFECT_CHARGE_TURN_DEF_UP: + case BATTLE_EFFECT_SKIP_CHARGE_TURN_IN_SUN: + case BATTLE_EFFECT_FLY: + case BATTLE_EFFECT_DIVE: + case BATTLE_EFFECT_DIG: + case BATTLE_EFFECT_BOUNCE: + case BATTLE_EFFECT_SHADOW_FORCE: + return TRUE; } - return 0; + return FALSE; } BOOL BattleSystem_TypeMatchup(BattleSystem *battleSys, int idx, u8 *moveType, u8 *vsType, u8 *multi) @@ -3055,9 +3054,9 @@ BOOL Move_IsInvoker(u16 move) return FALSE; } -BOOL BattleSystem_IsGhostCurse (BattleContext * param0, u16 param1, int param2) +BOOL Move_IsGhostCurse(BattleContext *battleCtx, u16 move, int battler) { - return (param1 == 174) && ((BattleMon_Get(param0, param2, 27, NULL) == 7) || (BattleMon_Get(param0, param2, 28, NULL) == 7)); + return move == MOVE_CURSE && MON_HAS_TYPE(battler, TYPE_GHOST); } BOOL BattleSystem_CanStealItem(BattleSystem *battleSys, BattleContext *battleCtx, int battler) @@ -3095,17 +3094,24 @@ BOOL BattleSystem_CanWhirlwind(BattleSystem *battleSys, BattleContext *battleCtx return result; } -u8 Battler_Ability (BattleContext * param0, int param1) +u8 Battler_Ability(BattleContext *battleCtx, int battler) { - if ((param0->battleMons[param1].moveEffectsMask & 0x200000) && (param0->battleMons[param1].ability != 121)) { - return 0; - } else if ((param0->fieldConditionsMask & 0x7000) && (param0->battleMons[param1].ability == 26)) { - return 0; - } else if ((param0->battleMons[param1].moveEffectsMask & 0x400) && (param0->battleMons[param1].ability == 26)) { - return 0; - } else { - return param0->battleMons[param1].ability; + if ((battleCtx->battleMons[battler].moveEffectsMask & MOVE_EFFECT_ABILITY_SUPPRESSED) + && battleCtx->battleMons[battler].ability != ABILITY_MULTITYPE) { + return ABILITY_NONE; + } + + if ((battleCtx->fieldConditionsMask & FIELD_CONDITION_GRAVITY) + && battleCtx->battleMons[battler].ability == ABILITY_LEVITATE) { + return ABILITY_NONE; + } + + if ((battleCtx->battleMons[battler].moveEffectsMask & MOVE_EFFECT_INGRAIN) + && battleCtx->battleMons[battler].ability == ABILITY_LEVITATE) { + return ABILITY_NONE; } + + return battleCtx->battleMons[battler].ability; } BOOL Battler_IgnorableAbility(BattleContext *battleCtx, int attacker, int defender, int ability)