Trainer Class - pret/pokered GitHub Wiki

Adding a new trainer class is fairly straightforward. A lot the changes are just for specifying information about the new trainer you'd like to add. For example, their name, what A.I. they'll have, what the Pokemon teams will be, etc... Although, slight code modification is necessary to allow for the new sprites to be loaded.

This tutorial will specifically replace the unused classes, UNUSED_JUGGLER and CHIEF. If you want to add more than this you can repeat the process but add them at the end of the each list if you'd like.

1. Update trainer constants

constants/trainer_constants.asm:

DEF OPP_ID_OFFSET EQU 200

MACRO trainer_const
	const \1
	DEF OPP_\1 EQU OPP_ID_OFFSET + \1
ENDM

; trainer class ids
; indexes for:
; - TrainerNames (see data/trainers/names.asm)
; - TrainerNamePointers (see data/trainers/name_pointers.asm)
; - TrainerDataPointers (see data/trainers/parties.asm)
; - TrainerPicAndMoneyPointers (see data/trainers/pic_pointers_money.asm)
; - TrainerAIPointers (see data/trainers/ai_pointers.asm)
; - TrainerClassMoveChoiceModifications (see data/trainers/move_choices.asm)
	const_def
	trainer_const NOBODY         ; $00
	trainer_const YOUNGSTER      ; $01
	trainer_const BUG_CATCHER    ; $02
	trainer_const LASS           ; $03
	trainer_const SAILOR         ; $04
	trainer_const JR_TRAINER_M   ; $05
	trainer_const JR_TRAINER_F   ; $06
	trainer_const POKEMANIAC     ; $07
	trainer_const SUPER_NERD     ; $08
	trainer_const HIKER          ; $09
	trainer_const BIKER          ; $0A
	trainer_const BURGLAR        ; $0B
	trainer_const ENGINEER       ; $0C
-	trainer_const UNUSED_JUGGLER ; $0D
+       trainer_const NEW_TRAINER1   ; $0D
	trainer_const FISHER         ; $0E
	trainer_const SWIMMER        ; $0F
	trainer_const CUE_BALL       ; $10
	trainer_const GAMBLER        ; $11
	trainer_const BEAUTY         ; $12
	trainer_const PSYCHIC_TR     ; $13
	trainer_const ROCKER         ; $14
	trainer_const JUGGLER        ; $15
	trainer_const TAMER          ; $16
	trainer_const BIRD_KEEPER    ; $17
	trainer_const BLACKBELT      ; $18
	trainer_const RIVAL1         ; $19
	trainer_const PROF_OAK       ; $1A
-	trainer_const CHIEF          ; $1B
+       trainer_const NEW_TRAINER2   ; $1B
	trainer_const SCIENTIST      ; $1C
	trainer_const GIOVANNI       ; $1D
	trainer_const ROCKET         ; $1E
	trainer_const COOLTRAINER_M  ; $1F
	trainer_const COOLTRAINER_F  ; $20
	trainer_const BRUNO          ; $21
	trainer_const BROCK          ; $22
	trainer_const MISTY          ; $23
	trainer_const LT_SURGE       ; $24
	trainer_const ERIKA          ; $25
	trainer_const KOGA           ; $26
	trainer_const BLAINE         ; $27
	trainer_const SABRINA        ; $28
	trainer_const GENTLEMAN      ; $29
	trainer_const RIVAL2         ; $2A
	trainer_const RIVAL3         ; $2B
	trainer_const LORELEI        ; $2C
	trainer_const CHANNELER      ; $2D
	trainer_const AGATHA         ; $2E
	trainer_const LANCE          ; $2F
DEF NUM_TRAINERS EQU const_value - 1

2. Update AI pointers

data/trainers/ai_pointers.asm:

TrainerAIPointers:
	table_width 3, TrainerAIPointers
	; one entry per trainer class
	; first byte, number of times (per Pokémon) it can occur
	; next two bytes, pointer to AI subroutine for trainer class
	; subroutines are defined in engine/battle/trainer_ai.asm
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
-	dbw 3, JugglerAI ; unused_juggler
+       dbw 3, GenericAI ; new trainer1
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 3, JugglerAI ; juggler
	dbw 3, GenericAI
	dbw 3, GenericAI
	dbw 2, BlackbeltAI ; blackbelt
	dbw 3, GenericAI ; rival1
	dbw 3, GenericAI
