From c825203e701dcd54c620b9f2e0fc29e6c4fc6bca Mon Sep 17 00:00:00 2001 From: Remnants of Forgotten Disney Date: Mon, 4 Mar 2024 16:56:14 -0600 Subject: [PATCH] Modifying save data flags --- include/mystery_gift_builder.h | 6 --- include/mystery_gift_injector.h | 2 +- include/pokemon_data.h | 2 +- include/rom_data.h | 7 ++- source/mystery_gift_builder.cpp | 83 ++++++++++++++++---------------- source/mystery_gift_injector.cpp | 32 +++++++----- source/pokemon.cpp | 9 ++-- source/rom_data.cpp | 9 ++-- source/script_array.cpp | 3 +- 9 files changed, 80 insertions(+), 73 deletions(-) diff --git a/include/mystery_gift_builder.h b/include/mystery_gift_builder.h index 727d53e..1c4b495 100644 --- a/include/mystery_gift_builder.h +++ b/include/mystery_gift_builder.h @@ -16,10 +16,6 @@ #define NPC_LOCATION_OFFSET 0x4 #define READ_AS_THUMB 0x1 -#define FLAG_ID_START 0x21 - - - #define VAR_ID_START 0x8000 // This one should also stay consistant #define VIRTUAL_ADDRESS 0x08000000 // This will also stay constant @@ -77,8 +73,6 @@ public: u8 get_script_value_at(int index); u32 calc_checksum32(); u16 calc_crc16(); - bool validity_array[MAX_PKMN_IN_BOX]; - int dex_array[MAX_PKMN_IN_BOX]; private: void add_command(int len); diff --git a/include/mystery_gift_injector.h b/include/mystery_gift_injector.h index 5d1d138..24cdcdd 100644 --- a/include/mystery_gift_injector.h +++ b/include/mystery_gift_injector.h @@ -2,7 +2,7 @@ #define MYSTERY_GIFT_INJECTOR_H #include "pokemon_party.h" -#include "mystery_gift_builder.h" +#include "pokemon_data.h" bool inject_mystery(Pokemon_Party &incoming_box_data); diff --git a/include/pokemon_data.h b/include/pokemon_data.h index a95ebd1..509a953 100644 --- a/include/pokemon_data.h +++ b/include/pokemon_data.h @@ -28,7 +28,7 @@ #define SILVER_ID 5 #define CRYSTAL_ID 6 -#define MAX_PKMN_IN_BOX 6 +#define MAX_PKMN_IN_BOX 30 extern const u8 EXP_MAX[252]; diff --git a/include/rom_data.h b/include/rom_data.h index 46773a8..8a762b5 100644 --- a/include/rom_data.h +++ b/include/rom_data.h @@ -47,8 +47,11 @@ public: int text_region; // PKHeX's list of flags is useful for making sure the detection is accurate: https://github.com/kwsch/PKHeX/blob/78a557c3cdaa6f48b42cc96df8ccb4d20b897937/PKHeX.Core/Resources/text/other/flags_rs.txt - int e4_flag; // The flag that is set when you become champion. Often listed as "GAME_CLEAR" - int mg_flag; // The flag that is set when you enable Mystery Gift. Known as "EXDATA_ENABLE" in RS + int e4_flag; // The flag that is set when you become champion. Often listed as "GAME_CLEAR" + int mg_flag; // The flag that is set when you enable Mystery Gift. Known as "EXDATA_ENABLE" in RS + int unused_flag_start; // The start of the unused flags and must have 31 open flags in a row + int all_collected_flag; // The flag for if everything has been collected + int pkmn_collected_flag_start; // The beginning of the flags for each of the Pokemon u8 map_bank; u8 map_id; diff --git a/source/mystery_gift_builder.cpp b/source/mystery_gift_builder.cpp index b264b8f..b5aade6 100644 --- a/source/mystery_gift_builder.cpp +++ b/source/mystery_gift_builder.cpp @@ -20,13 +20,12 @@ int var_dex_num = (VAR_ID_START + 0x08); int var_index = (VAR_ID_START + 0x09); int var_pkmn_offset = (VAR_ID_START + 0x0A); -//int flag_pkmn_1 = (FLAG_ID_START + 0x0); -//int flag_pkmn_2 = (FLAG_ID_START + 0x1); -//int flag_pkmn_3 = (FLAG_ID_START + 0x2); -//int flag_pkmn_4 = (FLAG_ID_START + 0x3); -//int flag_pkmn_5 = (FLAG_ID_START + 0x4); -//int flag_pkmn_6 = (FLAG_ID_START + 0x5); -int flag_all_collected = (FLAG_ID_START + 6); +// int flag_pkmn_1 = (FLAG_ID_START + 0x0); +// int flag_pkmn_2 = (FLAG_ID_START + 0x1); +// int flag_pkmn_3 = (FLAG_ID_START + 0x2); +// int flag_pkmn_4 = (FLAG_ID_START + 0x3); +// int flag_pkmn_5 = (FLAG_ID_START + 0x4); +// int flag_pkmn_6 = (FLAG_ID_START + 0x5); // These will all be set based on the ROM pointers /* @@ -126,40 +125,40 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data) textReceived.set_text(u"ȆÀÁƲÀ’S POKÉMON were sent to theŇPC!"); // Located at 0x?8A8 in the .sav - init_npc_location(curr_rom.map_bank, curr_rom.map_id, curr_rom.npc_id); // Set the location of the NPC - setvirtualaddress(VIRTUAL_ADDRESS); // Set virtual address - lock(); // Lock the player - faceplayer(); // Have the NPC face the player - checkflag(flag_all_collected); // Check if the "all collected" flag has been set - virtualgotoif(COND_FLAGTRUE, jumpAllCollected.add_reference(2)); // If "all collected" is true, then jump to the "thank you" text - virtualmsgbox(textGreet.add_reference(1)); // Otherwise, greet the player - waitmsg(); // Wait for the message to finish - waitkeypress(); // Wait for the player to press A/B - setvar(var_index, 0); // set the index to 0 - setvar(var_callASM, rev_endian(0x0023)); // set the call_asm variable to 0x23: 0x23 = CALL ASM - setvar(var_pkmn_offset, 0); // Set the Pokemon struct offset to 0 - if (curr_rom.is_ruby_sapphire()) // Ruby and Sapphire don't shift their save blocks around, so we can hardcode it - { // FOR RUBY AND SAPPHIRE: - setvar(var_script_ptr_low, curr_rom.loc_gSaveBlock1 & 0xFFFF); // Copy the first two bytes of the saveblock1 location to a variable - setvar(var_script_ptr_high, curr_rom.loc_gSaveBlock1 >> 16); // Copy the second two bytes of the saveblock1 location to a variable - } // - else // - { // FOR FIRERED, LEAFGREEN, AND EMERALD - copybyte(ptr_script_ptr_low, ptr_block_ptr_low); // Copy the first byte of the saveblock1ptr to a variable - copybyte(ptr_script_ptr_low + 1, ptr_block_ptr_low + 1); // Copy the second byte of the saveblock1ptr to a variable - copybyte(ptr_script_ptr_high, ptr_block_ptr_high); // Copy the third byte of the saveblock1ptr to a variable - copybyte(ptr_script_ptr_high + 1, ptr_block_ptr_high + 1); // Copy the fourth byte of the saveblock1ptr to a variable - } // - addvar(var_script_ptr_low, curr_rom.offset_ramscript + 8 + READ_AS_THUMB); // add the offset for ramscript, plus 8. 8 is for the 8 bytes of Checksum, padding and NPC info - addvar(var_script_ptr_low, readFlashStart.add_reference(3)); // Add the offset for the start of ASM - setvar(var_call_return_1, rev_endian(0x0300)); // Set the vairable to 0x03. 0x03 = RETURN - setvar(var_call_check_flag, rev_endian(0x2B00)); // Set the variable to 0x2B. 0x2B = CHECK FLAG - addvar(var_call_check_flag, rev_endian(FLAG_ID_START)); // Add the starting flag ID to the check flag ASM variable - setvar(var_call_return_2, rev_endian(0x0003)); // Set the variable to 0x03. 0x03 = RETURN - jumpLoop.set_start(); // Set the jump destination for the JUMP_LOOP - call(ptr_call_check_flag); // Call the check flag ASM - virtualgotoif(COND_FLAGFALSE, jumpPkmnCollected.add_reference(2)); // If the "pokemon collected" flag is false, jump to the end of the loop - call(ptr_callASM); // Call readFlash ASM + init_npc_location(curr_rom.map_bank, curr_rom.map_id, curr_rom.npc_id); // Set the location of the NPC + setvirtualaddress(VIRTUAL_ADDRESS); // Set virtual address + lock(); // Lock the player + faceplayer(); // Have the NPC face the player + checkflag(curr_rom.all_collected_flag); // Check if the "all collected" flag has been set + virtualgotoif(COND_FLAGTRUE, jumpAllCollected.add_reference(2)); // If "all collected" is true, then jump to the "thank you" text + virtualmsgbox(textGreet.add_reference(1)); // Otherwise, greet the player + waitmsg(); // Wait for the message to finish + waitkeypress(); // Wait for the player to press A/B + setvar(var_index, 0); // set the index to 0 + setvar(var_callASM, rev_endian(0x0023)); // set the call_asm variable to 0x23: 0x23 = CALL ASM + setvar(var_pkmn_offset, 0); // Set the Pokemon struct offset to 0 + if (curr_rom.is_ruby_sapphire()) // Ruby and Sapphire don't shift their save blocks around, so we can hardcode it + { // FOR RUBY AND SAPPHIRE: + setvar(var_script_ptr_low, curr_rom.loc_gSaveBlock1 & 0xFFFF); // Copy the first two bytes of the saveblock1 location to a variable + setvar(var_script_ptr_high, curr_rom.loc_gSaveBlock1 >> 16); // Copy the second two bytes of the saveblock1 location to a variable + } // + else // + { // FOR FIRERED, LEAFGREEN, AND EMERALD + copybyte(ptr_script_ptr_low, ptr_block_ptr_low); // Copy the first byte of the saveblock1ptr to a variable + copybyte(ptr_script_ptr_low + 1, ptr_block_ptr_low + 1); // Copy the second byte of the saveblock1ptr to a variable + copybyte(ptr_script_ptr_high, ptr_block_ptr_high); // Copy the third byte of the saveblock1ptr to a variable + copybyte(ptr_script_ptr_high + 1, ptr_block_ptr_high + 1); // Copy the fourth byte of the saveblock1ptr to a variable + } // + addvar(var_script_ptr_low, curr_rom.offset_ramscript + 8 + READ_AS_THUMB); // add the offset for ramscript, plus 8. 8 is for the 8 bytes of Checksum, padding and NPC info + addvar(var_script_ptr_low, readFlashStart.add_reference(3)); // Add the offset for the start of ASM + setvar(var_call_return_1, rev_endian(0x0300)); // Set the vairable to 0x03. 0x03 = RETURN + setvar(var_call_check_flag, rev_endian(0x2B00)); // Set the variable to 0x2B. 0x2B = CHECK FLAG + addvar(var_call_check_flag, rev_endian(curr_rom.pkmn_collected_flag_start)); // Add the starting flag ID (plus one to ignore the is collected flag) to the check flag ASM variable + setvar(var_call_return_2, rev_endian(0x0003)); // Set the variable to 0x03. 0x03 = RETURN + jumpLoop.set_start(); // Set the jump destination for the JUMP_LOOP + call(ptr_call_check_flag); // Call the check flag ASM + virtualgotoif(COND_FLAGFALSE, jumpPkmnCollected.add_reference(2)); // If the "pokemon collected" flag is false, jump to the end of the loop + call(ptr_callASM); // Call readFlash ASM addvar(var_script_ptr_low, mainAsmStart.add_reference(3, &readFlashStart)); call(ptr_callASM); // Call SendMonToPC ASM @@ -178,7 +177,7 @@ void mystery_gift_script::build_script(Pokemon_Party &incoming_box_data) addvar(var_call_check_flag, rev_endian(1)); // Add one to the flag index compare(var_index, MAX_PKMN_IN_BOX); // Compare the index to 30 virtualgotoif(COND_LESSTHAN, jumpLoop.add_reference(2)); // if index is less than six, jump to the start of the loop - setflag(flag_all_collected); // Set the "all collected" flag + setflag(curr_rom.all_collected_flag); // Set the "all collected" flag fanfare(0xA4); // Play the received fanfare virtualmsgbox(textReceived.add_reference(1)); // Display the recieved text waitfanfare(); // Wait for the fanfare diff --git a/source/mystery_gift_injector.cpp b/source/mystery_gift_injector.cpp index 31a59f8..ccac82a 100644 --- a/source/mystery_gift_injector.cpp +++ b/source/mystery_gift_injector.cpp @@ -14,6 +14,9 @@ static u8 lanette_wonder_card[0x14E] = { bool inject_mystery(Pokemon_Party &incoming_box_data) { + int validity_array[MAX_PKMN_IN_BOX]; + int dex_array[MAX_PKMN_IN_BOX]; + mystery_gift_script script; script.build_script(incoming_box_data); u32 checksum = 0; @@ -70,13 +73,13 @@ bool inject_mystery(Pokemon_Party &incoming_box_data) global_memory_buffer[curr_index] = curr_pkmn.get_gen_3_data(curr_byte); curr_index++; } - script.validity_array[i] = curr_pkmn.get_validity(); - script.dex_array[i] = curr_pkmn.get_dex_number(); + validity_array[i] = curr_pkmn.get_validity(); + dex_array[i] = curr_pkmn.get_dex_number(); } - + for (int i = 0; i < MAX_PKMN_IN_BOX; i++) // Add in the dex numbers { - global_memory_buffer[curr_index] = script.dex_array[i]; + global_memory_buffer[curr_index] = dex_array[i]; curr_index++; } @@ -85,21 +88,26 @@ bool inject_mystery(Pokemon_Party &incoming_box_data) copy_ram_to_save(&global_memory_buffer[0], 0x1E000, 0x1000); // Set flags - copy_save_to_ram(memory_section_array[1 + ((curr_rom.offset_flags + (FLAG_ID_START / 8)) / 0xF80)], &global_memory_buffer[0], 0x1000); - global_memory_buffer[(curr_rom.offset_flags + (FLAG_ID_START / 8)) % 0xF80] &= (~0b01111111 << (FLAG_ID_START % 8)); // Set "collected all" flag to 0 and reset the "to obtain" flags -for (int i = 0; i < MAX_PKMN_IN_BOX; i++) + int memory_section = 1 + ((curr_rom.offset_flags + (curr_rom.unused_flag_start / 8)) / 0xF80); // This sets the correct memory section, since flags stretch between section 1 and 2. + copy_save_to_ram(memory_section_array[memory_section], &global_memory_buffer[0], 0x1000); + global_memory_buffer[(curr_rom.offset_flags + (curr_rom.all_collected_flag / 8)) % 0xF80] &= ~(1 << (curr_rom.all_collected_flag % 8)); // Set "collected all" flag to 0 + + for (int i = 0; i < MAX_PKMN_IN_BOX; i++) { - if (script.validity_array[i]) + int curr_flag; + curr_flag = curr_rom.pkmn_collected_flag_start + i; + global_memory_buffer[(curr_rom.offset_flags + (curr_flag / 8)) % 0xF80] &= ~(1 << (curr_flag % 8)); // Reset the flag + if (validity_array[i]) { - global_memory_buffer[(curr_rom.offset_flags + (FLAG_ID_START / 8)) % 0xF80] |= ((1 << i) << (FLAG_ID_START % 8)); // Set "to obtain" flags accordingly + global_memory_buffer[(curr_rom.offset_flags + (curr_flag / 8)) % 0xF80] |= (1 << (curr_flag % 8)); // Set flag accordingly } } update_memory_buffer_checksum(false); - erase_sector(memory_section_array[1 + ((curr_rom.offset_flags + (FLAG_ID_START / 8)) / 0xF80)]); - copy_ram_to_save(&global_memory_buffer[0], memory_section_array[1 + ((curr_rom.offset_flags + (FLAG_ID_START / 8)) / 0xF80)], 0x1000); + erase_sector(memory_section_array[memory_section]); + copy_ram_to_save(&global_memory_buffer[0], memory_section_array[memory_section], 0x1000); // Save custom save data write_custom_save_data(); return true; -} \ No newline at end of file +} diff --git a/source/pokemon.cpp b/source/pokemon.cpp index 4f199f0..15d3665 100644 --- a/source/pokemon.cpp +++ b/source/pokemon.cpp @@ -135,9 +135,8 @@ void Pokemon::convert_to_gen_three() 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 { - // while(true){}; - // is_valid = false; - // return; + is_valid = false; + return; } is_valid = true; // Generate PID @@ -642,7 +641,7 @@ byte Pokemon::get_rand_gender_byte(byte index_num, byte attack_DVs) byte Pokemon::get_dex_number() { - return species_index_struct; + return (is_valid ? species_index_struct : 0); } bool Pokemon::get_validity() @@ -652,5 +651,5 @@ bool Pokemon::get_validity() bool Pokemon::get_is_new() { - return is_new; + return (is_valid ? is_new : false); } \ No newline at end of file diff --git a/source/rom_data.cpp b/source/rom_data.cpp index 205f49d..534e0f3 100644 --- a/source/rom_data.cpp +++ b/source/rom_data.cpp @@ -115,9 +115,9 @@ bool rom_data::load_rom() break; case (EMERALD_ID): - map_bank = 20; - map_id = 2; - npc_id = 1; + map_bank = 5; //20; + map_id = 4; //2; + npc_id = 2; //1; def_map_bank = 0xFF; def_map_id = 0xFF; @@ -129,6 +129,9 @@ bool rom_data::load_rom() e4_flag = 0x860 + 0x04; mg_flag = 0x860 + 0x7B; + unused_flag_start = 0x20; + all_collected_flag = 0x20; + pkmn_collected_flag_start = 0x21; loc_sendMonToPC = 0x0806B490; loc_gSpecialVar_0x8000 = 0x020375D8; diff --git a/source/script_array.cpp b/source/script_array.cpp index efdf09a..0440365 100644 --- a/source/script_array.cpp +++ b/source/script_array.cpp @@ -5,6 +5,7 @@ #include "sprite_data.h" #include "flash_mem.h" #include "pokemon_data.h" +#include "mystery_gift_builder.h" #include int last_error; @@ -133,7 +134,7 @@ bool run_conditional(int index) return compare_map_and_npc_data(curr_rom.def_map_bank, curr_rom.def_map_id, curr_rom.def_npc_id) && !IGNORE_MG_E4_FLAGS; case COND_PKMN_TO_COLLECT: - return compare_map_and_npc_data(curr_rom.map_bank, curr_rom.map_id, curr_rom.npc_id) && !read_flag(FLAG_ID_START + 0x06) && !IGNORE_MG_E4_FLAGS; + return compare_map_and_npc_data(curr_rom.map_bank, curr_rom.map_id, curr_rom.npc_id) && !read_flag(curr_rom.all_collected_flag) && !IGNORE_MG_E4_FLAGS; case CMD_START_LINK: party_data.start_link();