Merge pull request #81 from rh-hideout/master

sync update
This commit is contained in:
RoamerX 2025-12-22 16:23:01 +08:00 committed by GitHub
commit 32a49667b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 99 additions and 57 deletions

View File

@ -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 */ \

View File

@ -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;
}
}

View File

@ -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;
}
}
}
}

View File

@ -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)

View File

@ -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]);
}
}
}

View File

@ -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]);
}
}
}

View File

@ -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
}
}