summaryrefslogtreecommitdiff
path: root/arm9
diff options
context:
space:
mode:
authorPikalaxALT <pikalaxalt@gmail.com>2020-09-01 13:10:08 -0400
committerPikalaxALT <pikalaxalt@gmail.com>2020-09-01 13:10:08 -0400
commitc9b75afe693fb283790ee52c7b620619b881051a (patch)
tree8f5ab482dc345e1553bcb08d1962fc99025b645c /arm9
parent4b896d306d3cb1e650e91029a46d8c1e549d7b26 (diff)
Decompile trainer_data engine code
Diffstat (limited to 'arm9')
-rw-r--r--arm9/arm9.lsf6
-rw-r--r--arm9/asm/scrcmd.s2
-rw-r--r--arm9/asm/unk_0204653C.s2
-rw-r--r--arm9/asm/unk_0206ABC4.s749
-rw-r--r--arm9/global.inc8
-rw-r--r--arm9/modules/06/asm/module_06.s6
-rw-r--r--arm9/modules/07/asm/module_07.s16
-rw-r--r--arm9/modules/11/asm/module_11_thumb2.s10
-rw-r--r--arm9/src/pokemon.c2
-rw-r--r--arm9/src/trainer_data.c403
10 files changed, 431 insertions, 773 deletions
diff --git a/arm9/arm9.lsf b/arm9/arm9.lsf
index 29b8e407..6abd904a 100644
--- a/arm9/arm9.lsf
+++ b/arm9/arm9.lsf
@@ -246,9 +246,11 @@ Static arm9
Object unk_02064E90.o
Object unk_020653EC.o
Object unk_02066840.o
+
+ ##poketool##
Object pokemon.o
Object waza.o
- Object unk_0206ABC4.o
+ Object trainer_data.o
Object pokemon_storage_system.o
Object unk_0206B688.o
Object party.o
@@ -259,6 +261,8 @@ Static arm9
Object unk_0206DE24.o
Object unk_0206E0F0.o
Object unk_0206E2F0.o
+
+ ##itemtool##
Object itemtool.o
Object bag.o
Object unk_0206F1F0.o
diff --git a/arm9/asm/scrcmd.s b/arm9/asm/scrcmd.s
index b874b757..affbe1c1 100644
--- a/arm9/asm/scrcmd.s
+++ b/arm9/asm/scrcmd.s
@@ -6376,7 +6376,7 @@ FUN_0203CBE8: ; 0x0203CBE8
ldr r0, [sp, #0x0]
ldr r2, [r6, #0x0]
mov r3, #0xb
- bl FUN_0206AD4C
+ bl GetTrainerMessageByIdPair
add r0, r4, #0x0
mov r1, #0x1
bl FUN_02039438
diff --git a/arm9/asm/unk_0204653C.s b/arm9/asm/unk_0204653C.s
index b74847fc..4309494e 100644
--- a/arm9/asm/unk_0204653C.s
+++ b/arm9/asm/unk_0204653C.s
@@ -1482,7 +1482,7 @@ _0204711A:
ldr r1, [r7, #0xc]
ldr r2, [sp, #0x20]
add r0, r4, #0x0
- bl FUN_0206ABC4
+ bl EnemyTrainerSet_Init
ldr r0, [r7, #0xc]
bl FUN_02029FC8
mov r1, #0x8
diff --git a/arm9/asm/unk_0206ABC4.s b/arm9/asm/unk_0206ABC4.s
deleted file mode 100644
index b4b3d88e..00000000
--- a/arm9/asm/unk_0206ABC4.s
+++ /dev/null
@@ -1,749 +0,0 @@
- .include "asm/macros.inc"
- .include "global.inc"
-
- .section .rodata
-
- .global UNK_020F8010
-UNK_020F8010: ; 0x020F8010
- .byte 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0
- .byte 0, 1, 1, 0, 0, 1, 1, 2, 0, 1, 1, 0, 0, 0, 1, 2
- .byte 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 2
- .byte 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0
- .byte 0, 0, 1, 0, 0, 1, 2, 0, 1, 0, 1, 0, 1, 1, 1, 0
- .byte 1, 0, 2, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0
- .byte 1, 0, 0, 0
-
- .text
-
- thumb_func_start FUN_0206ABC4
-FUN_0206ABC4: ; 0x0206ABC4
- push {r3-r7, lr}
- sub sp, #0x48
- str r2, [sp, #0x4]
- ldr r2, _0206AC70 ; =0x0000022F
- str r0, [sp, #0x0]
- add r4, r1, #0x0
- ldr r3, [sp, #0x4]
- mov r0, #0x1
- mov r1, #0x1a
- bl NewMsgDataFromNarc
- str r0, [sp, #0x10]
- add r0, r4, #0x0
- bl FUN_02024EC0
- bl FUN_02024EE8
- ldr r4, [sp, #0x0]
- str r0, [sp, #0xc]
- add r0, r4, #0x0
- add r5, r4, #0x0
- mov r7, #0x0
- str r0, [sp, #0x8]
- add r5, #0x3c
-_0206ABF4:
- ldr r0, [r4, #0x18]
- cmp r0, #0x0
- beq _0206AC48
- add r1, sp, #0x14
- bl TrainerData_ReadTrData
- ldr r3, [sp, #0x8]
- add r6, sp, #0x14
- add r3, #0x28
- mov r2, #0x6
-_0206AC08:
- ldmia r6!, {r0-r1}
- stmia r3!, {r0-r1}
- sub r2, r2, #0x1
- bne _0206AC08
- ldr r0, [r6, #0x0]
- str r0, [r3, #0x0]
- add r0, sp, #0x14
- ldrb r0, [r0, #0x1]
- cmp r0, #0x3f
- bne _0206AC26
- ldr r1, [sp, #0xc]
- add r0, r5, #0x0
- bl CopyU16StringArray
- b _0206AC3E
-_0206AC26:
- ldr r0, [sp, #0x10]
- ldr r1, [r4, #0x18]
- bl NewString_ReadMsgData
- add r6, r0, #0x0
- add r1, r5, #0x0
- mov r2, #0x8
- bl CopyStringToU16Array
- add r0, r6, #0x0
- bl String_dtor
-_0206AC3E:
- ldr r0, [sp, #0x0]
- ldr r2, [sp, #0x4]
- add r1, r7, #0x0
- bl LoadTrainerParty
-_0206AC48:
- ldr r0, [sp, #0x8]
- add r7, r7, #0x1
- add r0, #0x34
- add r4, r4, #0x4
- add r5, #0x34
- str r0, [sp, #0x8]
- cmp r7, #0x4
- blt _0206ABF4
- ldr r0, [sp, #0x0]
- ldr r1, [r0, #0x0]
- ldr r0, [sp, #0x24]
- orr r1, r0
- ldr r0, [sp, #0x0]
- str r1, [r0, #0x0]
- ldr r0, [sp, #0x10]
- bl DestroyMsgData
- add sp, #0x48
- pop {r3-r7, pc}
- nop
-_0206AC70: .word 0x0000022F
-
- thumb_func_start TrainerData_GetAttr
-TrainerData_GetAttr: ; 0x0206AC74
- push {r4-r5, lr}
- sub sp, #0x34
- add r5, r1, #0x0
- add r1, sp, #0x0
- bl TrainerData_ReadTrData
- cmp r5, #0x9
- bhi _0206ACCC
- add r0, r5, r5
- add r0, pc
- ldrh r0, [r0, #0x6]
- lsl r0, r0, #0x10
- asr r0, r0, #0x10
- add pc, r0
-_0206AC90: ; jump table (using 16-bit offset)
- .short _0206ACA4 - _0206AC90 - 2; case 0
- .short _0206ACAA - _0206AC90 - 2; case 1
- .short _0206ACB0 - _0206AC90 - 2; case 2
- .short _0206ACB6 - _0206AC90 - 2; case 3
- .short _0206ACBC - _0206AC90 - 2; case 4
- .short _0206ACBC - _0206AC90 - 2; case 5
- .short _0206ACBC - _0206AC90 - 2; case 6
- .short _0206ACBC - _0206AC90 - 2; case 7
- .short _0206ACC6 - _0206AC90 - 2; case 8
- .short _0206ACCA - _0206AC90 - 2; case 9
-_0206ACA4:
- add r0, sp, #0x0
- ldrb r4, [r0, #0x0]
- b _0206ACCC
-_0206ACAA:
- add r0, sp, #0x0
- ldrb r4, [r0, #0x1]
- b _0206ACCC
-_0206ACB0:
- add r0, sp, #0x0
- ldrb r4, [r0, #0x2]
- b _0206ACCC
-_0206ACB6:
- add r0, sp, #0x0
- ldrb r4, [r0, #0x3]
- b _0206ACCC
-_0206ACBC:
- sub r0, r5, #0x4
- lsl r1, r0, #0x1
- add r0, sp, #0x4
- ldrh r4, [r0, r1]
- b _0206ACCC
-_0206ACC6:
- ldr r4, [sp, #0xc]
- b _0206ACCC
-_0206ACCA:
- ldr r4, [sp, #0x10]
-_0206ACCC:
- add r0, r4, #0x0
- add sp, #0x34
- pop {r4-r5, pc}
- .balign 4
-
- thumb_func_start FUN_0206ACD4
-FUN_0206ACD4: ; 0x0206ACD4
- push {r4-r7, lr}
- sub sp, #0x14
- add r5, r0, #0x0
- mov r0, #0x0
- str r0, [sp, #0x4]
- add r7, r1, #0x0
- ldr r1, [sp, #0x4]
- mov r0, #0x3b
- add r4, r2, #0x0
- bl GetNarcMemberSizeByIdPair
- add r6, r0, #0x0
- mov r0, #0x2
- str r0, [sp, #0x0]
- add r0, sp, #0xc
- mov r1, #0x89
- mov r2, #0x0
- lsl r3, r5, #0x1
- bl ReadFromNarcMemberByIdPair
- mov r0, #0x3b
- add r1, r4, #0x0
- bl NARC_ctor
- add r4, sp, #0xc
- ldrh r2, [r4, #0x0]
- str r0, [sp, #0x8]
- cmp r2, r6
- beq _0206AD40
-_0206AD0E:
- add r0, sp, #0xc
- add r0, #0x2
- str r0, [sp, #0x0]
- ldr r0, [sp, #0x8]
- mov r1, #0x0
- mov r3, #0x4
- bl NARC_ReadFromMember
- ldrh r1, [r4, #0x2]
- cmp r1, r5
- bne _0206AD30
- ldrh r0, [r4, #0x4]
- cmp r0, r7
- bne _0206AD30
- mov r0, #0x1
- str r0, [sp, #0x4]
- b _0206AD40
-_0206AD30:
- cmp r1, r5
- bne _0206AD40
- ldrh r0, [r4, #0x0]
- add r0, r0, #0x4
- strh r0, [r4, #0x0]
- ldrh r2, [r4, #0x0]
- cmp r2, r6
- bne _0206AD0E
-_0206AD40:
- ldr r0, [sp, #0x8]
- bl NARC_dtor
- ldr r0, [sp, #0x4]
- add sp, #0x14
- pop {r4-r7, pc}
-
- thumb_func_start FUN_0206AD4C
-FUN_0206AD4C: ; 0x0206AD4C
- push {r3-r7, lr}
- sub sp, #0x18
- add r6, r0, #0x0
- add r7, r1, #0x0
- mov r0, #0x3b
- mov r1, #0x0
- str r2, [sp, #0x4]
- str r3, [sp, #0x8]
- bl GetNarcMemberSizeByIdPair
- add r5, r0, #0x0
- mov r0, #0x2
- str r0, [sp, #0x0]
- add r0, sp, #0x10
- mov r1, #0x89
- mov r2, #0x0
- lsl r3, r6, #0x1
- bl ReadFromNarcMemberByIdPair
- ldr r1, [sp, #0x8]
- mov r0, #0x3b
- bl NARC_ctor
- add r4, sp, #0x10
- ldrh r2, [r4, #0x0]
- str r0, [sp, #0xc]
- cmp r2, r5
- beq _0206ADC2
-_0206AD84:
- add r0, sp, #0x10
- add r0, #0x2
- str r0, [sp, #0x0]
- ldr r0, [sp, #0xc]
- mov r1, #0x0
- mov r3, #0x4
- bl NARC_ReadFromMember
- ldrh r0, [r4, #0x2]
- cmp r0, r6
- bne _0206ADB6
- ldrh r0, [r4, #0x4]
- cmp r0, r7
- bne _0206ADB6
- ldr r0, [sp, #0x4]
- add r2, sp, #0x10
- str r0, [sp, #0x0]
- ldrh r2, [r2, #0x0]
- ldr r1, _0206ADDC ; =0x0000022E
- ldr r3, [sp, #0x8]
- mov r0, #0x1a
- lsr r2, r2, #0x2
- bl ReadMsgData_NewNarc_ExistingString
- b _0206ADC2
-_0206ADB6:
- ldrh r0, [r4, #0x0]
- add r0, r0, #0x4
- strh r0, [r4, #0x0]
- ldrh r2, [r4, #0x0]
- cmp r2, r5
- bne _0206AD84
-_0206ADC2:
- ldr r0, [sp, #0xc]
- bl NARC_dtor
- add r0, sp, #0x10
- ldrh r0, [r0, #0x0]
- cmp r0, r5
- bne _0206ADD6
- ldr r0, [sp, #0x4]
- bl StringSetEmpty
-_0206ADD6:
- add sp, #0x18
- pop {r3-r7, pc}
- nop
-_0206ADDC: .word 0x0000022E
-
- thumb_func_start TrainerData_ReadTrData
-TrainerData_ReadTrData: ; 0x0206ADE0
- ldr r3, _0206ADEC ; =ReadWholeNarcMemberByIdPair
- add r2, r0, #0x0
- add r0, r1, #0x0
- mov r1, #0x39
- bx r3
- nop
-_0206ADEC: .word ReadWholeNarcMemberByIdPair
-
- thumb_func_start TrainerData_ReadTrPoke
-TrainerData_ReadTrPoke: ; 0x0206ADF0
- ldr r3, _0206ADFC ; =ReadWholeNarcMemberByIdPair
- add r2, r0, #0x0
- add r0, r1, #0x0
- mov r1, #0x3a
- bx r3
- nop
-_0206ADFC: .word ReadWholeNarcMemberByIdPair
-
- thumb_func_start FUN_0206AE00
-FUN_0206AE00: ; 0x0206AE00
- ldr r1, _0206AE08 ; =UNK_020F8010
- ldrb r0, [r1, r0]
- bx lr
- nop
-_0206AE08: .word UNK_020F8010
-
- thumb_func_start LoadTrainerParty
-LoadTrainerParty: ; 0x0206AE0C
- push {r3-r7, lr}
- sub sp, #0x50
- add r7, r1, #0x0
- add r4, r0, #0x0
- add r5, r2, #0x0
- bl GetLCRNGSeed
- lsl r6, r7, #0x2
- str r0, [sp, #0x44]
- add r0, r4, r6
- ldr r0, [r0, #0x4]
- mov r1, #0x6
- bl InitPartyWithMaxSize
- add r0, r5, #0x0
- mov r1, #0x60
- bl AllocFromHeap
- str r0, [sp, #0x4c]
- add r0, r5, #0x0
- bl AllocMonZeroed
- str r0, [sp, #0x40]
- add r0, r4, r6
- ldr r0, [r0, #0x18]
- ldr r1, [sp, #0x4c]
- bl TrainerData_ReadTrPoke
- mov r0, #0x34
- add r5, r7, #0x0
- mul r5, r0
- add r0, r4, r5
- add r0, #0x29
- ldrb r0, [r0, #0x0]
- bl FUN_0206AE00
- cmp r0, #0x1
- bne _0206AE5E
- mov r0, #0x78
- str r0, [sp, #0x10]
- b _0206AE62
-_0206AE5E:
- mov r0, #0x88
- str r0, [sp, #0x10]
-_0206AE62:
- add r0, r4, r5
- add r0, #0x28
- ldrb r0, [r0, #0x0]
- cmp r0, #0x3
- bhi _0206AF26
- add r0, r0, r0
- add r0, pc
- ldrh r0, [r0, #0x6]
- lsl r0, r0, #0x10
- asr r0, r0, #0x10
- add pc, r0
-_0206AE78: ; jump table (using 16-bit offset)
- .short _0206AE80 - _0206AE78 - 2; case 0
- .short _0206AF28 - _0206AE78 - 2; case 1
- .short _0206AFE8 - _0206AE78 - 2; case 2
- .short _0206B08C - _0206AE78 - 2; case 3
-_0206AE80:
- mov r0, #0x0
- str r0, [sp, #0x48]
- add r0, r4, r5
- add r0, #0x2b
- ldrb r0, [r0, #0x0]
- cmp r0, #0x0
- ble _0206AF26
- ldr r0, [sp, #0x4c]
- str r0, [sp, #0x28]
- add r0, r4, r6
- str r0, [sp, #0x24]
-_0206AE96:
- ldr r0, [sp, #0x24]
- ldr r2, [sp, #0x28]
- ldr r1, [r0, #0x18]
- ldr r0, [sp, #0x28]
- ldrh r3, [r2, #0x0]
- ldrh r2, [r2, #0x2]
- ldrh r0, [r0, #0x4]
- add r2, r3, r2
- add r0, r0, r2
- add r7, r1, r0
- add r0, r7, #0x0
- bl SetLCRNGSeed
- add r0, r4, r5
- add r0, #0x29
- ldrb r0, [r0, #0x0]
- mov r6, #0x0
- cmp r0, #0x0
- ble _0206AECE
-_0206AEBC:
- bl LCRandom
- add r7, r0, #0x0
- add r0, r4, r5
- add r0, #0x29
- ldrb r0, [r0, #0x0]
- add r6, r6, #0x1
- cmp r6, r0
- blt _0206AEBC
-_0206AECE:
- ldr r0, [sp, #0x10]
- lsl r1, r7, #0x8
- add r6, r1, r0
- ldr r0, [sp, #0x28]
- ldrh r1, [r0, #0x0]
- mov r0, #0x1f
- mul r0, r1
- mov r1, #0xff
- bl _s32_div_f
- add r3, r0, #0x0
- mov r0, #0x1
- str r0, [sp, #0x0]
- lsl r3, r3, #0x18
- str r6, [sp, #0x4]
- mov r0, #0x2
- str r0, [sp, #0x8]
- mov r0, #0x0
- str r0, [sp, #0xc]
- ldr r1, [sp, #0x28]
- ldr r2, [sp, #0x28]
- ldrh r1, [r1, #0x4]
- ldrh r2, [r2, #0x2]
- ldr r0, [sp, #0x40]
- lsr r3, r3, #0x18
- bl CreateMon
- ldr r0, [sp, #0x24]
- ldr r1, [sp, #0x40]
- ldr r0, [r0, #0x4]
- bl AddMonToParty
- ldr r0, [sp, #0x28]
- add r0, r0, #0x6
- str r0, [sp, #0x28]
- ldr r0, [sp, #0x48]
- add r0, r0, #0x1
- str r0, [sp, #0x48]
- add r0, r4, r5
- add r0, #0x2b
- ldrb r1, [r0, #0x0]
- ldr r0, [sp, #0x48]
- cmp r0, r1
- blt _0206AE96
-_0206AF26:
- b _0206B156
-_0206AF28:
- mov r0, #0x0
- str r0, [sp, #0x18]
- add r0, r4, r5
- add r0, #0x2b
- ldrb r0, [r0, #0x0]
- cmp r0, #0x0
- ble _0206AFE6
- ldr r0, [sp, #0x4c]
- str r0, [sp, #0x30]
- add r0, r4, r6
- str r0, [sp, #0x2c]
-_0206AF3E:
- ldr r0, [sp, #0x2c]
- ldr r2, [sp, #0x30]
- ldr r1, [r0, #0x18]
- ldr r0, [sp, #0x30]
- ldrh r3, [r2, #0x0]
- ldrh r2, [r2, #0x2]
- ldrh r0, [r0, #0x4]
- add r2, r3, r2
- add r0, r0, r2
- add r7, r1, r0
- add r0, r7, #0x0
- bl SetLCRNGSeed
- add r0, r4, r5
- add r0, #0x29
- ldrb r0, [r0, #0x0]
- mov r6, #0x0
- cmp r0, #0x0
- ble _0206AF76
-_0206AF64:
- bl LCRandom
- add r7, r0, #0x0
- add r0, r4, r5
- add r0, #0x29
- ldrb r0, [r0, #0x0]
- add r6, r6, #0x1
- cmp r6, r0
- blt _0206AF64
-_0206AF76:
- ldr r0, [sp, #0x10]
- lsl r1, r7, #0x8
- add r6, r1, r0
- ldr r0, [sp, #0x30]
- ldrh r1, [r0, #0x0]
- mov r0, #0x1f
- mul r0, r1
- mov r1, #0xff
- bl _s32_div_f
- add r3, r0, #0x0
- mov r0, #0x1
- str r0, [sp, #0x0]
- lsl r3, r3, #0x18
- str r6, [sp, #0x4]
- mov r0, #0x2
- str r0, [sp, #0x8]
- mov r0, #0x0
- str r0, [sp, #0xc]
- ldr r1, [sp, #0x30]
- ldr r2, [sp, #0x30]
- ldrh r1, [r1, #0x4]
- ldrh r2, [r2, #0x2]
- ldr r0, [sp, #0x40]
- lsr r3, r3, #0x18
- bl CreateMon
- ldr r7, [sp, #0x30]
- mov r6, #0x0
-_0206AFB0:
- ldrh r1, [r7, #0x6]
- lsl r2, r6, #0x18
- ldr r0, [sp, #0x40]
- lsr r2, r2, #0x18
- bl MonSetMoveInSlot
- add r6, r6, #0x1
- add r7, r7, #0x2
- cmp r6, #0x4
- blt _0206AFB0
- ldr r0, [sp, #0x2c]
- ldr r1, [sp, #0x40]
- ldr r0, [r0, #0x4]
- bl AddMonToParty
- ldr r0, [sp, #0x30]
- add r0, #0xe
- str r0, [sp, #0x30]
- ldr r0, [sp, #0x18]
- add r0, r0, #0x1
- str r0, [sp, #0x18]
- add r0, r4, r5
- add r0, #0x2b
- ldrb r1, [r0, #0x0]
- ldr r0, [sp, #0x18]
- cmp r0, r1
- blt _0206AF3E
-_0206AFE6:
- b _0206B156
-_0206AFE8:
- mov r0, #0x0
- str r0, [sp, #0x1c]
- add r0, r4, r5
- add r0, #0x2b
- ldrb r0, [r0, #0x0]
- cmp r0, #0x0
- ble _0206B08A
- add r0, r4, r6
- ldr r7, [sp, #0x4c]
- str r0, [sp, #0x34]
-_0206AFFC:
- ldr r0, [sp, #0x34]
- ldrh r3, [r7, #0x0]
- ldrh r2, [r7, #0x2]
- ldr r1, [r0, #0x18]
- ldrh r0, [r7, #0x4]
- add r2, r3, r2
- add r0, r0, r2
- add r0, r1, r0
- str r0, [sp, #0x14]
- bl SetLCRNGSeed
- add r0, r4, r5
- add r0, #0x29
- ldrb r0, [r0, #0x0]
- mov r6, #0x0
- cmp r0, #0x0
- ble _0206B030
-_0206B01E:
- bl LCRandom
- str r0, [sp, #0x14]
- add r0, r4, r5
- add r0, #0x29
- ldrb r0, [r0, #0x0]
- add r6, r6, #0x1
- cmp r6, r0
- blt _0206B01E
-_0206B030:
- ldr r0, [sp, #0x14]
- lsl r1, r0, #0x8
- ldr r0, [sp, #0x10]
- add r6, r1, r0
- ldrh r1, [r7, #0x0]
- mov r0, #0x1f
- mul r0, r1
- mov r1, #0xff
- bl _s32_div_f
- add r3, r0, #0x0
- mov r0, #0x1
- str r0, [sp, #0x0]
- lsl r3, r3, #0x18
- str r6, [sp, #0x4]
- mov r0, #0x2
- str r0, [sp, #0x8]
- mov r0, #0x0
- str r0, [sp, #0xc]
- ldrh r1, [r7, #0x4]
- ldrh r2, [r7, #0x2]
- ldr r0, [sp, #0x40]
- lsr r3, r3, #0x18
- bl CreateMon
- ldr r0, [sp, #0x40]
- mov r1, #0x6
- add r2, r7, #0x6
- bl SetMonData
- ldr r0, [sp, #0x34]
- ldr r1, [sp, #0x40]
- ldr r0, [r0, #0x4]
- bl AddMonToParty
- ldr r0, [sp, #0x1c]
- add r7, #0x8
- add r0, r0, #0x1
- str r0, [sp, #0x1c]
- add r0, r4, r5
- add r0, #0x2b
- ldrb r1, [r0, #0x0]
- ldr r0, [sp, #0x1c]
- cmp r0, r1
- blt _0206AFFC
-_0206B08A:
- b _0206B156
-_0206B08C:
- mov r0, #0x0
- str r0, [sp, #0x20]
- add r0, r4, r5
- add r0, #0x2b
- ldrb r0, [r0, #0x0]
- cmp r0, #0x0
- ble _0206B156
- ldr r0, [sp, #0x4c]
- str r0, [sp, #0x3c]
- add r0, r4, r6
- str r0, [sp, #0x38]
-_0206B0A2:
- ldr r0, [sp, #0x38]
- ldr r2, [sp, #0x3c]
- ldr r1, [r0, #0x18]
- ldr r0, [sp, #0x3c]
- ldrh r3, [r2, #0x0]
- ldrh r2, [r2, #0x2]
- ldrh r0, [r0, #0x4]
- add r2, r3, r2
- add r0, r0, r2
- add r7, r1, r0
- add r0, r7, #0x0
- bl SetLCRNGSeed
- add r0, r4, r5
- add r0, #0x29
- ldrb r0, [r0, #0x0]
- mov r6, #0x0
- cmp r0, #0x0
- ble _0206B0DA
-_0206B0C8:
- bl LCRandom
- add r7, r0, #0x0
- add r0, r4, r5
- add r0, #0x29
- ldrb r0, [r0, #0x0]
- add r6, r6, #0x1
- cmp r6, r0
- blt _0206B0C8
-_0206B0DA:
- ldr r0, [sp, #0x10]
- lsl r1, r7, #0x8
- add r6, r1, r0
- ldr r0, [sp, #0x3c]
- ldrh r1, [r0, #0x0]
- mov r0, #0x1f
- mul r0, r1
- mov r1, #0xff
- bl _s32_div_f
- add r3, r0, #0x0
- mov r0, #0x1
- str r0, [sp, #0x0]
- lsl r3, r3, #0x18
- str r6, [sp, #0x4]
- mov r0, #0x2
- str r0, [sp, #0x8]
- mov r0, #0x0
- str r0, [sp, #0xc]
- ldr r1, [sp, #0x3c]
- ldr r2, [sp, #0x3c]
- ldrh r1, [r1, #0x4]
- ldrh r2, [r2, #0x2]
- ldr r0, [sp, #0x40]
- lsr r3, r3, #0x18
- bl CreateMon
- ldr r2, [sp, #0x3c]
- ldr r0, [sp, #0x40]
- mov r1, #0x6
- add r2, r2, #0x6
- bl SetMonData
- ldr r7, [sp, #0x3c]
- mov r6, #0x0
-_0206B120:
- ldrh r1, [r7, #0x8]
- lsl r2, r6, #0x18
- ldr r0, [sp, #0x40]
- lsr r2, r2, #0x18
- bl MonSetMoveInSlot
- add r6, r6, #0x1
- add r7, r7, #0x2
- cmp r6, #0x4
- blt _0206B120
- ldr r0, [sp, #0x38]
- ldr r1, [sp, #0x40]
- ldr r0, [r0, #0x4]
- bl AddMonToParty
- ldr r0, [sp, #0x3c]
- add r0, #0x10
- str r0, [sp, #0x3c]
- ldr r0, [sp, #0x20]
- add r0, r0, #0x1
- str r0, [sp, #0x20]
- add r0, r4, r5
- add r0, #0x2b
- ldrb r1, [r0, #0x0]
- ldr r0, [sp, #0x20]
- cmp r0, r1
- blt _0206B0A2
-_0206B156:
- ldr r0, [sp, #0x4c]
- bl FreeToHeap
- ldr r0, [sp, #0x40]
- bl FreeToHeap
- ldr r0, [sp, #0x44]
- bl SetLCRNGSeed
- add sp, #0x50
- pop {r3-r7, pc}
diff --git a/arm9/global.inc b/arm9/global.inc
index c039fd35..2f9c965b 100644
--- a/arm9/global.inc
+++ b/arm9/global.inc
@@ -4837,13 +4837,13 @@
.extern GetWazaAttr
.extern WazaGetMaxPp
.extern GetAttrFromWazaTbl
-.extern FUN_0206ABC4
+.extern EnemyTrainerSet_Init
.extern TrainerData_GetAttr
-.extern FUN_0206ACD4
-.extern FUN_0206AD4C
+.extern TrainerMessageWithIdPairExists
+.extern GetTrainerMessageByIdPair
.extern TrainerData_ReadTrData
.extern TrainerData_ReadTrPoke
-.extern FUN_0206AE00
+.extern TrainerClass_GetGenderOrTrainerCount
.extern PCStorage_init
.extern PCStorage_sizeof
.extern PCStorage_PlaceMonInFirstEmptySlotInAnyBox
diff --git a/arm9/modules/06/asm/module_06.s b/arm9/modules/06/asm/module_06.s
index 2af29137..f20313a9 100644
--- a/arm9/modules/06/asm/module_06.s
+++ b/arm9/modules/06/asm/module_06.s
@@ -5094,7 +5094,7 @@ _0223BC5A:
str r0, [r1, #0x20]
ldr r0, [sp, #0x2c]
ldr r1, [r5, #0xc]
- bl FUN_0206ABC4
+ bl EnemyTrainerSet_Init
add r0, sp, #0x30
str r0, [sp]
ldr r1, [sp, #0x20]
@@ -5531,7 +5531,7 @@ _0223BFFE:
str r0, [r1, #0x20]
ldr r0, [sp, #0x24]
ldr r1, [r5, #0xc]
- bl FUN_0206ABC4
+ bl EnemyTrainerSet_Init
add r0, sp, #0x28
str r0, [sp]
ldr r1, [sp, #0x18]
@@ -5841,7 +5841,7 @@ _0223C2A2:
str r0, [r1, #0x20]
ldr r0, [r4]
ldr r1, [r5, #0xc]
- bl FUN_0206ABC4
+ bl EnemyTrainerSet_Init
add r0, sp, #0x28
str r0, [sp]
ldr r1, [sp, #0x1c]
diff --git a/arm9/modules/07/asm/module_07.s b/arm9/modules/07/asm/module_07.s
index 2659dd5c..05283e3d 100644
--- a/arm9/modules/07/asm/module_07.s
+++ b/arm9/modules/07/asm/module_07.s
@@ -5049,7 +5049,7 @@ MOD07_02214720: ; 0x02214720
add r0, r1, r0
add r0, #0x29
ldrb r0, [r0]
- bl FUN_0206AE00
+ bl TrainerClass_GetGenderOrTrainerCount
str r0, [sp, #0x10]
ldr r0, [r4, #0x24]
mov r1, #0x10
@@ -5101,7 +5101,7 @@ _022147BC:
add r0, r1, r0
add r0, #0x29
ldrb r0, [r0]
- bl FUN_0206AE00
+ bl TrainerClass_GetGenderOrTrainerCount
str r0, [sp, #0x14]
ldr r0, [r4, #0x24]
mov r1, #0x10
@@ -5134,7 +5134,7 @@ _02214808:
add r0, r1, r0
add r0, #0x29
ldrb r0, [r0]
- bl FUN_0206AE00
+ bl TrainerClass_GetGenderOrTrainerCount
str r0, [sp, #0x18]
ldr r0, [r4, #0x24]
mov r1, #0x10
@@ -5167,7 +5167,7 @@ _02214854:
add r0, r1, r0
add r0, #0x29
ldrb r0, [r0]
- bl FUN_0206AE00
+ bl TrainerClass_GetGenderOrTrainerCount
str r0, [sp, #0x1c]
ldr r0, [r4, #0x24]
mov r1, #0x10
@@ -5205,12 +5205,12 @@ _022148A0:
bne _022148EA
add r0, #0x5d
ldrb r0, [r0]
- bl FUN_0206AE00
+ bl TrainerClass_GetGenderOrTrainerCount
str r0, [sp, #8]
ldr r0, [r4]
add r0, #0xc5
ldrb r0, [r0]
- bl FUN_0206AE00
+ bl TrainerClass_GetGenderOrTrainerCount
str r0, [sp, #0xc]
ldr r0, [r4, #0x18]
add r1, r5, #0
@@ -5224,12 +5224,12 @@ _022148A0:
_022148EA:
add r0, #0x29
ldrb r0, [r0]
- bl FUN_0206AE00
+ bl TrainerClass_GetGenderOrTrainerCount
str r0, [sp, #8]
ldr r0, [r4]
add r0, #0x91
ldrb r0, [r0]
- bl FUN_0206AE00
+ bl TrainerClass_GetGenderOrTrainerCount
str r0, [sp, #0xc]
ldr r0, [r4, #0x14]
add r1, r5, #0
diff --git a/arm9/modules/11/asm/module_11_thumb2.s b/arm9/modules/11/asm/module_11_thumb2.s
index a962fbf2..0c87c27f 100644
--- a/arm9/modules/11/asm/module_11_thumb2.s
+++ b/arm9/modules/11/asm/module_11_thumb2.s
@@ -4914,7 +4914,7 @@ _0223174C:
add r0, r4, #0
add r1, r7, #0
mov r3, #5
- bl FUN_0206AD4C
+ bl GetTrainerMessageByIdPair
add r0, r6, #0
mov r1, #0xff
bl FUN_02019620
@@ -45181,7 +45181,7 @@ _022452F8:
ldr r0, [sp, #8]
mov r1, #0xd
mov r2, #5
- bl FUN_0206ACD4
+ bl TrainerMessageWithIdPairExists
cmp r0, #0
beq _02245334
mov r1, #0x85
@@ -45219,7 +45219,7 @@ _0224533C:
ldr r0, [sp, #8]
mov r1, #0xe
mov r2, #5
- bl FUN_0206ACD4
+ bl TrainerMessageWithIdPairExists
cmp r0, #0
beq _0224537C
ldr r1, _0224548C ; =0x00002E7D
@@ -45276,7 +45276,7 @@ _022453C6:
ldr r0, [sp, #8]
mov r1, #0xf
mov r2, #5
- bl FUN_0206ACD4
+ bl TrainerMessageWithIdPairExists
cmp r0, #0
beq _022453F0
ldr r1, _0224548C ; =0x00002E7D
@@ -45340,7 +45340,7 @@ _0224543A:
ldr r0, [sp, #8]
mov r1, #0x10
mov r2, #5
- bl FUN_0206ACD4
+ bl TrainerMessageWithIdPairExists
cmp r0, #0
beq _02245472
ldr r1, _0224548C ; =0x00002E7D
diff --git a/arm9/src/pokemon.c b/arm9/src/pokemon.c
index 48b1a225..7931ba51 100644
--- a/arm9/src/pokemon.c
+++ b/arm9/src/pokemon.c
@@ -3711,7 +3711,7 @@ int FUN_0206AA30(int x)
case TRAINER_CLASS_PKMN_TRAINER_POKEKID:
return x - TRAINER_CLASS_COMMANDER_JUPITER;
default:
- if (FUN_0206AE00(x) == 1)
+ if (TrainerClass_GetGenderOrTrainerCount(x) == 1)
return 1;
else
return 0;
diff --git a/arm9/src/trainer_data.c b/arm9/src/trainer_data.c
new file mode 100644
index 00000000..7c52a78f
--- /dev/null
+++ b/arm9/src/trainer_data.c
@@ -0,0 +1,403 @@
+#include "global.h"
+#include "heap.h"
+#include "trainer_data.h"
+#include "math_util.h"
+#include "party.h"
+#include "proto.h"
+#include "msgdata.h"
+#include "constants/trainer_classes.h"
+
+#pragma thumb on
+
+extern void * FUN_02024EC0(struct SaveBlock2 *);
+extern u16 * FUN_02024EE8(void *);
+
+// Loads all battle opponents, including multi-battle partner if exists.
+void EnemyTrainerSet_Init(struct EnemyTrainerSet * enemies, struct SaveBlock2 * sav2, u32 heap_id)
+{
+ struct TrainerDataLoaded trdata;
+ struct MsgData * msgData;
+ u16 * rivalName;
+ s32 i;
+ struct String * str;
+
+ // FIXME: String formatting in files/msgdata/msg/narc_0559.txt is abnormal.
+ msgData = NewMsgDataFromNarc(1, NARC_MSGDATA_MSG, 559, heap_id);
+ rivalName = FUN_02024EE8(FUN_02024EC0(sav2));
+ for (i = 0; i < 4; i++)
+ {
+ if (enemies->trainer_idxs[i] != 0)
+ {
+ TrainerData_ReadTrData(enemies->trainer_idxs[i], &trdata.data);
+ enemies->datas[i] = trdata;
+ if (trdata.data.trainerClass == TRAINER_CLASS_PKMN_TRAINER_BARRY)
+ {
+ CopyU16StringArray(enemies->datas[i].name, rivalName);
+ }
+ else
+ {
+ str = NewString_ReadMsgData(msgData, enemies->trainer_idxs[i]);
+ CopyStringToU16Array(str, enemies->datas[i].name, OT_NAME_LENGTH + 1);
+ String_dtor(str);
+ }
+ CreateNPCTrainerParty(enemies, i, heap_id);
+ }
+ }
+ enemies->flags |= trdata.data.doubleBattle;
+ DestroyMsgData(msgData);
+}
+
+s32 TrainerData_GetAttr(u32 tr_idx, u32 attr_no)
+{
+ struct TrainerDataLoaded trainer;
+ s32 ret;
+
+ TrainerData_ReadTrData(tr_idx, &trainer.data);
+ switch (attr_no)
+ {
+ case 0:
+ ret = trainer.data.trainerType;
+ break;
+ case 1:
+ ret = trainer.data.trainerClass;
+ break;
+ case 2:
+ ret = trainer.data.unk_2;
+ break;
+ case 3:
+ ret = trainer.data.npoke;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ attr_no -= 4;
+ ret = trainer.data.items[attr_no];
+ break;
+ case 8:
+ ret = (s32)trainer.data.unk_C;
+ break;
+ case 9:
+ ret = (s32)trainer.data.doubleBattle;
+ break;
+ }
+ return ret; // UB: uninitialized in event of invalid attr
+}
+
+// Relevant files:
+// files/poketool/trmsg/trtbl.narc
+// files/poketool/trmsg/trtblofs.narc
+// files/msgdata/msg/narc_0558.txt
+// trtbl is a single-member NARC whose entries are two shorts each. The first short
+// designates the trainer ID and the second the message ID. They are ordered the same
+// as the corresponding msgdata file. All messages for a given trainer are found together,
+// however the trainers are not in order in this file. trtblofs gives a pointer into trtbl
+// for each trainer. trtblofs is also a single-member NARC whose entries are shorts, one
+// per NPC trainer.
+BOOL TrainerMessageWithIdPairExists(u32 trainer_idx, u32 msg_id, u32 heap_id)
+{
+ u16 rdbuf[3];
+ struct NARC * trTblNarc;
+ BOOL ret = FALSE;
+ u32 trTblSize;
+
+ trTblSize = GetNarcMemberSizeByIdPair(NARC_POKETOOL_TRMSG_TRTBL, 0);
+ ReadFromNarcMemberByIdPair(&rdbuf[0], NARC_POKETOOL_TRMSG_TRTBLOFS, 0, trainer_idx * 2, 2);
+ trTblNarc = NARC_ctor(NARC_POKETOOL_TRMSG_TRTBL, heap_id);
+ while (rdbuf[0] != trTblSize)
+ {
+ NARC_ReadFromMember(trTblNarc, 0, rdbuf[0], 4, &rdbuf[1]);
+ if (rdbuf[1] == trainer_idx && rdbuf[2] == msg_id)
+ {
+ ret = TRUE;
+ break;
+ }
+ if (rdbuf[1] != trainer_idx)
+ break;
+ rdbuf[0] += 4;
+ }
+ NARC_dtor(trTblNarc);
+ return ret;
+}
+
+void GetTrainerMessageByIdPair(u32 trainer_idx, u32 msg_id, struct String * str, u32 heap_id)
+{
+ u16 rdbuf[3];
+ u32 trTblSize;
+ struct NARC * trTblNarc;
+
+ trTblSize = GetNarcMemberSizeByIdPair(NARC_POKETOOL_TRMSG_TRTBL, 0);
+ ReadFromNarcMemberByIdPair(&rdbuf[0], NARC_POKETOOL_TRMSG_TRTBLOFS, 0, trainer_idx * 2, 2);
+ trTblNarc = NARC_ctor(NARC_POKETOOL_TRMSG_TRTBL, heap_id);
+ while (rdbuf[0] != trTblSize)
+ {
+ NARC_ReadFromMember(trTblNarc, 0, rdbuf[0], 4, &rdbuf[1]);
+ if (rdbuf[1] == trainer_idx && rdbuf[2] == msg_id)
+ {
+ ReadMsgData_NewNarc_ExistingString(NARC_MSGDATA_MSG, 558, (u32)(rdbuf[0] / 4), heap_id, str);
+ break;
+ }
+ rdbuf[0] += 4;
+ }
+ NARC_dtor(trTblNarc);
+ if (rdbuf[0] == trTblSize)
+ StringSetEmpty(str);
+}
+
+void TrainerData_ReadTrData(u32 idx, struct TrainerData * dest)
+{
+ ReadWholeNarcMemberByIdPair(dest, NARC_POKETOOL_TRAINER_TRDATA, (s32)idx);
+}
+
+void TrainerData_ReadTrPoke(u32 idx, union TrainerMon * dest)
+{
+ ReadWholeNarcMemberByIdPair(dest, NARC_POKETOOL_TRAINER_TRPOKE, (s32)idx);
+}
+
+const u8 sTrainerClassGenderCountTbl[] = {
+ /*TRAINER_CLASS_PKMN_TRAINER_M*/ 0,
+ /*TRAINER_CLASS_PKMN_TRAINER_F*/ 1,
+ /*TRAINER_CLASS_YOUNGSTER*/ 0,
+ /*TRAINER_CLASS_LASS*/ 1,
+ /*TRAINER_CLASS_CAMPER*/ 0,
+ /*TRAINER_CLASS_PICNICKER*/ 1,
+ /*TRAINER_CLASS_BUG_CATCHER*/ 0,
+ /*TRAINER_CLASS_AROMA_LADY*/ 1,
+ /*TRAINER_CLASS_TWINS*/ 1,
+ /*TRAINER_CLASS_HIKER*/ 0,
+ /*TRAINER_CLASS_BATTLE_GIRL*/ 1,
+ /*TRAINER_CLASS_FISHERMAN*/ 0,
+ /*TRAINER_CLASS_CYCLIST_M*/ 0,
+ /*TRAINER_CLASS_CYCLIST_F*/ 1,
+ /*TRAINER_CLASS_BLACK_BELT*/ 0,
+ /*TRAINER_CLASS_ARTIST*/ 0,
+ /*TRAINER_CLASS_PKMN_BREEDER_M*/ 0,
+ /*TRAINER_CLASS_PKMN_BREEDER_F*/ 1,
+ /*TRAINER_CLASS_COWGIRL*/ 1,
+ /*TRAINER_CLASS_JOGGER*/ 0,
+ /*TRAINER_CLASS_POKEFAN_M*/ 0,
+ /*TRAINER_CLASS_POKEFAN_F*/ 1,
+ /*TRAINER_CLASS_POKE_KID*/ 1,
+ /*TRAINER_CLASS_YOUNG_COUPLE*/ 2,
+ /*TRAINER_CLASS_ACE_TRAINER_M*/ 0,
+ /*TRAINER_CLASS_ACE_TRAINER_F*/ 1,
+ /*TRAINER_CLASS_WAITRESS*/ 1,
+ /*TRAINER_CLASS_VETERAN*/ 0,
+ /*TRAINER_CLASS_NINJA_BOY*/ 0,
+ /*TRAINER_CLASS_DRAGON_TAMER*/ 0,
+ /*TRAINER_CLASS_BIRD_KEEPER*/ 1,
+ /*TRAINER_CLASS_DOUBLE_TEAM*/ 2,
+ /*TRAINER_CLASS_RICH_BOY*/ 0,
+ /*TRAINER_CLASS_LADY*/ 1,
+ /*TRAINER_CLASS_GENTLEMAN*/ 0,
+ /*TRAINER_CLASS_SOCIALITE*/ 1,
+ /*TRAINER_CLASS_BEAUTY*/ 1,
+ /*TRAINER_CLASS_COLLECTOR*/ 0,
+ /*TRAINER_CLASS_POLICEMAN*/ 0,
+ /*TRAINER_CLASS_PKMN_RANGER_M*/ 0,
+ /*TRAINER_CLASS_PKMN_RANGER_F*/ 1,
+ /*TRAINER_CLASS_SCIENTIST*/ 0,
+ /*TRAINER_CLASS_SWIMMER_M*/ 0,
+ /*TRAINER_CLASS_SWIMMER_F*/ 1,
+ /*TRAINER_CLASS_TUBER_M*/ 0,
+ /*TRAINER_CLASS_TUBER_F*/ 1,
+ /*TRAINER_CLASS_SAILOR*/ 0,
+ /*TRAINER_CLASS_SIS_AND_BRO*/ 2,
+ /*TRAINER_CLASS_RUIN_MANIAC*/ 0,
+ /*TRAINER_CLASS_PSYCHIC_M*/ 0,
+ /*TRAINER_CLASS_PSYCHIC_F*/ 1,
+ /*TRAINER_CLASS_PI*/ 0,
+ /*TRAINER_CLASS_GUITARIST*/ 0,
+ /*TRAINER_CLASS_ACE_TRAINER_SNOW_M*/ 0,
+ /*TRAINER_CLASS_ACE_TRAINER_SNOW_F*/ 1,
+ /*TRAINER_CLASS_SKIER_M*/ 0,
+ /*TRAINER_CLASS_SKIER_F*/ 1,
+ /*TRAINER_CLASS_ROUGHNECK*/ 0,
+ /*TRAINER_CLASS_CLOWN*/ 0,
+ /*TRAINER_CLASS_WORKER*/ 0,
+ /*TRAINER_CLASS_SCHOOL_KID_M*/ 0,
+ /*TRAINER_CLASS_SCHOOL_KID_F*/ 1,
+ /*TRAINER_CLASS_LEADER_ROARK*/ 0,
+ /*TRAINER_CLASS_PKMN_TRAINER_BARRY*/ 0,
+ /*TRAINER_CLASS_LEADER_BYRON*/ 0,
+ /*TRAINER_CLASS_ELITE_FOUR_AARON*/ 0,
+ /*TRAINER_CLASS_ELITE_FOUR_BERTHA*/ 1,
+ /*TRAINER_CLASS_ELITE_FOUR_FLINT*/ 0,
+ /*TRAINER_CLASS_ELITE_FOUR_LUCIEN*/ 0,
+ /*TRAINER_CLASS_CHAMPION*/ 1,
+ /*TRAINER_CLASS_BELLE__PA*/ 2,
+ /*TRAINER_CLASS_RANCHER*/ 0,
+ /*TRAINER_CLASS_COMMANDER_MARS*/ 1,
+ /*TRAINER_CLASS_GALACTIC*/ 0,
+ /*TRAINER_CLASS_LEADER_GARDENIA*/ 1,
+ /*TRAINER_CLASS_LEADER_WAKE*/ 0,
+ /*TRAINER_CLASS_LEADER_MAYLENE*/ 1,
+ /*TRAINER_CLASS_LEADER_FANTINA*/ 1,
+ /*TRAINER_CLASS_LEADER_CANDICE*/ 1,
+ /*TRAINER_CLASS_LEADER_VOLKNER*/ 0,
+ /*TRAINER_CLASS_PARASOL_LADY*/ 1,
+ /*TRAINER_CLASS_WAITER*/ 0,
+ /*TRAINER_CLASS_INTERVIEWERS*/ 2,
+ /*TRAINER_CLASS_CAMERAMAN*/ 0,
+ /*TRAINER_CLASS_REPORTER*/ 1,
+ /*TRAINER_CLASS_IDOL*/ 1,
+ /*TRAINER_CLASS_GALACTIC_BOSS*/ 0,
+ /*TRAINER_CLASS_COMMANDER_JUPITER*/ 1,
+ /*TRAINER_CLASS_COMMANDER_SATURN*/ 1,
+ /*TRAINER_CLASS_GALACTIC_F*/ 1,
+ /*TRAINER_CLASS_PKMN_TRAINER_AROMA_LADY*/ 1,
+ /*TRAINER_CLASS_PKMN_TRAINER_RICH_BOY*/ 0,
+ /*TRAINER_CLASS_PKMN_TRAINER_PICNICKER*/ 1,
+ /*TRAINER_CLASS_PKMN_TRAINER_CAMPER*/ 0,
+ /*TRAINER_CLASS_PKMN_TRAINER_POKEKID*/ 1,
+ /*TRAINER_CLASS_PKMN_TRAINER_LUCAS*/ 0,
+ /*TRAINER_CLASS_PKMN_TRAINER_DAWN*/ 1,
+ /*TRAINER_CLASS_TOWER_TYCOON*/ 0
+};
+
+// Returns 0 for male, 1 for female, 2 for doubles. See above vector.
+int TrainerClass_GetGenderOrTrainerCount(int a0)
+{
+ return sTrainerClassGenderCountTbl[a0];
+}
+
+void CreateNPCTrainerParty(struct EnemyTrainerSet * enemies, s32 party_id, u32 heap_id)
+{
+ union TrainerMon * data;
+ s32 i;
+ s32 j;
+ u32 seed_bak;
+ struct Pokemon * pokemon;
+ struct TrainerMonSpeciesItemMoves * monSpeciesItemMoves;
+ struct TrainerMonSpeciesItem * monSpeciesItem;
+ struct TrainerMonSpeciesMoves * monSpeciesMoves;
+ struct TrainerMonSpecies * monSpecies;
+ u32 seed;
+ u32 personality;
+ u8 iv;
+ u32 pid_gender;
+
+ // We abuse the RNG for personality value generation, so back up the overworld
+ // state
+ seed_bak = GetLCRNGSeed();
+ InitPartyWithMaxSize(enemies->parties[party_id], PARTY_SIZE);
+ data = (union TrainerMon *)AllocFromHeap(heap_id, sizeof(union TrainerMon) * PARTY_SIZE);
+ pokemon = AllocMonZeroed(heap_id);
+ TrainerData_ReadTrPoke(enemies->trainer_idxs[party_id], data);
+
+ // If a Pokemon's gender ratio is 50/50, the generated Pokemon will be the same
+ // gender as its trainer. Otherwise, it will assume the more abundant gender
+ // according to its species gender ratio. In double battles, the behavior is
+ // identical to that of a solitary male opponent.
+ pid_gender = (u32)((TrainerClass_GetGenderOrTrainerCount(enemies->datas[party_id].data.trainerClass) == 1) ? 0x78 : 0x88);
+
+ // The trainer types can be more efficiently and expandibly treated as a flag
+ // array, with bit 0 being custom moveset and bit 1 being held item.
+ // Nintendo didn't do it that way, instead using a switch statement and a lot
+ // of code duplication. This has been the case since the 2nd generation games.
+ switch (enemies->datas[party_id].data.trainerType)
+ {
+ case TRTYPE_MON:
+ {
+ monSpecies = &data->species;
+ for (i = 0; i < enemies->datas[party_id].data.npoke; i++)
+ {
+ // Generate personality by seeding with a value based on the difficulty,
+ // level, species, and opponent ID. Roll the RNG N times, where N is
+ // the index of its trainer class. Finally, left shift the 16-bit
+ // pseudorandom value and add the gender selector.
+ // This guarantees that NPC trainers' Pokemon are generated in a
+ // consistent manner between attempts.
+ seed = monSpecies[i].difficulty + monSpecies[i].level + monSpecies[i].species + enemies->trainer_idxs[party_id];
+ SetLCRNGSeed(seed);
+ for (j = 0; j < enemies->datas[party_id].data.trainerClass; j++)
+ {
+ seed = LCRandom();
+ }
+ personality = (seed << 8);
+ personality += pid_gender;
+
+ // Difficulty is a number between 0 and 250 which directly corresponds
+ // to the (uniform) IV spread of the generated Pokemon.
+ iv = (u8)((monSpecies[i].difficulty * 31) / 255);
+ CreateMon(pokemon, monSpecies[i].species, monSpecies[i].level, iv, 1, (s32)personality, 2, 0);
+
+ // If you were treating the trainer type as a bitfield, you'd put the
+ // checks for held item and moves here. You'd also treat the trpoke
+ // data as a flat u16 array rather than an array of fixed-width structs.
+ AddMonToParty(enemies->parties[party_id], pokemon);
+ }
+ break;
+ }
+ case TRTYPE_MON_MOVES:
+ {
+ monSpeciesMoves = &data->species_moves;
+ for (i = 0; i < enemies->datas[party_id].data.npoke; i++)
+ {
+ seed = monSpeciesMoves[i].difficulty + monSpeciesMoves[i].level + monSpeciesMoves[i].species + enemies->trainer_idxs[party_id];
+ SetLCRNGSeed(seed);
+ for (j = 0; j < enemies->datas[party_id].data.trainerClass; j++)
+ {
+ seed = LCRandom();
+ }
+ personality = (seed << 8);
+ personality += pid_gender;
+ iv = (u8)((monSpeciesMoves[i].difficulty * 31) / 255);
+ CreateMon(pokemon, monSpeciesMoves[i].species, monSpeciesMoves[i].level, iv, 1, (s32)personality, 2, 0);
+ for (j = 0; j < 4; j++)
+ {
+ MonSetMoveInSlot(pokemon, monSpeciesMoves[i].moves[j], (u8)j);
+ }
+ AddMonToParty(enemies->parties[party_id], pokemon);
+ }
+ break;
+ }
+ case TRTYPE_MON_ITEM:
+ {
+ monSpeciesItem = &data->species_item;
+ for (i = 0; i < enemies->datas[party_id].data.npoke; i++)
+ {
+ seed = monSpeciesItem[i].difficulty + monSpeciesItem[i].level + monSpeciesItem[i].species + enemies->trainer_idxs[party_id];
+ SetLCRNGSeed(seed);
+ for (j = 0; j < enemies->datas[party_id].data.trainerClass; j++)
+ {
+ seed = LCRandom();
+ }
+ personality = (seed << 8);
+ personality += pid_gender;
+ iv = (u8)((monSpeciesItem[i].difficulty * 31) / 255);
+ CreateMon(pokemon, monSpeciesItem[i].species, monSpeciesItem[i].level, iv, 1, (s32)personality, 2, 0);
+ SetMonData(pokemon, MON_DATA_HELD_ITEM, &monSpeciesItem[i].item);
+ AddMonToParty(enemies->parties[party_id], pokemon);
+ }
+ break;
+ }
+ case TRTYPE_MON_ITEM_MOVES:
+ {
+ monSpeciesItemMoves = &data->species_item_moves;
+ for (i = 0; i < enemies->datas[party_id].data.npoke; i++)
+ {
+ seed = monSpeciesItemMoves[i].difficulty + monSpeciesItemMoves[i].level + monSpeciesItemMoves[i].species + enemies->trainer_idxs[party_id];
+ SetLCRNGSeed(seed);
+ for (j = 0; j < enemies->datas[party_id].data.trainerClass; j++)
+ {
+ seed = LCRandom();
+ }
+ personality = (seed << 8);
+ personality += pid_gender;
+ iv = (u8)((monSpeciesItemMoves[i].difficulty * 31) / 255);
+ CreateMon(pokemon, monSpeciesItemMoves[i].species, monSpeciesItemMoves[i].level, iv, 1, (s32)personality, 2, 0);
+ SetMonData(pokemon, MON_DATA_HELD_ITEM, &monSpeciesItemMoves[i].item);
+ for (j = 0; j < 4; j++)
+ {
+ MonSetMoveInSlot(pokemon, monSpeciesItemMoves[i].moves[j], (u8)j);
+ }
+ AddMonToParty(enemies->parties[party_id], pokemon);
+ }
+ break;
+ }
+ }
+ FreeToHeap(data);
+ FreeToHeap(pokemon);
+ SetLCRNGSeed(seed_bak);
+}