diff --git a/include/constants/generational_changes.h b/include/constants/generational_changes.h index 755a4d1186..8cabad41ea 100644 --- a/include/constants/generational_changes.h +++ b/include/constants/generational_changes.h @@ -32,7 +32,7 @@ F(HIDDEN_POWER_DMG, hiddenPowerDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(ROUGH_SKIN_DMG, roughSkinDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(KNOCK_OFF_DMG, knockOffDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ - F(SPORT_DMG_REDUCTION, sportDmgReduction, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(SPORT_DMG_REDUCTION, sportDmgReduction, (u32, GEN_COUNT - 1)) \ F(EXPLOSION_DEFENSE, explosionDefense, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(PARENTAL_BOND_DMG, parentalBondDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(MULTIPLE_TARGETS_DMG, multipleTargetsDmg, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ @@ -47,7 +47,7 @@ F(ROOST_PURE_FLYING, roostPureFlying, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ F(STATUS_TYPE_IMMUNITY, statusTypeImmunity, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ /* Turn settings */ \ - F(BINDING_TURNS, bindingTurns, (u32, GEN_COUNT - 1)) /* TODO: use in tests */ \ + F(BINDING_TURNS, bindingTurns, (u32, GEN_COUNT - 1)) \ 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 */ \ diff --git a/src/battle_ai_main.c b/src/battle_ai_main.c index 8dde9c4a97..eca9c3209f 100644 --- a/src/battle_ai_main.c +++ b/src/battle_ai_main.c @@ -5519,7 +5519,7 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, stru ADJUST_SCORE(GOOD_EFFECT); break; case EFFECT_MAGNET_RISE: - if (AI_IsBattlerGrounded(battlerAtk) && HasDamagingMoveOfType(battlerDef, TYPE_ELECTRIC) + if (AI_IsBattlerGrounded(battlerAtk) && HasDamagingMoveOfType(battlerDef, TYPE_GROUND) && !(effectiveness == UQ_4_12(0.0))) // Doesn't resist ground move { if (AI_IsFaster(battlerAtk, battlerDef, move, predictedMoveSpeedCheck, CONSIDER_PRIORITY)) // Attacker goes first @@ -5530,8 +5530,7 @@ static s32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move, stru } else // Opponent Goes First { - if (HasDamagingMoveOfType(battlerDef, TYPE_GROUND)) - ADJUST_SCORE(DECENT_EFFECT); + ADJUST_SCORE(DECENT_EFFECT); break; } } diff --git a/src/battle_script_commands.c b/src/battle_script_commands.c index 9dbbbe914d..e13a18fc97 100644 --- a/src/battle_script_commands.c +++ b/src/battle_script_commands.c @@ -3213,9 +3213,9 @@ void SetMoveEffect(u32 battler, u32 effectBattler, enum MoveEffect moveEffect, c else { if (GetBattlerHoldEffect(gBattlerAttacker) == HOLD_EFFECT_GRIP_CLAW) - gDisableStructs[gEffectBattler].wrapTurns = B_BINDING_TURNS >= GEN_5 ? 7 : 5; + gDisableStructs[gEffectBattler].wrapTurns = GetConfig(CONFIG_BINDING_TURNS) >= GEN_5 ? 7 : 5; else - gDisableStructs[gEffectBattler].wrapTurns = B_BINDING_TURNS >= GEN_5 ? RandomUniform(RNG_WRAP, 4, 5) : RandomUniform(RNG_WRAP, 2, 5); + gDisableStructs[gEffectBattler].wrapTurns = GetConfig(CONFIG_BINDING_TURNS) >= GEN_5 ? RandomUniform(RNG_WRAP, 4, 5) : RandomUniform(RNG_WRAP, 2, 5); gBattleMons[gEffectBattler].volatiles.wrapped = TRUE; gBattleMons[gEffectBattler].volatiles.wrappedMove = gCurrentMove; gBattleMons[gEffectBattler].volatiles.wrappedBy = gBattlerAttacker; @@ -3975,7 +3975,7 @@ void SetMoveEffect(u32 battler, u32 effectBattler, enum MoveEffect moveEffect, c { gBattleMons[battler].volatiles.wrapped = TRUE; if (GetBattlerHoldEffect(gBattlerAttacker) == HOLD_EFFECT_GRIP_CLAW) - gDisableStructs[battler].wrapTurns = (B_BINDING_TURNS >= GEN_5) ? 7 : 5; + gDisableStructs[battler].wrapTurns = (GetConfig(CONFIG_BINDING_TURNS) >= GEN_5) ? 7 : 5; else gDisableStructs[battler].wrapTurns = (Random() % 2) + 4; // The Wrap effect does not expire when the user switches, so here's some cheese. @@ -13278,47 +13278,50 @@ static void Cmd_settypebasedhalvers(void) bool8 worked = FALSE; - if (GetMoveEffect(gCurrentMove) == EFFECT_MUD_SPORT) + if (!gBattleStruct->isSkyBattle) { - if (B_SPORT_TURNS >= GEN_6) + if (GetMoveEffect(gCurrentMove) == EFFECT_MUD_SPORT) { - if (!(gFieldStatuses & STATUS_FIELD_MUDSPORT)) + if (B_SPORT_TURNS >= GEN_6) { - gFieldStatuses |= STATUS_FIELD_MUDSPORT; - gFieldTimers.mudSportTimer = 5; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_ELECTRIC; - worked = TRUE; + if (!(gFieldStatuses & STATUS_FIELD_MUDSPORT)) + { + gFieldStatuses |= STATUS_FIELD_MUDSPORT; + gFieldTimers.mudSportTimer = 5; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_ELECTRIC; + worked = TRUE; + } + } + else + { + if (!gBattleMons[gBattlerAttacker].volatiles.mudSport) + { + gBattleMons[gBattlerAttacker].volatiles.mudSport = TRUE; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_ELECTRIC; + worked = TRUE; + } } } - else + else // Water Sport { - if (!gBattleMons[gBattlerAttacker].volatiles.waterSport) + if (B_SPORT_TURNS >= GEN_6) { - gBattleMons[gBattlerAttacker].volatiles.waterSport = TRUE; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_ELECTRIC; - worked = TRUE; + if (!(gFieldStatuses & STATUS_FIELD_WATERSPORT)) + { + gFieldStatuses |= STATUS_FIELD_WATERSPORT; + gFieldTimers.waterSportTimer = 5; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_FIRE; + worked = TRUE; + } } - } - } - else // Water Sport - { - if (B_SPORT_TURNS >= GEN_6) - { - if (!(gFieldStatuses & STATUS_FIELD_WATERSPORT)) + else { - gFieldStatuses |= STATUS_FIELD_WATERSPORT; - gFieldTimers.waterSportTimer = 5; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_FIRE; - worked = TRUE; - } - } - else - { - if (!gBattleMons[gBattlerAttacker].volatiles.mudSport) - { - gBattleMons[gBattlerAttacker].volatiles.mudSport = TRUE; - gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_FIRE; - worked = TRUE; + if (!gBattleMons[gBattlerAttacker].volatiles.waterSport) + { + gBattleMons[gBattlerAttacker].volatiles.waterSport = TRUE; + gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_WEAKEN_FIRE; + worked = TRUE; + } } } } diff --git a/src/battle_util.c b/src/battle_util.c index 11a5ef583c..6e47859071 100644 --- a/src/battle_util.c +++ b/src/battle_util.c @@ -6961,7 +6961,10 @@ u32 CalcFuryCutterBasePower(u32 basePower, u32 furyCutterCounter) static inline u32 IsFieldMudSportAffected(enum Type moveType) { - if (moveType == TYPE_ELECTRIC && (gFieldStatuses & STATUS_FIELD_MUDSPORT)) + if (moveType != TYPE_ELECTRIC) + return FALSE; + + if (gFieldStatuses & STATUS_FIELD_MUDSPORT) return TRUE; if (B_SPORT_TURNS < GEN_6) @@ -6978,7 +6981,10 @@ static inline u32 IsFieldMudSportAffected(enum Type moveType) static inline u32 IsFieldWaterSportAffected(enum Type moveType) { - if (moveType == TYPE_FIRE && (gFieldStatuses & STATUS_FIELD_WATERSPORT)) + if (moveType != TYPE_FIRE) + return FALSE; + + if (gFieldStatuses & STATUS_FIELD_WATERSPORT) return TRUE; if (B_SPORT_TURNS < GEN_6) @@ -7335,9 +7341,9 @@ static inline u32 CalcMoveBasePowerAfterModifiers(struct DamageContext *ctx) if (IsBattlerTerrainAffected(battlerAtk, ctx->abilityAtk, ctx->holdEffectAtk, STATUS_FIELD_PSYCHIC_TERRAIN) && moveType == TYPE_PSYCHIC) modifier = uq4_12_multiply(modifier, (B_TERRAIN_TYPE_BOOST >= GEN_8 ? UQ_4_12(1.3) : UQ_4_12(1.5))); if (IsFieldMudSportAffected(ctx->moveType)) - modifier = uq4_12_multiply(modifier, UQ_4_12(B_SPORT_DMG_REDUCTION >= GEN_5 ? 0.33 : 0.5)); + modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(CONFIG_SPORT_DMG_REDUCTION) >= GEN_5 ? 0.33 : 0.5)); if (IsFieldWaterSportAffected(ctx->moveType)) - modifier = uq4_12_multiply(modifier, UQ_4_12(B_SPORT_DMG_REDUCTION >= GEN_5 ? 0.33 : 0.5)); + modifier = uq4_12_multiply(modifier, UQ_4_12(GetConfig(CONFIG_SPORT_DMG_REDUCTION) >= GEN_5 ? 0.33 : 0.5)); // attacker's abilities switch (ctx->abilityAtk) diff --git a/test/battle/move_effect/mud_sport.c b/test/battle/move_effect/mud_sport.c index ff483699b4..31e0ea18ff 100644 --- a/test/battle/move_effect/mud_sport.c +++ b/test/battle/move_effect/mud_sport.c @@ -3,11 +3,15 @@ TO_DO_BATTLE_TEST("TODO: Write Mud Sport (Move Effect) test titles") -SINGLE_BATTLE_TEST("Mud Sport reduces the damage of Electric Type moves by 67% (Gen5+)") +SINGLE_BATTLE_TEST("Mud Sport reduces the damage of Electric Type moves by 50% (Gen3-4) or 67% (Gen5+)") { + u32 config; s16 playerDmg[2]; s16 opponentDmg[2]; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_SPORT_DMG_REDUCTION, config); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -28,7 +32,13 @@ SINGLE_BATTLE_TEST("Mud Sport reduces the damage of Electric Type moves by 67% ( HP_BAR(player, captureDamage: &playerDmg[1]); } THEN { - EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.33), opponentDmg[1]); - EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.33), playerDmg[1]); + if (config >= GEN_5) { + EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.33), opponentDmg[1]); + EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.33), playerDmg[1]); + } + else { + EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.5), opponentDmg[1]); + EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.5), playerDmg[1]); + } } } diff --git a/test/battle/move_effect/water_sport.c b/test/battle/move_effect/water_sport.c index cf4ec929c3..5cf52ed1c2 100644 --- a/test/battle/move_effect/water_sport.c +++ b/test/battle/move_effect/water_sport.c @@ -3,11 +3,15 @@ TO_DO_BATTLE_TEST("TODO: Write Water Sport (Move Effect) test titles") -SINGLE_BATTLE_TEST("Water Sport reduces the damage of Fire Type moves by 67% (Gen5+)") +SINGLE_BATTLE_TEST("Water Sport reduces the damage of Fire Type moves by 50% (Gen3-4) or 67% (Gen5+)") { + u32 config; s16 playerDmg[2]; s16 opponentDmg[2]; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_SPORT_DMG_REDUCTION, config); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -28,7 +32,13 @@ SINGLE_BATTLE_TEST("Water Sport reduces the damage of Fire Type moves by 67% (Ge HP_BAR(player, captureDamage: &playerDmg[1]); } THEN { - EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.33), opponentDmg[1]); - EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.33), playerDmg[1]); + if (config >= GEN_5) { + EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.33), opponentDmg[1]); + EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.33), playerDmg[1]); + } + else { + EXPECT_MUL_EQ(opponentDmg[0], Q_4_12(0.5), opponentDmg[1]); + EXPECT_MUL_EQ(playerDmg[0], Q_4_12(0.5), playerDmg[1]); + } } } diff --git a/test/battle/move_effect_secondary/wrap.c b/test/battle/move_effect_secondary/wrap.c index dc05bbe288..2e430871fd 100644 --- a/test/battle/move_effect_secondary/wrap.c +++ b/test/battle/move_effect_secondary/wrap.c @@ -6,10 +6,14 @@ ASSUMPTIONS ASSUME(MoveHasAdditionalEffect(MOVE_WRAP, MOVE_EFFECT_WRAP)); } -SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 5 turns 50% of the time") +SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 5 turns 25% (Gen3-4) or 50% (Gen5+) of the time") { - PASSES_RANDOMLY(50, 100, RNG_WRAP); + u32 config, passes, trials; + PARAMETRIZE { config = GEN_4; passes = 25; trials = 100; } + PARAMETRIZE { config = GEN_5; passes = 50; trials = 100; } + PASSES_RANDOMLY(passes, trials, RNG_WRAP); GIVEN { + WITH_CONFIG(CONFIG_BINDING_TURNS, config); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -32,10 +36,14 @@ SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 5 turns 50% of the time" } } -SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 4 turns 50% of the time") +SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 4 turns 25% (Gen3-4) or 50% (Gen5+) of the time") { - PASSES_RANDOMLY(50, 100, RNG_WRAP); + u32 config, passes, trials; + PARAMETRIZE { config = GEN_4; passes = 25; trials = 100; } + PARAMETRIZE { config = GEN_5; passes = 50; trials = 100; } + PASSES_RANDOMLY(passes, trials, RNG_WRAP); GIVEN { + WITH_CONFIG(CONFIG_BINDING_TURNS, config); PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -56,9 +64,13 @@ SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon for 4 turns 50% of the time" } } -SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon 7 turns while holding a Grip Claw") +SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon 5 turns (Gen4) or 7 turns (Gen5+) while holding a Grip Claw") { + u32 config; + PARAMETRIZE { config = GEN_4; } + PARAMETRIZE { config = GEN_5; } GIVEN { + WITH_CONFIG(CONFIG_BINDING_TURNS, config); PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_GRIP_CLAW); } OPPONENT(SPECIES_WOBBUFFET); } WHEN { @@ -79,8 +91,10 @@ SINGLE_BATTLE_TEST("Wrap can damage the wrapped mon 7 turns while holding a Grip HP_BAR(opponent); // Residual Damage HP_BAR(opponent); // Residual Damage HP_BAR(opponent); // Residual Damage - HP_BAR(opponent); // Residual Damage - HP_BAR(opponent); // Residual Damage + if (config >= GEN_5) { + HP_BAR(opponent); // Residual Damage + HP_BAR(opponent); // Residual Damage + } NOT HP_BAR(opponent); // Residual Damage } }