Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add various tests, add RNG_RANDOM_TARGET #5438

Merged
merged 13 commits into from
Oct 11, 2024
1 change: 1 addition & 0 deletions include/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ enum RandomTag
RNG_AI_SWITCH_HASBADODDS,
RNG_AI_SWITCH_WONDER_GUARD,
RNG_SHELL_SIDE_ARM,
RNG_RANDOM_TARGET,
};

#define RandomWeighted(tag, ...) \
Expand Down
3 changes: 2 additions & 1 deletion src/battle_script_commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -11476,10 +11476,11 @@ static void Cmd_setmiracleeye(void)
bool8 UproarWakeUpCheck(u8 battler)
{
s32 i;
bool32 hasSoundproof = (B_UPROAR_IGNORE_SOUNDPROOF < GEN_5 && GetBattlerAbility(battler) == ABILITY_SOUNDPROOF);

for (i = 0; i < gBattlersCount; i++)
{
if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || (GetBattlerAbility(battler) == ABILITY_SOUNDPROOF && B_UPROAR_IGNORE_SOUNDPROOF < GEN_5))
if (!(gBattleMons[i].status2 & STATUS2_UPROAR) || hasSoundproof)
continue;

gBattleScripting.battler = i;
Expand Down
39 changes: 6 additions & 33 deletions src/battle_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,20 +251,7 @@ void HandleAction_UseMove(void)
{
if (moveTarget & MOVE_TARGET_RANDOM)
{
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
{
if (Random() & 1)
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
else
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
}
else
{
if (Random() & 1)
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
else
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
}
gBattlerTarget = SetRandomTarget(gBattlerAttacker);
AlexOn1ine marked this conversation as resolved.
Show resolved Hide resolved
}
else if (moveTarget & MOVE_TARGET_FOES_AND_ALLY)
{
Expand Down Expand Up @@ -311,21 +298,7 @@ void HandleAction_UseMove(void)
}
else if (IsDoubleBattle() && moveTarget & MOVE_TARGET_RANDOM)
{
if (GetBattlerSide(gBattlerAttacker) == B_SIDE_PLAYER)
{
if (Random() & 1)
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_LEFT);
else
gBattlerTarget = GetBattlerAtPosition(B_POSITION_OPPONENT_RIGHT);
}
else
{
if (Random() & 1)
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_LEFT);
else
gBattlerTarget = GetBattlerAtPosition(B_POSITION_PLAYER_RIGHT);
}

gBattlerTarget = SetRandomTarget(gBattlerAttacker);
if (gAbsentBattlerFlags & (1u << gBattlerTarget)
&& GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
{
Expand Down Expand Up @@ -2662,7 +2635,7 @@ u8 DoBattlerEndTurnEffects(void)
for (gBattlerAttacker = 0; gBattlerAttacker < gBattlersCount; gBattlerAttacker++)
{
if ((gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP)
&& GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF)
&& (B_UPROAR_IGNORE_SOUNDPROOF >= GEN_5 || GetBattlerAbility(gBattlerAttacker) != ABILITY_SOUNDPROOF))
{
gBattleMons[gBattlerAttacker].status1 &= ~STATUS1_SLEEP;
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_NIGHTMARE;
Expand Down Expand Up @@ -8285,7 +8258,7 @@ void HandleAction_RunBattleScript(void) // identical to RunBattleScriptCommands
gBattleScriptingCommandsTable[*gBattlescriptCurrInstr]();
}

u32 SetRandomTarget(u32 battler)
u32 SetRandomTarget(u32 battlerAtk)
{
u32 target;
static const u8 targets[2][2] =
Expand All @@ -8296,13 +8269,13 @@ u32 SetRandomTarget(u32 battler)

if (IsDoubleBattle())
{
target = GetBattlerAtPosition(targets[GetBattlerSide(battler)][Random() % 2]);
target = GetBattlerAtPosition(targets[GetBattlerSide(battlerAtk)][RandomUniform(RNG_RANDOM_TARGET, 0, 1)]);
if (!IsBattlerAlive(target))
target ^= BIT_FLANK;
}
else
{
target = GetBattlerAtPosition(targets[GetBattlerSide(battler)][0]);
target = GetBattlerAtPosition(targets[GetBattlerSide(battlerAtk)][0]);
}

return target;
Expand Down
20 changes: 20 additions & 0 deletions test/battle/ability/contrary.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,3 +221,23 @@ SINGLE_BATTLE_TEST("Contrary lowers a stat after using a move which would normal
EXPECT_MUL_EQ(results[1].damageBefore, UQ_4_12(4.0), results[1].damageAfter);
}
}

SINGLE_BATTLE_TEST("Sticky Web raises Speed by 1 for Contrary mon on switch-in")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_SNIVY) { Ability(ABILITY_CONTRARY); }
} WHEN {
TURN { MOVE(player, MOVE_STICKY_WEB); }
TURN { SWITCH(opponent, 1); }
TURN {}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, player);
MESSAGE("A sticky web spreads out on the ground around the opposing team!");
MESSAGE("2 sent out Snivy!");
MESSAGE("Foe Snivy was caught in a Sticky Web!");
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponent);
MESSAGE("Foe Snivy's Speed rose!");
}
}
26 changes: 25 additions & 1 deletion test/battle/move_effect/belly_drum.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,31 @@ SINGLE_BATTLE_TEST("Belly Drum's HP cost doesn't trigger effects that trigger on
}
}