-	dbw 1, GenericAI ; chief
+       dbw 3, GenericAI ; new trainer2
	dbw 3, GenericAI
	dbw 1, GiovanniAI ; giovanni
	dbw 3, GenericAI
	dbw 2, CooltrainerMAI ; cooltrainerm
	dbw 1, CooltrainerFAI ; cooltrainerf
	dbw 2, BrunoAI ; bruno
	dbw 5, BrockAI ; brock
	dbw 1, MistyAI ; misty
	dbw 1, LtSurgeAI ; surge
	dbw 1, ErikaAI ; erika
	dbw 2, KogaAI ; koga
	dbw 2, BlaineAI ; blaine
	dbw 1, SabrinaAI ; sabrina
	dbw 3, GenericAI
	dbw 1, Rival2AI ; rival2
	dbw 1, Rival3AI ; rival3
	dbw 2, LoreleiAI ; lorelei
	dbw 3, GenericAI
	dbw 2, AgathaAI ; agatha
	dbw 1, LanceAI ; lance
	assert_table_length NUM_TRAINERS

3. Update encounter types (Optional)

Encounter Types: for default Male/Gym trainers encounter music, just not put in any list.

data/trainers/encounter_types.asm:

FemaleTrainerList::
	db OPP_LASS
	db OPP_JR_TRAINER_F
	db OPP_BEAUTY
	db OPP_COOLTRAINER_F
	db -1 ; end

EvilTrainerList::
-	db OPP_UNUSED_JUGGLER
	db OPP_GAMBLER
	db OPP_ROCKER
	db OPP_JUGGLER
-	db OPP_CHIEF
	db OPP_SCIENTIST
	db OPP_GIOVANNI
	db OPP_ROCKET
	db -1 ; end

4. Update move_choices

data/trainers/move_choices.asm:

MACRO move_choices
	IF _NARG
		db \# ; all args
	ENDC
	db 0 ; end
	DEF list_index += 1
ENDM

; move choice modification methods that are applied for each trainer class
TrainerClassMoveChoiceModifications:
	list_start TrainerClassMoveChoiceModifications
	move_choices         ; YOUNGSTER
	move_choices 1       ; BUG CATCHER
	move_choices 1       ; LASS
	move_choices 1, 3    ; SAILOR
	move_choices 1       ; JR_TRAINER_M
	move_choices 1       ; JR_TRAINER_F
	move_choices 1, 2, 3 ; POKEMANIAC
	move_choices 1, 2    ; SUPER_NERD
	move_choices 1       ; HIKER
	move_choices 1       ; BIKER
	move_choices 1, 3    ; BURGLAR
	move_choices 1       ; ENGINEER
-	move_choices 1, 2    ; UNUSED_JUGGLER
+       move_choices 1, 2, 3 ; NEW_TRAINER1
	move_choices 1, 3    ; FISHER
	move_choices 1, 3    ; SWIMMER
	move_choices         ; CUE_BALL
	move_choices 1       ; GAMBLER
	move_choices 1, 3    ; BEAUTY
	move_choices 1, 2    ; PSYCHIC_TR
	move_choices 1, 3    ; ROCKER
	move_choices 1       ; JUGGLER
	move_choices 1       ; TAMER
	move_choices 1       ; BIRD_KEEPER
	move_choices 1       ; BLACKBELT
	move_choices 1       ; RIVAL1
	move_choices 1, 3    ; PROF_OAK
