From 445dd2c70361991855ddb6e427b9b021a740421d Mon Sep 17 00:00:00 2001 From: Dalton-V Date: Sat, 31 Oct 2026 21:53:44 -0500 Subject: [PATCH 1/3] FRLG BoxSorter LivingDex --- .../PokemonFRLG/PokemonFRLG_Panels.cpp | 3 + .../PokemonFRLG_BoxSorterLivingDex.cpp | 125 ++++++++++++++++++ .../PokemonFRLG_BoxSorterLivingDex.h | 58 ++++++++ SerialPrograms/cmake/SourceFiles.cmake | 2 + 4 files changed, 188 insertions(+) create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.cpp create mode 100644 SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.h diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Panels.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Panels.cpp index 7db5e9c999..4903c0cf80 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Panels.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Panels.cpp @@ -11,6 +11,8 @@ #include "PokemonFRLG_Settings.h" #include "Programs/BoxOrganization/PokemonFRLG_BoxSorter.h" + +#include "Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.h" #include "Programs/Farming/PokemonFRLG_EliteFourFarmer.h" #include "Programs/Farming/PokemonFRLG_HeldItemFarmer-SafariZone.h" #include "Programs/Farming/PokemonFRLG_ItemDuplication.h" @@ -92,6 +94,7 @@ std::vector PanelListFactory::make_panels() const{ if (IS_BETA_VERSION || STATIC_GLOBALS.DEVELOPER_MODE){ ret.emplace_back("---- Untested/Beta/WIP ----"); ret.emplace_back(make_SingleSwitchProgram()); + ret.emplace_back(make_SingleSwitchProgram()); } if (STATIC_GLOBALS.DEVELOPER_MODE){ diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.cpp new file mode 100644 index 0000000000..f3a9fe0ca2 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.cpp @@ -0,0 +1,125 @@ +/* Box Sorter Living Dex + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include +#include "Common/Cpp/Exceptions.h" +#include "Common/Cpp/Filesystem/FileIO.h" +#include "CommonFramework/GlobalAutoPaths.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" +#include "CommonTools/StartupChecks/StartProgramChecks.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonFRLG_BoxOrganization.h" +#include "PokemonFRLG_BoxSorterLivingDex.h" +#include "VideoGames/PokemonFRLG/PokemonFRLG_Navigation.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +using namespace Pokemon; + +BoxSorterLivingDex_Descriptor::BoxSorterLivingDex_Descriptor() + : SingleSwitchProgramDescriptor( + "PokemonFRLG:BoxSorterLivingDex", + STRING_POKEMON + " FRLG", "Box Sorter Living Dex", + "Programs/PokemonFRLG/BoxSorterLivingDex.html", + "Arrange boxes of " + STRING_POKEMON + " into living dex order. Start in Move " + STRING_POKEMON + + " with an empty hand in the first box to organize. Uses English species names.", + ProgramControllerClass::StandardController_NoRestrictions, + FeedbackType::REQUIRED, + AllowCommandsWhenRunning::DISABLE_COMMANDS + ) +{} + +std::unique_ptr BoxSorterLivingDex_Descriptor::make_stats() const{ + return std::unique_ptr(new Stats()); +} + +BoxSorterLivingDex::BoxSorterLivingDex() + : NUM_BOXES( + "Number of Boxes to Organize:
Starting with the current box and continuing to the right. " + "Include room after the template for duplicates and other Pokemon.", + LockMode::LOCK_WHILE_RUNNING, 8, 1, 14 + ) + , LIVING_DEX_TEMPLATE( + "Living Dex Template:
Placement begins in the first slot of the current box. " + "Missing species leave empty slots; extras follow the template. Forms are ignored.", + {{LivingDexTemplate::Condensed, "frlg_living_dex_condensed", "FRLG Living Dex (Condensed)"}}, + LockMode::LOCK_WHILE_RUNNING, LivingDexTemplate::Condensed + ) + , SHINY_DEX( + "Shiny Dex:
Only shiny Pokemon fill the living dex template. Non-shiny Pokemon follow the template with the extras.", + LockMode::LOCK_WHILE_RUNNING, false + ) + , DRY_RUN( + "Dry Run:
Scan boxes and write the current and organized box catalogues and " + "frlg-living-dex-missing-pokemon.txt without moving any " + STRING_POKEMON + ".", + LockMode::LOCK_WHILE_RUNNING, false + ) + , NOTIFICATIONS({&NOTIFICATION_PROGRAM_FINISH, &NOTIFICATION_ERROR_FATAL}) +{ + PA_ADD_OPTION(NUM_BOXES); + PA_ADD_OPTION(LIVING_DEX_TEMPLATE); + PA_ADD_OPTION(SHINY_DEX); + PA_ADD_OPTION(DRY_RUN); + PA_ADD_OPTION(NOTIFICATIONS); +} + +void BoxSorterLivingDex::program(SingleSwitchProgramEnvironment& env, ProControllerContext& context){ + home_black_border_check(env.console, context); + + std::vector living_dex_order; + bool obey_gender_differences; + switch (LIVING_DEX_TEMPLATE){ + case LivingDexTemplate::Condensed: + living_dex_order = load_living_dex_template( + RESOURCE_PATH() + "PokemonFRLG/Box/DexTemplates/frlg_living_dex_condensed.json" + ); + obey_gender_differences = false; + break; + default: + throw InternalProgramError(&env.logger(), PA_CURRENT_FUNCTION, "Invalid living dex template."); + } + const size_t slot_count = (size_t)NUM_BOXES * BOX_ROWS * BOX_COLS; + if (living_dex_order.size() > slot_count){ + const size_t boxes_required = (living_dex_order.size() + BOX_ROWS * BOX_COLS - 1) / (BOX_ROWS * BOX_COLS); + throw UserSetupError(env.console, + "The living dex template requires at least " + std::to_string(boxes_required) + " boxes." + ); + } + + const std::vector preferences{{SortingRuleType::DexNo, false}}; + auto& stats = env.current_stats(); + const bool shiny_dex = SHINY_DEX; + BoxOrganizationScan scan = scan_box_data(env, context, preferences, (uint16_t)NUM_BOXES, shiny_dex); + const auto boxes_sorted = make_living_dex_order( + env.logger(), scan.boxes_data, living_dex_order, obey_gender_differences, shiny_dex + ); + const BoxSortingPlan plan = make_box_sorting_plan(scan.boxes_data, boxes_sorted); + stats.compares += plan.compares; + env.update_stats(); + save_boxes_data_to_json(scan.boxes_data, "frlg-living-dex-box-order.json"); + save_boxes_data_to_json(boxes_sorted, "frlg-living-dex-box-order-sorted.json"); + env.log("Saved current and organized box catalogues."); + + if (DRY_RUN){ + env.log("Dry run complete."); + }else{ + env.log("Start living dex organization..."); + execute_box_sorting_plan(env, context, plan, scan.cursor, scan.mode); + } + + const std::string missing_path = "frlg-living-dex-missing-pokemon.txt"; + string_to_file(missing_path, make_missing_living_dex_report(boxes_sorted, living_dex_order)); + env.log("Saved missing Pokemon list to " + missing_path + "."); + send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); +} + + + +} +} +} diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.h b/SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.h new file mode 100644 index 0000000000..91bc2c9902 --- /dev/null +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.h @@ -0,0 +1,58 @@ +/* Box Sorter Living Dex + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonFRLG_BoxSorterLivingDex_H +#define PokemonAutomation_PokemonFRLG_BoxSorterLivingDex_H + +#include +#include "Common/Cpp/Options/BooleanCheckBoxOption.h" +#include "Common/Cpp/Options/EnumDropdownOption.h" +#include "Common/Cpp/Options/SimpleIntegerOption.h" +#include "CommonFramework/Notifications/EventNotificationsTable.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" + +namespace PokemonAutomation{ class Logger; } + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonFRLG{ + +struct BoxOrganizationStats; + +class BoxSorterLivingDex_Descriptor : public SingleSwitchProgramDescriptor{ +public: + BoxSorterLivingDex_Descriptor(); + + using Stats = BoxOrganizationStats; + virtual std::unique_ptr make_stats() const override; +}; + +class BoxSorterLivingDex : public SingleSwitchProgramInstance{ +public: + using Descriptor = BoxSorterLivingDex_Descriptor; + BoxSorterLivingDex(); + + virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override; + virtual void start_program_border_check(VideoStream&, FeedbackType) override{} + +private: + enum class LivingDexTemplate{ + Condensed, + }; + + SimpleIntegerOption NUM_BOXES; + EnumDropdownOption LIVING_DEX_TEMPLATE; + BooleanCheckBoxOption SHINY_DEX; + BooleanCheckBoxOption DRY_RUN; + EventNotificationsOption NOTIFICATIONS; +}; + + + +} +} +} +#endif diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 5d130faff9..767fe3d43a 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1765,6 +1765,8 @@ file(GLOB LIBRARY_SOURCES Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxOrganization.h Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorter.cpp Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorter.h + Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.cpp + Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.h Source/VideoGames/PokemonFRLG/Programs/Farming/PokemonFRLG_EliteFourFarmer.cpp Source/VideoGames/PokemonFRLG/Programs/Farming/PokemonFRLG_EliteFourFarmer.h Source/VideoGames/PokemonFRLG/Programs/Farming/PokemonFRLG_EvTrainer.cpp From 1ba7d45825c17c25a532f9d03fe4db772c8d6e13 Mon Sep 17 00:00:00 2001 From: Dalton-V Date: Fri, 6 Nov 2026 07:42:26 -0600 Subject: [PATCH 2/3] Fix build after rebase --- .../BoxOrganization/PokemonFRLG_BoxSorterLivingDex.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.cpp index f3a9fe0ca2..3ec3e23cc5 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.cpp @@ -12,8 +12,8 @@ #include "CommonTools/StartupChecks/StartProgramChecks.h" #include "Pokemon/Pokemon_Strings.h" #include "PokemonFRLG_BoxOrganization.h" -#include "PokemonFRLG_BoxSorterLivingDex.h" #include "VideoGames/PokemonFRLG/PokemonFRLG_Navigation.h" +#include "PokemonFRLG_BoxSorterLivingDex.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -28,6 +28,7 @@ BoxSorterLivingDex_Descriptor::BoxSorterLivingDex_Descriptor() "Programs/PokemonFRLG/BoxSorterLivingDex.html", "Arrange boxes of " + STRING_POKEMON + " into living dex order. Start in Move " + STRING_POKEMON + " with an empty hand in the first box to organize. Uses English species names.", + PanelQualityStanding::OFFICIAL_BETA, ProgramControllerClass::StandardController_NoRestrictions, FeedbackType::REQUIRED, AllowCommandsWhenRunning::DISABLE_COMMANDS From ac5566c286357311529694b95e8af97e79c0bb9a Mon Sep 17 00:00:00 2001 From: Dalton-V Date: Fri, 6 Nov 2026 07:43:11 -0600 Subject: [PATCH 3/3] cleanup --- .../Source/VideoGames/PokemonFRLG/PokemonFRLG_Panels.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Panels.cpp b/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Panels.cpp index 4903c0cf80..535e83b659 100644 --- a/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Panels.cpp +++ b/SerialPrograms/Source/VideoGames/PokemonFRLG/PokemonFRLG_Panels.cpp @@ -11,7 +11,6 @@ #include "PokemonFRLG_Settings.h" #include "Programs/BoxOrganization/PokemonFRLG_BoxSorter.h" - #include "Programs/BoxOrganization/PokemonFRLG_BoxSorterLivingDex.h" #include "Programs/Farming/PokemonFRLG_EliteFourFarmer.h" #include "Programs/Farming/PokemonFRLG_HeldItemFarmer-SafariZone.h"