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))