-	move_choices 1, 2    ; CHIEF
+       move_choices 1       ; NEW_TRAINER2
	move_choices 1, 2    ; SCIENTIST
	move_choices 1, 3    ; GIOVANNI
	move_choices 1       ; ROCKET
	move_choices 1, 3    ; COOLTRAINER_M
	move_choices 1, 3    ; COOLTRAINER_F
	move_choices 1       ; BRUNO
	move_choices 1       ; BROCK
	move_choices 1, 3    ; MISTY
	move_choices 1, 3    ; LT_SURGE
	move_choices 1, 3    ; ERIKA
	move_choices 1, 3    ; KOGA
	move_choices 1, 3    ; BLAINE
	move_choices 1, 3    ; SABRINA
	move_choices 1, 2    ; GENTLEMAN
	move_choices 1, 3    ; RIVAL2
	move_choices 1, 3    ; RIVAL3
	move_choices 1, 2, 3 ; LORELEI
	move_choices 1       ; CHANNELER
	move_choices 1       ; AGATHA
	move_choices 1, 3    ; LANCE
	assert_list_length NUM_TRAINERS

5. Update name pointers

data/trainers/name_pointers.asm:

TrainerNamePointers:
; These are only used for trainers' defeat speeches.
; They were originally shortened variants of the trainer class names
; in the Japanese versions, but are now redundant with TrainerNames.
	table_width 2, TrainerNamePointers
	dw .YoungsterName
	dw .BugCatcherName
	dw .LassName
	dw wTrainerName
	dw .JrTrainerMName
	dw .JrTrainerFName
	dw .PokemaniacName
	dw .SuperNerdName
	dw wTrainerName
	dw wTrainerName
	dw .BurglarName
	dw .EngineerName
-	dw .UnusedJugglerName
+	dw wTrainerName
	dw wTrainerName
	dw .SwimmerName
	dw wTrainerName
	dw wTrainerName
	dw .BeautyName
	dw wTrainerName
	dw .RockerName
	dw .JugglerName
	dw wTrainerName
	dw wTrainerName
	dw .BlackbeltName
	dw wTrainerName
	dw .ProfOakName
-	dw .ChiefName
+	dw wTrainerName
	dw .ScientistName
	dw wTrainerName
	dw .RocketName
	dw .CooltrainerMName
	dw .CooltrainerFName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	dw wTrainerName
	assert_table_length NUM_TRAINERS

.YoungsterName:     db "YOUNGSTER@"
.BugCatcherName:    db "BUG CATCHER@"
.LassName:          db "LASS@"
.JrTrainerMName:    db "JR.TRAINER♂@"
.JrTrainerFName:    db "JR.TRAINER♀@"
.PokemaniacName:    db "POKéMANIAC@"
.SuperNerdName:     db "SUPER NERD@"
.BurglarName:       db "BURGLAR@"
.EngineerName:      db "ENGINEER@"
-.UnusedJugglerName: db "JUGGLER@"
.SwimmerName:       db "SWIMMER@"
.BeautyName:        db "BEAUTY@"
.RockerName:        db "ROCKER@"
.JugglerName:       db "JUGGLER@"
.BlackbeltName:     db "BLACKBELT@"
.ProfOakName:       db "PROF.OAK@"
-.ChiefName:         db "CHIEF@"
.ScientistName:     db "SCIENTIST@"
.RocketName:        db "ROCKET@"
.CooltrainerMName:  db "COOLTRAINER♂@"
.CooltrainerFName:  db "COOLTRAINER♀@"

6. Update trainer names

data/trainers/names.asm:

TrainerNames::
	list_start TrainerNames
	li "YOUNGSTER"
	li "BUG CATCHER"
	li "LASS"
	li "SAILOR"
	li "JR.TRAINER♂"
	li "JR.TRAINER♀"
	li "POKéMANIAC"
	li "SUPER NERD"
	li "HIKER"
	li "BIKER"
	li "BURGLAR"
	li "ENGINEER"
-	li "JUGGLER"
+       li "NEW TRAINER1"
	li "FISHERMAN"
	li "SWIMMER"
	li "CUE BALL"
	li "GAMBLER"
	li "BEAUTY"
	li "PSYCHIC"
	li "ROCKER"
	li "JUGGLER"
	li "TAMER"
	li "BIRD KEEPER"
	li "BLACKBELT"
	li "RIVAL1"
	li "PROF.OAK"
-	li "CHIEF"
+       li "NEW TRAINER2"
	li "SCIENTIST"
	li "GIOVANNI"
	li "ROCKET"
	li "COOLTRAINER♂"
	li "COOLTRAINER♀"
	li "BRUNO"
	li "BROCK"
	li "MISTY"
	li "LT.SURGE"
	li "ERIKA"
	li "KOGA"
	li "BLAINE"
	li "SABRINA"
	li "GENTLEMAN"
	li "RIVAL2"
	li "RIVAL3"
	li "LORELEI"
	li "CHANNELER"
	li "AGATHA"
	li "LANCE"
	assert_list_length NUM_TRAINERS

7. Update parties

data/trainers/parties.asm:

TrainerDataPointers:
	table_width 2, TrainerDataPointers
	dw YoungsterData
	dw BugCatcherData
	dw LassData
	dw SailorData
	dw JrTrainerMData
	dw JrTrainerFData
	dw PokemaniacData
	dw SuperNerdData
	dw HikerData
	dw BikerData
	dw BurglarData
	dw EngineerData
-	dw UnusedJugglerData
+       dw NewTrainer1Data
	dw FisherData
	dw SwimmerData
	dw CueBallData
	dw GamblerData
	dw BeautyData
	dw PsychicData
	dw RockerData
	dw JugglerData
	dw TamerData
	dw BirdKeeperData
	dw BlackbeltData
	dw Green1Data
	dw ProfOakData
-	dw ChiefData
+       dw NewTrainer2Data
	dw ScientistData
	dw GiovanniData
...
...
EngineerData:
; Unused
	db 21, VOLTORB, MAGNEMITE, 0
; Route 11
	db 21, MAGNEMITE, 0
	db 18, MAGNEMITE, MAGNEMITE, MAGNETON, 0

-UnusedJugglerData:
-; none
+NewTrainer1Data:
+       db 5, CATERPIE, 0

FisherData:
...
...
ProfOakData:
; Unused
	db $FF, 66, TAUROS, 67, EXEGGUTOR, 68, ARCANINE, 69, BLASTOISE, 70, GYARADOS, 0
	db $FF, 66, TAUROS, 67, EXEGGUTOR, 68, ARCANINE, 69, VENUSAUR, 70, GYARADOS, 0
	db $FF, 66, TAUROS, 67, EXEGGUTOR, 68, ARCANINE, 69, CHARIZARD, 70, GYARADOS, 0

-ChiefData:
-; none
+NewTrainer2Data:
+       db $FF, 50, CHARIZARD, 50, BLASTOISE, 0

ScientistData:

8. Update pic pointers and base reward money

data/trainers/pic_pointers_money.asm:

MACRO pic_money
	dw \1
	bcd3 \2
ENDM

TrainerPicAndMoneyPointers::
	table_width 5, TrainerPicAndMoneyPointers
	; pic pointer, base reward money
	; money received after battle = base money × level of last enemy mon
	pic_money YoungsterPic,    1500
	pic_money BugCatcherPic,   1000
	pic_money LassPic,         1500
	pic_money SailorPic,       3000
	pic_money JrTrainerMPic,   2000
	pic_money JrTrainerFPic,   2000
	pic_money PokemaniacPic,   5000
	pic_money SuperNerdPic,    2500
	pic_money HikerPic,        3500
	pic_money BikerPic,        2000
	pic_money BurglarPic,      9000
	pic_money EngineerPic,     5000
-	pic_money JugglerPic,      3500
+       pic_money NewTrainer1Pic,   500
	pic_money FisherPic,       3500
	pic_money SwimmerPic,       500
	pic_money CueBallPic,      2500
	pic_money GamblerPic,      7000
	pic_money BeautyPic,       7000
	pic_money PsychicPic,      1000
	pic_money RockerPic,       2500
	pic_money JugglerPic,      3500
	pic_money TamerPic,        4000
	pic_money BirdKeeperPic,   2500
	pic_money BlackbeltPic,    2500
	pic_money Rival1Pic,       3500
	pic_money ProfOakPic,      9900
-	pic_money ChiefPic,        3000
+       pic_money NewTrainer2Pic,  9900
	pic_money ScientistPic,    5000
	pic_money GiovanniPic,     9900
	pic_money RocketPic,       3000
	pic_money CooltrainerMPic, 3500
	pic_money CooltrainerFPic, 3500
	pic_money BrunoPic,        9900
	pic_money BrockPic,        9900
	pic_money MistyPic,        9900
	pic_money LtSurgePic,      9900
	pic_money ErikaPic,        9900
	pic_money KogaPic,         9900
	pic_money BlainePic,       9900
	pic_money SabrinaPic,      9900
	pic_money GentlemanPic,    7000
	pic_money Rival2Pic,       6500
	pic_money Rival3Pic,       9900
	pic_money LoreleiPic,      9900
	pic_money ChannelerPic,    3000
	pic_money AgathaPic,       9900
	pic_money LancePic,        9900
	assert_table_length NUM_TRAINERS

9. Handling Trainer Pics section growing too big

In the original game, trainer pics share their bank ($13) with other data. Adding pics will eventually make the bank grow too big. You have multiple ways of handling it.

9.1. Allow the trainer pics section to be in any bank

This is the simplest solution as long as all your pics can fit into a single bank.

Simply edit layout.link:

 ROMX $13
-	"Trainer Pics"
 	"Maps 9"
 	"Predefs"
 ROMX $14

The linker will automatically put your pics into a bank they can fit into instead of trying to put them in bank $13.

You probably won't need to split the section but just in case, here are 2 ways you can approach splitting the section.

9.2. Splitting the section (hardcoded way)

One way to split the section is to load the bank based on the trainer class ID. This assumes that trainer pics are ordered by trainer class ID.

In this example, the section is split at Prof Oak's trainer class.

First, modify _LoadTrainerPic to handle multiple banks engine/battle/core.asm:

 _LoadTrainerPic:
...
	ld d, a ; de contains pointer to trainer pic
	ld a, [wLinkState]
	and a
-	ld a, BANK("Trainer Pics")
-	jr z, .loadSprite
+	jr nz, .useRed
+	ld a, [wTrainerClass]
+	cp PROF_OAK ; first trainer class in "Trainer Pics 2"
+	ld a, BANK("Trainer Pics 2")
+	jr nc, .loadSprite
+	ld a, BANK("Trainer Pics 1")
+	jr .loadSprite
+.useRed
 	ld a, BANK(RedPicFront)
 .loadSprite
 	call UncompressSpriteFromDE
...

Then split the section in 2 gfx/pics.asm:

...
-SECTION "Trainer Pics", ROMX
+SECTION "Trainer Pics 1", ROMX

YoungsterPic::     INCBIN "gfx/trainers/youngster.pic"
BugCatcherPic::    INCBIN "gfx/trainers/bugcatcher.pic"
LassPic::          INCBIN "gfx/trainers/lass.pic"
SailorPic::        INCBIN "gfx/trainers/sailor.pic"
JrTrainerMPic::    INCBIN "gfx/trainers/jr.trainerm.pic"
JrTrainerFPic::    INCBIN "gfx/trainers/jr.trainerf.pic"
PokemaniacPic::    INCBIN "gfx/trainers/pokemaniac.pic"
SuperNerdPic::     INCBIN "gfx/trainers/supernerd.pic"
HikerPic::         INCBIN "gfx/trainers/hiker.pic"
BikerPic::         INCBIN "gfx/trainers/biker.pic"
BurglarPic::       INCBIN "gfx/trainers/burglar.pic"
EngineerPic::      INCBIN "gfx/trainers/engineer.pic"
FisherPic::        INCBIN "gfx/trainers/fisher.pic"
SwimmerPic::       INCBIN "gfx/trainers/swimmer.pic"
CueBallPic::       INCBIN "gfx/trainers/cueball.pic"
GamblerPic::       INCBIN "gfx/trainers/gambler.pic"
BeautyPic::        INCBIN "gfx/trainers/beauty.pic"
PsychicPic::       INCBIN "gfx/trainers/psychic.pic"
RockerPic::        INCBIN "gfx/trainers/rocker.pic"
JugglerPic::       INCBIN "gfx/trainers/juggler.pic"
TamerPic::         INCBIN "gfx/trainers/tamer.pic"
BirdKeeperPic::    INCBIN "gfx/trainers/birdkeeper.pic"
BlackbeltPic::     INCBIN "gfx/trainers/blackbelt.pic"
Rival1Pic::        INCBIN "gfx/trainers/rival1.pic"
+NewTrainer1Pic::  INCBIN "gfx/trainers/newtrainer1.pic"

+SECTION "Trainer Pics 2", ROMX

ProfOakPic::       INCBIN "gfx/trainers/prof.oak.pic"
-ChiefPic::
+NewTrainer2Pic::  INCBIN "gfx/trainers/newtrainer2.pic"
ScientistPic::     INCBIN "gfx/trainers/scientist.pic"
GiovanniPic::      INCBIN "gfx/trainers/giovanni.pic"
RocketPic::        INCBIN "gfx/trainers/rocket.pic"
CooltrainerMPic::  INCBIN "gfx/trainers/cooltrainerm.pic"
CooltrainerFPic::  INCBIN "gfx/trainers/cooltrainerf.pic"
BrunoPic::         INCBIN "gfx/trainers/bruno.pic"
BrockPic::         INCBIN "gfx/trainers/brock.pic"
MistyPic::         INCBIN "gfx/trainers/misty.pic"
LtSurgePic::       INCBIN "gfx/trainers/lt.surge.pic"
ErikaPic::         INCBIN "gfx/trainers/erika.pic"
KogaPic::          INCBIN "gfx/trainers/koga.pic"
BlainePic::        INCBIN "gfx/trainers/blaine.pic"
SabrinaPic::       INCBIN "gfx/trainers/sabrina.pic"
GentlemanPic::     INCBIN "gfx/trainers/gentleman.pic"
Rival2Pic::        INCBIN "gfx/trainers/rival2.pic"
Rival3Pic::        INCBIN "gfx/trainers/rival3.pic"
LoreleiPic::       INCBIN "gfx/trainers/lorelei.pic"
ChannelerPic::     INCBIN "gfx/trainers/channeler.pic"
AgathaPic::        INCBIN "gfx/trainers/agatha.pic"
LancePic::         INCBIN "gfx/trainers/lance.pic"

If you don't want to add a check for each new section, you may want to try the dynamic way.

9.3. Splitting the section (dynamic way)

One other way of splitting the section is to include the bank directly into TrainerPicAndMoneyPointers. If you don't mind using some space in the home bank, the WRAM byte after wTrainerPicPointer and one more byte per entry in TrainerPicAndMoneyPointers data, you can use this way instead of the hardcoded one.

Reserve wTrainerPicBank in ram/wram.asm:

 wTrainerPicPointer:: dw
 
-	ds 1
+wTrainerPicBank:: db

Update TrainerPicAndMoneyPointers to include the bank data/trainers/pic_pointers_money.asm

 MACRO pic_money
-	dw \1
+	dab \1
 	bcd3 \2
 ENDM
 
 TrainerPicAndMoneyPointers::
-	table_width 5
+	table_width 6
 	; pic pointer, base reward money
 	; money received after battle = base money × level of last enemy mon
 	pic_money YoungsterPic,    1500

Update home/trainers2.asm:

 GetTrainerInformation::
 ; ...
 	ld a, [wTrainerClass]
 	dec a
 	ld hl, TrainerPicAndMoneyPointers
-	ld bc, $5
+	ld bc, 6
 	call AddNTimes
 	ld de, wTrainerPicPointer
 	ld a, [hli]
 	ld [de], a
 	inc de
 	ld a, [hli]
 	ld [de], a
+	ASSERT wTrainerPicPointer + 2 == wTrainerPicBank, "wTrainerPicBank should follow wTrainerPicPointer"
+	inc de
+	ld a, [hli]
+	ld [de], a
 	ld de, wTrainerBaseMoney
 	ld a, [hli]
 	ld [de], a

Update _LoadTrainerPic in engine/battle/core.asm:

 	ld d, a ; de contains pointer to trainer pic
 	ld a, [wLinkState]
 	and a
-	ld a, BANK("Trainer Pics")
+	ld a, [wTrainerPicBank]
 	jr z, .loadSprite
 	ld a, BANK(RedPicFront)
 .loadSprite

