shithub: pokered

Download patch

ref: ce9940a2eb89caa9f53507a6d6071f8eaf85ee48
parent: 10211cc461b35140c815e18e95f7070eb0dcc586
author: xCrystal <rgr.crystal@gmail.com>
date: Wed Apr 1 13:27:51 EDT 2015

Further split bank e stuff

--- /dev/null
+++ b/engine/battle/bank_e_misc.asm
@@ -1,0 +1,122 @@
+; formats a string at wMovesString that lists the moves at wMoves
+FormatMovesString: ; 39b87 (e:5b87)
+	ld hl, wMoves
+	ld de, wMovesString
+	ld b, $0
+.printMoveNameLoop
+	ld a, [hli]
+	and a ; end of move list?
+	jr z, .printDashLoop ; print dashes when no moves are left
+	push hl
+	ld [wd0b5], a
+	ld a, BANK(MoveNames)
+	ld [wPredefBank], a
+	ld a, MOVE_NAME
+	ld [wNameListType], a
+	call GetName
+	ld hl, wcd6d
+.copyNameLoop
+	ld a, [hli]
+	cp $50
+	jr z, .doneCopyingName
+	ld [de], a
+	inc de
+	jr .copyNameLoop
+.doneCopyingName
+	ld a, b
+	ld [wcd6c], a
+	inc b
+	ld a, $4e ; line break
+	ld [de], a
+	inc de
+	pop hl
+	ld a, b
+	cp NUM_MOVES
+	jr z, .done
+	jr .printMoveNameLoop
+.printDashLoop
+	ld a, "-"
+	ld [de], a
+	inc de
+	inc b
+	ld a, b
+	cp NUM_MOVES
+	jr z, .done
+	ld a, $4e ; line break
+	ld [de], a
+	inc de
+	jr .printDashLoop
+.done
+	ld a, "@"
+	ld [de], a
+	ret
+
+; XXX this is called in a few places, but it doesn't appear to do anything useful
+Func_39bd5: ; 39bd5 (e:5bd5)
+	ld a, [wd11b]
+	cp $1
+	jr nz, .asm_39be6
+	ld hl, wEnemyPartyCount
+	ld de, wEnemyMonOT
+	ld a, ENEMYOT_NAME
+	jr .asm_39c18
+.asm_39be6
+	cp $4
+	jr nz, .calcAttackStat4
+	ld hl, wPartyCount
+	ld de, wPartyMonOT
+	ld a, PLAYEROT_NAME
+	jr .asm_39c18
+.calcAttackStat4
+	cp $5
+	jr nz, .asm_39c02
+	ld hl, wStringBuffer2 + 11
+	ld de, MonsterNames
+	ld a, MONSTER_NAME
+	jr .asm_39c18
+.asm_39c02
+	cp $2
+	jr nz, .asm_39c10
+	ld hl, wNumBagItems
+	ld de, ItemNames
+	ld a, ITEM_NAME
+	jr .asm_39c18
+.asm_39c10
+	ld hl, wStringBuffer2 + 11
+	ld de, ItemNames
+	ld a, ITEM_NAME
+.asm_39c18
+	ld [wNameListType], a
+	ld a, l
+	ld [wList], a
+	ld a, h
+	ld [wList + 1], a
+	ld a, e
+	ld [wcf8d], a
+	ld a, d
+	ld [wcf8e], a
+	ld bc, ItemPrices
+	ld a, c
+	ld [wItemPrices], a
+	ld a, b
+	ld [wItemPrices + 1], a
+	ret
+
+; get species of mon e in list [wcc49] for LoadMonData
+GetMonSpecies: ; 39c37 (e:5c37)
+	ld hl, wPartySpecies
+	ld a, [wcc49]
+	and a
+	jr z, .getSpecies
+	dec a
+	jr z, .enemyParty
+	ld hl, wBoxSpecies
+	jr .getSpecies
+.enemyParty
+	ld hl, wEnemyPartyMons
+.getSpecies
+	ld d, 0
+	add hl, de
+	ld a, [hl]
+	ld [wcf91], a
+	ret
\ No newline at end of file
--- /dev/null
+++ b/engine/battle/read_trainer_party.asm
@@ -1,0 +1,164 @@
+ReadTrainer: ; 39c53 (e:5c53)
+
+; don't change any moves in a link battle
+	ld a,[wLinkState]
+	and a
+	ret nz
+
+; set [wEnemyPartyCount] to 0, [wEnemyPartyMons] to FF
+; XXX first is total enemy pokemon?
+; XXX second is species of first pokemon?
+	ld hl,wEnemyPartyCount
+	xor a
+	ld [hli],a
+	dec a
+	ld [hl],a
+
+; get the pointer to trainer data for this class
+	ld a,[W_CUROPPONENT]
+	sub $C9 ; convert value from pokemon to trainer
+	add a,a
+	ld hl,TrainerDataPointers
+	ld c,a
+	ld b,0
+	add hl,bc ; hl points to trainer class
+	ld a,[hli]
+	ld h,[hl]
+	ld l,a
+	ld a,[W_TRAINERNO]
+	ld b,a
+; At this point b contains the trainer number,
+; and hl points to the trainer class.
+; Our next task is to iterate through the trainers,
+; decrementing b each time, until we get to the right one.
+.outer
+	dec b
+	jr z,.IterateTrainer
+.inner
+	ld a,[hli]
+	and a
+	jr nz,.inner
+	jr .outer
+
+; if the first byte of trainer data is FF,
+; - each pokemon has a specific level
+;      (as opposed to the whole team being of the same level)
+; - if [W_LONEATTACKNO] != 0, one pokemon on the team has a special move
+; else the first byte is the level of every pokemon on the team
+.IterateTrainer
+	ld a,[hli]
+	cp $FF ; is the trainer special?
+	jr z,.SpecialTrainer ; if so, check for special moves
+	ld [W_CURENEMYLVL],a
+.LoopTrainerData
+	ld a,[hli]
+	and a ; have we reached the end of the trainer data?
+	jr z,.FinishUp
+	ld [wcf91],a ; write species somewhere (XXX why?)
+	ld a,1
+	ld [wcc49],a
+	push hl
+	call AddPartyMon
+	pop hl
+	jr .LoopTrainerData
+.SpecialTrainer
+; if this code is being run:
+; - each pokemon has a specific level
+;      (as opposed to the whole team being of the same level)
+; - if [W_LONEATTACKNO] != 0, one pokemon on the team has a special move
+	ld a,[hli]
+	and a ; have we reached the end of the trainer data?
+	jr z,.AddLoneMove
+	ld [W_CURENEMYLVL],a
+	ld a,[hli]
+	ld [wcf91],a
+	ld a,1
+	ld [wcc49],a
+	push hl
+	call AddPartyMon
+	pop hl
+	jr .SpecialTrainer
+.AddLoneMove
+; does the trainer have a single monster with a different move
+	ld a,[W_LONEATTACKNO] ; Brock is 01, Misty is 02, Erika is 04, etc
+	and a
+	jr z,.AddTeamMove
+	dec a
+	add a,a
+	ld c,a
+	ld b,0
+	ld hl,LoneMoves
+	add hl,bc
+	ld a,[hli]
+	ld d,[hl]
+	ld hl,wEnemyMon1Moves + 2
+	ld bc,wEnemyMon2 - wEnemyMon1
+	call AddNTimes
+	ld [hl],d
+	jr .FinishUp
+.AddTeamMove
+; check if our trainer's team has special moves
+
+; get trainer class number
+	ld a,[W_CUROPPONENT]
+	sub $C8
+	ld b,a
+	ld hl,TeamMoves
+
+; iterate through entries in TeamMoves, checking each for our trainer class
+.IterateTeamMoves
+	ld a,[hli]
+	cp b
+	jr z,.GiveTeamMoves ; is there a match?
+	inc hl ; if not, go to the next entry
+	inc a
+	jr nz,.IterateTeamMoves
+
+; no matches found. is this trainer champion rival?
+	ld a,b
+	cp SONY3
+	jr z,.ChampionRival
+	jr .FinishUp ; nope
+.GiveTeamMoves
+	ld a,[hl]
+	ld [wEnemyMon5Moves + 2],a
+	jr .FinishUp
+.ChampionRival ; give moves to his team
+
+; pidgeot
+	ld a,SKY_ATTACK
+	ld [wEnemyMon1Moves + 2],a
+
+; starter
+	ld a,[W_RIVALSTARTER]
+	cp STARTER3
+	ld b,MEGA_DRAIN
+	jr z,.GiveStarterMove
+	cp STARTER1
+	ld b,FIRE_BLAST
+	jr z,.GiveStarterMove
+	ld b,BLIZZARD ; must be squirtle
+.GiveStarterMove
+	ld a,b
+	ld [wEnemyMon6Moves + 2],a
+.FinishUp ; XXX this needs documenting
+	xor a       ; clear D079-D07B
+	ld de,wd079
+	ld [de],a
+	inc de
+	ld [de],a
+	inc de
+	ld [de],a
+	ld a,[W_CURENEMYLVL]
+	ld b,a
+.LastLoop
+	ld hl,wd047
+	ld c,2
+	push bc
+	predef AddBCDPredef
+	pop bc
+	inc de
+	inc de
+	dec b
+	jr nz,.LastLoop
+	ret
\ No newline at end of file
--- /dev/null
+++ b/engine/battle/trainer_ai.asm
@@ -1,0 +1,837 @@
+; creates a set of moves that may be used and returns its address in hl
+; unused slots are filled with 0, all used slots may be chosen with equal probability
+AIEnemyTrainerChooseMoves: ; 39719 (e:5719)
+	ld a, $a
+	ld hl, wHPBarMaxHP  ; init temporary move selection array. Only the moves with the lowest numbers are chosen in the end
+	ld [hli], a   ; move 1
+	ld [hli], a   ; move 2
+	ld [hli], a   ; move 3
+	ld [hl], a    ; move 4
+	ld a, [W_ENEMYDISABLEDMOVE] ; forbid disabled move (if any)
+	swap a
+	and $f
+	jr z, .noMoveDisabled
+	ld hl, wHPBarMaxHP
+	dec a
+	ld c, a
+	ld b, $0
+	add hl, bc    ; advance pointer to forbidden move
+	ld [hl], $50  ; forbid (highly discourage) disabled move
+.noMoveDisabled
+	ld hl, TrainerClassMoveChoiceModifications ; 589B
+	ld a, [W_TRAINERCLASS]
+	ld b, a
+.loopTrainerClasses
+	dec b
+	jr z, .readTrainerClassData
+.loopTrainerClassData
+	ld a, [hli]
+	and a
+	jr nz, .loopTrainerClassData
+	jr .loopTrainerClasses
+.readTrainerClassData
+	ld a, [hl]
+	and a
+	jp z, .useOriginalMoveSet
+	push hl
+.nextMoveChoiceModification
+	pop hl
+	ld a, [hli]
+	and a
+	jr z, .loopFindMinimumEntries
+	push hl
+	ld hl, AIMoveChoiceModificationFunctionPointers ; $57a3
+	dec a
+	add a
+	ld c, a
+	ld b, $0
+	add hl, bc    ; skip to pointer
+	ld a, [hli]   ; read pointer into hl
+	ld h, [hl]
+	ld l, a
+	ld de, .nextMoveChoiceModification  ; set return address
+	push de
+	jp [hl]       ; execute modification function
+.loopFindMinimumEntries ; all entries will be decremented sequentially until one of them is zero
+	ld hl, wHPBarMaxHP  ; temp move selection array
+	ld de, wEnemyMonMoves  ; enemy moves
+	ld c, $4
+.loopDecrementEntries
+	ld a, [de]
+	inc de
+	and a
+	jr z, .loopFindMinimumEntries
+	dec [hl]
+	jr z, .minimumEntriesFound
+	inc hl
+	dec c
+	jr z, .loopFindMinimumEntries
+	jr .loopDecrementEntries
+.minimumEntriesFound
+	ld a, c
+.loopUndoPartialIteration ; undo last (partial) loop iteration
+	inc [hl]
+	dec hl
+	inc a
+	cp $5
+	jr nz, .loopUndoPartialIteration
+	ld hl, wHPBarMaxHP  ; temp move selection array
+	ld de, wEnemyMonMoves  ; enemy moves
+	ld c, $4
+.filterMinimalEntries ; all minimal entries now have value 1. All other slots will be disabled (move set to 0)
+	ld a, [de]
+	and a
+	jr nz, .moveExisting ; 0x3978a $1
+	ld [hl], a
+.moveExisting
+	ld a, [hl]
+	dec a
+	jr z, .slotWithMinimalValue
+	xor a
+	ld [hli], a     ; disable move slot
+	jr .next
+.slotWithMinimalValue
+	ld a, [de]
+	ld [hli], a     ; enable move slot
+.next
+	inc de
+	dec c
+	jr nz, .filterMinimalEntries
+	ld hl, wHPBarMaxHP    ; use created temporary array as move set
+	ret
+.useOriginalMoveSet
+	ld hl, wEnemyMonMoves    ; use original move set
+	ret
+
+AIMoveChoiceModificationFunctionPointers: ; 397a3 (e:57a3)
+	dw AIMoveChoiceModification1
+	dw AIMoveChoiceModification2
+	dw AIMoveChoiceModification3
+	dw AIMoveChoiceModification4 ; unused, does nothing
+
+; discourages moves that cause no damage but only a status ailment if player's mon already has one
+AIMoveChoiceModification1: ; 397ab (e:57ab)
+	ld a, [wBattleMonStatus]
+	and a
+	ret z ; return if no status ailment on player's mon
+	ld hl, wBuffer - 1 ; temp move selection array (-1 byte offest)
+	ld de, wEnemyMonMoves ; enemy moves
+	ld b, NUM_MOVES + 1
+.nextMove
+	dec b
+	ret z ; processed all 4 moves
+	inc hl
+	ld a, [de]
+	and a
+	ret z ; no more moves in move set
+	inc de
+	call ReadMove
+	ld a, [W_ENEMYMOVEPOWER]
+	and a
+	jr nz, .nextMove
+	ld a, [W_ENEMYMOVEEFFECT]
+	push hl
+	push de
+	push bc
+	ld hl, StatusAilmentMoveEffects
+	ld de, $0001
+	call IsInArray
+	pop bc
+	pop de
+	pop hl
+	jr nc, .nextMove
+	ld a, [hl]
+	add $5 ; heavily discourage move
+	ld [hl], a
+	jr .nextMove
+
+StatusAilmentMoveEffects ; 57e2
+	db $01 ; unused sleep effect
+	db SLEEP_EFFECT
+	db POISON_EFFECT
+	db PARALYZE_EFFECT
+	db $FF
+
+; slightly encourage moves with specific effects.
+; in particular, stat-modifying moves and other move effects
+; that fall in-bewteen
+AIMoveChoiceModification2: ; 397e7 (e:57e7)
+	ld a, [wAILayer2Encouragement]
+	cp $1 
+	ret nz
+	ld hl, wBuffer - 1 ; temp move selection array (-1 byte offset)
+	ld de, wEnemyMonMoves ; enemy moves
+	ld b, NUM_MOVES + 1
+.nextMove
+	dec b
+	ret z ; processed all 4 moves
+	inc hl
+	ld a, [de]
+	and a
+	ret z ; no more moves in move set
+	inc de
+	call ReadMove
+	ld a, [W_ENEMYMOVEEFFECT]
+	cp ATTACK_UP1_EFFECT
+	jr c, .nextMove
+	cp BIDE_EFFECT
+	jr c, .preferMove
+	cp ATTACK_UP2_EFFECT
+	jr c, .nextMove
+	cp POISON_EFFECT
+	jr c, .preferMove
+	jr .nextMove
+.preferMove
+	dec [hl] ; sligthly encourage this move
+	jr .nextMove
+
+; encourages moves that are effective against the player's mon (even if non-damaging).
+; discourage damaging moves that are ineffective or not very effective against the player's mon,
+; unless there's no damaging move that deals at least neutral damage
+AIMoveChoiceModification3: ; 39817 (e:5817)
+	ld hl, wBuffer - 1 ; temp move selection array (-1 byte offset)
+	ld de, wEnemyMonMoves ; enemy moves
+	ld b, $5
+.nextMove
+	dec b
+	ret z ; processed all 4 moves
+	inc hl
+	ld a, [de]
+	and a
+	ret z ; no more moves in move set
+	inc de
+	call ReadMove
+	push hl
+	push bc
+	push de
+	callab AIGetTypeEffectiveness
+	pop de
+	pop bc
+	pop hl
+	ld a, [wd11e]
+	cp $10
+	jr z, .nextMove
+	jr c, .notEffectiveMove
+	dec [hl] ; sligthly encourage this move
+	jr .nextMove
+.notEffectiveMove ; discourages non-effective moves if better moves are available
+	push hl
+	push de
+	push bc
+	ld a, [W_ENEMYMOVETYPE]
+	ld d, a
+	ld hl, wEnemyMonMoves  ; enemy moves
+	ld b, NUM_MOVES + 1
+	ld c, $0
+.loopMoves
+	dec b
+	jr z, .done
+	ld a, [hli]
+	and a
+	jr z, .done
+	call ReadMove
+	ld a, [W_ENEMYMOVEEFFECT]
+	cp SUPER_FANG_EFFECT
+	jr z, .betterMoveFound ; Super Fang is considered to be a better move
+	cp SPECIAL_DAMAGE_EFFECT
+	jr z, .betterMoveFound ; any special damage moves are considered to be better moves
+	cp FLY_EFFECT
+	jr z, .betterMoveFound ; Fly is considered to be a better move
+	ld a, [W_ENEMYMOVETYPE]
+	cp d
+	jr z, .loopMoves
+	ld a, [W_ENEMYMOVEPOWER]
+	and a
+	jr nz, .betterMoveFound ; damaging moves of a different type are considered to be better moves
+	jr .loopMoves
+.betterMoveFound
+	ld c, a
+.done
+	ld a, c
+	pop bc
+	pop de
+	pop hl
+	and a
+	jr z, .nextMove
+	inc [hl] ; sligthly discourage this move
+	jr .nextMove
+AIMoveChoiceModification4: ; 39883 (e:5883)
+	ret
+
+ReadMove: ; 39884 (e:5884)
+	push hl
+	push de
+	push bc
+	dec a
+	ld hl,Moves
+	ld bc,6
+	call AddNTimes
+	ld de,W_ENEMYMOVENUM
+	call CopyData
+	pop bc
+	pop de
+	pop hl
+	ret
+
+; move choice modification methods that are applied for each trainer class
+; 0 is sentinel value
+TrainerClassMoveChoiceModifications: ; 3989b (e:589b)
+	db 0      ; YOUNGSTER
+	db 1,0    ; BUG CATCHER
+	db 1,0    ; LASS
+	db 1,3,0  ; SAILOR
+	db 1,0    ; JR__TRAINER_M
+	db 1,0    ; JR__TRAINER_F
+	db 1,2,3,0; POKEMANIAC
+	db 1,2,0  ; SUPER_NERD
+	db 1,0    ; HIKER
+	db 1,0    ; BIKER
+	db 1,3,0  ; BURGLAR
+	db 1,0    ; ENGINEER
+	db 1,2,0  ; JUGGLER_X
+	db 1,3,0  ; FISHER
+	db 1,3,0  ; SWIMMER
+	db 0      ; CUE_BALL
+	db 1,0    ; GAMBLER
+	db 1,3,0  ; BEAUTY
+	db 1,2,0  ; PSYCHIC_TR
+	db 1,3,0  ; ROCKER
+	db 1,0    ; JUGGLER
+	db 1,0    ; TAMER
+	db 1,0    ; BIRD_KEEPER
+	db 1,0    ; BLACKBELT
+	db 1,0    ; SONY1
+	db 1,3,0  ; PROF_OAK
+	db 1,2,0  ; CHIEF
+	db 1,2,0  ; SCIENTIST
+	db 1,3,0  ; GIOVANNI
+	db 1,0    ; ROCKET
+	db 1,3,0  ; COOLTRAINER_M
+	db 1,3,0  ; COOLTRAINER_F
+	db 1,0    ; BRUNO
+	db 1,0    ; BROCK
+	db 1,3,0  ; MISTY
+	db 1,3,0  ; LT__SURGE
+	db 1,3,0  ; ERIKA
+	db 1,3,0  ; KOGA
+	db 1,3,0  ; BLAINE
+	db 1,3,0  ; SABRINA
+	db 1,2,0  ; GENTLEMAN
+	db 1,3,0  ; SONY2
+	db 1,3,0  ; SONY3
+	db 1,2,3,0; LORELEI
+	db 1,0    ; CHANNELER
+	db 1,0    ; AGATHA
+	db 1,3,0  ; LANCE
+
+INCLUDE "engine/battle/trainer_pic_money_pointers.asm"
+	
+INCLUDE "text/trainer_names.asm"	
+
+INCLUDE "engine/battle/bank_e_misc.asm"
+
+INCLUDE "engine/battle/read_trainer_party.asm"
+
+INCLUDE "data/trainer_moves.asm"
+
+INCLUDE "data/trainer_parties.asm"
+
+TrainerAI: ; 3a52e (e:652e)
+;XXX called at 34964, 3c342, 3c398
+	and a
+	ld a,[W_ISINBATTLE]
+	dec a
+	ret z ; if not a trainer, we're done here
+	ld a,[wLinkState]
+	cp LINK_STATE_BATTLING
+	ret z
+	ld a,[W_TRAINERCLASS] ; what trainer class is this?
+	dec a
+	ld c,a
+	ld b,0
+	ld hl,TrainerAIPointers
+	add hl,bc
+	add hl,bc
+	add hl,bc
+	ld a,[wAICount]
+	and a
+	ret z ; if no AI uses left, we're done here
+	inc hl
+	inc a
+	jr nz,.getpointer
+	dec hl
+	ld a,[hli]
+	ld [wAICount],a
+.getpointer
+	ld a,[hli]
+	ld h,[hl]
+	ld l,a
+	call Random
+	jp [hl]
+
+TrainerAIPointers: ; 3a55c (e:655c)
+; 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
+	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 ; juggler_x
+	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
+	dbw 3,GenericAI
+	dbw 1,GenericAI ; chief
+	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,Sony2AI ; sony2
+	dbw 1,Sony3AI ; sony3
+	dbw 2,LoreleiAI ; lorelei
+	dbw 3,GenericAI
+	dbw 2,AgathaAI ; agatha
+	dbw 1,LanceAI ; lance
+
+JugglerAI: ; 3a5e9 (e:65e9)
+	cp $40
+	ret nc
+	jp AISwitchIfEnoughMons
+
+BlackbeltAI: ; 3a5ef (e:65ef)
+	cp $20
+	ret nc
+	jp AIUseXAttack
+
+GiovanniAI: ; 3a5f5 (e:65f5)
+	cp $40
+	ret nc
+	jp AIUseGuardSpec
+
+CooltrainerMAI: ; 3a5fb (e:65fb)
+	cp $40
+	ret nc
+	jp AIUseXAttack
+
+CooltrainerFAI: ; 3a601 (e:6601)
+	cp $40
+	ld a,$A
+	call AICheckIfHPBelowFraction
+	jp c,AIUseHyperPotion
+	ld a,5
+	call AICheckIfHPBelowFraction
+	ret nc
+	jp AISwitchIfEnoughMons
+
+BrockAI: ; 3a614 (e:6614)
+; if his active monster has a status condition, use a full heal
+	ld a,[wEnemyMonStatus]
+	and a
+	ret z
+	jp AIUseFullHeal
+
+MistyAI: ; 3a61c (e:661c)
+	cp $40
+	ret nc
+	jp AIUseXDefend
+
+LtSurgeAI: ; 3a622 (e:6622)
+	cp $40
+	ret nc
+	jp AIUseXSpeed
+
+ErikaAI: ; 3a628 (e:6628)
+	cp $80
+	ret nc
+	ld a,$A
+	call AICheckIfHPBelowFraction
+	ret nc
+	jp AIUseSuperPotion
+
+KogaAI: ; 3a634 (e:6634)
+	cp $40
+	ret nc
+	jp AIUseXAttack
+
+BlaineAI: ; 3a63a (e:663a)
+	cp $40
+	ret nc
+	jp AIUseSuperPotion
+
+SabrinaAI: ; 3a640 (e:6640)
+	cp $40
+	ret nc
+	ld a,$A
+	call AICheckIfHPBelowFraction
+	ret nc
+	jp AIUseHyperPotion
+
+Sony2AI: ; 3a64c (e:664c)
+	cp $20
+	ret nc
+	ld a,5
+	call AICheckIfHPBelowFraction
+	ret nc
+	jp AIUsePotion
+
+Sony3AI: ; 3a658 (e:6658)
+	cp $20
+	ret nc
+	ld a,5
+	call AICheckIfHPBelowFraction
+	ret nc
+	jp AIUseFullRestore
+
+LoreleiAI: ; 3a664 (e:6664)
+	cp $80
+	ret nc
+	ld a,5
+	call AICheckIfHPBelowFraction
+	ret nc
+	jp AIUseSuperPotion
+
+BrunoAI: ; 3a670 (e:6670)
+	cp $40
+	ret nc
+	jp AIUseXDefend
+
+AgathaAI: ; 3a676 (e:6676)
+	cp $14
+	jp c,AISwitchIfEnoughMons
+	cp $80
+	ret nc
+	ld a,4
+	call AICheckIfHPBelowFraction
+	ret nc
+	jp AIUseSuperPotion
+
+LanceAI: ; 3a687 (e:6687)
+	cp $80
+	ret nc
+	ld a,5
+	call AICheckIfHPBelowFraction
+	ret nc
+	jp AIUseHyperPotion
+
+GenericAI: ; 3a693 (e:6693)
+	and a ; clear carry
+	ret
+
+; end of individual trainer AI routines
+
+DecrementAICount: ; 3a695 (e:6695)
+	ld hl,wAICount
+	dec [hl]
+	scf
+	ret
+
+Func_3a69b: ; 3a69b (e:669b)
+	ld a,(SFX_08_3e - SFX_Headers_08) / 3
+	jp PlaySoundWaitForCurrent
+
+AIUseFullRestore: ; 3a6a0 (e:66a0)
+	call AICureStatus
+	ld a,FULL_RESTORE
+	ld [wcf05],a
+	ld de,wHPBarOldHP
+	ld hl,wEnemyMonHP + 1
+	ld a,[hld]
+	ld [de],a
+	inc de
+	ld a,[hl]
+	ld [de],a
+	inc de
+	ld hl,wEnemyMonMaxHP + 1
+	ld a,[hld]
+	ld [de],a
+	inc de
+	ld [wHPBarMaxHP],a
+	ld [wEnemyMonHP + 1],a
+	ld a,[hl]
+	ld [de],a
+	ld [wHPBarMaxHP+1],a
+	ld [wEnemyMonHP],a
+	jr AIPrintItemUseAndUpdateHPBar
+
+AIUsePotion: ; 3a6ca (e:66ca)
+; enemy trainer heals his monster with a potion
+	ld a,POTION
+	ld b,20
+	jr AIRecoverHP
+
+AIUseSuperPotion: ; 3a6d0 (e:66d0)
+; enemy trainer heals his monster with a super potion
+	ld a,SUPER_POTION
+	ld b,50
+	jr AIRecoverHP
+
+AIUseHyperPotion: ; 3a6d6 (e:66d6)
+; enemy trainer heals his monster with a hyper potion
+	ld a,HYPER_POTION
+	ld b,200
+	; fallthrough
+
+AIRecoverHP: ; 3a6da (e:66da)
+; heal b HP and print "trainer used $(a) on pokemon!"
+	ld [wcf05],a
+	ld hl,wEnemyMonHP + 1
+	ld a,[hl]
+	ld [wHPBarOldHP],a
+	add b
+	ld [hld],a
+	ld [wHPBarNewHP],a
+	ld a,[hl]
+	ld [wHPBarOldHP+1],a
+	ld [wHPBarNewHP+1],a
+	jr nc,.next
+	inc a
+	ld [hl],a
+	ld [wHPBarNewHP+1],a
+.next
+	inc hl
+	ld a,[hld]
+	ld b,a
+	ld de,wEnemyMonMaxHP + 1
+	ld a,[de]
+	dec de
+	ld [wHPBarMaxHP],a
+	sub b
+	ld a,[hli]
+	ld b,a
+	ld a,[de]
+	ld [wHPBarMaxHP+1],a
+	sbc b
+	jr nc,AIPrintItemUseAndUpdateHPBar
+	inc de
+	ld a,[de]
+	dec de
+	ld [hld],a
+	ld [wHPBarNewHP],a
+	ld a,[de]
+	ld [hl],a
+	ld [wHPBarNewHP+1],a
+	; fallthrough
+
+AIPrintItemUseAndUpdateHPBar: ; 3a718 (e:6718)
+	call AIPrintItemUse_
+	hlCoord 2, 2
+	xor a
+	ld [wHPBarType],a
+	predef UpdateHPBar2
+	jp DecrementAICount
+
+AISwitchIfEnoughMons: ; 3a72a (e:672a)
+; enemy trainer switches if there are 3 or more unfainted mons in party
+	ld a,[wEnemyPartyCount]
+	ld c,a
+	ld hl,wEnemyMon1HP
+
+	ld d,0 ; keep count of unfainted monsters
+
+	; count how many monsters haven't fainted yet
+.loop
+	ld a,[hli]
+	ld b,a
+	ld a,[hld]
+	or b
+	jr z,.Fainted ; has monster fainted?
+	inc d
+.Fainted
+	push bc
+	ld bc,$2C
+	add hl,bc
+	pop bc
+	dec c
+	jr nz,.loop
+
+	ld a,d ; how many available monsters are there?
+	cp 2 ; don't bother if only 1 or 2
+	jp nc,SwitchEnemyMon
+	and a
+	ret
+
+SwitchEnemyMon: ; 3a74b (e:674b)
+
+; prepare to withdraw the active monster: copy hp, number, and status to roster
+
+	ld a,[wEnemyMonPartyPos]
+	ld hl,wEnemyMon1HP
+	ld bc,wEnemyMon2 - wEnemyMon1
+	call AddNTimes
+	ld d,h
+	ld e,l
+	ld hl,wEnemyMonHP
+	ld bc,4
+	call CopyData
+
+	ld hl, AIBattleWithdrawText
+	call PrintText
+
+	ld a,1
+	ld [wd11d],a
+	callab EnemySendOut
+	xor a
+	ld [wd11d],a
+
+	ld a,[wLinkState]
+	cp LINK_STATE_BATTLING
+	ret z
+	scf
+	ret
+
+AIBattleWithdrawText: ; 3a781 (e:6781)
+	TX_FAR _AIBattleWithdrawText
+	db "@"
+
+AIUseFullHeal: ; 3a786 (e:6786)
+	call Func_3a69b
+	call AICureStatus
+	ld a,FULL_HEAL
+	jp AIPrintItemUse
+
+AICureStatus: ; 3a791 (e:6791)
+; cures the status of enemy's active pokemon
+	ld a,[wEnemyMonPartyPos]
+	ld hl,wEnemyMon1Status
+	ld bc,wEnemyMon2 - wEnemyMon1
+	call AddNTimes
+	xor a
+	ld [hl],a ; clear status in enemy team roster
+	ld [wEnemyMonStatus],a ; clear status of active enemy
+	ld hl,W_ENEMYBATTSTATUS3
+	res 0,[hl]
+	ret
+
+AIUseXAccuracy: ; 0x3a7a8 unused
+	call Func_3a69b
+	ld hl,W_ENEMYBATTSTATUS2
+	set 0,[hl]
+	ld a,X_ACCURACY
+	jp AIPrintItemUse
+
+AIUseGuardSpec: ; 3a7b5 (e:67b5)
+	call Func_3a69b
+	ld hl,W_ENEMYBATTSTATUS2
+	set 1,[hl]
+	ld a,GUARD_SPEC_
+	jp AIPrintItemUse
+
+AIUseDireHit: ; 0x3a7c2 unused
+	call Func_3a69b
+	ld hl,W_ENEMYBATTSTATUS2
+	set 2,[hl]
+	ld a,DIRE_HIT
+	jp AIPrintItemUse
+
+AICheckIfHPBelowFraction: ; 3a7cf (e:67cf)
+; return carry if enemy trainer's current HP is below 1 / a of the maximum
+	ld [H_DIVISOR],a
+	ld hl,wEnemyMonMaxHP
+	ld a,[hli]
+	ld [H_DIVIDEND],a
+	ld a,[hl]
+	ld [H_DIVIDEND + 1],a
+	ld b,2
+	call Divide
+	ld a,[H_QUOTIENT + 3]
+	ld c,a
+	ld a,[H_QUOTIENT + 2]
+	ld b,a
+	ld hl,wEnemyMonHP + 1
+	ld a,[hld]
+	ld e,a
+	ld a,[hl]
+	ld d,a
+	ld a,d
+	sub b
+	ret nz
+	ld a,e
+	sub c
+	ret
+
+AIUseXAttack: ; 3a7f2 (e:67f2)
+	ld b,$A
+	ld a,X_ATTACK
+	jr AIIncreaseStat
+
+AIUseXDefend: ; 3a7f8 (e:67f8)
+	ld b,$B
+	ld a,X_DEFEND
+	jr AIIncreaseStat
+
+AIUseXSpeed: ; 3a7fe (e:67fe)
+	ld b,$C
+	ld a,X_SPEED
+	jr AIIncreaseStat
+
+AIUseXSpecial: ; 3a804 (e:6804)
+	ld b,$D
+	ld a,X_SPECIAL
+	; fallthrough
+
+AIIncreaseStat: ; 3a808 (e:6808)
+	ld [wcf05],a
+	push bc
+	call AIPrintItemUse_
+	pop bc
+	ld hl,W_ENEMYMOVEEFFECT
+	ld a,[hld]
+	push af
+	ld a,[hl]
+	push af
+	push hl
+	ld a,$AF
+	ld [hli],a
+	ld [hl],b
+	callab StatModifierUpEffect
+	pop hl
+	pop af
+	ld [hli],a
+	pop af
+	ld [hl],a
+	jp DecrementAICount
+
+AIPrintItemUse: ; 3a82c (e:682c)
+	ld [wcf05],a
+	call AIPrintItemUse_
+	jp DecrementAICount
+
+AIPrintItemUse_: ; 3a835 (e:6835)
+; print "x used [wcf05] on z!"
+	ld a,[wcf05]
+	ld [wd11e],a
+	call GetItemName
+	ld hl, AIBattleUseItemText
+	jp PrintText
+
+AIBattleUseItemText: ; 3a844 (e:6844)
+	TX_FAR _AIBattleUseItemText
+	db "@"
--- a/engine/battle/trainer_party_ai_misc.asm
+++ /dev/null
@@ -1,1263 +1,0 @@
-; creates a set of moves that may be used and returns its address in hl
-; unused slots are filled with 0, all used slots may be chosen with equal probability
-AIEnemyTrainerChooseMoves: ; 39719 (e:5719)
-	ld a, $a
-	ld hl, wHPBarMaxHP  ; init temporary move selection array. Only the moves with the lowest numbers are chosen in the end
-	ld [hli], a   ; move 1
-	ld [hli], a   ; move 2
-	ld [hli], a   ; move 3
-	ld [hl], a    ; move 4
-	ld a, [W_ENEMYDISABLEDMOVE] ; forbid disabled move (if any)
-	swap a
-	and $f
-	jr z, .noMoveDisabled
-	ld hl, wHPBarMaxHP
-	dec a
-	ld c, a
-	ld b, $0
-	add hl, bc    ; advance pointer to forbidden move
-	ld [hl], $50  ; forbid (highly discourage) disabled move
-.noMoveDisabled
-	ld hl, TrainerClassMoveChoiceModifications ; 589B
-	ld a, [W_TRAINERCLASS]
-	ld b, a
-.loopTrainerClasses
-	dec b
-	jr z, .readTrainerClassData
-.loopTrainerClassData
-	ld a, [hli]
-	and a
-	jr nz, .loopTrainerClassData
-	jr .loopTrainerClasses
-.readTrainerClassData
-	ld a, [hl]
-	and a
-	jp z, .useOriginalMoveSet
-	push hl
-.nextMoveChoiceModification
-	pop hl
-	ld a, [hli]
-	and a
-	jr z, .loopFindMinimumEntries
-	push hl
-	ld hl, AIMoveChoiceModificationFunctionPointers ; $57a3
-	dec a
-	add a
-	ld c, a
-	ld b, $0
-	add hl, bc    ; skip to pointer
-	ld a, [hli]   ; read pointer into hl
-	ld h, [hl]
-	ld l, a
-	ld de, .nextMoveChoiceModification  ; set return address
-	push de
-	jp [hl]       ; execute modification function
-.loopFindMinimumEntries ; all entries will be decremented sequentially until one of them is zero
-	ld hl, wHPBarMaxHP  ; temp move selection array
-	ld de, wEnemyMonMoves  ; enemy moves
-	ld c, $4
-.loopDecrementEntries
-	ld a, [de]
-	inc de
-	and a
-	jr z, .loopFindMinimumEntries
-	dec [hl]
-	jr z, .minimumEntriesFound
-	inc hl
-	dec c
-	jr z, .loopFindMinimumEntries
-	jr .loopDecrementEntries
-.minimumEntriesFound
-	ld a, c
-.loopUndoPartialIteration ; undo last (partial) loop iteration
-	inc [hl]
-	dec hl
-	inc a
-	cp $5
-	jr nz, .loopUndoPartialIteration
-	ld hl, wHPBarMaxHP  ; temp move selection array
-	ld de, wEnemyMonMoves  ; enemy moves
-	ld c, $4
-.filterMinimalEntries ; all minimal entries now have value 1. All other slots will be disabled (move set to 0)
-	ld a, [de]
-	and a
-	jr nz, .moveExisting ; 0x3978a $1
-	ld [hl], a
-.moveExisting
-	ld a, [hl]
-	dec a
-	jr z, .slotWithMinimalValue
-	xor a
-	ld [hli], a     ; disable move slot
-	jr .next
-.slotWithMinimalValue
-	ld a, [de]
-	ld [hli], a     ; enable move slot
-.next
-	inc de
-	dec c
-	jr nz, .filterMinimalEntries
-	ld hl, wHPBarMaxHP    ; use created temporary array as move set
-	ret
-.useOriginalMoveSet
-	ld hl, wEnemyMonMoves    ; use original move set
-	ret
-
-AIMoveChoiceModificationFunctionPointers: ; 397a3 (e:57a3)
-	dw AIMoveChoiceModification1
-	dw AIMoveChoiceModification2
-	dw AIMoveChoiceModification3
-	dw AIMoveChoiceModification4 ; unused, does nothing
-
-; discourages moves that cause no damage but only a status ailment if player's mon already has one
-AIMoveChoiceModification1: ; 397ab (e:57ab)
-	ld a, [wBattleMonStatus]
-	and a
-	ret z ; return if no status ailment on player's mon
-	ld hl, wBuffer - 1 ; temp move selection array (-1 byte offest)
-	ld de, wEnemyMonMoves ; enemy moves
-	ld b, NUM_MOVES + 1
-.nextMove
-	dec b
-	ret z ; processed all 4 moves
-	inc hl
-	ld a, [de]
-	and a
-	ret z ; no more moves in move set
-	inc de
-	call ReadMove
-	ld a, [W_ENEMYMOVEPOWER]
-	and a
-	jr nz, .nextMove
-	ld a, [W_ENEMYMOVEEFFECT]
-	push hl
-	push de
-	push bc
-	ld hl, StatusAilmentMoveEffects
-	ld de, $0001
-	call IsInArray
-	pop bc
-	pop de
-	pop hl
-	jr nc, .nextMove
-	ld a, [hl]
-	add $5 ; heavily discourage move
-	ld [hl], a
-	jr .nextMove
-
-StatusAilmentMoveEffects ; 57e2
-	db $01 ; unused sleep effect
-	db SLEEP_EFFECT
-	db POISON_EFFECT
-	db PARALYZE_EFFECT
-	db $FF
-
-; slightly encourage moves with specific effects.
-; in particular, stat-modifying moves and other move effects
-; that fall in-bewteen
-AIMoveChoiceModification2: ; 397e7 (e:57e7)
-	ld a, [wAILayer2Encouragement]
-	cp $1 
-	ret nz
-	ld hl, wBuffer - 1 ; temp move selection array (-1 byte offset)
-	ld de, wEnemyMonMoves ; enemy moves
-	ld b, NUM_MOVES + 1
-.nextMove
-	dec b
-	ret z ; processed all 4 moves
-	inc hl
-	ld a, [de]
-	and a
-	ret z ; no more moves in move set
-	inc de
-	call ReadMove
-	ld a, [W_ENEMYMOVEEFFECT]
-	cp ATTACK_UP1_EFFECT
-	jr c, .nextMove
-	cp BIDE_EFFECT
-	jr c, .preferMove
-	cp ATTACK_UP2_EFFECT
-	jr c, .nextMove
-	cp POISON_EFFECT
-	jr c, .preferMove
-	jr .nextMove
-.preferMove
-	dec [hl] ; sligthly encourage this move
-	jr .nextMove
-
-; encourages moves that are effective against the player's mon (even if non-damaging).
-; discourage damaging moves that are ineffective or not very effective against the player's mon,
-; unless there's no damaging move that deals at least neutral damage
-AIMoveChoiceModification3: ; 39817 (e:5817)
-	ld hl, wBuffer - 1 ; temp move selection array (-1 byte offset)
-	ld de, wEnemyMonMoves ; enemy moves
-	ld b, $5
-.nextMove
-	dec b
-	ret z ; processed all 4 moves
-	inc hl
-	ld a, [de]
-	and a
-	ret z ; no more moves in move set
-	inc de
-	call ReadMove
-	push hl
-	push bc
-	push de
-	callab AIGetTypeEffectiveness
-	pop de
-	pop bc
-	pop hl
-	ld a, [wd11e]
-	cp $10
-	jr z, .nextMove
-	jr c, .notEffectiveMove
-	dec [hl] ; sligthly encourage this move
-	jr .nextMove
-.notEffectiveMove ; discourages non-effective moves if better moves are available
-	push hl
-	push de
-	push bc
-	ld a, [W_ENEMYMOVETYPE]
-	ld d, a
-	ld hl, wEnemyMonMoves  ; enemy moves
-	ld b, NUM_MOVES + 1
-	ld c, $0
-.loopMoves
-	dec b
-	jr z, .done
-	ld a, [hli]
-	and a
-	jr z, .done
-	call ReadMove
-	ld a, [W_ENEMYMOVEEFFECT]
-	cp SUPER_FANG_EFFECT
-	jr z, .betterMoveFound ; Super Fang is considered to be a better move
-	cp SPECIAL_DAMAGE_EFFECT
-	jr z, .betterMoveFound ; any special damage moves are considered to be better moves
-	cp FLY_EFFECT
-	jr z, .betterMoveFound ; Fly is considered to be a better move
-	ld a, [W_ENEMYMOVETYPE]
-	cp d
-	jr z, .loopMoves
-	ld a, [W_ENEMYMOVEPOWER]
-	and a
-	jr nz, .betterMoveFound ; damaging moves of a different type are considered to be better moves
-	jr .loopMoves
-.betterMoveFound
-	ld c, a
-.done
-	ld a, c
-	pop bc
-	pop de
-	pop hl
-	and a
-	jr z, .nextMove
-	inc [hl] ; sligthly discourage this move
-	jr .nextMove
-AIMoveChoiceModification4: ; 39883 (e:5883)
-	ret
-
-ReadMove: ; 39884 (e:5884)
-	push hl
-	push de
-	push bc
-	dec a
-	ld hl,Moves
-	ld bc,6
-	call AddNTimes
-	ld de,W_ENEMYMOVENUM
-	call CopyData
-	pop bc
-	pop de
-	pop hl
-	ret
-
-; move choice modification methods that are applied for each trainer class
-; 0 is sentinel value
-TrainerClassMoveChoiceModifications: ; 3989b (e:589b)
-	db 0      ; YOUNGSTER
-	db 1,0    ; BUG CATCHER
-	db 1,0    ; LASS
-	db 1,3,0  ; SAILOR
-	db 1,0    ; JR__TRAINER_M
-	db 1,0    ; JR__TRAINER_F
-	db 1,2,3,0; POKEMANIAC
-	db 1,2,0  ; SUPER_NERD
-	db 1,0    ; HIKER
-	db 1,0    ; BIKER
-	db 1,3,0  ; BURGLAR
-	db 1,0    ; ENGINEER
-	db 1,2,0  ; JUGGLER_X
-	db 1,3,0  ; FISHER
-	db 1,3,0  ; SWIMMER
-	db 0      ; CUE_BALL
-	db 1,0    ; GAMBLER
-	db 1,3,0  ; BEAUTY
-	db 1,2,0  ; PSYCHIC_TR
-	db 1,3,0  ; ROCKER
-	db 1,0    ; JUGGLER
-	db 1,0    ; TAMER
-	db 1,0    ; BIRD_KEEPER
-	db 1,0    ; BLACKBELT
-	db 1,0    ; SONY1
-	db 1,3,0  ; PROF_OAK
-	db 1,2,0  ; CHIEF
-	db 1,2,0  ; SCIENTIST
-	db 1,3,0  ; GIOVANNI
-	db 1,0    ; ROCKET
-	db 1,3,0  ; COOLTRAINER_M
-	db 1,3,0  ; COOLTRAINER_F
-	db 1,0    ; BRUNO
-	db 1,0    ; BROCK
-	db 1,3,0  ; MISTY
-	db 1,3,0  ; LT__SURGE
-	db 1,3,0  ; ERIKA
-	db 1,3,0  ; KOGA
-	db 1,3,0  ; BLAINE
-	db 1,3,0  ; SABRINA
-	db 1,2,0  ; GENTLEMAN
-	db 1,3,0  ; SONY2
-	db 1,3,0  ; SONY3
-	db 1,2,3,0; LORELEI
-	db 1,0    ; CHANNELER
-	db 1,0    ; AGATHA
-	db 1,3,0  ; LANCE
-
-TrainerPicAndMoneyPointers: ; 39914 (e:5914)
-; trainer pic pointers and base money.
-; money received after battle = base money × level of highest-level enemy mon
-	dw YoungsterPic
-	money 1500
-
-	dw BugCatcherPic
-	money 1000
-
-	dw LassPic
-	money 1500
-
-	dw SailorPic
-	money 3000
-
-	dw JrTrainerMPic
-	money 2000
-
-	dw JrTrainerFPic
-	money 2000
-
-	dw PokemaniacPic
-	money 5000
-
-	dw SuperNerdPic
-	money 2500
-
-	dw HikerPic
-	money 3500
-
-	dw BikerPic
-	money 2000
-
-	dw BurglarPic
-	money 9000
-
-	dw EngineerPic
-	money 5000
-
-	dw JugglerPic
-	money 3500
-
-	dw FisherPic
-	money 3500
-
-	dw SwimmerPic
-	money 500
-
-	dw CueBallPic
-	money 2500
-
-	dw GamblerPic
-	money 7000
-
-	dw BeautyPic
-	money 7000
-
-	dw PsychicPic
-	money 1000
-
-	dw RockerPic
-	money 2500
-
-	dw JugglerPic
-	money 3500
-
-	dw TamerPic
-	money 4000
-
-	dw BirdKeeperPic
-	money 2500
-
-	dw BlackbeltPic
-	money 2500
-
-	dw Rival1Pic
-	money 3500
-
-	dw ProfOakPic
-	money 9900
-
-	dw ChiefPic
-	money 3000
-
-	dw ScientistPic
-	money 5000
-
-	dw GiovanniPic
-	money 9900
-
-	dw RocketPic
-	money 3000
-
-	dw CooltrainerMPic
-	money 3500
-
-	dw CooltrainerFPic
-	money 3500
-
-	dw BrunoPic
-	money 9900
-
-	dw BrockPic
-	money 9900
-
-	dw MistyPic
-	money 9900
-
-	dw LtSurgePic
-	money 9900
-
-	dw ErikaPic
-	money 9900
-
-	dw KogaPic
-	money 9900
-
-	dw BlainePic
-	money 9900
-
-	dw SabrinaPic
-	money 9900
-
-	dw GentlemanPic
-	money 7000
-
-	dw Rival2Pic
-	money 6500
-
-	dw Rival3Pic
-	money 9900
-
-	dw LoreleiPic
-	money 9900
-
-	dw ChannelerPic
-	money 3000
-
-	dw AgathaPic
-	money 9900
-
-	dw LancePic
-	money 9900
-
-INCLUDE "text/trainer_names.asm"
-
-; formats a string at wMovesString that lists the moves at wMoves
-FormatMovesString: ; 39b87 (e:5b87)
-	ld hl, wMoves
-	ld de, wMovesString
-	ld b, $0
-.printMoveNameLoop
-	ld a, [hli]
-	and a ; end of move list?
-	jr z, .printDashLoop ; print dashes when no moves are left
-	push hl
-	ld [wd0b5], a
-	ld a, BANK(MoveNames)
-	ld [wPredefBank], a
-	ld a, MOVE_NAME
-	ld [wNameListType], a
-	call GetName
-	ld hl, wcd6d
-.copyNameLoop
-	ld a, [hli]
-	cp $50
-	jr z, .doneCopyingName
-	ld [de], a
-	inc de
-	jr .copyNameLoop
-.doneCopyingName
-	ld a, b
-	ld [wcd6c], a
-	inc b
-	ld a, $4e ; line break
-	ld [de], a
-	inc de
-	pop hl
-	ld a, b
-	cp NUM_MOVES
-	jr z, .done
-	jr .printMoveNameLoop
-.printDashLoop
-	ld a, "-"
-	ld [de], a
-	inc de
-	inc b
-	ld a, b
-	cp NUM_MOVES
-	jr z, .done
-	ld a, $4e ; line break
-	ld [de], a
-	inc de
-	jr .printDashLoop
-.done
-	ld a, "@"
-	ld [de], a
-	ret
-
-; XXX this is called in a few places, but it doesn't appear to do anything useful
-Func_39bd5: ; 39bd5 (e:5bd5)
-	ld a, [wd11b]
-	cp $1
-	jr nz, .asm_39be6
-	ld hl, wEnemyPartyCount
-	ld de, wEnemyMonOT
-	ld a, ENEMYOT_NAME
-	jr .asm_39c18
-.asm_39be6
-	cp $4
-	jr nz, .calcAttackStat4
-	ld hl, wPartyCount
-	ld de, wPartyMonOT
-	ld a, PLAYEROT_NAME
-	jr .asm_39c18
-.calcAttackStat4
-	cp $5
-	jr nz, .asm_39c02
-	ld hl, wStringBuffer2 + 11
-	ld de, MonsterNames
-	ld a, MONSTER_NAME
-	jr .asm_39c18
-.asm_39c02
-	cp $2
-	jr nz, .asm_39c10
-	ld hl, wNumBagItems
-	ld de, ItemNames
-	ld a, ITEM_NAME
-	jr .asm_39c18
-.asm_39c10
-	ld hl, wStringBuffer2 + 11
-	ld de, ItemNames
-	ld a, ITEM_NAME
-.asm_39c18
-	ld [wNameListType], a
-	ld a, l
-	ld [wList], a
-	ld a, h
-	ld [wList + 1], a
-	ld a, e
-	ld [wcf8d], a
-	ld a, d
-	ld [wcf8e], a
-	ld bc, ItemPrices
-	ld a, c
-	ld [wItemPrices], a
-	ld a, b
-	ld [wItemPrices + 1], a
-	ret
-
-; get species of mon e in list [wcc49] for LoadMonData
-GetMonSpecies: ; 39c37 (e:5c37)
-	ld hl, wPartySpecies
-	ld a, [wcc49]
-	and a
-	jr z, .getSpecies
-	dec a
-	jr z, .enemyParty
-	ld hl, wBoxSpecies
-	jr .getSpecies
-.enemyParty
-	ld hl, wEnemyPartyMons
-.getSpecies
-	ld d, 0
-	add hl, de
-	ld a, [hl]
-	ld [wcf91], a
-	ret
-
-ReadTrainer: ; 39c53 (e:5c53)
-
-; don't change any moves in a link battle
-	ld a,[wLinkState]
-	and a
-	ret nz
-
-; set [wEnemyPartyCount] to 0, [wEnemyPartyMons] to FF
-; XXX first is total enemy pokemon?
-; XXX second is species of first pokemon?
-	ld hl,wEnemyPartyCount
-	xor a
-	ld [hli],a
-	dec a
-	ld [hl],a
-
-; get the pointer to trainer data for this class
-	ld a,[W_CUROPPONENT]
-	sub $C9 ; convert value from pokemon to trainer
-	add a,a
-	ld hl,TrainerDataPointers
-	ld c,a
-	ld b,0
-	add hl,bc ; hl points to trainer class
-	ld a,[hli]
-	ld h,[hl]
-	ld l,a
-	ld a,[W_TRAINERNO]
-	ld b,a
-; At this point b contains the trainer number,
-; and hl points to the trainer class.
-; Our next task is to iterate through the trainers,
-; decrementing b each time, until we get to the right one.
-.outer
-	dec b
-	jr z,.IterateTrainer
-.inner
-	ld a,[hli]
-	and a
-	jr nz,.inner
-	jr .outer
-
-; if the first byte of trainer data is FF,
-; - each pokemon has a specific level
-;      (as opposed to the whole team being of the same level)
-; - if [W_LONEATTACKNO] != 0, one pokemon on the team has a special move
-; else the first byte is the level of every pokemon on the team
-.IterateTrainer
-	ld a,[hli]
-	cp $FF ; is the trainer special?
-	jr z,.SpecialTrainer ; if so, check for special moves
-	ld [W_CURENEMYLVL],a
-.LoopTrainerData
-	ld a,[hli]
-	and a ; have we reached the end of the trainer data?
-	jr z,.FinishUp
-	ld [wcf91],a ; write species somewhere (XXX why?)
-	ld a,1
-	ld [wcc49],a
-	push hl
-	call AddPartyMon
-	pop hl
-	jr .LoopTrainerData
-.SpecialTrainer
-; if this code is being run:
-; - each pokemon has a specific level
-;      (as opposed to the whole team being of the same level)
-; - if [W_LONEATTACKNO] != 0, one pokemon on the team has a special move
-	ld a,[hli]
-	and a ; have we reached the end of the trainer data?
-	jr z,.AddLoneMove
-	ld [W_CURENEMYLVL],a
-	ld a,[hli]
-	ld [wcf91],a
-	ld a,1
-	ld [wcc49],a
-	push hl
-	call AddPartyMon
-	pop hl
-	jr .SpecialTrainer
-.AddLoneMove
-; does the trainer have a single monster with a different move
-	ld a,[W_LONEATTACKNO] ; Brock is 01, Misty is 02, Erika is 04, etc
-	and a
-	jr z,.AddTeamMove
-	dec a
-	add a,a
-	ld c,a
-	ld b,0
-	ld hl,LoneMoves
-	add hl,bc
-	ld a,[hli]
-	ld d,[hl]
-	ld hl,wEnemyMon1Moves + 2
-	ld bc,wEnemyMon2 - wEnemyMon1
-	call AddNTimes
-	ld [hl],d
-	jr .FinishUp
-.AddTeamMove
-; check if our trainer's team has special moves
-
-; get trainer class number
-	ld a,[W_CUROPPONENT]
-	sub $C8
-	ld b,a
-	ld hl,TeamMoves
-
-; iterate through entries in TeamMoves, checking each for our trainer class
-.IterateTeamMoves
-	ld a,[hli]
-	cp b
-	jr z,.GiveTeamMoves ; is there a match?
-	inc hl ; if not, go to the next entry
-	inc a
-	jr nz,.IterateTeamMoves
-
-	; no matches found. is this trainer champion rival?
-	ld a,b
-	cp SONY3
-	jr z,.ChampionRival
-	jr .FinishUp ; nope
-.GiveTeamMoves
-	ld a,[hl]
-	ld [wEnemyMon5Moves + 2],a
-	jr .FinishUp
-.ChampionRival ; give moves to his team
-
-; pidgeot
-	ld a,SKY_ATTACK
-	ld [wEnemyMon1Moves + 2],a
-
-; starter
-	ld a,[W_RIVALSTARTER]
-	cp STARTER3
-	ld b,MEGA_DRAIN
-	jr z,.GiveStarterMove
-	cp STARTER1
-	ld b,FIRE_BLAST
-	jr z,.GiveStarterMove
-	ld b,BLIZZARD ; must be squirtle
-.GiveStarterMove
-	ld a,b
-	ld [wEnemyMon6Moves + 2],a
-.FinishUp ; XXX this needs documenting
-	xor a       ; clear D079-D07B
-	ld de,wd079
-	ld [de],a
-	inc de
-	ld [de],a
-	inc de
-	ld [de],a
-	ld a,[W_CURENEMYLVL]
-	ld b,a
-.LastLoop
-	ld hl,wd047
-	ld c,2
-	push bc
-	predef AddBCDPredef
-	pop bc
-	inc de
-	inc de
-	dec b
-	jr nz,.LastLoop
-	ret
-
-INCLUDE "data/trainer_moves.asm"
-
-INCLUDE "data/trainer_parties.asm"
-
-TrainerAI: ; 3a52e (e:652e)
-;XXX called at 34964, 3c342, 3c398
-	and a
-	ld a,[W_ISINBATTLE]
-	dec a
-	ret z ; if not a trainer, we're done here
-	ld a,[wLinkState]
-	cp LINK_STATE_BATTLING
-	ret z
-	ld a,[W_TRAINERCLASS] ; what trainer class is this?
-	dec a
-	ld c,a
-	ld b,0
-	ld hl,TrainerAIPointers
-	add hl,bc
-	add hl,bc
-	add hl,bc
-	ld a,[wAICount]
-	and a
-	ret z ; if no AI uses left, we're done here
-	inc hl
-	inc a
-	jr nz,.getpointer
-	dec hl
-	ld a,[hli]
-	ld [wAICount],a
-.getpointer
-	ld a,[hli]
-	ld h,[hl]
-	ld l,a
-	call Random
-	jp [hl]
-
-TrainerAIPointers: ; 3a55c (e:655c)
-; 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
-	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 ; juggler_x
-	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
-	dbw 3,GenericAI
-	dbw 1,GenericAI ; chief
-	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,Sony2AI ; sony2
-	dbw 1,Sony3AI ; sony3
-	dbw 2,LoreleiAI ; lorelei
-	dbw 3,GenericAI
-	dbw 2,AgathaAI ; agatha
-	dbw 1,LanceAI ; lance
-
-JugglerAI: ; 3a5e9 (e:65e9)
-	cp $40
-	ret nc
-	jp AISwitchIfEnoughMons
-
-BlackbeltAI: ; 3a5ef (e:65ef)
-	cp $20
-	ret nc
-	jp AIUseXAttack
-
-GiovanniAI: ; 3a5f5 (e:65f5)
-	cp $40
-	ret nc
-	jp AIUseGuardSpec
-
-CooltrainerMAI: ; 3a5fb (e:65fb)
-	cp $40
-	ret nc
-	jp AIUseXAttack
-
-CooltrainerFAI: ; 3a601 (e:6601)
-	cp $40
-	ld a,$A
-	call AICheckIfHPBelowFraction
-	jp c,AIUseHyperPotion
-	ld a,5
-	call AICheckIfHPBelowFraction
-	ret nc
-	jp AISwitchIfEnoughMons
-
-BrockAI: ; 3a614 (e:6614)
-; if his active monster has a status condition, use a full heal
-	ld a,[wEnemyMonStatus]
-	and a
-	ret z
-	jp AIUseFullHeal
-
-MistyAI: ; 3a61c (e:661c)
-	cp $40
-	ret nc
-	jp AIUseXDefend
-
-LtSurgeAI: ; 3a622 (e:6622)
-	cp $40
-	ret nc
-	jp AIUseXSpeed
-
-ErikaAI: ; 3a628 (e:6628)
-	cp $80
-	ret nc
-	ld a,$A
-	call AICheckIfHPBelowFraction
-	ret nc
-	jp AIUseSuperPotion
-
-KogaAI: ; 3a634 (e:6634)
-	cp $40
-	ret nc
-	jp AIUseXAttack
-
-BlaineAI: ; 3a63a (e:663a)
-	cp $40
-	ret nc
-	jp AIUseSuperPotion
-
-SabrinaAI: ; 3a640 (e:6640)
-	cp $40
-	ret nc
-	ld a,$A
-	call AICheckIfHPBelowFraction
-	ret nc
-	jp AIUseHyperPotion
-
-Sony2AI: ; 3a64c (e:664c)
-	cp $20
-	ret nc
-	ld a,5
-	call AICheckIfHPBelowFraction
-	ret nc
-	jp AIUsePotion
-
-Sony3AI: ; 3a658 (e:6658)
-	cp $20
-	ret nc
-	ld a,5
-	call AICheckIfHPBelowFraction
-	ret nc
-	jp AIUseFullRestore
-
-LoreleiAI: ; 3a664 (e:6664)
-	cp $80
-	ret nc
-	ld a,5
-	call AICheckIfHPBelowFraction
-	ret nc
-	jp AIUseSuperPotion
-
-BrunoAI: ; 3a670 (e:6670)
-	cp $40
-	ret nc
-	jp AIUseXDefend
-
-AgathaAI: ; 3a676 (e:6676)
-	cp $14
-	jp c,AISwitchIfEnoughMons
-	cp $80
-	ret nc
-	ld a,4
-	call AICheckIfHPBelowFraction
-	ret nc
-	jp AIUseSuperPotion
-
-LanceAI: ; 3a687 (e:6687)
-	cp $80
-	ret nc
-	ld a,5
-	call AICheckIfHPBelowFraction
-	ret nc
-	jp AIUseHyperPotion
-
-GenericAI: ; 3a693 (e:6693)
-	and a ; clear carry
-	ret
-
-; end of individual trainer AI routines
-
-DecrementAICount: ; 3a695 (e:6695)
-	ld hl,wAICount
-	dec [hl]
-	scf
-	ret
-
-Func_3a69b: ; 3a69b (e:669b)
-	ld a,(SFX_08_3e - SFX_Headers_08) / 3
-	jp PlaySoundWaitForCurrent
-
-AIUseFullRestore: ; 3a6a0 (e:66a0)
-	call AICureStatus
-	ld a,FULL_RESTORE
-	ld [wcf05],a
-	ld de,wHPBarOldHP
-	ld hl,wEnemyMonHP + 1
-	ld a,[hld]
-	ld [de],a
-	inc de
-	ld a,[hl]
-	ld [de],a
-	inc de
-	ld hl,wEnemyMonMaxHP + 1
-	ld a,[hld]
-	ld [de],a
-	inc de
-	ld [wHPBarMaxHP],a
-	ld [wEnemyMonHP + 1],a
-	ld a,[hl]
-	ld [de],a
-	ld [wHPBarMaxHP+1],a
-	ld [wEnemyMonHP],a
-	jr AIPrintItemUseAndUpdateHPBar
-
-AIUsePotion: ; 3a6ca (e:66ca)
-; enemy trainer heals his monster with a potion
-	ld a,POTION
-	ld b,20
-	jr AIRecoverHP
-
-AIUseSuperPotion: ; 3a6d0 (e:66d0)
-; enemy trainer heals his monster with a super potion
-	ld a,SUPER_POTION
-	ld b,50
-	jr AIRecoverHP
-
-AIUseHyperPotion: ; 3a6d6 (e:66d6)
-; enemy trainer heals his monster with a hyper potion
-	ld a,HYPER_POTION
-	ld b,200
-	; fallthrough
-
-AIRecoverHP: ; 3a6da (e:66da)
-; heal b HP and print "trainer used $(a) on pokemon!"
-	ld [wcf05],a
-	ld hl,wEnemyMonHP + 1
-	ld a,[hl]
-	ld [wHPBarOldHP],a
-	add b
-	ld [hld],a
-	ld [wHPBarNewHP],a
-	ld a,[hl]
-	ld [wHPBarOldHP+1],a
-	ld [wHPBarNewHP+1],a
-	jr nc,.next
-	inc a
-	ld [hl],a
-	ld [wHPBarNewHP+1],a
-.next
-	inc hl
-	ld a,[hld]
-	ld b,a
-	ld de,wEnemyMonMaxHP + 1
-	ld a,[de]
-	dec de
-	ld [wHPBarMaxHP],a
-	sub b
-	ld a,[hli]
-	ld b,a
-	ld a,[de]
-	ld [wHPBarMaxHP+1],a
-	sbc b
-	jr nc,AIPrintItemUseAndUpdateHPBar
-	inc de
-	ld a,[de]
-	dec de
-	ld [hld],a
-	ld [wHPBarNewHP],a
-	ld a,[de]
-	ld [hl],a
-	ld [wHPBarNewHP+1],a
-	; fallthrough
-
-AIPrintItemUseAndUpdateHPBar: ; 3a718 (e:6718)
-	call AIPrintItemUse_
-	hlCoord 2, 2
-	xor a
-	ld [wHPBarType],a
-	predef UpdateHPBar2
-	jp DecrementAICount
-
-AISwitchIfEnoughMons: ; 3a72a (e:672a)
-; enemy trainer switches if there are 3 or more unfainted mons in party
-	ld a,[wEnemyPartyCount]
-	ld c,a
-	ld hl,wEnemyMon1HP
-
-	ld d,0 ; keep count of unfainted monsters
-
-	; count how many monsters haven't fainted yet
-.loop
-	ld a,[hli]
-	ld b,a
-	ld a,[hld]
-	or b
-	jr z,.Fainted ; has monster fainted?
-	inc d
-.Fainted
-	push bc
-	ld bc,$2C
-	add hl,bc
-	pop bc
-	dec c
-	jr nz,.loop
-
-	ld a,d ; how many available monsters are there?
-	cp 2 ; don't bother if only 1 or 2
-	jp nc,SwitchEnemyMon
-	and a
-	ret
-
-SwitchEnemyMon: ; 3a74b (e:674b)
-
-; prepare to withdraw the active monster: copy hp, number, and status to roster
-
-	ld a,[wEnemyMonPartyPos]
-	ld hl,wEnemyMon1HP
-	ld bc,wEnemyMon2 - wEnemyMon1
-	call AddNTimes
-	ld d,h
-	ld e,l
-	ld hl,wEnemyMonHP
-	ld bc,4
-	call CopyData
-
-	ld hl, AIBattleWithdrawText
-	call PrintText
-
-	ld a,1
-	ld [wd11d],a
-	callab EnemySendOut
-	xor a
-	ld [wd11d],a
-
-	ld a,[wLinkState]
-	cp LINK_STATE_BATTLING
-	ret z
-	scf
-	ret
-
-AIBattleWithdrawText: ; 3a781 (e:6781)
-	TX_FAR _AIBattleWithdrawText
-	db "@"
-
-AIUseFullHeal: ; 3a786 (e:6786)
-	call Func_3a69b
-	call AICureStatus
-	ld a,FULL_HEAL
-	jp AIPrintItemUse
-
-AICureStatus: ; 3a791 (e:6791)
-; cures the status of enemy's active pokemon
-	ld a,[wEnemyMonPartyPos]
-	ld hl,wEnemyMon1Status
-	ld bc,wEnemyMon2 - wEnemyMon1
-	call AddNTimes
-	xor a
-	ld [hl],a ; clear status in enemy team roster
-	ld [wEnemyMonStatus],a ; clear status of active enemy
-	ld hl,W_ENEMYBATTSTATUS3
-	res 0,[hl]
-	ret
-
-AIUseXAccuracy: ; 0x3a7a8 unused
-	call Func_3a69b
-	ld hl,W_ENEMYBATTSTATUS2
-	set 0,[hl]
-	ld a,X_ACCURACY
-	jp AIPrintItemUse
-
-AIUseGuardSpec: ; 3a7b5 (e:67b5)
-	call Func_3a69b
-	ld hl,W_ENEMYBATTSTATUS2
-	set 1,[hl]
-	ld a,GUARD_SPEC_
-	jp AIPrintItemUse
-
-AIUseDireHit: ; 0x3a7c2 unused
-	call Func_3a69b
-	ld hl,W_ENEMYBATTSTATUS2
-	set 2,[hl]
-	ld a,DIRE_HIT
-	jp AIPrintItemUse
-
-AICheckIfHPBelowFraction: ; 3a7cf (e:67cf)
-; return carry if enemy trainer's current HP is below 1 / a of the maximum
-	ld [H_DIVISOR],a
-	ld hl,wEnemyMonMaxHP
-	ld a,[hli]
-	ld [H_DIVIDEND],a
-	ld a,[hl]
-	ld [H_DIVIDEND + 1],a
-	ld b,2
-	call Divide
-	ld a,[H_QUOTIENT + 3]
-	ld c,a
-	ld a,[H_QUOTIENT + 2]
-	ld b,a
-	ld hl,wEnemyMonHP + 1
-	ld a,[hld]
-	ld e,a
-	ld a,[hl]
-	ld d,a
-	ld a,d
-	sub b
-	ret nz
-	ld a,e
-	sub c
-	ret
-
-AIUseXAttack: ; 3a7f2 (e:67f2)
-	ld b,$A
-	ld a,X_ATTACK
-	jr AIIncreaseStat
-
-AIUseXDefend: ; 3a7f8 (e:67f8)
-	ld b,$B
-	ld a,X_DEFEND
-	jr AIIncreaseStat
-
-AIUseXSpeed: ; 3a7fe (e:67fe)
-	ld b,$C
-	ld a,X_SPEED
-	jr AIIncreaseStat
-
-AIUseXSpecial: ; 3a804 (e:6804)
-	ld b,$D
-	ld a,X_SPECIAL
-	; fallthrough
-
-AIIncreaseStat: ; 3a808 (e:6808)
-	ld [wcf05],a
-	push bc
-	call AIPrintItemUse_
-	pop bc
-	ld hl,W_ENEMYMOVEEFFECT
-	ld a,[hld]
-	push af
-	ld a,[hl]
-	push af
-	push hl
-	ld a,$AF
-	ld [hli],a
-	ld [hl],b
-	callab StatModifierUpEffect
-	pop hl
-	pop af
-	ld [hli],a
-	pop af
-	ld [hl],a
-	jp DecrementAICount
-
-AIPrintItemUse: ; 3a82c (e:682c)
-	ld [wcf05],a
-	call AIPrintItemUse_
-	jp DecrementAICount
-
-AIPrintItemUse_: ; 3a835 (e:6835)
-; print "x used [wcf05] on z!"
-	ld a,[wcf05]
-	ld [wd11e],a
-	call GetItemName
-	ld hl, AIBattleUseItemText
-	jp PrintText
-
-AIBattleUseItemText: ; 3a844 (e:6844)
-	TX_FAR _AIBattleUseItemText
-	db "@"
--- /dev/null
+++ b/engine/battle/trainer_pic_money_pointers.asm
@@ -1,0 +1,143 @@
+TrainerPicAndMoneyPointers: ; 39914 (e:5914)
+; trainer pic pointers and base money.
+; money received after battle = base money × level of highest-level enemy mon
+	dw YoungsterPic
+	money 1500
+
+	dw BugCatcherPic
+	money 1000
+
+	dw LassPic
+	money 1500
+
+	dw SailorPic
+	money 3000
+
+	dw JrTrainerMPic
+	money 2000
+
+	dw JrTrainerFPic
+	money 2000
+
+	dw PokemaniacPic
+	money 5000
+
+	dw SuperNerdPic
+	money 2500
+
+	dw HikerPic
+	money 3500
+
+	dw BikerPic
+	money 2000
+
+	dw BurglarPic
+	money 9000
+
+	dw EngineerPic
+	money 5000
+
+	dw JugglerPic
+	money 3500
+
+	dw FisherPic
+	money 3500
+
+	dw SwimmerPic
+	money 500
+
+	dw CueBallPic
+	money 2500
+
+	dw GamblerPic
+	money 7000
+
+	dw BeautyPic
+	money 7000
+
+	dw PsychicPic
+	money 1000
+
+	dw RockerPic
+	money 2500
+
+	dw JugglerPic
+	money 3500
+
+	dw TamerPic
+	money 4000
+
+	dw BirdKeeperPic
+	money 2500
+
+	dw BlackbeltPic
+	money 2500
+
+	dw Rival1Pic
+	money 3500
+
+	dw ProfOakPic
+	money 9900
+
+	dw ChiefPic
+	money 3000
+
+	dw ScientistPic
+	money 5000
+
+	dw GiovanniPic
+	money 9900
+
+	dw RocketPic
+	money 3000
+
+	dw CooltrainerMPic
+	money 3500
+
+	dw CooltrainerFPic
+	money 3500
+
+	dw BrunoPic
+	money 9900
+
+	dw BrockPic
+	money 9900
+
+	dw MistyPic
+	money 9900
+
+	dw LtSurgePic
+	money 9900
+
+	dw ErikaPic
+	money 9900
+
+	dw KogaPic
+	money 9900
+
+	dw BlainePic
+	money 9900
+
+	dw SabrinaPic
+	money 9900
+
+	dw GentlemanPic
+	money 7000
+
+	dw Rival2Pic
+	money 6500
+
+	dw Rival3Pic
+	money 9900
+
+	dw LoreleiPic
+	money 9900
+
+	dw ChannelerPic
+	money 3000
+
+	dw AgathaPic
+	money 9900
+
+	dw LancePic
+	money 9900
\ No newline at end of file
--- a/main.asm
+++ b/main.asm
@@ -5465,7 +5465,7 @@
 INCLUDE "data/cries.asm"
 INCLUDE "engine/battle/unused_stats_functions.asm"
 INCLUDE "engine/battle/scroll_draw_trainer_pic.asm"
-INCLUDE "engine/battle/trainer_party_ai_misc.asm"
+INCLUDE "engine/battle/trainer_ai.asm"
 INCLUDE "engine/battle/draw_hud_pokeball_gfx.asm"
 
 TradingAnimationGraphics: