diff --git a/graphics/unique_duel_frame_menu_sprites.png b/graphics/unique_duel_frame_menu_sprites.png index 729acce..95077ed 100644 Binary files a/graphics/unique_duel_frame_menu_sprites.png and b/graphics/unique_duel_frame_menu_sprites.png differ diff --git a/include/debug_mode.h b/include/debug_mode.h index 7ab039c..204a824 100644 --- a/include/debug_mode.h +++ b/include/debug_mode.h @@ -1,7 +1,7 @@ #ifndef DEBUG_MODE_H #define DEBUG_MODE_H -#define VERSION "v1.1.2" +#define VERSION "v1.1.3" #define PTGB_BUILD_LANGUAGE ENG_ID #define DEBUG_MODE false @@ -14,7 +14,7 @@ #define IGNORE_UNRECEIVED_PKMN (true && DEBUG_MODE) #define FORCE_TUTORIAL (false && DEBUG_MODE) #define DONT_REMOVE_PKMN (true && DEBUG_MODE) -#define NO_INVALID_PKMN (false && DEBUG_MODE) +#define DONT_HIDE_INVALID_PKMN (false && DEBUG_MODE) #define IGNORE_DEX_COMPLETION (false && DEBUG_MODE) #define WRITE_CABLE_DATA_TO_SAVE (false && DEBUG_MODE) #define SHOW_DATA_PACKETS (false && DEBUG_MODE) diff --git a/include/global_frame_controller.h b/include/global_frame_controller.h index 3eb5448..48fbc88 100644 --- a/include/global_frame_controller.h +++ b/include/global_frame_controller.h @@ -13,6 +13,8 @@ void link_animation_state(int state); void determine_fennel_blink(); void set_missingno(bool val); bool get_missingno_enabled(); +void set_treecko(bool val); +bool get_treecko_enabled(); u32 fnv1a_hash(unsigned char* data, size_t length); #endif diff --git a/include/pokemon_data.h b/include/pokemon_data.h index e95968f..83ec3e0 100644 --- a/include/pokemon_data.h +++ b/include/pokemon_data.h @@ -37,19 +37,21 @@ #define MAX_PKMN_IN_BOX 30 +#define NUM_POKEMON 252 +#define POKEMON_ARRAY_SIZE NUM_POKEMON + 1 -extern const u8 EXP_GROUPS[252]; +extern const u8 EXP_GROUPS[POKEMON_ARRAY_SIZE]; extern const u32 EXP_MAXIMUMS[6]; extern const int GENDER_THRESHOLDS[2][8]; -extern const u8 GENDER_RATIO[252]; -extern const bool NUM_ABILITIES[252]; -extern const byte MOVESETS[252][32]; -extern const byte FIRST_MOVES[252]; -extern const std::string_view NAMES[252]; -extern const u16 JPN_NAMES[252][6]; -extern const u8 EVOLUTIONS[252]; +extern const u8 GENDER_RATIO[POKEMON_ARRAY_SIZE]; +extern const bool NUM_ABILITIES[POKEMON_ARRAY_SIZE]; +extern const byte MOVESETS[POKEMON_ARRAY_SIZE][32]; +extern const byte FIRST_MOVES[POKEMON_ARRAY_SIZE]; +extern const std::string_view NAMES[POKEMON_ARRAY_SIZE]; +extern const u16 JPN_NAMES[POKEMON_ARRAY_SIZE][6]; +extern const u8 EVOLUTIONS[POKEMON_ARRAY_SIZE]; extern const u8 POWER_POINTS[252]; -extern const u8 MENU_SPRITE_PALS[252 + 26][2]; +extern const u8 MENU_SPRITE_PALS[POKEMON_ARRAY_SIZE + 26][2]; extern const byte gen_1_index_array[191]; extern const u16 gen_1_Jpn_char_array[256]; extern const u16 gen_1_Eng_char_array[256]; @@ -62,7 +64,7 @@ extern const u16 gen_2_ItaSpa_char_array[256]; extern const u16 gen_3_Jpn_char_array[256]; extern const u16 gen_3_Intern_char_array[256]; extern const byte EVENT_PKMN[8][80]; -extern const u8 TYPES[252][2]; +extern const u8 TYPES[POKEMON_ARRAY_SIZE][2]; u32 get_max_exp(int index_num); u8 get_gender_threshold(int index_num, bool is_gen_3); diff --git a/source/global_frame_controller.cpp b/source/global_frame_controller.cpp index 1da469b..0c5cf70 100644 --- a/source/global_frame_controller.cpp +++ b/source/global_frame_controller.cpp @@ -14,6 +14,7 @@ int curr_link_animation_state = 0; int fennel_blink_timer = 0; int fennel_blink_state = 0; bool missingno_enabled = false; +bool treecko_enabled = false; void global_next_frame() { @@ -236,10 +237,21 @@ void set_missingno(bool val) } } +void set_treecko(bool val) +{ + treecko_enabled = val; +} + bool get_missingno_enabled() { return missingno_enabled; } + +bool get_treecko_enabled() +{ + return treecko_enabled; +} + // FNV-1a 32-bit hash function for byte arrays u32 fnv1a_hash(unsigned char *data, size_t length) { diff --git a/source/main.cpp b/source/main.cpp index b7b6b3b..91e5ac3 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -185,6 +185,7 @@ int credits() #define CREDITS_ARRAY_SIZE 18 int curr_credits_num = 0; std::string credits_array[CREDITS_ARRAY_SIZE] = { + //"testing: う", "Lead developer:\n\nThe Gears of\nProgress", "Logo and co-ideator:\n\n-Jome\n\nSpritework:\n\n-LJ Birdman\n\n", "Icon Sprites: \n\n-LuigiTKO\n-GuiAbel\n-SourApple\n & the artists from\nPok@mon Showdown and\nCrystal Clear", @@ -226,6 +227,10 @@ int credits() } if (ENABLE_DEBUG_SCREEN && key_hit(KEY_SELECT)) { + if (key_held(KEY_UP) && key_held(KEY_L) && key_held(KEY_R)) + { + set_treecko(true); + } u32 pkmn_flags = 0; bool e4_flag = read_flag(curr_rom.e4_flag); bool mg_flag = read_flag(curr_rom.mg_flag); @@ -276,6 +281,10 @@ int credits() tte_write("\n\n"); tte_write(VERSION); + if (get_treecko_enabled()) + { + tte_write(".T"); + } while (true) { if (key_hit(KEY_B)) diff --git a/source/pokemon.cpp b/source/pokemon.cpp index 8e29bf1..f5b2f58 100644 --- a/source/pokemon.cpp +++ b/source/pokemon.cpp @@ -178,14 +178,14 @@ void Pokemon::convert_to_gen_three(bool simplified, bool stabilize_mythical) species_index_party = species_index_struct; } - if ( // index_in_box % 4 == 0 || - species_index_struct > 251 || // Checks if the Pokemon is beyond Celebi - species_index_struct == 0 || // Checks that the Pokemon isn't a blank party space - species_index_struct != species_index_party || // Checks that the Pokemon isn't a hybrid or an egg - index_in_box >= num_in_box || // Checks that we're not reading beyond the Pokemon in the box - item != 0) // Checks that the Pokemon doesn't have an item + if ( // index_in_box % 4 == 0 || + (species_index_struct > NUM_POKEMON - (get_treecko_enabled() ? 0 : 1)) || // Checks if the Pokemon is beyond the supported Pokemon + species_index_struct == 0 || // Checks that the Pokemon isn't a blank party space + species_index_struct != species_index_party || // Checks that the Pokemon isn't a hybrid or an egg + index_in_box >= num_in_box || // Checks that we're not reading beyond the Pokemon in the box + item != 0) // Checks that the Pokemon doesn't have an item { - if (!NO_INVALID_PKMN) + if (!DONT_HIDE_INVALID_PKMN) { is_valid = false; return; @@ -314,7 +314,7 @@ void Pokemon::convert_to_gen_three(bool simplified, bool stabilize_mythical) pp_bonus[i] = 0; } } - else if (species_index_struct != 0xEB) // Ignore Smeargle due to Sketch + else if ((species_index_struct != 0xEB) && (species_index_struct != 0xFC)) // Ignore Smeargle due to Sketch, Ignore Treecko because Treecko { for (int i = 0; i < 4; i++) { @@ -483,9 +483,9 @@ void Pokemon::convert_to_gen_three(bool simplified, bool stabilize_mythical) data_section_M[i] = 0; } - data_section_G[0] = species_index_struct; - data_section_G[1] = 0x00; // Species Index, check for glitch Pokemon - data_section_G[2] = (is_new ? 0x44 : 0x00); // Rare Candy if new + data_section_G[0] = (species_index_struct != 252 ? species_index_struct : 277); // Treecko check + data_section_G[1] = (species_index_struct != 252 ? 0x00 : 0x01); // Treecko check; + data_section_G[2] = (is_new ? 0x44 : 0x00); // Rare Candy if new data_section_G[3] = 0x00; for (int i = 0; i < 3; i++) { diff --git a/source/pokemon_data.cpp b/source/pokemon_data.cpp index c1fb814..f37c8f5 100644 --- a/source/pokemon_data.cpp +++ b/source/pokemon_data.cpp @@ -2846,7 +2846,7 @@ const u16 gen_3_Intern_char_array[256]{ 0x147, 0x19E, }; -const u8 EXP_GROUPS[252] = { +const u8 EXP_GROUPS[POKEMON_ARRAY_SIZE] = { 0, // Offset the list to remove "off by one" errors 3, // Bulbasaur 3, // Ivysaur @@ -3099,8 +3099,9 @@ const u8 EXP_GROUPS[252] = { 5, // Lugia 5, // Ho-Oh 3, // Celebi + 3, // Treecko }; -const u8 GENDER_RATIO[252] = { +const u8 GENDER_RATIO[POKEMON_ARRAY_SIZE] = { 0, // Offset the list to remove "off by one" errors 1, // Bulbasaur [1♀:7♂] 1, // Ivysaur [1♀:7♂] @@ -3353,8 +3354,10 @@ const u8 GENDER_RATIO[252] = { 7, // Lugia [Gender Unknown] 7, // Ho-Oh [Gender Unknown] 7, // Celebi [Gender Unknown] + 1, // Treecko [1♀:7♂] + }; -const bool NUM_ABILITIES[252] = { +const bool NUM_ABILITIES[POKEMON_ARRAY_SIZE] = { 0, // Offset the list to remove "off by one" errors 0, // Bulbasaur Overgrow 0, // Ivysaur Overgrow @@ -3607,8 +3610,9 @@ const bool NUM_ABILITIES[252] = { 0, // Lugia Pressure 0, // Ho-Oh Pressure 0, // Celebi Natural Cure + 0, // Treecko Overgrow }; -const byte MOVESETS[252][32] = { +const byte MOVESETS[POKEMON_ARRAY_SIZE][32] = { // This data is stored as 32 bytes of binary data per Pokemon, depending on if they can learn the move. Data obtained through PokeAPI // 0(unused) 8 16 24 32 40 48 56 64 72 80 88 96 104 112 120 128 136 144 152 160 168 176 184 192 200 208 216 224 232 240 248 {0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000}, // Offset the list to remove "off by one" errors @@ -3863,8 +3867,9 @@ const byte MOVESETS[252][32] = { {0b00000000, 0b00000000, 0b10110000, 0b00000000, 0b00100010, 0b00000010, 0b00000000, 0b11110001, 0b00000010, 0b00000000, 0b00000111, 0b01001010, 0b00000010, 0b11000000, 0b01010000, 0b00000001, 0b01000000, 0b00100000, 0b00000000, 0b00001000, 0b00001000, 0b00000100, 0b01000010, 0b00000100, 0b00001000, 0b01110001, 0b00010010, 0b10110000, 0b00000001, 0b00000100, 0b11001011, 0b11000000}, // Lugia {0b00000000, 0b00000000, 0b10110000, 0b00000000, 0b00000010, 0b00000010, 0b00000100, 0b00000001, 0b00000010, 0b00001000, 0b00000111, 0b01001010, 0b00000010, 0b11000000, 0b01010000, 0b00000010, 0b01000000, 0b00100000, 0b00001000, 0b00001000, 0b00001000, 0b00000100, 0b00000010, 0b00000100, 0b00000000, 0b01110001, 0b00010010, 0b10110100, 0b00000000, 0b00000100, 0b11001011, 0b11000000}, // Ho-oh {0b00000000, 0b00000011, 0b00000000, 0b00000000, 0b00000010, 0b00000000, 0b00000000, 0b00000001, 0b00000000, 0b01001000, 0b00000000, 0b00001110, 0b00000010, 0b11000001, 0b01010010, 0b00000000, 0b01000000, 0b00100000, 0b00001000, 0b00001000, 0b00001000, 0b00000100, 0b00000010, 0b00000100, 0b00010000, 0b01110001, 0b00000011, 0b10110000, 0b00100000, 0b00000100, 0b11001011, 0b10000000}, // Celebi + {0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000010, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00000000}, // Treecko }; -const byte FIRST_MOVES[252] = { +const byte FIRST_MOVES[POKEMON_ARRAY_SIZE] = { // Data obtained through PokeAPI 0, // Offset the list to remove "off by one" errors 0x21, // Bulbasaur (tackle) @@ -4118,8 +4123,9 @@ const byte FIRST_MOVES[252] = { 0x12, // Lugia (whirlwind) 0x12, // Ho-oh (whirlwind) 0x49, // Celebi (leech-seed) + 0x01, // Treecko (pound) }; -const std::string_view NAMES[252]{ +const std::string_view NAMES[POKEMON_ARRAY_SIZE]{ "MissingNo", // Offset the list to remove "off by one" errors "Bulbasaur", "Ivysaur", @@ -4372,8 +4378,9 @@ const std::string_view NAMES[252]{ "Lugia", "Ho-Oh", "Celebi", + "Treecko", }; -const u16 JPN_NAMES[252][6]{ +const u16 JPN_NAMES[POKEMON_ARRAY_SIZE][6]{ {}, // Offset the list to remove "off by one" errors {0x30D5, 0x30B7, 0x30AE, 0x30C0, 0x30CD, 0x19E}, // Bulbasaur {0x30D5, 0x30B7, 0x30AE, 0x30BD, 0x30A6, 0x19E}, // Ivysaur @@ -4626,8 +4633,9 @@ const u16 JPN_NAMES[252][6]{ {0x30EB, 0x30AE, 0x30A2, 0x19E}, // Lugia {0x30DB, 0x30A6, 0x30AA, 0x30A6, 0x19E}, // Ho-Oh {0x30BB, 0x30EC, 0x30D3, 0x30A3, 0x19E}, // Celebi + {0x30AD, 0x30E2, 0x30EA}, // Treecko }; -const u8 EVOLUTIONS[252]{ +const u8 EVOLUTIONS[POKEMON_ARRAY_SIZE]{ 0, // Offset the list to remove "off by one" errors 0x0, // Bulbasaur is a base evolution 0x1, // Ivysaur evolves from Bulbasaur @@ -4880,6 +4888,7 @@ const u8 EVOLUTIONS[252]{ 0x0, // Lugia is a base evolution 0x0, // Ho-oh is a base evolution 0x0, // Celebi is a base evolution + 0x0, // Treecko is a base evolution }; const u8 POWER_POINTS[252]{ 0, // Offset the list to remove "off by one" errors @@ -5142,7 +5151,7 @@ const u8 POWER_POINTS[252]{ #define ICON_BRN 3 #define ICON_PNK 4 -const u8 MENU_SPRITE_PALS[252 + 26][2] = { +const u8 MENU_SPRITE_PALS[POKEMON_ARRAY_SIZE + 26][2] = { {ICON_BLU, ICON_RED}, // MISSINGNO {ICON_GRN, ICON_GRN}, // BULBASAUR {ICON_GRN, ICON_GRN}, // IVYSAUR @@ -5395,6 +5404,7 @@ const u8 MENU_SPRITE_PALS[252 + 26][2] = { {ICON_BLU, ICON_PNK}, // LUGIA {ICON_RED, ICON_BRN}, // HO_OH {ICON_GRN, ICON_PNK}, // CELEBI + {ICON_GRN, ICON_BLU}, // TREECKO {ICON_BRN, ICON_BLU}, // UNOWN {ICON_BRN, ICON_BLU}, // UNOWN {ICON_BRN, ICON_BLU}, // UNOWN @@ -5445,7 +5455,7 @@ extern const byte EVENT_PKMN[8][80]{ {0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0xBD, 0xBF, 0xC6, 0xBF, 0xBC, 0xC3, 0xFF, 0x34, 0x01, 0x31, 0x02, 0x02, 0xA2, 0xA1, 0x00, 0xBB, 0xC8, 0xC3, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0x00, 0x00, 0x00, 0x80, 0x43, 0x05, 0x00, 0x00, 0x64, 0x00, 0x00, 0xF6, 0x00, 0xF8, 0x00, 0xE2, 0x00, 0xC3, 0x00, 0x05, 0x0F, 0x28, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x46, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, }; -const u8 TYPES[252][2]{ +const u8 TYPES[POKEMON_ARRAY_SIZE][2]{ {0x0, 0x0}, // Missingno is ???/??? {0xc, 0x3}, // Bulbasaur is grass/poison {0xc, 0x3}, // Ivysaur is grass/poison @@ -5698,4 +5708,5 @@ const u8 TYPES[252][2]{ {0xe, 0x2}, // Lugia is psychic/flying {0xa, 0x2}, // Ho-oh is fire/flying {0xe, 0xc}, // Celebi is psychic/grass + {0xc, 0xc}, // Treecko is grass/grass }; \ No newline at end of file diff --git a/source/pokemon_party.cpp b/source/pokemon_party.cpp index 933e418..d43b35a 100644 --- a/source/pokemon_party.cpp +++ b/source/pokemon_party.cpp @@ -91,7 +91,7 @@ byte gen2_debug_box_data[0x44E] = { // Num of Pokemon 0x14, // Pokemon 1-20 - 0xD5, 0x7B, 0xE3, 0x9D, 0xC3, 0xD5, 0xD5, 0xC9, 0xC9, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xFF, + 0xD5, 0x7B, 0xE3, 0x9D, 0xC3, 0xD5, 0xD5, 0xC9, 0xC9, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xD5, 0xFC, 0xFF, // Pokemon list 0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10, 0x7B, 0x00, 0x62, 0x2B, 0x74, 0xE4, 0xBB, 0x4C, 0x00, 0x08, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA, 0xF9, 0x1E, 0x1E, 0x1E, 0x14, 0x46, 0x00, 0x00, 0x00, 0x0D, @@ -112,7 +112,7 @@ byte gen2_debug_box_data[0x44E] = { 0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10, 0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10, 0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10, - 0xD5, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10, + 0xFC, 0x00, 0x84, 0x6E, 0x23, 0xE3, 0xBB, 0x4C, 0x00, 0x0A, 0x4E, 0x00, 0x20, 0x00, 0x32, 0x00, 0x23, 0x00, 0x34, 0x00, 0x28, 0x9C, 0x90, 0x23, 0x28, 0x14, 0x05, 0x58, 0x00, 0x00, 0x00, 0x10, // Trainer names 0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00, 0x80, 0x94, 0x92, 0x93, 0x88, 0x8D, 0x50, 0x50, 0x00, 0x00, 0x00, @@ -294,7 +294,7 @@ bool Pokemon_Party::fill_simple_pkmn_array() contains_invalid |= !converted_mon.get_validity(); contains_missingno |= converted_mon.is_missingno; } - return contains_valid || NO_INVALID_PKMN; + return contains_valid || DONT_HIDE_INVALID_PKMN; } int Pokemon_Party::get_num_pkmn() diff --git a/source/sprite_data.cpp b/source/sprite_data.cpp index 7460778..1dd186b 100644 --- a/source/sprite_data.cpp +++ b/source/sprite_data.cpp @@ -356,13 +356,13 @@ void load_temp_box_sprites(Pokemon_Party party_data) u32 curr_tile_id = global_tile_id_end; for (int i = 0; i < 30; i++) { - if (party_data.get_simple_pkmn(i).is_valid || NO_INVALID_PKMN) + if (party_data.get_simple_pkmn(i).is_valid || DONT_HIDE_INVALID_PKMN) { Simplified_Pokemon curr_pkmn = party_data.get_simple_pkmn(i); int dex_num = curr_pkmn.dex_number; if (dex_num == 201) { - dex_num = 252 + curr_pkmn.unown_letter; + dex_num = POKEMON_ARRAY_SIZE + curr_pkmn.unown_letter; } else if (curr_pkmn.is_missingno) {