split the section however you want gfx/pics.asm:

...
-SECTION "Trainer Pics", ROMX
+SECTION "Trainer Pics 1", ROMX

YoungsterPic::     INCBIN "gfx/trainers/youngster.pic"
BugCatcherPic::    INCBIN "gfx/trainers/bugcatcher.pic"
LassPic::          INCBIN "gfx/trainers/lass.pic"
SailorPic::        INCBIN "gfx/trainers/sailor.pic"
JrTrainerMPic::    INCBIN "gfx/trainers/jr.trainerm.pic"
JrTrainerFPic::    INCBIN "gfx/trainers/jr.trainerf.pic"
PokemaniacPic::    INCBIN "gfx/trainers/pokemaniac.pic"
SuperNerdPic::     INCBIN "gfx/trainers/supernerd.pic"
HikerPic::         INCBIN "gfx/trainers/hiker.pic"
BikerPic::         INCBIN "gfx/trainers/biker.pic"
BurglarPic::       INCBIN "gfx/trainers/burglar.pic"
EngineerPic::      INCBIN "gfx/trainers/engineer.pic"
FisherPic::        INCBIN "gfx/trainers/fisher.pic"
SwimmerPic::       INCBIN "gfx/trainers/swimmer.pic"
CueBallPic::       INCBIN "gfx/trainers/cueball.pic"
GamblerPic::       INCBIN "gfx/trainers/gambler.pic"
BeautyPic::        INCBIN "gfx/trainers/beauty.pic"
PsychicPic::       INCBIN "gfx/trainers/psychic.pic"
RockerPic::        INCBIN "gfx/trainers/rocker.pic"
JugglerPic::       INCBIN "gfx/trainers/juggler.pic"
TamerPic::         INCBIN "gfx/trainers/tamer.pic"
BirdKeeperPic::    INCBIN "gfx/trainers/birdkeeper.pic"
BlackbeltPic::     INCBIN "gfx/trainers/blackbelt.pic"
Rival1Pic::        INCBIN "gfx/trainers/rival1.pic"
+NewTrainer1Pic::  INCBIN "gfx/trainers/newtrainer1.pic"
+
+SECTION "Trainer Pics 2", ROMX
+
ProfOakPic::       INCBIN "gfx/trainers/prof.oak.pic"
-ChiefPic::
ScientistPic::     INCBIN "gfx/trainers/scientist.pic"
GiovanniPic::      INCBIN "gfx/trainers/giovanni.pic"
RocketPic::        INCBIN "gfx/trainers/rocket.pic"
CooltrainerMPic::  INCBIN "gfx/trainers/cooltrainerm.pic"
CooltrainerFPic::  INCBIN "gfx/trainers/cooltrainerf.pic"
BrunoPic::         INCBIN "gfx/trainers/bruno.pic"
+
+SECTION "Trainer Pics 3", ROMX
BrockPic::         INCBIN "gfx/trainers/brock.pic"
MistyPic::         INCBIN "gfx/trainers/misty.pic"
LtSurgePic::       INCBIN "gfx/trainers/lt.surge.pic"
ErikaPic::         INCBIN "gfx/trainers/erika.pic"
KogaPic::          INCBIN "gfx/trainers/koga.pic"
BlainePic::        INCBIN "gfx/trainers/blaine.pic"
SabrinaPic::       INCBIN "gfx/trainers/sabrina.pic"
+
+SECTION "Trainer Pics 4", ROMX
GentlemanPic::     INCBIN "gfx/trainers/gentleman.pic"
Rival2Pic::        INCBIN "gfx/trainers/rival2.pic"
Rival3Pic::        INCBIN "gfx/trainers/rival3.pic"
LoreleiPic::       INCBIN "gfx/trainers/lorelei.pic"
ChannelerPic::     INCBIN "gfx/trainers/channeler.pic"
AgathaPic::        INCBIN "gfx/trainers/agatha.pic"
LancePic::         INCBIN "gfx/trainers/lance.pic"
+NewTrainer2Pic::  INCBIN "gfx/trainers/newtrainer2.pic"