Skip to content

Commit d5a4e34

Browse files
committed
Add a feature to release all Pokémon from Boxes
1 parent ccb1b59 commit d5a4e34

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

src/swsh/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,18 @@ During the Egg hatch animation (RX/TX lighted up, L blinking) you can interrupt
274274
process by pressing the button. The process will give you back control. Press it again
275275
while on the Switch main menu (cursor on the game icon) to get back back into the
276276
automation “main menu” where you can choose another automation task.
277+
278+
### Release Boxes [Feature 5 - five button presses]
279+
280+
This feature allows releasing one or multiple Boxes of Pokémon.
281+
282+
**Pre-requisites:**
283+
284+
- The Boxes menu is open on the first Box whose Pokémon are to be released.
285+
- The selection modes (X/Y buttons) are normal.
286+
- The Boxes whose Pokémon are to be released are completely full.
287+
288+
When this feature is activated, it will start by moving the selection cursor
289+
to the top left Pokémon in the Box. It will then wait for input; press the
290+
button once to release all Pokémon in the current Box and move to the next Box
291+
(on the right); press the button twice when you are done.

src/swsh/swsh.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ static void go_to_nursery_helper(void);
2626
static void get_egg(void);
2727
static void move_in_circles(uint16_t cycles, bool go_up_first);
2828
static bool hatch_egg(void);
29+
static void release_full_boxes(void);
30+
static void position_box_cursor_topleft(void);
31+
static void for_each_box_pos(bool top_left_start, void (*callback)(void));
32+
static void release_from_box(void);
33+
2934

3035
int main(void)
3136
{
@@ -72,6 +77,10 @@ int main(void)
7277
auto_breeding();
7378
break;
7479

80+
case 5:
81+
release_full_boxes();
82+
break;
83+
7584
default:
7685
/* Wrong selection */
7786
delay(100, 200, 1500);
@@ -733,3 +742,115 @@ bool hatch_egg(void)
733742

734743
return false;
735744
}
745+
746+
747+
/*
748+
* From the Box menu, releases all Pokémon in the current box, then move
749+
* to the next Box. User confirmation is asked for each Box. The Boxes must
750+
* be completely full.
751+
*/
752+
void release_full_boxes(void)
753+
{
754+
position_box_cursor_topleft();
755+
756+
bool cursor_topleft = true;
757+
758+
for (;;) {
759+
/* Wait for user confirmation */
760+
beep();
761+
if (count_button_presses(500, 500) > 1) {
762+
/* User cancelled, we are done */
763+
return;
764+
}
765+
766+
/* Release the Box content */
767+
for_each_box_pos(cursor_topleft, &release_from_box);
768+
769+
/* The cursor position was toggled by the operation */
770+
cursor_topleft ^= true;
771+
772+
/* Move to the next Box */
773+
SEND_BUTTON_SEQUENCE(
774+
{ BT_R, DP_NEUTRAL, SEQ_MASH, 1 }, /* Next Box */
775+
);
776+
}
777+
}
778+
779+
780+
/*
781+
* Position the cursor to the top left Pokémon in the Box menu.
782+
*/
783+
void position_box_cursor_topleft(void)
784+
{
785+
/* We hold the D-pad to put the cursor in a known position (mashing it does
786+
not work since it makes the cursor roll around the edges of the screen).
787+
We need to avoir getting the cursor on the Box title since the D-pad
788+
will start changing the selected Box. The screen layout also tend to
789+
make the cursor stuck in random positions if diagonal directions are
790+
used.*/
791+
792+
SEND_BUTTON_SEQUENCE(
793+
{ BT_NONE, DP_BOTTOM, SEQ_HOLD, 25 }, /* Bottom row */
794+
{ BT_NONE, DP_LEFT, SEQ_HOLD, 25 }, /* Last Pokémon */
795+
{ BT_NONE, DP_TOP, SEQ_MASH, 5 }, /* First team Pokémon */
796+
{ BT_NONE, DP_RIGHT, SEQ_MASH, 1 }, /* Top/Left Box Pokémon */
797+
);
798+
}
799+
800+
801+
/*
802+
* Calls a callback after positioning the cursor on each Pokémon in the Box.
803+
* The starting position can either be the top left Pokémon or the bottom
804+
* right. The ending cursor position will be the reverse of the starting
805+
* cursor position.
806+
*/
807+
void for_each_box_pos(bool top_left_start, void (*callback)(void))
808+
{
809+
/* Do we go left on even rows (row 0, row 2, etc)? */
810+
uint8_t left_on_even = (top_left_start ? 0 : 1);
811+
812+
/* Which direction to use to move between rows? */
813+
enum d_pad_state change_row_dir = (top_left_start ? DP_BOTTOM : DP_TOP);
814+
815+
for (uint8_t row = 0 ; row < 5 ; row += 1) {
816+
for (uint8_t col = 0 ; col < 5 ; col += 1) {
817+
enum d_pad_state move_dir;
818+
819+
callback();
820+
821+
if ((row % 2) == left_on_even) {
822+
move_dir = DP_RIGHT;
823+
} else {
824+
move_dir = DP_LEFT;
825+
}
826+
827+
SEND_BUTTON_SEQUENCE(
828+
{ BT_NONE, move_dir, SEQ_MASH, 1 },
829+
);
830+
}
831+
832+
callback();
833+
if (row < 4) {
834+
SEND_BUTTON_SEQUENCE(
835+
{ BT_NONE, change_row_dir, SEQ_MASH, 1 },
836+
);
837+
}
838+
}
839+
}
840+
841+
842+
/*
843+
* Release from the Box the Pokémon on which the cursor is on.
844+
*/
845+
void release_from_box(void)
846+
{
847+
SEND_BUTTON_SEQUENCE(
848+
{ BT_A, DP_NEUTRAL, SEQ_HOLD, 8 }, /* Open menu */
849+
{ BT_NONE, DP_TOP, SEQ_MASH, 2 }, /* Go to option */
850+
{ BT_A, DP_NEUTRAL, SEQ_HOLD, 20 }, /* Select option */
851+
{ BT_NONE, DP_TOP, SEQ_MASH, 1 }, /* Go to Yes */
852+
{ BT_A, DP_NEUTRAL, SEQ_HOLD, 25 }, /* Validate dialog 1 */
853+
{ BT_NONE, DP_NEUTRAL, SEQ_HOLD, 1 }, /* Release 1 */
854+
{ BT_A, DP_NEUTRAL, SEQ_HOLD, 10 }, /* Validate dialog 2 */
855+
);
856+
}

0 commit comments

Comments
 (0)