Skip to content

Commit

Permalink
fixup! Fix speed ties
Browse files Browse the repository at this point in the history
  • Loading branch information
mrgriffin committed Jun 12, 2024
1 parent 7a041e1 commit 5ce276c
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 32 deletions.
2 changes: 1 addition & 1 deletion include/battle.h
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ struct BattleStruct
u8 quickClawRandom[MAX_BATTLERS_COUNT];
u8 quickDrawRandom[MAX_BATTLERS_COUNT];
u8 shellSideArmCategory[MAX_BATTLERS_COUNT][MAX_BATTLERS_COUNT];
u8 speedTieBreaks; // MAX_BATTLERS_COUNT! values, determines all speed tie-breaks.
u8 speedTieBreaks; // MAX_BATTLERS_COUNT! values.
};

// The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider,
Expand Down
47 changes: 31 additions & 16 deletions src/battle_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5164,29 +5164,44 @@ s32 GetWhichBattlerFasterOrTies(u32 battler1, u32 battler2, bool32 ignoreChosenM
);
}

u32 GetBattlerOrder(u32 battler)
// 24 == MAX_BATTLERS_COUNT!.
// These are the possible orders if all the battlers speed tie. An order
// is chosen at the start of the turn.
static const u8 sBattlerOrders[24][4] =
{
u32 i;
u32 div = MAX_BATTLERS_COUNT;
u32 n = gBattleStruct->speedTieBreaks;
for (i = 0; i < battler; i++)
{
n /= div;
div--;
}
if (div > 0)
return n % div;
else
return n;
}
{ 0, 1, 2, 3 },
{ 0, 1, 3, 2 },
{ 0, 2, 1, 3 },
{ 0, 2, 3, 1 },
{ 0, 3, 1, 2 },
{ 0, 3, 2, 1 },
{ 1, 0, 2, 3 },
{ 1, 0, 3, 2 },
{ 1, 2, 0, 3 },
{ 1, 2, 3, 0 },
{ 1, 3, 0, 2 },
{ 1, 3, 2, 0 },
{ 2, 0, 1, 3 },
{ 2, 0, 3, 1 },
{ 2, 1, 0, 3 },
{ 2, 1, 3, 0 },
{ 2, 3, 0, 1 },
{ 2, 3, 1, 0 },
{ 3, 0, 1, 2 },
{ 3, 0, 2, 1 },
{ 3, 1, 0, 2 },
{ 3, 1, 2, 0 },
{ 3, 2, 0, 1 },
{ 3, 2, 1, 0 },
};

s32 GetWhichBattlerFaster(u32 battler1, u32 battler2, bool32 ignoreChosenMoves)
{
s32 strikesFirst = GetWhichBattlerFasterOrTies(battler1, battler2, ignoreChosenMoves);
if (strikesFirst == 0)
{
s32 order1 = GetBattlerOrder(battler1);
s32 order2 = GetBattlerOrder(battler2);
s32 order1 = sBattlerOrders[gBattleStruct->speedTieBreaks][battler1];
s32 order2 = sBattlerOrders[gBattleStruct->speedTieBreaks][battler2];
if (order1 < order2)
strikesFirst = 1;
else
Expand Down
56 changes: 41 additions & 15 deletions test/battle/move.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ SINGLE_BATTLE_TEST("Turn order is determined by Speed if priority ties")
}
}

SINGLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie")
SINGLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie [singles]")
{
PASSES_RANDOMLY(1, 2, RNG_SPEED_TIE);
GIVEN {
Expand All @@ -80,15 +80,44 @@ SINGLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie"
}
}

DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie")
DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie [doubles]")
{
struct BattlePokemon *fastest = NULL;
PARAMETRIZE { fastest = playerLeft; }
PARAMETRIZE { fastest = playerRight; }
PARAMETRIZE { fastest = opponentLeft; }
PARAMETRIZE { fastest = opponentRight; }
struct BattlePokemon *order[4] = { NULL, NULL, NULL, NULL };
u32 a, b, c, d;

PASSES_RANDOMLY(1, 4, RNG_SPEED_TIE);
// TODO: Test all of these in a single PASSES_RANDOMLY pass rather
// than 24 PARAMETRIZEd passes.
PARAMETRIZE { a = 0; b = 1; c = 2; d = 3; }
PARAMETRIZE { a = 0; b = 1; c = 3; d = 2; }
PARAMETRIZE { a = 0; b = 2; c = 1; d = 3; }
PARAMETRIZE { a = 0; b = 2; c = 3; d = 1; }
PARAMETRIZE { a = 0; b = 3; c = 1; d = 2; }
PARAMETRIZE { a = 0; b = 3; c = 2; d = 1; }
PARAMETRIZE { a = 1; b = 0; c = 2; d = 3; }
PARAMETRIZE { a = 1; b = 0; c = 3; d = 2; }
PARAMETRIZE { a = 1; b = 2; c = 0; d = 3; }
PARAMETRIZE { a = 1; b = 2; c = 3; d = 0; }
PARAMETRIZE { a = 1; b = 3; c = 0; d = 2; }
PARAMETRIZE { a = 1; b = 3; c = 2; d = 0; }
PARAMETRIZE { a = 2; b = 0; c = 1; d = 3; }
PARAMETRIZE { a = 2; b = 0; c = 3; d = 1; }
PARAMETRIZE { a = 2; b = 1; c = 0; d = 3; }
PARAMETRIZE { a = 2; b = 1; c = 3; d = 0; }
PARAMETRIZE { a = 2; b = 3; c = 0; d = 1; }
PARAMETRIZE { a = 2; b = 3; c = 1; d = 0; }
PARAMETRIZE { a = 3; b = 0; c = 1; d = 2; }
PARAMETRIZE { a = 3; b = 0; c = 2; d = 1; }
PARAMETRIZE { a = 3; b = 1; c = 0; d = 2; }
PARAMETRIZE { a = 3; b = 1; c = 2; d = 0; }
PARAMETRIZE { a = 3; b = 2; c = 0; d = 1; }
PARAMETRIZE { a = 3; b = 2; c = 1; d = 0; }

order[a] = playerLeft;
order[b] = playerRight;
order[c] = opponentLeft;
order[d] = opponentRight;

PASSES_RANDOMLY(1, 24, RNG_SPEED_TIE);

GIVEN {
PLAYER(SPECIES_WOBBUFFET) { Speed(1); }
Expand All @@ -98,13 +127,10 @@ DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie"
} WHEN {
TURN { MOVE(playerLeft, MOVE_SPLASH); MOVE(playerRight, MOVE_SPLASH); MOVE(opponentLeft, MOVE_SPLASH); MOVE(opponentRight, MOVE_SPLASH); }
} SCENE {
NONE_OF {
if (fastest != playerLeft) ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, playerLeft);
if (fastest != playerRight) ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, playerRight);
if (fastest != opponentLeft) ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, opponentLeft);
if (fastest != opponentRight) ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, opponentRight);
}
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, fastest);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[0]);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[1]);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[2]);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, order[3]);
}
}

Expand Down

0 comments on commit 5ce276c

Please sign in to comment.