Skip to content

Commit b4ced98

Browse files
committed
2 parents 18ba017 + eec139a commit b4ced98

13 files changed

+338
-9
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,6 @@ opencv_world4110d.dll
5252

5353
# Python cache
5454
__pycache__
55+
56+
# Jupyter Notebooks
57+
*.ipynb

SerialPrograms/CMakeLists.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -992,13 +992,13 @@ file(GLOB MAIN_SOURCES
992992
Source/NintendoSwitch/Options/UI/NintendoSwitch_FriendCodeListWidget.h
993993
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip.cpp
994994
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip.h
995+
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManipBase.h
996+
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManipTools.cpp
997+
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManipTools.h
995998
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip_24h.cpp
996999
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip_24h.h
9971000
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip_US.cpp
9981001
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManip_US.h
999-
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManipBase.h
1000-
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManipTools.cpp
1001-
Source/NintendoSwitch/Programs/DateManip/NintendoSwitch_DateManipTools.h
10021002
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch_HomeToDateTime.cpp
10031003
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch_HomeToDateTime.h
10041004
Source/NintendoSwitch/Programs/DateSpam/NintendoSwitch_NeutralDateSkip.cpp
@@ -1058,6 +1058,8 @@ file(GLOB MAIN_SOURCES
10581058
Source/Pokemon/Inference/Pokemon_TrainPokemonOCR.cpp
10591059
Source/Pokemon/Inference/Pokemon_TrainPokemonOCR.h
10601060
Source/Pokemon/Options/Pokemon_EncounterBotOptions.h
1061+
Source/Pokemon/Options/Pokemon_HomeSpriteSelectOption.cpp
1062+
Source/Pokemon/Options/Pokemon_HomeSpriteSelectOption.h
10611063
Source/Pokemon/Options/Pokemon_IvJudgeOption.cpp
10621064
Source/Pokemon/Options/Pokemon_IvJudgeOption.h
10631065
Source/Pokemon/Options/Pokemon_NameSelectOption.cpp
@@ -1093,6 +1095,10 @@ file(GLOB MAIN_SOURCES
10931095
Source/Pokemon/Resources/Pokemon_EggSteps.h
10941096
Source/Pokemon/Resources/Pokemon_PokeballNames.cpp
10951097
Source/Pokemon/Resources/Pokemon_PokeballNames.h
1098+
Source/Pokemon/Resources/Pokemon_PokemonForms.cpp
1099+
Source/Pokemon/Resources/Pokemon_PokemonForms.h
1100+
Source/Pokemon/Resources/Pokemon_PokemonHomeSprites.cpp
1101+
Source/Pokemon/Resources/Pokemon_PokemonHomeSprites.h
10961102
Source/Pokemon/Resources/Pokemon_PokemonNames.cpp
10971103
Source/Pokemon/Resources/Pokemon_PokemonNames.h
10981104
Source/Pokemon/Resources/Pokemon_PokemonSlugs.cpp

SerialPrograms/Source/CommonTools/Resources/SpriteDatabase.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ class SpriteDatabase{
4242
const Sprite& get_throw(const std::string& slug) const;
4343
const Sprite* get_nothrow(const std::string& slug) const;
4444

45-
const std::map<std::string, Sprite>& get() const{
46-
return m_database;
47-
}
48-
4945
public:
5046
using const_iterator = std::map<std::string, Sprite>::const_iterator;
5147
using iterator = std::map<std::string, Sprite>::iterator;

SerialPrograms/Source/ML/Programs/ML_LabelImages.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,14 @@ LabelImages::LabelImages(const LabelImages_Descriptor& descriptor)
180180
, Y("<b>Y Coordinate:</b>", LockMode::UNLOCK_WHILE_RUNNING, 0.3, 0.0, 1.0)
181181
, WIDTH("<b>Width:</b>", LockMode::UNLOCK_WHILE_RUNNING, 0.4, 0.0, 1.0)
182182
, HEIGHT("<b>Height:</b>", LockMode::UNLOCK_WHILE_RUNNING, 0.4, 0.0, 1.0)
183+
, FORM_LABEL("bulbasaur")
183184
, m_sam_session{RESOURCE_PATH() + "ML/sam_cpu.onnx"}
184185
{
185186
ADD_OPTION(X);
186187
ADD_OPTION(Y);
187188
ADD_OPTION(WIDTH);
188189
ADD_OPTION(HEIGHT);
190+
ADD_OPTION(FORM_LABEL);
189191
}
190192
void LabelImages::from_json(const JsonValue& json){
191193
const JsonObject* obj = json.to_object();

SerialPrograms/Source/ML/Programs/ML_LabelImages.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include "CommonFramework/Panels/UI/PanelWidget.h"
1414
#include "CommonFramework/ImageTypes/ImageViewRGB32.h"
1515
#include "CommonFramework/ImageTypes/ImageRGB32.h"
16-
// #include "CommonFramework/VideoPipeline/VideoOverlayTypes.h"
16+
#include "Pokemon/Options/Pokemon_HomeSpriteSelectOption.h"
1717
#include "NintendoSwitch/Framework/NintendoSwitch_SwitchSystemOption.h"
1818
#include "NintendoSwitch/Framework/NintendoSwitch_SwitchSystemSession.h"
1919
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
@@ -65,6 +65,7 @@ class LabelImages : public PanelInstance{
6565
FloatingPointOption Y;
6666
FloatingPointOption WIDTH;
6767
FloatingPointOption HEIGHT;
68+
Pokemon::HomeSpriteSelectCell FORM_LABEL;
6869

6970
size_t source_image_height = 0;
7071
size_t source_image_width = 0;
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* HomeSprite Selector, UI component to select multiple berries
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#include "Common/Cpp/Exceptions.h"
8+
#include "CommonFramework/Logging/Logger.h"
9+
#include "Pokemon/Resources/Pokemon_PokemonForms.h"
10+
#include "Pokemon/Resources/Pokemon_PokemonHomeSprites.h"
11+
#include "Pokemon_HomeSpriteSelectOption.h"
12+
13+
namespace PokemonAutomation{
14+
namespace Pokemon{
15+
16+
17+
StringSelectDatabase make_all_home_sprites_database(){
18+
StringSelectDatabase ret;
19+
for(const auto& slug: ALL_POKEMON_FORMS()){
20+
// for(const auto& p: ALL_POKEMON_HOME_SPRITES().get()){
21+
const SpriteDatabase::Sprite* sprite = ALL_POKEMON_HOME_SPRITES().get_nothrow(slug);
22+
const PokemonForm* form_ptr = get_pokemon_form(slug);
23+
if (form_ptr == nullptr){
24+
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "A form slug is in ALL_POKEMON_FORMS but not available in get_pokemon_form() : " + slug);
25+
}
26+
if (sprite == nullptr){
27+
// we don't have the sprite. Use a replacement sprite instead:
28+
const auto& no_show_sprite = ALL_POKEMON_HOME_SPRITES().get_throw("floette-eternal-flower");
29+
ret.add_entry(StringSelectEntry(slug, form_ptr->display_name(), no_show_sprite.icon));
30+
} else{
31+
ret.add_entry(StringSelectEntry(slug, form_ptr->display_name(), sprite->icon));
32+
}
33+
}
34+
35+
return ret;
36+
}
37+
const StringSelectDatabase& ALL_HOME_SPRITES_SELECT_DATABASE(){
38+
static StringSelectDatabase database = make_all_home_sprites_database();
39+
return database;
40+
}
41+
42+
43+
44+
45+
HomeSpriteSelectCell::HomeSpriteSelectCell(
46+
const std::string& default_slug
47+
)
48+
: StringSelectCell(
49+
ALL_HOME_SPRITES_SELECT_DATABASE(),
50+
LockMode::LOCK_WHILE_RUNNING,
51+
default_slug
52+
)
53+
{}
54+
55+
56+
}
57+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* HomeSprite Selector, UI component to select multiple berries
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_PokemonBDSP_HomeSpriteSelectOption_H
8+
#define PokemonAutomation_PokemonBDSP_HomeSpriteSelectOption_H
9+
10+
#include "CommonTools/Options/StringSelectOption.h"
11+
12+
namespace PokemonAutomation{
13+
namespace Pokemon{
14+
15+
16+
17+
// Option to select a pokemon form with a Pokemon Home sprite shown.
18+
// The forms are all the unique forms including shiny and non-shiny.
19+
class HomeSpriteSelectCell : public StringSelectCell{
20+
public:
21+
HomeSpriteSelectCell(const std::string& default_slug);
22+
};
23+
24+
25+
26+
27+
}
28+
}
29+
#endif
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/* Pokemon Forms
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
8+
#include <string>
9+
#include <vector>
10+
#include <map>
11+
#include <iostream>
12+
#include <set>
13+
#include <fstream>
14+
#include "Common/Cpp/Json/JsonValue.h"
15+
#include "Common/Cpp/Json/JsonObject.h"
16+
#include "Common/Cpp/Json/JsonArray.h"
17+
#include "CommonFramework/Globals.h"
18+
#include "Pokemon_PokemonNames.h"
19+
#include "Pokemon_PokemonForms.h"
20+
#include "Pokemon_PokemonSlugs.h"
21+
22+
namespace PokemonAutomation{
23+
namespace Pokemon{
24+
25+
26+
struct PokemonFormDatabase{
27+
PokemonFormDatabase();
28+
static const PokemonFormDatabase& instance(){
29+
static PokemonFormDatabase database;
30+
return database;
31+
}
32+
33+
std::map<std::string, PokemonForm> m_slug_to_form;
34+
std::vector<std::string> m_slugs;
35+
};
36+
37+
bool is_form_shiny(const std::string& form_slug){
38+
const std::string& suffix = "-shiny";
39+
if (form_slug.length() < suffix.length()) {
40+
return false;
41+
}
42+
return form_slug.compare(form_slug.length() - suffix.length(), suffix.length(), suffix) == 0;
43+
}
44+
45+
bool PokemonForm::is_shiny() const {
46+
return is_form_shiny(m_slug);
47+
}
48+
49+
PokemonFormDatabase::PokemonFormDatabase(){
50+
// Load form map JSON
51+
const std::string form_display_map_path = RESOURCE_PATH() + "Pokemon/AllFormDisplayMap.json";
52+
JsonValue json = load_json_file(form_display_map_path);
53+
// a map from form slug to list of tuples, where each tuple contains a form slug and a display name
54+
JsonObject& form_displays = json.to_object_throw(form_display_map_path);
55+
56+
const std::string no_shiny_pokemon_path = RESOURCE_PATH() + "Pokemon/SpecialPokemonWithNoShinyForm.txt";
57+
std::ifstream fin(no_shiny_pokemon_path);
58+
if (!fin.is_open()) {
59+
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "canot open resource file: " + no_shiny_pokemon_path);
60+
}
61+
std::string line;
62+
std::set<std::string> no_shiny_forms;
63+
while (std::getline(fin, line)) {
64+
fin >> std::ws;
65+
no_shiny_forms.emplace(std::move(line));
66+
}
67+
68+
for(const auto& species_slug: NATIONAL_DEX_SLUGS()){
69+
const std::string& species_display_name = get_pokemon_name(species_slug).display_name();
70+
const JsonArray* form_array = form_displays.get_array(species_slug);
71+
if (form_array == nullptr){
72+
// there is a single form for this species
73+
m_slug_to_form.emplace(species_slug, PokemonForm(species_slug, species_display_name, species_slug));
74+
std::string shiny_slug = species_slug + "-shiny";
75+
m_slug_to_form.emplace(shiny_slug, PokemonForm(shiny_slug, "Shiny " + species_display_name, species_slug));
76+
m_slugs.push_back(species_slug);
77+
m_slugs.emplace_back(std::move(shiny_slug));
78+
continue;
79+
}
80+
81+
bool has_shiny_form = false;
82+
std::vector<std::map<std::string, PokemonForm>::const_iterator> forms;
83+
for (const auto& form : *form_array){
84+
// form is a list of two elements, first the form slug name, second the display name
85+
const JsonArray* form_ptr = form.to_array();
86+
if (form_ptr == nullptr){
87+
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "No [form_slug, display_name] format in form display map: " + species_slug);
88+
}
89+
const JsonArray& form_slug_and_display = *form_ptr;
90+
if (form_slug_and_display.size() != 2){
91+
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Wrong [form_slug, display_name] length in form display map: " + species_slug);
92+
}
93+
const std::string& form_slug = form_slug_and_display[0].to_string_throw();
94+
const std::string& display_name = form_slug_and_display[1].to_string_throw();
95+
if (form_slug.empty() || display_name.empty()){
96+
throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "Empty string in [form_slug, display_name] in form display map: " + species_slug);
97+
}
98+
if (is_form_shiny(form_slug)){
99+
has_shiny_form = true;
100+
}
101+
const auto it = m_slug_to_form.emplace(form_slug, PokemonForm(form_slug, display_name, species_slug)).first;
102+
m_slugs.push_back(form_slug);
103+
forms.push_back(it);
104+
}
105+
if (!has_shiny_form){ // if no explict shiny form loaded, we build it our own
106+
for (const auto& it: forms){
107+
const auto& form = it->second;
108+
if (no_shiny_forms.find(form.m_slug) != no_shiny_forms.end()){
109+
continue; // this form has no shiny
110+
}
111+
std::string shiny_slug = form.m_slug + "-shiny";
112+
m_slug_to_form.emplace(shiny_slug, PokemonForm(
113+
shiny_slug, "Shiny " + form.m_display_name, form.m_species
114+
));
115+
m_slugs.emplace_back(std::move(shiny_slug));
116+
}
117+
}
118+
}
119+
std::cout << "Loaded " << m_slug_to_form.size() << " form slugs" << std::endl;
120+
}
121+
122+
const PokemonForm* get_pokemon_form(const std::string& slug){
123+
const auto& slug_to_form = PokemonFormDatabase::instance().m_slug_to_form;
124+
const auto it = slug_to_form.find(slug);
125+
if (it == slug_to_form.end()){
126+
return nullptr;
127+
}
128+
return &it->second;
129+
}
130+
131+
const std::vector<std::string>& ALL_POKEMON_FORMS(){
132+
return PokemonFormDatabase::instance().m_slugs;
133+
}
134+
135+
136+
}
137+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/* Pokemon Forms
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_Pokemon_PokemonForms_H
8+
#define PokemonAutomation_Pokemon_PokemonForms_H
9+
10+
#include <string>
11+
#include <vector>
12+
13+
namespace PokemonAutomation{
14+
namespace Pokemon{
15+
16+
17+
// slug and display names related to a pokemon form
18+
class PokemonForm{
19+
public:
20+
const std::string& slug() const{ return m_slug; }
21+
const std::string& display_name() const{ return m_display_name; }
22+
bool is_shiny() const;
23+
// slug of the base species
24+
const std::string& species() const { return m_species; }
25+
// const PokemonForm& shiny_form() const;
26+
// const PokemonForm& non_shiny_form() const;
27+
28+
private:
29+
PokemonForm(std::string slug, std::string display_name, std::string species)
30+
: m_slug(std::move(slug)), m_display_name(std::move(display_name)), m_species(std::move(species)) {}
31+
friend struct PokemonFormDatabase;
32+
33+
std::string m_slug;
34+
std::string m_display_name;
35+
std::string m_species;
36+
};
37+
38+
39+
// Given a slug, find the form related data
40+
// You can find all form slugs with unique appearance from the map keys of:
41+
// Pokemon_PokemonHomeSprites.h:ALL_POKEMON_HOME_SPRITES().get()
42+
// If no such slug is found, return nullptr
43+
const PokemonForm* get_pokemon_form(const std::string& form_slug);
44+
45+
// Get a vector of form slugs. Each slug is a form with unique appearance
46+
// that has a unique sprite loaded in Pokemon_PokemonHomeSprites.h:ALL_POKEMON_HOME_SPRITES()
47+
const std::vector<std::string>& ALL_POKEMON_FORMS();
48+
49+
}
50+
}
51+
#endif
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* Pokemon Home Sprites
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#include "Pokemon_PokemonHomeSprites.h"
8+
9+
namespace PokemonAutomation{
10+
namespace Pokemon{
11+
12+
13+
14+
const SpriteDatabase& ALL_POKEMON_HOME_SPRITES(){
15+
static const SpriteDatabase database("Pokemon/AllHomeSprites.png", "Pokemon/AllHomeSprites.json");
16+
return database;
17+
}
18+
19+
20+
21+
22+
}
23+
}

0 commit comments

Comments
 (0)