diff --git a/asm/macros/scrcmd.inc b/asm/macros/scrcmd.inc index b18d9dffc1..7c21afb8a9 100644 --- a/asm/macros/scrcmd.inc +++ b/asm/macros/scrcmd.inc @@ -6,6 +6,7 @@ #include "generated/journal_online_events.h" #include "generated/map_headers.h" #include "generated/moves.h" +#include "generated/npc_trades.h" #include "generated/poketch_apps.h" #include "generated/save_types.h" #include "generated/sdat.h" @@ -2967,19 +2968,19 @@ .short \arg0 .endm - .macro ScrCmd_226 arg0 + .macro StartNpcTrade npcTradeID .short 550 - .byte \arg0 + .byte \npcTradeID .endm - .macro ScrCmd_227 arg0 + .macro GetNpcTradeSpecies destVar .short 551 - .short \arg0 + .short \destVar .endm - .macro ScrCmd_228 arg0 + .macro GetNpcTradeRequestedSpecies destVar .short 552 - .short \arg0 + .short \destVar .endm .macro ScrCmd_229 arg0 @@ -2987,7 +2988,7 @@ .short \arg0 .endm - .macro ScrCmd_22A + .macro FinishNpcTrade .short 554 .endm diff --git a/generated/meson.build b/generated/meson.build index 2d7601b5a7..818a1e670e 100644 --- a/generated/meson.build +++ b/generated/meson.build @@ -59,6 +59,7 @@ metang_generators = { 'move_ranges': { 'type': 'mask', 'tag': 'MoveRange', 'extra': ['--no-auto'] }, 'movement_actions': { 'type': 'enum', 'tag': 'MovementAction' }, 'moves': { 'type': 'enum', 'tag': 'Move' }, + 'npc_trades': { 'type': 'enum', 'tag': 'NpcTradeID' }, 'pal_park_land_area': { 'type': 'enum', 'tag': 'PalParkLandArea' }, 'pal_park_water_area': { 'type': 'enum', 'tag': 'PalParkWaterArea' }, 'pokemon_body_shapes': { 'type': 'enum', 'tag': 'PokemonBodyShape' }, @@ -116,6 +117,7 @@ foreach gen_key : metang_generators.keys() ) endforeach +npc_trades_txt = files('npc_trades.txt') species_txt = files('species.txt') text_banks_txt = files('text_banks.txt') trainers_txt = files('trainers.txt') diff --git a/generated/npc_trades.txt b/generated/npc_trades.txt new file mode 100644 index 0000000000..0cc8db75b5 --- /dev/null +++ b/generated/npc_trades.txt @@ -0,0 +1,5 @@ +NPC_TRADE_KAZZA_ABRA +NPC_TRADE_CHARAP_CHATOT +NPC_TRADE_GASPAR_HAUNTER +NPC_TRADE_FOOPA_MAGIKARP +MAX_NPC_TRADES diff --git a/generated/text_banks.txt b/generated/text_banks.txt index 82c49e4003..a691f884bf 100644 --- a/generated/text_banks.txt +++ b/generated/text_banks.txt @@ -368,7 +368,7 @@ TEXT_BANK_JOURNAL_ENTRIES TEXT_BANK_UNK_0367 TEXT_BANK_BATTLE_STRINGS TEXT_BANK_UNK_0369 -TEXT_BANK_UNK_0370 +TEXT_BANK_NPC_TRADE_NAMES TEXT_BANK_FURNITURE_NAMES TEXT_BANK_UNK_0372 TEXT_BANK_UNK_0373 diff --git a/include/overlay006/npc_trade.h b/include/overlay006/npc_trade.h new file mode 100644 index 0000000000..4bb5a92629 --- /dev/null +++ b/include/overlay006/npc_trade.h @@ -0,0 +1,47 @@ +#ifndef POKEPLATINUM_NPC_TRADE_H +#define POKEPLATINUM_NPC_TRADE_H + +#include "field/field_system_decl.h" +#include "overlay006/struct_ov6_02246254.h" + +#include "pokemon.h" + +typedef struct NpcTradeMon { + u32 species; + u32 hpIV; + u32 atkIV; + u32 defIV; + u32 speedIV; + u32 spAtkIV; + u32 spDefIV; + u32 unused1; + u32 otID; + u32 cool; + u32 beauty; + u32 cute; + u32 smart; + u32 tough; + u32 personality; + u32 heldItem; + u32 otGender; + u32 unused2; + u32 language; + u32 requestedSpecies; +} NpcTradeMon; + +typedef struct NpcTradeData { + NpcTradeMon *npcTradeMon; + Pokemon *mon; + TrainerInfo *trainerInfo; + u32 npcTradeID; + u32 heapID; +} NpcTradeData; + +NpcTradeData *NpcTrade_Init(u32 heapID, u32 entryID); +void NpcTrade_Free(NpcTradeData *data); +u32 NpcTrade_GetSpecies(const NpcTradeData *data); +u32 NpcTrade_GetRequestedSpecies(const NpcTradeData *data); +void NpcTrade_ReceiveMon(FieldSystem *fieldSystem, NpcTradeData *data, int slot); +void ov6_02246254(FieldSystem *fieldSystem, NpcTradeData *data, int slot, UnkStruct_ov6_02246254 *param3, Pokemon *givingMon, Pokemon *receivingMon); + +#endif // POKEPLATINUM_NPC_TRADE_H diff --git a/include/overlay006/ov6_02246184.h b/include/overlay006/ov6_02246184.h deleted file mode 100644 index dbd01d0308..0000000000 --- a/include/overlay006/ov6_02246184.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef POKEPLATINUM_OV6_02246184_H -#define POKEPLATINUM_OV6_02246184_H - -#include "field/field_system_decl.h" -#include "overlay006/struct_ov6_02246204_decl.h" -#include "overlay006/struct_ov6_02246254.h" - -#include "pokemon.h" - -UnkStruct_ov6_02246204 *ov6_02246184(u32 param0, u32 param1); -void ov6_02246204(UnkStruct_ov6_02246204 *param0); -u32 ov6_02246224(const UnkStruct_ov6_02246204 *param0); -u32 ov6_0224622C(const UnkStruct_ov6_02246204 *param0); -void ov6_02246234(FieldSystem *fieldSystem, UnkStruct_ov6_02246204 *param1, int param2); -void ov6_02246254(FieldSystem *fieldSystem, UnkStruct_ov6_02246204 *param1, int param2, UnkStruct_ov6_02246254 *param3, Pokemon *param4, Pokemon *param5); - -#endif // POKEPLATINUM_OV6_02246184_H diff --git a/include/overlay006/struct_ov6_02246204_decl.h b/include/overlay006/struct_ov6_02246204_decl.h deleted file mode 100644 index 39587bcdb0..0000000000 --- a/include/overlay006/struct_ov6_02246204_decl.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef POKEPLATINUM_STRUCT_OV6_02246204_DECL_H -#define POKEPLATINUM_STRUCT_OV6_02246204_DECL_H - -typedef struct UnkStruct_ov6_02246204_t UnkStruct_ov6_02246204; - -#endif // POKEPLATINUM_STRUCT_OV6_02246204_DECL_H diff --git a/include/unk_0206C660.h b/include/unk_0206C660.h index ef7d51068e..7fa26067af 100644 --- a/include/unk_0206C660.h +++ b/include/unk_0206C660.h @@ -1,10 +1,10 @@ #ifndef POKEPLATINUM_UNK_0206C660_H #define POKEPLATINUM_UNK_0206C660_H -#include "overlay006/struct_ov6_02246204_decl.h" +#include "overlay006/npc_trade.h" #include "field_task.h" -void sub_0206C740(FieldTask *param0, UnkStruct_ov6_02246204 *param1, int param2, u32 param3); +void sub_0206C740(FieldTask *param0, NpcTradeData *data, int param2, u32 param3); #endif // POKEPLATINUM_UNK_0206C660_H diff --git a/platinum.us/filesys.sha1 b/platinum.us/filesys.sha1 index 86d994362c..63f9076da0 100644 --- a/platinum.us/filesys.sha1 +++ b/platinum.us/filesys.sha1 @@ -329,7 +329,7 @@ ecdb14e0bc6619f114549e6126c8b6934cfc3aeb *res/prebuilt/battle/b_pl_stage/pl_bsdp cec363028fa6bc6240f9c8da7ab8f9e8bb1b1465 *res/prebuilt/contest/graphic/contest_obj.narc 7fa87d90ba039f67221a43782bf6a1a1107d5947 *res/prebuilt/demo/title/op_demo.narc d7e86fadf59a54f922fc7cf65ae65fa326b8429e *res/prebuilt/demo/title/titledemo.narc -32a0989a18cc7f3eb17c5949adecb3f057a84eea *res/prebuilt/fielddata/pokemon_trade/fld_trade.narc +32a0989a18cc7f3eb17c5949adecb3f057a84eea *res/field/trades/fld_trade.narc d4b6f9731b808a613338005f59959325ce1e3ac9 *res/prebuilt/resource/eng/zukan/zukan.narc 7e85af57b27fa4a0829b24550fc6c0dd275cf994 *res/prebuilt/resource/eng/batt_rec/batt_rec_gra.narc 2994f2955035001a22a1f225c68bfa809e4c85bf *res/prebuilt/resource/eng/wifi_lobby_minigame/wlmngm_tool.narc diff --git a/platinum.us/main.lsf b/platinum.us/main.lsf index 490ff33d98..bdb771f5d0 100644 --- a/platinum.us/main.lsf +++ b/platinum.us/main.lsf @@ -574,7 +574,7 @@ Overlay overlay6 Object main.nef.p/src_overlay006_swarm.c.o Object main.nef.p/src_overlay006_ov6_02243258.c.o Object main.nef.p/src_overlay006_roamer_after_battle.c.o - Object main.nef.p/src_overlay006_ov6_02246184.c.o + Object main.nef.p/src_overlay006_npc_trade.c.o Object main.nef.p/src_overlay006_ov6_02246444.c.o Object main.nef.p/src_overlay006_ov6_022465FC.c.o Object main.nef.p/src_overlay006_ov6_02246A30.c.o diff --git a/platinum.us/rom.rsf b/platinum.us/rom.rsf index 5737d8ec1b..4fcf078500 100644 --- a/platinum.us/rom.rsf +++ b/platinum.us/rom.rsf @@ -506,7 +506,14 @@ RomSpec File contest/graphic/contest_obj.narc File demo/title/op_demo.narc File demo/title/titledemo.narc - File fielddata/pokemon_trade/fld_trade.narc + + Root /fielddata/pokemon_trade + HostRoot res/field/trades + File fld_trade.narc + + Root / + HostRoot res/prebuilt + File resource/eng/zukan/zukan.narc File resource/eng/batt_rec/batt_rec_gra.narc File resource/eng/wifi_lobby_minigame/wlmngm_tool.narc diff --git a/res/field/meson.build b/res/field/meson.build index 632e993556..cb50cff8e0 100644 --- a/res/field/meson.build +++ b/res/field/meson.build @@ -1,3 +1,4 @@ subdir('encounters') subdir('events') subdir('scripts') +subdir('trades') diff --git a/res/field/scripts/scripts_eterna_city_condominiums_1f.s b/res/field/scripts/scripts_eterna_city_condominiums_1f.s index 5e683c3899..c14e90f846 100644 --- a/res/field/scripts/scripts_eterna_city_condominiums_1f.s +++ b/res/field/scripts/scripts_eterna_city_condominiums_1f.s @@ -113,13 +113,13 @@ _0168: FadeScreen 6, 1, 1, 0 WaitFadeScreen GoToIfEq 0x800C, 0xFF, _01D9 - ScrCmd_226 1 + StartNpcTrade NPC_TRADE_CHARAP_CHATOT SetVar 0x8004, 0x800C ScrCmd_198 0x8004, 0x8005 - ScrCmd_228 0x800C + GetNpcTradeRequestedSpecies 0x800C GoToIfNe 0x8005, 0x800C, _01CC ScrCmd_229 0x8004 - ScrCmd_22A + FinishNpcTrade SetFlag 134 Message 10 WaitABXPadPress @@ -128,7 +128,7 @@ _0168: End _01CC: - ScrCmd_22A + FinishNpcTrade Message 11 WaitABXPadPress CloseMessage diff --git a/res/field/scripts/scripts_oreburgh_city_north_house_1f.s b/res/field/scripts/scripts_oreburgh_city_north_house_1f.s index 747015bad8..883fa31a9a 100644 --- a/res/field/scripts/scripts_oreburgh_city_north_house_1f.s +++ b/res/field/scripts/scripts_oreburgh_city_north_house_1f.s @@ -28,13 +28,13 @@ _003B: FadeScreen 6, 1, 1, 0 WaitFadeScreen GoToIfEq 0x800C, 0xFF, _00AC - ScrCmd_226 0 + StartNpcTrade NPC_TRADE_KAZZA_ABRA SetVar 0x8004, 0x800C ScrCmd_198 0x8004, 0x8005 - ScrCmd_228 0x800C + GetNpcTradeRequestedSpecies 0x800C GoToIfNe 0x8005, 0x800C, _009F ScrCmd_229 0x8004 - ScrCmd_22A + FinishNpcTrade SetFlag 133 Message 1 WaitABXPadPress @@ -43,7 +43,7 @@ _003B: End _009F: - ScrCmd_22A + FinishNpcTrade Message 2 WaitABXPadPress CloseMessage diff --git a/res/field/scripts/scripts_route_226_house.s b/res/field/scripts/scripts_route_226_house.s index 229fc18da1..5b3d3c5ca2 100644 --- a/res/field/scripts/scripts_route_226_house.s +++ b/res/field/scripts/scripts_route_226_house.s @@ -43,13 +43,13 @@ _0060: FadeScreen 6, 1, 1, 0 WaitFadeScreen GoToIfEq 0x800C, 0xFF, _00D1 - ScrCmd_226 3 + StartNpcTrade NPC_TRADE_FOOPA_MAGIKARP SetVar 0x8004, 0x800C ScrCmd_198 0x8004, 0x8005 - ScrCmd_228 0x800C + GetNpcTradeRequestedSpecies 0x800C GoToIfNe 0x8005, 0x800C, _00C4 ScrCmd_229 0x8004 - ScrCmd_22A + FinishNpcTrade SetFlag 245 Message 3 WaitABXPadPress @@ -58,7 +58,7 @@ _0060: End _00C4: - ScrCmd_22A + FinishNpcTrade Message 4 WaitABXPadPress CloseMessage diff --git a/res/field/scripts/scripts_snowpoint_city_west_house.s b/res/field/scripts/scripts_snowpoint_city_west_house.s index cf726573a5..34ad9ed5c8 100644 --- a/res/field/scripts/scripts_snowpoint_city_west_house.s +++ b/res/field/scripts/scripts_snowpoint_city_west_house.s @@ -45,13 +45,13 @@ _0060: FadeScreen 6, 1, 1, 0 WaitFadeScreen GoToIfEq 0x800C, 0xFF, _00D1 - ScrCmd_226 2 + StartNpcTrade NPC_TRADE_GASPAR_HAUNTER SetVar 0x8004, 0x800C ScrCmd_198 0x8004, 0x8005 - ScrCmd_228 0x800C + GetNpcTradeRequestedSpecies 0x800C GoToIfNe 0x8005, 0x800C, _00C4 ScrCmd_229 0x8004 - ScrCmd_22A + FinishNpcTrade SetFlag 244 Message 3 WaitABXPadPress @@ -60,7 +60,7 @@ _0060: End _00C4: - ScrCmd_22A + FinishNpcTrade Message 4 WaitABXPadPress CloseMessage diff --git a/res/field/trades/meson.build b/res/field/trades/meson.build new file mode 100644 index 0000000000..0b0ea5aad9 --- /dev/null +++ b/res/field/trades/meson.build @@ -0,0 +1,29 @@ +npc_trades_bin_gen = generator( + npc_trades_py, + arguments: [ '@INPUT@', '@OUTPUT@', ], + output: '@BASENAME@' +) + +npc_trades_consts = fs.read(npc_trades_txt).splitlines() +npc_trades_files = [] +foreach npc_trade: npc_trades_consts + if npc_trade.startswith('MAX_') + continue + endif + npc_trades_files += files(npc_trade.to_lower() + '.json') +endforeach + +npc_trades_order = files('npc_trades.order') +npc_trades_narc = custom_target('fld_trade.narc', + output: 'fld_trade.narc', + input: npc_trades_bin_gen.process(npc_trades_files, env: json2bin_env), + depends: [ py_consts_generators ], + command: [ + narc_exe, 'create', + '--order', npc_trades_order, + '--output', '@OUTPUT0@', + '@PRIVATE_DIR@', + ] +) + +nitrofs_files += npc_trades_narc diff --git a/res/field/trades/npc_trade_charap_chatot.json b/res/field/trades/npc_trade_charap_chatot.json new file mode 100644 index 0000000000..94c41c58c4 --- /dev/null +++ b/res/field/trades/npc_trade_charap_chatot.json @@ -0,0 +1,22 @@ +{ + "species": "SPECIES_CHATOT", + "hpIV": 15, + "atkIV": 20, + "defIV": 15, + "speedIV": 25, + "spAtkIV": 25, + "spDefIV": 15, + "unused1": 77, + "otID": 44142, + "cool": 20, + "beauty": 20, + "cute": 20, + "smart": 20, + "tough": 20, + "personality": 2151, + "heldItem": "ITEM_LEPPA_BERRY", + "otGender": "GENDER_MALE", + "unused2": 50, + "language": 2, + "requestedSpecies": "SPECIES_BUIZEL" +} diff --git a/res/field/trades/npc_trade_foopa_magikarp.json b/res/field/trades/npc_trade_foopa_magikarp.json new file mode 100644 index 0000000000..c7a147b87b --- /dev/null +++ b/res/field/trades/npc_trade_foopa_magikarp.json @@ -0,0 +1,22 @@ +{ + "species": "SPECIES_MAGIKARP", + "hpIV": 15, + "atkIV": 25, + "defIV": 15, + "speedIV": 20, + "spAtkIV": 25, + "spDefIV": 15, + "unused1": 33, + "otID": 53277, + "cool": 0, + "beauty": 0, + "cute": 0, + "smart": 0, + "tough": 0, + "personality": 1116, + "heldItem": "ITEM_LUM_BERRY", + "otGender": "GENDER_MALE", + "unused2": 0, + "language": 5, + "requestedSpecies": "SPECIES_FINNEON" +} diff --git a/res/field/trades/npc_trade_gaspar_haunter.json b/res/field/trades/npc_trade_gaspar_haunter.json new file mode 100644 index 0000000000..64aa415597 --- /dev/null +++ b/res/field/trades/npc_trade_gaspar_haunter.json @@ -0,0 +1,22 @@ +{ + "species": "SPECIES_HAUNTER", + "hpIV": 20, + "atkIV": 25, + "defIV": 15, + "speedIV": 25, + "spAtkIV": 15, + "spDefIV": 15, + "unused1": 26, + "otID": 19248, + "cool": 0, + "beauty": 0, + "cute": 0, + "smart": 0, + "tough": 0, + "personality": 136, + "heldItem": "ITEM_EVERSTONE", + "otGender": "GENDER_FEMALE", + "unused2": 0, + "language": 2, + "requestedSpecies": "SPECIES_MEDICHAM" +} diff --git a/res/field/trades/npc_trade_kazza_abra.json b/res/field/trades/npc_trade_kazza_abra.json new file mode 100644 index 0000000000..fe8b5a7c25 --- /dev/null +++ b/res/field/trades/npc_trade_kazza_abra.json @@ -0,0 +1,22 @@ +{ + "species": "SPECIES_ABRA", + "hpIV": 15, + "atkIV": 15, + "defIV": 15, + "speedIV": 20, + "spAtkIV": 25, + "spDefIV": 25, + "unused1": 28, + "otID": 25643, + "cool": 0, + "beauty": 0, + "cute": 0, + "smart": 0, + "tough": 0, + "personality": 142, + "heldItem": "ITEM_ORAN_BERRY", + "otGender": "GENDER_FEMALE", + "unused2": 0, + "language": 2, + "requestedSpecies": "SPECIES_MACHOP" +} diff --git a/res/field/trades/npc_trades.order b/res/field/trades/npc_trades.order new file mode 100644 index 0000000000..f82f2d14e0 --- /dev/null +++ b/res/field/trades/npc_trades.order @@ -0,0 +1,4 @@ +npc_trade_kazza_abra +npc_trade_charap_chatot +npc_trade_gaspar_haunter +npc_trade_foopa_magikarp diff --git a/res/prebuilt/fielddata/meson.build b/res/prebuilt/fielddata/meson.build index d4c40e595b..f8ae32894a 100644 --- a/res/prebuilt/fielddata/meson.build +++ b/res/prebuilt/fielddata/meson.build @@ -5,5 +5,4 @@ subdir('land_data') subdir('mapmatrix') subdir('maptable') subdir('mm_list') -subdir('pokemon_trade') subdir('tornworld') diff --git a/res/prebuilt/fielddata/pokemon_trade/fld_trade.narc b/res/prebuilt/fielddata/pokemon_trade/fld_trade.narc deleted file mode 100644 index 71cc3a09a3..0000000000 Binary files a/res/prebuilt/fielddata/pokemon_trade/fld_trade.narc and /dev/null differ diff --git a/res/prebuilt/fielddata/pokemon_trade/meson.build b/res/prebuilt/fielddata/pokemon_trade/meson.build deleted file mode 100644 index 40c71625f1..0000000000 --- a/res/prebuilt/fielddata/pokemon_trade/meson.build +++ /dev/null @@ -1,7 +0,0 @@ -prebuilt_files = [ - 'fld_trade.narc' -] - -foreach f : prebuilt_files - nitrofs_files += fs.copyfile(f) -endforeach \ No newline at end of file diff --git a/res/text/unk_0370.gmm b/res/text/npc_trade_names.gmm similarity index 72% rename from res/text/unk_0370.gmm rename to res/text/npc_trade_names.gmm index d6ff1dd7b4..433eaf0320 100644 --- a/res/text/unk_0370.gmm +++ b/res/text/npc_trade_names.gmm @@ -1,35 +1,35 @@ - + used Kazza - + used Charap - + used Gaspar - + used Foppa - + used Hilary - + used Norton - + used Mindy - + used Meister diff --git a/src/meson.build b/src/meson.build index a0d004ed36..f9f9de212d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -463,7 +463,7 @@ pokeplatinum_c = files( 'overlay006/swarm.c', 'overlay006/ov6_02243258.c', 'overlay006/roamer_after_battle.c', - 'overlay006/ov6_02246184.c', + 'overlay006/npc_trade.c', 'overlay006/ov6_02246444.c', 'overlay006/ov6_022465FC.c', 'overlay006/ov6_02246A30.c', diff --git a/src/overlay006/npc_trade.c b/src/overlay006/npc_trade.c new file mode 100644 index 0000000000..92a8f44861 --- /dev/null +++ b/src/overlay006/npc_trade.c @@ -0,0 +1,152 @@ +#include "overlay006/npc_trade.h" + +#include +#include + +#include "generated/npc_trades.h" +#include "generated/text_banks.h" + +#include "field/field_system.h" +#include "overlay006/struct_ov6_02246254.h" + +#include "graphics.h" +#include "heap.h" +#include "map_header.h" +#include "message.h" +#include "party.h" +#include "pokemon.h" +#include "save_player.h" +#include "strbuf.h" +#include "trainer_info.h" +#include "unk_0202F180.h" +#include "unk_020559DC.h" +#include "unk_02092494.h" + +static inline Strbuf *NpcTrade_GetOtName(u32 heapID, u32 npcTradeID); +static Strbuf *NpcTrade_GetNickname(u32 heapID, u32 npcTradeID); +static void NpcTrade_CreateMon(Pokemon *mon, NpcTradeMon *npcTrade, u32 level, u32 npcTradeID, u32 heapID, u32 mapID); + +NpcTradeData *NpcTrade_Init(u32 heapID, u32 npcTradeID) +{ + GF_ASSERT(npcTradeID < MAX_NPC_TRADES); + + NpcTradeData *data = Heap_AllocFromHeap(heapID, sizeof(NpcTradeData)); + memset(data, 0, sizeof(NpcTradeData)); + + data->npcTradeMon = LoadMemberFromNARC(NARC_INDEX_FIELDDATA__POKEMON_TRADE__FLD_TRADE, npcTradeID, FALSE, heapID, FALSE); + data->heapID = heapID; + data->npcTradeID = npcTradeID; + data->mon = Pokemon_New(heapID); + data->trainerInfo = TrainerInfo_New(heapID); + + TrainerInfo_Init(data->trainerInfo); + Strbuf *strbuf = NpcTrade_GetOtName(heapID, npcTradeID); + + u16 otName[128]; + Strbuf_ToChars(strbuf, otName, NELEMS(otName)); + Strbuf_Free(strbuf); + TrainerInfo_SetName(data->trainerInfo, otName); + TrainerInfo_SetGender(data->trainerInfo, data->npcTradeMon->otGender); + + return data; +} + +void NpcTrade_Free(NpcTradeData *data) +{ + Heap_FreeToHeap(data->npcTradeMon); + Heap_FreeToHeap(data->mon); + Heap_FreeToHeap(data->trainerInfo); + Heap_FreeToHeap(data); +} + +u32 NpcTrade_GetSpecies(const NpcTradeData *data) +{ + return data->npcTradeMon->species; +} + +u32 NpcTrade_GetRequestedSpecies(const NpcTradeData *data) +{ + return data->npcTradeMon->requestedSpecies; +} + +void NpcTrade_ReceiveMon(FieldSystem *fieldSystem, NpcTradeData *data, int slot) +{ + sub_0207A128(Party_GetFromSavedata(fieldSystem->saveData), slot, data->mon); + sub_0202F180(fieldSystem->saveData, data->mon); +} + +void ov6_02246254(FieldSystem *fieldSystem, NpcTradeData *data, int slot, UnkStruct_ov6_02246254 *param3, Pokemon *givingMon, Pokemon *receivingMon) +{ + Party *party = Party_GetFromSavedata(fieldSystem->saveData); + Pokemon *partyMon = Party_GetPokemonBySlotIndex(party, slot); + u32 level = Pokemon_GetValue(partyMon, MON_DATA_LEVEL, NULL); + + NpcTrade_CreateMon(data->mon, data->npcTradeMon, level, data->npcTradeID, data->heapID, fieldSystem->location->mapId); + + Pokemon_Copy(partyMon, givingMon); + Pokemon_Copy(data->mon, receivingMon); + + param3->unk_00 = Pokemon_GetBoxPokemon(givingMon); + param3->unk_04 = Pokemon_GetBoxPokemon(receivingMon); + param3->unk_08 = data->trainerInfo; + param3->unk_10 = 1; + param3->unk_14 = SaveData_Options(fieldSystem->saveData); + + int timeOfDay = FieldSystem_GetTimeOfDay(fieldSystem); + if (timeOfDay == TIMEOFDAY_MORNING || timeOfDay == TIMEOFDAY_DAY) { + param3->unk_0C = 0; + } else if (timeOfDay == TIMEOFDAY_TWILIGHT) { + param3->unk_0C = 1; + } else { + param3->unk_0C = 2; + } +} + +static inline Strbuf *NpcTrade_GetOtName(u32 heapID, u32 npcTradeID) +{ + return NpcTrade_GetNickname(heapID, MAX_NPC_TRADES + npcTradeID); +} + +static Strbuf *NpcTrade_GetNickname(u32 heapID, u32 npcTradeID) +{ + MessageLoader *loader = MessageLoader_Init(MESSAGE_LOADER_BANK_HANDLE, NARC_INDEX_MSGDATA__PL_MSG, TEXT_BANK_NPC_TRADE_NAMES, heapID); + Strbuf *strbuf = MessageLoader_GetNewStrbuf(loader, npcTradeID); + MessageLoader_Free(loader); + return strbuf; +} + +static void NpcTrade_CreateMon(Pokemon *mon, NpcTradeMon *npcTradeMon, u32 level, u32 npcTradeID, u32 heapID, u32 mapID) +{ + Pokemon_InitWith(mon, npcTradeMon->species, level, INIT_IVS_RANDOM, TRUE, npcTradeMon->personality, OTID_SET, npcTradeMon->otID); + + Strbuf *strbuf = NpcTrade_GetNickname(heapID, npcTradeID); + Pokemon_SetValue(mon, MON_DATA_NICKNAME_STRBUF, strbuf); + Strbuf_Free(strbuf); + + u8 hasNickname = TRUE; + Pokemon_SetValue(mon, MON_DATA_HAS_NICKNAME, &hasNickname); + Pokemon_SetValue(mon, MON_DATA_HP_IV, &npcTradeMon->hpIV); + Pokemon_SetValue(mon, MON_DATA_ATK_IV, &npcTradeMon->atkIV); + Pokemon_SetValue(mon, MON_DATA_DEF_IV, &npcTradeMon->defIV); + Pokemon_SetValue(mon, MON_DATA_SPEED_IV, &npcTradeMon->speedIV); + Pokemon_SetValue(mon, MON_DATA_SPATK_IV, &npcTradeMon->spAtkIV); + Pokemon_SetValue(mon, MON_DATA_SPDEF_IV, &npcTradeMon->spDefIV); + Pokemon_SetValue(mon, MON_DATA_COOL, &npcTradeMon->cool); + Pokemon_SetValue(mon, MON_DATA_BEAUTY, &npcTradeMon->beauty); + Pokemon_SetValue(mon, MON_DATA_CUTE, &npcTradeMon->cute); + Pokemon_SetValue(mon, MON_DATA_SMART, &npcTradeMon->smart); + Pokemon_SetValue(mon, MON_DATA_TOUGH, &npcTradeMon->tough); + Pokemon_SetValue(mon, MON_DATA_HELD_ITEM, &npcTradeMon->heldItem); + + strbuf = NpcTrade_GetOtName(heapID, npcTradeID); + Pokemon_SetValue(mon, MON_DATA_OTNAME_STRBUF, strbuf); + Strbuf_Free(strbuf); + + Pokemon_SetValue(mon, MON_DATA_OT_GENDER, &npcTradeMon->otGender); + Pokemon_SetValue(mon, MON_DATA_LANGUAGE, &npcTradeMon->language); + + sub_0209304C(mon, NULL, 1, MapHeader_GetMapLabelTextID(mapID), heapID); + Pokemon_CalcLevelAndStats(mon); + + GF_ASSERT(!Pokemon_IsShiny(mon)); +} diff --git a/src/overlay006/ov6_02246184.c b/src/overlay006/ov6_02246184.c deleted file mode 100644 index f48c5191b3..0000000000 --- a/src/overlay006/ov6_02246184.c +++ /dev/null @@ -1,196 +0,0 @@ -#include "overlay006/ov6_02246184.h" - -#include -#include - -#include "field/field_system.h" -#include "overlay006/struct_ov6_02246204_decl.h" -#include "overlay006/struct_ov6_02246254.h" - -#include "graphics.h" -#include "heap.h" -#include "map_header.h" -#include "message.h" -#include "party.h" -#include "pokemon.h" -#include "save_player.h" -#include "strbuf.h" -#include "trainer_info.h" -#include "unk_0202F180.h" -#include "unk_020559DC.h" -#include "unk_02092494.h" - -typedef struct { - u32 unk_00; - u32 unk_04; - u32 unk_08; - u32 unk_0C; - u32 unk_10; - u32 unk_14; - u32 unk_18; - u32 unk_1C; - u32 unk_20; - u32 unk_24; - u32 unk_28; - u32 unk_2C; - u32 unk_30; - u32 unk_34; - u32 unk_38; - u32 unk_3C; - u32 unk_40; - u32 unk_44; - u32 unk_48; - u32 unk_4C; -} UnkStruct_ov6_0224630C; - -typedef struct UnkStruct_ov6_02246204_t { - UnkStruct_ov6_0224630C *unk_00; - Pokemon *unk_04; - TrainerInfo *unk_08; - u32 unk_0C; - u32 unk_10; -}; - -static Strbuf *ov6_022462E4(u32 param0, u32 param1); -static void ov6_0224630C(Pokemon *param0, UnkStruct_ov6_0224630C *param1, u32 param2, u32 param3, u32 param4, u32 param5); - -UnkStruct_ov6_02246204 *ov6_02246184(u32 param0, u32 param1) -{ - UnkStruct_ov6_02246204 *v0; - Strbuf *v1; - u16 v2[128]; - - GF_ASSERT(param1 < 4); - - v0 = Heap_AllocFromHeap(param0, sizeof(UnkStruct_ov6_02246204)); - memset(v0, 0, sizeof(UnkStruct_ov6_02246204)); - - v0->unk_00 = LoadMemberFromNARC(115, param1, 0, param0, 0); - v0->unk_10 = param0; - v0->unk_0C = param1; - v0->unk_04 = Pokemon_New(param0); - v0->unk_08 = TrainerInfo_New(param0); - - TrainerInfo_Init(v0->unk_08); - v1 = ov6_022462E4(param0, 4 + param1); - - Strbuf_ToChars(v1, v2, 128); - Strbuf_Free(v1); - TrainerInfo_SetName(v0->unk_08, v2); - TrainerInfo_SetGender(v0->unk_08, v0->unk_00->unk_40); - - return v0; -} - -void ov6_02246204(UnkStruct_ov6_02246204 *param0) -{ - Heap_FreeToHeap(param0->unk_00); - Heap_FreeToHeap(param0->unk_04); - Heap_FreeToHeap(param0->unk_08); - Heap_FreeToHeap(param0); -} - -u32 ov6_02246224(const UnkStruct_ov6_02246204 *param0) -{ - return param0->unk_00->unk_00; -} - -u32 ov6_0224622C(const UnkStruct_ov6_02246204 *param0) -{ - return param0->unk_00->unk_4C; -} - -void ov6_02246234(FieldSystem *fieldSystem, UnkStruct_ov6_02246204 *param1, int param2) -{ - Party *v0 = Party_GetFromSavedata(fieldSystem->saveData); - - sub_0207A128(v0, param2, param1->unk_04); - sub_0202F180(fieldSystem->saveData, param1->unk_04); -} - -void ov6_02246254(FieldSystem *fieldSystem, UnkStruct_ov6_02246204 *param1, int param2, UnkStruct_ov6_02246254 *param3, Pokemon *param4, Pokemon *param5) -{ - Party *v0 = Party_GetFromSavedata(fieldSystem->saveData); - Pokemon *v1; - Strbuf *v2; - u32 v3; - int v4; - - v1 = Party_GetPokemonBySlotIndex(v0, param2); - v3 = Pokemon_GetValue(v1, MON_DATA_LEVEL, NULL); - - ov6_0224630C(param1->unk_04, param1->unk_00, v3, param1->unk_0C, param1->unk_10, fieldSystem->location->mapId); - - Pokemon_Copy(v1, param4); - Pokemon_Copy(param1->unk_04, param5); - - param3->unk_00 = Pokemon_GetBoxPokemon(param4); - param3->unk_04 = Pokemon_GetBoxPokemon(param5); - param3->unk_08 = param1->unk_08; - param3->unk_10 = 1; - param3->unk_14 = SaveData_Options(fieldSystem->saveData); - - v4 = FieldSystem_GetTimeOfDay(fieldSystem); - - if ((v4 == 0) || (v4 == 1)) { - param3->unk_0C = 0; - } else if (v4 == 2) { - param3->unk_0C = 1; - } else { - param3->unk_0C = 2; - } -} - -static Strbuf *ov6_022462E4(u32 fieldSystem, u32 param1) -{ - Strbuf *v0; - MessageLoader *v1 = MessageLoader_Init(0, 26, 370, fieldSystem); - - v0 = MessageLoader_GetNewStrbuf(v1, param1); - MessageLoader_Free(v1); - return v0; -} - -static void ov6_0224630C(Pokemon *param0, UnkStruct_ov6_0224630C *param1, u32 param2, u32 param3, u32 param4, u32 param5) -{ - Strbuf *v0; - u8 v1; - u32 v2; - - Pokemon_InitWith(param0, param1->unk_00, param2, INIT_IVS_RANDOM, TRUE, param1->unk_38, OTID_SET, param1->unk_20); - - v0 = ov6_022462E4(param4, param3); - - Pokemon_SetValue(param0, MON_DATA_NICKNAME_STRBUF, v0); - Strbuf_Free(v0); - - v1 = 1; - - Pokemon_SetValue(param0, MON_DATA_HAS_NICKNAME, &v1); - Pokemon_SetValue(param0, MON_DATA_HP_IV, ¶m1->unk_04); - Pokemon_SetValue(param0, MON_DATA_ATK_IV, ¶m1->unk_08); - Pokemon_SetValue(param0, MON_DATA_DEF_IV, ¶m1->unk_0C); - Pokemon_SetValue(param0, MON_DATA_SPEED_IV, ¶m1->unk_10); - Pokemon_SetValue(param0, MON_DATA_SPATK_IV, ¶m1->unk_14); - Pokemon_SetValue(param0, MON_DATA_SPDEF_IV, ¶m1->unk_18); - Pokemon_SetValue(param0, MON_DATA_COOL, ¶m1->unk_24); - Pokemon_SetValue(param0, MON_DATA_BEAUTY, ¶m1->unk_28); - Pokemon_SetValue(param0, MON_DATA_CUTE, ¶m1->unk_2C); - Pokemon_SetValue(param0, MON_DATA_SMART, ¶m1->unk_30); - Pokemon_SetValue(param0, MON_DATA_TOUGH, ¶m1->unk_34); - Pokemon_SetValue(param0, MON_DATA_HELD_ITEM, ¶m1->unk_3C); - - v0 = ov6_022462E4(param4, 4 + param3); - - Pokemon_SetValue(param0, MON_DATA_OTNAME_STRBUF, v0); - Strbuf_Free(v0); - Pokemon_SetValue(param0, MON_DATA_OT_GENDER, ¶m1->unk_40); - Pokemon_SetValue(param0, MON_DATA_LANGUAGE, ¶m1->unk_48); - - v2 = MapHeader_GetMapLabelTextID(param5); - - sub_0209304C(param0, NULL, 1, v2, param4); - Pokemon_CalcLevelAndStats(param0); - - GF_ASSERT(Pokemon_IsShiny(param0) == 0); -} diff --git a/src/scrcmd.c b/src/scrcmd.c index 369be3f565..c6b754258d 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -63,11 +63,11 @@ #include "overlay005/struct_ov5_021DC1A4_decl.h" #include "overlay005/struct_ov5_021DD42C.h" #include "overlay005/vs_seeker.h" +#include "overlay006/npc_trade.h" #include "overlay006/ov6_0223E140.h" #include "overlay006/ov6_02242AF0.h" #include "overlay006/ov6_02243004.h" #include "overlay006/ov6_02243258.h" -#include "overlay006/ov6_02246184.h" #include "overlay006/ov6_02246C24.h" #include "overlay006/ov6_02246F00.h" #include "overlay006/ov6_02247078.h" @@ -75,7 +75,6 @@ #include "overlay006/ov6_02247D30.h" #include "overlay006/ov6_02247F5C.h" #include "overlay006/ov6_02248948.h" -#include "overlay006/struct_ov6_02246204_decl.h" #include "overlay006/swarm.h" #include "overlay006/trophy_garden_daily_encounters.h" #include "overlay007/communication_club.h" @@ -601,11 +600,11 @@ static BOOL ScrCmd_219(ScriptContext *ctx); static BOOL ScrCmd_21A(ScriptContext *ctx); static BOOL ScrCmd_EnableSwarms(ScriptContext *ctx); static BOOL ScrCmd_21C(ScriptContext *ctx); -static BOOL ScrCmd_226(ScriptContext *ctx); -static BOOL ScrCmd_227(ScriptContext *ctx); -static BOOL ScrCmd_228(ScriptContext *ctx); +static BOOL ScrCmd_StartNpcTrade(ScriptContext *ctx); +static BOOL ScrCmd_GetNpcTradeSpecies(ScriptContext *ctx); +static BOOL ScrCmd_GetNpcTradeRequestedSpecies(ScriptContext *ctx); static BOOL ScrCmd_229(ScriptContext *ctx); -static BOOL ScrCmd_22A(ScriptContext *ctx); +static BOOL ScrCmd_FinishNpcTrade(ScriptContext *ctx); static BOOL ScrCmd_22B(ScriptContext *ctx); static BOOL ScrCmd_22C(ScriptContext *ctx); static BOOL ScrCmd_22D(ScriptContext *ctx); @@ -1313,11 +1312,11 @@ const ScrCmdFunc Unk_020EAC58[] = { ScrCmd_223, ScrCmd_224, ScrCmd_225, - ScrCmd_226, - ScrCmd_227, - ScrCmd_228, + ScrCmd_StartNpcTrade, + ScrCmd_GetNpcTradeSpecies, + ScrCmd_GetNpcTradeRequestedSpecies, ScrCmd_229, - ScrCmd_22A, + ScrCmd_FinishNpcTrade, ScrCmd_22B, ScrCmd_22C, ScrCmd_22D, @@ -6516,48 +6515,41 @@ static BOOL ScrCmd_21C(ScriptContext *ctx) return 0; } -static BOOL ScrCmd_226(ScriptContext *ctx) +static BOOL ScrCmd_StartNpcTrade(ScriptContext *ctx) { - void **v0 = FieldSystem_GetScriptMemberPtr(ctx->fieldSystem, SCRIPT_MANAGER_DATA_PTR); - u8 v1 = ScriptContext_ReadByte(ctx); - - *v0 = ov6_02246184(11, v1); - return 0; + void **data = FieldSystem_GetScriptMemberPtr(ctx->fieldSystem, SCRIPT_MANAGER_DATA_PTR); + *data = NpcTrade_Init(HEAP_ID_FIELDMAP, ScriptContext_ReadByte(ctx)); + return FALSE; } -static BOOL ScrCmd_227(ScriptContext *ctx) +static BOOL ScrCmd_GetNpcTradeSpecies(ScriptContext *ctx) { - void **v0 = FieldSystem_GetScriptMemberPtr(ctx->fieldSystem, SCRIPT_MANAGER_DATA_PTR); - u16 *v1 = ScriptContext_GetVarPointer(ctx); - - *v1 = ov6_02246224((UnkStruct_ov6_02246204 *)*v0); - return 0; + void **data = FieldSystem_GetScriptMemberPtr(ctx->fieldSystem, SCRIPT_MANAGER_DATA_PTR); + u16 *destVar = ScriptContext_GetVarPointer(ctx); + *destVar = NpcTrade_GetSpecies((NpcTradeData *)*data); + return FALSE; } -static BOOL ScrCmd_228(ScriptContext *ctx) +static BOOL ScrCmd_GetNpcTradeRequestedSpecies(ScriptContext *ctx) { - void **v0 = FieldSystem_GetScriptMemberPtr(ctx->fieldSystem, SCRIPT_MANAGER_DATA_PTR); - u16 *v1 = ScriptContext_GetVarPointer(ctx); - - *v1 = ov6_0224622C((UnkStruct_ov6_02246204 *)*v0); - return 0; + void **data = FieldSystem_GetScriptMemberPtr(ctx->fieldSystem, SCRIPT_MANAGER_DATA_PTR); + u16 *destVar = ScriptContext_GetVarPointer(ctx); + *destVar = NpcTrade_GetRequestedSpecies((NpcTradeData *)*data); + return FALSE; } static BOOL ScrCmd_229(ScriptContext *ctx) { - void **v0 = FieldSystem_GetScriptMemberPtr(ctx->fieldSystem, SCRIPT_MANAGER_DATA_PTR); - u16 v1 = ScriptContext_GetVar(ctx); - - sub_0206C740(ctx->task, (UnkStruct_ov6_02246204 *)*v0, v1, 11); - return 1; + void **data = FieldSystem_GetScriptMemberPtr(ctx->fieldSystem, SCRIPT_MANAGER_DATA_PTR); + sub_0206C740(ctx->task, (NpcTradeData *)*data, ScriptContext_GetVar(ctx), HEAP_ID_FIELDMAP); + return TRUE; } -static BOOL ScrCmd_22A(ScriptContext *ctx) +static BOOL ScrCmd_FinishNpcTrade(ScriptContext *ctx) { - void **v0 = FieldSystem_GetScriptMemberPtr(ctx->fieldSystem, SCRIPT_MANAGER_DATA_PTR); - - ov6_02246204((UnkStruct_ov6_02246204 *)*v0); - return 0; + void **data = FieldSystem_GetScriptMemberPtr(ctx->fieldSystem, SCRIPT_MANAGER_DATA_PTR); + NpcTrade_Free((NpcTradeData *)*data); + return FALSE; } static BOOL ScrCmd_22B(ScriptContext *ctx) diff --git a/src/unk_0206C660.c b/src/unk_0206C660.c index 9c1266c94c..b3727b7c7b 100644 --- a/src/unk_0206C660.c +++ b/src/unk_0206C660.c @@ -4,8 +4,7 @@ #include #include "field/field_system.h" -#include "overlay006/ov6_02246184.h" -#include "overlay006/struct_ov6_02246204_decl.h" +#include "overlay006/npc_trade.h" #include "overlay006/struct_ov6_02246254.h" #include "overlay095/ov95_02246C20.h" @@ -17,7 +16,7 @@ FS_EXTERN_OVERLAY(overlay95); typedef struct { - UnkStruct_ov6_02246204 *unk_00; + NpcTradeData *unk_00; u32 unk_04; int unk_08; UnkStruct_ov6_02246254 unk_0C; @@ -55,7 +54,7 @@ static BOOL sub_0206C680(FieldTask *param0) switch (v1->unk_04) { case 0: ov6_02246254(fieldSystem, v1->unk_00, v1->unk_08, &v1->unk_0C, v1->unk_24, v1->unk_28); - ov6_02246234(fieldSystem, v1->unk_00, v1->unk_08); + NpcTrade_ReceiveMon(fieldSystem, v1->unk_00, v1->unk_08); v1->unk_04++; break; case 1: @@ -88,7 +87,7 @@ static BOOL sub_0206C680(FieldTask *param0) return 0; } -void sub_0206C740(FieldTask *param0, UnkStruct_ov6_02246204 *param1, int param2, u32 param3) +void sub_0206C740(FieldTask *param0, NpcTradeData *param1, int param2, u32 param3) { UnkStruct_0206C660 *v0 = Heap_AllocFromHeap(param3, sizeof(UnkStruct_0206C660)); diff --git a/tools/json2bin/convert.py b/tools/json2bin/convert.py index ce63c0c256..fa9ce660be 100644 --- a/tools/json2bin/convert.py +++ b/tools/json2bin/convert.py @@ -5,6 +5,7 @@ from generated import ( ai_flags, items, + genders, moves, species, trainer_classes @@ -37,6 +38,9 @@ def from_trainer_class(s: str) -> int: def from_trainer_ai_flag(s: str) -> int: return ai_flags.AIFlag[s].value +def from_gender(s: str) -> int: + return genders.Gender[s].value + TrainerDataFlags = collections.namedtuple('TrainerDataFlags', ['has_moves', 'has_items']) def derive_data_flags(party: list[dict]) -> TrainerDataFlags: diff --git a/tools/json2bin/meson.build b/tools/json2bin/meson.build index 5859573297..788dcc2330 100644 --- a/tools/json2bin/meson.build +++ b/tools/json2bin/meson.build @@ -11,3 +11,4 @@ encdata_ex_elusive_rod_py = find_program('encdata_ex_elusive_rod.py', native: tr encdata_ex_honey_trees_py = find_program('encdata_ex_honey_trees.py', native: true) encdata_ex_trophy_garden_py = find_program('encdata_ex_trophy_garden.py', native: true) encdata_ex_great_marsh_py = find_program('encdata_ex_great_marsh.py', native: true) +npc_trades_py = find_program('npc_trades.py', native: true) diff --git a/tools/json2bin/npc_trades.py b/tools/json2bin/npc_trades.py new file mode 100644 index 0000000000..0435e020ec --- /dev/null +++ b/tools/json2bin/npc_trades.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +import json +import pathlib +import sys + +from convert import from_item, from_gender, from_species, u32 + +def parse_npc_trade(data) -> bytes: + return b"".join([ + u32(from_species(data["species"])), + u32(data["hpIV"]), + u32(data["atkIV"]), + u32(data["defIV"]), + u32(data["speedIV"]), + u32(data["spAtkIV"]), + u32(data["spDefIV"]), + u32(data["unused1"]), + u32(data["otID"]), + u32(data["cool"]), + u32(data["beauty"]), + u32(data["cute"]), + u32(data["smart"]), + u32(data["tough"]), + u32(data["personality"]), + u32(from_item(data["heldItem"])), + u32(from_gender(data["otGender"])), + u32(data["unused2"]), + u32(data["language"]), + u32(from_species(data["requestedSpecies"])), + ]) + +input_path = pathlib.Path(sys.argv[1]) +output_path = pathlib.Path(sys.argv[2]) + +data = {} +with open(input_path, "r", encoding="utf-8") as input_file: + data = json.load(input_file) + +with open(output_path, "wb") as output_file: + output_file.write(parse_npc_trade(data))