diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b89016fddd..88ef358dbb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,7 +23,7 @@ The best bug reports have enough information that we won't have to contact you f - A maintainer will [label](https://github.com/rh-hideout/pokeemerald-expansion/labels) the bug report. - A maintainer will try to reproduce the bug with your provided steps. - - If there are no reproduction steps or no obvious way to reproduce the issue, somebody will ask you for those steps. Until the bug can be reproduced, the bug will retain the `bug:unconfirmed` label. Unconfirmed bugs are less likely get fixed. + - If there are no reproduction steps or no obvious way to reproduce the issue, somebody will ask you for those steps. Until the bug can be reproduced, the bug will retain the `bug:unconfirmed` label. Unconfirmed bugs are less likely to get fixed. - If the team is able to reproduce the bug, it will be labeled `bug:confirmed`, and the bug will be left to be [fixed by someone](#Pull-Requests). - If the issue is particularly game-breaking, a maintainer will add it to a future version's [milestone](), meaning that version will not be released until the problem is solved. diff --git a/docs/tutorials/how_to_testing_system.md b/docs/tutorials/how_to_testing_system.md index c2b9912898..70ee6c4033 100644 --- a/docs/tutorials/how_to_testing_system.md +++ b/docs/tutorials/how_to_testing_system.md @@ -497,10 +497,10 @@ Causes the test to fail if the `SCENE` command succeeds before the following com ``` Causes the test to fail unless one of the `SCENE` commands succeeds. ``` - ONE_OF { - MESSAGE("Wobbuffet used Celebrate!"); - MESSAGE("Wobbuffet couldn't move because it's paralyzed!"); - } + ONE_OF { + MESSAGE("Wobbuffet used Celebrate!"); + MESSAGE("Wobbuffet couldn't move because it's paralyzed!"); + } ``` ### `NONE_OF` @@ -511,12 +511,12 @@ Causes the test to fail unless one of the `SCENE` commands succeeds. ``` Causes the test to fail if one of the `SCENE` commands succeeds before the command after the `NONE_OF` succeeds. ``` - // Our Wobbuffet does not move before the foe's. - NONE_OF { - MESSAGE("Wobbuffet used Celebrate!"); - MESSAGE("Wobbuffet couldn't move because it's paralyzed!"); - } - MESSAGE("The opposing Wobbuffet used Celebrate!"); + // Our Wobbuffet does not move before the foe's. + NONE_OF { + MESSAGE("Wobbuffet used Celebrate!"); + MESSAGE("Wobbuffet couldn't move because it's paralyzed!"); + } + MESSAGE("The opposing Wobbuffet used Celebrate!"); ``` ### `PLAYER_PARTY` diff --git a/include/battle_util.h b/include/battle_util.h index 8ea72866e5..9ebc837952 100644 --- a/include/battle_util.h +++ b/include/battle_util.h @@ -343,7 +343,7 @@ bool32 IsPartnerMonFromSameTrainer(u32 battler); enum DamageCategory GetCategoryBasedOnStats(u32 battler); void SetShellSideArmCategory(void); bool32 MoveIsAffectedBySheerForce(u32 move); -bool32 TestIfSheerForceAffected(u32 battler, u16 move); +bool32 IsSheerForceAffected(u16 move, enum Ability ability); void TryRestoreHeldItems(void); bool32 CanStealItem(u32 battlerStealing, u32 battlerItem, u16 item); void TrySaveExchangedItem(u32 battler, u16 stolenItem); diff --git a/include/constants/generational_changes.h b/include/constants/generational_changes.h index f94b7e8309..755a4d1186 100644 --- a/include/constants/generational_changes.h +++ b/include/constants/generational_changes.h @@ -24,7 +24,7 @@ F(MAX_LEVEL_EV_GAINS, maxLevelEvGains, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(RECALCULATE_STATS, recalculateStats, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ /* Damage settings */ \ - F(BURN_DAMAGE, burnDamage, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(BURN_DAMAGE, burnDamage, (u32, GEN_COUNT - 1)) \ F(BURN_FACADE_DMG, burnFacadeDmg, (u32, GEN_COUNT - 1)) \ F(BINDING_DAMAGE, bindingDamage, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(PSYWAVE_DMG, psywaveDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ @@ -51,7 +51,7 @@ F(UPROAR_TURNS, uproarTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(UPROAR_IGNORE_SOUNDPROOF, uproarIgnoreSoundproof, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(DISABLE_TURNS, disableTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ - F(TAILWIND_TURNS, tailwindTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(TAILWIND_TURNS, tailwindTurns, (u32, GEN_COUNT - 1)) \ F(SLEEP_TURNS, sleepTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(TAUNT_TURNS, tauntTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(SPORT_TURNS, sportTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ @@ -64,9 +64,9 @@ F(UPDATED_MOVE_FLAGS, updatedMoveFlags, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(PHYSICAL_SPECIAL_SPLIT, physicalSpecialSplit, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(RECOIL_IF_MISS_DMG, recoilIfMissDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ - F(KLUTZ_FLING_INTERACTION, klutzFlingInteraction, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(KLUTZ_FLING_INTERACTION, klutzFlingInteraction, (u32, GEN_COUNT - 1)) \ F(UPDATED_CONVERSION, updatedConversion, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ - F(UPDATED_CONVERSION_2, updatedConversion2, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(UPDATED_CONVERSION_2, updatedConversion2, (u32, GEN_COUNT - 1)) \ F(PP_REDUCED_BY_SPITE, ppReducedBySpite, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(EXTRAPOLATED_MOVE_FLAGS, extrapolatedMoveFlags, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ /* Ability data settings */ \ @@ -129,15 +129,15 @@ F(SHADOW_TAG_ESCAPE, shadowTagEscape, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(MOODY_ACC_EVASION, moodyAccEvasion, (u32, GEN_COUNT - 1)) \ F(FLASH_FIRE_FROZEN, flashFireFrozen, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ - F(SYNCHRONIZE_TOXIC, synchronizeToxic, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(SYNCHRONIZE_TOXIC, synchronizeToxic, (u32, GEN_COUNT - 1)) \ F(UPDATED_INTIMIDATE, updatedIntimidate, (u32, GEN_COUNT - 1)) \ F(OBLIVIOUS_TAUNT, obliviousTaunt, (u32, GEN_COUNT - 1)) \ - F(STURDY, sturdy, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(STURDY, sturdy, (u32, GEN_COUNT - 1)) \ F(PLUS_MINUS_INTERACTION, plusMinusInteraction, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(WEATHER_FORMS, weatherForms, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(SYMBIOSIS_GEMS, symbiosisGems, (u32, GEN_COUNT - 1)) \ F(ABSORBING_ABILITY_STRING, absorbingAbilityString, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ - F(REDIRECT_ABILITY_IMMUNITY, redirectAbilityImmunity, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(REDIRECT_ABILITY_IMMUNITY, redirectAbilityImmunity, (u32, GEN_COUNT - 1)) \ F(REDIRECT_ABILITY_ALLIES, redirectAbilityAllies, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(LEAF_GUARD_PREVENTS_REST, leafGuardPreventsRest, (u32, GEN_COUNT - 1)) \ F(TRANSISTOR_BOOST, transistorBoost, (u32, GEN_COUNT - 1)) \ @@ -176,7 +176,7 @@ F(SAFARI_BALL_MODIFIER, safariBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(FRIEND_BALL_MODIFIER, friendBallModifier, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(SERENE_GRACE_BOOST, sereneGraceBoost, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ - F(IRON_BALL, ironBall, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(IRON_BALL, ironBall, (u32, GEN_COUNT - 1)) \ /* Weather settings */ \ F(ABILITY_WEATHER, abilityWeather, (u32, GEN_COUNT - 1)) \ F(SANDSTORM_SPDEF_BOOST, sandstormSpDefBoost, (u32, GEN_COUNT - 1)) \ diff --git a/include/pokemon.h b/include/pokemon.h index bc6af2a48e..9ca2743300 100644 --- a/include/pokemon.h +++ b/include/pokemon.h @@ -723,7 +723,6 @@ void CreateBattleTowerMon_HandleLevel(struct Pokemon *mon, struct BattleTowerPok void CreateApprenticeMon(struct Pokemon *mon, const struct Apprentice *src, u8 monId); void CreateMonWithEVSpreadNatureOTID(struct Pokemon *mon, u16 species, u8 level, u8 nature, u8 fixedIV, u8 evSpread, u32 otId); void ConvertPokemonToBattleTowerPokemon(struct Pokemon *mon, struct BattleTowerPokemon *dest); -bool8 ShouldIgnoreDeoxysForm(u8 caseId, u8 battler); u16 GetUnionRoomTrainerPic(void); enum TrainerClassID GetUnionRoomTrainerClass(void); void CreateEnemyEventMon(void); diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index ac97f1e004..8dde9c4a97 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -3398,7 +3398,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case ABILITY_VOLT_ABSORB: if (moveType == TYPE_ELECTRIC) { - if (B_REDIRECT_ABILITY_IMMUNITY < GEN_5 && atkPartnerAbility == ABILITY_LIGHTNING_ROD) + if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) < GEN_5 && atkPartnerAbility == ABILITY_LIGHTNING_ROD) { RETURN_SCORE_MINUS(10); } @@ -3444,7 +3444,7 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score) case ABILITY_STORM_DRAIN: if (moveType == TYPE_WATER) { - if (B_REDIRECT_ABILITY_IMMUNITY < GEN_5 && atkPartnerAbility == ABILITY_STORM_DRAIN) + if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) < GEN_5 && atkPartnerAbility == ABILITY_STORM_DRAIN) { RETURN_SCORE_MINUS(10); } @@ -5397,7 +5397,7 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, stru case EFFECT_ION_DELUGE: if ((aiData->abilities[battlerAtk] == ABILITY_VOLT_ABSORB || aiData->abilities[battlerAtk] == ABILITY_MOTOR_DRIVE - || (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5 && aiData->abilities[battlerAtk] == ABILITY_LIGHTNING_ROD)) + || (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && aiData->abilities[battlerAtk] == ABILITY_LIGHTNING_ROD)) && predictedType == TYPE_NORMAL) ADJUST_SCORE(DECENT_EFFECT); break; @@ -5457,7 +5457,7 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, stru if (predictedMove != MOVE_NONE && (aiData->abilities[battlerAtk] == ABILITY_VOLT_ABSORB || aiData->abilities[battlerAtk] == ABILITY_MOTOR_DRIVE - || (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5 && aiData->abilities[battlerAtk] == ABILITY_LIGHTNING_ROD))) + || (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && aiData->abilities[battlerAtk] == ABILITY_LIGHTNING_ROD))) { ADJUST_SCORE(DECENT_EFFECT); } @@ -5697,17 +5697,14 @@ static s32 AI_CalcAdditionalEffectScore(u32 battlerAtk, u32 battlerDef, u32 move u32 i; u32 additionalEffectCount = GetMoveAdditionalEffectCount(move); + if (IsSheerForceAffected(move, aiData->abilities[battlerAtk])) + return score; + // check move additional effects that are likely to happen for (i = 0; i < additionalEffectCount; i++) { const struct AdditionalEffect *additionalEffect = GetMoveAdditionalEffectById(move, i); - if (aiData->abilities[battlerAtk] == ABILITY_SHEER_FORCE) - { - if ((additionalEffect->chance > 0) != additionalEffect->sheerForceOverride) - continue; - } - // Only consider effects with a guaranteed chance to happen if (!MoveEffectIsGuaranteed(battlerAtk, aiData->abilities[battlerAtk], additionalEffect)) continue; diff --git a/src/battle_ai_switch_items.c b/src/battle_ai_switch_items.c index 5b924d23e5..05091a815e 100644 --- a/src/battle_ai_switch_items.c +++ b/src/battle_ai_switch_items.c @@ -298,7 +298,7 @@ static bool32 ShouldSwitchIfHasBadOdds(u32 battler) // Check if mon gets one shot if (maxDamageTaken > gBattleMons[battler].hp - && !(gItemsInfo[gBattleMons[battler].item].holdEffect == HOLD_EFFECT_FOCUS_SASH || (!IsMoldBreakerTypeAbility(opposingBattler, gAiLogicData->abilities[opposingBattler]) && B_STURDY >= GEN_5 && aiAbility == ABILITY_STURDY))) + && !(gItemsInfo[gBattleMons[battler].item].holdEffect == HOLD_EFFECT_FOCUS_SASH || (!IsMoldBreakerTypeAbility(opposingBattler, gAiLogicData->abilities[opposingBattler]) && GetConfig(CONFIG_STURDY) >= GEN_5 && aiAbility == ABILITY_STURDY))) { getsOneShot = TRUE; } @@ -534,14 +534,14 @@ static bool32 FindMonThatAbsorbsOpponentsMove(u32 battler) { absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_WATER_ABSORB; absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_DRY_SKIN; - if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) + if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5) absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_STORM_DRAIN; } else if (incomingType == TYPE_ELECTRIC || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_ELECTRIC)) { absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_VOLT_ABSORB; absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_MOTOR_DRIVE; - if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) + if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5) absorbingTypeAbilities[numAbsorbingAbilities++] = ABILITY_LIGHTNING_ROD; } else if (incomingType == TYPE_GRASS || (isOpposingBattlerChargingOrInvulnerable && incomingType == TYPE_GRASS)) @@ -1757,7 +1757,7 @@ static u32 GetSwitchinStatusDamage(u32 battler) { if (status & STATUS1_BURN) { - if (B_BURN_DAMAGE >= GEN_7) + if (GetConfig(CONFIG_BURN_DAMAGE) >= GEN_7) statusDamage = maxHP / 16; else statusDamage = maxHP / 8; @@ -1768,7 +1768,7 @@ static u32 GetSwitchinStatusDamage(u32 battler) } else if (status & STATUS1_FROSTBITE) { - if (B_BURN_DAMAGE >= GEN_7) + if (GetConfig(CONFIG_BURN_DAMAGE) >= GEN_7) statusDamage = maxHP / 16; else statusDamage = maxHP / 8; @@ -1852,7 +1852,7 @@ static u32 GetSwitchinHitsToKO(s32 damageTaken, u32 battler) currentHP = currentHP - damageTaken; // One shot prevention effects - if (damageTaken >= maxHP && startingHP == maxHP && (heldItemEffect == HOLD_EFFECT_FOCUS_SASH || (!opponentCanBreakMold && B_STURDY >= GEN_5 && ability == ABILITY_STURDY)) && hitsToKO < 1) + if (damageTaken >= maxHP && startingHP == maxHP && (heldItemEffect == HOLD_EFFECT_FOCUS_SASH || (!opponentCanBreakMold && GetConfig(CONFIG_STURDY) >= GEN_5 && ability == ABILITY_STURDY)) && hitsToKO < 1) currentHP = 1; // If mon is still alive, apply weather impact first, as it might KO the mon before it can heal with its item (order is weather -> item -> status) diff --git a/src/battle_ai_util.c b/src/battle_ai_util.c index 413bbcc8ac..20ebfdb27f 100644 --- a/src/battle_ai_util.c +++ b/src/battle_ai_util.c @@ -1030,6 +1030,9 @@ static bool32 AI_IsMoveEffectInPlus(u32 battlerAtk, u32 battlerDef, u32 move, s3 enum Ability abilityDef = gAiLogicData->abilities[battlerDef]; enum Ability abilityAtk = gAiLogicData->abilities[battlerAtk]; + if (IsSheerForceAffected(move, abilityAtk)) + return FALSE; + switch (GetMoveEffect(move)) { case EFFECT_HIT_ESCAPE: @@ -1469,7 +1472,7 @@ bool32 CanEndureHit(u32 battler, u32 battlerTarget, u32 move) if (!DoesBattlerIgnoreAbilityChecks(battler, gAiLogicData->abilities[battler], move)) { - if (B_STURDY >= GEN_5 && gAiLogicData->abilities[battlerTarget] == ABILITY_STURDY) + if (GetConfig(CONFIG_STURDY) >= GEN_5 && gAiLogicData->abilities[battlerTarget] == ABILITY_STURDY) return TRUE; if (IsMimikyuDisguised(battlerTarget)) return TRUE; @@ -3351,7 +3354,7 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, enum Ability defAbility if (!IsBattleMoveStatus(move) && ((gAiLogicData->shouldSwitch & (1u << battlerAtk)) || (AI_BattlerAtMaxHp(battlerDef) && (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH - || (B_STURDY >= GEN_5 && defAbility == ABILITY_STURDY) + || (GetConfig(CONFIG_STURDY) >= GEN_5 && defAbility == ABILITY_STURDY) || defAbility == ABILITY_MULTISCALE || defAbility == ABILITY_SHADOW_SHIELD)))) return SHOULD_PIVOT; // pivot to break sash/sturdy/multiscale @@ -3359,7 +3362,7 @@ enum AIPivot ShouldPivot(u32 battlerAtk, u32 battlerDef, enum Ability defAbility else if (!hasStatBoost) { if (!IsBattleMoveStatus(move) && (AI_BattlerAtMaxHp(battlerDef) && (gAiLogicData->holdEffects[battlerDef] == HOLD_EFFECT_FOCUS_SASH - || (B_STURDY >= GEN_5 && defAbility == ABILITY_STURDY) + || (GetConfig(CONFIG_STURDY) >= GEN_5 && defAbility == ABILITY_STURDY) || defAbility == ABILITY_MULTISCALE || defAbility == ABILITY_SHADOW_SHIELD))) return SHOULD_PIVOT; // pivot to break sash/sturdy/multiscale @@ -5241,6 +5244,9 @@ bool32 ShouldUseZMove(u32 battlerAtk, u32 battlerDef, u32 chosenMove) return FALSE; } + if (GetMoveEffect(chosenMove) == EFFECT_LAST_RESORT && !CanUseLastResort(battlerAtk)) + return TRUE; + uq4_12_t effectiveness; struct SimulatedDamage dmg; @@ -5766,7 +5772,7 @@ bool32 ShouldTriggerAbility(u32 battlerAtk, u32 battlerDef, enum Ability ability { case ABILITY_LIGHTNING_ROD: case ABILITY_STORM_DRAIN: - if (B_REDIRECT_ABILITY_IMMUNITY < GEN_5) + if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) < GEN_5) return FALSE; else return (BattlerStatCanRise(battlerDef, ability, STAT_SPATK) && HasMoveWithCategory(battlerDef, DAMAGE_CATEGORY_SPECIAL)); diff --git a/src/battle_end_turn.c b/src/battle_end_turn.c index ca4c46fa11..ef5539ebbf 100644 --- a/src/battle_end_turn.c +++ b/src/battle_end_turn.c @@ -531,7 +531,7 @@ static bool32 HandleEndTurnBurn(u32 battler) && IsBattlerAlive(battler) && !IsAbilityAndRecord(battler, ability, ABILITY_MAGIC_GUARD)) { - s32 burnDamage = GetNonDynamaxMaxHP(battler) / (B_BURN_DAMAGE >= GEN_7 ? 16 : 8); + s32 burnDamage = GetNonDynamaxMaxHP(battler) / (GetConfig(CONFIG_BURN_DAMAGE) >= GEN_7 ? 16 : 8); if (ability == ABILITY_HEATPROOF) { if (burnDamage > (burnDamage / 2) + 1) // Record ability if the burn takes less damage than it normally would. @@ -556,7 +556,7 @@ static bool32 HandleEndTurnFrostbite(u32 battler) && IsBattlerAlive(battler) && !IsAbilityAndRecord(battler, GetBattlerAbility(battler), ABILITY_MAGIC_GUARD)) { - SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / (B_BURN_DAMAGE >= GEN_7 ? 16 : 8)); + SetPassiveDamageAmount(battler, GetNonDynamaxMaxHP(battler) / (GetConfig(CONFIG_BURN_DAMAGE) >= GEN_7 ? 16 : 8)); BattleScriptExecute(BattleScript_FrostbiteTurnDmg); effect = TRUE; } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 92c4bff67c..9dbbbe914d 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -1929,7 +1929,7 @@ static void Cmd_adjustdamage(void) gLastUsedItem = gBattleMons[battlerDef].item; gBattleStruct->moveResultFlags[battlerDef] |= MOVE_RESULT_FOE_HUNG_ON; } - else if (B_STURDY >= GEN_5 && GetBattlerAbility(battlerDef) == ABILITY_STURDY && IsBattlerAtMaxHp(battlerDef)) + else if (GetConfig(CONFIG_STURDY) >= GEN_5 && GetBattlerAbility(battlerDef) == ABILITY_STURDY && IsBattlerAtMaxHp(battlerDef)) { enduredHit |= 1u << battlerDef; RecordAbilityBattle(battlerDef, ABILITY_STURDY); @@ -3049,7 +3049,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, enum MoveEffect moveEffect, c if (!primary && !affectsUser && IsMoveEffectBlockedByTarget(battlerAbility)) moveEffect = MOVE_EFFECT_NONE; else if (!primary - && TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove) + && IsSheerForceAffected(gCurrentMove, GetBattlerAbility(battler)) && !(GetMoveEffect(gCurrentMove) == EFFECT_ORDER_UP && gBattleStruct->battlerState[gBattlerAttacker].commanderSpecies != SPECIES_NONE)) moveEffect = MOVE_EFFECT_NONE; else if (!IsBattlerAlive(gEffectBattler) && !activateAfterFaint) @@ -6400,7 +6400,7 @@ static void Cmd_moveend(void) && gBattlerTarget != gBattlerAttacker && !IsBattlerAlly(gBattlerTarget, gBattlerAttacker) && gProtectStructs[gBattlerTarget].physicalBattlerId == gBattlerAttacker - && !TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)) + && !IsSheerForceAffected(gCurrentMove, GetBattlerAbility(gBattlerAttacker))) { gProtectStructs[gBattlerTarget].shellTrap = TRUE; // Change move order in double battles, so the hit mon with shell trap moves immediately after being hit. @@ -6660,7 +6660,7 @@ static void Cmd_moveend(void) gBattleScripting.moveendState++; break; case MOVEEND_SHEER_FORCE: - if (TestIfSheerForceAffected(gBattlerAttacker, gCurrentMove)) + if (IsSheerForceAffected(gCurrentMove, GetBattlerAbility(gBattlerAttacker))) gBattleScripting.moveendState = MOVEEND_EJECT_PACK; else gBattleScripting.moveendState++; @@ -9525,7 +9525,7 @@ static bool32 IsElectricAbilityAffected(u32 battler, enum Ability ability) moveType = GetMoveType(gCurrentMove); if (moveType == TYPE_ELECTRIC - && (ability != ABILITY_LIGHTNING_ROD || B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) + && (ability != ABILITY_LIGHTNING_ROD || GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5) && GetBattlerAbility(battler) == ability) return TRUE; else @@ -11526,120 +11526,75 @@ static void Cmd_settypetorandomresistance(void) // Before Gen 5 Conversion 2 only worked on a move the attacker was actually hit by. // This changed later to the last move used by the selected target. - if (B_UPDATED_CONVERSION_2 < GEN_5) + u32 moveToCheck; + u32 typeToCheck; + + if (GetConfig(CONFIG_UPDATED_CONVERSION_2) < GEN_5) { - if (gLastLandedMoves[gBattlerAttacker] == MOVE_NONE - || gLastLandedMoves[gBattlerAttacker] == MOVE_UNAVAILABLE) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (gBattleMoveEffects[GetMoveEffect(gLastLandedMoves[gBattlerAttacker])].twoTurnEffect - && gBattleMons[gLastHitBy[gBattlerAttacker]].volatiles.multipleTurns) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (gLastHitByType[gBattlerAttacker] == TYPE_STELLAR || gLastHitByType[gBattlerAttacker] == TYPE_MYSTERY) - { - gBattlescriptCurrInstr = cmd->failInstr; - } + moveToCheck = gLastLandedMoves[gBattlerAttacker]; + if (GetMoveEffect(moveToCheck) == EFFECT_STRUGGLE) + typeToCheck = TYPE_NORMAL; else - { - u32 i, resistTypes = 0; - u32 hitByType = gLastHitByType[gBattlerAttacker]; - - for (i = 0; i < NUMBER_OF_MON_TYPES; i++) // Find all types that resist. - { - switch (GetTypeModifier(hitByType, i)) - { - case UQ_4_12(0): - case UQ_4_12(0.5): - resistTypes |= 1u << i; - break; - } - } - - while (resistTypes != 0) - { - i = Random() % NUMBER_OF_MON_TYPES; - if (resistTypes & 1u << i) - { - if (IS_BATTLER_OF_TYPE(gBattlerAttacker, i)) - { - resistTypes &= ~(1u << i); // Type resists, but the user is already of this type. - } - else - { - SET_BATTLER_TYPE(gBattlerAttacker, i); - PREPARE_TYPE_BUFFER(gBattleTextBuff1, i); - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - } - } - - gBattlescriptCurrInstr = cmd->failInstr; - } + typeToCheck = gLastHitByType[gBattlerAttacker]; } else { - if (gLastResultingMoves[gBattlerTarget] == MOVE_NONE - || gLastResultingMoves[gBattlerTarget] == MOVE_UNAVAILABLE - || gLastResultingMoves[gBattlerTarget] == MOVE_STRUGGLE) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (!BreaksThroughSemiInvulnerablity(gBattlerTarget, gCurrentMove)) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (gLastUsedMoveType[gBattlerTarget] == TYPE_NONE || gLastUsedMoveType[gBattlerTarget] == TYPE_STELLAR || gLastUsedMoveType[gBattlerTarget] == TYPE_MYSTERY) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA) - { - gBattlescriptCurrInstr = cmd->failInstr; - } - else - { - u32 i, resistTypes = 0; + moveToCheck = gLastResultingMoves[gBattlerTarget]; + typeToCheck = gLastUsedMoveType[gBattlerTarget]; + } - for (i = 0; i < NUMBER_OF_MON_TYPES; i++) // Find all types that resist. + if (moveToCheck == MOVE_NONE + || moveToCheck == MOVE_UNAVAILABLE) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else if (!BreaksThroughSemiInvulnerablity(gBattlerTarget, moveToCheck)) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_TERA) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else if (typeToCheck == TYPE_NONE || typeToCheck == TYPE_STELLAR || typeToCheck == TYPE_MYSTERY) + { + gBattlescriptCurrInstr = cmd->failInstr; + } + else + { + u32 i, resistTypes = 0; + + for (i = 0; i < NUMBER_OF_MON_TYPES; i++) // Find all types that resist. + { + switch (GetTypeModifier(typeToCheck, i)) { - switch (GetTypeModifier(gLastUsedMoveType[gBattlerTarget], i)) + case UQ_4_12(0): + case UQ_4_12(0.5): + resistTypes |= 1u << i; + break; + } + } + + while (resistTypes != 0) + { + i = Random() % NUMBER_OF_MON_TYPES; + if (resistTypes & 1u << i) + { + if (IS_BATTLER_OF_TYPE(gBattlerAttacker, i)) { - case UQ_4_12(0): - case UQ_4_12(0.5): - resistTypes |= 1u << i; - break; + resistTypes &= ~(1u << i); // Type resists, but the user is already of this type. + } + else + { + SET_BATTLER_TYPE(gBattlerAttacker, i); + PREPARE_TYPE_BUFFER(gBattleTextBuff1, i); + gBattlescriptCurrInstr = cmd->nextInstr; + return; } } - - while (resistTypes != 0) - { - i = Random() % NUMBER_OF_MON_TYPES; - if (resistTypes & 1u << i) - { - if (IS_BATTLER_OF_TYPE(gBattlerAttacker, i)) - { - resistTypes &= ~(1u << i); // Type resists, but the user is already of this type. - } - else - { - SET_BATTLER_TYPE(gBattlerAttacker, i); - PREPARE_TYPE_BUFFER(gBattleTextBuff1, i); - gBattlescriptCurrInstr = cmd->nextInstr; - return; - } - } - } - - gBattlescriptCurrInstr = cmd->failInstr; } + + gBattlescriptCurrInstr = cmd->failInstr; } } @@ -11739,7 +11694,7 @@ static void Cmd_settailwind(void) if (!(gSideStatuses[side] & SIDE_STATUS_TAILWIND)) { gSideStatuses[side] |= SIDE_STATUS_TAILWIND; - gSideTimers[side].tailwindTimer = (B_TAILWIND_TURNS >= GEN_5 ? 4 : 3); + gSideTimers[side].tailwindTimer = (GetConfig(CONFIG_TAILWIND_TURNS) >= GEN_5 ? 4 : 3); gBattlescriptCurrInstr = cmd->nextInstr; } else diff --git a/src/battle_util.c b/src/battle_util.c index 888580f3fd..11a5ef583c 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -3552,14 +3552,14 @@ bool32 CanAbilityAbsorbMove(u32 battlerAtk, u32 battlerDef, enum Ability ability } break; case ABILITY_LIGHTNING_ROD: - if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5 && moveType == TYPE_ELECTRIC && GetBattlerMoveTargetType(battlerAtk, move) != MOVE_TARGET_ALL_BATTLERS) + if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && moveType == TYPE_ELECTRIC && GetBattlerMoveTargetType(battlerAtk, move) != MOVE_TARGET_ALL_BATTLERS) { effect = MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY; statId = STAT_SPATK; } break; case ABILITY_STORM_DRAIN: - if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5 && moveType == TYPE_WATER) + if (GetConfig(CONFIG_REDIRECT_ABILITY_IMMUNITY) >= GEN_5 && moveType == TYPE_WATER) { effect = MOVE_ABSORBED_BY_STAT_INCREASE_ABILITY; statId = STAT_SPATK; @@ -5500,7 +5500,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, u32 battler, enum Ability ab gBattleScripting.battler = gBattlerAbility = gBattlerTarget; RecordAbilityBattle(gBattlerTarget, ABILITY_SYNCHRONIZE); - if (B_SYNCHRONIZE_TOXIC < GEN_5 && gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC) + if (GetConfig(CONFIG_SYNCHRONIZE_TOXIC) < GEN_5 && gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC) gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_POISON; if (CanSetNonVolatileStatus( @@ -5530,7 +5530,7 @@ u32 AbilityBattleEffects(enum AbilityEffect caseID, u32 battler, enum Ability ab gBattleScripting.battler = gBattlerAbility = gBattlerAttacker; RecordAbilityBattle(gBattlerAttacker, ABILITY_SYNCHRONIZE); - if (B_SYNCHRONIZE_TOXIC < GEN_5 && gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC) + if (GetConfig(CONFIG_SYNCHRONIZE_TOXIC) < GEN_5 && gBattleStruct->synchronizeMoveEffect == MOVE_EFFECT_TOXIC) gBattleStruct->synchronizeMoveEffect = MOVE_EFFECT_POISON; if (CanSetNonVolatileStatus( @@ -8798,7 +8798,7 @@ static inline uq4_12_t CalcTypeEffectivenessMultiplierInternal(struct DamageCont } // Iron Ball ignores type modifiers for flying-type mons if it is the only source of grounding - if (B_IRON_BALL >= GEN_5 + if (GetConfig(CONFIG_IRON_BALL) >= GEN_5 && ctx->moveType == TYPE_GROUND && ctx->holdEffectDef == HOLD_EFFECT_IRON_BALL && IS_BATTLER_OF_TYPE(ctx->battlerDef, TYPE_FLYING) @@ -9743,7 +9743,7 @@ bool32 CanFling(u32 battler) u16 item = gBattleMons[battler].item; if (item == ITEM_NONE - || (B_KLUTZ_FLING_INTERACTION >= GEN_5 && GetBattlerAbility(battler) == ABILITY_KLUTZ) + || (GetConfig(CONFIG_KLUTZ_FLING_INTERACTION) >= GEN_5 && GetBattlerAbility(battler) == ABILITY_KLUTZ) || gFieldStatuses & STATUS_FIELD_MAGIC_ROOM || gBattleMons[battler].volatiles.embargo || GetFlingPowerFromItemId(item) == 0 @@ -9892,9 +9892,9 @@ bool32 IsBattlerAffectedByHazards(u32 battler, bool32 toxicSpikes) return ret; } -bool32 TestIfSheerForceAffected(u32 battler, u16 move) +bool32 IsSheerForceAffected(u16 move, enum Ability ability) { - return GetBattlerAbility(battler) == ABILITY_SHEER_FORCE && MoveIsAffectedBySheerForce(move); + return ability == ABILITY_SHEER_FORCE && MoveIsAffectedBySheerForce(move); } // This function is the body of "jumpifstat", but can be used dynamically in a function diff --git a/src/pokemon.c b/src/pokemon.c index 68775003e0..89da3a21f9 100644 --- a/src/pokemon.c +++ b/src/pokemon.c @@ -1554,63 +1554,6 @@ static void CreateEventMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedI SetMonData(mon, MON_DATA_MODERN_FATEFUL_ENCOUNTER, &isModernFatefulEncounter); } -// If FALSE, should load this game's Deoxys form. If TRUE, should load normal Deoxys form -bool8 ShouldIgnoreDeoxysForm(u8 caseId, u8 battler) -{ - switch (caseId) - { - case 0: - default: - return FALSE; - case 1: // Player's side in battle - if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - return FALSE; - if (!gMain.inBattle) - return FALSE; - if (gLinkPlayers[GetMultiplayerId()].id == battler) - return FALSE; - break; - case 2: - break; - case 3: // Summary Screen - if (!(gBattleTypeFlags & BATTLE_TYPE_MULTI)) - return FALSE; - if (!gMain.inBattle) - return FALSE; - if (battler == 1 || battler == 4 || battler == 5) - return TRUE; - return FALSE; - case 4: - break; - case 5: // In move animation, e.g. in Role Play or Snatch - if (gBattleTypeFlags & BATTLE_TYPE_LINK) - { - if (!gMain.inBattle) - return FALSE; - if (gBattleTypeFlags & BATTLE_TYPE_MULTI) - { - if (gLinkPlayers[GetMultiplayerId()].id == battler) - return FALSE; - } - else - { - if (IsOnPlayerSide(battler)) - return FALSE; - } - } - else - { - if (!gMain.inBattle) - return FALSE; - if (IsOnPlayerSide(battler)) - return FALSE; - } - break; - } - - return TRUE; -} - u16 GetUnionRoomTrainerPic(void) { u8 linkId; diff --git a/src/trainer_pools.c b/src/trainer_pools.c index 6f0e57fdb2..faf93fcc9e 100644 --- a/src/trainer_pools.c +++ b/src/trainer_pools.c @@ -167,6 +167,10 @@ static u32 PickMonFromPool(const struct Trainer *trainer, u8 *poolIndexArray, u3 // If no mon has been found yet continue looking if (monIndex == POOL_SLOT_DISABLED) monIndex = pickFunctions.OtherFunction(trainer, poolIndexArray, partyIndex, monsCount, battleTypeFlags, rules); + // If a mon still hasn't been found, return POOL_SLOT_DISABLED which makes party generation default to regular party generation + if (monIndex == POOL_SLOT_DISABLED) + return monIndex; + u32 chosenTags = trainer->party[monIndex].tags; u16 chosenSpecies = trainer->party[monIndex].species; u16 chosenItem = trainer->party[monIndex].heldItem; diff --git a/test/battle/ability/lightning_rod.c b/test/battle/ability/lightning_rod.c index aec2e7fea4..e1fedbe17d 100644 --- a/test/battle/ability/lightning_rod.c +++ b/test/battle/ability/lightning_rod.c @@ -1,16 +1,20 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Lightning Rod absorbs Electric-type moves and increases the Sp. Attack [Gen5+]") +SINGLE_BATTLE_TEST("Lightning Rod absorbs Electric-type moves and increases the Sp. Attack (Gen5+)") { + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config); ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); } } WHEN { TURN { MOVE(player, MOVE_THUNDERBOLT); MOVE(opponent, MOVE_CELEBRATE); } } SCENE { - if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) { + if (config >= GEN_5) { NONE_OF { ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player); HP_BAR(opponent); @@ -29,13 +33,21 @@ SINGLE_BATTLE_TEST("Lightning Rod absorbs Electric-type moves and increases the } ANIMATION(ANIM_TYPE_MOVE, MOVE_CELEBRATE, opponent); } THEN { - EXPECT_EQ(gBattleHistory->abilities[1], ABILITY_LIGHTNING_ROD); // Check if the correct ability has been recorded + if (config >= GEN_5) { + EXPECT_EQ(gBattleHistory->abilities[1], ABILITY_LIGHTNING_ROD); // Check if the correct ability has been recorded + } else { + EXPECT_EQ(gBattleHistory->abilities[1], ABILITY_NONE); + } } } DOUBLE_BATTLE_TEST("Lightning Rod forces single-target Electric-type moves to target the Pokémon with this Ability.") { + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config); ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -49,7 +61,7 @@ DOUBLE_BATTLE_TEST("Lightning Rod forces single-target Electric-type moves to ta MOVE(opponentRight, MOVE_CELEBRATE); } } SCENE { - if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) { + if (config >= GEN_5) { NONE_OF { HP_BAR(opponentLeft); HP_BAR(opponentRight); @@ -86,7 +98,7 @@ DOUBLE_BATTLE_TEST("Lightning Rod redirects an ally's attack") TURN { MOVE(opponentRight, MOVE_THUNDERBOLT, target: playerLeft); } } SCENE { MESSAGE("The opposing Wobbuffet used Thunderbolt!"); - if (B_REDIRECT_ABILITY_ALLIES >= GEN_5) + if (B_REDIRECT_ABILITY_ALLIES >= GEN_4) { NOT HP_BAR(playerLeft); ABILITY_POPUP(opponentLeft, ABILITY_LIGHTNING_ROD); @@ -100,9 +112,10 @@ DOUBLE_BATTLE_TEST("Lightning Rod redirects an ally's attack") } } -DOUBLE_BATTLE_TEST("Lightning Rod absorbs moves that targets all battlers but does not redirect") +DOUBLE_BATTLE_TEST("Lightning Rod absorbs moves that targets all battlers but does not redirect (Gen6+)") { GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); diff --git a/test/battle/ability/parental_bond.c b/test/battle/ability/parental_bond.c index 824399379c..d8be7c76f2 100644 --- a/test/battle/ability/parental_bond.c +++ b/test/battle/ability/parental_bond.c @@ -109,8 +109,9 @@ SINGLE_BATTLE_TEST("Parental Bond-converted moves only hit once on Lightning Rod enum Type type; enum Ability ability; PARAMETRIZE { move = MOVE_THUNDERBOLT; ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; type = TYPE_ELECTRIC; } - PARAMETRIZE { move = MOVE_SURF; ability = ABILITY_STORM_DRAIN; species = SPECIES_LILEEP; type = TYPE_WATER; } + PARAMETRIZE { move = MOVE_SURF; ability = ABILITY_STORM_DRAIN; species = SPECIES_LILEEP; type = TYPE_WATER; } GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); ASSUME(GetMoveStrikeCount(move) < 2); ASSUME(GetMoveType(move) == type); PLAYER(SPECIES_KANGASKHAN) { Item(ITEM_KANGASKHANITE); } diff --git a/test/battle/ability/stalwart.c b/test/battle/ability/stalwart.c index 6bebe17cb6..3cca8e58ad 100644 --- a/test/battle/ability/stalwart.c +++ b/test/battle/ability/stalwart.c @@ -21,10 +21,13 @@ DOUBLE_BATTLE_TEST("Stalwart ignores redirection from Follow-Me") DOUBLE_BATTLE_TEST("Stalwart stops Lightning Rod and Storm Drain from redirecting moves") { enum Ability ability; - u32 species; - PARAMETRIZE { ability = ABILITY_STORM_DRAIN; species = SPECIES_LUMINEON; } - PARAMETRIZE { ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; } + u32 species, config; + PARAMETRIZE { ability = ABILITY_STORM_DRAIN; species = SPECIES_LUMINEON; config = GEN_4; } + PARAMETRIZE { ability = ABILITY_STORM_DRAIN; species = SPECIES_LUMINEON; config = GEN_5; } + PARAMETRIZE { ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; config = GEN_4; } + PARAMETRIZE { ability = ABILITY_LIGHTNING_ROD; species = SPECIES_RAICHU; config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config); ASSUME(GetMoveType(MOVE_SPARK) == TYPE_ELECTRIC); ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_STALWART); } @@ -39,15 +42,14 @@ DOUBLE_BATTLE_TEST("Stalwart stops Lightning Rod and Storm Drain from redirectin MOVE(playerLeft, MOVE_WATER_GUN, target: opponentRight); } } SCENE { - if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) { - HP_BAR(opponentRight); + HP_BAR(opponentRight); + if (config >= GEN_5) { NONE_OF { ABILITY_POPUP(opponentLeft, ability); ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft); MESSAGE("The opposing Raichu's Sp. Atk rose!"); } } else { - HP_BAR(opponentRight); NONE_OF { HP_BAR(opponentLeft); } diff --git a/test/battle/ability/storm_drain.c b/test/battle/ability/storm_drain.c index 962317b108..c1cf5c890b 100644 --- a/test/battle/ability/storm_drain.c +++ b/test/battle/ability/storm_drain.c @@ -1,16 +1,20 @@ #include "global.h" #include "test/battle.h" -SINGLE_BATTLE_TEST("Storm Drain absorbs Water-type moves and increases the Sp. Attack [Gen5+]") +SINGLE_BATTLE_TEST("Storm Drain absorbs Water-type moves and increases the Sp. Attack (Gen5+)") { + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config); ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_GASTRODON_EAST) { Ability(ABILITY_STORM_DRAIN); } } WHEN { TURN { MOVE(player, MOVE_WATER_GUN); MOVE(opponent, MOVE_CELEBRATE); } } SCENE { - if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) { + if (config >= GEN_5) { NONE_OF { ANIMATION(ANIM_TYPE_MOVE, MOVE_WATER_GUN, player); HP_BAR(opponent); @@ -33,7 +37,11 @@ SINGLE_BATTLE_TEST("Storm Drain absorbs Water-type moves and increases the Sp. A DOUBLE_BATTLE_TEST("Storm Drain forces single-target Water-type moves to target the Pokémon with this Ability.") { + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config); ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -47,7 +55,7 @@ DOUBLE_BATTLE_TEST("Storm Drain forces single-target Water-type moves to target MOVE(opponentRight, MOVE_CELEBRATE); } } SCENE { - if (B_REDIRECT_ABILITY_IMMUNITY >= GEN_5) { + if (config >= GEN_5) { NONE_OF { HP_BAR(opponentLeft); HP_BAR(opponentRight); diff --git a/test/battle/ability/sturdy.c b/test/battle/ability/sturdy.c index 5ba7e16ea8..7087de3a02 100644 --- a/test/battle/ability/sturdy.c +++ b/test/battle/ability/sturdy.c @@ -18,18 +18,37 @@ SINGLE_BATTLE_TEST("Sturdy prevents OHKO moves") } } -SINGLE_BATTLE_TEST("Sturdy prevents OHKOs") +SINGLE_BATTLE_TEST("Sturdy prevents OHKOs (Gen5+)") { + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_STURDY, config); PLAYER(SPECIES_GEODUDE) { Ability(ABILITY_STURDY); MaxHP(100); HP(100); } + PLAYER(SPECIES_GEODUDE); OPPONENT(SPECIES_WOBBUFFET); } WHEN { - TURN { MOVE(opponent, MOVE_SEISMIC_TOSS); } + TURN { + MOVE(opponent, MOVE_SEISMIC_TOSS); + if (config < GEN_5) { + SEND_OUT(player, 1); + } + } } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_SEISMIC_TOSS, opponent); - HP_BAR(player, hp: 1); - ABILITY_POPUP(player, ABILITY_STURDY); - MESSAGE("Geodude endured the hit using Sturdy!"); + if (config >= GEN_5) { + HP_BAR(player, hp: 1); + ABILITY_POPUP(player, ABILITY_STURDY); + MESSAGE("Geodude endured the hit using Sturdy!"); + } else { + HP_BAR(player, hp: 0); + NONE_OF { + ABILITY_POPUP(player, ABILITY_STURDY); + MESSAGE("Geodude endured the hit using Sturdy!"); + } + SEND_IN_MESSAGE("Geodude"); + } } } diff --git a/test/battle/ability/synchronize.c b/test/battle/ability/synchronize.c index 8e92936e41..8604814fab 100644 --- a/test/battle/ability/synchronize.c +++ b/test/battle/ability/synchronize.c @@ -3,11 +3,13 @@ SINGLE_BATTLE_TEST("Synchronize will mirror back non volatile status back at opposing mon") { - + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { ASSUME(GetMoveEffect(MOVE_TOXIC) == EFFECT_NON_VOLATILE_STATUS); ASSUME(GetMoveNonVolatileStatus(MOVE_TOXIC) == MOVE_EFFECT_TOXIC); - ASSUME(GetMoveNonVolatileStatus(MOVE_TOXIC) == MOVE_EFFECT_TOXIC); + WITH_CONFIG(CONFIG_SYNCHRONIZE_TOXIC, config); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_ABRA) { Ability(ABILITY_SYNCHRONIZE); } } WHEN { @@ -18,7 +20,10 @@ SINGLE_BATTLE_TEST("Synchronize will mirror back non volatile status back at opp STATUS_ICON(opponent, badPoison: TRUE); ABILITY_POPUP(opponent, ABILITY_SYNCHRONIZE); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, player); - STATUS_ICON(player, badPoison: TRUE); + if (config >= GEN_5) + STATUS_ICON(player, badPoison: TRUE); + else + STATUS_ICON(player, poison: TRUE); } } diff --git a/test/battle/ai/ai.c b/test/battle/ai/ai.c index 61100a9161..0cb4a97375 100644 --- a/test/battle/ai/ai.c +++ b/test/battle/ai/ai.c @@ -846,6 +846,7 @@ AI_DOUBLE_BATTLE_TEST("AI sees opposing drain ability") ASSUME(GetMoveType(MOVE_THUNDERBOLT) == TYPE_ELECTRIC); ASSUME(GetMoveType(MOVE_RAZOR_LEAF) != TYPE_ELECTRIC); ASSUME(GetMoveType(MOVE_METAL_CLAW) != TYPE_ELECTRIC); + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT); PLAYER(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); Moves(MOVE_CELEBRATE); } PLAYER(SPECIES_KRABBY) { Ability(ABILITY_VOLT_ABSORB); Moves(MOVE_CELEBRATE); } diff --git a/test/battle/ai/ai_calc_best_move_score.c b/test/battle/ai/ai_calc_best_move_score.c index 88525249dc..7fcf0ced24 100644 --- a/test/battle/ai/ai_calc_best_move_score.c +++ b/test/battle/ai/ai_calc_best_move_score.c @@ -133,3 +133,16 @@ AI_SINGLE_BATTLE_TEST("HasMoveThatChangesKOThreshold - AI should not see self-ta TURN { MOVE(player, MOVE_HAMMER_ARM); EXPECT_MOVE(opponent, move == MOVE_EARTHQUAKE ? MOVE_NASTY_PLOT : MOVE_AURA_SPHERE); } } } + +AI_SINGLE_BATTLE_TEST("AI_IsMoveEffectInPlus - AI should not see secondary effect of Sheer Force boosted moves as beneficial") +{ + GIVEN { + ASSUME(GetMovePower(MOVE_PSYCHIC) == 90); + ASSUME(MoveHasAdditionalEffect(MOVE_PSYCHIC, MOVE_EFFECT_SP_DEF_MINUS_1) == TRUE); + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES | AI_FLAG_OMNISCIENT); + PLAYER(SPECIES_STEELIX) { Level(100); Nature(NATURE_SASSY); Item(ITEM_STEELIXITE); Ability(ABILITY_STURDY); Speed(58); Moves(MOVE_GYRO_BALL); } + OPPONENT(SPECIES_BRAVIARY_HISUI) { Level(100); Nature(NATURE_TIMID); Ability(ABILITY_SHEER_FORCE); Speed(251); Moves(MOVE_PSYCHIC, MOVE_NIGHT_SHADE); } + } WHEN { + TURN { MOVE(player, MOVE_GYRO_BALL); SCORE_EQ_VAL(opponent, MOVE_PSYCHIC, 101); SCORE_EQ_VAL(opponent, MOVE_NIGHT_SHADE, 101); } + } +} diff --git a/test/battle/ai/ai_doubles.c b/test/battle/ai/ai_doubles.c index a35ff248bd..746789cf5e 100644 --- a/test/battle/ai/ai_doubles.c +++ b/test/battle/ai/ai_doubles.c @@ -542,54 +542,28 @@ AI_DOUBLE_BATTLE_TEST("AI sees corresponding absorbing abilities on partners") } } -AI_DOUBLE_BATTLE_TEST("AI treats an ally's redirection ability appropriately (gen 4)") +AI_DOUBLE_BATTLE_TEST("AI treats an ally's redirection ability appropriately") { - KNOWN_FAILING; - ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY); - ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC); - ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY); - ASSUME(GetMoveType(MOVE_SURF) == TYPE_WATER); + u32 ability, move, species, config, expectedMove; - enum Ability ability; - u32 move, species; - - PARAMETRIZE { species = SPECIES_SEAKING; ability = ABILITY_LIGHTNING_ROD; move = MOVE_DISCHARGE; } - PARAMETRIZE { species = SPECIES_SHELLOS; ability = ABILITY_STORM_DRAIN; move = MOVE_SURF; } + PARAMETRIZE { species = SPECIES_SEAKING; ability = ABILITY_LIGHTNING_ROD; move = MOVE_DISCHARGE; config = GEN_4; expectedMove = MOVE_HEADBUTT; } + PARAMETRIZE { species = SPECIES_SHELLOS; ability = ABILITY_STORM_DRAIN; move = MOVE_SURF; config = GEN_4; expectedMove = MOVE_HEADBUTT; } + PARAMETRIZE { species = SPECIES_SEAKING; ability = ABILITY_LIGHTNING_ROD; move = MOVE_DISCHARGE; config = GEN_5; expectedMove = MOVE_DISCHARGE; } + PARAMETRIZE { species = SPECIES_SHELLOS; ability = ABILITY_STORM_DRAIN; move = MOVE_SURF; config = GEN_5; expectedMove = MOVE_SURF; } GIVEN { + ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC); + ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY); + ASSUME(GetMoveType(MOVE_SURF) == TYPE_WATER); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_HP_AWARE); - WITH_CONFIG(B_REDIRECT_ABILITY_IMMUNITY, GEN_4); + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, config); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Moves(move, MOVE_HEADBUTT); } OPPONENT(species) { HP(1); Ability(ability); Moves(MOVE_ROUND); } } WHEN { - TURN { EXPECT_MOVE(opponentLeft, MOVE_HEADBUTT); } - } -} - -AI_DOUBLE_BATTLE_TEST("AI treats an ally's redirection ability appropriately (gen 5+)") -{ - ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY); - ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC); - ASSUME(GetMoveTarget(MOVE_SURF) == MOVE_TARGET_FOES_AND_ALLY); - ASSUME(GetMoveType(MOVE_SURF) == TYPE_WATER); - - enum Ability ability; - u32 move, species; - - PARAMETRIZE { species = SPECIES_SEAKING; ability = ABILITY_LIGHTNING_ROD; move = MOVE_DISCHARGE; } - PARAMETRIZE { species = SPECIES_SHELLOS; ability = ABILITY_STORM_DRAIN; move = MOVE_SURF; } - - GIVEN { - AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_HP_AWARE); - WITH_CONFIG(B_REDIRECT_ABILITY_IMMUNITY, GEN_5); - PLAYER(SPECIES_WOBBUFFET); - PLAYER(SPECIES_WOBBUFFET); - OPPONENT(SPECIES_WOBBUFFET) { Moves(move, MOVE_HEADBUTT); } - OPPONENT(species) { HP(1); Ability(ability); Moves(MOVE_ROUND); } - } WHEN { - TURN { EXPECT_MOVE(opponentLeft, move); } + TURN { EXPECT_MOVE(opponentLeft, expectedMove); } } } diff --git a/test/battle/ai/ai_switching.c b/test/battle/ai/ai_switching.c index 8c6c6ae623..91098f28a3 100644 --- a/test/battle/ai/ai_switching.c +++ b/test/battle/ai/ai_switching.c @@ -1109,7 +1109,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will switch out if it has an PARAMETRIZE { aiMon = SPECIES_CHESNAUGHT; absorbingAbility = ABILITY_BULLETPROOF; move = MOVE_SLUDGE_BOMB;} PARAMETRIZE { aiMon = SPECIES_BRAMBLEGHAST; absorbingAbility = ABILITY_WIND_RIDER; move = MOVE_HURRICANE;} GIVEN { - ASSUME(B_REDIRECT_ABILITY_IMMUNITY >= GEN_5); + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_ZIGZAGOON) { Moves(move); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SCRATCH); } @@ -1662,7 +1662,7 @@ AI_SINGLE_BATTLE_TEST("AI_FLAG_SMART_SWITCHING: AI will consider Hidden Power wh { PASSES_RANDOMLY(SHOULD_SWITCH_ABSORBS_HIDDEN_POWER_PERCENTAGE, 100, RNG_AI_SWITCH_ABSORBING_HIDDEN_POWER); GIVEN { - ASSUME(B_REDIRECT_ABILITY_IMMUNITY >= GEN_5); + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_SMART_SWITCHING); PLAYER(SPECIES_ZIGZAGOON) { Moves(MOVE_HIDDEN_POWER); HPIV(31); AttackIV(30); DefenseIV(31); SpAttackIV(30); SpDefenseIV(31); SpeedIV(30); } OPPONENT(SPECIES_ZIGZAGOON) { Moves(MOVE_SCRATCH); } diff --git a/test/battle/ai/gimmick_z_move.c b/test/battle/ai/gimmick_z_move.c index fcc8d81658..b6432987b7 100644 --- a/test/battle/ai/gimmick_z_move.c +++ b/test/battle/ai/gimmick_z_move.c @@ -47,6 +47,18 @@ AI_SINGLE_BATTLE_TEST("AI uses Z-Moves -- Extreme Evoboost") } } +AI_SINGLE_BATTLE_TEST("AI uses Z-Moves to bypass move limitations") +{ + GIVEN { + AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT | AI_FLAG_OMNISCIENT ); + ASSUME(GetMoveType(MOVE_QUICK_ATTACK) == TYPE_NORMAL); + PLAYER(SPECIES_WOBBUFFET); + OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_NORMALIUM_Z); Moves(MOVE_POUND, MOVE_LAST_RESORT); } + } WHEN { + TURN { EXPECT_MOVE(opponent, MOVE_LAST_RESORT, gimmick: GIMMICK_Z_MOVE); } + } +} + AI_SINGLE_BATTLE_TEST("AI uses Z-Moves -- 10,000,000 Volt Thunderbolt") { GIVEN { diff --git a/test/battle/gimmick/dynamax.c b/test/battle/gimmick/dynamax.c index bf4abb86d5..25a0d5d08e 100644 --- a/test/battle/gimmick/dynamax.c +++ b/test/battle/gimmick/dynamax.c @@ -1611,16 +1611,16 @@ SINGLE_BATTLE_TEST("Dynamax: Max Moves don't bypass absorbing abilities") { u32 move, species; enum Ability ability; - PARAMETRIZE { move = MOVE_SPARK; ability = ABILITY_VOLT_ABSORB; species = SPECIES_LANTURN; } - PARAMETRIZE { move = MOVE_WATER_GUN; ability = ABILITY_WATER_ABSORB; species = SPECIES_LANTURN; } - PARAMETRIZE { move = MOVE_EMBER; ability = ABILITY_FLASH_FIRE; species = SPECIES_HEATRAN; } - PARAMETRIZE { move = MOVE_SPARK; ability = ABILITY_LIGHTNING_ROD; species = SPECIES_PIKACHU; } - PARAMETRIZE { move = MOVE_WATER_GUN; ability = ABILITY_STORM_DRAIN; species = SPECIES_GASTRODON; } - PARAMETRIZE { move = MOVE_EMBER; ability = ABILITY_WELL_BAKED_BODY; species = SPECIES_DACHSBUN; } - PARAMETRIZE { move = MOVE_SPARK; ability = ABILITY_MOTOR_DRIVE; species = SPECIES_ELECTIVIRE; } - PARAMETRIZE { move = MOVE_WATER_GUN; ability = ABILITY_DRY_SKIN; species = SPECIES_PARASECT; } - PARAMETRIZE { move = MOVE_MUD_BOMB; ability = ABILITY_EARTH_EATER; species = SPECIES_ORTHWORM; } - PARAMETRIZE { move = MOVE_VINE_WHIP; ability = ABILITY_SAP_SIPPER; species = SPECIES_MILTANK; } + PARAMETRIZE { move = MOVE_SPARK; ability = ABILITY_VOLT_ABSORB; species = SPECIES_LANTURN; } + PARAMETRIZE { move = MOVE_WATER_GUN; ability = ABILITY_WATER_ABSORB; species = SPECIES_LANTURN; } + PARAMETRIZE { move = MOVE_EMBER; ability = ABILITY_FLASH_FIRE; species = SPECIES_HEATRAN; } + PARAMETRIZE { move = MOVE_SPARK; ability = ABILITY_LIGHTNING_ROD; species = SPECIES_PIKACHU; } + PARAMETRIZE { move = MOVE_WATER_GUN; ability = ABILITY_STORM_DRAIN; species = SPECIES_GASTRODON; } + PARAMETRIZE { move = MOVE_EMBER; ability = ABILITY_WELL_BAKED_BODY; species = SPECIES_DACHSBUN; } + PARAMETRIZE { move = MOVE_SPARK; ability = ABILITY_MOTOR_DRIVE; species = SPECIES_ELECTIVIRE; } + PARAMETRIZE { move = MOVE_WATER_GUN; ability = ABILITY_DRY_SKIN; species = SPECIES_PARASECT; } + PARAMETRIZE { move = MOVE_MUD_BOMB; ability = ABILITY_EARTH_EATER; species = SPECIES_ORTHWORM; } + PARAMETRIZE { move = MOVE_VINE_WHIP; ability = ABILITY_SAP_SIPPER; species = SPECIES_MILTANK; } GIVEN { ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); @@ -1628,6 +1628,7 @@ SINGLE_BATTLE_TEST("Dynamax: Max Moves don't bypass absorbing abilities") ASSUME(GetMoveType(MOVE_EMBER) == TYPE_FIRE); ASSUME(GetMoveType(MOVE_MUD_BOMB) == TYPE_GROUND); ASSUME(GetMoveType(MOVE_VINE_WHIP) == TYPE_GRASS); + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(species) { Ability(ability); } } WHEN { diff --git a/test/battle/gimmick/terastal.c b/test/battle/gimmick/terastal.c index d78a68dc53..2379df58dc 100644 --- a/test/battle/gimmick/terastal.c +++ b/test/battle/gimmick/terastal.c @@ -327,33 +327,6 @@ SINGLE_BATTLE_TEST("(TERA) Reflect Type fails if used by a Terastallized Pokemon } } -SINGLE_BATTLE_TEST("(TERA) Conversion fails if used by a Terastallized Pokemon") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_PSYCHIC); } - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_CONVERSION, gimmick: GIMMICK_TERA); } - } SCENE { - MESSAGE("Wobbuffet used Conversion!"); - MESSAGE("But it failed!"); - } -} - -SINGLE_BATTLE_TEST("(TERA) Conversion2 fails if used by a Terastallized Pokemon") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_PSYCHIC); } - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(opponent, MOVE_SCRATCH); } - TURN { MOVE(player, MOVE_CONVERSION_2, gimmick: GIMMICK_TERA); } - } SCENE { - MESSAGE("Wobbuffet used Conversion 2!"); - MESSAGE("But it failed!"); - } -} - SINGLE_BATTLE_TEST("(TERA) Reflect Type copies a Terastallized Pokemon's Tera Type") { GIVEN { @@ -506,26 +479,6 @@ SINGLE_BATTLE_TEST("(TERA) Revelation Dance uses a Stellar-type Pokemon's base t } } -#if B_UPDATED_CONVERSION_2 < GEN_5 -SINGLE_BATTLE_TEST("(TERA) Conversion2 fails if last hit by a Stellar-type move") -{ - GIVEN { - PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_STELLAR); } - OPPONENT(SPECIES_WOBBUFFET); - } WHEN { - TURN { MOVE(player, MOVE_TERA_BLAST, gimmick: GIMMICK_TERA); } - TURN { MOVE(opponent, MOVE_CONVERSION_2); } - } SCENE { - // turn 1 - MESSAGE("Wobbuffet used Tera Blast!"); - ANIMATION(ANIM_TYPE_MOVE, MOVE_TERA_BLAST, player); - // turn 2 - MESSAGE("The opposing Wobbuffet used Conversion 2!"); - MESSAGE("But it failed!"); - } -} -#endif - SINGLE_BATTLE_TEST("(TERA) Roost does not remove Flying-type ground immunity when Terastallized into the Stellar type") { GIVEN { diff --git a/test/battle/hold_effect/iron_ball.c b/test/battle/hold_effect/iron_ball.c index 134c47d9af..90c370e8f3 100644 --- a/test/battle/hold_effect/iron_ball.c +++ b/test/battle/hold_effect/iron_ball.c @@ -5,17 +5,24 @@ ASSUMPTIONS{ ASSUME(gItemsInfo[ITEM_IRON_BALL].holdEffect == HOLD_EFFECT_IRON_BALL); } -SINGLE_BATTLE_TEST("Ground-type moves do neutral damage to non-grounded Flying types holding Iron Ball regardless of other typings") //gen5+ only +SINGLE_BATTLE_TEST("Ground-type moves do neutral damage to non-grounded Flying types holding Iron Ball regardless of other typings (Gen5+)") { - ASSUME(B_IRON_BALL >= GEN_5); + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_IRON_BALL, config); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_SKARMORY) { Item(ITEM_IRON_BALL); }; } WHEN { TURN { MOVE(player, MOVE_EARTHQUAKE); }; } SCENE { ANIMATION(ANIM_TYPE_MOVE, MOVE_EARTHQUAKE, player); - NONE_OF { + if (config >= GEN_5) { + NONE_OF { + MESSAGE("It's super effective!"); + } + } else { MESSAGE("It's super effective!"); } } diff --git a/test/battle/hold_effect/life_orb.c b/test/battle/hold_effect/life_orb.c index 7d99449bcb..39891ca53b 100644 --- a/test/battle/hold_effect/life_orb.c +++ b/test/battle/hold_effect/life_orb.c @@ -110,6 +110,7 @@ SINGLE_BATTLE_TEST("Life Orb does not activate if on a confusion hit") SINGLE_BATTLE_TEST("Life Orb does not activate if move was absorbed by target") { GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_LIFE_ORB); } OPPONENT(SPECIES_RAICHU) { Ability(ABILITY_LIGHTNING_ROD); } } WHEN { diff --git a/test/battle/move_effect/conversion.c b/test/battle/move_effect/conversion.c index ac863cf2b2..165d274a50 100644 --- a/test/battle/move_effect/conversion.c +++ b/test/battle/move_effect/conversion.c @@ -8,3 +8,16 @@ TO_DO_BATTLE_TEST("Conversion fails if all the user's moves share types with the TO_DO_BATTLE_TEST("Conversion changes the user's types to the one in the user's first slot (Gen 6+)"); TO_DO_BATTLE_TEST("Conversion can read the user's first move slot even if that move cannot be selected (Gen 6+)"); //Eg. Disable TO_DO_BATTLE_TEST("Conversion can change the user's types to Conversion's type"); + +SINGLE_BATTLE_TEST("(TERA) Conversion fails if used by a Terastallized Pokemon") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_PSYCHIC); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_CONVERSION, gimmick: GIMMICK_TERA); } + } SCENE { + MESSAGE("Wobbuffet used Conversion!"); + MESSAGE("But it failed!"); + } +} diff --git a/test/battle/move_effect/conversion_2.c b/test/battle/move_effect/conversion_2.c index acd21125c3..169243019b 100644 --- a/test/battle/move_effect/conversion_2.c +++ b/test/battle/move_effect/conversion_2.c @@ -3,10 +3,10 @@ TO_DO_BATTLE_TEST("Conversion 2's type change considers Inverse Battles"); -#if B_UPDATED_CONVERSION_2 < GEN_5 -SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type that resists the last move that hit the user (Gen 3-4)") +SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type that resists the last move that hit the user (Gen 1-4)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_4); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -16,15 +16,16 @@ SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type MESSAGE("Wobbuffet used Ominous Wind!"); // turn 1 ONE_OF { - MESSAGE("The opposing Wobbuffet transformed into the Normal type!"); - MESSAGE("The opposing Wobbuffet transformed into the Dark type!"); + MESSAGE("The opposing Wobbuffet transformed into the Normal type!"); + MESSAGE("The opposing Wobbuffet transformed into the Dark type!"); } } } -SINGLE_BATTLE_TEST("Conversion 2's type change considers Struggle to be Normal type (Gen 3-4)") +SINGLE_BATTLE_TEST("Conversion 2's type change considers Struggle to be Normal type (Gen 1-4)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_4); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -35,18 +36,17 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers Struggle to be Normal t MESSAGE("The opposing Wobbuffet used Struggle!"); // turn 2 ONE_OF { - MESSAGE("Wobbuffet transformed into the Steel type!"); - MESSAGE("Wobbuffet transformed into the Rock type!"); - MESSAGE("Wobbuffet transformed into the Ghost type!"); + MESSAGE("Wobbuffet transformed into the Steel type!"); + MESSAGE("Wobbuffet transformed into the Rock type!"); + MESSAGE("Wobbuffet transformed into the Ghost type!"); } } } -#endif -#if B_UPDATED_CONVERSION_2 >= GEN_5 SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type that resists the last used target's move (Gen 5+)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -56,8 +56,8 @@ SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type MESSAGE("Wobbuffet used Ominous Wind!"); // turn 1 ONE_OF { - MESSAGE("The opposing Wobbuffet transformed into the Normal type!"); - MESSAGE("The opposing Wobbuffet transformed into the Dark type!"); + MESSAGE("The opposing Wobbuffet transformed into the Normal type!"); + MESSAGE("The opposing Wobbuffet transformed into the Dark type!"); } } } @@ -65,6 +65,7 @@ SINGLE_BATTLE_TEST("Conversion 2 randomly changes the type of the user to a type SINGLE_BATTLE_TEST("Conversion 2's type change considers status moves (Gen 5+)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -75,8 +76,8 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers status moves (Gen 5+)") MESSAGE("The opposing Wobbuffet used Curse!"); // turn 2 ONE_OF { - MESSAGE("Wobbuffet transformed into the Normal type!"); - MESSAGE("Wobbuffet transformed into the Dark type!"); + MESSAGE("Wobbuffet transformed into the Normal type!"); + MESSAGE("Wobbuffet transformed into the Dark type!"); } } } @@ -84,6 +85,7 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers status moves (Gen 5+)") SINGLE_BATTLE_TEST("Conversion 2's type change considers the type of moves called by other moves") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -94,8 +96,8 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers the type of moves calle MESSAGE("The opposing Wobbuffet used Mirror Move!"); // turn 2 ONE_OF { - MESSAGE("Wobbuffet transformed into the Normal type!"); - MESSAGE("Wobbuffet transformed into the Dark type!"); + MESSAGE("Wobbuffet transformed into the Normal type!"); + MESSAGE("Wobbuffet transformed into the Dark type!"); } } } @@ -103,6 +105,7 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers the type of moves calle SINGLE_BATTLE_TEST("Conversion 2's type change considers dynamic type moves") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -113,10 +116,10 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers dynamic type moves") MESSAGE("The opposing Wobbuffet used Weather Ball!"); // turn 2 ONE_OF { - MESSAGE("Wobbuffet transformed into the Steel type!"); - MESSAGE("Wobbuffet transformed into the Fire type!"); - MESSAGE("Wobbuffet transformed into the Water type!"); - MESSAGE("Wobbuffet transformed into the Ice type!"); + MESSAGE("Wobbuffet transformed into the Steel type!"); + MESSAGE("Wobbuffet transformed into the Fire type!"); + MESSAGE("Wobbuffet transformed into the Water type!"); + MESSAGE("Wobbuffet transformed into the Ice type!"); } } } @@ -124,6 +127,7 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers dynamic type moves") SINGLE_BATTLE_TEST("Conversion 2's type change considers move types changed by Normalize and Electrify") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_NORMALIZE); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -136,17 +140,17 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers move types changed by N MESSAGE("The opposing Wobbuffet used Pound!"); // turn 2 ONE_OF { - MESSAGE("Wobbuffet transformed into the Ground type!"); - MESSAGE("Wobbuffet transformed into the Dragon type!"); - MESSAGE("Wobbuffet transformed into the Grass type!"); - MESSAGE("Wobbuffet transformed into the Electric type!"); + MESSAGE("Wobbuffet transformed into the Ground type!"); + MESSAGE("Wobbuffet transformed into the Dragon type!"); + MESSAGE("Wobbuffet transformed into the Grass type!"); + MESSAGE("Wobbuffet transformed into the Electric type!"); } // turn 3 MESSAGE("Wobbuffet used Water Gun!"); ONE_OF { - MESSAGE("The opposing Wobbuffet transformed into the Steel type!"); - MESSAGE("The opposing Wobbuffet transformed into the Rock type!"); - MESSAGE("The opposing Wobbuffet transformed into the Ghost type!"); + MESSAGE("The opposing Wobbuffet transformed into the Steel type!"); + MESSAGE("The opposing Wobbuffet transformed into the Rock type!"); + MESSAGE("The opposing Wobbuffet transformed into the Ghost type!"); } } } @@ -154,6 +158,7 @@ SINGLE_BATTLE_TEST("Conversion 2's type change considers move types changed by N SINGLE_BATTLE_TEST("Conversion 2's type change fails targeting Struggle (Gen 5+)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -171,6 +176,7 @@ SINGLE_BATTLE_TEST("Conversion 2's type change fails targeting Struggle (Gen 5+) SINGLE_BATTLE_TEST("Conversion 2 fails if the move used is of typeless damage (Gen 5+)") { GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_5); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_ENTEI); } WHEN { @@ -187,7 +193,6 @@ SINGLE_BATTLE_TEST("Conversion 2 fails if the move used is of typeless damage (G MESSAGE("But it failed!"); } } -#endif SINGLE_BATTLE_TEST("Conversion 2 fails if the targeted move is Stellar Type") { @@ -205,3 +210,35 @@ SINGLE_BATTLE_TEST("Conversion 2 fails if the targeted move is Stellar Type") MESSAGE("But it failed!"); } } + +SINGLE_BATTLE_TEST("Conversion 2 fails if used by a Terastallized Pokemon") +{ + GIVEN { + PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_PSYCHIC); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(opponent, MOVE_TACKLE); } + TURN { MOVE(player, MOVE_CONVERSION_2, gimmick: GIMMICK_TERA); } + } SCENE { + MESSAGE("Wobbuffet used Conversion 2!"); + MESSAGE("But it failed!"); + } +} + +SINGLE_BATTLE_TEST("Conversion 2 fails if last hit by a Stellar-type move (Gen 1-4)") +{ + GIVEN { + WITH_CONFIG(CONFIG_UPDATED_CONVERSION_2, GEN_4); + PLAYER(SPECIES_WOBBUFFET) { TeraType(TYPE_STELLAR); } + OPPONENT(SPECIES_WOBBUFFET); + } WHEN { + TURN { MOVE(player, MOVE_TERA_BLAST, gimmick: GIMMICK_TERA); MOVE(opponent, MOVE_CONVERSION_2); } + } SCENE { + // turn 1 + MESSAGE("Wobbuffet used Tera Blast!"); + ANIMATION(ANIM_TYPE_MOVE, MOVE_TERA_BLAST, player); + // turn 2 + MESSAGE("The opposing Wobbuffet used Conversion 2!"); + MESSAGE("But it failed!"); + } +} diff --git a/test/battle/move_effect/court_change.c b/test/battle/move_effect/court_change.c index 40a1fe4e86..5ebe4c70f6 100644 --- a/test/battle/move_effect/court_change.c +++ b/test/battle/move_effect/court_change.c @@ -81,6 +81,7 @@ DOUBLE_BATTLE_TEST("Court Change swaps entry hazards used by the player") DOUBLE_BATTLE_TEST("Court Change used by the player swaps Mist, Safeguard, Aurora Veil, Reflect, Light Screen, Tailwind") { GIVEN { + WITH_CONFIG(CONFIG_TAILWIND_TURNS, GEN_5); PLAYER(SPECIES_WYNAUT); PLAYER(SPECIES_WYNAUT); PLAYER(SPECIES_WYNAUT); @@ -119,6 +120,7 @@ DOUBLE_BATTLE_TEST("Court Change used by the player swaps Mist, Safeguard, Auror DOUBLE_BATTLE_TEST("Court Change used by the opponent swaps Mist, Safeguard, Aurora Veil, Reflect, Light Screen, Tailwind") { GIVEN { + WITH_CONFIG(CONFIG_TAILWIND_TURNS, GEN_5); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WOBBUFFET); @@ -248,4 +250,3 @@ AI_SINGLE_BATTLE_TEST("AI uses Court Change") TURN { MOVE(player, MOVE_CELEBRATE); EXPECT_MOVE(opponent, MOVE_COURT_CHANGE); } } } - diff --git a/test/battle/move_effect/fling.c b/test/battle/move_effect/fling.c index 2046ebe638..012485abe8 100644 --- a/test/battle/move_effect/fling.c +++ b/test/battle/move_effect/fling.c @@ -56,22 +56,24 @@ SINGLE_BATTLE_TEST("Fling fails if Pokémon is under the effects of Embargo or M } } -SINGLE_BATTLE_TEST("Fling fails for Pokémon with Klutz ability") +SINGLE_BATTLE_TEST("Fling fails for Pokémon with Klutz ability (Gen5+)") { enum Ability ability; + u32 config; - PARAMETRIZE {ability = ABILITY_KLUTZ; } - PARAMETRIZE {ability = ABILITY_RUN_AWAY; } + PARAMETRIZE { ability = ABILITY_RUN_AWAY; config = GEN_4; } + PARAMETRIZE { ability = ABILITY_KLUTZ; config = GEN_4; } + PARAMETRIZE { ability = ABILITY_KLUTZ; config = GEN_5; } GIVEN { - ASSUME(B_KLUTZ_FLING_INTERACTION >= GEN_5); + WITH_CONFIG(CONFIG_KLUTZ_FLING_INTERACTION, config); PLAYER(SPECIES_BUNEARY) { Item(ITEM_RAZOR_CLAW); Ability(ability); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { TURN { MOVE(player, MOVE_FLING); } } SCENE { MESSAGE("Buneary used Fling!"); - if (ability != ABILITY_KLUTZ) { + if (ability != ABILITY_KLUTZ || config == GEN_4) { ANIMATION(ANIM_TYPE_MOVE, MOVE_FLING, player); HP_BAR(opponent); } else { diff --git a/test/battle/move_effect/instruct.c b/test/battle/move_effect/instruct.c index 834546009f..be6e557990 100644 --- a/test/battle/move_effect/instruct.c +++ b/test/battle/move_effect/instruct.c @@ -239,6 +239,7 @@ DOUBLE_BATTLE_TEST("Instructed move will be redirected and absorbed by Lightning PARAMETRIZE { moveTarget = opponentLeft; } PARAMETRIZE { moveTarget = opponentRight; } GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); PLAYER(SPECIES_WOBBUFFET); PLAYER(SPECIES_WYNAUT); OPPONENT(SPECIES_PIKACHU) { Ability(ABILITY_LIGHTNING_ROD); } diff --git a/test/battle/move_effect/pledge.c b/test/battle/move_effect/pledge.c index a7935450b6..f2607b4ff7 100644 --- a/test/battle/move_effect/pledge.c +++ b/test/battle/move_effect/pledge.c @@ -910,6 +910,7 @@ DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move DOUBLE_BATTLE_TEST("Pledge move combo doesn't trigger on opponent's Pledge move - Storm Drain") { GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); PLAYER(SPECIES_GASTRODON) { Ability(ABILITY_STORM_DRAIN); } PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/sleep_talk.c b/test/battle/move_effect/sleep_talk.c index ace40150c5..6980954714 100644 --- a/test/battle/move_effect/sleep_talk.c +++ b/test/battle/move_effect/sleep_talk.c @@ -113,6 +113,7 @@ DOUBLE_BATTLE_TEST("Sleep Talk calls move and that move may be redirected by Lig { PASSES_RANDOMLY(1, 2, RNG_RANDOM_TARGET); GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); ASSUME(GetMoveType(MOVE_SPARK) == TYPE_ELECTRIC); PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_SPARK, MOVE_FLY, MOVE_DIG); } PLAYER(SPECIES_WOBBUFFET); @@ -132,6 +133,7 @@ DOUBLE_BATTLE_TEST("Sleep Talk calls move and that move may be redirected by Sto { PASSES_RANDOMLY(1, 2, RNG_RANDOM_TARGET); GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); ASSUME(GetMoveType(MOVE_WATER_GUN) == TYPE_WATER); PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); Moves(MOVE_SLEEP_TALK, MOVE_WATER_GUN, MOVE_FLY, MOVE_DIG); } PLAYER(SPECIES_WOBBUFFET); diff --git a/test/battle/move_effect/tailwind.c b/test/battle/move_effect/tailwind.c index 9ed101301d..d22f36d285 100644 --- a/test/battle/move_effect/tailwind.c +++ b/test/battle/move_effect/tailwind.c @@ -6,10 +6,13 @@ ASSUMPTIONS ASSUME(GetMoveEffect(MOVE_TAILWIND) == EFFECT_TAILWIND); } -SINGLE_BATTLE_TEST("Tailwind applies for 4 turns") +SINGLE_BATTLE_TEST("Tailwind applies for 3 turns (Gen4) or 4 turns (Gen5+)") { + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { - ASSUME(B_TAILWIND_TURNS >= GEN_5); + WITH_CONFIG(CONFIG_TAILWIND_TURNS, config); PLAYER(SPECIES_WOBBUFFET) { Speed(10); } OPPONENT(SPECIES_WOBBUFFET) { Speed(15); } } WHEN { @@ -28,8 +31,10 @@ SINGLE_BATTLE_TEST("Tailwind applies for 4 turns") MESSAGE("Wobbuffet used Celebrate!"); MESSAGE("The opposing Wobbuffet used Celebrate!"); - MESSAGE("Wobbuffet used Celebrate!"); - MESSAGE("The opposing Wobbuffet used Celebrate!"); + if (config >= GEN_5) { + MESSAGE("Wobbuffet used Celebrate!"); + MESSAGE("The opposing Wobbuffet used Celebrate!"); + } MESSAGE("The opposing Wobbuffet used Celebrate!"); MESSAGE("Wobbuffet used Celebrate!"); diff --git a/test/battle/move_effect/teatime.c b/test/battle/move_effect/teatime.c index fc4ad22198..b5935d0cde 100644 --- a/test/battle/move_effect/teatime.c +++ b/test/battle/move_effect/teatime.c @@ -205,6 +205,7 @@ SINGLE_BATTLE_TEST("Teatime triggers Lightning Rod if it has been affected by El PARAMETRIZE { move = MOVE_PLASMA_FISTS; item = ITEM_NONE; } GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); PLAYER(SPECIES_PIKACHU) { Ability(ABILITY_LIGHTNING_ROD); Item(item); } OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_LIECHI_BERRY); } } WHEN { diff --git a/test/battle/spread_moves.c b/test/battle/spread_moves.c index d5e6b5c26d..68b9f40273 100644 --- a/test/battle/spread_moves.c +++ b/test/battle/spread_moves.c @@ -172,6 +172,7 @@ DOUBLE_BATTLE_TEST("Spread Moves: A spread move attack will be weakened by stron DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Disguise, Volt Absorb (right) and Lightning Rod (left)") { GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY); ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC); PLAYER(SPECIES_WOBBUFFET); @@ -191,6 +192,7 @@ DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Disguise, Volt Absorb (right) and DOUBLE_BATTLE_TEST("Spread Moves: AOE move vs Disguise, Volt Absorb (left) and Lightning Rod (right)") { GIVEN { + WITH_CONFIG(CONFIG_REDIRECT_ABILITY_IMMUNITY, GEN_5); ASSUME(GetMoveTarget(MOVE_DISCHARGE) == MOVE_TARGET_FOES_AND_ALLY); ASSUME(GetMoveType(MOVE_DISCHARGE) == TYPE_ELECTRIC); PLAYER(SPECIES_WOBBUFFET); diff --git a/test/battle/status1/burn.c b/test/battle/status1/burn.c index 8ec9d05835..33eae7bd85 100644 --- a/test/battle/status1/burn.c +++ b/test/battle/status1/burn.c @@ -7,10 +7,13 @@ ASSUMPTIONS ASSUME(GetMoveNonVolatileStatus(MOVE_WILL_O_WISP) == MOVE_EFFECT_BURN); } -SINGLE_BATTLE_TEST("Burn deals 1/16th (Gen7+) or 1/8th damage per turn") +SINGLE_BATTLE_TEST("Burn deals 1/8th damage (Gen1-6) or 1/16th (Gen7+) per turn") { - u32 j; + u32 j, config, value; + PARAMETRIZE { config = GEN_7; value = 16; } + PARAMETRIZE { config = GEN_6; value = 8; } GIVEN { + WITH_CONFIG(CONFIG_BURN_DAMAGE, config); PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_BURN); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -19,7 +22,7 @@ SINGLE_BATTLE_TEST("Burn deals 1/16th (Gen7+) or 1/8th damage per turn") } SCENE { s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP); for (j = 0; j < 4; j++) - HP_BAR(player, damage: maxHP / ((B_BURN_DAMAGE >= GEN_7) ? 16 : 8)); + HP_BAR(player, damage: maxHP / value); } } diff --git a/test/battle/status1/frostbite.c b/test/battle/status1/frostbite.c index e221a0eae3..9ae86a8738 100644 --- a/test/battle/status1/frostbite.c +++ b/test/battle/status1/frostbite.c @@ -23,11 +23,14 @@ SINGLE_BATTLE_TEST("Frostbite reduces the special attack by 50 percent") } THEN { EXPECT_EQ(reducedDamage * 2, normaleDamage); } } -SINGLE_BATTLE_TEST("Frostbite deals 1/16th (Gen7+) or 1/8th damage to affected Pokémon") +SINGLE_BATTLE_TEST("Frostbite deals 1/8th damage (Gen1-6) or 1/16th (Gen7+) per turn") { s16 frostbiteDamage; - + u32 config, value; + PARAMETRIZE { config = GEN_7; value = 16; } + PARAMETRIZE { config = GEN_6; value = 8; } GIVEN { + WITH_CONFIG(CONFIG_BURN_DAMAGE, config); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET) { Status1(STATUS1_FROSTBITE); } } WHEN { @@ -36,7 +39,9 @@ SINGLE_BATTLE_TEST("Frostbite deals 1/16th (Gen7+) or 1/8th damage to affected P MESSAGE("The opposing Wobbuffet was hurt by its frostbite!"); ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_FRB, opponent); HP_BAR(opponent, captureDamage: &frostbiteDamage); - } THEN { EXPECT_EQ(frostbiteDamage, opponent->maxHP / ((B_BURN_DAMAGE >= GEN_7) ? 16 : 8)); } + } THEN { + EXPECT_EQ(frostbiteDamage, opponent->maxHP / value); + } } SINGLE_BATTLE_TEST("Frostbite is healed if hit with a thawing move")