diff --git a/include/pokemon.h b/include/pokemon.h index c303e32dff..d1f2c1d575 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -399,20 +399,21 @@ struct BattleMove const struct AdditionalEffect *additionalEffects; }; +// for some reason struct arguments are counted as 2? #define ADDITIONAL_EFFECTS(...)\ - .numAdditionalEffects = NARG_8(__VA_ARGS__) - 1,\ + .numAdditionalEffects = NARG_8(__VA_ARGS__) / 2,\ .additionalEffects = (const struct AdditionalEffect[]){\ VARARG_8(ADDITIONAL_EFFECTS_, __VA_ARGS__)\ } #define ADDITIONAL_EFFECTS_0() -#define ADDITIONAL_EFFECTS_1(a) a, -#define ADDITIONAL_EFFECTS_2(a, b) a, b, -#define ADDITIONAL_EFFECTS_3(a, b, c) a, b, c, +#define ADDITIONAL_EFFECTS_2(a, b) a, b +#define ADDITIONAL_EFFECTS_4(a, b, c, d) a, b, c, d +#define ADDITIONAL_EFFECTS_6(a, b, c, d, e, f) a, b, c, d, e, f -#define PRIMARY_EFFECT(_moveEffect, ...) {.moveEffect = _moveEffect} -#define PRIMARY_EFFECT_SELF(_moveEffect, ...) {.self = TRUE, .moveEffect = _moveEffect} -#define SECONDARY_EFFECT(_moveEffect, _chance, ...) {.chance = _chance, .moveEffect = _moveEffect} -#define SECONDARY_EFFECT_SELF(_moveEffect, _chance, ...) {.self = TRUE, .chance = _chance, .moveEffect = _moveEffect} +#define PRIMARY_EFFECT(_moveEffect, ...){.moveEffect = _moveEffect} +#define PRIMARY_EFFECT_SELF(_moveEffect, ...){.self = TRUE, .moveEffect = _moveEffect} +#define SECONDARY_EFFECT(_moveEffect, _chance, ...){.chance = _chance, .moveEffect = _moveEffect} +#define SECONDARY_EFFECT_SELF(_moveEffect, _chance, ...){.self = TRUE, .chance = _chance, .moveEffect = _moveEffect} struct AdditionalEffect { diff --git a/include/random.h b/include/random.h index 8d801ebe74..2fe536d66b 100644 --- a/include/random.h +++ b/include/random.h @@ -89,6 +89,8 @@ enum RandomTag RNG_POISON_POINT, RNG_RAMPAGE_TURNS, RNG_SECONDARY_EFFECT, + RNG_SECONDARY_EFFECT_2, + RNG_SECONDARY_EFFECT_3, RNG_SLEEP_TURNS, RNG_SPEED_TIE, RNG_STATIC, diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 0a9e0a269a..651329c766 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -3576,7 +3576,6 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score case EFFECT_TOXIC: case EFFECT_POISON: case EFFECT_BARB_BARRAGE: - case EFFECT_MORTAL_SPIN: IncreasePoisonScore(battlerAtk, battlerDef, move, &score); break; case EFFECT_LIGHT_SCREEN: @@ -4882,6 +4881,20 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score break; } // move effect checks + // check move additional effects + for (i = 0; i < gBattleMoves[move].numAdditionalEffects; i++) + { + if (gBattleMoves[move].additionalEffects[i].self) + continue; + + switch (gBattleMoves[move].additionalEffects[i].moveEffect) + { + case MOVE_EFFECT_POISON: + IncreasePoisonScore(battlerAtk, battlerDef, move, &score); + break; + } + } + return score; } diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 272e9ca592..4f2aa642a0 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -843,21 +843,6 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3 u32 abilityDef = AI_DATA->abilities[battlerDef]; u32 abilityAtk = AI_DATA->abilities[battlerAtk]; - // check ADDITIONAL_EFFECTS - if (gBattleMoves[move].numAdditionalEffects > 0) - { - for (i = gBattleMoves[move].numAdditionalEffects; i > 0; i--) - { - switch (gBattleMoves[move].additionalEffects[i - 1].moveEffect) - { - case MOVE_EFFECT_PARALYSIS: - if (AI_CanParalyze(battlerAtk, battlerDef, abilityDef, move, MOVE_NONE)) - return TRUE; - break; - } - } - } - switch (gBattleMoves[move].effect) { case EFFECT_HIT: @@ -962,6 +947,22 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3 } return FALSE; + + // check ADDITIONAL_EFFECTS + for (i = 0; i < gBattleMoves[move].numAdditionalEffects; i++) + { + // Obviously ignore moves that target self + if (gBattleMoves[move].additionalEffects[i].self) + continue; + + switch (gBattleMoves[move].additionalEffects[i].moveEffect) + { + case MOVE_EFFECT_PARALYSIS: + if (AI_CanParalyze(battlerAtk, battlerDef, abilityDef, move, MOVE_NONE)) + return TRUE; + break; + } + } } static bool32 AI_IsMoveEffectInMinus(u32 battlerAtk, u32 battlerDef, u32 move, s32 noOfHitsToKo) diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index ef00c476f5..5f6ae074e7 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3636,6 +3636,7 @@ static void Cmd_seteffectwithchance(void) { CMD_ARGS(); + u8 i; u32 percentChance = CalcSecondaryEffectChance(gBattlerAttacker, gBattleMoves[gCurrentMove].secondaryEffectChance); if (!(gMoveResultFlags & MOVE_RESULT_NO_EFFECT) @@ -3665,18 +3666,15 @@ static void Cmd_seteffectwithchance(void) gBattleScripting.multihitMoveEffect = 0; // Set any move effects in this move's ADDITIONAL_EFFECTS - if (gBattleMoves[gCurrentMove].numAdditionalEffects > 0) + // In reverse array order so that effects are applied in correct order + for (i = gBattleMoves[gCurrentMove].numAdditionalEffects; i > 0; i--) { - u8 i, percentChance; - for (i = gBattleMoves[gCurrentMove].numAdditionalEffects; i > 0; i--) + percentChance = gBattleMoves[gCurrentMove].additionalEffects[i - 1].chance; + // Each effect needs its own RNG_SECONDARY_EFFECT tag + if ((percentChance == 0) || RandomPercentage(RNG_SECONDARY_EFFECT + i - 1, percentChance)) { - percentChance = gBattleMoves[gCurrentMove].additionalEffects[i - 1].chance; - if (percentChance == 0 || RandomPercentage(RNG_SECONDARY_EFFECT, percentChance)) - { - gBattleScripting.moveEffect = gBattleMoves[gCurrentMove].additionalEffects[i - 1].moveEffect; - SetMoveEffect(percentChance == 0, 0); - } - + gBattleScripting.moveEffect = gBattleMoves[gCurrentMove].additionalEffects[i - 1].moveEffect; + SetMoveEffect((percentChance == 0), 0); } } } diff --git a/src/data/battle_moves.h b/src/data/battle_moves.h index 2e90484dc3..6f0157b672 100644 --- a/src/data/battle_moves.h +++ b/src/data/battle_moves.h @@ -13777,7 +13777,7 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = [MOVE_MORTAL_SPIN] = { - .effect = EFFECT_MORTAL_SPIN, + .effect = EFFECT_HIT, .power = 30, .type = TYPE_POISON, .accuracy = 100, @@ -13789,6 +13789,10 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] = .zMoveEffect = Z_EFFECT_NONE, .sheerForceBoost = TRUE, .makesContact = TRUE, + ADDITIONAL_EFFECTS( + PRIMARY_EFFECT_SELF(MOVE_EFFECT_RAPIDSPIN), + SECONDARY_EFFECT(MOVE_EFFECT_POISON, 100) + ) }, [MOVE_DOODLE] = diff --git a/test/battle/move_effect/mortal_spin.c b/test/battle/move_effect/mortal_spin.c index 0ac8403e28..cedbfee30c 100644 --- a/test/battle/move_effect/mortal_spin.c +++ b/test/battle/move_effect/mortal_spin.c @@ -3,7 +3,8 @@ ASSUMPTIONS { - ASSUME(gBattleMoves[MOVE_MORTAL_SPIN].effect == EFFECT_MORTAL_SPIN); + ASSUME(gBattleMoves[MOVE_MORTAL_SPIN].additionalEffects[0].moveEffect == MOVE_EFFECT_RAPIDSPIN); + ASSUME(gBattleMoves[MOVE_MORTAL_SPIN].additionalEffects[1].moveEffect == MOVE_EFFECT_POISON); } SINGLE_BATTLE_TEST("Mortal Spin blows away hazards and poisons foe")