SINGLE_BATTLE_TEST("Belly Drum minimizes the user's Attack stat with Contrary", s16 damage)
{
bool32 raiseAttack;
PARAMETRIZE { raiseAttack = FALSE; }
PARAMETRIZE { raiseAttack = TRUE; }
GIVEN {
ASSUME(gMovesInfo[MOVE_TACKLE].category == DAMAGE_CATEGORY_PHYSICAL);
PLAYER(SPECIES_WOBBUFFET) { Ability(ABILITY_CONTRARY); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
if (raiseAttack) TURN { MOVE(player, MOVE_BELLY_DRUM); }
TURN { MOVE(player, MOVE_TACKLE); }
} SCENE {
if (raiseAttack) {
ANIMATION(ANIM_TYPE_MOVE, MOVE_BELLY_DRUM, player);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
MESSAGE("Wobbuffet cut its own HP and maximized ATTACK!"); // Message unaffected by Contrary
}
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[1].damage, Q_4_12(4), results[0].damage);
}
}

TO_DO_BATTLE_TEST("Belly Drum maximizes the user's Attack stat, even when below 0");
TO_DO_BATTLE_TEST("Belly Drum minimizes the user's Attack stat if it has Contrary"); // Should still say "maximized attack"
TO_DO_BATTLE_TEST("Belly Drum fails if the user's Attack is already at +6, even with Contrary");
TO_DO_BATTLE_TEST("Belly Drum deducts HP if the user has contrary and is at -6");
6 changes: 5 additions & 1 deletion test/battle/move_effect/protect.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ SINGLE_BATTLE_TEST("King's Shield, Silk Trap and Obstruct protect from damaging
u32 j;
static const u16 protectMoves[][3] =
{ // Move Stat Stages
{MOVE_KINGS_SHIELD, STAT_ATK, 1},
{MOVE_KINGS_SHIELD, STAT_ATK, (B_KINGS_SHIELD_LOWER_ATK >= GEN_8) ? 1 : 2},
{MOVE_SILK_TRAP, STAT_SPEED, 1},
{MOVE_OBSTRUCT, STAT_DEF, 2},
};
Expand Down Expand Up @@ -99,7 +99,11 @@ SINGLE_BATTLE_TEST("King's Shield, Silk Trap and Obstruct protect from damaging
NOT HP_BAR(opponent);
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, player);
if (statId == STAT_ATK) {
#if B_KINGS_SHIELD_LOWER_ATK >= GEN_8
MESSAGE("Wobbuffet's Attack fell!");
#else
MESSAGE("Wobbuffet's Attack harshly fell!");
#endif
} else if (statId == STAT_SPEED) {
MESSAGE("Wobbuffet's Speed fell!");
} else if (statId == STAT_DEF) {
Expand Down
1 change: 1 addition & 0 deletions test/battle/move_effect/uproar.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ ASSUMPTIONS

DOUBLE_BATTLE_TEST("Uproar status causes sleeping pokemon to wake up during an attack")
{
PASSES_RANDOMLY(1, 2, RNG_RANDOM_TARGET); // test fails if we target soundproof mon
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_SLEEP); }
Expand Down
5 changes: 2 additions & 3 deletions test/battle/status1/burn.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#include "global.h"
#include "test/battle.h"

SINGLE_BATTLE_TEST("Burn deals 1/16th damage per turn")
SINGLE_BATTLE_TEST("Burn deals 1/16th (Gen7+) or 1/8th damage per turn")
{
u32 j;
GIVEN {
ASSUME(B_BURN_DAMAGE >= GEN_LATEST);
PLAYER(SPECIES_WOBBUFFET) { Status1(STATUS1_BURN); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
Expand All @@ -14,7 +13,7 @@ SINGLE_BATTLE_TEST("Burn deals 1/16th 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 / 16);
HP_BAR(player, damage: maxHP / ((B_BURN_DAMAGE >= GEN_7) ? 16 : 8));
}
}

Expand Down
4 changes: 2 additions & 2 deletions test/battle/status1/frostbite.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ SINGLE_BATTLE_TEST("Frostbite reduces the special attack by 50 percent")
} THEN { EXPECT_EQ(reducedDamage * 2, normaleDamage); }
}

SINGLE_BATTLE_TEST("Frostbite deals 1/16 damage to effected pokemon")
SINGLE_BATTLE_TEST("Frostbite deals 1/16th (Gen7+) or 1/8th damage to affected pokemon")
{
s16 frostbiteDamage;

Expand All @@ -36,7 +36,7 @@ SINGLE_BATTLE_TEST("Frostbite deals 1/16 damage to effected pokemon")
MESSAGE("Foe Wobbuffet is hurt by its frostbite!");
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_FRZ, opponent);
HP_BAR(opponent, captureDamage: &frostbiteDamage);
} THEN { EXPECT_EQ(frostbiteDamage, opponent->maxHP / 16); }
} THEN { EXPECT_EQ(frostbiteDamage, opponent->maxHP / ((B_BURN_DAMAGE >= GEN_7) ? 16 : 8)); }
}

SINGLE_BATTLE_TEST("Frostbite is healed if hit with a thawing move")
Expand Down
Loading