diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_AlphaDetector.cpp b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_AlphaDetector.cpp index 9e6ca8be01..18de05632b 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_AlphaDetector.cpp +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_AlphaDetector.cpp @@ -57,6 +57,48 @@ class Test_AlphaDetector : public UnitTest{ }; void add_tests_AlphaDetector(UnitTestDatabase& database){ + database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", false); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", false); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", false); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", false); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", false); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", false); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", false); + database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", false); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", false); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", false); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", false); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", false); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", false); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", false); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", false); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/machamp_Regular.png", false); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", false); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", false); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", false); + database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", true); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", false); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", false); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", false); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", false); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", false); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", false); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", false); } diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BallReader.cpp b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BallReader.cpp index e21dceb65d..1190aa81ca 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BallReader.cpp +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BallReader.cpp @@ -158,6 +158,47 @@ class Test_BallReader : public UnitTest{ void add_tests_BallReader(UnitTestDatabase& database){ database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", "ultra-ball"); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", "ultra-ball"); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", "repeat-ball"); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", "quick-ball"); + database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", "cherish-ball"); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", "ultra-ball"); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", "ultra-ball"); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", "dive-ball"); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", "quick-ball"); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", "quick-ball"); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", "ultra-ball"); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", "net-ball"); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", "ultra-ball"); + database.add("PokemonHome/SummaryScreen/machamp_Regular.png", "repeat-ball"); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", "luxury-ball"); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", "ultra-ball"); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", "great-ball"); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", "jet-ball"); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", "great-ball"); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", "beast-ball"); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", "cherish-ball"); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", "quick-ball"); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", "wing-ball"); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", "luxury-ball"); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", "poke-ball"); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", "luxury-ball"); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", "ultra-ball"); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", "premier-ball"); } diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BoxGenderDetector.cpp b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BoxGenderDetector.cpp index c2cff39010..42b85250ef 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BoxGenderDetector.cpp +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BoxGenderDetector.cpp @@ -97,6 +97,47 @@ class Test_BoxGenderDetector : public UnitTest{ void add_tests_BoxGenderDetector(UnitTestDatabase& database){ database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", Pokemon::StatsHuntGenderFilter::Genderless); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", Pokemon::StatsHuntGenderFilter::Genderless); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", Pokemon::StatsHuntGenderFilter::Genderless); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", Pokemon::StatsHuntGenderFilter::Genderless); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", Pokemon::StatsHuntGenderFilter::Genderless); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", Pokemon::StatsHuntGenderFilter::Genderless); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/machamp_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", Pokemon::StatsHuntGenderFilter::Genderless); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", Pokemon::StatsHuntGenderFilter::Genderless); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", Pokemon::StatsHuntGenderFilter::Female); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", Pokemon::StatsHuntGenderFilter::Male); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", Pokemon::StatsHuntGenderFilter::Female); } diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BoxViewDetector.cpp b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BoxViewDetector.cpp index 92a5a97c30..e57a42c798 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BoxViewDetector.cpp +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_BoxViewDetector.cpp @@ -57,9 +57,48 @@ class Test_BoxViewDetector : public UnitTest{ void add_tests_BoxViewDetector(UnitTestDatabase& database){ database.add("PokemonHome/BoxView/BoxView-1.png", true); + database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", false); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", false); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", false); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", false); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", false); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", false); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", false); database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", false); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", false); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", false); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", false); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", false); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", false); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", false); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", false); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", false); database.add("PokemonHome/SummaryScreen/machamp_Regular.png", false); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", false); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", false); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", false); database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", false); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", false); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", false); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", false); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", false); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", false); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", false); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", false); } } diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_ButtonDetector.cpp b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_ButtonDetector.cpp index a06902f0c0..f52cfdb8a3 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_ButtonDetector.cpp +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_ButtonDetector.cpp @@ -206,6 +206,47 @@ class Test_ButtonDetector : public UnitTest{ void add_tests_ButtonDetector(UnitTestDatabase& database){ database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/machamp_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", ButtonType::ButtonB); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", ButtonType::ButtonB); } } diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_GigantamaxDetector.cpp b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_GigantamaxDetector.cpp index 998caf2b76..d7afced950 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_GigantamaxDetector.cpp +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_GigantamaxDetector.cpp @@ -117,6 +117,47 @@ class Test_GigantamaxDetector : public UnitTest{ void add_tests_GigantamaxDetector(UnitTestDatabase& database){ database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", false); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", false); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", false); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", false); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", false); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", false); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", false); + database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", false); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", false); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", false); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", true); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", false); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", false); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", false); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", false); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/machamp_Regular.png", false); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", false); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", false); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", false); + database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", false); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", false); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", false); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", false); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", false); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", false); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", false); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", false); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", false); } diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_GigantamaxDetector.h b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_GigantamaxDetector.h index ea8737ecff..81998fa19f 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_GigantamaxDetector.h +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_GigantamaxDetector.h @@ -23,7 +23,7 @@ class GigantamaxDetector : public StaticScreenDetector{ GigantamaxDetector( Color color, VideoOverlay* overlay, - const ImageFloatBox& box + const ImageFloatBox& box = ImageFloatBox(0.463, 0.09, 0.04, 0.06) ); const ImageFloatBox& last_detected() const{ return m_last_detected; } diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_OriginMarkReader.cpp b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_OriginMarkReader.cpp index aab7e09396..67b92e3115 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_OriginMarkReader.cpp +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_OriginMarkReader.cpp @@ -260,19 +260,27 @@ OriginMark origin_mark_from_slug(const std::string& slug){ throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Invalid origin mark slug: " + slug); } -OriginMark OriginMarkReader::read_mark( - const ImageViewRGB32& original_screen, - const ImageFloatBox& box -){ +OriginMarkReader::OriginMarkReader(Color color, VideoOverlay* overlay) + : m_color(color) + , m_overlay(overlay) + , m_box(0.617, 0.084, 0.044, 0.069) +{} + +void OriginMarkReader::make_overlays(VideoOverlaySet& items) const{ + items.add(m_color, m_box); +} + +OriginMark OriginMarkReader::read_mark(const ImageViewRGB32& original_screen){ const double screen_rel_size = (original_screen.height() / 1080.0); const double screen_rel_size_2 = screen_rel_size * screen_rel_size; const double min_area_1080p = 400; const size_t min_area = size_t(screen_rel_size_2 * min_area_1080p); - ImageViewRGB32 image = extract_box_reference(original_screen, box); + ImageViewRGB32 image = extract_box_reference(original_screen, m_box); m_last_detected.clear(); + m_last_detected_box.reset(); std::multimap> candidates; @@ -289,7 +297,7 @@ OriginMark OriginMarkReader::read_mark( m_last_detected.emplace_back( DetectedBox{ matcher->name(), - translate_to_parent(original_screen, box, object) + translate_to_parent(original_screen, m_box, object) } ); return true; @@ -297,6 +305,9 @@ OriginMark OriginMarkReader::read_mark( ); if (!m_last_detected.empty()){ + if (m_overlay){ + m_last_detected_box.emplace(*m_overlay, m_box, COLOR_GREEN); + } return origin_mark_from_slug(m_last_detected[0].name); } } @@ -318,7 +329,7 @@ class Test_OriginMarkReader : public UnitTest{ virtual UnitTestResult run(Logger& logger, CancellableScope& scope) const override{ ImageRGB32 image(m_image); - OriginMark result = OriginMarkReader().read_mark(image, ImageFloatBox(0.617, 0.084, 0.044, 0.069)); + OriginMark result = OriginMarkReader().read_mark(image); if (result == m_expected) return true; diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_OriginMarkReader.h b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_OriginMarkReader.h index 23cce3bcc8..67c4f933cc 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_OriginMarkReader.h +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_OriginMarkReader.h @@ -7,10 +7,12 @@ #ifndef PokemonAutomation_PokemonHome_OriginMarkReader_H #define PokemonAutomation_PokemonHome_OriginMarkReader_H +#include #include #include "Common/Cpp/TestRunners/UnitTestDatabase.h" #include "CommonFramework/ImageTypes/ImageViewRGB32.h" #include "CommonFramework/ImageTools/ImageBoxes.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" #include "CommonTools/DetectedBoxes.h" #include "Pokemon/Pokemon_OriginMarks.h" @@ -23,13 +25,20 @@ using Pokemon::OriginMark; class OriginMarkReader{ public: + OriginMarkReader(Color color = COLOR_RED, VideoOverlay* overlay = nullptr); + + void make_overlays(VideoOverlaySet& items) const; + OriginMark read_mark( - const ImageViewRGB32& original_screen, - const ImageFloatBox& box + const ImageViewRGB32& original_screen ); private: + Color m_color; + VideoOverlay* m_overlay; + ImageFloatBox m_box; std::vector m_last_detected; + std::optional m_last_detected_box; }; diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SelectionArrowDetector.cpp b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SelectionArrowDetector.cpp index 82086b5a7b..eccfb4be78 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SelectionArrowDetector.cpp +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SelectionArrowDetector.cpp @@ -159,6 +159,47 @@ class Test_SelectionArrowDetector : public UnitTest{ void add_tests_SelectionArrowDetector(UnitTestDatabase& database){ database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/machamp_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", std::nullopt); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", std::nullopt); } } diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_ShinyDetector.cpp b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_ShinyDetector.cpp index ac22064f3c..9c035e74c4 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_ShinyDetector.cpp +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_ShinyDetector.cpp @@ -57,6 +57,48 @@ class Test_ShinyDetector : public UnitTest{ }; void add_tests_ShinyDetector(UnitTestDatabase& database){ + database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", false); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", true); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", true); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", false); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", false); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", false); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", false); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", false); + database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", false); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", false); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", false); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", false); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", false); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", false); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", false); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", false); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", false); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/machamp_Regular.png", false); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", false); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", false); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", false); + database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", true); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", false); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", false); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", false); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", false); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", false); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", false); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", false); } diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SummaryReader.cpp b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SummaryReader.cpp index e4a656a453..8d45af006d 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SummaryReader.cpp +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SummaryReader.cpp @@ -4,6 +4,7 @@ * */ +#include #include #include "Common/Cpp/CancellableScope.h" #include "Common/Cpp/Strings/Unicode.h" @@ -94,7 +95,7 @@ int read_number( SummaryReader::SummaryReader(Color color) : m_color(color) , m_national_dex_number_box(0.448, 0.245, 0.049, 0.04) - , m_level_box(0.546, 0.099, 0.044, 0.041) + , m_level_box(0.506141, 0.090805, 0.100194, 0.057471) , m_original_trainer_id_box(0.782, 0.719, 0.193, 0.046) , m_original_trainer_name_box(0.492, 0.719, 0.165, 0.049) , m_nature_box(0.157, 0.783, 0.212, 0.042) @@ -130,11 +131,24 @@ std::string SummaryReader::read_ability(Language language, const ImageViewRGB32& return read_text(language, screen, m_ability_box, gray_text_filters()); } +// Due to the position of the level changing slightly depending on digits and language. The box contains the "Lv" text and the level number. int SummaryReader::read_level(Logger& logger, const ImageViewRGB32& screen) const{ - return read_number(logger, screen, m_level_box, gray_number_filters()); -} + try{ + std::string text = read_text(Language::English, screen, m_level_box, gray_text_filters()); + size_t pos = text.find('v'); + if (pos != std::string::npos){ + std::string level = text.substr(pos + 1); + return std::stoi(level); + } + return std::stoi(text.c_str()); + } + catch (const std::exception&){ + logger.log("Failed to read level from summary screen.", COLOR_RED); + return -1; + } +} class Test_SummaryReader_Numbers : public UnitTest{ public: @@ -206,8 +220,138 @@ class Test_SummaryReader_OtName : public UnitTest{ Language m_language; }; -void add_tests_SummaryReader(UnitTestDatabase& database){} - +void add_tests_SummaryReader(UnitTestDatabase& database){ + //Numbers + database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", 979, 493124, 75); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", 399, 4610, 5); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", 1, 493001, 6); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", 1, 493001, 4); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", 1, 725174, 51); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", 951, 493124, 15); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", 351, 248782, 13); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", 967, 254804, 45); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", 982, 911993, 45); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", 982, 787315, 60); + database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", 905, 250128, 50); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", 999, 493124, 35); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", 969, 254804, 35); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", 673, 57594, 38); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", 984, 402737, 100); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", 858, 302862, 60); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", 972, 254804, 45); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", 991, 92396, 60); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", 991, 493124, 57); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", 993, 493124, 58); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", 995, 493124, 57); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", 941, 254804, 45); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", 99, 840209, 40); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", 775, 254804, 45); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", 98, 840209, 20); + database.add("PokemonHome/SummaryScreen/machamp_Regular.png", 68, 639783, 100); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", 674, 225962, 29); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", 78, 144934, 37); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", 953, 493124, 26); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", 447, 348226, 25); + database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", 722, 764041, 31); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", 952, 493124, 41); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", 988, 402737, 100); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", 7, 700052, 1); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", 786, 181130, 62); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", 978, 493124, 52); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", 216, 333685, 29); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", 1024, 493124, 100); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", 37, 226403, 11); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", 37, 225962, 14); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", 8, 379916, 15); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", 265, 843926, 1); + //Text + database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", "hardy", "1nnerf0cus", Language::English); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", "10ne1y", "s1mp1e", Language::English); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", "re1axed", "", Language::English); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", "10ne1y", "", Language::English); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", "sassy", "", Language::English); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", "sassy", "1ns0mn1a", Language::English); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", "m0dest", "f0recast", Language::English); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", "1mp1sh", "shedsk1n", Language::English); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", "st111", "hasenfub", Language::German); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", "re1axed", "serenegrace", Language::English); + database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", "na1ve", "", Language::English); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", "qu1et", "ratt1ed", Language::English); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", "na1ve", "t0x1cdebr1s", Language::English); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", "qu1rky", "saps1pper", Language::English); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", "固执", "古代活性", Language::ChineseSimplified); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", "qu1et", "hea1er", Language::English); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", "b01d", "sandrush", Language::English); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", "carefu1", "quarkdr1ve", Language::English); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", "ca1m", "quarkdr1ve", Language::English); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", "d0c11e", "quarkdr1ve", Language::English); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", "carefu1", "quarkdr1ve", Language::English); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", "1mp1sh", "v01tabs0rb", Language::English); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", "10ne1y", "sheerf0rce", Language::English); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", "gent1e", "c0mat0se", Language::English); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", "hasty", "hypercutter", Language::English); + database.add("PokemonHome/SummaryScreen/machamp_Regular.png", "b01d", "guts", Language::English); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", "na1ve", "1r0nf1st", Language::English); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", "ca1m", "", Language::English); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", "hasty", "c0mp0undeyes", Language::English); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", "rash", "", Language::English); + database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", "rash", "", Language::English); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", "t1m1d", "1ns0mn1a", Language::English); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", "固执", "古代活性", Language::ChineseSimplified); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", "ruh1g", "sturzbach", Language::German); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", "sassy", "psych1csurge", Language::English); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", "rash", "c0mmander", Language::English); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", "m11d", "", Language::English); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", "hardy", "terash1ft", Language::English); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", "frech", "feuerfanger", Language::German); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", "fr0h", "feuerfanger", Language::German); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", "mut1g", "sturzbach", Language::German); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", "sassy", "sh1e1ddust", Language::English); + //OT Name + database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", "h1karu", Language::English); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", "kev1n", Language::English); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", "kev1n", Language::English); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", "zazuba", Language::English); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", "kr0n0s", Language::English); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", "bj0rn", Language::German); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", "mythra", Language::English); + database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", "h0me", Language::English); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", "このは", Language::Japanese); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", "yam1", Language::English); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", "hunter", Language::English); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", "t0r1", Language::English); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", "maarxx1e", Language::English); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", "maarxx1e", Language::English); + database.add("PokemonHome/SummaryScreen/machamp_Regular.png", "g10r1a", Language::English); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", "m00n", Language::English); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", "emmy", Language::English); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", "b0nd", Language::English); + database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", "akar1", Language::English); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", "yam1", Language::English); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", "puppycat1012", Language::English); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", "aka1a", Language::English); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", "コウ", Language::Japanese); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", "da1t0n", Language::English); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", "bj0rn", Language::German); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", "m00n", Language::English); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", "ru", Language::German); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", "r0n", Language::English); +} + } } diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SummaryScreenDetector.cpp b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SummaryScreenDetector.cpp index 246caf9e5a..57b2eae1d5 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SummaryScreenDetector.cpp +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_SummaryScreenDetector.cpp @@ -54,9 +54,48 @@ class Test_SummaryScreenDetector : public UnitTest{ void add_tests_SummaryScreenDetector(UnitTestDatabase& database){ database.add("PokemonHome/BoxView/BoxView-1.png", false); + database.add("PokemonHome/SummaryScreen/annihilape_Regular.png", true); + database.add("PokemonHome/SummaryScreen/bidoof_Regular.png", true); + database.add("PokemonHome/SummaryScreen/bulbasaur_Regular.png", true); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Go.png", true); + database.add("PokemonHome/SummaryScreen/bulbasuar_Shiny_Lza.png", true); + database.add("PokemonHome/SummaryScreen/capskid_Regular.png", true); + database.add("PokemonHome/SummaryScreen/castform_Regular.png", true); + database.add("PokemonHome/SummaryScreen/cyclizar_Regular.png", true); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular.png", true); + database.add("PokemonHome/SummaryScreen/dudunsparce_Regular_Sv.png", true); database.add("PokemonHome/SummaryScreen/enamorus_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/gimmighoul_Regular.png", true); + database.add("PokemonHome/SummaryScreen/glimmet_Regular.png", true); + database.add("PokemonHome/SummaryScreen/gogoat_Regular.png", true); + database.add("PokemonHome/SummaryScreen/greatTusk_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/hatterne_Regular.png", true); + database.add("PokemonHome/SummaryScreen/houndstone_Regular.png", true); + database.add("PokemonHome/SummaryScreen/ironBunde_Regular.png", true); + database.add("PokemonHome/SummaryScreen/ironBundle_Regular_Sv.png", true); + database.add("PokemonHome/SummaryScreen/ironJugulis_Regular.png", true); + database.add("PokemonHome/SummaryScreen/ironThorns_Regular.png", true); + database.add("PokemonHome/SummaryScreen/kilowattrel_Regular.png", true); + database.add("PokemonHome/SummaryScreen/kingler_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/komala_Regular.png", true); + database.add("PokemonHome/SummaryScreen/krabby_Shiny.png", true); database.add("PokemonHome/SummaryScreen/machamp_Regular.png", true); + database.add("PokemonHome/SummaryScreen/pancham_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/rapidash_Regular.png", true); + database.add("PokemonHome/SummaryScreen/rellor_Regular.png", true); + database.add("PokemonHome/SummaryScreen/riolu_Regular.png", true); database.add("PokemonHome/SummaryScreen/rowlet_ShinyAlpha.png", true); + database.add("PokemonHome/SummaryScreen/scovillain_Regular.png", true); + database.add("PokemonHome/SummaryScreen/slitherWing_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/squirtle_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/tapuLele_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/tatsugiri_Regular.png", true); + database.add("PokemonHome/SummaryScreen/teddiursa_Regular.png", true); + database.add("PokemonHome/SummaryScreen/terapagos_regular.png", true); + database.add("PokemonHome/SummaryScreen/vulpix_Regular.png", true); + database.add("PokemonHome/SummaryScreen/vulpix_Shiny.png", true); + database.add("PokemonHome/SummaryScreen/wartortle_Regular.png", true); + database.add("PokemonHome/SummaryScreen/wurmple_Regular.png", true); } } diff --git a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_TeraTypeReader.h b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_TeraTypeReader.h index 1256572122..260cc5018b 100644 --- a/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_TeraTypeReader.h +++ b/SerialPrograms/Source/PokemonHome/Inference/PokemonHome_TeraTypeReader.h @@ -27,7 +27,7 @@ std::multimap> find_t // Reads the tera type of a Pokemon. Pokemon::PokemonTeraType read_pokemon_tera_type( const ImageViewRGB32& original_screen, - const ImageFloatBox& box + const ImageFloatBox& box = ImageFloatBox(0.463, 0.09, 0.04, 0.06) ); void add_tests_TeraTypeReader(UnitTestDatabase& database); diff --git a/SerialPrograms/Source/PokemonHome/PokemonHome_Panels.cpp b/SerialPrograms/Source/PokemonHome/PokemonHome_Panels.cpp index bbd1f3eb4b..70876b76bf 100644 --- a/SerialPrograms/Source/PokemonHome/PokemonHome_Panels.cpp +++ b/SerialPrograms/Source/PokemonHome/PokemonHome_Panels.cpp @@ -16,6 +16,7 @@ #include "Programs/PokemonHome_GenerateNameOCR.h" #include "Programs/TestPrograms/PokemonHome_ReadSummaryScreen.h" +#include "Programs/TestPrograms/PokemonHome_TestDatabaseGenerator.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -51,6 +52,7 @@ std::vector PanelListFactory::make_panels() const{ ret.emplace_back("---- Developer Tools ----"); ret.emplace_back(make_single_switch_program()); ret.emplace_back(make_single_switch_program()); + ret.emplace_back(make_single_switch_program()); } return ret; diff --git a/SerialPrograms/Source/PokemonHome/Programs/PokemonHome_BoxNavigation.cpp b/SerialPrograms/Source/PokemonHome/Programs/PokemonHome_BoxNavigation.cpp index 9af9a160ae..4efeda5e0f 100644 --- a/SerialPrograms/Source/PokemonHome/Programs/PokemonHome_BoxNavigation.cpp +++ b/SerialPrograms/Source/PokemonHome/Programs/PokemonHome_BoxNavigation.cpp @@ -225,24 +225,23 @@ void read_summary_screen( ) { VideoOverlaySet video_overlay_set(env.console); - ImageFloatBox gmax_tera_symbol_box(0.463, 0.09, 0.04, 0.06); // gmax OR tera symbol pos - ImageFloatBox origin_symbol_box(0.617, 0.084, 0.044, 0.069); // origin symbol pos ImageFloatBox pokemon_box(0.69, 0.18, 0.28, 0.46); // pokemon render pos ImageFloatBox type_box(0.615, 0.240, 0.071, 0.057); // Type symbols + video_overlay_set.add(COLOR_DARK_BLUE, pokemon_box); + video_overlay_set.add(COLOR_RED, type_box); - - video_overlay_set.add(COLOR_RED, gmax_tera_symbol_box); + GigantamaxDetector gmax_detector(COLOR_RED, &env.console.overlay()); ShinyDetector shiny_detector(COLOR_RED, &env.console.overlay()); AlphaDetector alpha_detector(COLOR_RED, &env.console.overlay()); + OriginMarkReader origin_mark_reader(COLOR_RED, &env.console.overlay()); + SummaryReader summary_reader(COLOR_RED); + + gmax_detector.make_overlays(video_overlay_set); shiny_detector.make_overlays(video_overlay_set); alpha_detector.make_overlays(video_overlay_set); - video_overlay_set.add(COLOR_DARKGREEN, origin_symbol_box); - video_overlay_set.add(COLOR_DARK_BLUE, pokemon_box); - video_overlay_set.add(COLOR_RED, type_box); - BoxGenderDetector::make_overlays(video_overlay_set); - SummaryReader summary_reader(COLOR_RED); + origin_mark_reader.make_overlays(video_overlay_set); summary_reader.make_overlays(video_overlay_set); - + BoxGenderDetector::make_overlays(video_overlay_set); // Wait for the summary screen transition to end FrozenImageDetector frozen_image_detector(COLOR_GREEN, { 0.388, 0.238, 0.109, 0.062 }, Milliseconds(80), 20); @@ -265,10 +264,9 @@ void read_summary_screen( const bool is_shiny = shiny_detector.detect(screen); cur_pokemon_info.shiny = is_shiny; - GigantamaxDetector gmax_detector(COLOR_RED, &env.console.overlay(), gmax_tera_symbol_box); cur_pokemon_info.gmax = gmax_detector.detect(screen); - cur_pokemon_info.tera_type = read_pokemon_tera_type(screen, gmax_tera_symbol_box); + cur_pokemon_info.tera_type = read_pokemon_tera_type(screen); const bool is_alpha = alpha_detector.detect(screen); cur_pokemon_info.alpha = is_alpha; @@ -295,7 +293,7 @@ void read_summary_screen( ot_name_language, screen ); - cur_pokemon_info.origin_mark = OriginMarkReader().read_mark(screen, origin_symbol_box); + cur_pokemon_info.origin_mark = origin_mark_reader.read_mark(screen); env.add_overlay_log(create_overlay_info(cur_pokemon_info)); video_overlay_set.clear(); diff --git a/SerialPrograms/Source/PokemonHome/Programs/TestPrograms/PokemonHome_TestDatabaseGenerator.cpp b/SerialPrograms/Source/PokemonHome/Programs/TestPrograms/PokemonHome_TestDatabaseGenerator.cpp new file mode 100644 index 0000000000..2d74eef43f --- /dev/null +++ b/SerialPrograms/Source/PokemonHome/Programs/TestPrograms/PokemonHome_TestDatabaseGenerator.cpp @@ -0,0 +1,369 @@ +/* Pokemon Home Test Database Generator + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "Common/Cpp/Filesystem/Filesystem.h" +#include "CommonFramework/ImageTypes/ImageRGB32.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include "Pokemon/Options/Pokemon_StatsHuntFilter.h" +#include "Pokemon/Pokemon_OriginMarks.h" +#include "Pokemon/Resources/Pokemon_PokemonSlugs.h" +#include "Pokemon/Pokemon_Strings.h" +#include "Pokemon/Pokemon_Types.h" +#include "PokemonHome/Inference/PokemonHome_BallReader.h" +#include "PokemonHome/Inference/PokemonHome_AlphaDetector.h" +#include "PokemonHome/Inference/PokemonHome_BoxGenderDetector.h" +#include "PokemonHome/Inference/PokemonHome_BoxViewDetector.h" +#include "PokemonHome/Inference/PokemonHome_ButtonDetector.h" +#include "PokemonHome/Inference/PokemonHome_GigantamaxDetector.h" +#include "PokemonHome/Inference/PokemonHome_OriginMarkReader.h" +#include "PokemonHome/Inference/PokemonHome_SelectionArrowDetector.h" +#include "PokemonHome/Inference/PokemonHome_ShinyDetector.h" +#include "PokemonHome/Inference/PokemonHome_SummaryReader.h" +#include "PokemonHome/Inference/PokemonHome_SummaryScreenDetector.h" +#include "PokemonHome/Inference/PokemonHome_TeraTypeReader.h" +#include "PokemonHome_TestDatabaseGenerator.h" + + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonHome{ +using namespace Pokemon; + + +TestDatabaseGenerator_Descriptor::TestDatabaseGenerator_Descriptor() + : SingleSwitchProgramDescriptor( + "PokemonHome:TestDatabaseGenerator", + STRING_POKEMON + " Home", "Test Database Generator", + "", + "Run all Pokemon Home image readers and detectors against a directory of screenshots.", + ProgramControllerClass::StandardController_NoRestrictions, + FeedbackType::NONE, + AllowCommandsWhenRunning::DISABLE_COMMANDS + ) +{} + +TestDatabaseGenerator::TestDatabaseGenerator() + : DIRECTORY( + false, + "Screenshot Directory:", + LockMode::LOCK_WHILE_RUNNING, + "", + "Path to a directory containing PNG screenshots." + ) + , PRINT_DIRECTORY( + false, + "Printed Directory Override:", + LockMode::LOCK_WHILE_RUNNING, + "", + "Optional directory prefix for logged and generated database paths." + ) + , RENAME_FILES( + "Rename Screenshots:", + LockMode::LOCK_WHILE_RUNNING, + false + ) +{ + PA_ADD_OPTION(DIRECTORY); + PA_ADD_OPTION(PRINT_DIRECTORY); + PA_ADD_OPTION(RENAME_FILES); +} + +namespace{ + +[[nodiscard]] std::string optional_arrow_name(std::optional arrow){ + if (!arrow){ + return "none"; + } + return *arrow == SelectionArrowType::RIGHT ? "right" : "down"; +} + +[[nodiscard]] std::string to_uppercase(std::string value){ + std::transform(value.begin(), value.end(), value.begin(), [](unsigned char c){ + return static_cast(std::toupper(c)); + }); + return value; +} + +[[nodiscard]] std::string quote_string(std::string value){ + return "\"" + value + "\""; +} + +[[nodiscard]] std::string boolean(bool value){ + return value ? "true" : "false"; +} + +} + +struct TestEntry{ + std::string box_view; + std::string summary; + std::string shiny; + std::string alpha; + std::string gigantamax; + std::string selection_arrow; + std::string button; + std::string ball; + std::string gender; + std::string tera_type; + std::string origin_mark; + std::string summary_numbers; + std::string summary_text; + std::string summary_ot_name; +}; + + +void TestDatabaseGenerator::program( + SingleSwitchProgramEnvironment& env, + CancellableScope& scope +){ + const Filesystem::Path directory = Filesystem::Path((std::string)DIRECTORY); + std::vector screenshots; + + try{ + for (const std::filesystem::directory_entry& entry : std::filesystem::directory_iterator(directory.stdpath())){ + if (!entry.is_regular_file()) + continue; + + Filesystem::Path path(entry.path()); + std::string extension = path.extension().string(); + std::transform(extension.begin(), extension.end(), extension.begin(), [](unsigned char c){ + return (char)std::tolower(c); + }); + if (extension == ".png") + screenshots.emplace_back(std::move(path)); + } + }catch (const std::filesystem::filesystem_error& error){ + env.log(std::string("Unable to read screenshot directory: ") + error.what(), COLOR_RED); + return; + } + + std::sort(screenshots.begin(), screenshots.end(), [](const Filesystem::Path& x, const Filesystem::Path& y){ + return x.string() < y.string(); + }); + + std::vector entries; + entries.reserve(screenshots.size()); + + for (const Filesystem::Path& path : screenshots){ + try{ + ImageRGB32 image(path.string()); + ImageFloatBox arrow_box(0.021, 0.073, 0.47, 0.72); + ImageFloatBox button_box(0.100, 0.956, 0.107, 0.041); + + SummaryReader summary_reader; + const int dex_number = summary_reader.read_national_dex(env.console, image); + const int original_trainer_id = summary_reader.read_original_trainer_id(env.console, image); + const std::string original_trainer_name = summary_reader.read_original_trainer_name(Language::English, image); + const std::string nature = summary_reader.read_nature(Language::English, image); + const std::string ability = summary_reader.read_ability(Language::English, image); + const int level = summary_reader.read_level(env.console, image); + BoxViewDetector box_view_detector(&env.console.overlay()); + SummaryScreenDetector summary_detector(&env.console.overlay()); + ShinyDetector shiny_detector(COLOR_RED, &env.console.overlay()); + AlphaDetector alpha_detector(COLOR_RED, &env.console.overlay()); + GigantamaxDetector gigantamax_detector(COLOR_RED, &env.console.overlay()); + SelectionArrowDetector right_arrow_detector(COLOR_RED, &env.console.overlay(), SelectionArrowType::RIGHT, arrow_box); + SelectionArrowDetector down_arrow_detector(COLOR_RED, &env.console.overlay(), SelectionArrowType::DOWN, arrow_box); + ButtonDetector b_detector(COLOR_RED, ButtonType::ButtonB, button_box, &env.console.overlay()); + ButtonDetector plus_detector(COLOR_RED, ButtonType::ButtonPlus, button_box, &env.console.overlay()); + BallReader ball_reader(env.console); + OriginMarkReader origin_reader; + + const bool box_view = box_view_detector.detect(image); + const bool summary = summary_detector.detect(image); + const bool shiny = shiny_detector.detect(image); + const bool alpha = alpha_detector.detect(image); + const bool gigantamax = gigantamax_detector.detect(image); + const bool right_arrow = right_arrow_detector.detect(image); + const bool down_arrow = down_arrow_detector.detect(image); + const bool button_b = b_detector.detect(image); + const bool button_plus = plus_detector.detect(image); + const std::string ball = ball_reader.read_ball(image); + const Pokemon::StatsHuntGenderFilter gender = BoxGenderDetector::detect(image); + const Pokemon::PokemonTeraType tera_type = read_pokemon_tera_type(image, { 0.463, 0.09, 0.04, 0.06 }); + const Pokemon::OriginMark origin = origin_reader.read_mark(image); + + std::string renamed_path; + if (RENAME_FILES){ + if (dex_number <= 0 || dex_number > static_cast(NATIONAL_DEX_SLUGS().size())){ + env.log(path.string() + " | unable to rename: invalid dex number " + std::to_string(dex_number), COLOR_RED); + }else{ + const std::string new_name = NATIONAL_DEX_SLUGS()[dex_number - 1] + + "_" + (alpha ? "Alpha" : "Regular") + + (shiny ? "_Shiny" : "") + + "_" + ORIGIN_MARK_SLUGS().get_string(origin) + + ".png"; + const Filesystem::Path destination = path.parent_path() / new_name; + if (destination == path){ + renamed_path = destination.string(); + }else if (Filesystem::exists(destination)){ + env.log(path.string() + " | unable to rename: destination already exists " + destination.string(), COLOR_RED); + }else{ + Filesystem::rename(path, destination); + renamed_path = destination.string(); + } + } + } + + std::optional arrow; + if (right_arrow) + arrow = SelectionArrowType::RIGHT; + else if (down_arrow) + arrow = SelectionArrowType::DOWN; + + const Filesystem::Path database_file = renamed_path.empty() ? path : Filesystem::Path(renamed_path); + const std::string print_directory = (std::string)PRINT_DIRECTORY; + const std::string database_path = print_directory.empty() + ? database_file.string() + : print_directory + database_file.filename().string(); + + std::ostringstream output; + output << std::boolalpha + << database_path; + if (!renamed_path.empty()){ + output << " (renamed -> " << renamed_path << ")"; + } + output << "\n" + << " UI State: box-view=" << box_view + << ", summary=" << summary + << ", arrow=" << optional_arrow_name(arrow) + << ", B=" << button_b + << ", plus=" << button_plus << "\n" + << " Box Indicators: form=" << (alpha ? "Alpha" : "Regular") + << ", shiny=" << shiny + << ", gigantamax=" << gigantamax + << ", gender=" << gender_to_string(gender) + << ", ball=" << (ball.empty() ? "none" : ball) + << ", tera=" << POKEMON_TERA_TYPE_SLUGS().get_string(tera_type) + << ", origin=" << ORIGIN_MARK_SLUGS().get_string(origin) << "\n" + << " Summary Info: dex=" << dex_number + << ", level=" << level + << ", nature=" << quote_string(nature) + << ", ability=" << quote_string(ability) + << ", OT=" << quote_string(original_trainer_name) + << ", OT-ID=" << original_trainer_id; + env.log(output.str()); + + TestEntry entry; + entry.summary_numbers = std::format( + "database.add({}, {}, {}, {});", + quote_string(database_path), dex_number, original_trainer_id, level + ); + + entry.summary_text = std::format( + "database.add({}, {}, {}, Language::English);", + quote_string(database_path), quote_string(nature), quote_string(ability) + ); + + entry.summary_ot_name = std::format( + "database.add({}, {}, Language::English);", + quote_string(database_path), quote_string(original_trainer_name) + ); + + entry.box_view = std::format( + "database.add({}, {});", quote_string(database_path), boolean(box_view) + ); + + entry.summary = std::format( + "database.add({}, {});", quote_string(database_path), boolean(summary) + ); + + entry.shiny = std::format( + "database.add({}, {});", quote_string(database_path), boolean(shiny) + ); + + entry.alpha = std::format( + "database.add({}, {});", quote_string(database_path), boolean(alpha) + ); + + entry.gigantamax = std::format( + "database.add({}, {});", quote_string(database_path), boolean(gigantamax) + ); + + entry.selection_arrow = std::format( + "database.add({}, {});", + quote_string(database_path), + arrow ? "SelectionArrowType::" + to_uppercase(optional_arrow_name(arrow)) : "std::nullopt" + ); + + entry.button = std::format( + "database.add({}, {});", + quote_string(database_path), + button_b ? "ButtonType::ButtonB" : button_plus ? "ButtonType::ButtonPlus" : "std::nullopt" + ); + + entry.ball = std::format( + "database.add({}, {});", quote_string(database_path), quote_string(ball) + ); + + entry.gender = std::format( + "database.add({}, Pokemon::StatsHuntGenderFilter::{});", + quote_string(database_path), gender_to_string(gender) + ); + + entry.tera_type = std::format( + "database.add({}, PokemonTeraType::{});", + quote_string(database_path), to_uppercase(POKEMON_TERA_TYPE_SLUGS().get_string(tera_type)) + ); + + entry.origin_mark = std::format( + "database.add({}, OriginMark::{});", + quote_string(database_path), to_uppercase(ORIGIN_MARK_SLUGS().get_string(origin)) + ); + + entries.push_back(std::move(entry)); + }catch (const std::exception& error){ + env.log(path.string() + " | error: " + error.what(), COLOR_RED); + } + } + + struct Section{ + const char* name; + std::string TestEntry::* member; + }; + static constexpr Section SECTIONS[] = { + {"BoxViewDetector", &TestEntry::box_view}, + {"SummaryScreenDetector", &TestEntry::summary}, + {"ShinyDetector", &TestEntry::shiny}, + {"AlphaDetector", &TestEntry::alpha}, + {"GigantamaxDetector", &TestEntry::gigantamax}, + {"SelectionArrowDetector", &TestEntry::selection_arrow}, + {"ButtonDetector", &TestEntry::button}, + {"BallReader", &TestEntry::ball}, + {"BoxGenderDetector", &TestEntry::gender}, + {"TeraTypeReader", &TestEntry::tera_type}, + {"OriginMarkReader", &TestEntry::origin_mark}, + {"SummaryReader_Numbers", &TestEntry::summary_numbers}, + {"SummaryReader_Text", &TestEntry::summary_text}, + {"SummaryReader_OtName", &TestEntry::summary_ot_name}, + }; + + const Filesystem::Path output_path = directory / "PokemonHome_TestDatabase.txt"; + std::ofstream output_file(output_path.string()); + if (!output_file){ + env.log("Unable to write database output file: " + output_path.string(), COLOR_RED); + return; + } + + for (const Section& section : SECTIONS){ + output_file << section.name << ":\n"; + for (const TestEntry& entry : entries){ + output_file << entry.*section.member << "\n"; + } + } +} + +} +} +} diff --git a/SerialPrograms/Source/PokemonHome/Programs/TestPrograms/PokemonHome_TestDatabaseGenerator.h b/SerialPrograms/Source/PokemonHome/Programs/TestPrograms/PokemonHome_TestDatabaseGenerator.h new file mode 100644 index 0000000000..64c9a744a2 --- /dev/null +++ b/SerialPrograms/Source/PokemonHome/Programs/TestPrograms/PokemonHome_TestDatabaseGenerator.h @@ -0,0 +1,43 @@ +/* Pokemon Home Test Database Generator + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonHome_TestDatabaseGenerator_H +#define PokemonAutomation_PokemonHome_TestDatabaseGenerator_H + +#include "Common/Cpp/Options/StringOption.h" +#include "Common/Cpp/Options/BooleanCheckBoxOption.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonHome{ + + +class TestDatabaseGenerator_Descriptor : public SingleSwitchProgramDescriptor{ +public: + TestDatabaseGenerator_Descriptor(); +}; + +class TestDatabaseGenerator : public SingleSwitchProgramInstance{ +public: + TestDatabaseGenerator(); + virtual void start_program_controller_check(ControllerSession& session) override{} + virtual void program( + SingleSwitchProgramEnvironment& env, + CancellableScope& scope + ) override; + +private: + StringOption DIRECTORY; + StringOption PRINT_DIRECTORY; + BooleanCheckBoxOption RENAME_FILES; +}; + + +} +} +} +#endif diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index f6da07157c..06af8bdff9 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1755,6 +1755,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonHome/Programs/PokemonHome_PageSwap.h Source/PokemonHome/Programs/TestPrograms/PokemonHome_ReadSummaryScreen.cpp Source/PokemonHome/Programs/TestPrograms/PokemonHome_ReadSummaryScreen.h + Source/PokemonHome/Programs/TestPrograms/PokemonHome_TestDatabaseGenerator.cpp + Source/PokemonHome/Programs/TestPrograms/PokemonHome_TestDatabaseGenerator.h Source/PokemonHome/Resources/PokemonHome_PokeballSprites.cpp Source/PokemonHome/Resources/PokemonHome_PokeballSprites.h Source/PokemonLA/Inference/Battles/PokemonLA_BattleMenuDetector.cpp