shithub: pokered

ref: a02c3279102dca60deee70141c31af9fcfa1ff75
dir: /main.asm/

View raw version
INCLUDE "constants.asm"

; The rst vectors are unused.
SECTION "rst00",ROM0[$00]
	rst $38
SECTION "rst08",ROM0[$08]
	rst $38
SECTION "rst10",ROM0[$10]
	rst $38
SECTION "rst18",ROM0[$18]
	rst $38
SECTION "rst20",ROM0[$20]
	rst $38
SECTION "rst28",ROM0[$28]
	rst $38
SECTION "rst30",ROM0[$30]
	rst $38
SECTION "rst38",ROM0[$38]
	rst $38

; interrupts
SECTION "vblank",ROM0[$40]
	jp VBlank
SECTION "lcdc",ROM0[$48]
	db $FF
SECTION "timer",ROM0[$50]
	jp Timer
SECTION "serial",ROM0[$58]
	jp Serial
SECTION "joypad",ROM0[$60]
	reti

SECTION "bank0",ROM0[$61]

DisableLCD:: ; 0061 (0:0061)
	xor a
	ld [$ff0f],a
	ld a,[$ffff]
	ld b,a
	res 0,a
	ld [$ffff],a
.waitVBlank
	ld a,[$ff44]
	cp a,$91
	jr nz,.waitVBlank
	ld a,[$ff40]
	and a,$7f	; res 7,a
	ld [$ff40],a
	ld a,b
	ld [$ffff],a
	ret

EnableLCD:: ; 007b (0:007b)
	ld a,[$ff40]
	set 7,a
	ld [$ff40],a
	ret

CleanLCD_OAM:: ; 0082 (0:0082)
	xor a
	ld hl,wOAMBuffer
	ld b,$a0
.loop
	ld [hli],a
	dec b
	jr nz,.loop
	ret

ResetLCD_OAM:: ; 008d (0:008d)
	ld a,$a0
	ld hl,wOAMBuffer
	ld de,$0004
	ld b,$28
.loop
	ld [hl],a
	add hl,de
	dec b
	jr nz,.loop
	ret

FarCopyData:: ; 009d (0:009d)
; copy bc bytes of data from a:hl to de
	ld [$CEE9],a ; save future bank # for later
	ld a,[H_LOADEDROMBANK] ; get current bank #
	push af
	ld a,[$CEE9] ; get future bank #, switch
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call CopyData
	pop af       ; okay, done, time to switch back
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret
CopyData:: ; 00b5 (0:00b5)
; copy bc bytes of data from hl to de
	ld a,[hli]
	ld [de],a
	inc de
	dec bc
	ld a,c
	or b
	jr nz,CopyData
	ret

SECTION "romheader",ROM0[$100]
	nop
	jp Start

SECTION "start",ROM0[$150]
Start:: ; 0150 (0:0150)
	cp $11 ; value that indicates Gameboy Color
	jr z,.gbcDetected
	xor a
	jr .storeValue
.gbcDetected
	ld a,$00
.storeValue
	ld [$cf1a],a ; same value ($00) either way
	jp InitGame

; this function directly reads the joypad I/O register
; it reads many times in order to give the joypad a chance to stabilize
; it saves a result in [$fff8] in the following format
; (set bit indicates pressed button)
; bit 0 - A button
; bit 1 - B button
; bit 2 - Select button
; bit 3 - Start button
; bit 4 - Right
; bit 5 - Left
; bit 6 - Up
; bit 7 - Down
ReadJoypadRegister:: ; 015f (0:015f)
	ld a,%00100000 ; select direction keys
	ld c,$00
	ld [rJOYP],a
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	cpl ; complement the result so that a set bit indicates a pressed key
	and a,%00001111
	swap a ; put direction keys in upper nibble
	ld b,a
	ld a,%00010000 ; select button keys
	ld [rJOYP],a
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	ld a,[rJOYP]
	cpl ; complement the result so that a set bit indicates a pressed key
	and a,%00001111
	or b ; put button keys in lower nibble
	ld [H_JOYPADSTATE],a ; save joypad state
	ld a,%00110000 ; unselect all keys
	ld [rJOYP],a
	ret

; function to update the joypad state variables
; output:
; [H_NEWLYRELEASEDBUTTONS] = keys released since last time
; [H_NEWLYPRESSEDBUTTONS] = keys pressed since last time
; [H_CURRENTPRESSEDBUTTONS] = currently pressed keys
GetJoypadState:: ; 019a (0:019a)
	ld a, [H_LOADEDROMBANK]
	push af
	ld a,Bank(_GetJoypadState)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call _GetJoypadState
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; see also MapHeaderBanks
MapHeaderPointers:: ; 01ae (0:01ae)
	dw PalletTown_h
	dw ViridianCity_h
	dw PewterCity_h
	dw CeruleanCity_h
	dw LavenderTown_h
	dw VermilionCity_h
	dw CeladonCity_h
	dw FuchsiaCity_h
	dw CinnabarIsland_h
	dw IndigoPlateau_h
	dw SaffronCity_h
	dw SaffronCity_h
	dw Route1_h
	dw Route2_h
	dw Route3_h
	dw Route4_h
	dw Route5_h
	dw Route6_h
	dw Route7_h
	dw Route8_h
	dw Route9_h
	dw Route10_h
	dw Route11_h
	dw Route12_h
	dw Route13_h
	dw Route14_h
	dw Route15_h
	dw Route16_h
	dw Route17_h
	dw Route18_h
	dw Route19_h
	dw Route20_h
	dw Route21_h
	dw Route22_h
	dw Route23_h
	dw Route24_h
	dw Route25_h
	dw RedsHouse1F_h
	dw RedsHouse2F_h
	dw BluesHouse_h
	dw OaksLab_h ;id=40
	dw ViridianPokecenter_h
	dw ViridianMart_h
	dw School_h
	dw ViridianHouse_h
	dw ViridianGym_h
	dw DiglettsCaveRoute2_h
	dw ViridianForestExit_h
	dw Route2House_h
	dw Route2Gate_h
	dw ViridianForestEntrance_h ;id=50
	dw ViridianForest_h
	dw Museum1F_h
	dw Museum2F_h
	dw PewterGym_h
	dw PewterHouse1_h
	dw PewterMart_h
	dw PewterHouse2_h
	dw PewterPokecenter_h
	dw MtMoon1_h
	dw MtMoon2_h ;id=60
	dw MtMoon3_h
	dw CeruleanHouseTrashed_h
	dw CeruleanHouse1_h
	dw CeruleanPokecenter_h
	dw CeruleanGym_h
	dw BikeShop_h
	dw CeruleanMart_h
	dw MtMoonPokecenter_h
	dw CeruleanHouseTrashed_h ; copy
	dw Route5Gate_h
	dw UndergroundPathEntranceRoute5_h
	dw DayCareM_h
	dw Route6Gate_h
	dw UndergroundPathEntranceRoute6_h
	dw UndergroundPathEntranceRoute6_h ; unused
	dw Route7Gate_h
	dw UndergroundPathEntranceRoute7_h
	dw UndergroundPathEntranceRoute7Copy_h
	dw Route8Gate_h
	dw UndergroundPathEntranceRoute8_h ;id=80
	dw RockTunnelPokecenter_h
	dw RockTunnel1_h
	dw PowerPlant_h
	dw Route11Gate_h
	dw DiglettsCaveEntranceRoute11_h
	dw Route11GateUpstairs_h
	dw Route12Gate_h
	dw BillsHouse_h
	dw VermilionPokecenter_h
	dw FanClub_h ;id=90
	dw VermilionMart_h
	dw VermilionGym_h
	dw VermilionHouse1_h
	dw VermilionDock_h
	dw SSAnne1_h
	dw SSAnne2_h
	dw SSAnne3_h
	dw SSAnne4_h
	dw SSAnne5_h
	dw SSAnne6_h ;id=100
	dw SSAnne7_h
	dw SSAnne8_h
	dw SSAnne9_h
	dw SSAnne10_h
	dw Lance_h ; unused
	dw Lance_h ; unused
	dw Lance_h ; unused
	dw VictoryRoad1_h
	dw Lance_h ; unused
	dw Lance_h ; unused ;id=110
	dw Lance_h ; unused
	dw Lance_h ; unused
	dw Lance_h
	dw Lance_h ; unused
	dw Lance_h ; unused
	dw Lance_h ; unused
	dw Lance_h ; unused
	dw HallofFameRoom_h
	dw UndergroundPathNS_h
	dw Gary_h ;id=120
	dw UndergroundPathWE_h
	dw CeladonMart1_h
	dw CeladonMart2_h
	dw CeladonMart3_h
	dw CeladonMart4_h
	dw CeladonMartRoof_h
	dw CeladonMartElevator_h
	dw CeladonMansion1_h
	dw CeladonMansion2_h
	dw CeladonMansion3_h ;id=130
	dw CeladonMansion4_h
	dw CeladonMansion5_h
	dw CeladonPokecenter_h
	dw CeladonGym_h
	dw CeladonGameCorner_h
	dw CeladonMart5_h
	dw CeladonPrizeRoom_h
	dw CeladonDiner_h
	dw CeladonHouse_h
	dw CeladonHotel_h ;id=140
	dw LavenderPokecenter_h
	dw PokemonTower1_h
	dw PokemonTower2_h
	dw PokemonTower3_h
	dw PokemonTower4_h
	dw PokemonTower5_h
	dw PokemonTower6_h
	dw PokemonTower7_h
	dw LavenderHouse1_h
	dw LavenderMart_h ;id=150
	dw LavenderHouse2_h
	dw FuchsiaMart_h
	dw FuchsiaHouse1_h
	dw FuchsiaPokecenter_h
	dw FuchsiaHouse2_h
	dw SafariZoneEntrance_h
	dw FuchsiaGym_h
	dw FuchsiaMeetingRoom_h
	dw SeafoamIslands2_h
	dw SeafoamIslands3_h ;id=160
	dw SeafoamIslands4_h
	dw SeafoamIslands5_h
	dw VermilionHouse2_h
	dw FuchsiaHouse3_h
	dw Mansion1_h
	dw CinnabarGym_h
	dw Lab1_h
	dw Lab2_h
	dw Lab3_h
	dw Lab4_h ;id=170
	dw CinnabarPokecenter_h
	dw CinnabarMart_h
	dw CinnabarMart_h ; unused
	dw IndigoPlateauLobby_h
	dw CopycatsHouse1F_h
	dw CopycatsHouse2F_h
	dw FightingDojo_h
	dw SaffronGym_h
	dw SaffronHouse1_h
	dw SaffronMart_h ;id=180
	dw SilphCo1_h
	dw SaffronPokecenter_h
	dw SaffronHouse2_h
	dw Route15Gate_h
	dw Route15GateUpstairs_h
	dw Route16Gate_h
	dw Route16GateUpstairs_h
	dw Route16House_h
	dw Route12House_h
	dw Route18Gate_h ;id=190
	dw Route18GateUpstairs_h
	dw SeafoamIslands1_h
	dw Route22Gate_h
	dw VictoryRoad2_h
	dw Route12GateUpstairs_h
	dw VermilionHouse3_h
	dw DiglettsCave_h
	dw VictoryRoad3_h
	dw RocketHideout1_h
	dw RocketHideout2_h ;200
	dw RocketHideout3_h
	dw RocketHideout4_h
	dw RocketHideoutElevator_h
	dw RocketHideoutElevator_h ; unused
	dw RocketHideoutElevator_h ; unused
	dw RocketHideoutElevator_h ; unused
	dw SilphCo2_h
	dw SilphCo3_h
	dw SilphCo4_h
	dw SilphCo5_h ;210
	dw SilphCo6_h
	dw SilphCo7_h
	dw SilphCo8_h
	dw Mansion2_h
	dw Mansion3_h
	dw Mansion4_h
	dw SafariZoneEast_h
	dw SafariZoneNorth_h
	dw SafariZoneWest_h
	dw SafariZoneCenter_h ;220
	dw SafariZoneRestHouse1_h
	dw SafariZoneSecretHouse_h
	dw SafariZoneRestHouse2_h
	dw SafariZoneRestHouse3_h
	dw SafariZoneRestHouse4_h
	dw UnknownDungeon2_h
	dw UnknownDungeon3_h
	dw UnknownDungeon1_h
	dw NameRater_h
	dw CeruleanHouse2_h
	dw Route16Gate_h ; unused
	dw RockTunnel2_h
	dw SilphCo9_h
	dw SilphCo10_h
	dw SilphCo11_h
	dw SilphCoElevator_h
	dw SilphCo2_h ; unused
	dw SilphCo2_h ; unused
	dw BattleCenterM_h
	dw TradeCenterM_h
	dw SilphCo2_h ; unused
	dw SilphCo2_h ; unused
	dw SilphCo2_h ; unused
	dw SilphCo2_h ; unused
	dw Lorelei_h
	dw Bruno_h
	dw Agatha_h ;247

; this function calls a function that takes necessary actions
; at the beginning of each overworld loop iteration as the player jumps
; down a ledge
; it also ends the jump when it's completed
HandleMidJump:: ; 039e (0:039e)
	ld b, BANK(_HandleMidJump)
	ld hl, _HandleMidJump
	jp Bankswitch

; this is jumped to immediately after loading a save / starting a new game / loading a new map
EnterMap:: ; 03a6 (0:03a6)
	ld a,$ff
	ld [wJoypadForbiddenButtonsMask],a
	call LoadMapData ; load map data
	callba Func_c335 ; initialize some variables
	ld hl,$d72c
	bit 0,[hl]
	jr z,.doNotCountSteps
	ld a,$03
	ld [$d13c],a ; some kind of step counter (counts up to 3 steps?)
.doNotCountSteps
	ld hl,$d72e
	bit 5,[hl] ; did a battle happen immediately before this?
	res 5,[hl] ; unset the "battle just happened" flag
	call z,Func_12e7
	call nz,MapEntryAfterBattle
	ld hl,$d732
	ld a,[hl]
	and a,$18
	jr z,.didNotFlyOrTeleportIn
	res 3,[hl]
	callba Func_70510 ; display fly/teleport in graphical effect
	call UpdateSprites ; move sprites
.didNotFlyOrTeleportIn
	callba CheckForceBikeOrSurf ; handle currents in SF islands and forced bike riding in cycling road
	ld hl,$d72d
	res 5,[hl]
	call UpdateSprites ; move sprites
	ld hl,$d126
	set 5,[hl]
	set 6,[hl]
	xor a
	ld [wJoypadForbiddenButtonsMask],a

OverworldLoop:: ; 03ff (0:03ff)
	call DelayFrame
OverworldLoopLessDelay:: ; 0402 (0:0402)
	call DelayFrame
	call LoadGBPal
	ld a,[$d736]
	bit 6,a ; jumping down a ledge?
	call nz, HandleMidJump
	ld a,[wWalkCounter]
	and a
	jp nz,.moveAhead ; if the player sprite has not yet completed the walking animation
	call GetJoypadStateOverworld ; get joypad state (which is possibly simulated)
	callba Func_1e988
	ld a,[$da46]
	and a
	jp nz,WarpFound2
	ld hl,$d72d
	bit 3,[hl]
	res 3,[hl]
	jp nz,WarpFound2
	ld a,[$d732]
	and a,$18
	jp nz,HandleFlyOrTeleportAway
	ld a,[W_CUROPPONENT]
	and a
	jp nz,.newBattle
	ld a,[$d730]
	bit 7,a ; are we simulating button presses?
	jr z,.notSimulating
	ld a,[H_CURRENTPRESSEDBUTTONS]
	jr .checkIfStartIsPressed
.notSimulating
	ld a,[H_NEWLYPRESSEDBUTTONS]
.checkIfStartIsPressed
	bit 3,a ; start button
	jr z,.startButtonNotPressed
; if START is pressed
	xor a
	ld [$ff8c],a ; the $2920 ID for the start menu is 0
	jp .displayDialogue
.startButtonNotPressed
	bit 0,a ; A button
	jp z,.checkIfDownButtonIsPressed
; if A is pressed
	ld a,[$d730]
	bit 2,a
	jp nz,.noDirectionButtonsPressed
	call Func_30fd
	jr nz,.checkForOpponent
	call Func_3eb5 ; check for hidden items, PC's, etc.
	ld a,[$ffeb]
	and a
	jp z,OverworldLoop
	call IsSpriteOrSignInFrontOfPlayer ; check for sign or sprite in front of the player
	ld a,[$ff8c] ; $2920 ID for NPC/sign text, if any
	and a
	jp z,OverworldLoop
.displayDialogue
	ld a,$35
	call Predef ; check what is in front of the player
	call UpdateSprites ; move sprites
	ld a,[wFlags_0xcd60]
	bit 2,a
	jr nz,.checkForOpponent
	bit 0,a
	jr nz,.checkForOpponent
	FuncCoord 8, 9 ; $c45c
	ld a,[Coord]
	ld [$cf0e],a
	call DisplayTextID ; display either the start menu or the NPC/sign text
	ld a,[$cc47]
	and a
	jr z,.checkForOpponent
	dec a
	ld a,$00
	ld [$cc47],a
	jr z,.changeMap
	ld a,$52
	call Predef
	ld a,[W_CURMAP]
	ld [$d71a],a
	call Func_62ce
	ld a,[W_CURMAP]
	call SwitchToMapRomBank ; switch to the ROM bank of the current map
	ld hl,$d367
	set 7,[hl]
.changeMap
	jp EnterMap
.checkForOpponent
	ld a,[W_CUROPPONENT]
	and a
	jp nz,.newBattle
	jp OverworldLoop
.noDirectionButtonsPressed
	ld hl,wFlags_0xcd60
	res 2,[hl]
	call UpdateSprites ; move sprites
	ld a,$01
	ld [$cc4b],a
	ld a,[$d528] ; the direction that was pressed last time
	and a
	jp z,OverworldLoop
; if a direction was pressed last time
	ld [$d529],a ; save the last direction
	xor a
	ld [$d528],a ; zero the direction
	jp OverworldLoop
.checkIfDownButtonIsPressed
	ld a,[H_CURRENTPRESSEDBUTTONS] ; current joypad state
	bit 7,a ; down button
	jr z,.checkIfUpButtonIsPressed
	ld a,$01
	ld [$c103],a
	ld a,$04
	jr .handleDirectionButtonPress
.checkIfUpButtonIsPressed
	bit 6,a ; up button
	jr z,.checkIfLeftButtonIsPressed
	ld a,$ff
	ld [$c103],a
	ld a,$08
	jr .handleDirectionButtonPress
.checkIfLeftButtonIsPressed
	bit 5,a ; left button
	jr z,.checkIfRightButtonIsPressed
	ld a,$ff
	ld [$c105],a
	ld a,$02
	jr .handleDirectionButtonPress
.checkIfRightButtonIsPressed
	bit 4,a ; right button
	jr z,.noDirectionButtonsPressed
	ld a,$01
	ld [$c105],a
.handleDirectionButtonPress
	ld [$d52a],a ; new direction
	ld a,[$d730]
	bit 7,a ; are we simulating button presses?
	jr nz,.noDirectionChange ; ignore direction changes if we are
	ld a,[$cc4b]
	and a
	jr z,.noDirectionChange
	ld a,[$d52a] ; new direction
	ld b,a
	ld a,[$d529] ; old direction
	cp b
	jr z,.noDirectionChange
; the code below is strange
; it computes whether or not the player did a 180 degree turn, but then overwrites the result
; also, it does a seemingly pointless loop afterwards
	swap a ; put old direction in upper half
	or b ; put new direction in lower half
	cp a,$48 ; change dir from down to up
	jr nz,.notDownToUp
	ld a,$02
	ld [$d528],a
	jr .oddLoop
.notDownToUp
	cp a,$84 ; change dir from up to down
	jr nz,.notUpToDown
	ld a,$01
	ld [$d528],a
	jr .oddLoop
.notUpToDown
	cp a,$12 ; change dir from right to left
	jr nz,.notRightToLeft
	ld a,$04
	ld [$d528],a
	jr .oddLoop
.notRightToLeft
	cp a,$21 ; change dir from left to right
	jr nz,.oddLoop
	ld a,$08
	ld [$d528],a
.oddLoop
	ld hl,wFlags_0xcd60
	set 2,[hl]
	ld hl,$cc4b
	dec [hl]
	jr nz,.oddLoop
	ld a,[$d52a]
	ld [$d528],a
	call NewBattle
	jp c,.battleOccurred
	jp OverworldLoop
.noDirectionChange
	ld a,[$d52a] ; current direction
	ld [$d528],a ; save direction
	call UpdateSprites ; move sprites
	ld a,[$d700]
	cp a,$02 ; surfing
	jr z,.surfing
; not surfing
	call CollisionCheckOnLand
	jr nc,.noCollision
	push hl
	ld hl,$d736
	bit 2,[hl]
	pop hl
	jp z,OverworldLoop
	push hl
	call ExtraWarpCheck ; sets carry if there is a potential to warp
	pop hl
	jp c,CheckWarpsCollision
	jp OverworldLoop
.surfing
	call CollisionCheckOnWater
	jp c,OverworldLoop
.noCollision
	ld a,$08
	ld [wWalkCounter],a
	jr .moveAhead2
.moveAhead
	ld a,[$d736]
	bit 7,a
	jr z,.noSpinning
	callba LoadSpinnerArrowTiles ; spin while moving
.noSpinning
	call UpdateSprites ; move sprites
.moveAhead2
	ld hl,wFlags_0xcd60
	res 2,[hl]
	ld a,[$d700]
	dec a ; riding a bike?
	jr nz,.normalPlayerSpriteAdvancement
	ld a,[$d736]
	bit 6,a ; jumping a ledge?
	jr nz,.normalPlayerSpriteAdvancement
	call BikeSpeedup ; if riding a bike and not jumping a ledge
.normalPlayerSpriteAdvancement
	call AdvancePlayerSprite
	ld a,[wWalkCounter]
	and a
	jp nz,CheckMapConnections ; it seems like this check will never succeed (the other place where CheckMapConnections is run works)
; walking animation finished
	ld a,[$d730]
	bit 7,a
	jr nz,.doneStepCounting ; if button presses are being simulated, don't count steps
; step counting
	ld hl,$d13b ; step counter
	dec [hl]
	ld a,[$d72c]
	bit 0,a
	jr z,.doneStepCounting
	ld hl,$d13c
	dec [hl]
	jr nz,.doneStepCounting
	ld hl,$d72c
	res 0,[hl]
.doneStepCounting
	ld a,[$d790]
	bit 7,a ; in the safari zone?
	jr z,.notSafariZone
	callba Func_1e997
	ld a,[$da46]
	and a
	jp nz,WarpFound2
.notSafariZone
	ld a,[W_ISINBATTLE]
	and a
	jp nz,CheckWarpsNoCollision
	ld a,$13
	call Predef ; decrement HP of poisoned pokemon
	ld a,[$d12d]
	and a
	jp nz,HandleBlackOut ; if all pokemon fainted
.newBattle
	call NewBattle
	ld hl,$d736
	res 2,[hl]
	jp nc,CheckWarpsNoCollision ; check for warps if there was no battle
.battleOccurred
	ld hl,$d72d
	res 6,[hl]
	ld hl,W_FLAGS_D733
	res 3,[hl]
	ld hl,$d126
	set 5,[hl]
	set 6,[hl]
	xor a
	ld [H_CURRENTPRESSEDBUTTONS],a ; clear joypad state
	ld a,[W_CURMAP]
	cp a,CINNABAR_GYM
	jr nz,.notCinnabarGym
	ld hl,$d79b
	set 7,[hl]
.notCinnabarGym
	ld hl,$d72e
	set 5,[hl]
	ld a,[W_CURMAP]
	cp a,OAKS_LAB
	jp z,.noFaintCheck
	callab AnyPokemonAliveCheck ; check if all the player's pokemon fainted
	ld a,d
	and a
	jr z,.allPokemonFainted
.noFaintCheck
	ld c,$0a
	call DelayFrames
	jp EnterMap
.allPokemonFainted
	ld a,$ff
	ld [$d057],a
	call RunMapScript
	jp HandleBlackOut

; function to determine if there will be a battle and execute it (either a trainer battle or wild battle)
; sets carry if a battle occurred and unsets carry if not
NewBattle:: ; 0683 (0:0683)
	ld a,[$d72d]
	bit 4,a
	jr nz,.noBattle
	call Func_30fd
	jr nz,.noBattle
	ld a,[$d72e]
	bit 4,a
	jr nz,.noBattle
	ld b, BANK(InitBattle)
	ld hl, InitBattle
	jp Bankswitch ; determines if a battle will occur and runs the battle if so
.noBattle
	and a
	ret

; function to make bikes twice as fast as walking
BikeSpeedup:: ; 06a0 (0:06a0)
	ld a,[$cc57]
	and a
	ret nz
	ld a,[W_CURMAP]
	cp a,ROUTE_17 ; Cycling Road
	jr nz,.goFaster
	ld a,[H_CURRENTPRESSEDBUTTONS] ; current joypad state
	and a,%01110000 ; bit mask for up, left, right buttons
	ret nz
.goFaster
	jp AdvancePlayerSprite

; check if the player has stepped onto a warp after having not collided
CheckWarpsNoCollision:: ; 06b4 (0:06b4)
	ld a,[$d3ae] ; number of warps
	and a
	jp z,CheckMapConnections
	ld a,[$d3ae] ; number of warps
	ld b,$00
	ld c,a
	ld a,[W_YCOORD]
	ld d,a
	ld a,[W_XCOORD]
	ld e,a
	ld hl,$d3af ; start of warp entries
CheckWarpsNoCollisionLoop:: ; 06cc (0:06cc)
	ld a,[hli] ; check if the warp's Y position matches
	cp d
	jr nz,CheckWarpsNoCollisionRetry1
	ld a,[hli] ; check if the warp's X position matches
	cp e
	jr nz,CheckWarpsNoCollisionRetry2
; if a match was found
	push hl
	push bc
	ld hl,$d736
	set 2,[hl]
	callba Func_c49d ; check if the player sprite is standing on a "door" tile
	pop bc
	pop hl
	jr c,WarpFound1 ; if it is, go to 0735
	push hl
	push bc
	call ExtraWarpCheck ; sets carry if the warp is confirmed
	pop bc
	pop hl
	jr nc,CheckWarpsNoCollisionRetry2
; if the extra check passed
	ld a,[W_FLAGS_D733]
	bit 2,a
	jr nz,WarpFound1
	push de
	push bc
	call GetJoypadState
	pop bc
	pop de
	ld a,[H_CURRENTPRESSEDBUTTONS] ; current joypad state
	and a,%11110000 ; bit mask for directional buttons
	jr z,CheckWarpsNoCollisionRetry2 ; if directional buttons aren't being pressed, do not pass through the warp
	jr WarpFound1

; check if the player has stepped onto a warp after having collided
CheckWarpsCollision:: ; 0706 (0:0706)
	ld a,[$d3ae] ; number of warps
	ld c,a
	ld hl,$d3af ; start of warp entries
.loop
	ld a,[hli] ; Y coordinate of warp
	ld b,a
	ld a,[W_YCOORD]
	cp b
	jr nz,.retry1
	ld a,[hli] ; X coordinate of warp
	ld b,a
	ld a,[W_XCOORD]
	cp b
	jr nz,.retry2
	ld a,[hli]
	ld [$d42f],a ; save target warp ID
	ld a,[hl]
	ld [$ff8b],a ; save target map
	jr WarpFound2
.retry1
	inc hl
.retry2
	inc hl
	inc hl
	dec c
	jr nz,.loop
	jp OverworldLoop

CheckWarpsNoCollisionRetry1:: ; 072f (0:072f)
	inc hl
CheckWarpsNoCollisionRetry2:: ; 0730 (0:0730)
	inc hl
	inc hl
	jp ContinueCheckWarpsNoCollisionLoop

WarpFound1:: ; 0735 (0:0735)
	ld a,[hli]
	ld [$d42f],a ; save target warp ID
	ld a,[hli]
	ld [$ff8b],a ; save target map

WarpFound2:: ; 073c (0:073c)
	ld a,[$d3ae] ; number of warps
	sub c
	ld [$d73b],a ; save ID of used warp
	ld a,[W_CURMAP]
	ld [$d73c],a
	call CheckIfInOutsideMap
	jr nz,.indoorMaps
; this is for handling "outside" maps that can't have the 0xFF destination map
	ld a,[W_CURMAP]
	ld [wLastMap],a
	ld a,[W_CURMAPWIDTH]
	ld [$d366],a
	ld a,[$ff8b] ; destination map number
	ld [W_CURMAP],a ; change current map to destination map
	cp a,ROCK_TUNNEL_1
	jr nz,.notRockTunnel
	ld a,$06
	ld [$d35d],a
	call GBFadeIn1
.notRockTunnel
	call PlayMapChangeSound
	jr .done
; for maps that can have the 0xFF destination map, which means to return to the outside map; not all these maps are necessarily indoors, though
.indoorMaps
	ld a,[$ff8b] ; destination map
	cp a,$ff
	jr z,.goBackOutside
; if not going back to the previous map
	ld [W_CURMAP],a ; current map number
	callba Func_70787 ; check if the warp was a Silph Co. teleporter
	ld a,[$cd5b]
	dec a
	jr nz,.notTeleporter
; if it's a Silph Co. teleporter
	ld hl,$d732
	set 3,[hl]
	call DoFlyOrTeleportAwayGraphics
	jr .skipMapChangeSound
.notTeleporter
	call PlayMapChangeSound
.skipMapChangeSound
	ld hl,$d736
	res 0,[hl]
	res 1,[hl]
	jr .done
.goBackOutside
	ld a,[wLastMap]
	ld [W_CURMAP],a
	call PlayMapChangeSound
	xor a
	ld [$d35d],a
.done
	ld hl,$d736
	set 0,[hl]
	call Func_12da
	jp EnterMap

ContinueCheckWarpsNoCollisionLoop:: ; 07b5 (0:07b5)
	inc b ; increment warp number
	dec c ; decrement number of warps
	jp nz,CheckWarpsNoCollisionLoop

; if no matching warp was found
CheckMapConnections:: ; 07ba (0:07ba)
.checkWestMap
	ld a,[W_XCOORD]
	cp a,$ff
	jr nz,.checkEastMap
	ld a,[$d387]
	ld [W_CURMAP],a
	ld a,[$d38f] ; new X coordinate upon entering west map
	ld [W_XCOORD],a
	ld a,[W_YCOORD]
	ld c,a
	ld a,[$d38e] ; Y adjustment upon entering west map
	add c
	ld c,a
	ld [W_YCOORD],a
	ld a,[$d390] ; pointer to upper left corner of map without adjustment for Y position
	ld l,a
	ld a,[$d391]
	ld h,a
	srl c
	jr z,.savePointer1
.pointerAdjustmentLoop1
	ld a,[$d38d] ; width of connected map
	add a,$06
	ld e,a
	ld d,$00
	ld b,$00
	add hl,de
	dec c
	jr nz,.pointerAdjustmentLoop1
.savePointer1
	ld a,l
	ld [$d35f],a ; pointer to upper left corner of current tile block map section
	ld a,h
	ld [$d360],a
	jp .loadNewMap
.checkEastMap
	ld b,a
	ld a,[$d525] ; map width
	cp b
	jr nz,.checkNorthMap
	ld a,[$d392]
	ld [W_CURMAP],a
	ld a,[$d39a] ; new X coordinate upon entering east map
	ld [W_XCOORD],a
	ld a,[W_YCOORD]
	ld c,a
	ld a,[$d399] ; Y adjustment upon entering east map
	add c
	ld c,a
	ld [W_YCOORD],a
	ld a,[$d39b] ; pointer to upper left corner of map without adjustment for Y position
	ld l,a
	ld a,[$d39c]
	ld h,a
	srl c
	jr z,.savePointer2
.pointerAdjustmentLoop2
	ld a,[$d398]
	add a,$06
	ld e,a
	ld d,$00
	ld b,$00
	add hl,de
	dec c
	jr nz,.pointerAdjustmentLoop2
.savePointer2
	ld a,l
	ld [$d35f],a ; pointer to upper left corner of current tile block map section
	ld a,h
	ld [$d360],a
	jp .loadNewMap
.checkNorthMap
	ld a,[W_YCOORD]
	cp a,$ff
	jr nz,.checkSouthMap
	ld a,[$d371]
	ld [W_CURMAP],a
	ld a,[$d378] ; new Y coordinate upon entering north map
	ld [W_YCOORD],a
	ld a,[W_XCOORD]
	ld c,a
	ld a,[$d379] ; X adjustment upon entering north map
	add c
	ld c,a
	ld [W_XCOORD],a
	ld a,[$d37a] ; pointer to upper left corner of map without adjustment for X position
	ld l,a
	ld a,[$d37b]
	ld h,a
	ld b,$00
	srl c
	add hl,bc
	ld a,l
	ld [$d35f],a ; pointer to upper left corner of current tile block map section
	ld a,h
	ld [$d360],a
	jp .loadNewMap
.checkSouthMap
	ld b,a
	ld a,[$d524]
	cp b
	jr nz,.didNotEnterConnectedMap
	ld a,[$d37c]
	ld [W_CURMAP],a
	ld a,[$d383] ; new Y coordinate upon entering south map
	ld [W_YCOORD],a
	ld a,[W_XCOORD]
	ld c,a
	ld a,[$d384] ; X adjustment upon entering south map
	add c
	ld c,a
	ld [W_XCOORD],a
	ld a,[$d385] ; pointer to upper left corner of map without adjustment for X position
	ld l,a
	ld a,[$d386]
	ld h,a
	ld b,$00
	srl c
	add hl,bc
	ld a,l
	ld [$d35f],a ; pointer to upper left corner of current tile block map section
	ld a,h
	ld [$d360],a
.loadNewMap ; load the connected map that was entered
	call LoadMapHeader
	call Func_2312 ; music
	ld b,$09
	call GoPAL_SET
; Since the sprite set shouldn't change, this will just update VRAM slots at
; $C2XE without loading any tile patterns.
	callba InitMapSprites
	call LoadTileBlockMap
	jp OverworldLoopLessDelay
.didNotEnterConnectedMap
	jp OverworldLoop

; function to play a sound when changing maps
PlayMapChangeSound:: ; 08c9 (0:08c9)
	FuncCoord 8, 8 ; $c448
	ld a,[Coord] ; upper left tile of the 4x4 square the player's sprite is standing on
	cp a,$0b ; door tile in tileset 0
	jr nz,.didNotGoThroughDoor
	ld a,(SFX_02_57 - SFX_Headers_02) / 3
	jr .playSound
.didNotGoThroughDoor
	ld a,(SFX_02_5c - SFX_Headers_02) / 3
.playSound
	call PlaySound
	ld a,[$d35d]
	and a
	ret nz
	jp GBFadeIn1

CheckIfInOutsideMap:: ; 08e1 (0:08e1)
; If the player is in an outside map (a town or route), set the z flag
	ld a, [W_CURMAPTILESET]
	and a ; most towns/routes have tileset 0 (OVERWORLD)
	ret z
	cp PLATEAU ; Route 23 / Indigo Plateau
	ret

; this function is an extra check that sometimes has to pass in order to warp, beyond just standing on a warp
; the "sometimes" qualification is necessary because of CheckWarpsNoCollision's behavior
; depending on the map, either "function 1" or "function 2" is used for the check
; "function 1" passes when the player is at the edge of the map and is facing towards the outside of the map
; "function 2" passes when the the tile in front of the player is among a certain set
; sets carry if the check passes, otherwise clears carry
ExtraWarpCheck:: ; 08e9 (0:08e9)
	ld a, [W_CURMAP]
	cp SS_ANNE_3
	jr z, .useFunction1
	cp ROCKET_HIDEOUT_1
	jr z, .useFunction2
	cp ROCKET_HIDEOUT_2
	jr z, .useFunction2
	cp ROCKET_HIDEOUT_4
	jr z, .useFunction2
	cp ROCK_TUNNEL_1
	jr z, .useFunction2
	ld a, [W_CURMAPTILESET]
	and a ; outside tileset (OVERWORLD)
	jr z, .useFunction2
	cp SHIP ; S.S. Anne tileset
	jr z, .useFunction2
	cp SHIP_PORT ; Vermilion Port tileset
	jr z, .useFunction2
	cp PLATEAU ; Indigo Plateau tileset
	jr z, .useFunction2
.useFunction1
	ld hl, Func_c3ff
	jr .doBankswitch
.useFunction2
	ld hl, Func_c44e
.doBankswitch
	ld b, BANK(Func_c44e)
	jp Bankswitch

MapEntryAfterBattle:: ; 091f (0:091f)
	callba Func_c35f ; function that appears to disable warp testing after collisions if the player is standing on a warp
	ld a,[$d35d]
	and a
	jp z,GBFadeIn2
	jp LoadGBPal

; for when all the player's pokemon faint
; other code prints the "you blacked out" message before this is called
HandleBlackOut:: ; 0931 (0:0931)
	call GBFadeIn1
	ld a,$08
	call StopMusic
	ld hl,$d72e
	res 5,[hl]
	ld a,Bank(Func_40b0) ; Bank(Func_40b0) and Bank(Func_62ce) need to be equal.
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call Func_40b0
	call Func_62ce
	call Func_2312
	jp Func_5d5f

StopMusic:: ; 0951 (0:0951)
	ld [wMusicHeaderPointer],a
	ld a,$ff
	ld [$c0ee],a
	call PlaySound
.waitLoop
	ld a,[wMusicHeaderPointer]
	and a
	jr nz,.waitLoop
	jp StopAllSounds

HandleFlyOrTeleportAway:: ; 0965 (0:0965)
	call UpdateSprites ; move sprites
	call Delay3
	xor a
	ld [$cf0b],a
	ld [$d700],a
	ld [$d057],a
	ld [$d35d],a
	ld hl,$d732
	set 2,[hl]
	res 5,[hl]
	call DoFlyOrTeleportAwayGraphics
	ld a,Bank(Func_62ce)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call Func_62ce
	jp Func_5d5f

; function that calls a function to do fly away or teleport away graphics
DoFlyOrTeleportAwayGraphics:: ; 098f (0:098f)
	ld b, BANK(_DoFlyOrTeleportAwayGraphics)
	ld hl, _DoFlyOrTeleportAwayGraphics
	jp Bankswitch

; load sprite graphics based on whether the player is standing, biking, or surfing
LoadPlayerSpriteGraphics:: ; 0997 (0:0997)
	ld a,[$d700]
	dec a
	jr z,.ridingBike
	ld a,[$ffd7]
	and a
	jr nz,.determineGraphics
	jr .startWalking
.ridingBike
	call IsBikeRidingAllowed
	jr c,.determineGraphics ; don't start walking if bike riding is allowed
.startWalking
	xor a
	ld [$d700],a
	ld [$d11a],a
	jp LoadWalkingPlayerSpriteGraphics
.determineGraphics
	ld a,[$d700]
	and a
	jp z,LoadWalkingPlayerSpriteGraphics
	dec a
	jp z,LoadBikePlayerSpriteGraphics
	dec a
	jp z,LoadSurfingPlayerSpriteGraphics
	jp LoadWalkingPlayerSpriteGraphics

; function to check if bike riding is allowed on the current map
; sets carry if bike is allowed, clears carry otherwise
IsBikeRidingAllowed:: ; 09c5 (0:09c5)
	ld a,[W_CURMAP]
	cp a,ROUTE_23
	jr z,.allowed
	cp a,INDIGO_PLATEAU
	jr z,.allowed
	ld a,[W_CURMAPTILESET]
	ld b,a
	ld hl,BikeRidingTilesets
.loop
	ld a,[hli]
	cp b
	jr z,.allowed
	inc a
	jr nz,.loop
	and a
	ret
.allowed
	scf
	ret

INCLUDE "data/bike_riding_tilesets.asm"

; load the tile pattern data of the current tileset into VRAM
LoadTilesetTilePatternData:: ; 09e8 (0:09e8)
	ld a,[$d52e]
	ld l,a
	ld a,[$d52f]
	ld h,a
	ld de,$9000
	ld bc,$0600
	ld a,[$d52b]
	jp FarCopyData2

; this loads the current maps complete tile map (which references blocks, not individual tiles) to C6E8
; it can also load partial tile maps of connected maps into a border of length 3 around the current map
LoadTileBlockMap:: ; 09fc (0:09fc)
; fill C6E8-CBFB with the background tile
	ld hl,$c6e8
	ld a,[$d3ad] ; background tile number
	ld d,a
	ld bc,$0514
.backgroundTileLoop
	ld a,d
	ld [hli],a
	dec bc
	ld a,c
	or b
	jr nz,.backgroundTileLoop
; load tile map of current map (made of tile block IDs)
; a 3-byte border at the edges of the map is kept so that there is space for map connections
	ld hl,$c6e8
	ld a,[W_CURMAPWIDTH]
	ld [$ff8c],a
	add a,$06 ; border (east and west)
	ld [$ff8b],a ; map width + border
	ld b,$00
	ld c,a
; make space for north border (next 3 lines)
	add hl,bc
	add hl,bc
	add hl,bc
	ld c,$03
	add hl,bc ; this puts us past the (west) border
	ld a,[$d36a] ; tile map pointer
	ld e,a
	ld a,[$d36b]
	ld d,a ; de = tile map pointer
	ld a,[W_CURMAPHEIGHT]
	ld b,a
.rowLoop ; copy one row each iteration
	push hl
	ld a,[$ff8c] ; map width (without border)
	ld c,a
.rowInnerLoop
	ld a,[de]
	inc de
	ld [hli],a
	dec c
	jr nz,.rowInnerLoop
; add the map width plus the border to the base address of the current row to get the next row's address
	pop hl
	ld a,[$ff8b] ; map width + border
	add l
	ld l,a
	jr nc,.noCarry
	inc h
.noCarry
	dec b
	jr nz,.rowLoop
.northConnection
	ld a,[$d371]
	cp a,$ff
	jr z,.southConnection
	call SwitchToMapRomBank
	ld a,[$d372]
	ld l,a
	ld a,[$d373]
	ld h,a
	ld a,[$d374]
	ld e,a
	ld a,[$d375]
	ld d,a
	ld a,[$d376]
	ld [$ff8b],a
	ld a,[$d377]
	ld [$ff8c],a
	call LoadNorthSouthConnectionsTileMap
.southConnection
	ld a,[$d37c]
	cp a,$ff
	jr z,.westConnection
	call SwitchToMapRomBank
	ld a,[$d37d]
	ld l,a
	ld a,[$d37e]
	ld h,a
	ld a,[$d37f]
	ld e,a
	ld a,[$d380]
	ld d,a
	ld a,[$d381]
	ld [$ff8b],a
	ld a,[$d382]
	ld [$ff8c],a
	call LoadNorthSouthConnectionsTileMap
.westConnection
	ld a,[$d387]
	cp a,$ff
	jr z,.eastConnection
	call SwitchToMapRomBank
	ld a,[$d388]
	ld l,a
	ld a,[$d389]
	ld h,a
	ld a,[$d38a]
	ld e,a
	ld a,[$d38b]
	ld d,a
	ld a,[$d38c]
	ld b,a
	ld a,[$d38d]
	ld [$ff8b],a
	call LoadEastWestConnectionsTileMap
.eastConnection
	ld a,[$d392]
	cp a,$ff
	jr z,.done
	call SwitchToMapRomBank
	ld a,[$d393]
	ld l,a
	ld a,[$d394]
	ld h,a
	ld a,[$d395]
	ld e,a
	ld a,[$d396]
	ld d,a
	ld a,[$d397]
	ld b,a
	ld a,[$d398]
	ld [$ff8b],a
	call LoadEastWestConnectionsTileMap
.done
	ret

LoadNorthSouthConnectionsTileMap:: ; 0ade (0:0ade)
	ld c,$03
.loop
	push de
	push hl
	ld a,[$ff8b] ; width of connection
	ld b,a
.innerLoop
	ld a,[hli]
	ld [de],a
	inc de
	dec b
	jr nz,.innerLoop
	pop hl
	pop de
	ld a,[$ff8c] ; width of connected map
	add l
	ld l,a
	jr nc,.noCarry1
	inc h
.noCarry1
	ld a,[W_CURMAPWIDTH]
	add a,$06
	add e
	ld e,a
	jr nc,.noCarry2
	inc d
.noCarry2
	dec c
	jr nz,.loop
	ret

LoadEastWestConnectionsTileMap:: ; 0b02 (0:0b02)
	push hl
	push de
	ld c,$03
.innerLoop
	ld a,[hli]
	ld [de],a
	inc de
	dec c
	jr nz,.innerLoop
	pop de
	pop hl
	ld a,[$ff8b] ; width of connected map
	add l
	ld l,a
	jr nc,.noCarry1
	inc h
.noCarry1
	ld a,[W_CURMAPWIDTH]
	add a,$06
	add e
	ld e,a
	jr nc,.noCarry2
	inc d
.noCarry2
	dec b
	jr nz,LoadEastWestConnectionsTileMap
	ret

; function to check if there is a sign or sprite in front of the player
; if so, it is stored in [$FF8C]
; if not, [$FF8C] is set to 0
IsSpriteOrSignInFrontOfPlayer:: ; 0b23 (0:0b23)
	xor a
	ld [$ff8c],a
	ld a,[$d4b0] ; number of signs in the map
	and a
	jr z,.extendRangeOverCounter
; if there are signs
	ld a,$35
	call Predef ; get the coordinates in front of the player in de
	ld hl,$d4b1 ; start of sign coordinates
	ld a,[$d4b0] ; number of signs in the map
	ld b,a
	ld c,$00
.signLoop
	inc c
	ld a,[hli] ; sign Y
	cp d
	jr z,.yCoordMatched
	inc hl
	jr .retry
.yCoordMatched
	ld a,[hli] ; sign X
	cp e
	jr nz,.retry
.xCoordMatched
; found sign
	push hl
	push bc
	ld hl,$d4d1 ; start of sign text ID's
	ld b,$00
	dec c
	add hl,bc
	ld a,[hl]
	ld [$ff8c],a ; store sign text ID
	pop bc
	pop hl
	ret
.retry
	dec b
	jr nz,.signLoop
; check if the player is front of a counter in a pokemon center, pokemart, etc. and if so, extend the range at which he can talk to the NPC
.extendRangeOverCounter
	ld a,$35
	call Predef ; get the tile in front of the player in c
	ld hl,$d532 ; list of tiles that extend talking range (counter tiles)
	ld b,$03
	ld d,$20 ; talking range in pixels (long range)
.counterTilesLoop
	ld a,[hli]
	cp c
	jr z,IsSpriteInFrontOfPlayer2 ; jumps if the tile in front of the player is a counter tile
	dec b
	jr nz,.counterTilesLoop

; part of the above function, but sometimes its called on its own, when signs are irrelevant
; the caller must zero [$FF8C]
IsSpriteInFrontOfPlayer:: ; 0b6b (0:0b6b)
	ld d,$10 ; talking range in pixels (normal range)
IsSpriteInFrontOfPlayer2:: ; 0b6d (0:0b6d)
	ld bc,$3c40 ; Y and X position of player sprite
	ld a,[$c109] ; direction the player is facing
.checkIfPlayerFacingUp
	cp a,$04
	jr nz,.checkIfPlayerFacingDown
; facing up
	ld a,b
	sub d
	ld b,a
	ld a,$08
	jr .doneCheckingDirection
.checkIfPlayerFacingDown
	cp a,$00
	jr nz,.checkIfPlayerFacingRight
; facing down
	ld a,b
	add d
	ld b,a
	ld a,$04
	jr .doneCheckingDirection
.checkIfPlayerFacingRight
	cp a,$0c
	jr nz,.playerFacingLeft
; facing right
	ld a,c
	add d
	ld c,a
	ld a,$01
	jr .doneCheckingDirection
.playerFacingLeft
; facing left
	ld a,c
	sub d
	ld c,a
	ld a,$02
.doneCheckingDirection
	ld [$d52a],a
	ld a,[$d4e1] ; number of sprites
	and a
	ret z
; if there are sprites
	ld hl,$c110
	ld d,a
	ld e,$01
.spriteLoop
	push hl
	ld a,[hli] ; image (0 if no sprite)
	and a
	jr z,.nextSprite
	inc l
	ld a,[hli] ; sprite visibility
	inc a
	jr z,.nextSprite
	inc l
	ld a,[hli] ; Y location
	cp b
	jr nz,.nextSprite
	inc l
	ld a,[hl] ; X location
	cp c
	jr z,.foundSpriteInFrontOfPlayer
.nextSprite
	pop hl
	ld a,l
	add a,$10
	ld l,a
	inc e
	dec d
	jr nz,.spriteLoop
	ret
.foundSpriteInFrontOfPlayer
	pop hl
	ld a,l
	and a,$f0
	inc a
	ld l,a
	set 7,[hl]
	ld a,e
	ld [$ff8c],a ; store sprite ID
	ret

; function to check if the player will jump down a ledge and check if the tile ahead is passable (when not surfing)
; sets the carry flag if there is a collision, and unsets it if there isn't a collision
CollisionCheckOnLand:: ; 0bd1 (0:0bd1)
	ld a,[$d736]
	bit 6,a ; is the player jumping?
	jr nz,.noCollision
; if not jumping a ledge
	ld a,[$cd38]
	and a
	jr nz,.noCollision
	ld a,[$d52a] ; the direction that the player is trying to go in
	ld d,a
	ld a,[$c10c] ; the player sprite's collision data (bit field) (set in the sprite movement code)
	and d ; check if a sprite is in the direction the player is trying to go
	jr nz,.collision
	xor a
	ld [$ff8c],a
	call IsSpriteInFrontOfPlayer ; check for sprite collisions again? when does the above check fail to detect a sprite collision?
	ld a,[$ff8c]
	and a ; was there a sprite collision?
	jr nz,.collision
; if no sprite collision
	ld hl,TilePairCollisionsLand
	call CheckForJumpingAndTilePairCollisions
	jr c,.collision
	call CheckTilePassable
	jr nc,.noCollision
.collision
	ld a,[$c02a]
	cp a,(SFX_02_5b - SFX_Headers_02) / 3 ; check if collision sound is already playing
	jr z,.setCarry
	ld a,(SFX_02_5b - SFX_Headers_02) / 3
	call PlaySound ; play collision sound (if it's not already playing)
.setCarry
	scf
	ret
.noCollision
	and a
	ret

; function that checks if the tile in front of the player is passable
; clears carry if it is, sets carry if not
CheckTilePassable:: ; 0c10 (0:0c10)
	ld a,$35
	call Predef ; get tile in front of player
	ld a,[$cfc6] ; tile in front of player
	ld c,a
	ld hl,$d530 ; pointer to list of passable tiles
	ld a,[hli]
	ld h,[hl]
	ld l,a ; hl now points to passable tiles
.loop
	ld a,[hli]
	cp a,$ff
	jr z,.tileNotPassable
	cp c
	ret z
	jr .loop
.tileNotPassable
	scf
	ret

; check if the player is going to jump down a small ledge
; and check for collisions that only occur between certain pairs of tiles
; Input: hl - address of directional collision data
; sets carry if there is a collision and unsets carry if not
CheckForJumpingAndTilePairCollisions:: ; 0c2a (0:0c2a)
	push hl
	ld a,$35
	call Predef ; get the tile in front of the player
	push de
	push bc
	callba Func_1a672 ; check if the player is trying to jump a ledge
	pop bc
	pop de
	pop hl
	and a
	ld a,[$d736]
	bit 6,a ; is the player jumping?
	ret nz
; if not jumping

Func_c44:: ; 0c44 (0:0c44)
	FuncCoord 8, 9 ; $c45c
	ld a,[Coord] ; tile the player is on
	ld [$cf0e],a

CheckForTilePairCollisions:: ; 0c4a (0:0c4a)
	ld a,[$cfc6] ; tile in front of the player
	ld c,a
.tilePairCollisionLoop
	ld a,[W_CURMAPTILESET] ; tileset number
	ld b,a
	ld a,[hli]
	cp a,$ff
	jr z,.noMatch
	cp b
	jr z,.tilesetMatches
	inc hl
.retry
	inc hl
	jr .tilePairCollisionLoop
.tilesetMatches
	ld a,[$cf0e] ; tile the player is on
	ld b,a
	ld a,[hl]
	cp b
	jr z,.currentTileMatchesFirstInPair
	inc hl
	ld a,[hl]
	cp b
	jr z,.currentTileMatchesSecondInPair
	jr .retry
.currentTileMatchesFirstInPair
	inc hl
	ld a,[hl]
	cp c
	jr z,.foundMatch
	jr .tilePairCollisionLoop
.currentTileMatchesSecondInPair
	dec hl
	ld a,[hli]
	cp c
	inc hl
	jr nz,.tilePairCollisionLoop
.foundMatch
	scf
	ret
.noMatch
	and a
	ret

; FORMAT: tileset number, tile 1, tile 2
; terminated by 0xFF
; these entries indicate that the player may not cross between tile 1 and tile 2
; it's mainly used to simulate differences in elevation

TilePairCollisionsLand:: ; 0c7e (0:0c7e)
	db CAVERN, $20, $05
	db CAVERN, $41, $05
	db FOREST, $30, $2E
	db CAVERN, $2A, $05
	db CAVERN, $05, $21
	db FOREST, $52, $2E
	db FOREST, $55, $2E
	db FOREST, $56, $2E
	db FOREST, $20, $2E
	db FOREST, $5E, $2E
	db FOREST, $5F, $2E
	db $FF

TilePairCollisionsWater:: ; 0ca0 (0:0ca0)
	db FOREST, $14, $2E
	db FOREST, $48, $2E
	db CAVERN, $14, $05
	db $FF

; this builds a tile map from the tile block map based on the current X/Y coordinates of the player's character
LoadCurrentMapView:: ; 0caa (0:0caa)
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,[$d52b] ; tile data ROM bank
	ld [H_LOADEDROMBANK],a
	ld [$2000],a ; switch to ROM bank that contains tile data
	ld a,[$d35f] ; address of upper left corner of current map view
	ld e,a
	ld a,[$d360]
	ld d,a
	ld hl,wTileMapBackup
	ld b,$05
.rowLoop ; each loop iteration fills in one row of tile blocks
	push hl
	push de
	ld c,$06
.rowInnerLoop ; loop to draw each tile block of the current row
	push bc
	push de
	push hl
	ld a,[de]
	ld c,a ; tile block number
	call DrawTileBlock
	pop hl
	pop de
	pop bc
	inc hl
	inc hl
	inc hl
	inc hl
	inc de
	dec c
	jr nz,.rowInnerLoop
; update tile block map pointer to next row's address
	pop de
	ld a,[W_CURMAPWIDTH]
	add a,$06
	add e
	ld e,a
	jr nc,.noCarry
	inc d
.noCarry
; update tile map pointer to next row's address
	pop hl
	ld a,$60
	add l
	ld l,a
	jr nc,.noCarry2
	inc h
.noCarry2
	dec b
	jr nz,.rowLoop
	ld hl,wTileMapBackup
	ld bc,$0000
.adjustForYCoordWithinTileBlock
	ld a,[W_YBLOCKCOORD]
	and a
	jr z,.adjustForXCoordWithinTileBlock
	ld bc,$0030
	add hl,bc
.adjustForXCoordWithinTileBlock
	ld a,[W_XBLOCKCOORD]
	and a
	jr z,.copyToVisibleAreaBuffer
	ld bc,$0002
	add hl,bc
.copyToVisibleAreaBuffer
	ld de,wTileMap ; base address for the tiles that are directly transfered to VRAM during V-blank
	ld b,$12
.rowLoop2
	ld c,$14
.rowInnerLoop2
	ld a,[hli]
	ld [de],a
	inc de
	dec c
	jr nz,.rowInnerLoop2
	ld a,$04
	add l
	ld l,a
	jr nc,.noCarry3
	inc h
.noCarry3
	dec b
	jr nz,.rowLoop2
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a ; restore previous ROM bank
	ret

AdvancePlayerSprite:: ; 0d27 (0:0d27)
	ld a,[$c103] ; delta Y
	ld b,a
	ld a,[$c105] ; delta X
	ld c,a
	ld hl,wWalkCounter ; walking animation counter
	dec [hl]
	jr nz,.afterUpdateMapCoords
; if it's the end of the animation, update the player's map coordinates
	ld a,[W_YCOORD]
	add b
	ld [W_YCOORD],a
	ld a,[W_XCOORD]
	add c
	ld [W_XCOORD],a
.afterUpdateMapCoords
	ld a,[wWalkCounter] ; walking animation counter
	cp a,$07
	jp nz,.scrollBackgroundAndSprites
; if this is the first iteration of the animation
	ld a,c
	cp a,$01
	jr nz,.checkIfMovingWest
; moving east
	ld a,[$d526]
	ld e,a
	and a,$e0
	ld d,a
	ld a,e
	add a,$02
	and a,$1f
	or d
	ld [$d526],a
	jr .adjustXCoordWithinBlock
.checkIfMovingWest
	cp a,$ff
	jr nz,.checkIfMovingSouth
; moving west
	ld a,[$d526]
	ld e,a
	and a,$e0
	ld d,a
	ld a,e
	sub a,$02
	and a,$1f
	or d
	ld [$d526],a
	jr .adjustXCoordWithinBlock
.checkIfMovingSouth
	ld a,b
	cp a,$01
	jr nz,.checkIfMovingNorth
; moving south
	ld a,[$d526]
	add a,$40
	ld [$d526],a
	jr nc,.adjustXCoordWithinBlock
	ld a,[$d527]
	inc a
	and a,$03
	or a,$98
	ld [$d527],a
	jr .adjustXCoordWithinBlock
.checkIfMovingNorth
	cp a,$ff
	jr nz,.adjustXCoordWithinBlock
; moving north
	ld a,[$d526]
	sub a,$40
	ld [$d526],a
	jr nc,.adjustXCoordWithinBlock
	ld a,[$d527]
	dec a
	and a,$03
	or a,$98
	ld [$d527],a
.adjustXCoordWithinBlock
	ld a,c
	and a
	jr z,.pointlessJump ; mistake?
.pointlessJump
	ld hl,W_XBLOCKCOORD
	ld a,[hl]
	add c
	ld [hl],a
	cp a,$02
	jr nz,.checkForMoveToWestBlock
; moved into the tile block to the east
	xor a
	ld [hl],a
	ld hl,$d4e3
	inc [hl]
	ld de,$d35f
	call MoveTileBlockMapPointerEast
	jr .updateMapView
.checkForMoveToWestBlock
	cp a,$ff
	jr nz,.adjustYCoordWithinBlock
; moved into the tile block to the west
	ld a,$01
	ld [hl],a
	ld hl,$d4e3
	dec [hl]
	ld de,$d35f
	call MoveTileBlockMapPointerWest
	jr .updateMapView
.adjustYCoordWithinBlock
	ld hl,W_YBLOCKCOORD
	ld a,[hl]
	add b
	ld [hl],a
	cp a,$02
	jr nz,.checkForMoveToNorthBlock
; moved into the tile block to the south
	xor a
	ld [hl],a
	ld hl,$d4e2
	inc [hl]
	ld de,$d35f
	ld a,[W_CURMAPWIDTH]
	call MoveTileBlockMapPointerSouth
	jr .updateMapView
.checkForMoveToNorthBlock
	cp a,$ff
	jr nz,.updateMapView
; moved into the tile block to the north
	ld a,$01
	ld [hl],a
	ld hl,$d4e2
	dec [hl]
	ld de,$d35f
	ld a,[W_CURMAPWIDTH]
	call MoveTileBlockMapPointerNorth
.updateMapView
	call LoadCurrentMapView
	ld a,[$c103] ; delta Y
	cp a,$01
	jr nz,.checkIfMovingNorth2
; if moving south
	call ScheduleSouthRowRedraw
	jr .scrollBackgroundAndSprites
.checkIfMovingNorth2
	cp a,$ff
	jr nz,.checkIfMovingEast2
; if moving north
	call ScheduleNorthRowRedraw
	jr .scrollBackgroundAndSprites
.checkIfMovingEast2
	ld a,[$c105] ; delta X
	cp a,$01
	jr nz,.checkIfMovingWest2
; if moving east
	call ScheduleEastColumnRedraw
	jr .scrollBackgroundAndSprites
.checkIfMovingWest2
	cp a,$ff
	jr nz,.scrollBackgroundAndSprites
; if moving west
	call ScheduleWestColumnRedraw
.scrollBackgroundAndSprites
	ld a,[$c103] ; delta Y
	ld b,a
	ld a,[$c105] ; delta X
	ld c,a
	sla b
	sla c
	ld a,[$ffaf]
	add b
	ld [$ffaf],a ; update background scroll Y
	ld a,[$ffae]
	add c
	ld [$ffae],a ; update background scroll X
; shift all the sprites in the direction opposite of the player's motion
; so that the player appears to move relative to them
	ld hl,$c114
	ld a,[$d4e1] ; number of sprites
	and a ; are there any sprites?
	jr z,.done
	ld e,a
.spriteShiftLoop
	ld a,[hl]
	sub b
	ld [hli],a
	inc l
	ld a,[hl]
	sub c
	ld [hl],a
	ld a,$0e
	add l
	ld l,a
	dec e
	jr nz,.spriteShiftLoop
.done
	ret

; the following four functions are used to move the pointer to the upper left
; corner of the tile block map in the direction of motion

MoveTileBlockMapPointerEast:: ; 0e65 (0:0e65)
	ld a,[de]
	add a,$01
	ld [de],a
	ret nc
	inc de
	ld a,[de]
	inc a
	ld [de],a
	ret

MoveTileBlockMapPointerWest:: ; 0e6f (0:0e6f)
	ld a,[de]
	sub a,$01
	ld [de],a
	ret nc
	inc de
	ld a,[de]
	dec a
	ld [de],a
	ret

MoveTileBlockMapPointerSouth:: ; 0e79 (0:0e79)
	add a,$06
	ld b,a
	ld a,[de]
	add b
	ld [de],a
	ret nc
	inc de
	ld a,[de]
	inc a
	ld [de],a
	ret

MoveTileBlockMapPointerNorth:: ; 0e85 (0:0e85)
	add a,$06
	ld b,a
	ld a,[de]
	sub b
	ld [de],a
	ret nc
	inc de
	ld a,[de]
	dec a
	ld [de],a
	ret

; the following 6 functions are used to tell the V-blank handler to redraw
; the portion of the map that was newly exposed due to the player's movement

ScheduleNorthRowRedraw:: ; 0e91 (0:0e91)
	FuncCoord 0, 0
	ld hl,Coord
	call ScheduleRowRedrawHelper
	ld a,[$d526]
	ld [H_SCREENEDGEREDRAWADDR],a
	ld a,[$d527]
	ld [H_SCREENEDGEREDRAWADDR + 1],a
	ld a,REDRAWROW
	ld [H_SCREENEDGEREDRAW],a
	ret

ScheduleRowRedrawHelper:: ; 0ea6 (0:0ea6)
	ld de,wScreenEdgeTiles
	ld c,$28
.loop
	ld a,[hli]
	ld [de],a
	inc de
	dec c
	jr nz,.loop
	ret

ScheduleSouthRowRedraw:: ; 0eb2 (0:0eb2)
	FuncCoord 0,16
	ld hl,Coord
	call ScheduleRowRedrawHelper
	ld a,[$d526]
	ld l,a
	ld a,[$d527]
	ld h,a
	ld bc,$0200
	add hl,bc
	ld a,h
	and a,$03
	or a,$98
	ld [H_SCREENEDGEREDRAWADDR + 1],a
	ld a,l
	ld [H_SCREENEDGEREDRAWADDR],a
	ld a,REDRAWROW
	ld [H_SCREENEDGEREDRAW],a
	ret

ScheduleEastColumnRedraw:: ; 0ed3 (0:0ed3)
	FuncCoord 18,0
	ld hl,Coord
	call ScheduleColumnRedrawHelper
	ld a,[$d526]
	ld c,a
	and a,$e0
	ld b,a
	ld a,c
	add a,18
	and a,$1f
	or b
	ld [H_SCREENEDGEREDRAWADDR],a
	ld a,[$d527]
	ld [H_SCREENEDGEREDRAWADDR + 1],a
	ld a,REDRAWCOL
	ld [H_SCREENEDGEREDRAW],a
	ret

ScheduleColumnRedrawHelper:: ; 0ef2 (0:0ef2)
	ld de,wScreenEdgeTiles
	ld c,$12
.loop
	ld a,[hli]
	ld [de],a
	inc de
	ld a,[hl]
	ld [de],a
	inc de
	ld a,19
	add l
	ld l,a
	jr nc,.noCarry
	inc h
.noCarry
	dec c
	jr nz,.loop
	ret

ScheduleWestColumnRedraw:: ; 0f08 (0:0f08)
	FuncCoord 0,0
	ld hl,Coord
	call ScheduleColumnRedrawHelper
	ld a,[$d526]
	ld [H_SCREENEDGEREDRAWADDR],a
	ld a,[$d527]
	ld [H_SCREENEDGEREDRAWADDR + 1],a
	ld a,REDRAWCOL
	ld [H_SCREENEDGEREDRAW],a
	ret

; function to write the tiles that make up a tile block to memory
; Input: c = tile block ID, hl = destination address
DrawTileBlock:: ; 0f1d (0:0f1d)
	push hl
	ld a,[$d52c] ; pointer to tiles
	ld l,a
	ld a,[$d52d]
	ld h,a
	ld a,c
	swap a
	ld b,a
	and a,$f0
	ld c,a
	ld a,b
	and a,$0f
	ld b,a ; bc = tile block ID * 0x10
	add hl,bc
	ld d,h
	ld e,l ; de = address of the tile block's tiles
	pop hl
	ld c,$04 ; 4 loop iterations
.loop ; each loop iteration, write 4 tile numbers
	push bc
	ld a,[de]
	ld [hli],a
	inc de
	ld a,[de]
	ld [hli],a
	inc de
	ld a,[de]
	ld [hli],a
	inc de
	ld a,[de]
	ld [hl],a
	inc de
	ld bc,$0015
	add hl,bc
	pop bc
	dec c
	jr nz,.loop
	ret

; function to update joypad state and simulate button presses
GetJoypadStateOverworld:: ; 0f4d (0:0f4d)
	xor a
	ld [$c103],a
	ld [$c105],a
	call RunMapScript
	call GetJoypadState
	ld a,[W_FLAGS_D733]
	bit 3,a ; check if a trainer wants a challenge
	jr nz,.notForcedDownwards
	ld a,[W_CURMAP]
	cp a,ROUTE_17 ; Cycling Road
	jr nz,.notForcedDownwards
	ld a,[H_CURRENTPRESSEDBUTTONS] ; current joypad state
	and a,%11110011 ; bit mask for all directions and A/B
	jr nz,.notForcedDownwards
	ld a,%10000000 ; down pressed
	ld [H_CURRENTPRESSEDBUTTONS],a ; on the cycling road, if there isn't a trainer and the player isn't pressing buttons, simulate a down press
.notForcedDownwards
	ld a,[$d730]
	bit 7,a
	ret z
; if simulating button presses
	ld a,[H_CURRENTPRESSEDBUTTONS] ; current joypad state
	ld b,a
	ld a,[$cd3b] ; bit mask for button presses that override simulated ones
	and b
	ret nz ; return if the simulated button presses are overridden
	ld hl,$cd38 ; index of current simulated button press
	dec [hl]
	ld a,[hl]
	cp a,$ff
	jr z,.doneSimulating ; if the end of the simulated button presses has been reached
	ld hl,$ccd3 ; base address of simulated button presses
; add offset to base address
	add l
	ld l,a
	jr nc,.noCarry
	inc h
.noCarry
	ld a,[hl]
	ld [H_CURRENTPRESSEDBUTTONS],a ; store simulated button press in joypad state
	and a
	ret nz
	ld [H_NEWLYPRESSEDBUTTONS],a
	ld [H_NEWLYRELEASEDBUTTONS],a
	ret
; if done simulating button presses
.doneSimulating
	xor a
	ld [$cd3a],a
	ld [$cd38],a
	ld [$ccd3],a
	ld [wJoypadForbiddenButtonsMask],a
	ld [H_CURRENTPRESSEDBUTTONS],a
	ld hl,$d736
	ld a,[hl]
	and a,$f8
	ld [hl],a
	ld hl,$d730
	res 7,[hl]
	ret

; function to check the tile ahead to determine if the character should get on land or keep surfing
; sets carry if there is a collision and clears carry otherwise
; It seems that this function has a bug in it, but due to luck, it doesn't
; show up. After detecting a sprite collision, it jumps to the code that
; checks if the next tile is passable instead of just directly jumping to the
; "collision detected" code. However, it doesn't store the next tile in c,
; so the old value of c is used. 2429 is always called before this function,
; and 2429 always sets c to 0xF0. There is no 0xF0 background tile, so it
; is considered impassable and it is detected as a collision.
CollisionCheckOnWater:: ; 0fb7 (0:0fb7)
	ld a,[$d730]
	bit 7,a
	jp nz,.noCollision ; return and clear carry if button presses are being simulated
	ld a,[$d52a] ; the direction that the player is trying to go in
	ld d,a
	ld a,[$c10c] ; the player sprite's collision data (bit field) (set in the sprite movement code)
	and d ; check if a sprite is in the direction the player is trying to go
	jr nz,.checkIfNextTileIsPassable ; bug?
	ld hl,TilePairCollisionsWater
	call CheckForJumpingAndTilePairCollisions
	jr c,.collision
	ld a,$35
	call Predef ; get tile in front of player (puts it in c and [$CFC6])
	ld a,[$cfc6] ; tile in front of player
	cp a,$14 ; water tile
	jr z,.noCollision ; keep surfing if it's a water tile
	cp a,$32 ; either the left tile of the S.S. Anne boarding platform or the tile on eastern coastlines (depending on the current tileset)
	jr z,.checkIfVermilionDockTileset
	cp a,$48 ; tile on right on coast lines in Safari Zone
	jr z,.noCollision ; keep surfing
; check if the [land] tile in front of the player is passable
.checkIfNextTileIsPassable
	ld hl,$d530 ; pointer to list of passable tiles
	ld a,[hli]
	ld h,[hl]
	ld l,a
.loop
	ld a,[hli]
	cp a,$ff
	jr z,.collision
	cp c
	jr z,.stopSurfing ; stop surfing if the tile is passable
	jr .loop
.collision
	ld a,[$c02a]
	cp a,(SFX_02_5b - SFX_Headers_02) / 3 ; check if collision sound is already playing
	jr z,.setCarry
	ld a,(SFX_02_5b - SFX_Headers_02) / 3
	call PlaySound ; play collision sound (if it's not already playing)
.setCarry
	scf
	jr .done
.noCollision
	and a
.done
	ret
.stopSurfing
	xor a
	ld [$d700],a
	call LoadPlayerSpriteGraphics
	call Func_2307
	jr .noCollision
.checkIfVermilionDockTileset
	ld a, [W_CURMAPTILESET] ; tileset
	cp SHIP_PORT ; Vermilion Dock tileset
	jr nz, .noCollision ; keep surfing if it's not the boarding platform tile
	jr .stopSurfing ; if it is the boarding platform tile, stop surfing

; function to run the current map's script
RunMapScript:: ; 101b (0:101b)
	push hl
	push de
	push bc
	callba Func_f225 ; check if the player is pushing a boulder
	ld a,[wFlags_0xcd60]
	bit 1,a ; is the player pushing a boulder?
	jr z,.afterBoulderEffect
	callba Func_f2b5 ; displays dust effect when pushing a boulder
.afterBoulderEffect
	pop bc
	pop de
	pop hl
	call Func_310e
	ld a,[W_CURMAP] ; current map number
	call SwitchToMapRomBank ; change to the ROM bank the map's data is in
	ld hl,W_MAPSCRIPTPTR
	ld a,[hli]
	ld h,[hl]
	ld l,a
	ld de,.return
	push de
	jp [hl] ; jump to script
.return
	ret

LoadWalkingPlayerSpriteGraphics:: ; 104d (0:104d)
	ld de,RedSprite ; $4180
	ld hl,$8000
	jr LoadPlayerSpriteGraphicsCommon

LoadSurfingPlayerSpriteGraphics:: ; 1055 (0:1055)
	ld de,SeelSprite
	ld hl,$8000
	jr LoadPlayerSpriteGraphicsCommon

LoadBikePlayerSpriteGraphics:: ; 105d (0:105d)
	ld de,RedCyclingSprite
	ld hl,$8000

LoadPlayerSpriteGraphicsCommon:: ; 1063 (0:1063)
	push de
	push hl
	ld bc,(BANK(RedSprite) << 8) + $0c
	call CopyVideoData
	pop hl
	pop de
	ld a,$c0
	add e
	ld e,a
	jr nc,.noCarry
	inc d
.noCarry
	set 3,h
	ld bc,$050c
	jp CopyVideoData

; function to load data from the map header
LoadMapHeader:: ; 107c (0:107c)
	callba Func_f113
	ld a,[W_CURMAPTILESET]
	ld [$d119],a
	ld a,[W_CURMAP]
	call SwitchToMapRomBank
	ld a,[W_CURMAPTILESET]
	ld b,a
	res 7,a
	ld [W_CURMAPTILESET],a
	ld [$ff8b],a
	bit 7,b
	ret nz
	ld hl,MapHeaderPointers
	ld a,[W_CURMAP]
	sla a
	jr nc,.noCarry1
	inc h
.noCarry1
	add l
	ld l,a
	jr nc,.noCarry2
	inc h
.noCarry2
	ld a,[hli]
	ld h,[hl]
	ld l,a ; hl = base of map header
; copy the first 10 bytes (the fixed area) of the map data to D367-D370
	ld de,$d367
	ld c,$0a
.copyFixedHeaderLoop
	ld a,[hli]
	ld [de],a
	inc de
	dec c
	jr nz,.copyFixedHeaderLoop
; initialize all the connected maps to disabled at first, before loading the actual values
	ld a,$ff
	ld [$d371],a
	ld [$d37c],a
	ld [$d387],a
	ld [$d392],a
; copy connection data (if any) to WRAM
	ld a,[W_MAPCONNECTIONS]
	ld b,a
.checkNorth
	bit 3,b
	jr z,.checkSouth
	ld de,W_MAPCONN1PTR
	call CopyMapConnectionHeader
.checkSouth
	bit 2,b
	jr z,.checkWest
	ld de,W_MAPCONN2PTR
	call CopyMapConnectionHeader
.checkWest
	bit 1,b
	jr z,.checkEast
	ld de,W_MAPCONN3PTR
	call CopyMapConnectionHeader
.checkEast
	bit 0,b
	jr z,.getObjectDataPointer
	ld de,W_MAPCONN4PTR
	call CopyMapConnectionHeader
.getObjectDataPointer
	ld a,[hli]
	ld [$d3a9],a
	ld a,[hli]
	ld [$d3aa],a
	push hl
	ld a,[$d3a9]
	ld l,a
	ld a,[$d3aa]
	ld h,a ; hl = base of object data
	ld de,$d3ad ; background tile ID
	ld a,[hli]
	ld [de],a ; save background tile ID
.loadWarpData
	ld a,[hli] ; number of warps
	ld [$d3ae],a ; save the number of warps
	and a ; are there any warps?
	jr z,.loadSignData ; if not, skip this
	ld c,a
	ld de,$d3af ; base address of warps
.warpLoop ; one warp per loop iteration
	ld b,$04
.warpInnerLoop
	ld a,[hli]
	ld [de],a
	inc de
	dec b
	jr nz,.warpInnerLoop
	dec c
	jr nz,.warpLoop
.loadSignData
	ld a,[hli] ; number of signs
	ld [$d4b0],a ; save the number of signs
	and a ; are there any signs?
	jr z,.loadSpriteData ; if not, skip this
	ld c,a
	ld de,$d4d1 ; base address of sign text IDs
	ld a,d
	ld [$ff95],a
	ld a,e
	ld [$ff96],a
	ld de,$d4b1 ; base address of sign coordinates
.signLoop
	ld a,[hli]
	ld [de],a
	inc de
	ld a,[hli]
	ld [de],a
	inc de
	push de
	ld a,[$ff95]
	ld d,a
	ld a,[$ff96]
	ld e,a
	ld a,[hli]
	ld [de],a
	inc de
	ld a,d
	ld [$ff95],a
	ld a,e
	ld [$ff96],a
	pop de
	dec c
	jr nz,.signLoop
.loadSpriteData
	ld a,[$d72e]
	bit 5,a ; did a battle happen immediately before this?
	jp nz,.finishUp ; if so, skip this because battles don't destroy this data
	ld a,[hli]
	ld [$d4e1],a ; save the number of sprites
	push hl
; zero C110-C1FF and C210-C2FF
	ld hl,$c110
	ld de,$c210
	xor a
	ld b,$f0
.zeroSpriteDataLoop
	ld [hli],a
	ld [de],a
	inc e
	dec b
	jr nz,.zeroSpriteDataLoop
; initialize all C100-C1FF sprite entries to disabled (other than player's)
	ld hl,$c112
	ld de,$0010
	ld c,$0f
.disableSpriteEntriesLoop
	ld [hl],$ff
	add hl,de
	dec c
	jr nz,.disableSpriteEntriesLoop
	pop hl
	ld de,$c110
	ld a,[$d4e1] ; number of sprites
	and a ; are there any sprites?
	jp z,.finishUp ; if there are no sprites, skip the rest
	ld b,a
	ld c,$00
.loadSpriteLoop
	ld a,[hli]
	ld [de],a ; store picture ID at C1X0
	inc d
	ld a,$04
	add e
	ld e,a
	ld a,[hli]
	ld [de],a ; store Y position at C2X4
	inc e
	ld a,[hli]
	ld [de],a ; store X position at C2X5
	inc e
	ld a,[hli]
	ld [de],a ; store movement byte 1 at C2X6
	ld a,[hli]
	ld [$ff8d],a ; save movement byte 2
	ld a,[hli]
	ld [$ff8e],a ; save text ID and flags byte
	push bc
	push hl
	ld b,$00
	ld hl,W_MAPSPRITEDATA
	add hl,bc
	ld a,[$ff8d]
	ld [hli],a ; store movement byte 2 in byte 0 of sprite entry
	ld a,[$ff8e]
	ld [hl],a ; this appears pointless, since the value is overwritten immediately after
	ld a,[$ff8e]
	ld [$ff8d],a
	and a,$3f
	ld [hl],a ; store text ID in byte 1 of sprite entry
	pop hl
	ld a,[$ff8d]
	bit 6,a
	jr nz,.trainerSprite
	bit 7,a
	jr nz,.itemBallSprite
	jr .regularSprite
.trainerSprite
	ld a,[hli]
	ld [$ff8d],a ; save trainer class
	ld a,[hli]
	ld [$ff8e],a ; save trainer number (within class)
	push hl
	ld hl,W_MAPSPRITEEXTRADATA
	add hl,bc
	ld a,[$ff8d]
	ld [hli],a ; store trainer class in byte 0 of the entry
	ld a,[$ff8e]
	ld [hl],a ; store trainer number in byte 1 of the entry
	pop hl
	jr .nextSprite
.itemBallSprite
	ld a,[hli]
	ld [$ff8d],a ; save item number
	push hl
	ld hl,W_MAPSPRITEEXTRADATA
	add hl,bc
	ld a,[$ff8d]
	ld [hli],a ; store item number in byte 0 of the entry
	xor a
	ld [hl],a ; zero byte 1, since it is not used
	pop hl
	jr .nextSprite
.regularSprite
	push hl
	ld hl,W_MAPSPRITEEXTRADATA
	add hl,bc
; zero both bytes, since regular sprites don't use this extra space
	xor a
	ld [hli],a
	ld [hl],a
	pop hl
.nextSprite
	pop bc
	dec d
	ld a,$0a
	add e
	ld e,a
	inc c
	inc c
	dec b
	jp nz,.loadSpriteLoop
.finishUp
	ld a,$19
	call Predef ; load tileset data
	callab LoadWildData ; load wild pokemon data
	pop hl ; restore hl from before going to the warp/sign/sprite data (this value was saved for seemingly no purpose)
	ld a,[W_CURMAPHEIGHT] ; map height in 4x4 tile blocks
	add a ; double it
	ld [$d524],a ; store map height in 2x2 tile blocks
	ld a,[W_CURMAPWIDTH] ; map width in 4x4 tile blocks
	add a ; double it
	ld [$d525],a ; map width in 2x2 tile blocks
	ld a,[W_CURMAP]
	ld c,a
	ld b,$00
	ld a,[H_LOADEDROMBANK]
	push af
	ld a, BANK(MapSongBanks)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ld hl, MapSongBanks
	add hl,bc
	add hl,bc
	ld a,[hli]
	ld [$d35b],a ; music 1
	ld a,[hl]
	ld [$d35c],a ; music 2
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; function to copy map connection data from ROM to WRAM
; Input: hl = source, de = destination
CopyMapConnectionHeader:: ; 1238 (0:1238)
	ld c,$0b
.loop
	ld a,[hli]
	ld [de],a
	inc de
	dec c
	jr nz,.loop
	ret

; function to load map data
LoadMapData:: ; 1241 (0:1241)
	ld a,[H_LOADEDROMBANK]
	push af
	call DisableLCD
	ld a,$98
	ld [$d527],a
	xor a
	ld [$d526],a
	ld [$ffaf],a
	ld [$ffae],a
	ld [wWalkCounter],a
	ld [$d119],a
	ld [$d11a],a
	ld [$d3a8],a
	call LoadTextBoxTilePatterns
	call LoadMapHeader
	callba InitMapSprites ; load tile pattern data for sprites
	call LoadTileBlockMap
	call LoadTilesetTilePatternData
	call LoadCurrentMapView
; copy current map view to VRAM
	ld hl,wTileMap
	ld de,$9800
	ld b,$12
.vramCopyLoop
	ld c,$14
.vramCopyInnerLoop
	ld a,[hli]
	ld [de],a
	inc e
	dec c
	jr nz,.vramCopyInnerLoop
	ld a,$0c
	add e
	ld e,a
	jr nc,.noCarry
	inc d
.noCarry
	dec b
	jr nz,.vramCopyLoop
	ld a,$01
	ld [$cfcb],a
	call EnableLCD
	ld b,$09
	call GoPAL_SET
	call LoadPlayerSpriteGraphics
	ld a,[$d732]
	and a,$18 ; did the player fly or teleport in?
	jr nz,.restoreRomBank
	ld a,[W_FLAGS_D733]
	bit 1,a
	jr nz,.restoreRomBank
	call Func_235f ; music related
	call Func_2312 ; music related
.restoreRomBank
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; function to switch to the ROM bank that a map is stored in
; Input: a = map number
SwitchToMapRomBank:: ; 12bc (0:12bc)
	push hl
	push bc
	ld c,a
	ld b,$00
	ld a,Bank(MapHeaderBanks)
	call BankswitchHome ; switch to ROM bank 3
	ld hl,MapHeaderBanks
	add hl,bc
	ld a,[hl]
	ld [$ffe8],a ; save map ROM bank
	call BankswitchBack
	ld a,[$ffe8]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a ; switch to map ROM bank
	pop bc
	pop hl
	ret

Func_12da:: ; 12da (0:12da)
	ld a, $1e
	ld [$d13a], a
	ld hl, $d730
	ld a, [hl]
	or $26
	ld [hl], a
	ret

Func_12e7:: ; 12e7 (0:12e7)
	ld hl, $d728
	res 0, [hl]
	ret

;appears to be called twice inside function $C38B
;if $d700,$d11a == $1 then biking
;if $d700,$d11a == $2 then surfing
ForceBikeOrSurf:: ; 12ed (0:12ed)
	ld b,5 ;graphics bank 5
	ld hl,LoadPlayerSpriteGraphics ;load player sprite graphics
	call Bankswitch ;loads bank 5 and then calls LoadPlayerSpriteGraphics
	jp Func_2307 ;update map/player state?

; this is used to check if the player wants to interrupt the opening sequence at several points
; XXX is this used anywhere else?
; INPUT:
; c = number of frames to wait
; sets carry if Up+Select+B, Start, or A is pressed within c frames
; unsets carry otherwise
CheckForUserInterruption:: ; 12f8 (0:12f8)
	call DelayFrame
	push bc
	call GetJoypadStateLowSensitivity
	pop bc
	ld a,[H_CURRENTPRESSEDBUTTONS] ; currently pressed buttons
	cp a,%01000110 ; Up, Select button, B button
	jr z,.setCarry ; if all three keys are pressed
	ld a,[$ffb5] ; either newly pressed buttons or currently pressed buttons at low sampling rate
	and a,%00001001 ; Start button, A button
	jr nz,.setCarry ; if either key is pressed
	dec c
	jr nz,CheckForUserInterruption
.unsetCarry
	and a
	ret
.setCarry
	scf
	ret

; function to load position data for destination warp when switching maps
; INPUT:
; a = ID of destination warp within destination map
LoadDestinationWarpPosition:: ; 1313 (0:1313)
	ld b,a
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,[$cf12]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ld a,b
	add a
	add a
	ld c,a
	ld b,0
	add hl,bc
	ld bc,4
	ld de,$d35f
	call CopyData
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; INPUT:
; c: if nonzero, show at least a sliver of health
; d = number of HP bar sections (normally 6)
; e = health (in eighths of bar sections) (normally out of 48)
DrawHPBar:: ; 1336 (0:1336)
	push hl
	push de
	push bc
	ld a,$71 ; left of HP bar tile 1
	ld [hli],a
	ld a,$62 ; left of HP bar tile 2
	ld [hli],a
	push hl
	ld a,$63 ; empty bar section tile
.drawEmptyBarLoop
	ld [hli],a
	dec d
	jr nz,.drawEmptyBarLoop
	ld a,[$cf94]
	dec a ; what should the right of HP bar tile be?
	ld a,$6d ; right of HP bar tile, in status screen and battles
	jr z,.writeTile
	dec a ; right of HP bar tile, in pokemon menu
.writeTile
	ld [hl],a
	pop hl
	ld a,e
	and a ; is there enough health to show up on the HP bar?
	jr nz,.loop ; if so, draw the HP bar
	ld a,c
	and a ; should a sliver of health be shown no matter what?
	jr z,.done
	ld e,1 ; if so, fill one eighth of a bar section
; loop to draw every full bar section
.loop
	ld a,e
	sub a,8
	jr c,.drawPartialBarSection
	ld e,a
	ld a,$6b ; filled bar section tile
	ld [hli],a
	ld a,e
	and a
	jr z,.done
	jr .loop
; draws a partial bar section at the end (if necessary)
; there are 7 possible partial bar sections from 1/8 to 7/8 full
.drawPartialBarSection
	ld a,$63 ; empty bar section tile
	add e ; add e to get the appropriate partial bar section tile
	ld [hl],a ; write the tile
.done
	pop bc
	pop de
	pop hl
	ret

; loads pokemon data from one of multiple sources to $cf98
; loads base stats to $d0b8
; INPUT:
; [$cf92] = index of pokemon within party/box
; [$cc49] = source
; 00: player's party
; 01: enemy's party
; 02: current box
; 03: daycare
; OUTPUT:
; [$cf91] = pokemon ID
; $cf98 = base address of pokemon data
; $d0b8 = base address of base stats
LoadMonData:: ; 1372 (0:1372)
	ld hl,LoadMonData_
	ld b,BANK(LoadMonData_)
	jp Bankswitch

; writes c to $d0dc+b
Func_137a:: ; 137a (0:137a)
	ld hl, $d0dc
	ld e, b
	ld d, $0
	add hl, de
	ld a, c
	ld [hl], a
	ret

LoadFlippedFrontSpriteByMonIndex:: ; 1384 (0:1384)
	ld a, $1
	ld [W_SPRITEFLIPPED], a

LoadFrontSpriteByMonIndex:: ; 1389 (0:1389)
	push hl
	ld a, [$d11e]
	push af
	ld a, [$cf91]
	ld [$d11e], a
	ld a, $3a
	call Predef ; indirect jump to IndexToPokedex (41010 (10:5010))
	ld hl, $d11e
	ld a, [hl]
	pop bc
	ld [hl], b
	and a
	pop hl
	jr z, .invalidDexNumber  ; dex #0 invalid
	cp 151 + 1
	jr c, .validDexNumber    ; dex >#151 invalid
.invalidDexNumber
	ld a, RHYDON ; $1
	ld [$cf91], a
	ret
.validDexNumber
	push hl
	ld de, $9000
	call LoadMonFrontSprite
	pop hl
	ld a, [H_LOADEDROMBANK]
	push af
	ld a, Bank(asm_3f0d0)
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	xor a
	ld [$ffe1], a
	call asm_3f0d0
	xor a
	ld [W_SPRITEFLIPPED], a
	pop af
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	ret

; plays the cry of a pokemon
; INPUT:
; a = pokemon ID
PlayCry:: ; 13d0 (0:13d0)
	call GetCryData
	call PlaySound ; play cry
	jp WaitForSoundToFinish ; wait for sound to be done playing

; gets a pokemon's cry data
; INPUT:
; a = pokemon ID
GetCryData:: ; 13d9 (0:13d9)
	dec a
	ld c,a
	ld b,0
	ld hl,CryData
	add hl,bc
	add hl,bc
	add hl,bc
	ld a,Bank(CryData)
	call BankswitchHome
	ld a,[hli]
	ld b,a
	ld a,[hli]
	ld [$c0f1],a
	ld a,[hl]
	ld [$c0f2],a
	call BankswitchBack
	ld a,b ; a = cryID
	ld c,$14 ; base sound ID for pokemon cries
	rlca
	add b ; a = cryID * 3
	add c ; a = $14 + cryID * 3
	ret

DisplayPartyMenu:: ; 13fc (0:13fc)
	ld a,[$ffd7]
	push af
	xor a
	ld [$ffd7],a
	call GBPalWhiteOutWithDelay3
	call CleanLCD_OAM
	call PartyMenuInit
	call DrawPartyMenu
	jp HandlePartyMenuInput

GoBackToPartyMenu:: ; 1411 (0:1411)
	ld a,[$ffd7]
	push af
	xor a
	ld [$ffd7],a
	call PartyMenuInit
	call RedrawPartyMenu
	jp HandlePartyMenuInput

PartyMenuInit:: ; 1420 (0:1420)
	ld a,$01
	call BankswitchHome
	call LoadHpBarAndStatusTilePatterns
	ld hl,$d730
	set 6,[hl] ; turn off letter printing delay
	xor a
	ld [$cc49],a
	ld [$cc37],a
	ld hl,wTopMenuItemY
	inc a
	ld [hli],a ; top menu item Y
	xor a
	ld [hli],a ; top menu item X
	ld a,[$cc2b]
	push af
	ld [hli],a ; current menu item ID
	inc hl
	ld a,[W_NUMINPARTY]
	and a ; are there more than 0 pokemon in the party?
	jr z,.storeMaxMenuItemID
	dec a
; if party is not empty, the max menu item ID is ([W_NUMINPARTY] - 1)
; otherwise, it is 0
.storeMaxMenuItemID
	ld [hli],a ; max menu item ID
	ld a,[$d11f]
	and a
	ld a,%00000011 ; A button and B button
	jr z,.next
	xor a
	ld [$d11f],a
	inc a
.next
	ld [hli],a ; menu watched keys
	pop af
	ld [hl],a ; old menu item ID
	ret

HandlePartyMenuInput:: ; 145a (0:145a)
	ld a,1
	ld [$cc4a],a
	ld a,$40
	ld [$d09b],a
	call HandleMenuInputPokemonSelection
	call PlaceUnfilledArrowMenuCursor
	ld b,a
	xor a
	ld [$d09b],a
	ld a,[wCurrentMenuItem]
	ld [$cc2b],a
	ld hl,$d730
	res 6,[hl] ; turn on letter printing delay
	ld a,[$cc35]
	and a
	jp nz,.swappingPokemon
	pop af
	ld [$ffd7],a
	bit 1,b
	jr nz,.noPokemonChosen
	ld a,[W_NUMINPARTY]
	and a
	jr z,.noPokemonChosen
	ld a,[wCurrentMenuItem]
	ld [wWhichPokemon],a
	ld hl,W_PARTYMON1
	ld b,0
	ld c,a
	add hl,bc
	ld a,[hl]
	ld [$cf91],a
	ld [$cfd9],a
	call BankswitchBack
	and a
	ret
.noPokemonChosen
	call BankswitchBack
	scf
	ret
.swappingPokemon
	bit 1,b ; was the B button pressed?
	jr z,.handleSwap ; if not, handle swapping the pokemon
.cancelSwap ; if the B button was pressed
	callba ErasePartyMenuCursors
	xor a
	ld [$cc35],a
	ld [$d07d],a
	call RedrawPartyMenu
	jr HandlePartyMenuInput
.handleSwap
	ld a,[wCurrentMenuItem]
	ld [wWhichPokemon],a
	callba SwitchPartyMon
	jr HandlePartyMenuInput

DrawPartyMenu:: ; 14d4 (0:14d4)
	ld hl, DrawPartyMenu_
	jr DrawPartyMenuCommon

RedrawPartyMenu:: ; 14d9 (0:14d9)
	ld hl, RedrawPartyMenu_

DrawPartyMenuCommon:: ; 14dc (0:14dc)
	ld b, BANK(RedrawPartyMenu_)
	jp Bankswitch

; prints a pokemon's status condition
; INPUT:
; de = address of status condition
; hl = destination address
PrintStatusCondition:: ; 14e1 (0:14e1)
	push de
	dec de
	dec de ; de = address of current HP
	ld a,[de]
	ld b,a
	dec de
	ld a,[de]
	or b ; is the pokemon's HP zero?
	pop de
	jr nz,PrintStatusConditionNotFainted
; if the pokemon's HP is 0, print "FNT"
	ld a,"F"
	ld [hli],a
	ld a,"N"
	ld [hli],a
	ld [hl],"T"
	and a
	ret
PrintStatusConditionNotFainted ; 14f6
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,BANK(PrintStatusAilment)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call PrintStatusAilment ; print status condition
	pop bc
	ld a,b
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; function to print pokemon level, leaving off the ":L" if the level is at least 100
; INPUT:
; hl = destination address
; [$cfb9] = level
PrintLevel:: ; 150b (0:150b)
	ld a,$6e ; ":L" tile ID
	ld [hli],a
	ld c,2 ; number of digits
	ld a,[$cfb9] ; level
	cp a,100
	jr c,PrintLevelCommon
; if level at least 100, write over the ":L" tile
	dec hl
	inc c ; increment number of digits to 3
	jr PrintLevelCommon

; prints the level without leaving off ":L" regardless of level
; INPUT:
; hl = destination address
; [$cfb9] = level
PrintLevelFull:: ; 151b (0:151b)
	ld a,$6e ; ":L" tile ID
	ld [hli],a
	ld c,3 ; number of digits
	ld a,[$cfb9] ; level

PrintLevelCommon:: ; 1523 (0:1523)
	ld [$d11e],a
	ld de,$d11e
	ld b,$41 ; no leading zeroes, left-aligned, one byte
	jp PrintNumber

Func_152e:: ; 152e (0:152e)
	ld hl,$d0dc
	ld c,a
	ld b,0
	add hl,bc
	ld a,[hl]
	ret

; copies the base stat data of a pokemon to $D0B8 (W_MONHEADER)
; INPUT:
; [$D0B5] = pokemon ID
GetMonHeader:: ; 1537 (0:1537)
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,BANK(BulbasaurBaseStats)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	push bc
	push de
	push hl
	ld a,[$d11e]
	push af
	ld a,[$d0b5]
	ld [$d11e],a
	ld de,FossilKabutopsPic
	ld b,$66 ; size of Kabutops fossil and Ghost sprites
	cp a,FOSSIL_KABUTOPS ; Kabutops fossil
	jr z,.specialID
	ld de,GhostPic
	cp a,MON_GHOST ; Ghost
	jr z,.specialID
	ld de,FossilAerodactylPic
	ld b,$77 ; size of Aerodactyl fossil sprite
	cp a,FOSSIL_AERODACTYL ; Aerodactyl fossil
	jr z,.specialID
	cp a,MEW
	jr z,.mew
	ld a,$3a
	call Predef   ; convert pokemon ID in [$D11E] to pokedex number
	ld a,[$d11e]
	dec a
	ld bc,28
	ld hl,BulbasaurBaseStats
	call AddNTimes
	ld de,W_MONHEADER
	ld bc,28
	call CopyData
	jr .done
.specialID
	ld hl,W_MONHSPRITEDIM
	ld [hl],b ; write sprite dimensions
	inc hl
	ld [hl],e ; write front sprite pointer
	inc hl
	ld [hl],d
	jr .done
.mew
	ld hl,MewBaseStats
	ld de,W_MONHEADER
	ld bc,28
	ld a,BANK(MewBaseStats)
	call FarCopyData
.done
	ld a,[$d0b5]
	ld [$d0b8],a
	pop af
	ld [$d11e],a
	pop hl
	pop de
	pop bc
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; copy party pokemon's name to $CD6D
GetPartyMonName2:: ; 15b4 (0:15b4)
	ld a,[wWhichPokemon] ; index within party
	ld hl,W_PARTYMON1NAME

; this is called more often
GetPartyMonName:: ; 15ba (0:15ba)
	push hl
	push bc
	call SkipFixedLengthTextEntries ; add 11 to hl, a times
	ld de,$cd6d
	push de
	ld bc,11
	call CopyData
	pop de
	pop bc
	pop hl
	ret

; function to print a BCD (Binary-coded decimal) number
; de = address of BCD number
; hl = destination address
; c = flags and length
; bit 7: if set, do not print leading zeroes
;        if unset, print leading zeroes
; bit 6: if set, left-align the string (do not pad empty digits with spaces)
;        if unset, right-align the string
; bit 5: if set, print currency symbol at the beginning of the string
;        if unset, do not print the currency symbol
; bits 0-4: length of BCD number in bytes
; Note that bits 5 and 7 are modified during execution. The above reflects
; their meaning at the beginning of the functions's execution.
PrintBCDNumber:: ; 15cd (0:15cd)
	ld b,c ; save flags in b
	res 7,c
	res 6,c
	res 5,c ; c now holds the length
	bit 5,b
	jr z,.loop
	bit 7,b
	jr nz,.loop
	ld [hl],"¥"
	inc hl
.loop
	ld a,[de]
	swap a
	call PrintBCDDigit ; print upper digit
	ld a,[de]
	call PrintBCDDigit ; print lower digit
	inc de
	dec c
	jr nz,.loop
	bit 7,b ; were any non-zero digits printed?
	jr z,.done ; if so, we are done
.numberEqualsZero ; if every digit of the BCD number is zero
	bit 6,b ; left or right alignment?
	jr nz,.skipRightAlignmentAdjustment
	dec hl ; if the string is right-aligned, it needs to be moved back one space
.skipRightAlignmentAdjustment
	bit 5,b
	jr z,.skipCurrencySymbol
	ld [hl],"¥"
	inc hl
.skipCurrencySymbol
	ld [hl],"0"
	call PrintLetterDelay
	inc hl
.done
	ret

PrintBCDDigit:: ; 1604 (0:1604)
	and a,%00001111
	and a
	jr z,.zeroDigit
.nonzeroDigit
	bit 7,b ; have any non-space characters been printed?
	jr z,.outputDigit
; if bit 7 is set, then no numbers have been printed yet
	bit 5,b ; print the currency symbol?
	jr z,.skipCurrencySymbol
	ld [hl],"¥"
	inc hl
	res 5,b
.skipCurrencySymbol
	res 7,b ; unset 7 to indicate that a nonzero digit has been reached
.outputDigit
	add a,"0"
	ld [hli],a
	jp PrintLetterDelay
.zeroDigit
	bit 7,b ; either printing leading zeroes or already reached a nonzero digit?
	jr z,.outputDigit ; if so, print a zero digit
	bit 6,b ; left or right alignment?
	ret nz
	inc hl ; if right-aligned, "print" a space by advancing the pointer
	ret

; uncompresses the front or back sprite of the specified mon
; assumes the corresponding mon header is already loaded
; hl contains offset to sprite pointer ($b for front or $d for back)
UncompressMonSprite:: ; 1627 (0:1627)
	ld bc,W_MONHEADER
	add hl,bc
	ld a,[hli]
	ld [W_SPRITEINPUTPTR],a    ; fetch sprite input pointer
	ld a,[hl]
	ld [W_SPRITEINPUTPTR+1],a
; define (by index number) the bank that a pokemon's image is in
; index = Mew, bank 1
; index = Kabutops fossil, bank $B
;	index < $1F, bank 9
; $1F ≤ index < $4A, bank $A
; $4A ≤ index < $74, bank $B
; $74 ≤ index < $99, bank $C
; $99 ≤ index,       bank $D
	ld a,[$CF91] ; XXX name for this ram location
	ld b,a
	cp MEW
	ld a,BANK(MewPicFront)
	jr z,.GotBank
	ld a,b
	cp FOSSIL_KABUTOPS
	ld a,BANK(FossilKabutopsPic)
	jr z,.GotBank
	ld a,b
	cp TANGELA + 1
	ld a,BANK(TangelaPicFront)
	jr c,.GotBank
	ld a,b
	cp MOLTRES + 1
	ld a,BANK(MoltresPicFront)
	jr c,.GotBank
	ld a,b
	cp BEEDRILL + 2
	ld a,BANK(BeedrillPicFront)
	jr c,.GotBank
	ld a,b
	cp STARMIE + 1
	ld a,BANK(StarmiePicFront)
	jr c,.GotBank
	ld a,BANK(VictreebelPicFront)
.GotBank
	jp UncompressSpriteData

; de: destination location
LoadMonFrontSprite:: ; 1665 (0:1665)
	push de
	ld hl, W_MONHFRONTSPRITE - W_MONHEADER
	call UncompressMonSprite
	ld hl, W_MONHSPRITEDIM
	ld a, [hli]
	ld c, a
	pop de
	; fall through

; postprocesses uncompressed sprite chunks to a 2bpp sprite and loads it into video ram
; calculates alignment parameters to place both sprite chunks in the center of the 7*7 tile sprite buffers
; de: destination location
; a,c:  sprite dimensions (in tiles of 8x8 each)
LoadUncompressedSpriteData:: ; 1672 (0:1672)
	push de
	and $f
	ld [H_SPRITEWIDTH], a ; each byte contains 8 pixels (in 1bpp), so tiles=bytes for width
	ld b, a
	ld a, $7
	sub b      ; 7-w
	inc a      ; 8-w
	srl a      ; (8-w)/2     ; horizontal center (in tiles, rounded up)
	ld b, a
	add a
	add a
	add a
	sub b      ; 7*((8-w)/2) ; skip for horizontal center (in tiles)
	ld [H_SPRITEOFFSET], a
	ld a, c
	swap a
	and $f
	ld b, a
	add a
	add a
	add a     ; 8*tiles is height in bytes
	ld [H_SPRITEHEIGHT], a ; $ff8c
	ld a, $7
	sub b      ; 7-h         ; skip for vertical center (in tiles, relative to current column)
	ld b, a
	ld a, [H_SPRITEOFFSET]
	add b     ; 7*((8-w)/2) + 7-h ; combined overall offset (in tiles)
	add a
	add a
	add a     ; 8*(7*((8-w)/2) + 7-h) ; combined overall offset (in bytes)
	ld [H_SPRITEOFFSET], a
	xor a
	ld [$4000], a
	ld hl, S_SPRITEBUFFER0
	call ZeroSpriteBuffer   ; zero buffer 0
	ld de, S_SPRITEBUFFER1
	ld hl, S_SPRITEBUFFER0
	call AlignSpriteDataCentered    ; copy and align buffer 1 to 0 (containing the MSB of the 2bpp sprite)
	ld hl, S_SPRITEBUFFER1
	call ZeroSpriteBuffer   ; zero buffer 1
	ld de, S_SPRITEBUFFER2
	ld hl, S_SPRITEBUFFER1
	call AlignSpriteDataCentered    ; copy and align buffer 2 to 1 (containing the LSB of the 2bpp sprite)
	pop de
	jp InterlaceMergeSpriteBuffers

; copies and aligns the sprite data properly inside the sprite buffer
; sprite buffers are 7*7 tiles in size, the loaded sprite is centered within this area
AlignSpriteDataCentered:: ; 16c2 (0:16c2)
	ld a, [H_SPRITEOFFSET]
	ld b, $0
	ld c, a
	add hl, bc
	ld a, [H_SPRITEWIDTH] ; $ff8b
.columnLoop
	push af
	push hl
	ld a, [H_SPRITEHEIGHT] ; $ff8c
	ld c, a
.columnInnerLoop
	ld a, [de]
	inc de
	ld [hli], a
	dec c
	jr nz, .columnInnerLoop
	pop hl
	ld bc, 7*8    ; 7 tiles
	add hl, bc    ; advance one full column
	pop af
	dec a
	jr nz, .columnLoop
	ret

; fills the sprite buffer (pointed to in hl) with zeros
ZeroSpriteBuffer:: ; 16df (0:16df)
	ld bc, SPRITEBUFFERSIZE
.nextByteLoop
	xor a
	ld [hli], a
	dec bc
	ld a, b
	or c
	jr nz, .nextByteLoop
	ret

; combines the (7*7 tiles, 1bpp) sprite chunks in buffer 0 and 1 into a 2bpp sprite located in buffer 1 through 2
; in the resulting sprite, the rows of the two source sprites are interlaced
; de: output address
InterlaceMergeSpriteBuffers:: ; 16ea (0:16ea)
	xor a
	ld [$4000], a
	push de
	ld hl, S_SPRITEBUFFER2 + (SPRITEBUFFERSIZE - 1) ; destination: end of buffer 2
	ld de, S_SPRITEBUFFER1 + (SPRITEBUFFERSIZE - 1) ; source 2: end of buffer 1
	ld bc, S_SPRITEBUFFER0 + (SPRITEBUFFERSIZE - 1) ; source 1: end of buffer 0
	ld a, SPRITEBUFFERSIZE/2 ; $c4
	ld [H_SPRITEINTERLACECOUNTER], a ; $ff8b
.interlaceLoop
	ld a, [de]
	dec de
	ld [hld], a   ; write byte of source 2
	ld a, [bc]
	dec bc
	ld [hld], a   ; write byte of source 1
	ld a, [de]
	dec de
	ld [hld], a   ; write byte of source 2
	ld a, [bc]
	dec bc
	ld [hld], a   ; write byte of source 1
	ld a, [H_SPRITEINTERLACECOUNTER] ; $ff8b
	dec a
	ld [H_SPRITEINTERLACECOUNTER], a ; $ff8b
	jr nz, .interlaceLoop
	ld a, [W_SPRITEFLIPPED]
	and a
	jr z, .notFlipped
	ld bc, 2*SPRITEBUFFERSIZE
	ld hl, S_SPRITEBUFFER1
.swapLoop
	swap [hl]    ; if flipped swap nybbles in all bytes
	inc hl
	dec bc
	ld a, b
	or c
	jr nz, .swapLoop
.notFlipped
	pop hl
	ld de, S_SPRITEBUFFER1
	ld c, (2*SPRITEBUFFERSIZE)/16 ; $31, number of 16 byte chunks to be copied
	ld a, [H_LOADEDROMBANK]
	ld b, a
	jp CopyVideoData

Underground_Coll:: ; 172f (0:172f)
	INCBIN "gfx/tilesets/underground.tilecoll"
Overworld_Coll:: ; 1735 (0:1735)
	INCBIN "gfx/tilesets/overworld.tilecoll"
RedsHouse1_Coll::
RedsHouse2_Coll:: ; 1749 (0:1749)
	INCBIN "gfx/tilesets/reds_house.tilecoll"
Mart_Coll
Pokecenter_Coll:: ; 1753 (0:1753)
	INCBIN "gfx/tilesets/pokecenter.tilecoll"
Dojo_Coll::
Gym_Coll:: ; 1759 (0:1759)
	INCBIN "gfx/tilesets/gym.tilecoll"
Forest_Coll:: ; 1765 (0:1765)
	INCBIN "gfx/tilesets/forest.tilecoll"
House_Coll:: ; 1775 (0:1775)
	INCBIN "gfx/tilesets/house.tilecoll"
ForestGate_Coll::
Museum_Coll::
Gate_Coll:: ; 177f (0:177f)
	INCBIN "gfx/tilesets/gate.tilecoll"
Ship_Coll:: ; 178a (0:178a)
	INCBIN "gfx/tilesets/ship.tilecoll"
ShipPort_Coll:: ; 1795 (0:1795)
	INCBIN "gfx/tilesets/ship_port.tilecoll"
Cemetery_Coll:: ; 179a (0:179a)
	INCBIN "gfx/tilesets/cemetery.tilecoll"
Interior_Coll:: ; 17a2 (0:17a2)
	INCBIN "gfx/tilesets/interior.tilecoll"
Cavern_Coll:: ; 17ac (0:17ac)
	INCBIN "gfx/tilesets/cavern.tilecoll"
Lobby_Coll:: ; 17b8 (0:17b8)
	INCBIN "gfx/tilesets/lobby.tilecoll"
Mansion_Coll:: ; 17c0 (0:17c0)
	INCBIN "gfx/tilesets/mansion.tilecoll"
Lab_Coll:: ; 17ca (0:17ca)
	INCBIN "gfx/tilesets/lab.tilecoll"
Club_Coll:: ; 17d1 (0:17d1)
	INCBIN "gfx/tilesets/club.tilecoll"
Facility_Coll:: ; 17dd (0:17dd)
	INCBIN "gfx/tilesets/facility.tilecoll"
Plateau_Coll:: ; 17f0 (0:17f0)
	INCBIN "gfx/tilesets/plateau.tilecoll"

; does the same thing as FarCopyData at 009D
; only difference is that it uses [$ff8b] instead of [$cee9] for a temp value
; copy bc bytes of data from a:hl to de
FarCopyData2:: ; 17f7 (0:17f7)
	ld [$ff8b],a
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,[$ff8b]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call CopyData
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; does a far copy but the source is de and the destination is hl
; copy bc bytes of data from a:de to hl
FarCopyData3:: ; 180d (0:180d)
	ld [$ff8b],a
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,[$ff8b]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	push hl
	push de
	push de
	ld d,h
	ld e,l
	pop hl
	call CopyData
	pop de
	pop hl
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; copies each source byte to the destination twice (next to each other)
; copy bc source bytes from a:hl to de
FarCopyDataDouble:: ; 182b (0:182b)
	ld [$ff8b],a
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,[$ff8b]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
.loop
	ld a,[hli]
	ld [de],a
	inc de
	ld [de],a
	inc de
	dec bc
	ld a,c
	or b
	jr nz,.loop
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; copy (c * 16) bytes from b:de to hl during V-blank
; transfers up to 128 bytes per V-blank
CopyVideoData:: ; 1848 (0:1848)
	ld a,[H_AUTOBGTRANSFERENABLED] ; save auto-transfer enabled flag
	push af
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a ; disable auto-transfer while copying
	ld a,[H_LOADEDROMBANK]
	ld [$ff8b],a
	ld a,b
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ld a,e
	ld [H_VBCOPYSRC],a
	ld a,d
	ld [H_VBCOPYSRC + 1],a
	ld a,l
	ld [H_VBCOPYDEST],a
	ld a,h
	ld [H_VBCOPYDEST + 1],a
.loop
	ld a,c
	cp a,8 ; are there more than 128 bytes left to copy?
	jr nc,.copyMaxSize ; only copy up to 128 bytes at a time
.copyRemainder
	ld [H_VBCOPYSIZE],a
	call DelayFrame ; wait for V-blank handler to perform the copy
	ld a,[$ff8b]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	pop af
	ld [H_AUTOBGTRANSFERENABLED],a ; restore original auto-transfer enabled flag
	ret
.copyMaxSize
	ld a,8 ; 128 bytes
	ld [H_VBCOPYSIZE],a
	call DelayFrame ; wait for V-blank handler to perform the copy
	ld a,c
	sub a,8
	ld c,a
	jr .loop

; copy (c * 8) source bytes from b:de to hl during V-blank
; copies each source byte to the destination twice (next to each other)
; transfers up to 64 source bytes per V-blank
CopyVideoDataDouble:: ; 1886 (0:1886)
	ld a,[H_AUTOBGTRANSFERENABLED] ; save auto-transfer enabled flag
	push af
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a ; disable auto-transfer while copying
	ld a,[H_LOADEDROMBANK]
	ld [$ff8b],a
	ld a,b
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ld a,e
	ld [H_VBCOPYDOUBLESRC],a
	ld a,d
	ld [H_VBCOPYDOUBLESRC + 1],a
	ld a,l
	ld [H_VBCOPYDOUBLEDEST],a
	ld a,h
	ld [H_VBCOPYDOUBLEDEST + 1],a
.loop
	ld a,c
	cp a,8 ; are there more than 64 source bytes left to copy?
	jr nc,.copyMaxSize ; only copy up to 64 source bytes at a time
.copyRemainder
	ld [H_VBCOPYDOUBLESIZE],a
	call DelayFrame ; wait for V-blank handler to perform the copy
	ld a,[$ff8b]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	pop af
	ld [H_AUTOBGTRANSFERENABLED],a ; restore original auto-transfer enabled flag
	ret
.copyMaxSize
	ld a,8 ; 64 source bytes
	ld [H_VBCOPYDOUBLESIZE],a
	call DelayFrame ; wait for V-blank handler to perform the copy
	ld a,c
	sub a,8
	ld c,a
	jr .loop

; clears an area of the screen
; INPUT:
; hl = address of upper left corner of the area
; b = height
; c = width
ClearScreenArea:: ; 18c4 (0:18c4)
	ld   a,$7F ; blank tile
	ld   de,20 ; screen width
.loop
	push hl
	push bc
.innerLoop
	ld [hli],a
	dec c
	jr nz,.innerLoop
	pop bc
	pop hl
	add hl,de
	dec b
	jr nz,.loop
	ret

; copies the screen tile buffer from WRAM to VRAM
; copying is done in 3 chunks of 6 rows each
; b: high byte of VRAM destination address ($98 or $9c for window tile map 0 or 1 resp.)
CopyScreenTileBufferToVRAM:: ; 18d6 (0:18d6)
	ld c, $6
	ld hl, $0000
	ld de, wTileMap
	call InitScreenTileBufferTransferParameters
	call DelayFrame
	ld hl, $600
	ld de, wTileMap + 20 * 6 ; $c418
	call InitScreenTileBufferTransferParameters
	call DelayFrame
	ld hl, $c00
	ld de, wTileMap + 20 * 12 ; $c490
	call InitScreenTileBufferTransferParameters
	jp DelayFrame

InitScreenTileBufferTransferParameters:: ; 18fc (0:18fc)
	ld a, d
	ld [H_VBCOPYBGSRC+1], a
	call GetRowColAddressBgMap
	ld a, l
	ld [H_VBCOPYBGDEST], a ; $ffc3
	ld a, h
	ld [H_VBCOPYBGDEST+1], a
	ld a, c
	ld [H_VBCOPYBGNUMROWS], a ; $ffc5
	ld a, e
	ld [H_VBCOPYBGSRC], a ; $ffc1
	ret

ClearScreen:: ; 190f (0:190f)
; clears all tiles in the tilemap,
; then wait three frames
	ld bc,$0168 ; tilemap size
	inc b
	ld hl,wTileMap ; TILEMAP_START
	ld a,$7F    ; $7F is blank tile
.loop
	ld [hli],a
	dec c
	jr nz,.loop
	dec b
	jr nz,.loop
	jp Delay3

TextBoxBorder:: ; 1922 (0:1922)
; draw a text box
; upper-left corner at coordinates hl
; height b
; width c

	; first row
	push hl
	ld a,"┌"
	ld [hli],a
	inc a    ; horizontal border ─
	call NPlaceChar
	inc a    ; upper-right border ┐
	ld [hl],a

	; middle rows
	pop hl
	ld de,20
	add hl,de ; skip the top row

.PlaceRow
	push hl
	ld a,"│"
	ld [hli],a
	ld a," "
	call NPlaceChar
	ld [hl],"│"

	pop hl
	ld de,20
	add hl,de ; move to next row
	dec b
	jr nz,.PlaceRow

	; bottom row
	ld a,"└"
	ld [hli],a
	ld a,"─"
	call NPlaceChar
	ld [hl],"┘"
	ret
;
NPlaceChar:: ; 194f (0:194f)
; place a row of width c of identical characters
	ld d,c
.loop
	ld [hli],a
	dec d
	jr nz,.loop
	ret

PlaceString:: ; 1955 (0:1955)
	push hl
PlaceNextChar:: ; 1956 (0:1956)
	ld a,[de]

	cp "@"
	jr nz,.PlaceText
	ld b,h
	ld c,l
	pop hl
	ret

.PlaceText
	cp $4E
	jr nz,.next
	ld bc,$0028
	ld a,[$FFF6]
	bit 2,a
	jr z,.next2
	ld bc,$14
.next2
	pop hl
	add hl,bc
	push hl
	jp Next19E8

.next
	cp $4F
	jr nz,.next3
	pop hl
	FuncCoord 1, 16 ; $c4e1
	ld hl,Coord
	push hl
	jp Next19E8

.next3 ; Check against a dictionary
	and a
	jp z,Char00
	cp $4C
	jp z,Char4C
	cp $4B
	jp z,Char4B
	cp $51
	jp z,Char51
	cp $49
	jp z,Char49
	cp $52
	jp z,Char52
	cp $53
	jp z,Char53
	cp $54
	jp z,Char54
	cp $5B
	jp z,Char5B
	cp $5E
	jp z,Char5E
	cp $5C
	jp z,Char5C
	cp $5D
	jp z,Char5D
	cp $55
	jp z,Char55
	cp $56
	jp z,Char56
	cp $57
	jp z,Char57
	cp $58
	jp z,Char58
	cp $4A
	jp z,Char4A
	cp $5F
	jp z,Char5F
	cp $59
	jp z,Char59
	cp $5A
	jp z,Char5A
	ld [hli],a
	call PrintLetterDelay
Next19E8:: ; 19e8 (0:19e8)
	inc de
	jp PlaceNextChar

Char00:: ; 19ec (0:19ec)
	ld b,h
	ld c,l
	pop hl
	ld de,Char00Text
	dec de
	ret

Char00Text:: ; 0x19f4 “%d ERROR.”
	TX_FAR _Char00Text
	db "@"

Char52:: ; 0x19f9 player’s name
	push de
	ld de,W_PLAYERNAME
	jr FinishDTE

Char53:: ; 19ff (0:19ff) ; rival’s name
	push de
	ld de,W_RIVALNAME
	jr FinishDTE

Char5D:: ; 1a05 (0:1a05) ; TRAINER
	push de
	ld de,Char5DText
	jr FinishDTE

Char5C:: ; 1a0b (0:1a0b) ; TM
	push de
	ld de,Char5CText
	jr FinishDTE

Char5B:: ; 1a11 (0:1a11) ; PC
	push de
	ld de,Char5BText
	jr FinishDTE

Char5E:: ; 1a17 (0:1a17) ; ROCKET
	push de
	ld de,Char5EText
	jr FinishDTE

Char54:: ; 1a1d (0:1a1d) ; POKé
	push de
	ld de,Char54Text
	jr FinishDTE

Char56:: ; 1a23 (0:1a23) ; ……
	push de
	ld de,Char56Text
	jr FinishDTE

Char4A:: ; 1a29 (0:1a29) ; PKMN
	push de
	ld de,Char4AText
	jr FinishDTE

Char59:: ; 1a2f (0:1a2f)
; depending on whose turn it is, print
; enemy active monster’s name, prefixed with “Enemy ”
; or
; player active monster’s name
; (like Char5A but flipped)
	ld a,[H_WHOSETURN]
	xor 1
	jr MonsterNameCharsCommon

Char5A:: ; 1a35 (0:1a35)
; depending on whose turn it is, print
; player active monster’s name
; or
; enemy active monster’s name, prefixed with “Enemy ”
	ld a,[H_WHOSETURN]
MonsterNameCharsCommon:: ; 1a37 (0:1a37)
	push de
	and a
	jr nz,.Enemy
	ld de,W_PLAYERMONNAME ; player active monster name
	jr FinishDTE

.Enemy ; 1A40
	; print “Enemy ”
	ld de,Char5AText
	call PlaceString

	ld h,b
	ld l,c
	ld de,W_ENEMYMONNAME ; enemy active monster name

FinishDTE:: ; 1a4b (0:1a4b)
	call PlaceString
	ld h,b
	ld l,c
	pop de
	inc de
	jp PlaceNextChar

Char5CText:: ; 1a55 (0:1a55)
	db "TM@"
Char5DText:: ; 1a58 (0:1a58)
	db "TRAINER@"
Char5BText:: ; 1a60 (0:1a60)
	db "PC@"
Char5EText:: ; 1a63 (0:1a63)
	db "ROCKET@"
Char54Text:: ; 1a6a (0:1a6a)
	db "POKé@"
Char56Text:: ; 1a6f (0:1a6f)
	db "……@"
Char5AText:: ; 1a72 (0:1a72)
	db "Enemy @"
Char4AText:: ; 1a79 (0:1a79)
	db $E1,$E2,"@" ; PKMN

Char55:: ; 1a7c (0:1a7c)
	push de
	ld b,h
	ld c,l
	ld hl,Char55Text
	call TextCommandProcessor
	ld h,b
	ld l,c
	pop de
	inc de
	jp PlaceNextChar

Char55Text:: ; 1a8c (0:1a8c)
; equivalent to Char4B
	TX_FAR _Char55Text
	db "@"

Char5F:: ; 1a91 (0:1a91)
; ends a Pokédex entry
	ld [hl],"."
	pop hl
	ret

Char58:: ; 1a95 (0:1a95)
	ld a,[$D12B]
	cp 4
	jp z,Next1AA2
	ld a,$EE
	FuncCoord 18, 16 ; $c4f2
	ld [Coord],a
Next1AA2:: ; 1aa2 (0:1aa2)
	call ProtectedDelay3
	call ManualTextScroll
	ld a,$7F
	FuncCoord 18, 16 ; $c4f2
	ld [Coord],a
Char57:: ; 1aad (0:1aad)
	pop hl
	ld de,Char58Text
	dec de
	ret

Char58Text:: ; 1ab3 (0:1ab3)
	db "@"

Char51:: ; 1ab4 (0:1ab4)
	push de
	ld a,$EE
	FuncCoord 18, 16 ; $c4f2
	ld [Coord],a
	call ProtectedDelay3
	call ManualTextScroll
	FuncCoord 1, 13 ; $c4a5
	ld hl,Coord
	ld bc,$0412
	call ClearScreenArea
	ld c,$14
	call DelayFrames
	pop de
	FuncCoord 1, 14 ; $c4b9
	ld hl,Coord
	jp Next19E8

Char49:: ; 1ad5 (0:1ad5)
	push de
	ld a,$EE
	FuncCoord 18, 16 ; $c4f2
	ld [Coord],a
	call ProtectedDelay3
	call ManualTextScroll
	FuncCoord 1, 10 ; $c469
	ld hl,Coord
	ld bc,$0712
	call ClearScreenArea
	ld c,$14
	call DelayFrames
	pop de
	pop hl
	FuncCoord 1, 11 ; $c47d
	ld hl,Coord
	push hl
	jp Next19E8

Char4B:: ; 1af8 (0:1af8)
	ld a,$EE
	FuncCoord 18, 16 ; $c4f2
	ld [Coord],a
	call ProtectedDelay3
	push de
	call ManualTextScroll
	pop de
	ld a,$7F
	FuncCoord 18, 16 ; $c4f2
	ld [Coord],a
	;fall through
Char4C:: ; 1b0a (0:1b0a)
	push de
	call Next1B18
	call Next1B18
	FuncCoord 1, 16 ; $c4e1
	ld hl,Coord
	pop de
	jp Next19E8

Next1B18:: ; 1b18 (0:1b18)
	FuncCoord 0, 14 ; $c4b8
	ld hl,Coord
	FuncCoord 0, 13 ; $c4a4
	ld de,Coord
	ld b,$3C
.next
	ld a,[hli]
	ld [de],a
	inc de
	dec b
	jr nz,.next
	FuncCoord 1, 16 ; $c4e1
	ld hl,Coord
	ld a,$7F
	ld b,$12
.next2
	ld [hli],a
	dec b
	jr nz,.next2

	; wait five frames
	ld b,5
.WaitFrame
	call DelayFrame
	dec b
	jr nz,.WaitFrame

	ret

ProtectedDelay3:: ; 1b3a (0:1b3a)
	push bc
	call Delay3
	pop bc
	ret

TextCommandProcessor:: ; 1b40 (0:1b40)
	ld a,[$d358]
	push af
	set 1,a
	ld e,a
	ld a,[$fff4]
	xor e
	ld [$d358],a
	ld a,c
	ld [$cc3a],a
	ld a,b
	ld [$cc3b],a

NextTextCommand:: ; 1b55 (0:1b55)
	ld a,[hli]
	cp a, "@" ; terminator
	jr nz,.doTextCommand
	pop af
	ld [$d358],a
	ret
.doTextCommand
	push hl
	cp a,$17
	jp z,TextCommand17
	cp a,$0e
	jp nc,TextCommand0B ; if a != 0x17 and a >= 0xE, go to command 0xB
; if a < 0xE, use a jump table
	ld hl,TextCommandJumpTable
	push bc
	add a
	ld b,$00
	ld c,a
	add hl,bc
	pop bc
	ld a,[hli]
	ld h,[hl]
	ld l,a
	jp [hl]

; draw box
; 04AAAABBCC
; AAAA = address of upper left corner
; BB = height
; CC = width
TextCommand04:: ; 1b78 (0:1b78)
	pop hl
	ld a,[hli]
	ld e,a
	ld a,[hli]
	ld d,a
	ld a,[hli]
	ld b,a
	ld a,[hli]
	ld c,a
	push hl
	ld h,d
	ld l,e
	call TextBoxBorder
	pop hl
	jr NextTextCommand

; place string inline
; 00{string}
TextCommand00:: ; 1b8a (0:1b8a)
	pop hl
	ld d,h
	ld e,l
	ld h,b
	ld l,c
	call PlaceString
	ld h,d
	ld l,e
	inc hl
	jr NextTextCommand

; place string from RAM
; 01AAAA
; AAAA = address of string
TextCommand01:: ; 1b97 (0:1b97)
	pop hl
	ld a,[hli]
	ld e,a
	ld a,[hli]
	ld d,a
	push hl
	ld h,b
	ld l,c
	call PlaceString
	pop hl
	jr NextTextCommand

; print BCD number
; 02AAAABB
; AAAA = address of BCD number
; BB
; bits 0-4 = length in bytes
; bits 5-7 = unknown flags
TextCommand02:: ; 1ba5 (0:1ba5)
	pop hl
	ld a,[hli]
	ld e,a
	ld a,[hli]
	ld d,a
	ld a,[hli]
	push hl
	ld h,b
	ld l,c
	ld c,a
	call PrintBCDNumber
	ld b,h
	ld c,l
	pop hl
	jr NextTextCommand

; repoint destination address
; 03AAAA
; AAAA = new destination address
TextCommand03:: ; 1bb7 (0:1bb7)
	pop hl
	ld a,[hli]
	ld [$cc3a],a
	ld c,a
	ld a,[hli]
	ld [$cc3b],a
	ld b,a
	jp NextTextCommand

; repoint destination to second line of dialogue text box
; 05
; (no arguments)
TextCommand05:: ; 1bc5 (0:1bc5)
	pop hl
	FuncCoord 1, 16 ; $c4e1
	ld bc,Coord ; address of second line of dialogue text box
	jp NextTextCommand

; blink arrow and wait for A or B to be pressed
; 06
; (no arguments)
TextCommand06:: ; 1bcc (0:1bcc)
	ld a,[W_ISLINKBATTLE]
	cp a,$04
	jp z,TextCommand0D
	ld a,$ee ; down arrow
	FuncCoord 18, 16 ; $c4f2
	ld [Coord],a ; place down arrow in lower right corner of dialogue text box
	push bc
	call ManualTextScroll ; blink arrow and wait for A or B to be pressed
	pop bc
	ld a," "
	FuncCoord 18, 16 ; $c4f2
	ld [Coord],a ; overwrite down arrow with blank space
	pop hl
	jp NextTextCommand

; scroll text up one line
; 07
; (no arguments)
TextCommand07:: ; 1be7 (0:1be7)
	ld a," "
	FuncCoord 18, 16 ; $c4f2
	ld [Coord],a ; place blank space in lower right corner of dialogue text box
	call Next1B18 ; scroll up text
	call Next1B18
	pop hl
	FuncCoord 1, 16 ; $c4e1
	ld bc,Coord ; address of second line of dialogue text box
	jp NextTextCommand

; execute asm inline
; 08{code}
TextCommand08:: ; 1bf9 (0:1bf9)
	pop hl
	ld de,NextTextCommand
	push de ; return address
	jp [hl]

; print decimal number (converted from binary number)
; 09AAAABB
; AAAA = address of number
; BB
; bits 0-3 = how many digits to display
; bits 4-7 = how long the number is in bytes
TextCommand09:: ; 1bff (0:1bff)
	pop hl
	ld a,[hli]
	ld e,a
	ld a,[hli]
	ld d,a
	ld a,[hli]
	push hl
	ld h,b
	ld l,c
	ld b,a
	and a,$0f
	ld c,a
	ld a,b
	and a,$f0
	swap a
	set 6,a
	ld b,a
	call PrintNumber
	ld b,h
	ld c,l
	pop hl
	jp NextTextCommand

; wait half a second if the user doesn't hold A or B
; 0A
; (no arguments)
TextCommand0A:: ; 1c1d (0:1c1d)
	push bc
	call GetJoypadState
	ld a,[H_CURRENTPRESSEDBUTTONS]
	and a,%00000011 ; A and B buttons
	jr nz,.skipDelay
	ld c,30
	call DelayFrames
.skipDelay
	pop bc
	pop hl
	jp NextTextCommand

; plays sounds
; this actually handles various command ID's, not just 0B
; (no arguments)
TextCommand0B:: ; 1c31 (0:1c31)
	pop hl
	push bc
	dec hl
	ld a,[hli]
	ld b,a ; b = command number that got us here
	push hl
	ld hl,TextCommandSounds
.loop
	ld a,[hli]
	cp b
	jr z,.matchFound
	inc hl
	jr .loop
.matchFound
	cp a,$14
	jr z,.pokemonCry
	cp a,$15
	jr z,.pokemonCry
	cp a,$16
	jr z,.pokemonCry
	ld a,[hl]
	call PlaySound
	call WaitForSoundToFinish
	pop hl
	pop bc
	jp NextTextCommand
.pokemonCry
	push de
	ld a,[hl]
	call PlayCry
	pop de
	pop hl
	pop bc
	jp NextTextCommand

; format: text command ID, sound ID or cry ID
TextCommandSounds:: ; 1c64 (0:1c64)
	db $0B,(SFX_02_3a - SFX_Headers_02) / 3
	db $12,(SFX_02_46 - SFX_Headers_02) / 3
	db $0E,(SFX_02_41 - SFX_Headers_02) / 3
	db $0F,(SFX_02_3a - SFX_Headers_02) / 3
	db $10,(SFX_02_3b - SFX_Headers_02) / 3
	db $11,(SFX_02_42 - SFX_Headers_02) / 3
	db $13,(SFX_02_44 - SFX_Headers_02) / 3
	db $14,NIDORINA ; used in OakSpeech
	db $15,PIDGEOT  ; used in SaffronCityText12
	db $16,DEWGONG  ; unused?

; draw ellipses
; 0CAA
; AA = number of ellipses to draw
TextCommand0C:: ; 1c78 (0:1c78)
	pop hl
	ld a,[hli]
	ld d,a
	push hl
	ld h,b
	ld l,c
.loop
	ld a,$75 ; ellipsis
	ld [hli],a
	push de
	call GetJoypadState
	pop de
	ld a,[H_CURRENTPRESSEDBUTTONS] ; joypad state
	and a,%00000011 ; is A or B button pressed?
	jr nz,.skipDelay ; if so, skip the delay
	ld c,10
	call DelayFrames
.skipDelay
	dec d
	jr nz,.loop
	ld b,h
	ld c,l
	pop hl
	jp NextTextCommand

; wait for A or B to be pressed
; 0D
; (no arguments)
TextCommand0D:: ; 1c9a (0:1c9a)
	push bc
	call ManualTextScroll ; wait for A or B to be pressed
	pop bc
	pop hl
	jp NextTextCommand

; process text commands in another ROM bank
; 17AAAABB
; AAAA = address of text commands
; BB = bank
TextCommand17:: ; 1ca3 (0:1ca3)
	pop hl
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,[hli]
	ld e,a
	ld a,[hli]
	ld d,a
	ld a,[hli]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	push hl
	ld l,e
	ld h,d
	call TextCommandProcessor
	pop hl
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	jp NextTextCommand

TextCommandJumpTable:: ; 1cc1 (0:1cc1)
	dw TextCommand00
	dw TextCommand01
	dw TextCommand02
	dw TextCommand03
	dw TextCommand04
	dw TextCommand05
	dw TextCommand06
	dw TextCommand07
	dw TextCommand08
	dw TextCommand09
	dw TextCommand0A
	dw TextCommand0B
	dw TextCommand0C
	dw TextCommand0D

; this function seems to be used only once
; it store the address of a row and column of the VRAM background map in hl
; INPUT: h - row, l - column, b - high byte of background tile map address in VRAM
GetRowColAddressBgMap:: ; 1cdd (0:1cdd)
	xor a
	srl h
	rr a
	srl h
	rr a
	srl h
	rr a
	or l
	ld l,a
	ld a,b
	or h
	ld h,a
	ret

; clears a VRAM background map with blank space tiles
; INPUT: h - high byte of background tile map address in VRAM
ClearBgMap:: ; 1cf0 (0:1cf0)
	ld a," "
	jr .next
	ld a,l
.next
	ld de,$400 ; size of VRAM background map
	ld l,e
.loop
	ld [hli],a
	dec e
	jr nz,.loop
	dec d
	jr nz,.loop
	ret

; When the player takes a step, a row or column of 2x2 tile blocks at the edge
; of the screen toward which they moved is exposed and has to be redrawn.
; This function does the redrawing.
RedrawExposedScreenEdge:: ; 1d01 (0:1d01)
	ld a,[H_SCREENEDGEREDRAW]
	and a
	ret z
	ld b,a
	xor a
	ld [H_SCREENEDGEREDRAW],a
	dec b
	jr nz,.redrawRow
.redrawColumn
	ld hl,wScreenEdgeTiles
	ld a,[H_SCREENEDGEREDRAWADDR]
	ld e,a
	ld a,[H_SCREENEDGEREDRAWADDR + 1]
	ld d,a
	ld c,18 ; screen height
.loop1
	ld a,[hli]
	ld [de],a
	inc de
	ld a,[hli]
	ld [de],a
	ld a,31
	add e
	ld e,a
	jr nc,.noCarry
	inc d
.noCarry
; the following 4 lines wrap us from bottom to top if necessary
	ld a,d
	and a,$03
	or a,$98
	ld d,a
	dec c
	jr nz,.loop1
	xor a
	ld [H_SCREENEDGEREDRAW],a
	ret
.redrawRow
	ld hl,wScreenEdgeTiles
	ld a,[H_SCREENEDGEREDRAWADDR]
	ld e,a
	ld a,[H_SCREENEDGEREDRAWADDR + 1]
	ld d,a
	push de
	call .drawHalf ; draw upper half
	pop de
	ld a,32 ; width of VRAM background map
	add e
	ld e,a
	                 ; draw lower half
.drawHalf
	ld c,10
.loop2
	ld a,[hli]
	ld [de],a
	inc de
	ld a,[hli]
	ld [de],a
	ld a,e
	inc a
; the following 6 lines wrap us from the right edge to the left edge if necessary
	and a,$1f
	ld b,a
	ld a,e
	and a,$e0
	or b
	ld e,a
	dec c
	jr nz,.loop2
	ret

; This function automatically transfers tile number data from the tile map at
; wTileMap to VRAM during V-blank. Note that it only transfers one third of the
; background per V-blank. It cycles through which third it draws.
; This transfer is turned off when walking around the map, but is turned
; on when talking to sprites, battling, using menus, etc. This is because
; the above function, RedrawExposedScreenEdge, is used when walking to
; improve efficiency.
AutoBgMapTransfer:: ; 1d57 (0:1d57)
	ld a,[H_AUTOBGTRANSFERENABLED]
	and a
	ret z
	ld hl,[sp + 0]
	ld a,h
	ld [H_SPTEMP],a
	ld a,l
	ld [H_SPTEMP + 1],a ; save stack pinter
	ld a,[H_AUTOBGTRANSFERPORTION]
	and a
	jr z,.transferTopThird
	dec a
	jr z,.transferMiddleThird
.transferBottomThird
	FuncCoord 0,12
	ld hl,Coord
	ld sp,hl
	ld a,[H_AUTOBGTRANSFERDEST + 1]
	ld h,a
	ld a,[H_AUTOBGTRANSFERDEST]
	ld l,a
	ld de,(12 * 32)
	add hl,de
	xor a ; TRANSFERTOP
	jr .doTransfer
.transferTopThird
	FuncCoord 0,0
	ld hl,Coord
	ld sp,hl
	ld a,[H_AUTOBGTRANSFERDEST + 1]
	ld h,a
	ld a,[H_AUTOBGTRANSFERDEST]
	ld l,a
	ld a,TRANSFERMIDDLE
	jr .doTransfer
.transferMiddleThird
	FuncCoord 0,6
	ld hl,Coord
	ld sp,hl
	ld a,[H_AUTOBGTRANSFERDEST + 1]
	ld h,a
	ld a,[H_AUTOBGTRANSFERDEST]
	ld l,a
	ld de,(6 * 32)
	add hl,de
	ld a,TRANSFERBOTTOM
.doTransfer
	ld [H_AUTOBGTRANSFERPORTION],a ; store next portion
	ld b,6

; unrolled loop and using pop for speed
TransferBgRows:: ; 1d9e (0:1d9e)
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	ld a,13
	add l
	ld l,a
	jr nc,.noCarry
	inc h
.noCarry
	dec b
	jr nz,TransferBgRows
	ld a,[H_SPTEMP]
	ld h,a
	ld a,[H_SPTEMP + 1]
	ld l,a
	ld sp,hl ; restore stack pointer
	ret

; Copies [H_VBCOPYBGNUMROWS] rows from H_VBCOPYBGSRC to H_VBCOPYBGDEST.
; If H_VBCOPYBGSRC is XX00, the transfer is disabled.
VBlankCopyBgMap:: ; 1de1 (0:1de1)
	ld a,[H_VBCOPYBGSRC] ; doubles as enabling byte
	and a
	ret z
	ld hl,[sp + 0]
	ld a,h
	ld [H_SPTEMP],a
	ld a,l
	ld [H_SPTEMP + 1],a ; save stack pointer
	ld a,[H_VBCOPYBGSRC]
	ld l,a
	ld a,[H_VBCOPYBGSRC + 1]
	ld h,a
	ld sp,hl
	ld a,[H_VBCOPYBGDEST]
	ld l,a
	ld a,[H_VBCOPYBGDEST + 1]
	ld h,a
	ld a,[H_VBCOPYBGNUMROWS]
	ld b,a
	xor a
	ld [H_VBCOPYBGSRC],a ; disable transfer so it doesn't continue next V-blank
	jr TransferBgRows

; This function copies ([H_VBCOPYDOUBLESIZE] * 8) source bytes
; from H_VBCOPYDOUBLESRC to H_VBCOPYDOUBLEDEST.
; It copies each source byte to the destination twice (next to each other).
; The function updates the source and destination addresses, so the transfer
; can be continued easily by repeatingly calling this function.
VBlankCopyDouble:: ; 1e02 (0:1e02)
	ld a,[H_VBCOPYDOUBLESIZE]
	and a ; are there any bytes to copy?
	ret z
	ld hl,[sp + 0]
	ld a,h
	ld [H_SPTEMP],a
	ld a,l
	ld [H_SPTEMP + 1],a ; save stack pointer
	ld a,[H_VBCOPYDOUBLESRC]
	ld l,a
	ld a,[H_VBCOPYDOUBLESRC + 1]
	ld h,a
	ld sp,hl
	ld a,[H_VBCOPYDOUBLEDEST]
	ld l,a
	ld a,[H_VBCOPYDOUBLEDEST + 1]
	ld h,a
	ld a,[H_VBCOPYDOUBLESIZE]
	ld b,a
	xor a
	ld [H_VBCOPYDOUBLESIZE],a ; disable transfer so it doesn't continue next V-blank
.loop
	pop de
	ld [hl],e
	inc l
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	ld [hl],d
	inc hl
	dec b
	jr nz,.loop
	ld a,l
	ld [H_VBCOPYDOUBLEDEST],a
	ld a,h
	ld [H_VBCOPYDOUBLEDEST + 1],a ; update destination address
	ld hl,[sp + 0]
	ld a,l
	ld [H_VBCOPYDOUBLESRC],a
	ld a,h
	ld [H_VBCOPYDOUBLESRC + 1],a ; update source address
	ld a,[H_SPTEMP]
	ld h,a
	ld a,[H_SPTEMP + 1]
	ld l,a
	ld sp,hl ; restore stack pointer
	ret

; Copies ([H_VBCOPYSIZE] * 16) bytes from H_VBCOPYSRC to H_VBCOPYDEST.
; The function updates the source and destination addresses, so the transfer
; can be continued easily by repeatingly calling this function.
VBlankCopy:: ; 1e5e (0:1e5e)
	ld a,[H_VBCOPYSIZE]
	and a ; are there any bytes to copy?
	ret z
	ld hl,[sp + 0]
	ld a,h
	ld [H_SPTEMP],a
	ld a,l
	ld [H_SPTEMP + 1],a ; save stack pointer
	ld a,[H_VBCOPYSRC]
	ld l,a
	ld a,[H_VBCOPYSRC + 1]
	ld h,a
	ld sp,hl
	ld a,[H_VBCOPYDEST]
	ld l,a
	ld a,[H_VBCOPYDEST + 1]
	ld h,a
	ld a,[H_VBCOPYSIZE]
	ld b,a
	xor a
	ld [H_VBCOPYSIZE],a ; disable transfer so it doesn't continue next V-blank
.loop
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc l
	pop de
	ld [hl],e
	inc l
	ld [hl],d
	inc hl
	dec b
	jr nz,.loop
	ld a,l
	ld [H_VBCOPYDEST],a
	ld a,h
	ld [H_VBCOPYDEST + 1],a
	ld hl,[sp + 0]
	ld a,l
	ld [H_VBCOPYSRC],a
	ld a,h
	ld [H_VBCOPYSRC + 1],a
	ld a,[H_SPTEMP]
	ld h,a
	ld a,[H_SPTEMP + 1]
	ld l,a
	ld sp,hl ; restore stack pointer
	ret

; This function updates the moving water and flower background tiles.
UpdateMovingBgTiles:: ; 1ebe (0:1ebe)
	ld a,[$ffd7]
	and a
	ret z
	ld a,[$ffd8]
	inc a
	ld [$ffd8],a
	cp a,20
	ret c
	cp a,21
	jr z,.updateFlowerTile
	ld hl,$9140 ; water tile pattern VRAM location
	ld c,16 ; number of bytes in a tile pattern
	ld a,[$d085]
	inc a
	and a,$07
	ld [$d085],a
	and a,$04
	jr nz,.rotateWaterLeftLoop
.rotateWaterRightloop
	ld a,[hl]
	rrca
	ld [hli],a
	dec c
	jr nz,.rotateWaterRightloop
	jr .done
.rotateWaterLeftLoop
	ld a,[hl]
	rlca
	ld [hli],a
	dec c
	jr nz,.rotateWaterLeftLoop
.done
	ld a,[$ffd7]
	rrca
	ret nc
	xor a
	ld [$ffd8],a
	ret
.updateFlowerTile
	xor a
	ld [$ffd8],a
	ld a,[$d085]
	and a,$03
	cp a,2
	ld hl,FlowerTilePattern1
	jr c,.writeTilePatternToVram
	ld hl,FlowerTilePattern2
	jr z,.writeTilePatternToVram
	ld hl,FlowerTilePattern3
.writeTilePatternToVram
	ld de,$9030 ; flower tile pattern VRAM location
	ld c,16 ; number of bytes in a tile pattern
.flowerTileLoop
	ld a,[hli]
	ld [de],a
	inc de
	dec c
	jr nz,.flowerTileLoop
	ret

FlowerTilePattern1:: ; 1f19 (0:1f19)
	INCBIN "gfx/tilesets/flower/flower1.2bpp"

FlowerTilePattern2:: ; 1f29 (0:1f29)
	INCBIN "gfx/tilesets/flower/flower2.2bpp"

FlowerTilePattern3:: ; 1f39 (0:1f39)
	INCBIN "gfx/tilesets/flower/flower3.2bpp"

SoftReset:: ; 1f49 (0:1f49)
	call StopAllSounds
	call GBPalWhiteOut
	ld c, $20
	call DelayFrames
	;fall through

; initialization code
; explanation for %11100011 (value stored in rLCDC)
; * LCD enabled
; * Window tile map at $9C00
; * Window display enabled
; * BG and window tile data at $8800
; * BG tile map at $9800
; * 8x8 OBJ size
; * OBJ display enabled
; * BG display enabled
InitGame:: ; 1f54 (0:1f54)
	di
; zero I/O registers
	xor a
	ld [$ff0f],a
	ld [$ffff],a
	ld [$ff43],a
	ld [$ff42],a
	ld [$ff01],a
	ld [$ff02],a
	ld [$ff4b],a
	ld [$ff4a],a
	ld [$ff06],a
	ld [$ff07],a
	ld [$ff47],a
	ld [$ff48],a
	ld [$ff49],a
	ld a,%10000000 ; enable LCD
	ld [rLCDC],a
	call DisableLCD ; why enable then disable?
	ld sp,$dfff ; initialize stack pointer
	ld hl,$c000 ; start of WRAM
	ld bc,$2000 ; size of WRAM
.zeroWramLoop
	ld [hl],0
	inc hl
	dec bc
	ld a,b
	or c
	jr nz,.zeroWramLoop
	call ZeroVram
	ld hl,$ff80
	ld bc,$007f
	call FillMemory ; zero HRAM
	call CleanLCD_OAM ; this is unnecessary since it was already cleared above
	ld a,Bank(WriteDMACodeToHRAM)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call WriteDMACodeToHRAM ; copy DMA code to HRAM
	xor a
	ld [$ffd7],a
	ld [$ff41],a
	ld [$ffae],a
	ld [$ffaf],a
	ld [$ff0f],a
	ld a,%00001101 ; enable V-blank, timer, and serial interrupts
	ld [rIE],a
	ld a,$90 ; put the window off the screen
	ld [$ffb0],a
	ld [rWY],a
	ld a,$07
	ld [rWX],a
	ld a,$ff
	ld [$ffaa],a
	ld h,$98
	call ClearBgMap ; fill $9800-$9BFF (BG tile map) with $7F tiles
	ld h,$9c
	call ClearBgMap ; fill $9C00-$9FFF (Window tile map) with $7F tiles
	ld a,%11100011
	ld [rLCDC],a ; enabled LCD
	ld a,$10
	ld [H_SOFTRESETCOUNTER],a
	call StopAllSounds
	ei
	ld a,$40
	call Predef ; SGB border
	ld a,$1f
	ld [$c0ef],a
	ld [$c0f0],a
	ld a,$9c
	ld [$ffbd],a
	xor a
	ld [$ffbc],a
	dec a
	ld [$cfcb],a
	ld a,$32
	call Predef ; display the copyrights, GameFreak logo, and battle animation
	call DisableLCD
	call ZeroVram
	call GBPalNormal
	call CleanLCD_OAM
	ld a,%11100011
	ld [rLCDC],a ; enable LCD
	jp SetDefaultNamesBeforeTitlescreen

; zeroes all VRAM
ZeroVram:: ; 2004 (0:2004)
	ld hl,$8000
	ld bc,$2000
	xor a
	jp FillMemory

; immediately stops all sounds
StopAllSounds:: ; 200e (0:200e)
	ld a, Bank(Func_9876)
	ld [$c0ef], a
	ld [$c0f0], a
	xor a
	ld [wMusicHeaderPointer], a
	ld [$c0ee], a
	ld [$cfca], a
	dec a
	jp PlaySound

VBlank:: ; 2024 (0:2024)
	push af
	push bc
	push de
	push hl
	ld a,[H_LOADEDROMBANK] ; current ROM bank
	ld [$d122],a
	ld a,[$ffae]
	ld [rSCX],a
	ld a,[$ffaf]
	ld [rSCY],a
	ld a,[$d0a0]
	and a
	jr nz,.doVramTransfers
	ld a,[$ffb0]
	ld [rWY],a
.doVramTransfers
	call AutoBgMapTransfer
	call VBlankCopyBgMap
	call RedrawExposedScreenEdge
	call VBlankCopy
	call VBlankCopyDouble
	call UpdateMovingBgTiles
	call $ff80 ; OAM DMA
	ld a,Bank(PrepareOAMData)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call PrepareOAMData ; update OAM buffer with current sprite data
	call GenRandom
	ld a,[H_VBLANKOCCURRED]
	and a
	jr z,.next
	xor a
	ld [H_VBLANKOCCURRED],a
.next
	ld a,[H_FRAMECOUNTER]
	and a
	jr z,.handleMusic
	dec a
	ld [H_FRAMECOUNTER],a
.handleMusic
	call Func_28cb
	ld a,[$c0ef] ; music ROM bank
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	cp a,$02
	jr nz,.checkIfBank08
.bank02
	call Func_9103
	jr .afterMusic
.checkIfBank08
	cp a,$08
	jr nz,.bank1F
.bank08
	call Func_2136e
	call Func_21879
	jr .afterMusic
.bank1F
	call Func_7d177
.afterMusic
	callba Func_18dee ; keep track of time played
	ld a,[$fff9]
	and a
	call z,ReadJoypadRegister
	ld a,[$d122]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	pop hl
	pop de
	pop bc
	pop af
	reti

DelayFrame:: ; 20af (0:20af)
; delay for one frame
	ld a,1
	ld [H_VBLANKOCCURRED],a

; wait for the next Vblank, halting to conserve battery
.halt
	db $76 ; XXX this is a hack--rgbasm adds a nop after this instr even when ints are enabled
	ld a,[H_VBLANKOCCURRED]
	and a
	jr nz,.halt
	ret

; These routines manage gradual fading
; (e.g., entering a doorway)
LoadGBPal:: ; 20ba (0:20ba)
	ld a,[$d35d] ;tells if cur.map is dark (requires HM5_FLASH?)
	ld b,a
	ld hl,GBPalTable_00	;16
	ld a,l
	sub b
	ld l,a
	jr nc,.jr0
	dec h
.jr0
	ld a,[hli]
	ld [rBGP],a
	ld a,[hli]
	ld [rOBP0],a
	ld a,[hli]
	ld [rOBP1],a
	ret

GBFadeOut1:: ; 20d1 (0:20d1)
	ld hl,IncGradGBPalTable_01	;0d
	ld b,$04
	jr GBFadeOutCommon

GBFadeOut2:: ; 20d8 (0:20d8)
	ld hl,IncGradGBPalTable_02	;1c
	ld b,$03

GBFadeOutCommon:: ; 20dd (0:20dd)
	ld a,[hli]
	ld [rBGP],a
	ld a,[hli]
	ld [rOBP0],a
	ld a,[hli]
	ld [rOBP1],a
	ld c,8
	call DelayFrames
	dec b
	jr nz,GBFadeOutCommon
	ret

GBFadeIn1:: ; 20ef (0:20ef)
	ld hl,DecGradGBPalTable_01	;18
	ld b,$04
	jr GBFadeInCommon

GBFadeIn2:: ; 20f6 (0:20f6)
	ld hl,DecGradGBPalTable_02	;21
	ld b,$03

GBFadeInCommon:: ; 20fb (0:20fb)
	ld a,[hld]
	ld [rOBP1],a
	ld a,[hld]
	ld [rOBP0],a
	ld a,[hld]
	ld [rBGP],a
	ld c,8
	call DelayFrames
	dec b
	jr nz,GBFadeInCommon
	ret

IncGradGBPalTable_01:: ; 210d (0:210d)
	db %11111111 ;BG Pal
	db %11111111 ;OBJ Pal 1
	db %11111111 ;OBJ Pal 2
	             ;and so on...
	db %11111110
	db %11111110
	db %11111000

	db %11111001
	db %11100100
	db %11100100
GBPalTable_00:: ; 2116 (0:2116)
	db %11100100
	db %11010000
DecGradGBPalTable_01:: ; 2118 (0:2118)
	db %11100000
	;19
	db %11100100
	db %11010000
	db %11100000
IncGradGBPalTable_02:: ; 211c (0:211c)
	db %10010000
	db %10000000
	db %10010000

	db %01000000
	db %01000000
DecGradGBPalTable_02:: ; 2121 (0:2121)
	db %01000000

	db %00000000
	db %00000000
	db %00000000

Serial:: ; 2125 (0:2125)
	push af
	push bc
	push de
	push hl
	ld a, [$ffaa]
	inc a
	jr z, .asm_2142
	ld a, [$ff01]
	ld [$ffad], a
	ld a, [$ffac]
	ld [$ff01], a
	ld a, [$ffaa]
	cp $2
	jr z, .asm_2162
	ld a, $80
	ld [$ff02], a
	jr .asm_2162
.asm_2142
	ld a, [$ff01]
	ld [$ffad], a
	ld [$ffaa], a
	cp $2
	jr z, .asm_215f
	xor a
	ld [$ff01], a
	ld a, $3
	ld [rDIV], a ; $ff04
.asm_2153
	ld a, [rDIV] ; $ff04
	bit 7, a
	jr nz, .asm_2153
	ld a, $80
	ld [$ff02], a
	jr .asm_2162
.asm_215f
	xor a
	ld [$ff01], a
.asm_2162
	ld a, $1
	ld [$ffa9], a
	ld a, $fe
	ld [$ffac], a
	pop hl
	pop de
	pop bc
	pop af
	reti

Func_216f:: ; 216f (0:216f)
	ld a, $1
	ld [$ffab], a
.asm_2173
	ld a, [hl]
	ld [$ffac], a
	call Func_219a
	push bc
	ld b, a
	inc hl
	ld a, $30
.asm_217e
	dec a
	jr nz, .asm_217e
	ld a, [$ffab]
	and a
	ld a, b
	pop bc
	jr z, .asm_2192
	dec hl
	cp $fd
	jr nz, .asm_2173
	xor a
	ld [$ffab], a
	jr .asm_2173
.asm_2192
	ld [de], a
	inc de
	dec bc
	ld a, b
	or c
	jr nz, .asm_2173
	ret

Func_219a:: ; 219a (0:219a)
	xor a
	ld [$ffa9], a
	ld a, [$ffaa]
	cp $2
	jr nz, .asm_21a7
	ld a, $81
	ld [$ff02], a
.asm_21a7
	ld a, [$ffa9]
	and a
	jr nz, .asm_21f1
	ld a, [$ffaa]
	cp $1
	jr nz, .asm_21cc
	call Func_2237
	jr z, .asm_21cc
	call Func_2231
	push hl
	ld hl, $cc48
	inc [hl]
	jr nz, .asm_21c3
	dec hl
	inc [hl]
.asm_21c3
	pop hl
	call Func_2237
	jr nz, .asm_21a7
	jp Func_223f
.asm_21cc
	ld a, [rIE] ; $ffff
	and $f
	cp $8
	jr nz, .asm_21a7
	ld a, [W_NUMHITS] ; $d074
	dec a
	ld [W_NUMHITS], a ; $d074
	jr nz, .asm_21a7
	ld a, [$d075]
	dec a
	ld [$d075], a
	jr nz, .asm_21a7
	ld a, [$ffaa]
	cp $1
	jr z, .asm_21f1
	ld a, $ff
.asm_21ee
	dec a
	jr nz, .asm_21ee
.asm_21f1
	xor a
	ld [$ffa9], a
	ld a, [rIE] ; $ffff
	and $f
	sub $8
	jr nz, .asm_2204
	ld [W_NUMHITS], a ; $d074
	ld a, $50
	ld [$d075], a
.asm_2204
	ld a, [$ffad]
	cp $fe
	ret nz
	call Func_2237
	jr z, .asm_221f
	push hl
	ld hl, $cc48
	ld a, [hl]
	dec a
	ld [hld], a
	inc a
	jr nz, .asm_2219
	dec [hl]
.asm_2219
	pop hl
	call Func_2237
	jr z, Func_223f
.asm_221f
	ld a, [rIE] ; $ffff
	and $f
	cp $8
	ld a, $fe
	ret z
	ld a, [hl]
	ld [$ffac], a
	call DelayFrame
	jp Func_219a

Func_2231:: ; 2231 (0:2231)
	ld a, $f
.asm_2233
	dec a
	jr nz, .asm_2233
	ret

Func_2237:: ; 2237 (0:2237)
	push hl
	ld hl, $cc47
	ld a, [hli]
	or [hl]
	pop hl
	ret

Func_223f:: ; 223f (0:223f)
	dec a
	ld [$cc47], a
	ld [$cc48], a
	ret

Func_2247:: ; 2247 (0:2247)
	ld hl, $cc42
	ld de, $cc3d
	ld c, $2
	ld a, $1
	ld [$ffab], a
.asm_2253
	call DelayFrame
	ld a, [hl]
	ld [$ffac], a
	call Func_219a
	ld b, a
	inc hl
	ld a, [$ffab]
	and a
	ld a, $0
	ld [$ffab], a
	jr nz, .asm_2253
	ld a, b
	ld [de], a
	inc de
	dec c
	jr nz, .asm_2253
	ret

Func_226e:: ; 226e (0:226e)
	call SaveScreenTilesToBuffer1
	callab PrintWaitingText
	call Func_227f
	jp LoadScreenTilesFromBuffer1

Func_227f:: ; 227f (0:227f)
	ld a, $ff
	ld [$cc3e], a
.asm_2284
	call Func_22c3
	call DelayFrame
	call Func_2237
	jr z, .asm_22a0
	push hl
	ld hl, $cc48
	dec [hl]
	jr nz, .asm_229f
	dec hl
	dec [hl]
	jr nz, .asm_229f
	pop hl
	xor a
	jp Func_223f
.asm_229f
	pop hl
.asm_22a0
	ld a, [$cc3e]
	inc a
	jr z, .asm_2284
	ld b, $a
.asm_22a8
	call DelayFrame
	call Func_22c3
	dec b
	jr nz, .asm_22a8
	ld b, $a
.asm_22b3
	call DelayFrame
	call Func_22ed
	dec b
	jr nz, .asm_22b3
	ld a, [$cc3e]
	ld [$cc3d], a
	ret

Func_22c3:: ; 22c3 (0:22c3)
	call asm_22d7
	ld a, [$cc42]
	add $60
	ld [$ffac], a
	ld a, [$ffaa]
	cp $2
	jr nz, asm_22d7
	ld a, $81
	ld [$ff02], a
asm_22d7:: ; 22d7 (0:22d7)
	ld a, [$ffad]
	ld [$cc3d], a
	and $f0
	cp $60
	ret nz
	xor a
	ld [$ffad], a
	ld a, [$cc3d]
	and $f
	ld [$cc3e], a
	ret

Func_22ed:: ; 22ed (0:22ed)
	xor a
	ld [$ffac], a
	ld a, [$ffaa]
	cp $2
	ret nz
	ld a, $81
	ld [$ff02], a
	ret

Func_22fa:: ; 22fa (0:22fa)
	ld a, $2
	ld [$ff01], a
	xor a
	ld [$ffad], a
	ld a, $80
	ld [$ff02], a
	ret

; timer interrupt is apparently not invoked anyway
Timer:: ; 2306 (0:2306)
	reti

Func_2307:: ; 2307 (0:2307)
	call WaitForSoundToFinish
	xor a
	ld c, a
	ld d, a
	ld [$cfca], a
	jr asm_2324

Func_2312:: ; 2312 (0:2312)
	ld c, $a
	ld d, $0
	ld a, [$d72e]
	bit 5, a
	jr z, asm_2324
	xor a
	ld [$cfca], a
	ld c, $8
	ld d, c
asm_2324:: ; 2324 (0:2324)
	ld a, [$d700]
	and a
	jr z, .asm_2343
	cp $2
	jr z, .asm_2332
	ld a, MUSIC_BIKE_RIDING
	jr .asm_2334
.asm_2332
	ld a, MUSIC_SURFING
.asm_2334
	ld b, a
	ld a, d
	and a
	ld a, Bank(Func_7d8ea)
	jr nz, .asm_233e
	ld [$c0ef], a
.asm_233e
	ld [$c0f0], a
	jr .asm_234c
.asm_2343
	ld a, [$d35b]
	ld b, a
	call Func_2385
	jr c, .asm_2351
.asm_234c
	ld a, [$cfca]
	cp b
	ret z
.asm_2351
	ld a, c
	ld [wMusicHeaderPointer], a
	ld a, b
	ld [$cfca], a
	ld [$c0ee], a
	jp PlaySound

Func_235f:: ; 235f (0:235f)
	ld a, [$c0ef]
	ld b, a
	cp $2
	jr nz, .checkForBank08
.bank02
	ld hl, Func_9103
	jr .asm_2378
.checkForBank08
	cp $8
	jr nz, .bank1F
.bank08
	ld hl, Func_21879
	jr .asm_2378
.bank1F
	ld hl, Func_7d177
.asm_2378
	ld c, $6
.asm_237a
	push bc
	push hl
	call Bankswitch
	pop hl
	pop bc
	dec c
	jr nz, .asm_237a
	ret

Func_2385:: ; 2385 (0:2385)
	ld a, [$d35c]
	ld e, a
	ld a, [$c0ef]
	cp e
	jr nz, .asm_2394
	ld [$c0f0], a
	and a
	ret
.asm_2394
	ld a, c
	and a
	ld a, e
	jr nz, .asm_239c
	ld [$c0ef], a
.asm_239c
	ld [$c0f0], a
	scf
	ret

PlayMusic:: ; 23a1 (0:23a1)
	ld b, a
	ld [$c0ee], a
	xor a
	ld [wMusicHeaderPointer], a
	ld a, c
	ld [$c0ef], a
	ld [$c0f0], a
	ld a, b

; plays music specified by a. If value is $ff, music is stopped
PlaySound:: ; 23b1 (0:23b1)
	push hl
	push de
	push bc
	ld b, a
	ld a, [$c0ee]
	and a
	jr z, .asm_23c8
	xor a
	ld [$c02a], a
	ld [$c02b], a
	ld [$c02c], a
	ld [$c02d], a
.asm_23c8
	ld a, [wMusicHeaderPointer]
	and a
	jr z, .asm_23e3
	ld a, [$c0ee]
	and a
	jr z, .asm_2425
	xor a
	ld [$c0ee], a
	ld a, [$cfca]
	cp $ff
	jr nz, .asm_2414
	xor a
	ld [wMusicHeaderPointer], a
.asm_23e3
	xor a
	ld [$c0ee], a
	ld a, [H_LOADEDROMBANK]
	ld [$ffb9], a
	ld a, [$c0ef]
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	cp $2
	jr nz, .checkForBank08
.bank02
	ld a, b
	call Func_9876
	jr .asm_240b
.checkForBank08
	cp $8
	jr nz, .bank1F
.bank08
	ld a, b
	call Func_22035
	jr .asm_240b
.bank1F
	ld a, b
	call Func_7d8ea
.asm_240b
	ld a, [$ffb9]
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	jr .asm_2425
.asm_2414
	ld a, b
	ld [$cfca], a
	ld a, [wMusicHeaderPointer]
	ld [$cfc8], a
	ld [$cfc9], a
	ld a, b
	ld [wMusicHeaderPointer], a
.asm_2425
	pop bc
	pop de
	pop hl
	ret

UpdateSprites:: ; 2429 (0:2429)
	ld a, [$cfcb]
	dec a
	ret nz
	ld a, [H_LOADEDROMBANK]
	push af
	ld a, Bank(_UpdateSprites)
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	call _UpdateSprites
	pop af
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	ret

INCLUDE "data/mart_inventories.asm"

TextScriptEndingChar:: ; 24d6 (0:24d6)
	db "@"
TextScriptEnd:: ; 24d7 (0:24d7)
	ld hl,TextScriptEndingChar
	ret

ExclamationText:: ; 24db (0:24db)
	TX_FAR _ExclamationText
	db "@"

GroundRoseText:: ; 24e0 (0:24e0)
	TX_FAR _GroundRoseText
	db "@"

BoulderText:: ; 24e5 (0:24e5)
	TX_FAR _BoulderText
	db "@"

MartSignText:: ; 24ea (0:24ea)
	TX_FAR _MartSignText
	db "@"

PokeCenterSignText:: ; 24ef (0:24ef)
	TX_FAR _PokeCenterSignText
	db "@"

Predef5CText:: ; 24f4 (0:24f4)
; XXX better label (what does predef $5C do?)
	db $08 ; asm
	ld a, $5c
	call Predef
	jp TextScriptEnd

; bankswitches and runs _UncompressSpriteData
; bank is given in a, sprite input stream is pointed to in W_SPRITEINPUTPTR
UncompressSpriteData:: ; 24fd (0:24fd)
	ld b, a
	ld a, [H_LOADEDROMBANK]
	push af
	ld a, b
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	ld a, $a
	ld [$0], a
	xor a
	ld [$4000], a
	call _UncompressSpriteData
	pop af
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	ret

; initializes necessary data to load a sprite and runs UncompressSpriteDataLoop
_UncompressSpriteData:: ; 251a (0:251a)
	ld hl, S_SPRITEBUFFER1
	ld c, (2*SPRITEBUFFERSIZE) % $100
	ld b, (2*SPRITEBUFFERSIZE) / $100
	xor a
	call FillMemory           ; clear sprite buffer 1 and 2
	ld a, $1
	ld [W_SPRITEINPUTBITCOUNTER], a
	ld a, $3
	ld [W_SPRITEOUTPUTBITOFFSET], a
	xor a
	ld [W_SPRITECURPOSX], a
	ld [W_SPRITECURPOSY], a
	ld [W_SPRITELOADFLAGS], a ; $d0a8
	call ReadNextInputByte    ; first byte of input determines sprite width (high nybble) and height (low nybble) in tiles (8x8 pixels)
	ld b, a
	and $f
	add a
	add a
	add a
	ld [W_SPRITEHEIGHT], a
	ld a, b
	swap a
	and $f
	add a
	add a
	add a
	ld [W_SPRITEWITDH], a
	call ReadNextInputBit
	ld [W_SPRITELOADFLAGS], a ; initialite bit1 to 0 and bit0 to the first input bit
	                          ; this will load two chunks of data to S_SPRITEBUFFER1 and S_SPRITEBUFFER2
	                          ; bit 0 decides in which one the first chunk is placed
	; fall through

; uncompresses a chunk from the sprite input data stream (pointed to at $d0da) into S_SPRITEBUFFER1 or S_SPRITEBUFFER2
; each chunk is a 1bpp sprite. A 2bpp sprite consist of two chunks which are merged afterwards
; note that this is an endless loop which is terminated during a call to MoveToNextBufferPosition by manipulating the stack
UncompressSpriteDataLoop:: ; 2556 (0:2556)
	ld hl, S_SPRITEBUFFER1
	ld a, [W_SPRITELOADFLAGS]  ; $d0a8
	bit 0, a
	jr z, .useSpriteBuffer1    ; check which buffer to use
	ld hl, S_SPRITEBUFFER2
.useSpriteBuffer1
	call StoreSpriteOutputPointer
	ld a, [W_SPRITELOADFLAGS]  ; $d0a8
	bit 1, a
	jr z, .startDecompression  ; check if last iteration
	call ReadNextInputBit      ; if last chunk, read 1-2 bit unpacking mode
	and a
	jr z, .unpackingMode0      ; 0   -> mode 0
	call ReadNextInputBit      ; 1 0 -> mode 1
	inc a                      ; 1 1 -> mode 2
.unpackingMode0
	ld [W_SPRITEUNPACKMODE], a
.startDecompression
	call ReadNextInputBit
	and a
	jr z, .readRLEncodedZeros ; if first bit is 0, the input starts with zeroes, otherwise with (non-zero) input
.readNextInput
	call ReadNextInputBit
	ld c, a
	call ReadNextInputBit
	sla c
	or c                       ; read next two bits into c
	and a
	jr z, .readRLEncodedZeros ; 00 -> RLEncoded zeroes following
	call WriteSpriteBitsToBuffer  ; otherwise write input to output and repeat
	call MoveToNextBufferPosition
	jr .readNextInput
.readRLEncodedZeros
	ld c, $0                   ; number of zeroes it length encoded, the number
.countConsecutiveOnesLoop      ; of consecutive ones determines the number of bits the number has
	call ReadNextInputBit
	and a
	jr z, .countConsecutiveOnesFinished
	inc c
	jr .countConsecutiveOnesLoop
.countConsecutiveOnesFinished
	ld a, c
	add a
	ld hl, LengthEncodingOffsetList
	add l
	ld l, a
	jr nc, .noCarry
	inc h
.noCarry
	ld a, [hli]                ; read offset that is added to the number later on
	ld e, a                    ; adding an offset of 2^length - 1 makes every integer uniquely
	ld d, [hl]                 ; representable in the length encoding and saves bits
	push de
	inc c
	ld e, $0
	ld d, e
.readNumberOfZerosLoop        ; reads the next c+1 bits of input
	call ReadNextInputBit
	or e
	ld e, a
	dec c
	jr z, .readNumberOfZerosDone
	sla e
	rl d
	jr .readNumberOfZerosLoop
.readNumberOfZerosDone
	pop hl                     ; add the offset
	add hl, de
	ld e, l
	ld d, h
.writeZerosLoop
	ld b, e
	xor a                      ; write 00 to buffer
	call WriteSpriteBitsToBuffer
	ld e, b
	call MoveToNextBufferPosition
	dec de
	ld a, d
	and a
	jr nz, .continueLoop
	ld a, e
	and a
.continueLoop
	jr nz, .writeZerosLoop
	jr .readNextInput

; moves output pointer to next position
; also cancels the calling function if the all output is done (by removing the return pointer from stack)
; and calls postprocessing functions according to the unpack mode
MoveToNextBufferPosition:: ; 25d8 (0:25d8)
	ld a, [W_SPRITEHEIGHT]
	ld b, a
	ld a, [W_SPRITECURPOSY]
	inc a
	cp b
	jr z, .curColumnDone
	ld [W_SPRITECURPOSY], a
	ld a, [W_SPRITEOUTPUTPTR]
	inc a
	ld [W_SPRITEOUTPUTPTR], a
	ret nz
	ld a, [W_SPRITEOUTPUTPTR+1]
	inc a
	ld [W_SPRITEOUTPUTPTR+1], a
	ret
.curColumnDone
	xor a
	ld [W_SPRITECURPOSY], a
	ld a, [W_SPRITEOUTPUTBITOFFSET]
	and a
	jr z, .bitOffsetsDone
	dec a
	ld [W_SPRITEOUTPUTBITOFFSET], a
	ld hl, W_SPRITEOUTPUTPTRCACHED
	ld a, [hli]
	ld [W_SPRITEOUTPUTPTR], a
	ld a, [hl]
	ld [W_SPRITEOUTPUTPTR+1], a
	ret
.bitOffsetsDone
	ld a, $3
	ld [W_SPRITEOUTPUTBITOFFSET], a
	ld a, [W_SPRITECURPOSX]
	add $8
	ld [W_SPRITECURPOSX], a
	ld b, a
	ld a, [W_SPRITEWITDH]
	cp b
	jr z, .allColumnsDone
	ld a, [W_SPRITEOUTPUTPTR]
	ld l, a
	ld a, [W_SPRITEOUTPUTPTR+1]
	ld h, a
	inc hl
	jp StoreSpriteOutputPointer
.allColumnsDone
	pop hl
	xor a
	ld [W_SPRITECURPOSX], a
	ld a, [W_SPRITELOADFLAGS] ; $d0a8
	bit 1, a
	jr nz, .done            ; test if there is one more sprite to go
	xor $1
	set 1, a
	ld [W_SPRITELOADFLAGS], a ; $d0a8
	jp UncompressSpriteDataLoop
.done
	jp UnpackSprite

; writes 2 bits (from a) to the output buffer (pointed to from W_SPRITEOUTPUTPTR)
WriteSpriteBitsToBuffer:: ; 2649 (0:2649)
	ld e, a
	ld a, [W_SPRITEOUTPUTBITOFFSET]
	and a
	jr z, .offset0
	cp $2
	jr c, .offset1
	jr z, .offset2
	rrc e ; offset 3
	rrc e
	jr .offset0
.offset1
	sla e
	sla e
	jr .offset0
.offset2
	swap e
.offset0
	ld a, [W_SPRITEOUTPUTPTR]
	ld l, a
	ld a, [W_SPRITEOUTPUTPTR+1]
	ld h, a
	ld a, [hl]
	or e
	ld [hl], a
	ret

; reads next bit from input stream and returns it in a
ReadNextInputBit:: ; 2670 (0:2670)
	ld a, [W_SPRITEINPUTBITCOUNTER]
	dec a
	jr nz, .curByteHasMoreBitsToRead
	call ReadNextInputByte
	ld [W_SPRITEINPUTCURBYTE], a
	ld a, $8
.curByteHasMoreBitsToRead
	ld [W_SPRITEINPUTBITCOUNTER], a
	ld a, [W_SPRITEINPUTCURBYTE]
	rlca
	ld [W_SPRITEINPUTCURBYTE], a
	and $1
	ret

; reads next byte from input stream and returns it in a
ReadNextInputByte:: ; 268b (0:268b)
	ld a, [W_SPRITEINPUTPTR]
	ld l, a
	ld a, [W_SPRITEINPUTPTR+1]
	ld h, a
	ld a, [hli]
	ld b, a
	ld a, l
	ld [W_SPRITEINPUTPTR], a
	ld a, h
	ld [W_SPRITEINPUTPTR+1], a
	ld a, b
	ret

; the nth item is 2^n - 1
LengthEncodingOffsetList:: ; 269f (0:269f)
	dw %0000000000000001
	dw %0000000000000011
	dw %0000000000000111
	dw %0000000000001111
	dw %0000000000011111
	dw %0000000000111111
	dw %0000000001111111
	dw %0000000011111111
	dw %0000000111111111
	dw %0000001111111111
	dw %0000011111111111
	dw %0000111111111111
	dw %0001111111111111
	dw %0011111111111111
	dw %0111111111111111
	dw %1111111111111111

; unpacks the sprite data depending on the unpack mode
UnpackSprite:: ; 26bf (0:26bf)
	ld a, [W_SPRITEUNPACKMODE]
	cp $2
	jp z, UnpackSpriteMode2
	and a
	jp nz, XorSpriteChunks
	ld hl, S_SPRITEBUFFER1
	call SpriteDifferentialDecode
	ld hl, S_SPRITEBUFFER2
	; fall through

; decodes differential encoded sprite data
; input bit value 0 preserves the current bit value and input bit value 1 toggles it (starting from initial value 0).
SpriteDifferentialDecode:: ; 26d4 (0:26d4)
	xor a
	ld [W_SPRITECURPOSX], a
	ld [W_SPRITECURPOSY], a
	call StoreSpriteOutputPointer
	ld a, [W_SPRITEFLIPPED]
	and a
	jr z, .notFlipped
	ld hl, DecodeNybble0TableFlipped
	ld de, DecodeNybble1TableFlipped
	jr .storeDecodeTablesPointers
.notFlipped
	ld hl, DecodeNybble0Table
	ld de, DecodeNybble1Table
.storeDecodeTablesPointers
	ld a, l
	ld [W_SPRITEDECODETABLE0PTR], a
	ld a, h
	ld [W_SPRITEDECODETABLE0PTR+1], a
	ld a, e
	ld [W_SPRITEDECODETABLE1PTR], a
	ld a, d
	ld [W_SPRITEDECODETABLE1PTR+1], a
	ld e, $0                          ; last decoded nybble, initialized to 0
.decodeNextByteLoop
	ld a, [W_SPRITEOUTPUTPTR]
	ld l, a
	ld a, [W_SPRITEOUTPUTPTR+1]
	ld h, a
	ld a, [hl]
	ld b, a
	swap a
	and $f
	call DifferentialDecodeNybble     ; decode high nybble
	swap a
	ld d, a
	ld a, b
	and $f
	call DifferentialDecodeNybble     ; decode low nybble
	or d
	ld b, a
	ld a, [W_SPRITEOUTPUTPTR]
	ld l, a
	ld a, [W_SPRITEOUTPUTPTR+1]
	ld h, a
	ld a, b
	ld [hl], a                        ; write back decoded data
	ld a, [W_SPRITEHEIGHT]
	add l                             ; move on to next column
	jr nc, .noCarry
	inc h
.noCarry
	ld [W_SPRITEOUTPUTPTR], a
	ld a, h
	ld [W_SPRITEOUTPUTPTR+1], a
	ld a, [W_SPRITECURPOSX]
	add $8
	ld [W_SPRITECURPOSX], a
	ld b, a
	ld a, [W_SPRITEWITDH]
	cp b
	jr nz, .decodeNextByteLoop        ; test if current row is done
	xor a
	ld e, a
	ld [W_SPRITECURPOSX], a
	ld a, [W_SPRITECURPOSY]           ; move on to next row
	inc a
	ld [W_SPRITECURPOSY], a
	ld b, a
	ld a, [W_SPRITEHEIGHT]
	cp b
	jr z, .done                       ; test if all rows finished
	ld a, [W_SPRITEOUTPUTPTRCACHED]
	ld l, a
	ld a, [W_SPRITEOUTPUTPTRCACHED+1]
	ld h, a
	inc hl
	call StoreSpriteOutputPointer
	jr .decodeNextByteLoop
.done
	xor a
	ld [W_SPRITECURPOSY], a
	ret

; decodes the nybble stored in a. Last decoded data is assumed to be in e (needed to determine if initial value is 0 or 1)
DifferentialDecodeNybble:: ; 276d (0:276d)
	srl a               ; c=a%2, a/=2
	ld c, $0
	jr nc, .evenNumber
	ld c, $1
.evenNumber
	ld l, a
	ld a, [W_SPRITEFLIPPED]
	and a
	jr z, .notFlipped     ; determine if initial value is 0 or one
	bit 3, e              ; if flipped, consider MSB of last data
	jr .selectLookupTable
.notFlipped
	bit 0, e              ; else consider LSB
.selectLookupTable
	ld e, l
	jr nz, .initialValue1 ; load the appropriate table
	ld a, [W_SPRITEDECODETABLE0PTR]
	ld l, a
	ld a, [W_SPRITEDECODETABLE0PTR+1]
	jr .tableLookup
.initialValue1
	ld a, [W_SPRITEDECODETABLE1PTR]
	ld l, a
	ld a, [W_SPRITEDECODETABLE1PTR+1]
.tableLookup
	ld h, a
	ld a, e
	add l
	ld l, a
	jr nc, .noCarry
	inc h
.noCarry
	ld a, [hl]
	bit 0, c
	jr nz, .selectLowNybble
	swap a  ; select high nybble
.selectLowNybble
	and $f
	ld e, a ; update last decoded data
	ret

DecodeNybble0Table:: ; 27a7 (0:27a7)
	dn $0, $1
	dn $3, $2
	dn $7, $6
	dn $4, $5
	dn $f, $e
	dn $c, $d
	dn $8, $9
	dn $b, $a
DecodeNybble1Table:: ; 27af (0:27af)
	dn $f, $e
	dn $c, $d
	dn $8, $9
	dn $b, $a
	dn $0, $1
	dn $3, $2
	dn $7, $6
	dn $4, $5
DecodeNybble0TableFlipped:: ; 27b7 (0:27b7)
	dn $0, $8
	dn $c, $4
	dn $e, $6
	dn $2, $a
	dn $f, $7
	dn $3, $b
	dn $1, $9
	dn $d, $5
DecodeNybble1TableFlipped:: ; 27bf (0:27bf)
	dn $f, $7
	dn $3, $b
	dn $1, $9
	dn $d, $5
	dn $0, $8
	dn $c, $4
	dn $e, $6
	dn $2, $a

; combines the two loaded chunks with xor (the chunk loaded second is the destination). The source chunk is differeintial decoded beforehand.
XorSpriteChunks:: ; 27c7 (0:27c7)
	xor a
	ld [W_SPRITECURPOSX], a
	ld [W_SPRITECURPOSY], a
	call ResetSpriteBufferPointers
	ld a, [W_SPRITEOUTPUTPTR]          ; points to buffer 1 or 2, depending on flags
	ld l, a
	ld a, [W_SPRITEOUTPUTPTR+1]
	ld h, a
	call SpriteDifferentialDecode      ; decode buffer 1 or 2, depending on flags
	call ResetSpriteBufferPointers
	ld a, [W_SPRITEOUTPUTPTR]          ; source buffer, points to buffer 1 or 2, depending on flags
	ld l, a
	ld a, [W_SPRITEOUTPUTPTR+1]
	ld h, a
	ld a, [W_SPRITEOUTPUTPTRCACHED]    ; destination buffer, points to buffer 2 or 1, depending on flags
	ld e, a
	ld a, [W_SPRITEOUTPUTPTRCACHED+1]
	ld d, a
.xorChunksLoop
	ld a, [W_SPRITEFLIPPED]
	and a
	jr z, .notFlipped
	push de
	ld a, [de]
	ld b, a
	swap a
	and $f
	call ReverseNybble                 ; if flipped reverse the nybbles in the destination buffer
	swap a
	ld c, a
	ld a, b
	and $f
	call ReverseNybble
	or c
	pop de
	ld [de], a
.notFlipped
	ld a, [hli]
	ld b, a
	ld a, [de]
	xor b
	ld [de], a
	inc de
	ld a, [W_SPRITECURPOSY]
	inc a
	ld [W_SPRITECURPOSY], a             ; go to next row
	ld b, a
	ld a, [W_SPRITEHEIGHT]
	cp b
	jr nz, .xorChunksLoop               ; test if column finished
	xor a
	ld [W_SPRITECURPOSY], a
	ld a, [W_SPRITECURPOSX]
	add $8
	ld [W_SPRITECURPOSX], a             ; go to next column
	ld b, a
	ld a, [W_SPRITEWITDH]
	cp b
	jr nz, .xorChunksLoop               ; test if all columns finished
	xor a
	ld [W_SPRITECURPOSX], a
	ret

; reverses the bits in the nybble given in register a
ReverseNybble:: ; 2837 (0:2837)
	ld de, NybbleReverseTable
	add e
	ld e, a
	jr nc, .asm_283f
	inc d
.asm_283f
	ld a, [de]
	ret

; resets sprite buffer pointers to buffer 1 and 2, depending on W_SPRITELOADFLAGS
ResetSpriteBufferPointers:: ; 2841 (0:2841)
	ld a, [W_SPRITELOADFLAGS] ; $d0a8
	bit 0, a
	jr nz, .buffer2Selected
	ld de, S_SPRITEBUFFER1
	ld hl, S_SPRITEBUFFER2
	jr .storeBufferPointers
.buffer2Selected
	ld de, S_SPRITEBUFFER2
	ld hl, S_SPRITEBUFFER1
.storeBufferPointers
	ld a, l
	ld [W_SPRITEOUTPUTPTR], a
	ld a, h
	ld [W_SPRITEOUTPUTPTR+1], a
	ld a, e
	ld [W_SPRITEOUTPUTPTRCACHED], a
	ld a, d
	ld [W_SPRITEOUTPUTPTRCACHED+1], a
	ret

; maps each nybble to its reverse
NybbleReverseTable:: ; 2867 (0:2867)
	db $0, $8, $4, $c, $2, $a, $6 ,$e, $1, $9, $5, $d, $3, $b, $7 ,$f

; combines the two loaded chunks with xor (the chunk loaded second is the destination). Both chunks are differeintial decoded beforehand.
UnpackSpriteMode2:: ; 2877 (0:2877)
	call ResetSpriteBufferPointers
	ld a, [W_SPRITEFLIPPED]
	push af
	xor a
	ld [W_SPRITEFLIPPED], a            ; temporarily clear flipped flag for decoding the destination chunk
	ld a, [W_SPRITEOUTPUTPTRCACHED]
	ld l, a
	ld a, [W_SPRITEOUTPUTPTRCACHED+1]
	ld h, a
	call SpriteDifferentialDecode
	call ResetSpriteBufferPointers
	pop af
	ld [W_SPRITEFLIPPED], a
	jp XorSpriteChunks

; stores hl into the output pointers
StoreSpriteOutputPointer:: ; 2897 (0:2897)
	ld a, l
	ld [W_SPRITEOUTPUTPTR], a
	ld [W_SPRITEOUTPUTPTRCACHED], a
	ld a, h
	ld [W_SPRITEOUTPUTPTR+1], a
	ld [W_SPRITEOUTPUTPTRCACHED+1], a
	ret

ResetPlayerSpriteData:: ; 28a6 (0:28a6)
	ld hl, wSpriteStateData1
	call ResetPlayerSpriteData_ClearSpriteData
	ld hl, wSpriteStateData2
	call ResetPlayerSpriteData_ClearSpriteData
	ld a, $1
	ld [wSpriteStateData1], a
	ld [$c20e], a
	ld hl, $c104
	ld [hl], $3c     ; set Y screen pos
	inc hl
	inc hl
	ld [hl], $40     ; set X screen pos
	ret

; overwrites sprite data with zeroes
ResetPlayerSpriteData_ClearSpriteData:: ; 28c4 (0:28c4)
	ld bc, $10
	xor a
	jp FillMemory

Func_28cb:: ; 28cb (0:28cb)
	ld a, [wMusicHeaderPointer]
	and a
	jr nz, .asm_28dc
	ld a, [$d72c]
	bit 1, a
	ret nz
	ld a, $77
	ld [$ff24], a
	ret
.asm_28dc
	ld a, [$cfc9]
	and a
	jr z, .asm_28e7
	dec a
	ld [$cfc9], a
	ret
.asm_28e7
	ld a, [$cfc8]
	ld [$cfc9], a
	ld a, [$ff24]
	and a
	jr z, .asm_2903
	ld b, a
	and $f
	dec a
	ld c, a
	ld a, b
	and $f0
	swap a
	dec a
	swap a
	or c
	ld [$ff24], a
	ret
.asm_2903
	ld a, [wMusicHeaderPointer]
	ld b, a
	xor a
	ld [wMusicHeaderPointer], a
	ld a, $ff
	ld [$c0ee], a
	call PlaySound
	ld a, [$c0f0]
	ld [$c0ef], a
	ld a, b
	ld [$c0ee], a
	jp PlaySound

; this function is used to display sign messages, sprite dialog, etc.
; INPUT: [$ff8c] = sprite ID or text ID
DisplayTextID:: ; 2920 (0:2920)
	ld a,[H_LOADEDROMBANK]
	push af
	callba DisplayTextIDInit ; initialization
	ld hl,$cf11
	bit 0,[hl]
	res 0,[hl]
	jr nz,.skipSwitchToMapBank
	ld a,[W_CURMAP]
	call SwitchToMapRomBank
.skipSwitchToMapBank
	ld a,30 ; half a second
	ld [H_FRAMECOUNTER],a ; used as joypad poll timer
	ld hl,W_MAPTEXTPTR
	ld a,[hli]
	ld h,[hl]
	ld l,a ; hl = map text pointer
	ld d,$00
	ld a,[$ff8c] ; text ID
	ld [$cf13],a
	and a
	jp z,DisplayStartMenu
	cp a,$d3 ; safari game over
	jp z,DisplaySafariGameOverText
	cp a,$d0 ; fainted
	jp z,DisplayPokemonFaintedText
	cp a,$d1 ; blacked out
	jp z,DisplayPlayerBlackedOutText
	cp a,$d2 ; repel wore off
	jp z,DisplayRepelWoreOffText
	ld a,[$d4e1] ; number of sprites
	ld e,a
	ld a,[$ff8c] ; sprite ID
	cp e
	jr z,.spriteHandling
	jr nc,.skipSpriteHandling
.spriteHandling
; get the text ID of the sprite
	push hl
	push de
	push bc
	callba Func_13074 ; update the graphics of the sprite the player is talking to (to face the right direction)
	pop bc
	pop de
	ld hl,W_MAPSPRITEDATA ; NPC text entries
	ld a,[$ff8c]
	dec a
	add a
	add l
	ld l,a
	jr nc,.noCarry
	inc h
.noCarry
	inc hl
	ld a,[hl] ; a = text ID of the sprite
	pop hl
.skipSpriteHandling
; look up the address of the text in the map's text entries
	dec a
	ld e,a
	sla e
	add hl,de
	ld a,[hli]
	ld h,[hl]
	ld l,a ; hl = address of the text
	ld a,[hl] ; a = first byte of text
; check first byte of text for special cases
	cp a,$fe   ; Pokemart NPC
	jp z,DisplayPokemartDialogue
	cp a,$ff   ; Pokemon Center NPC
	jp z,DisplayPokemonCenterDialogue
	cp a,$fc   ; Item Storage PC
	jp z,FuncTX_ItemStoragePC
	cp a,$fd   ; Bill's PC
	jp z,FuncTX_BillsPC
	cp a,$f9   ; Pokemon Center PC
	jp z,FuncTX_PokemonCenterPC
	cp a,$f5   ; Vending Machine
	jr nz,.notVendingMachine
	callba VendingMachineMenu 	; jump banks to vending machine routine
	jr AfterDisplayingTextID
.notVendingMachine
	cp a,$f7   ; slot machine
	jp z,FuncTX_SlotMachine
	cp a,$f6   ; cable connection NPC in Pokemon Center
	jr nz,.notSpecialCase
	callab CableClubNPC
	jr AfterDisplayingTextID
.notSpecialCase
	call Func_3c59 ; display the text
	ld a,[$cc3c]
	and a
	jr nz,HoldTextDisplayOpen

AfterDisplayingTextID:: ; 29d6 (0:29d6)
	ld a,[$cc47]
	and a
	jr nz,HoldTextDisplayOpen
	call WaitForTextScrollButtonPress ; wait for a button press after displaying all the text

; loop to hold the dialogue box open as long as the player keeps holding down the A button
HoldTextDisplayOpen:: ; 29df (0:29df)
	call GetJoypadState
	ld a,[H_CURRENTPRESSEDBUTTONS]
	bit 0,a ; is the A button being pressed?
	jr nz,HoldTextDisplayOpen

CloseTextDisplay:: ; 29e8 (0:29e8)
	ld a,[W_CURMAP]
	call SwitchToMapRomBank
	ld a,$90
	ld [$ffb0],a ; move the window off the screen
	call DelayFrame
	call LoadGBPal
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a ; disable continuous WRAM to VRAM transfer each V-blank
; loop to make sprites face the directions they originally faced before the dialogue
	ld hl,$c219
	ld c,$0f
	ld de,$0010
.restoreSpriteFacingDirectionLoop
	ld a,[hl]
	dec h
	ld [hl],a
	inc h
	add hl,de
	dec c
	jr nz,.restoreSpriteFacingDirectionLoop
	ld a,BANK(InitMapSprites)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call InitMapSprites ; reload sprite tile pattern data (since it was partially overwritten by text tile patterns)
	ld hl,$cfc4
	res 0,[hl]
	ld a,[$d732]
	bit 3,a
	call z,LoadPlayerSpriteGraphics
	call LoadCurrentMapView
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	jp UpdateSprites ; move sprites

DisplayPokemartDialogue:: ; 2a2e (0:2a2e)
	push hl
	ld hl,PokemartGreetingText
	call PrintText
	pop hl
	inc hl
	call LoadItemList
	ld a,$02
	ld [$cf94],a ; selects between subtypes of menus
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,Bank(DisplayPokemartDialogue_)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call DisplayPokemartDialogue_
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	jp AfterDisplayingTextID

PokemartGreetingText:: ; 2a55 (0:2a55)
	TX_FAR _PokemartGreetingText
	db "@"

LoadItemList:: ; 2a5a (0:2a5a)
	ld a,$01
	ld [$cfcb],a
	ld a,h
	ld [$d128],a
	ld a,l
	ld [$d129],a
	ld de,$cf7b
.loop
	ld a,[hli]
	ld [de],a
	inc de
	cp a,$ff
	jr nz,.loop
	ret

DisplayPokemonCenterDialogue:: ; 2a72 (0:2a72)
	xor a
	ld [$ff8b],a
	ld [$ff8c],a
	ld [$ff8d],a
	inc hl
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,Bank(DisplayPokemonCenterDialogue_)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call DisplayPokemonCenterDialogue_
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	jp AfterDisplayingTextID

DisplaySafariGameOverText:: ; 2a90 (0:2a90)
	callab Func_1e9ed
	jp AfterDisplayingTextID

DisplayPokemonFaintedText:: ; 2a9b (0:2a9b)
	ld hl,PokemonFaintedText
	call PrintText
	jp AfterDisplayingTextID

PokemonFaintedText:: ; 2aa4 (0:2aa4)
	TX_FAR _PokemonFaintedText
	db "@"

DisplayPlayerBlackedOutText:: ; 2aa9 (0:2aa9)
	ld hl,PlayerBlackedOutText
	call PrintText
	ld a,[$d732]
	res 5,a
	ld [$d732],a
	jp HoldTextDisplayOpen

PlayerBlackedOutText:: ; 2aba (0:2aba)
	TX_FAR _PlayerBlackedOutText
	db "@"

DisplayRepelWoreOffText:: ; 2abf (0:2abf)
	ld hl,RepelWoreOffText
	call PrintText
	jp AfterDisplayingTextID

RepelWoreOffText:: ; 2ac8 (0:2ac8)
	TX_FAR _RepelWoreOffText
	db "@"

DisplayStartMenu:: ; 2acd (0:2acd)
	ld a,$04 ; hardcoded Bank, not sure what's it refers to
	ld [H_LOADEDROMBANK],a
	ld [$2000],a ; ROM bank 4
	ld a,[$d700] ; walking/biking/surfing
	ld [$d11a],a
	ld a, (SFX_02_3f - SFX_Headers_02) / 3 ; Start menu sound
	call PlaySound

RedisplayStartMenu:: ; 2adf (0:2adf)
	callba DrawStartMenu
	callba PrintSafariZoneSteps ; print Safari Zone info, if in Safari Zone
	call UpdateSprites ; move sprites
.loop
	call HandleMenuInput
	ld b,a
.checkIfUpPressed
	bit 6,a ; was Up pressed?
	jr z,.checkIfDownPressed
	ld a,[wCurrentMenuItem] ; menu selection
	and a
	jr nz,.loop
	ld a,[wLastMenuItem]
	and a
	jr nz,.loop
; if the player pressed tried to go past the top item, wrap around to the bottom
	ld a,[$d74b]
	bit 5,a ; does the player have the pokedex?
	ld a,6 ; there are 7 menu items with the pokedex, so the max index is 6
	jr nz,.wrapMenuItemId
	dec a ; there are only 6 menu items without the pokedex
.wrapMenuItemId
	ld [wCurrentMenuItem],a
	call EraseMenuCursor
	jr .loop
.checkIfDownPressed
	bit 7,a
	jr z,.buttonPressed
; if the player pressed tried to go past the bottom item, wrap around to the top
	ld a,[$d74b]
	bit 5,a ; does the player have the pokedex?
	ld a,[wCurrentMenuItem]
	ld c,7 ; there are 7 menu items with the pokedex
	jr nz,.checkIfPastBottom
	dec c ; there are only 6 menu items without the pokedex
.checkIfPastBottom
	cp c
	jr nz,.loop
; the player went past the bottom, so wrap to the top
	xor a
	ld [wCurrentMenuItem],a
	call EraseMenuCursor
	jr .loop
.buttonPressed ; A, B, or Start button pressed
	call PlaceUnfilledArrowMenuCursor
	ld a,[wCurrentMenuItem]
	ld [$cc2d],a ; save current menu item ID
	ld a,b
	and a,%00001010 ; was the Start button or B button pressed?
	jp nz,CloseStartMenu
	call SaveScreenTilesToBuffer2 ; copy background from wTileMap to wTileMapBackup2
	ld a,[$d74b]
	bit 5,a ; does the player have the pokedex?
	ld a,[wCurrentMenuItem]
	jr nz,.displayMenuItem
	inc a ; adjust position to account for missing pokedex menu item
.displayMenuItem
	cp a,0
	jp z,StartMenu_Pokedex
	cp a,1
	jp z,StartMenu_Pokemon
	cp a,2
	jp z,StartMenu_Item
	cp a,3
	jp z,StartMenu_TrainerInfo
	cp a,4
	jp z,StartMenu_SaveReset
	cp a,5
	jp z,StartMenu_Option

; EXIT falls through to here
CloseStartMenu:: ; 2b70 (0:2b70)
	call GetJoypadState
	ld a,[H_NEWLYPRESSEDBUTTONS]
	bit 0,a ; was A button newly pressed?
	jr nz,CloseStartMenu
	call LoadTextBoxTilePatterns
	jp CloseTextDisplay

; function to count how many bits are set in a string of bytes
; INPUT:
; hl = address of string of bytes
; b = length of string of bytes
; OUTPUT:
; [$D11E] = number of set bits
CountSetBits:: ; 2b7f (0:2b7f)
	ld c,0
.loop
	ld a,[hli]
	ld e,a
	ld d,8
.innerLoop ; count how many bits are set in the current byte
	srl e
	ld a,0
	adc c
	ld c,a
	dec d
	jr nz,.innerLoop
	dec b
	jr nz,.loop
	ld a,c
	ld [$d11e],a ; store number of set bits
	ret

; subtracts the amount the player paid from their money
; sets carry flag if there is enough money and unsets carry flag if not
SubtractAmountPaidFromMoney:: ; 2b96 (0:2b96)
	ld b,BANK(SubtractAmountPaidFromMoney_)
	ld hl,SubtractAmountPaidFromMoney_
	jp Bankswitch

; adds the amount the player sold to their money
AddAmountSoldToMoney:: ; 2b9e (0:2b9e)
	ld de,wPlayerMoney + 2
	ld hl,$ffa1 ; total price of items
	ld c,3 ; length of money in bytes
	ld a,$0b
	call Predef ; add total price to money
	ld a,$13
	ld [$d125],a
	call DisplayTextBoxID ; redraw money text box
	ld a, (SFX_02_5a - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent ; play sound
	jp WaitForSoundToFinish ; wait until sound is done playing

; function to remove an item (in varying quantities) from the player's bag or PC box
; INPUT:
; HL = address of inventory (either wNumBagItems or wNumBoxItems)
; [$CF92] = index (within the inventory) of the item to remove
; [$CF96] = quantity to remove
RemoveItemFromInventory:: ; 2bbb (0:2bbb)
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,BANK(RemoveItemFromInventory_)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call RemoveItemFromInventory_
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; function to add an item (in varying quantities) to the player's bag or PC box
; INPUT:
; HL = address of inventory (either wNumBagItems or wNumBoxItems)
; [$CF91] = item ID
; [$CF96] = item quantity
; sets carry flag if successful, unsets carry flag if unsuccessful
AddItemToInventory:: ; 2bcf (0:2bcf)
	push bc
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,BANK(AddItemToInventory_)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call AddItemToInventory_
	pop bc
	ld a,b
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	pop bc
	ret

; INPUT:
; [wListMenuID] = list menu ID
; [$cf8b] = address of the list (2 bytes)
DisplayListMenuID:: ; 2be6 (0:2be6)
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a ; disable auto-transfer
	ld a,1
	ld [$ffb7],a ; joypad state update flag
	ld a,[W_BATTLETYPE]
	and a ; is it the Old Man battle?
	jr nz,.specialBattleType
	ld a,$01 ; hardcoded bank
	jr .bankswitch
.specialBattleType ; Old Man battle
	ld a, Bank(OldManItemList)
.bankswitch
	call BankswitchHome
	ld hl,$d730
	set 6,[hl] ; turn off letter printing delay
	xor a
	ld [$cc35],a ; 0 means no item is currently being swapped
	ld [$d12a],a
	ld a,[$cf8b]
	ld l,a
	ld a,[$cf8c]
	ld h,a ; hl = address of the list
	ld a,[hl]
	ld [$d12a],a ; [$d12a] = number of list entries
	ld a,$0d ; list menu text box ID
	ld [$d125],a
	call DisplayTextBoxID ; draw the menu text box
	call UpdateSprites ; move sprites
	FuncCoord 4,2 ; coordinates of upper left corner of menu text box
	ld hl,Coord
	ld de,$090e ; height and width of menu text box
	ld a,[wListMenuID]
	and a ; is it a PC pokemon list?
	jr nz,.skipMovingSprites
	call UpdateSprites ; move sprites
.skipMovingSprites
	ld a,1 ; max menu item ID is 1 if the list has less than 2 entries
	ld [$cc37],a
	ld a,[$d12a]
	cp a,2 ; does the list have less than 2 entries?
	jr c,.setMenuVariables
	ld a,2 ; max menu item ID is 2 if the list has at least 2 entries
.setMenuVariables
	ld [wMaxMenuItem],a
	ld a,4
	ld [wTopMenuItemY],a
	ld a,5
	ld [wTopMenuItemX],a
	ld a,%00000111 ; A button, B button, Select button
	ld [wMenuWatchedKeys],a
	ld c,10
	call DelayFrames

DisplayListMenuIDLoop:: ; 2c53 (0:2c53)
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a ; disable transfer
	call PrintListMenuEntries
	ld a,1
	ld [H_AUTOBGTRANSFERENABLED],a ; enable transfer
	call Delay3
	ld a,[W_BATTLETYPE]
	and a ; is it the Old Man battle?
	jr z,.notOldManBattle
.oldManBattle
	ld a,"▶"
	FuncCoord 5,4
	ld [Coord],a ; place menu cursor in front of first menu entry
	ld c,80
	call DelayFrames
	xor a
	ld [wCurrentMenuItem],a
	ld hl,Coord
	ld a,l
	ld [wMenuCursorLocation],a
	ld a,h
	ld [wMenuCursorLocation + 1],a
	jr .buttonAPressed
.notOldManBattle
	call LoadGBPal
	call HandleMenuInput
	push af
	call PlaceMenuCursor
	pop af
	bit 0,a ; was the A button pressed?
	jp z,.checkOtherKeys
.buttonAPressed
	ld a,[wCurrentMenuItem]
	call PlaceUnfilledArrowMenuCursor
	ld a,$01
	ld [$d12e],a
	ld [$d12d],a
	xor a
	ld [$cc37],a
	ld a,[wCurrentMenuItem]
	ld c,a
	ld a,[wListScrollOffset]
	add c
	ld c,a
	ld a,[$d12a] ; number of list entries
	and a ; is the list empty?
	jp z,ExitListMenu ; if so, exit the menu
	dec a
	cp c ; did the player select Cancel?
	jp c,ExitListMenu ; if so, exit the menu
	ld a,c
	ld [wWhichPokemon],a
	ld a,[wListMenuID]
	cp a,ITEMLISTMENU
	jr nz,.skipMultiplying
; if it's an item menu
	sla c ; item entries are 2 bytes long, so multiply by 2
.skipMultiplying
	ld a,[$cf8b]
	ld l,a
	ld a,[$cf8c]
	ld h,a
	inc hl ; hl = beginning of list entries
	ld b,0
	add hl,bc
	ld a,[hl]
	ld [$cf91],a
	ld a,[wListMenuID]
	and a ; is it a PC pokemon list?
	jr z,.pokemonList
	push hl
	call GetItemPrice
	pop hl
	ld a,[wListMenuID]
	cp a,ITEMLISTMENU
	jr nz,.skipGettingQuantity
; if it's an item menu
	inc hl
	ld a,[hl] ; a = item quantity
	ld [$cf97],a
.skipGettingQuantity
	ld a,[$cf91]
	ld [$d0b5],a
	ld a,$01
	ld [$d0b7],a
	call GetName
	jr .storeChosenEntry
.pokemonList
	ld hl,W_NUMINPARTY
	ld a,[$cf8b]
	cp l ; is it a list of party pokemon or box pokemon?
	ld hl,W_PARTYMON1NAME
	jr z,.getPokemonName
	ld hl, W_BOXMON1NAME ; box pokemon names
.getPokemonName
	ld a,[wWhichPokemon]
	call GetPartyMonName
.storeChosenEntry ; store the menu entry that the player chose and return
	ld de,$cd6d
	call CopyStringToCF4B ; copy name to $cf4b
	ld a,$01
	ld [$d12e],a
	ld a,[wCurrentMenuItem]
	ld [$d12d],a
	xor a
	ld [$ffb7],a ; joypad state update flag
	ld hl,$d730
	res 6,[hl] ; turn on letter printing delay
	jp BankswitchBack
.checkOtherKeys ; check B, SELECT, Up, and Down keys
	bit 1,a ; was the B button pressed?
	jp nz,ExitListMenu ; if so, exit the menu
	bit 2,a ; was the select button pressed?
	jp nz,HandleItemListSwapping ; if so, allow the player to swap menu entries
	ld b,a
	bit 7,b ; was Down pressed?
	ld hl,wListScrollOffset
	jr z,.upPressed
.downPressed
	ld a,[hl]
	add a,3
	ld b,a
	ld a,[$d12a] ; number of list entries
	cp b ; will going down scroll past the Cancel button?
	jp c,DisplayListMenuIDLoop
	inc [hl] ; if not, go down
	jp DisplayListMenuIDLoop
.upPressed
	ld a,[hl]
	and a
	jp z,DisplayListMenuIDLoop
	dec [hl]
	jp DisplayListMenuIDLoop

DisplayChooseQuantityMenu:: ; 2d57 (0:2d57)
; text box dimensions/coordinates for just quantity
	FuncCoord 15,9
	ld hl,Coord
	ld b,1 ; height
	ld c,3 ; width
	ld a,[wListMenuID]
	cp a,PRICEDITEMLISTMENU
	jr nz,.drawTextBox
; text box dimensions/coordinates for quantity and price
	FuncCoord 7,9
	ld hl,Coord
	ld b,1  ; height
	ld c,11 ; width
.drawTextBox
	call TextBoxBorder
	FuncCoord 16,10
	ld hl,Coord
	ld a,[wListMenuID]
	cp a,PRICEDITEMLISTMENU
	jr nz,.printInitialQuantity
	FuncCoord 8,10
	ld hl,Coord
.printInitialQuantity
	ld de,InitialQuantityText
	call PlaceString
	xor a
	ld [$cf96],a ; initialize current quantity to 0
	jp .incrementQuantity
.waitForKeyPressLoop
	call GetJoypadStateLowSensitivity
	ld a,[H_NEWLYPRESSEDBUTTONS] ; newly pressed buttons
	bit 0,a ; was the A button pressed?
	jp nz,.buttonAPressed
	bit 1,a ; was the B button pressed?
	jp nz,.buttonBPressed
	bit 6,a ; was Up pressed?
	jr nz,.incrementQuantity
	bit 7,a ; was Down pressed?
	jr nz,.decrementQuantity
	jr .waitForKeyPressLoop
.incrementQuantity
	ld a,[$cf97] ; max quantity
	inc a
	ld b,a
	ld hl,$cf96 ; current quantity
	inc [hl]
	ld a,[hl]
	cp b
	jr nz,.handleNewQuantity
; wrap to 1 if the player goes above the max quantity
	ld a,1
	ld [hl],a
	jr .handleNewQuantity
.decrementQuantity
	ld hl,$cf96 ; current quantity
	dec [hl]
	jr nz,.handleNewQuantity
; wrap to the max quantity if the player goes below 1
	ld a,[$cf97] ; max quantity
	ld [hl],a
.handleNewQuantity
	FuncCoord 17,10
	ld hl,Coord
	ld a,[wListMenuID]
	cp a,PRICEDITEMLISTMENU
	jr nz,.printQuantity
.printPrice
	ld c,$03
	ld a,[$cf96]
	ld b,a
	ld hl,$ff9f ; total price
; initialize total price to 0
	xor a
	ld [hli],a
	ld [hli],a
	ld [hl],a
.addLoop ; loop to multiply the individual price by the quantity to get the total price
	ld de,$ffa1
	ld hl,$ff8d
	push bc
	ld a,$0b
	call Predef ; add the individual price to the current sum
	pop bc
	dec b
	jr nz,.addLoop
	ld a,[$ff8e]
	and a ; should the price be halved (for selling items)?
	jr z,.skipHalvingPrice
	xor a
	ld [$ffa2],a
	ld [$ffa3],a
	ld a,$02
	ld [$ffa4],a
	ld a,$0d
	call Predef ; halves the price
; store the halved price
	ld a,[$ffa2]
	ld [$ff9f],a
	ld a,[$ffa3]
	ld [$ffa0],a
	ld a,[$ffa4]
	ld [$ffa1],a
.skipHalvingPrice
	FuncCoord 12,10
	ld hl,Coord
	ld de,SpacesBetweenQuantityAndPriceText
	call PlaceString
	ld de,$ff9f ; total price
	ld c,$a3
	call PrintBCDNumber
	FuncCoord 9,10
	ld hl,Coord
.printQuantity
	ld de,$cf96 ; current quantity
	ld bc,$8102 ; print leading zeroes, 1 byte, 2 digits
	call PrintNumber
	jp .waitForKeyPressLoop
.buttonAPressed ; the player chose to make the transaction
	xor a
	ld [$cc35],a ; 0 means no item is currently being swapped
	ret
.buttonBPressed ; the player chose to cancel the transaction
	xor a
	ld [$cc35],a ; 0 means no item is currently being swapped
	ld a,$ff
	ret

InitialQuantityText:: ; 2e30 (0:2e30)
	db "×01@"

SpacesBetweenQuantityAndPriceText:: ; 2e34 (0:2e34)
	db "      @"

ExitListMenu:: ; 2e3b (0:2e3b)
	ld a,[wCurrentMenuItem]
	ld [$d12d],a
	ld a,$02
	ld [$d12e],a
	ld [$cc37],a
	xor a
	ld [$ffb7],a
	ld hl,$d730
	res 6,[hl]
	call BankswitchBack
	xor a
	ld [$cc35],a ; 0 means no item is currently being swapped
	scf
	ret

PrintListMenuEntries:: ; 2e5a (0:2e5a)
	FuncCoord 5, 3 ; $c3e1
	ld hl,Coord
	ld b,$09
	ld c,$0e
	call ClearScreenArea
	ld a,[$cf8b]
	ld e,a
	ld a,[$cf8c]
	ld d,a
	inc de ; de = beginning of list entries
	ld a,[wListScrollOffset]
	ld c,a
	ld a,[wListMenuID]
	cp a,ITEMLISTMENU
	ld a,c
	jr nz,.skipMultiplying
; if it's an item menu
; item entries are 2 bytes long, so multiply by 2
	sla a
	sla c
.skipMultiplying
	add e
	ld e,a
	jr nc,.noCarry
	inc d
.noCarry
	FuncCoord 6,4 ; coordinates of first list entry name
	ld hl,Coord
	ld b,4 ; print 4 names
.loop
	ld a,b
	ld [wWhichPokemon],a
	ld a,[de]
	ld [$d11e],a
	cp a,$ff
	jp z,.printCancelMenuItem
	push bc
	push de
	push hl
	push hl
	push de
	ld a,[wListMenuID]
	and a
	jr z,.pokemonPCMenu
	cp a,$01
	jr z,.movesMenu
.itemMenu
	call GetItemName
	jr .placeNameString
.pokemonPCMenu
	push hl
	ld hl,W_NUMINPARTY
	ld a,[$cf8b]
	cp l ; is it a list of party pokemon or box pokemon?
	ld hl,W_PARTYMON1NAME
	jr z,.getPokemonName
	ld hl, W_BOXMON1NAME ; box pokemon names
.getPokemonName
	ld a,[wWhichPokemon]
	ld b,a
	ld a,4
	sub b
	ld b,a
	ld a,[wListScrollOffset]
	add b
	call GetPartyMonName
	pop hl
	jr .placeNameString
.movesMenu
	call GetMoveName
.placeNameString
	call PlaceString
	pop de
	pop hl
	ld a,[$cf93]
	and a ; should prices be printed?
	jr z,.skipPrintingItemPrice
.printItemPrice
	push hl
	ld a,[de]
	ld de,ItemPrices
	ld [$cf91],a
	call GetItemPrice ; get price
	pop hl
	ld bc,20 + 5 ; 1 row down and 5 columns right
	add hl,bc
	ld c,$a3 ; no leading zeroes, right-aligned, print currency symbol, 3 bytes
	call PrintBCDNumber
.skipPrintingItemPrice
	ld a,[wListMenuID]
	and a
	jr nz,.skipPrintingPokemonLevel
.printPokemonLevel
	ld a,[$d11e]
	push af
	push hl
	ld hl,W_NUMINPARTY
	ld a,[$cf8b]
	cp l ; is it a list of party pokemon or box pokemon?
	ld a,$00
	jr z,.next
	ld a,$02
.next
	ld [$cc49],a
	ld hl,wWhichPokemon
	ld a,[hl]
	ld b,a
	ld a,$04
	sub b
	ld b,a
	ld a,[wListScrollOffset]
	add b
	ld [hl],a
	call LoadMonData ; load pokemon info
	ld a,[$cc49]
	and a ; is it a list of party pokemon or box pokemon?
	jr z,.skipCopyingLevel
.copyLevel
	ld a,[$cf9b]
	ld [$cfb9],a
.skipCopyingLevel
	pop hl
	ld bc,$001c
	add hl,bc
	call PrintLevel ; print level
	pop af
	ld [$d11e],a
.skipPrintingPokemonLevel
	pop hl
	pop de
	inc de
	ld a,[wListMenuID]
	cp a,ITEMLISTMENU
	jr nz,.nextListEntry
.printItemQuantity
	ld a,[$d11e]
	ld [$cf91],a
	call IsKeyItem ; check if item is unsellable
	ld a,[$d124]
	and a ; is the item unsellable?
	jr nz,.skipPrintingItemQuantity ; if so, don't print the quantity
	push hl
	ld bc,20 + 8 ; 1 row down and 8 columns right
	add hl,bc
	ld a,"×"
	ldi [hl],a
	ld a,[$d11e]
	push af
	ld a,[de]
	ld [$cf97],a
	push de
	ld de,$d11e
	ld [de],a
	ld bc,$0102
	call PrintNumber
	pop de
	pop af
	ld [$d11e],a
	pop hl
.skipPrintingItemQuantity
	inc de
	pop bc
	inc c
	push bc
	inc c
	ld a,[$cc35] ; ID of item chosen for swapping (counts from 1)
	and a ; is an item being swapped?
	jr z,.nextListEntry
	sla a
	cp c ; is it this item?
	jr nz,.nextListEntry
	dec hl
	ld a,$ec ; unfilled right arrow menu cursor to indicate an item being swapped
	ld [hli],a
.nextListEntry
	ld bc,2 * 20 ; 2 rows
	add hl,bc
	pop bc
	inc c
	dec b
	jp nz,.loop
	ld bc,-8
	add hl,bc
	ld a,$ee ; down arrow
	ld [hl],a
	ret
.printCancelMenuItem
	ld de,ListMenuCancelText
	jp PlaceString

ListMenuCancelText:: ; 2f97 (0:2f97)
	db "CANCEL@"

GetMonName:: ; 2f9e (0:2f9e)
	push hl
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,BANK(MonsterNames) ; 07
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ld a,[$d11e]
	dec a
	ld hl,MonsterNames ; 421E
	ld c,10
	ld b,0
	call AddNTimes
	ld de,$cd6d
	push de
	ld bc,10
	call CopyData
	ld hl,$cd77
	ld [hl], "@"
	pop de
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	pop hl
	ret

GetItemName:: ; 2fcf (0:2fcf)
; given an item ID at [$D11E], store the name of the item into a string
;     starting at $CD6D
	push hl
	push bc
	ld a,[$D11E]
	cp HM_01 ; is this a TM/HM?
	jr nc,.Machine

	ld [$D0B5],a
	ld a,ITEM_NAME
	ld [W_LISTTYPE],a
	ld a,BANK(ItemNames)
	ld [$D0B7],a
	call GetName
	jr .Finish

.Machine
	call GetMachineName
.Finish
	ld de,$CD6D ; pointer to where item name is stored in RAM
	pop bc
	pop hl
	ret

GetMachineName:: ; 2ff3 (0:2ff3)
; copies the name of the TM/HM in [$D11E] to $CD6D
	push hl
	push de
	push bc
	ld a,[$D11E]
	push af
	cp TM_01 ; is this a TM? [not HM]
	jr nc,.WriteTM
; if HM, then write "HM" and add 5 to the item ID, so we can reuse the
; TM printing code
	add 5
	ld [$D11E],a
	ld hl,HiddenPrefix ; points to "HM"
	ld bc,2
	jr .WriteMachinePrefix
.WriteTM
	ld hl,TechnicalPrefix ; points to "TM"
	ld bc,2
.WriteMachinePrefix
	ld de,$CD6D
	call CopyData

; now get the machine number and convert it to text
	ld a,[$D11E]
	sub TM_01 - 1
	ld b,$F6 ; "0"
.FirstDigit
	sub 10
	jr c,.SecondDigit
	inc b
	jr .FirstDigit
.SecondDigit
	add 10
	push af
	ld a,b
	ld [de],a
	inc de
	pop af
	ld b,$F6 ; "0"
	add b
	ld [de],a
	inc de
	ld a,"@"
	ld [de],a

	pop af
	ld [$D11E],a
	pop bc
	pop de
	pop hl
	ret

TechnicalPrefix:: ; 303c (0:303c)
	db "TM"
HiddenPrefix:: ; 303e (0:303e)
	db "HM"

; sets carry if item is HM, clears carry if item is not HM
; Input: a = item ID
IsItemHM:: ; 3040 (0:3040)
	cp a,HM_01
	jr c,.notHM
	cp a,TM_01
	ret
.notHM
	and a
	ret

; sets carry if move is an HM, clears carry if move is not an HM
; Input: a = move ID
IsMoveHM:: ; 3049 (0:3049)
	ld hl,HMMoves
	ld de,1
	jp IsInArray

HMMoves:: ; 3052 (0:3052)
	db CUT,FLY,SURF,STRENGTH,FLASH
	db $ff ; terminator

GetMoveName:: ; 3058 (0:3058)
	push hl
	ld a,MOVE_NAME
	ld [W_LISTTYPE],a
	ld a,[$d11e]
	ld [$d0b5],a
	ld a,BANK(MoveNames)
	ld [$d0b7],a
	call GetName
	ld de,$cd6d ; pointer to where move name is stored in RAM
	pop hl
	ret

; reloads text box tile patterns, current map view, and tileset tile patterns
ReloadMapData:: ; 3071 (0:3071)
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,[W_CURMAP]
	call SwitchToMapRomBank
	call DisableLCD
	call LoadTextBoxTilePatterns
	call LoadCurrentMapView
	call LoadTilesetTilePatternData
	call EnableLCD
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; reloads tileset tile patterns
ReloadTilesetTilePatterns:: ; 3090 (0:3090)
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,[W_CURMAP]
	call SwitchToMapRomBank
	call DisableLCD
	call LoadTilesetTilePatternData
	call EnableLCD
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; shows the town map and lets the player choose a destination to fly to
ChooseFlyDestination:: ; 30a9 (0:30a9)
	ld hl,$d72e
	res 4,[hl]
	ld b, BANK(LoadTownMap_Fly)
	ld hl, LoadTownMap_Fly
	jp Bankswitch

; causes the text box to close waithout waiting for a button press after displaying text
DisableWaitingAfterTextDisplay:: ; 30b6 (0:30b6)
	ld a,$01
	ld [$cc3c],a
	ret

; uses an item
; UseItem is used with dummy items to perform certain other functions as well
; INPUT:
; [$cf91] = item ID
; OUTPUT:
; [$cd6a] = success
; 00: unsucessful
; 01: successful
; 02: not able to be used right now, no extra menu displayed (only certain items use this)
UseItem:: ; 30bc (0:30bc)
	ld b,BANK(UseItem_)
	ld hl,UseItem_
	jp Bankswitch

; confirms the item toss and then tosses the item
; INPUT:
; hl = address of inventory (either wNumBagItems or wNumBoxItems)
; [$cf91] = item ID
; [$cf92] = index of item within inventory
; [$cf96] = quantity to toss
; OUTPUT:
; clears carry flag if the item is tossed, sets carry flag if not
TossItem:: ; 30c4 (0:30c4)
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,BANK(TossItem_)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call TossItem_
	pop de
	ld a,d
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; checks if an item is a key item
; INPUT:
; [$cf91] = item ID
; OUTPUT:
; [$d124] = result
; 00: item is not key item
; 01: item is key item
IsKeyItem:: ; 30d9 (0:30d9)
	push hl
	push de
	push bc
	callba IsKeyItem_
	pop bc
	pop de
	pop hl
	ret

; function to draw various text boxes
; INPUT:
; [$D125] = text box ID
DisplayTextBoxID:: ; 30e8 (0:30e8)
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,BANK(DisplayTextBoxID_)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call DisplayTextBoxID_
	pop bc
	ld a,b
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

Func_30fd:: ; 30fd (0:30fd)
	ld a, [$cc57]
	and a
	ret nz
	ld a, [$d736]
	bit 1, a
	ret nz
	ld a, [$d730]
	and $80
	ret

Func_310e:: ; 310e (0:310e)
	ld hl, $d736
	bit 0, [hl]
	res 0, [hl]
	jr nz, .asm_3146
	ld a, [$cc57]
	and a
	ret z
	dec a
	add a
	ld d, $0
	ld e, a
	ld hl, .pointerTable_3140
	add hl, de
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld a, [H_LOADEDROMBANK]
	push af
	ld a, [$cc58]
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	ld a, [$cf10]
	call CallFunctionInTable
	pop af
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	ret
.pointerTable_3140
	dw PointerTable_1a442
	dw PointerTable_1a510
	dw PointerTable_1a57d
.asm_3146
	ld b, BANK(Func_1a3e0)
	ld hl, Func_1a3e0
	jp Bankswitch

Func_314e:: ; 314e (0:314e)
	ld b, BANK(Func_1a41d)
	ld hl, Func_1a41d
	jp Bankswitch

Func_3156:: ; 3156 (0:3156)
	ret

; stores hl in [W_TRAINERHEADERPTR]
StoreTrainerHeaderPointer:: ; 3157 (0:3157)
	ld a, h
	ld [W_TRAINERHEADERPTR], a
	ld a, l
	ld [W_TRAINERHEADERPTR+1], a
	ret

; executes the current map script from the function pointer array provided in hl.
; a: map script index to execute (unless overridden by [$d733] bit 4)
ExecuteCurMapScriptInTable:: ; 3160 (0:3160)
	push af
	push de
	call StoreTrainerHeaderPointer
	pop hl
	pop af
	push hl
	ld hl, W_FLAGS_D733
	bit 4, [hl]
	res 4, [hl]
	jr z, .useProvidedIndex   ; test if map script index was overridden manually
	ld a, [W_CURMAPSCRIPT]
.useProvidedIndex
	pop hl
	ld [W_CURMAPSCRIPT], a
	call CallFunctionInTable
	ld a, [W_CURMAPSCRIPT]
	ret

LoadGymLeaderAndCityName:: ; 317f (0:317f)
	push de
	ld de, wGymCityName
	ld bc, $11
	call CopyData   ; load city name
	pop hl
	ld de, wGymLeaderName
	ld bc, $b
	jp CopyData     ; load gym leader name

; reads specific information from trainer header (pointed to at W_TRAINERHEADERPTR)
; a: offset in header data
;    0 -> flag's bit (into wTrainerHeaderFlagBit)
;    2 -> flag's byte ptr (into hl)
;    4 -> before battle text (into hl)
;    6 -> after battle text (into hl)
;    8 -> end battle text (into hl)
ReadTrainerHeaderInfo:: ; 3193 (0:3193)
	push de
	push af
	ld d, $0
	ld e, a
	ld hl, W_TRAINERHEADERPTR
	ld a, [hli]
	ld l, [hl]
	ld h, a
	add hl, de
	pop af
	and a
	jr nz, .nonZeroOffset
	ld a, [hl]
	ld [wTrainerHeaderFlagBit], a  ; store flag's bit
	jr .done
.nonZeroOffset
	cp $2
	jr z, .readPointer ; read flag's byte ptr
	cp $4
	jr z, .readPointer ; read before battle text
	cp $6
	jr z, .readPointer ; read after battle text
	cp $8
	jr z, .readPointer ; read end battle text
	cp $a
	jr nz, .done
	ld a, [hli]        ; read end battle text (2) but override the result afterwards (XXX why, bug?)
	ld d, [hl]
	ld e, a
	jr .done
.readPointer
	ld a, [hli]
	ld h, [hl]
	ld l, a
.done
	pop de
	ret

; calls HandleBitArray
HandleBitArray_Bank0:: ; 31c7 (0:31c7)
	ld a, $10
	jp Predef ; indirect jump to HandleBitArray (f666 (3:7666))

; direct talking to a trainer (rather than getting seen by one)
TalkToTrainer:: ; 31cc (0:31cc)
	call StoreTrainerHeaderPointer
	xor a
	call ReadTrainerHeaderInfo     ; read flag's bit
	ld a, $2
	call ReadTrainerHeaderInfo     ; read flag's byte ptr
	ld a, [wTrainerHeaderFlagBit]
	ld c, a
	ld b, $2
	call HandleBitArray_Bank0      ; read trainer's flag
	ld a, c
	and a
	jr z, .trainerNotYetFought     ; test trainer's flag
	ld a, $6
	call ReadTrainerHeaderInfo     ; print after battle text
	jp PrintText
.trainerNotYetFought ; 0x31ed
	ld a, $4
	call ReadTrainerHeaderInfo     ; print before battle text
	call PrintText
	ld a, $a
	call ReadTrainerHeaderInfo     ; (?) does nothing apparently (maybe bug in ReadTrainerHeaderInfo)
	push de
	ld a, $8
	call ReadTrainerHeaderInfo     ; read end battle text
	pop de
	call PreBattleSaveRegisters
	ld hl, W_FLAGS_D733
	set 4, [hl]                    ; activate map script index override (index is set below)
	ld hl, wFlags_0xcd60
	bit 0, [hl]                    ; test if player is already being engaged by another trainer
	ret nz
	call EngageMapTrainer
	ld hl, W_CURMAPSCRIPT
	inc [hl]      ; progress map script index (assuming it was 0 before) to start pre-battle routines
	jp Func_325d

; checks if any trainers are seeing the player and wanting to fight
CheckFightingMapTrainers:: ; 3219 (0:3219)
	call CheckForEngagingTrainers
	ld a, [$cf13]
	cp $ff
	jr nz, .trainerEngaging
	xor a
	ld [$cf13], a
	ld [wTrainerHeaderFlagBit], a
	ret
.trainerEngaging
	ld hl, W_FLAGS_D733
	set 3, [hl]
	ld [$cd4f], a
	xor a
	ld [$cd50], a
	ld a, $4c
	call Predef
	ld a, BTN_RIGHT | BTN_LEFT | BTN_UP | BTN_DOWN
	ld [wJoypadForbiddenButtonsMask], a
	xor a
	ldh [$b4], a
	call TrainerWalkUpToPlayer_Bank0
	ld hl, W_CURMAPSCRIPT
	inc [hl]      ; progress to battle phase 1 (engaging)
	ret

Func_324c:: ; 324c (0:324c)
	ld a, [$d730]
	and $1
	ret nz
	ld [wJoypadForbiddenButtonsMask], a
	ld a, [$cf13]
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call DisplayTextID

Func_325d:: ; 325d (0:325d)
	xor a
	ld [wJoypadForbiddenButtonsMask], a
	call InitBattleEnemyParameters
	ld hl, $d72d
	set 6, [hl]
	set 7, [hl]
	ld hl, $d72e
	set 1, [hl]
	ld hl, W_CURMAPSCRIPT
	inc [hl]        ; progress to battle phase 2 (battling)
	ret

EndTrainerBattle:: ; 3275 (0:3275)
	ld hl, $d126
	set 5, [hl]
	set 6, [hl]
	ld hl, $d72d
	res 7, [hl]
	ld hl, wFlags_0xcd60
	res 0, [hl]                  ; player is no longer engaged by any trainer
	ld a, [W_ISINBATTLE] ; $d057
	cp $ff
	jp z, ResetButtonPressedAndMapScript
	ld a, $2
	call ReadTrainerHeaderInfo
	ld a, [wTrainerHeaderFlagBit]
	ld c, a
	ld b, $1
	call HandleBitArray_Bank0   ; flag trainer as fought
	ld a, [W_ENEMYMONORTRAINERCLASS]
	cp $c8
	jr nc, .skipRemoveSprite    ; test if trainer was fought (in that case skip removing the corresponding sprite)
	ld hl, W_MISSABLEOBJECTLIST
	ld de, $2
	ld a, [$cf13]
	call IsInArray              ; search for sprite ID
	inc hl
	ld a, [hl]
	ld [$cc4d], a               ; load corresponding missable object index and remove it
	ld a, $11
	call Predef ; indirect jump to RemoveMissableObject (f1d7 (3:71d7))
.skipRemoveSprite
	ld hl, $d730
	bit 4, [hl]
	res 4, [hl]
	ret nz

ResetButtonPressedAndMapScript:: ; 32c1 (0:32c1)
	xor a
	ld [wJoypadForbiddenButtonsMask], a
	ld [H_CURRENTPRESSEDBUTTONS], a
	ld [H_NEWLYPRESSEDBUTTONS], a
	ld [H_NEWLYRELEASEDBUTTONS], a
	ld [W_CURMAPSCRIPT], a               ; reset battle status
	ret

; calls TrainerWalkUpToPlayer
TrainerWalkUpToPlayer_Bank0:: ; 32cf (0:32cf)
	ld b, BANK(TrainerWalkUpToPlayer)
	ld hl, TrainerWalkUpToPlayer
	jp Bankswitch

; sets opponent type and mon set/lvl based on the engaging trainer data
InitBattleEnemyParameters:: ; 32d7 (0:32d7)
	ld a, [wEngagedTrainerClass]
	ld [W_CUROPPONENT], a ; $d059
	ld [W_ENEMYMONORTRAINERCLASS], a
	cp $c8
	ld a, [wEngagedTrainerSet] ; $cd2e
	jr c, .noTrainer
	ld [W_TRAINERNO], a ; $d05d
	ret
.noTrainer
	ld [W_CURENEMYLVL], a ; $d127
	ret

Func_32ef:: ; 32ef (0:32ef)
	ld hl, Func_567f9
	jr asm_3301

Func_32f4:: ; 32f4 (0:32f4)
	ld hl, Func_56819
	jr asm_3301 ; 0x32f7 $8

Func_32f9:: ; 32f9 (0:32f9)
	ld hl, Func_5683d
	jr asm_3301

Func_32fe:: ; 32fe (0:32fe)
	ld hl, Func_5685d
asm_3301:: ; 3301 (0:3301)
	ld b, BANK(Func_567f9) ; BANK(Func_56819), BANK(Func_5683d), BANK(Func_5685d)
	jp Bankswitch ; indirect jump to one of the four functions

CheckForEngagingTrainers:: ; 3306 (0:3306)
	xor a
	call ReadTrainerHeaderInfo       ; read trainer flag's bit (unused)
	ld d, h                          ; store trainer header address in de
	ld e, l
.trainerLoop
	call StoreTrainerHeaderPointer   ; set trainer header pointer to current trainer
	ld a, [de]
	ld [$cf13], a                     ; store trainer flag's bit
	ld [wTrainerHeaderFlagBit], a
	cp $ff
	ret z
	ld a, $2
	call ReadTrainerHeaderInfo       ; read trainer flag's byte ptr
	ld b, $2
	ld a, [wTrainerHeaderFlagBit]
	ld c, a
	call HandleBitArray_Bank0        ; read trainer flag
	ld a, c
	and a
	jr nz, .trainerAlreadyFought
	push hl
	push de
	push hl
	xor a
	call ReadTrainerHeaderInfo       ; get trainer header pointer
	inc hl
	ld a, [hl]                       ; read trainer engage distance
	pop hl
	ld [wTrainerEngageDistance], a
	ld a, [$cf13]
	swap a
	ld [wTrainerSpriteOffset], a ; $cd3d
	ld a, $39
	call Predef ; indirect jump to CheckEngagePlayer (5690f (15:690f))
	pop de
	pop hl
	ld a, [wTrainerSpriteOffset] ; $cd3d
	and a
	ret nz        ; break if the trainer is engaging
.trainerAlreadyFought
	ld hl, $c
	add hl, de
	ld d, h
	ld e, l
	jr .trainerLoop

; saves loaded rom bank and hl as well as de registers
PreBattleSaveRegisters:: ; 3354 (0:3354)
	ld a, [H_LOADEDROMBANK]
	ld [W_PBSTOREDROMBANK], a
	ld a, h
	ld [W_PBSTOREDREGISTERH], a
	ld a, l
	ld [W_PBSTOREDREGISTERL], a
	ld a, d
	ld [W_PBSTOREDREGISTERD], a
	ld a, e
	ld [W_PBSTOREDREGISTERE], a
	ret

; loads data of some trainer on the current map and plays pre-battle music
; [$cf13]: sprite ID of trainer who is engaged
EngageMapTrainer:: ; 336a (0:336a)
	ld hl, W_MAPSPRITEEXTRADATA
	ld d, $0
	ld a, [$cf13]
	dec a
	add a
	ld e, a
	add hl, de     ; seek to engaged trainer data
	ld a, [hli]    ; load trainer class
	ld [wEngagedTrainerClass], a
	ld a, [hl]     ; load trainer mon set
	ld [wEnemyMonAttackMod], a ; $cd2e
	jp PlayTrainerMusic

Func_3381:: ; 3381 (0:3381)
	push hl
	ld hl, $d72d
	bit 7, [hl]
	res 7, [hl]
	pop hl
	ret z
	ld a, [H_LOADEDROMBANK]
	push af
	ld a, [W_PBSTOREDROMBANK]
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	push hl
	callba SaveTrainerName
	ld hl, TrainerNameText
	call PrintText
	pop hl
	pop af
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	callba Func_1a5e7
	jp WaitForSoundToFinish

Func_33b7:: ; 33b7 (0:33b7)
	ld a, [$cf0b]
	and a
	jr nz, .asm_33c6
	ld a, [W_PBSTOREDREGISTERH]
	ld h, a
	ld a, [W_PBSTOREDREGISTERL]
	ld l, a
	ret
.asm_33c6
	ld a, [W_PBSTOREDREGISTERD]
	ld h, a
	ld a, [W_PBSTOREDREGISTERE]
	ld l, a
	ret

TrainerNameText:: ; 33cf (0:33cf)
	TX_FAR _TrainerNameText
	db $08

Func_33d4:: ; 33d4 (0:33d4)
	call Func_33b7
	call TextCommandProcessor
	jp TextScriptEnd

Func_33dd:: ; 33dd (0:33dd)
	ld a, [wFlags_0xcd60]
	bit 0, a
	ret nz
	call EngageMapTrainer
	xor a
	ret

PlayTrainerMusic:: ; 33e8 (0:33e8)
	ld a, [wEngagedTrainerClass]
	cp $c8 + SONY1
	ret z
	cp $c8 + SONY2
	ret z
	cp $c8 + SONY3
	ret z
	ld a, [W_GYMLEADERNO] ; $d05c
	and a
	ret nz
	xor a
	ld [wMusicHeaderPointer], a
	ld a, $ff
	call PlaySound      ; stop music
	ld a, BANK(Music_MeetEvilTrainer)
	ld [$c0ef], a
	ld [$c0f0], a
	ld a, [wEngagedTrainerClass]
	ld b, a
	ld hl, EvilTrainerList
.evilTrainerListLoop
	ld a, [hli]
	cp $ff
	jr z, .noEvilTrainer
	cp b
	jr nz, .evilTrainerListLoop
	ld a, MUSIC_MEET_EVIL_TRAINER
	jr .PlaySound
.noEvilTrainer
	ld hl, FemaleTrainerList
.femaleTrainerListLoop
	ld a, [hli]
	cp $ff
	jr z, .maleTrainer
	cp b
	jr nz, .femaleTrainerListLoop
	ld a, MUSIC_MEET_FEMALE_TRAINER
	jr .PlaySound
.maleTrainer
	ld a, MUSIC_MEET_MALE_TRAINER
.PlaySound
	ld [$c0ee], a
	jp PlaySound

INCLUDE "data/trainer_types.asm"

Func_3442:: ; 3442 (0:3442)
	ld a, [hli]
	cp $ff
	ret z
	cp b
	jr nz, .asm_345b
	ld a, [hli]
	cp c
	jr nz, .asm_345c
	ld a, [hli]
	ld d, [hl]
	ld e, a
	ld hl, $ccd3
	call DecodeRLEList
	dec a
	ld [$cd38], a
	ret
.asm_345b
	inc hl
.asm_345c
	inc hl
	inc hl
	jr Func_3442

FuncTX_ItemStoragePC:: ; 3460 (0:3460)
	call SaveScreenTilesToBuffer2
	ld b, BANK(PlayerPC)
	ld hl, PlayerPC
	jr bankswitchAndContinue

FuncTX_BillsPC:: ; 346a (0:346a)
	call SaveScreenTilesToBuffer2
	ld b, BANK(Func_214c2)
	ld hl, Func_214c2
	jr bankswitchAndContinue

FuncTX_SlotMachine:: ; 3474 (0:3474)
; XXX find a better name for this function
; special_F7
	ld b,BANK(CeladonPrizeMenu)
	ld hl,CeladonPrizeMenu
bankswitchAndContinue:: ; 3479 (0:3479)
	call Bankswitch
	jp HoldTextDisplayOpen        ; continue to main text-engine function

FuncTX_PokemonCenterPC:: ; 347f (0:347f)
	ld b, BANK(ActivatePC)
	ld hl, ActivatePC
	jr bankswitchAndContinue

Func_3486:: ; 3486 (0:3486)
	xor a
	ld [$cd3b], a
	ld [$c206], a
	ld hl, $d730
	set 7, [hl]
	ret

IsItemInBag:: ; 3493 (0:3493)
; given an item_id in b
; set zero flag if item isn't in player's bag
; else reset zero flag
; related to Pokémon Tower and ghosts
	ld a,$1C
	call Predef
	ld a,b
	and a
	ret

DisplayPokedex:: ; 349b (0:349b)
	ld [$d11e], a
	ld b, BANK(Func_7c18)
	ld hl, Func_7c18
	jp Bankswitch

Func_34a6:: ; 34a6 (0:34a6)
	call Func_34ae
	ld c, $6
	jp DelayFrames

Func_34ae:: ; 34ae (0:34ae)
	ld a, $9
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	call Func_34fc
	ld a, [$ff8d]
	ld [hl], a
	ret

Func_34b9:: ; 34b9 (0:34b9)
	ld de, $fff9
	add hl, de
	ld [hl], a
	ret

; tests if the player's coordinates are in a specified array
; INPUT:
; hl = address of array
; OUTPUT:
; [$cd3d] = if there is match, the matching array index
; sets carry if the coordinates are in the array, clears carry if not
ArePlayerCoordsInArray:: ; 34bf (0:34bf)
	ld a,[W_YCOORD]
	ld b,a
	ld a,[W_XCOORD]
	ld c,a
	; fallthrough

CheckCoords:: ; 34c7 (0:34c7)
	xor a
	ld [$cd3d],a
.loop
	ld a,[hli]
	cp a,$ff ; reached terminator?
	jr z,.notInArray
	push hl
	ld hl,$cd3d
	inc [hl]
	pop hl
.compareYCoord
	cp b
	jr z,.compareXCoord
	inc hl
	jr .loop
.compareXCoord
	ld a,[hli]
	cp c
	jr nz,.loop
.inArray
	scf
	ret
.notInArray
	and a
	ret

; tests if a boulder's coordinates are in a specified array
; INPUT:
; hl = address of array
; ff8c = which boulder to check? XXX
; OUTPUT:
; [$cd3d] = if there is match, the matching array index
; sets carry if the coordinates are in the array, clears carry if not
CheckBoulderCoords:: ; 34e4 (0:34e4)
	push hl
	ld hl, $c204
	ld a, [$ff8c]
	swap a
	ld d, $0
	ld e, a
	add hl, de
	ld a, [hli]
	sub $4 ; because sprite coordinates are offset by 4
	ld b, a
	ld a, [hl]
	sub $4 ; because sprite coordinates are offset by 4
	ld c, a
	pop hl
	jp CheckCoords

Func_34fc:: ; 34fc (0:34fc)
	ld h, $c1
	jr asm_3502

Func_3500:: ; 3500 (0:3500)
	ld h, $c2
asm_3502:: ; 3502 (0:3502)
	ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
	ld b, a
	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
	swap a
	add b
	ld l, a
	ret

; decodes a $ff-terminated RLEncoded list
; each entry is a pair of bytes <byte value> <repetitions>
; the final $ff will be replicated in the output list and a contains the number of bytes written
; de: input list
; hl: output list
DecodeRLEList:: ; 350c (0:350c)
	xor a
	ld [wRLEByteCount], a     ; count written bytes here
.listLoop
	ld a, [de]
	cp $ff
	jr z, .endOfList
	ld [H_DOWNARROWBLINKCNT1], a ; store byte value to be written
	inc de
	ld a, [de]
	ld b, $0
	ld c, a                      ; number of bytes to be written
	ld a, [wRLEByteCount]
	add c
	ld [wRLEByteCount], a     ; update total number of written bytes
	ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
	call FillMemory              ; write a c-times to output
	inc de
	jr .listLoop
.endOfList
	ld a, $ff
	ld [hl], a                   ; write final $ff
	ld a, [wRLEByteCount]
	inc a                        ; include sentinel in counting
	ret

; sets movement byte 1 for sprite [$FF8C] to $FE and byte 2 to [$FF8D]
SetSpriteMovementBytesToFE:: ; 3533 (0:3533)
	push hl
	call GetSpriteMovementByte1Pointer
	ld [hl], $fe
	call GetSpriteMovementByte2Pointer
	ld a, [$ff8d]
	ld [hl], a
	pop hl
	ret

; sets both movement bytes for sprite [$FF8C] to $FF
SetSpriteMovementBytesToFF:: ; 3541 (0:3541)
	push hl
	call GetSpriteMovementByte1Pointer
	ld [hl],$FF
	call GetSpriteMovementByte2Pointer
	ld [hl],$FF ; prevent person from walking?
	pop hl
	ret

; returns the sprite movement byte 1 pointer for sprite [$FF8C] in hl
GetSpriteMovementByte1Pointer:: ; 354e (0:354e)
	ld h,$C2
	ld a,[$FF8C] ; the sprite to move
	swap a
	add a,6
	ld l,a
	ret

; returns the sprite movement byte 2 pointer for sprite [$FF8C] in hl
GetSpriteMovementByte2Pointer:: ; 3558 (0:3558)
	push de
	ld hl,W_MAPSPRITEDATA
	ld a,[$FF8C] ; the sprite to move
	dec a
	add a
	ld d,0
	ld e,a
	add hl,de
	pop de
	ret

Func_3566:: ; 3566 (0:3566)
	call Func_359e
	ld a, [W_ISLINKBATTLE] ; $d12b
	and a
	jr nz, .asm_3594
	ld a, Bank(TrainerPicAndMoneyPointers)
	call BankswitchHome
	ld a, [W_TRAINERCLASS] ; $d031
	dec a
	ld hl, TrainerPicAndMoneyPointers
	ld bc, $5
	call AddNTimes
	ld de, $d033
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hli]
	ld [de], a
	ld de, $d046
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hli]
	ld [de], a
	jp BankswitchBack
.asm_3594
	ld hl, $d033
	ld de, RedPicFront
	ld [hl], e
	inc hl
	ld [hl], d
	ret

Func_359e:: ; 359e (0:359e)
	ld b, BANK(Func_13a58)
	ld hl, Func_13a58
	jp Bankswitch

; tests if player's money are at least as much as [$ff9f]
; sets carry flag if not enough money
; sets zero flag if amounts match exactly
HasEnoughMoney:: ; 35a6 (0:35a6)
	ld de, wPlayerMoney ; $d347
	ld hl, $ff9f
	ld c, $3
	jp StringCmp

; tests if player's game corner coins are at least as many as [$ffa0]
; sets carry flag if not enough coins
; sets zero flag if amounts match exactly
HasEnoughCoins:: ; 35b1 (0:35b1)
	ld de, wPlayerCoins
	ld hl, $ffa0
	ld c, $2
	jp StringCmp

BankswitchHome:: ; 35bc (0:35bc)
; switches to bank # in a
; Only use this when in the home bank!
	ld [$CF09],a
	ld a,[H_LOADEDROMBANK]
	ld [$CF08],a
	ld a,[$CF09]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

BankswitchBack:: ; 35cd (0:35cd)
; returns from BankswitchHome
	ld a,[$CF08]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

Bankswitch:: ; 35d6 (0:35d6)
; self-contained bankswitch, use this when not in the home bank
; switches to the bank in b
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,b
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ld bc,.Return
	push bc
	jp [hl]
.Return
	pop bc
	ld a,b
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

; displays yes/no choice
; yes -> set carry
YesNoChoice:: ; 35ec (0:35ec)
	call SaveScreenTilesToBuffer1
	call InitYesNoTextBoxParameters
	jr DisplayYesNoChoice

Func_35f4:: ; 35f4 (0:35f4)
	ld a, $14
	ld [$d125], a
	call InitYesNoTextBoxParameters
	jp DisplayTextBoxID

InitYesNoTextBoxParameters:: ; 35ff (0:35ff)
	xor a
	ld [$d12c], a
	FuncCoord 14, 7 ; $c43a
	ld hl, Coord
	ld bc, $80f
	ret

YesNoChoicePokeCenter:: ; 360a (0:360a)
	call SaveScreenTilesToBuffer1
	ld a, $6
	ld [$d12c], a
	FuncCoord 11, 6 ; $c423
	ld hl, Coord
	ld bc, $80c
	jr DisplayYesNoChoice

Func_361a:: ; 361a (0:361a)
	call SaveScreenTilesToBuffer1
	ld a, $3
	ld [$d12c], a
	FuncCoord 12, 7 ; $c438
	ld hl, Coord
	ld bc, $080d
DisplayYesNoChoice:: ; 3628 (0:3628)
	ld a, $14
	ld [$d125], a
	call DisplayTextBoxID
	jp LoadScreenTilesFromBuffer1

; calculates the difference |a-b|, setting carry flag if a<b
CalcDifference:: ; 3633 (0:3633)
	sub b
	ret nc
	cpl
	add $1
	scf
	ret

MoveSprite:: ; 363a (0:363a)
; move the sprite [$FF8C] with the movement pointed to by de
; actually only copies the movement data to $CC5B for later
	call SetSpriteMovementBytesToFF
MoveSprite_:: ; 363d (0:363d)
	push hl
	push bc
	call GetSpriteMovementByte1Pointer
	xor a
	ld [hl],a
	ld hl,$CC5B
	ld c,0

.loop
	ld a,[de]
	ld [hli],a
	inc de
	inc c
	cp a,$FF ; have we reached the end of the movement data?
	jr nz,.loop

	ld a,c
	ld [$CF0F],a ; number of steps taken

	pop bc
	ld hl,$D730
	set 0,[hl]
	pop hl
	xor a
	ld [$CD3B],a
	ld [$CCD3],a
	dec a
	ld [wJoypadForbiddenButtonsMask],a
	ld [$CD3A],a
	ret

Func_366b:: ; 366b (0:366b)
	push hl
	ld hl, $ffe7
	xor a
	ld [hld], a
	ld a, [hld]
	and a
	jr z, .asm_367e
	ld a, [hli]
.asm_3676
	sub [hl]
	jr c, .asm_367e
	inc hl
	inc [hl]
	dec hl
	jr .asm_3676
.asm_367e
	pop hl
	ret

; copies the tile patterns for letters and numbers into VRAM
LoadFontTilePatterns:: ; 3680 (0:3680)
	ld a,[rLCDC]
	bit 7,a ; is the LCD enabled?
	jr nz,.lcdEnabled
.lcdDisabled
	ld hl,FontGraphics
	ld de,$8800
	ld bc,$400
	ld a,BANK(FontGraphics)
	jp FarCopyDataDouble ; if LCD is off, transfer all at once
.lcdEnabled
	ld de,FontGraphics
	ld hl,$8800
	ld bc,(BANK(FontGraphics) << 8 | $80)
	jp CopyVideoDataDouble ; if LCD is on, transfer during V-blank

; copies the text box tile patterns into VRAM
LoadTextBoxTilePatterns:: ; 36a0 (0:36a0)
	ld a,[rLCDC]
	bit 7,a ; is the LCD enabled?
	jr nz,.lcdEnabled
.lcdDisabled
	ld hl,TextBoxGraphics
	ld de,$9600
	ld bc,$0200
	ld a,BANK(TextBoxGraphics)
	jp FarCopyData2 ; if LCD is off, transfer all at once
.lcdEnabled
	ld de,TextBoxGraphics
	ld hl,$9600
	ld bc,(BANK(TextBoxGraphics) << 8 | $20)
	jp CopyVideoData ; if LCD is on, transfer during V-blank

; copies HP bar and status display tile patterns into VRAM
LoadHpBarAndStatusTilePatterns:: ; 36c0 (0:36c0)
	ld a,[rLCDC]
	bit 7,a ; is the LCD enabled?
	jr nz,.lcdEnabled
.lcdDisabled
	ld hl,HpBarAndStatusGraphics
	ld de,$9620
	ld bc,$01e0
	ld a,BANK(HpBarAndStatusGraphics)
	jp FarCopyData2 ; if LCD is off, transfer all at once
.lcdEnabled
	ld de,HpBarAndStatusGraphics
	ld hl,$9620
	ld bc,(BANK(HpBarAndStatusGraphics) << 8 | $1e)
	jp CopyVideoData ; if LCD is on, transfer during V-blank

;Fills memory range with the specified byte.
;input registers a = fill_byte, bc = length, hl = address
FillMemory:: ; 36e0 (0:36e0)
	push de
	ld d, a
.loop
	ld a, d
	ldi [hl], a
	dec bc
	ld a, b
	or c
	jr nz, .loop
	pop de
	ret

; loads sprite that de points to
; bank of sprite is given in a
UncompressSpriteFromDE:: ; 36eb (0:36eb)
	ld hl, W_SPRITEINPUTPTR
	ld [hl], e
	inc hl
	ld [hl], d
	jp UncompressSpriteData

SaveScreenTilesToBuffer2:: ; 36f4 (0:36f4)
	ld hl, wTileMap
	ld de, wTileMapBackup2
	ld bc, $168
	call CopyData
	ret

LoadScreenTilesFromBuffer2:: ; 3701 (0:3701)
	call LoadScreenTilesFromBuffer2DisableBGTransfer
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ret

; loads screen tiles stored in wTileMapBackup2 but leaves H_AUTOBGTRANSFERENABLED disabled
LoadScreenTilesFromBuffer2DisableBGTransfer:: ; 3709 (0:3709)
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld hl, wTileMapBackup2
	ld de, wTileMap
	ld bc, $168
	call CopyData
	ret

SaveScreenTilesToBuffer1:: ; 3719 (0:3719)
	ld hl, wTileMap
	ld de, wTileMapBackup
	ld bc, $168
	jp CopyData

LoadScreenTilesFromBuffer1:: ; 3725 (0:3725)
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld hl, wTileMapBackup
	ld de, wTileMap
	ld bc, $168
	call CopyData
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ret

DelayFrames:: ; 3739 (0:3739)
; wait n frames, where n is the value in c
	call DelayFrame
	dec c
	jr nz,DelayFrames
	ret

PlaySoundWaitForCurrent:: ; 3740 (0:3740)
	push af
	call WaitForSoundToFinish
	pop af
	jp PlaySound

; Wait for sound to finish playing
WaitForSoundToFinish:: ; 3748 (0:3748)
	ld a, [$d083]
	and $80
	ret nz
	push hl
.asm_374f
	ld hl, $c02a
	xor a
	or [hl]
	inc hl
	or [hl]
	inc hl
	inc hl
	or [hl]
	jr nz, .asm_374f
	pop hl
	ret

NamePointers:: ; 375d (0:375d)
	dw MonsterNames
	dw MoveNames
	dw UnusedNames
	dw ItemNames
	dw W_PARTYMON1OT ; player's OT names list
	dw W_ENEMYMON1OT ; enemy's OT names list
	dw TrainerNames

GetName:: ; 376b (0:376b)
; arguments:
; [$D0B5] = which name
; [$D0B6] = which list (W_LISTTYPE)
; [$D0B7] = bank of list
;
; returns pointer to name in de
	ld a,[$d0b5]
	ld [$d11e],a
	cp a,$C4        ;it's TM/HM
	jp nc,GetMachineName
	ld a,[H_LOADEDROMBANK]
	push af
	push hl
	push bc
	push de
	ld a,[W_LISTTYPE]    ;List3759_entrySelector
	dec a
	jr nz,.otherEntries
	;1 = MON_NAMES
	call GetMonName
	ld hl,11
	add hl,de
	ld e,l
	ld d,h
	jr .gotPtr
.otherEntries ; $378d
	;2-7 = OTHER ENTRIES
	ld a,[$d0b7]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ld a,[W_LISTTYPE]    ;VariousNames' entryID
	dec a
	add a
	ld d,0
	ld e,a
	jr nc,.skip
	inc d
.skip ; $37a0
	ld hl,NamePointers
	add hl,de
	ld a,[hli]
	ld [$ff96],a
	ld a,[hl]
	ld [$ff95],a
	ld a,[$ff95]
	ld h,a
	ld a,[$ff96]
	ld l,a
	ld a,[$d0b5]
	ld b,a
	ld c,0
.nextName
	ld d,h
	ld e,l
.nextChar
	ld a,[hli]
	cp a, "@"
	jr nz,.nextChar
	inc c           ;entry counter
	ld a,b          ;wanted entry
	cp c
	jr nz,.nextName
	ld h,d
	ld l,e
	ld de,$cd6d
	ld bc,$0014
	call CopyData
.gotPtr ; $37cd
	ld a,e
	ld [$cf8d],a
	ld a,d
	ld [$cf8e],a
	pop de
	pop bc
	pop hl
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

GetItemPrice:: ; 37df (0:37df)
	ld a, [H_LOADEDROMBANK]
	push af
	ld a, [wListMenuID] ; $cf94
	cp $1
	ld a, $1 ; hardcoded Bank
	jr nz, .asm_37ed
	ld a, $f ; hardcoded Bank
.asm_37ed
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	ld hl, $cf8f
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld a, [$cf91]
	cp HM_01
	jr nc, .asm_3812
	ld bc, $3
.asm_3802
	add hl, bc
	dec a
	jr nz, .asm_3802
	dec hl
	ld a, [hld]
	ld [$ff8d], a
	ld a, [hld]
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	ld a, [hl]
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	jr .asm_381c
.asm_3812
	ld a, Bank(GetMachinePrice)
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	call GetMachinePrice
.asm_381c
	ld de, H_DOWNARROWBLINKCNT1 ; $ff8b
	pop af
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	ret

; copies a string from [de] to [$cf4b]
CopyStringToCF4B:: ; 3826 (0:3826)
	ld hl, $cf4b
	; fall through

; copies a string from [de] to [hl]
CopyString:: ; 3829 (0:3829)
	ld a, [de]
	inc de
	ld [hli], a
	cp "@"
	jr nz, CopyString
	ret

; this function is used when lower button sensitivity is wanted (e.g. menus)
; OUTPUT: [$ffb5] = pressed buttons in usual format
; there are two flags that control its functionality, [$ffb6] and [$ffb7]
; there are esentially three modes of operation
; 1. Get newly pressed buttons only
;    ([$ffb7] == 0, [$ffb6] == any)
;    Just copies [H_NEWLYPRESSEDBUTTONS] to [$ffb5].
; 2. Get currently pressed buttons at low sample rate with delay
;    ([$ffb7] == 1, [$ffb6] != 0)
;    If the user holds down buttons for more than half a second,
;    report buttons as being pressed up to 12 times per second thereafter.
;    If the user holds down buttons for less than half a second,
;    report only one button press.
; 3. Same as 2, but report no buttons as pressed if A or B is held down.
;    ([$ffb7] == 1, [$ffb6] == 0)
GetJoypadStateLowSensitivity:: ; 3831 (0:3831)
	call GetJoypadState
	ld a,[$ffb7] ; flag
	and a ; get all currently pressed buttons or only newly pressed buttons?
	ld a,[H_NEWLYPRESSEDBUTTONS] ; newly pressed buttons
	jr z,.storeButtonState
	ld a,[H_CURRENTPRESSEDBUTTONS] ; all currently pressed buttons
.storeButtonState
	ld [$ffb5],a
	ld a,[H_NEWLYPRESSEDBUTTONS] ; newly pressed buttons
	and a ; have any buttons been newly pressed since last check?
	jr z,.noNewlyPressedButtons
.newlyPressedButtons
	ld a,30 ; half a second delay
	ld [H_FRAMECOUNTER],a
	ret
.noNewlyPressedButtons
	ld a,[H_FRAMECOUNTER]
	and a ; is the delay over?
	jr z,.delayOver
.delayNotOver
	xor a
	ld [$ffb5],a ; report no buttons as pressed
	ret
.delayOver
; if [$ffb6] = 0 and A or B is pressed, report no buttons as pressed
	ld a,[H_CURRENTPRESSEDBUTTONS]
	and a,%00000011 ; A and B buttons
	jr z,.setShortDelay
	ld a,[$ffb6] ; flag
	and a
	jr nz,.setShortDelay
	xor a
	ld [$ffb5],a
.setShortDelay
	ld a,5 ; 1/12 of a second delay
	ld [H_FRAMECOUNTER],a
	ret

WaitForTextScrollButtonPress:: ; 3865 (0:3865)
	ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
	push af
	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
	push af
	xor a
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld a, $6
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
.asm_3872
	push hl
	ld a, [$d09b]
	and a
	jr z, .asm_387c
	call Func_716c6
.asm_387c
	FuncCoord 18, 16 ; $c4f2
	ld hl, Coord
	call HandleDownArrowBlinkTiming
	pop hl
	call GetJoypadStateLowSensitivity
	ld a, $2d
	call Predef ; indirect jump to Func_5a5f (5a5f (1:5a5f))
	ld a, [$ffb5]
	and BTN_A | BTN_B ; $3
	jr z, .asm_3872
	pop af
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	pop af
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ret

; (unlass in link battle) waits for A or B being pressed and outputs the scrolling sound effect
ManualTextScroll:: ; 3898 (0:3898)
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr z, .inLinkBattle
	call WaitForTextScrollButtonPress
	ld a, (SFX_02_40 - SFX_Headers_02) / 3
	jp PlaySound
.inLinkBattle
	ld c, $41
	jp DelayFrames

; function to do multiplication
; all values are big endian
; INPUT
; FF96-FF98 =  multiplicand
; FF99 = multiplier
; OUTPUT
; FF95-FF98 = product
Multiply:: ; 38ac (0:38ac)
	push hl
	push bc
	callab _Multiply
	pop bc
	pop hl
	ret

; function to do division
; all values are big endian
; INPUT
; FF95-FF98 = dividend
; FF99 = divisor
; b = number of bytes in the dividend (starting from FF95)
; OUTPUT
; FF95-FF98 = quotient
; FF99 = remainder
Divide:: ; 38b9 (0:38b9)
	push hl
	push de
	push bc
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,Bank(_Divide)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call _Divide
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	pop bc
	pop de
	pop hl
	ret

; This function is used to wait a short period after printing a letter to the
; screen unless the player presses the A/B button or the delay is turned off
; through the [$d730] or [$d358] flags.
PrintLetterDelay:: ; 38d3 (0:38d3)
	ld a,[$d730]
	bit 6,a
	ret nz
	ld a,[$d358]
	bit 1,a
	ret z
	push hl
	push de
	push bc
	ld a,[$d358]
	bit 0,a
	jr z,.waitOneFrame
	ld a,[$d355]
	and a,$0f
	ld [H_FRAMECOUNTER],a
	jr .checkButtons
.waitOneFrame
	ld a,1
	ld [H_FRAMECOUNTER],a
.checkButtons
	call GetJoypadState
	ld a,[H_CURRENTPRESSEDBUTTONS]
.checkAButton
	bit 0,a ; is the A button pressed?
	jr z,.checkBButton
	jr .endWait
.checkBButton
	bit 1,a ; is the B button pressed?
	jr z,.buttonsNotPressed
.endWait
	call DelayFrame
	jr .done
.buttonsNotPressed ; if neither A nor B is pressed
	ld a,[H_FRAMECOUNTER]
	and a
	jr nz,.checkButtons
.done
	pop bc
	pop de
	pop hl
	ret

; Copies [hl, bc) to [de, bc - hl).
; In other words, the source data is from hl up to but not including bc,
; and the destination is de.
CopyDataUntil:: ; 3913 (0:3913)
	ld a,[hli]
	ld [de],a
	inc de
	ld a,h
	cp b
	jr nz,CopyDataUntil
	ld a,l
	cp c
	jr nz,CopyDataUntil
	ret

; Function to remove a pokemon from the party or the current box.
; wWhichPokemon determines the pokemon.
; [$cf95] == 0 specifies the party.
; [$cf95] != 0 specifies the current box.
RemovePokemon:: ; 391f (0:391f)
	ld hl, _RemovePokemon
	ld b, BANK(_RemovePokemon)
	jp Bankswitch

AddPokemonToParty:: ; 3927 (0:3927)
	push hl
	push de
	push bc
	callba _AddPokemonToParty
	pop bc
	pop de
	pop hl
	ret

; calculates all 5 stats of current mon and writes them to [de]
CalcStats:: ; 3936 (0:3936)
	ld c, $0
.statsLoop
	inc c
	call CalcStat
	ld a, [H_MULTIPLICAND+1]
	ld [de], a
	inc de
	ld a, [H_MULTIPLICAND+2]
	ld [de], a
	inc de
	ld a, c
	cp $5
	jr nz, .statsLoop
	ret

; calculates stat c of current mon
; c: stat to calc (HP=1,Atk=2,Def=3,Spd=4,Spc=5)
; b: consider stat exp?
; hl: base ptr to stat exp values ([hl + 2*c - 1] and [hl + 2*c])
CalcStat:: ; 394a (0:394a)
	push hl
	push de
	push bc
	ld a, b
	ld d, a
	push hl
	ld hl, W_MONHEADER
	ld b, $0
	add hl, bc
	ld a, [hl]          ; read base value of stat
	ld e, a
	pop hl
	push hl
	sla c
	ld a, d
	and a
	jr z, .statExpDone  ; consider stat exp?
	add hl, bc          ; skip to corresponding stat exp value
.statExpLoop            ; calculates ceil(Sqrt(stat exp)) in b
	xor a
	ld [H_MULTIPLICAND], a
	ld [H_MULTIPLICAND+1], a
	inc b               ; increment current stat exp bonus
	ld a, b
	cp $ff
	jr z, .statExpDone
	ld [H_MULTIPLICAND+2], a
	ld [H_MULTIPLIER], a
	call Multiply
	ld a, [hld]
	ld d, a
	ld a, [$ff98]
	sub d
	ld a, [hli]
	ld d, a
	ld a, [$ff97]
	sbc d               ; test if (current stat exp bonus)^2 < stat exp
	jr c, .statExpLoop
.statExpDone
	srl c
	pop hl
	push bc
	ld bc, $b           ; skip to stat IV values
	add hl, bc
	pop bc
	ld a, c
	cp $2
	jr z, .getAttackIV
	cp $3
	jr z, .getDefenseIV
	cp $4
	jr z, .getSpeedIV
	cp $5
	jr z, .getSpecialIV
.getHpIV
	push bc
	ld a, [hl]  ; Atk IV
	swap a
	and $1
	sla a
	sla a
	sla a
	ld b, a
	ld a, [hli] ; Def IV
	and $1
	sla a
	sla a
	add b
	ld b, a
	ld a, [hl] ; Spd IV
	swap a
	and $1
	sla a
	add b
	ld b, a
	ld a, [hl] ; Spc IV
	and $1
	add b      ; HP IV: LSB of the other 4 IVs
	pop bc
	jr .calcStatFromIV
.getAttackIV
	ld a, [hl]
	swap a
	and $f
	jr .calcStatFromIV
.getDefenseIV
	ld a, [hl]
	and $f
	jr .calcStatFromIV
.getSpeedIV
	inc hl
	ld a, [hl]
	swap a
	and $f
	jr .calcStatFromIV
.getSpecialIV
	inc hl
	ld a, [hl]
	and $f
.calcStatFromIV
	ld d, $0
	add e
	ld e, a
	jr nc, .noCarry
	inc d                     ; de = Base + IV
.noCarry
	sla e
	rl d                      ; de = (Base + IV) * 2
	srl b
	srl b                     ; b = ceil(Sqrt(stat exp)) / 4
	ld a, b
	add e
	jr nc, .noCarry2
	inc d                     ; da = (Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4
.noCarry2
	ld [H_MULTIPLICAND+2], a
	ld a, d
	ld [H_MULTIPLICAND+1], a
	xor a
	ld [H_MULTIPLICAND], a
	ld a, [W_CURENEMYLVL] ; $d127
	ld [H_MULTIPLIER], a
	call Multiply            ; ((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level
	ld a, [H_MULTIPLICAND]
	ld [H_DIVIDEND], a
	ld a, [H_MULTIPLICAND+1]
	ld [H_DIVIDEND+1], a
	ld a, [H_MULTIPLICAND+2]
	ld [H_DIVIDEND+2], a
	ld a, $64
	ld [H_DIVISOR], a
	ld a, $3
	ld b, a
	call Divide             ; (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100
	ld a, c
	cp $1
	ld a, $5
	jr nz, .notHPStat
	ld a, [W_CURENEMYLVL] ; $d127
	ld b, a
	ld a, [H_MULTIPLICAND+2]
	add b
	ld [H_MULTIPLICAND+2], a
	jr nc, .noCarry3
	ld a, [H_MULTIPLICAND+1]
	inc a
	ld [H_MULTIPLICAND+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level
.noCarry3
	ld a, $a
.notHPStat
	ld b, a
	ld a, [H_MULTIPLICAND+2]
	add b
	ld [H_MULTIPLICAND+2], a
	jr nc, .noCarry4
	ld a, [H_MULTIPLICAND+1]
	inc a                    ; non-HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + 5
	ld [H_MULTIPLICAND+1], a ; HP: (((Base + IV) * 2 + ceil(Sqrt(stat exp)) / 4) * Level) / 100 + Level + 10
.noCarry4
	ld a, [H_MULTIPLICAND+1] ; check for overflow (>999)
	cp $4
	jr nc, .overflow
	cp $3
	jr c, .noOverflow
	ld a, [H_MULTIPLICAND+2]
	cp $e8
	jr c, .noOverflow
.overflow
	ld a, $3                 ; overflow: cap at 999
	ld [H_MULTIPLICAND+1], a
	ld a, $e7
	ld [H_MULTIPLICAND+2], a
.noOverflow
	pop bc
	pop de
	pop hl
	ret

AddEnemyMonToPlayerParty:: ; 3a53 (0:3a53)
	ld a, [H_LOADEDROMBANK]
	push af
	ld a, BANK(_AddEnemyMonToPlayerParty)
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	call _AddEnemyMonToPlayerParty
	pop bc
	ld a, b
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	ret

Func_3a68:: ; 3a68 (0:3a68)
	ld a, [H_LOADEDROMBANK]
	push af
	ld a, BANK(Func_f51e)
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	call Func_f51e
	pop bc
	ld a, b
	ld [H_LOADEDROMBANK], a
	ld [$2000], a
	ret

; skips a text entries, each of size $b (like trainer name, OT name, rival name, ...)
; hl: base pointer, will be incremented by $b * a
SkipFixedLengthTextEntries:: ; 3a7d (0:3a7d)
	and a
	ret z
	ld bc, $b
.skipLoop
	add hl, bc
	dec a
	jr nz, .skipLoop
	ret

AddNTimes:: ; 3a87 (0:3a87)
; add bc to hl a times
	and a
	ret z
.loop
	add hl,bc
	dec a
	jr nz,.loop
	ret

; Compare strings, c bytes in length, at de and hl.
; Often used to compare big endian numbers in battle calculations.
StringCmp:: ; 3a8e (0:3a8e)
	ld a,[de]
	cp [hl]
	ret nz
	inc de
	inc hl
	dec c
	jr nz,StringCmp
	ret

; INPUT:
; a = oam block index (each block is 4 oam entries)
; b = Y coordinate of upper left corner of sprite
; c = X coordinate of upper left corner of sprite
; de = base address of 4 tile number and attribute pairs
WriteOAMBlock:: ; 3a97 (0:3a97)
	ld h,$c3
	swap a ; multiply by 16
	ld l,a
	call .writeOneEntry ; upper left
	push bc
	ld a,8
	add c
	ld c,a
	call .writeOneEntry ; upper right
	pop bc
	ld a,8
	add b
	ld b,a
	call .writeOneEntry ; lower left
	ld a,8
	add c
	ld c,a
	                      ; lower right
.writeOneEntry
	ld [hl],b ; Y coordinate
	inc hl
	ld [hl],c ; X coordinate
	inc hl
	ld a,[de] ; tile number
	inc de
	ld [hli],a
	ld a,[de] ; attribute
	inc de
	ld [hli],a
	ret

HandleMenuInput:: ; 3abe (0:3abe)
	xor a
	ld [$d09b],a

HandleMenuInputPokemonSelection:: ; 3ac2 (0:3ac2)
	ld a,[H_DOWNARROWBLINKCNT1]
	push af
	ld a,[H_DOWNARROWBLINKCNT2]
	push af ; save existing values on stack
	xor a
	ld [H_DOWNARROWBLINKCNT1],a ; blinking down arrow timing value 1
	ld a,$06
	ld [H_DOWNARROWBLINKCNT2],a ; blinking down arrow timing value 2
.loop1
	xor a
	ld [$d08b],a ; counter for pokemon shaking animation
	call PlaceMenuCursor
	call Delay3
.loop2
	push hl
	ld a,[$d09b]
	and a ; is it a pokemon selection menu?
	jr z,.getJoypadState
	callba AnimatePartyMon ; shake mini sprite of selected pokemon
.getJoypadState
	pop hl
	call GetJoypadStateLowSensitivity
	ld a,[$ffb5]
	and a ; was a key pressed?
	jr nz,.keyPressed
	push hl
	FuncCoord 18,11 ; coordinates of blinking down arrow in some menus
	ld hl,Coord
	call HandleDownArrowBlinkTiming ; blink down arrow (if any)
	pop hl
	ld a,[wMenuJoypadPollCount]
	dec a
	jr z,.giveUpWaiting
	jr .loop2
.giveUpWaiting
; if a key wasn't pressed within the specified number of checks
	pop af
	ld [H_DOWNARROWBLINKCNT2],a
	pop af
	ld [H_DOWNARROWBLINKCNT1],a ; restore previous values
	xor a
	ld [wMenuWrappingEnabled],a ; disable menu wrapping
	ret
.keyPressed
	xor a
	ld [$cc4b],a
	ld a,[$ffb5]
	ld b,a
	bit 6,a ; pressed Up key?
	jr z,.checkIfDownPressed
.upPressed
	ld a,[wCurrentMenuItem] ; selected menu item
	and a ; already at the top of the menu?
	jr z,.alreadyAtTop
.notAtTop
	dec a
	ld [wCurrentMenuItem],a ; move selected menu item up one space
	jr .checkOtherKeys
.alreadyAtTop
	ld a,[wMenuWrappingEnabled]
	and a ; is wrapping around enabled?
	jr z,.noWrappingAround
	ld a,[wMaxMenuItem]
	ld [wCurrentMenuItem],a ; wrap to the bottom of the menu
	jr .checkOtherKeys
.checkIfDownPressed
	bit 7,a
	jr z,.checkOtherKeys
.downPressed
	ld a,[wCurrentMenuItem]
	inc a
	ld c,a
	ld a,[wMaxMenuItem]
	cp c
	jr nc,.notAtBottom
.alreadyAtBottom
	ld a,[wMenuWrappingEnabled]
	and a ; is wrapping around enabled?
	jr z,.noWrappingAround
	ld c,$00 ; wrap from bottom to top
.notAtBottom
	ld a,c
	ld [wCurrentMenuItem],a
.checkOtherKeys
	ld a,[wMenuWatchedKeys]
	and b ; does the menu care about any of the pressed keys?
	jp z,.loop1
.checkIfAButtonOrBButtonPressed
	ld a,[$ffb5]
	and a,%00000011 ; pressed A button or B button?
	jr z,.skipPlayingSound
.AButtonOrBButtonPressed
	push hl
	ld hl,wFlags_0xcd60
	bit 5,[hl]
	pop hl
	jr nz,.skipPlayingSound
	ld a,(SFX_02_40 - SFX_Headers_02) / 3
	call PlaySound ; play sound
.skipPlayingSound
	pop af
	ld [H_DOWNARROWBLINKCNT2],a
	pop af
	ld [H_DOWNARROWBLINKCNT1],a ; restore previous values
	xor a
	ld [wMenuWrappingEnabled],a ; disable menu wrapping
	ld a,[$ffb5]
	ret
.noWrappingAround
	ld a,[$cc37]
	and a ; should we return if the user tried to go past the top or bottom?
	jr z,.checkOtherKeys
	jr .checkIfAButtonOrBButtonPressed

PlaceMenuCursor:: ; 3b7c (0:3b7c)
	ld a,[wTopMenuItemY]
	and a ; is the y coordinate 0?
	jr z,.adjustForXCoord
	ld hl,wTileMap
	ld bc,20 ; screen width
.topMenuItemLoop
	add hl,bc
	dec a
	jr nz,.topMenuItemLoop
.adjustForXCoord
	ld a,[wTopMenuItemX]
	ld b,$00
	ld c,a
	add hl,bc
	push hl
	ld a,[wLastMenuItem]
	and a ; was the previous menu id 0?
	jr z,.checkForArrow1
	push af
	ld a,[$fff6]
	bit 1,a ; is the menu double spaced?
	jr z,.doubleSpaced1
	ld bc,20
	jr .getOldMenuItemScreenPosition
.doubleSpaced1
	ld bc,40
.getOldMenuItemScreenPosition
	pop af
.oldMenuItemLoop
	add hl,bc
	dec a
	jr nz,.oldMenuItemLoop
.checkForArrow1
	ld a,[hl]
	cp a,"▶" ; was an arrow next to the previously selected menu item?
	jr nz,.skipClearingArrow
.clearArrow
	ld a,[wTileBehindCursor]
	ld [hl],a
.skipClearingArrow
	pop hl
	ld a,[wCurrentMenuItem]
	and a
	jr z,.checkForArrow2
	push af
	ld a,[$fff6]
	bit 1,a ; is the menu double spaced?
	jr z,.doubleSpaced2
	ld bc,20
	jr .getCurrentMenuItemScreenPosition
.doubleSpaced2
	ld bc,40
.getCurrentMenuItemScreenPosition
	pop af
.currentMenuItemLoop
	add hl,bc
	dec a
	jr nz,.currentMenuItemLoop
.checkForArrow2
	ld a,[hl]
	cp a,"▶" ; has the right arrow already been placed?
	jr z,.skipSavingTile ; if so, don't lose the saved tile
	ld [wTileBehindCursor],a ; save tile before overwriting with right arrow
.skipSavingTile
	ld a,"▶" ; place right arrow
	ld [hl],a
	ld a,l
	ld [wMenuCursorLocation],a
	ld a,h
	ld [wMenuCursorLocation + 1],a
	ld a,[wCurrentMenuItem]
	ld [wLastMenuItem],a
	ret

; This is used to mark a menu cursor other than the one currently being
; manipulated. In the case of submenus, this is used to show the location of
; the menu cursor in the parent menu. In the case of swapping items in list,
; this is used to mark the item that was first chosen to be swapped.
PlaceUnfilledArrowMenuCursor:: ; 3bec (0:3bec)
	ld b,a
	ld a,[wMenuCursorLocation]
	ld l,a
	ld a,[wMenuCursorLocation + 1]
	ld h,a
	ld [hl],$ec ; outline of right arrow
	ld a,b
	ret

; Replaces the menu cursor with a blank space.
EraseMenuCursor:: ; 3bf9 (0:3bf9)
	ld a,[wMenuCursorLocation]
	ld l,a
	ld a,[wMenuCursorLocation + 1]
	ld h,a
	ld [hl]," "
	ret

; This toggles a blinking down arrow at hl on and off after a delay has passed.
; This is often called even when no blinking is occurring.
; The reason is that most functions that call this initialize H_DOWNARROWBLINKCNT1 to 0.
; The effect is that if the tile at hl is initialized with a down arrow,
; this function will toggle that down arrow on and off, but if the tile isn't
; initliazed with a down arrow, this function does nothing.
; That allows this to be called without worrying about if a down arrow should
; be blinking.
HandleDownArrowBlinkTiming:: ; 3c04 (0:3c04)
	ld a,[hl]
	ld b,a
	ld a,$ee ; down arrow
	cp b
	jr nz,.downArrowOff
.downArrowOn
	ld a,[H_DOWNARROWBLINKCNT1]
	dec a
	ld [H_DOWNARROWBLINKCNT1],a
	ret nz
	ld a,[H_DOWNARROWBLINKCNT2]
	dec a
	ld [H_DOWNARROWBLINKCNT2],a
	ret nz
	ld a," "
	ld [hl],a
	ld a,$ff
	ld [H_DOWNARROWBLINKCNT1],a
	ld a,$06
	ld [H_DOWNARROWBLINKCNT2],a
	ret
.downArrowOff
	ld a,[H_DOWNARROWBLINKCNT1]
	and a
	ret z
	dec a
	ld [H_DOWNARROWBLINKCNT1],a
	ret nz
	dec a
	ld [H_DOWNARROWBLINKCNT1],a
	ld a,[H_DOWNARROWBLINKCNT2]
	dec a
	ld [H_DOWNARROWBLINKCNT2],a
	ret nz
	ld a,$06
	ld [H_DOWNARROWBLINKCNT2],a
	ld a,$ee ; down arrow
	ld [hl],a
	ret

; The following code either enables or disables the automatic drawing of
; text boxes by DisplayTextID. Both functions cause DisplayTextID to wait
; for a button press after displaying text (unless [$cc47] is set).

EnableAutoTextBoxDrawing:: ; 3c3c (0:3c3c)
	xor a
	jr AutoTextBoxDrawingCommon

DisableAutoTextBoxDrawing:: ; 3c3f (0:3c3f)
	ld a,$01

AutoTextBoxDrawingCommon:: ; 3c41 (0:3c41)
	ld [$cf0c],a ; control text box drawing
	xor a
	ld [$cc3c],a ; make DisplayTextID wait for button press
	ret

PrintText:: ; 3c49 (0:3c49)
; given a pointer in hl, print the text there
	push hl
	ld a,1
	ld [$D125],a
	call DisplayTextBoxID
	call UpdateSprites
	call Delay3
	pop hl
Func_3c59:: ; 3c59 (0:3c59)
	FuncCoord 1,14
	ld bc,Coord ;$C4B9
	jp TextCommandProcessor

; converts a big-endian binary number into decimal and prints it
; INPUT:
; b = flags and number of bytes
; bit 7: if set, print leading zeroes
;        if unset, do not print leading zeroes
; bit 6: if set, left-align the string (do not pad empty digits with spaces)
;        if unset, right-align the string
; bits 4-5: unused
; bits 0-3: number of bytes (only 1 - 3 bytes supported)
; c = number of decimal digits
; de = address of the number (big-endian)
PrintNumber:: ; 3c5f (0:3c5f)
	push bc
	xor a
	ld [H_PASTLEADINGZEROES],a
	ld [H_NUMTOPRINT],a
	ld [H_NUMTOPRINT + 1],a
	ld a,b
	and a,%00001111
	cp a,1
	jr z,.oneByte
	cp a,2
	jr z,.twoBytes
.threeBytes
	ld a,[de]
	ld [H_NUMTOPRINT],a
	inc de
	ld a,[de]
	ld [H_NUMTOPRINT + 1],a
	inc de
	ld a,[de]
	ld [H_NUMTOPRINT + 2],a
	jr .checkNumDigits
.twoBytes
	ld a,[de]
	ld [H_NUMTOPRINT + 1],a
	inc de
	ld a,[de]
	ld [H_NUMTOPRINT + 2],a
	jr .checkNumDigits
.oneByte
	ld a,[de]
	ld [H_NUMTOPRINT + 2],a
.checkNumDigits
	push de
	ld d,b
	ld a,c
	ld b,a
	xor a
	ld c,a
	ld a,b ; a = number of decimal digits
	cp a,2
	jr z,.tensPlace
	cp a,3
	jr z,.hundredsPlace
	cp a,4
	jr z,.thousandsPlace
	cp a,5
	jr z,.tenThousandsPlace
	cp a,6
	jr z,.hundredThousandsPlace
.millionsPlace
	ld a,1000000 >> 16
	ld [H_POWEROFTEN],a
	ld a,(1000000 >> 8) & $FF
	ld [H_POWEROFTEN + 1],a
	ld a,1000000 & $FF
	ld [H_POWEROFTEN + 2],a
	call PrintNumber_PrintDigit
	call PrintNumber_AdvancePointer
.hundredThousandsPlace
	ld a,100000 >> 16
	ld [H_POWEROFTEN],a
	ld a,(100000 >> 8) & $FF
	ld [H_POWEROFTEN + 1],a
	ld a,100000 & $FF
	ld [H_POWEROFTEN + 2],a
	call PrintNumber_PrintDigit
	call PrintNumber_AdvancePointer
.tenThousandsPlace
	xor a
	ld [H_POWEROFTEN],a
	ld a,10000 >> 8
	ld [H_POWEROFTEN + 1],a
	ld a,10000 & $FF
	ld [H_POWEROFTEN + 2],a
	call PrintNumber_PrintDigit
	call PrintNumber_AdvancePointer
.thousandsPlace
	xor a
	ld [H_POWEROFTEN],a
	ld a,1000 >> 8
	ld [H_POWEROFTEN + 1],a
	ld a,1000 & $FF
	ld [H_POWEROFTEN + 2],a
	call PrintNumber_PrintDigit
	call PrintNumber_AdvancePointer
.hundredsPlace
	xor a
	ld [H_POWEROFTEN],a
	xor a
	ld [H_POWEROFTEN + 1],a
	ld a,100
	ld [H_POWEROFTEN + 2],a
	call PrintNumber_PrintDigit
	call PrintNumber_AdvancePointer
.tensPlace
	ld c,00
	ld a,[H_NUMTOPRINT + 2]
.loop
	cp a,10
	jr c,.underflow
	sub a,10
	inc c
	jr .loop
.underflow
	ld b,a
	ld a,[H_PASTLEADINGZEROES]
	or c
	ld [H_PASTLEADINGZEROES],a
	jr nz,.pastLeadingZeroes
	call PrintNumber_PrintLeadingZero
	jr .advancePointer
.pastLeadingZeroes
	ld a,"0"
	add c
	ld [hl],a
.advancePointer
	call PrintNumber_AdvancePointer
.onesPlace
	ld a,"0"
	add b
	ld [hli],a
	pop de
	dec de
	pop bc
	ret

; prints a decimal digit
; This works by repeatedely subtracting a power of ten until the number becomes negative.
; The number of subtractions it took in order to make the number negative is the digit for the current number place.
; The last value that the number had before becoming negative is kept as the new value of the number.
; A more succinct description is that the number is divided by a power of ten
; and the quotient becomes the digit while the remainder is stored as the new value of the number.
PrintNumber_PrintDigit:: ; 3d25 (0:3d25)
	ld c,0 ; counts number of loop iterations to determine the decimal digit
.loop
	ld a,[H_POWEROFTEN]
	ld b,a
	ld a,[H_NUMTOPRINT]
	ld [H_SAVEDNUMTOPRINT],a
	cp b
	jr c,.underflow0
	sub b
	ld [H_NUMTOPRINT],a
	ld a,[H_POWEROFTEN + 1]
	ld b,a
	ld a,[H_NUMTOPRINT + 1]
	ld [H_SAVEDNUMTOPRINT + 1],a
	cp b
	jr nc,.noBorrowForByte1
.byte1BorrowFromByte0
	ld a,[H_NUMTOPRINT]
	or a,0
	jr z,.underflow1
	dec a
	ld [H_NUMTOPRINT],a
	ld a,[H_NUMTOPRINT + 1]
.noBorrowForByte1
	sub b
	ld [H_NUMTOPRINT + 1],a
	ld a,[H_POWEROFTEN + 2]
	ld b,a
	ld a,[H_NUMTOPRINT + 2]
	ld [H_SAVEDNUMTOPRINT + 2],a
	cp b
	jr nc,.noBorrowForByte2
.byte2BorrowFromByte1
	ld a,[H_NUMTOPRINT + 1]
	and a
	jr nz,.finishByte2BorrowFromByte1
.byte2BorrowFromByte0
	ld a,[H_NUMTOPRINT]
	and a
	jr z,.underflow2
	dec a
	ld [H_NUMTOPRINT],a
	xor a
.finishByte2BorrowFromByte1
	dec a
	ld [H_NUMTOPRINT + 1],a
	ld a,[H_NUMTOPRINT + 2]
.noBorrowForByte2
	sub b
	ld [H_NUMTOPRINT + 2],a
	inc c
	jr .loop
.underflow2
	ld a,[H_SAVEDNUMTOPRINT + 1]
	ld [H_NUMTOPRINT + 1],a
.underflow1
	ld a,[H_SAVEDNUMTOPRINT]
	ld [H_NUMTOPRINT],a
.underflow0
	ld a,[H_PASTLEADINGZEROES]
	or c
	jr z,PrintNumber_PrintLeadingZero
	ld a,"0"
	add c
	ld [hl],a
	ld [H_PASTLEADINGZEROES],a
	ret

; prints a leading zero unless they are turned off in the flags
PrintNumber_PrintLeadingZero:: ; 3d83 (0:3d83)
	bit 7,d ; print leading zeroes?
	ret z
	ld [hl],"0"
	ret

; increments the pointer unless leading zeroes are not being printed,
; the number is left-aligned, and no nonzero digits have been printed yet
PrintNumber_AdvancePointer:: ; 3d89 (0:3d89)
	bit 7,d ; print leading zeroes?
	jr nz,.incrementPointer
	bit 6,d ; left alignment or right alignment?
	jr z,.incrementPointer
	ld a,[H_PASTLEADINGZEROES]
	and a
	ret z
.incrementPointer
	inc hl
	ret

; calls a function from a table of function pointers
; INPUT:
; a = index within table
; hl = address of function pointer table
CallFunctionInTable:: ; 3d97 (0:3d97)
	push hl
	push de
	push bc
	add a
	ld d,0
	ld e,a
	add hl,de
	ld a,[hli]
	ld h,[hl]
	ld l,a
	ld de,.returnAddress
	push de
	jp [hl]
.returnAddress
	pop bc
	pop de
	pop hl
	ret

; searches an array at hl for the value in a.
; skips (de − 1) bytes between reads, so to check every byte, de should be 1.
; if found, returns count in b and sets carry.
IsInArray:: ; 3dab (0:3dab)
	ld b,0
	; fall through

IsInArrayCummulativeCount:: ; 3dad (0:3dad)
	ld c,a
.loop
	ld a,[hl]
	cp a,$FF
	jr z,.NotInArray
	cp c
	jr z,.InArray
	inc b
	add hl,de
	jr .loop
.NotInArray
	and a
	ret
.InArray
	scf
	ret

Func_3dbe:: ; 3dbe (0:3dbe)
	call CleanLCD_OAM
	ld a, $1
	ld [$cfcb], a
	call Func_3e08
	call LoadScreenTilesFromBuffer2
	call LoadTextBoxTilePatterns
	call GoPAL_SET_CF1C
	jr Delay3

; calls GBPalWhiteOut and then Delay3
GBPalWhiteOutWithDelay3:: ; 3dd4 (0:3dd4)
	call GBPalWhiteOut

Delay3:: ; 3dd7 (0:3dd7)
; call Delay with a parameter of 3
	ld c,3
	jp DelayFrames

; resets BGP and OBP0 to their usual colors
GBPalNormal:: ; 3ddc (0:3ddc)
	ld a,%11100100
	ld [rBGP],a
	ld a,%11010000
	ld [rOBP0],a
	ret

; makes all palette colors white
GBPalWhiteOut:: ; 3de5 (0:3de5)
	xor a
	ld [rBGP],a
	ld [rOBP0],a
	ld [rOBP1],a
	ret

GoPAL_SET_CF1C:: ; 3ded (0:3ded)
	ld b,$ff
GoPAL_SET:: ; 3def (0:3def)
	ld a,[$cf1b]
	and a
	ret z
	ld a,$45
	jp Predef

Func_3df9:: ; 3df9 (0:3df9)
	ld a, e
	cp $1b
	ld d, $0
	jr nc, .asm_3e06
	cp $a
	inc d
	jr nc, .asm_3e06
	inc d
.asm_3e06
	ld [hl], d
	ret

Func_3e08:: ; 3e08 (0:3e08)
	ld hl, $cfc4
	ld a, [hl]
	push af
	res 0, [hl]
	push hl
	xor a
	ld [W_SPRITESETID], a ; $d3a8
	call DisableLCD
	callba InitMapSprites
	call EnableLCD
	pop hl
	pop af
	ld [hl], a
	call LoadPlayerSpriteGraphics
	call LoadFontTilePatterns
	jp UpdateSprites

GiveItem:: ; 3e2e (0:3e2e)
; Give player quantity c of item b, and copy item name to $cf4b.
; Set carry on success. If no room in bag, reset carry.
	ld a, b
	ld [$d11e], a
	ld [$cf91], a
	ld a, c
	ld [$cf96], a
	ld hl,wNumBagItems
	call AddItemToInventory
	ret nc
	call GetItemName ; $2fcf
	call CopyStringToCF4B
	scf
	ret

GivePokemon:: ; 3e48 (0:3e48)
	ld a, b
	ld [$cf91], a
	ld a, c
	ld [$d127], a
	xor a
	ld [$cc49], a
	ld b, BANK(_GivePokemon)
	ld hl, _GivePokemon
	jp Bankswitch

GenRandom:: ; 3e5c (0:3e5c)
; store a random 8-bit value in a
	push hl
	push de
	push bc
	callba GenRandom_
	ld a,[H_RAND1]
	pop bc
	pop de
	pop hl
	ret

Predef:: ; 3e6d (0:3e6d)
; runs a predefined ASM command, where the command ID is read from $D0B7
; $3E6D grabs the ath pointer from PredefPointers and executes it

	ld [$CC4E],a ; save the predef routine's ID for later

	ld a,[H_LOADEDROMBANK]
	ld [$CF12],a

	; save bank and call 13:7E49
	push af
	ld a,BANK(GetPredefPointer)
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	call GetPredefPointer

	; call the predef function
	; ($D0B7 has the bank of the predef routine)
	ld a,[$D0B7]
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ld de,.Return
	push de
	jp [hl]
	; after the predefined function finishes it returns here
.Return
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ret

;loads hl from cc4f, de from cc51, and bc from cc53

Load16BitRegisters:: ; 3e94 (0:3e94)
	ld a, [$cc4f]
	ld h, a
	ld a, [$cc50]
	ld l, a
	ld a, [$cc51]
	ld d, a
	ld a, [$cc52]
	ld e, a
	ld a, [$cc53]
	ld b, a
	ld a, [$cc54]
	ld c, a
	ret

Func_3ead:: ; 3ead (0:3ead)
	ld b, BANK(Func_1eb0a)
	ld hl, Func_1eb0a
	jp Bankswitch

Func_3eb5:: ; 3eb5 (0:3eb5)
	ld a, [H_LOADEDROMBANK]
	push af
	ld a, [H_CURRENTPRESSEDBUTTONS]
	bit 0, a
	jr z, .asm_3eea
	ld a, Bank(Func_469a0)
	ld [$2000], a
	ld [H_LOADEDROMBANK], a
	call Func_469a0
	ld a, [$ffee]
	and a
	jr nz, .asm_3edd
	ld a, [$cd3e]
	ld [$2000], a
	ld [H_LOADEDROMBANK], a
	ld de, .asm_3eda
	push de
	jp [hl]
.asm_3eda
	xor a
	jr .asm_3eec
.asm_3edd
	callba PrintBookshelfText
	ld a, [$ffdb]
	and a
	jr z, .asm_3eec
.asm_3eea
	ld a, $ff
.asm_3eec
	ld [$ffeb], a
	pop af
	ld [$2000], a
	ld [H_LOADEDROMBANK], a
	ret

PrintPredefTextID:: ; 3ef5 (0:3ef5)
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	ld hl, PointerTable_3f22
	call Func_3f0f
	ld hl, $cf11
	set 0, [hl]
	call DisplayTextID

Func_3f05:: ; 3f05 (0:3f05)
	ld hl, W_MAPTEXTPTR ; $d36c
	ld a, [$ffec]
	ld [hli], a
	ld a, [$ffed]
	ld [hl], a
	ret

Func_3f0f:: ; 3f0f (0:3f0f)
	ld a, [W_MAPTEXTPTR] ; $d36c
	ld [$ffec], a
	ld a, [$d36d]
	ld [$ffed], a
	ld a, l
	ld [W_MAPTEXTPTR], a ; $d36c
	ld a, h
	ld [$d36d], a
	ret

PointerTable_3f22:: ; 3f22 (0:3f22)
	dw CardKeySuccessText                   ; id = 01
	dw CardKeyFailText                      ; id = 02
	dw Route15UpstairsLeftBinoculars        ; id = 03
	dw RedBedroomSNESText                   ; id = 04
	dw PushStartText                        ; id = 05
	dw SaveOptionText                       ; id = 06
	dw StrengthsAndWeaknessesText           ; id = 07
	dw OakLabEmailText                      ; id = 08
	dw AerodactylFossilText                 ; id = 09
	dw Route15UpstairsBinocularsText        ; id = 0A
	dw KabutopsFossilText                   ; id = 0B
	dw GymStatueText1                       ; id = 0C
	dw GymStatueText2                       ; id = 0D
	dw BookcaseText                         ; id = 0E
	dw ViridianCityPokecenterBenchGuyText   ; id = 0F
	dw PewterCityPokecenterBenchGuyText     ; id = 10
	dw CeruleanCityPokecenterBenchGuyText   ; id = 11
	dw LavenderCityPokecenterBenchGuyText   ; id = 12
	dw VermilionCityPokecenterBenchGuyText  ; id = 13
	dw CeladonCityPokecenterBenchGuyText    ; id = 14
	dw CeladonCityHotelText                 ; id = 15
	dw FuchsiaCityPokecenterBenchGuyText    ; id = 16
	dw CinnabarIslandPokecenterBenchGuyText ; id = 17
	dw SaffronCityPokecenterBenchGuyText    ; id = 18
	dw MtMoonPokecenterBenchGuyText         ; id = 19
	dw RockTunnelPokecenterBenchGuyText     ; id = 1A
	dw UnnamedText_624c1                    ; id = 1B
	dw UnnamedText_624c6                    ; id = 1C
	dw UnnamedText_624cb                    ; id = 1D
	dw TerminatorText_62508                 ; id = 1E
	dw PredefText1f                         ; id = 1F
	dw ViridianSchoolNotebook               ; id = 20
	dw ViridianSchoolBlackboard             ; id = 21
	dw JustAMomentText                      ; id = 22
	dw PredefText23                         ; id = 23
	dw FoundHiddenItemText                  ; id = 24
	dw HiddenItemBagFullText                ; id = 25
	dw VermilionGymTrashText                ; id = 26
	dw IndigoPlateauHQText                  ; id = 27
	dw GameCornerOutOfOrderText             ; id = 28
	dw GameCornerOutToLunchText             ; id = 29
	dw GameCornerSomeonesKeysText           ; id = 2A
	dw FoundHiddenCoinsText                 ; id = 2B
	dw DroppedHiddenCoinsText               ; id = 2C
	dw BillsHouseMonitorText                ; id = 2D
	dw BillsHouseInitiatedText              ; id = 2E
	dw BillsHousePokemonList                ; id = 2F
	dw MagazinesText                        ; id = 30
	dw CinnabarGymQuiz                      ; id = 31
	dw GameCornerNoCoinsText                ; id = 32
	dw GameCornerCoinCaseText               ; id = 33
	dw LinkCableHelp                        ; id = 34
	dw TMNotebook                           ; id = 35
	dw FightingDojoText                     ; id = 36
	dw UnnamedText_52a10                    ; id = 37
	dw UnnamedText_52a1d                    ; id = 38
	dw NewBicycleText                       ; id = 39
	dw IndigoPlateauStatues                 ; id = 3A
	dw VermilionGymTrashSuccesText1         ; id = 3B
	dw VermilionGymTrashSuccesText2         ; id = 3C
	dw VermilionGymTrashSuccesText3         ; id = 3D
	dw VermilionGymTrashFailText            ; id = 3E
	dw TownMapText                          ; id = 3F
	dw BookOrSculptureText                  ; id = 40
	dw ElevatorText                         ; id = 41
	dw PokemonStuffText                     ; id = 42

SECTION "bank1",ROMX,BANK[$1]

SpriteFacingAndAnimationTable: ; 4000 (1:4000)
	dw SpriteFacingDownAndStanding, SpriteOAMParameters        ; facing down, walk animation frame 0
	dw SpriteFacingDownAndWalking, SpriteOAMParameters         ; facing down, walk animation frame 1
	dw SpriteFacingDownAndStanding, SpriteOAMParameters        ; facing down, walk animation frame 2
	dw SpriteFacingDownAndWalking, SpriteOAMParametersFlipped  ; facing down, walk animation frame 3
	dw SpriteFacingUpAndStanding, SpriteOAMParameters          ; facing up, walk animation frame 0
	dw SpriteFacingUpAndWalking, SpriteOAMParameters           ; facing up, walk animation frame 1
	dw SpriteFacingUpAndStanding, SpriteOAMParameters          ; facing up, walk animation frame 2
	dw SpriteFacingUpAndWalking, SpriteOAMParametersFlipped    ; facing up, walk animation frame 3
	dw SpriteFacingLeftAndStanding, SpriteOAMParameters        ; facing left, walk animation frame 0
	dw SpriteFacingLeftAndWalking, SpriteOAMParameters         ; facing left, walk animation frame 1
	dw SpriteFacingLeftAndStanding, SpriteOAMParameters        ; facing left, walk animation frame 2
	dw SpriteFacingLeftAndWalking, SpriteOAMParameters         ; facing left, walk animation frame 3
	dw SpriteFacingLeftAndStanding, SpriteOAMParametersFlipped ; facing right, walk animation frame 0
	dw SpriteFacingLeftAndWalking, SpriteOAMParametersFlipped  ; facing right, walk animation frame 1
	dw SpriteFacingLeftAndStanding, SpriteOAMParametersFlipped ; facing right, walk animation frame 2
	dw SpriteFacingLeftAndWalking, SpriteOAMParametersFlipped  ; facing right, walk animation frame 3
	dw SpriteFacingDownAndStanding, SpriteOAMParameters        ; ---
	dw SpriteFacingDownAndStanding, SpriteOAMParameters        ; This table is used for sprites $a and $b.
	dw SpriteFacingDownAndStanding, SpriteOAMParameters        ; All orientation and animation parameters
	dw SpriteFacingDownAndStanding, SpriteOAMParameters        ; lead to the same result. Used for immobile
	dw SpriteFacingDownAndStanding, SpriteOAMParameters        ; sprites like items on the ground
	dw SpriteFacingDownAndStanding, SpriteOAMParameters        ; ---
	dw SpriteFacingDownAndStanding, SpriteOAMParameters
	dw SpriteFacingDownAndStanding, SpriteOAMParameters
	dw SpriteFacingDownAndStanding, SpriteOAMParameters
	dw SpriteFacingDownAndStanding, SpriteOAMParameters
	dw SpriteFacingDownAndStanding, SpriteOAMParameters
	dw SpriteFacingDownAndStanding, SpriteOAMParameters
	dw SpriteFacingDownAndStanding, SpriteOAMParameters
	dw SpriteFacingDownAndStanding, SpriteOAMParameters
	dw SpriteFacingDownAndStanding, SpriteOAMParameters
	dw SpriteFacingDownAndStanding, SpriteOAMParameters

SpriteFacingDownAndStanding: ; 4080 (1:4080)
	db $00,$01,$02,$03
SpriteFacingDownAndWalking: ; 4084 (1:4084)
	db $80,$81,$82,$83
SpriteFacingUpAndStanding: ; 4088 (1:4088)
	db $04,$05,$06,$07
SpriteFacingUpAndWalking: ; 408c (1:408c)
	db $84,$85,$86,$87
SpriteFacingLeftAndStanding: ; 4090 (1:4090)
	db $08,$09,$0a,$0b
SpriteFacingLeftAndWalking: ; 4094 (1:4094)
	db $88,$89,$8a,$8b

SpriteOAMParameters: ; 4098 (1:4098)
	db $00,$00, $00                                      ; top left
	db $00,$08, $00                                      ; top right
	db $08,$00, OAMFLAG_CANBEMASKED                      ; bottom left
	db $08,$08, OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA  ; bottom right
SpriteOAMParametersFlipped: ; 40a4 (1:40a4)
	db $00,$08, OAMFLAG_VFLIPPED
	db $00,$00, OAMFLAG_VFLIPPED
	db $08,$08, OAMFLAG_VFLIPPED | OAMFLAG_CANBEMASKED
	db $08,$00, OAMFLAG_VFLIPPED | OAMFLAG_CANBEMASKED | OAMFLAG_ENDOFDATA

Func_40b0: ; 40b0 (1:40b0)
	xor a
	ld [$cf0b], a
	ld [$d700], a
	ld [W_ISINBATTLE], a ; $d057
	ld [$d35d], a
	ld [$cf10], a
	ld [H_CURRENTPRESSEDBUTTONS], a
	ld [$cc57], a
	ld [wFlags_0xcd60], a
	ld [$ff9f], a
	ld [$ffa0], a
	ld [$ffa1], a
	call HasEnoughMoney
	jr c, .asm_40ff
	ld a, [wPlayerMoney] ; $d347
	ld [$ff9f], a
	ld a, [wPlayerMoney + 1] ; $d348
	ld [$ffa0], a
	ld a, [wPlayerMoney + 2] ; $d349
	ld [$ffa1], a
	xor a
	ld [$ffa2], a
	ld [$ffa3], a
	ld a, $2
	ld [$ffa4], a
	ld a, $d
	call Predef ; indirect jump to Func_f71e (f71e (3:771e))
	ld a, [$ffa2]
	ld [wPlayerMoney], a ; $d347
	ld a, [$ffa3]
	ld [wPlayerMoney + 1], a ; $d348
	ld a, [$ffa4]
	ld [wPlayerMoney + 2], a ; $d349
.asm_40ff
	ld hl, $d732
	set 2, [hl]
	res 3, [hl]
	set 6, [hl]
	ld a, $ff
	ld [wJoypadForbiddenButtonsMask], a
	ld a, $7
	jp Predef ; indirect jump to HealParty (f6a5 (3:76a5))

MewPicFront: ; 4112 (1:4112)
	INCBIN "pic/bmon/mew.pic"
MewPicBack: ; 4205 (1:4205)
	INCBIN "pic/monback/mewb.pic"

INCLUDE "data/baseStats/mew.asm"

PrintSafariZoneBattleText: ; 4277 (1:4277)
	ld hl, $cce9
	ld a, [hl]
	and a
	jr z, .asm_4284
	dec [hl]
	ld hl, SafariZoneEatingText
	jr .asm_429f
.asm_4284
	dec hl
	ld a, [hl]
	and a
	ret z
	dec [hl]
	ld hl, SafariZoneAngryText
	jr nz, .asm_429f
	push hl
	ld a, [$cfe5]
	ld [$d0b5], a
	call GetMonHeader
	ld a, [W_MONHCATCHRATE]
	ld [$d007], a
	pop hl
.asm_429f
	push hl
	call LoadScreenTilesFromBuffer1
	pop hl
	jp PrintText

SafariZoneEatingText: ; 42a7 (1:42a7)
	TX_FAR _SafariZoneEatingText
	db "@"

SafariZoneAngryText: ; 42ac (1:42ac)
	TX_FAR _SafariZoneAngryText
	db "@"

; copy text of fixed length $b (like player name, rival name, mon names, ...)
CopyFixedLengthText: ; 42b1 (1:42b1)
	ld bc, $b
	jp CopyData

SetDefaultNamesBeforeTitlescreen: ; 42b7 (1:42b7)
	ld hl, NintenText
	ld de, W_PLAYERNAME ; $d158
	call CopyFixedLengthText
	ld hl, SonyText
	ld de, W_RIVALNAME ; $d34a
	call CopyFixedLengthText
	xor a
	ld [$ffb0], a
	ld [$d358], a
	ld hl, $d732
	ld [hli], a
	ld [hli], a
	ld [hl], a
	ld a, Bank(Func_7d8ea)
	ld [$c0ef], a
	ld [$c0f0], a

LoadTitlescreenGraphics: ; 42dd (1:42dd)
	call GBPalWhiteOut
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	xor a
	ld [$ffd7], a
	ld [$ffae], a
	ld a, $40
	ld [$ffaf], a
	ld a, $90
	ld [$ffb0], a
	call ClearScreen
	call DisableLCD
	call LoadFontTilePatterns
	ld hl, NintendoCopyrightLogoGraphics ; $60c8
	ld de, $9410
	ld bc, $50
	ld a, BANK(NintendoCopyrightLogoGraphics)
	call FarCopyData2
	ld hl, GamefreakLogoGraphics ; $61f8
	ld de, $9460
	ld bc, $90
	ld a, BANK(GamefreakLogoGraphics)
	call FarCopyData2
	ld hl, PokemonLogoGraphics ; $5380
	ld de, $8800
	ld bc, $600
	ld a, BANK(PokemonLogoGraphics)
	call FarCopyData2          ; first chunk
	ld hl, PokemonLogoGraphics+$600 ; $5980
	ld de, $9310
	ld bc, $100
	ld a, BANK(PokemonLogoGraphics)
	call FarCopyData2          ; second chunk
	ld hl, Version_GFX ; $402f
IF _RED
	ld de,$9600 ; where to put redgreenversion.2bpp in the VRAM
	ld bc,$50 ; how big that file is
ENDC
IF _BLUE
	ld de,$9610 ; where to put blueversion.2bpp in the VRAM
	ld bc,$40 ; how big that file is
ENDC

	ld a, BANK(Version_GFX)
	call FarCopyDataDouble
	call Func_4519
	FuncCoord 2, 1 ; $c3b6
	ld hl, Coord
	ld a, $80
	ld de, $14
	ld c, $6
.asm_434d
	ld b, $10
	push hl
.asm_4350
	ld [hli], a
	inc a
	dec b
	jr nz, .asm_4350
	pop hl
	add hl, de
	dec c
	jr nz, .asm_434d
	FuncCoord 2, 7 ; $c42e
	ld hl, Coord
	ld a, $31
	ld b, $10
.asm_4361
	ld [hli], a
	inc a
	dec b
	jr nz, .asm_4361
	call Func_44dd
	ld hl, $c328
	ld a, $74
	ld [hl], a
	FuncCoord 2, 17 ; $c4f6
	ld hl, Coord
	ld de, .titlescreenTilemap ; $437f
	ld b, $10
.asm_4377
	ld a, [de]
	ld [hli], a
	inc de
	dec b
	jr nz, .asm_4377
	jr .asm_438f

.titlescreenTilemap ; 437f (1:437f)
	db $41,$42,$43,$42,$44,$42,$45,$46,$47,$48,$49,$4A,$4B,$4C,$4D,$4E ; ©'95.'96.'98 GAME FREAK inc.

.asm_438f
	call SaveScreenTilesToBuffer2
	call LoadScreenTilesFromBuffer2
	call EnableLCD
IF _RED
	ld a,CHARMANDER ; which Pokemon to show first on the title screen
ENDC
IF _BLUE
	ld a,SQUIRTLE ; which Pokemon to show first on the title screen
ENDC

	ld [wWhichTrade], a ; $cd3d
	call Func_4524
	ld a, $9b
	call Func_4533
	call SaveScreenTilesToBuffer1
	ld a, $40
	ld [$ffb0], a
	call LoadScreenTilesFromBuffer2
	ld a, $98
	call Func_4533
	ld b, $6
	call GoPAL_SET
	call GBPalNormal
	ld a, $e4
	ld [rOBP0], a ; $ff48
	ld bc, $ffaf ; background scroll Y
	ld hl, .TitleScreenPokemonLogoYScrolls ; $43db
.asm_43c6
	ld a, [hli]
	and a
	jr z, .asm_43f4
	ld d, a
	cp $fd
	jr nz, .asm_43d4
	ld a, (SFX_1f_62 - SFX_Headers_1f) / 3
	call PlaySound
.asm_43d4
	ld a, [hli]
	ld e, a
	call .ScrollTitleScreenPokemonLogo
	jr .asm_43c6

.TitleScreenPokemonLogoYScrolls: ; 43db (1:43db)
; Controls the bouncing effect of the Pokemon logo on the title screen
	db -4,16  ; y scroll amount, number of times to scroll
	db 3,4
	db -3,4
	db 2,2
	db -2,2
	db 1,2
	db -1,2
	db 0      ; terminate list with 0

.ScrollTitleScreenPokemonLogo
; Scrolls the Pokemon logo on the title screen to create the bouncing effect
; Scrolls d pixels e times
	call DelayFrame
	ld a, [bc]
	add d
	ld [bc], a
	dec e
	jr nz, .ScrollTitleScreenPokemonLogo
	ret
.asm_43f4
	call LoadScreenTilesFromBuffer1
	ld c, $24
	call DelayFrames
	ld a, (SFX_1f_63 - SFX_Headers_1f) / 3
	call PlaySound
	call PrintGameVersionOnTitleScreen
	ld a, $90
	ld [$ffb0], a
	ld d, $90
.asm_440a
	ld h, d
	ld l, $40
	call Func_44cf
	ld h, $0
	ld l, $50
	call Func_44cf
	ld a, d
	add $4
	ld d, a
	and a
	jr nz, .asm_440a
	ld a, $9c
	call Func_4533
	call LoadScreenTilesFromBuffer2
	call PrintGameVersionOnTitleScreen
	call Delay3
	call WaitForSoundToFinish
	ld a, MUSIC_TITLE_SCREEN
	ld [$c0ee], a
	call PlaySound
	xor a
	ld [$cc5b], a
.asm_443b
	ld c, $c8
	call CheckForUserInterruption
	jr c, .asm_4459
	call Func_44c1
	ld c, $1
	call CheckForUserInterruption
	jr c, .asm_4459
	callba Func_372ac
	call Func_4496
	jr .asm_443b
.asm_4459
	ld a, [wWhichTrade] ; $cd3d
	call PlayCry
	call WaitForSoundToFinish
	call GBPalWhiteOutWithDelay3
	call CleanLCD_OAM
	xor a
	ld [$ffb0], a
	inc a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call ClearScreen
	ld a, $98
	call Func_4533
	ld a, $9c
	call Func_4533
	call Delay3
	call LoadGBPal
	ld a, [H_CURRENTPRESSEDBUTTONS]
	ld b, a
	and $46
	cp $46
	jp z, Func_448e
	jp MainMenu

Func_448e: ; 448e (1:448e)
	ld b, BANK(Func_1c98a)
	ld hl, Func_1c98a
	jp Bankswitch

Func_4496: ; 4496 (1:4496)
	ld a, $98
	call Func_4533

.new
; Generate a new TitleMon.
	call GenRandom
	and $f
	ld c, a
	ld b, 0
	ld hl, TitleMons
	add hl, bc
	ld a, [hl]
	ld hl, wWhichTrade ; $cd3d

; Can't be the same as before.
	cp [hl]
	jr z, .new

	ld [hl], a
	call Func_4524

	ld a, $90
	ld [$ffb0], a
	ld d, 1 ; scroll out
	callba TitleScroll ; indirect jump to TitleScroll (37258 (d:7258))
	ret

Func_44c1: ; 44c1 (1:44c1)
	ld d, 0 ; scroll in
	callba TitleScroll ; indirect jump to TitleScroll (37258 (d:7258))
	xor a
	ld [$ffb0], a
	ret

Func_44cf: ; 44cf (1:44cf)
.wait
	ld a, [$ff44] ; rLY
	cp l
	jr nz, .wait

	ld a, h
	ld [rSCX], a ; $ff43

.wait2
	ld a, [$ff44] ; rLY
	cp h
	jr z, .wait2
	ret

Func_44dd: ; 44dd (1:44dd)
	ld hl, PlayerCharacterTitleGraphics ; $66a8
	ld de, $8000
	ld bc, $230
	ld a, BANK(PlayerCharacterTitleGraphics)
	call FarCopyData2
	call CleanLCD_OAM
	xor a
	ld [wWhichTrade], a ; $cd3d
	ld hl, wOAMBuffer
	ld de, $605a
	ld b, $7
.asm_44fa
	push de
	ld c, $5
.asm_44fd
	ld a, d
	ld [hli], a
	ld a, e
	ld [hli], a
	add $8
	ld e, a
	ld a, [wWhichTrade] ; $cd3d
	ld [hli], a
	inc a
	ld [wWhichTrade], a ; $cd3d
	inc hl
	dec c
	jr nz, .asm_44fd
	pop de
	ld a, $8
	add d
	ld d, a
	dec b
	jr nz, .asm_44fa
	ret

Func_4519: ; 4519 (1:4519)
	ld hl, $9800
	ld bc, $800
	ld a, $7f
	jp FillMemory

Func_4524: ; 4524 (1:4524)
	ld [$cf91], a
	ld [$d0b5], a
	FuncCoord 5, 10 ; $c46d
	ld hl, Coord
	call GetMonHeader
	jp LoadFrontSpriteByMonIndex

Func_4533: ; 4533 (1:4533)
	ld [$ffbd], a
	jp Delay3

Func_4538: ; 4538 (1:4538)
	xor a
	ld [$ffb0], a
	call ClearScreen
	call LoadTextBoxTilePatterns

Func_4541: ; 4541 (1:4541)
	ld de, NintendoCopyrightLogoGraphics ; $60c8
	ld hl, $9600
	ld bc, (BANK(NintendoCopyrightLogoGraphics) << 8) + $1c
	call CopyVideoData
	FuncCoord 2, 7 ; $c42e
	ld hl, Coord
	ld de, CopyrightTextString ; $4556
	jp PlaceString

CopyrightTextString: ; 4556 (1:4556)
	db   $60,$61,$62,$61,$63,$61,$64,$7F,$65,$66,$67,$68,$69,$6A             ; ©'95.'96.'98 Nintendo
	next $60,$61,$62,$61,$63,$61,$64,$7F,$6B,$6C,$6D,$6E,$6F,$70,$71,$72     ; ©'95.'96.'98 Creatures inc.
	next $60,$61,$62,$61,$63,$61,$64,$7F,$73,$74,$75,$76,$77,$78,$79,$7A,$7B ; ©'95.'96.'98 GAME FREAK inc.
	db   "@"

INCLUDE "data/title_mons.asm"

; prints version text (red, blue)
PrintGameVersionOnTitleScreen: ; 4598 (1:4598)
	FuncCoord 7, 8 ; $c447
	ld hl, Coord
	ld de, VersionOnTitleScreenText
	jp PlaceString

; these point to special tiles specifically loaded for that purpose and are not usual text
VersionOnTitleScreenText: ; 45a1 (1:45a1)
IF _RED
	db $60,$61,$7F,$65,$66,$67,$68,$69,"@" ; "Red Version"
ENDC
IF _BLUE
	db $61,$62,$63,$64,$65,$66,$67,$68,"@" ; "Blue Version"
ENDC

NintenText: ; 45aa (1:45aa)
	db "NINTEN@"

SonyText: ; 45b1 (1:45b1)
	db "SONY@"

; loads pokemon data from one of multiple sources to $cf98
; loads base stats to $d0b8
; INPUT:
; [$cf92] = index of pokemon within party/box
; [$cc49] = source
; 00: player's party
; 01: enemy's party
; 02: current box
; 03: daycare
; OUTPUT:
; [$cf91] = pokemon ID
; $cf98 = base address of pokemon data
; $d0b8 = base address of base stats
LoadMonData_: ; 45b6 (1:45b6)
	ld a,[W_DAYCAREMONDATA] ; daycare pokemon ID
	ld [$cf91],a
	ld a,[$cc49]
	cp a,$03
	jr z,.GetMonHeader
	ld a,[wWhichPokemon]
	ld e,a
	callab Func_39c37 ; get pokemon ID
.GetMonHeader
	ld a,[$cf91]
	ld [$d0b5],a ; input for GetMonHeader
	call GetMonHeader ; load base stats to $d0b8
	ld hl,W_PARTYMON1DATA
	ld bc,44
	ld a,[$cc49]
	cp a,$01
	jr c,.getMonEntry
	ld hl,wEnemyMons ; enemy pokemon 1 data
	jr z,.getMonEntry
	cp a,$02
	ld hl,W_BOXMON1DATA ; box pokemon 1 data
	ld bc,33
	jr z,.getMonEntry
	ld hl, W_DAYCAREMONDATA ; daycare pokemon data
	jr .copyMonData
.getMonEntry ; add the product of the index and the size of each entry
	ld a,[wWhichPokemon]
	call AddNTimes
.copyMonData
	ld de,$cf98
	ld bc,44
	jp CopyData

INCLUDE "data/item_prices.asm"

INCLUDE "text/item_names.asm"

UnusedNames: ; 4a92 (1:4a92)
	db "かみなりバッヂ@"
	db "かいがらバッヂ@"
	db "おじぞうバッヂ@"
	db "はやぶさバッヂ@"
	db "ひんやりバッヂ@"
	db "なかよしバッヂ@"
	db "バラバッヂ@"
	db "ひのたまバッヂ@"
	db "ゴールドバッヂ@"
	db "たまご@"
	db "ひよこ@"
	db "ブロンズ@"
	db "シルバー@"
	db "ゴールド@"
	db "プチキャプテン@"
	db "キャプテン@"
	db "プチマスター@"
	db "マスター@"
	db "エクセレント"

; calculates the OAM data for all currently visible sprites and writes it to wOAMBuffer
PrepareOAMData: ; 4b0f (1:4b0f)
	ld a, [$cfcb]
	dec a
	jr z, .asm_4b1e
	cp $ff
	ret nz
	ld [$cfcb], a
	jp ResetLCD_OAM
.asm_4b1e
	xor a
	ld [$ff90], a
.asm_4b21
	ld [$ff8f], a
	ld d, $c1
	ld a, [$ff8f]
	ld e, a
	ld a, [de]         ; c1x0
	and a
	jp z, .asm_4bad
	inc e
	inc e
	ld a, [de]         ; c1x2 read combined orientation and animation info
	ld [$d5cd], a
	cp $ff
	jr nz, .spriteVisible   ; $ff -> offscreen, don't draw
	call Func_4bd1
	jr .asm_4bad
.spriteVisible
	cp $a0
	jr c, .considerOrientation ; if >= $a0, ignore the sprite orientation and animation (by using a different conversion table)
	and $f
	add $10
	jr .asm_4b48
.considerOrientation
	and $f                     ; the lower nybble contains orientation and animation info
.asm_4b48
	ld l, a
	push de
	inc d
	ld a, e
	add $5
	ld e, a
	ld a, [de]         ; c2x7
	and $80
	ld [$ff94], a          ; temp store bit 7 for later use in OAM flags (draws sprite behind background (used for grass))
	pop de
	ld h, $0
	ld bc, SpriteFacingAndAnimationTable
	add hl, hl
	add hl, hl
	add hl, bc                 ; skip to the table location determined by orientation and animation
	ld a, [hli]
	ld c, a
	ld a, [hli]
	ld b, a
	ld a, [hli]
	ld h, [hl]
	ld l, a
	call Func_4bd1
	ld a, [$ff90]
	ld e, a
	ld d, $c3                ; wOAMBuffer+x is buffer for OAM data
.spriteTilesLoop             ; loops 4 times for the 4 tiles a sprite consists of
	ld a, [$ff92]        ; temp for sprite Y position
	add $10                  ; Y=16 is top of screen (Y=0 is invisible)
	add [hl]                 ; add Y offset from table
	ld [de], a               ; write new sprite OAM Y position
	inc hl
	ld a, [$ff91]        ; temp for sprite X position
	add $8                   ; X=8 is left of screen (X=0 is invisible)
	add [hl]                 ; add X offset from table
	inc e
	ld [de], a               ; write new sprite OAM X position
	inc e
	ld a, [bc]               ; read pattern number offset (accomodates orientation (offset 0,4 or 8) and animation (offset 0 or $80))
	inc bc
	push bc
	ld b, a
	ld a, [$d5cd]            ; temp copy of c1x2
	swap a                   ; high nybble determines sprite used (0 is always player sprite, next are some npcs)
	and $f
	cp $b                    ; sprites $a and $b have no orientation or animation and therefore only 4 tiles
	jr nz, .calcTileOffset   ; (instead of 12), so tile b's offset is a special case
	ld a, $7c                ; = $a * 12 + 4
	jr .doneCalcTileOffset
.calcTileOffset
	sla a
	sla a
	ld c, a
	sla a
	add c                    ; a *= 12 (each sprite consists of 12 tiles)
.doneCalcTileOffset
	add b                    ; add orientation and animation offset
	pop bc
	ld [de], a               ; write OAM sprite pattern number
	inc hl
	inc e
	ld a, [hl]
	bit 1, a                 ; bit 1 is ignored for OAM, it's used here as an "always in foregroud" flag.
	jr z, .alwaysInForeground
	ld a, [$ff94]        ; load bit 7 (set to $80 if sprite is in grass and should be drawn behind it)
	or [hl]
.alwaysInForeground
	inc hl
	ld [de], a               ; write OAM sprite flags
	inc e
	bit 0, a                 ; test for OAMFLAG_ENDOFDATA
	jr z, .spriteTilesLoop
	ld a, e
	ld [$ff90], a
.asm_4bad
	ld a, [$ff8f]
	add $10
	cp $0
	jp nz, .asm_4b21
	ld a, [$ff90]
	ld l, a
	ld h, $c3
	ld de, $4
	ld b, $a0
	ld a, [$d736]
	bit 6, a
	ld a, $a0
	jr z, .clearUnusedOAMEntriesLoop
	ld a, $90
.clearUnusedOAMEntriesLoop
	cp l
	ret z
	ld [hl], b
	add hl, de
	jr .clearUnusedOAMEntriesLoop

Func_4bd1: ; 4bd1 (1:4bd1)
	inc e
	inc e
	ld a, [de]            ; c1x4
	ld [$ff92], a
	inc e
	inc e
	ld a, [de]            ; c1x6
	ld [$ff91], a
	ld a, $4
	add e
	ld e, a
	ld a, [$ff92]
	add $4
	and $f0
	ld [de], a            ; c1xa (sprite Y pos (snapped to whole steps (?))
	inc e
	ld a, [$ff91]
	and $f0
	ld [de], a            ; c1xb (sprite X pos (snapped to whole steps (?))
	ret

; copies DMA routine to HRAM. By GB specifications, all DMA needs to be done in HRAM (no other memory section is available during DMA)
WriteDMACodeToHRAM: ; 4bed (1:4bed)
	ld c, $80
	ld b, $a
	ld hl, DMARoutine
.copyLoop
	ld a, [hli]
	ld [$ff00+c], a
	inc c
	dec b
	jr nz, .copyLoop
	ret

; this routine is copied to HRAM and executed there on every VBlank
DMARoutine: ; 4bfb (1:4bfb)
	ld a, $c3
	ld [$ff46], a   ; start DMA
	ld a, $28
.waitLoop               ; wait for DMA to finish
	dec a
	jr nz, .waitLoop
	ret

PrintWaitingText: ; 4c05 (1:4c05)
	FuncCoord 3, 10 ; $c46b
	ld hl, Coord
	ld b, $1
	ld c, $b
	ld a, [W_ISINBATTLE] ; $d057
	and a
	jr z, .asm_4c17
	call TextBoxBorder
	jr .asm_4c1a
.asm_4c17
	call Func_5ab3
.asm_4c1a
	FuncCoord 4, 11 ; $c480
	ld hl, Coord
	ld de, WaitingText
	call PlaceString
	ld c, $32
	jp DelayFrames

WaitingText: ; 4c28 (1:4c28)
	db "Waiting...!@"

_UpdateSprites: ; 4c34 (1:4c34)
	ld h, $c1
	inc h
	ld a, $e    ; $c20e
.spriteLoop
	ld l, a
	sub $e
	ld c, a
	ld [H_CURRENTSPRITEOFFSET], a
	ld a, [hl]
	and a
	jr z, .skipSprite   ; tests $c2Xe
	push hl
	push de
	push bc
	call .updateCurrentSprite
	pop bc
	pop de
	pop hl
.skipSprite
	ld a, l
	add $10             ; move to next sprite
	cp $e               ; test for overflow (back at $0e)
	jr nz, .spriteLoop
	ret
.updateCurrentSprite ; 4c54 (1:4c54)
	cp $1
	jp nz, UpdateNonPlayerSprite
	jp UpdatePlayerSprite

UpdateNonPlayerSprite: ; 4c5c (1:4c5c)
	dec a
	swap a
	ld [$ff93], a  ; $10 * sprite#
	ld a, [$cf17] ; some sprite offset?
	ld b, a
	ld a, [H_CURRENTSPRITEOFFSET]
	cp b
	jr nz, .unequal
	jp Func_5236
.unequal
	jp Func_4ed1

Func_4c70: ; 4c70 (1:4c70)
	nop
	ld h, $c1
	ld a, [H_CURRENTSPRITEOFFSET]
	add $0
	ld l, a
	ld a, [hl]
	and a
	ret z
	ld a, l
	add $3
	ld l, a
	ld a, [hli]
	call Func_4d72
	ld a, [hli]
	add $4
	add b
	and $f0
	or c
	ld [$ff90], a
	ld a, [hli]
	call Func_4d72
	ld a, [hl]
	add b
	and $f0
	or c
	ld [$ff91], a
	ld a, l
	add $7
	ld l, a
	xor a
	ld [hld], a
	ld [hld], a
	ld a, [$ff91]
	ld [hld], a
	ld a, [$ff90]
	ld [hl], a
	xor a

Func_4ca5: ; 4ca5 (1:4ca5)
	ld [$ff8f], a
	swap a
	ld e, a
	ld a, [H_CURRENTSPRITEOFFSET]
	cp e
	jp z, .asm_4d69
	ld d, h
	ld a, [de]
	and a
	jp z, .asm_4d69
	inc e
	inc e
	ld a, [de]
	inc a
	jp z, .asm_4d69
	ld a, [H_CURRENTSPRITEOFFSET]
	add $a
	ld l, a
	inc e
	ld a, [de]
	call Func_4d72
	inc e
	ld a, [de]
	add $4
	add b
	and $f0
	or c
	sub [hl]
	jr nc, .asm_4cd4
	cpl
	inc a
.asm_4cd4
	ld [$ff90], a
	push af
	rl c
	pop af
	ccf
	rl c
	ld b, $7
	ld a, [hl]
	and $f
	jr z, .asm_4ce6
	ld b, $9
.asm_4ce6
	ld a, [$ff90]
	sub b
	ld [$ff92], a
	ld a, b
	ld [$ff90], a
	jr c, .asm_4d01
	ld b, $7
	dec e
	ld a, [de]
	inc e
	and a
	jr z, .asm_4cfa
	ld b, $9
.asm_4cfa
	ld a, [$ff92]
	sub b
	jr z, .asm_4d01
	jr nc, .asm_4d69
.asm_4d01
	inc e
	inc l
	ld a, [de]
	push bc
	call Func_4d72
	inc e
	ld a, [de]
	add b
	and $f0
	or c
	pop bc
	sub [hl]
	jr nc, .asm_4d14
	cpl
	inc a
.asm_4d14
	ld [$ff91], a
	push af
	rl c
	pop af
	ccf
	rl c
	ld b, $7
	ld a, [hl]
	and $f
	jr z, .asm_4d26
	ld b, $9
.asm_4d26
	ld a, [$ff91]
	sub b
	ld [$ff92], a
	ld a, b
	ld [$ff91], a
	jr c, .asm_4d41
	ld b, $7
	dec e
	ld a, [de]
	inc e
	and a
	jr z, .asm_4d3a
	ld b, $9
.asm_4d3a
	ld a, [$ff92]
	sub b
	jr z, .asm_4d41
	jr nc, .asm_4d69
.asm_4d41
	ld a, [$ff91]
	ld b, a
	ld a, [$ff90]
	inc l
	cp b
	jr c, .asm_4d4e
	ld b, $c
	jr .asm_4d50
.asm_4d4e
	ld b, $3
.asm_4d50
	ld a, c
	and b
	or [hl]
	ld [hl], a
	ld a, c
	inc l
	inc l
	ld a, [$ff8f]
	ld de, DiagonalLines ; $4d85
	add a
	add e
	ld e, a
	jr nc, .asm_4d62
	inc d
.asm_4d62
	ld a, [de]
	or [hl]
	ld [hli], a
	inc de
	ld a, [de]
	or [hl]
	ld [hl], a
.asm_4d69
	ld a, [$ff8f]
	inc a
	cp $10
	jp nz, Func_4ca5
	ret

Func_4d72: ; 4d72 (1:4d72)
	and a
	ld b, $0
	ld c, $0
	jr z, .asm_4d84
	ld c, $9
	cp $ff
	jr z, .asm_4d83
	ld c, $7
	ld a, $0
.asm_4d83
	ld b, a
.asm_4d84
	ret

DiagonalLines: ; 4d85 (1:4d85)
	INCBIN "gfx/diagonal_lines.2bpp"

Func_4da5: ; 4da5 (1:4da5)
	ret

Func_4da6: ; 4da6 (1:4da6)
	call GBPalNormal
	ld a, $80
	ld [W_OBTAINEDBADGES], a
	ld hl, W_FLAGS_D733
	set 0, [hl]
	ld hl, W_NUMINPARTY
	xor a
	ld [hli], a
	dec a
	ld [hl], a
	ld a, $1
	ld [$cf91], a
	ld a, 20
	ld [W_CURENEMYLVL], a
	xor a
	ld [$cc49], a
	ld [W_CURMAP], a
	call AddPokemonToParty
	ld a, RHYDON
	ld [W_CUROPPONENT], a
	ld a, $2c
	call Predef
	ld a, $1
	ld [$cfcb], a
	ld [H_AUTOBGTRANSFERENABLED], a
	jr Func_4da6

PickupItem: ; 4de1 (1:4de1)
	call EnableAutoTextBoxDrawing
	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
	ld b, a
	ld hl, W_MISSABLEOBJECTLIST
.missableObjectsListLoop
	ld a, [hli]
	cp $ff
	ret z
	cp b
	jr z, .isMissable
	inc hl
	jr .missableObjectsListLoop
.isMissable
	ld a, [hl]
	ld [$ffdb], a
	ld hl, W_MAPSPRITEEXTRADATA
	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
	dec a
	add a
	ld d, $0
	ld e, a
	add hl, de        ; seek to item data of found item
	ld a, [hl]        ; read Item type
	ld b, a
	ld c, 1          ; quantity is 1
	call GiveItem
	jr nc, .BagFull
	ld a, [$ffdb]
	ld [$cc4d], a
	ld a, $11
	call Predef ; indirect jump to RemoveMissableObject (f1d7 (3:71d7))
	ld a, $1
	ld [$cc3c], a
	ld hl, FoundItemText
	jr .printText
.BagFull
	ld hl, NoMoreRoomForItemText
.printText
	call PrintText
	ret

FoundItemText: ; 4e26 (1:4e26)
	TX_FAR _FoundItemText
	db $0B
	db "@"

NoMoreRoomForItemText: ; 4e2c (1:4e2c)
	TX_FAR _NoMoreRoomForItemText
	db "@"

UpdatePlayerSprite: ; 4e31 (1:4e31)
	ld a, [wSpriteStateData2]
	and a
	jr z, .asm_4e41
	cp $ff
	jr z, .asm_4e4a
	dec a
	ld [wSpriteStateData2], a
	jr .asm_4e4a
.asm_4e41
	FuncCoord 8, 9 ; $c45c
	ld a, [Coord]
	ld [$ff93], a
	cp $60
	jr c, .asm_4e50
.asm_4e4a
	ld a, $ff
	ld [$c102], a
	ret
.asm_4e50
	call Func_4c70
	ld h, $c1
	ld a, [wWalkCounter] ; $cfc5
	and a
	jr nz, .asm_4e90
	ld a, [$d528]
	bit 2, a
	jr z, .asm_4e65
	xor a
	jr .asm_4e86
.asm_4e65
	bit 3, a
	jr z, .asm_4e6d
	ld a, $4
	jr .asm_4e86
.asm_4e6d
	bit 1, a
	jr z, .asm_4e75
	ld a, $8
	jr .asm_4e86
.asm_4e75
	bit 0, a
	jr z, .asm_4e7d
	ld a, $c
	jr .asm_4e86
.asm_4e7d
	xor a
	ld [$c107], a
	ld [$c108], a
	jr .asm_4eab
.asm_4e86
	ld [$c109], a
	ld a, [$cfc4]
	bit 0, a
	jr nz, .asm_4e7d
.asm_4e90
	ld a, [$d736]
	bit 7, a
	jr nz, .asm_4eb6
	ld a, [H_CURRENTSPRITEOFFSET]
	add $7
	ld l, a
	ld a, [hl]
	inc a
	ld [hl], a
	cp $4
	jr nz, .asm_4eab
	xor a
	ld [hl], a
	inc hl
	ld a, [hl]
	inc a
	and $3
	ld [hl], a
.asm_4eab
	ld a, [$c108]
	ld b, a
	ld a, [$c109]
	add b
	ld [$c102], a
.asm_4eb6
	ld a, [$ff93]
	ld c, a
	ld a, [W_GRASSTILE]
	cp c
	ld a, $0
	jr nz, .asm_4ec3
	ld a, $80
.asm_4ec3
	ld [$c207], a
	ret

Func_4ec7: ; 4ec7 (1:4ec7)
	push bc
	push af
	ld a, [$ffda]
	ld c, a
	pop af
	add c
	ld l, a
	pop bc
	ret

Func_4ed1: ; 4ed1 (1:4ed1)
	ld a, [H_CURRENTSPRITEOFFSET]
	swap a
	dec a
	add a
	ld hl, W_MAPSPRITEDATA ; $d4e4
	add l
	ld l, a
	ld a, [hl]        ; read movement byte 2
	ld [wCurSpriteMovement2], a
	ld h, $c1
	ld a, [H_CURRENTSPRITEOFFSET]
	ld l, a
	inc l
	ld a, [hl]        ; c1x1
	and a
	jp z, InitializeSpriteStatus
	call CheckSpriteAvailability
	ret c             ; if sprite is invisible, on tile >=$60, in grass or player is currently walking
	ld h, $c1
	ld a, [H_CURRENTSPRITEOFFSET]
	ld l, a
	inc l
	ld a, [hl]        ; c1x1
	bit 7, a
	jp nz, InitializeSpriteFacingDirection  ; c1x1 >= $80
	ld b, a
	ld a, [$cfc4]
	bit 0, a
	jp nz, notYetMoving
	ld a, b
	cp $2
	jp z, UpdateSpriteMovementDelay  ; c1x1 == 2
	cp $3
	jp z, UpdateSpriteInWalkingAnimation  ; c1x1 == 3
	ld a, [wWalkCounter] ; $cfc5
	and a
	ret nz           ; don't do anything yet if player is currently moving (redundant, already tested in CheckSpriteAvailability)
	call InitializeSpriteScreenPosition
	ld h, $c2
	ld a, [H_CURRENTSPRITEOFFSET]
	add $6
	ld l, a
	ld a, [hl]       ; c2x6: movement byte 1
	inc a
	jr z, .asm_4f59  ; value $FF
	inc a
	jr z, .asm_4f59  ; value $FE
	dec a
	ld [hl], a       ; (temporarily) increment movement byte 1
	dec a
	push hl
	ld hl, $cf0f
	dec [hl]         ; decrement $cf0f
	pop hl
	ld de, $cc5b
	call LoadDEPlusA ; a = [$cc5b + movement byte 1]
	cp $e0
	jp z, ChangeFacingDirection
	cp $ff
	jr nz, .asm_4f4b
	ld [hl], a       ; reset movement byte 1 to initial value
	ld hl, $d730
	res 0, [hl]
	xor a
	ld [$cd38], a
	ld [$cd3a], a
	ret
.asm_4f4b
	cp $fe
	jr nz, .asm_4f5f
	ld [hl], $1     ; set movement byte 1 to $1
	ld de, $cc5b
	call LoadDEPlusA ; a = [$cc5b + $fe] (?)
	jr .asm_4f5f
.asm_4f59
	call getTileSpriteStandsOn
	call GenRandom
.asm_4f5f
	ld b, a
	ld a, [wCurSpriteMovement2]
	cp $d0
	jr z, .moveDown    ; movement byte 2 = $d0 forces down
	cp $d1
	jr z, .moveUp      ; movement byte 2 = $d1 forces up
	cp $d2
	jr z, .moveLeft    ; movement byte 2 = $d2 forces left
	cp $d3
	jr z, .moveRight   ; movement byte 2 = $d3 forces right
	ld a, b
	cp $40             ; a < $40: down (or left)
	jr nc, .notDown
	ld a, [wCurSpriteMovement2]
	cp $2
	jr z, .moveLeft    ; movement byte 2 = $2 only allows left or right
.moveDown
	ld de, 2*20
	add hl, de         ; move tile pointer two rows down
	ld de, $100

	ld bc, $400
	jr TryWalking
.notDown
	cp $80             ; $40 <= a < $80: up (or right)
	jr nc, .notUp
	ld a, [wCurSpriteMovement2]
	cp $2
	jr z, .moveRight   ; movement byte 2 = $2 only allows left or right
.moveUp
	ld de, -2*20 ; $ffd8
	add hl, de         ; move tile pointer two rows up
	ld de, $ff00
	ld bc, $804
	jr TryWalking
.notUp
	cp $c0             ; $80 <= a < $c0: left (or up)
	jr nc, .notLeft
	ld a, [wCurSpriteMovement2]
	cp $1
	jr z, .moveUp      ; movement byte 2 = $1 only allows up or down
.moveLeft
	dec hl
	dec hl             ; move tile pointer two columns left
	ld de, $ff
	ld bc, $208
	jr TryWalking
.notLeft              ; $c0 <= a: right (or down)
	ld a, [wCurSpriteMovement2]
	cp $1
	jr z, .moveDown    ; movement byte 2 = $1 only allows up or down
.moveRight
	inc hl
	inc hl             ; move tile pointer two columns right
	ld de, $1
	ld bc, $10c
	jr TryWalking

; changes facing direction by zeroing the movement delta and calling TryWalking
ChangeFacingDirection: ; 4fc8 (1:4fc8)
	ld de, $0
	; fall through

; b: direction (1,2,4 or 8)
; c: new facing direction (0,4,8 or $c)
; d: Y movement delta (-1, 0 or 1)
; e: X movement delta (-1, 0 or 1)
; hl: pointer to tile the sprite would wlak onto
; set carry on failure, clears carry on success
TryWalking: ; 4fcb (1:4fcb)
	push hl
	ld h, $c1
	ld a, [H_CURRENTSPRITEOFFSET]
	add $9
	ld l, a
	ld [hl], c          ; c1x9 (update facing direction)
	ld a, [H_CURRENTSPRITEOFFSET]
	add $3
	ld l, a
	ld [hl], d          ; c1x3 (update Y movement delta)
	inc l
	inc l
	ld [hl], e          ; c1x5 (update X movement delta)
	pop hl
	push de
	ld c, [hl]          ; read tile to walk onto
	call CanWalkOntoTile
	pop de
	ret c               ; cannot walk there (reinitialization of delay values already done)
	ld h, $c2
	ld a, [H_CURRENTSPRITEOFFSET]
	add $4
	ld l, a
	ld a, [hl]          ; c2x4: Y position
	add d
	ld [hli], a         ; update Y position
	ld a, [hl]          ; c2x5: X position
	add e
	ld [hl], a          ; update X position
	ld a, [H_CURRENTSPRITEOFFSET]
	ld l, a
	ld [hl], $10        ; c2x0=16: walk animation counter
	dec h
	inc l
	ld [hl], $3         ; c1x1: set movement status to walking
	jp UpdateSpriteImage

; update the walking animation parameters for a sprite that is currently walking
UpdateSpriteInWalkingAnimation: ; 4ffe (1:4ffe)
	ld a, [H_CURRENTSPRITEOFFSET]
	add $7
	ld l, a
	ld a, [hl]                       ; c1x7 (counter until next walk animation frame)
	inc a
	ld [hl], a                       ; c1x7 += 1
	cp $4
	jr nz, .noNextAnimationFrame
	xor a
	ld [hl], a                       ; c1x7 = 0
	inc l
	ld a, [hl]                       ; c1x8 (walk animation frame)
	inc a
	and $3
	ld [hl], a                       ; advance to next animation frame every 4 ticks (16 ticks total for one step)
.noNextAnimationFrame
	ld a, [H_CURRENTSPRITEOFFSET]
	add $3
	ld l, a
	ld a, [hli]                      ; c1x3 (movement Y delta)
	ld b, a
	ld a, [hl]                       ; c1x4 (screen Y position)
	add b
	ld [hli], a                      ; update screen Y position
	ld a, [hli]                      ; c1x5 (movement X delta)
	ld b, a
	ld a, [hl]                       ; c1x6 (screen X position)
	add b
	ld [hl], a                       ; update screen X position
	ld a, [H_CURRENTSPRITEOFFSET]
	ld l, a
	inc h
	ld a, [hl]                       ; c2x0 (walk animantion counter)
	dec a
	ld [hl], a                       ; update walk animantion counter
	ret nz
	ld a, $6                         ; walking finished, update state
	add l
	ld l, a
	ld a, [hl]                       ; c2x6 (movement byte 1)
	cp $fe
	jr nc, .initNextMovementCounter  ; values $fe and $ff
	ld a, [H_CURRENTSPRITEOFFSET]
	inc a
	ld l, a
	dec h
	ld [hl], $1                      ; c1x1 = 1 (movement status ready)
	ret
.initNextMovementCounter
	call GenRandom
	ld a, [H_CURRENTSPRITEOFFSET]
	add $8
	ld l, a
	ld a, [H_RAND1] ; $ffd3
	and $7f
	ld [hl], a                       ; c2x8: set next movement delay to a random value in [0,$7f]
	dec h                            ;       note that value 0 actually makes the delay $100 (bug?)
	ld a, [H_CURRENTSPRITEOFFSET]
	inc a
	ld l, a
	ld [hl], $2                      ; c1x1 = 2 (movement status)
	inc l
	inc l
	xor a
	ld b, [hl]                       ; c1x3 (movement Y delta)
	ld [hli], a                      ; reset movement Y delta
	inc l
	ld c, [hl]                       ; c1x5 (movement X delta)
	ld [hl], a                       ; reset movement X delta
	ret

; update delay value (c2x8) for sprites in the delayed state (c1x1)
UpdateSpriteMovementDelay: ; 5057 (1:5057)
	ld h, $c2
	ld a, [H_CURRENTSPRITEOFFSET]
	add $6
	ld l, a
	ld a, [hl]              ; c2x6: movement byte 1
	inc l
	inc l
	cp $fe
	jr nc, .tickMoveCounter ; values $fe or $ff
	ld [hl], $0
	jr .moving
.tickMoveCounter
	dec [hl]                ; c2x8: frame counter until next movement
	jr nz, notYetMoving
.moving
	dec h
	ld a, [H_CURRENTSPRITEOFFSET]
	inc a
	ld l, a
	ld [hl], $1             ; c1x1 = 1 (mark as ready to move)
notYetMoving: ; 5073 (1:5073)
	ld h, $c1
	ld a, [H_CURRENTSPRITEOFFSET]
	add $8
	ld l, a
	ld [hl], $0             ; c1x8 = 0 (walk animation frame)
	jp UpdateSpriteImage

InitializeSpriteFacingDirection: ; 507f (1:507f)
	ld a, [$d72d]
	bit 5, a
	jr nz, notYetMoving
	res 7, [hl]
	ld a, [$d52a]
	bit 3, a
	jr z, .notFacingDown
	ld c, $0                ; make sprite face down
	jr .facingDirectionDetermined
.notFacingDown
	bit 2, a
	jr z, .notFacingUp
	ld c, $4                ; make sprite face up
	jr .facingDirectionDetermined
.notFacingUp
	bit 1, a
	jr z, .notFacingRight
	ld c, $c                ; make sprite face right
	jr .facingDirectionDetermined
.notFacingRight
	ld c, $8                ; make sprite face left
.facingDirectionDetermined
	ld a, [H_CURRENTSPRITEOFFSET]
	add $9
	ld l, a
	ld [hl], c              ; c1x9: set facing direction
	jr notYetMoving

InitializeSpriteStatus: ; 50ad (1:50ad)
	ld [hl], $1   ; $c1x1: set movement status to ready
	inc l
	ld [hl], $ff  ; $c1x2: set sprite image to $ff (invisible/off screen)
	inc h
	ld a, [H_CURRENTSPRITEOFFSET]
	add $2
	ld l, a
	ld a, $8
	ld [hli], a   ; $c2x2: set Y displacement to 8
	ld [hl], a    ; $c2x3: set X displacement to 8
	ret

; calculates the spprite's scrren position form its map position and the player position
InitializeSpriteScreenPosition: ; 50bd (1:50bd)
	ld h, $c2
	ld a, [H_CURRENTSPRITEOFFSET]
	add $4
	ld l, a
	ld a, [W_YCOORD] ; $d361
	ld b, a
	ld a, [hl]      ; c2x4 (Y position + 4)
	sub b           ; relative to player position
	swap a          ; * 16
	sub $4          ; - 4
	dec h
	ld [hli], a     ; c1x4 (screen Y position)
	inc h
	ld a, [W_XCOORD] ; $d362
	ld b, a
	ld a, [hli]     ; c2x6 (X position + 4)
	sub b           ; relative to player position
	swap a          ; * 16
	dec h
	ld [hl], a      ; c1x6 (screen X position)
	ret

; tests if sprite is off screen or otherwise unable to do anything
CheckSpriteAvailability: ; 50dc (1:50dc)
	ld a, $12
	call Predef ; indirect jump to IsMissableObjectHidden (f1a6 (3:71a6))
	ld a, [$ffe5]
	and a
	jp nz, .spriteInvisible
	ld h, $c2
	ld a, [H_CURRENTSPRITEOFFSET]
	add $6
	ld l, a
	ld a, [hl]      ; c2x6: movement byte 1
	cp $fe
	jr c, .skipXVisibilityTest ; movement byte 1 < $fe
	ld a, [H_CURRENTSPRITEOFFSET]
	add $4
	ld l, a
	ld b, [hl]      ; c2x4: Y pos (+4)
	ld a, [W_YCOORD] ; $d361
	cp b
	jr z, .skipYVisibilityTest
	jr nc, .spriteInvisible ; above screen region
	add $8                  ; screen is 9 tiles high
	cp b
	jr c, .spriteInvisible  ; below screen region
.skipYVisibilityTest
	inc l
	ld b, [hl]      ; c2x5: X pos (+4)
	ld a, [W_XCOORD] ; $d362
	cp b
	jr z, .skipXVisibilityTest
	jr nc, .spriteInvisible ; left of screen region
	add $9                  ; screen is 10 tiles wide
	cp b
	jr c, .spriteInvisible  ; right of screen region
.skipXVisibilityTest
	call getTileSpriteStandsOn
	ld d, $60
	ld a, [hli]
	cp d
	jr nc, .spriteInvisible ; standing on tile with ID >=$60 (bottom left tile)
	ld a, [hld]
	cp d
	jr nc, .spriteInvisible ; standing on tile with ID >=$60 (bottom right tile)
	ld bc, -20 ; $ffec
	add hl, bc              ; go back one row of tiles
	ld a, [hli]
	cp d
	jr nc, .spriteInvisible ; standing on tile with ID >=$60 (top left tile)
	ld a, [hl]
	cp d
	jr c, .spriteVisible    ; standing on tile with ID >=$60 (top right tile)
.spriteInvisible
	ld h, $c1
	ld a, [H_CURRENTSPRITEOFFSET]
	add $2
	ld l, a
	ld [hl], $ff       ; c1x2
	scf
	jr .done
.spriteVisible
	ld c, a
	ld a, [wWalkCounter] ; $cfc5
	and a
	jr nz, .done           ; if player is currently walking, we're done
	call UpdateSpriteImage
	inc h
	ld a, [H_CURRENTSPRITEOFFSET]
	add $7
	ld l, a
	ld a, [W_GRASSTILE]
	cp c
	ld a, $0
	jr nz, .notInGrass
	ld a, $80
.notInGrass
	ld [hl], a       ; c2x7
	and a
.done
	ret

UpdateSpriteImage: ; 5157 (1:5157)
	ld h, $c1
	ld a, [H_CURRENTSPRITEOFFSET]
	add $8
	ld l, a
	ld a, [hli]        ; c1x8: walk animation frame
	ld b, a
	ld a, [hl]         ; c1x9: facing direction
	add b
	ld b, a
	ld a, [$ff93]  ; current sprite offset
	add b
	ld b, a
	ld a, [H_CURRENTSPRITEOFFSET]
	add $2
	ld l, a
	ld [hl], b         ; c1x2: sprite to display
	ret

; tests if sprite can walk the specified direction
; b: direction (1,2,4 or 8)
; c: ID of tile the sprite would walk onto
; d: Y movement delta (-1, 0 or 1)
; e: X movement delta (-1, 0 or 1)
; set carry on failure, clears carry on success
CanWalkOntoTile: ; 516e (1:516e)
	ld h, $c2
	ld a, [H_CURRENTSPRITEOFFSET]
	add $6
	ld l, a
	ld a, [hl]         ; c2x6 (movement byte 1)
	cp $fe
	jr nc, .canMove    ; values $fe and $ff
	and a
	ret
.canMove
	ld a, [W_TILESETCOLLISIONPTR]
	ld l, a
	ld a, [W_TILESETCOLLISIONPTR+1]
	ld h, a
.tilePassableLoop
	ld a, [hli]
	cp $ff
	jr z, .impassable
	cp c
	jr nz, .tilePassableLoop
	ld h, $c2
	ld a, [H_CURRENTSPRITEOFFSET]
	add $6
	ld l, a
	ld a, [hl]         ; $c2x6 (movement byte 1)
	inc a
	jr z, .impassable  ; if $ff, no movement allowed (however, changing direction is)
	ld h, $c1
	ld a, [H_CURRENTSPRITEOFFSET]
	add $4
	ld l, a
	ld a, [hli]        ; c1x4 (screen Y pos)
	add $4             ; align to blocks (Y pos is always 4 pixels off)
	add d              ; add Y delta
	cp $80             ; if value is >$80, the destination is off screen (either $81 or $FF underflow)
	jr nc, .impassable ; don't walk off screen
	inc l
	ld a, [hl]         ; c1x6 (screen X pos)
	add e              ; add X delta
	cp $90             ; if value is >$90, the destination is off screen (either $91 or $FF underflow)
	jr nc, .impassable ; don't walk off screen
	push de
	push bc
	call Func_4c70
	pop bc
	pop de
	ld h, $c1
	ld a, [H_CURRENTSPRITEOFFSET]
	add $c
	ld l, a
	ld a, [hl]         ; c1xc (forbidden directions flags(?))
	and b              ; check against chosen direction (1,2,4 or 8)
	jr nz, .impassable ; direction forbidden, don't go there
	ld h, $c2
	ld a, [H_CURRENTSPRITEOFFSET]
	add $2
	ld l, a
	ld a, [hli]        ; c2x2 (sprite Y displacement, initialized at $8, keep track of where a sprite did go)
	bit 7, d           ; check if going upwards (d=$ff)
	jr nz, .upwards
	add d
	cp $5
	jr c, .impassable  ; if c2x2+d < 5, don't go ;bug: this tests probably were supposed to prevent sprites
	jr .checkHorizontal                          ; from walking out too far, but this line makes sprites get stuck
.upwards                                         ; whenever they walked upwards 5 steps
	sub $1                                       ; on the other hand, the amount a sprite can walk out to the
	jr c, .impassable  ; if d2x2 == 0, don't go  ; right of bottom is not limited (until the counter overflows)
.checkHorizontal
	ld d, a
	ld a, [hl]         ; c2x3 (sprite X displacement, initialized at $8, keep track of where a sprite did go)
	bit 7, e           ; check if going left (e=$ff)
	jr nz, .left
	add e
	cp $5              ; compare, but no conditional jump like in the vertical check above (bug?)
	jr .passable
.left
	sub $1
	jr c, .impassable  ; if d2x3 == 0, don't go
.passable
	ld [hld], a        ; update c2x3
	ld [hl], d         ; update c2x2
	and a              ; clear carry (marking success)
	ret
.impassable
	ld h, $c1
	ld a, [H_CURRENTSPRITEOFFSET]
	inc a
	ld l, a
	ld [hl], $2        ; c1x1 = 2 (set movement status to delayed)
	inc l
	inc l
	xor a
	ld [hli], a        ; c1x3 = 0 (clear Y movement delta)
	inc l
	ld [hl], a         ; c1x5 = 0 (clear X movement delta)
	inc h
	ld a, [H_CURRENTSPRITEOFFSET]
	add $8
	ld l, a
	call GenRandom
	ld a, [H_RAND1] ; $ffd3
	and $7f
	ld [hl], a         ; c2x8: set next movement delay to a random value in [0,$7f] (again with delay $100 if value is 0)
	scf                ; set carry (marking failure to walk)
	ret

; calculates the tile pointer pointing to the tile the current sprite stancs on
; this is always the lower left tile of the 2x2 tile blocks all sprites are snapped to
; hl: output pointer
getTileSpriteStandsOn: ; 5207 (1:5207)
	ld h, $c1
	ld a, [H_CURRENTSPRITEOFFSET]
	add $4
	ld l, a
	ld a, [hli]     ; c1x4: screen Y position
	add $4          ; align to 2*2 tile blocks (Y position is always off 4 pixels to the top)
	and $f0         ; in case object is currently moving
	srl a           ; screen Y tile * 4
	ld c, a
	ld b, $0
	inc l
	ld a, [hl]      ; c1x6: screen Y position
	srl a
	srl a
	srl a           ; screen X tile
	add $14         ; screen X tile + 20
	ld d, $0
	ld e, a
	ld hl, wTileMap
	add hl, bc
	add hl, bc
	add hl, bc
	add hl, bc
	add hl, bc
	add hl, de     ; wTileMap + 20*(screen Y tile + 1) + screen X tile
	ret

; loads [de+a] into a
LoadDEPlusA: ; 522f (1:522f)
	add e
	ld e, a
	jr nc, .noCarry
	inc d
.noCarry
	ld a, [de]
	ret

Func_5236: ; 5236 (1:5236)
	ld a, [$d730]
	bit 7, a
	ret z
	ld hl, $d72e
	bit 7, [hl]
	set 7, [hl]
	jp z, Func_52a6
	ld hl, $cc97
	ld a, [$cd37]
	add l
	ld l, a
	jr nc, .asm_5251
	inc h
.asm_5251
	ld a, [hl]
	cp $40
	jr nz, .asm_525f
	call Func_52b2
	ld c, $4
	ld a, $fe
	jr .asm_5289
.asm_525f
	cp $0
	jr nz, .asm_526c
	call Func_52b2
	ld c, $0
	ld a, $2
	jr .asm_5289
.asm_526c
	cp $80
	jr nz, .asm_5279
	call Func_52b7
	ld c, $8
	ld a, $fe
	jr .asm_5289
.asm_5279
	cp $c0
	jr nz, .asm_5286
	call Func_52b7
	ld c, $c
	ld a, $2
	jr .asm_5289
.asm_5286
	cp $ff
	ret
.asm_5289
	ld b, a
	ld a, [hl]
	add b
	ld [hl], a
	ld a, [H_CURRENTSPRITEOFFSET]
	add $9
	ld l, a
	ld a, c
	ld [hl], a
	call Func_52c3
	ld hl, $cf18
	dec [hl]
	ret nz
	ld a, $8
	ld [$cf18], a
	ld hl, $cd37
	inc [hl]
	ret

Func_52a6: ; 52a6 (1:52a6)
	xor a
	ld [$cd37], a
	ld a, $8
	ld [$cf18], a
	jp Func_52c3

Func_52b2: ; 52b2 (1:52b2)
	ld a, $4
	ld b, a
	jr asm_52ba

Func_52b7: ; 52b7 (1:52b7)
	ld a, $6
	ld b, a
asm_52ba: ; 52ba (1:52ba)
	ld hl, wSpriteStateData1
	ld a, [H_CURRENTSPRITEOFFSET]
	add l
	add b
	ld l, a
	ret

Func_52c3: ; 52c3 (1:52c3)
	ld hl, wSpriteStateData2
	ld a, [H_CURRENTSPRITEOFFSET]
	add $e
	ld l, a
	ld a, [hl]
	dec a
	swap a
	ld b, a
	ld hl, wSpriteStateData1
	ld a, [H_CURRENTSPRITEOFFSET]
	add $9
	ld l, a
	ld a, [hl]
	cp $0
	jr z, .asm_52ea
	cp $4
	jr z, .asm_52ea
	cp $8
	jr z, .asm_52ea
	cp $c
	jr z, .asm_52ea
	ret
.asm_52ea
	add b
	ld b, a
	ld [$ffe9], a
	call Func_5301
	ld hl, wSpriteStateData1
	ld a, [H_CURRENTSPRITEOFFSET]
	add $2
	ld l, a
	ld a, [$ffe9]
	ld b, a
	ld a, [$ffea]
	add b
	ld [hl], a
	ret

Func_5301: ; 5301 (1:5301)
	ld a, [H_CURRENTSPRITEOFFSET]
	add $7
	ld l, a
	ld a, [hl]
	inc a
	ld [hl], a
	cp $4
	ret nz
	xor a
	ld [hl], a
	inc l
	ld a, [hl]
	inc a
	and $3
	ld [hl], a
	ld [$ffea], a
	ret

Func_5317: ; 5317 (1:5317)
	ld c, $50
	call DelayFrames
	call ClearScreen
	call UpdateSprites
	call LoadFontTilePatterns
	call LoadHpBarAndStatusTilePatterns
	call LoadTrainerInfoTextBoxTiles
	FuncCoord 3, 8 ; $c443
	ld hl, Coord
	ld b, $2
	ld c, $c
	call Func_5ab3
	FuncCoord 4, 10 ; $c46c
	ld hl, Coord
	ld de, PleaseWaitString ; $550f
	call PlaceString
	ld hl, W_NUMHITS ; $d074
	xor a
	ld [hli], a
	ld [hl], $50

Func_5345: ; 5345
	ld hl, $d152
	ld a, $fd
	ld b, $6
.asm_534c
	ld [hli], a
	dec b
	jr nz, .asm_534c
	ld hl, $d141
	ld a, $fd
	ld b, $7
.asm_5357
	ld [hli], a
	dec b
	jr nz, .asm_5357
	ld b, $a
.asm_535d
	call GenRandom
	cp $fd
	jr nc, .asm_535d
	ld [hli], a
	dec b
	jr nz, .asm_535d
	ld hl, wTileMapBackup
	ld a, $fd
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld b, $c8
	xor a
.asm_5373
	ld [hli], a
	dec b
	jr nz, .asm_5373
	ld hl, W_GRASSRATE ; $d887
	ld bc, $1a9
.asm_537d
	xor a
	ld [hli], a
	dec bc
	ld a, b
	or c
	jr nz, .asm_537d
	ld hl, W_PARTYMONEND ; $d16a
	ld de, $c512
	ld bc, $0
.asm_538d
	inc c
	ld a, c
	cp $fd
	jr z, .asm_53a9
	ld a, b
	dec a
	jr nz, .asm_539c
	ld a, c
	cp $d
	jr z, .asm_53b2
.asm_539c
	inc hl
	ld a, [hl]
	cp $fe
	jr nz, .asm_538d
	ld a, c
	ld [de], a
	inc de
	ld [hl], $ff
	jr .asm_538d
.asm_53a9
	ld a, $ff
	ld [de], a
	inc de
	ld bc, $100
	jr .asm_538d
.asm_53b2
	ld a, $ff
	ld [de], a
	call Func_227f
	ld a, [$ffaa]
	cp $2
	jr nz, .asm_53d2
	call Delay3
	xor a
	ld [$ffac], a
	ld a, $81
	ld [$ff02], a
	call DelayFrame
	xor a
	ld [$ffac], a
	ld a, $81
	ld [$ff02], a
.asm_53d2
	call Delay3
	ld a, $8
	ld [rIE], a ; $ffff
	ld hl, $d141
	ld de, wTileMapBackup2
	ld bc, $11
	call Func_216f
	ld a, $fe
	ld [de], a
	ld hl, $d152
	ld de, $d893
	ld bc, $1a8
	call Func_216f
	ld a, $fe
	ld [de], a
	ld hl, wTileMapBackup
	ld de, $c5d0
	ld bc, $c8
	call Func_216f
	ld a, $d
	ld [rIE], a ; $ffff
	ld a, $ff
	call PlaySound
	ld a, [$ffaa]
	cp $2
	jr z, .asm_5431
	ld hl, wTileMapBackup2
.asm_5415
	ld a, [hli]
	and a
	jr z, .asm_5415
	cp $fd
	jr z, .asm_5415
	cp $fe
	jr z, .asm_5415
	dec hl
	ld de, $d148
	ld c, $a
.asm_5427
	ld a, [hli]
	cp $fe
	jr z, .asm_5427
	ld [de], a
	inc de
	dec c
	jr nz, .asm_5427
.asm_5431
	ld hl, $d896
.asm_5434
	ld a, [hli]
	and a
	jr z, .asm_5434
	cp $fd
	jr z, .asm_5434
	cp $fe
	jr z, .asm_5434
	dec hl
	ld de, W_GRASSRATE ; $d887
	ld c, $b
.asm_5446
	ld a, [hli]
	cp $fe
	jr z, .asm_5446
	ld [de], a
	inc de
	dec c
	jr nz, .asm_5446
	ld de, wEnemyPartyCount ; $d89c
	ld bc, $194
.asm_5456
	ld a, [hli]
	cp $fe
	jr z, .asm_5456
	ld [de], a
	inc de
	dec bc
	ld a, b
	or c
	jr nz, .asm_5456
	ld de, wTileMapBackup
	ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
	ld c, $2
.asm_546a
	ld a, [de]
	inc de
	and a
	jr z, .asm_546a
	cp $fd
	jr z, .asm_546a
	cp $fe
	jr z, .asm_546a
	cp $ff
	jr z, .asm_5489
	push hl
	push bc
	ld b, $0
	dec a
	ld c, a
	add hl, bc
	ld a, $fe
	ld [hl], a
	pop bc
	pop hl
	jr .asm_546a
.asm_5489
	ld hl, W_PARTYMON6DATA + W_PARTYMON1_MOVE4PP - W_PARTYMON1DATA ; $d267
	dec c
	jr nz, .asm_546a
	ld de, $c5d0
	ld hl, W_WATERRATE ; $d8a4
	ld c, $2
.asm_5497
	ld a, [de]
	inc de
	and a
	jr z, .asm_5497
	cp $fd
	jr z, .asm_5497
	cp $fe
	jr z, .asm_5497
	cp $ff
	jr z, .asm_54b6
	push hl
	push bc
	ld b, $0
	dec a
	ld c, a
	add hl, bc
	ld a, $fe
	ld [hl], a
	pop bc
	pop hl
	jr .asm_5497
.asm_54b6
	ld hl, $d9a0
	dec c
	jr nz, .asm_5497
	ld a, $ac
	ld [$cf8d], a
	ld a, $d9
	ld [$cf8e], a
	xor a
	ld [$cc38], a
	ld a, $ff
	call PlaySound
	ld a, [$ffaa]
	cp $2
	ld c, $42
	call z, DelayFrames
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $3
	ld a, $32
	ld [W_ISLINKBATTLE], a ; $d12b
	jr nz, .asm_5506
	ld a, $4
	ld [W_ISLINKBATTLE], a ; $d12b
	ld a, SONY1 + $c8
	ld [W_CUROPPONENT], a ; $d059
	call ClearScreen
	call Delay3
	ld hl, W_OPTIONS ; $d355
	res 7, [hl]
	ld a, $2c
	call Predef ; indirect jump to Func_3ef18 (3ef18 (f:6f18))
	ld a, $7
	call Predef ; indirect jump to HealParty (f6a5 (3:76a5))
	jp Func_577d
.asm_5506
	ld c, BANK(Music_GameCorner)
	ld a, MUSIC_GAME_CORNER
	call PlayMusic
	jr Func_551c

PleaseWaitString: ; 550f (1:550f)
	db "PLEASE WAIT!@"

Func_551c:
	ld hl, PointerTable_5a5b ; $5a5b
	ld b, $0
	ld a, [$cc38]
	cp $ff
	jp z, LoadTitlescreenGraphics
	add a
	ld c, a
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	jp [hl]

Func_5530:
	call ClearScreen
	call LoadTrainerInfoTextBoxTiles
	call Func_57f2
	call Func_57a2
	xor a
	ld hl, $cc3d
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hl], a
	ld [$cc37], a
	ld [$cc26], a
	ld [$cc2a], a
	ld [$cc34], a
	inc a
	ld [$cc42], a
	jp .asm_55dc
.asm_5557
	xor a
	ld [$cc37], a
	inc a
	ld [$cc49], a
	ld a, $a1
	ld [$cc29], a
	ld a, [$d89c]
	ld [$cc28], a
	ld a, $9
	ld [$cc24], a
	ld a, $1
	ld [$cc25], a
.asm_5574
	ld hl, $fff6
	set 1, [hl]
	call HandleMenuInput
	ld hl, $fff6
	res 1, [hl]
	and a
	jp z, .asm_565b
	bit 0, a
	jr z, .asm_55b0 ; 0x5587 $27
	ld a, [$cc28]
	ld c, a
	ld a, [$cc26]
	cp c
	jr c, .asm_559a ; 0x5591 $7
	ld a, [$cc28]
	dec a
	ld [$cc26], a
.asm_559a
	ld a, $1
	ld [$d11b], a
	callab Func_39bd5
	ld hl, wEnemyMons
	call Func_57d6
	jp .asm_565b
.asm_55b0
	bit 5, a
	jr z, .asm_55d4 ; 0x55b2 $20
	xor a
	ld [$cc49], a
	ld a, [$cc30]
	ld l, a
	ld a, [$cc31]
	ld h, a
	ld a, [$cc27]
	ld [hl], a
	ld a, [$cc26]
	ld b, a
	ld a, [$d163]
	dec a
	cp b
	jr nc, .asm_55dc ; 0x55cd $d
	ld [$cc26], a
	jr .asm_55dc ; 0x55d2 $8
.asm_55d4
	bit 7, a
	jp z, .asm_565b
	jp .asm_572f
.asm_55dc
	xor a
	ld [$cc49], a
	ld [$cc37], a
	ld a, $91
	ld [$cc29], a
	ld a, [$d163]
	ld [$cc28], a
	ld a, $1
	ld [$cc24], a
	ld a, $1
	ld [$cc25], a
	ld hl, $c3b5
	ld bc, $0601
	call ClearScreenArea
.asm_5601
	ld hl, $fff6
	set 1, [hl]
	call HandleMenuInput
	ld hl, $fff6
	res 1, [hl]
	and a
	jr nz, .asm_5614 ; 0x560f $3
	jp .asm_565b
.asm_5614
	bit 0, a
	jr z, .asm_562e ; 0x5616 $16
	jp .asm_5665
	ld a, $4
	ld [$d11b], a
	callab Func_39bd5
	call Func_57d6
	jp .asm_565b
.asm_562e
	bit 4, a
	jr z, .asm_5654 ; 0x5630 $22
	ld a, $1
	ld [$cc49], a
	ld a, [$cc30]
	ld l, a
	ld a, [$cc31]
	ld h, a
	ld a, [$cc27]
	ld [hl], a
	ld a, [$cc26]
	ld b, a
	ld a, [$d89c]
	dec a
	cp b
	jr nc, .asm_5651 ; 0x564c $3
	ld [$cc26], a
.asm_5651
	jp .asm_5557
.asm_5654
	bit 7, a
	jr z, .asm_565b ; 0x5656 $3
	jp .asm_572f
.asm_565b
	ld a, [$cc49]
	and a
	jp z, .asm_5601
	jp .asm_5574
.asm_5665
	call SaveScreenTilesToBuffer1
	call PlaceUnfilledArrowMenuCursor
	ld a, [$cc28]
	ld c, a
	ld a, [$cc26]
	cp c
	jr c, .asm_5679 ; 0x5673 $4
	ld a, [$cc28]
	dec a
.asm_5679
	push af
	ld hl, $c4b8
	ld b, $2
	ld c, $12
	call Func_5ab3
	ld hl, $c4e2
	ld de, .statsTrade
	call PlaceString
	xor a
	ld [$cc26], a
	ld [$cc2a], a
	ld [$cc34], a
	ld [$cc28], a
	ld a, $10
	ld [$cc24], a
.asm_569f
	ld a, $7f
	ld [$c4eb], a
	ld a, $13
	ld [$cc29], a
	ld a, $1
	ld [$cc25], a
	call HandleMenuInput
	bit 4, a
	jr nz, .asm_56c3 ; 0x56b3 $e
	bit 1, a
	jr z, .asm_56df ; 0x56b7 $26
.asm_56b9
	pop af
	ld [$cc26], a
	call LoadScreenTilesFromBuffer1
	jp .asm_55dc
.asm_56c3
	ld a, $7f
	ld [$c4e1], a
	ld a, $23
	ld [$cc29], a
	ld a, $b
	ld [$cc25], a
	call HandleMenuInput
	bit 5, a
	jr nz, .asm_569f ; 0x56d7 $c6
	bit 1, a
	jr nz, .asm_56b9 ; 0x56db $dc
	jr .asm_56f9 ; 0x56dd $1a
.asm_56df
	pop af
	ld [$cc26], a
	ld a, $4
	ld [$d11b], a
	callab Func_39bd5
	call Func_57d6
	call LoadScreenTilesFromBuffer1
	jp .asm_55dc
.asm_56f9
	call PlaceUnfilledArrowMenuCursor
	pop af
	ld [$cc26], a
	ld [$cd3d], a
	ld [$cc42], a
	call Func_226e
	ld a, [$cc3d]
	cp $f
	jp z, Func_551c
	ld [$cd3e], a
	call Func_57c7
	ld a, $1
	ld [$cc38], a
	jp Func_551c
.statsTrade
	db "STATS     TRADE@"
.asm_572f
	ld a, [$cc26]
	ld b, a
	ld a, [$cc28]
	cp b
	jp nz, .asm_565b
	ld a, [$cc30]
	ld l, a
	ld a, [$cc31]
	ld h, a
	ld a, $7f
	ld [hl], a
.asm_5745
	ld a, $ed
	ld [$c4e1], a
.asm_574a
	call GetJoypadStateLowSensitivity
	ld a, [$ffb5]
	and a
	jr z, .asm_574a ; 0x5750 $f8
	bit 0, a
	jr nz, .asm_5769 ; 0x5754 $13
	bit 6, a
	jr z, .asm_574a ; 0x5758 $f0
	ld a, $7f
	ld [$c4e1], a
	ld a, [$d163]
	dec a
	ld [$cc26], a
	jp .asm_55dc
.asm_5769
	ld a, $ec
	ld [$c4e1], a
	ld a, $f
	ld [$cc42], a
	call Func_226e
	ld a, [$cc3d]
	cp $f
	jr nz, .asm_5745 ; 0x577b $c8

Func_577d: ; 577d (1:577d)
	call GBPalWhiteOutWithDelay3
	ld hl, $cfc4
	ld a, [hl]
	push af
	push hl
	res 0, [hl]
	xor a
	ld [$d72d], a
	dec a
	ld [$d42f], a
	call LoadMapData
	callba Func_c335
	pop hl
	pop af
	ld [hl], a
	call GBFadeIn2
	ret

Func_57a2:
	ld hl, $c4d7
	ld a, $7e
	ld bc, $0031
	call FillMemory
	ld hl, $c4cc
	ld b, $1
	ld c, $9
	call Func_5ab3
	ld hl, $c4e2
	ld de, CancelTextString
	jp PlaceString

CancelTextString:
	db "CANCEL@"

Func_57c7:
	ld a, [$cc3d]
	ld hl, $c455
	ld bc, $0014
	call AddNTimes
	ld [hl], $ec
	ret

Func_57d6:
	ld a, [$cc26]
	ld [wWhichPokemon], a
	ld a, $36
	call Predef
	ld a, $37
	call Predef
	call GBPalNormal
	call LoadTrainerInfoTextBoxTiles
	call Func_57f2
	jp Func_57a2

Func_57f2:
	ld hl, wTileMap
	ld b, $6
	ld c, $12
	call Func_5ab3
	ld hl, $c440
	ld b, $6
	ld c, $12
	call Func_5ab3
	ld hl, $c3a5
	ld de, W_PLAYERNAME
	call PlaceString
	ld hl, $c445
	ld de, $d887
	call PlaceString
	ld hl, $c3b6
	ld de, $d164
	call Func_5827
	ld hl, $c456
	ld de, $d89d

Func_5827:
	ld c, $0
.asm_5829
	ld a, [de]
	cp $ff
	ret z
	ld [$d11e], a
	push bc
	push hl
	push de
	push hl
	ld a, c
	ld [$ff95], a
	call GetMonName
	pop hl
	call PlaceString
	pop de
	inc de
	pop hl
	ld bc, $0014
	add hl, bc
	pop bc
	inc c
	jr .asm_5829 ; 0x5847 $e0

CableClubTradeCenter:
	ld c, $64
	call DelayFrames
	xor a
	ld [$cc43], a
	ld [$cc3e], a
	ld [$cc37], a
	ld [$cc34], a
	ld hl, $c490
	ld b, $4
	ld c, $12
	call Func_5ab3
	ld a, [$cd3d]
	ld hl, $d164
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]
	ld [$d11e], a
	call GetMonName
	ld hl, $cd6d
	ld de, $cd3f
	ld bc, $000b
	call CopyData
	ld a, [$cd3e]
	ld hl, $d89d
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]
	ld [$d11e], a
	call GetMonName
	ld hl, WillBeTradedText
	ld bc, $c4b9
	call TextCommandProcessor
	call SaveScreenTilesToBuffer1
	ld hl, $c436
	ld bc, $080b
	ld a, $5
	ld [$d12c], a
	ld a, $14
	ld [$d125], a
	call DisplayTextBoxID
	call LoadScreenTilesFromBuffer1
	ld a, [$cc26]
	and a
	jr z, .asm_58d9 ; 0x58b9 $1e
	ld a, $1
	ld [$cc42], a
	ld hl, $c490
	ld b, $4
	ld c, $12
	call Func_5ab3
	ld hl, $c4b9
	ld de, TradeCanceled
	call PlaceString
	call Func_226e
	jp Func_5a18
.asm_58d9
	ld a, $2
	ld [$cc42], a
	call Func_226e
	ld a, [$cc3d]
	dec a
	jr nz, .asm_58fd ; 0x58e5 $16
	ld hl, $c490
	ld b, $4
	ld c, $12
	call Func_5ab3
	ld hl, $c4b9
	ld de, TradeCanceled
	call PlaceString
	jp Func_5a18
.asm_58fd
	ld a, [$cd3d]
	ld hl, W_PARTYMON1OT ; OT names of player
	call SkipFixedLengthTextEntries
	ld de, $cd41
	ld bc, $000b
	call CopyData
	ld hl, $d16b
	ld a, [$cd3d]
	ld bc, $002c
	call AddNTimes
	ld bc, $000c
	add hl, bc
	ld a, [hli]
	ld [$cd4c], a
	ld a, [hl]
	ld [$cd4d], a
	ld a, [$cd3e]
	ld hl, W_ENEMYMON1OT ; OT names of other player
	call SkipFixedLengthTextEntries
	ld de, $cd4e
	ld bc, $000b
	call CopyData
	ld hl, wEnemyMons
	ld a, [$cd3e]
	ld bc, $002c
	call AddNTimes
	ld bc, $000c
	add hl, bc
	ld a, [hli]
	ld [$cd59], a
	ld a, [hl]
	ld [$cd5a], a
	ld a, [$cd3d]
	ld [wWhichPokemon], a
	ld hl, $d164
	ld b, $0
	ld c, a
	add hl, bc
	ld a, [hl]
	ld [$cd3d], a
	xor a
	ld [$cf95], a
	call RemovePokemon
	ld a, [$cd3e]
	ld c, a
	ld [wWhichPokemon], a
	ld hl, $d89d
	ld d, $0
	ld e, a
	add hl, de
	ld a, [hl]
	ld [$cf91], a
	ld hl, wEnemyMons
	ld a, c
	ld bc, $002c
	call AddNTimes
	ld de, $cf98
	ld bc, $002c
	call CopyData
	call AddEnemyMonToPlayerParty
	ld a, [$d163]
	dec a
	ld [wWhichPokemon], a
	ld a, $1
	ld [$ccd4], a
	ld a, [$cd3e]
	ld hl, $d89d
	ld b, $0
	ld c, a
	add hl, bc
	ld a, [hl]
	ld [$cd3e], a
	ld a, $a
	ld [wMusicHeaderPointer], a
	ld a, $2
	ld [$c0f0], a
	ld a, MUSIC_SAFARI_ZONE
	ld [$c0ee], a
	call PlaySound
	ld c, $64
	call DelayFrames
	call ClearScreen
	call LoadHpBarAndStatusTilePatterns
	xor a
	ld [$cc5b], a
	ld a, [$ffaa]
	cp $1
	jr z, .asm_59d9 ; 0x59d0 $7
	ld a, $38
	call Predef
	jr .asm_59de ; 0x59d7 $5
.asm_59d9
	ld a, $2f
	call Predef
.asm_59de
	callab Func_3ad0e
	call ClearScreen
	call LoadTrainerInfoTextBoxTiles
	call Func_226e
	ld c, $28
	call DelayFrames
	ld hl, $c490
	ld b, $4
	ld c, $12
	call Func_5ab3
	ld hl, $c4b9
	ld de, TradeCompleted
	call PlaceString
	ld a, $50
	call Predef
	ld c, $32
	call DelayFrames
	xor a
	ld [$cc38], a
	jp Func_5345

Func_5a18:
	ld c, $64
	call DelayFrames
	xor a
	ld [$cc38], a
	jp Func_551c

WillBeTradedText: ; 5a24 (1:5a24)
	TX_FAR _WillBeTradedText
	db "@"

TradeCompleted:
	db "Trade completed!@"

TradeCanceled:
	db   "Too bad! The trade"
	next "was canceled!@"

PointerTable_5a5b: ; 5a5b (1:5a5b)
	dw Func_5530
	dw CableClubTradeCenter

Func_5a5f: ; 5a5f (1:5a5f)
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $2
	jr z, .asm_5a75
	cp $3
	jr z, .asm_5a75
	cp $5
	ret nz
	ld a, $4d
	call Predef ; indirect jump to Func_5aaf (5aaf (1:5aaf))
	jp InitGame
.asm_5a75
	call Func_5317
	ld hl, Club_GFX
	ld a, h
	ld [$d52f], a
	ld a, l
	ld [$d52e], a
	ld a, Bank(Club_GFX)
	ld [$d52b], a
	ld hl, Club_Coll
	ld a, h
	ld [$d531], a
	ld a, l
	ld [$d530], a
	xor a
	ld [W_GRASSRATE], a ; $d887
	inc a
	ld [W_ISLINKBATTLE], a ; $d12b
	ld [$ffb5], a
	ld a, $a
	ld [wMusicHeaderPointer], a
	ld a, BANK(Music_Celadon)
	ld [$c0f0], a
	ld a, MUSIC_CELADON
	ld [$c0ee], a
	jp PlaySound

Func_5aaf: ; 5aaf (1:5aaf)
	ret

Func_5ab0:
	call Load16BitRegisters

Func_5ab3: ; 5ab3 (1:5ab3)
	push hl
	ld a, $78
	ld [hli], a
	inc a
	call Func_5ae0
	inc a
	ld [hl], a
	pop hl
	ld de, $14
	add hl, de
.asm_5ac2
	push hl
	ld a, $7b
	ld [hli], a
	ld a, $7f
	call Func_5ae0
	ld [hl], $77
	pop hl
	ld de, $14
	add hl, de
	dec b
	jr nz, .asm_5ac2
	ld a, $7c
	ld [hli], a
	ld a, $76
	call Func_5ae0
	ld [hl], $7d
	ret

Func_5ae0: ; 5ae0 (1:5ae0)
	ld d, c
.asm_5ae1
	ld [hli], a
	dec d
	jr nz, .asm_5ae1
	ret

LoadTrainerInfoTextBoxTiles: ; 5ae6 (1:5ae6)
	ld de, TrainerInfoTextBoxTileGraphics ; $7b98
	ld hl, $9760
	ld bc, (BANK(TrainerInfoTextBoxTileGraphics) << 8) +$09
	jp CopyVideoData

MainMenu: ; 5af2 (1:5af2)
; Check save file
	call Func_5bff
	xor a
	ld [$D08A],a
	inc a
	ld [$D088],a
	call Func_609e
	jr nc,.next0

	; Predef 52 loads the save from SRAM to RAM
	ld a,$52
	call Predef

.next0
	ld c,20
	call DelayFrames
	xor a
	ld [$D12B],a
	ld hl,$CC2B
	ld [hli],a
	ld [hli],a
	ld [hli],a
	ld [hl],a
	ld [$D07C],a
	ld hl,$D72E
	res 6,[hl]
	call ClearScreen
	call GoPAL_SET_CF1C
	call LoadTextBoxTilePatterns
	call LoadFontTilePatterns
	ld hl,$D730
	set 6,[hl]
	ld a,[$D088]
	cp a,1
	jr z,.next1
	FuncCoord 0,0
	ld hl,Coord
	ld b,6
	ld c,13
	call TextBoxBorder
	FuncCoord 2,2
	ld hl,Coord
	ld de,ContinueText
	call PlaceString
	jr .next2
.next1
	FuncCoord 0,0
	ld hl,Coord
	ld b,4
	ld c,13
	call TextBoxBorder
	FuncCoord 2,2
	ld hl,Coord
	ld de,NewGameText
	call PlaceString
.next2
	ld hl,$D730
	res 6,[hl]
	call UpdateSprites ; OAM?
	xor a
	ld [$CC26],a
	ld [$CC2A],a
	ld [$CC34],a
	inc a
	ld [$CC25],a
	inc a
	ld [$CC24],a
	ld a,$B
	ld [$CC29],a
	ld a,[$D088]
	ld [$CC28],a
	call HandleMenuInput
	bit 1,a
	jp nz,LoadTitlescreenGraphics ; load title screen (gfx and arrangement)
	ld c,20
	call DelayFrames
	ld a,[$CC26]
	ld b,a
	ld a,[$D088]
	cp a,2
	jp z,.next3
	inc b ; adjust MenuArrow_Counter
.next3
	ld a,b
	and a
	jr z,.next4 ; if press_A on Continue
	cp a,1
	jp z,Func_5d52 ; if press_A on NewGame
	call DisplayOptionMenu ; if press_a on Options
	ld a,1
	ld [$D08A],a
	jp .next0
.next4
	call ContinueGame
	ld hl,$D126
	set 5,[hl]
.next6
	xor a
	ld [H_NEWLYPRESSEDBUTTONS],a
	ld [H_NEWLYRELEASEDBUTTONS],a
	ld [H_CURRENTPRESSEDBUTTONS],a
	call GetJoypadState
	ld a,[H_CURRENTPRESSEDBUTTONS]
	bit 0,a
	jr nz,.next5
	bit 1,a
	jp nz,.next0
	jr .next6
.next5
	call GBPalWhiteOutWithDelay3
	call ClearScreen
	ld a,4
	ld [$D52A],a
	ld c,10
	call DelayFrames
	ld a,[$D5A2]
	and a
	jp z,Func_5d5f
	ld a,[W_CURMAP] ; map ID
	cp a,HALL_OF_FAME
	jp nz,Func_5d5f
	xor a
	ld [$D71A],a
	ld hl,$D732
	set 2,[hl]
	call Func_62ce
	jp Func_5d5f
Func_5bff: ; 5bff (1:5bff)
	ld a,1
	ld [$D358],a
	ld a,3
	ld [$D355],a
	ret

LinkMenu: ; 5c0a (1:5c0a)
	xor a
	ld [$d358], a
	ld hl, $d72e
	set 6, [hl]
	ld hl, TextTerminator_6b20 ; $6b20
	call PrintText
	call SaveScreenTilesToBuffer1
	ld hl, WhereWouldYouLikeText
	call PrintText
	FuncCoord 5, 5 ; $c409
	ld hl, Coord
	ld b, $6
	ld c, $d
	call TextBoxBorder
	call UpdateSprites
	FuncCoord 7, 7 ; $c433
	ld hl, Coord
	ld de, TradeCenterText
	call PlaceString
	xor a
	ld [$cd37], a
	ld [$d72d], a
	ld hl, wTopMenuItemY ; $cc24
	ld a, $7
	ld [hli], a
	ld a, $6
	ld [hli], a
	xor a
	ld [hli], a
	inc hl
	ld a, $2
	ld [hli], a
	inc a
	ld [hli], a
	xor a
	ld [hl], a
.asm_5c52
	call HandleMenuInput
	and $3
	add a
	add a
	ld b, a
	ld a, [wCurrentMenuItem] ; $cc26
	add b
	add $d0
	ld [$cc42], a
	ld [$cc43], a
.asm_5c66
	call Func_2247
	ld a, [$cc3d]
	ld b, a
	and $f0
	cp $d0
	jr z, .asm_5c7d
	ld a, [$cc3e]
	ld b, a
	and $f0
	cp $d0
	jr nz, .asm_5c66
.asm_5c7d
	ld a, b
	and $c
	jr nz, .asm_5c8b
	ld a, [$cc42]
	and $c
	jr z, .asm_5c52
	jr .asm_5ca1
.asm_5c8b
	ld a, [$cc42]
	and $c
	jr z, .asm_5c98
	ld a, [$ffaa]
	cp $2
	jr z, .asm_5ca1
.asm_5c98
	ld a, b
	ld [$cc42], a
	and $3
	ld [wCurrentMenuItem], a ; $cc26
.asm_5ca1
	ld a, [$ffaa]
	cp $2
	jr nz, .asm_5cb1
	call DelayFrame
	call DelayFrame
	ld a, $81
	ld [$ff02], a
.asm_5cb1
	ld b, $7f
	ld c, $7f
	ld d, $ec
	ld a, [$cc42]
	and $8
	jr nz, .asm_5ccc
	ld a, [wCurrentMenuItem] ; $cc26
	cp $2
	jr z, .asm_5ccc
	ld c, d
	ld d, b
	dec a
	jr z, .asm_5ccc
	ld b, c
	ld c, d
.asm_5ccc
	ld a, b
	FuncCoord 6, 7 ; $c432
	ld [Coord], a
	ld a, c
	FuncCoord 6, 9 ; $c45a
	ld [Coord], a
	ld a, d
	FuncCoord 6, 11 ; $c482
	ld [Coord], a
	ld c, $28
	call DelayFrames
	call LoadScreenTilesFromBuffer1
	ld a, [$cc42]
	and $8
	jr nz, .asm_5d2d
	ld a, [wCurrentMenuItem] ; $cc26
	cp $2
	jr z, .asm_5d2d
	xor a
	ld [$d700], a
	ld a, [wCurrentMenuItem] ; $cc26
	and a
	ld a, TRADE_CENTER
	jr nz, .asm_5cfc
	ld a, BATTLE_CENTER
.asm_5cfc
	ld [$d72d], a
	ld hl, PleaseWaitText
	call PrintText
	ld c, $32
	call DelayFrames
	ld hl, $d732
	res 1, [hl]
	ld a, [W_ANIMATIONID] ; $d07c
	ld [$d71a], a
	call Func_62ce
	ld c, $14
	call DelayFrames
	xor a
	ld [wMenuJoypadPollCount], a ; $cc34
	ld [$cc42], a
	inc a
	ld [W_ISLINKBATTLE], a ; $d12b
	ld [$cc47], a
	jr Func_5d5f
.asm_5d2d
	xor a
	ld [wMenuJoypadPollCount], a ; $cc34
	call Delay3
	call Func_72d7
	ld hl, LinkCanceledText
	call PrintText
	ld hl, $d72e
	res 6, [hl]
	ret

WhereWouldYouLikeText: ; 5d43 (1:5d43)
	TX_FAR _WhereWouldYouLikeText
	db "@"

PleaseWaitText: ; 5d48 (1:5d48)
	TX_FAR _PleaseWaitText
	db "@"

LinkCanceledText: ; 5d4d (1:5d4d)
	TX_FAR _LinkCanceledText
	db "@"

Func_5d52: ; 5d52 (1:5d52)
	ld hl, $d732
	res 1, [hl]
	call OakSpeech
	ld c, $14
	call DelayFrames

Func_5d5f: ; 5d5f (1:5d5f)
	xor a
	ld [H_NEWLYPRESSEDBUTTONS], a
	ld [H_CURRENTPRESSEDBUTTONS], a
	ld [$ffb5], a
	ld [$d72d], a
	ld hl, $d732
	set 0, [hl]
	call ResetPlayerSpriteData
	ld c, $14
	call DelayFrames
	ld a, [$cc47]
	and a
	ret nz
	jp EnterMap

ContinueText: ; 5d7e (1:5d7e)
	db "CONTINUE", $4e

NewGameText: ; 5d87 (1:5d87)
	db "NEW GAME", $4e
	db "OPTION@"

TradeCenterText: ; 5d97 (1:5d97)
	db "TRADE CENTER", $4e
	db "COLOSSEUM",    $4e
	db "CANCEL@"

ContinueGame: ; 5db5 (1:5db5)
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	FuncCoord 4, 7 ; $c430
	ld hl, Coord
	ld b, $8
	ld c, $e
	call TextBoxBorder
	FuncCoord 5, 9 ; $c459
	ld hl, Coord
	ld de, SaveScreenInfoText
	call PlaceString
	FuncCoord 12, 9 ; $c460
	ld hl, Coord
	ld de, W_PLAYERNAME ; $d158
	call PlaceString
	FuncCoord 17, 11 ; $c48d
	ld hl, Coord
	call Func_5e2f
	FuncCoord 16, 13 ; $c4b4
	ld hl, Coord
	call Func_5e42
	FuncCoord 13, 15 ; $c4d9
	ld hl, Coord
	call Func_5e55
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld c, $1e
	jp DelayFrames

PrintSaveScreenText: ; 5def (1:5def)
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a
	ld hl, $c3a4
	ld b, $8
	ld c, $e
	call TextBoxBorder
	call LoadTextBoxTilePatterns
	call UpdateSprites
	ld hl, $c3cd
	ld de, SaveScreenInfoText
	call PlaceString
	ld hl, $c3d4
	ld de, W_PLAYERNAME
	call PlaceString
	ld hl, $c401
	call Func_5e2f
	ld hl, $c428
	call Func_5e42
	ld hl, $c44d
	call Func_5e55
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a
	ld c, $1e
	jp DelayFrames

Func_5e2f: ; 5e2f (1:5e2f)
	push hl
	ld hl, W_OBTAINEDBADGES
	ld b, $1
	call CountSetBits
	pop hl
	ld de, $d11e
	ld bc, $102
	jp PrintNumber

Func_5e42: ; 5e42 (1:5e42)
	push hl
	ld hl, wPokedexOwned ; $d2f7
	ld b, wPokedexOwnedEnd - wPokedexOwned
	call CountSetBits
	pop hl
	ld de, $d11e
	ld bc, $103
	jp PrintNumber

Func_5e55: ; 5e55 (1:5e55)
	ld de, $da41
	ld bc, $103
	call PrintNumber
	ld [hl], $6d
	inc hl
	ld de, $da43
	ld bc, $8102
	jp PrintNumber

SaveScreenInfoText: ; 5e6a (1:5e6a)
	db   "PLAYER"
	next "BADGES    "
	next "#DEX    "
	next "TIME@"

DisplayOptionMenu: ; 5e8a (1:5e8a)
	FuncCoord 0,0
	ld hl,Coord
	ld b,3
	ld c,18
	call TextBoxBorder
	FuncCoord 0,5
	ld hl,Coord
	ld b,3
	ld c,18
	call TextBoxBorder
	FuncCoord 0,10
	ld hl,Coord
	ld b,3
	ld c,18
	call TextBoxBorder
	FuncCoord 1,1
	ld hl,Coord
	ld de,TextSpeedOptionText
	call PlaceString
	FuncCoord 1,6
	ld hl,Coord
	ld de,BattleAnimationOptionText
	call PlaceString
	FuncCoord 1,11
	ld hl,Coord
	ld de,BattleStyleOptionText
	call PlaceString
	FuncCoord 2,16
	ld hl,Coord
	ld de,OptionMenuCancelText
	call PlaceString
	xor a
	ld [wCurrentMenuItem],a
	ld [wLastMenuItem],a
	inc a
	ld [$d358],a
	ld [$cd40],a
	ld a,3 ; text speed cursor Y coordinate
	ld [wTopMenuItemY],a
	call SetCursorPositionsFromOptions
	ld a,[$cd3d] ; text speed cursor X coordinate
	ld [wTopMenuItemX],a
	ld a,$01
	ld [H_AUTOBGTRANSFERENABLED],a ; enable auto background transfer
	call Delay3
.loop
	call PlaceMenuCursor
	call SetOptionsFromCursorPositions
.getJoypadStateLoop
	call GetJoypadStateLowSensitivity
	ld a,[$ffb5]
	ld b,a
	and a,%11111011 ; any key besides select pressed?
	jr z,.getJoypadStateLoop
	bit 1,b ; B button pressed?
	jr nz,.exitMenu
	bit 3,b ; Start button pressed?
	jr nz,.exitMenu
	bit 0,b ; A button pressed?
	jr z,.checkDirectionKeys
	ld a,[wTopMenuItemY]
	cp a,16 ; is the cursor on Cancel?
	jr nz,.loop
.exitMenu
	ld a,(SFX_02_40 - SFX_Headers_02) / 3
	call PlaySound ; play sound
	ret
.eraseOldMenuCursor
	ld [wTopMenuItemX],a
	call EraseMenuCursor
	jp .loop
.checkDirectionKeys
	ld a,[wTopMenuItemY]
	bit 7,b ; Down pressed?
	jr nz,.downPressed
	bit 6,b ; Up pressed?
	jr nz,.upPressed
	cp a,8 ; cursor in Battle Animation section?
	jr z,.cursorInBattleAnimation
	cp a,13 ; cursor in Battle Style section?
	jr z,.cursorInBattleStyle
	cp a,16 ; cursor on Cancel?
	jr z,.loop
.cursorInTextSpeed
	bit 5,b ; Left pressed?
	jp nz,.pressedLeftInTextSpeed
	jp .pressedRightInTextSpeed
.downPressed
	cp a,16
	ld b,-13
	ld hl,$cd3d
	jr z,.updateMenuVariables
	ld b,5
	cp a,3
	inc hl
	jr z,.updateMenuVariables
	cp a,8
	inc hl
	jr z,.updateMenuVariables
	ld b,3
	inc hl
	jr .updateMenuVariables
.upPressed
	cp a,8
	ld b,-5
	ld hl,$cd3d
	jr z,.updateMenuVariables
	cp a,13
	inc hl
	jr z,.updateMenuVariables
	cp a,16
	ld b,-3
	inc hl
	jr z,.updateMenuVariables
	ld b,13
	inc hl
.updateMenuVariables
	add b
	ld [wTopMenuItemY],a
	ld a,[hl]
	ld [wTopMenuItemX],a
	call PlaceUnfilledArrowMenuCursor
	jp .loop
.cursorInBattleAnimation
	ld a,[$cd3e] ; battle animation cursor X coordinate
	xor a,$0b ; toggle between 1 and 10
	ld [$cd3e],a
	jp .eraseOldMenuCursor
.cursorInBattleStyle
	ld a,[$cd3f] ; battle style cursor X coordinate
	xor a,$0b ; toggle between 1 and 10
	ld [$cd3f],a
	jp .eraseOldMenuCursor
.pressedLeftInTextSpeed
	ld a,[$cd3d] ; text speed cursor X coordinate
	cp a,1
	jr z,.updateTextSpeedXCoord
	cp a,7
	jr nz,.fromSlowToMedium
	sub a,6
	jr .updateTextSpeedXCoord
.fromSlowToMedium
	sub a,7
	jr .updateTextSpeedXCoord
.pressedRightInTextSpeed
	ld a,[$cd3d] ; text speed cursor X coordinate
	cp a,14
	jr z,.updateTextSpeedXCoord
	cp a,7
	jr nz,.fromFastToMedium
	add a,7
	jr .updateTextSpeedXCoord
.fromFastToMedium
	add a,6
.updateTextSpeedXCoord
	ld [$cd3d],a ; text speed cursor X coordinate
	jp .eraseOldMenuCursor

TextSpeedOptionText: ; 5fc0 (1:5fc0)
	db   "TEXT SPEED"
	next " FAST  MEDIUM SLOW@"

BattleAnimationOptionText: ; 5fde (1:5fde)
	db   "BATTLE ANIMATION"
	next " ON       OFF@"

BattleStyleOptionText: ; 5ffd (1:5ffd)
	db   "BATTLE STYLE"
	next " SHIFT    SET@"

OptionMenuCancelText: ; 6018 (1:6018)
	db "CANCEL@"

; sets the options variable according to the current placement of the menu cursors in the options menu
SetOptionsFromCursorPositions: ; 601f (1:601f)
	ld hl,TextSpeedOptionData
	ld a,[$cd3d] ; text speed cursor X coordinate
	ld c,a
.loop
	ld a,[hli]
	cp c
	jr z,.textSpeedMatchFound
	inc hl
	jr .loop
.textSpeedMatchFound
	ld a,[hl]
	ld d,a
	ld a,[$cd3e] ; battle animation cursor X coordinate
	dec a
	jr z,.battleAnimationOn
.battleAnimationOff
	set 7,d
	jr .checkBattleStyle
.battleAnimationOn
	res 7,d
.checkBattleStyle
	ld a,[$cd3f] ; battle style cursor X coordinate
	dec a
	jr z,.battleStyleShift
.battleStyleSet
	set 6,d
	jr .storeOptions
.battleStyleShift
	res 6,d
.storeOptions
	ld a,d
	ld [W_OPTIONS],a
	ret

; reads the options variable and places menu cursors in the correct positions within the options menu
SetCursorPositionsFromOptions: ; 604c (1:604c)
	ld hl,TextSpeedOptionData + 1
	ld a,[W_OPTIONS]
	ld c,a
	and a,$3f
	push bc
	ld de,2
	call IsInArray
	pop bc
	dec hl
	ld a,[hl]
	ld [$cd3d],a ; text speed cursor X coordinate
	FuncCoord 0,3
	ld hl,Coord
	call .placeUnfilledRightArrow
	sla c
	ld a,1 ; On
	jr nc,.storeBattleAnimationCursorX
	ld a,10 ; Off
.storeBattleAnimationCursorX
	ld [$cd3e],a ; battle animation cursor X coordinate
	FuncCoord 0,8
	ld hl,Coord
	call .placeUnfilledRightArrow
	sla c
	ld a,1
	jr nc,.storeBattleStyleCursorX
	ld a,10
.storeBattleStyleCursorX
	ld [$cd3f],a ; battle style cursor X coordinate
	FuncCoord 0,13
	ld hl,Coord
	call .placeUnfilledRightArrow
; cursor in front of Cancel
	FuncCoord 0,16
	ld hl,Coord
	ld a,1
.placeUnfilledRightArrow
	ld e,a
	ld d,0
	add hl,de
	ld [hl],$ec ; unfilled right arrow menu cursor
	ret

; table that indicates how the 3 text speed options affect frame delays
; Format:
; 00: X coordinate of menu cursor
; 01: delay after printing a letter (in frames)
TextSpeedOptionData: ; 6096 (1:6096)
	db 14,5 ; Slow
	db  7,3 ; Medium
	db  1,1 ; Fast
	db 7 ; default X coordinate (Medium)
	db $ff ; terminator

Func_609e: ; 609e (1:609e)
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	ld [$4000], a
	ld b, $b
	ld hl, $a598
.asm_60b0
	ld a, [hli]
	cp $50
	jr z, .asm_60c1
	dec b
	jr nz, .asm_60b0
	xor a
	ld [$0], a
	ld [$6000], a
	and a
	ret
.asm_60c1
	xor a
	ld [$0], a
	ld [$6000], a
	scf
	ret

SetDefaultNames: ; 60ca (1:60ca)
	ld a, [$d358]
	push af
	ld a, [W_OPTIONS] ; $d355
	push af
	ld a, [$d732]
	push af
	ld hl, W_PLAYERNAME ; $d158
	ld bc, $d8a
	xor a
	call FillMemory
	ld hl, wSpriteStateData1
	ld bc, $200
	xor a
	call FillMemory
	pop af
	ld [$d732], a
	pop af
	ld [W_OPTIONS], a ; $d355
	pop af
	ld [$d358], a
	ld a, [$d08a]
	and a
	call z, Func_5bff
	ld hl, NintenText
	ld de, W_PLAYERNAME ; $d158
	ld bc, $b
	call CopyData
	ld hl, SonyText
	ld de, W_RIVALNAME ; $d34a
	ld bc, $b
	jp CopyData

OakSpeech: ; 6115 (1:6115)
	ld a,$FF
	call PlaySound ; stop music
	ld a, BANK(Music_Routes2) ; bank of song
	ld c,a
	ld a, MUSIC_ROUTES2 ; song #
	call PlayMusic  ; plays music
	call ClearScreen
	call LoadTextBoxTilePatterns
	call SetDefaultNames
	ld a,$18
	call Predef ; indirect jump to InitializePlayerData
	ld hl,$D53A
	ld a,POTION
	ld [$CF91],a
	ld a,1
	ld [$CF96],a
	call AddItemToInventory  ; give one potion
	ld a,[$D07C]
	ld [$D71A],a
	call Func_62ce
	xor a
	ld [$FFD7],a
	ld a,[$D732]
	bit 1,a ; XXX when is bit 1 set?
	jp nz,Func_61bc ; easter egg: skip the intro
	ld de,ProfOakPic
	ld bc, (Bank(ProfOakPic) << 8) | $00
	call IntroPredef3B   ; displays Oak pic?
	call FadeInIntroPic
	ld hl,OakSpeechText1
	call PrintText      ; prints text box
	call GBFadeOut2
	call ClearScreen
	ld a,NIDORINO
	ld [$D0B5],a    ; pic displayed is stored at this location
	ld [$CF91],a
	call GetMonHeader      ; this is also related to the pic
	FuncCoord 6, 4 ; $c3f6
	ld hl,Coord     ; position on tilemap the pic is displayed
	call LoadFlippedFrontSpriteByMonIndex      ; displays pic?
	call MovePicLeft
	ld hl,OakSpeechText2
	call PrintText      ; Prints text box
	call GBFadeOut2
	call ClearScreen
	ld de,RedPicFront
	ld bc,(Bank(RedPicFront) << 8) | $00
	call IntroPredef3B      ; displays player pic?
	call MovePicLeft
	ld hl,IntroducePlayerText
	call PrintText
	call LoadDefaultNamesPlayer ; brings up NewName/Red/etc menu
	call GBFadeOut2
	call ClearScreen
	ld de,Rival1Pic
	ld bc,(Bank(Rival1Pic) << 8) | $00
	call IntroPredef3B ; displays rival pic
	call FadeInIntroPic
	ld hl,IntroduceRivalText
	call PrintText
	call LoadDefaultNamesRival

Func_61bc: ; 61bc (1:61bc)
	call GBFadeOut2
	call ClearScreen
	ld de,RedPicFront
	ld bc,(Bank(RedPicFront) << 8) | $00
	call IntroPredef3B
	call GBFadeIn2
	ld a,[$D72D]
	and a
	jr nz,.next
	ld hl,OakSpeechText3
	call PrintText
.next
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,(SFX_02_48 - SFX_Headers_02) / 3
	call PlaySound
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ld c,4
	call DelayFrames
	ld de,RedSprite ; $4180
	ld hl,$8000
	ld bc,(BANK(RedSprite) << 8) | $0C
	call CopyVideoData
	ld de,ShrinkPic1
	ld bc,(BANK(ShrinkPic1) << 8) | $00
	call IntroPredef3B
	ld c,4
	call DelayFrames
	ld de,ShrinkPic2
	ld bc,(BANK(ShrinkPic2) << 8) | $00
	call IntroPredef3B
	call ResetPlayerSpriteData
	ld a,[H_LOADEDROMBANK]
	push af
	ld a,2
	ld [$C0EF],a
	ld [$C0F0],a
	ld a,$A
	ld [wMusicHeaderPointer],a
	ld a,$FF
	ld [$C0EE],a
	call PlaySound ; stop music
	pop af
	ld [H_LOADEDROMBANK],a
	ld [$2000],a
	ld c,$14
	call DelayFrames
	FuncCoord 6, 5 ; $c40a
	ld hl,Coord
	ld b,7
	ld c,7
	call ClearScreenArea
	call LoadTextBoxTilePatterns
	ld a,1
	ld [$CFCB],a
	ld c,$32
	call DelayFrames
	call GBFadeOut2
	jp ClearScreen
OakSpeechText1: ; 6253 (1:6253)
	TX_FAR _OakSpeechText1
	db "@"
OakSpeechText2: ; 6258 (1:6258)
	TX_FAR _OakSpeechText2A
	db $14 ; play NIDORINA cry from TextCommandSounds
	TX_FAR _OakSpeechText2B
	db "@"
IntroducePlayerText: ; 6262 (1:6262)
	TX_FAR _IntroducePlayerText
	db "@"
IntroduceRivalText: ; 6267 (1:6267)
	TX_FAR _IntroduceRivalText
	db "@"
OakSpeechText3: ; 626c (1:626c)
	TX_FAR _OakSpeechText3
	db "@"

FadeInIntroPic: ; 6271 (1:6271)
	ld hl,IntroFadePalettes
	ld b,6
.next
	ld a,[hli]
	ld [rBGP],a
	ld c,10
	call DelayFrames
	dec b
	jr nz,.next
	ret

IntroFadePalettes: ; 6282 (1:6282)
	db %01010100
	db %10101000
	db %11111100
	db %11111000
	db %11110100
	db %11100100

MovePicLeft: ; 6288 (1:6288)
	ld a,119
	ld [$FF4B],a
	call DelayFrame

	ld a,$E4
	ld [rBGP],a
.next
	call DelayFrame
	ld a,[$FF4B]
	sub 8
	cp $FF
	ret z
	ld [$FF4B],a
	jr .next

Predef3B: ; 62a1 (1:62a1)
	call Load16BitRegisters
IntroPredef3B: ; 62a4 (1:62a4)
; bank of sprite given in b
	push bc
	ld a,b
	call UncompressSpriteFromDE
	ld hl,S_SPRITEBUFFER1
	ld de,$A000
	ld bc,$0310
	call CopyData
	ld de,$9000
	call InterlaceMergeSpriteBuffers
	pop bc
	ld a,c
	and a
	FuncCoord 15, 1 ; $c3c3
	ld hl,Coord
	jr nz,.next
	FuncCoord 6, 4 ; $c3f6
	ld hl,Coord
.next
	xor a
	ld [$FFE1],a
	ld a,1
	jp Predef

Func_62ce: ; 62ce (1:62ce)
	call Func_62ff
	ld a,$19
	call Predef
	ld hl,$D732
	bit 2,[hl]
	res 2,[hl]
	jr z,.next
	ld a,[$D71A]
	jr .next2
.next
	bit 1,[hl]
	jr z,.next3
	call Func_64ea
.next3
	ld a,0
.next2
	ld b,a
	ld a,[$D72D]
	and a
	jr nz,.next4
	ld a,b
.next4
	ld hl,$D732
	bit 4,[hl]
	ret nz
	ld [wLastMap],a
	ret

Func_62ff: ; 62ff (1:62ff)
	ld a, [$d72d]
	cp BATTLE_CENTER
	jr nz, .asm_6314
	ld hl, BattleCenterSpec1 ; $6428
	ld a, [$ffaa]
	cp $2
	jr z, .asm_6334
	ld hl, BattleCenterSpec2 ; $6430
	jr .asm_6334
.asm_6314
	cp TRADE_CENTER
	jr nz, .asm_6326
	ld hl, TradeCenterSpec1 ; $6438
	ld a, [$ffaa]
	cp $2
	jr z, .asm_6334
	ld hl, TradeCenterSpec2 ; $6440
	jr .asm_6334
.asm_6326
	ld a, [$d732]
	bit 1, a
	jr nz, .asm_6346
	bit 2, a
	jr nz, .asm_6346
	ld hl, FirstMapSpec ; $6420
.asm_6334
	ld de, W_CURMAP ; $d35e
	ld c, $7
.asm_6339
	ld a, [hli]
	ld [de], a
	inc de
	dec c
	jr nz, .asm_6339
	ld a, [hli]
	ld [W_CURMAPTILESET], a ; $d367
	xor a
	jr .asm_63b3
.asm_6346
	ld a, [wLastMap]
	ld hl, $d732
	bit 4, [hl]
	jr nz, .asm_635b
	bit 6, [hl]
	res 6, [hl]
	jr z, .asm_638e
	ld a, [wLastBlackoutMap]
	jr .asm_6391
.asm_635b
	ld hl, $d72d
	res 4, [hl]
	ld a, [$d71d]
	ld b, a
	ld [W_CURMAP], a ; $d35e
	ld a, [$d71e]
	ld c, a
	ld hl, DungeonWarpList ; $63bf
	ld de, $0
	ld a, $6
	ld [$d12f], a
.asm_6376
	ld a, [hli]
	cp b
	jr z, .asm_637d
	inc hl
	jr .asm_6381
.asm_637d
	ld a, [hli]
	cp c
	jr z, .asm_6388
.asm_6381
	ld a, [$d12f]
	add e
	ld e, a
	jr .asm_6376
.asm_6388
	ld hl, DungeonWarpData ; $63d8
	add hl, de
	jr .asm_63a4
.asm_638e
	ld a, [$d71a]
.asm_6391
	ld b, a
	ld [W_CURMAP], a ; $d35e
	ld hl, FlyWarpDataPtr ; $6448
.asm_6398
	ld a, [hli]
	inc hl
	cp b
	jr z, .asm_63a1
	inc hl
	inc hl
	jr .asm_6398
.asm_63a1
	ld a, [hli]
	ld h, [hl]
	ld l, a
.asm_63a4
	ld de, $d35f
	ld c, $6
.asm_63a9
	ld a, [hli]
	ld [de], a
	inc de
	dec c
	jr nz, .asm_63a9
	xor a
	ld [W_CURMAPTILESET], a ; $d367
.asm_63b3
	ld [$d4e2], a
	ld [$d4e3], a
	ld a, $ff
	ld [$d42f], a
	ret

INCLUDE "data/special_warps.asm"

; This function appears to never be used.
; It is likely a debugging feature to give the player Tsunekazu Ishihara's
; favorite Pokemon. This is indicated by the overpowered Exeggutor, which
; Ishihara (president of Creatures Inc.) said was his favorite Pokemon in an ABC
; interview on February 8, 2000.
; "Exeggutor is my favorite. That's because I was always using this character
; while I was debugging the program."
; http://www.ign.com/articles/2000/02/09/abc-news-pokamon-chat-transcript

SetIshiharaTeam: ; 64ca (1:64ca)
	ld de, IshiharaTeam
.loop
	ld a, [de]
	cp $ff
	ret z
	ld [$cf91], a
	inc de
	ld a, [de]
	ld [W_CURENEMYLVL], a
	inc de
	call AddPokemonToParty
	jr .loop

IshiharaTeam: ; 64df (1:64df)
	db EXEGGUTOR,90
	db MEW,20
	db JOLTEON,56
	db DUGTRIO,56
	db ARTICUNO,57
	db $FF

Func_64ea: ; 64ea (1:64ea)
	ret

AskForMonNickname: ; 64eb (1:64eb)
	call SaveScreenTilesToBuffer1
	call Load16BitRegisters
	push hl
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	ld hl, wTileMap
	ld b, $4
	ld c, $b
	call z, ClearScreenArea ; only if in wild batle
	ld a, [$cf91]
	ld [$d11e], a
	call GetMonName
	ld hl, DoYouWantToNicknameText
	call PrintText
	FuncCoord 14, 7 ; $c43a
	ld hl, Coord
	ld bc, $80f
	ld a, $14
	ld [$d125], a
	call DisplayTextBoxID
	pop hl
	ld a, [wCurrentMenuItem] ; $cc26
	and a
	jr nz, .asm_654c
	ld a, [$cfcb]
	push af
	xor a
	ld [$cfcb], a
	push hl
	ld a, $2
	ld [$d07d], a
	call DisplayNamingScreen
	ld a, [W_ISINBATTLE] ; $d057
	and a
	jr nz, .asm_653e
	call Func_3e08
.asm_653e
	call LoadScreenTilesFromBuffer1
	pop hl
	pop af
	ld [$cfcb], a
	ld a, [$cf4b]
	cp $50
	ret nz
.asm_654c
	ld d, h
	ld e, l
	ld hl, $cd6d
	ld bc, $000b
	jp CopyData

DoYouWantToNicknameText: ; 0x6557
	TX_FAR _DoYouWantToNicknameText
	db "@"

Func_655c: ; 655c (1:655c)
	ld hl, $cee9
	xor a
	ld [$cfcb], a
	ld a, $2
	ld [$d07d], a
	call DisplayNamingScreen
	call GBPalWhiteOutWithDelay3
	call Func_3dbe
	call LoadGBPal
	ld a, [$cf4b]
	cp $50
	jr z, .asm_6594
	ld hl, W_PARTYMON1NAME ; $d2b5
	ld bc, $b
	ld a, [wWhichPokemon] ; $cf92
	call AddNTimes
	ld e, l
	ld d, h
	ld hl, $cee9
	ld bc, $b
	call CopyData
	and a
	ret
.asm_6594
	scf
	ret

DisplayNamingScreen: ; 6596 (1:6596)
	push hl
	ld hl, $d730
	set 6, [hl]
	call GBPalWhiteOutWithDelay3
	call ClearScreen
	call UpdateSprites
	ld b, $8
	call GoPAL_SET
	call LoadHpBarAndStatusTilePatterns
	call LoadEDTile
	callba Func_7176c
	FuncCoord 0, 4 ; $c3f0
	ld hl, Coord
	ld b, $9
	ld c, $12
	call TextBoxBorder
	call PrintNamingText
	ld a, $3
	ld [wTopMenuItemY], a ; $cc24
	ld a, $1
	ld [wTopMenuItemX], a ; $cc25
	ld [wLastMenuItem], a ; $cc2a
	ld [wCurrentMenuItem], a ; $cc26
	ld a, $ff
	ld [wMenuWatchedKeys], a ; $cc29
	ld a, $7
	ld [wMaxMenuItem], a ; $cc28
	ld a, $50
	ld [$cf4b], a
	xor a
	ld hl, $ceea
	ld [hli], a
	ld [hli], a
	ld [W_SUBANIMTRANSFORM], a ; $d08b
.asm_65ed
	call PrintAlphabet
	call GBPalNormal
.asm_65f3
	ld a, [$ceea]
	and a
	jr nz, .asm_662d
	call Func_680e
.asm_65fc
	call PlaceMenuCursor
.asm_65ff
	ld a, [wCurrentMenuItem] ; $cc26
	push af
	callba AnimatePartyMon_ForceSpeed1
	pop af
	ld [wCurrentMenuItem], a ; $cc26
	call GetJoypadStateLowSensitivity
	ld a, [H_NEWLYPRESSEDBUTTONS]
	and a
	jr z, .asm_65ff
	ld hl, .unknownPointerTable_665e ; $665e
.asm_661a
	sla a
	jr c, .asm_6624
	inc hl
	inc hl
	inc hl
	inc hl
	jr .asm_661a
.asm_6624
	ld a, [hli]
	ld e, a
	ld a, [hli]
	ld d, a
	ld a, [hli]
	ld h, [hl]
	ld l, a
	push de
	jp [hl]
.asm_662d
	pop de
	ld hl, $cf4b
	ld bc, $b
	call CopyData
	call GBPalWhiteOutWithDelay3
	call ClearScreen
	call CleanLCD_OAM
	call GoPAL_SET_CF1C
	call GBPalNormal
	xor a
	ld [W_SUBANIMTRANSFORM], a ; $d08b
	ld hl, $d730
	res 6, [hl]
	ld a, [W_ISINBATTLE] ; $d057
	and a
	jp z, LoadTextBoxTilePatterns
	ld hl, Func_3ee5b
	ld b, BANK(Func_3ee5b)
	jp Bankswitch

.unknownPointerTable_665e: ; 665e (1:665e)
	dw .asm_65fc
	dw .asm_673e
	dw .asm_65fc
	dw .asm_672c
	dw .asm_65fc
	dw .asm_6718
	dw .asm_65fc
	dw .asm_6702
	dw .asm_65f3
	dw .asm_668c
	dw .asm_65ed
	dw .asm_6683
	dw .asm_65f3
	dw .deleteLetter
	dw .asm_65f3
	dw .asm_6692

.asm_667e
	pop de
	ld de, .asm_65ed ; $65ed
	push de
.asm_6683
	ld a, [$ceeb]
	xor $1
	ld [$ceeb], a
	ret
.asm_668c
	ld a, $1
	ld [$ceea], a
	ret
.asm_6692
	ld a, [wCurrentMenuItem] ; $cc26
	cp $5
	jr nz, .asm_66a0
	ld a, [wTopMenuItemX] ; $cc25
	cp $11
	jr z, .asm_668c
.asm_66a0
	ld a, [wCurrentMenuItem] ; $cc26
	cp $6
	jr nz, .asm_66ae
	ld a, [wTopMenuItemX] ; $cc25
	cp $1
	jr z, .asm_667e
.asm_66ae
	ld hl, wMenuCursorLocation ; $cc30
	ld a, [hli]
	ld h, [hl]
	ld l, a
	inc hl
	ld a, [hl]
	ld [$ceed], a
	call CalcStringLength
	ld a, [$ceed]
	cp $e5
	ld de, Dakutens ; $6885
	jr z, .asm_66e3
	cp $e4
	ld de, Handakutens ; $68d6
	jr z, .asm_66e3
	ld a, [$d07d]
	cp $2
	jr nc, .checkMonNameLength
	ld a, [$cee9]
	cp $7 ; max length of player/rival names
	jr .checkNameLength
.checkMonNameLength
	ld a, [$cee9]
	cp $a ; max length of pokemon nicknames
.checkNameLength
	jr c, .addLetter
	ret
.asm_66e3
	push hl
	call Func_6871
	pop hl
	ret nc
	dec hl
.addLetter
	ld a, [$ceed]
	ld [hli], a
	ld [hl], $50
	ld a, (SFX_02_40 - SFX_Headers_02) / 3
	call PlaySound
	ret
.deleteLetter
	ld a, [$cee9]
	and a
	ret z
	call CalcStringLength
	dec hl
	ld [hl], $50
	ret
.asm_6702
	ld a, [wCurrentMenuItem] ; $cc26
	cp $6
	ret z
	ld a, [wTopMenuItemX] ; $cc25
	cp $11
	jp z, .asm_6714
	inc a
	inc a
	jr .asm_6755
.asm_6714
	ld a, $1
	jr .asm_6755
.asm_6718
	ld a, [wCurrentMenuItem] ; $cc26
	cp $6
	ret z
	ld a, [wTopMenuItemX] ; $cc25
	dec a
	jp z, .asm_6728
	dec a
	jr .asm_6755
.asm_6728
	ld a, $11
	jr .asm_6755
.asm_672c
	ld a, [wCurrentMenuItem] ; $cc26
	dec a
	ld [wCurrentMenuItem], a ; $cc26
	and a
	ret nz
	ld a, $6
	ld [wCurrentMenuItem], a ; $cc26
	ld a, $1
	jr .asm_6755
.asm_673e
	ld a, [wCurrentMenuItem] ; $cc26
	inc a
	ld [wCurrentMenuItem], a ; $cc26
	cp $7
	jr nz, .asm_6750
	ld a, $1
	ld [wCurrentMenuItem], a ; $cc26
	jr .asm_6755
.asm_6750
	cp $6
	ret nz
	ld a, $1
.asm_6755
	ld [wTopMenuItemX], a ; $cc25
	jp EraseMenuCursor

LoadEDTile: ; 675b (1:675b)
	ld de, ED_Tile
	ld hl, $8f00
	ld bc, $1
	jp CopyVideoDataDouble

ED_Tile: ; 6767 (1:6767)
	INCBIN "gfx/ED_tile.1bpp"

PrintAlphabet: ; 676f (1:676f)
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, [$ceeb]
	and a
	ld de, LowerCaseAlphabet ; $679e
	jr nz, .asm_677e
	ld de, UpperCaseAlphabet ; $67d6
.asm_677e
	FuncCoord 2, 5 ; $c406
	ld hl, Coord
	ld bc, $509
.asm_6784
	push bc
.asm_6785
	ld a, [de]
	ld [hli], a
	inc hl
	inc de
	dec c
	jr nz, .asm_6785
	ld bc, $16
	add hl, bc
	pop bc
	dec b
	jr nz, .asm_6784
	call PlaceString
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	jp Delay3

LowerCaseAlphabet: ; 679e (1:679e)
	db "abcdefghijklmnopqrstuvwxyz ×():;[]",$e1,$e2,"-?!♂♀/",$f2,",¥UPPER CASE@"

UpperCaseAlphabet: ; 67d6 (1:67d6)
	db "ABCDEFGHIJKLMNOPQRSTUVWXYZ ×():;[]",$e1,$e2,"-?!♂♀/",$f2,",¥lower case@"

Func_680e: ; 680e (1:680e)
	call CalcStringLength
	ld a, c
	ld [$cee9], a
	FuncCoord 10, 2 ; $c3d2
	ld hl, Coord
	ld bc, $10a
	call ClearScreenArea
	FuncCoord 10, 2 ; $c3d2
	ld hl, Coord
	ld de, $cf4b
	call PlaceString
	FuncCoord 10, 3 ; $c3e6
	ld hl, Coord
	ld a, [$d07d]
	cp $2
	jr nc, .asm_6835
	ld b, $7
	jr .asm_6837
.asm_6835
	ld b, $a
.asm_6837
	ld a, $76
.asm_6839
	ld [hli], a
	dec b
	jr nz, .asm_6839
	ld a, [$d07d]
	cp $2
	ld a, [$cee9]
	jr nc, .asm_684b
	cp $7
	jr .asm_684d
.asm_684b
	cp $a
.asm_684d
	jr nz, .asm_6867
	call EraseMenuCursor
	ld a, $11
	ld [wTopMenuItemX], a ; $cc25
	ld a, $5
	ld [wCurrentMenuItem], a ; $cc26
	ld a, [$d07d]
	cp $2
	ld a, $9
	jr nc, .asm_6867
	ld a, $6
.asm_6867
	ld c, a
	ld b, $0
	FuncCoord 10, 3 ; $c3e6
	ld hl, Coord
	add hl, bc
	ld [hl], $77
	ret

Func_6871: ; 6871 (1:6871)
	push de
	call CalcStringLength
	dec hl
	ld a, [hl]
	pop hl
	ld de, $2
	call IsInArray
	ret nc
	inc hl
	ld a, [hl]
	ld [$ceed], a
	ret

Dakutens: ; 6885 (1:6885)
	db "かが", "きぎ", "くぐ", "けげ", "こご"
	db "さざ", "しじ", "すず", "せぜ", "そぞ"
	db "ただ", "ちぢ", "つづ", "てで", "とど"
	db "はば", "ひび", "ふぶ", "へべ", "ほぼ"
	db "カガ", "キギ", "クグ", "ケゲ", "コゴ"
	db "サザ", "シジ", "スズ", "セゼ", "ソゾ"
	db "タダ", "チヂ", "ツヅ", "テデ", "トド"
	db "ハバ", "ヒビ", "フブ", "へべ", "ホボ"
	db $ff

Handakutens: ; 68d6 (1:68d6)
	db "はぱ", "ひぴ", "ふぷ", "へぺ", "ほぽ"
	db "ハパ", "ヒピ", "フプ", "へぺ", "ホポ"
	db $ff

; calculates the length of the string at $cf4b and stores it in c
CalcStringLength: ; 68eb (1:68eb)
	ld hl, $cf4b
	ld c, $0
.asm_68f0
	ld a, [hl]
	cp $50
	ret z
	inc hl
	inc c
	jr .asm_68f0

PrintNamingText: ; 68f8 (1:68f8)
	FuncCoord 0, 1 ; $c3b4
	ld hl, Coord
	ld a, [$d07d]
	ld de, YourTextString ; $693f
	and a
	jr z, .notNickname
	ld de, RivalsTextString ; $6945
	dec a
	jr z, .notNickname
	ld a, [$cf91]
	ld [$cd5d], a
	push af
	callba Func_71882
	pop af
	ld [$d11e], a
	call GetMonName
	FuncCoord 4, 1 ; $c3b8
	ld hl, Coord
	call PlaceString
	ld hl, $1
	add hl, bc
	ld [hl], $c9
	FuncCoord 1, 3 ; $c3dd
	ld hl, Coord
	ld de, NicknameTextString ; $6953
	jr .placeString
.notNickname
	call PlaceString
	ld l, c
	ld h, b
	ld de, NameTextString ; $694d
.placeString
	jp PlaceString

YourTextString: ; 693f (1:693f)
	db "YOUR @"

RivalsTextString: ; 6945 (1:6945)
	db "RIVAL's @"

NameTextString: ; 694d (1:694d)
	db "NAME?@"

NicknameTextString: ; 6953 (1:6953)
	db "NICKNAME?@"

LoadDefaultNamesPlayer: ; 695d (1:695d)
	call Func_6a12
	ld de, DefaultNamesPlayer ; $6aa8
	call DisplayIntroNameTextBox
	ld a, [wCurrentMenuItem] ; $cc26
	and a
	jr z, .asm_697a
	ld hl, DefaultNamesPlayerList ; $6af2
	call Func_6ad6
	ld de, W_PLAYERNAME ; $d158
	call Func_69ec
	jr .asm_6999
.asm_697a
	ld hl, W_PLAYERNAME ; $d158
	xor a
	ld [$d07d], a
	call DisplayNamingScreen
	ld a, [$cf4b]
	cp $50
	jr z, .asm_697a
	call ClearScreen
	call Delay3
	ld de, RedPicFront ; $6ede
	ld b, BANK(RedPicFront)
	call IntroPredef3B
.asm_6999
	ld hl, YourNameIsText
	jp PrintText

YourNameIsText: ; 699f (1:699f)
	TX_FAR _YourNameIsText
	db "@"

LoadDefaultNamesRival: ; 69a4 (1:69a4)
	call Func_6a12 ; 0x69a4 call 0x6a12
	ld de, DefaultNamesRival
	call DisplayIntroNameTextBox
	ld a, [wCurrentMenuItem] ; $cc26
	and a
	jr z, .asm_69c1
	ld hl, DefaultNamesRivalList
	call Func_6ad6
	ld de, W_RIVALNAME ; $d34a
	call Func_69ec
	jr .asm_69e1
.asm_69c1
	ld hl, W_RIVALNAME ; $d34a
	ld a, $1
	ld [$d07d], a
	call DisplayNamingScreen
	ld a, [$cf4b]
	cp $50
	jr z, .asm_69c1
	call ClearScreen
	call Delay3
	ld de, Rival1Pic ; $6049
	ld b, $13
	call IntroPredef3B
.asm_69e1
	ld hl, HisNameIsText
	jp PrintText

HisNameIsText: ; 69e7 (1:69e7)
	TX_FAR _HisNameIsText
	db "@"

Func_69ec: ; 69ec (1:69ec)
	push de
	ld hl, wTileMap
	ld bc, $c0b
	call ClearScreenArea
	ld c, $a
	call DelayFrames
	pop de
	ld hl, $cd6d
	ld bc, $b
	call CopyData
	call Delay3
	FuncCoord 12, 4 ; $c3fc
	ld hl, Coord
	ld de, $67d
	ld a, $ff
	jr asm_6a19

Func_6a12: ; 6a12 (1:6a12)
	FuncCoord 5, 4 ; $c3f5
	ld hl, Coord
	ld de, $67d
	xor a
asm_6a19: ; 6a19 (1:6a19)
	push hl
	push de
	push bc
	ld [$ff8d], a
	ld a, d
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld a, e
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	ld c, a
	ld a, [$ff8d]
	and a
	jr nz, .asm_6a2d
	ld d, $0
	add hl, de
.asm_6a2d
	ld d, h
	ld e, l
.asm_6a2f
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, [$ff8d]
	and a
	jr nz, .asm_6a3c
	ld a, [hli]
	ld [hld], a
	dec hl
	jr .asm_6a3f
.asm_6a3c
	ld a, [hld]
	ld [hli], a
	inc hl
.asm_6a3f
	dec c
	jr nz, .asm_6a2f
	ld a, [$ff8d]
	and a
	jr z, .asm_6a4a
	xor a
	dec hl
	ld [hl], a
.asm_6a4a
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Delay3
	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
	ld c, a
	ld h, d
	ld l, e
	ld a, [$ff8d]
	and a
	jr nz, .asm_6a5e
	inc hl
	jr .asm_6a5f
.asm_6a5e
	dec hl
.asm_6a5f
	ld d, h
	ld e, l
	ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
	dec a
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	jr nz, .asm_6a2f
	pop bc
	pop de
	pop hl
	ret

DisplayIntroNameTextBox: ; 6a6c (1:6a6c)
	push de
	ld hl, wTileMap
	ld b, $a
	ld c, $9
	call TextBoxBorder
	FuncCoord 3, 0 ; $c3a3
	ld hl, Coord
	ld de, .namestring ; $6aa3
	call PlaceString
	pop de
	FuncCoord 2, 2 ; $c3ca
	ld hl, Coord
	call PlaceString
	call UpdateSprites
	xor a
	ld [wCurrentMenuItem], a ; $cc26
	ld [wLastMenuItem], a ; $cc2a
	inc a
	ld [wTopMenuItemX], a ; $cc25
	ld [wMenuWatchedKeys], a ; $cc29
	inc a
	ld [wTopMenuItemY], a ; $cc24
	inc a
	ld [wMaxMenuItem], a ; $cc28
	jp HandleMenuInput

.namestring ; 6aa3 (1:6aa3)
	db "NAME@"

IF _RED
DefaultNamesPlayer: ; 6aa8 (1:6aa8)
	db   "NEW NAME"
	next "RED"
	next "ASH"
	next "JACK"
	db   "@"

DefaultNamesRival: ; 6abe (1:6abe)
	db   "NEW NAME"
	next "BLUE"
	next "GARY"
	next "JOHN"
	db   "@"
ENDC

IF _BLUE
DefaultNamesPlayer: ; 6aa8 (1:6aa8)
	db   "NEW NAME"
	next "BLUE"
	next "GARY"
	next "JOHN"
	db   "@"

DefaultNamesRival: ; 6abe (1:6abe)
	db   "NEW NAME"
	next "RED"
	next "ASH"
	next "JACK"
	db   "@"
ENDC

Func_6ad6: ; 6ad6 (1:6ad6)
	ld b, a
	ld c, $0
.asm_6ad9
	ld d, h
	ld e, l
.asm_6adb
	ld a, [hli]
	cp $50
	jr nz, .asm_6adb
	ld a, b
	cp c
	jr z, .asm_6ae7
	inc c
	jr .asm_6ad9
.asm_6ae7
	ld h, d
	ld l, e
	ld de, $cd6d
	ld bc, $14
	jp CopyData
IF _RED
DefaultNamesPlayerList: ; 6af2 (1:6af2)
	db "NEW NAME@RED@ASH@JACK@"
DefaultNamesRivalList: ; 6b08 (1:6b08)
	db "NEW NAME@BLUE@GARY@JOHN@"
ENDC
IF _BLUE
DefaultNamesPlayerList: ; 6af2 (1:6af2)
	db "NEW NAME@BLUE@GARY@JOHN@"
DefaultNamesRivalList: ; 6b08 (1:6b08)
	db "NEW NAME@RED@ASH@JACK@"
ENDC

TextTerminator_6b20: ; 6b20 (1:6b20)
	db "@"

; subtracts the amount the player paid from their money
; sets carry flag if there is enough money and unsets carry flag if not
SubtractAmountPaidFromMoney_: ; 6b21 (1:6b21)
	ld de,wPlayerMoney
	ld hl,$ff9f ; total price of items
	ld c,3 ; length of money in bytes
	call StringCmp
	ret c
	ld de,wPlayerMoney + 2
	ld hl,$ffa1 ; total price of items
	ld c,3 ; length of money in bytes
	ld a,$0c
	call Predef ; subtract total price from money
	ld a,$13
	ld [$d125],a
	call DisplayTextBoxID ; redraw money text box
	and a
	ret

HandleItemListSwapping: ; 6b44 (1:6b44)
	ld a,[wListMenuID]
	cp a,ITEMLISTMENU
	jp nz,DisplayListMenuIDLoop ; only rearrange item list menus
	push hl
	ld hl,$cf8b
	ld a,[hli]
	ld h,[hl]
	ld l,a
	inc hl ; hl = beginning of list entries
	ld a,[wCurrentMenuItem]
	ld b,a
	ld a,[wListScrollOffset]
	add b
	add a
	ld c,a
	ld b,0
	add hl,bc ; hl = address of currently selected item entry
	ld a,[hl]
	pop hl
	inc a
	jp z,DisplayListMenuIDLoop ; ignore attempts to swap the Cancel menu item
	ld a,[$cc35] ; ID of item chosen for swapping (counts from 1)
	and a ; has the first item to swap already been chosen?
	jr nz,.swapItems
; if not, set the currently selected item as the first item
	ld a,[wCurrentMenuItem]
	inc a
	ld b,a
	ld a,[wListScrollOffset] ; index of top (visible) menu item within the list
	add b
	ld [$cc35],a ; ID of item chosen for swapping (counts from 1)
	ld c,20
	call DelayFrames
	jp DisplayListMenuIDLoop
.swapItems
	ld a,[wCurrentMenuItem]
	inc a
	ld b,a
	ld a,[wListScrollOffset]
	add b
	ld b,a
	ld a,[$cc35] ; ID of item chosen for swapping (counts from 1)
	cp b ; is the currently selected item the same as the first item to swap?
	jp z,DisplayListMenuIDLoop ; ignore attempts to swap an item with itself
	dec a
	ld [$cc35],a ; ID of item chosen for swapping (counts from 1)
	ld c,20
	call DelayFrames
	push hl
	push de
	ld hl,$cf8b
	ld a,[hli]
	ld h,[hl]
	ld l,a
	inc hl ; hl = beginning of list entries
	ld d,h
	ld e,l ; de = beginning of list entries
	ld a,[wCurrentMenuItem]
	ld b,a
	ld a,[wListScrollOffset]
	add b
	add a
	ld c,a
	ld b,0
	add hl,bc ; hl = address of currently selected item entry
	ld a,[$cc35] ; ID of item chosen for swapping (counts from 1)
	add a
	add e
	ld e,a
	jr nc,.noCarry
	inc d
.noCarry ; de = address of first item to swap
	ld a,[de]
	ld b,a
	ld a,[hli]
	cp b
	jr z,.swapSameItemType
.swapDifferentItems
	ld [$ff95],a ; [$ff95] = second item ID
	ld a,[hld]
	ld [$ff96],a ; [$ff96] = second item quantity
	ld a,[de]
	ld [hli],a ; put first item ID in second item slot
	inc de
	ld a,[de]
	ld [hl],a ; put first item quantity in second item slot
	ld a,[$ff96]
	ld [de],a ; put second item quantity in first item slot
	dec de
	ld a,[$ff95]
	ld [de],a ; put second item ID in first item slot
	xor a
	ld [$cc35],a ; 0 means no item is currently being swapped
	pop de
	pop hl
	jp DisplayListMenuIDLoop
.swapSameItemType
	inc de
	ld a,[hl]
	ld b,a
	ld a,[de]
	add b ; a = sum of both item quantities
	cp a,100 ; is the sum too big for one item slot?
	jr c,.combineItemSlots
; swap enough items from the first slot to max out the second slot if they can't be combined
	sub a,99
	ld [de],a
	ld a,99
	ld [hl],a
	jr .done
.combineItemSlots
	ld [hl],a ; put the sum in the second item slot
	ld hl,$cf8b
	ld a,[hli]
	ld h,[hl]
	ld l,a
	dec [hl] ; decrease the number of items
	ld a,[hl]
	ld [$d12a],a ; update number of items variable
	cp a,1
	jr nz,.skipSettingMaxMenuItemID
	ld [wMaxMenuItem],a ; if the number of items is only one now, update the max menu item ID
.skipSettingMaxMenuItemID
	dec de
	ld h,d
	ld l,e
	inc hl
	inc hl ; hl = address of item after first item to swap
.moveItemsUpLoop ; erase the first item slot and move up all the following item slots to fill the gap
	ld a,[hli]
	ld [de],a
	inc de
	inc a ; reached the $ff terminator?
	jr z,.afterMovingItemsUp
	ld a,[hli]
	ld [de],a
	inc de
	jr .moveItemsUpLoop
.afterMovingItemsUp
	xor a
	ld [wListScrollOffset],a
	ld [wCurrentMenuItem],a
.done
	xor a
	ld [$cc35],a ; 0 means no item is currently being swapped
	pop de
	pop hl
	jp DisplayListMenuIDLoop

DisplayPokemartDialogue_: ; 6c20 (1:6c20)
	ld a,[wListScrollOffset]
	ld [$d07e],a
	call UpdateSprites ; move sprites
	xor a
	ld [$cf0a],a ; flag that is set if something is sold or bought
.loop
	xor a
	ld [wListScrollOffset],a
	ld [wCurrentMenuItem],a
	ld [$cc2f],a
	inc a
	ld [$cf93],a
	ld a,$13
	ld [$d125],a
	call DisplayTextBoxID ; draw money text box
	ld a,$15
	ld [$d125],a
	call DisplayTextBoxID ; do buy/sell/quit menu
	ld hl,$d128 ; pointer to this pokemart's inventory
	ld a,[hli]
	ld l,[hl]
	ld h,a ; hl = address of inventory
	ld a,[$d12e]
	cp a,$02
	jp z,.done
	ld a,[$d12d] ; ID of the chosen menu item
	and a ; buying?
	jp z,.buyMenu
	dec a ; selling?
	jp z,.sellMenu
	dec a ; quitting?
	jp z,.done
.sellMenu
	xor a
	ld [$cf93],a
	ld a,$02
	ld [$d11b],a
	callab Func_39bd5
	ld a,[wNumBagItems]
	and a
	jp z,.bagEmpty
	ld hl,PokemonSellingGreetingText
	call PrintText
	call SaveScreenTilesToBuffer1 ; save screen
.sellMenuLoop
	call LoadScreenTilesFromBuffer1 ; restore saved screen
	ld a,$13
	ld [$d125],a
	call DisplayTextBoxID ; draw money text box
	ld hl,wNumBagItems
	ld a,l
	ld [$cf8b],a
	ld a,h
	ld [$cf8c],a
	xor a
	ld [$cf93],a
	ld [wCurrentMenuItem],a
	ld a,ITEMLISTMENU
	ld [wListMenuID],a
	call DisplayListMenuID
	jp c,.returnToMainPokemartMenu ; if the player closed the menu
.confirmItemSale ; if the player is trying to sell a specific item
	call IsKeyItem ; check if item is unsellable
	ld a,[$d124]
	and a
	jr nz,.unsellableItem
	ld a,[$cf91]
	call IsItemHM
	jr c,.unsellableItem
	ld a,PRICEDITEMLISTMENU
	ld [wListMenuID],a
	ld [$ff8e],a ; halve prices when selling
	call DisplayChooseQuantityMenu
	inc a
	jr z,.sellMenuLoop ; if the player closed the choose quantity menu with the B button
	ld hl,PokemartTellSellPriceText
	ld bc,$0e01
	call PrintText
	FuncCoord 14,7
	ld hl,Coord
	ld bc,$080f
	ld a,$14
	ld [$d125],a
	call DisplayTextBoxID ; yes/no menu
	ld a,[$d12e]
	cp a,$02
	jr z,.sellMenuLoop ; if the player pressed the B button
	ld a,[$d12d] ; ID of the chosen menu item
	dec a
	jr z,.sellMenuLoop ; if the player chose No
.sellItem
	ld a,[$cf0a] ; flag that is set if something is sold or bought
	and a
	jr nz,.skipSettingFlag1
	inc a
	ld [$cf0a],a
.skipSettingFlag1
	call AddAmountSoldToMoney
	ld hl,wNumBagItems
	call RemoveItemFromInventory
	jp .sellMenuLoop
.unsellableItem
	ld hl,PokemartUnsellableItemText
	call PrintText
	jp .returnToMainPokemartMenu
.bagEmpty
	ld hl,PokemartItemBagEmptyText
	call PrintText
	call SaveScreenTilesToBuffer1 ; save screen
	jp .returnToMainPokemartMenu
.buyMenu
	ld a,$01
	ld [$cf93],a
	ld a,$03
	ld [$d11b],a
	callab Func_39bd5
	ld hl,PokemartBuyingGreetingText
	call PrintText
	call SaveScreenTilesToBuffer1 ; save screen
.buyMenuLoop
	call LoadScreenTilesFromBuffer1 ; restore saved screen
	ld a,$13
	ld [$d125],a
	call DisplayTextBoxID ; draw money text box
	ld hl,$cf7b
	ld a,l
	ld [$cf8b],a
	ld a,h
	ld [$cf8c],a
	xor a
	ld [wCurrentMenuItem],a
	inc a
	ld [$cf93],a
	inc a ; a = 2 (PRICEDITEMLISTMENU)
	ld [wListMenuID],a
	call DisplayListMenuID
	jr c,.returnToMainPokemartMenu ; if the player closed the menu
	ld a,$63
	ld [$cf97],a
	xor a
	ld [$ff8e],a
	call DisplayChooseQuantityMenu
	inc a
	jr z,.buyMenuLoop ; if the player closed the choose quantity menu with the B button
	ld a,[$cf91] ; item ID
	ld [$d11e],a ; store item ID for GetItemName
	call GetItemName
	call CopyStringToCF4B ; copy name to $cf4b
	ld hl,PokemartTellBuyPriceText
	call PrintText
	FuncCoord 14,7
	ld hl,Coord
	ld bc,$080f
	ld a,$14
	ld [$d125],a
	call DisplayTextBoxID ; yes/no menu
	ld a,[$d12e]
	cp a,$02
	jp z,.buyMenuLoop ; if the player pressed the B button
	ld a,[$d12d] ; ID of the chosen menu item
	dec a
	jr z,.buyMenuLoop ; if the player chose No
.buyItem
	call .isThereEnoughMoney
	jr c,.notEnoughMoney
	ld hl,wNumBagItems
	call AddItemToInventory
	jr nc,.bagFull
	call SubtractAmountPaidFromMoney
	ld a,[$cf0a] ; flag that is set if something is sold or bought
	and a
	jr nz,.skipSettingFlag2
	ld a,$01
	ld [$cf0a],a
.skipSettingFlag2
	ld a,(SFX_02_5a - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent ; play sound
	call WaitForSoundToFinish ; wait until sound is done playing
	ld hl,PokemartBoughtItemText
	call PrintText
	jp .buyMenuLoop
.returnToMainPokemartMenu
	call LoadScreenTilesFromBuffer1 ; restore save screen
	ld a,$13
	ld [$d125],a
	call DisplayTextBoxID ; draw money text box
	ld hl,PokemartAnythingElseText
	call PrintText
	jp .loop
.isThereEnoughMoney
	ld de,wPlayerMoney
	ld hl,$ff9f ; item price
	ld c,3 ; length of money in bytes
	jp StringCmp
.notEnoughMoney
	ld hl,PokemartNotEnoughMoneyText
	call PrintText
	jr .returnToMainPokemartMenu
.bagFull
	ld hl,PokemartItemBagFullText
	call PrintText
	jr .returnToMainPokemartMenu
.done
	ld hl,PokemartThankYouText
	call PrintText
	ld a,$01
	ld [$cfcb],a
	call UpdateSprites ; move sprites
	ld a,[$d07e]
	ld [wListScrollOffset],a
	ret

PokemartBuyingGreetingText: ; 6e0c (1:6e0c)
	TX_FAR _PokemartBuyingGreetingText
	db "@"

PokemartTellBuyPriceText: ; 6e11 (1:6e11)
	TX_FAR _PokemartTellBuyPriceText
	db "@"

PokemartBoughtItemText: ; 6e16 (1:6e16)
	TX_FAR _PokemartBoughtItemText
	db "@"

PokemartNotEnoughMoneyText: ; 6e1b (1:6e1b)
	TX_FAR _PokemartNotEnoughMoneyText
	db "@"

PokemartItemBagFullText: ; 6e20 (1:6e20)
	TX_FAR _PokemartItemBagFullText
	db "@"

PokemonSellingGreetingText: ; 6e25 (1:6e25)
	TX_FAR _PokemonSellingGreetingText
	db "@"

PokemartTellSellPriceText: ; 6e2a (1:6e2a)
	TX_FAR _PokemartTellSellPriceText
	db "@"

PokemartItemBagEmptyText: ; 6e2f (1:6e2f)
	TX_FAR _PokemartItemBagEmptyText
	db "@"

PokemartUnsellableItemText: ; 6e34 (1:6e34)
	TX_FAR _PokemartUnsellableItemText
	db "@"

PokemartThankYouText: ; 6e39 (1:6e39)
	TX_FAR _PokemartThankYouText
	db "@"

PokemartAnythingElseText: ; 6e3e (1:6e3e)
	TX_FAR _PokemartAnythingElseText
	db "@"

LearnMove: ; 6e43 (1:6e43)
	call SaveScreenTilesToBuffer1
	ld a, [wWhichPokemon] ; $cf92
	ld hl, W_PARTYMON1NAME ; $d2b5
	call GetPartyMonName
	ld hl, $cd6d
	ld de, $d036
	ld bc, $b
	call CopyData

DontAbandonLearning: ; 6e5b (1:6e5b)
	ld hl, W_PARTYMON1_MOVE1 ; $d173
	ld bc, $2c
	ld a, [wWhichPokemon] ; $cf92
	call AddNTimes
	ld d, h
	ld e, l
	ld b, $4
.asm_6e6b
	ld a, [hl]
	and a
	jr z, .asm_6e8b
	inc hl
	dec b
	jr nz, .asm_6e6b
	push de
	call TryingToLearn
	pop de
	jp c, AbandonLearning
	push hl
	push de
	ld [$d11e], a
	call GetMoveName
	ld hl, OneTwoAndText
	call PrintText
	pop de
	pop hl
.asm_6e8b
	ld a, [$d0e0]
	ld [hl], a
	ld bc, $15
	add hl, bc
	push hl
	push de
	dec a
	ld hl, Moves ; $4000
	ld bc, $6
	call AddNTimes
	ld de, $cee9
	ld a, BANK(Moves)
	call FarCopyData
	ld a, [$ceee]
	pop de
	pop hl
	ld [hl], a
	ld a, [W_ISINBATTLE] ; $d057
	and a
	jp z, PrintLearnedMove
	ld a, [wWhichPokemon] ; $cf92
	ld b, a
	ld a, [wPlayerMonNumber] ; $cc2f
	cp b
	jp nz, PrintLearnedMove
	ld h, d
	ld l, e
	ld de, W_PLAYERMONMOVES
	ld bc, $4
	call CopyData
	ld bc, $11
	add hl, bc
	ld de, W_PLAYERMONPP ; $d02d
	ld bc, $4
	call CopyData
	jp PrintLearnedMove

AbandonLearning: ; 6eda (1:6eda)
	ld hl, AbandonLearningText
	call PrintText
	FuncCoord 14, 7 ; $c43a
	ld hl, Coord
	ld bc, $80f
	ld a, $14
	ld [$d125], a
	call DisplayTextBoxID
	ld a, [wCurrentMenuItem] ; $cc26
	and a
	jp nz, DontAbandonLearning
	ld hl, DidNotLearnText
	call PrintText
	ld b, $0
	ret

PrintLearnedMove: ; 6efe (1:6efe)
	ld hl, LearnedMove1Text
	call PrintText
	ld b, $1
	ret

TryingToLearn: ; 6f07 (1:6f07)
	push hl
	ld hl, TryingToLearnText
	call PrintText
	FuncCoord 14, 7 ; $c43a
	ld hl, Coord
	ld bc, $80f
	ld a, $14
	ld [$d125], a
	call DisplayTextBoxID
	pop hl
	ld a, [wCurrentMenuItem] ; $cc26
	rra
	ret c
	ld bc, $fffc
	add hl, bc
	push hl
	ld de, $d0dc
	ld bc, $4
	call CopyData
	callab Func_39b87
	pop hl
.asm_6f39
	push hl
	ld hl, WhichMoveToForgetText
	call PrintText
	FuncCoord 4, 7 ; $c430
	ld hl, Coord
	ld b, $4
	ld c, $e
	call TextBoxBorder
	FuncCoord 6, 8 ; $c446
	ld hl, Coord
	ld de, $d0e1
	ld a, [$fff6]
	set 2, a
	ld [$fff6], a
	call PlaceString
	ld a, [$fff6]
	res 2, a
	ld [$fff6], a
	ld hl, wTopMenuItemY ; $cc24
	ld a, $8
	ld [hli], a
	ld a, $5
	ld [hli], a
	xor a
	ld [hli], a
	inc hl
	ld a, [$cd6c]
	ld [hli], a
	ld a, $3
	ld [hli], a
	ld [hl], $0
	ld hl, $fff6
	set 1, [hl]
	call HandleMenuInput
	ld hl, $fff6
	res 1, [hl]
	push af
	call LoadScreenTilesFromBuffer1
	pop af
	pop hl
	bit 1, a
	jr nz, .asm_6fab
	push hl
	ld a, [wCurrentMenuItem] ; $cc26
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]
	push af
	push bc
	call IsMoveHM
	pop bc
	pop de
	ld a, d
	jr c, .asm_6fa2
	pop hl
	add hl, bc
	and a
	ret
.asm_6fa2
	ld hl, HMCantDeleteText
	call PrintText
	pop hl
	jr .asm_6f39
.asm_6fab
	scf
	ret

LearnedMove1Text: ; 6fb4 (1:6fb4)
	TX_FAR _LearnedMove1Text
	db $b,6,"@"

WhichMoveToForgetText: ; 6fb4 (1:6fb4)
	TX_FAR _WhichMoveToForgetText
	db "@"

AbandonLearningText: ; 6fb9 (1:6fb9)
	TX_FAR _AbandonLearningText
	db "@"

DidNotLearnText: ; 6fbe (1:6fbe)
	TX_FAR _DidNotLearnText
	db "@"

TryingToLearnText: ; 6fc3 (1:6fc3)
	TX_FAR _TryingToLearnText
	db "@"

OneTwoAndText: ; 6fc8 (1:6fc8)
	TX_FAR _OneTwoAndText
	db $a
	db $8
	ld a, (SFX_02_58 - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent
	ld hl, PoofText
	ret

PoofText: ; 6fd7 (1:6fd7)
	TX_FAR _PoofText
	db $a
ForgotAndText: ; 6fdc (1:6fdc)
	TX_FAR _ForgotAndText
	db "@"

HMCantDeleteText: ; 6fe1 (1:6fe1)
	TX_FAR _HMCantDeleteText
	db "@"

DisplayPokemonCenterDialogue_: ; 6fe6 (1:6fe6)
	call SaveScreenTilesToBuffer1 ; save screen
	ld hl, PokemonCenterWelcomeText
	call PrintText
	ld hl, $d72e
	bit 2, [hl]
	set 1, [hl]
	set 2, [hl]
	jr nz, .skipShallWeHealYourPokemon
	ld hl, ShallWeHealYourPokemonText
	call PrintText
.skipShallWeHealYourPokemon
	call YesNoChoicePokeCenter ; yes/no menu
	ld a, [wCurrentMenuItem]
	and a
	jr nz, .declinedHealing ; if the player chose No
	call SetLastBlackoutMap
	call LoadScreenTilesFromBuffer1 ; restore screen
	ld hl, NeedYourPokemonText
	call PrintText
	ld a, $18
	ld [$c112], a ; make the nurse turn to face the machine
	call Delay3
	PREDEF HealPartyPredef
	callba AnimateHealingMachine ; do the healing machine animation
	xor a
	ld [wMusicHeaderPointer], a
	ld a, [$c0f0]
	ld [$c0ef], a
	ld a, [$d35b]
	ld [$cfca], a
	ld [$c0ee], a
	call PlaySound
	ld hl, PokemonFightingFitText
	call PrintText
	ld a, $14
	ld [$c112], a ; make the nurse bow
	ld c, a
	call DelayFrames
	jr .done
.declinedHealing
	call LoadScreenTilesFromBuffer1 ; restore screen
.done
	ld hl, PokemonCenterFarewellText
	call PrintText
	jp UpdateSprites ; move sprites

PokemonCenterWelcomeText: ; 705d (1:705d)
	TX_FAR _PokemonCenterWelcomeText
	db "@"

ShallWeHealYourPokemonText: ; 7062 (1:7062)
	db $a
	TX_FAR _ShallWeHealYourPokemonText
	db "@"

NeedYourPokemonText: ; 7068 (1:7068)
	TX_FAR _NeedYourPokemonText
	db "@"

PokemonFightingFitText: ; 706d (1:706d)
	TX_FAR _PokemonFightingFitText
	db "@"

PokemonCenterFarewellText: ; 7072 (1:7072)
	db $a
	TX_FAR _PokemonCenterFarewellText
	db "@"

SetLastBlackoutMap:
; Set the map to return to when
; blacking out or using Teleport or Dig.
; Safari rest houses don't count.

	push hl
	ld hl, SafariZoneRestHouses
	ld a, [W_CURMAP]
	ld b, a
.loop
	ld a, [hli]
	cp -1
	jr z, .notresthouse
	cp b
	jr nz, .loop
	jr .done

.notresthouse
	ld a, [wLastMap]
	ld [wLastBlackoutMap], a
.done
	pop hl
	ret

SafariZoneRestHouses:
	db SAFARI_ZONE_REST_HOUSE_2
	db SAFARI_ZONE_REST_HOUSE_3
	db SAFARI_ZONE_REST_HOUSE_4
	db -1

; function that performs initialization for DisplayTextID
DisplayTextIDInit: ; 7096 (1:7096)
	xor a
	ld [$cf94],a
	ld a,[$cf0c]
	bit 0,a
	jr nz,.skipDrawingTextBoxBorder
	ld a,[$ff8c] ; text ID (or sprite ID)
	and a
	jr nz,.notStartMenu
; if text ID is 0 (i.e. the start menu)
; Note that the start menu text border is also drawn in the function directly
; below this, so this seems unnecessary.
	ld a,[$d74b]
	bit 5,a ; does the player have the pokedex?
; start menu with pokedex
	FuncCoord 10, 0 ; $c3aa
	ld hl,Coord
	ld b,$0e
	ld c,$08
	jr nz,.drawTextBoxBorder
; start menu without pokedex
	FuncCoord 10, 0 ; $c3aa
	ld hl,Coord
	ld b,$0c
	ld c,$08
	jr .drawTextBoxBorder
; if text ID is not 0 (i.e. not the start menu) then do a standard dialogue text box
.notStartMenu
	FuncCoord 0, 12 ; $c490
	ld hl,Coord
	ld b,$04
	ld c,$12
.drawTextBoxBorder
	call TextBoxBorder
.skipDrawingTextBoxBorder
	ld hl,$cfc4
	set 0,[hl]
	ld hl,wFlags_0xcd60
	bit 4,[hl]
	res 4,[hl]
	jr nz,.skipMovingSprites
	call UpdateSprites ; move sprites
.skipMovingSprites
; loop to copy C1X9 (direction the sprite is facing) to C2X9 for each sprite
; this is done because when you talk to an NPC, they turn to look your way
; the original direction they were facing must be restored after the dialogue is over
	ld hl,$c119
	ld c,$0f
	ld de,$0010
.spriteFacingDirectionCopyLoop
	ld a,[hl]
	inc h
	ld [hl],a
	dec h
	add hl,de
	dec c
	jr nz,.spriteFacingDirectionCopyLoop
; loop to force all the sprites in the middle of animation to stand still
; (so that they don't like they're frozen mid-step during the dialogue)
	ld hl,$c102
	ld de,$0010
	ld c,e
.spriteStandStillLoop
	ld a,[hl]
	cp a,$ff ; is the sprite visible?
	jr z,.nextSprite
; if it is visible
	and a,$fc
	ld [hl],a
.nextSprite
	add hl,de
	dec c
	jr nz,.spriteStandStillLoop
	ld b,$9c ; window background address
	call CopyScreenTileBufferToVRAM ; transfer background in WRAM to VRAM
	xor a
	ld [$ffb0],a ; put the window on the screen
	call LoadFontTilePatterns
	ld a,$01
	ld [H_AUTOBGTRANSFERENABLED],a ; enable continuous WRAM to VRAM transfer each V-blank
	ret

; function that displays the start menu
DrawStartMenu: ; 710b (1:710b)
	ld a,[$d74b]
	bit 5,a ; does the player have the pokedex?
; menu with pokedex
	FuncCoord 10, 0 ; $c3aa
	ld hl,Coord
	ld b,$0e
	ld c,$08
	jr nz,.drawTextBoxBorder
; shorter menu if the player doesn't have the pokedex
	FuncCoord 10, 0 ; $c3aa
	ld hl,Coord
	ld b,$0c
	ld c,$08
.drawTextBoxBorder
	call TextBoxBorder
	ld a,%11001011 ; bit mask for down, up, start, B, and A buttons
	ld [$cc29],a
	ld a,$02
	ld [$cc24],a ; Y position of first menu choice
	ld a,$0b
	ld [$cc25],a ; X position of first menu choice
	ld a,[$cc2d] ; remembered menu selection from last time
	ld [$cc26],a
	ld [$cc2a],a
	xor a
	ld [$cc37],a
	ld hl,$d730
	set 6,[hl] ; no pauses between printing each letter
	FuncCoord 12, 2 ; $c3d4
	ld hl,Coord
	ld a,[$d74b]
	bit 5,a ; does the player have the pokedex?
; case for not having pokdex
	ld a,$06
	jr z,.storeMenuItemCount
; case for having pokedex
	ld de,StartMenuPokedexText
	call PrintStartMenuItem
	ld a,$07
.storeMenuItemCount
	ld [$cc28],a ; number of menu items
	ld de,StartMenuPokemonText
	call PrintStartMenuItem
	ld de,StartMenuItemText
	call PrintStartMenuItem
	ld de,W_PLAYERNAME ; player's name
	call PrintStartMenuItem
	ld a,[$d72e]
	bit 6,a ; is the player using the link feature?
; case for not using link feature
	ld de,StartMenuSaveText
	jr z,.printSaveOrResetText
; case for using link feature
	ld de,StartMenuResetText
.printSaveOrResetText
	call PrintStartMenuItem
	ld de,StartMenuOptionText
	call PrintStartMenuItem
	ld de,StartMenuExitText
	call PlaceString
	ld hl,$d730
	res 6,[hl] ; turn pauses between printing letters back on
	ret

StartMenuPokedexText: ; 718f (1:718f)
	db "POKéDEX@"

StartMenuPokemonText: ; 7197 (1:7197)
	db "POKéMON@"

StartMenuItemText: ; 719f (1:719f)
	db "ITEM@"

StartMenuSaveText: ; 71a4 (1:71a4)
	db "SAVE@"

StartMenuResetText: ; 71a9 (1:71a9)
	db "RESET@"

StartMenuExitText: ; 71af (1:71af)
	db "EXIT@"

StartMenuOptionText: ; 71b4 (1:71b4)
	db "OPTION@"

PrintStartMenuItem: ; 71bb (1:71bb)
	push hl
	call PlaceString
	pop hl
	ld de,$28
	add hl,de
	ret

CableClubNPC: ; 71c5 (1:71c5)
	ld hl, CableClubNPCText1
	call PrintText
	ld a, [$d74b]
	bit 5, a
	jp nz, Func_71e1
	ld c, $3c
	call DelayFrames
	ld hl, CableClubNPCText6
	call PrintText
	jp Func_7298

Func_71e1: ; 71e1 (1:71e1)
	ld a, $1
	ld [$cc34], a
	ld a, $5a
	ld [$cc47], a
.asm_71eb
	ld a, [$ffaa]
	cp $2
	jr z, .asm_721a ; 0x71ef $29
	cp $1
	jr z, .asm_721a ; 0x71f3 $25
	ld a, $ff
	ld [$ffaa], a
	ld a, $2
	ld [$ff01], a
	xor a
	ld [$ffad], a
	ld a, $80
	ld [$ff02], a
	ld a, [$cc47]
	dec a
	ld [$cc47], a
	jr z, .asm_7287 ; 0x720b $7a
	ld a, $1
	ld [$ff01], a
	ld a, $81
	ld [$ff02], a
	call DelayFrame
	jr .asm_71eb ; 0x7218 $d1
.asm_721a
	call Func_22ed
	call DelayFrame
	call Func_22ed
	ld c, $32
	call DelayFrames
	ld hl, CableClubNPCText2
	call PrintText
	xor a
	ld [$cc34], a
	call YesNoChoice
	ld a, $1
	ld [$cc34], a
	ld a, [$cc26]
	and a
	jr nz, .asm_728f ; 0x723e $4f
	callab SaveSAVtoSRAM
	call WaitForSoundToFinish
	ld a, (SFX_02_5d - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent
	ld hl, CableClubNPCText3
	call PrintText
	ld hl, $cc47
	ld a, $3
	ld [hli], a
	xor a
	ld [hl], a
	ld [$ffa9], a
	ld [$cc42], a
	call Func_227f
	ld hl, $cc47
	ld a, [hli]
	inc a
	jr nz, Func_72a8 ; 0x726b $3b
	ld a, [hl]
	inc a
	jr nz, Func_72a8 ; 0x726f $37
	ld b, $a
.asm_7273
	call DelayFrame
	call Func_22ed
	dec b
	jr nz, .asm_7273 ; 0x727a $f7
	call Func_72d7
	ld hl, CableClubNPCText4
	call PrintText
	jr Func_7298 ; 0x7285 $11
.asm_7287
	ld hl, CableClubNPCText7
	call PrintText
	jr Func_7298 ; 0x728d $9
.asm_728f
	call Func_72d7
	ld hl, CableClubNPCText5
	call PrintText
	; fall through

Func_7298: ; 7298 (1:7298)
	xor a
	ld hl, $cc47
	ld [hli], a
	ld [hl], a
	ld hl, $d72e
	res 6, [hl]
	xor a
	ld [$cc34], a
	ret

Func_72a8: ; 72a8 (1:72a8)
	xor a
	ld [hld], a
	ld [hl], a
	ld hl, LinkMenu
	ld b, BANK(LinkMenu)
	jp Bankswitch

CableClubNPCText7: ; 72b3 (1:72b3)
	TX_FAR _CableClubNPCText7
	db "@"

CableClubNPCText1: ; 72b8 (1:72b8)
	TX_FAR _CableClubNPCText1
	db "@"

CableClubNPCText2: ; 72bd (1:72bd)
	TX_FAR _CableClubNPCText2
	db "@"

CableClubNPCText3: ; 72c2 (1:72c2)
	TX_FAR _CableClubNPCText3
	db $a, "@"

CableClubNPCText4: ; 72c8 (1:72c8)
	TX_FAR _CableClubNPCText4
	db "@"

CableClubNPCText5: ; 72cd (1:72cd)
	TX_FAR _CableClubNPCText5
	db "@"

CableClubNPCText6: ; 72d2 (1:72d2)
	TX_FAR _CableClubNPCText6
	db "@"

Func_72d7: ; 72d7 (1:72d7)
	call Delay3
	ld a, $ff
	ld [$ffaa], a
	ld a, $2
	ld [$ff01], a
	xor a
	ld [$ffad], a
	ld a, $80
	ld [$ff02], a
	ret

; function to draw various text boxes
; INPUT:
; [$D125] = text box ID
DisplayTextBoxID_: ; 72ea (1:72ea)
	ld a,[$d125] ; a = text box ID
	cp a,$14
	jp z,DisplayYesNoTextBox
	ld c,a
	ld hl,TextBoxFunctionTable
	ld de,3
	call SearchTextBoxTable
	jr c,.functionTableMatch
	ld hl,TextBoxCoordTable
	ld de,5
	call SearchTextBoxTable
	jr c,.coordTableMatch
	ld hl,TextBoxTextAndCoordTable
	ld de,9
	call SearchTextBoxTable
	jr c,.textAndCoordTableMatch
.done
	ret
.functionTableMatch
	ld a,[hli]
	ld h,[hl]
	ld l,a ; hl = address of function
	ld de,.done
	push de
	jp [hl] ; jump to the function
.coordTableMatch
	call GetTextBoxIDCoords
	call GetAddressOfScreenCoords
	call TextBoxBorder
	ret
.textAndCoordTableMatch
	call GetTextBoxIDCoords
	push hl
	call GetAddressOfScreenCoords
	call TextBoxBorder
	pop hl
	call GetTextBoxIDText
	ld a,[$d730]
	push af
	ld a,[$d730]
	set 6,a ; no pauses between printing each letter
	ld [$d730],a
	call PlaceString
	pop af
	ld [$d730],a
	call UpdateSprites ; move sprites
	ret

; function to search a table terminated with $ff for a byte matching c in increments of de
; sets carry flag if a match is found and clears carry flag if not
SearchTextBoxTable: ; 734c (1:734c)
	dec de
.loop
	ld a,[hli]
	cp a,$ff
	jr z,.notFound
	cp c
	jr z,.found
	add hl,de
	jr .loop
.found
	scf
.notFound
	ret

; function to load coordinates from the TextBoxCoordTable or the TextBoxTextAndCoordTable
; INPUT:
; hl = address of coordinates
; OUTPUT:
; b = height
; c = width
; d = row of upper left corner
; e = column of upper left corner
GetTextBoxIDCoords: ; 735a (1:735a)
	ld a,[hli] ; column of upper left corner
	ld e,a
	ld a,[hli] ; row of upper left corner
	ld d,a
	ld a,[hli] ; column of lower right corner
	sub e
	dec a
	ld c,a     ; c = width
	ld a,[hli] ; row of lower right corner
	sub d
	dec a
	ld b,a     ; b = height
	ret

; function to load a text address and text coordinates from the TextBoxTextAndCoordTable
GetTextBoxIDText: ; 7367 (1:7367)
	ld a,[hli]
	ld e,a
	ld a,[hli]
	ld d,a ; de = address of text
	push de ; save text address
	ld a,[hli]
	ld e,a ; column of upper left corner of text
	ld a,[hl]
	ld d,a ; row of upper left corner of text
	call GetAddressOfScreenCoords
	pop de ; restore text address
	ret

; function to point hl to the screen coordinates
; INPUT:
; d = row
; e = column
; OUTPUT:
; hl = address of upper left corner of text box
GetAddressOfScreenCoords: ; 7375 (1:7375)
	push bc
	ld hl,wTileMap
	ld bc,20
.loop ; loop to add d rows to the base address
	ld a,d
	and a
	jr z,.addedRows
	add hl,bc
	dec d
	jr .loop
.addedRows
	pop bc
	add hl,de
	ret

; Format:
; 00: text box ID
; 01-02: function address
TextBoxFunctionTable: ; 7387 (1:7387)
	dbw $13, Func_74ba
	dbw $15, Func_74ea
	dbw $04, Func_76e1
	db $ff ; terminator

; Format:
; 00: text box ID
; 01: column of upper left corner
; 02: row of upper left corner
; 03: column of lower right corner
; 04: row of lower right corner
TextBoxCoordTable: ; 7391 (1:7391)
	db $01,  0, 12, 19, 17
	db $03,  0,  0, 19, 14
	db $07,  0,  0, 11,  6
	db $0d,  4,  2, 19, 12
	db $10,  7,  0, 19, 17
	db $11,  6,  4, 14, 13
	db $ff ; terminator

; Format:
; 00: text box ID
; 01: column of upper left corner
; 02: row of upper left corner
; 03: column of lower right corner
; 04: row of lower right corner
; 05-06: address of text
; 07: column of beginning of text
; 08: row of beginning of text
; table of window positions and corresponding text [key, start column, start row, end column, end row, text pointer [2 bytes], text column, text row]
TextBoxTextAndCoordTable: ; 73b0 (1:73b0)
	db $05 ; text box ID
	db 0,0,14,17   ; text box coordinates
	dw JapaneseMochimonoText
	db 3,0   ; text coordinates

	db $06 ; text box ID
	db 13,10,19,14 ; text box coordinates
	dw UseTossText
	db 15,11 ; text coordinates

	db $08 ; text box ID
	db 0,0,7,5     ; text box coordinates
	dw JapaneseSaveMessageText
	db 2,2   ; text coordinates

	db $09 ; text box ID
	db 0,6,5,10    ; text box coordinates
	dw JapaneseSpeedOptionsText
	db 2,7   ; text coordinates

	db $0b ; text box ID
	db 8,12,19,17  ; text box coordinates
	dw BattleMenuText
	db 10,14 ; text coordinates

	db $1b ; text box ID
	db 0,12,19,17  ; text box coordinates
	dw SafariZoneBattleMenuText
	db 2,14  ; text coordinates

	db $0c ; text box ID
	db 11,11,19,17 ; text box coordinates
	dw SwitchStatsCancelText
	db 13,12 ; text coordinates

	db $0e ; text box ID
	db 0,0,10,6    ; text box coordinates
	dw BuySellQuitText
	db 2,1   ; text coordinates

	db $0f ; text box ID
	db 11,0,19,2   ; text box coordinates
	dw MoneyText
	db 13,0  ; text coordinates

	db $12 ; text box ID
	db 7,6,11,10   ; text box coordinates
	dw JapaneseAhText
	db 8,8   ; text coordinates

	db $1a ; text box ID
	db 11,8,19,17  ; text box coordinates
	dw JapanesePokedexMenu
	db 12,10 ; text coordinates

; note that there is no terminator

BuySellQuitText: ; 7413 (1:7413)
	db   "BUY"
	next "SELL"
	next "QUIT@@"

UseTossText: ; 7422 (1:7422)
	db   "USE"
	next "TOSS@"

JapaneseSaveMessageText: ; 742b (1:742b)
	db   "きろく"
	next "メッセージ@"

JapaneseSpeedOptionsText: ; 7435 (1:7435)
	db   "はやい"
	next "おそい@"

MoneyText: ; 743d (1:743d)
	db "MONEY@"

JapaneseMochimonoText: ; 7443 (1:7443)
	db "もちもの@"

JapaneseMainMenuText: ; 7448 (1:7448)
	db   "つづきから"
	next "さいしょから@"

BattleMenuText: ; 7455 (1:7455)
	db   "FIGHT ",$E1,$E2
	next "ITEM  RUN@"

SafariZoneBattleMenuText: ; 7468 (1:7468)
	db   "BALL×       BAIT"
	next "THROW ROCK  RUN@"

SwitchStatsCancelText: ; 7489 (1:7489)
	db   "SWITCH"
	next "STATS"
	next "CANCEL@"

JapaneseAhText: ; 749d (1:749d)
	db "アッ!@"

JapanesePokedexMenu: ; 74a1 (1:74a1)
	db   "データをみる"
	next "なきごえ"
	next "ぶんぷをみる"
	next "キャンセル@"

Func_74ba: ; 74ba (1:74ba)
	ld hl, $d730
	set 6, [hl]
	ld a, $f
	ld [$d125], a
	call DisplayTextBoxID
	FuncCoord 13, 1 ; $c3c1
	ld hl, Coord
	ld b, $1
	ld c, $6
	call ClearScreenArea
	FuncCoord 12, 1 ; $c3c0
	ld hl, Coord
	ld de, wPlayerMoney ; $d347
	ld c, $a3
	call PrintBCDNumber
	ld hl, $d730
	res 6, [hl]
	ret

CurrencyString: ; 74e2 (1:74e2)
	db "      ¥@"

Func_74ea: ; 74ea (1:74ea)
	ld a, [$d730]
	set 6, a
	ld [$d730], a
	xor a
	ld [$d12d], a
	ld a, $e
	ld [$d125], a
	call DisplayTextBoxID
	ld a, $3
	ld [wMenuWatchedKeys], a ; $cc29
	ld a, $2
	ld [wMaxMenuItem], a ; $cc28
	ld a, $1
	ld [wTopMenuItemY], a ; $cc24
	ld a, $1
	ld [wTopMenuItemX], a ; $cc25
	xor a
	ld [wCurrentMenuItem], a ; $cc26
	ld [wLastMenuItem], a ; $cc2a
	ld [$cc37], a
	ld a, [$d730]
	res 6, a
	ld [$d730], a
	call HandleMenuInput
	call PlaceUnfilledArrowMenuCursor
	bit 0, a
	jr nz, .asm_7539
	bit 1, a
	jr z, .asm_7539
	ld a, $2
	ld [$d12e], a
	jr .asm_754c
.asm_7539
	ld a, $1
	ld [$d12e], a
	ld a, [wCurrentMenuItem] ; $cc26
	ld [$d12d], a
	ld b, a
	ld a, [wMaxMenuItem] ; $cc28
	cp b
	jr z, .asm_754c
	ret
.asm_754c
	ld a, $2
	ld [$d12e], a
	ld a, [wCurrentMenuItem] ; $cc26
	ld [$d12d], a
	scf
	ret

DisplayYesNoTextBox: ; 7559 (1:7559)
	push hl
	ld a, [$d730]
	set 6, a
	ld [$d730], a
	xor a
	ld [$d12d], a
	ld [$d12e], a
	ld a, $3
	ld [wMenuWatchedKeys], a ; $cc29
	ld a, $1
	ld [wMaxMenuItem], a ; $cc28
	ld a, b
	ld [wTopMenuItemY], a ; $cc24
	ld a, c
	ld [wTopMenuItemX], a ; $cc25
	xor a
	ld [wLastMenuItem], a ; $cc2a
	ld [$cc37], a
	push hl
	ld hl, $d12c
	bit 7, [hl]
	res 7, [hl]
	jr z, .asm_758d
	inc a
.asm_758d
	ld [wCurrentMenuItem], a ; $cc26
	pop hl
	push hl
	push hl
	call Func_763e
	ld a, [$d12c]
	ld hl, MenuStrings ; $7671
	ld e, a
	ld d, $0
	ld a, $5
.loop
	add hl, de
	dec a
	jr nz, .loop
	ld a, [hli]
	ld c, a
	ld a, [hli]
	ld b, a
	ld e, l
	ld d, h
	pop hl
	push de
	ld a, [$d12c]
	cp $5
	jr nz, .asm_75b9
	call Func_5ab3
	jr .asm_75bc
.asm_75b9
	call TextBoxBorder
.asm_75bc
	call UpdateSprites
	pop hl
	ld a, [hli]
	and a
	ld bc, $16
	jr z, .asm_75ca
	ld bc, $2a
.asm_75ca
	ld a, [hli]
	ld e, a
	ld a, [hli]
	ld d, a
	pop hl
	add hl, bc
	call PlaceString
	ld hl, $d730
	res 6, [hl]
	ld a, [$d12c]
	cp $7
	jr nz, .asm_7603
	xor a
	ld [$d12c], a
	ld a, [wFlags_0xcd60]
	push af
	push hl
	ld hl, wFlags_0xcd60
	bit 5, [hl]
	set 5, [hl]
	pop hl
.asm_75f0
	call HandleMenuInput
	bit 1, a
	jr nz, .asm_75f0
	pop af
	pop hl
	ld [wFlags_0xcd60], a
	ld a, (SFX_02_40 - SFX_Headers_02) / 3
	call PlaySound
	jr .asm_760f
.asm_7603
	xor a
	ld [$d12c], a
	call HandleMenuInput
	pop hl
	bit 1, a
	jr nz, .asm_7627
.asm_760f
	ld a, [wCurrentMenuItem] ; $cc26
	ld [$d12d], a
	and a
	jr nz, .asm_7627
	ld a, $1
	ld [$d12e], a
	ld c, $f
	call DelayFrames
	call Func_7656
	and a
	ret
.asm_7627
	ld a, $1
	ld [wCurrentMenuItem], a ; $cc26
	ld [$d12d], a
	ld a, $2
	ld [$d12e], a
	ld c, $f
	call DelayFrames
	call Func_7656
	scf
	ret

Func_763e: ; 763e (1:763e)
	ld de, $cee9
	ld bc, $506
.asm_7644
	ld a, [hli]
	ld [de], a
	inc de
	dec c
	jr nz, .asm_7644
	push bc
	ld bc, $e
	add hl, bc
	pop bc
	ld c, $6
	dec b
	jr nz, .asm_7644
	ret

Func_7656: ; 7656 (1:7656)
	ld de, $cee9
	ld bc, $506
.asm_765c
	ld a, [de]
	inc de
	ld [hli], a
	dec c
	jr nz, .asm_765c
	push bc
	ld bc, $e
	add hl, bc
	pop bc
	ld c, $6
	dec b
	jr nz, .asm_765c
	call UpdateSprites
	ret

MenuStrings: ; 7671 (1:7671)
	db 4,3,0
	dw .YesNoMenu
	db 6,3,0
	dw .NorthWestMenu
	db 6,3,0
	dw .SouthEastMenu
	db 6,3,0
	dw .YesNoMenu
	db 6,3,0
	dw .NorthEastMenu
	db 7,3,0
	dw .TradeCancelMenu
	db 7,4,1
	dw .HealCancelMenu
	db 4,3,0
	dw .NoYesMenu

.NoYesMenu ; 7699 (1:3699)
	db "NO",$4E,"YES@"
.YesNoMenu ; 76a0 (1:36a0)
	db "YES",$4E,"NO@"
.NorthWestMenu ; 76a7 (1:36a7)
	db "NORTH",$4E,"WEST@"
.SouthEastMenu ; 76b2 (1:36b2)
	db "SOUTH",$4E,"EAST@"
.NorthEastMenu ; 76bd (1:36bd)
	db "NORTH",$4E,"EAST@"
.TradeCancelMenu ; 76c8 (1:36c8)
	db "TRADE",$4E,"CANCEL@"
.HealCancelMenu ; 76d5 (1:36d5)
	db "HEAL",$4E,"CANCEL@"

Func_76e1: ; 76e1 (1:36e1)
	xor a
	ld hl, wWhichTrade ; $cd3d
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hl], $c
	call GetMonFieldMoves
	ld a, [$cd41]
	and a
	jr nz, .asm_770f
	FuncCoord 11, 11 ; $c487
	ld hl, Coord
	ld b, $5
	ld c, $7
	call TextBoxBorder
	call UpdateSprites
	ld a, $c
	ld [$fff7], a
	FuncCoord 13, 12 ; $c49d
	ld hl, Coord
	ld de, PokemonMenuEntries ; $77c2
	jp PlaceString
.asm_770f
	push af
	FuncCoord 0, 11 ; $c47c
	ld hl, Coord
	ld a, [$cd42]
	dec a
	ld e, a
	ld d, $0
	add hl, de
	ld b, $5
	ld a, $12
	sub e
	ld c, a
	pop af
	ld de, $ffd8
.asm_7725
	add hl, de
	inc b
	inc b
	dec a
	jr nz, .asm_7725
	ld de, $ffec
	add hl, de
	inc b
	call TextBoxBorder
	call UpdateSprites
	FuncCoord 0, 12 ; $c490
	ld hl, Coord
	ld a, [$cd42]
	inc a
	ld e, a
	ld d, $0
	add hl, de
	ld de, $ffd8
	ld a, [$cd41]
.asm_7747
	add hl, de
	dec a
	jr nz, .asm_7747
	xor a
	ld [$cd41], a
	ld de, wWhichTrade ; $cd3d
.asm_7752
	push hl
	ld hl, FieldMoveNames ; $778d
	ld a, [de]
	and a
	jr z, .asm_7776
	inc de
	ld b, a
.asm_775c
	dec b
	jr z, .asm_7766
.asm_775f
	ld a, [hli]
	cp $50
	jr nz, .asm_775f
	jr .asm_775c
.asm_7766
	ld b, h
	ld c, l
	pop hl
	push de
	ld d, b
	ld e, c
	call PlaceString
	ld bc, $28
	add hl, bc
	pop de
	jr .asm_7752
.asm_7776
	pop hl
	ld a, [$cd42]
	ld [$fff7], a
	FuncCoord 0, 12 ; $c490
	ld hl, Coord
	ld a, [$cd42]
	inc a
	ld e, a
	ld d, $0
	add hl, de
	ld de, PokemonMenuEntries ; $77c2
	jp PlaceString

FieldMoveNames: ; 778d (1:778d)
	db "CUT@"
	db "FLY@"
	db "@"
	db "SURF@"
	db "STRENGTH@"
	db "FLASH@"
	db "DIG@"
	db "TELEPORT@"
	db "SOFTBOILED@"

PokemonMenuEntries: ; 77c2 (1:77c2)
	db   "STATS"
	next "SWITCH"
	next "CANCEL@"

GetMonFieldMoves: ; 77d6 (1:77d6)
	ld a, [wWhichPokemon] ; $cf92
	ld hl, W_PARTYMON1_MOVE1 ; $d173
	ld bc, $2c
	call AddNTimes
	ld d, h
	ld e, l
	ld c, $5
	ld hl, wWhichTrade ; $cd3d
.asm_77e9
	push hl
.asm_77ea
	dec c
	jr z, .asm_7821
	ld a, [de] ; de is RAM address of move
	and a
	jr z, .asm_7821
	ld b, a
	inc de ; go to next move
	ld hl, FieldMoveDisplayData ; $7823
.asm_77f6
	ld a, [hli]
	cp $ff
	jr z, .asm_77ea
	cp b
	jr z, .asm_7802
	inc hl
	inc hl
	jr .asm_77f6
.asm_7802
	ld a, b
	ld [$cd43], a
	ld a, [hli]
	ld b, [hl]
	pop hl
	ld [hli], a
	ld a, [$cd41]
	inc a
	ld [$cd41], a
	ld a, [$cd42]
	cp b
	jr c, .asm_781b
	ld a, b
	ld [$cd42], a
.asm_781b
	ld a, [$cd43]
	ld b, a
	jr .asm_77e9
.asm_7821
	pop hl
	ret

; Format: [Move id], [list priority], [leftmost tile]
; Move id = id of move
; List priority = lower number means higher priority when field moves are displayed
;                 these priorities must be unique
; Leftmost tile = -1 + tile column in which the first letter of the move's name should be displayed
;                 "SOFTBOILED" is $08 because it has 4 more letters than "SURF", for example, whose value is $0C
FieldMoveDisplayData: ; 7823 (1:7823)
	db CUT, $01, $0C
	db FLY, $02, $0C
	db $B4, $03, $0C ; unused field move
	db SURF, $04, $0C
	db STRENGTH, $05, $0A
	db FLASH, $06, $0C
	db DIG, $07, $0C
	db TELEPORT, $08, $0A
	db SOFTBOILED, $09, $08
	db $ff ; list terminator


DrainHPEffect_: ; 783f (1:783f)
	ld hl, W_DAMAGE ; $d0d7
	ld a, [hl]
	srl a ; divide damage by 2
	ld [hli], a
	ld a, [hl]
	rr a
	ld [hld], a
	or [hl]
	jr nz, .asm_784f
	inc hl
	inc [hl]
.asm_784f
	ld hl, W_PLAYERMONCURHP ; $d015
	ld de, W_PLAYERMONMAXHP ; $d023
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jp z, Func_7861
	ld hl, W_ENEMYMONCURHP ; $cfe6
	ld de, W_ENEMYMONMAXHP ; $cff4

Func_7861: ; 7861 (1:7861)
	ld bc, wHPBarOldHP+1
	ld a, [hli]
	ld [bc], a
	ld a, [hl]
	dec bc
	ld [bc], a
	ld a, [de]
	dec bc
	ld [bc], a
	inc de
	ld a, [de]
	dec bc
	ld [bc], a
	ld a, [$d0d8]
	ld b, [hl]
	add b
	ld [hld], a
	ld [wHPBarNewHP], a
	ld a, [W_DAMAGE] ; $d0d7
	ld b, [hl]
	adc b
	ld [hli], a
	ld [wHPBarNewHP+1], a
	jr c, .asm_7890
	ld a, [hld]
	ld b, a
	ld a, [de]
	dec de
	sub b
	ld a, [hli]
	ld b, a
	ld a, [de]
	inc de
	sbc b
	jr nc, .asm_789c
.asm_7890
	ld a, [de]
	ld [hld], a
	ld [wHPBarNewHP], a
	dec de
	ld a, [de]
	ld [hli], a
	ld [wHPBarNewHP+1], a
	inc de
.asm_789c
	ld a, [H_WHOSETURN] ; $fff3
	and a
	FuncCoord 10, 9 ; $c45e
	ld hl, Coord
	ld a, $1
	jr z, .asm_78aa
	FuncCoord 2, 2 ; $c3ca
	ld hl, Coord
	xor a
.asm_78aa
	ld [wListMenuID], a ; $cf94
	ld a, $48
	call Predef ; indirect jump to UpdateHPBar (fa1d (3:7a1d))
	ld a, $0
	call Predef ; indirect jump to Func_3cd60 (3cd60 (f:4d60))
	ld a, $49
	call Predef ; indirect jump to Func_3cdec (3cdec (f:4dec))
	callab ReadPlayerMonCurHPAndStatus
	ld hl, SuckedHealthText ; $78dc
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, [W_PLAYERMOVEEFFECT] ; $cfd3
	jr z, .asm_78d2
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
.asm_78d2
	cp DREAM_EATER_EFFECT
	jr nz, .asm_78d9
	ld hl, DreamWasEatenText
.asm_78d9
	jp PrintText

SuckedHealthText: ; 78dc (1:78dc)
	TX_FAR _SuckedHealthText
	db "@"

DreamWasEatenText: ; 78e1 (1:78e1)
	TX_FAR _DreamWasEatenText
	db "@"

PlayerPC: ; 78e6 (1:78e6)
	ld hl, $d730
	set 6, [hl]
	ld a, ITEM_NAME
	ld [W_LISTTYPE], a
	call SaveScreenTilesToBuffer1
	xor a
	ld [$cc2c], a
	ld [$ccd3], a
	ld a, [wFlags_0xcd60]
	bit 3, a
	jr nz, Func_790c
	ld a, (SFX_02_45 - SFX_Headers_02) / 3
	call PlaySound
	ld hl, TurnedOnPC2Text
	call PrintText

Func_790c: ; 790c (1:790c)
	ld a, [$ccd3]
	ld [wCurrentMenuItem], a ; $cc26
	ld hl, wFlags_0xcd60
	set 5, [hl]
	call LoadScreenTilesFromBuffer2
	ld hl, wTileMap
	ld b, $8
	ld c, $e
	call TextBoxBorder
	call UpdateSprites
	FuncCoord 2, 2 ; $c3ca
	ld hl, Coord
	ld de, PlayersPCMenuEntries ; $7af5
	call PlaceString
	ld hl, wTopMenuItemY ; $cc24
	ld a, $2
	ld [hli], a
	dec a
	ld [hli], a
	inc hl
	inc hl
	ld a, $3
	ld [hli], a
	ld a, $3
	ld [hli], a
	xor a
	ld [hl], a
	ld hl, wListScrollOffset ; $cc36
	ld [hli], a
	ld [hl], a
	ld [wPlayerMonNumber], a ; $cc2f
	ld hl, WhatDoYouWantText
	call PrintText
	call HandleMenuInput
	bit 1, a
	jp nz, Func_796d
	call PlaceUnfilledArrowMenuCursor
	ld a, [wCurrentMenuItem] ; $cc26
	ld [$ccd3], a
	and a
	jp z, Func_7a12
	dec a
	jp z, Func_7995
	dec a
	jp z, Func_7a8f

Func_796d: ; 796d (1:796d)
	ld a, [wFlags_0xcd60]
	bit 3, a
	jr nz, .asm_797c
	ld a, (SFX_02_46 - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
.asm_797c
	ld hl, wFlags_0xcd60
	res 5, [hl]
	call LoadScreenTilesFromBuffer2
	xor a
	ld [wListScrollOffset], a ; $cc36
	ld [$cc2c], a
	ld hl, $d730
	res 6, [hl]
	xor a
	ld [$cc3c], a
	ret

Func_7995: ; 7995 (1:7995)
	xor a
	ld [wCurrentMenuItem], a ; $cc26
	ld [wListScrollOffset], a ; $cc36
	ld a, [wNumBagItems] ; $d31d
	and a
	jr nz, Func_79ab
	ld hl, NothingToDepositText
	call PrintText
	jp Func_790c

Func_79ab: ; 79ab (1:79ab)
	ld hl, WhatToDepositText
	call PrintText
	ld hl, wNumBagItems ; $d31d
	ld a, l
	ld [$cf8b], a
	ld a, h
	ld [$cf8c], a
	xor a
	ld [$cf93], a
	ld a, $3
	ld [wListMenuID], a ; $cf94
	call DisplayListMenuID
	jp c, Func_790c
	call IsKeyItem
	ld a, $1
	ld [$cf96], a
	ld a, [$d124]
	and a
	jr nz, .asm_79e7
	ld hl, DepositHowManyText
	call PrintText
	call DisplayChooseQuantityMenu
	cp $ff
	jp z, Func_79ab
.asm_79e7
	ld hl, wNumBoxItems ; $d53a
	call AddItemToInventory
	jr c, .asm_79f8
	ld hl, NoRoomToStoreText
	call PrintText
	jp Func_79ab
.asm_79f8
	ld hl, wNumBagItems ; $d31d
	call RemoveItemFromInventory
	call WaitForSoundToFinish
	ld a, (SFX_02_55 - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	ld hl, ItemWasStoredText
	call PrintText
	jp Func_79ab

Func_7a12: ; 7a12 (1:7a12)
	xor a
	ld [wCurrentMenuItem], a ; $cc26
	ld [wListScrollOffset], a ; $cc36
	ld a, [wNumBoxItems] ; $d53a
	and a
	jr nz, Func_7a28
	ld hl, NothingStoredText
	call PrintText
	jp Func_790c

Func_7a28: ; 7a28 (1:7a28)
	ld hl, WhatToWithdrawText
	call PrintText
	ld hl, wNumBoxItems ; $d53a
	ld a, l
	ld [$cf8b], a
	ld a, h
	ld [$cf8c], a
	xor a
	ld [$cf93], a
	ld a, $3
	ld [wListMenuID], a ; $cf94
	call DisplayListMenuID
	jp c, Func_790c
	call IsKeyItem
	ld a, $1
	ld [$cf96], a
	ld a, [$d124]
	and a
	jr nz, .asm_7a64
	ld hl, WithdrawHowManyText
	call PrintText
	call DisplayChooseQuantityMenu
	cp $ff
	jp z, Func_7a28
.asm_7a64
	ld hl, wNumBagItems ; $d31d
	call AddItemToInventory
	jr c, .asm_7a75
	ld hl, CantCarryMoreText
	call PrintText
	jp Func_7a28
.asm_7a75
	ld hl, wNumBoxItems ; $d53a
	call RemoveItemFromInventory
	call WaitForSoundToFinish
	ld a, (SFX_02_55 - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	ld hl, WithdrewItemText
	call PrintText
	jp Func_7a28

Func_7a8f: ; 7a8f (1:7a8f)
	xor a
	ld [wCurrentMenuItem], a ; $cc26
	ld [wListScrollOffset], a ; $cc36
	ld a, [wNumBoxItems] ; $d53a
	and a
	jr nz, Func_7aa5
	ld hl, NothingStoredText
	call PrintText
	jp Func_790c

Func_7aa5: ; 7aa5 (1:7aa5)
	ld hl, WhatToTossText
	call PrintText
	ld hl, wNumBoxItems ; $d53a
	ld a, l
	ld [$cf8b], a
	ld a, h
	ld [$cf8c], a
	xor a
	ld [$cf93], a
	ld a, $3
	ld [wListMenuID], a ; $cf94
	push hl
	call DisplayListMenuID
	pop hl
	jp c, Func_790c
	push hl
	call IsKeyItem
	pop hl
	ld a, $1
	ld [$cf96], a
	ld a, [$d124]
	and a
	jr nz, .asm_7aef
	ld a, [$cf91]
	call IsItemHM
	jr c, .asm_7aef
	push hl
	ld hl, TossHowManyText
	call PrintText
	call DisplayChooseQuantityMenu
	pop hl
	cp $ff
	jp z, Func_7aa5
.asm_7aef
	call TossItem
	jp Func_7aa5

PlayersPCMenuEntries: ; 7af5 (1:7af5)
	db   "WITHDRAW ITEM"
	next "DEPOSIT ITEM"
	next "TOSS ITEM"
	next "LOG OFF@"

TurnedOnPC2Text: ; 7b22 (1:7b22)
	TX_FAR _TurnedOnPC2Text
	db "@"

WhatDoYouWantText: ; 7b27 (1:7b27)
	TX_FAR _WhatDoYouWantText
	db "@"

WhatToDepositText: ; 7b2c (1:7b2c)
	TX_FAR _WhatToDepositText
	db "@"

DepositHowManyText: ; 7b31 (1:7b31)
	TX_FAR _DepositHowManyText
	db "@"

ItemWasStoredText: ; 7b36 (1:7b36)
	TX_FAR _ItemWasStoredText
	db "@"

NothingToDepositText: ; 7b3b (1:7b3b)
	TX_FAR _NothingToDepositText
	db "@"

NoRoomToStoreText: ; 7b40 (1:7b40)
	TX_FAR _NoRoomToStoreText
	db "@"

WhatToWithdrawText: ; 7b45 (1:7b45)
	TX_FAR _WhatToWithdrawText
	db "@"

WithdrawHowManyText: ; 7b4a (1:7b4a)
	TX_FAR _WithdrawHowManyText
	db "@"

WithdrewItemText: ; 7b4f (1:7b4f)
	TX_FAR _WithdrewItemText
	db "@"

NothingStoredText: ; 7b54 (1:7b54)
	TX_FAR _NothingStoredText
	db "@"

CantCarryMoreText: ; 7b59 (1:7b59)
	TX_FAR _CantCarryMoreText
	db "@"

WhatToTossText: ; 7b5e (1:7b5e)
	TX_FAR _WhatToTossText
	db "@"

TossHowManyText: ; 7b63 (1:7b63)
	TX_FAR _TossHowManyText
	db "@"

_RemovePokemon: ; 7b68 (1:7b68)
	ld hl, W_NUMINPARTY ; $d163
	ld a, [$cf95]
	and a
	jr z, .asm_7b74
	ld hl, W_NUMINBOX ; $da80
.asm_7b74
	ld a, [hl]
	dec a
	ld [hli], a
	ld a, [wWhichPokemon] ; $cf92
	ld c, a
	ld b, $0
	add hl, bc
	ld e, l
	ld d, h
	inc de
.asm_7b81
	ld a, [de]
	inc de
	ld [hli], a
	inc a
	jr nz, .asm_7b81
	ld hl, W_PARTYMON1OT ; $d273
	ld d, $5
	ld a, [$cf95]
	and a
	jr z, .asm_7b97
	ld hl, W_BOXMON1OT
	ld d, $13
.asm_7b97
	ld a, [wWhichPokemon] ; $cf92
	call SkipFixedLengthTextEntries
	ld a, [wWhichPokemon] ; $cf92
	cp d
	jr nz, .asm_7ba6
	ld [hl], $ff
	ret
.asm_7ba6
	ld d, h
	ld e, l
	ld bc, $b
	add hl, bc
	ld bc, W_PARTYMON1NAME ; $d2b5
	ld a, [$cf95]
	and a
	jr z, .asm_7bb8
	ld bc, W_BOXMON1NAME
.asm_7bb8
	call CopyDataUntil
	ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
	ld bc, $2c
	ld a, [$cf95]
	and a
	jr z, .asm_7bcd
	ld hl, W_BOXMON1DATA
	ld bc, $21
.asm_7bcd
	ld a, [wWhichPokemon] ; $cf92
	call AddNTimes
	ld d, h
	ld e, l
	ld a, [$cf95]
	and a
	jr z, .asm_7be4
	ld bc, $21
	add hl, bc
	ld bc, W_BOXMON1OT
	jr .asm_7beb
.asm_7be4
	ld bc, $2c
	add hl, bc
	ld bc, W_PARTYMON1OT ; $d273
.asm_7beb
	call CopyDataUntil
	ld hl, W_PARTYMON1NAME ; $d2b5
	ld a, [$cf95]
	and a
	jr z, .asm_7bfa
	ld hl, W_BOXMON1NAME
.asm_7bfa
	ld bc, $b
	ld a, [wWhichPokemon] ; $cf92
	call AddNTimes
	ld d, h
	ld e, l
	ld bc, $b
	add hl, bc
	ld bc, wPokedexOwned ; $d2f7
	ld a, [$cf95]
	and a
	jr z, .asm_7c15
	ld bc, $dee2
.asm_7c15
	jp CopyDataUntil

Func_7c18: ; 7c18 (1:7c18)
	ld hl, $d730
	set 6, [hl]
	ld a, $3d
	call Predef
	ld hl, $d730
	res 6, [hl]
	call ReloadMapData
	ld c, $a
	call DelayFrames
	ld a, $3a
	call Predef
	ld a, [$d11e]
	dec a
	ld c, a
	ld b, $1
	ld hl, wPokedexSeen
	ld a, $10
	call Predef
	ld a, $1
	ld [$cc3c], a
	ret


SECTION "bank3",ROMX,BANK[$3]

_GetJoypadState: ; c000 (3:4000)
	ld a, [H_JOYPADSTATE]
	cp BTN_A | BTN_B | BTN_SELECT | BTN_START ; soft reset sequence
	jp z, HandleJoypadResetButtons
	ld b, a
	ld a, [H_OLDPRESSEDBUTTONS]
	ld e, a
	xor b
	ld d, a
	and e
	ld [H_NEWLYRELEASEDBUTTONS], a
	ld a, d
	and b
	ld [H_NEWLYPRESSEDBUTTONS], a
	ld a, b
	ld [H_OLDPRESSEDBUTTONS], a
	ld a, [$d730]
	bit 5, a
	jr nz, DiscardButtonPresses
	ld a, [H_OLDPRESSEDBUTTONS]
	ld [H_CURRENTPRESSEDBUTTONS], a
	ld a, [wJoypadForbiddenButtonsMask]
	and a
	ret z
	cpl
	ld b, a
	ld a, [H_CURRENTPRESSEDBUTTONS]
	and b
	ld [H_CURRENTPRESSEDBUTTONS], a
	ld a, [H_NEWLYPRESSEDBUTTONS]
	and b
	ld [H_NEWLYPRESSEDBUTTONS], a
	ret

; clears all button presses
DiscardButtonPresses: ; c034 (3:4034)
	xor a
	ld [H_CURRENTPRESSEDBUTTONS], a
	ld [H_NEWLYPRESSEDBUTTONS], a
	ld [H_NEWLYRELEASEDBUTTONS], a
	ret

HandleJoypadResetButtons: ; c03c (3:403c)
	call DelayFrame
	ld a, $30
	ld [rJOYP], a ; reset joypad state (to enusre the user really intends to reset)
	ld hl, H_SOFTRESETCOUNTER
	dec [hl]
	jp z, SoftReset
	jp GetJoypadState

INCLUDE "data/map_songs.asm"

; see also MapHeaderPointers
MapHeaderBanks: ; c23d (3:423d)
	db BANK(PalletTown_h) ;PALLET_TOWN
	db BANK(ViridianCity_h) ; VIRIDIAN_CITY
	db BANK(PewterCity_h) ; PEWTER_CITY
	db BANK(CeruleanCity_h) ; CERULEAN_CITY
	db BANK(LavenderTown_h) ; LAVENDER_TOWN
	db BANK(VermilionCity_h) ; VERMILION_CITY
	db BANK(CeladonCity_h) ; CELADON_CITY
	db BANK(FuchsiaCity_h) ; FUCHSIA_CITY
	db BANK(CinnabarIsland_h) ; CINNABAR_ISLAND
	db BANK(IndigoPlateau_h) ; INDIGO_PLATEAU
	db BANK(SaffronCity_h) ; SAFFRON_CITY
	db $1 ; unused
	db BANK(Route1_h) ; ROUTE_1
	db BANK(Route2_h) ; ROUTE_2
	db BANK(Route3_h) ; ROUTE_3
	db BANK(Route4_h) ; ROUTE_4
	db BANK(Route5_h) ; ROUTE_5
	db BANK(Route6_h) ; ROUTE_6
	db BANK(Route7_h) ; ROUTE_7
	db BANK(Route8_h) ; ROUTE_8
	db BANK(Route9_h) ; ROUTE_9
	db BANK(Route10_h) ; ROUTE_10
	db BANK(Route11_h) ; ROUTE_11
	db BANK(Route12_h) ; ROUTE_12
	db BANK(Route13_h) ; ROUTE_13
	db BANK(Route14_h) ; ROUTE_14
	db BANK(Route15_h) ; ROUTE_15
	db BANK(Route16_h) ; ROUTE_16
	db BANK(Route17_h) ; ROUTE_17
	db BANK(Route18_h) ; ROUTE_18
	db BANK(Route19_h) ; ROUTE_19
	db BANK(Route20_h) ; ROUTE_20
	db BANK(Route21_h) ; ROUTE_21
	db BANK(Route22_h) ; ROUTE_22
	db BANK(Route23_h) ; ROUTE_23
	db BANK(Route24_h) ; ROUTE_24
	db BANK(Route25_h) ; ROUTE_25
	db BANK(RedsHouse1F_h)
	db BANK(RedsHouse2F_h)
	db BANK(BluesHouse_h)
	db BANK(OaksLab_h)
	db BANK(ViridianPokecenter_h)
	db BANK(ViridianMart_h)
	db BANK(School_h)
	db BANK(ViridianHouse_h)
	db BANK(ViridianGym_h)
	db BANK(DiglettsCaveRoute2_h)
	db BANK(ViridianForestExit_h)
	db BANK(Route2House_h)
	db BANK(Route2Gate_h)
	db BANK(ViridianForestEntrance_h)
	db BANK(ViridianForest_h)
	db BANK(Museum1F_h)
	db BANK(Museum2F_h)
	db BANK(PewterGym_h)
	db BANK(PewterHouse1_h)
	db BANK(PewterMart_h)
	db BANK(PewterHouse2_h)
	db BANK(PewterPokecenter_h)
	db BANK(MtMoon1_h)
	db BANK(MtMoon2_h)
	db BANK(MtMoon3_h)
	db BANK(CeruleanHouseTrashed_h)
	db BANK(CeruleanHouse1_h)
	db BANK(CeruleanPokecenter_h)
	db BANK(CeruleanGym_h)
	db BANK(BikeShop_h)
	db BANK(CeruleanMart_h)
	db BANK(MtMoonPokecenter_h)
	db BANK(CeruleanHouseTrashed_h)
	db BANK(Route5Gate_h)
	db BANK(UndergroundPathEntranceRoute5_h)
	db BANK(DayCareM_h)
	db BANK(Route6Gate_h)
	db BANK(UndergroundPathEntranceRoute6_h)
	db BANK(UndergroundPathEntranceRoute6_h) ;FREEZE
	db BANK(Route7Gate_h)
	db BANK(UndergroundPathEntranceRoute7_h)
	db BANK(UndergroundPathEntranceRoute7Copy_h) ;FREEZE
	db BANK(Route8Gate_h)
	db BANK(UndergroundPathEntranceRoute8_h)
	db BANK(RockTunnelPokecenter_h)
	db BANK(RockTunnel1_h)
	db BANK(PowerPlant_h)
	db BANK(Route11Gate_h)
	db BANK(DiglettsCaveEntranceRoute11_h)
	db BANK(Route11GateUpstairs_h)
	db BANK(Route12Gate_h)
	db BANK(BillsHouse_h)
	db BANK(VermilionPokecenter_h)
	db BANK(FanClub_h)
	db BANK(VermilionMart_h)
	db BANK(VermilionGym_h)
	db BANK(VermilionHouse1_h)
	db BANK(VermilionDock_h)
	db BANK(SSAnne1_h)
	db BANK(SSAnne2_h)
	db BANK(SSAnne3_h)
	db BANK(SSAnne4_h)
	db BANK(SSAnne5_h)
	db BANK(SSAnne6_h)
	db BANK(SSAnne7_h)
	db BANK(SSAnne8_h)
	db BANK(SSAnne9_h)
	db BANK(SSAnne10_h)
	db $1D ;unused
	db $1D ;unused
	db $1D ;unused
	db BANK(VictoryRoad1_h)
	db $1D ;unused
	db $1D ;unused
	db $1D ;unused
	db $1D ;unused
	db BANK(Lance_h)
	db $1D ;unused
	db $1D ;unused
	db $1D ;unused
	db $1D ;unused
	db BANK(HallofFameRoom_h)
	db BANK(UndergroundPathNS_h)
	db BANK(Gary_h)
	db BANK(UndergroundPathWE_h)
	db BANK(CeladonMart1_h)
	db BANK(CeladonMart2_h)
	db BANK(CeladonMart3_h)
	db BANK(CeladonMart4_h)
	db BANK(CeladonMartRoof_h)
	db BANK(CeladonMartElevator_h)
	db BANK(CeladonMansion1_h)
	db BANK(CeladonMansion2_h)
	db BANK(CeladonMansion3_h)
	db BANK(CeladonMansion4_h)
	db BANK(CeladonMansion5_h)
	db BANK(CeladonPokecenter_h)
	db BANK(CeladonGym_h)
	db BANK(CeladonGameCorner_h)
	db BANK(CeladonMart5_h)
	db BANK(CeladonPrizeRoom_h)
	db BANK(CeladonDiner_h)
	db BANK(CeladonHouse_h)
	db BANK(CeladonHotel_h)
	db BANK(LavenderPokecenter_h)
	db BANK(PokemonTower1_h)
	db BANK(PokemonTower2_h)
	db BANK(PokemonTower3_h)
	db BANK(PokemonTower4_h)
	db BANK(PokemonTower5_h)
	db BANK(PokemonTower6_h)
	db BANK(PokemonTower7_h)
	db BANK(LavenderHouse1_h)
	db BANK(LavenderMart_h)
	db BANK(LavenderHouse2_h)
	db BANK(FuchsiaMart_h)
	db BANK(FuchsiaHouse1_h)
	db BANK(FuchsiaPokecenter_h)
	db BANK(FuchsiaHouse2_h)
	db BANK(SafariZoneEntrance_h)
	db BANK(FuchsiaGym_h)
	db BANK(FuchsiaMeetingRoom_h)
	db BANK(SeafoamIslands2_h)
	db BANK(SeafoamIslands3_h)
	db BANK(SeafoamIslands4_h)
	db BANK(SeafoamIslands5_h)
	db BANK(VermilionHouse2_h)
	db BANK(FuchsiaHouse3_h)
	db BANK(Mansion1_h)
	db BANK(CinnabarGym_h)
	db BANK(Lab1_h)
	db BANK(Lab2_h)
	db BANK(Lab3_h)
	db BANK(Lab4_h)
	db BANK(CinnabarPokecenter_h)
	db BANK(CinnabarMart_h)
	db BANK(CinnabarMart_h)
	db BANK(IndigoPlateauLobby_h)
	db BANK(CopycatsHouse1F_h)
	db BANK(CopycatsHouse2F_h)
	db BANK(FightingDojo_h)
	db BANK(SaffronGym_h)
	db BANK(SaffronHouse1_h)
	db BANK(SaffronMart_h)
	db BANK(SilphCo1_h)
	db BANK(SaffronPokecenter_h)
	db BANK(SaffronHouse2_h)
	db BANK(Route15Gate_h)
	db BANK(Route15GateUpstairs_h)
	db BANK(Route16Gate_h)
	db BANK(Route16GateUpstairs_h)
	db BANK(Route16House_h)
	db BANK(Route12House_h)
	db BANK(Route18Gate_h)
	db BANK(Route18GateUpstairs_h)
	db BANK(SeafoamIslands1_h)
	db BANK(Route22Gate_h)
	db BANK(VictoryRoad2_h)
	db BANK(Route12GateUpstairs_h)
	db BANK(VermilionHouse3_h)
	db BANK(DiglettsCave_h)
	db BANK(VictoryRoad3_h)
	db BANK(RocketHideout1_h)
	db BANK(RocketHideout2_h)
	db BANK(RocketHideout3_h)
	db BANK(RocketHideout4_h)
	db BANK(RocketHideoutElevator_h)
	db $01
	db $01
	db $01
	db BANK(SilphCo2_h)
	db BANK(SilphCo3_h)
	db BANK(SilphCo4_h)
	db BANK(SilphCo5_h)
	db BANK(SilphCo6_h)
	db BANK(SilphCo7_h)
	db BANK(SilphCo8_h)
	db BANK(Mansion2_h)
	db BANK(Mansion3_h)
	db BANK(Mansion4_h)
	db BANK(SafariZoneEast_h)
	db BANK(SafariZoneNorth_h)
	db BANK(SafariZoneWest_h)
	db BANK(SafariZoneCenter_h)
	db BANK(SafariZoneRestHouse1_h)
	db BANK(SafariZoneSecretHouse_h)
	db BANK(SafariZoneRestHouse2_h)
	db BANK(SafariZoneRestHouse3_h)
	db BANK(SafariZoneRestHouse4_h)
	db BANK(UnknownDungeon2_h)
	db BANK(UnknownDungeon3_h)
	db BANK(UnknownDungeon1_h)
	db BANK(NameRater_h)
	db BANK(CeruleanHouse2_h)
	db $01
	db BANK(RockTunnel2_h)
	db BANK(SilphCo9_h)
	db BANK(SilphCo10_h)
	db BANK(SilphCo11_h)
	db BANK(SilphCoElevator_h)
	db $11
	db $11
	db BANK(BattleCenterM_h)
	db BANK(TradeCenterM_h)
	db $11
	db $11
	db $11
	db $11
	db BANK(Lorelei_h)
	db BANK(Bruno_h)
	db BANK(Agatha_h)

Func_c335: ; c335 (3:4335)
	ld a, $90
	ld [$ffb0], a
	ld [rWY], a ; $ff4a
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld [$d13b], a
	ld [W_LONEATTACKNO], a ; $d05c
	ld [H_NEWLYPRESSEDBUTTONS], a
	ld [H_NEWLYRELEASEDBUTTONS], a
	ld [H_CURRENTPRESSEDBUTTONS], a
	ld [$cd6a], a
	ld [$d5a3], a
	ld hl, $d73f
	ld [hli], a
	ld [hl], a
	ld hl, wWhichTrade ; $cd3d
	ld bc, $1e
	call FillMemory
	ret

Func_c35f: ; c35f (3:435f)
	ld a, [$d3ae]
	and a
	ret z
	ld c, a
	ld hl, $d3af
.asm_c368
	ld a, [W_YCOORD] ; $d361
	cp [hl]
	jr nz, .asm_c383
	inc hl
	ld a, [W_XCOORD] ; $d362
	cp [hl]
	jr nz, .asm_c384
	inc hl
	ld a, [hli]
	ld [$d42f], a
	ld a, [hl]
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld hl, $d736
	set 2, [hl]
	ret
.asm_c383
	inc hl
.asm_c384
	inc hl
	inc hl
	inc hl
	dec c
	jr nz, .asm_c368
	ret

CheckForceBikeOrSurf: ; c38b (3:438b)
	ld hl, $D732
	bit 5, [hl]
	ret nz
	ld hl, ForcedBikeOrSurfMaps
	ld a, [W_YCOORD]
	ld b, a
	ld a, [W_XCOORD]
	ld c, a
	ld a, [W_CURMAP]
	ld d, a
.loop
	ld a, [hli]
	cp $ff
	ret z ;if we reach FF then it's not part of the list
	cp d ;compare to current map
	jr nz, .incorrectMap
	ld a, [hli]
	cp b ;compare y-coord
	jr nz, .incorrectY
	ld a, [hli]
	cp c ;compare x-coord
	jr nz, .loop ; incorrect x-coord, check next item
	ld a, [W_CURMAP]
	cp SEAFOAM_ISLANDS_4
	ld a, $2
	ld [W_SEAFOAMISLANDS4CURSCRIPT], a
	jr z, .forceSurfing
	ld a, [W_CURMAP]
	cp SEAFOAM_ISLANDS_5
	ld a, $2
	ld [W_SEAFOAMISLANDS5CURSCRIPT], a
	jr z, .forceSurfing
	;force bike riding
	ld hl, $d732
	set 5, [hl]
	ld a, $1
	ld [$d700], a
	ld [$d11a], a
	jp ForceBikeOrSurf
.incorrectMap
	inc hl
.incorrectY
	inc hl
	jr .loop
.forceSurfing
	ld a, $2
	ld [$d700], a
	ld [$d11a], a
	jp ForceBikeOrSurf

INCLUDE "data/force_bike_surf.asm"

Func_c3ff: ; c3ff (3:43ff)
	push hl
	push de
	push bc
	ld a, [$c109]
	srl a
	ld c, a
	ld b, $0
	ld hl, PointerTable_c422 ; $4422
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld a, [W_YCOORD] ; $d361
	ld b, a
	ld a, [W_XCOORD] ; $d362
	ld c, a
	ld de, .asm_c41e ; $441e
	push de
	jp [hl]
.asm_c41e
	pop bc
	pop de
	pop hl
	ret

PointerTable_c422: ; c422 (3:4422)
	dw .asm_c42a
	dw .asm_4434
	dw .asm_443A
	dw .asm_4440

.asm_c42a
	ld a, [W_CURMAPHEIGHT] ; $d368
	add a
	dec a
	cp b
	jr z, .setCarry
	jr .resetCarry

.asm_4434
	ld a, b
	and a
	jr z, .setCarry
	jr .resetCarry

.asm_443A
	ld a, c
	and a
	jr z, .setCarry
	jr .resetCarry

.asm_4440
	ld a, [W_CURMAPWIDTH] ; $d369
	add a
	dec a
	cp c
	jr z, .setCarry
	jr .resetCarry
.resetCarry
	and a
	ret
.setCarry
	scf
	ret

Func_c44e: ; c44e (3:444e)
	push hl
	push de
	push bc
	call Func_c589
	ld a, [W_CURMAP] ; $d35e
	cp SS_ANNE_5
	jr z, .ssAnne5
	ld a, [$c109]
	srl a
	ld c, a
	ld b, $0
	ld hl, .pointerTable_c477 ; $4477
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld a, [$cfc6]
	ld de, $1
	call IsInArray
.asm_c473
	pop bc
	pop de
	pop hl
	ret

.pointerTable_c477: ; c477 (3:4477)
	dw .arrayData_c47f
	dw .arrayData_c487
	dw .arrayData_c48a
	dw .arrayData_c48d

.arrayData_c47f
	db $01,$12,$17,$3D,$04,$18,$33,$FF

.arrayData_c487
	db $01,$5C,$FF

.arrayData_c48a
	db $1A,$4B,$FF

.arrayData_c48d
	db $0F,$4E,$FF

.ssAnne5
	ld a, [$cfc6]
	cp $15
	jr nz, .asm_c49a
	scf
	jr .asm_c473
.asm_c49a
	and a
	jr .asm_c473

Func_c49d: ; c49d (3:449d)
	push hl
	push de
	push bc
	callba Func_1a609
	jr c, .asm_c4c8
	ld a, [W_CURMAPTILESET] ; $d367
	add a
	ld c, a
	ld b, $0
	ld hl, WarpTileIDPointers ; $44cc
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld de, $1
	FuncCoord 8, 9 ; $c45c
	ld a, [Coord]
	call IsInArray
	jr nc, .asm_c4c8
	ld hl, $d736
	res 2, [hl]
.asm_c4c8
	pop bc
	pop de
	pop hl
	ret

INCLUDE "data/warp_tile_ids.asm"

PrintSafariZoneSteps: ; c52f (3:452f)
	ld a, [W_CURMAP] ; $d35e
	cp SAFARI_ZONE_EAST
	ret c
	cp UNKNOWN_DUNGEON_2
	ret nc
	ld hl, wTileMap
	ld b, $3
	ld c, $7
	call TextBoxBorder
	FuncCoord 1, 1 ; $c3b5
	ld hl, Coord
	ld de, wSafariSteps ; $d70d
	ld bc, $203
	call PrintNumber
	FuncCoord 4, 1 ; $c3b8
	ld hl, Coord
	ld de, SafariSteps ; $4579
	call PlaceString
	FuncCoord 1, 3 ; $c3dd
	ld hl, Coord
	ld de, SafariBallText
	call PlaceString
	ld a, [W_NUMSAFARIBALLS] ; $da47
	cp $a
	jr nc, .asm_c56d
	FuncCoord 5, 3 ; $c3e1
	ld hl, Coord
	ld a, $7f
	ld [hl], a
.asm_c56d
	FuncCoord 6, 3 ; $c3e2
	ld hl, Coord
	ld de, W_NUMSAFARIBALLS ; $da47
	ld bc, $102
	jp PrintNumber

SafariSteps: ; c579 (3:4579)
	db "/500@"

SafariBallText: ; c57e (3:457e)
	db "BALL×× @"

Func_c586: ; c586 (3:4586)
	call Load16BitRegisters

Func_c589: ; c589 (3:4589)
	ld a, [W_YCOORD] ; $d361
	ld d, a
	ld a, [W_XCOORD] ; $d362
	ld e, a
	ld a, [$c109]
	and a
	jr nz, .asm_c59d
	FuncCoord 8, 11 ; $c484
	ld a, [Coord]
	inc d
	jr .asm_c5b9
.asm_c59d
	cp $4
	jr nz, .asm_c5a7
	FuncCoord 8, 7 ; $c434
	ld a, [Coord]
	dec d
	jr .asm_c5b9
.asm_c5a7
	cp $8
	jr nz, .asm_c5b1
	FuncCoord 6, 9 ; $c45a
	ld a, [Coord]
	dec e
	jr .asm_c5b9
.asm_c5b1
	cp $c
	jr nz, .asm_c5b9
	FuncCoord 10, 9 ; $c45e
	ld a, [Coord]
	inc e
.asm_c5b9
	ld c, a
	ld [$cfc6], a
	ret

Func_c5be: ; c5be (3:45be)
	xor a
	ld [$ffdb], a
	ld hl, W_YCOORD ; $d361
	ld a, [hli]
	ld d, a
	ld e, [hl]
	ld a, [$c109]
	and a
	jr nz, .asm_c5d8
	ld hl, $ffdb
	set 0, [hl]
	FuncCoord 8, 13 ; $c4ac
	ld a, [Coord]
	inc d
	jr .asm_c603
.asm_c5d8
	cp $4
	jr nz, .asm_c5e7
	ld hl, $ffdb
	set 1, [hl]
	FuncCoord 8, 5 ; $c40c
	ld a, [Coord]
	dec d
	jr .asm_c603
.asm_c5e7
	cp $8
	jr nz, .asm_c5f6
	ld hl, $ffdb
	set 2, [hl]
	FuncCoord 4, 9 ; $c458
	ld a, [Coord]
	dec e
	jr .asm_c603
.asm_c5f6
	cp $c
	jr nz, .asm_c603
	ld hl, $ffdb
	set 3, [hl]
	FuncCoord 12, 9 ; $c460
	ld a, [Coord]
	inc e
.asm_c603
	ld c, a
	ld [$d71c], a
	ld [$cfc6], a
	ret

Func_c60b: ; c60b (3:460b)
	call Func_c5be
	ld hl, $d530
	ld a, [hli]
	ld h, [hl]
	ld l, a
.asm_c614
	ld a, [hli]
	cp $ff
	jr z, .asm_c632
	cp c
	jr nz, .asm_c614
	ld hl, $c7e
	call Func_c44
	ld a, $ff
	jr c, .asm_c632
	ld a, [$d71c]
	cp $15
	ld a, $ff
	jr z, .asm_c632
	call Func_c636
.asm_c632
	ld [$d71c], a
	ret

Func_c636: ; c636 (3:4636)
	ld a, [$d718]
	dec a
	swap a
	ld d, $0
	ld e, a
	ld hl, $c214
	add hl, de
	ld a, [hli]
	ld [$ffdc], a
	ld a, [hl]
	ld [$ffdd], a
	ld a, [W_NUMSPRITES] ; $d4e1
	ld c, a
	ld de, $f
	ld hl, $c214
	ld a, [$ffdb]
	and $3
	jr z, .asm_c678
.asm_c659
	inc hl
	ld a, [$ffdd]
	cp [hl]
	jr nz, .asm_c672
	dec hl
	ld a, [hli]
	ld b, a
	ld a, [$ffdb]
	rrca
	jr c, .asm_c66c
	ld a, [$ffdc]
	dec a
	jr .asm_c66f
.asm_c66c
	ld a, [$ffdc]
	inc a
.asm_c66f
	cp b
	jr z, .asm_c697
.asm_c672
	dec c
	jr z, .asm_c69a
	add hl, de
	jr .asm_c659
.asm_c678
	ld a, [hli]
	ld b, a
	ld a, [$ffdc]
	cp b
	jr nz, .asm_c691
	ld b, [hl]
	ld a, [$ffdb]
	bit 2, a
	jr nz, .asm_c68b
	ld a, [$ffdd]
	inc a
	jr .asm_c68e
.asm_c68b
	ld a, [$ffdd]
	dec a
.asm_c68e
	cp b
	jr z, .asm_c697
.asm_c691
	dec c
	jr z, .asm_c69a
	add hl, de
	jr .asm_c678
.asm_c697
	ld a, $ff
	ret
.asm_c69a
	xor a
	ret

Func_c69c: ; c69c (3:469c)
	ld a, [$d730]
	add a
	jp c, .asm_c74f
	ld a, [W_NUMINPARTY] ; $d163
	and a
	jp z, .asm_c74f
	call Func_c8de
	ld a, [$d13b]
	and $3
	jp nz, .asm_c74f
	ld [wWhichPokemon], a ; $cf92
	ld hl, W_PARTYMON1_STATUS ; $d16f
	ld de, W_PARTYMON1 ; $d164
.asm_c6be
	ld a, [hl]
	and $8
	jr z, .asm_c6fd
	dec hl
	dec hl
	ld a, [hld]
	ld b, a
	ld a, [hli]
	or b
	jr z, .asm_c6fb
	ld a, [hl]
	dec a
	ld [hld], a
	inc a
	jr nz, .asm_c6d5
	dec [hl]
	inc hl
	jr .asm_c6fb
.asm_c6d5
	ld a, [hli]
	or [hl]
	jr nz, .asm_c6fb
	push hl
	inc hl
	inc hl
	ld [hl], a
	ld a, [de]
	ld [$d11e], a
	push de
	ld a, [wWhichPokemon] ; $cf92
	ld hl, W_PARTYMON1NAME ; $d2b5
	call GetPartyMonName
	xor a
	ld [wJoypadForbiddenButtonsMask], a
	call EnableAutoTextBoxDrawing
	ld a, $d0
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call DisplayTextID
	pop de
	pop hl
.asm_c6fb
	inc hl
	inc hl
.asm_c6fd
	inc de
	ld a, [de]
	inc a
	jr z, .asm_c70e
	ld bc, $2c
	add hl, bc
	push hl
	ld hl, wWhichPokemon ; $cf92
	inc [hl]
	pop hl
	jr .asm_c6be
.asm_c70e
	ld hl, W_PARTYMON1_STATUS ; $d16f
	ld a, [W_NUMINPARTY] ; $d163
	ld d, a
	ld e, $0
.asm_c717
	ld a, [hl]
	and $8
	or e
	ld e, a
	ld bc, $2c
	add hl, bc
	dec d
	jr nz, .asm_c717
	ld a, e
	and a
	jr z, .asm_c733
	ld b, $2
	ld a, $1f
	call Predef ; indirect jump to Func_480eb (480eb (12:40eb))
	ld a, (SFX_02_43 - SFX_Headers_02) / 3
	call PlaySound
.asm_c733
	ld a, $14
	call Predef ; indirect jump to AnyPokemonAliveCheck (3ca83 (f:4a83))
	ld a, d
	and a
	jr nz, .asm_c74f
	call EnableAutoTextBoxDrawing
	ld a, $d1
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call DisplayTextID
	ld hl, $d72e
	set 5, [hl]
	ld a, $ff
	jr .asm_c750
.asm_c74f
	xor a
.asm_c750
	ld [$d12d], a
	ret

Func_c754: ; c754 (3:4754)
	call Load16BitRegisters
	push hl
	ld d, $0
	ld a, [W_CURMAPTILESET] ; $d367
	add a
	add a
	ld b, a
	add a
	add b
	jr nc, .asm_c765
	inc d
.asm_c765
	ld e, a
	ld hl, Tilesets
	add hl, de
	ld de, $d52b
	ld c, $b
.asm_c76f
	ld a, [hli]
	ld [de], a
	inc de
	dec c
	jr nz, .asm_c76f
	ld a, [hl]
	ld [$ffd7], a
	xor a
	ld [$ffd8], a
	pop hl
	ld a, [W_CURMAPTILESET] ; $d367
	push hl
	push de
	ld hl, DungeonTilesets ; $47b2
	ld de, $1
	call IsInArray
	pop de
	pop hl
	jr c, .asm_c797
	ld a, [W_CURMAPTILESET] ; $d367
	ld b, a
	ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
	cp b
	jr z, .asm_c7b1
.asm_c797
	ld a, [$d42f]
	cp $ff
	jr z, .asm_c7b1
	call LoadDestinationWarpPosition
	ld a, [W_YCOORD] ; $d361
	and $1
	ld [W_YBLOCKCOORD], a ; $d363
	ld a, [W_XCOORD] ; $d362
	and $1
	ld [W_XBLOCKCOORD], a ; $d364
.asm_c7b1
	ret

INCLUDE "data/dungeon_tilesets.asm"

INCLUDE "data/tileset_headers.asm"

Func_c8de: ; c8de (3:48de)
	ld a, [W_DAYCARE_IN_USE]
	and a
	ret z
	ld hl, $da6f
	inc [hl]
	ret nz
	dec hl
	inc [hl]
	ret nz
	dec hl
	inc [hl]
	ld a, [hl]
	cp $50
	ret c
	ld a, $50
	ld [hl], a
	ret

INCLUDE "data/hide_show_data.asm"

PrintUsedStrengthText: ; cd99 (3:4d99)
	ld hl, $d728
	set 0, [hl]
	ld hl, UsedStrengthText
	call PrintText
	ld hl, CanMoveBouldersText
	jp PrintText

UsedStrengthText: ; cdaa (3:4daa)
	TX_FAR _UsedStrengthText
	db $08 ; asm
	ld a, [$cf91]
	call PlayCry
	call Delay3
	jp TextScriptEnd

CanMoveBouldersText: ; cdbb (3:4dbb)
	TX_FAR _CanMoveBouldersText
	db "@"

CheckForForcedBikeSurf: ; cdc0 (3:4dc0)
	ld hl, $d728
	set 1, [hl]
	ld a, [$d732]
	bit 5, a
	jr nz, .asm_cdec
	ld a, [W_CURMAP] ; $d35e
	cp SEAFOAM_ISLANDS_5
	ret nz
	ld a, [$d881]
	and $3
	cp $3
	ret z
	ld hl, CoordsData_cdf7 ; $4df7
	call ArePlayerCoordsInArray
	ret nc
	ld hl, $d728
	res 1, [hl]
	ld hl, CurrentTooFastText
	jp PrintText
.asm_cdec
	ld hl, $d728
	res 1, [hl]
	ld hl, CyclingIsFunText
	jp PrintText

CoordsData_cdf7: ; cdf7 (3:4df7)
	db $0B,$07,$FF

CurrentTooFastText: ; cdfa (3:4dfa)
	TX_FAR _CurrentTooFastText
	db "@"

CyclingIsFunText: ; cdff (3:4dff)
	TX_FAR _CyclingIsFunText
	db "@"

; function to add an item (in varying quantities) to the player's bag or PC box
; INPUT:
; hl = address of inventory (either wNumBagItems or wNumBoxItems)
; [$CF91] = item ID
; [$CF96] = item quantity
; sets carry flag if successful, unsets carry flag if unsuccessful
AddItemToInventory_: ; ce04 (3:4e04)
	ld a,[$cf96] ; a = item quantity
	push af
	push bc
	push de
	push hl
	push hl
	ld d,50 ; PC box can hold 50 items
	ld a,wNumBagItems & $FF
	cp l
	jr nz,.checkIfInventoryFull
	ld a,wNumBagItems >> 8
	cp h
	jr nz,.checkIfInventoryFull
; if the destination is the bag
	ld d,20 ; bag can hold 20 items
.checkIfInventoryFull
	ld a,[hl]
	sub d
	ld d,a
	ld a,[hli]
	and a
	jr z,.addNewItem
.loop
	ld a,[hli]
	ld b,a ; b = ID of current item in table
	ld a,[$cf91] ; a = ID of item being added
	cp b ; does the current item in the table match the item being added?
	jp z,.increaseItemQuantity ; if so, increase the item's quantity
	inc hl
	ld a,[hl]
	cp a,$ff ; is it the end of the table?
	jr nz,.loop
.addNewItem ; add an item not yet in the inventory
	pop hl
	ld a,d
	and a ; is there room for a new item slot?
	jr z,.done
; if there is room
	inc [hl] ; increment the number of items in the inventory
	ld a,[hl] ; the number of items will be the index of the new item
	add a
	dec a
	ld c,a
	ld b,0
	add hl,bc ; hl = address to store the item
	ld a,[$cf91]
	ld [hli],a ; store item ID
	ld a,[$cf96]
	ld [hli],a ; store item quantity
	ld [hl],$ff ; store terminator
	jp .success
.increaseItemQuantity ; increase the quantity of an item already in the inventory
	ld a,[$cf96]
	ld b,a ; b = quantity to add
	ld a,[hl] ; a = existing item quantity
	add b ; a = new item quantity
	cp a,100
	jp c,.storeNewQuantity ; if the new quantity is less than 100, store it
; if the new quantity is greater than or equal to 100,
; try to max out the current slot and add the rest in a new slot
	sub a,99
	ld [$cf96],a ; a = amount left over (to put in the new slot)
	ld a,d
	and a ; is there room for a new item slot?
	jr z,.increaseItemQuantityFailed
; if so, store 99 in the current slot and store the rest in a new slot
	ld a,99
	ld [hli],a
	jp .loop
.increaseItemQuantityFailed
	pop hl
	and a
	jr .done
.storeNewQuantity
	ld [hl],a
	pop hl
.success
	scf
.done
	pop hl
	pop de
	pop bc
	pop bc
	ld a,b
	ld [$cf96],a ; restore the initial value from when the function was called
	ret

; function to remove an item (in varying quantities) from the player's bag or PC box
; INPUT:
; hl = address of inventory (either wNumBagItems or wNumBoxItems)
; [$CF92] = index (within the inventory) of the item to remove
; [$CF96] = quantity to remove
RemoveItemFromInventory_: ; ce74 (3:4e74)
	push hl
	inc hl
	ld a,[wWhichPokemon] ; index (within the inventory) of the item being removed
	sla a
	add l
	ld l,a
	jr nc,.noCarry
	inc h
.noCarry
	inc hl
	ld a,[$cf96] ; quantity being removed
	ld e,a
	ld a,[hl] ; a = current quantity
	sub e
	ld [hld],a ; store new quantity
	ld [$cf97],a
	and a
	jr nz,.skipMovingUpSlots
; if the remaining quantity is 0,
; remove the emptied item slot and move up all the following item slots
.moveSlotsUp
	ld e,l
	ld d,h
	inc de
	inc de ; de = address of the slot following the emptied one
.loop ; loop to move up the following slots
	ld a,[de]
	inc de
	ld [hli],a
	cp a,$ff
	jr nz,.loop
; update menu info
	xor a
	ld [wListScrollOffset],a
	ld [wCurrentMenuItem],a
	ld [$cc2c],a
	ld [$d07e],a
	pop hl
	ld a,[hl] ; a = number of items in inventory
	dec a ; decrement the number of items
	ld [hl],a ; store new number of items
	ld [$d12a],a
	cp a,2
	jr c,.done
	ld [wMaxMenuItem],a
	jr .done
.skipMovingUpSlots
	pop hl
.done
	ret

; wild pokemon data: from 4EB8 to 55C7

LoadWildData: ; ceb8 (3:4eb8)
	ld hl,WildDataPointers
	ld a,[W_CURMAP]

	; get wild data for current map
	ld c,a
	ld b,0
	add hl,bc
	add hl,bc
	ld a,[hli]
	ld h,[hl]
	ld l,a       ; hl now points to wild data for current map
	ld a,[hli]
	ld [W_GRASSRATE],a
	and a
	jr z,.NoGrassData ; if no grass data, skip to surfing data
	push hl
	ld de,W_GRASSMONS ; otherwise, load grass data
	ld bc,$0014
	call CopyData
	pop hl
	ld bc,$0014
	add hl,bc
.NoGrassData
	ld a,[hli]
	ld [W_WATERRATE],a
	and a
	ret z        ; if no water data, we're done
	ld de,W_WATERMONS  ; otherwise, load surfing data
	ld bc,$0014
	jp CopyData

INCLUDE "data/wild_mons.asm"

UseItem_: ; d5c7 (3:55c7)
	ld a,1
	ld [$cd6a],a
	ld a,[$cf91]	;contains item_ID
	cp a,HM_01
	jp nc,ItemUseTMHM
	ld hl,ItemUsePtrTable
	dec a
	add a
	ld c,a
	ld b,0
	add hl,bc
	ld a,[hli]
	ld h,[hl]
	ld l,a
	jp [hl]

ItemUsePtrTable: ; d5e1 (3:55e1)
	dw ItemUseBall       ; MASTER_BALL
	dw ItemUseBall       ; ULTRA_BALL
	dw ItemUseBall       ; GREAT_BALL
	dw ItemUseBall       ; POKE_BALL
	dw ItemUseTownMap    ; TOWN_MAP
	dw ItemUseBicycle    ; BICYCLE
	dw ItemUseSurfboard  ; out-of-battle Surf effect
	dw ItemUseBall       ; SAFARI_BALL
	dw ItemUsePokedex    ; POKEDEX
	dw ItemUseEvoStone   ; MOON_STONE
	dw ItemUseMedicine   ; ANTIDOTE
	dw ItemUseMedicine   ; BURN_HEAL
	dw ItemUseMedicine   ; ICE_HEAL
	dw ItemUseMedicine   ; AWAKENING
	dw ItemUseMedicine   ; PARLYZ_HEAL
	dw ItemUseMedicine   ; FULL_RESTORE
	dw ItemUseMedicine   ; MAX_POTION
	dw ItemUseMedicine   ; HYPER_POTION
	dw ItemUseMedicine   ; SUPER_POTION
	dw ItemUseMedicine   ; POTION
	dw ItemUseBait       ; BOULDERBADGE
	dw ItemUseRock       ; CASCADEBADGE
	dw UnusableItem      ; THUNDERBADGE
	dw UnusableItem      ; RAINBOWBADGE
	dw UnusableItem      ; SOULBADGE
	dw UnusableItem      ; MARSHBADGE
	dw UnusableItem      ; VOLCANOBADGE
	dw UnusableItem      ; EARTHBADGE
	dw ItemUseEscapeRope ; ESCAPE_ROPE
	dw ItemUseRepel      ; REPEL
	dw UnusableItem      ; OLD_AMBER
	dw ItemUseEvoStone   ; FIRE_STONE
	dw ItemUseEvoStone   ; THUNDER_STONE
	dw ItemUseEvoStone   ; WATER_STONE
	dw ItemUseVitamin    ; HP_UP
	dw ItemUseVitamin    ; PROTEIN
	dw ItemUseVitamin    ; IRON
	dw ItemUseVitamin    ; CARBOS
	dw ItemUseVitamin    ; CALCIUM
	dw ItemUseVitamin    ; RARE_CANDY
	dw UnusableItem      ; DOME_FOSSIL
	dw UnusableItem      ; HELIX_FOSSIL
	dw UnusableItem      ; SECRET_KEY
	dw UnusableItem
	dw UnusableItem      ; BIKE_VOUCHER
	dw ItemUseXAccuracy  ; X_ACCURACY
	dw ItemUseEvoStone   ; LEAF_STONE
	dw ItemUseCardKey    ; CARD_KEY
	dw UnusableItem      ; NUGGET
	dw UnusableItem      ; ??? PP_UP
	dw ItemUsePokedoll   ; POKE_DOLL
	dw ItemUseMedicine   ; FULL_HEAL
	dw ItemUseMedicine   ; REVIVE
	dw ItemUseMedicine   ; MAX_REVIVE
	dw ItemUseGuardSpec  ; GUARD_SPEC_
	dw ItemUseSuperRepel ; SUPER_REPL
	dw ItemUseMaxRepel   ; MAX_REPEL
	dw ItemUseDireHit    ; DIRE_HIT
	dw UnusableItem      ; COIN
	dw ItemUseMedicine   ; FRESH_WATER
	dw ItemUseMedicine   ; SODA_POP
	dw ItemUseMedicine   ; LEMONADE
	dw UnusableItem      ; S_S__TICKET
	dw UnusableItem      ; GOLD_TEETH
	dw ItemUseXStat      ; X_ATTACK
	dw ItemUseXStat      ; X_DEFEND
	dw ItemUseXStat      ; X_SPEED
	dw ItemUseXStat      ; X_SPECIAL
	dw ItemUseCoinCase   ; COIN_CASE
	dw ItemUseOaksParcel ; OAKS_PARCEL
	dw ItemUseItemfinder ; ITEMFINDER
	dw UnusableItem      ; SILPH_SCOPE
	dw ItemUsePokeflute  ; POKE_FLUTE
	dw UnusableItem      ; LIFT_KEY
	dw UnusableItem      ; EXP__ALL
	dw OldRodCode        ; OLD_ROD
	dw GoodRodCode       ; GOOD_ROD
	dw SuperRodCode      ; SUPER_ROD
	dw ItemUsePPUp       ; PP_UP (real one)
	dw ItemUsePPRestore  ; ETHER
	dw ItemUsePPRestore  ; MAX_ETHER
	dw ItemUsePPRestore  ; ELIXER
	dw ItemUsePPRestore  ; MAX_ELIXER

ItemUseBall: ; d687 (3:5687)
	ld a,[W_ISINBATTLE]
	and a
	jp z,ItemUseNotTime ; not in battle
	dec a
	jp nz,ThrowBallAtTrainerMon
	ld a,[W_BATTLETYPE]
	dec a
	jr z,.UseBall
	ld a,[W_NUMINPARTY]	;is Party full?
	cp a,6
	jr nz,.UseBall
	ld a,[W_NUMINBOX]	;is Box full?
	cp a,20
	jp z,BoxFullCannotThrowBall
.UseBall	;$56a7
;ok, you can use a ball
	xor a
	ld [$d11c],a
	ld a,[W_BATTLETYPE]
	cp a,2		;SafariBattle
	jr nz,.skipSafariZoneCode
.safariZone
	; remove a Safari Ball from inventory
	ld hl,W_NUMSAFARIBALLS
	dec [hl]
.skipSafariZoneCode	;$56b6
	call GoPAL_SET_CF1C
	ld a,$43
	ld [$d11e],a
	call LoadScreenTilesFromBuffer1	;restore screenBuffer from Backup
	ld hl,ItemUseText00
	call PrintText
	callab IsGhostBattle
	ld b,$10
	jp z,.next12
	ld a,[W_BATTLETYPE]
	dec a
	jr nz,.notOldManBattle
.oldManBattle
	ld hl,W_GRASSRATE
	ld de,W_PLAYERNAME
	ld bc,11
	call CopyData ; save the player's name in the Wild Monster data (part of the Cinnabar Island Missingno glitch)
	jp .BallSuccess	;$578b
.notOldManBattle	;$56e9
	ld a,[W_CURMAP]
	cp a,POKEMONTOWER_6
	jr nz,.loop
	ld a,[W_ENEMYMONID]
	cp a,MAROWAK
	ld b,$10
	jp z,.next12
; if not fighting ghost Marowak, loop until a random number in the current
; pokeball's allowed range is found
.loop	;$56fa
	call GenRandom
	ld b,a
	ld hl,$cf91
	ld a,[hl]
	cp a,MASTER_BALL
	jp z,.BallSuccess	;$578b
	cp a,POKE_BALL
	jr z,.checkForAilments
	ld a,200
	cp b
	jr c,.loop	;get only numbers <= 200 for Great Ball
	ld a,[hl]
	cp a,GREAT_BALL
	jr z,.checkForAilments
	ld a,150	;get only numbers <= 150 for Ultra Ball
	cp b
	jr c,.loop
.checkForAilments	;$571a
; pokemon can be caught more easily with any (primary) status ailment
; Frozen/Asleep pokemon are relatively even easier to catch
; for Frozen/Asleep pokemon, any random number from 0-24 ensures a catch.
; for the others, a random number from 0-11 ensures a catch.
	ld a,[W_ENEMYMONSTATUS]	;status ailments
	and a
	jr z,.noAilments
	and a, 1 << FRZ | SLP	;is frozen and/or asleep?
	ld c,12
	jr z,.notFrozenOrAsleep
	ld c,25
.notFrozenOrAsleep	;$5728
	ld a,b
	sub c
	jp c,.BallSuccess	;$578b
	ld b,a
.noAilments	;$572e
	push bc		;save RANDOM number
	xor a
	ld [H_MULTIPLICAND],a
	ld hl,W_ENEMYMONMAXHP
	ld a,[hli]
	ld [H_MULTIPLICAND + 1],a
	ld a,[hl]
	ld [H_MULTIPLICAND + 2],a
	ld a,255
	ld [H_MULTIPLIER],a
	call Multiply	; MaxHP * 255
	ld a,[$cf91]
	cp a,GREAT_BALL
	ld a,12		;any other BallFactor
	jr nz,.next7
	ld a,8
.next7	;$574d
	ld [H_DIVISOR],a
	ld b,4		; number of bytes in dividend
	call Divide
	ld hl,W_ENEMYMONCURHP
	ld a,[hli]
	ld b,a
	ld a,[hl]

; explanation: we have a 16-bit value equal to [b << 8 | a].
; This number is divided by 4. The result is 8 bit (reg. a).
; Always bigger than zero.
	srl b
	rr a
	srl b
	rr a ; a = current HP / 4
	and a
	jr nz,.next8
	inc a
.next8	;$5766
	ld [H_DIVISOR],a
	ld b,4
	call Divide	; ((MaxHP * 255) / BallFactor) / (CurHP / 4)
	ld a,[H_QUOTIENT + 2]
	and a
	jr z,.next9
	ld a,255
	ld [H_QUOTIENT + 3],a
.next9	;$5776
	pop bc
	ld a,[$d007]	;enemy: Catch Rate
	cp b
	jr c,.next10
	ld a,[H_QUOTIENT + 2]
	and a
	jr nz,.BallSuccess ; if ((MaxHP * 255) / BallFactor) / (CurHP / 4) > 0x255, automatic success
	call GenRandom
	ld b,a
	ld a,[H_QUOTIENT + 3]
	cp b
	jr c,.next10
.BallSuccess	;$578b
	jr .BallSuccess2
.next10	;$578d
	ld a,[H_QUOTIENT + 3]
	ld [$d11e],a
	xor a
	ld [H_MULTIPLICAND],a
	ld [H_MULTIPLICAND + 1],a
	ld a,[$d007]	;enemy: Catch Rate
	ld [H_MULTIPLICAND + 2],a
	ld a,100
	ld [H_MULTIPLIER],a
	call Multiply	; CatchRate * 100
	ld a,[$cf91]
	ld b,255
	cp a,POKE_BALL
	jr z,.next11
	ld b,200
	cp a,GREAT_BALL
	jr z,.next11
	ld b,150
	cp a,ULTRA_BALL
	jr z,.next11
.next11	;$57b8
	ld a,b
	ld [H_DIVISOR],a
	ld b,4
	call Divide
	ld a,[H_QUOTIENT + 2]
	and a
	ld b,$63
	jr nz,.next12
	ld a,[$d11e]
	ld [H_MULTIPLIER],a
	call Multiply
	ld a,255
	ld [H_DIVISOR],a
	ld b,4
	call Divide
	ld a,[W_ENEMYMONSTATUS]	;status ailments
	and a
	jr z,.next13
	and a, 1 << FRZ | SLP
	ld b,5
	jr z,.next14
	ld b,10
.next14	;$57e6
	ld a,[H_QUOTIENT + 3]
	add b
	ld [H_QUOTIENT + 3],a
.next13	;$57eb
	ld a,[H_QUOTIENT + 3]
	cp a,10
	ld b,$20
	jr c,.next12
	cp a,30
	ld b,$61
	jr c,.next12
	cp a,70
	ld b,$62
	jr c,.next12
	ld b,$63
.next12	;$5801
	ld a,b
	ld [$d11e],a
.BallSuccess2	;$5805
	ld c,20
	call DelayFrames
	ld a,TOSS_ANIM
	ld [W_ANIMATIONID],a
	xor a
	ld [$fff3],a
	ld [$cc5b],a
	ld [$d05b],a
	ld a,[wWhichPokemon]
	push af
	ld a,[$cf91]
	push af
	ld a,$08	;probably animations
	call Predef
	pop af
	ld [$cf91],a
	pop af
	ld [wWhichPokemon],a
	ld a,[$d11e]
	cp a,$10
	ld hl,ItemUseBallText00
	jp z,.printText0
	cp a,$20
	ld hl,ItemUseBallText01
	jp z,.printText0
	cp a,$61
	ld hl,ItemUseBallText02
	jp z,.printText0
	cp a,$62
	ld hl,ItemUseBallText03
	jp z,.printText0
	cp a,$63
	ld hl,ItemUseBallText04
	jp z,.printText0
	ld hl,$cfe6	;current HP
	ld a,[hli]
	push af
	ld a,[hli]
	push af		;backup currentHP...
	inc hl
	ld a,[hl]
	push af		;...and status ailments
	push hl
	ld hl,$d069
	bit 3,[hl]
	jr z,.next15
	ld a,$4c
	ld [W_ENEMYMONID],a
	jr .next16
.next15	;$5871
	set 3,[hl]
	ld hl,$cceb
	ld a,[$cff1]
	ld [hli],a
	ld a,[$cff2]
	ld [hl],a
.next16	;$587e
	ld a,[$cf91]
	push af
	ld a,[W_ENEMYMONID]
	ld [$cf91],a
	ld a,[$cff3]
	ld [$d127],a
	callab Func_3eb01
	pop af
	ld [$cf91],a
	pop hl
	pop af
	ld [hld],a
	dec hl
	pop af
	ld [hld],a
	pop af
	ld [hl],a
	ld a,[$cfe5]	;enemy
	ld [$d11c],a
	ld [$cf91],a
	ld [$d11e],a
	ld a,[W_BATTLETYPE]
	dec a
	jr z,.printText1
	ld hl,ItemUseBallText05
	call PrintText
	ld a,$3a	;convert order: Internal->Dex
	call Predef
	ld a,[$d11e]
	dec a
	ld c,a
	ld b,2
	ld hl,wPokedexOwned	;Dex_own_flags (pokemon)
	ld a,$10
	call Predef	;check Dex flag (own already or not)
	ld a,c
	push af
	ld a,[$d11e]
	dec a
	ld c,a
	ld b,1
	ld a,$10	;set Dex_own_flag?
	call Predef
	pop af
	and a
	jr nz,.checkParty
	ld hl,ItemUseBallText06
	call PrintText
	call CleanLCD_OAM
	ld a,[$cfe5]	;caught mon_ID
	ld [$d11e],a
	ld a,$3d
	call Predef
.checkParty	;$58f4
	ld a,[W_NUMINPARTY]
	cp a,6		;is party full?
	jr z,.sendToBox
	xor a
	ld [$cc49],a
	call CleanLCD_OAM
	call AddPokemonToParty	;add mon to Party
	jr .End
.sendToBox	;$5907
	call CleanLCD_OAM
	call Func_e7a4
	ld hl,ItemUseBallText07
	ld a,[$d7f1]
	bit 0,a		;already met Bill?
	jr nz,.sendToBox2
	ld hl,ItemUseBallText08
.sendToBox2	;$591a
	call PrintText
	jr .End
.printText1	;$591f
	ld hl,ItemUseBallText05
.printText0	;$5922
	call PrintText
	call CleanLCD_OAM
.End	;$5928
	ld a,[W_BATTLETYPE]
	and a
	ret nz
	ld hl,$d31d
	inc a
	ld [$cf96],a
	jp RemoveItemFromInventory	;remove ITEM (XXX)
ItemUseBallText00: ; d937 (3:5937)
;"It dodged the thrown ball!"
;"This pokemon can't be caught"
	TX_FAR _ItemUseBallText00
	db "@"
ItemUseBallText01: ; d93c (3:593c)
;"You missed the pokemon!"
	TX_FAR _ItemUseBallText01
	db "@"
ItemUseBallText02: ; d941 (3:5941)
;"Darn! The pokemon broke free!"
	TX_FAR _ItemUseBallText02
	db "@"
ItemUseBallText03: ; d946 (3:5946)
;"Aww! It appeared to be caught!"
	TX_FAR _ItemUseBallText03
	db "@"
ItemUseBallText04: ; d94b (3:594b)
;"Shoot! It was so close too!"
	TX_FAR _ItemUseBallText04
	db "@"
ItemUseBallText05: ; d950 (3:5950)
;"All right! {MonName} was caught!"
;play sound
	TX_FAR _ItemUseBallText05
	db $12,$06
	db "@"
ItemUseBallText07: ; d957 (3:5957)
;"X was transferred to Bill's PC"
	TX_FAR _ItemUseBallText07
	db "@"
ItemUseBallText08: ; d95c (3:595c)
;"X was transferred to someone's PC"
	TX_FAR _ItemUseBallText08
	db "@"

ItemUseBallText06: ; d961 (3:5961)
;"New DEX data will be added..."
;play sound
	TX_FAR _ItemUseBallText06
	db $13,$06
	db "@"

ItemUseTownMap: ; d968 (3:5968)
	ld a,[W_ISINBATTLE]
	and a
	jp nz,ItemUseNotTime
	ld b, BANK(DisplayTownMap)
	ld hl, DisplayTownMap
	jp Bankswitch ; display Town Map

ItemUseBicycle: ; d977 (3:5977)
	ld a,[W_ISINBATTLE]
	and a
	jp nz,ItemUseNotTime
	ld a,[$d700]
	ld [$d11a],a
	cp a,2 ; is the player surfing?
	jp z,ItemUseNotTime
	dec a ; is player already bicycling?
	jr nz,.tryToGetOnBike
.getOffBike
	call ItemUseReloadOverworldData
	xor a
	ld [$d700],a ; change player state to walking
	call Func_2307 ; play walking music
	ld hl,GotOffBicycleText
	jr .printText
.tryToGetOnBike
	call IsBikeRidingAllowed
	jp nc,NoCyclingAllowedHere
	call ItemUseReloadOverworldData
	xor a ; no keys pressed
	ld [H_CURRENTPRESSEDBUTTONS],a ; current joypad state
	inc a
	ld [$d700],a ; change player state to bicycling
	ld hl,GotOnBicycleText
	call Func_2307 ; play bike riding music
.printText
	jp PrintText

; used for Surf out-of-battle effect
ItemUseSurfboard: ; d9b4 (3:59b4)
	ld a,[$d700]
	ld [$d11a],a
	cp a,2 ; is the player already surfing?
	jr z,.tryToStopSurfing
.tryToSurf
	call IsNextTileShoreOrWater
	jp c,SurfingAttemptFailed
	ld hl,TilePairCollisionsWater
	call CheckForTilePairCollisions
	jp c,SurfingAttemptFailed
.surf
	call .makePlayerMoveForward
	ld hl,$d730
	set 7,[hl]
	ld a,2
	ld [$d700],a ; change player state to surfing
	call Func_2307 ; play surfing music
	ld hl,SurfingGotOnText
	jp PrintText
.tryToStopSurfing
	xor a
	ld [$ff8c],a
	ld d,16 ; talking range in pixels (normal range)
	call IsSpriteInFrontOfPlayer2
	res 7,[hl]
	ld a,[$ff8c]
	and a ; is there a sprite in the way?
	jr nz,.cannotStopSurfing
	ld hl,TilePairCollisionsWater
	call CheckForTilePairCollisions
	jr c,.cannotStopSurfing
	ld hl,$d530 ; pointer to list of passable tiles
	ld a,[hli]
	ld h,[hl]
	ld l,a ; hl now points to passable tiles
	ld a,[$cfc6] ; tile in front of the player
	ld b,a
.passableTileLoop
	ld a,[hli]
	cp b
	jr z,.stopSurfing
	cp a,$ff
	jr nz,.passableTileLoop
.cannotStopSurfing
	ld hl,SurfingNoPlaceToGetOffText
	jp PrintText
.stopSurfing
	call .makePlayerMoveForward
	ld hl,$d730
	set 7,[hl]
	xor a
	ld [$d700],a ; change player state to walking
	dec a
	ld [wJoypadForbiddenButtonsMask],a
	call Func_2307 ; play walking music
	jp LoadWalkingPlayerSpriteGraphics
; uses a simulated button press to make the player move forward
.makePlayerMoveForward
	ld a,[$d52a] ; direction the player is going
	bit 3,a
	ld b,%01000000 ; Up key
	jr nz,.storeSimulatedButtonPress
	bit 2,a
	ld b,%10000000 ; Down key
	jr nz,.storeSimulatedButtonPress
	bit 1,a
	ld b,%00100000 ; Left key
	jr nz,.storeSimulatedButtonPress
	ld b,%00010000 ; Right key
.storeSimulatedButtonPress
	ld a,b
	ld [$ccd3],a ; base address of simulated button presses
	xor a
	ld [$cd39],a
	inc a
	ld [$cd38],a ; index of current simulated button press
	ret

SurfingGotOnText: ; da4c (3:5a4c)
	TX_FAR _SurfingGotOnText
	db "@"

SurfingNoPlaceToGetOffText: ; da51 (3:5a51)
	TX_FAR _SurfingNoPlaceToGetOffText
	db "@"

ItemUsePokedex: ; da56 (3:5a56)
	ld a,$29
	jp Predef

ItemUseEvoStone: ; da5b (3:5a5b)
	ld a,[W_ISINBATTLE]
	and a
	jp nz,ItemUseNotTime
	ld a,[wWhichPokemon]
	push af
	ld a,[$cf91]
	ld [$d156],a
	push af
	ld a,$05 ; evolution stone party menu
	ld [$d07d],a
	ld a,$ff
	ld [$cfcb],a
	call DisplayPartyMenu
	pop bc
	jr c,.canceledItemUse
	ld a,b
	ld [$cf91],a
	ld a,$01
	ld [$ccd4],a
	ld a,(SFX_02_3e - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent ; play sound
	call WaitForSoundToFinish ; wait for sound to end
	callab Func_3ad0e ; try to evolve pokemon
	ld a,[$d121]
	and a
	jr z,.noEffect
	pop af
	ld [wWhichPokemon],a
	ld hl,wNumBagItems
	ld a,1 ; remove 1 stone
	ld [$cf96],a
	jp RemoveItemFromInventory
.noEffect
	call ItemUseNoEffect
.canceledItemUse
	xor a
	ld [$cd6a],a
	pop af
	ret

ItemUseVitamin: ; dab4 (3:5ab4)
	ld a,[W_ISINBATTLE]
	and a
	jp nz,ItemUseNotTime

ItemUseMedicine: ; dabb (3:5abb)
	ld a,[W_NUMINPARTY]
	and a
	jp z,.emptyParty
	ld a,[wWhichPokemon]
	push af
	ld a,[$cf91]
	push af
	ld a,$01
	ld [$d07d],a ; item use party menu
	ld a,$ff
	ld [$cfcb],a
	ld a,[$d152]
	and a ; using Softboiled?
	jr z,.notUsingSoftboiled
; if using softboiled
	call GoBackToPartyMenu
	jr .getPartyMonDataAddress
.emptyParty
	ld hl,.emptyPartyText
	xor a
	ld [$cd6a],a ; item use failed
	jp PrintText
.emptyPartyText
	text "You don't have"
	line "any #MON!"
	prompt
.notUsingSoftboiled
	call DisplayPartyMenu
.getPartyMonDataAddress
	jp c,.canceledItemUse
	ld hl,W_PARTYMON1DATA
	ld bc,44
	ld a,[wWhichPokemon]
	call AddNTimes
	ld a,[wWhichPokemon]
	ld [$cf06],a
	ld d,a
	ld a,[$cf91]
	ld e,a
	ld [$d0b5],a
	pop af
	ld [$cf91],a
	pop af
	ld [wWhichPokemon],a
	ld a,[$d152]
	and a ; using Softboiled?
	jr z,.checkItemType
; if using softboiled
	ld a,[wWhichPokemon]
	cp d ; is the pokemon trying to use softboiled on itself?
	jr z,ItemUseMedicine ; if so, force another choice
.checkItemType
	ld a,[$cf91]
	cp a,REVIVE
	jr nc,.healHP ; if it's a Revive or Max Revive
	cp a,FULL_HEAL
	jr z,.cureStatusAilment ; if it's a Full Heal
	cp a,HP_UP
	jp nc,.useVitamin ; if it's a vitamin or Rare Candy
	cp a,FULL_RESTORE
	jr nc,.healHP ; if it's a Full Restore or one of the potions
; fall through if it's one of the status-specifc healing items
.cureStatusAilment
	ld bc,4
	add hl,bc ; hl now points to status
	ld a,[$cf91]
	ld bc,$f008
	cp a,ANTIDOTE
	jr z,.checkMonStatus
	ld bc,$f110
	cp a,BURN_HEAL
	jr z,.checkMonStatus
	ld bc,$f220
	cp a,ICE_HEAL
	jr z,.checkMonStatus
	ld bc,$f307
	cp a,AWAKENING
	jr z,.checkMonStatus
	ld bc,$f440
	cp a,PARLYZ_HEAL
	jr z,.checkMonStatus
	ld bc,$f6ff ; Full Heal
.checkMonStatus
	ld a,[hl] ; pokemon's status
	and c ; does the pokemon have a status ailment the item can cure?
	jp z,.healingItemNoEffect
; if the pokemon has a status the item can heal
	xor a
	ld [hl],a ; remove the status ailment in the party data
	ld a,b
	ld [$d07d],a ; the message to display for the item used
	ld a,[wPlayerMonNumber]
	cp d ; is pokemon the item was used on active in battle?
	jp nz,.doneHealing
; if it is active in battle
	xor a
	ld [W_PLAYERMONSTATUS],a ; remove the status ailment in the in-battle pokemon data
	push hl
	ld hl,W_PLAYERBATTSTATUS3
	res 0,[hl] ; heal Toxic status
	pop hl
	ld bc,30
	add hl,bc ; hl now points to party stats
	ld de,W_PLAYERMONMAXHP
	ld bc,10
	call CopyData ; copy party stats to in-battle stat data
	ld a,$28
	call Predef
	jp .doneHealing
.healHP
	inc hl ; hl = address of current HP
	ld a,[hli]
	ld b,a
	ld [wHPBarOldHP+1],a
	ld a,[hl]
	ld c,a
	ld [wHPBarOldHP],a ; current HP stored at $ceeb (2 bytes, big-endian)
	or b
	jr nz,.notFainted
.fainted
	ld a,[$cf91]
	cp a,REVIVE
	jr z,.updateInBattleFaintedData
	cp a,MAX_REVIVE
	jr z,.updateInBattleFaintedData
	jp .healingItemNoEffect
.updateInBattleFaintedData
	ld a,[W_ISINBATTLE]
	and a
	jr z,.compareCurrentHPToMaxHP
	push hl
	push de
	push bc
	ld a,[$cf06]
	ld c,a
	ld hl,$ccf5
	ld b,$02
	ld a,$10
	call Predef
	ld a,c
	and a
	jr z,.next
	ld a,[$cf06]
	ld c,a
	ld hl,W_PLAYERMONSALIVEFLAGS
	ld b,$01
	ld a,$10
	call Predef
.next
	pop bc
	pop de
	pop hl
	jr .compareCurrentHPToMaxHP
.notFainted
	ld a,[$cf91]
	cp a,REVIVE
	jp z,.healingItemNoEffect
	cp a,MAX_REVIVE
	jp z,.healingItemNoEffect
.compareCurrentHPToMaxHP
	push hl
	push bc
	ld bc,32
	add hl,bc ; hl now points to max HP
	pop bc
	ld a,[hli]
	cp b
	jr nz,.skipComparingLSB ; no need to compare the LSB's if the MSB's don't match
	ld a,[hl]
	cp c
.skipComparingLSB
	pop hl
	jr nz,.notFullHP
.fullHP ; if the pokemon's current HP equals its max HP
	ld a,[$cf91]
	cp a,FULL_RESTORE
	jp nz,.healingItemNoEffect
	inc hl
	inc hl
	ld a,[hld] ; status ailment
	and a ; does the pokemon have a status ailment?
	jp z,.healingItemNoEffect
	ld a,FULL_HEAL
	ld [$cf91],a
	dec hl
	dec hl
	dec hl
	jp .cureStatusAilment
.notFullHP ; if the pokemon's current HP doesn't equal its max HP
	xor a
	ld [$d083],a
	ld [$c02a],a
	push hl
	push de
	ld bc,32
	add hl,bc ; hl now points to max HP
	ld a,[hli]
	ld [wHPBarMaxHP+1],a
	ld a,[hl]
	ld [wHPBarMaxHP],a ; max HP stored at $cee9 (2 bytes, big-endian)
	ld a,[$d152]
	and a ; using Softboiled?
	jp z,.notUsingSoftboiled2
; if using softboiled
	ld hl,wHPBarMaxHP
	ld a,[hli]
	push af
	ld a,[hli]
	push af
	ld a,[hli]
	push af
	ld a,[hl]
	push af
	ld hl,W_PARTYMON1_MAXHP
	ld a,[wWhichPokemon]
	ld bc,44
	call AddNTimes
	ld a,[hli]
	ld [$ceea],a
	ld [H_DIVIDEND],a
	ld a,[hl]
	ld [wHPBarMaxHP],a
	ld [H_DIVIDEND + 1],a
	ld a,5
	ld [H_DIVISOR],a
	ld b,2 ; number of bytes
	call Divide ; get 1/5 of max HP of pokemon that used Softboiled
	ld bc,-33
	add hl,bc ; hl now points to LSB of current HP of pokemon that used Softboiled
; subtract 1/5 of max HP from current HP of pokemon that used Softboiled
	ld a,[H_QUOTIENT + 3]
	push af
	ld b,a
	ld a,[hl]
	ld [wHPBarOldHP],a
	sub b
	ld [hld],a
	ld [wHPBarNewHP],a
	ld a,[H_QUOTIENT + 2]
	ld b,a
	ld a,[hl]
	ld [wHPBarOldHP+1],a
	sbc b
	ld [hl],a
	ld [wHPBarNewHP+1],a
	FuncCoord 4, 1 ; $c3b8
	ld hl,Coord
	ld a,[wWhichPokemon]
	ld bc,2 * 20
	call AddNTimes ; calculate coordinates of HP bar of pokemon that used Softboiled
	ld a,(SFX_02_3d - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent ; play sound
	ld a,[$fff6]
	set 0,a
	ld [$fff6],a
	ld a,$02
	ld [$cf94],a
	ld a,$48
	call Predef ; animate HP bar decrease of pokemon that used Softboiled
	ld a,[$fff6]
	res 0,a
	ld [$fff6],a
	pop af
	ld b,a ; store heal amount (1/5 of max HP)
	ld hl,$ceec
	pop af
	ld [hld],a
	pop af
	ld [hld],a
	pop af
	ld [hld],a
	pop af
	ld [hl],a
	jr .addHealAmount
.notUsingSoftboiled2
	ld a,[$cf91]
	cp a,SODA_POP
	ld b,60 ; Soda Pop heal amount
	jr z,.addHealAmount
	ld b,80 ; Lemonade heal amount
	jr nc,.addHealAmount
	cp a,FRESH_WATER
	ld b,50 ; Fresh Water heal amount
	jr z,.addHealAmount
	cp a,SUPER_POTION
	ld b,200 ; Hyper Potion heal amount
	jr c,.addHealAmount
	ld b,50 ; Super Potion heal amount
	jr z,.addHealAmount
	ld b,20 ; Potion heal amount
.addHealAmount
	pop de
	pop hl
	ld a,[hl]
	add b
	ld [hld],a
	ld [wHPBarNewHP],a
	ld a,[hl]
	ld [wHPBarNewHP+1],a
	jr nc,.noCarry
	inc [hl]
	ld a,[hl]
	ld [$ceee],a
.noCarry
	push de
	inc hl
	ld d,h
	ld e,l ; de now points to current HP
	ld hl,33
	add hl,de ; hl now points to max HP
	ld a,[$cf91]
	cp a,REVIVE
	jr z,.setCurrentHPToHalfMaxHP
	ld a,[hld]
	ld b,a
	ld a,[de]
	sub b
	dec de
	ld b,[hl]
	ld a,[de]
	sbc b
	jr nc,.setCurrentHPToMaxHp ; if current HP exceeds max HP after healing
	ld a,[$cf91]
	cp a,HYPER_POTION
	jr c,.setCurrentHPToMaxHp ; if using a Full Restore or Max Potion
	cp a,MAX_REVIVE
	jr z,.setCurrentHPToMaxHp ; if using a Max Revive
	jr .updateInBattleData
.setCurrentHPToHalfMaxHP
	dec hl
	dec de
	ld a,[hli]
	srl a
	ld [de],a
	ld [wHPBarNewHP+1],a
	ld a,[hl]
	rr a
	inc de
	ld [de],a
	ld [wHPBarNewHP],a
	dec de
	jr .doneHealingPartyHP
.setCurrentHPToMaxHp
	ld a,[hli]
	ld [de],a
	ld [wHPBarNewHP+1],a
	inc de
	ld a,[hl]
	ld [de],a
	ld [wHPBarNewHP],a
	dec de
.doneHealingPartyHP ; done updating the pokemon's current HP in the party data structure
	ld a,[$cf91]
	cp a,FULL_RESTORE
	jr nz,.updateInBattleData
	ld bc,-31
	add hl,bc
	xor a
	ld [hl],a ; remove the status ailment in the party data
.updateInBattleData
	ld h,d
	ld l,e
	pop de
	ld a,[wPlayerMonNumber]
	cp d ; is pokemon the item was used on active in battle?
	jr nz,.calculateHPBarCoords
; copy party HP to in-battle HP
	ld a,[hli]
	ld [W_PLAYERMONCURHP],a
	ld a,[hld]
	ld [W_PLAYERMONCURHP + 1],a
	ld a,[$cf91]
	cp a,FULL_RESTORE
	jr nz,.calculateHPBarCoords
	xor a
	ld [W_PLAYERMONSTATUS],a ; remove the status ailment in the in-battle pokemon data
.calculateHPBarCoords
	ld hl,$c390
	ld bc,2 * 20
	inc d
.calculateHPBarCoordsLoop
	add hl,bc
	dec d
	jr nz,.calculateHPBarCoordsLoop
	jr .doneHealing
.healingItemNoEffect
	call ItemUseNoEffect
	jp .done
.doneHealing
	ld a,[$d152]
	and a ; using Softboiled?
	jr nz,.skipRemovingItem ; no item to remove if using Softboiled
	push hl
	call RemoveUsedItem
	pop hl
.skipRemovingItem
	ld a,[$cf91]
	cp a,FULL_RESTORE
	jr c,.playStatusAilmentCuringSound
	cp a,FULL_HEAL
	jr z,.playStatusAilmentCuringSound
	ld a,(SFX_02_3d - SFX_Headers_02) / 3 ; HP healing sound
	call PlaySoundWaitForCurrent ; play sound
	ld a,[$fff6]
	set 0,a
	ld [$fff6],a
	ld a,$02
	ld [$cf94],a
	ld a,$48
	call Predef ; animate the HP bar lengthening
	ld a,[$fff6]
	res 0,a
	ld [$fff6],a
	ld a,$f7 ; revived message
	ld [$d07d],a
	ld a,[$cf91]
	cp a,REVIVE
	jr z,.showHealingItemMessage
	cp a,MAX_REVIVE
	jr z,.showHealingItemMessage
	ld a,$f5 ; standard HP healed message
	ld [$d07d],a
	jr .showHealingItemMessage
.playStatusAilmentCuringSound
	ld a,(SFX_02_3e - SFX_Headers_02) / 3 ; status ailment curing sound
	call PlaySoundWaitForCurrent ; play sound
.showHealingItemMessage
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a
	call ClearScreen
	dec a
	ld [$cfcb],a
	call RedrawPartyMenu ; redraws the party menu and displays the message
	ld a,1
	ld [H_AUTOBGTRANSFERENABLED],a
	ld c,50
	call DelayFrames
	call WaitForTextScrollButtonPress ; wait for a button press
	jr .done
.canceledItemUse
	xor a
	ld [$cd6a],a ; item use failed
	pop af
	pop af
.done
	ld a,[$d152]
	and a ; using Softboiled?
	ret nz ; if so, return
	call GBPalWhiteOut
	call z,GoPAL_SET_CF1C
	ld a,[W_ISINBATTLE]
	and a
	ret nz
	jp ReloadMapData ; restore saved screen
.useVitamin
	push hl
	ld a,[hl]
	ld [$d0b5],a
	ld [$d11e],a
	ld bc,33
	add hl,bc ; hl now points to level
	ld a,[hl] ; a = level
	ld [$d127],a ; store level
	call GetMonHeader
	push de
	ld a,d
	ld hl,W_PARTYMON1NAME
	call GetPartyMonName
	pop de
	pop hl
	ld a,[$cf91]
	cp a,RARE_CANDY
	jp z,.useRareCandy
	push hl
	sub a,HP_UP
	add a
	ld bc,17
	add hl,bc
	add l
	ld l,a
	jr nc,.noCarry2
	inc h
.noCarry2
	ld a,10
	ld b,a
	ld a,[hl] ; a = MSB of stat experience of the appropriate stat
	cp a,100 ; is there already at least 25600 (256 * 100) stat experience?
	jr nc,.vitaminNoEffect ; if so, vitamins can't add any more
	add b ; add 2560 (256 * 10) stat experience
	jr nc,.noCarry3 ; a carry should be impossible here, so this will always jump
	ld a,255
.noCarry3
	ld [hl],a
	pop hl
	call .recalculateStats
	ld hl,VitaminText
	ld a,[$cf91]
	sub a,HP_UP - 1
	ld c,a
.statNameLoop ; loop to get the address of the name of the stat the vitamin increases
	dec c
	jr z,.gotStatName
.statNameInnerLoop
	ld a,[hli]
	ld b,a
	ld a,$50
	cp b
	jr nz,.statNameInnerLoop
	jr .statNameLoop
.gotStatName
	ld de,$cf4b
	ld bc,10
	call CopyData ; copy the stat's name to $cf4b
	ld a,(SFX_02_3e - SFX_Headers_02) / 3
	call PlaySound ; play sound
	ld hl,VitaminStatRoseText
	call PrintText
	jp RemoveUsedItem
.vitaminNoEffect
	pop hl
	ld hl,VitaminNoEffectText
	call PrintText
	jp GBPalWhiteOut
.recalculateStats
	ld bc,34
	add hl,bc
	ld d,h
	ld e,l ; de now points to stats
	ld bc,-18
	add hl,bc ; hl now points to byte 3 of experience
	ld b,1
	jp CalcStats ; recalculate stats
.useRareCandy
	push hl
	ld bc,33
	add hl,bc ; hl now points to level
	ld a,[hl] ; a = level
	cp a,100
	jr z,.vitaminNoEffect ; can't raise level above 100
	inc a
	ld [hl],a ; store incremented level
	ld [$d127],a
	push hl
	push de
	ld d,a
	callab CalcExperience ; calculate experience for next level and store it at $ff96
	pop de
	pop hl
	ld bc,-19
	add hl,bc ; hl now points to experience
; update experience to minimum for new level
	ld a,[$ff96]
	ld [hli],a
	ld a,[$ff97]
	ld [hli],a
	ld a,[$ff98]
	ld [hl],a
	pop hl
	ld a,[wWhichPokemon]
	push af
	ld a,[$cf91]
	push af
	push de
	push hl
	ld bc,34
	add hl,bc ; hl now points to MSB of max HP
	ld a,[hli]
	ld b,a
	ld c,[hl]
	pop hl
	push bc
	push hl
	call .recalculateStats
	pop hl
	ld bc,35 ; hl now points to LSB of max HP
	add hl,bc
	pop bc
	ld a,[hld]
	sub c
	ld c,a
	ld a,[hl]
	sbc b
	ld b,a ; bc = the amount of max HP gained from leveling up
; add the amount gained to the current HP
	ld de,-32
	add hl,de ; hl now points to MSB of current HP
	ld a,[hl]
	add c
	ld [hld],a
	ld a,[hl]
	adc b
	ld [hl],a
	ld a,$f8 ; level up message
	ld [$d07d],a
	call RedrawPartyMenu
	pop de
	ld a,d
	ld [wWhichPokemon],a
	ld a,e
	ld [$d11e],a
	xor a
	ld [$cc49],a ; load from player's party
	call LoadMonData
	ld d,$01
	callab PrintStatsBox ; display new stats text box
	call WaitForTextScrollButtonPress ; wait for button press
	xor a
	ld [$cc49],a
	ld a,$1a
	call Predef ; learn level up move, if any
	xor a
	ld [$ccd4],a
	callab Func_3ad0e ; evolve pokemon, if appropriate
	ld a,$01
	ld [$cfcb],a
	pop af
	ld [$cf91],a
	pop af
	ld [wWhichPokemon],a
	jp RemoveUsedItem

VitaminStatRoseText: ; df24 (3:5f24)
	TX_FAR _VitaminStatRoseText
	db "@"

VitaminNoEffectText: ; df29 (3:5f29)
	TX_FAR _VitaminNoEffectText
	db "@"

VitaminText: ; df2e (3:5f2e)
	db "HEALTH@"
	db "ATTACK@"
	db "DEFENSE@"
	db "SPEED@"
	db "SPECIAL@"

ItemUseBait: ; df52 (3:5f52)
	ld hl,ThrewBaitText
	call PrintText
	ld hl,$d007 ; catch rate
	srl [hl] ; halve catch rate
	ld a,BAIT_ANIM
	ld hl,$cce9 ; bait factor
	ld de,$cce8 ; escape factor
	jr BaitRockCommon

ItemUseRock: ; df67 (3:5f67)
	ld hl,ThrewRockText
	call PrintText
	ld hl,$d007 ; catch rate
	ld a,[hl]
	add a ; double catch rate
	jr nc,.noCarry
	ld a,$ff
.noCarry
	ld [hl],a
	ld a,ROCK_ANIM
	ld hl,$cce8 ; escape factor
	ld de,$cce9 ; bait factor

BaitRockCommon: ; df7f (3:5f7f)
	ld [W_ANIMATIONID],a
	xor a
	ld [$cc5b],a
	ld [H_WHOSETURN],a
	ld [de],a ; zero escape factor (for bait), zero bait factor (for rock)
.randomLoop ; loop until a random number less than 5 is generated
	call GenRandom
	and a,7
	cp a,5
	jr nc,.randomLoop
	inc a ; increment the random number, giving a range from 1 to 5 inclusive
	ld b,a
	ld a,[hl]
	add b ; increase bait factor (for bait), increase escape factor (for rock)
	jr nc,.noCarry
	ld a,$ff
.noCarry
	ld [hl],a
	ld a,$08
	call Predef ; do animation
	ld c,70
	jp DelayFrames

ThrewBaitText: ; dfa5 (3:5fa5)
	TX_FAR _ThrewBaitText
	db "@"

ThrewRockText: ; dfaa (3:5faa)
	TX_FAR _ThrewRockText
	db "@"

; also used for Dig out-of-battle effect
ItemUseEscapeRope: ; dfaf (3:5faf)
	ld a,[W_ISINBATTLE]
	and a
	jr nz,.notUsable
	ld a,[W_CURMAP]
	cp a,AGATHAS_ROOM
	jr z,.notUsable
	ld a,[W_CURMAPTILESET]
	ld b,a
	ld hl,EscapeRopeTilesets
.loop
	ld a,[hli]
	cp a,$ff
	jr z,.notUsable
	cp b
	jr nz,.loop
	ld hl,$d732
	set 3,[hl]
	set 6,[hl]
	ld hl,$d72e
	res 4,[hl]
	ld hl,$d790
	res 7,[hl] ; unset Safari Zone bit
	xor a
	ld [$da47],a
	ld [W_SAFARIZONEENTRANCECURSCRIPT],a
	inc a
	ld [$d078],a
	ld [$cd6a],a ; item used
	ld a,[$d152]
	and a ; using Dig?
	ret nz ; if so, return
	call ItemUseReloadOverworldData
	ld c,30
	call DelayFrames
	jp RemoveUsedItem
.notUsable
	jp ItemUseNotTime

EscapeRopeTilesets: ; dffd (3:5ffd)
	db FOREST, CEMETERY, CAVERN, FACILITY, INTERIOR
	db $ff ; terminator

ItemUseRepel: ; e003 (3:6003)
	ld b,100

ItemUseRepelCommon: ; e005 (3:6005)
	ld a,[W_ISINBATTLE]
	and a
	jp nz,ItemUseNotTime
	ld a,b
	ld [$d0db],a
	jp PrintItemUseTextAndRemoveItem

; handles X Accuracy item
ItemUseXAccuracy: ; e013 (3:6013)
	ld a,[W_ISINBATTLE]
	and a
	jp z,ItemUseNotTime
	ld hl,W_PLAYERBATTSTATUS2
	set 0,[hl] ; X Accuracy bit
	jp PrintItemUseTextAndRemoveItem

; This function is bugged and never works. It always jumps to ItemUseNotTime.
; The Card Key is handled in a different way.
ItemUseCardKey: ; e022 (3:6022)
	xor a
	ld [$d71f],a
	call Func_c586
	ld a,[Func_c586] ; $4586
	cp a,$18
	jr nz,.next0
	ld hl,CardKeyTable1
	jr .next1
.next0
	cp a,$24
	jr nz,.next2
	ld hl,CardKeyTable2
	jr .next1
.next2
	cp a,$5e
	jp nz,ItemUseNotTime
	ld hl,CardKeyTable3
.next1
	ld a,[W_CURMAP]
	ld b,a
.loop
	ld a,[hli]
	cp a,$ff
	jp z,ItemUseNotTime
	cp b
	jr nz,.nextEntry1
	ld a,[hli]
	cp d
	jr nz,.nextEntry2
	ld a,[hli]
	cp e
	jr nz,.nextEntry3
	ld a,[hl]
	ld [$d71f],a
	jr .done
.nextEntry1
	inc hl
.nextEntry2
	inc hl
.nextEntry3
	inc hl
	jr .loop
.done
	ld hl,ItemUseText00
	call PrintText
	ld hl,$d728
	set 7,[hl]
	ret

; These tables are probably supposed to be door locations in Silph Co.,
; but they are unused.
; The reason there are 3 tables is unknown.

; Format:
; 00: Map ID
; 01: Y
; 02: X
; 03: ID?

CardKeyTable1: ; e072 (3:6072)
	db  SILPH_CO_2F,$04,$04,$00
	db  SILPH_CO_2F,$04,$05,$01
	db  SILPH_CO_4F,$0C,$04,$02
	db  SILPH_CO_4F,$0C,$05,$03
	db  SILPH_CO_7F,$06,$0A,$04
	db  SILPH_CO_7F,$06,$0B,$05
	db  SILPH_CO_9F,$04,$12,$06
	db  SILPH_CO_9F,$04,$13,$07
	db SILPH_CO_10F,$08,$0A,$08
	db SILPH_CO_10F,$08,$0B,$09
	db $ff

CardKeyTable2: ; e09b (3:609b)
	db SILPH_CO_3F,$08,$09,$0A
	db SILPH_CO_3F,$09,$09,$0B
	db SILPH_CO_5F,$04,$07,$0C
	db SILPH_CO_5F,$05,$07,$0D
	db SILPH_CO_6F,$0C,$05,$0E
	db SILPH_CO_6F,$0D,$05,$0F
	db SILPH_CO_8F,$08,$07,$10
	db SILPH_CO_8F,$09,$07,$11
	db SILPH_CO_9F,$08,$03,$12
	db SILPH_CO_9F,$09,$03,$13
	db $ff

CardKeyTable3: ; e0c4 (3:60c4)
	db SILPH_CO_11F,$08,$09,$14
	db SILPH_CO_11F,$09,$09,$15
	db $ff

ItemUsePokedoll: ; e0cd (3:60cd)
	ld a,[W_ISINBATTLE]
	dec a
	jp nz,ItemUseNotTime
	ld a,$01
	ld [$d078],a
	jp PrintItemUseTextAndRemoveItem

ItemUseGuardSpec: ; e0dc (3:60dc)
	ld a,[W_ISINBATTLE]
	and a
	jp z,ItemUseNotTime
	ld hl,W_PLAYERBATTSTATUS2
	set 1,[hl] ; Mist bit
	jp PrintItemUseTextAndRemoveItem

ItemUseSuperRepel: ; e0eb (3:60eb)
	ld b,200
	jp ItemUseRepelCommon

ItemUseMaxRepel: ; e0f0 (3:60f0)
	ld b,250
	jp ItemUseRepelCommon

ItemUseDireHit: ; e0f5 (3:60f5)
	ld a,[W_ISINBATTLE]
	and a
	jp z,ItemUseNotTime
	ld hl,W_PLAYERBATTSTATUS2
	set 2,[hl] ; Focus Energy bit
	jp PrintItemUseTextAndRemoveItem

ItemUseXStat: ; e104 (3:6104)
	ld a,[W_ISINBATTLE]
	and a
	jr nz,.inBattle
	call ItemUseNotTime
	ld a,2
	ld [$cd6a],a ; item not used
	ret
.inBattle
	ld hl,W_PLAYERMOVENUM
	ld a,[hli]
	push af ; save [W_PLAYERMOVENUM]
	ld a,[hl]
	push af ; save [W_PLAYERMOVEEFFECT]
	push hl
	ld a,[$cf91]
	sub a,X_ATTACK - ATTACK_UP1_EFFECT
	ld [hl],a ; store player move effect
	call PrintItemUseTextAndRemoveItem
	ld a,XSTATITEM_ANIM ; X stat item animation ID
	ld [W_PLAYERMOVENUM],a
	call LoadScreenTilesFromBuffer1 ; restore saved screen
	call Delay3
	xor a
	ld [H_WHOSETURN],a ; set turn to player's turn
	callba StatModifierUpEffect ; do stat increase move
	pop hl
	pop af
	ld [hld],a ; restore [W_PLAYERMOVEEFFECT]
	pop af
	ld [hl],a ; restore [W_PLAYERMOVENUM]
	ret

ItemUsePokeflute: ; e140 (3:6140)
	ld a,[W_ISINBATTLE]
	and a
	jr nz,.inBattle
; if not in battle
	call ItemUseReloadOverworldData
	ld a,[W_CURMAP]
	cp a,ROUTE_12
	jr nz,.notRoute12
	ld a,[$d7d8]
	bit 7,a ; has the player beaten Route 12 Snorlax yet?
	jr nz,.noSnorlaxToWakeUp
; if the player hasn't beaten Route 12 Snorlax
	ld hl,Route12SnorlaxFluteCoords
	call ArePlayerCoordsInArray
	jr nc,.noSnorlaxToWakeUp
	ld hl,PlayedFluteHadEffectText
	call PrintText
	ld hl,$d7d8
	set 6,[hl] ; trigger Snorlax fight (handled by map script)
	ret
.notRoute12
	cp a,ROUTE_16
	jr nz,.noSnorlaxToWakeUp
	ld a,[$d7e0]
	bit 1,a ; has the player beaten Route 16 Snorlax yet?
	jr nz,.noSnorlaxToWakeUp
; if the player hasn't beaten Route 16 Snorlax
	ld hl,Route16SnorlaxFluteCoords
	call ArePlayerCoordsInArray
	jr nc,.noSnorlaxToWakeUp
	ld hl,PlayedFluteHadEffectText
	call PrintText
	ld hl,$d7e0
	set 0,[hl] ; trigger Snorlax fight (handled by map script)
	ret
.noSnorlaxToWakeUp
	ld hl,PlayedFluteNoEffectText
	jp PrintText
.inBattle
	xor a
	ld [$cd3d],a ; initialize variable that indicates if any pokemon were woken up to zero
	ld b,~SLP & $FF
	ld hl,W_PARTYMON1_STATUS
	call WakeUpEntireParty
	ld a,[W_ISINBATTLE]
	dec a ; is it a trainer battle?
	jr z,.skipWakingUpEnemyParty
; if it's a trainer battle
	ld hl,$d8a8 ; enemy party pokemon 1 status
	call WakeUpEntireParty
.skipWakingUpEnemyParty
	ld hl,W_PLAYERMONSTATUS
	ld a,[hl]
	and b ; remove Sleep status
	ld [hl],a
	ld hl,W_ENEMYMONSTATUS
	ld a,[hl]
	and b ; remove Sleep status
	ld [hl],a
	call LoadScreenTilesFromBuffer2 ; restore saved screen
	ld a,[$cd3d]
	and a ; were any pokemon asleep before playing the flute?
	ld hl,PlayedFluteNoEffectText
	jp z,PrintText ; if no pokemon were asleep
; if some pokemon were asleep
	ld hl,PlayedFluteHadEffectText
	call PrintText
	ld a,[$d083]
	and a,$80
	jr nz,.skipMusic
	call WaitForSoundToFinish ; wait for sound to end
	callba Music_PokeFluteInBattle ; play in-battle pokeflute music
.musicWaitLoop ; wait for music to finish playing
	ld a,[$c02c]
	and a ; music off?
	jr nz,.musicWaitLoop
.skipMusic
	ld hl,FluteWokeUpText
	jp PrintText

; wakes up all party pokemon
; INPUT:
; hl must point to status of first pokemon in party (player's or enemy's)
; b must equal ~SLP
; [$cd3d] should be initialized to 0
; OUTPUT:
; [$cd3d]: set to 1 if any pokemon were asleep
WakeUpEntireParty: ; e1e5 (3:61e5)
	ld de,44
	ld c,6
.loop
	ld a,[hl]
	push af
	and a,SLP ; is pokemon asleep?
	jr z,.notAsleep
	ld a,1
	ld [$cd3d],a ; indicate that a pokemon had to be woken up
.notAsleep
	pop af
	and b ; remove Sleep status
	ld [hl],a
	add hl,de
	dec c
	jr nz,.loop
	ret

; Format:
; 00: Y
; 01: X
Route12SnorlaxFluteCoords: ; e1fd (3:61fd)
	db 62,9  ; one space West of Snorlax
	db 61,10 ; one space North of Snorlax
	db 63,10 ; one space South of Snorlax
	db 62,11 ; one space East of Snorlax
	db $ff ; terminator

; Format:
; 00: Y
; 01: X
Route16SnorlaxFluteCoords: ; e206 (3:6206)
	db 10,27 ; one space East of Snorlax
	db 10,25 ; one space West of Snorlax
	db $ff ; terminator

PlayedFluteNoEffectText: ; e20b (3:620b)
	TX_FAR _PlayedFluteNoEffectText
	db "@"

FluteWokeUpText: ; e210 (3:6210)
	TX_FAR _FluteWokeUpText
	db "@"

PlayedFluteHadEffectText: ; e215 (3:6215)
	TX_FAR _PlayedFluteHadEffectText
	db $06
	db $08
	ld a,[W_ISINBATTLE]
	and a
	jr nz,.done
; play out-of-battle pokeflute music
	ld a,$ff
	call PlaySound ; turn off music
	ld a, (SFX_02_5e - SFX_Headers_02) / 3
	ld c, BANK(SFX_02_5e)
	call PlayMusic ; play music
.musicWaitLoop ; wait for music to finish playing
	ld a,[$c028]
	cp a,$b8
	jr z,.musicWaitLoop
	call Func_2307 ; start playing normal music again
.done
	jp TextScriptEnd ; end text

ItemUseCoinCase: ; e23a (3:623a)
	ld a,[W_ISINBATTLE]
	and a
	jp nz,ItemUseNotTime
	ld hl,CoinCaseNumCoinsText
	jp PrintText

CoinCaseNumCoinsText: ; e247 (3:6247)
	TX_FAR _CoinCaseNumCoinsText
	db "@"

OldRodCode: ; e24c (3:624c)
	call FishingInit
	jp c, ItemUseNotTime
	ld bc, (5 << 8) | MAGIKARP
	ld a, $1 ; set bite
	jr RodResponse ; 0xe257 $34

GoodRodCode: ; e259 (3:6259)
	call FishingInit
	jp c,ItemUseNotTime
.RandomLoop
	call GenRandom
	srl a
	jr c, .SetBite
	and %11
	cp 2
	jr nc, .RandomLoop
	; choose which monster appears
	ld hl,GoodRodMons
	add a,a
	ld c,a
	ld b,0
	add hl,bc
	ld b,[hl]
	inc hl
	ld c,[hl]
	and a
.SetBite
	ld a,0
	rla
	xor 1
	jr RodResponse

INCLUDE "data/good_rod.asm"

SuperRodCode: ; e283 (3:6283)
	call FishingInit
	jp c, ItemUseNotTime
	call ReadSuperRodData ; 0xe8ea
	ld a, e
RodResponse: ; e28d (3:628d)
	ld [$CD3D], a

	dec a ; is there a bite?
	jr nz, .next
	; if yes, store level and species data
	ld a, 1
	ld [$D05F], a
	ld a, b ; level
	ld [W_CURENEMYLVL], a
	ld a, c ; species
	ld [W_CUROPPONENT], a

.next
	ld hl, $D700
	ld a, [hl] ; store the value in a
	push af
	push hl
	ld [hl], 0
	callba Func_707b6
	pop hl
	pop af
	ld [hl], a
	ret

; checks if fishing is possible and if so, runs initialization code common to all rods
; unsets carry if fishing is possible, sets carry if not
FishingInit: ; e2b4 (3:62b4)
	ld a,[W_ISINBATTLE]
	and a
	jr z,.notInBattle
	scf ; can't fish during battle
	ret
.notInBattle
	call IsNextTileShoreOrWater
	ret c
	ld a,[$d700]
	cp a,2 ; Surfing?
	jr z,.surfing
	call ItemUseReloadOverworldData
	ld hl,ItemUseText00
	call PrintText
	ld a,(SFX_02_3e - SFX_Headers_02) / 3
	call PlaySound ; play sound
	ld c,80
	call DelayFrames
	and a
	ret
.surfing
	scf ; can't fish when surfing
	ret

ItemUseOaksParcel: ; e2de (3:62de)
	jp ItemUseNotYoursToUse

ItemUseItemfinder: ; e2e1 (3:62e1)
	ld a,[W_ISINBATTLE]
	and a
	jp nz,ItemUseNotTime
	call ItemUseReloadOverworldData
	callba HiddenItemNear ; check for hidden items
	ld hl,ItemfinderFoundNothingText
	jr nc,.printText ; if no hidden items
	ld c,4
.loop
	ld a,(SFX_02_4a - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent ; play sound
	ld a,(SFX_02_5a - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent ; play sound
	dec c
	jr nz,.loop
	ld hl,ItemfinderFoundItemText
.printText
	jp PrintText

ItemfinderFoundItemText: ; e30d (3:630d)
	TX_FAR _ItemfinderFoundItemText
	db "@"

ItemfinderFoundNothingText: ; e312 (3:6312)
	TX_FAR _ItemfinderFoundNothingText
	db "@"

ItemUsePPUp: ; e317 (3:6317)
	ld a,[W_ISINBATTLE]
	and a
	jp nz,ItemUseNotTime

ItemUsePPRestore: ; e31e (3:631e)
	ld a,[wWhichPokemon]
	push af
	ld a,[$cf91]
	ld [$cd3d],a
.chooseMon
	xor a
	ld [$cfcb],a
	ld a,$01 ; item use party menu
	ld [$d07d],a
	call DisplayPartyMenu
	jr nc,.chooseMove
	jp .itemNotUsed
.chooseMove
	ld a,[$cd3d]
	cp a,ELIXER
	jp nc,.useElixir ; if Elixir or Max Elixir
	ld a,$02
	ld [wMoveMenuType],a
	ld hl,RaisePPWhichTechniqueText
	ld a,[$cd3d]
	cp a,ETHER ; is it a PP Up?
	jr c,.printWhichTechniqueMessage ; if so, print the raise PP message
	ld hl,RestorePPWhichTechniqueText ; otherwise, print the restore PP message
.printWhichTechniqueMessage
	call PrintText
	xor a
	ld [$cc2e],a
	callab MoveSelectionMenu ; move selection menu
	ld a,0
	ld [$cc2e],a
	jr nz,.chooseMon
	ld hl,W_PARTYMON1_MOVE1
	ld bc,44
	call GetSelectedMoveOffset
	push hl
	ld a,[hl]
	ld [$d11e],a
	call GetMoveName
	call CopyStringToCF4B ; copy name to $cf4b
	pop hl
	ld a,[$cd3d]
	cp a,ETHER
	jr nc,.useEther ; if Ether or Max Ether
.usePPUp
	ld bc,21
	add hl,bc
	ld a,[hl] ; move PP
	cp a,3 << 6 ; have 3 PP Ups already been used?
	jr c,.PPNotMaxedOut
	ld hl,PPMaxedOutText
	call PrintText
	jr .chooseMove
.PPNotMaxedOut
	ld a,[hl]
	add a,1 << 6 ; increase PP Up count by 1
	ld [hl],a
	ld a,1 ; 1 PP Up used
	ld [$d11e],a
	call RestoreBonusPP ; add the bonus PP to current PP
	ld hl,PPIncreasedText
	call PrintText
.done
	pop af
	ld [wWhichPokemon],a
	call GBPalWhiteOut
	call GoPAL_SET_CF1C
	jp RemoveUsedItem
.afterRestoringPP ; after using a (Max) Ether/Elixir
	ld a,[wWhichPokemon]
	ld b,a
	ld a,[wPlayerMonNumber]
	cp b ; is the pokemon whose PP was restored active in battle?
	jr nz,.skipUpdatingInBattleData
	ld hl,W_PARTYMON1_MOVE1PP
	ld bc,44
	call AddNTimes
	ld de,W_PLAYERMONPP
	ld bc,4
	call CopyData ; copy party data to in-battle data
.skipUpdatingInBattleData
	ld a,(SFX_02_3e - SFX_Headers_02) / 3
	call PlaySound
	ld hl,PPRestoredText
	call PrintText
	jr .done
.useEther
	call .restorePP
	jr nz,.afterRestoringPP
	jp .noEffect
; unsets zero flag if PP was restored, sets zero flag if not
; however, this is bugged for Max Ethers and Max Elixirs (see below)
.restorePP
	xor a
	ld [$cc49],a ; party pokemon
	call GetMaxPP
	ld hl,W_PARTYMON1_MOVE1
	ld bc,44
	call GetSelectedMoveOffset
	ld bc,21
	add hl,bc ; hl now points to move's PP
	ld a,[$d11e]
	ld b,a ; b = max PP
	ld a,[$cd3d]
	cp a,MAX_ETHER
	jr z,.fullyRestorePP
	ld a,[hl] ; move PP
	and a,%00111111 ; lower 6 bit bits store current PP
	cp b ; does current PP equal max PP?
	ret z ; if so, return
	add a,10 ; increase current PP by 10
; b holds the max PP amount and b will hold the new PP amount.
; So, if the new amount meets or exceeds the max amount,
; cap the amount to the max amount by leaving b unchanged.
; Otherwise, store the new amount in b.
	cp b ; does the new amount meet or exceed the maximum?
	jr nc,.storeNewAmount
	ld b,a
.storeNewAmount
	ld a,[hl] ; move PP
	and a,%11000000 ; PP Up counter bits
	add b
	ld [hl],a
	ret
.fullyRestorePP
	ld a,[hl] ; move PP
; Note that this code has a bug. It doesn't mask out the upper two bits, which
; are used to count how many PP Ups have been used on the move. So, Max Ethers
; and Max Elixirs will not be detected as having no effect on a move with full
; PP if the move has had any PP Ups used on it.
	cp b ; does current PP equal max PP?
	ret z
	jr .storeNewAmount
.useElixir
; decrement the item ID so that ELIXER becomes ETHER and MAX_ELIXER becomes MAX_ETHER
	ld hl,$cd3d
	dec [hl]
	dec [hl]
	xor a
	ld hl,wCurrentMenuItem
	ld [hli],a
	ld [hl],a ; zero the counter for number of moves that had their PP restored
	ld b,4
; loop through each move and restore PP
.elixirLoop
	push bc
	ld hl,W_PARTYMON1_MOVE1
	ld bc,44
	call GetSelectedMoveOffset
	ld a,[hl]
	and a ; does the current slot have a move?
	jr z,.nextMove
	call .restorePP
	jr z,.nextMove
; if some PP was restored
	ld hl,$cc27 ; counter for number of moves that had their PP restored
	inc [hl]
.nextMove
	ld hl,wCurrentMenuItem
	inc [hl]
	pop bc
	dec b
	jr nz,.elixirLoop
	ld a,[$cc27]
	and a ; did any moves have their PP restored?
	jp nz,.afterRestoringPP
.noEffect
	call ItemUseNoEffect
.itemNotUsed
	call GBPalWhiteOut
	call GoPAL_SET_CF1C
	pop af
	xor a
	ld [$cd6a],a ; item use failed
	ret

RaisePPWhichTechniqueText: ; e45d (3:645d)
	TX_FAR _RaisePPWhichTechniqueText
	db "@"

RestorePPWhichTechniqueText: ; e462 (3:6462)
	TX_FAR _RestorePPWhichTechniqueText
	db "@"

PPMaxedOutText: ; e467 (3:6467)
	TX_FAR _PPMaxedOutText
	db "@"

PPIncreasedText: ; e46c (3:646c)
	TX_FAR _PPIncreasedText
	db "@"

PPRestoredText: ; e471 (3:6471)
	TX_FAR _PPRestoredText
	db "@"

; for items that can't be used from the Item menu
UnusableItem: ; e476 (3:6476)
	jp ItemUseNotTime

ItemUseTMHM: ; e479 (3:6479)
	ld a,[W_ISINBATTLE]
	and a
	jp nz,ItemUseNotTime
	ld a,[$cf91]
	sub a,TM_01
	push af
	jr nc,.skipAdding
	add a,55 ; if item is an HM, add 55
.skipAdding
	inc a
	ld [$d11e],a
	ld a,$44
	call Predef ; get move ID from TM/HM ID
	ld a,[$d11e]
	ld [$d0e0],a
	call GetMoveName
	call CopyStringToCF4B ; copy name to $cf4b
	pop af
	ld hl,BootedUpTMText
	jr nc,.printBootedUpMachineText
	ld hl,BootedUpHMText
.printBootedUpMachineText
	call PrintText
	ld hl,TeachMachineMoveText
	call PrintText
	FuncCoord 14,7
	ld hl,Coord
	ld bc,$080f
	ld a,$14
	ld [$d125],a
	call DisplayTextBoxID ; yes/no menu
	ld a,[wCurrentMenuItem]
	and a
	jr z,.useMachine
	ld a,2
	ld [$cd6a],a ; item not used
	ret
.useMachine
	ld a,[wWhichPokemon]
	push af
	ld a,[$cf91]
	push af
.chooseMon
	ld hl,$cf4b
	ld de,$d036
	ld bc,14
	call CopyData
	ld a,$ff
	ld [$cfcb],a
	ld a,$03 ; teach TM/HM party menu
	ld [$d07d],a
	call DisplayPartyMenu
	push af
	ld hl,$d036
	ld de,$cf4b
	ld bc,14
	call CopyData
	pop af
	jr nc,.checkIfAbleToLearnMove
; if the player canceled teaching the move
	pop af
	pop af
	call GBPalWhiteOutWithDelay3
	call CleanLCD_OAM
	call GoPAL_SET_CF1C
	jp LoadScreenTilesFromBuffer1 ; restore saved screen
.checkIfAbleToLearnMove
	ld a,$43
	call Predef ; check if the pokemon can learn the move
	push bc
	ld a,[wWhichPokemon]
	ld hl,W_PARTYMON1NAME
	call GetPartyMonName
	pop bc
	ld a,c
	and a ; can the pokemon learn the move?
	jr nz,.checkIfAlreadyLearnedMove
; if the pokemon can't learn the move
	ld a,(SFX_02_51 - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent ; play sound
	ld hl,MonCannotLearnMachineMoveText
	call PrintText
	jr .chooseMon
.checkIfAlreadyLearnedMove
	callab CheckIfMoveIsKnown ; check if the pokemon already knows the move
	jr c,.chooseMon
	ld a,$1b
	call Predef ; teach move
	pop af
	ld [$cf91],a
	pop af
	ld [wWhichPokemon],a
	ld a,b
	and a
	ret z
	ld a,[$cf91]
	call IsItemHM
	ret c
	jp RemoveUsedItem

BootedUpTMText: ; e54f (3:654f)
	TX_FAR _BootedUpTMText
	db "@"

BootedUpHMText: ; e554 (3:6554)
	TX_FAR _BootedUpHMText
	db "@"

TeachMachineMoveText: ; e559 (3:6559)
	TX_FAR _TeachMachineMoveText
	db "@"

MonCannotLearnMachineMoveText: ; e55e (3:655e)
	TX_FAR _MonCannotLearnMachineMoveText
	db "@"

PrintItemUseTextAndRemoveItem: ; e563 (3:6563)
	ld hl,ItemUseText00
	call PrintText
	ld a,(SFX_02_3e - SFX_Headers_02) / 3
	call PlaySound ; play sound
	call WaitForTextScrollButtonPress ; wait for button press

RemoveUsedItem: ; e571 (3:6571)
	ld hl,wNumBagItems
	ld a,1 ; one item
	ld [$cf96],a ; store quantity
	jp RemoveItemFromInventory

ItemUseNoEffect: ; e57c (3:657c)
	ld hl,ItemUseNoEffectText
	jr ItemUseFailed

ItemUseNotTime: ; e581 (3:6581)
	ld hl,ItemUseNotTimeText
	jr ItemUseFailed

ItemUseNotYoursToUse: ; e586 (3:6586)
	ld hl,ItemUseNotYoursToUseText
	jr ItemUseFailed

ThrowBallAtTrainerMon: ; e58b (3:658b)
	call GoPAL_SET_CF1C
	call LoadScreenTilesFromBuffer1 ; restore saved screen
	call Delay3
	ld a,TOSS_ANIM
	ld [W_ANIMATIONID],a
	ld a,$08
	call Predef ; do animation
	ld hl,ThrowBallAtTrainerMonText1
	call PrintText
	ld hl,ThrowBallAtTrainerMonText2
	call PrintText
	jr RemoveUsedItem

NoCyclingAllowedHere: ; e5ac (3:65ac)
	ld hl,NoCyclingAllowedHereText
	jr ItemUseFailed

BoxFullCannotThrowBall: ; e5b1 (3:65b1)
	ld hl,BoxFullCannotThrowBallText
	jr ItemUseFailed

SurfingAttemptFailed: ; e5b6 (3:65b6)
	ld hl,NoSurfingHereText

ItemUseFailed: ; e5b9 (3:65b9)
	xor a
	ld [$cd6a],a ; item use failed
	jp PrintText

ItemUseNotTimeText: ; e5c0 (3:65c0)
	TX_FAR _ItemUseNotTimeText
	db "@"

ItemUseNotYoursToUseText: ; e5c5 (3:65c5)
	TX_FAR _ItemUseNotYoursToUseText
	db "@"

ItemUseNoEffectText: ; e5ca (3:65ca)
	TX_FAR _ItemUseNoEffectText
	db "@"

ThrowBallAtTrainerMonText1: ; e5cf (3:65cf)
	TX_FAR _ThrowBallAtTrainerMonText1
	db "@"

ThrowBallAtTrainerMonText2: ; e5d4 (3:65d4)
	TX_FAR _ThrowBallAtTrainerMonText2
	db "@"

NoCyclingAllowedHereText: ; e5d9 (3:65d9)
	TX_FAR _NoCyclingAllowedHereText
	db "@"

NoSurfingHereText: ; e5de (3:65de)
	TX_FAR _NoSurfingHereText
	db "@"

BoxFullCannotThrowBallText: ; e5e3 (3:65e3)
	TX_FAR _BoxFullCannotThrowBallText
	db "@"

ItemUseText00: ; e5e8 (3:65e8)
	TX_FAR _ItemUseText001
	db $05
	TX_FAR _ItemUseText002
	db "@"

GotOnBicycleText: ; e5f2 (3:65f2)
	TX_FAR _GotOnBicycleText1
	db $05
	TX_FAR _GotOnBicycleText2
	db "@"

GotOffBicycleText: ; e5fc (3:65fc)
	TX_FAR _GotOffBicycleText1
	db $05
	TX_FAR _GotOffBicycleText2
	db "@"

; restores bonus PP (from PP Ups) when healing at a pokemon center
; also, when a PP Up is used, it increases the current PP by one PP Up bonus
; INPUT:
; [wWhichPokemon] = index of pokemon in party
; [$d11e] = mode
; 0: Pokemon Center healing
; 1: using a PP Up
; [wCurrentMenuItem] = index of move (when using a PP Up)
RestoreBonusPP: ; e606 (3:6606)
	ld hl,W_PARTYMON1_MOVE1
	ld bc,44
	ld a,[wWhichPokemon]
	call AddNTimes
	push hl
	ld de,$cd78 - 1
	ld a,$5e
	call Predef ; loads the normal max PP of each of the pokemon's moves to $cd78
	pop hl
	ld c,21
	ld b,0
	add hl,bc ; hl now points to move 1 PP
	ld de,$cd78
	ld b,0 ; initialize move counter to zero
; loop through the pokemon's moves
.loop
	inc b
	ld a,b
	cp a,5 ; reached the end of the pokemon's moves?
	ret z ; if so, return
	ld a,[$d11e]
	dec a ; using a PP Up?
	jr nz,.skipMenuItemIDCheck
; if using a PP Up, check if this is the move it's being used on
	ld a,[wCurrentMenuItem]
	inc a
	cp b
	jr nz,.nextMove
.skipMenuItemIDCheck
	ld a,[hl]
	and a,%11000000 ; have any PP Ups been used?
	call nz,AddBonusPP ; if so, add bonus PP
.nextMove
	inc hl
	inc de
	jr .loop

; adds bonus PP from PP Ups to current PP
; 1/5 of normal max PP (capped at 7) is added for each PP Up
; INPUT:
; [de] = normal max PP
; [hl] = move PP
; [$d11e] = max number of times to add bonus
; set to 1 when using a PP Up, set to 255 otherwise
AddBonusPP: ; e642 (3:6642)
	push bc
	ld a,[de] ; normal max PP of move
	ld [H_DIVIDEND + 3],a
	xor a
	ld [H_DIVIDEND],a
	ld [H_DIVIDEND + 1],a
	ld [H_DIVIDEND + 2],a
	ld a,5
	ld [H_DIVISOR],a
	ld b,4
	call Divide
	ld a,[hl] ; move PP
	ld b,a
	swap a
	and a,%00001111
	srl a
	srl a
	ld c,a ; c = number of PP Ups used
.loop
	ld a,[H_QUOTIENT + 3]
	cp a,8 ; is the amount greater than or equal to 8?
	jr c,.addAmount
	ld a,7 ; cap the amount at 7
.addAmount
	add b
	ld b,a
	ld a,[$d11e]
	dec a
	jr z,.done
	dec c
	jr nz,.loop
.done
	ld [hl],b
	pop bc
	ret

; gets max PP of a pokemon's move (including PP from PP Ups)
; INPUT:
; [wWhichPokemon] = index of pokemon within party/box
; [$cc49] = pokemon source
; 00: player's party
; 01: enemy's party
; 02: current box
; 03: daycare
; 04: player's in-battle pokemon
; [wCurrentMenuItem] = move index
; OUTPUT:
; [$d11e] = max PP
GetMaxPP: ; e677 (3:6677)
	ld a,[$cc49]
	and a
	ld hl,W_PARTYMON1_MOVE1
	ld bc,44
	jr z,.sourceWithMultipleMon
	ld hl,$d8ac ; enemy party
	dec a
	jr z,.sourceWithMultipleMon
	ld hl,$da9e ; current box
	ld bc,33
	dec a
	jr z,.sourceWithMultipleMon
	ld hl,$da67 ; daycare
	dec a
	jr z,.sourceWithOneMon
	ld hl,W_PLAYERMONMOVES ; player's in-battle pokemon
.sourceWithOneMon
	call GetSelectedMoveOffset2
	jr .next
.sourceWithMultipleMon
	call GetSelectedMoveOffset
.next
	ld a,[hl]
	dec a
	push hl
	ld hl,Moves
	ld bc,6
	call AddNTimes
	ld de,$cd6d
	ld a,BANK(Moves)
	call FarCopyData
	ld de,$cd72
	ld a,[de]
	ld b,a ; b = normal max PP
	pop hl
	push bc
	ld bc,21 ; PP offset if not player's in-battle pokemon data
	ld a,[$cc49]
	cp a,4 ; player's in-battle pokemon?
	jr nz,.addPPOffset
	ld bc,17 ; PP offset if player's in-battle pokemon data
.addPPOffset
	add hl,bc
	ld a,[hl] ; a = current PP
	and a,%11000000 ; get PP Up count
	pop bc
	or b ; place normal max PP in 6 lower bits of a
	ld h,d
	ld l,e
	inc hl ; hl = $cd73
	ld [hl],a
	xor a
	ld [$d11e],a ; no limit on PP Up amount
	call AddBonusPP ; add bonus PP from PP Ups
	ld a,[hl]
	and a,%00111111 ; mask out the PP Up count
	ld [$d11e],a ; store max PP
	ret

GetSelectedMoveOffset: ; e6e3 (3:66e3)
	ld a,[wWhichPokemon]
	call AddNTimes

GetSelectedMoveOffset2: ; e6e9 (3:66e9)
	ld a,[wCurrentMenuItem]
	ld c,a
	ld b,0
	add hl,bc
	ret

; confirms the item toss and then tosses the item
; INPUT:
; hl = address of inventory (either wNumBagItems or wNumBoxItems)
; [$cf91] = item ID
; [wWhichPokemon] = index of item within inventory
; [$cf96] = quantity to toss
; OUTPUT:
; clears carry flag if the item is tossed, sets carry flag if not
TossItem_: ; e6f1 (3:66f1)
	push hl
	ld a,[$cf91]
	call IsItemHM
	pop hl
	jr c,.tooImportantToToss
	push hl
	call IsKeyItem_
	ld a,[$d124]
	pop hl
	and a
	jr nz,.tooImportantToToss
	push hl
	ld a,[$cf91]
	ld [$d11e],a
	call GetItemName
	call CopyStringToCF4B ; copy name to $cf4b
	ld hl,IsItOKToTossItemText
	call PrintText
	FuncCoord 14,7
	ld hl,Coord
	ld bc,$080f
	ld a,$14
	ld [$d125],a
	call DisplayTextBoxID ; yes/no menu
	ld a,[$d12e]
	cp a,2
	pop hl
	scf
	ret z
; if the player chose Yes
	push hl
	ld a,[wWhichPokemon]
	call RemoveItemFromInventory
	ld a,[$cf91]
	ld [$d11e],a
	call GetItemName
	call CopyStringToCF4B ; copy name to $cf4b
	ld hl,ThrewAwayItemText
	call PrintText
	pop hl
	and a
	ret
.tooImportantToToss
	push hl
	ld hl,TooImportantToTossText
	call PrintText
	pop hl
	scf
	ret

ThrewAwayItemText: ; e755 (3:6755)
	TX_FAR _ThrewAwayItemText
	db "@"

IsItOKToTossItemText: ; e75a (3:675a)
	TX_FAR _IsItOKToTossItemText
	db "@"

TooImportantToTossText: ; e75f (3:675f)
	TX_FAR _TooImportantToTossText
	db "@"

; checks if an item is a key item
; INPUT:
; [$cf91] = item ID
; OUTPUT:
; [$d124] = result
; 00: item is not key item
; 01: item is key item
IsKeyItem_: ; e764 (3:6764)
	ld a,$01
	ld [$d124],a
	ld a,[$cf91]
	cp a,HM_01 ; is the item an HM or TM?
	jr nc,.checkIfItemIsHM
; if the item is not an HM or TM
	push af
	ld hl,KeyItemBitfield
	ld de,$cee9
	ld bc,15 ; only 11 bytes are actually used
	call CopyData
	pop af
	dec a
	ld c,a
	ld hl,$cee9
	ld b,$02 ; test bit
	ld a,$10
	call Predef ; bitfield operation function
	ld a,c
	and a
	ret nz
.checkIfItemIsHM
	ld a,[$cf91]
	call IsItemHM
	ret c
	xor a
	ld [$d124],a
	ret

INCLUDE "data/key_items.asm"

Func_e7a4: ; e7a4 (3:67a4)
	ld de, W_NUMINBOX ; $da80
	ld a, [de]
	inc a
	ld [de], a
	ld a, [$cf91]
	ld [$d0b5], a
	ld c, a
.asm_e7b1
	inc de
	ld a, [de]
	ld b, a
	ld a, c
	ld c, b
	ld [de], a
	cp $ff
	jr nz, .asm_e7b1
	call GetMonHeader
	ld hl, W_BOXMON1OT
	ld bc, $b
	ld a, [W_NUMINBOX] ; $da80
	dec a
	jr z, .asm_e7ee
	dec a
	call AddNTimes
	push hl
	ld bc, $b
	add hl, bc
	ld d, h
	ld e, l
	pop hl
	ld a, [W_NUMINBOX] ; $da80
	dec a
	ld b, a
.asm_e7db
	push bc
	push hl
	ld bc, $b
	call CopyData
	pop hl
	ld d, h
	ld e, l
	ld bc, $fff5
	add hl, bc
	pop bc
	dec b
	jr nz, .asm_e7db
.asm_e7ee
	ld hl, W_PLAYERNAME ; $d158
	ld de, W_BOXMON1OT
	ld bc, $b
	call CopyData
	ld a, [W_NUMINBOX] ; $da80
	dec a
	jr z, .asm_e82a
	ld hl, W_BOXMON1NAME
	ld bc, $b
	dec a
	call AddNTimes
	push hl
	ld bc, $b
	add hl, bc
	ld d, h
	ld e, l
	pop hl
	ld a, [W_NUMINBOX] ; $da80
	dec a
	ld b, a
.asm_e817
	push bc
	push hl
	ld bc, $b
	call CopyData
	pop hl
	ld d, h
	ld e, l
	ld bc, $fff5
	add hl, bc
	pop bc
	dec b
	jr nz, .asm_e817
.asm_e82a
	ld hl, W_BOXMON1NAME
	ld a, $2
	ld [$d07d], a
	ld a, $4e
	call Predef ; indirect jump to Func_64eb (64eb (1:64eb))
	ld a, [W_NUMINBOX] ; $da80
	dec a
	jr z, .asm_e867
	ld hl, W_BOXMON1DATA
	ld bc, $21
	dec a
	call AddNTimes
	push hl
	ld bc, $21
	add hl, bc
	ld d, h
	ld e, l
	pop hl
	ld a, [W_NUMINBOX] ; $da80
	dec a
	ld b, a
.asm_e854
	push bc
	push hl
	ld bc, $21
	call CopyData
	pop hl
	ld d, h
	ld e, l
	ld bc, $ffdf
	add hl, bc
	pop bc
	dec b
	jr nz, .asm_e854
.asm_e867
	ld a, [W_ENEMYMONLEVEL] ; $cff3
	ld [W_ENEMYMONNUMBER], a ; $cfe8
	ld hl, $cfe5
	ld de, W_BOXMON1DATA
	ld bc, $c
	call CopyData
	ld hl, wPlayerID ; $d359
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hl]
	ld [de], a
	inc de
	push de
	ld a, [W_CURENEMYLVL] ; $d127
	ld d, a
	callab CalcExperience
	pop de
	ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
	ld [de], a
	inc de
	ld a, [$ff97]
	ld [de], a
	inc de
	ld a, [$ff98]
	ld [de], a
	inc de
	xor a
	ld b, $a
.asm_e89f
	ld [de], a
	inc de
	dec b
	jr nz, .asm_e89f
	ld hl, $cff1
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hli]
	ld [de], a
	ld hl, W_ENEMYMONPP ; $cffe
	ld b, $4
.asm_e8b1
	ld a, [hli]
	inc de
	ld [de], a
	dec b
	jr nz, .asm_e8b1
	ret

; checks if the tile in front of the player is a shore or water tile
; used for surfing and fishing
; unsets carry if it is, sets carry if not
IsNextTileShoreOrWater: ; e8b8 (3:68b8)
	ld a, [W_CURMAPTILESET]
	ld hl, WaterTilesets
	ld de,1
	call IsInArray
	jr nc, .notShoreOrWater
	ld a, [W_CURMAPTILESET]
	cp SHIP_PORT ; Vermilion Dock tileset
	ld a, [$cfc6] ; tile in front of player
	jr z, .skipShoreTiles ; if it's the Vermilion Dock tileset
	cp $48 ; eastern shore tile in Safari Zone
	jr z, .shoreOrWater
	cp $32 ; usual eastern shore tile
	jr z, .shoreOrWater
.skipShoreTiles
	cp $14 ; water tile
	jr z, .shoreOrWater
.notShoreOrWater
	scf
	ret
.shoreOrWater
	and a
	ret

; tilesets with water
WaterTilesets: ; e8e0 (3:68e0)
	db OVERWORLD, FOREST, DOJO, GYM, SHIP, SHIP_PORT, CAVERN, FACILITY, PLATEAU
	db $ff ; terminator

ReadSuperRodData: ; e8ea (3:68ea)
; return e = 2 if no fish on this map
; return e = 1 if a bite, bc = level,species
; return e = 0 if no bite
	ld a, [W_CURMAP]
	ld de, 3 ; each fishing group is three bytes wide
	ld hl, SuperRodData
	call IsInArray
	jr c, .ReadFishingGroup
	ld e, $2 ; $2 if no fishing groups found
	ret

.ReadFishingGroup ; 0xe8f6
; hl points to the fishing group entry in the index
	inc hl ; skip map id

	; read fishing group address
	ld a, [hli]
	ld h, [hl]
	ld l, a

	ld b, [hl] ; how many mons in group
	inc hl ; point to data
	ld e, $0 ; no bite yet

.RandomLoop ; 0xe90c
	call GenRandom
	srl a
	ret c ; 50% chance of no battle

	and %11 ; 2-bit random number
	cp b
	jr nc, .RandomLoop ; if a is greater than the number of mons, regenerate

	; get the mon
	add a
	ld c, a
	ld b, $0
	add hl, bc
	ld b, [hl] ; level
	inc hl
	ld c, [hl] ; species
	ld e, $1 ; $1 if there's a bite
	ret

INCLUDE "data/super_rod.asm"

; reloads map view and processes sprite data
; for items that cause the overworld to be displayed
ItemUseReloadOverworldData: ; e9c5 (3:69c5)
	call LoadCurrentMapView
	jp UpdateSprites

Func_e9cb: ; e9cb (3:69cb)
	ld hl, WildDataPointers ; $4eeb
	ld de, $cee9
	ld c, $0
.asm_e9d3
	inc hl
	ld a, [hld]
	inc a
	jr z, .asm_e9ec
	push hl
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld a, [hli]
	and a
	call nz, Func_e9f0
	ld a, [hli]
	and a
	call nz, Func_e9f0
	pop hl
	inc hl
	inc hl
	inc c
	jr .asm_e9d3
.asm_e9ec
	ld a, $ff
	ld [de], a
	ret

Func_e9f0: ; e9f0 (3:69f0)
	inc hl
	ld b, $a
.asm_e9f3
	ld a, [$d11e]
	cp [hl]
	jr nz, .asm_e9fc
	ld a, c
	ld [de], a
	inc de
.asm_e9fc
	inc hl
	inc hl
	dec b
	jr nz, .asm_e9f3
	dec hl
	ret

DrawBadges: ; ea03 (3:6a03)
; Draw 4x2 gym leader faces, with the faces replaced by
; badges if they are owned. Used in the player status screen.

; In Japanese versions, names are displayed above faces.
; Instead of removing relevant code, the name graphics were erased.

; Tile ids for face/badge graphics.
	ld de, $cd3f
	ld hl, .FaceBadgeTiles
	ld bc, 8
	call CopyData

; Booleans for each badge.
	ld hl, $cd49
	ld bc, 8
	xor a
	call FillMemory

; Alter these based on owned badges.
	ld de, $cd49
	ld hl, $cd3f
	ld a, [W_OBTAINEDBADGES]
	ld b, a
	ld c, 8
.CheckBadge
	srl b
	jr nc, .NextBadge
	ld a, [hl]
	add 4 ; Badge graphics are after each face
	ld [hl], a
	ld a, 1
	ld [de], a
.NextBadge
	inc hl
	inc de
	dec c
	jr nz, .CheckBadge

; Draw two rows of badges.
	ld hl, $cd3d
	ld a, $d8 ; [1]
	ld [hli], a
	ld [hl], $60 ; First name

	FuncCoord 2, 11
	ld hl, Coord
	ld de, $cd49
	call .DrawBadgeRow

	FuncCoord 2, 14
	ld hl, Coord
	ld de, $cd49 + 4
;	call .DrawBadgeRow
;	ret

.DrawBadgeRow ; ea4c (3:6a4c)
; Draw 4 badges.

	ld c, 4
.DrawBadge
	push de
	push hl

; Badge no.
	ld a, [$cd3d]
	ld [hli], a
	inc a
	ld [$cd3d], a

; Names aren't printed if the badge is owned.
	ld a, [de]
	and a
	ld a, [$cd3e]
	jr nz, .SkipName
	call .PlaceTiles
	jr .PlaceBadge

.SkipName
	inc a
	inc a
	inc hl

.PlaceBadge
	ld [$cd3e], a
	ld de, 20 - 1
	add hl, de
	ld a, [$cd3f]
	call .PlaceTiles
	add hl, de
	call .PlaceTiles

; Shift badge array back one byte.
	push bc
	ld hl, $cd3f + 1
	ld de, $cd3f
	ld bc, 8
	call CopyData
	pop bc

	pop hl
	ld de, 4
	add hl, de

	pop de
	inc de
	dec c
	jr nz, .DrawBadge
	ret

.PlaceTiles
	ld [hli], a
	inc a
	ld [hl], a
	inc a
	ret

.FaceBadgeTiles
	db $20, $28, $30, $38, $40, $48, $50, $58

GymLeaderFaceAndBadgeTileGraphics: ; ea9e (3:6a9e)
	INCBIN "gfx/badges.w16.2bpp"

Func_ee9e: ; ee9e (3:6e9e)
	call Load16BitRegisters
	ld hl, $c6e8
	ld a, [W_CURMAPWIDTH] ; $d369
	add $6
	ld e, a
	ld d, $0
	add hl, de
	add hl, de
	add hl, de
	ld e, $3
	add hl, de
	ld e, a
	ld a, b
	and a
	jr z, .asm_eebb
.asm_eeb7
	add hl, de
	dec b
	jr nz, .asm_eeb7
.asm_eebb
	add hl, bc
	ld a, [$d09f]
	ld [hl], a
	ld a, [$d35f]
	ld c, a
	ld a, [$d360]
	ld b, a
	call Func_ef4e
	ret c
	push hl
	ld l, e
	ld h, $0
	ld e, $6
	ld d, h
	add hl, hl
	add hl, hl
	add hl, de
	add hl, bc
	pop bc
	call Func_ef4e
	ret c

Func_eedc: ; eedc (3:6edc)
	ld a, [W_ISINBATTLE] ; $d057
	inc a
	ret z
	ld a, [H_AUTOBGTRANSFERENABLED] ; $ffba
	push af
	ld a, [$ffd7]
	push af
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld [$ffd7], a
	call LoadCurrentMapView
	call GoPAL_SET_CF1C
	ld hl, $d526
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld de, $ffc0
	add hl, de
	ld a, h
	and $3
	or $98
	ld a, l
	ld [$cee9], a
	ld a, h
	ld [$ceea], a
	ld a, $2
	ld [$ffbe], a
	ld c, $9
.asm_ef0f
	push bc
	push hl
	push hl
	ld hl, $c378
	ld de, $14
	ld a, [$ffbe]
.asm_ef1a
	add hl, de
	dec a
	jr nz, .asm_ef1a
	call ScheduleRowRedrawHelper
	pop hl
	ld de, $20
	ld a, [$ffbe]
	ld c, a
.asm_ef28
	add hl, de
	ld a, h
	and $3
	or $98
	dec c
	jr nz, .asm_ef28
	ld [$ffd2], a
	ld a, l
	ld [H_SCREENEDGEREDRAWADDR], a ; $ffd1
	ld a, $2
	ld [H_SCREENEDGEREDRAW], a ; $ffd0
	call DelayFrame
	ld hl, $ffbe
	inc [hl]
	inc [hl]
	pop hl
	pop bc
	dec c
	jr nz, .asm_ef0f
	pop af
	ld [$ffd7], a
	pop af
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ret

Func_ef4e: ; ef4e (3:6f4e)
	ld a, h
	sub b
	ret nz
	ld a, l
	sub c
	ret

UsedCut: ; ef54 (3:6f54)
	xor a
	ld [$cd6a], a
	ld a, [W_CURMAPTILESET] ; $d367
	and a ; OVERWORLD
	jr z, .asm_ef6b
	cp GYM
	jr nz, .asm_ef77
	ld a, [$cfc6]
	cp $50 ; gym cut tree
	jr nz, .asm_ef77
	jr asm_ef82
.asm_ef6b
	dec a
	ld a, [$cfc6]
	cp $3d ; cut tree
	jr z, asm_ef82
	cp $52 ; grass
	jr z, asm_ef82
.asm_ef77
	ld hl, NothingToCutText
	jp PrintText

NothingToCutText: ; ef7d (3:6f7d)
	TX_FAR _NothingToCutText
	db "@"

asm_ef82: ; ef82 (3:6f82)
	ld [$cd4d], a
	ld a, $1
	ld [$cd6a], a
	ld a, [wWhichPokemon] ; $cf92
	ld hl, W_PARTYMON1NAME ; $d2b5
	call GetPartyMonName
	ld hl, $d730
	set 6, [hl]
	call GBPalWhiteOutWithDelay3
	call CleanLCD_OAM
	call Func_3dbe
	ld a, $90
	ld [$ffb0], a
	call Delay3
	call LoadGBPal
	call LoadCurrentMapView
	call SaveScreenTilesToBuffer2
	call Delay3
	xor a
	ld [$ffb0], a
	ld hl, UsedCutText
	call PrintText
	call LoadScreenTilesFromBuffer2
	ld hl, $d730
	res 6, [hl]
	ld a, $ff
	ld [$cfcb], a
	call AnimateCutTree
	ld de, CutTreeBlockSwaps ; $7100
	call Func_f09f
	call Func_eedc
	callba Func_79e96
	ld a, $1
	ld [$cfcb], a
	ld a, (SFX_02_56 - SFX_Headers_02) / 3
	call PlaySound
	ld a, $90
	ld [$ffb0], a
	call UpdateSprites
	jp Func_eedc

UsedCutText: ; eff2 (3:6ff2)
	TX_FAR _UsedCutText
	db "@"

AnimateCutTree: ; eff7 (3:6ff7)
	xor a
	ld [$cd50], a
	ld a, $e4
	ld [rOBP1], a ; $ff49
	ld a, [$cd4d]
	cp $52
	jr z, .asm_f020
	ld de, Overworld_GFX + $2d0 ; $42d0 ; cuttable tree sprite top row
	ld hl, $8fc0
	ld bc, (BANK(Overworld_GFX) << 8) + $02
	call CopyVideoData
	ld de, Overworld_GFX + $3d0 ; $43d0 ; cuttable tree sprite bottom row
	ld hl, $8fe0
	ld bc, (BANK(Overworld_GFX) << 8) + $02
	call CopyVideoData
	jr asm_f055
.asm_f020
	ld hl, $8fc0
	call LoadCutTreeOAM
	ld hl, $8fd0
	call LoadCutTreeOAM
	ld hl, $8fe0
	call LoadCutTreeOAM
	ld hl, $8ff0
	call LoadCutTreeOAM
	call asm_f055
	ld hl, $c393
	ld de, $4
	ld a, $30
	ld c, e
.asm_f044
	ld [hl], a
	add hl, de
	xor $60
	dec c
	jr nz, .asm_f044
	ret

LoadCutTreeOAM: ; f04c (3:704c)
	ld de, AnimationTileset2 + $60 ; $474e ; tile depicting a leaf
	ld bc, (BANK(AnimationTileset2) << 8) + $01
	jp CopyVideoData
asm_f055: ; f055 (3:7055)
	call Func_f068
	ld a, $9
	ld de, CutTreeOAM ; $7060
	jp WriteOAMBlock

CutTreeOAM: ; f060 (3:7060)
	db $FC,$10,$FD,$10
	db $FE,$10,$FF,$10

Func_f068: ; f068 (3:7068)
	ld hl, $c104
	ld a, [hli]
	ld b, a
	inc hl
	ld a, [hli]
	ld c, a ; bc holds ypos/xpos of player's sprite
	inc hl
	inc hl
	ld a, [hl] ; a holds direction of player (00: down, 04: up, 08: left, 0C: right)
	srl a
	ld e, a
	ld d, $0 ; de holds direction (00: down, 02: up, 04: left, 06: right)
	ld a, [$cd50]
	and a
	ld hl, CutTreeAnimationOffsets ; $708f
	jr z, .asm_f084
	ld hl, CutTreeAnimationOffsets2 ; $7097
.asm_f084
	add hl, de
	ld e, [hl]
	inc hl
	ld d, [hl]
	ld a, b
	add d
	ld b, a
	ld a, c
	add e
	ld c, a
	ret

CutTreeAnimationOffsets: ; f08f (3:708f)
; Each pair represents the x and y pixels offsets from the player of where the cut tree animation should be drawn
	db  8, 36 ; player is facing down
	db  8,  4 ; player is facing up
	db -8, 20 ; player is facing left
	db 24, 20 ; player is facing right

CutTreeAnimationOffsets2: ; f097 (3:7097)
; Not sure if these ever get used. CutTreeAnimationOffsets only seems to be used.
; Each pair represents the x and y pixels offsets from the player of where the cut tree animation should be drawn
; These offsets represent 2 blocks away from the player
	db  8,  52 ; player is facing down
	db  8, -12 ; player is facing up
	db -24, 20 ; player is facing left
	db 40,  20 ; player is facing right

Func_f09f: ; f09f (3:709f)
	push de
	ld a, [W_CURMAPWIDTH] ; $d369
	add $6
	ld c, a
	ld b, $0
	ld d, $0
	ld hl, $d35f
	ld a, [hli]
	ld h, [hl]
	ld l, a
	add hl, bc
	ld a, [$c109]
	and a
	jr z, .asm_f0c7
	cp $4
	jr z, .asm_f0cf
	cp $8
	jr z, .asm_f0d7
	ld a, [W_XBLOCKCOORD] ; $d364
	and a
	jr z, .asm_f0e0
	jr .asm_f0ec
.asm_f0c7
	ld a, [W_YBLOCKCOORD] ; $d363
	and a
	jr z, .asm_f0e0
	jr .asm_f0df
.asm_f0cf
	ld a, [W_YBLOCKCOORD] ; $d363
	and a
	jr z, .asm_f0e1
	jr .asm_f0e0
.asm_f0d7
	ld a, [W_XBLOCKCOORD] ; $d364
	and a
	jr z, .asm_f0e6
	jr .asm_f0e0
.asm_f0df
	add hl, bc
.asm_f0e0
	add hl, bc
.asm_f0e1
	ld e, $2
	add hl, de
	jr .asm_f0f0
.asm_f0e6
	ld e, $1
	add hl, bc
	add hl, de
	jr .asm_f0f0
.asm_f0ec
	ld e, $3
	add hl, bc
	add hl, de
.asm_f0f0
	pop de
	ld a, [hl]
	ld c, a
.asm_f0f3
	ld a, [de]
	inc de
	inc de
	cp $ff
	ret z
	cp c
	jr nz, .asm_f0f3
	dec de
	ld a, [de]
	ld [hl], a
	ret

CutTreeBlockSwaps: ; f100 (3:7100)
; first byte = tileset block containing the cut tree
; second byte = corresponding tileset block after the cut animation happens
	db $32, $6D
	db $33, $6C
	db $34, $6F
	db $35, $4C
	db $60, $6E
	db $0B, $0A
	db $3C, $35
	db $3F, $35
	db $3D, $36
	db $FF ; list terminator

Func_f113: ; f113 (3:7113)
	ld a, [W_CURMAP] ; $d35e
	cp ROUTE_1
	jr nc, .notInTown
	ld c, a
	ld b, $1
	ld hl, W_TOWNVISITEDFLAG   ; mark town as visited (for flying)
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
.notInTown
	ld hl, MapHSPointers
	ld a, [W_CURMAP] ; $d35e
	ld b, $0
	ld c, a
	add hl, bc
	add hl, bc
	ld a, [hli]                ; load missable objects pointer in hl
	ld h, [hl]

Func_f132: ; f132 (3:7132)
	ld l, a
	push hl
	ld de, MapHS00             ; calculate difference between out pointer and the base pointer
	ld a, l
	sub e
	jr nc, .asm_f13c
	dec h
.asm_f13c
	ld l, a
	ld a, h
	sub d
	ld h, a
	ld a, h
	ld [H_DIVIDEND], a
	ld a, l
	ld [H_DIVIDEND+1], a
	xor a
	ld [H_DIVIDEND+2], a
	ld [H_DIVIDEND+3], a
	ld a, $3
	ld [H_DIVISOR], a
	ld b, $2
	call Divide                ; divide difference by 3, resulting in the global offset (number of missable items before ours)
	ld a, [W_CURMAP] ; $d35e
	ld b, a
	ld a, [H_DIVIDEND+3]
	ld c, a                    ; store global offset in c
	ld de, W_MISSABLEOBJECTLIST
	pop hl
.writeMissableObjectsListLoop
	ld a, [hli]
	cp $ff
	jr z, .done     ; end of list
	cp b
	jr nz, .done    ; not for current map anymore
	ld a, [hli]
	inc hl
	ld [de], a                 ; write (map-local) sprite ID
	inc de
	ld a, c
	inc c
	ld [de], a                 ; write (global) missable object index
	inc de
	jr .writeMissableObjectsListLoop
.done
	ld a, $ff
	ld [de], a                 ; write sentinel
	ret

InitializeMissableObjectsFlags: ; f175 (3:7175)
	ld hl, W_MISSABLEOBJECTFLAGS
	ld bc, $20
	xor a
	call FillMemory ; clear missable objects flags
	ld hl, MapHS00
	xor a
	ld [$d048], a
.missableObjectsLoop
	ld a, [hli]
	cp $ff          ; end of list
	ret z
	push hl
	inc hl
	ld a, [hl]
	cp Hide
	jr nz, .asm_f19d
	ld hl, W_MISSABLEOBJECTFLAGS
	ld a, [$d048]
	ld c, a
	ld b, $1
	call HandleBitArray2 ; set flag iff Item is hidden
.asm_f19d
	ld hl, $d048
	inc [hl]
	pop hl
	inc hl
	inc hl
	jr .missableObjectsLoop

; tests if current sprite is a missable object that is hidden/has been removed
IsMissableObjectHidden: ; f1a6 (3:71a6)
	ld a, [H_CURRENTSPRITEOFFSET]
	swap a
	ld b, a
	ld hl, W_MISSABLEOBJECTLIST
.loop
	ld a, [hli]
	cp $ff
	jr z, .notHidden ; not missable -> not hidden
	cp b
	ld a, [hli]
	jr nz, .loop
	ld c, a
	ld b, $2
	ld hl, W_MISSABLEOBJECTFLAGS
	call HandleBitArray2
	ld a, c
	and a
	jr nz, .hidden
.notHidden
	xor a
.hidden
	ld [$ffe5], a
	ret

; adds missable object (items, leg. pokemon, etc.) to the map
; [$cc4d]: index of the missable object to be added (global index)
AddMissableObject: ; f1c8 (3:71c8)
	ld hl, W_MISSABLEOBJECTFLAGS
	ld a, [$cc4d]
	ld c, a
	ld b, $0
	call HandleBitArray2   ; reset "removed" flag
	jp UpdateSprites

; removes missable object (items, leg. pokemon, etc.) from the map
; [$cc4d]: index of the missable object to be removed (global index)
RemoveMissableObject: ; f1d7 (3:71d7)
	ld hl, W_MISSABLEOBJECTFLAGS
	ld a, [$cc4d]
	ld c, a
	ld b, $1
	call HandleBitArray2   ; set "removed" flag
	jp UpdateSprites

; functionally identical to _HandleBitArray, but with less optimized instructions
; executes operations on a field of bits
; b = 0 -> reset bit
; b = 1 -> set bit
; b = 2 -> read bit (into c and z-flag)
; hl: base address
; c: bit index
HandleBitArray2: ; f1e6 (3:71e6)
	push hl
	push de
	push bc
	ld a, c
	ld d, a
	and $7
	ld e, a        ; store bit offset in e
	ld a, d
	srl a
	srl a
	srl a          ; calc byte offset
	add l
	ld l, a
	jr nc, .noCarry
	inc h
.noCarry
	inc e
	ld d, $1
.shiftLeftLoop     ; d = 1 << e, bitmask for the used bit
	dec e
	jr z, .operationSelect
	sla d
	jr .shiftLeftLoop
.operationSelect
	ld a, b
	and a
	jr z, .resetBit
	cp $2
	jr z, .readBit
	ld a, [hl] ; set bit
	ld b, a
	ld a, d
	or b
	ld [hl], a
	jr .done
.resetBit
	ld a, [hl]
	ld b, a
	ld a, d
	xor $ff
	and b
	ld [hl], a
	jr .done
.readBit
	ld a, [hl]
	ld b, a
	ld a, d
	and b
.done
	pop bc
	pop de
	pop hl
	ld c, a
	ret

Func_f225: ; f225 (3:7225)
	ld a, [$d728]
	bit 0, a
	ret z
	ld a, [wFlags_0xcd60]
	bit 1, a
	ret nz
	xor a
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call IsSpriteInFrontOfPlayer
	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
	ld [$d718], a
	and a
	jp z, Func_f2dd
	ld hl, $c101
	ld d, $0
	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
	swap a
	ld e, a
	add hl, de
	res 7, [hl]
	call GetSpriteMovementByte2Pointer
	ld a, [hl]
	cp $10
	jp nz, Func_f2dd
	ld hl, wFlags_0xcd60
	bit 6, [hl]
	set 6, [hl]
	ret z
	ld a, [H_CURRENTPRESSEDBUTTONS]
	and $f0
	ret z
	ld a, $5a
	call Predef ; indirect jump to Func_c60b (c60b (3:460b))
	ld a, [$d71c]
	and a
	jp nz, Func_f2dd
	ld a, [H_CURRENTPRESSEDBUTTONS]
	ld b, a
	ld a, [$c109]
	cp $4
	jr z, .asm_f289
	cp $8
	jr z, .asm_f291
	cp $c
	jr z, .asm_f299
	bit 7, b
	ret z
	ld de, MovementData_f2af
	jr .asm_f29f
.asm_f289
	bit 6, b
	ret z
	ld de, MovementData_f2ad
	jr .asm_f29f
.asm_f291
	bit 5, b
	ret z
	ld de, MovementData_f2b1
	jr .asm_f29f
.asm_f299
	bit 4, b
	ret z
	ld de, MovementData_f2b3
.asm_f29f
	call MoveSprite
	ld a, (SFX_02_53 - SFX_Headers_02) / 3
	call PlaySound
	ld hl, wFlags_0xcd60
	set 1, [hl]
	ret

MovementData_f2ad: ; f2ad (3:72ad)
	db $40,$FF

MovementData_f2af: ; f2af (3:72af)
	db $00,$FF

MovementData_f2b1: ; f2b1 (3:72b1)
	db $80,$FF

MovementData_f2b3: ; f2b3 (3:72b3)
	db $C0,$FF

Func_f2b5: ; f2b5 (3:72b5)
	ld a, [$d730]
	bit 0, a
	ret nz
	callab Func_79f54
	call DiscardButtonPresses
	ld [wJoypadForbiddenButtonsMask], a
	call Func_f2dd
	set 7, [hl]
	ld a, [$d718]
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call GetSpriteMovementByte2Pointer
	ld [hl], $10
	ld a, (SFX_02_56 - SFX_Headers_02) / 3
	jp PlaySound

Func_f2dd: ; f2dd (3:72dd)
	ld hl, wFlags_0xcd60
	res 1, [hl]
	res 6, [hl]
	ret

_AddPokemonToParty: ; f2e5 (3:72e5)
	ld de, W_NUMINPARTY ; $d163
	ld a, [$cc49]
	and $f
	jr z, .asm_f2f2
	ld de, wEnemyPartyCount ; $d89c
.asm_f2f2
	ld a, [de]
	inc a
	cp $7
	ret nc
	ld [de], a
	ld a, [de]
	ld [$ffe4], a
	add e
	ld e, a
	jr nc, .asm_f300
	inc d
.asm_f300
	ld a, [$cf91]
	ld [de], a
	inc de
	ld a, $ff
	ld [de], a
	ld hl, W_PARTYMON1OT ; $d273
	ld a, [$cc49]
	and $f
	jr z, .asm_f315
	ld hl, W_ENEMYMON1OT
.asm_f315
	ld a, [$ffe4]
	dec a
	call SkipFixedLengthTextEntries
	ld d, h
	ld e, l
	ld hl, W_PLAYERNAME ; $d158
	ld bc, $b
	call CopyData
	ld a, [$cc49]
	and a
	jr nz, .asm_f33f
	ld hl, W_PARTYMON1NAME ; $d2b5
	ld a, [$ffe4]
	dec a
	call SkipFixedLengthTextEntries
	ld a, $2
	ld [$d07d], a
	ld a, $4e
	call Predef ; indirect jump to Func_64eb (64eb (1:64eb))
.asm_f33f
	ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
	ld a, [$cc49]
	and $f
	jr z, .asm_f34c
	ld hl, wEnemyMons ; $d8a4
.asm_f34c
	ld a, [$ffe4]
	dec a
	ld bc, $2c
	call AddNTimes
	ld e, l
	ld d, h
	push hl
	ld a, [$cf91]
	ld [$d0b5], a
	call GetMonHeader
	ld hl, W_MONHEADER
	ld a, [hli]
	ld [de], a
	inc de
	pop hl
	push hl
	ld a, [$cc49]
	and $f
	ld a, $98     ; set enemy trainer mon IVs to fixed average values
	ld b, $88
	jr nz, .writeFreshMonData
	ld a, [$cf91]
	ld [$d11e], a
	push de
	ld a, $3a
	call Predef ; indirect jump to IndexToPokedex (41010 (10:5010))
	pop de
	ld a, [$d11e]
	dec a
	ld c, a
	ld b, $2
	ld hl, wPokedexOwned ; $d2f7
	call _HandleBitArray
	ld a, c
	ld [$d153], a
	ld a, [$d11e]
	dec a
	ld c, a
	ld b, $1
	push bc
	call _HandleBitArray
	pop bc
	ld hl, wPokedexSeen ; $d30a
	call _HandleBitArray
	pop hl
	push hl
	ld a, [W_ISINBATTLE] ; $d057
	and a
	jr nz, .copyEnemyMonData
	call GenRandom     ; generate random IVs
	ld b, a
	call GenRandom
.writeFreshMonData ; f3b3
	push bc
	ld bc, $1b
	add hl, bc
	pop bc
	ld [hli], a
	ld [hl], b         ; write IVs
	ld bc, $fff4
	add hl, bc
	ld a, $1
	ld c, a
	xor a
	ld b, a
	call CalcStat      ; calc HP stat (set cur Hp to max HP)
	ld a, [H_MULTIPLICAND+1]
	ld [de], a
	inc de
	ld a, [H_MULTIPLICAND+2]
	ld [de], a
	inc de
	xor a
	ld [de], a         ; level (?)
	inc de
	ld [de], a         ; status ailments
	inc de
	jr .copyMonTypesAndMoves
.copyEnemyMonData
	ld bc, $1b
	add hl, bc
	ld a, [W_ENEMYMONATKDEFIV] ; copy IVs from cur enemy mon
	ld [hli], a
	ld a, [W_ENEMYMONSPDSPCIV]
	ld [hl], a
	ld a, [W_ENEMYMONCURHP]    ; copy HP from cur enemy mon
	ld [de], a
	inc de
	ld a, [W_ENEMYMONCURHP+1]
	ld [de], a
	inc de
	xor a
	ld [de], a                 ; level (?)
	inc de
	ld a, [W_ENEMYMONSTATUS]   ; copy status ailments from cur enemy mon
	ld [de], a
	inc de
.copyMonTypesAndMoves
	ld hl, W_MONHTYPES
	ld a, [hli]       ; type 1
	ld [de], a
	inc de
	ld a, [hli]       ; type 2
	ld [de], a
	inc de
	ld a, [hli]       ; unused (?)
	ld [de], a
	ld hl, W_MONHMOVES
	ld a, [hli]
	inc de
	push de
	ld [de], a
	ld a, [hli]
	inc de
	ld [de], a
	ld a, [hli]
	inc de
	ld [de], a
	ld a, [hli]
	inc de
	ld [de], a
	push de
	dec de
	dec de
	dec de
	xor a
	ld [$cee9], a
	ld a, $3e
	call Predef ; indirect jump to WriteMonMoves (3afb8 (e:6fb8))
	pop de
	ld a, [wPlayerID]  ; set trainer ID to player ID
	inc de
	ld [de], a
	ld a, [wPlayerID + 1]
	inc de
	ld [de], a
	push de
	ld a, [W_CURENEMYLVL]
	ld d, a
	callab CalcExperience
	pop de
	inc de
	ld a, [H_MULTIPLICAND] ; write experience
	ld [de], a
	inc de
	ld a, [H_MULTIPLICAND+1]
	ld [de], a
	inc de
	ld a, [H_MULTIPLICAND+2]
	ld [de], a
	xor a
	ld b, $a
.writeEVsLoop              ; set all EVs to 0
	inc de
	ld [de], a
	dec b
	jr nz, .writeEVsLoop
	inc de
	inc de
	pop hl
	call AddPokemonToParty_WriteMovePP
	inc de
	ld a, [W_CURENEMYLVL] ; $d127
	ld [de], a
	inc de
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	jr nz, .calcFreshStats
	ld hl, W_ENEMYMONMAXHP ; $cff4
	ld bc, $a
	call CopyData          ; copy stats of cur enemy mon
	pop hl
	jr .done
.calcFreshStats
	pop hl
	ld bc, $10
	add hl, bc
	ld b, $0
	call CalcStats         ; calculate fresh set of stats
.done
	scf
	ret

LoadMovePPs: ; f473 (3:7473)
	call Load16BitRegisters
	; fallthrough
AddPokemonToParty_WriteMovePP: ; f476 (3:7476)
	ld b, $4
.pploop
	ld a, [hli]     ; read move ID
	and a
	jr z, .empty
	dec a
	push hl
	push de
	push bc
	ld hl, Moves
	ld bc, $6
	call AddNTimes
	ld de, $cd6d
	ld a, BANK(Moves)
	call FarCopyData
	pop bc
	pop de
	pop hl
	ld a, [$cd72] ; sixth move byte = pp
.empty
	inc de
	ld [de], a
	dec b
	jr nz, .pploop ; there are still moves to read
	ret

; adds enemy mon [$cf91] (at position [$cf92] in enemy list) to own party
; used in the cable club trade center
_AddEnemyMonToPlayerParty: ; f49d (3:749d)
	ld hl, W_NUMINPARTY
	ld a, [hl]
	cp $6
	scf
	ret z            ; party full, return failure
	inc a
	ld [hl], a       ; add 1 to party members
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [$cf91]
	ld [hli], a      ; add mon as last list entry
	ld [hl], $ff     ; write new sentinel
	ld hl, W_PARTYMON1DATA
	ld a, [W_NUMINPARTY]
	dec a
	ld bc, W_PARTYMON2DATA - W_PARTYMON1DATA
	call AddNTimes
	ld e, l
	ld d, h
	ld hl, $cf98
	call CopyData    ; write new mon's data (from $cf98)
	ld hl, W_PARTYMON1OT
	ld a, [W_NUMINPARTY]
	dec a
	call SkipFixedLengthTextEntries
	ld d, h
	ld e, l
	ld hl, W_ENEMYMON1OT
	ld a, [wWhichPokemon]
	call SkipFixedLengthTextEntries
	ld bc, $000b
	call CopyData    ; write new mon's OT name (from an enemy mon)
	ld hl, W_PARTYMON1NAME
	ld a, [W_NUMINPARTY]
	dec a
	call SkipFixedLengthTextEntries
	ld d, h
	ld e, l
	ld hl, W_ENEMYMON1NAME
	ld a, [wWhichPokemon]
	call SkipFixedLengthTextEntries
	ld bc, $000b
	call CopyData    ; write new mon's nickname (from an enemy mon)
	ld a, [$cf91]
	ld [$d11e], a
	ld a, $3a
	call Predef
	ld a, [$d11e]
	dec a
	ld c, a
	ld b, $1
	ld hl, wPokedexOwned
	push bc
	call _HandleBitArray ; add to owned pokemon
	pop bc
	ld hl, wPokedexSeen
	call _HandleBitArray ; add to seen pokemon
	and a
	ret                  ; return success

Func_f51e: ; f51e (3:751e)
	ld a, [$cf95]
	and a
	jr z, .checkPartyMonSlots
	cp $2
	jr z, .checkPartyMonSlots
	cp $3
	ld hl, W_DAYCAREMONDATA
	jr z, .asm_f575
	ld hl, W_NUMINBOX ; $da80
	ld a, [hl]
	cp $14
	jr nz, .partyOrBoxNotFull
	jr .boxFull
.checkPartyMonSlots
	ld hl, W_NUMINPARTY ; $d163
	ld a, [hl]
	cp $6
	jr nz, .partyOrBoxNotFull
.boxFull
	scf
	ret
.partyOrBoxNotFull
	inc a
	ld [hl], a           ; increment number of mons in party/box
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [$cf95]
	cp $2
	ld a, [W_DAYCAREMONDATA]
	jr z, .asm_f556
	ld a, [$cf91]
.asm_f556
	ld [hli], a          ; write new mon ID
	ld [hl], $ff         ; write new sentinel
	ld a, [$cf95]
	dec a
	ld hl, W_PARTYMON1DATA ; $d16b
	ld bc, W_PARTYMON2DATA - W_PARTYMON1DATA ; $2c
	ld a, [W_NUMINPARTY] ; $d163
	jr nz, .skipToNewMonEntry
	ld hl, W_BOXMON1DATA
	ld bc, W_BOXMON2DATA - W_BOXMON1DATA ; $21
	ld a, [W_NUMINBOX] ; $da80
.skipToNewMonEntry
	dec a
	call AddNTimes
.asm_f575
	push hl
	ld e, l
	ld d, h
	ld a, [$cf95]
	and a
	ld hl, W_BOXMON1DATA
	ld bc, W_BOXMON2DATA - W_BOXMON1DATA ; $21
	jr z, .asm_f591
	cp $2
	ld hl, W_DAYCAREMONDATA
	jr z, .asm_f597
	ld hl, W_PARTYMON1DATA ; $d16b
	ld bc, W_PARTYMON2DATA - W_PARTYMON1DATA ; $2c
.asm_f591
	ld a, [wWhichPokemon] ; $cf92
	call AddNTimes
.asm_f597
	push hl
	push de
	ld bc, $21
	call CopyData
	pop de
	pop hl
	ld a, [$cf95]
	and a
	jr z, .asm_f5b4
	cp $2
	jr z, .asm_f5b4
	ld bc, $21
	add hl, bc
	ld a, [hl]
	inc de
	inc de
	inc de
	ld [de], a
.asm_f5b4
	ld a, [$cf95]
	cp $3
	ld de, W_DAYCAREMONOT
	jr z, .asm_f5d3
	dec a
	ld hl, W_PARTYMON1OT ; $d273
	ld a, [W_NUMINPARTY] ; $d163
	jr nz, .asm_f5cd
	ld hl, W_BOXMON1OT
	ld a, [W_NUMINBOX] ; $da80
.asm_f5cd
	dec a
	call SkipFixedLengthTextEntries
	ld d, h
	ld e, l
.asm_f5d3
	ld hl, W_BOXMON1OT
	ld a, [$cf95]
	and a
	jr z, .asm_f5e6
	ld hl, W_DAYCAREMONOT
	cp $2
	jr z, .asm_f5ec
	ld hl, W_PARTYMON1OT ; $d273
.asm_f5e6
	ld a, [wWhichPokemon] ; $cf92
	call SkipFixedLengthTextEntries
.asm_f5ec
	ld bc, $b
	call CopyData
	ld a, [$cf95]
	cp $3
	ld de, W_DAYCAREMONNAME
	jr z, .asm_f611
	dec a
	ld hl, W_PARTYMON1NAME ; $d2b5
	ld a, [W_NUMINPARTY] ; $d163
	jr nz, .asm_f60b
	ld hl, W_BOXMON1NAME
	ld a, [W_NUMINBOX] ; $da80
.asm_f60b
	dec a
	call SkipFixedLengthTextEntries
	ld d, h
	ld e, l
.asm_f611
	ld hl, W_BOXMON1NAME
	ld a, [$cf95]
	and a
	jr z, .asm_f624
	ld hl, W_DAYCAREMONNAME
	cp $2
	jr z, .asm_f62a
	ld hl, W_PARTYMON1NAME ; $d2b5
.asm_f624
	ld a, [wWhichPokemon] ; $cf92
	call SkipFixedLengthTextEntries
.asm_f62a
	ld bc, $b
	call CopyData
	pop hl
	ld a, [$cf95]
	cp $1
	jr z, .asm_f664
	cp $3
	jr z, .asm_f664
	push hl
	srl a
	add $2
	ld [$cc49], a
	call LoadMonData
	callba Func_58f43
	ld a, d
	ld [W_CURENEMYLVL], a ; $d127
	pop hl
	ld bc, $21
	add hl, bc
	ld [hli], a
	ld d, h
	ld e, l
	ld bc, $ffee
	add hl, bc
	ld b, $1
	call CalcStats
.asm_f664
	and a
	ret

; predef $10
; executes operations on a field of bits
; b = 0 -> reset bit
; b = 1 -> set bit
; b = 2 -> read bit (into c and z-flag)
; hl: base address
; c: bit index
HandleBitArray: ; f666 (3:7666)
	call Load16BitRegisters

_HandleBitArray: ; f669 (3:7669)
	push hl
	push de
	push bc
	ld a, c
	ld d, a
	and $7
	ld e, a        ; store bit offset in e
	ld a, d
	srl a
	srl a
	srl a          ; calc byte offset
	add l
	ld l, a
	jr nc, .noCarry
	inc h
.noCarry
	inc e
	ld d, $1
.shiftLeftLoop     ; d = 1 << e, bitmask for the used bit
	dec e
	jr z, .operationSelect
	sla d
	jr .shiftLeftLoop
.operationSelect
	ld a, b
	and a
	jr z, .resetBit
	cp $2
	jr z, .readBit
	ld b, [hl] ; set bit
	ld a, d
	or b
	ld [hl], a
	jr .done
.resetBit
	ld b, [hl]
	ld a, d
	xor $ff
	and b
	ld [hl], a
	jr .done
.readBit
	ld b, [hl]
	ld a, d
	and b
.done
	pop bc
	pop de
	pop hl
	ld c, a
	ret

HealParty: ; f6a5 (3:76a5)
	ld hl, W_PARTYMON1
	ld de, W_PARTYMON1_HP
.HealPokemon: ; f6ab (3:76ab)
	ld a, [hli]
	cp $ff
	jr z, .DoneHealing ; End if there's no Pokémon
	push hl
	push de
	ld hl, $0003 ; Status offset
	add hl, de
	xor a
	ld [hl], a ; Clean status conditions
	push de
	ld b, $4 ; A Pokémon has 4 moves
.RestorePP: ; f6bb (3:76bb)
	ld hl, $0007 ; Move offset
	add hl, de
	ld a, [hl]
	and a
	jr z, .HealNext ; Skip if there's no move here
	dec a
	ld hl, $001c ; PP offset
	add hl, de
	push hl
	push de
	push bc
	ld hl, Moves
	ld bc, $0006
	call AddNTimes
	ld de, $cd6d
	ld a, BANK(Moves)
	call FarCopyData ; copy move header to memory
	ld a, [$cd72] ; get default PP
	pop bc
	pop de
	pop hl
	inc de
	push bc
	ld b, a
	ld a, [hl]
	and $c0
	add b
	ld [hl], a
	pop bc
.HealNext: ; f6eb (3:76eb)
	dec b
	jr nz, .RestorePP ; Continue if there's still moves
	pop de
	ld hl, $0021 ; Max HP offset
	add hl, de
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hl]
	ld [de], a ; Restore full HP
	pop de
	pop hl
	push hl
	ld bc, $002c
	ld h, d
	ld l, e
	add hl, bc
	ld d, h
	ld e, l
	pop hl
	jr .HealPokemon ; Next Pokémon
.DoneHealing
	xor a
	ld [wWhichPokemon], a
	ld [$d11e], a
	ld a, [W_NUMINPARTY]
	ld b, a
.restoreBonusPPLoop ; loop to restore bonus PP from PP Ups
	push bc
	call RestoreBonusPP
	pop bc
	ld hl, wWhichPokemon
	inc [hl]
	dec b
	jr nz,.restoreBonusPPLoop
	ret

; predef $9
; predef $a
; predef $d
; predef $e
Func_f71e: ; f71e (3:771e)
	call Load16BitRegisters
	xor a
	ld [$ffa5], a
	ld [$ffa6], a
	ld [$ffa7], a
	ld d, $1
.asm_f72a
	ld a, [$ffa2]
	and $f0
	jr nz, .asm_f75b
	inc d
	ld a, [$ffa2]
	swap a
	and $f0
	ld b, a
	ld a, [$ffa3]
	swap a
	ld [$ffa3], a
	and $f
	or b
	ld [$ffa2], a
	ld a, [$ffa3]
	and $f0
	ld b, a
	ld a, [$ffa4]
	swap a
	ld [$ffa4], a
	and $f
	or b
	ld [$ffa3], a
	ld a, [$ffa4]
	and $f0
	ld [$ffa4], a
	jr .asm_f72a
.asm_f75b
	push de
	push de
	call Func_f800
	pop de
	ld a, b
	swap a
	and $f0
	ld [$ffa5], a
	dec d
	jr z, .asm_f7bc
	push de
	call Func_f7d7
	call Func_f800
	pop de
	ld a, [$ffa5]
	or b
	ld [$ffa5], a
	dec d
	jr z, .asm_f7bc
	push de
	call Func_f7d7
	call Func_f800
	pop de
	ld a, b
	swap a
	and $f0
	ld [$ffa6], a
	dec d
	jr z, .asm_f7bc
	push de
	call Func_f7d7
	call Func_f800
	pop de
	ld a, [$ffa6]
	or b
	ld [$ffa6], a
	dec d
	jr z, .asm_f7bc
	push de
	call Func_f7d7
	call Func_f800
	pop de
	ld a, b
	swap a
	and $f0
	ld [$ffa7], a
	dec d
	jr z, .asm_f7bc
	push de
	call Func_f7d7
	call Func_f800
	pop de
	ld a, [$ffa7]
	or b
	ld [$ffa7], a
.asm_f7bc
	ld a, [$ffa5]
	ld [$ffa2], a
	ld a, [$ffa6]
	ld [$ffa3], a
	ld a, [$ffa7]
	ld [$ffa4], a
	pop de
	ld a, $6
	sub d
	and a
	ret z
.asm_f7ce
	push af
	call Func_f7d7
	pop af
	dec a
	jr nz, .asm_f7ce
	ret

Func_f7d7: ; f7d7 (3:77d7)
	ld a, [$ffa4]
	swap a
	and $f
	ld b, a
	ld a, [$ffa3]
	swap a
	ld [$ffa3], a
	and $f0
	or b
	ld [$ffa4], a
	ld a, [$ffa3]
	and $f
	ld b, a
	ld a, [$ffa2]
	swap a
	ld [$ffa2], a
	and $f0
	or b
	ld [$ffa3], a
	ld a, [$ffa2]
	and $f
	ld [$ffa2], a
	ret

Func_f800: ; f800 (3:7800)
	ld bc, $3
.asm_f803
	ld de, $ff9f
	ld hl, $ffa2
	push bc
	call StringCmp
	pop bc
	ret c
	inc b
	ld de, $ffa1
	ld hl, $ffa4
	push bc
	call Func_f839
	pop bc
	jr .asm_f803

Func_f81d: ; f81d (3:781d)
	call Load16BitRegisters
	and a
	ld b, c
.asm_f822
	ld a, [de]
	adc [hl]
	daa
	ld [de], a
	dec de
	dec hl
	dec c
	jr nz, .asm_f822
	jr nc, .asm_f835
	ld a, $99
	inc de
.asm_f830
	ld [de], a
	inc de
	dec b
	jr nz, .asm_f830
.asm_f835
	ret

Func_f836: ; f836 (3:7836)
	call Load16BitRegisters

Func_f839: ; f839 (3:7839)
	and a
	ld b, c
.asm_f83b
	ld a, [de]
	sbc [hl]
	daa
	ld [de], a
	dec de
	dec hl
	dec c
	jr nz, .asm_f83b
	jr nc, .asm_f84f
	ld a, $0
	inc de
.asm_f849
	ld [de], a
	inc de
	dec b
	jr nz, .asm_f849
	scf
.asm_f84f
	ret

InitializePlayerData: ; f850 (3:7850)
	call GenRandom
	ld a, [H_RAND2]
	ld [wPlayerID], a          ; set player trainer id
	call GenRandom
	ld a, [H_RAND1]
	ld [wPlayerID + 1], a
	ld a, $ff
	ld [$d71b], a                 ; XXX what's this?
	ld hl, W_NUMINPARTY ; $d163
	call InitializeEmptyList      ; no party mons
	ld hl, W_NUMINBOX ; $da80
	call InitializeEmptyList      ; no boxed mons
	ld hl, wNumBagItems ; $d31d
	call InitializeEmptyList      ; no items
	ld hl, wNumBoxItems ; $d53a
	call InitializeEmptyList      ; no boxed items
	ld hl, wPlayerMoney + 1 ; $d348
	ld a, $30
	ld [hld], a                   ; set money to 00 30 00 (3000)
	xor a
	ld [hli], a
	inc hl
	ld [hl], a
	ld [$cc49], a                 ; XXX what's this?
	ld hl, W_OBTAINEDBADGES
	ld [hli], a                   ; no badges obtained
	ld [hl], a                    ; XXX what's this?
	ld hl, wPlayerCoins ; $d5a4
	ld [hli], a                   ; no coins
	ld [hl], a
	ld hl, W_GAMEPROGRESSFLAGS ; $d5f0
	ld bc, $c8
	call FillMemory               ; clear all game progress flags
	jp InitializeMissableObjectsFlags

; writes two bytes $00 $ff to hl
InitializeEmptyList: ; f8a0 (3:78a0)
	xor a
	ld [hli], a
	dec a
	ld [hl], a
	ret

Func_f8a5: ; f8a5 (3:78a5)
	call Load16BitRegisters
	ld hl, wNumBagItems ; $d31d
.asm_f8ab
	inc hl
	ld a, [hli]
	cp $ff
	jr z, .asm_f8b7
	cp b
	jr nz, .asm_f8ab
	ld a, [hl]
	ld b, a
	ret
.asm_f8b7
	ld b, $0
	ret

Func_f8ba: ; f8ba (3:78ba)
	xor a
	ld hl, $ff97
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hl], a
	ld hl, $cc97
	ld de, $0

Func_f8c8: ; f8c8 (3:78c8)
	ld a, [H_REMAINDER] ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld b, a
	ld a, [H_DIVIDEND] ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	call CalcDifference
	ld d, a
	and a
	jr nz, .asm_f8da
	ld a, [$ff98]
	set 0, a
	ld [$ff98], a
.asm_f8da
	ld a, [$ff9a]
	ld b, a
	ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
	call CalcDifference
	ld e, a
	and a
	jr nz, .asm_f8ec
	ld a, [$ff98]
	set 1, a
	ld [$ff98], a
.asm_f8ec
	ld a, [$ff98]
	cp $3
	jr z, .asm_f926
	ld a, e
	cp d
	jr c, .asm_f90a
	ld a, [$ff9d]
	bit 1, a
	jr nz, .asm_f900
	ld d, $c0
	jr .asm_f902
.asm_f900
	ld d, $80
.asm_f902
	ld a, [$ff9a]
	add $1
	ld [$ff9a], a
	jr .asm_f91c
.asm_f90a
	ld a, [$ff9d]
	bit 0, a
	jr nz, .asm_f914
	ld d, $0
	jr .asm_f916
.asm_f914
	ld d, $40
.asm_f916
	ld a, [H_REMAINDER] ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	add $1
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
.asm_f91c
	ld a, d
	ld [hli], a
	ld a, [$ff97]
	inc a
	ld [$ff97], a
	jp Func_f8c8
.asm_f926
	ld [hl], $ff
	ret

Func_f929: ; f929 (3:7929)
	xor a
	ld [$ff9d], a
	ld a, [$c104]
	ld d, a
	ld a, [$c106]
	ld e, a
	ld hl, wSpriteStateData1
	ld a, [H_DIVIDEND] ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	add l
	add $4
	ld l, a
	jr nc, .asm_f940
	inc h
.asm_f940
	ld a, d
	ld b, a
	ld a, [hli]
	call CalcDifference
	jr nc, .asm_f953
	push hl
	ld hl, $ff9d
	bit 0, [hl]
	set 0, [hl]
	pop hl
	jr .asm_f95c
.asm_f953
	push hl
	ld hl, $ff9d
	bit 0, [hl]
	res 0, [hl]
	pop hl
.asm_f95c
	push hl
	ld hl, $ffe5
	ld [hli], a
	ld a, $10
	ld [hli], a
	call Func_366b
	ld a, [hl]
	ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	pop hl
	inc hl
	ld b, e
	ld a, [hl]
	call CalcDifference
	jr nc, .asm_f97e
	push hl
	ld hl, $ff9d
	bit 1, [hl]
	set 1, [hl]
	pop hl
	jr .asm_f987
.asm_f97e
	push hl
	ld hl, $ff9d
	bit 1, [hl]
	res 1, [hl]
	pop hl
.asm_f987
	ld [$ffe5], a
	ld a, $10
	ld [$ffe6], a
	call Func_366b
	ld a, [$ffe7]
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, [$ff9b]
	and a
	ret z
	ld a, [$ff9d]
	cpl
	and $3
	ld [$ff9d], a
	ret

Func_f9a0: ; f9a0 (3:79a0)
	ld a, [$ff95]
	ld [$cd37], a
	dec a
	ld de, $ccd3
	ld hl, $cc97
	add l
	ld l, a
	jr nc, .asm_f9b1
	inc h
.asm_f9b1
	ld a, [hld]
	call Func_f9bf
	ld [de], a
	inc de
	ld a, [$ff95]
	dec a
	ld [$ff95], a
	jr nz, .asm_f9b1
	ret

Func_f9bf: ; f9bf (3:79bf)
	push hl
	ld b, a
	ld hl, DataTable_f9d2
.asm_f9c4
	ld a, [hli]
	cp $ff
	jr z, .asm_f9d0
	cp b
	jr z, .asm_f9cf
	inc hl
	jr .asm_f9c4
.asm_f9cf
	ld a, [hl]
.asm_f9d0
	pop hl
	ret

DataTable_f9d2: ; f9d2 (3:79d2)
	db $40, $40, $00, $80, $80, $20, $c0, $10, $ff

Func_f9db: ; f9db (3:79db)
	ret

Func_f9dc: ; f9dc (3:79dc)
	call Load16BitRegisters

; calculates bc * 48 / de, the number of pixels the HP bar has
; the result is always at least 1
UpdateHPBar_CalcNumberOfHPBarPixels: ; f9df (3:79df)
	push hl
	xor a
	ld hl, H_MULTIPLICAND
	ld [hli], a
	ld a, b
	ld [hli], a
	ld a, c
	ld [hli], a
	ld [hl], $30
	call Multiply      ; 48 * bc (hp bar is 48 pixels long)
	ld a, d
	and a
	jr z, .maxHPSmaller256
	srl d              ; make HP in de fit into 1 byte by dividing by 4
	rr e
	srl d
	rr e
	ld a, [H_MULTIPLICAND+1]
	ld b, a
	ld a, [H_MULTIPLICAND+2]
	srl b              ; divide multiplication result as well
	rr a
	srl b
	rr a
	ld [H_MULTIPLICAND+2], a
	ld a, b
	ld [H_MULTIPLICAND+1], a
.maxHPSmaller256
	ld a, e
	ld [H_DIVISOR], a
	ld b, $4
	call Divide
	ld a, [H_MULTIPLICAND+2]
	ld e, a            ; e = bc * 48 / de (num of pixels of HP bar)
	pop hl
	and a
	ret nz
	ld e, $1           ; make result at least 1
	ret

; predef $48
UpdateHPBar: ; fa1d (3:7a1d)
	push hl
	ld hl, wHPBarOldHP
	ld a, [hli]
	ld c, a      ; old HP into bc
	ld a, [hli]
	ld b, a
	ld a, [hli]
	ld e, a      ; new HP into de
	ld d, [hl]
	pop hl
	push de
	push bc
	call UpdateHPBar_CalcHPDifference
	ld a, e
	ld [wHPBarHPDifference+1], a
	ld a, d
	ld [wHPBarHPDifference], a
	pop bc
	pop de
	call UpdateHPBar_CompareNewHPToOldHP
	ret z
	ld a, $ff
	jr c, .HPdecrease
	ld a, $1
.HPdecrease
	ld [wHPBarDelta], a
	call Load16BitRegisters
	ld a, [wHPBarNewHP]
	ld e, a
	ld a, [wHPBarNewHP+1]
	ld d, a
.animateHPBarLoop
	push de
	ld a, [wHPBarOldHP]
	ld c, a
	ld a, [wHPBarOldHP+1]
	ld b, a
	call UpdateHPBar_CompareNewHPToOldHP
	jr z, .animateHPBarDone
	jr nc, .HPIncrease
	dec bc        ; subtract 1 HP
	ld a, c
	ld [wHPBarNewHP], a
	ld a, b
	ld [wHPBarNewHP+1], a
	call UpdateHPBar_CalcOldNewHPBarPixels
	ld a, e
	sub d         ; calc pixel difference
	jr .asm_fa7e
.HPIncrease
	inc bc        ; add 1 HP
	ld a, c
	ld [wHPBarNewHP], a
	ld a, b
	ld [wHPBarNewHP+1], a
	call UpdateHPBar_CalcOldNewHPBarPixels
	ld a, d
	sub e         ; calc pixel difference
.asm_fa7e
	call UpdateHPBar_PrintHPNumber
	and a
	jr z, .noPixelDifference
	call UpdateHPBar_AnimateHPBar
.noPixelDifference
	ld a, [wHPBarNewHP]
	ld [wHPBarOldHP], a
	ld a, [wHPBarNewHP+1]
	ld [wHPBarOldHP+1], a
	pop de
	jr .animateHPBarLoop
.animateHPBarDone
	pop de
	ld a, e
	ld [wHPBarOldHP], a
	ld a, d
	ld [wHPBarOldHP+1], a
	or e
	jr z, .monFainted
	call UpdateHPBar_CalcOldNewHPBarPixels
	ld d, e
.monFainted
	call UpdateHPBar_PrintHPNumber
	ld a, $1
	call UpdateHPBar_AnimateHPBar
	jp Delay3

; animates the HP bar going up or down for (a) ticks (two waiting frames each)
; stops prematurely if bar is filled up
; e: current health (in pixels) to start with
UpdateHPBar_AnimateHPBar: ; fab1 (3:7ab1)
	push hl
.barAnimationLoop
	push af
	push de
	ld d, $6
	call DrawHPBar
	ld c, $2
	call DelayFrames
	pop de
	ld a, [wHPBarDelta] ; +1 or -1
	add e
	cp $31
	jr nc, .barFilledUp
	ld e, a
	pop af
	dec a
	jr nz, .barAnimationLoop
	pop hl
	ret
.barFilledUp
	pop af
	pop hl
	ret

; compares old HP and new HP and sets c and z flags accordingly
UpdateHPBar_CompareNewHPToOldHP: ; fad1 (3:7ad1)
	ld a, d
	sub b
	ret nz
	ld a, e
	sub c
	ret

; calcs HP difference between bc and de (into de)
UpdateHPBar_CalcHPDifference: ; fad7 (3:7ad7)
	ld a, d
	sub b
	jr c, .oldHPGreater
	jr z, .testLowerByte
.newHPGreater
	ld a, e
	sub c
	ld e, a
	ld a, d
	sbc b
	ld d, a
	ret
.oldHPGreater
	ld a, c
	sub e
	ld e, a
	ld a, b
	sbc d
	ld d, a
	ret
.testLowerByte
	ld a, e
	sub c
	jr c, .oldHPGreater
	jr nz, .newHPGreater
	ld de, $0
	ret

UpdateHPBar_PrintHPNumber: ; faf5 (3:7af5)
	push af
	push de
	ld a, [wListMenuID] ; $cf94
	and a
	jr z, .asm_fb2d
	ld a, [wHPBarOldHP]
	ld [$cef1], a
	ld a, [wHPBarOldHP+1]
	ld [$cef0], a
	push hl
	ld a, [$fff6]
	bit 0, a
	jr z, .asm_fb15
	ld de, $9
	jr .asm_fb18
.asm_fb15
	ld de, $15
.asm_fb18
	add hl, de
	push hl
	ld a, $7f
	ld [hli], a
	ld [hli], a
	ld [hli], a
	pop hl
	ld de, $cef0
	ld bc, $203
	call PrintNumber
	call DelayFrame
	pop hl
.asm_fb2d
	pop de
	pop af
	ret

; calcs number of HP bar pixels for old and new HP value
; d: new pixels
; e: old pixels
UpdateHPBar_CalcOldNewHPBarPixels: ; fb30 (3:7b30)
	push hl
	ld hl, wHPBarMaxHP
	ld a, [hli]  ; max HP into de
	ld e, a
	ld a, [hli]
	ld d, a
	ld a, [hli]  ; old HP into bc
	ld c, a
	ld a, [hli]
	ld b, a
	ld a, [hli]  ; new HP into hl
	ld h, [hl]
	ld l, a
	push hl
	push de
	call UpdateHPBar_CalcNumberOfHPBarPixels ; calc num pixels for old HP
	ld a, e
	pop de
	pop bc
	push af
	call UpdateHPBar_CalcNumberOfHPBarPixels ; calc num pixels for new HP
	pop af
	ld d, e
	ld e, a
	pop hl
	ret

; prints text for bookshelves in buildings without sign events
PrintBookshelfText: ; fb50 (3:7b50)
	ld a, [$c109]
	cp $4
	jr nz, .asm_fb7f
	ld a, [W_CURMAPTILESET] ; $d367
	ld b, a
	FuncCoord 8, 7 ; $c434
	ld a, [Coord]
	ld c, a
	ld hl, BookshelfTileIDs ; $7b8b
.asm_fb62
	ld a, [hli]
	cp $ff
	jr z, .asm_fb7f
	cp b
	jr nz, .asm_fb7b
	ld a, [hli]
	cp c
	jr nz, .asm_fb7c
	ld a, [hl]
	push af
	call EnableAutoTextBoxDrawing
	pop af
	call PrintPredefTextID
	xor a
	ld [$ffdb], a
	ret
.asm_fb7b
	inc hl
.asm_fb7c
	inc hl
	jr .asm_fb62
.asm_fb7f
	ld a, $ff
	ld [$ffdb], a
	ld b, BANK(PrintCardKeyText)
	ld hl, PrintCardKeyText
	jp Bankswitch

; format: db tileset id, bookshelf tile id, text id
BookshelfTileIDs: ; fb8b (3:7b8b)
	db PLATEAU,      $30, $3A
	db HOUSE,        $3D, $3F
	db HOUSE,        $1E, $40
	db MANSION,      $32, $40
	db REDS_HOUSE_1, $32, $40
	db LAB,          $28, $40
	db LOBBY,        $16, $41
	db GYM,          $1D, $40
	db DOJO,         $1D, $40
	db GATE,         $22, $40
	db MART,         $54, $42
	db MART,         $55, $42
	db POKECENTER,   $54, $42
	db POKECENTER,   $55, $42
	db LOBBY,        $50, $42
	db LOBBY,        $52, $42
	db SHIP,         $36, $40
	db $FF

IndigoPlateauStatues: ; fbbf (3:7bbf)
	db $08 ; asm
	ld hl, IndigoPlateauStatuesText1
	call PrintText
	ld a, [W_XCOORD]
	bit 0, a
	ld hl, IndigoPlateauStatuesText2
	jr nz, .asm_fbd3
	ld hl, IndigoPlateauStatuesText3
.asm_fbd3
	call PrintText
	jp TextScriptEnd

IndigoPlateauStatuesText1: ; fbd9 (3:7bd9)
	TX_FAR _IndigoPlateauStatuesText1
	db "@"

IndigoPlateauStatuesText2: ; fbde (3:7bde)
	TX_FAR _IndigoPlateauStatuesText2
	db "@"

IndigoPlateauStatuesText3: ; fbe3 (3:7be3)
	TX_FAR _IndigoPlateauStatuesText3
	db "@"

BookOrSculptureText: ; fbe8 (3:7be8)
	db $08 ; asm
	ld hl, PokemonBooksText
	ld a, [W_CURMAPTILESET]
	cp MANSION ; Celadon Mansion tileset
	jr nz, .asm_fbfd
	ld a, [$c420]
	cp $38
	jr nz, .asm_fbfd
	ld hl, DiglettSculptureText
.asm_fbfd
	call PrintText
	jp TextScriptEnd

PokemonBooksText: ; fc03 (3:7c03)
	TX_FAR _PokemonBooksText
	db "@"

DiglettSculptureText: ; fc08 (3:7c08)
	TX_FAR _DiglettSculptureText
	db "@"

ElevatorText: ; fc0d (3:7c0d)
	TX_FAR _ElevatorText
	db "@"

TownMapText: ; fc12 (3:7c12)
	TX_FAR _TownMapText
	db $06
	db $08 ; asm
	ld a, $1
	ld [$cc3c], a
	ld hl, $d730
	set 6, [hl]
	call GBPalWhiteOutWithDelay3
	xor a
	ld [$ffb0], a
	inc a
	ld [H_AUTOBGTRANSFERENABLED], a
	call LoadFontTilePatterns
	callba DisplayTownMap
	ld hl, $d730
	res 6, [hl]
	ld de, TextScriptEnd
	push de
	ld a, [H_LOADEDROMBANK]
	push af
	jp CloseTextDisplay

PokemonStuffText: ; fc45 (3:7c45)
	TX_FAR _PokemonStuffText
	db "@"

SECTION "bank4",ROMX,BANK[$4]

OakAideSprite: ; 10000 (4:4000)
	INCBIN "gfx/sprites/oak_aide.2bpp" ; was $10000
RockerSprite: ; 10180 (4:4180)
	INCBIN "gfx/sprites/rocker.2bpp" ; was $10180
SwimmerSprite: ; 10300 (4:4300)
	INCBIN "gfx/sprites/swimmer.2bpp" ; was $10300
WhitePlayerSprite: ; 10480 (4:4480)
	INCBIN "gfx/sprites/white_player.2bpp" ; was $10480
GymHelperSprite: ; 10540 (4:4540)
	INCBIN "gfx/sprites/gym_helper.2bpp" ; was $10540
OldPersonSprite: ; 10600 (4:4600)
	INCBIN "gfx/sprites/old_person.2bpp" ; was $10600
MartGuySprite: ; 106c0 (4:46c0)
	INCBIN "gfx/sprites/mart_guy.2bpp" ; was $106c0
FisherSprite: ; 10780 (4:4780)
	INCBIN "gfx/sprites/fisher.2bpp" ; was $10780
OldMediumWomanSprite: ; 10840 (4:4840)
	INCBIN "gfx/sprites/old_medium_woman.2bpp" ; was $10840
NurseSprite: ; 10900 (4:4900)
	INCBIN "gfx/sprites/nurse.2bpp" ; was $10900
CableClubWomanSprite: ; 109c0 (4:49c0)
	INCBIN "gfx/sprites/cable_club_woman.2bpp" ; was $109c0
MrMasterballSprite: ; 10a80 (4:4a80)
	INCBIN "gfx/sprites/mr_masterball.2bpp" ; was $10a80
LaprasGiverSprite: ; 10b40 (4:4b40)
	INCBIN "gfx/sprites/lapras_giver.2bpp" ; was $10b40
WardenSprite: ; 10c00 (4:4c00)
	INCBIN "gfx/sprites/warden.2bpp" ; was $10c00
SsCaptainSprite: ; 10cc0 (4:4cc0)
	INCBIN "gfx/sprites/ss_captain.2bpp" ; was $10cc0
Fisher2Sprite: ; 10d80 (4:4d80)
	INCBIN "gfx/sprites/fisher2.2bpp" ; was $10d80
BlackbeltSprite: ; 10f00 (4:4f00)
	INCBIN "gfx/sprites/blackbelt.2bpp" ; was $10f00
GuardSprite: ; 11080 (4:5080)
	INCBIN "gfx/sprites/guard.2bpp" ; was $11080
BallSprite: ; 11140 (4:5140)
	INCBIN "gfx/sprites/ball.2bpp" ; was $11140
OmanyteSprite: ; 11180 (4:5180)
	INCBIN "gfx/sprites/omanyte.2bpp" ; was $11180
BoulderSprite: ; 111c0 (4:51c0)
	INCBIN "gfx/sprites/boulder.2bpp" ; was $111c0
PaperSheetSprite: ; 11200 (4:5200)
	INCBIN "gfx/sprites/paper_sheet.2bpp" ; was $11200
BookMapDexSprite: ; 11240 (4:5240)
	INCBIN "gfx/sprites/book_map_dex.2bpp" ; was $11240
ClipboardSprite: ; 11280 (4:5280)
	INCBIN "gfx/sprites/clipboard.2bpp" ; was $11280
SnorlaxSprite: ; 112c0 (4:52c0)
	INCBIN "gfx/sprites/snorlax.2bpp" ; was $112c0
OldAmberSprite: ; 11300 (4:5300)
	INCBIN "gfx/sprites/old_amber.2bpp" ; was $11300
LyingOldManSprite: ; 11340 (4:5340)
	INCBIN "gfx/sprites/lying_old_man.2bpp" ; was $11340

PokemonLogoGraphics: ; 11380 (4:5380)
	INCBIN "gfx/pokemon_logo.w128.2bpp"

FontGraphics: ; 11a80 (4:5a80)
	INCBIN "gfx/font.w128.1bpp"

ABTiles: ; 11e80 (4:5e80)
	INCBIN "gfx/AB.2bpp"

HpBarAndStatusGraphics: ; 11ea0 (4:5ea0)
	INCBIN "gfx/hp_bar_and_status.2bpp"

BattleHudTiles1: ; 12080 (4:6080)
	INCBIN "gfx/battle_hud1.1bpp"

BattleHudTiles2: ; 12098 (4:6098)
	INCBIN "gfx/battle_hud2.1bpp"

BattleHudTiles3: ; 120b0 (4:60b0)
	INCBIN "gfx/battle_hud3.1bpp"

NintendoCopyrightLogoGraphics: ; 120c8 (4:60c8)
	INCBIN "gfx/copyright.h8.2bpp"

GamefreakLogoGraphics: ; 121f8 (4:61f8)
	INCBIN "gfx/gamefreak.h8.2bpp"

TextBoxGraphics: ; 12288 (4:6288)
	INCBIN "gfx/text_box.2bpp"

PokedexTileGraphics: ; 12488 (4:6488)
	INCBIN "gfx/pokedex.2bpp"

WorldMapTileGraphics: ; 125a8 (4:65a8)
	INCBIN "gfx/town_map.2bpp"

PlayerCharacterTitleGraphics: ; 126a8 (4:66a8)
	INCBIN "gfx/player_title.2bpp"

Func_128d8: ; 128d8 (4:68d8)
	ld a, [W_YCOORD] ; $d361
	ld b, a
	ld a, [W_CURMAPHEIGHT] ; $d368
	call Func_128ea
	ret z
	ld a, [W_XCOORD] ; $d362
	ld b, a
	ld a, [W_CURMAPWIDTH] ; $d369

Func_128ea: ; 128ea (4:68ea)
	add a
	cp b
	ret z
	inc b
	ret

Func_128ef: ; 128ef (4:68ef)
	call Load16BitRegisters
	ld a, $1
	jr asm_128fb

Func_128f6: ; 128f6 (4:68f6)
	call Load16BitRegisters
	ld a, $2
asm_128fb: ; 128fb (4:68fb)
	ld [wListMenuID], a ; $cf94
	push hl
	ld a, [$cf99]
	ld b, a
	ld a, [$cf9a]
	ld c, a
	or b
	jr nz, .asm_12913
	xor a
	ld c, a
	ld e, a
	ld a, $6
	ld d, a
	jp Func_12924
.asm_12913
	ld a, [$cfba]
	ld d, a
	ld a, [$cfbb]
	ld e, a
	ld a, $26
	call Predef ; indirect jump to Func_f9dc (f9dc (3:79dc))
	ld a, $6
	ld d, a
	ld c, a

Func_12924: ; 12924 (4:6924)
	pop hl
	push de
	push hl
	push hl
	call DrawHPBar
	pop hl
	ld a, [$fff6]
	bit 0, a
	jr z, .asm_12937
	ld bc, $9
	jr .asm_1293a
.asm_12937
	ld bc, $15
.asm_1293a
	add hl, bc
	ld de, $cf99
	ld bc, $203
	call PrintNumber
	ld a, "/"
	ld [hli], a
	ld de, $cfba
	ld bc, $203
	call PrintNumber
	pop hl
	pop de
	ret

; Predef 0x37
StatusScreen: ; 12953 (4:6953)
	call LoadMonData
	ld a, [$cc49]
	cp $2 ; 2 means we're in a PC box
	jr c, .DontRecalculate ; 0x1295b $14
	ld a, [$cf9b]
	ld [$cfb9], a
	ld [$d127], a
	ld hl, $cfa8
	ld de, $cfba
	ld b, $1
	call CalcStats ; Recalculate stats
.DontRecalculate
	ld hl, $d72c
	set 1, [hl]
	ld a, $33
	ld [$ff24], a ; Reduce the volume
	call GBPalWhiteOutWithDelay3
	call ClearScreen
	call UpdateSprites ; move sprites (?)
	call LoadHpBarAndStatusTilePatterns
	ld de, BattleHudTiles1  ; $6080 ; source
	ld hl, $96d0 ; dest
	ld bc, (BANK(BattleHudTiles1) << 8) + $03 ; bank bytes/8
	call CopyVideoDataDouble ; ·│ :L and halfarrow line end
	ld de, BattleHudTiles2 ; $6098
	ld hl, $9780
	ld bc, (BANK(BattleHudTiles2) << 8) + $01
	call CopyVideoDataDouble ; │
	ld de, BattleHudTiles3 ; $60b0
	ld hl, $9760
	ld bc, (BANK(BattleHudTiles3) << 8) + $02
	call CopyVideoDataDouble ; ─┘
	ld de, PTile
	ld hl, $9720
	ld bc,(BANK(PTile) << 8 | $01)
	call CopyVideoDataDouble ; P (for PP), inline
	ld a, [$ffd7]
	push af
	xor a
	ld [$ffd7], a
	FuncCoord 19,1
	ld hl, Coord
	ld bc, $060a
	call DrawLineBox ; Draws the box around name, HP and status
	ld de, $fffa
	add hl, de
	ld [hl], $f2 ; . after No ("." is a different one)
	dec hl
	ld [hl], "№"
	FuncCoord 19,9
	ld hl, Coord
	ld bc, $0806
	call DrawLineBox ; Draws the box around types, ID No. and OT
	FuncCoord 10,9
	ld hl, Coord
	ld de, Type1Text
	call PlaceString ; "TYPE1/"
	FuncCoord 11,3
	ld hl, Coord
	PREDEF DrawHPBarPredef ; predef $5f
	ld hl, $cf25
	call Func_3df9
	ld b, $3
	call GoPAL_SET ; SGB palette
	FuncCoord 16,6
	ld hl, Coord
	ld de, $cf9c
	call PrintStatusCondition
	jr nz, .StatusWritten ; 0x129fc $9
	FuncCoord 16,6
	ld hl, Coord
	ld de, OKText
	call PlaceString ; "OK"
.StatusWritten
	FuncCoord 9,6
	ld hl, Coord
	ld de, StatusText
	call PlaceString ; "STATUS/"
	FuncCoord 14,2
	ld hl, Coord
	call PrintLevel ; Pokémon level
	ld a, [$d0b8]
	ld [$d11e], a
	ld [$d0b5], a
	ld a, $3a
	call Predef
	FuncCoord 3,7
	ld hl, Coord
	ld de, $d11e
	ld bc, $8103 ; Zero-padded, 3
	call PrintNumber ; Pokémon no.
	FuncCoord 11,10
	ld hl, Coord
	ld a, $4b
	call Predef ; Prints the type (?)
	ld hl, NamePointers2 ; $6a9d
	call .unk_12a7e
	ld d, h
	ld e, l
	FuncCoord 9,1
	ld hl, Coord
	call PlaceString ; Pokémon name
	ld hl, OTPointers ; $6a95
	call .unk_12a7e
	ld d, h
	ld e, l
	FuncCoord 12,16
	ld hl, Coord
	call PlaceString ; OT
	FuncCoord 12,14
	ld hl, Coord
	ld de, $cfa4
	ld bc, $8205 ; 5
	call PrintNumber ; ID Number
	ld d, $0
	call PrintStatsBox
	call Delay3
	call GBPalNormal
	FuncCoord 1, 0 ; $c3a1
	ld hl, Coord
	call LoadFlippedFrontSpriteByMonIndex ; draw Pokémon picture
	ld a, [$cf91]
	call PlayCry ; play Pokémon cry
	call WaitForTextScrollButtonPress ; wait for button
	pop af
	ld [$ffd7], a
	ret
.unk_12a7e ; 0x12a7e ; I don't know what this does, iterates over pointers?
	ld a, [$cc49]
	add a
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld a, [$cc49]
	cp $3
	ret z
	ld a, [wWhichPokemon]
	jp SkipFixedLengthTextEntries

OTPointers: ; 12a95 (4:6a95)
	dw W_PARTYMON1OT
	dw W_ENEMYMON1OT
	dw W_BOXMON1OT
	dw W_DAYCAREMONOT

NamePointers2: ; 12a9d (4:6a9d)
	dw W_PARTYMON1NAME
	dw W_ENEMYMON1NAME
	dw W_BOXMON1NAME
	dw W_DAYCAREMONNAME

Type1Text: ; 12aa5 (4:6aa5)
	db "TYPE1/", $4e

Type2Text: ; 12aac (4:6aac)
	db "TYPE2/", $4e

IDNoText: ; 12ab3 (4:6ab3)
	db $73, "№", "/", $4e

OTText: ; 12ab7 (4:6ab7)
	db "OT/", $4e, "@"

StatusText: ; 12abc (4:6abc)
	db "STATUS/@"

OKText: ; 12ac4 (4:6ac4)
	db "OK@"

; Draws a line starting from hl high b and wide c
DrawLineBox ; 0x12ac7
	ld de, $0014 ; New line
.PrintVerticalLine
	ld [hl], $78 ; │
	add hl, de
	dec b
	jr nz, .PrintVerticalLine ; 0x12ace $fa
	ld [hl], $77 ; ┘
	dec hl
.PrintHorizLine
	ld [hl], $76 ; ─
	dec hl
	dec c
	jr nz, .PrintHorizLine ; 0x12ad7 $fa
	ld [hl], $6f ; ← (halfarrow ending)
	ret

PTile: ; 12adc (4:6adc) ; This is a single 1bpp "P" tile
	INCBIN "gfx/p_tile.1bpp"

PrintStatsBox: ; 12ae4 (4:6ae4)
	ld a, d
	and a ; a is 0 from the status screen
	jr nz, .DifferentBox ; 0x12ae6 $12
	FuncCoord 0,8
	ld hl, Coord
	ld b, $8
	ld c, $8
	call TextBoxBorder ; Draws the box
	FuncCoord 1,9 ; Start printing stats from here
	ld hl, Coord
	ld bc, $0019 ; Number offset
	jr .PrintStats ; 0x12af8 $10
.DifferentBox
	FuncCoord 9,2
	ld hl, Coord
	ld b, $8
	ld c, $9
	call TextBoxBorder
	FuncCoord 11, 3 ; $c3e7
	ld hl, Coord
	ld bc, $0018
.PrintStats
	push bc
	push hl
	ld de, StatsText
	call PlaceString
	pop hl
	pop bc
	add hl, bc
	ld de, $cfbc
	ld bc, $0203 ; three digits
	call PrintStat
	ld de, $cfbe
	call PrintStat
	ld de, $cfc0
	call PrintStat
	ld de, $cfc2
	jp PrintNumber
PrintStat
	push hl
	call PrintNumber
	pop hl
	ld de, $0028
	add hl, de
	ret

StatsText: ; 12b3a (4:6b3a)
	db   "ATTACK"
	next "DEFENSE"
	next "SPEED"
	next "SPECIAL@"

StatusScreen2: ; 12b57 (4:6b57)
	ld a, [$ffd7]
	push af
	xor a
	ld [$ffd7], a
	ld [$ffba], a
	ld bc, $0005
	ld hl, $d0dc
	call FillMemory
	ld hl, $cfa0
	ld de, $d0dc
	ld bc, $0004
	call CopyData
	callab Func_39b87
	FuncCoord 9,2
	ld hl, Coord
	ld bc, $050a
	call ClearScreenArea ; Clear under name
	FuncCoord 19, 3 ; $c3ef
	ld hl, Coord
	ld [hl], $78
	FuncCoord 0,8
	ld hl, Coord
	ld b, $8
	ld c, $12
	call TextBoxBorder ; Draw move container
	FuncCoord 2,9
	ld hl, Coord
	ld de, $d0e1
	call PlaceString ; Print moves
	ld a, [$cd6c]
	inc a
	ld c, a
	ld a, $4
	sub c
	ld b, a ; Number of moves ?
	FuncCoord 11,10
	ld hl, Coord
	ld de, $0028
	ld a, $72
	call Func_12ccb ; Print "PP"
	ld a, b
	and a
	jr z, .InitPP ; 0x12bb3 $6
	ld c, a
	ld a, "-"
	call Func_12ccb ; Fill the rest with --
.InitPP ; 12bbb
	ld hl, $cfa0
	FuncCoord 14,10
	ld de, Coord
	ld b, $0
.PrintPP ; 12bc3
	ld a, [hli]
	and a
	jr z, .PPDone ; 0x12bc5 $4a
	push bc
	push hl
	push de
	ld hl, wCurrentMenuItem
	ld a, [hl]
	push af
	ld a, b
	ld [hl], a
	push hl
	callab GetMaxPP
	pop hl
	pop af
	ld [hl], a
	pop de
	pop hl
	push hl
	ld bc, $0014
	add hl, bc
	ld a, [hl]
	and $3f
	ld [$cd71], a
	ld h, d
	ld l, e
	push hl
	ld de, $cd71
	ld bc, $0102
	call PrintNumber
	ld a, "/"
	ld [hli], a
	ld de, $d11e
	ld bc, $0102
	call PrintNumber
	pop hl
	ld de, $0028
	add hl, de
	ld d, h
	ld e, l
	pop hl
	pop bc
	inc b
	ld a, b
	cp $4
	jr nz, .PrintPP ; 0x12c0f $b2
.PPDone
	FuncCoord 9,3
	ld hl, Coord
	ld de, EXPPointsText
	call PlaceString
	ld a, [$cfb9] ; level
	push af
	cp 100
	jr z, .Level100 ; 0x12c20 $4
	inc a
	ld [$cfb9], a ; Increase temporarily if not 100
.Level100
	FuncCoord 14,6
	ld hl, Coord
	ld [hl], $70 ; 1-tile "to"
	inc hl
	inc hl
	call PrintLevel
	pop af
	ld [$cfb9], a
	ld de, $cfa6
	FuncCoord 12,4
	ld hl, Coord
	ld bc, $0307
	call PrintNumber ; exp
	call .asm_12c86
	ld de, $cfa6
	FuncCoord 7,6
	ld hl, Coord
	ld bc, $0307
	call PrintNumber
	FuncCoord 9,0
	ld hl, Coord
	call Func_12cc3
	FuncCoord 9,1
	ld hl, Coord
	call Func_12cc3
	ld a, [$d0b8]
	ld [$d11e], a
	call GetMonName
	FuncCoord 9,1
	ld hl, Coord
	call PlaceString
	ld a, $1
	ld [$ffba], a
	call Delay3
	call WaitForTextScrollButtonPress ; wait for button
	pop af
	ld [$ffd7], a
	ld hl, $d72c
	res 1, [hl]
	ld a, $77
	ld [$ff24], a
	call GBPalWhiteOut
	jp ClearScreen
.asm_12c86 ; This does some magic with lvl/exp?
	ld a, [$cfb9] ; Load level
	cp $64
	jr z, .asm_12ca7 ; 0x12c8b $1a ; If 100
	inc a
	ld d, a
	callab CalcExperience
	ld hl, $cfa8
	ld a, [$ff98]
	sub [hl]
	ld [hld], a
	ld a, [$ff97]
	sbc [hl]
	ld [hld], a
	ld a, [$ff96]
	sbc [hl]
	ld [hld], a
	ret
.asm_12ca7
	ld hl, $cfa6
	xor a
	ld [hli], a
	ld [hli], a
	ld [hl], a
	ret

EXPPointsText: ; 12caf (4:6caf)
	db "EXP POINTS", $4e

LevelUpText: ; 12cba (4:6cba)
	db "LEVEL UP@"

Func_12cc3: ; 12cc3 (4:6cc3)
	ld bc, $a
	ld a, $7f
	jp FillMemory

Func_12ccb: ; 12ccb (4:6ccb)
	ld [hli], a
	ld [hld], a
	add hl, de
	dec c
	jr nz, Func_12ccb
	ret

; [$D07D] = menu type / message ID
; if less than $F0, it is a menu type
; menu types:
; 00: normal pokemon menu (e.g. Start menu)
; 01: use healing item on pokemon menu
; 02: in-battle switch pokemon menu
; 03: learn TM/HM menu
; 04: swap pokemon positions menu
; 05: use evolution stone on pokemon menu
; otherwise, it is a message ID
; f0: poison healed
; f1: burn healed
; f2: freeze healed
; f3: sleep healed
; f4: paralysis healed
; f5: HP healed
; f6: health returned
; f7: revitalized
; f8: leveled up
DrawPartyMenu_: ; 12cd2 (4:6cd2)
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a
	call ClearScreen
	call UpdateSprites ; move sprites
	callba Func_71791 ; load pokemon icon graphics

RedrawPartyMenu_: ; 12ce3 (4:6ce3)
	ld a,[$D07D]
	cp a,$04
	jp z,.printMessage
	call ErasePartyMenuCursors
	callba SendBlkPacket_PartyMenu ; loads some data to $cf2e
	FuncCoord 3,0
	ld hl,Coord
	ld de,W_PARTYMON1
	xor a
	ld c,a
	ld [$FF8C],a ; loop counter
	ld [$CF2D],a
.loop
	ld a,[de]
	cp a,$FF ; reached the terminator?
	jp z,.afterDrawingMonEntries
	push bc
	push de
	push hl
	ld a,c
	push hl
	ld hl,W_PARTYMON1NAME
	call GetPartyMonName
	pop hl
	call PlaceString ; print the pokemon's name
	callba Func_71868 ; place the appropriate pokemon icon
	ld a,[$FF8C] ; loop counter
	ld [wWhichPokemon],a
	inc a
	ld [$FF8C],a
	call LoadMonData
	pop hl
	push hl
	ld a,[$CC35]
	and a ; is the player swapping pokemon positions?
	jr z,.skipUnfilledRightArrow
; if the player is swapping pokemon positions
	dec a
	ld b,a
	ld a,[wWhichPokemon]
	cp b ; is the player swapping the current pokemon in the list?
	jr nz,.skipUnfilledRightArrow
; the player is swapping the current pokemon in the list
	dec hl
	dec hl
	dec hl
	ld a,$EC ; unfilled right arrow menu cursor
	ld [hli],a ; place the cursor
	inc hl
	inc hl
.skipUnfilledRightArrow
	ld a,[$D07D] ; menu type
	cp a,$03
	jr z,.teachMoveMenu
	cp a,$05
	jr z,.evolutionStoneMenu
	push hl
	ld bc,14 ; 14 columns to the right
	add hl,bc
	ld de,$CF9C
	call PrintStatusCondition
	pop hl
	push hl
	ld bc,20 + 1 ; down 1 row and right 1 column
	ld a,[$FFF6]
	set 0,a
	ld [$FFF6],a
	add hl,bc
	ld a,$60
	call Predef ; draw HP bar and prints current / max HP
	ld a,[$FFF6]
	res 0,a
	ld [$FFF6],a
	call Func_12ec7 ; color the HP bar (on SGB)
	pop hl
	jr .printLevel
.teachMoveMenu
	push hl
	ld a,$43
	call Predef ; check if the pokemon can learn the move
	pop hl
	ld de,.ableToLearnMoveText
	ld a,c
	and a
	jr nz,.placeMoveLearnabilityString
	ld de,.notAbleToLearnMoveText
.placeMoveLearnabilityString
	ld bc,20 + 9 ; down 1 row and right 9 columns
	push hl
	add hl,bc
	call PlaceString
	pop hl
.printLevel
	ld bc,10 ; move 10 columns to the right
	add hl,bc
	call PrintLevel
	pop hl
	pop de
	inc de
	ld bc,2 * 20
	add hl,bc
	pop bc
	inc c
	jp .loop
.ableToLearnMoveText
	db "ABLE@"
.notAbleToLearnMoveText
	db "NOT ABLE@"
.evolutionStoneMenu
	push hl
	ld hl,EvosMovesPointerTable
	ld b,0
	ld a,[$CF98] ; pokemon ID
	dec a
	add a
	rl b
	ld c,a
	add hl,bc
	ld de,$CD6D
	ld a,BANK(EvosMovesPointerTable)
	ld bc,2
	call FarCopyData
	ld hl,$CD6D
	ld a,[hli]
	ld h,[hl]
	ld l,a
	ld de,$CD6D
	ld a,BANK(EvosMovesPointerTable)
	ld bc,13
	call FarCopyData
	ld hl,$CD6D
	ld de,.notAbleToEvolveText
; loop through the pokemon's evolution entries
.checkEvolutionsLoop
	ld a,[hli]
	and a ; reached terminator?
	jr z,.placeEvolutionStoneString ; if so, place the "NOT ABLE" string
	inc hl
	inc hl
	cp a,EV_ITEM
	jr nz,.checkEvolutionsLoop
; if it's a stone evolution entry
	dec hl
	dec hl
	ld b,[hl]
	ld a,[$D156] ; evolution stone item ID
	inc hl
	inc hl
	inc hl
	cp b ; does the player's stone match this evolution entry's stone?
	jr nz,.checkEvolutionsLoop
; if it does match
	ld de,.ableToEvolveText
.placeEvolutionStoneString
	ld bc,20 + 9 ; down 1 row and right 9 columns
	pop hl
	push hl
	add hl,bc
	call PlaceString
	pop hl
	jr .printLevel
.ableToEvolveText
	db "ABLE@"
.notAbleToEvolveText
	db "NOT ABLE@"
.afterDrawingMonEntries
	ld b,$0A
	call GoPAL_SET
.printMessage
	ld hl,$D730
	ld a,[hl]
	push af
	push hl
	set 6,[hl] ; turn off letter printing delay
	ld a,[$D07D] ; message ID
	cp a,$F0
	jr nc,.printItemUseMessage
	add a
	ld hl,PartyMenuMessagePointers
	ld b,0
	ld c,a
	add hl,bc
	ld a,[hli]
	ld h,[hl]
	ld l,a
	call PrintText
.done
	pop hl
	pop af
	ld [hl],a
	ld a,1
	ld [H_AUTOBGTRANSFERENABLED],a
	call Delay3
	jp GBPalNormal
.printItemUseMessage
	and a,$0F
	ld hl,PartyMenuItemUseMessagePointers
	add a
	ld c,a
	ld b,0
	add hl,bc
	ld a,[hli]
	ld h,[hl]
	ld l,a
	push hl
	ld a,[$CF06]
	ld hl,W_PARTYMON1NAME
	call GetPartyMonName
	pop hl
	call PrintText
	jr .done

PartyMenuItemUseMessagePointers: ; 12e61 (4:6e61)
	dw AntidoteText
	dw BurnHealText
	dw IceHealText
	dw AwakeningText
	dw ParlyzHealText
	dw PotionText
	dw FullHealText
	dw ReviveText
	dw RareCandyText

PartyMenuMessagePointers: ; 12e73 (4:6e73)
	dw PartyMenuNormalText
	dw PartyMenuItemUseText
	dw PartyMenuBattleText
	dw PartyMenuUseTMText
	dw PartyMenuSwapMonText
	dw PartyMenuItemUseText

PartyMenuNormalText: ; 12e7f (4:6e7f)
	TX_FAR _PartyMenuNormalText
	db "@"

PartyMenuItemUseText: ; 12e84 (4:6e84)
	TX_FAR _PartyMenuItemUseText
	db "@"

PartyMenuBattleText: ; 12e89 (4:6e89)
	TX_FAR _PartyMenuBattleText
	db "@"

PartyMenuUseTMText: ; 12e8e (4:6e8e)
	TX_FAR _PartyMenuUseTMText
	db "@"

PartyMenuSwapMonText: ; 12e93 (4:6e93)
	TX_FAR _PartyMenuSwapMonText
	db "@"

PotionText: ; 12e98 (4:6e98)
	TX_FAR _PotionText
	db "@"

AntidoteText: ; 12e9d (4:6e9d)
	TX_FAR _AntidoteText
	db "@"

ParlyzHealText: ; 12ea2 (4:6ea2)
	TX_FAR _ParlyzHealText
	db "@"

BurnHealText: ; 12ea7 (4:6ea7)
	TX_FAR _BurnHealText
	db "@"

IceHealText: ; 12eac (4:6eac)
	TX_FAR _IceHealText
	db "@"

AwakeningText: ; 12eb1 (4:6eb1)
	TX_FAR _AwakeningText
	db "@"

FullHealText: ; 12eb6 (4:6eb6)
	TX_FAR _FullHealText
	db "@"

ReviveText: ; 12ebb (4:6ebb)
	TX_FAR _ReviveText
	db "@"

RareCandyText: ; 12ec0 (4:6ec0)
	TX_FAR _RareCandyText
	db $0B
	db $06
	db "@"

Func_12ec7: ; 12ec7 (4:6ec7)
	ld hl, $cf1f
	ld a, [$cf2d]
	ld c, a
	ld b, $0
	add hl, bc
	call Func_3df9
	ld b, $fc
	call GoPAL_SET
	ld hl, $cf2d
	inc [hl]
	ret

RedPicFront: ; 12ede (4:6ede)
	INCBIN "pic/trainer/red.pic"
ShrinkPic1: ; 12fe8 (4:6fe8)
	INCBIN "pic/trainer/shrink1.pic"
ShrinkPic2: ; 13042 (4:7042)
	INCBIN "pic/trainer/shrink2.pic"

Func_13074: ; 13074 (4:7074)
	ld h, $c2
	ld a, [H_CURRENTSPRITEOFFSET]
	add $8
	ld l, a
	ld a, $7f
	ld [hl], a
	dec h
	ld a, [H_CURRENTSPRITEOFFSET]
	add $9
	ld l, a
	ld a, [hld]
	ld b, a
	xor a
	ld [hld], a
	ld [hl], a
	ld a, [H_CURRENTSPRITEOFFSET]
	add $2
	ld l, a
	ld a, [hl]
	or b
	ld [hld], a
	ld a, $2
	ld [hl], a
	ret

StartMenu_Pokedex: ; 13095 (4:7095)
	ld a,$29
	call Predef
	call LoadScreenTilesFromBuffer2 ; restore saved screen
	call Delay3
	call LoadGBPal
	call UpdateSprites
	jp RedisplayStartMenu

StartMenu_Pokemon: ; 130a9 (4:70a9)
	ld a,[W_NUMINPARTY]
	and a
	jp z,RedisplayStartMenu
	xor a
	ld [$cc35],a
	ld [$d07d],a
	ld [$cfcb],a
	call DisplayPartyMenu
	jr .checkIfPokemonChosen
.loop
	xor a
	ld [$cc35],a
	ld [$d07d],a
	call GoBackToPartyMenu
.checkIfPokemonChosen
	jr nc,.chosePokemon
.exitMenu
	call GBPalWhiteOutWithDelay3
	call Func_3dbe
	call LoadGBPal
	jp RedisplayStartMenu
.chosePokemon
	call SaveScreenTilesToBuffer1 ; save screen
	ld a,$04
	ld [$d125],a
	call DisplayTextBoxID ; display pokemon menu options
	ld hl,$cd3d
	ld bc,$020c ; max menu item ID, top menu item Y
	ld e,5
.adjustMenuVariablesLoop
	dec e
	jr z,.storeMenuVariables
	ld a,[hli]
	and a
	jr z,.storeMenuVariables
	inc b
	dec c
	dec c
	jr .adjustMenuVariablesLoop
.storeMenuVariables
	ld hl,wTopMenuItemY
	ld a,c
	ld [hli],a ; top menu item Y
	ld a,[$fff7]
	ld [hli],a ; top menu item X
	xor a
	ld [hli],a ; current menu item ID
	inc hl
	ld a,b
	ld [hli],a ; max menu item ID
	ld a,%00000011 ; A button, B button
	ld [hli],a ; menu watched keys
	xor a
	ld [hl],a
	call HandleMenuInput
	push af
	call LoadScreenTilesFromBuffer1 ; restore saved screen
	pop af
	bit 1,a ; was the B button pressed?
	jp nz,.loop
; if the B button wasn't pressed
	ld a,[wMaxMenuItem]
	ld b,a
	ld a,[wCurrentMenuItem] ; menu selection
	cp b
	jp z,.exitMenu ; if the player chose Cancel
	dec b
	cp b
	jr z,.choseSwitch
	dec b
	cp b
	jp z,.choseStats
	ld c,a
	ld b,0
	ld hl,$cd3d
	add hl,bc
	jp .choseOutOfBattleMove
.choseSwitch
	ld a,[W_NUMINPARTY]
	cp a,2 ; is there more than one pokemon in the party?
	jp c,StartMenu_Pokemon ; if not, no switching
	call SwitchPartyMon_Stats
	ld a,$04 ; swap pokemon positions menu
	ld [$d07d],a
	call GoBackToPartyMenu
	jp .checkIfPokemonChosen
.choseStats
	call CleanLCD_OAM
	xor a
	ld [$cc49],a
	ld a,$36
	call Predef
	ld a,$37
	call Predef
	call ReloadMapData
	jp StartMenu_Pokemon
.choseOutOfBattleMove
	push hl
	ld a,[wWhichPokemon]
	ld hl,W_PARTYMON1NAME
	call GetPartyMonName
	pop hl
	ld a,[hl]
	dec a
	add a
	ld b,0
	ld c,a
	ld hl,.outOfBattleMovePointers
	add hl,bc
	ld a,[hli]
	ld h,[hl]
	ld l,a
	ld a,[W_OBTAINEDBADGES] ; badges obtained
	jp [hl]
.outOfBattleMovePointers
	dw .cut
	dw .fly
	dw .surf
	dw .surf
	dw .strength
	dw .flash
	dw .dig
	dw .teleport
	dw .softboiled
.fly
	bit 2,a ; does the player have the Thunder Badge?
	jp z,.newBadgeRequired
	call CheckIfInOutsideMap
	jr z,.canFly
	ld a,[wWhichPokemon]
	ld hl,W_PARTYMON1NAME
	call GetPartyMonName
	ld hl,.cannotFlyHereText
	call PrintText
	jp .loop
.canFly
	call ChooseFlyDestination
	ld a,[$d732]
	bit 3,a ; did the player decide to fly?
	jp nz,.goBackToMap
	call LoadFontTilePatterns
	ld hl,$d72e
	set 1,[hl]
	jp StartMenu_Pokemon
.cut
	bit 1,a ; does the player have the Cascade Badge?
	jp z,.newBadgeRequired
	ld a,$3c
	call Predef
	ld a,[$cd6a]
	and a
	jp z,.loop
	jp CloseTextDisplay
.surf
	bit 4,a ; does the player have the Soul Badge?
	jp z,.newBadgeRequired
	callba CheckForForcedBikeSurf
	ld hl,$d728
	bit 1,[hl]
	res 1,[hl]
	jp z,.loop
	ld a,SURFBOARD
	ld [$cf91],a
	ld [$d152],a
	call UseItem
	ld a,[$cd6a]
	and a
	jp z,.loop
	call GBPalWhiteOutWithDelay3
	jp .goBackToMap
.strength
	bit 3,a ; does the player have the Rainbow Badge?
	jp z,.newBadgeRequired
	ld a,$5b
	call Predef
	call GBPalWhiteOutWithDelay3
	jp .goBackToMap
.flash
	bit 0,a ; does the player have the Boulder Badge?
	jp z,.newBadgeRequired
	xor a
	ld [$d35d],a
	ld hl,.flashLightsAreaText
	call PrintText
	call GBPalWhiteOutWithDelay3
	jp .goBackToMap
.flashLightsAreaText
	TX_FAR _FlashLightsAreaText
	db "@"
.dig
	ld a,ESCAPE_ROPE
	ld [$cf91],a
	ld [$d152],a
	call UseItem
	ld a,[$cd6a]
	and a
	jp z,.loop
	call GBPalWhiteOutWithDelay3
	jp .goBackToMap
.teleport
	call CheckIfInOutsideMap
	jr z,.canTeleport
	ld a,[wWhichPokemon]
	ld hl,W_PARTYMON1NAME
	call GetPartyMonName
	ld hl,.cannotUseTeleportNowText
	call PrintText
	jp .loop
.canTeleport
	ld hl,.warpToLastPokemonCenterText
	call PrintText
	ld hl,$d732
	set 3,[hl]
	set 6,[hl]
	ld hl,$d72e
	set 1,[hl]
	res 4,[hl]
	ld c,60
	call DelayFrames
	call GBPalWhiteOutWithDelay3 ; zero all three palettes and wait 3 V-blanks
	jp .goBackToMap
.warpToLastPokemonCenterText
	TX_FAR _WarpToLastPokemonCenterText
	db "@"
.cannotUseTeleportNowText
	TX_FAR _CannotUseTeleportNowText
	db "@"
.cannotFlyHereText
	TX_FAR _CannotFlyHereText
	db "@"
.softboiled
	ld hl,W_PARTYMON1_MAXHP
	ld a,[wWhichPokemon]
	ld bc,44
	call AddNTimes
	ld a,[hli]
	ld [H_DIVIDEND],a
	ld a,[hl]
	ld [H_DIVIDEND + 1],a
	ld a,5
	ld [H_DIVISOR],a
	ld b,2 ; number of bytes
	call Divide
	ld bc,-33
	add hl,bc
	ld a,[hld]
	ld b,a
	ld a,[H_QUOTIENT + 3]
	sub b
	ld b,[hl]
	ld a,[H_QUOTIENT + 2]
	sbc b
	jp nc,.notHealthyEnough
	ld a,[$cc2b]
	push af
	ld a,POTION
	ld [$cf91],a
	ld [$d152],a
	call UseItem
	pop af
	ld [$cc2b],a
	jp .loop
.notHealthyEnough ; if current HP is less than 1/5 of max HP
	ld hl,.notHealthyEnoughText
	call PrintText
	jp .loop
.notHealthyEnoughText
	TX_FAR _NotHealthyEnoughText
	db "@"
.goBackToMap
	call Func_3dbe
	jp CloseTextDisplay
.newBadgeRequired
	ld hl,.newBadgeRequiredText
	call PrintText
	jp .loop
.newBadgeRequiredText
	TX_FAR _NewBadgeRequiredText
	db "@"

; writes a blank tile to all possible menu cursor positions on the party menu
ErasePartyMenuCursors: ; 132ed (4:72ed)
	FuncCoord 0,1
	ld hl,Coord
	ld bc,2 * 20 ; menu cursor positions are 2 rows apart
	ld a,6 ; 6 menu cursor positions
.loop
	ld [hl]," "
	add hl,bc
	dec a
	jr nz,.loop
	ret

ItemMenuLoop: ; 132fc (4:72fc)
	call LoadScreenTilesFromBuffer2DisableBGTransfer ; restore saved screen
	call GoPAL_SET_CF1C

StartMenu_Item: ; 13302 (4:7302)
	ld a,[W_ISLINKBATTLE]
	dec a
	jr nz,.notInLinkBattle
	ld hl,CannotUseItemsHereText
	call PrintText
	jr .exitMenu
.notInLinkBattle
	ld bc,wNumBagItems
	ld hl,$cf8b
	ld a,c
	ld [hli],a
	ld [hl],b ; store item bag pointer at $cf8b (for DisplayListMenuID)
	xor a
	ld [$cf93],a
	ld a,ITEMLISTMENU
	ld [wListMenuID],a
	ld a,[$cc2c]
	ld [wCurrentMenuItem],a
	call DisplayListMenuID
	ld a,[wCurrentMenuItem]
	ld [$cc2c],a
	jr nc,.choseItem
.exitMenu
	call LoadScreenTilesFromBuffer2 ; restore saved screen
	call LoadTextBoxTilePatterns
	call UpdateSprites ; move sprites
	jp RedisplayStartMenu
.choseItem
; erase menu cursor (blank each tile in front of an item name)
	ld a," "
	FuncCoord 5,4
	ld [Coord],a
	FuncCoord 5,6
	ld [Coord],a
	FuncCoord 5,8
	ld [Coord],a
	FuncCoord 5,10
	ld [Coord],a
	call PlaceUnfilledArrowMenuCursor
	xor a
	ld [$cc35],a
	ld a,[$cf91]
	cp a,BICYCLE
	jp z,.useOrTossItem
.notBicycle1
	ld a,$06 ; use/toss menu
	ld [$d125],a
	call DisplayTextBoxID
	ld hl,wTopMenuItemY
	ld a,11
	ld [hli],a ; top menu item Y
	ld a,14
	ld [hli],a ; top menu item X
	xor a
	ld [hli],a ; current menu item ID
	inc hl
	inc a ; a = 1
	ld [hli],a ; max menu item ID
	ld a,%00000011 ; A button, B button
	ld [hli],a ; menu watched keys
	xor a
	ld [hl],a ; old menu item id
	call HandleMenuInput
	call PlaceUnfilledArrowMenuCursor
	bit 1,a ; was the B button pressed?
	jr z,.useOrTossItem
	jp ItemMenuLoop
.useOrTossItem ; if the player made the choice to use or toss the item
	ld a,[$cf91]
	ld [$d11e],a
	call GetItemName
	call CopyStringToCF4B ; copy name to $cf4b
	ld a,[$cf91]
	cp a,BICYCLE
	jr nz,.notBicycle2
	ld a,[$d732]
	bit 5,a
	jr z,.useItem_closeMenu
	ld hl,CannotGetOffHereText
	call PrintText
	jp ItemMenuLoop
.notBicycle2
	ld a,[wCurrentMenuItem]
	and a
	jr nz,.tossItem
.useItem
	ld [$d152],a
	ld a,[$cf91]
	cp a,HM_01
	jr nc,.useItem_partyMenu
	ld hl,UsableItems_CloseMenu
	ld de,1
	call IsInArray
	jr c,.useItem_closeMenu
	ld a,[$cf91]
	ld hl,UsableItems_PartyMenu
	ld de,1
	call IsInArray
	jr c,.useItem_partyMenu
	call UseItem
	jp ItemMenuLoop
.useItem_closeMenu
	xor a
	ld [$d152],a
	call UseItem
	ld a,[$cd6a]
	and a
	jp z,ItemMenuLoop
	jp CloseStartMenu
.useItem_partyMenu
	ld a,[$cfcb]
	push af
	call UseItem
	ld a,[$cd6a]
	cp a,$02
	jp z,.partyMenuNotDisplayed
	call GBPalWhiteOutWithDelay3
	call Func_3dbe
	pop af
	ld [$cfcb],a
	jp StartMenu_Item
.partyMenuNotDisplayed
	pop af
	ld [$cfcb],a
	jp ItemMenuLoop
.tossItem
	call IsKeyItem
	ld a,[$d124]
	and a
	jr nz,.skipAskingQuantity
	ld a,[$cf91]
	call IsItemHM
	jr c,.skipAskingQuantity
	call DisplayChooseQuantityMenu
	inc a
	jr z,.tossZeroItems
.skipAskingQuantity
	ld hl,wNumBagItems
	call TossItem
.tossZeroItems
	jp ItemMenuLoop

CannotUseItemsHereText: ; 1342a (4:742a)
	TX_FAR _CannotUseItemsHereText
	db "@"

CannotGetOffHereText: ; 1342f (4:742f)
	TX_FAR _CannotGetOffHereText
	db "@"

; items which bring up the party menu when used
UsableItems_PartyMenu: ; 13434 (4:7434)
	db MOON_STONE
	db ANTIDOTE
	db BURN_HEAL
	db ICE_HEAL
	db AWAKENING
	db PARLYZ_HEAL
	db FULL_RESTORE
	db MAX_POTION
	db HYPER_POTION
	db SUPER_POTION
	db POTION
	db FIRE_STONE
	db THUNDER_STONE
	db WATER_STONE
	db HP_UP
	db PROTEIN
	db IRON
	db CARBOS
	db CALCIUM
	db RARE_CANDY
	db LEAF_STONE
	db FULL_HEAL
	db REVIVE
	db MAX_REVIVE
	db FRESH_WATER
	db SODA_POP
	db LEMONADE
	db X_ATTACK
	db X_DEFEND
	db X_SPEED
	db X_SPECIAL
	db PP_UP
	db ETHER
	db MAX_ETHER
	db ELIXER
	db MAX_ELIXER
	db $ff

; items which close the item menu when used
UsableItems_CloseMenu: ; 13459 (4:7459)
	db ESCAPE_ROPE
	db ITEMFINDER
	db POKE_FLUTE
	db OLD_ROD
	db GOOD_ROD
	db SUPER_ROD
	db $ff

StartMenu_TrainerInfo: ; 13460 (4:7460)
	call GBPalWhiteOut
	call ClearScreen
	call UpdateSprites ; move sprites
	ld a,[$ffd7]
	push af
	xor a
	ld [$ffd7],a
	call DrawTrainerInfo
	ld a,$2e
	call Predef ; draw badges
	ld b,$0d
	call GoPAL_SET
	call GBPalNormal
	call WaitForTextScrollButtonPress ; wait for button press
	call GBPalWhiteOut
	call LoadFontTilePatterns
	call LoadScreenTilesFromBuffer2 ; restore saved screen
	call GoPAL_SET_CF1C
	call ReloadMapData
	call LoadGBPal
	pop af
	ld [$ffd7],a
	jp RedisplayStartMenu

; loads tile patterns and draws everything except for gym leader faces / badges
DrawTrainerInfo: ; 1349a (4:749a)
	ld de,RedPicFront
	ld bc,(BANK(RedPicFront) << 8) | $01
	ld a,$3b
	call Predef
	call DisableLCD
	FuncCoord 0,2
	ld hl,Coord
	ld a," "
	call TrainerInfo_DrawVerticalLine
	FuncCoord 1,2
	ld hl,Coord
	call TrainerInfo_DrawVerticalLine
	ld hl,$9070
	ld de,$9000
	ld bc,$01c0
	call CopyData
	ld hl,TrainerInfoTextBoxTileGraphics ; $7b98 ; trainer info text box tile patterns
	ld de,$9770
	ld bc,$0080
	push bc
	call TrainerInfo_FarCopyData
	ld hl,BlankLeaderNames ; $7c28
	ld de,$9600
	ld bc,$0170
	call TrainerInfo_FarCopyData
	pop bc
	ld hl,BadgeNumbersTileGraphics  ; $7d98 ; badge number tile patterns
	ld de,$8d80
	call TrainerInfo_FarCopyData
	ld hl,GymLeaderFaceAndBadgeTileGraphics  ; $6a9e ; gym leader face and badge tile patterns
	ld de,$9200
	ld bc,$0400
	ld a,$03
	call FarCopyData2
	ld hl,TextBoxGraphics ; $6288
	ld de,$00d0
	add hl,de ; hl = colon tile pattern
	ld de,$8d60
	ld bc,$0010
	ld a,$04
	push bc
	call FarCopyData2
	pop bc
	ld hl,TrainerInfoTextBoxTileGraphics + $80  ; $7c18 ; background tile pattern
	ld de,$8d70
	call TrainerInfo_FarCopyData
	call EnableLCD
	ld hl,$cd3d
	ld a,18 + 1
	ld [hli],a
	dec a
	ld [hli],a
	ld [hl],1
	FuncCoord 0,0
	ld hl,Coord
	call TrainerInfo_DrawTextBox
	ld hl,$cd3d
	ld a,16 + 1
	ld [hli],a
	dec a
	ld [hli],a
	ld [hl],3
	FuncCoord 1,10
	ld hl,Coord
	call TrainerInfo_DrawTextBox
	FuncCoord 0,10
	ld hl,Coord
	ld a,$d7
	call TrainerInfo_DrawVerticalLine
	FuncCoord 19,10
	ld hl,Coord
	call TrainerInfo_DrawVerticalLine
	FuncCoord 6,9
	ld hl,Coord
	ld de,TrainerInfo_BadgesText
	call PlaceString
	FuncCoord 2,2
	ld hl,Coord
	ld de,TrainerInfo_NameMoneyTimeText
	call PlaceString
	FuncCoord 7,2
	ld hl,Coord
	ld de,W_PLAYERNAME
	call PlaceString
	FuncCoord 8,4
	ld hl,Coord
	ld de,wPlayerMoney
	ld c,$e3
	call PrintBCDNumber
	FuncCoord 9,6
	ld hl,Coord
	ld de,$da41 ; hours
	ld bc,$4103
	call PrintNumber
	ld [hl],$d6 ; colon tile ID
	inc hl
	ld de,$da43 ; minutes
	ld bc,$8102
	jp PrintNumber

TrainerInfo_FarCopyData: ; 1357f (4:757f)
	ld a,$0b
	jp FarCopyData2

TrainerInfo_NameMoneyTimeText: ; 13584 (4:7584)
	db   "NAME/"
	next "MONEY/"
	next "TIME/@"

; $76 is a circle tile
TrainerInfo_BadgesText: ; 13597 (4:7597)
	db $76,"BADGES",$76,"@"

; draws a text box on the trainer info screen
; height is always 6
; INPUT:
; hl = destination address
; [$cd3d] = width + 1
; [$cd3e] = width
; [$cd3f] = distance from the end of a text box row to the start of the next
TrainerInfo_DrawTextBox: ; 135a0 (4:75a0)
	ld a,$79 ; upper left corner tile ID
	ld de,$7a7b ; top edge and upper right corner tile ID's
	call TrainerInfo_DrawHorizontalEdge ; draw top edge
	call TrainerInfo_NextTextBoxRow
	ld a,[$cd3d] ; width of the text box plus one
	ld e,a
	ld d,0
	ld c,6 ; height of the text box
.loop
	ld [hl],$7c ; left edge tile ID
	add hl,de
	ld [hl],$78 ; right edge tile ID
	call TrainerInfo_NextTextBoxRow
	dec c
	jr nz,.loop
	ld a,$7d ; lower left corner tile ID
	ld de,$777e ; bottom edge and lower right corner tile ID's

TrainerInfo_DrawHorizontalEdge: ; 135c3 (4:75c3)
	ld [hli],a ; place left corner tile
	ld a,[$cd3e] ; width of the text box
	ld c,a
	ld a,d
.loop
	ld [hli],a ; place edge tile
	dec c
	jr nz,.loop
	ld a,e
	ld [hl],a ; place right corner tile
	ret

TrainerInfo_NextTextBoxRow: ; 135d0 (4:75d0)
	ld a,[$cd3f] ; distance to the start of the next row
.loop
	inc hl
	dec a
	jr nz,.loop
	ret

; draws a vertical line
; INPUT:
; hl = address of top tile in the line
; a = tile ID
TrainerInfo_DrawVerticalLine: ; 135d8 (4:75d8)
	ld de,20
	ld c,8
.loop
	ld [hl],a
	add hl,de
	dec c
	jr nz,.loop
	ret

StartMenu_SaveReset: ; 135e3 (4:75e3)
	ld a,[$d72e]
	bit 6,a ; is the player using the link feature?
	jp nz,InitGame
	ld a,$3f
	call Predef ; save the game
	call LoadScreenTilesFromBuffer2 ; restore saved screen
	jp HoldTextDisplayOpen

StartMenu_Option: ; 135f6 (4:75f6)
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a
	call ClearScreen
	call UpdateSprites
	callab DisplayOptionMenu
	call LoadScreenTilesFromBuffer2 ; restore saved screen
	call LoadTextBoxTilePatterns
	call UpdateSprites
	jp RedisplayStartMenu

SwitchPartyMon: ; 13613 (4:7613)
	call SwitchPartyMon_Stats
	ld a, [wWhichTrade] ; $cd3d
	call SwitchPartyMon_OAM
	ld a, [wCurrentMenuItem] ; $cc26
	call SwitchPartyMon_OAM
	jp RedrawPartyMenu_

SwitchPartyMon_OAM: ; 13625 (4:7625)
	push af
	ld hl, wTileMap
	ld bc, $28
	call AddNTimes
	ld c, $28
	ld a, $7f
.asm_13633
	ld [hli], a
	dec c
	jr nz, .asm_13633
	pop af
	ld hl, wOAMBuffer
	ld bc, $10
	call AddNTimes
	ld de, $4
	ld c, e
.asm_13645
	ld [hl], $a0
	add hl, de
	dec c
	jr nz, .asm_13645
	call WaitForSoundToFinish
	ld a, (SFX_02_58 - SFX_Headers_02) / 3
	jp PlaySound

SwitchPartyMon_Stats: ; 13653 (4:7653)
	ld a, [$cc35]
	and a
	jr nz, .asm_13661
	ld a, [wWhichPokemon] ; $cf92
	inc a
	ld [$cc35], a
	ret
.asm_13661
	xor a
	ld [$d07d], a
	ld a, [$cc35]
	dec a
	ld b, a
	ld a, [wCurrentMenuItem] ; $cc26
	ld [wWhichTrade], a ; $cd3d
	cp b
	jr nz, .asm_1367b
	xor a
	ld [$cc35], a
	ld [$d07d], a
	ret
.asm_1367b
	ld a, b
	ld [$cc35], a
	push hl
	push de
	ld hl, W_PARTYMON1 ; $d164
	ld d, h
	ld e, l
	ld a, [wCurrentMenuItem] ; $cc26
	add l
	ld l, a
	jr nc, .asm_1368e
	inc h
.asm_1368e
	ld a, [$cc35]
	add e
	ld e, a
	jr nc, .asm_13696
	inc d
.asm_13696
	ld a, [hl]
	ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	ld a, [de]
	ld [hl], a
	ld a, [H_DIVIDEND] ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	ld [de], a
	ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
	ld bc, $2c
	ld a, [wCurrentMenuItem] ; $cc26
	call AddNTimes
	push hl
	ld de, $cc97
	ld bc, $2c
	call CopyData
	ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
	ld bc, $2c
	ld a, [$cc35]
	call AddNTimes
	pop de
	push hl
	ld bc, $2c
	call CopyData
	pop de
	ld hl, $cc97
	ld bc, $2c
	call CopyData
	ld hl, W_PARTYMON1OT ; $d273
	ld a, [wCurrentMenuItem] ; $cc26
	call SkipFixedLengthTextEntries
	push hl
	ld de, $cc97
	ld bc, $b
	call CopyData
	ld hl, W_PARTYMON1OT ; $d273
	ld a, [$cc35]
	call SkipFixedLengthTextEntries
	pop de
	push hl
	ld bc, $b
	call CopyData
	pop de
	ld hl, $cc97
	ld bc, $b
	call CopyData
	ld hl, W_PARTYMON1NAME ; $d2b5
	ld a, [wCurrentMenuItem] ; $cc26
	call SkipFixedLengthTextEntries
	push hl
	ld de, $cc97
	ld bc, $b
	call CopyData
	ld hl, W_PARTYMON1NAME ; $d2b5
	ld a, [$cc35]
	call SkipFixedLengthTextEntries
	pop de
	push hl
	ld bc, $b
	call CopyData
	pop de
	ld hl, $cc97
	ld bc, $b
	call CopyData
	ld a, [$cc35]
	ld [wWhichTrade], a ; $cd3d
	xor a
	ld [$cc35], a
	ld [$d07d], a
	pop de
	pop hl
	ret

; tests if mon [$cf91] can learn move [$d0e0]
TestMonMoveCompatibility: ; 1373e (4:773e)
	ld a, [$cf91]
	ld [$d0b5], a
	call GetMonHeader
	ld hl, W_MONHLEARNSET
	push hl
	ld a, [$d0e0]
	ld b, a
	ld c, $0
	ld hl, TechnicalMachines
.findTMloop
	ld a, [hli]
	cp b
	jr z, .TMfoundLoop
	inc c
	jr .findTMloop
.TMfoundLoop
	pop hl
	ld b, $2  ; read corresponding bit from TM compatibility array
	ld a, $10
	jp Predef ; indirect jump to HandleBitArray (f666 (3:7666))

; converts TM/HM number in $d11e into move number
; HMs start at 51
TMToMove: ; 13763 (4:7763)
	ld a, [$d11e]
	dec a
	ld hl, TechnicalMachines
	ld b, $0
	ld c, a
	add hl, bc
	ld a, [hl]
	ld [$d11e], a
	ret

INCLUDE "data/tms.asm"

Func_137aa: ; 137aa (4:77aa)
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr nz, .asm_137eb
	ld a, [W_ENEMYMONNUMBER] ; $cfe8
	ld hl, $d8a8
	ld bc, $2c
	call AddNTimes
	ld a, [W_ENEMYMONSTATUS] ; $cfe9
	ld [hl], a
	call ClearScreen
	callab Func_372d6
	ld a, [$cf0b]
	cp $1
	ld de, YouWinText
	jr c, .asm_137de
	ld de, YouLoseText
	jr z, .asm_137de
	ld de, DrawText
.asm_137de
	FuncCoord 6, 8 ; $c446
	ld hl, Coord
	call PlaceString
	ld c, $c8
	call DelayFrames
	jr .asm_1380a
.asm_137eb
	ld a, [$cf0b]
	and a
	jr nz, .asm_13813
	ld hl, $cce5
	ld a, [hli]
	or [hl]
	inc hl
	or [hl]
	jr z, .asm_1380a
	ld de, wPlayerMoney + 2 ; $d349
	ld c, $3
	ld a, $b
	call Predef ; indirect jump to Func_f81d (f81d (3:781d))
	ld hl, PickUpPayDayMoneyText
	call PrintText
.asm_1380a
	xor a
	ld [$ccd4], a
	ld a, $2a
	call Predef ; indirect jump to Func_3ad1c (3ad1c (e:6d1c))
.asm_13813
	xor a
	ld [$d083], a
	ld [$c02a], a
	ld [W_ISINBATTLE], a ; $d057
	ld [W_BATTLETYPE], a ; $d05a
	ld [W_MOVEMISSED], a ; $d05f
	ld [W_CUROPPONENT], a ; $d059
	ld [$d11f], a
	ld [$d120], a
	ld [$d078], a
	ld hl, $cc2b
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hl], a
	ld [wListScrollOffset], a ; $cc36
	ld hl, $d060
	ld b, $18
.asm_1383e
	ld [hli], a
	dec b
	jr nz, .asm_1383e
	ld hl, $d72c
	set 0, [hl]
	call WaitForSoundToFinish
	call GBPalWhiteOut
	ld a, $ff
	ld [$d42f], a
	ret

YouWinText: ; 13853 (4:7853)
	db "YOU WIN@"

YouLoseText: ; 1385b (4:785b)
	db "YOU LOSE@"

DrawText: ; 13864 (4:7864)
	db "  DRAW@"

PickUpPayDayMoneyText: ; 1386b (4:786b)
	TX_FAR _PickUpPayDayMoneyText
	db "@"

Func_13870: ; 13870 (4:7870)
	ld a, [$cc57]
	and a
	ret nz
	ld a, [$d736]
	and a
	ret nz
	callab Func_c49d
	jr nc, .asm_13888
.asm_13884
	ld a, $1
	and a
	ret
.asm_13888
	callab Func_128d8
	jr z, .asm_13884
	ld a, [$d0db]
	and a
	jr z, .asm_1389e
	dec a
	jr z, .asm_13905
	ld [$d0db], a
.asm_1389e
	FuncCoord 9, 9 ; $c45d
	ld hl, Coord
	ld c, [hl]
	ld a, [W_GRASSTILE]
	cp c
	ld a, [W_GRASSRATE] ; $d887
	jr z, .asm_138c4
	ld a, $14
	cp c
	ld a, [W_WATERRATE] ; $d8a4
	jr z, .asm_138c4
	ld a, [W_CURMAP] ; $d35e
	cp REDS_HOUSE_1F
	jr c, .asm_13912
	ld a, [W_CURMAPTILESET] ; $d367
	cp FOREST ; Viridian Forest/Safari Zone
	jr z, .asm_13912
	ld a, [W_GRASSRATE] ; $d887
.asm_138c4
	ld b, a
	ld a, [H_RAND1] ; $ffd3
	cp b
	jr nc, .asm_13912
	ld a, [H_RAND2] ; $ffd4
	ld b, a
	ld hl, WildMonEncounterSlotChances ; $7918
.asm_138d0
	ld a, [hli]
	cp b
	jr nc, .asm_138d7
	inc hl
	jr .asm_138d0
.asm_138d7
	ld c, [hl]
	ld hl, W_GRASSMONS ; $d888
	FuncCoord 8, 9 ; $c45c
	ld a, [Coord]
	cp $14
	jr nz, .asm_138e5
	ld hl, W_WATERMONS ; $d8a5 (aliases: W_ENEMYMON1HP)
.asm_138e5
	ld b, $0
	add hl, bc
	ld a, [hli]
	ld [W_CURENEMYLVL], a ; $d127
	ld a, [hl]
	ld [$cf91], a
	ld [W_ENEMYMONID], a
	ld a, [$d0db]
	and a
	jr z, .asm_13916
	ld a, [W_PARTYMON1_LEVEL] ; $d18c
	ld b, a
	ld a, [W_CURENEMYLVL] ; $d127
	cp b
	jr c, .asm_13912
	jr .asm_13916
.asm_13905
	ld [$d0db], a
	ld a, $d2
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call EnableAutoTextBoxDrawing
	call DisplayTextID
.asm_13912
	ld a, $1
	and a
	ret
.asm_13916
	xor a
	ret

WildMonEncounterSlotChances: ; 13918 (4:7918)
; There are 10 slots for wild pokemon, and this is the table that defines how common each of
; those 10 slots is. A random number is generated and then the first byte of each pair in this
; table is compared against that random number. If the random number is less than or equal
; to the first byte, then that slot is chosen.  The second byte is double the slot number.
	db $32, $00 ; 51/256 = 19.9% chance of slot 0
	db $65, $02 ; 51/256 = 19.9% chance of slot 1
	db $8C, $04 ; 39/256 = 15.2% chance of slot 2
	db $A5, $06 ; 25/256 =  9.8% chance of slot 3
	db $BE, $08 ; 25/256 =  9.8% chance of slot 4
	db $D7, $0A ; 25/256 =  9.8% chance of slot 5
	db $E4, $0C ; 13/256 =  5.1% chance of slot 6
	db $F1, $0E ; 13/256 =  5.1% chance of slot 7
	db $FC, $10 ; 11/256 =  4.3% chance of slot 8
	db $FF, $12 ;  3/256 =  1.2% chance of slot 9

RecoilEffect_: ; 1392c (4:792c)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, [W_PLAYERMOVENUM] ; $cfd2
	ld hl, W_PLAYERMONMAXHP ; $d023
	jr z, .asm_1393d
	ld a, [W_ENEMYMOVENUM] ; $cfcc
	ld hl, W_ENEMYMONMAXHP ; $cff4
.asm_1393d
	ld d, a
	ld a, [W_DAMAGE] ; $d0d7
	ld b, a
	ld a, [W_DAMAGE + 1]
	ld c, a
	srl b
	rr c
	ld a, d
	cp STRUGGLE
	jr z, .asm_13953
	srl b
	rr c
.asm_13953
	ld a, b
	or c
	jr nz, .asm_13958
	inc c
.asm_13958
	ld a, [hli]
	ld [wHPBarMaxHP+1], a
	ld a, [hl]
	ld [wHPBarMaxHP], a
	push bc
	ld bc, $fff2
	add hl, bc
	pop bc
	ld a, [hl]
	ld [wHPBarOldHP], a
	sub c
	ld [hld], a
	ld [wHPBarNewHP], a
	ld a, [hl]
	ld [wHPBarOldHP+1], a
	sbc b
	ld [hl], a
	ld [wHPBarNewHP+1], a
	jr nc, .asm_13982
	xor a
	ld [hli], a
	ld [hl], a
	ld hl, wHPBarNewHP
	ld [hli], a
	ld [hl], a
.asm_13982
	FuncCoord 10, 9 ; $c45e
	ld hl, Coord
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, $1
	jr z, .asm_13990
	FuncCoord 2, 2 ; $c3ca
	ld hl, Coord
	xor a
.asm_13990
	ld [wListMenuID], a ; $cf94
	ld a, $48
	call Predef ; indirect jump to UpdateHPBar (fa1d (3:7a1d))
	ld hl, HitWithRecoilText ; $799e
	jp PrintText
HitWithRecoilText: ; 1399e (4:799e)
	TX_FAR _HitWithRecoilText
	db "@"

ConversionEffect_: ; 139a3 (4:79a3)
	ld hl, W_ENEMYMONTYPE1
	ld de, W_PLAYERMONTYPE1
	ld a, [H_WHOSETURN]
	and a
	ld a, [W_ENEMYBATTSTATUS1]
	jr z, .asm_139b8
	push hl
	ld h, d
	ld l, e
	pop de
	ld a, [W_PLAYERBATTSTATUS1]
.asm_139b8
	bit 6, a ; is mon immune to typical attacks (dig/fly)
	jr nz, PrintButItFailedText
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hl]
	ld [de], a
	ld hl, Func_3fba8
	call Func_139d5
	ld hl, ConvertedTypeText
	jp PrintText

ConvertedTypeText: ; 139cd (4:79cd)
	TX_FAR _ConvertedTypeText
	db "@"

PrintButItFailedText: ; 139d2 (4:79d2)
	ld hl, PrintButItFailedText_
Func_139d5: ; 139d5 (4:79d5)
	ld b, BANK(PrintButItFailedText_)
	jp Bankswitch

HazeEffect_: ; 139da (4:79da)
	ld a, $7
	ld hl, wPlayerMonAttackMod
	call Func_13a43
	ld hl, wEnemyMonAttackMod
	call Func_13a43
	ld hl, $cd12
	ld de, W_PLAYERMONATK
	call Func_13a4a
	ld hl, $cd26
	ld de, W_ENEMYMONATTACK
	call Func_13a4a
	ld hl, W_ENEMYMONSTATUS
	ld de, wEnemySelectedMove
	ld a, [H_WHOSETURN]
	and a
	jr z, .asm_13a09
	ld hl, W_PLAYERMONSTATUS
	dec de

.asm_13a09
	ld a, [hl]
	ld [hl], $0
	and $27
	jr z, .asm_13a13
	ld a, $ff
	ld [de], a

.asm_13a13
	xor a
	ld [W_PLAYERDISABLEDMOVE], a
	ld [W_ENEMYDISABLEDMOVE], a
	ld hl, $ccee
	ld [hli], a
	ld [hl], a
	ld hl, W_PLAYERBATTSTATUS1
	call Func_13a37
	ld hl, W_ENEMYBATTSTATUS1
	call Func_13a37
	ld hl, Func_3fba8
	call Func_139d5
	ld hl, StatusChangesEliminatedText
	jp PrintText

Func_13a37: ; 13a37 (4:7a37)
	res 7, [hl]
	inc hl
	ld a, [hl]
	and $78
	ld [hli], a
	ld a, [hl]
	and $f8
	ld [hl], a
	ret

Func_13a43: ; 13a43 (4:7a43)
	ld b, $8
.loop
	ld [hli], a
	dec b
	jr nz, .loop
	ret

Func_13a4a: ; 13a4a (4:7a4a)
	ld b, $8
.loop
	ld a, [hli]
	ld [de], a
	inc de
	dec b
	jr nz, .loop
	ret

StatusChangesEliminatedText: ; 13a53 (4:7a53)
	TX_FAR _StatusChangesEliminatedText
	db "@"

Func_13a58: ; 13a58 (4:7a58)
	ld hl, W_GRASSRATE ; $d887
	ld a, [W_ISLINKBATTLE] ; $d12b
	and a
	jr nz, .asm_13a86
	ld hl, W_RIVALNAME ; $d34a
	ld a, [W_TRAINERCLASS] ; $d031
	cp SONY1
	jr z, .asm_13a86
	cp SONY2
	jr z, .asm_13a86
	cp SONY3
	jr z, .asm_13a86
	ld [$d0b5], a
	ld a, TRAINER_NAME
	ld [W_LISTTYPE], a
	ld a, $e
	ld [$d0b7], a
	call GetName
	ld hl, $cd6d
.asm_13a86
	ld de, W_TRAINERNAME
	ld bc, $d
	jp CopyData

GenRandom_: ; 13a8f (4:7a8f)
; generate a random 16-bit integer and store it at $FFD3,$FFD4
	ld a,[rDIV]
	ld b,a
	ld a,[H_RAND1]
	adc b
	ld [H_RAND1],a
	ld a,[rDIV]
	ld b,a
	ld a,[H_RAND2]
	sbc b
	ld [H_RAND2],a
	ret

SECTION "bank5",ROMX,BANK[$5]

RedCyclingSprite: ; 14000 (5:4000)
	INCBIN "gfx/sprites/cycling.2bpp" ; was $14000
RedSprite: ; 14180 (5:4180)
	INCBIN "gfx/sprites/red.2bpp" ; was $14180
BlueSprite: ; 14300 (5:4300)
	INCBIN "gfx/sprites/blue.2bpp" ; was $14300
OakSprite: ; 14480 (5:4480)
	INCBIN "gfx/sprites/oak.2bpp" ; was $14480
BugCatcherSprite: ; 14600 (5:4600)
	INCBIN "gfx/sprites/bug_catcher.2bpp" ; was $14600
SlowbroSprite: ; 14780 (5:4780)
	INCBIN "gfx/sprites/slowbro.2bpp" ; was $14780
LassSprite: ; 14900 (5:4900)
	INCBIN "gfx/sprites/lass.2bpp" ; was $14900
BlackHairBoy1Sprite: ; 14a80 (5:4a80)
	INCBIN "gfx/sprites/black_hair_boy_1.2bpp" ; was $14a80
LittleGirlSprite: ; 14c00 (5:4c00)
	INCBIN "gfx/sprites/little_girl.2bpp" ; was $14c00
BirdSprite: ; 14d80 (5:4d80)
	INCBIN "gfx/sprites/bird.2bpp" ; was $14d80
FatBaldGuySprite: ; 14f00 (5:4f00)
	INCBIN "gfx/sprites/fat_bald_guy.2bpp" ; was $14f00
GamblerSprite: ; 15080 (5:5080)
	INCBIN "gfx/sprites/gambler.2bpp" ; was $15080
BlackHairBoy2Sprite: ; 15200 (5:5200)
	INCBIN "gfx/sprites/black_hair_boy_2.2bpp" ; was $15200
GirlSprite: ; 15380 (5:5380)
	INCBIN "gfx/sprites/girl.2bpp" ; was $15380
HikerSprite: ; 15500 (5:5500)
	INCBIN "gfx/sprites/hiker.2bpp" ; was $15500
FoulardWomanSprite: ; 15680 (5:5680)
	INCBIN "gfx/sprites/foulard_woman.2bpp" ; was $15680
GentlemanSprite: ; 15800 (5:5800)
	INCBIN "gfx/sprites/gentleman.2bpp" ; was $15800
DaisySprite: ; 15980 (5:5980)
	INCBIN "gfx/sprites/daisy.2bpp" ; was $15980
BikerSprite: ; 15b00 (5:5b00)
	INCBIN "gfx/sprites/biker.2bpp" ; was $15b00
SailorSprite: ; 15c80 (5:5c80)
	INCBIN "gfx/sprites/sailor.2bpp" ; was $15c80
CookSprite: ; 15e00 (5:5e00)
	INCBIN "gfx/sprites/cook.2bpp" ; was $15e00
BikeShopGuySprite: ; 15f80 (5:5f80)
	INCBIN "gfx/sprites/bike_shop_guy.2bpp" ; was $15f80
MrFujiSprite: ; 16040 (5:6040)
	INCBIN "gfx/sprites/mr_fuji.2bpp" ; was $16040
GiovanniSprite: ; 161c0 (5:61c0)
	INCBIN "gfx/sprites/giovanni.2bpp" ; was $161c0
RocketSprite: ; 16340 (5:6340)
	INCBIN "gfx/sprites/rocket.2bpp" ; was $16340
MediumSprite: ; 164c0 (5:64c0)
	INCBIN "gfx/sprites/medium.2bpp" ; was $164c0
WaiterSprite: ; 16640 (5:6640)
	INCBIN "gfx/sprites/waiter.2bpp" ; was $16640
ErikaSprite: ; 167c0 (5:67c0)
	INCBIN "gfx/sprites/erika.2bpp" ; was $167c0
MomGeishaSprite: ; 16940 (5:6940)
	INCBIN "gfx/sprites/mom_geisha.2bpp" ; was $16940
BrunetteGirlSprite: ; 16ac0 (5:6ac0)
	INCBIN "gfx/sprites/brunette_girl.2bpp" ; was $16ac0
LanceSprite: ; 16c40 (5:6c40)
	INCBIN "gfx/sprites/lance.2bpp" ; was $16c40
MomSprite: ; 16dc0 (5:6dc0)
	INCBIN "gfx/sprites/mom.2bpp" ; was $16dc0
BaldingGuySprite: ; 16e80 (5:6e80)
	INCBIN "gfx/sprites/balding_guy.2bpp" ; was $16e80
YoungBoySprite: ; 16f40 (5:6f40)
	INCBIN "gfx/sprites/young_boy.2bpp" ; was $16f40
GameboyKidSprite: ; 17000 (5:7000)
	INCBIN "gfx/sprites/gameboy_kid.2bpp" ; was $17000
ClefairySprite: ; 170c0 (5:70c0)
	INCBIN "gfx/sprites/clefairy.2bpp" ; was $170c0
AgathaSprite: ; 17240 (5:7240)
	INCBIN "gfx/sprites/agatha.2bpp" ; was $17240
BrunoSprite: ; 173c0 (5:73c0)
	INCBIN "gfx/sprites/bruno.2bpp" ; was $173c0
LoreleiSprite: ; 17540 (5:7540)
	INCBIN "gfx/sprites/lorelei.2bpp" ; was $17540
SeelSprite: ; 176c0 (5:76c0)
	INCBIN "gfx/sprites/seel.2bpp" ; was $176c0

; Loads tile patterns for tiles used in the pokedex.
LoadPokedexTilePatterns: ; 17840 (5:7840)
	call LoadHpBarAndStatusTilePatterns
	ld de,PokedexTileGraphics ; $6488
	ld hl,$9600
	ld bc,(BANK(PokedexTileGraphics) << 8) + $12
	call CopyVideoData
	ld de,PokeballTileGraphics ; $697e
	ld hl,$9720
	ld bc,(BANK(PokeballTileGraphics) << 8) + $01
	jp CopyVideoData ; load pokeball tile for marking caught mons

; Loads tile patterns for map's sprites.
; For outside maps, it loads one of several fixed sets of sprites.
; For inside maps, it loads each sprite picture ID used in the map header.
; This is also called after displaying text because loading
; text tile patterns overwrites half of the sprite tile pattern data.
; Note on notation:
; $C1X* and $C2X* are used to denote $C100-$C1FF and $C200-$C2FF sprite slot
; fields, respectively, within loops. The X is the loop index.
; If there is an inner loop, Y is the inner loop index, i.e. $C1Y* and $C2Y*
; denote fields of the sprite slots interated over in the inner loop.
InitMapSprites: ; 1785b (5:785b)
	call InitOutsideMapSprites
	ret c ; return if the map is an outside map (already handled by above call)
; if the map is an inside map (i.e. mapID >= $25)
	ld hl,wSpriteStateData1
	ld de,$c20d
; Loop to copy picture ID's from $C1X0 to $C2XD for LoadMapSpriteTilePatterns.
.copyPictureIDLoop
	ld a,[hl] ; $C1X0 (picture ID)
	ld [de],a ; $C2XD
	ld a,$10
	add e
	ld e,a
	ld a,$10
	add l
	ld l,a
	jr nz,.copyPictureIDLoop

; This is used for both inside and outside maps, since it is called by
; InitOutsideMapSprites.
; Loads tile pattern data for sprites into VRAM.
LoadMapSpriteTilePatterns: ; 17871 (5:7871)
	ld a,[W_NUMSPRITES]
	and a ; are there any sprites?
	jr nz,.spritesExist
	ret
.spritesExist
	ld c,a ; c = [W_NUMSPRITES]
	ld b,$10 ; number of sprite slots
	ld hl,$c20d
	xor a
	ld [$ff8e],a ; 4-tile sprite counter
.copyPictureIDLoop ; loop to copy picture ID from $C2XD to $C2XE
	ld a,[hli] ; $C2XD (sprite picture ID)
	ld [hld],a ; $C2XE
	ld a,l
	add a,$10
	ld l,a
	dec b
	jr nz,.copyPictureIDLoop
	ld hl,$c21e
.loadTilePatternLoop
	ld de,$c21d
; Check if the current picture ID has already had its tile patterns loaded.
; This done by looping through the previous sprite slots and seeing if any of
; their picture ID's match that of the current sprite slot.
.checkIfAlreadyLoadedLoop
	ld a,e
	and a,$f0
	ld b,a ; b = offset of the wSpriteStateData2 sprite slot being checked against
	ld a,l
	and a,$f0 ; a = offset of current wSpriteStateData2 sprite slot
	cp b ; done checking all previous sprite slots?
	jr z,.notAlreadyLoaded
	ld a,[de] ; picture ID of the wSpriteStateData2 sprite slot being checked against
	cp [hl] ; do the picture ID's match?
	jp z,.alreadyLoaded
	ld a,e
	add a,$10
	ld e,a
	jr .checkIfAlreadyLoadedLoop
.notAlreadyLoaded
	ld de,$c20e
	ld b,$01
; loop to find the highest tile pattern VRAM slot (among the first 10 slots) used by a previous sprite slot
; this is done in order to find the first free VRAM slot available
.findNextVRAMSlotLoop
	ld a,e
	add a,$10
	ld e,a
	ld a,l
	cp e ; reached current slot?
	jr z,.foundNextVRAMSlot
	ld a,[de] ; $C2YE (VRAM slot)
	cp a,11 ; is it one of the first 10 slots?
	jr nc,.findNextVRAMSlotLoop
	cp b ; compare the slot being checked to the current max
	jr c,.findNextVRAMSlotLoop ; if the slot being checked is less than the current max
; if the slot being checked is greater than or equal to the current max
	ld b,a ; store new max VRAM slot
	jr .findNextVRAMSlotLoop
.foundNextVRAMSlot
	inc b ; increment previous max value to get next VRAM tile pattern slot
	ld a,b ; a = next VRAM tile pattern slot
	push af
	ld a,[hl] ; $C2XE (sprite picture ID)
	ld b,a ; b = current sprite picture ID
	cp a,SPRITE_BALL ; is it a 4-tile sprite?
	jr c,.notFourTileSprite
	pop af
	ld a,[$ff8e] ; 4-tile sprite counter
	add a,11
	jr .storeVRAMSlot
.notFourTileSprite
	pop af
.storeVRAMSlot
	ld [hl],a ; store VRAM slot at $C2XE
	ld [$ff8d],a ; used to determine if it's 4-tile sprite later
	ld a,b ; a = current sprite picture ID
	dec a
	add a
	add a
	push bc
	push hl
	ld hl,SpriteSheetPointerTable
	jr nc,.noCarry
	inc h
.noCarry
	add l
	ld l,a
	jr nc,.noCarry2
	inc h
.noCarry2
	push hl
	call ReadSpriteSheetData
	push af
	push de
	push bc
	ld hl,$8000 ; VRAM base address
	ld bc,$c0 ; number of bytes per VRAM slot
	ld a,[$ff8d]
	cp a,11 ; is it a 4-tile sprite?
	jr nc,.fourTileSpriteVRAMAddr
	ld d,a
	dec d
; Equivalent to multiplying $C0 (number of bytes in 12 tiles) times the VRAM
; slot and adding the result to $8000 (the VRAM base address).
.calculateVRAMAddrLoop
	add hl,bc
	dec d
	jr nz,.calculateVRAMAddrLoop
	jr .loadStillTilePattern
.fourTileSpriteVRAMAddr
	ld hl,$87c0 ; address for second 4-tile sprite
	ld a,[$ff8e] ; 4-tile sprite counter
	and a ; is it the first 4-tile sprite?
	jr nz,.loadStillTilePattern
; if it's the first 4-tile sprite
	ld hl,$8780 ; address for first 4-tile sprite
	inc a
	ld [$ff8e],a ; 4-tile sprite counter
.loadStillTilePattern
	pop bc
	pop de
	pop af
	push hl
	push hl
	ld h,d
	ld l,e
	pop de
	ld b,a
	ld a,[$cfc4]
	bit 0,a ; reloading upper half of tile patterns after displaying text?
	jr nz,.skipFirstLoad ; if so, skip loading data into the lower half
	ld a,b
	ld b,0
	call FarCopyData2 ; load tile pattern data for sprite when standing still
.skipFirstLoad
	pop de
	pop hl
	ld a,[$ff8d]
	cp a,11 ; is it a 4-tile sprite?
	jr nc,.skipSecondLoad ; if so, there is no second block
	push de
	call ReadSpriteSheetData
	push af
	ld a,$c0
	add e
	ld e,a
	jr nc,.noCarry3
	inc d
.noCarry3
	ld a,[$cfc4]
	bit 0,a ; reloading upper half of tile patterns after displaying text?
	jr nz,.loadWhileLCDOn
	pop af
	pop hl
	set 3,h ; add $800 to hl
	push hl
	ld h,d
	ld l,e
	pop de
	call FarCopyData2 ; load tile pattern data for sprite when walking
	jr .skipSecondLoad
; When reloading the upper half of tile patterns after diplaying text, the LCD
; will be on, so CopyVideoData (which writes to VRAM only during V-blank) must
; be used instead of FarCopyData2.
.loadWhileLCDOn
	pop af
	pop hl
	set 3,h ; add $800 to hl
	ld b,a
	swap c
	call CopyVideoData ; load tile pattern data for sprite when walking
.skipSecondLoad
	pop hl
	pop bc
	jr .nextSpriteSlot
.alreadyLoaded ; if the current picture ID has already had its tile patterns loaded
	inc de
	ld a,[de] ; a = VRAM slot for the current picture ID (from $C2YE)
	ld [hl],a ; store VRAM slot in current wSpriteStateData2 sprite slot (at $C2XE)
.nextSpriteSlot
	ld a,l
	add a,$10
	ld l,a
	dec c
	jp nz,.loadTilePatternLoop
	ld hl,$c20d
	ld b,$10
; the pictures ID's stored at $C2XD are no longer needed, so zero them
.zeroStoredPictureIDLoop
	xor a
	ld [hl],a ; $C2XD
	ld a,$10
	add l
	ld l,a
	dec b
	jr nz,.zeroStoredPictureIDLoop
	ret

; reads data from SpriteSheetPointerTable
; INPUT:
; hl = address of sprite sheet entry
; OUTPUT:
; de = pointer to sprite sheet
; bc = length in bytes
; a = ROM bank
ReadSpriteSheetData: ; 17971 (5:7971)
	ld a,[hli]
	ld e,a
	ld a,[hli]
	ld d,a
	ld a,[hli]
	ld c,a
	xor a
	ld b,a
	ld a,[hli]
	ret

; Loads sprite set for outside maps (cities and routes) and sets VRAM slots.
; sets carry if the map is a city or route, unsets carry if not
InitOutsideMapSprites: ; 1797b (5:797b)
	ld a,[W_CURMAP]
	cp a,REDS_HOUSE_1F ; is the map a city or a route (map ID less than $25)?
	ret nc ; if not, return
	ld hl,MapSpriteSets
	add l
	ld l,a
	jr nc,.noCarry
	inc h
.noCarry
	ld a,[hl] ; a = spriteSetID
	cp a,$f0 ; does the map have 2 sprite sets?
	call nc,GetSplitMapSpriteSetID ; if so, choose the appropriate one
	ld b,a ; b = spriteSetID
	ld a,[$cfc4]
	bit 0,a ; reloading upper half of tile patterns after displaying text?
	jr nz,.loadSpriteSet ; if so, forcibly reload the sprite set
	ld a,[W_SPRITESETID]
	cp b ; has the sprite set ID changed?
	jr z,.skipLoadingSpriteSet ; if not, don't load it again
.loadSpriteSet
	ld a,b
	ld [W_SPRITESETID],a
	dec a
	ld b,a
	sla a
	ld c,a
	sla a
	sla a
	add c
	add b ; a = (spriteSetID - 1) * 11
	ld de,SpriteSets
; add a to de to get offset of sprite set
	add e
	ld e,a
	jr nc,.noCarry2
	inc d
.noCarry2
	ld hl,$c20d
	ld a,SPRITE_RED
	ld [hl],a
	ld bc,W_SPRITESET
; Load the sprite set into RAM.
; This loop also fills $C2XD (sprite picture ID) where X is from $0 to $A
; with picture ID's. This is done so that LoadMapSpriteTilePatterns will
; load tile patterns for all sprite pictures in the sprite set.
.loadSpriteSetLoop
	ld a,$10
	add l
	ld l,a
	ld a,[de] ; sprite picture ID from sprite set
	ld [hl],a ; $C2XD (sprite picture ID)
	ld [bc],a
	inc de
	inc bc
	ld a,l
	cp a,$bd ; reached 11th sprite slot?
	jr nz,.loadSpriteSetLoop
	ld b,4 ; 4 remaining sprite slots
.zeroRemainingSlotsLoop ; loop to zero the picture ID's of the remaining sprite slots
	ld a,$10
	add l
	ld l,a
	xor a
	ld [hl],a ; $C2XD (sprite picture ID)
	dec b
	jr nz,.zeroRemainingSlotsLoop
	ld a,[W_NUMSPRITES]
	push af ; save number of sprites
	ld a,11 ; 11 sprites in sprite set
	ld [W_NUMSPRITES],a
	call LoadMapSpriteTilePatterns
	pop af
	ld [W_NUMSPRITES],a ; restore number of sprites
	ld hl,$c21e
	ld b,$0f
; The VRAM tile pattern slots that LoadMapSpriteTilePatterns set are in the
; order of the map's sprite set, not the order of the actual sprites loaded
; for the current map. So, they are not needed and are zeroed by this loop.
.zeroVRAMSlotsLoop
	xor a
	ld [hl],a ; $C2XE (VRAM slot)
	ld a,$10
	add l
	ld l,a
	dec b
	jr nz,.zeroVRAMSlotsLoop
.skipLoadingSpriteSet
	ld hl,$c110
; This loop stores the correct VRAM tile pattern slots according the sprite
; data from the map's header. Since the VRAM tile pattern slots are filled in
; the order of the sprite set, in order to find the VRAM tile pattern slot
; for a sprite slot, the picture ID for the sprite is looked up within the
; sprite set. The index of the picture ID within the sprite set plus one
; (since the Red sprite always has the first VRAM tile pattern slot) is the
; VRAM tile pattern slot.
.storeVRAMSlotsLoop
	ld c,0
	ld a,[hl] ; $C1X0 (picture ID) (zero if sprite slot is not used)
	and a ; is the sprite slot used?
	jr z,.skipGettingPictureIndex ; if the sprite slot is not used
	ld b,a ; b = picture ID
	ld de,W_SPRITESET
; Loop to find the index of the sprite's picture ID within the sprite set.
.getPictureIndexLoop
	inc c
	ld a,[de]
	inc de
	cp b ; does the picture ID match?
	jr nz,.getPictureIndexLoop
	inc c
.skipGettingPictureIndex
	push hl
	inc h
	ld a,$0e
	add l
	ld l,a
	ld a,c ; a = VRAM slot (zero if sprite slot is not used)
	ld [hl],a ; $C2XE (VRAM slot)
	pop hl
	ld a,$10
	add l
	ld l,a
	and a
	jr nz,.storeVRAMSlotsLoop
	scf
	ret

; Chooses the correct sprite set ID depending on the player's position within
; the map for maps with two sprite sets.
GetSplitMapSpriteSetID: ; 17a1a (5:7a1a)
	cp a,$f8
	jr z,.route20
	ld hl,SplitMapSpriteSets
	and a,$0f
	dec a
	sla a
	sla a
	add l
	ld l,a
	jr nc,.noCarry
	inc h
.noCarry
	ld a,[hli] ; determines whether the map is split East/West or North/South
	cp a,$01
	ld a,[hli] ; position of dividing line
	ld b,a
	jr z,.eastWestDivide
.northSouthDivide
	ld a,[W_YCOORD]
	jr .compareCoord
.eastWestDivide
	ld a,[W_XCOORD]
.compareCoord
	cp b
	jr c,.loadSpriteSetID
; if in the East side or South side
	inc hl
.loadSpriteSetID
	ld a,[hl]
	ret
; Uses sprite set $01 for West side and $0A for East side.
; Route 20 is a special case because the two map sections have a more complex
; shape instead of the map simply being split horizontally or vertically.
.route20
	ld hl,W_XCOORD
	ld a,[hl]
	cp a,$2b
	ld a,$01
	ret c
	ld a,[hl]
	cp a,$3e
	ld a,$0a
	ret nc
	ld a,[hl]
	cp a,$37
	ld b,$08
	jr nc,.next
	ld b,$0d
.next
	ld a,[W_YCOORD]
	cp b
	ld a,$0a
	ret c
	ld a,$01
	ret

INCLUDE "data/sprite_sets.asm"

PrintEmotionBubble: ; 17c47 (5:7c47)
	ld a, [$cd50]
	ld c, a
	ld b, $0
	ld hl, EmotionBubblesPointerTable ; $7caf
	add hl, bc
	add hl, bc
	ld e, [hl]
	inc hl
	ld d, [hl]
	ld hl, $8f80
	ld bc, (BANK(EmotionBubblesPointerTable) << 8) + $04
	call CopyVideoData
	ld a, [$cfcb]
	push af
	ld a, $ff
	ld [$cfcb], a
	ld a, [$d736]
	bit 6, a
	ld hl, $c38f
	ld de, $c39f
	jr z, .asm_17c7a
	ld hl, $c37f
	ld de, $c38f
.asm_17c7a
	ld bc, $90
.asm_17c7d
	ld a, [hl]
	ld [de], a
	dec hl
	dec de
	dec bc
	ld a, c
	or b
	jr nz, .asm_17c7d
	ld hl, $c104
	ld a, [$cd4f]
	swap a
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hli]
	ld b, a
	inc hl
	ld a, [hl]
	add $8
	ld c, a
	ld de, EmotionBubblesOAM ; $7cb5
	xor a
	call WriteOAMBlock
	ld c, $3c
	call DelayFrames
	pop af
	ld [$cfcb], a
	call DelayFrame
	jp UpdateSprites

EmotionBubblesPointerTable: ; 17caf (5:7caf)
	dw EmotionBubbles
	dw EmotionBubbles + $40
	dw EmotionBubbles + $80

EmotionBubblesOAM: ; 17cb5 (5:7cb5)
	db $F8,$00,$F9,$00
	db $FA,$00,$FB,$00

EmotionBubbles: ; 17cbd (5:7cbd)
	INCBIN "gfx/emotion_bubbles.w16.2bpp"

EvolveTradeMon: ; 17d7d (5:7d7d)
; Verify the TradeMon's species name before
; attempting to initiate a trade evolution.

; The names of the trade evolutions in Blue (JP)
; are checked. In that version, TradeMons that
; can evolve are Graveler and Haunter.

; In localization, this check was translated
; before monster names were finalized.
; Then, Haunter's name was "Spectre".
; Since its name no longer starts with
; "SP", it is prevented from evolving.

; This may have been why Red/Green's trades
; were used instead, where none can evolve.

; This was fixed in Yellow.

	ld a, [wTradeMonNick]

	; GRAVELER
	cp "G"
	jr z, .ok

	; "SPECTRE" (HAUNTER)
	cp "S"
	ret nz
	ld a, [wTradeMonNick + 1]
	cp "P"
	ret nz

.ok
	ld a, [W_NUMINPARTY] ; $d163
	dec a
	ld [wWhichPokemon], a ; $cf92
	ld a, $1
	ld [$ccd4], a
	ld a, $32
	ld [W_ISLINKBATTLE], a ; $d12b
	callab Func_3ad0e
	xor a
	ld [W_ISLINKBATTLE], a ; $d12b
	jp Func_2307

SubstituteEffectHandler: ; 17dad (5:7dad)
	ld c, 50
	call DelayFrames
	ld hl, W_PLAYERMONMAXHP
	ld de, wPlayerSubstituteHP
	ld bc, W_PLAYERBATTSTATUS2
	ld a, [$fff3]  ;whose turn?
	and a
	jr z, .notEnemy
	ld hl, W_ENEMYMONMAXHP
	ld de, wEnemySubstituteHP
	ld bc, W_ENEMYBATTSTATUS2
.notEnemy
	ld a, [bc]                    ;load flags
	bit 4, a                      ;user already has substitute?
	jr nz, .alreadyHasSubstitute  ;skip this code if so
	                              ;user doesn't have a substitute [yet]
	push bc
	ld a, [hli]  ;load max hp
	ld b, [hl]
	srl a        ;max hp / 4, [quarter health to remove from user]
	rr b
	srl a
	rr b
	push de
	ld de, $fff2  ;subtract 8 to point to [current hp] instead of [max hp]
	add hl, de    ;HL -= 8
	pop de
	ld a, b
	ld [de], a    ;save copy of HP to subtract in ccd7/ccd8 [how much HP substitute has]
	ld a, [hld]   ;load current hp
	sub b         ;subtract [max hp / 4]
	ld d, a       ;save low byte result in D
	ld a, [hl]
	sbc a, 0      ;borrow from high byte if needed
	pop bc
	jr c, .notEnoughHP  ;underflow means user would be left with negative health
                        ;bug: note since it only brances on carry, it will possibly leave user with 0HP
.userHasZeroOrMoreHP
	ldi [hl], a  ;store high byte HP
	ld [hl], d   ;store low byte HP
	ld h, b
	ld l, c
	set 4, [hl]    ;set bit 4 of flags, user now has substitute
	ld a, [$d355]  ;load options
	bit 7, a       ;battle animation is enabled?
	ld hl, Func_3fba8    ; $7ba8 ;animation enabled: 0F:7BA8
	ld b, BANK(Func_3fba8)
	jr z, .animationEnabled
	ld hl, AnimationSubstitute   ;animation disabled: 1E:56E0
	ld b, BANK(AnimationSubstitute)
.animationEnabled
	call Bankswitch           ;jump to routine depending on animation setting
	ld hl, SubstituteText
	call PrintText
	ld hl, Func_3cd5a
	ld b, BANK(Func_3cd5a)
	jp Bankswitch
.alreadyHasSubstitute
	ld hl, HasSubstituteText
	jr .printText
.notEnoughHP
	ld hl, TooWeakSubstituteText
.printText
	jp PrintText

SubstituteText: ; 17e1d (5:7e1d)
	TX_FAR _SubstituteText
	db "@"

HasSubstituteText: ; 17e22 (5:7e22)
	TX_FAR _HasSubstituteText
	db "@"

TooWeakSubstituteText: ; 17e27 (5:7e27)
	TX_FAR _TooWeakSubstituteText
	db "@"

ActivatePC: ; 17e2c (5:7e2c)
	call SaveScreenTilesToBuffer2  ;XXX: copy background from wTileMap to wTileMapBackup2
	ld a, (SFX_02_45 - SFX_Headers_02) / 3
	call PlaySound  ;XXX: play sound or stop music
	ld hl, TurnedOnPC1Text
	call PrintText
	call WaitForSoundToFinish  ;XXX: wait for sound to be done
	ld hl, wFlags_0xcd60
	set 3, [hl]
	call LoadScreenTilesFromBuffer2  ;XXX: restore saved screen
	call Delay3
PCMainMenu: ; 17e48 (5:7e48)
	callba Func_213c8
	ld hl, wFlags_0xcd60
	set 5, [hl]
	call HandleMenuInput
	bit 1, a              ;if player pressed B
	jp nz, LogOff
	ld a, [wMaxMenuItem]
	cp a, 2
	jr nz, .next ;if not 2 menu items (not counting log off) (2 occurs before you get the pokedex)
	ld a, [wCurrentMenuItem]
	and a
	jp z, BillsPC    ;if current menu item id is 0, it's bills pc
	cp a, 1
	jr z, .playersPC ;if current menu item id is 1, it's players pc
	jp LogOff        ;otherwise, it's 2, and you're logging off
.next
	cp a, 3
	jr nz, .next2 ;if not 3 menu items (not counting log off) (3 occurs after you get the pokedex, before you beat the pokemon league)
	ld a, [wCurrentMenuItem]
	and a
	jp z, BillsPC    ;if current menu item id is 0, it's bills pc
	cp a, 1
	jr z, .playersPC ;if current menu item id is 1, it's players pc
	cp a, 2
	jp z, OaksPC     ;if current menu item id is 2, it's oaks pc
	jp LogOff        ;otherwise, it's 3, and you're logging off
.next2
	ld a, [wCurrentMenuItem]
	and a
	jp z, BillsPC    ;if current menu item id is 0, it's bills pc
	cp a, 1
	jr z, .playersPC ;if current menu item id is 1, it's players pc
	cp a, 2
	jp z, OaksPC     ;if current menu item id is 2, it's oaks pc
	cp a, 3
	jp z, PKMNLeague ;if current menu item id is 3, it's pkmnleague
	jp LogOff        ;otherwise, it's 4, and you're logging off
.playersPC
	ld hl, wFlags_0xcd60
	res 5, [hl]
	set 3, [hl]
	ld a, (SFX_02_47 - SFX_Headers_02) / 3
	call PlaySound  ;XXX: play sound or stop music
	call WaitForSoundToFinish  ;XXX: wait for sound to be done
	ld hl, AccessedMyPCText
	call PrintText
	callba PlayerPC
	jr ReloadMainMenu
OaksPC: ; 17ec0 (5:7ec0)
	ld a, (SFX_02_47 - SFX_Headers_02) / 3
	call PlaySound  ;XXX: play sound or stop music
	call WaitForSoundToFinish  ;XXX: wait for sound to be done
	callba Func_1e915
	jr ReloadMainMenu
PKMNLeague: ; 17ed2 (5:7ed2)
	ld a, (SFX_02_47 - SFX_Headers_02) / 3
	call PlaySound  ;XXX: play sound or stop music
	call WaitForSoundToFinish  ;XXX: wait for sound to be done
	callba PKMNLeaguePC
	jr ReloadMainMenu
BillsPC: ; 17ee4 (5:7ee4)
	ld a, (SFX_02_47 - SFX_Headers_02) / 3
	call PlaySound    ;XXX: play sound or stop music
	call WaitForSoundToFinish    ;XXX: wait for sound to be done
	ld a, [$D7F1] ;has to do with having met Bill
	bit 0, a
	jr nz, .billsPC ;if you've met bill, use that bill's instead of someone's
	ld hl, AccessedSomeonesPCText
	jr .printText
.billsPC
	ld hl, AccessedBillsPCText
.printText
	call PrintText
	callba BillsPC_
ReloadMainMenu: ; 17f06 (5:7f06)
	xor a
	ld [$CC3C], a
	call ReloadMapData
	call UpdateSprites  ;XXX: moves sprites
	jp PCMainMenu
LogOff: ; 17f13 (5:7f13)
	ld a, (SFX_02_46 - SFX_Headers_02) / 3
	call PlaySound  ;XXX: play sound or stop music
	call WaitForSoundToFinish  ;XXX: wait for sound to be done
	ld hl, wFlags_0xcd60
	res 3, [hl]
	res 5, [hl]
	ret

TurnedOnPC1Text: ; 17f23 (5:7f23)
	TX_FAR _TurnedOnPC1Text
	db "@"

AccessedBillsPCText: ; 17f28 (5:7f28)
	TX_FAR _AccessedBillsPCText
	db "@"

AccessedSomeonesPCText: ; 17f2d (5:7f2d)
	TX_FAR _AccessedSomeonesPCText
	db "@"

AccessedMyPCText: ; 17f32 (5:7f32)
	TX_FAR _AccessedMyPCText
	db "@"

; removes one of the specified item ID [$FFdb] from bag (if existent)
RemoveItemByID: ; 17f37 (5:7f37)
	ld hl, wBagItems ; $d31e
	ld a, [$ffdb]
	ld b, a
	xor a
	ld [$ffdc], a
.asm_17f40
	ld a, [hli]
	cp $ff
	ret z
	cp b
	jr z, .asm_17f4f
	inc hl
	ld a, [$ffdc]
	inc a
	ld [$ffdc], a
	jr .asm_17f40
.asm_17f4f
	ld a, $1
	ld [$cf96], a
	ld a, [$ffdc]
	ld [wWhichPokemon], a ; $cf92
	ld hl, wNumBagItems ; $d31d
	jp RemoveItemFromInventory

SECTION "bank6",ROMX,BANK[$6]

INCLUDE "data/mapHeaders/celadoncity.asm"

INCLUDE "data/mapObjects/celadoncity.asm"

CeladonCityBlocks: ; 180df (6:40df)
	INCBIN "maps/celadoncity.blk"

INCLUDE "data/mapHeaders/pallettown.asm"

INCLUDE "data/mapObjects/pallettown.asm"

PalletTownBlocks: ; 182fd (6:42fd)
	INCBIN "maps/pallettown.blk"

INCLUDE "data/mapHeaders/viridiancity.asm"

INCLUDE "data/mapObjects/viridiancity.asm"

ViridianCityBlocks: ; 183ec (6:43ec)
	INCBIN "maps/viridiancity.blk"

INCLUDE "data/mapHeaders/pewtercity.asm"

INCLUDE "data/mapObjects/pewtercity.asm"

PewterCityBlocks: ; 185e6 (6:45e6)
	INCBIN "maps/pewtercity.blk"

INCLUDE "data/mapHeaders/ceruleancity.asm"

INCLUDE "data/mapObjects/ceruleancity.asm"

CeruleanCityBlocks: ; 18830 (6:4830)
	INCBIN "maps/ceruleancity.blk"

INCLUDE "data/mapHeaders/vermilioncity.asm"

INCLUDE "data/mapObjects/vermilioncity.asm"

VermilionCityBlocks: ; 18a3f (6:4a3f)
	INCBIN "maps/vermilioncity.blk"

INCLUDE "data/mapHeaders/fuchsiacity.asm"

INCLUDE "data/mapObjects/fuchsiacity.asm"

FuchsiaCityBlocks: ; 18c86 (6:4c86)
	INCBIN "maps/fuchsiacity.blk"

Func_18dee: ; 18dee (6:4dee)
	call Func_18e36
	ld a, [$d732]
	bit 0, a
	ret z
	ld a, [W_PLAYTIMEMINUTES] ; $da42
	and a
	ret nz
	ld a, [W_PLAYTIMEFRAMES] ; $da45
	inc a
	ld [W_PLAYTIMEFRAMES], a ; $da45
	cp $3c
	ret nz
	xor a
	ld [W_PLAYTIMEFRAMES], a ; $da45
	ld a, [W_PLAYTIMESECONDS] ; $da44
	inc a
	ld [W_PLAYTIMESECONDS], a ; $da44
	cp $3c
	ret nz
	xor a
	ld [W_PLAYTIMESECONDS], a ; $da44
	ld a, [$da43]
	inc a
	ld [$da43], a
	cp $3c
	ret nz
	xor a
	ld [$da43], a
	ld a, [$da41]
	inc a
	ld [$da41], a
	cp $ff
	ret nz
	ld a, $ff
	ld [W_PLAYTIMEMINUTES], a ; $da42
	ret

Func_18e36: ; 18e36 (6:4e36)
	ld a, [$d13a]
	and a
	jr nz, .asm_18e40
	ld a, $ff
	jr .asm_18e41
.asm_18e40
	dec a
.asm_18e41
	ld [$d13a], a
	and a
	ret nz
	ld a, [$d730]
	res 1, a
	res 2, a
	bit 5, a
	res 5, a
	ld [$d730], a
	ret z
	xor a
	ld [H_NEWLYPRESSEDBUTTONS], a
	ld [H_CURRENTPRESSEDBUTTONS], a
	ret

INCLUDE "scripts/pallettown.asm"

INCLUDE "scripts/viridiancity.asm"

INCLUDE "scripts/pewtercity.asm"

INCLUDE "scripts/ceruleancity.asm"

INCLUDE "scripts/vermilioncity.asm"

INCLUDE "scripts/celadoncity.asm"

INCLUDE "scripts/fuchsiacity.asm"

INCLUDE "data/mapHeaders/blueshouse.asm"

INCLUDE "scripts/blueshouse.asm"

INCLUDE "data/mapObjects/blueshouse.asm"

BluesHouseBlocks: ; 19bf6 (6:5bf6)
	INCBIN "maps/blueshouse.blk"

INCLUDE "data/mapHeaders/vermilionhouse3.asm"

INCLUDE "scripts/vermilionhouse3.asm"

INCLUDE "data/mapObjects/vermilionhouse3.asm"

VermilionHouse3Blocks: ; 19c3f (6:5c3f)
	INCBIN "maps/vermilionhouse3.blk"

INCLUDE "data/mapHeaders/indigoplateaulobby.asm"

INCLUDE "scripts/indigoplateaulobby.asm"

INCLUDE "data/mapObjects/indigoplateaulobby.asm"

IndigoPlateauLobbyBlocks: ; 19ccf (6:5ccf)
	INCBIN "maps/indigoplateaulobby.blk"

INCLUDE "data/mapHeaders/silphco4.asm"

INCLUDE "scripts/silphco4.asm"

INCLUDE "data/mapObjects/silphco4.asm"

SilphCo4Blocks: ; 19ea4 (6:5ea4)
	INCBIN "maps/silphco4.blk"

INCLUDE "data/mapHeaders/silphco5.asm"

INCLUDE "scripts/silphco5.asm"

INCLUDE "data/mapObjects/silphco5.asm"

SilphCo5Blocks: ; 1a116 (6:6116)
	INCBIN "maps/silphco5.blk"

INCLUDE "data/mapHeaders/silphco6.asm"

INCLUDE "scripts/silphco6.asm"

INCLUDE "data/mapObjects/silphco6.asm"

SilphCo6Blocks: ; 1a36b (6:636b)
	INCBIN "maps/silphco6.blk"

Func_1a3e0: ; 1a3e0 (6:63e0)
	ld hl, $d730
	res 1, [hl]
	call Func_1a609
	jr nc, .asm_1a406
	ld a, $fc
	ld [wJoypadForbiddenButtonsMask], a
	ld hl, $d736
	set 1, [hl]
	ld a, $1
	ld [$cd38], a
	ld a, $80
	ld [$ccd3], a
	xor a
	ld [$c102], a
	call Func_3486
	ret
.asm_1a406
	xor a
	ld [$cd3a], a
	ld [$cd38], a
	ld [$ccd3], a
	ld hl, $d736
	res 0, [hl]
	res 1, [hl]
	ld hl, $d730
	res 7, [hl]
	ret

Func_1a41d: ; 1a41d (6:641d)
	ld hl, $d730
	res 7, [hl]
	ld hl, $d72e
	res 7, [hl]
	ld hl, $d736
	res 0, [hl]
	res 1, [hl]
	xor a
	ld [$cf17], a
	ld [$cc57], a
	ld [$cf10], a
	ld [$cd3a], a
	ld [$cd38], a
	ld [$ccd3], a
	ret

PointerTable_1a442: ; 1a442 (6:6442)
	dw Func_1a44c
	dw Func_1a485
	dw Func_1a4a1
	dw Func_1a4a6
	dw Func_1a4f4

Func_1a44c: ; 1a44c (6:644c)
	ld a, [W_XCOORD] ; $d362
	sub $a
	ld [$cca1], a
	jr z, .asm_1a475
	ld b, $0
	ld c, a
	ld hl, $cc97
	ld a, $80
	call FillMemory
	ld [hl], $ff
	ld a, [$cf13]
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	ld de, $cc97
	call MoveSprite
	ld a, $1
	ld [$cf10], a
	jr .asm_1a47a
.asm_1a475
	ld a, $3
	ld [$cf10], a
.asm_1a47a
	ld hl, W_FLAGS_D733
	set 1, [hl]
	ld a, $fc
	ld [wJoypadForbiddenButtonsMask], a
	ret

Func_1a485: ; 1a485 (6:6485)
	ld a, [$d730]
	bit 0, a
	ret nz
	ld a, [$cca1]
	ld [$cd38], a
	ld [$ff95], a
	ld a, $23
	call Predef
	call Func_3486
	ld a, $2
	ld [$cf10], a
	ret

Func_1a4a1: ; 1a4a1 (6:64a1)
	ld a, [$cd38]
	and a
	ret nz

Func_1a4a6: ; 1a4a6 (6:64a6)
	xor a
	ld [$cd3b], a
	ld a, [$cf13]
	swap a
	ld [$cf17], a
	xor a
	ld [$c206], a
	ld hl, $ccd3
	ld de, RLEList_1a4e9
	call DecodeRLEList
	dec a
	ld [$cd38], a
	ld hl, $cc97
	ld de, RLEList_1a4dc
	call DecodeRLEList
	ld hl, $d72e
	res 7, [hl]
	ld hl, $d730
	set 7, [hl]
	ld a, $4
	ld [$cf10], a
	ret

RLEList_1a4dc: ; 1a4dc (6:64dc)
	db $00, $05
	db $80, $01
	db $00, $05
	db $C0, $03
	db $40, $01
	db $E0, $01
	db $FF

RLEList_1a4e9: ; 1a4e9 (6:64e9)
	db $40, $02
	db $10, $03
	db $80, $05
	db $20, $01
	db $80, $06
	db $FF

Func_1a4f4: ; 1a4f4 (6:64f4)
	ld a, [$cd38]
	and a
	ret nz
	ld a, $0
	ld [$cc4d], a
	ld a, $11
	call Predef ; indirect jump to RemoveMissableObject (f1d7 (3:71d7))
	ld hl, $d730
	res 7, [hl]
	ld hl, $d72e
	res 7, [hl]
	jp Func_314e

PointerTable_1a510: ; 1a510 (6:6510)
	dw Func_1a514
	dw Func_1a56b

Func_1a514: ; 1a514 (6:6514)
	ld a, Bank(Func_9876)
	ld [$c0ef], a
	ld [$c0f0], a
	ld a, MUSIC_MUSEUM_GUY
	ld [$c0ee], a
	call PlaySound
	ld a, [$cf13]
	swap a
	ld [$cf17], a
	call Func_3486
	ld hl, $ccd3
	ld de, RLEList_PewterMuseumPlayer
	call DecodeRLEList
	dec a
	ld [$cd38], a
	xor a
	ld [$d12f], a
	ld a, $4f
	call Predef
	ld hl, $cc97
	ld de, RLEList_PewterMuseumGuy
	call DecodeRLEList
	ld hl, $d72e
	res 7, [hl]
	ld a, $1
	ld [$cf10], a
	ret

RLEList_PewterMuseumPlayer: ; 1a559 (6:6559)
	db $00, $01
	db $40, $03
	db $20, $0D
	db $40, $06
	db $FF

RLEList_PewterMuseumGuy: ; 1a562 (6:6562)
	db $40, $06
	db $80, $0D
	db $40, $03
	db $80, $01
	db $FF

Func_1a56b: ; 1a56b (6:656b)
	ld a, [$cd38]
	and a
	ret nz
	ld hl, $d730
	res 7, [hl]
	ld hl, $d72e
	res 7, [hl]
	jp Func_314e

PointerTable_1a57d: ; 1a57d (6:657d)
	dw Func_1a581
	dw Func_1a56b

Func_1a581: ; 1a581 (6:6581)
	ld a, Bank(Func_9876)
	ld [$c0ef], a
	ld [$c0f0], a
	ld a, MUSIC_MUSEUM_GUY
	ld [$c0ee], a
	call PlaySound
	ld a, [$cf13]
	swap a
	ld [$cf17], a
	xor a
	ld [$c206], a
	ld hl, $ccd3
	ld de, RLEList_PewterGymPlayer
	call DecodeRLEList
	dec a
	ld [$cd38], a
	ld a, $1
	ld [$d12f], a
	ld a, $4f
	call Predef
	ld hl, $cc97
	ld de, RLEList_PewterGymGuy
	call DecodeRLEList
	ld hl, $d72e
	res 7, [hl]
	ld hl, $d730
	set 7, [hl]
	ld a, $1
	ld [$cf10], a
	ret

RLEList_PewterGymPlayer: ; 1a5cd (6:65cd)
	db $00, $01
	db $10, $02
	db $80, $05
	db $20, $0B
	db $40, $05
	db $20, $0F
	db $FF

RLEList_PewterGymGuy: ; 1a5da (6:65da)
	db $00, $02
	db $80, $0F
	db $40, $05
	db $80, $0B
	db $00, $05
	db $C0, $03
	db $FF

; XXX why would this function want to return on POKEMONTOWER_7?
Func_1a5e7: ; 1a5e7 (6:65e7)
	ld a, [W_CURMAP] ; $d35e
	cp POKEMONTOWER_7
	ret z
	ld hl, RivalIDs ; $6605
	ld a, [wEngagedTrainerClass]
	ld b, a
.loop
	ld a, [hli]
	cp $ff
	jr z, .notRival
	cp b
	ret z
	jr .loop
.notRival
	ld a, [$cf13]
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	jp SetSpriteMovementBytesToFF

RivalIDs: ; 1a605 (6:6605)
	db SONY1 + $c8
	db SONY2 + $c8
	db SONY3 + $c8
	db $ff

Func_1a609: ; 1a609 (6:6609)
	push de
	ld hl, DoorTileIDPointers ; $662c
	ld a, [W_CURMAPTILESET] ; $d367
	ld de, $3
	call IsInArray
	pop de
	jr nc, .asm_1a62a
	inc hl
	ld a, [hli]
	ld h, [hl]
	ld l, a
	FuncCoord 8, 9 ; $c45c
	ld a, [Coord]
	ld b, a
.asm_1a621
	ld a, [hli]
	and a
	jr z, .asm_1a62a
	cp b
	jr nz, .asm_1a621
	scf
	ret
.asm_1a62a
	and a
	ret

DoorTileIDPointers: ; 1a62c (6:662c)
	db OVERWORLD
	dw OverworldDoorTileIDs
	db FOREST
	dw ForestDoorTileIDs
	db MART
	dw MartDoorTileIDs
	db HOUSE
	dw HouseDoorTileIDs
	db FOREST_GATE
	dw TilesetMuseumDoorTileIDs
	db MUSEUM
	dw TilesetMuseumDoorTileIDs
	db GATE
	dw TilesetMuseumDoorTileIDs
	db SHIP
	dw ShipDoorTileIDs
	db LOBBY
	dw LobbyDoorTileIDs
	db MANSION
	dw MansionDoorTileIDs
	db LAB
	dw LabDoorTileIDs
	db FACILITY
	dw FacilityDoorTileIDs
	db PLATEAU
	dw PlateauDoorTileIDs
	db $ff

OverworldDoorTileIDs: ; 1a654 (6:6654)
	db $1B,$58,$00

ForestDoorTileIDs: ; 1a657 (6:6657)
	db $3a,$00

MartDoorTileIDs: ; 1a659 (6:6659)
	db $5e,$00

HouseDoorTileIDs: ; 1a65b (6:665b)
	db $54,$00

TilesetMuseumDoorTileIDs: ; 1a65d (6:665d)
	db $3b,$00

ShipDoorTileIDs: ; 1a65f (6:665f)
	db $1e,$00

LobbyDoorTileIDs: ; 1a661 (6:6661)
	db $1c,$38,$1a,$00

MansionDoorTileIDs: ; 1a665 (6:6665)
	db $1a,$1c,$53,$00

LabDoorTileIDs: ; 1a669 (6:6669)
	db $34,$00

FacilityDoorTileIDs: ; 1a66b (6:666b)
	db $43,$58,$1b,$00

PlateauDoorTileIDs: ; 1a66f (6:666f)
	db $3b,$1b,$00

Func_1a672: ; 1a672 (6:6672)
	ld a, [$d736]
	bit 6, a
	ret nz
	ld a, [W_CURMAPTILESET] ; $d367
	and a ; OVERWORLD
	ret nz
	ld a, $35
	call Predef ; indirect jump to Func_c586 (c586 (3:4586))
	ld a, [$c109]
	ld b, a
	FuncCoord 8, 9 ; $c45c
	ld a, [Coord]
	ld c, a
	ld a, [$cfc6]
	ld d, a
	ld hl, LedgeTiles ; $66cf
.asm_1a691
	ld a, [hli]
	cp $ff
	ret z
	cp b
	jr nz, .asm_1a6a4
	ld a, [hli]
	cp c
	jr nz, .asm_1a6a5
	ld a, [hli]
	cp d
	jr nz, .asm_1a6a6
	ld a, [hl]
	ld e, a
	jr .asm_1a6a9
.asm_1a6a4
	inc hl
.asm_1a6a5
	inc hl
.asm_1a6a6
	inc hl
	jr .asm_1a691
.asm_1a6a9
	ld a, [H_CURRENTPRESSEDBUTTONS]
	and e
	ret z
	ld a, $ff
	ld [wJoypadForbiddenButtonsMask], a
	ld hl, $d736
	set 6, [hl]
	call Func_3486
	ld a, e
	ld [$ccd3], a
	ld [$ccd4], a
	ld a, $2
	ld [$cd38], a
	call LoadHoppingShadowOAM
	ld a, (SFX_02_4e - SFX_Headers_02) / 3
	call PlaySound
	ret

	; (player direction) (tile player standing on) (ledge tile) (input required)
LedgeTiles: ; 1a6cf (6:66cf)
	db $00,$2C,$37,$80
	db $00,$39,$36,$80
	db $00,$39,$37,$80
	db $08,$2C,$27,$20
	db $08,$39,$27,$20
	db $0C,$2C,$0D,$10
	db $0C,$2C,$1D,$10
	db $0C,$39,$0D,$10
	db $FF

LoadHoppingShadowOAM: ; 1a6f0 (6:66f0)
	ld hl, $8ff0
	ld de, LedgeHoppingShadow ; $6708
	ld bc, (BANK(LedgeHoppingShadow) << 8) + $01
	call CopyVideoDataDouble
	ld a, $9
	ld bc, $5448 ; b, c = y, x coordinates of shadow
	ld de, LedgeHoppingShadowOAM ; $6710
	call WriteOAMBlock
	ret

LedgeHoppingShadow: ; 1a708 (6:6708)
	INCBIN "gfx/ledge_hopping_shadow.1bpp"

LedgeHoppingShadowOAM: ; 1a710 (6:6710)
	db $FF,$10,$FF,$20
	db $FF,$40,$FF,$60

SECTION "bank7",ROMX,BANK[$7]

INCLUDE "data/mapHeaders/cinnabarisland.asm"

INCLUDE "data/mapObjects/cinnabarisland.asm"

CinnabarIslandBlocks: ; 1c069 (7:4069)
	INCBIN "maps/cinnabarisland.blk"

INCLUDE "data/mapHeaders/route1.asm"

INCLUDE "data/mapObjects/route1.asm"

Route1Blocks: ; 1c0fc (7:40fc)
	INCBIN "maps/route1.blk"

UndergroundPathEntranceRoute8Blocks: ; 1c1b0 (7:41b0)
	INCBIN "maps/undergroundpathentranceroute8.blk"

OaksLabBlocks: ; 1c1c0 (7:41c0)
	INCBIN "maps/oakslab.blk"

Route16HouseBlocks: ; 1c1de (7:41de)
Route2HouseBlocks: ; 1c1de (7:41de)
SaffronHouse1Blocks: ; 1c1de (7:41de)
SaffronHouse2Blocks: ; 1c1de (7:41de)
VermilionHouse1Blocks: ; 1c1de (7:41de)
NameRaterBlocks: ; 1c1de (7:41de)
LavenderHouse1Blocks: ; 1c1de (7:41de)
LavenderHouse2Blocks: ; 1c1de (7:41de)
CeruleanHouse1Blocks: ; 1c1de (7:41de)
PewterHouse1Blocks: ; 1c1de (7:41de)
PewterHouse2Blocks: ; 1c1de (7:41de)
ViridianHouseBlocks: ; 0x1c1de 41DE size=16
	INCBIN "maps/viridianhouse.blk"

CeladonMansion5Blocks: ; 1c1ee (7:41ee)
SchoolBlocks: ; 0x1c1ee 41EE size=16
	INCBIN "maps/school.blk"

CeruleanHouseTrashedBlocks: ; 0x1c1fe size=16
	INCBIN "maps/ceruleanhousetrashed.blk"

DiglettsCaveEntranceRoute11Blocks: ; 1c20e (7:420e)
DiglettsCaveRoute2Blocks: ; 0x1c20e size=16
	INCBIN "maps/diglettscaveroute2.blk"

INCLUDE "text/monster_names.asm"

Func_1c98a: ; 1c98a (7:498a)
	call ClearScreen
	call GoPAL_SET_CF1C
	call LoadFontTilePatterns
	call LoadTextBoxTilePatterns
	ld hl, ClearSaveDataText
	call PrintText
	FuncCoord 14, 7 ; $c43a
	ld hl, Coord
	ld bc, $80f
	ld a, $7
	ld [$d12c], a
	ld a, $14
	ld [$d125], a
	call DisplayTextBoxID
	ld a, [wCurrentMenuItem] ; $cc26
	and a
	jp z, InitGame
	callba Func_73b6a
	jp InitGame

ClearSaveDataText: ; 1c9c1 (7:49c1)
	TX_FAR _ClearSaveDataText
	db "@"

Func_1c9c6: ; 1c9c6 (7:49c6)
	ld hl, WhichFloorText
	call PrintText
	ld hl, $cf7b
	ld a, l
	ld [$cf8b], a
	ld a, h
	ld [$cf8c], a
	ld a, [wListScrollOffset] ; $cc36
	push af
	xor a
	ld [wCurrentMenuItem], a ; $cc26
	ld [wListScrollOffset], a ; $cc36
	ld [$cf93], a
	ld a, $4
	ld [wListMenuID], a ; $cf94
	call DisplayListMenuID
	pop bc
	ld a, b
	ld [wListScrollOffset], a ; $cc36
	ret c
	ld hl, $d126
	set 7, [hl]
	ld hl, $cc5b
	ld a, [wWhichPokemon] ; $cf92
	add a
	ld d, $0
	ld e, a
	add hl, de
	ld a, [hli]
	ld b, a
	ld a, [hl]
	ld c, a
	ld hl, $d3af
	call Func_1ca0d

Func_1ca0d: ; 1ca0d (7:4a0d)
	inc hl
	inc hl
	ld a, b
	ld [hli], a
	ld a, c
	ld [hli], a
	ret

WhichFloorText: ; 1ca14 (7:4a14)
	TX_FAR _WhichFloorText
	db "@"

INCLUDE "scripts/cinnabarisland.asm"

INCLUDE "scripts/route1.asm"

INCLUDE "data/mapHeaders/oakslab.asm"

INCLUDE "scripts/oakslab.asm"

INCLUDE "data/mapObjects/oakslab.asm"

INCLUDE "data/mapHeaders/viridianmart.asm"

INCLUDE "scripts/viridianmart.asm"

INCLUDE "data/mapObjects/viridianmart.asm"

ViridianMartBlocks: ; 1d530 (7:5530)
	INCBIN "maps/viridianmart.blk"

INCLUDE "data/mapHeaders/school.asm"

INCLUDE "scripts/school.asm"

INCLUDE "data/mapObjects/school.asm"

INCLUDE "data/mapHeaders/viridianhouse.asm"

INCLUDE "scripts/viridianhouse.asm"

INCLUDE "data/mapObjects/viridianhouse.asm"

INCLUDE "data/mapHeaders/pewterhouse1.asm"

INCLUDE "scripts/pewterhouse1.asm"

INCLUDE "data/mapObjects/pewterhouse1.asm"

INCLUDE "data/mapHeaders/pewterhouse2.asm"

INCLUDE "scripts/pewterhouse2.asm"

INCLUDE "data/mapObjects/pewterhouse2.asm"

INCLUDE "data/mapHeaders/ceruleanhousetrashed.asm"

INCLUDE "scripts/ceruleanhousetrashed.asm"

INCLUDE "data/mapObjects/ceruleanhousetrashed.asm"

INCLUDE "data/mapHeaders/ceruleanhouse1.asm"

INCLUDE "scripts/ceruleanhouse1.asm"

INCLUDE "data/mapObjects/ceruleanhouse1.asm"

INCLUDE "data/mapHeaders/bikeshop.asm"

INCLUDE "scripts/bikeshop.asm"

INCLUDE "data/mapObjects/bikeshop.asm"

BikeShopBlocks: ; 1d88c (7:588c)
	INCBIN "maps/bikeshop.blk"

INCLUDE "data/mapHeaders/lavenderhouse1.asm"

INCLUDE "scripts/lavenderhouse1.asm"

INCLUDE "data/mapObjects/lavenderhouse1.asm"

INCLUDE "data/mapHeaders/lavenderhouse2.asm"

INCLUDE "scripts/lavenderhouse2.asm"

INCLUDE "data/mapObjects/lavenderhouse2.asm"

INCLUDE "data/mapHeaders/namerater.asm"

INCLUDE "scripts/namerater.asm"

INCLUDE "data/mapObjects/namerater.asm"

INCLUDE "data/mapHeaders/vermilionhouse1.asm"

INCLUDE "scripts/vermilionhouse1.asm"

INCLUDE "data/mapObjects/vermilionhouse1.asm"

INCLUDE "data/mapHeaders/vermiliondock.asm"

INCLUDE "scripts/vermiliondock.asm"

INCLUDE "data/mapObjects/vermiliondock.asm"

VermilionDockBlocks: ; 1dcda (7:5cda)
	INCBIN "maps/vermiliondock.blk"

INCLUDE "data/mapHeaders/celadonmansion5.asm"

INCLUDE "scripts/celadonmansion5.asm"

INCLUDE "data/mapObjects/celadonmansion5.asm"

INCLUDE "data/mapHeaders/fuchsiamart.asm"

INCLUDE "scripts/fuchsiamart.asm"

INCLUDE "data/mapObjects/fuchsiamart.asm"

FuchsiaMartBlocks: ; 1ddc1 (7:5dc1)
	INCBIN "maps/fuchsiamart.blk"

INCLUDE "data/mapHeaders/saffronhouse1.asm"

INCLUDE "scripts/saffronhouse1.asm"

INCLUDE "data/mapObjects/saffronhouse1.asm"

INCLUDE "data/mapHeaders/saffronhouse2.asm"

INCLUDE "scripts/saffronhouse2.asm"

INCLUDE "data/mapObjects/saffronhouse2.asm"

INCLUDE "data/mapHeaders/diglettscaveroute2.asm"

INCLUDE "scripts/diglettscaveroute2.asm"

INCLUDE "data/mapObjects/diglettscaveroute2.asm"

INCLUDE "data/mapHeaders/route2house.asm"

INCLUDE "scripts/route2house.asm"

INCLUDE "data/mapObjects/route2house.asm"

INCLUDE "data/mapHeaders/route5gate.asm"

INCLUDE "scripts/route5gate.asm"

INCLUDE "data/mapObjects/route5gate.asm"

Route5GateBlocks: ; 1e025 (7:6025)
	INCBIN "maps/route5gate.blk"

INCLUDE "data/mapHeaders/route6gate.asm"

INCLUDE "scripts/route6gate.asm"

INCLUDE "data/mapObjects/route6gate.asm"

Route6GateBlocks: ; 1e0e8 (7:60e8)
	INCBIN "maps/route6gate.blk"

INCLUDE "data/mapHeaders/route7gate.asm"

INCLUDE "scripts/route7gate.asm"

INCLUDE "data/mapObjects/route7gate.asm"

Route7GateBlocks: ; 1e1af (7:61af)
	INCBIN "maps/route7gate.blk"

INCLUDE "data/mapHeaders/route8gate.asm"

INCLUDE "scripts/route8gate.asm"

INCLUDE "data/mapObjects/route8gate.asm"

Route8GateBlocks: ; 1e271 (7:6271)
	INCBIN "maps/route8gate.blk"

INCLUDE "data/mapHeaders/undergroundpathentranceroute8.asm"

INCLUDE "scripts/undergroundpathentranceroute8.asm"

INCLUDE "data/mapObjects/undergroundpathentranceroute8.asm"

INCLUDE "data/mapHeaders/powerplant.asm"

INCLUDE "scripts/powerplant.asm"

INCLUDE "data/mapObjects/powerplant.asm"

PowerPlantBlocks: ; 1e446 (7:6446)
	INCBIN "maps/powerplant.blk"

INCLUDE "data/mapHeaders/diglettscaveroute11.asm"

INCLUDE "scripts/diglettscaveroute11.asm"

INCLUDE "data/mapObjects/diglettscaveroute11.asm"

INCLUDE "data/mapHeaders/route16house.asm"

INCLUDE "scripts/route16house.asm"

INCLUDE "data/mapObjects/route16house.asm"

INCLUDE "data/mapHeaders/route22gate.asm"

INCLUDE "scripts/route22gate.asm"

INCLUDE "data/mapObjects/route22gate.asm"

Route22GateBlocks: ; 1e74a (7:674a)
	INCBIN "maps/route22gate.blk"

INCLUDE "data/mapHeaders/billshouse.asm"

INCLUDE "scripts/billshouse.asm"

INCLUDE "data/mapObjects/billshouse.asm"

BillsHouseBlocks: ; 1e905 (7:6905)
	INCBIN "maps/billshouse.blk"

Func_1e915: ; 1e915 (7:6915)
	call SaveScreenTilesToBuffer2
	ld hl, AccessedOaksPCText
	call PrintText
	ld hl, GetDexRatedText
	call PrintText
	call YesNoChoice
	ld a, [wCurrentMenuItem] ; $cc26
	and a
	jr nz, .asm_1e932
	ld a, $56
	call Predef ; indirect jump to DisplayDexRating (44169 (11:4169))
.asm_1e932
	ld hl, ClosedOaksPCText
	call PrintText
	jp LoadScreenTilesFromBuffer2

GetDexRatedText: ; 1e93b (7:693b)
	TX_FAR _GetDexRatedText
	db "@"

ClosedOaksPCText: ; 1e940 (7:6940)
	TX_FAR _ClosedOaksPCText
	db $0d,"@"

AccessedOaksPCText: ; 1e946 (7:6946)
	TX_FAR _AccessedOaksPCText
	db "@"

Func_1e94b: ; 1e94b (7:694b)
	call EnableAutoTextBoxDrawing
	ld a, $39
	jp PrintPredefTextID

NewBicycleText: ; 1e953 (7:6953)
	TX_FAR _NewBicycleText
	db "@"

Func_1e958: ; 1e958 (7:6958)
	call EnableAutoTextBoxDrawing
	ld a, $05
	jp PrintPredefTextID

PushStartText: ; 1e960 (7:6960)
	TX_FAR _PushStartText
	db "@"

Func_1e965: ; 1e965 (7:6965)
	call EnableAutoTextBoxDrawing
	ld hl, wPokedexOwned
	ld b, wPokedexOwnedEnd - wPokedexOwned
	call CountSetBits
	ld a, [$d11e]
	cp $2
	ld a, $6
	jr c, .asm_1e97b
	ld a, $7
.asm_1e97b
	jp PrintPredefTextID

SaveOptionText: ; 1e97e (7:697e)
	TX_FAR _SaveOptionText
	db "@"

StrengthsAndWeaknessesText: ; 1e983 (7:6983)
	TX_FAR _StrengthsAndWeaknessesText
	db "@"

Func_1e988: ; 1e988 (7:6988)
	ld hl, $d790
	bit 7, [hl]
	jr z, asm_1e9ab
	ld a, [W_NUMSAFARIBALLS] ; $da47
	and a
	jr z, asm_1e9b0
	jr asm_1e9ab

Func_1e997: ; 1e997 (7:6997)
	ld a, [wSafariSteps] ; $d70d
	ld b, a
	ld a, [wSafariSteps + 1] ; $d70e
	ld c, a
	or b
	jr z, asm_1e9b0
	dec bc
	ld a, b
	ld [wSafariSteps], a ; $d70d
	ld a, c
	ld [wSafariSteps + 1], a ; $d70e
asm_1e9ab: ; 1e9ab (7:69ab)
	xor a
	ld [$da46], a
	ret
asm_1e9b0: ; 1e9b0 (7:69b0)
	call EnableAutoTextBoxDrawing
	xor a
	ld [wMusicHeaderPointer], a
	dec a
	call PlaySound
	ld c, BANK(SFX_02_5f)
	ld a, (SFX_02_5f - SFX_Headers_02) / 3
	call PlayMusic
.asm_1e9c2
	ld a, [$c02a]
	cp $b9
	jr nz, .asm_1e9c2
	ld a, $d3
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call DisplayTextID
	xor a
	ld [$d528], a
	ld a, $9c
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld a, $3
	ld [$d42f], a
	ld a, $5
	ld [W_SAFARIZONEENTRANCECURSCRIPT], a
	ld hl, $d790
	set 6, [hl]
	ld a, $1
	ld [$da46], a
	ret

Func_1e9ed: ; 1e9ed (7:69ed)
	xor a
	ld [wJoypadForbiddenButtonsMask], a
	ld hl, SafariGameOverText
	jp PrintText

SafariGameOverText: ; 1e9f7 (7:69f7)
	db $08 ; asm
	ld a, [W_NUMSAFARIBALLS] ; $da47
	and a
	jr z, .asm_1ea04
	ld hl, TimesUpText
	call PrintText
.asm_1ea04
	ld hl, GameOverText
	call PrintText
	jp TextScriptEnd

TimesUpText: ; 1ea0d (7:6a0d)
	TX_FAR _TimesUpText
	db "@"

GameOverText: ; 1ea12 (7:6a12)
	TX_FAR _GameOverText
	db "@"

Func_1eaa17: ; 1ea17 (7:6a17)
	ld a, [$c109]
	cp $4
	ret nz
	call EnableAutoTextBoxDrawing
	ld a, $31
	jp PrintPredefTextID

CinnabarGymQuiz: ; 1ea25 (7:6a25)
	db $08 ; asm
	xor a
	ld [$da38], a
	ld a, [wWhichTrade] ; $cd3d
	push af
	and $f
	ld [$ffdb], a
	pop af
	and $f0
	swap a
	ld [$ffdc], a
	ld hl, CinnabarGymQuizIntroText
	call PrintText
	ld a, [$ffdb]
	dec a
	add a
	ld d, $0
	ld e, a
	ld hl, CinnabarQuizQuestions
	add hl, de
	ld a, [hli]
	ld h, [hl]
	ld l, a
	call PrintText
	ld a, $1
	ld [$cc3c], a
	call Func_1ea92
	jp TextScriptEnd

CinnabarGymQuizIntroText: ; 1ea5b (7:6a5b)
	TX_FAR _CinnabarGymQuizIntroText
	db "@"

CinnabarQuizQuestions: ; 1ea60 (7:6a60)
	dw CinnabarQuizQuestionsText1
	dw CinnabarQuizQuestionsText2
	dw CinnabarQuizQuestionsText3
	dw CinnabarQuizQuestionsText4
	dw CinnabarQuizQuestionsText5
	dw CinnabarQuizQuestionsText6

CinnabarQuizQuestionsText1: ; 1ea6c (7:6a6c)
	TX_FAR _CinnabarQuizQuestionsText1
	db "@"

CinnabarQuizQuestionsText2: ; 1ea71 (7:6a71)
	TX_FAR _CinnabarQuizQuestionsText2
	db "@"

CinnabarQuizQuestionsText3: ; 1ea76 (7:6a76)
	TX_FAR _CinnabarQuizQuestionsText3
	db "@"

CinnabarQuizQuestionsText4: ; 1ea7b (7:6a7b)
	TX_FAR _CinnabarQuizQuestionsText4
	db "@"

CinnabarQuizQuestionsText5: ; 1ea80 (7:6a80)
	TX_FAR _CinnabarQuizQuestionsText5
	db "@"

CinnabarQuizQuestionsText6: ; 1ea85 (7:6a85)
	TX_FAR _CinnabarQuizQuestionsText6
	db "@"

Func_1ea8a: ; 1ea8a (7:6a8a)
	ld hl, $d79c
	ld a, $10
	jp Predef ; indirect jump to HandleBitArray (f666 (3:7666))

Func_1ea92: ; 1ea92 (7:6a92)
	call YesNoChoice
	ld a, [$ffdc]
	ld c, a
	ld a, [wCurrentMenuItem] ; $cc26
	cp c
	jr nz, .asm_1eab8
	ld hl, $d126
	set 5, [hl]
	ld a, [$ffdb]
	ld [$ffe0], a
	ld hl, CinnabarGymQuizCorrectText
	call PrintText
	ld a, [$ffe0]
	ld c, a
	ld b, $1
	call Func_1ea8a
	jp Func_1eb0a
.asm_1eab8
	call WaitForSoundToFinish
	ld a, (SFX_02_51 - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	ld hl, CinnabarGymQuizIncorrectText
	call PrintText
	ld a, [$ffdb]
	add $2
	ld c, a
	ld b, $2
	ld hl, $d79a
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	ld a, c
	and a
	ret nz
	ld a, [$ffdb]
	add $2
	ld [$da38], a
	ret

CinnabarGymQuizCorrectText: ; 1eae3 (7:6ae3)
	db $0b
	TX_FAR _CinnabarGymQuizCorrectText
	db $06,$08

	ld a, [$ffe0]
	ld c, a
	ld b, $2
	call Func_1ea8a
	ld a, c
	and a
	jp nz, TextScriptEnd
	call WaitForSoundToFinish
	ld a, (SFX_02_57 - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	jp TextScriptEnd

CinnabarGymQuizIncorrectText: ; 1eb05 (7:6b05)
	TX_FAR _CinnabarGymQuizIncorrectText
	db "@"

Func_1eb0a: ; 1eb0a (7:6b0a)
	ld a, $6
	ld [$ffdb], a
.asm_1eb0e
	ld a, [$ffdb]
	dec a
	add a
	add a
	ld d, $0
	ld e, a
	ld hl, CinnabarGymGateCoords ; $6b48
	add hl, de
	ld a, [hli]
	ld b, [hl]
	ld c, a
	inc hl
	ld a, [hl]
	ld [$d12f], a
	push bc
	ld a, [$ffdb]
	ld [$ffe0], a
	ld c, a
	ld b, $2
	call Func_1ea8a
	ld a, c
	and a
	jr nz, .asm_1eb36
	ld a, [$d12f]
	jr .asm_1eb38
.asm_1eb36
	ld a, $e
.asm_1eb38
	pop bc
	ld [$d09f], a
	ld a, $17
	call Predef ; indirect jump to Func_ee9e (ee9e (3:6e9e))
	ld hl, $ffdb
	dec [hl]
	jr nz, .asm_1eb0e
	ret

CinnabarGymGateCoords: ; 1eb48 (7:6b48)
	; format: x-coord, y-coord, direction, padding
	; direction: $54 = horizontal gate, $5f = vertical gate
	db $09,$03,$54,$00
	db $06,$03,$54,$00
	db $06,$06,$54,$00
	db $03,$08,$5f,$00
	db $02,$06,$54,$00
	db $02,$03,$54,$00

Func_1eb60: ; 1eb60 (7:6b60)
	call EnableAutoTextBoxDrawing
	ld a, $30
	call PrintPredefTextID
	ret

MagazinesText: ; 1eb69 (7:6b69)
	TX_FAR _MagazinesText
	db "@"

Func_1eb6e: ; 1eb6e (7:6b6e)
	call EnableAutoTextBoxDrawing
	ld a, [$c109]
	cp $4
	ret nz
	ld a, [$d7f2]
	bit 7, a
	jr nz, .asm_1ebd2
	bit 3, a
	jr nz, .asm_1eb86
	bit 6, a
	jr nz, .asm_1eb8b
.asm_1eb86
	ld a, $2d
	jp PrintPredefTextID
.asm_1eb8b
	ld a, $1
	ld [$cc3c], a
	ld a, $2e
	call PrintPredefTextID
	ld c, $20
	call DelayFrames
	ld a, (SFX_02_3c - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	ld c, $50
	call DelayFrames
	ld a, (SFX_02_48 - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	ld c, $30
	call DelayFrames
	ld a, (SFX_02_3c - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	ld c, $20
	call DelayFrames
	ld a, (SFX_02_3a - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	call Func_2307
	ld hl, $d7f2
	set 3, [hl]
	ret
.asm_1ebd2
	ld a, $1
	ld [$cc3c], a
	ld a, $2f
	call PrintPredefTextID
	ret

BillsHouseMonitorText: ; 1ebdd (7:6bdd)
	TX_FAR _BillsHouseMonitorText
	db "@"

BillsHouseInitiatedText: ; 1ebe2 (7:6be2)
	TX_FAR _BillsHouseInitiatedText
	db $06
	db $08 ; asm
	ld a, $ff
	ld [$c0ee], a
	call PlaySound
	ld c, $10
	call DelayFrames
	ld a, (SFX_02_49 - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	ld c, $3c
	call DelayFrames
	jp TextScriptEnd

BillsHousePokemonList: ; 1ec05 (7:6c05)
	db $08 ; asm
	call SaveScreenTilesToBuffer1
	ld hl, BillsHousePokemonListText1
	call PrintText
	xor a
	ld [$d07c], a
	ld [$cc26], a
	ld [$cc2a], a
	ld a, $3
	ld [$cc29], a
	ld a, $4
	ld [$cc28], a
	ld a, $2
	ld [$cc24], a
	ld a, $1
	ld [$cc25], a
.asm_1ec2d
	ld hl, $d730
	set 6, [hl]
	ld hl, wTileMap
	ld b, $a
	ld c, $9
	call TextBoxBorder
	ld hl, $c3ca
	ld de, BillsMonListText
	call PlaceString
	ld hl, BillsHousePokemonListText2
	call PrintText
	call SaveScreenTilesToBuffer2
	call HandleMenuInput
	bit 1, a
	jr nz, .asm_1ec74
	ld a, [$cc26]
	add EEVEE
	cp EEVEE
	jr z, .asm_1ec6c
	cp FLAREON
	jr z, .asm_1ec6c
	cp JOLTEON
	jr z, .asm_1ec6c
	cp VAPOREON
	jr z, .asm_1ec6c
	jr .asm_1ec74
.asm_1ec6c
	call DisplayPokedex
	call LoadScreenTilesFromBuffer2
	jr .asm_1ec2d
.asm_1ec74
	ld hl, $d730
	res 6, [hl]
	call LoadScreenTilesFromBuffer2
	jp TextScriptEnd

BillsHousePokemonListText1: ; 1ec7f (7:6c7f)
	TX_FAR _BillsHousePokemonListText1
	db "@"

BillsMonListText: ; 1ec84 (7:6c84)
	db   "EEVEE"
	next "FLAREON"
	next "JOLTEON"
	next "VAPOREON"
	next "CANCEL@"

BillsHousePokemonListText2: ; 1ecaa (7:6caa)
	TX_FAR _BillsHousePokemonListText2
	db "@"

Func_1ecaf: ; 1ecaf (7:6caf)
	ld a, [$c109]
	cp $4
	ret nz
	call EnableAutoTextBoxDrawing
	ld a, $8
	jp PrintPredefTextID

OakLabEmailText: ; 1ecbd (7:6cbd)
	TX_FAR _OakLabEmailText
	db "@"



SECTION "bank9",ROMX,BANK[$9]

RhydonPicFront: ; 24000 (9:4000)
	INCBIN "pic/bmon/rhydon.pic"
RhydonPicBack: ; 24202 (9:4202)
	INCBIN "pic/monback/rhydonb.pic"
KangaskhanPicFront: ; 2429a (9:429a)
	INCBIN "pic/bmon/kangaskhan.pic"
KangaskhanPicBack: ; 244a6 (9:44a6)
	INCBIN "pic/monback/kangaskhanb.pic"
NidoranMPicFront: ; 2453c (9:453c)
	INCBIN "pic/bmon/nidoranm.pic"
NidoranMPicBack: ; 24623 (9:4623)
	INCBIN "pic/monback/nidoranmb.pic"
ClefairyPicFront: ; 24682 (9:4682)
	INCBIN "pic/bmon/clefairy.pic"
ClefairyPicBack: ; 24785 (9:4785)
	INCBIN "pic/monback/clefairyb.pic"
SpearowPicFront: ; 247df (9:47df)
	INCBIN "pic/bmon/spearow.pic"
SpearowPicBack: ; 248c2 (9:48c2)
	INCBIN "pic/monback/spearowb.pic"
VoltorbPicFront: ; 24911 (9:4911)
	INCBIN "pic/bmon/voltorb.pic"
VoltorbPicBack: ; 2499a (9:499a)
	INCBIN "pic/monback/voltorbb.pic"
NidokingPicFront: ; 249f8 (9:49f8)
	INCBIN "pic/bmon/nidoking.pic"
NidokingPicBack: ; 24c60 (9:4c60)
	INCBIN "pic/monback/nidokingb.pic"
SlowbroPicFront: ; 24d0a (9:4d0a)
	INCBIN "pic/bmon/slowbro.pic"
SlowbroPicBack: ; 24f87 (9:4f87)
	INCBIN "pic/monback/slowbrob.pic"
IvysaurPicFront: ; 2502b (9:502b)
	INCBIN "pic/bmon/ivysaur.pic"
IvysaurPicBack: ; 25157 (9:5157)
	INCBIN "pic/monback/ivysaurb.pic"
ExeggutorPicFront: ; 251d6 (9:51d6)
	INCBIN "pic/bmon/exeggutor.pic"
ExeggutorPicBack: ; 253f8 (9:53f8)
	INCBIN "pic/monback/exeggutorb.pic"
LickitungPicFront: ; 254a7 (9:54a7)
	INCBIN "pic/bmon/lickitung.pic"
LickitungPicBack: ; 2563e (9:563e)
	INCBIN "pic/monback/lickitungb.pic"
ExeggcutePicFront: ; 256d7 (9:56d7)
	INCBIN "pic/bmon/exeggcute.pic"
ExeggcutePicBack: ; 258f0 (9:58f0)
	INCBIN "pic/monback/exeggcuteb.pic"
GrimerPicFront: ; 25973 (9:5973)
	INCBIN "pic/bmon/grimer.pic"
GrimerPicBack: ; 25ab0 (9:5ab0)
	INCBIN "pic/monback/grimerb.pic"
GengarPicFront: ; 25b76 (9:5b76)
	INCBIN "pic/bmon/gengar.pic"
GengarPicBack: ; 25cc6 (9:5cc6)
	INCBIN "pic/monback/gengarb.pic"
NidoranFPicFront: ; 25d28 (9:5d28)
	INCBIN "pic/bmon/nidoranf.pic"
NidoranFPicBack: ; 25dc2 (9:5dc2)
	INCBIN "pic/monback/nidoranfb.pic"
NidoqueenPicFront: ; 25e09 (9:5e09)
	INCBIN "pic/bmon/nidoqueen.pic"
NidoqueenPicBack: ; 25fef (9:5fef)
	INCBIN "pic/monback/nidoqueenb.pic"
CubonePicFront: ; 260a8 (9:60a8)
	INCBIN "pic/bmon/cubone.pic"
CubonePicBack: ; 26196 (9:6196)
	INCBIN "pic/monback/cuboneb.pic"
RhyhornPicFront: ; 26208 (9:6208)
	INCBIN "pic/bmon/rhyhorn.pic"
RhyhornPicBack: ; 2640f (9:640f)
	INCBIN "pic/monback/rhyhornb.pic"
LaprasPicFront: ; 264c1 (9:64c1)
	INCBIN "pic/bmon/lapras.pic"
LaprasPicBack: ; 2667c (9:667c)
	INCBIN "pic/monback/laprasb.pic"
ArcaninePicFront: ; 266ff (9:66ff)
	INCBIN "pic/bmon/arcanine.pic"
ArcaninePicBack: ; 2693d (9:693d)
	INCBIN "pic/monback/arcanineb.pic"
GyaradosPicFront: ; 269d4 (9:69d4)
	INCBIN "pic/bmon/gyarados.pic"
GyaradosPicBack: ; 26c25 (9:6c25)
	INCBIN "pic/monback/gyaradosb.pic"
ShellderPicFront: ; 26cb6 (9:6cb6)
	INCBIN "pic/bmon/shellder.pic"
ShellderPicBack: ; 26dc3 (9:6dc3)
	INCBIN "pic/monback/shellderb.pic"
TentacoolPicFront: ; 26e2a (9:6e2a)
	INCBIN "pic/bmon/tentacool.pic"
TentacoolPicBack: ; 26f1c (9:6f1c)
	INCBIN "pic/monback/tentacoolb.pic"
GastlyPicFront: ; 26f77 (9:6f77)
	INCBIN "pic/bmon/gastly.pic"
GastlyPicBack: ; 27190 (9:7190)
	INCBIN "pic/monback/gastlyb.pic"
ScytherPicFront: ; 2721c (9:721c)
	INCBIN "pic/bmon/scyther.pic"
ScytherPicBack: ; 2743c (9:743c)
	INCBIN "pic/monback/scytherb.pic"
StaryuPicFront: ; 274e0 (9:74e0)
	INCBIN "pic/bmon/staryu.pic"
StaryuPicBack: ; 275ec (9:75ec)
	INCBIN "pic/monback/staryub.pic"
BlastoisePicFront: ; 27637 (9:7637)
	INCBIN "pic/bmon/blastoise.pic"
BlastoisePicBack: ; 27851 (9:7851)
	INCBIN "pic/monback/blastoiseb.pic"
PinsirPicFront: ; 278da (9:78da)
	INCBIN "pic/bmon/pinsir.pic"
PinsirPicBack: ; 27aaa (9:7aaa)
	INCBIN "pic/monback/pinsirb.pic"
TangelaPicFront: ; 27b39 (9:7b39)
	INCBIN "pic/bmon/tangela.pic"
TangelaPicBack: ; 27ce7 (9:7ce7)
	INCBIN "pic/monback/tangelab.pic"

Func_27d6b: ; 27d6b (9:7d6b)
	call Load16BitRegisters
	push hl
	call GetMonHeader
	pop hl
	push hl
	ld a, [W_MONHTYPE1]
	call Func_27d89
	ld a, [W_MONHTYPE1]
	ld b, a
	ld a, [W_MONHTYPE2]
	cp b
	pop hl
	jr z, asm_27d8c
	ld bc, $28
	add hl, bc

Func_27d89: ; 27d89 (9:7d89)
	push hl
	jr asm_27d9f
asm_27d8c: ; 27d8c (9:7d8c)
	ld a, $7f
	ld bc, $13
	add hl, bc
	ld bc, $6
	jp FillMemory

Func_27d98: ; 27d98 (9:7d98)
	call Load16BitRegisters
	push hl
	ld a, [W_PLAYERMOVETYPE] ; $cfd5
asm_27d9f: ; 27d9f (9:7d9f)
	add a
	ld hl, TypeNamePointers ; $7dae
	ld e, a
	ld d, $0
	add hl, de
	ld a, [hli]
	ld e, a
	ld d, [hl]
	pop hl
	jp PlaceString

INCLUDE "text/type_names.asm"

SaveTrainerName: ; 27e4a (9:7e4a)
	ld hl,TrainerNamePointers
	ld a,[W_TRAINERCLASS]
	dec a
	ld c,a
	ld b,0
	add hl,bc
	add hl,bc
	ld a,[hli]
	ld h,[hl]
	ld l,a
	ld de,$CD6D
.CopyCharacter
	ld a,[hli]
	ld [de],a
	inc de
	cp "@"
	jr nz,.CopyCharacter
	ret

TrainerNamePointers: ; 27e64 (9:7e64)
; what is the point of these?
	dw YoungsterName
	dw BugCatcherName
	dw LassName
	dw W_TRAINERNAME
	dw JrTrainerMName
	dw JrTrainerFName
	dw PokemaniacName
	dw SuperNerdName
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw BurglarName
	dw EngineerName
	dw JugglerXName
	dw W_TRAINERNAME
	dw SwimmerName
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw BeautyName
	dw W_TRAINERNAME
	dw RockerName
	dw JugglerName
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw BlackbeltName
	dw W_TRAINERNAME
	dw ProfOakName
	dw ChiefName
	dw ScientistName
	dw W_TRAINERNAME
	dw RocketName
	dw CooltrainerMName
	dw CooltrainerFName
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME
	dw W_TRAINERNAME

YoungsterName: ; 27ec2 (9:7ec2)
	db "YOUNGSTER@"
BugCatcherName: ; 27ecc (9:7ecc)
	db "BUG CATCHER@"
LassName: ; 27ed8 (9:7ed8)
	db "LASS@"
JrTrainerMName: ; 27edd (9:7edd)
	db "JR.TRAINER♂@"
JrTrainerFName: ; 27ee9 (9:7ee9)
	db "JR.TRAINER♀@"
PokemaniacName: ; 27ef5 (9:7ef5)
	db "POKéMANIAC@"
SuperNerdName: ; 27f00 (9:7f00)
	db "SUPER NERD@"
BurglarName: ; 27f0b (9:7f0b)
	db "BURGLAR@"
EngineerName: ; 27f13 (9:7f13)
	db "ENGINEER@"
JugglerXName: ; 27f1c (9:7f1c)
	db "JUGGLER@"
SwimmerName: ; 27f24 (9:7f24)
	db "SWIMMER@"
BeautyName: ; 27f2c (9:7f2c)
	db "BEAUTY@"
RockerName: ; 27f33 (9:7f33)
	db "ROCKER@"
JugglerName: ; 27f3a (9:7f3a)
	db "JUGGLER@"
BlackbeltName: ; 27f42 (9:7f42)
	db "BLACKBELT@"
ProfOakName: ; 27f4c (9:7f4c)
	db "PROF.OAK@"
ChiefName: ; 27f55 (9:7f55)
	db "CHIEF@"
ScientistName: ; 27f5b (9:7f5b)
	db "SCIENTIST@"
RocketName: ; 27f65 (9:7f65)
	db "ROCKET@"
CooltrainerMName: ; 27f6c (9:7f6c)
	db "COOLTRAINER♂@"
CooltrainerFName: ; 27f79 (9:7f79)
	db "COOLTRAINER♀@"

FocusEnergyEffect_: ; 27f86 (9:7f86)
	ld hl, W_PLAYERBATTSTATUS2 ; $d063
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_27f91
	ld hl, W_ENEMYBATTSTATUS2 ; $d068
.asm_27f91
	bit 2, [hl] ; is mon already using focus energy?
	jr nz, .asm_27fa5
	set 2, [hl] ; mon is now using focus energy
	callab Func_3fba8
	ld hl, GettingPumpedText ; $7fb2
	jp PrintText
.asm_27fa5
	ld c, $32
	call DelayFrames
	ld hl, PrintButItFailedText_
	ld b, BANK(PrintButItFailedText_)
	jp Bankswitch

GettingPumpedText: ; 27fb3 (9:7fb3)
	db $0a
	TX_FAR _GettingPumpedText
	db "@"

SECTION "bankA",ROMX,BANK[$A]
GrowlithePicFront: ; 28000 (a:4000)
	INCBIN "pic/bmon/growlithe.pic"
GrowlithePicBack: ; 28101 (a:4101)
	INCBIN "pic/monback/growlitheb.pic"
OnixPicFront: ; 28164 (a:4164)
	INCBIN "pic/bmon/onix.pic"
OnixPicBack: ; 28300 (a:4300)
	INCBIN "pic/monback/onixb.pic"
FearowPicFront: ; 28383 (a:4383)
	INCBIN "pic/bmon/fearow.pic"
FearowPicBack: ; 28529 (a:4529)
	INCBIN "pic/monback/fearowb.pic"
PidgeyPicFront: ; 285a7 (a:45a7)
	INCBIN "pic/bmon/pidgey.pic"
PidgeyPicBack: ; 2865b (a:465b)
	INCBIN "pic/monback/pidgeyb.pic"
SlowpokePicFront: ; 286a0 (a:46a0)
	INCBIN "pic/bmon/slowpoke.pic"
SlowpokePicBack: ; 287c2 (a:47c2)
	INCBIN "pic/monback/slowpokeb.pic"
KadabraPicFront: ; 28830 (a:4830)
	INCBIN "pic/bmon/kadabra.pic"
KadabraPicBack: ; 289b9 (a:49b9)
	INCBIN "pic/monback/kadabrab.pic"
GravelerPicFront: ; 28a4c (a:4a4c)
	INCBIN "pic/bmon/graveler.pic"
GravelerPicBack: ; 28c00 (a:4c00)
	INCBIN "pic/monback/gravelerb.pic"
ChanseyPicFront: ; 28cae (a:4cae)
	INCBIN "pic/bmon/chansey.pic"
ChanseyPicBack: ; 28e21 (a:4e21)
	INCBIN "pic/monback/chanseyb.pic"
MachokePicFront: ; 28e85 (a:4e85)
	INCBIN "pic/bmon/machoke.pic"
MachokePicBack: ; 29063 (a:5063)
	INCBIN "pic/monback/machokeb.pic"
MrMimePicFront: ; 290f3 (a:50f3)
	INCBIN "pic/bmon/mr.mime.pic"
MrMimePicBack: ; 29247 (a:5247)
	INCBIN "pic/monback/mr.mimeb.pic"
HitmonleePicFront: ; 292bf (a:52bf)
	INCBIN "pic/bmon/hitmonlee.pic"
HitmonleePicBack: ; 2945e (a:545e)
	INCBIN "pic/monback/hitmonleeb.pic"
HitmonchanPicFront: ; 294bc (a:54bc)
	INCBIN "pic/bmon/hitmonchan.pic"
HitmonchanPicBack: ; 29643 (a:5643)
	INCBIN "pic/monback/hitmonchanb.pic"
ArbokPicFront: ; 296b4 (a:56b4)
	INCBIN "pic/bmon/arbok.pic"
ArbokPicBack: ; 29911 (a:5911)
	INCBIN "pic/monback/arbokb.pic"
ParasectPicFront: ; 299a8 (a:59a8)
	INCBIN "pic/bmon/parasect.pic"
ParasectPicBack: ; 29b8c (a:5b8c)
	INCBIN "pic/monback/parasectb.pic"
PsyduckPicFront: ; 29c0a (a:5c0a)
	INCBIN "pic/bmon/psyduck.pic"
PsyduckPicBack: ; 29d3e (a:5d3e)
	INCBIN "pic/monback/psyduckb.pic"
DrowzeePicFront: ; 29da9 (a:5da9)
	INCBIN "pic/bmon/drowzee.pic"
DrowzeePicBack: ; 29f05 (a:5f05)
	INCBIN "pic/monback/drowzeeb.pic"
GolemPicFront: ; 29f74 (a:5f74)
	INCBIN "pic/bmon/golem.pic"
GolemPicBack: ; 2a0f2 (a:60f2)
	INCBIN "pic/monback/golemb.pic"
MagmarPicFront: ; 2a161 (a:6161)
	INCBIN "pic/bmon/magmar.pic"
MagmarPicBack: ; 2a2bf (a:62bf)
	INCBIN "pic/monback/magmarb.pic"
ElectabuzzPicFront: ; 2a367 (a:6367)
	INCBIN "pic/bmon/electabuzz.pic"
ElectabuzzPicBack: ; 2a4ef (a:64ef)
	INCBIN "pic/monback/electabuzzb.pic"
MagnetonPicFront: ; 2a588 (a:6588)
	INCBIN "pic/bmon/magneton.pic"
MagnetonPicBack: ; 2a723 (a:6723)
	INCBIN "pic/monback/magnetonb.pic"
KoffingPicFront: ; 2a7a6 (a:67a6)
	INCBIN "pic/bmon/koffing.pic"
KoffingPicBack: ; 2a974 (a:6974)
	INCBIN "pic/monback/koffingb.pic"
MankeyPicFront: ; 2aa11 (a:6a11)
	INCBIN "pic/bmon/mankey.pic"
MankeyPicBack: ; 2ab16 (a:6b16)
	INCBIN "pic/monback/mankeyb.pic"
SeelPicFront: ; 2ab84 (a:6b84)
	INCBIN "pic/bmon/seel.pic"
SeelPicBack: ; 2ace8 (a:6ce8)
	INCBIN "pic/monback/seelb.pic"
DiglettPicFront: ; 2ad33 (a:6d33)
	INCBIN "pic/bmon/diglett.pic"
DiglettPicBack: ; 2ae10 (a:6e10)
	INCBIN "pic/monback/diglettb.pic"
TaurosPicFront: ; 2ae7e (a:6e7e)
	INCBIN "pic/bmon/tauros.pic"
TaurosPicBack: ; 2b054 (a:7054)
	INCBIN "pic/monback/taurosb.pic"
FarfetchdPicFront: ; 2b0e9 (a:70e9)
	INCBIN "pic/bmon/farfetchd.pic"
FarfetchdPicBack: ; 2b2c6 (a:72c6)
	INCBIN "pic/monback/farfetchdb.pic"
VenonatPicFront: ; 2b357 (a:7357)
	INCBIN "pic/bmon/venonat.pic"
VenonatPicBack: ; 2b45c (a:745c)
	INCBIN "pic/monback/venonatb.pic"
DragonitePicFront: ; 2b4aa (a:74aa)
	INCBIN "pic/bmon/dragonite.pic"
DragonitePicBack: ; 2b67f (a:767f)
	INCBIN "pic/monback/dragoniteb.pic"
DoduoPicFront: ; 2b72c (a:772c)
	INCBIN "pic/bmon/doduo.pic"
DoduoPicBack: ; 2b80d (a:780d)
	INCBIN "pic/monback/doduob.pic"
PoliwagPicFront: ; 2b875 (a:7875)
	INCBIN "pic/bmon/poliwag.pic"
PoliwagPicBack: ; 2b947 (a:7947)
	INCBIN "pic/monback/poliwagb.pic"
JynxPicFront: ; 2b98e (a:798e)
	INCBIN "pic/bmon/jynx.pic"
JynxPicBack: ; 2bb42 (a:7b42)
	INCBIN "pic/monback/jynxb.pic"
MoltresPicFront: ; 2bbac (a:7bac)
	INCBIN "pic/bmon/moltres.pic"
MoltresPicBack: ; 2be02 (a:7e02)
	INCBIN "pic/monback/moltresb.pic"

LeechSeedEffect_: ; 2bea9 (a:7ea9)
	callab MoveHitTest
	ld a, [W_MOVEMISSED] ; $d05f
	and a
	jr nz, .asm_2bee7
	ld hl, W_ENEMYBATTSTATUS2 ; $d068
	ld de, W_ENEMYMONTYPE1 ; $cfea (aliases: W_ENEMYMONTYPES)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_2bec8
	ld hl, W_PLAYERBATTSTATUS2 ; $d063
	ld de, W_PLAYERMONTYPE1 ; $d019 (aliases: W_PLAYERMONTYPES)
.asm_2bec8
	ld a, [de]
	cp GRASS
	jr z, .asm_2bee7
	inc de
	ld a, [de]
	cp GRASS
	jr z, .asm_2bee7
	bit 7, [hl]
	jr nz, .asm_2bee7
	set 7, [hl]
	callab Func_3fba8
	ld hl, WasSeededText ; $7ef2
	jp PrintText
.asm_2bee7
	ld c, $32
	call DelayFrames
	ld hl, EvadedAttackText ; $7ef7
	jp PrintText

WasSeededText: ; 2bef2 (a:7ef2)
	TX_FAR _WasSeededText
	db "@"

EvadedAttackText: ; 2bef7 (a:7ef7)
	TX_FAR _EvadedAttackText
	db "@"

SECTION "bankB",ROMX,BANK[$B]
ArticunoPicFront: ; 2c000 (b:4000)
	INCBIN "pic/bmon/articuno.pic"
ArticunoPicBack: ; 2c238 (b:4238)
	INCBIN "pic/monback/articunob.pic"
ZapdosPicFront: ; 2c29d (b:429d)
	INCBIN "pic/bmon/zapdos.pic"
ZapdosPicBack: ; 2c484 (b:4484)
	INCBIN "pic/monback/zapdosb.pic"
DittoPicFront: ; 2c514 (b:4514)
	INCBIN "pic/bmon/ditto.pic"
DittoPicBack: ; 2c5bd (b:45bd)
	INCBIN "pic/monback/dittob.pic"
MeowthPicFront: ; 2c609 (b:4609)
	INCBIN "pic/bmon/meowth.pic"
MeowthPicBack: ; 2c71f (b:471f)
	INCBIN "pic/monback/meowthb.pic"
KrabbyPicFront: ; 2c777 (b:4777)
	INCBIN "pic/bmon/krabby.pic"
KrabbyPicBack: ; 2c8b0 (b:48b0)
	INCBIN "pic/monback/krabbyb.pic"
VulpixPicFront: ; 2c924 (b:4924)
	INCBIN "pic/bmon/vulpix.pic"
VulpixPicBack: ; 2ca9a (b:4a9a)
	INCBIN "pic/monback/vulpixb.pic"
NinetalesPicFront: ; 2caff (b:4aff)
	INCBIN "pic/bmon/ninetales.pic"
NinetalesPicBack: ; 2ccfb (b:4cfb)
	INCBIN "pic/monback/ninetalesb.pic"
PikachuPicFront: ; 2cd7d (b:4d7d)
	INCBIN "pic/bmon/pikachu.pic"
PikachuPicBack: ; 2ce8b (b:4e8b)
	INCBIN "pic/monback/pikachub.pic"
RaichuPicFront: ; 2cf03 (b:4f03)
	INCBIN "pic/bmon/raichu.pic"
RaichuPicBack: ; 2d0c3 (b:50c3)
	INCBIN "pic/monback/raichub.pic"
DratiniPicFront: ; 2d151 (b:5151)
	INCBIN "pic/bmon/dratini.pic"
DratiniPicBack: ; 2d234 (b:5234)
	INCBIN "pic/monback/dratinib.pic"
DragonairPicFront: ; 2d297 (b:5297)
	INCBIN "pic/bmon/dragonair.pic"
DragonairPicBack: ; 2d3d9 (b:53d9)
	INCBIN "pic/monback/dragonairb.pic"
KabutoPicFront: ; 2d464 (b:5464)
	INCBIN "pic/bmon/kabuto.pic"
KabutoPicBack: ; 2d529 (b:5529)
	INCBIN "pic/monback/kabutob.pic"
KabutopsPicFront: ; 2d583 (b:5583)
	INCBIN "pic/bmon/kabutops.pic"
KabutopsPicBack: ; 2d73c (b:573c)
	INCBIN "pic/monback/kabutopsb.pic"
HorseaPicFront: ; 2d7c1 (b:57c1)
	INCBIN "pic/bmon/horsea.pic"
HorseaPicBack: ; 2d873 (b:5873)
	INCBIN "pic/monback/horseab.pic"
SeadraPicFront: ; 2d8c4 (b:58c4)
	INCBIN "pic/bmon/seadra.pic"
SeadraPicBack: ; 2da2b (b:5a2b)
	INCBIN "pic/monback/seadrab.pic"
SandshrewPicFront: ; 2dac9 (b:5ac9)
	INCBIN "pic/bmon/sandshrew.pic"
SandshrewPicBack: ; 2dbe7 (b:5be7)
	INCBIN "pic/monback/sandshrewb.pic"
SandslashPicFront: ; 2dc6b (b:5c6b)
	INCBIN "pic/bmon/sandslash.pic"
SandslashPicBack: ; 2de04 (b:5e04)
	INCBIN "pic/monback/sandslashb.pic"
OmanytePicFront: ; 2de9d (b:5e9d)
	INCBIN "pic/bmon/omanyte.pic"
OmanytePicBack: ; 2df76 (b:5f76)
	INCBIN "pic/monback/omanyteb.pic"
OmastarPicFront: ; 2dfd3 (b:5fd3)
	INCBIN "pic/bmon/omastar.pic"
OmastarPicBack: ; 2e18b (b:618b)
	INCBIN "pic/monback/omastarb.pic"
JigglypuffPicFront: ; 2e22f (b:622f)
	INCBIN "pic/bmon/jigglypuff.pic"
JigglypuffPicBack: ; 2e30f (b:630f)
	INCBIN "pic/monback/jigglypuffb.pic"
WigglytuffPicFront: ; 2e348 (b:6348)
	INCBIN "pic/bmon/wigglytuff.pic"
WigglytuffPicBack: ; 2e4bf (b:64bf)
	INCBIN "pic/monback/wigglytuffb.pic"
EeveePicFront: ; 2e531 (b:6531)
	INCBIN "pic/bmon/eevee.pic"
EeveePicBack: ; 2e625 (b:6625)
	INCBIN "pic/monback/eeveeb.pic"
FlareonPicFront: ; 2e68d (b:668d)
	INCBIN "pic/bmon/flareon.pic"
FlareonPicBack: ; 2e806 (b:6806)
	INCBIN "pic/monback/flareonb.pic"
JolteonPicFront: ; 2e88f (b:688f)
	INCBIN "pic/bmon/jolteon.pic"
JolteonPicBack: ; 2ea0a (b:6a0a)
	INCBIN "pic/monback/jolteonb.pic"
VaporeonPicFront: ; 2eaae (b:6aae)
	INCBIN "pic/bmon/vaporeon.pic"
VaporeonPicBack: ; 2ec02 (b:6c02)
	INCBIN "pic/monback/vaporeonb.pic"
MachopPicFront: ; 2ec9f (b:6c9f)
	INCBIN "pic/bmon/machop.pic"
MachopPicBack: ; 2eda2 (b:6da2)
	INCBIN "pic/monback/machopb.pic"
ZubatPicFront: ; 2ee0c (b:6e0c)
	INCBIN "pic/bmon/zubat.pic"
ZubatPicBack: ; 2ef17 (b:6f17)
	INCBIN "pic/monback/zubatb.pic"
EkansPicFront: ; 2ef6b (b:6f6b)
	INCBIN "pic/bmon/ekans.pic"
EkansPicBack: ; 2f06d (b:706d)
	INCBIN "pic/monback/ekansb.pic"
ParasPicFront: ; 2f0b4 (b:70b4)
	INCBIN "pic/bmon/paras.pic"
ParasPicBack: ; 2f177 (b:7177)
	INCBIN "pic/monback/parasb.pic"
PoliwhirlPicFront: ; 2f1ed (b:71ed)
	INCBIN "pic/bmon/poliwhirl.pic"
PoliwhirlPicBack: ; 2f35e (b:735e)
	INCBIN "pic/monback/poliwhirlb.pic"
PoliwrathPicFront: ; 2f3c1 (b:73c1)
	INCBIN "pic/bmon/poliwrath.pic"
PoliwrathPicBack: ; 2f52c (b:752c)
	INCBIN "pic/monback/poliwrathb.pic"
WeedlePicFront: ; 2f57d (b:757d)
	INCBIN "pic/bmon/weedle.pic"
WeedlePicBack: ; 2f624 (b:7624)
	INCBIN "pic/monback/weedleb.pic"
KakunaPicFront: ; 2f677 (b:7677)
	INCBIN "pic/bmon/kakuna.pic"
KakunaPicBack: ; 2f736 (b:7736)
	INCBIN "pic/monback/kakunab.pic"
BeedrillPicFront: ; 2f788 (b:7788)
	INCBIN "pic/bmon/beedrill.pic"
BeedrillPicBack: ; 2f980 (b:7980)
	INCBIN "pic/monback/beedrillb.pic"
FossilKabutopsPic: ; 2f9e8 (b:79e8)
	INCBIN "pic/bmon/fossilkabutops.pic"

DisplayEffectiveness: ; 2fb7b (b:7b7b)
	ld a, [$D05B]
	and a, $7F
	cp a, $0A
	ret z
	ld hl, SupperEffectiveText
	jr nc, .done
	ld hl, NotVeryEffectiveText
.done
	jp PrintText

SupperEffectiveText: ; 2fb8e (b:7b8e)
	TX_FAR _SupperEffectiveText
	db "@"

NotVeryEffectiveText: ; 2fb93 (b:7b93)
	TX_FAR _NotVeryEffectiveText
	db "@"

TrainerInfoTextBoxTileGraphics: ; 2fb98 (b:7b98)
	INCBIN "gfx/trainer_info.2bpp"

BlankLeaderNames: ; 2fc28 (b:7c28)
	INCBIN "gfx/blank_leader_names.2bpp"

CircleTile: ; 2fd88 (b:7d88)
	INCBIN "gfx/circle_tile.2bpp"

BadgeNumbersTileGraphics: ; 2fd98 (b:7d98)
	INCBIN "gfx/badge_numbers.2bpp"

; checks if the mon in wWhichPokemon already knows the move in $d0e0
CheckIfMoveIsKnown: ; 2fe18 (b:7e18)
	ld a, [wWhichPokemon]
	ld hl, W_PARTYMON1_MOVE1
	ld bc, $2c
	call AddNTimes
	ld a, [$d0e0]
	ld b, a
	ld c, $4 ; nubmer of moves
.loop
	ld a, [hli]
	cp b
	jr z, .alreadyKnown ; found a match
	dec c
	jr nz, .loop
	and a
	ret
.alreadyKnown
	ld hl, AlreadyKnowsText
	call PrintText
	scf
	ret

AlreadyKnowsText: ; 2fe3b (b:7e3b)
	TX_FAR _AlreadyKnowsText
	db "@"

; scales both uncompressed sprite chunks by two in every dimension (creating 2x2 output pixels per input pixel)
; assumes that input sprite chunks are 4x4 tiles, and the rightmost and bottommost 4 pixels will be ignored
; resulting in a 7*7 tile output sprite chunk
ScaleSpriteByTwo: ; 2fe40 (b:7e40)
	ld de, S_SPRITEBUFFER1 + (4*4*8) - 5          ; last byte of input data, last 4 rows already skipped
	ld hl, S_SPRITEBUFFER0 + SPRITEBUFFERSIZE - 1 ; end of destination buffer
	call ScaleLastSpriteColumnByTwo               ; last tile column is special case
	call ScaleFirstThreeSpriteColumnsByTwo        ; scale first 3 tile columns
	ld de, S_SPRITEBUFFER2 + (4*4*8) - 5          ; last byte of input data, last 4 rows already skipped
	ld hl, S_SPRITEBUFFER1 + SPRITEBUFFERSIZE - 1 ; end of destination buffer
	call ScaleLastSpriteColumnByTwo               ; last tile column is special case

ScaleFirstThreeSpriteColumnsByTwo: ; 2fe55 (b:7e55)
	ld b, $3 ; 3 tile columns
.columnLoop
	ld c, 4*8 - 4 ; $1c, 4 tiles minus 4 unused rows
.columnInnerLoop
	push bc
	ld a, [de]
	ld bc, -(7*8)+1       ; $ffc9, scale lower nybble and seek to previous output column
	call ScalePixelsByTwo
	ld a, [de]
	dec de
	swap a
	ld bc, 7*8+1-2        ; $37, scale upper nybble and seek back to current output column and to the next 2 rows
	call ScalePixelsByTwo
	pop bc
	dec c
	jr nz, .columnInnerLoop
	dec de
	dec de
	dec de
	dec de
	ld a, b
	ld bc, -7*8 ; $ffc8, skip one output column (which has already been written along with the current one)
	add hl, bc
	ld b, a
	dec b
	jr nz, .columnLoop
	ret

ScaleLastSpriteColumnByTwo: ; 2fe7d (b:7e7d)
	ld a, 4*8 - 4 ; $1c, 4 tiles minus 4 unused rows
	ld [H_SPRITEINTERLACECOUNTER], a ; $ff8b
	ld bc, -1 ; $ffff
.columnInnerLoop
	ld a, [de]
	dec de
	swap a                    ; only high nybble contains information
	call ScalePixelsByTwo
	ld a, [H_SPRITEINTERLACECOUNTER] ; $ff8b
	dec a
	ld [H_SPRITEINTERLACECOUNTER], a ; $ff8b
	jr nz, .columnInnerLoop
	dec de                    ; skip last 4 rows of new column
	dec de
	dec de
	dec de
	ret

; scales the given 4 bits in a (4x1 pixels) to 2 output bytes (8x2 pixels)
; hl: destination pointer
; bc: destination pointer offset (added after the two bytes have been written)
ScalePixelsByTwo: ; 2fe97 (b:7e97)
	push hl
	and $f
	ld hl, DuplicateBitsTable
	add l
	ld l, a
	jr nc, .noCarry
	inc h
.noCarry
	ld a, [hl]
	pop hl
	ld [hld], a  ; write output byte twice to make it 2 pixels high
	ld [hl], a
	add hl, bc   ; add offset
	ret

; repeats each input bit twice
DuplicateBitsTable: ; 2fea8 (b:7ea8)
	db $00, $03, $0c, $0f
	db $30, $33, $3c, $3f
	db $c0, $c3, $cc, $cf
	db $f0, $f3, $fc, $ff

PayDayEffect_ ; 2feb8 (b:7eb8)
	xor a
	ld hl, $cd6d
	ld [hli], a
	ld a, [$fff3]
	and a
	ld a, [$d022]
	jr z, .asm_2fec8 ; 0x2fec3 $3
	ld a, [$cff3]
.asm_2fec8
	add a
	ld [$ff98], a
	xor a
	ld [$ff95], a
	ld [$ff96], a
	ld [$ff97], a
	ld a, $64
	ld [$ff99], a
	ld b, $4
	call Divide
	ld a, [$ff98]
	ld [hli], a
	ld a, [$ff99]
	ld [$ff98], a
	ld a, $a
	ld [$ff99], a
	ld b, $4
	call Divide
	ld a, [$ff98]
	swap a
	ld b, a
	ld a, [$ff99]
	add b
	ld [hl], a
	ld de, $cce7
	ld c, $3
	ld a, $b
	call Predef
	ld hl, CoinsScatteredText ; $7f04
	jp PrintText

CoinsScatteredText: ; 2ff04 (b:7f04)
	TX_FAR _CoinsScatteredText
	db "@"

Func_2ff09 ; 2ff09 (b:7f09)
	ld a, [$c102]
	and $8
	jr z, .asm_2ff2e
	ld b, COIN_CASE
	ld a, $1c
	call Predef
	ld a, b
	and a
	ld b, $33
	jr z, .asm_2ff26
	ld hl, $d5a4
	ld a, [hli]
	or [hl]
	jr nz, .asm_2ff2e
	ld b, $32
.asm_2ff26
	call EnableAutoTextBoxDrawing
	ld a, b
	call PrintPredefTextID
	xor a
.asm_2ff2e
	ld [$cd3d], a
	ret

GameCornerCoinCaseText: ; 2ff32 (b:7f32)
	TX_FAR _GameCornerCoinCaseText
	db "@"

GameCornerNoCoinsText: ; 2ff37 (b:7f37)
	TX_FAR _GameCornerNoCoinsText
	db "@"

SECTION "bankC",ROMX,BANK[$C]
DodrioPicFront: ; 30000 (c:4000)
	INCBIN "pic/bmon/dodrio.pic"
DodrioPicBack: ; 301a2 (c:41a2)
	INCBIN "pic/monback/dodriob.pic"
PrimeapePicFront: ; 30247 (c:4247)
	INCBIN "pic/bmon/primeape.pic"
PrimeapePicBack: ; 30408 (c:4408)
	INCBIN "pic/monback/primeapeb.pic"
DugtrioPicFront: ; 30480 (c:4480)
	INCBIN "pic/bmon/dugtrio.pic"
DugtrioPicBack: ; 3062a (c:462a)
	INCBIN "pic/monback/dugtriob.pic"
VenomothPicFront: ; 306a9 (c:46a9)
	INCBIN "pic/bmon/venomoth.pic"
VenomothPicBack: ; 30841 (c:4841)
	INCBIN "pic/monback/venomothb.pic"
DewgongPicFront: ; 30899 (c:4899)
	INCBIN "pic/bmon/dewgong.pic"
DewgongPicBack: ; 309e2 (c:49e2)
	INCBIN "pic/monback/dewgongb.pic"
CaterpiePicFront: ; 30a49 (c:4a49)
	INCBIN "pic/bmon/caterpie.pic"
CaterpiePicBack: ; 30ae1 (c:4ae1)
	INCBIN "pic/monback/caterpieb.pic"
MetapodPicFront: ; 30b3a (c:4b3a)
	INCBIN "pic/bmon/metapod.pic"
MetapodPicBack: ; 30bc8 (c:4bc8)
	INCBIN "pic/monback/metapodb.pic"
ButterfreePicFront: ; 30c37 (c:4c37)
	INCBIN "pic/bmon/butterfree.pic"
ButterfreePicBack: ; 30e0e (c:4e0e)
	INCBIN "pic/monback/butterfreeb.pic"
MachampPicFront: ; 30e93 (c:4e93)
	INCBIN "pic/bmon/machamp.pic"
MachampPicBack: ; 3108c (c:508c)
	INCBIN "pic/monback/machampb.pic"
GolduckPicFront: ; 31108 (c:5108)
	INCBIN "pic/bmon/golduck.pic"
GolduckPicBack: ; 312c2 (c:52c2)
	INCBIN "pic/monback/golduckb.pic"
HypnoPicFront: ; 3135d (c:535d)
	INCBIN "pic/bmon/hypno.pic"
HypnoPicBack: ; 31552 (c:5552)
	INCBIN "pic/monback/hypnob.pic"
GolbatPicFront: ; 315e0 (c:55e0)
	INCBIN "pic/bmon/golbat.pic"
GolbatPicBack: ; 3180a (c:580a)
	INCBIN "pic/monback/golbatb.pic"
MewtwoPicFront: ; 3187f (c:587f)
	INCBIN "pic/bmon/mewtwo.pic"
MewtwoPicBack: ; 31a85 (c:5a85)
	INCBIN "pic/monback/mewtwob.pic"
SnorlaxPicFront: ; 31b19 (c:5b19)
	INCBIN "pic/bmon/snorlax.pic"
SnorlaxPicBack: ; 31ce5 (c:5ce5)
	INCBIN "pic/monback/snorlaxb.pic"
MagikarpPicFront: ; 31d31 (c:5d31)
	INCBIN "pic/bmon/magikarp.pic"
MagikarpPicBack: ; 31ec3 (c:5ec3)
	INCBIN "pic/monback/magikarpb.pic"
MukPicFront: ; 31f56 (c:5f56)
	INCBIN "pic/bmon/muk.pic"
MukPicBack: ; 3215f (c:615f)
	INCBIN "pic/monback/mukb.pic"
KinglerPicFront: ; 321ec (c:61ec)
	INCBIN "pic/bmon/kingler.pic"
KinglerPicBack: ; 323de (c:63de)
	INCBIN "pic/monback/kinglerb.pic"
CloysterPicFront: ; 3247f (c:647f)
	INCBIN "pic/bmon/cloyster.pic"
CloysterPicBack: ; 326ab (c:66ab)
	INCBIN "pic/monback/cloysterb.pic"
ElectrodePicFront: ; 32760 (c:6760)
	INCBIN "pic/bmon/electrode.pic"
ElectrodePicBack: ; 32827 (c:6827)
	INCBIN "pic/monback/electrodeb.pic"
ClefablePicFront: ; 3288c (c:688c)
	INCBIN "pic/bmon/clefable.pic"
ClefablePicBack: ; 329b8 (c:69b8)
	INCBIN "pic/monback/clefableb.pic"
WeezingPicFront: ; 32a44 (c:6a44)
	INCBIN "pic/bmon/weezing.pic"
WeezingPicBack: ; 32c76 (c:6c76)
	INCBIN "pic/monback/weezingb.pic"
PersianPicFront: ; 32d1e (c:6d1e)
	INCBIN "pic/bmon/persian.pic"
PersianPicBack: ; 32f04 (c:6f04)
	INCBIN "pic/monback/persianb.pic"
MarowakPicFront: ; 32f8f (c:6f8f)
	INCBIN "pic/bmon/marowak.pic"
MarowakPicBack: ; 33101 (c:7101)
	INCBIN "pic/monback/marowakb.pic"
HaunterPicFront: ; 3318a (c:718a)
	INCBIN "pic/bmon/haunter.pic"
HaunterPicBack: ; 33345 (c:7345)
	INCBIN "pic/monback/haunterb.pic"
AbraPicFront: ; 333cc (c:73cc)
	INCBIN "pic/bmon/abra.pic"
AbraPicBack: ; 334cf (c:74cf)
	INCBIN "pic/monback/abrab.pic"
AlakazamPicFront: ; 3355a (c:755a)
	INCBIN "pic/bmon/alakazam.pic"
AlakazamPicBack: ; 33779 (c:7779)
	INCBIN "pic/monback/alakazamb.pic"
PidgeottoPicFront: ; 3380a (c:780a)
	INCBIN "pic/bmon/pidgeotto.pic"
PidgeottoPicBack: ; 3395b (c:795b)
	INCBIN "pic/monback/pidgeottob.pic"
PidgeotPicFront: ; 339c2 (c:79c2)
	INCBIN "pic/bmon/pidgeot.pic"
PidgeotPicBack: ; 33b79 (c:7b79)
	INCBIN "pic/monback/pidgeotb.pic"
StarmiePicFront: ; 33c1c (c:7c1c)
	INCBIN "pic/bmon/starmie.pic"
StarmiePicBack: ; 33dac (c:7dac)
	INCBIN "pic/monback/starmieb.pic"
RedPicBack: ; 33e0a (c:7e0a)
	INCBIN "pic/trainer/redb.pic"
OldManPic: ; 33e9a (c:7e9a)
	INCBIN "pic/trainer/oldman.pic"

MistEffect_: ; 33f2b (c:7f2b)
	ld hl, W_PLAYERBATTSTATUS2
	ld a, [$fff3]
	and a
	jr z, .asm_33f36
	ld hl, W_ENEMYBATTSTATUS2
.asm_33f36
	bit 1, [hl] ; is mon protected by mist?
	jr nz, .asm_33f4a
	set 1, [hl] ; mon is now protected by mist
	callab Func_3fba8
	ld hl, ShroudedInMistText
	jp PrintText
.asm_33f4a
	ld hl, PrintButItFailedText_
	ld b, BANK(PrintButItFailedText_)
	jp Bankswitch

ShroudedInMistText: ; 33f52 (c:7f52)
	TX_FAR _ShroudedInMistText
	db "@"

OneHitKOEffect_: ; 33f57 (c:7f57)
	ld hl, W_DAMAGE ; $d0d7
	xor a
	ld [hli], a
	ld [hl], a ; set the damage output to zero
	dec a
	ld [$d05e], a
	ld hl, $d02a
	ld de, $cffb
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_33f72
	ld hl, $cffb
	ld de, $d02a
.asm_33f72
	ld a, [de]
	dec de
	ld b, a
	ld a, [hld]
	sub b
	ld a, [de]
	ld b, a
	ld a, [hl]
	sbc b
	jr c, .asm_33f8a
	ld hl, W_DAMAGE ; $d0d7
	ld a, $ff
	ld [hli], a
	ld [hl], a
	ld a, $2
	ld [$d05e], a
	ret
.asm_33f8a
	ld a, $1
	ld [W_MOVEMISSED], a ; $d05f
	ret

SECTION "bankD",ROMX,BANK[$D]
BulbasaurPicFront: ; 34000 (d:4000)
	INCBIN "pic/bmon/bulbasaur.pic"
BulbasaurPicBack: ; 340e5 (d:40e5)
	INCBIN "pic/monback/bulbasaurb.pic"
VenusaurPicFront: ; 34162 (d:4162)
	INCBIN "pic/bmon/venusaur.pic"
VenusaurPicBack: ; 34397 (d:4397)
	INCBIN "pic/monback/venusaurb.pic"
TentacruelPicFront: ; 34455 (d:4455)
	INCBIN "pic/bmon/tentacruel.pic"
TentacruelPicBack: ; 345c3 (d:45c3)
	INCBIN "pic/monback/tentacruelb.pic"
GoldeenPicFront: ; 3466f (d:466f)
	INCBIN "pic/bmon/goldeen.pic"
GoldeenPicBack: ; 34796 (d:4796)
	INCBIN "pic/monback/goldeenb.pic"
SeakingPicFront: ; 34803 (d:4803)
	INCBIN "pic/bmon/seaking.pic"
SeakingPicBack: ; 34a03 (d:4a03)
	INCBIN "pic/monback/seakingb.pic"
PonytaPicFront: ; 34ab1 (d:4ab1)
	INCBIN "pic/bmon/ponyta.pic"
RapidashPicFront: ; 34c10 (d:4c10)
	INCBIN "pic/bmon/rapidash.pic"
PonytaPicBack: ; 34e32 (d:4e32)
	INCBIN "pic/monback/ponytab.pic"
RapidashPicBack: ; 34eba (d:4eba)
	INCBIN "pic/monback/rapidashb.pic"
RattataPicFront: ; 34f6a (d:4f6a)
	INCBIN "pic/bmon/rattata.pic"
RattataPicBack: ; 35041 (d:5041)
	INCBIN "pic/monback/rattatab.pic"
RaticatePicFront: ; 3507a (d:507a)
	INCBIN "pic/bmon/raticate.pic"
RaticatePicBack: ; 3520d (d:520d)
	INCBIN "pic/monback/raticateb.pic"
NidorinoPicFront: ; 35282 (d:5282)
	INCBIN "pic/bmon/nidorino.pic"
NidorinoPicBack: ; 353f0 (d:53f0)
	INCBIN "pic/monback/nidorinob.pic"
NidorinaPicFront: ; 3548b (d:548b)
	INCBIN "pic/bmon/nidorina.pic"
NidorinaPicBack: ; 355c8 (d:55c8)
	INCBIN "pic/monback/nidorinab.pic"
GeodudePicFront: ; 3564f (d:564f)
	INCBIN "pic/bmon/geodude.pic"
GeodudePicBack: ; 35729 (d:5729)
	INCBIN "pic/monback/geodudeb.pic"
PorygonPicFront: ; 35784 (d:5784)
	INCBIN "pic/bmon/porygon.pic"
PorygonPicBack: ; 358d1 (d:58d1)
	INCBIN "pic/monback/porygonb.pic"
AerodactylPicFront: ; 35931 (d:5931)
	INCBIN "pic/bmon/aerodactyl.pic"
AerodactylPicBack: ; 35aec (d:5aec)
	INCBIN "pic/monback/aerodactylb.pic"
MagnemitePicFront: ; 35b87 (d:5b87)
	INCBIN "pic/bmon/magnemite.pic"
MagnemitePicBack: ; 35c0d (d:5c0d)
	INCBIN "pic/monback/magnemiteb.pic"
CharmanderPicFront: ; 35c5c (d:5c5c)
	INCBIN "pic/bmon/charmander.pic"
CharmanderPicBack: ; 35d5c (d:5d5c)
	INCBIN "pic/monback/charmanderb.pic"
SquirtlePicFront: ; 35db8 (d:5db8)
	INCBIN "pic/bmon/squirtle.pic"
SquirtlePicBack: ; 35e8f (d:5e8f)
	INCBIN "pic/monback/squirtleb.pic"
CharmeleonPicFront: ; 35f0c (d:5f0c)
	INCBIN "pic/bmon/charmeleon.pic"
CharmeleonPicBack: ; 36048 (d:6048)
	INCBIN "pic/monback/charmeleonb.pic"
WartortlePicFront: ; 360b1 (d:60b1)
	INCBIN "pic/bmon/wartortle.pic"
WartortlePicBack: ; 361f1 (d:61f1)
	INCBIN "pic/monback/wartortleb.pic"
CharizardPicFront: ; 36286 (d:6286)
	INCBIN "pic/bmon/charizard.pic"
CharizardPicBack: ; 36495 (d:6495)
	INCBIN "pic/monback/charizardb.pic"
FossilAerodactylPic: ; 36536 (d:6536)
	INCBIN "pic/bmon/fossilaerodactyl.pic"
GhostPic: ; 366b5 (d:66b5)
	INCBIN "pic/other/ghost.pic"
OddishPicFront: ; 3680b (d:680b)
	INCBIN "pic/bmon/oddish.pic"
OddishPicBack: ; 368a9 (d:68a9)
	INCBIN "pic/monback/oddishb.pic"
GloomPicFront: ; 36941 (d:6941)
	INCBIN "pic/bmon/gloom.pic"
GloomPicBack: ; 36a78 (d:6a78)
	INCBIN "pic/monback/gloomb.pic"
VileplumePicFront: ; 36b21 (d:6b21)
	INCBIN "pic/bmon/vileplume.pic"
VileplumePicBack: ; 36c82 (d:6c82)
	INCBIN "pic/monback/vileplumeb.pic"
BellsproutPicFront: ; 36d00 (d:6d00)
	INCBIN "pic/bmon/bellsprout.pic"
BellsproutPicBack: ; 36dba (d:6dba)
	INCBIN "pic/monback/bellsproutb.pic"
WeepinbellPicFront: ; 36e30 (d:6e30)
	INCBIN "pic/bmon/weepinbell.pic"
WeepinbellPicBack: ; 36f6f (d:6f6f)
	INCBIN "pic/monback/weepinbellb.pic"
VictreebelPicFront: ; 36fea (d:6fea)
	INCBIN "pic/bmon/victreebel.pic"
VictreebelPicBack: ; 371b2 (d:71b2)
	INCBIN "pic/monback/victreebelb.pic"


TitleScroll_WaitBall: ; 37244 (d:7244)
; Wait around for the TitleBall animation to play out.
; hi: speed
; lo: duration
	db $05, $05, 0

TitleScroll_In: ; 37247 (d:7247)
; Scroll a TitleMon in from the right.
; hi: speed
; lo: duration
	db $a2, $94, $84, $63, $52, $31, $11, 0

TitleScroll_Out: ; 3724f (d:724f)
; Scroll a TitleMon out to the left.
; hi: speed
; lo: duration
	db $12, $22, $32, $42, $52, $62, $83, $93, 0

TitleScroll: ; 37258 (d:7258)
	ld a, d

	ld bc, TitleScroll_In
	ld d, $88
	ld e, 0 ; don't animate titleball

	and a
	jr nz, .ok

	ld bc, TitleScroll_Out
	ld d, $00
	ld e, 0 ; don't animate titleball
.ok

_TitleScroll: ; 3726a (d:726a)
	ld a, [bc]
	and a
	ret z

	inc bc
	push bc

	ld b, a
	and $f
	ld c, a
	ld a, b
	and $f0
	swap a
	ld b, a

.loop
	ld h, d
	ld l, $48
	call .ScrollBetween

	ld h, $00
	ld l, $88
	call .ScrollBetween

	ld a, d
	add b
	ld d, a

	call GetTitleBallY
	dec c
	jr nz, .loop

	pop bc
	jr _TitleScroll

.ScrollBetween ; 37292 (d:7292)
.wait
	ld a, [$ff44] ; rLY
	cp l
	jr nz, .wait

	ld a, h
	ld [rSCX], a ; $ff43

.wait2
	ld a, [$ff44] ; rLY
	cp h
	jr z, .wait2
	ret

TitleBallYTable: ; 372a0 (d:72a0)
; OBJ y-positions for the Poke Ball held by Red in the title screen.
; This is really two 0-terminated lists. Initiated with an index of 1.
	db 0, $71, $6f, $6e, $6d, $6c, $6d, $6e, $6f, $71, $74, 0

Func_372ac: ; 372ac (d:72ac)
; Animate the TitleBall if a starter just got scrolled out.
	ld a, [wWhichTrade] ; $cd3d
	cp STARTER1
	jr z, .ok
	cp STARTER2
	jr z, .ok
	cp STARTER3
	ret nz
.ok
	ld e, 1 ; animate titleball
	ld bc, TitleScroll_WaitBall
	ld d, 0
	jp _TitleScroll

GetTitleBallY: ; 372c4 (d:72c4)
; Get position e from TitleBallYTable
	push de
	push hl
	xor a
	ld d, a
	ld hl, TitleBallYTable
	add hl, de
	ld a, [hl]
	pop hl
	pop de
	and a
	ret z
	ld [$c328], a
	inc e
	ret

Func_372d6: ; 372d6 (d:72d6)
	call LoadTextBoxTilePatterns
	FuncCoord 3, 4 ; $c3f3
	ld hl, Coord
	ld b, $7
	ld c, $c
	call TextBoxBorder
	FuncCoord 4, 5 ; $c408
	ld hl, Coord
	ld de, W_PLAYERNAME ; $d158
	call PlaceString
	FuncCoord 4, 10 ; $c46c
	ld hl, Coord
	ld de, W_GRASSRATE ; $d887
	call PlaceString
	FuncCoord 9, 8 ; $c449
	ld hl, Coord
	ld a, $69
	ld [hli], a
	ld [hl], $6a
	xor a
	ld [$cfcb], a
	callab Func_3a948
	ld c, $96
	jp DelayFrames

Func_3730e: ; 3730e (d:730e)
	call SaveScreenTilesToBuffer2
	ld a, BANK(DisplayTextIDInit)
	ld [$cf0c], a
	ld b, a
	ld hl, DisplayTextIDInit
	call Bankswitch
	ld hl, PlaySlotMachineText
	call PrintText
	call YesNoChoice
	ld a, [wCurrentMenuItem]
	and a
	jr nz, .skip
	dec a
	ld [$cfcb], a
	ld hl, $cd4f
	xor a
	ld [hli], a
	ld [hl], $2
	ld a, $4c
	call Predef
	call GBPalWhiteOutWithDelay3
	call LoadSlotMachineTiles
	call LoadFontTilePatterns
	ld b, $5
	call GoPAL_SET
	call GBPalNormal
	ld a, $e4
	ld [$ff48], a
	ld hl, $d730
	set 6, [hl]
	xor a
	ld [W_SUBANIMSUBENTRYADDR], a
	ld hl, wTrainerSpriteOffset
	ld bc, $0014
	call FillMemory
	call Func_37395
	ld hl, $d730
	res 6, [hl]
	xor a
	ld [W_SUBANIMSUBENTRYADDR], a
	call GBPalWhiteOutWithDelay3
	ld a, $1
	ld [$cfcb], a
	call GoPAL_SET_CF1C
	call Func_3e08
	call ReloadTilesetTilePatterns
.skip
	call LoadScreenTilesFromBuffer2
	call Delay3
	call GBPalNormal
	ld a, [$cc5e]
	push af
	jp CloseTextDisplay

PlaySlotMachineText: ; 37390 (d:7390)
	TX_FAR _PlaySlotMachineText
	db "@"

Func_37395: ; 37395 (d:7395)
	call Func_37754
	xor a
	ld hl, $cd4a
	ld [hli], a
	ld [hl], a
	call Func_3775f
	ld hl, BetHowManySlotMachineText
	call PrintText
	call SaveScreenTilesToBuffer1
.loop
	ld a, $3
	ld [wMenuWatchedKeys], a
	ld a, $2
	ld [wMaxMenuItem], a
	ld a, $c
	ld [wTopMenuItemY], a
	ld a, $f
	ld [wTopMenuItemX], a
	xor a
	ld [wCurrentMenuItem], a
	ld [wLastMenuItem], a
	ld [$cc37], a
	ld hl, $c48a
	ld b, $5
	ld c, $4
	call TextBoxBorder
	ld hl, $c4a0
	ld de, CoinMultiplierSlotMachineText
	call PlaceString
	call HandleMenuInput
	and $2
	jp nz, LoadScreenTilesFromBuffer1
	ld a, [wCurrentMenuItem]
	ld b, a
	ld a, $3
	sub b
	ld [$cd50], a
	ld hl, wPlayerCoins
	ld c, a
	ld a, [hli]
	and a
	jr nz, .skip1
	ld a, [hl]
	cp c
	jr nc, .skip1
	ld hl, NotEnoughCoinsSlotMachineText
	call PrintText
	jr .loop
.skip1
	call LoadScreenTilesFromBuffer1
	call Func_37741
	call Func_377d5
	call Func_37480
	ld a, $4
	ld hl, $cd4d
	ld [hli], a
	ld [hli], a
	ld [hl], a
	call WaitForSoundToFinish
	ld a, (SFX_1f_66 - SFX_Headers_1f) / 3
	call PlaySound
	ld hl, StartSlotMachineText
	call PrintText
	call Func_374ad
	call Func_37588
	ld hl, wPlayerCoins
	ld a, [hli]
	or [hl]
	jr nz, .skip2
	ld hl, OutOfCoinsSlotMachineText
	call PrintText
	ld c, $3c
	jp DelayFrames
.skip2
	ld hl, OneMoreGoSlotMachineText
	call PrintText
	ld hl, $c49e
	ld bc, $0d0f
	xor a
	ld [$d12c], a
	ld a, $14
	ld [$d125], a
	call DisplayTextBoxID
	ld a, [wCurrentMenuItem]
	and a
	ret nz
	call Func_377ce
	jp Func_37395

CoinMultiplierSlotMachineText: ; 3745e (d:745e)
	db   "×3"
	next "×2"
	next "×1@"

OutOfCoinsSlotMachineText: ; 37467 (d:7467)
	TX_FAR _OutOfCoinsSlotMachineText
	db "@"

BetHowManySlotMachineText: ; 3746c (d:746c)
	TX_FAR _BetHowManySlotMachineText
	db "@"

StartSlotMachineText: ; 37471 (d:7471)
	TX_FAR _StartSlotMachineText
	db "@"

NotEnoughCoinsSlotMachineText: ; 37476 (d:7476)
	TX_FAR _NotEnoughCoinsSlotMachineText
	db "@"

OneMoreGoSlotMachineText: ; 3747b (d:747b)
	TX_FAR _OneMoreGoSlotMachineText
	db "@"

Func_37480: ; 37480 (d:7480)
	ld hl, $cd4c
	bit 7, [hl]
	ret nz
	ld a, [W_SUBANIMSUBENTRYADDR]
	and a
	jr nz, .skip1
	call GenRandom
	and a
	jr z, .skip2
	ld b, a
	ld a, [$cc5b]
	cp b
	jr c, .skip3
	ld a, $d2
	cp b
	jr c, .skip1
	ld [hl], $0
	ret
.skip1
	set 6, [hl]
	ret
.skip2
	ld a, $3c
	ld [W_SUBANIMSUBENTRYADDR], a
	ret
.skip3
	set 7, [hl]
	ret

Func_374ad: ; 374ad (d:74ad)
	ld c, $14
.loop1
	push bc
	call Func_37813
	call Func_37823
	call Func_37833
	ld c, $2
	call DelayFrames
	pop bc
	dec c
	jr nz, .loop1
	xor a
	ld [wTrainerSpriteOffset], a
.loop2
	call Func_37882
	call Func_374df
	call Func_374fb
	call Func_37517
	ret c
	ld a, [$cf1b]
	xor $1
	inc a
	ld c, a
	call DelayFrames
	jr .loop2

Func_374df: ; 374df (d:74df)
	ld a, [wTrainerSpriteOffset]
	cp $1
	jr c, .skip
	ld de, wTrainerEngageDistance
	ld a, [de]
	rra
	jr nc, .skip
	ld hl, $cd4d
	ld a, [hl]
	and a
	ret z
	dec [hl]
	call Func_3752c
	ret nz
.skip
	jp Func_37813

Func_374fb: ; 374fb (d:74fb)
	ld a, [wTrainerSpriteOffset]
	cp $2
	jr c, .skip
	ld de, wTrainerFacingDirection
	ld a, [de]
	rra
	jr nc, .skip
	ld hl, $cd4e
	ld a, [hl]
	and a
	ret z
	dec [hl]
	call Func_37552
	ret z
.skip
	jp Func_37823

Func_37517: ; 37517 (d:7517)
	ld a, [wTrainerSpriteOffset]
	cp $3
	jr c, .skip
	ld de, wTrainerScreenY
	ld a, [de]
	rra
	jr nc, .skip
	scf
	ret
.skip
	call Func_37833
	and a
	ret

Func_3752c: ; 3752c (d:752c)
	call Func_376c0
	ld hl, wTrainerScreenX
	ld a, [$cd4c]
	and $80
	jr nz, .skip1
	inc hl
	ld a, [hl]
	cp $a
	jr nz, .skip2
	ret
.skip1
	ld c, $3
.loop
	ld a, [hli]
	cp $2
	jr c, .skip2
	dec c
	jr nz, .loop
	ret
.skip2
	inc a
	ld hl, $cd4d
	ld [hl], $0
	ret

Func_37552: ; 37552 (d:7552)
	call Func_376b4
	ld a, [$cd4c]
	and $80
	jr nz, .skip1
	call Func_3756e
	ret nz
	jr .skip2
.skip1
	call Func_3756e
	ld a, [de]
	cp $7
	ret nc
.skip2
	xor a
	ld [$cd4e], a
	ret

Func_3756e: ; 3756e (d:756e)
	ld hl, wTrainerScreenX
	ld de, $cd44
	ld a, [de]
	cp [hl]
	ret z
	inc de
	ld a, [de]
	cp [hl]
	ret z
	inc hl
	cp [hl]
	ret z
	inc hl
	cp [hl]
	ret z
	inc de
	ld a, [de]
	cp [hl]
	ret z
	dec de
	dec de
	ret

Func_37588: ; 37588 (d:7588)
	call Func_376a8
	ld a, [$cd50]
	cp $2
	jr z, .skip1
	cp $1
	jr z, .skip2
	ld hl, wTrainerScreenX
	ld de, $cd45
	ld bc, $cd49
	call Func_376a2
	jp z, .skip5
	ld hl, $cd43
	ld de, $cd45
	ld bc, $cd47
	call Func_376a2
	jr z, .skip5
.skip1
	ld hl, $cd43
	ld de, $cd46
	ld bc, $cd49
	call Func_376a2
	jr z, .skip5
	ld hl, wTrainerScreenX
	ld de, $cd44
	ld bc, $cd47
	call Func_376a2
	jr z, .skip5
.skip2
	ld hl, $cd42
	ld de, $cd45
	ld bc, $cd48
	call Func_376a2
	jr z, .skip5
	ld a, [$cd4c]
	and $c0
	jr z, .skip3
	ld hl, $cd4f
	dec [hl]
	jr nz, .skip4
.skip3
	ld hl, NotThisTimeText
	call PrintText
.loop
	xor a
	ld [$c002], a
	ret
.skip4
	call Func_37833
	call DelayFrame
	call Func_37833
	call DelayFrame
	jp Func_37588
.skip5
	ld a, [$cd4c]
	and $c0
	jr z, .skip4
	and $80
	jr nz, .skip6
	ld a, [hl]
	cp $7
	jr c, .skip4
.skip6
	ld a, [hl]
	sub $2
	ld [wTrainerScreenX], a
	ld hl, SlotRewardPointers
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hli]
	ld e, a
	ld a, [hli]
	ld d, a
	push de
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld de, $cf4b
	ld bc, $0004
	call CopyData
	pop hl
	ld de, .asm_37638
	push de
	jp [hl]

.asm_37638
	ld a, [$ff47]
	xor $40
	ld [$ff47], a
	ld c, $5
	call DelayFrames
	dec b
	jr nz, .asm_37638
	ld hl, $cd4a
	ld [hl], d
	inc hl
	ld [hl], e
	call Func_3775f
	ld hl, SlotsMachineText_37665
	call PrintText
	call WaitForTextScrollButtonPress
	call Func_3776b
	call Func_3775f
	ld a, $e4
	ld [$ff48], a
	jp .loop

SlotsMachineText_37665: ; 37665 (d:7665)
	db $08 ; asm
	push bc
	call Func_37728
	ld hl, LinedUpText
	pop bc
	inc bc
	inc bc
	inc bc
	inc bc
	ret

LinedUpText: ; 37673 (d:7673)
	TX_FAR _LinedUpText
	db "@"

SlotRewardPointers: ; 37678 (d:7678)
	dw SlotReward300Func
	dw SlotReward300Text
	dw SlotReward100Func
	dw SlotReward100Text
	dw SlotReward8Func
	dw SlotReward8Text
	dw SlotReward15Func
	dw SlotReward15Text
	dw SlotReward15Func
	dw SlotReward15Text
	dw SlotReward15Func
	dw SlotReward15Text

SlotReward300Text: ; 37690 (d:7690)
	db "300@"

SlotReward100Text: ; 37694 (d:7694)
	db "100@"

SlotReward8Text: ; 37698 (d:7698)
	db "8@"

SlotReward15Text: ; 3769a (d:769a)
	db "15@"

NotThisTimeText: ; 3769d (d:769d)
	TX_FAR _NotThisTimeText
	db "@"

Func_376a2: ; 376a2 (d:76a2)
	ld a, [de]
	cp [hl]
	ret nz
	ld a, [bc]
	cp [hl]
	ret

Func_376a8: ; 376a8 (d:76a8)
	ld de, $cd47
	ld hl, SlotMachineWheel3
	ld a, [wTrainerScreenY]
	call Func_376c9

Func_376b4: ; 376b4 (d:76b4)
	ld de, $cd44
	ld hl, SlotMachineWheel2
	ld a, [wTrainerFacingDirection]
	call Func_376c9

Func_376c0: ; 376c0 (d:76c0)
	ld de, wTrainerScreenX
	ld hl, SlotMachineWheel1
	ld a, [wTrainerEngageDistance]

Func_376c9: ; 376c9 (d:76c9)
	ld c, a
	ld b, $0
	add hl, bc
	ld c, $3
.loop
	ld a, [hli]
	ld [de], a
	inc de
	inc hl
	dec c
	jr nz, .loop
	ret

SlotReward8Func: ; 376d7 (d:76d7)
	ld hl, W_SUBANIMSUBENTRYADDR
	ld a, [hl]
	and a
	jr z, .skip
	dec [hl]
.skip
	ld b, $2
	ld de, 8
	ret

SlotReward15Func: ; 376e5 (d:76e5)
	ld hl, W_SUBANIMSUBENTRYADDR
	ld a, [hl]
	and a
	jr z, .skip
	dec [hl]
.skip
	ld b, $4
	ld de, 15
	ret

SlotReward100Func: ; 376f3 (d:76f3)
	ld a, (SFX_1f_42 - SFX_Headers_1f) / 3
	call PlaySound
	xor a
	ld [$cd4c], a
	ld b, $8
	ld de, 100
	ret

SlotReward300Func: ; 37702 (d:7702)
	ld hl, YeahText
	call PrintText
	ld a, (SFX_1f_3b - SFX_Headers_1f) / 3
	call PlaySound
	call GenRandom
	cp $80
	ld a, $0
	jr c, .skip
	ld [$cd4c], a
.skip
	ld [W_SUBANIMSUBENTRYADDR], a
	ld b, $14
	ld de, 300
	ret

YeahText: ; 37722 (d:7722)
	TX_FAR _YeahText
	db $0a, "@"

Func_37728: ; 37728 (d:7728)
	ld hl, $c4ba
	ld a, [wTrainerScreenX]
	add $25
	ld [hli], a
	inc a
	ld [hld], a
	inc a
	ld de, $ffec
	add hl, de
	ld [hli], a
	inc a
	ld [hl], a
	ld hl, $c4f2
	ld [hl], $ee
	ret

Func_37741: ; 37741 (d:7741)
	ld hl, $cd4b
	ld a, [$cd50]
	ld [hld], a
	xor a
	ld [hli], a
	ld de, $d5a5
	ld c, $2
	ld a, $c
	call Predef

Func_37754: ; 37754 (d:7754)
	ld hl, $c3b9
	ld de, wPlayerCoins
	ld c, $2
	jp PrintBCDNumber

Func_3775f: ; 3775f (d:775f)
	ld hl, $c3bf
	ld de, $cd4a
	ld bc, $8204
	jp PrintNumber

Func_3776b: ; 3776b (d:776b)
	ld a, $1
	ld [$c002], a
	call WaitForSoundToFinish
	ld hl, $cd46
	xor a
	ld [hli], a
	inc a
	ld [hl], a
	ld a, $5
	ld [W_SUBANIMTRANSFORM], a
.loop
	ld a, [$cd4b]
	ld l, a
	ld a, [$cd4a]
	ld h, a
	or l
	ret z
	ld de, $ffff
	add hl, de
	ld a, l
	ld [$cd4b], a
	ld a, h
	ld [$cd4a], a
	ld hl, $cd47
	ld de, $d5a5
	ld c, $2
	ld a, $b
	call Predef
	call Func_37754
	call Func_3775f
	ld a, (SFX_1f_65 - SFX_Headers_1f) / 3
	call PlaySound
	ld a, [W_SUBANIMTRANSFORM]
	dec a
	jr nz, .skip1
	ld a, [$ff48]
	xor $40
	ld [$ff48], a
	ld a, $5
.skip1
	ld [W_SUBANIMTRANSFORM], a
	ld a, [wTrainerScreenX]
	cp $7
	ld c, $8
	jr nc, .skip2
	srl c
.skip2
	call DelayFrames
	jr .loop

Func_377ce: ; 377ce (d:77ce)
	ld a, $23
	ld [$d08a], a
	jr Func_377e3

Func_377d5: ; 377d5 (d:77d5)
	ld a, $14
	ld [$d08a], a
	ld a, [$cd50]
	dec a
	jr z, Func_377fb
	dec a
	jr z, Func_377ef

Func_377e3: ; 377e3 (d:77e3)
	ld hl, $c3cb
	call Func_377fe
	ld hl, $c46b
	call Func_377fe

Func_377ef: ; 377ef (d:77ef)
	ld hl, $c3f3
	call Func_377fe
	ld hl, $c443
	call Func_377fe

Func_377fb: ; 377fb (d:77fb)
	ld hl, $c41b

Func_377fe: ; 377fe (d:77fe)
	ld a, [$d08a]
	ld [hl], a
	ld bc, $000d
	add hl, bc
	ld [hl], a
	ld bc, $0007
	add hl, bc
	inc a
	ld [hl], a
	ld bc, $000d
	add hl, bc
	ld [hl], a
	ret

Func_37813: ; 37813 (d:7813)
	ld bc, SlotMachineWheel1
	ld de, wTrainerEngageDistance
	ld hl, wOAMBuffer
	ld a, $30
	ld [W_BASECOORDX], a
	jr Func_37841

Func_37823: ; 37823 (d:7823)
	ld bc, SlotMachineWheel2
	ld de, wTrainerFacingDirection
	ld hl, $c330
	ld a, $50
	ld [W_BASECOORDX], a
	jr Func_37841

Func_37833: ; 37833 (d:7833)
	ld bc, SlotMachineWheel3
	ld de, wTrainerScreenY
	ld hl, $c360
	ld a, $70
	ld [W_BASECOORDX], a

Func_37841: ; 37841 (d:7841)
	ld a, $58
	ld [W_BASECOORDY], a
	push de
	ld a, [de]
	ld d, b
	add c
	ld e, a
	jr nc, Func_3784e
	inc d

Func_3784e: ; 3784e (d:784e)
	ld a, [W_BASECOORDY]
	ld [hli], a
	ld a, [W_BASECOORDX]
	ld [hli], a
	ld a, [de]
	ld [hli], a
	ld a, $80
	ld [hli], a
	ld a, [W_BASECOORDY]
	ld [hli], a
	ld a, [W_BASECOORDX]
	add $8
	ld [hli], a
	ld a, [de]
	inc a
	ld [hli], a
	ld a, $80
	ld [hli], a
	inc de
	ld a, [W_BASECOORDY]
	sub $8
	ld [W_BASECOORDY], a
	cp $28
	jr nz, Func_3784e
	pop de
	ld a, [de]
	inc a
	cp $1e
	jr nz, .skip
	xor a
.skip
	ld [de], a
	ret

Func_37882: ; 37882 (d:7882)
	call DelayFrame
	call GetJoypadStateLowSensitivity
	ld a, [$ffb5]
	and $1
	ret z
	ld hl, wTrainerSpriteOffset
	ld a, [hl]
	dec a
	ld de, $cd4d
	jr z, .skip
	dec a
	ld de, $cd4e
	jr z, .skip
.loop
	inc [hl]
	ld a, (SFX_1f_64 - SFX_Headers_1f) / 3
	jp PlaySound
.skip
	ld a, [de]
	and a
	ret nz
	jr .loop

LoadSlotMachineTiles: ; 378a8 (d:78a8)
	call DisableLCD
	ld hl, SlotMachineTiles2
	ld de, $8000
	ld bc, $01c0
	ld a, BANK(SlotMachineTiles2)
	call FarCopyData2
	ld hl, SlotMachineTiles1
	ld de, $9000
	ld bc, $0250
	ld a, BANK(SlotMachineTiles1)
	call FarCopyData2
	ld hl, SlotMachineTiles2
	ld de, $9250
	ld bc, $01c0
	ld a, BANK(SlotMachineTiles2)
	call FarCopyData2
	ld hl, SlotMachineMap
	ld de, wTileMap
	ld bc, $00f0
	call CopyData
	call EnableLCD
	ld hl, wTrainerEngageDistance
	ld a, $1c
	ld [hli], a
	ld [hli], a
	ld [hl], a
	call Func_37813
	call Func_37823
	jp Func_37833

SlotMachineMap: ; 378f5 (d:78f5)
	INCBIN "gfx/tilemaps/slotmachine.map"

SLOTS7		EQU $0200
SLOTSBAR	EQU $0604
SLOTSCHERRY	EQU $0A08
SLOTSFISH	EQU $0E0C
SLOTSBIRD	EQU $1210
SLOTSMOUSE	EQU $1614

INCLUDE "data/slot_machine_wheels.asm"

SlotMachineTiles1: ; 37a51 (d:7a51)
IF _RED
	INCBIN "gfx/red/slotmachine1.2bpp"
ENDC
IF _BLUE
	INCBIN "gfx/blue/slotmachine1.2bpp"
ENDC

Func_37ca1: ; 37ca1 (d:7ca1)
	ld hl, $ccd3
	ld a, [$cd38]
	dec a
	ld [$cd38], a
	ld d, 0
	ld e, a
	add hl, de
	ld d, h
	ld e, l
	ld hl, PointerTable_37ce6
	ld a, [$d12f]
	add a
	ld b, 0
	ld c, a
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld a, [W_YCOORD]
	ld b, a
	ld a, [W_XCOORD]
	ld c, a
.asm_37cc7
	ld a, [hli]
	cp b
	jr nz, .asm_37ce1
	ld a, [hli]
	cp c
	jr nz, .asm_37ce2
	ld a, [hli]
	ld h, [hl]
	ld l, a
.asm_37cd2
	ld a, [hli]
	cp $ff
	ret z
	ld [de], a
	inc de
	ld a, [$cd38]
	inc a
	ld [$cd38], a
	jr .asm_37cd2
.asm_37ce1
	inc hl
.asm_37ce2
	inc hl
	inc hl
	jr .asm_37cc7

PointerTable_37ce6: ; 37ce6 (d:7ce6)
	dw PewterMuseumGuyCoords
	dw PewterGymGuyCoords

; these are the four coordinates of the spaces below, above, to the left and
; to the right of the museum guy, and pointers to different movements for
; the player to make to get positioned before the main movement.
PewterMuseumGuyCoords: ; 37cea (d:7cea)
	db 18, 27
	dw .down
	db 16, 27
	dw .up
	db 17, 26
	dw .left
	db 17, 28
	dw .right

.down
	db $40, $40, $ff
.up
	db $10, $20, $ff
.left
	db $40, $10, $ff
.right
	db $40, $20, $ff

; these are the five coordinates which trigger the gym guy and pointers to
; different movements for the player to make to get positioned before the
; main movement
PewterGymGuyCoords: ; 37d06 (d:7d06)
	db 16, 34
	dw .one
	db 17, 35
	dw .two
	db 18, 37
	dw .three
	db 19, 37
	dw .four
	db 17, 36
	dw .five

.one
	db $20, $80, $80, $10, $ff
.two
	db $20, $80, $10, $20, $ff
.three
	db $20, $20, $20, $00, $00, $00, $00, $00, $00, $00, $00, $ff
.four
	db $20, $20, $40, $20, $ff
.five
	db $20, $80, $20, $00, $00, $00, $00, $00, $00, $00, $00, $ff


_Multiply: ; 37d41 (d:7d41)
	ld a, $8
	ld b, a
	xor a
	ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	ld [$ff9b], a
	ld [H_SAVEDNUMTOPRINT], a ; $ff9c
	ld [$ff9d], a
	ld [$ff9e], a
.asm_37d4f
	ld a, [H_REMAINDER] ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	srl a
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	jr nc, .asm_37d77
	ld a, [$ff9e]
	ld c, a
	ld a, [$ff98]
	add c
	ld [$ff9e], a
	ld a, [$ff9d]
	ld c, a
	ld a, [$ff97]
	adc c
	ld [$ff9d], a
	ld a, [H_SAVEDNUMTOPRINT] ; $ff9c
	ld c, a
	ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
	adc c
	ld [H_SAVEDNUMTOPRINT], a ; $ff9c
	ld a, [$ff9b]
	ld c, a
	ld a, [H_DIVIDEND] ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	adc c
	ld [$ff9b], a
.asm_37d77
	dec b
	jr z, .asm_37d94
	ld a, [$ff98]
	sla a
	ld [$ff98], a
	ld a, [$ff97]
	rl a
	ld [$ff97], a
	ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
	rl a
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, [H_DIVIDEND] ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	rl a
	ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	jr .asm_37d4f
.asm_37d94
	ld a, [$ff9e]
	ld [$ff98], a
	ld a, [$ff9d]
	ld [$ff97], a
	ld a, [H_SAVEDNUMTOPRINT] ; $ff9c
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, [$ff9b]
	ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	ret

_Divide: ; 37da5 (d:7da5)
	xor a
	ld [$ff9a], a
	ld [$ff9b], a
	ld [H_SAVEDNUMTOPRINT], a ; $ff9c
	ld [$ff9d], a
	ld [$ff9e], a
	ld a, $9
	ld e, a
.asm_37db3
	ld a, [$ff9a]
	ld c, a
	ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
	sub c
	ld d, a
	ld a, [H_REMAINDER] ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld c, a
	ld a, [H_DIVIDEND] ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	sbc c
	jr c, .asm_37dce
	ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	ld a, d
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, [$ff9e]
	inc a
	ld [$ff9e], a
	jr .asm_37db3
.asm_37dce
	ld a, b
	cp $1
	jr z, .asm_37e18
	ld a, [$ff9e]
	sla a
	ld [$ff9e], a
	ld a, [$ff9d]
	rl a
	ld [$ff9d], a
	ld a, [H_SAVEDNUMTOPRINT] ; $ff9c
	rl a
	ld [H_SAVEDNUMTOPRINT], a ; $ff9c
	ld a, [$ff9b]
	rl a
	ld [$ff9b], a
	dec e
	jr nz, .asm_37e04
	ld a, $8
	ld e, a
	ld a, [$ff9a]
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	xor a
	ld [$ff9a], a
	ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
	ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	ld a, [$ff97]
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, [$ff98]
	ld [$ff97], a
.asm_37e04
	ld a, e
	cp $1
	jr nz, .asm_37e0a
	dec b
.asm_37e0a
	ld a, [H_REMAINDER] ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	srl a
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld a, [$ff9a]
	rr a
	ld [$ff9a], a
	jr .asm_37db3
.asm_37e18
	ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld a, [$ff9e]
	ld [$ff98], a
	ld a, [$ff9d]
	ld [$ff97], a
	ld a, [H_SAVEDNUMTOPRINT] ; $ff9c
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, [$ff9b]
	ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	ret

Func_37e2d: ; 37e2d (d:7e2d)
	ld a, [wTrainerSpriteOffset]
	cp $fd
	jr z, .asm_37e66
	cp $fe
	jr z, .asm_37e6a
	cp $ff
	jr z, .asm_37e6e
	callba Func_2ff09
	ld a, [wTrainerSpriteOffset]
	and a
	ret z
	ld a, [$cd05]
	ld b, a
	ld a, [wTrainerFacingDirection]
	inc a
	cp b
	jr z, .asm_37e58
	ld a, $fd
	jr .asm_37e5a
.asm_37e58
	ld a, $fa
.asm_37e5a
	ld [$cc5b], a
	ld a, [H_LOADEDROMBANK]
	ld [$cc5e], a
	call Func_3730e
	ret
.asm_37e66
	ld a, $28
	jr .asm_37e70
.asm_37e6a
	ld a, $29
	jr .asm_37e70
.asm_37e6e
	ld a, $2a
.asm_37e70
	push af
	call EnableAutoTextBoxDrawing
	pop af
	call PrintPredefTextID
	ret

GameCornerOutOfOrderText: ; 37e79 (d:7e79)
	TX_FAR _GameCornerOutOfOrderText
	db "@"

GameCornerOutToLunchText: ; 37e7e (d:7e7e)
	TX_FAR _GameCornerOutToLunchText
	db "@"

GameCornerSomeonesKeysText: ; 37e83 (d:7e83)
	TX_FAR _GameCornerSomeonesKeysText
	db "@"

SECTION "bankE",ROMX,BANK[$E]

INCLUDE "data/moves.asm"

INCLUDE "data/base_stats.asm"

INCLUDE "data/cries.asm"

Func_39680: ; 39680 (e:5680)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, [$d060]
	ld hl, $d026
	jr z, .asm_39691
	ld a, [$d065]
	ld hl, $cff7
.asm_39691
	ld c, $4
	ld b, a
.asm_39694
	srl b
	call c, Func_3969f
	inc hl
	inc hl
	dec c
	ret z
	jr .asm_39694

Func_3969f: ; 3969f (e:569f)
	ld a, [hl]
	add a
	ld [hld], a
	ld a, [hl]
	rl a
	ld [hli], a
	ret

Func_396a7: ; 396a7 (e:56a7)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, [$d061]
	ld hl, W_PLAYERMONATK
	jr z, .asm_396b8
	ld a, [$d066]
	ld hl, W_ENEMYMONATTACK
.asm_396b8
	ld c, $4
	ld b, a
.asm_396bb
	srl b
	call c, Func_396c6
	inc hl
	inc hl
	dec c
	ret z
	jr .asm_396bb

Func_396c6: ; 396c6 (e:56c6)
	ld a, [hl]
	srl a
	ld [hli], a
	rr [hl]
	or [hl]
	jr nz, .asm_396d1
	ld [hl], $1
.asm_396d1
	dec hl
	ret

_ScrollTrainerPicAfterBattle: ; 396d3 (e:56d3)
; Load the enemy trainer's pic and scrolls it into
; the screen from the right.
	xor a
	ld [W_ENEMYMONID], a
	ld b, $1
	call GoPAL_SET
	callab _LoadTrainerPic
	FuncCoord 19, 0 ; $c3b3
	ld hl, Coord
	ld c, $0
.asm_396e9
	inc c
	ld a, c
	cp $7
	ret z
	ld d, $0
	push bc
	push hl
.asm_396f2
	call Func_39707
	inc hl
	ld a, $7
	add d
	ld d, a
	dec c
	jr nz, .asm_396f2
	ld c, $4
	call DelayFrames
	pop hl
	pop bc
	dec hl
	jr .asm_396e9

Func_39707: ; 39707 (e:5707)
	push hl
	push de
	push bc
	ld e, $7
.asm_3970c
	ld [hl], d
	ld bc, $14
	add hl, bc
	inc d
	dec e
	jr nz, .asm_3970c
	pop bc
	pop de
	pop hl
	ret

; 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, $cee9  ; 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, $cee9
	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, $cee9  ; temp move selection array
	ld de, W_ENEMYMONMOVES  ; 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, $cee9  ; temp move selection array
	ld de, W_ENEMYMONMOVES  ; 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, $cee9    ; use created temporary array as move set
	ret
.useOriginalMoveSet
	ld hl, W_ENEMYMONMOVES    ; 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, [W_PLAYERMONSTATUS]
	and a
	ret z       ; return if no status ailment on player's mon
	ld hl, $cee8  ; temp move selection array (-1 byte offest)
	ld de, W_ENEMYMONMOVES  ; 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
	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       ; discourage move
	ld [hl], a
	jr .nextMove

StatusAilmentMoveEffects ; 57e2
	db $01 ; some sleep effect?
	db SLEEP_EFFECT
	db POISON_EFFECT
	db PARALYZE_EFFECT
	db $FF

; slightly encourage moves with specific effects
AIMoveChoiceModification2: ; 397e7 (e:57e7)
	ld a, [$ccd5]
	cp $1
	ret nz
	ld hl, $cee8  ; temp move selection array (-1 byte offest)
	ld de, W_ENEMYMONMOVES  ; 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
	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]       ; slighly encourage this move
	jr .nextMove

; encourages moves that are effective against the player's mon
AIMoveChoiceModification3: ; 39817 (e:5817)
	ld hl, $cee8  ; temp move selection array (-1 byte offest)
	ld de, W_ENEMYMONMOVES  ; 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, [$d11e]
	cp $10
	jr z, .nextMove
	jr c, .notEffectiveMove
	dec [hl]       ; slighly 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, W_ENEMYMONMOVES  ; enemy moves
	ld b, $5
	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]       ; slighly 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,$CFCC
	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
	db 0,$15,0

	dw BugCatcherPic
	db 0,$10,0

	dw LassPic
	db 0,$15,0

	dw SailorPic
	db 0,$30,0

	dw JrTrainerMPic
	db 0,$20,0

	dw JrTrainerFPic
	db 0,$20,0

	dw PokemaniacPic
	db 0,$50,0

	dw SuperNerdPic
	db 0,$25,0

	dw HikerPic
	db 0,$35,0

	dw BikerPic
	db 0,$20,0

	dw BurglarPic
	db 0,$90,0

	dw EngineerPic
	db 0,$50,0

	dw JugglerPic
	db 0,$35,0

	dw FisherPic
	db 0,$35,0

	dw SwimmerPic
	db 0,$05,0

	dw CueBallPic
	db 0,$25,0

	dw GamblerPic
	db 0,$70,0

	dw BeautyPic
	db 0,$70,0

	dw PsychicPic
	db 0,$10,0

	dw RockerPic
	db 0,$25,0

	dw JugglerPic
	db 0,$35,0

	dw TamerPic
	db 0,$40,0

	dw BirdKeeperPic
	db 0,$25,0

	dw BlackbeltPic
	db 0,$25,0

	dw Rival1Pic
	db 0,$35,0

	dw ProfOakPic
	db 0,$99,0

	dw ChiefPic
	db 0,$30,0

	dw ScientistPic
	db 0,$50,0

	dw GiovanniPic
	db 0,$99,0

	dw RocketPic
	db 0,$30,0

	dw CooltrainerMPic
	db 0,$35,0

	dw CooltrainerFPic
	db 0,$35,0

	dw BrunoPic
	db 0,$99,0

	dw BrockPic
	db 0,$99,0

	dw MistyPic
	db 0,$99,0

	dw LtSurgePic
	db 0,$99,0

	dw ErikaPic
	db 0,$99,0

	dw KogaPic
	db 0,$99,0

	dw BlainePic
	db 0,$99,0

	dw SabrinaPic
	db 0,$99,0

	dw GentlemanPic
	db 0,$70,0

	dw Rival2Pic
	db 0,$65,0

	dw Rival3Pic
	db 0,$99,0

	dw LoreleiPic
	db 0,$99,0

	dw ChannelerPic
	db 0,$30,0

	dw AgathaPic
	db 0,$99,0

	dw LancePic
	db 0,$99,0

INCLUDE "text/trainer_names.asm"

Func_39b87: ; 39b87 (e:5b87)
	ld hl, $d0dc
	ld de, $d0e1
	ld b, $0
.asm_39b8f
	ld a, [hli]
	and a
	jr z, .asm_39bc1
	push hl
	ld [$d0b5], a
	ld a, $2c
	ld [$d0b7], a
	ld a, MOVE_NAME
	ld [W_LISTTYPE], a
	call GetName
	ld hl, $cd6d
.asm_39ba7
	ld a, [hli]
	cp $50
	jr z, .asm_39bb0
	ld [de], a
	inc de
	jr .asm_39ba7
.asm_39bb0
	ld a, b
	ld [$cd6c], a
	inc b
	ld a, $4e
	ld [de], a
	inc de
	pop hl
	ld a, b
	cp $4
	jr z, .asm_39bd1
	jr .asm_39b8f
.asm_39bc1
	ld a, "-"
	ld [de], a
	inc de
	inc b
	ld a, b
	cp $4
	jr z, .asm_39bd1
	ld a, $4e
	ld [de], a
	inc de
	jr .asm_39bc1
.asm_39bd1
	ld a, "@"
	ld [de], a
	ret

Func_39bd5: ; 39bd5 (e:5bd5)
	ld a, [$d11b]
	cp $1
	jr nz, .asm_39be6
	ld hl, wEnemyPartyCount ; $d89c
	ld de, W_ENEMYMON1OT ; $d9ac OT names of other player
	ld a, $6
	jr .asm_39c18
.asm_39be6
	cp $4
	jr nz, .calcAttackStat4
	ld hl, W_NUMINPARTY ; $d163
	ld de, W_PARTYMON1OT ; $d273
	ld a, $5
	jr .asm_39c18
.calcAttackStat4
	cp $5
	jr nz, .asm_39c02
	ld hl, $cf7b
	ld de, MonsterNames ; $421e
	ld a, $1
	jr .asm_39c18
.asm_39c02
	cp $2
	jr nz, .asm_39c10
	ld hl, wNumBagItems ; $d31d
	ld de, ItemNames ; $472b
	ld a, $4
	jr .asm_39c18
.asm_39c10
	ld hl, $cf7b
	ld de, ItemNames ; $472b
	ld a, ITEM_NAME
.asm_39c18
	ld [W_LISTTYPE], a
	ld a, l
	ld [$cf8b], a
	ld a, h
	ld [$cf8c], a
	ld a, e
	ld [$cf8d], a
	ld a, d
	ld [$cf8e], a
	ld bc, ItemPrices ; $4608
	ld a, c
	ld [$cf8f], a
	ld a, b
	ld [$cf90], a
	ret

Func_39c37: ; 39c37 (e:5c37)
	ld hl, W_PARTYMON1 ; $d164
	ld a, [$cc49]
	and a
	jr z, .asm_39c4b
	dec a
	jr z, .asm_39c48
	ld hl, $da81
	jr .asm_39c4b
.asm_39c48
	ld hl, $d89d
.asm_39c4b
	ld d, $0
	add hl, de
	ld a, [hl]
	ld [$cf91], a
	ret

ReadTrainer: ; 39c53 (e:5c53)

; don't change any moves in a link battle
	ld a,[W_ISLINKBATTLE]
	and a
	ret nz

; set [wEnemyPartyCount] to 0, [$D89D] 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 [$CF91],a ; write species somewhere (XXX why?)
	ld a,1
	ld [$CC49],a
	push hl
	call AddPokemonToParty
	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 [$CF91],a
	ld a,1
	ld [$CC49],a
	push hl
	call AddPokemonToParty
	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,W_ENEMYMON1MOVE3
	ld bc,W_ENEMYMON2MOVE3 - W_ENEMYMON1MOVE3
	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 [$D95E],a
	jr .FinishUp
.ChampionRival ; give moves to his team

; pidgeot
	ld a,SKY_ATTACK
	ld [W_ENEMYMON1MOVE3],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 [W_ENEMYMON6MOVE3],a
.FinishUp ; XXX this needs documenting
	xor a       ; clear D079-D07B
	ld de,$D079
	ld [de],a
	inc de
	ld [de],a
	inc de
	ld [de],a
	ld a,[W_CURENEMYLVL]
	ld b,a
.LastLoop
	ld hl,$D047
	ld c,2
	push bc
	ld a,$B
	call Predef
	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,[W_ISLINKBATTLE]
	cp 4
	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 GenRandom
	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 Func_3a72a

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 Func_3a7cf
	jp c,AIUseHyperPotion
	ld a,5
	call Func_3a7cf
	ret nc
	jp Func_3a72a

BrockAI: ; 3a614 (e:6614)
; if his active monster has a status condition, use a full heal
	ld a,[W_ENEMYMONSTATUS]
	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 Func_3a7cf
	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 Func_3a7cf
	ret nc
	jp AIUseHyperPotion

Sony2AI: ; 3a64c (e:664c)
	cp $20
	ret nc
	ld a,5
	call Func_3a7cf
	ret nc
	jp AIUsePotion

Sony3AI: ; 3a658 (e:6658)
	cp $20
	ret nc
	ld a,5
	call Func_3a7cf
	ret nc
	jp AIUseFullRestore

LoreleiAI: ; 3a664 (e:6664)
	cp $80
	ret nc
	ld a,5
	call Func_3a7cf
	ret nc
	jp AIUseSuperPotion

BrunoAI: ; 3a670 (e:6670)
	cp $40
	ret nc
	jp AIUseXDefend

AgathaAI: ; 3a676 (e:6676)
	cp $14
	jp c,Func_3a72a
	cp $80
	ret nc
	ld a,4
	call Func_3a7cf
	ret nc
	jp AIUseSuperPotion

LanceAI: ; 3a687 (e:6687)
	cp $80
	ret nc
	ld a,5
	call Func_3a7cf
	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 [$CF05],a
	ld de,wHPBarOldHP
	ld hl,$CFE7
	ld a,[hld]
	ld [de],a
	inc de
	ld a,[hl]
	ld [de],a
	inc de
	ld hl,$CFF5
	ld a,[hld]
	ld [de],a
	inc de
	ld [wHPBarMaxHP],a
	ld [$CFE7],a
	ld a,[hl]
	ld [de],a
	ld [wHPBarMaxHP+1],a
	ld [W_ENEMYMONCURHP],a
	jr Func_3a718

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 [$CF05],a
	ld hl,$CFE7
	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,$CFF5
	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,Func_3a718
	inc de
	ld a,[de]
	dec de
	ld [hld],a
	ld [wHPBarNewHP],a
	ld a,[de]
	ld [hl],a
	ld [wHPBarNewHP+1],a
	; fallthrough

Func_3a718: ; 3a718 (e:6718)
	call AIPrintItemUse_
	FuncCoord 2, 2 ; $c3ca
	ld hl,Coord
	xor a
	ld [$CF94],a
	ld a,$48
	call Predef
	jp DecrementAICount

Func_3a72a: ; 3a72a (e:672a)
	ld a,[wEnemyPartyCount]
	ld c,a
	ld hl,W_ENEMYMON1HP

	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,Func_3a74b
	and a
	ret

Func_3a74b: ; 3a74b (e:674b)

; prepare to withdraw the active monster: copy hp, number, and status to roster

	ld a,[W_ENEMYMONNUMBER]
	ld hl,W_ENEMYMON1HP
	ld bc,$2C
	call AddNTimes
	ld d,h
	ld e,l
	ld hl,W_ENEMYMONCURHP
	ld bc,4
	call CopyData

	ld hl, AIBattleWithdrawText
	call PrintText

	ld a,1
	ld [$D11D],a
	callab EnemySendOut
	xor a
	ld [$D11D],a

	ld a,[W_ISLINKBATTLE]
	cp 4
	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,[W_ENEMYMONNUMBER]
	ld hl,$D8A8
	ld bc,$2C
	call AddNTimes
	xor a
	ld [hl],a ; clear status in enemy team roster
	ld [W_ENEMYMONSTATUS],a ; clear status of active enemy
	ld hl,$D069
	res 0,[hl]
	ret

AIUseXAccuracy: ; 0x3a7a8 unused
	call Func_3a69b
	ld hl,$D068
	set 0,[hl]
	ld a,X_ACCURACY
	jp AIPrintItemUse

AIUseGuardSpec: ; 3a7b5 (e:67b5)
	call Func_3a69b
	ld hl,$D068
	set 1,[hl]
	ld a,GUARD_SPEC_
	jp AIPrintItemUse

AIUseDireHit: ; 0x3a7c2 unused
	call Func_3a69b
	ld hl,$D068
	set 2,[hl]
	ld a,DIRE_HIT
	jp AIPrintItemUse

Func_3a7cf: ; 3a7cf (e:67cf)
	ld [H_DIVISOR],a
	ld hl,$CFF4
	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,$CFE7
	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 [$CF05],a
	push bc
	call AIPrintItemUse_
	pop bc
	ld hl,$CFCD
	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 [$CF05],a
	call AIPrintItemUse_
	jp DecrementAICount

AIPrintItemUse_: ; 3a835 (e:6835)
; print "x used [$CF05] on z!"
	ld a,[$CF05]
	ld [$D11E],a
	call GetItemName
	ld hl, AIBattleUseItemText
	jp PrintText

AIBattleUseItemText: ; 3a844 (e:6844)
	TX_FAR _AIBattleUseItemText
	db "@"

DrawAllPokeballs: ; 3a849 (e:6849)
	call LoadPartyPokeballGfx
	call SetupOwnPartyPokeballs
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	ret z ; return if wild pokémon
	jp SetupEnemyPartyPokeballs

DrawEnemyPokeballs: ; 0x3a857
	call LoadPartyPokeballGfx
	jp SetupEnemyPartyPokeballs

LoadPartyPokeballGfx: ; 3a85d (e:685d)
	ld de, PokeballTileGraphics ; $697e
	ld hl, $8310
	ld bc, (BANK(PokeballTileGraphics) << 8) + $04
	jp CopyVideoData

SetupOwnPartyPokeballs: ; 3a869 (e:6869)
	call Func_3a902
	ld hl, W_PARTYMON1DATA
	ld de, W_NUMINPARTY ; $d163
	call SetupPokeballs
	ld a, $60
	ld hl, W_BASECOORDX ; $d081
	ld [hli], a
	ld [hl], a
	ld a, $8
	ld [$cd3e], a
	ld hl, wOAMBuffer
	jp Func_3a8e1

SetupEnemyPartyPokeballs: ; 3a887 (e:6887)
	call Func_3a919
	ld hl, wEnemyMons
	ld de, wEnemyPartyCount ; $d89c
	call SetupPokeballs
	ld hl, W_BASECOORDX ; $d081
	ld a, $48
	ld [hli], a
	ld [hl], $20
	ld a, $f8
	ld [$cd3e], a
	ld hl, $c318
	jp Func_3a8e1

SetupPokeballs: ; 0x3a8a6
	ld a, [de]
	push af
	ld de, wBuffer
	ld c, $6 ; max num of partymons
	ld a, $34 ; empty pokeball
.emptyloop
	ld [de], a
	inc de
	dec c
	jr nz, .emptyloop ; 0x3a8b2 $fb
	pop af
	ld de, wBuffer
.monloop
	push af
	call PickPokeball
	inc de
	pop af
	dec a
	jr nz, .monloop
	ret

PickPokeball: ; 3a8c2 (e:68c2)
	inc hl
	ld a, [hli]
	and a
	jr nz, .alive
	ld a, [hl]
	and a
	ld b, $33 ; crossed ball (fainted)
	jr z, .done_fainted
.alive
	inc hl
	inc hl
	ld a, [hl] ; status
	and a
	ld b, $32 ; black ball (status)
	jr nz, .done
	dec b ; regular ball
	jr .done
.done_fainted
	inc hl
	inc hl
.done
	ld a, b
	ld [de], a
	ld bc, $0028 ; rest of mon struct
	add hl, bc
	ret

Func_3a8e1: ; 3a8e1 (e:68e1)
	ld de, $cee9
	ld c, $6
.asm_3a8e6
	ld a, [W_BASECOORDY] ; $d082
	ld [hli], a
	ld a, [W_BASECOORDX] ; $d081
	ld [hli], a
	ld a, [de]
	ld [hli], a
	xor a
	ld [hli], a
	ld a, [W_BASECOORDX] ; $d081
	ld b, a
	ld a, [$cd3e]
	add b
	ld [W_BASECOORDX], a ; $d081
	inc de
	dec c
	jr nz, .asm_3a8e6
	ret

Func_3a902: ; 3a902 (e:6902)
	ld hl, PlayerBattleHUDGraphicsTiles ; $6916
	ld de, $cd3f
	ld bc, $3
	call CopyData
	FuncCoord 18, 10 ; $c47a
	ld hl, Coord
	ld de, rIE ; $ffff
	jr Func_3a930

PlayerBattleHUDGraphicsTiles: ; 3a916 (e:6916)
; The tile numbers for specific parts of the battle display for the player's pokemon
	db $73 ; unused ($73 is hardcoded into the routine that uses these bytes)
	db $77 ; lower-right corner tile of the HUD
	db $6F ; lower-left triangle tile of the HUD

Func_3a919: ; 3a919 (e:6919)
	ld hl, EnemyBattleHUDGraphicsTiles ; $692d
	ld de, $cd3f
	ld bc, $3
	call CopyData
	FuncCoord 1, 2 ; $c3c9
	ld hl, Coord
	ld de, $1
	jr Func_3a930

EnemyBattleHUDGraphicsTiles: ; 3a92d (e:692d)
; The tile numbers for specific parts of the battle display for the enemy
	db $73 ; unused ($73 is hardcoded in the routine that uses these bytes)
	db $74 ; lower-left corner tile of the HUD
	db $78 ; lower-right triangle tile of the HUD

Func_3a930: ; 3a930 (e:6930)
	ld [hl], $73
	ld bc, $14
	add hl, bc
	ld a, [$cd40]
	ld [hl], a
	ld a, $8
.asm_3a93c
	add hl, de
	ld [hl], $76
	dec a
	jr nz, .asm_3a93c
	add hl, de
	ld a, [$cd41]
	ld [hl], a
	ret

Func_3a948: ; 3a948 (e:6948)
	call LoadPartyPokeballGfx
	ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
	ld de, W_NUMINPARTY ; $d163
	call SetupPokeballs
	ld hl, W_BASECOORDX ; $d081
	ld a, $50
	ld [hli], a
	ld [hl], $40
	ld a, $8
	ld [$cd3e], a
	ld hl, wOAMBuffer
	call Func_3a8e1
	ld hl, wEnemyMons ; $d8a4
	ld de, wEnemyPartyCount ; $d89c
	call SetupPokeballs
	ld hl, W_BASECOORDX ; $d081
	ld a, $50
	ld [hli], a
	ld [hl], $68
	ld hl, $c318
	jp Func_3a8e1

; four tiles: pokeball, black pokeball (status ailment), crossed out pokeball (faited) and pokeball slot (no mon)
PokeballTileGraphics:: ; 3a97e (e:697e)
	INCBIN "gfx/pokeball.2bpp"

; tiles for gameboy and link cable graphics used for trading sequence animation
TradingAnimationGraphics: ; 3a9be (e:69be)
	INCBIN "gfx/game_boy.norepeat.2bpp"
	INCBIN "gfx/link_cable.2bpp"

; 4 tiles for actual wire transfer animation (pokeball wandering inside wire)
TradingAnimationGraphics2: ; 3acce (e:6cce)
	INCBIN "gfx/trade2.2bpp"

Func_3ad0e: ; 3ad0e (e:6d0e)
	ld hl, $ccd3
	xor a
	ld [hl], a
	ld a, [wWhichPokemon] ; $cf92
	ld c, a
	ld b, $1
	call Func_3b057

Func_3ad1c: ; 3ad1c (e:6d1c)
	ld a, [$ffd7]
	push af
	xor a
	ld [$d121], a
	dec a
	ld [wWhichPokemon], a ; $cf92
	push hl
	push bc
	push de
	ld hl, W_NUMINPARTY ; $d163
	push hl
asm_3ad2e: ; 3ad2e (e:6d2e)
	ld hl, wWhichPokemon ; $cf92
	inc [hl]
	pop hl
	inc hl
	ld a, [hl]
	cp $ff
	jp z, Func_3aede
	ld [$cee9], a
	push hl
	ld a, [wWhichPokemon] ; $cf92
	ld c, a
	ld hl, $ccd3
	ld b, $2
	call Func_3b057
	ld a, c
	and a
	jp z, asm_3ad2e
	ld a, [$cee9]
	dec a
	ld b, $0
	ld hl, EvosMovesPointerTable
	add a
	rl b
	ld c, a
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	push hl
	ld a, [$cf91]
	push af
	xor a
	ld [$cc49], a
	call LoadMonData
	pop af
	ld [$cf91], a
	pop hl

Func_3ad71: ; 3ad71 (e:6d71)
	ld a, [hli]
	and a
	jr z, asm_3ad2e
	ld b, a
	cp $3
	jr z, .asm_3ad91
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $32
	jr z, asm_3ad2e
	ld a, b
	cp $2
	jr z, .asm_3ada4
	ld a, [$ccd4]
	and a
	jr nz, asm_3ad2e
	ld a, b
	cp $1
	jr z, .asm_3adad
.asm_3ad91
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $32
	jp nz, Func_3aed9
	ld a, [hli]
	ld b, a
	ld a, [$cfb9]
	cp b
	jp c, asm_3ad2e
	jr .asm_3adb6
.asm_3ada4
	ld a, [hli]
	ld b, a
	ld a, [$cf91]
	cp b
	jp nz, Func_3aed9
.asm_3adad
	ld a, [hli]
	ld b, a
	ld a, [$cfb9]
	cp b
	jp c, Func_3aeda
.asm_3adb6
	ld [W_CURENEMYLVL], a ; $d127
	ld a, $1
	ld [$d121], a
	push hl
	ld a, [hl]
	ld [$ceea], a
	ld a, [wWhichPokemon] ; $cf92
	ld hl, W_PARTYMON1NAME ; $d2b5
	call GetPartyMonName
	call CopyStringToCF4B
	ld hl, IsEvolvingText
	call PrintText
	ld c, $32
	call DelayFrames
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld hl, wTileMap
	ld bc, $c14
	call ClearScreenArea
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, $ff
	ld [$cfcb], a
	call CleanLCD_OAM
	callab Func_7bde9
	jp c, Func_3af2e
	ld hl, EvolvedText
	call PrintText
	pop hl
	ld a, [hl]
	ld [$d0b5], a
	ld [$cf98], a
	ld [$ceea], a
	ld a, MONSTER_NAME
	ld [W_LISTTYPE], a
	ld a, $e
	ld [$d0b7], a
	call GetName
	push hl
	ld hl, IntoText
	call Func_3c59
	ld a, (SFX_02_3b - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent
	call WaitForSoundToFinish
	ld c, $28
	call DelayFrames
	call ClearScreen
	call Func_3aef7
	ld a, [$d11e]
	push af
	ld a, [$d0b5]
	ld [$d11e], a
	ld a, $3a
	call Predef ; indirect jump to IndexToPokedex (41010 (10:5010))
	ld a, [$d11e]
	dec a
	ld hl, BulbasaurBaseStats ; $43de
	ld bc, $1c
	call AddNTimes
	ld de, W_MONHEADER
	call CopyData
	ld a, [$d0b5]
	ld [$d0b8], a
	pop af
	ld [$d11e], a
	ld hl, $cfa8
	ld de, $cfba
	ld b, $1
	call CalcStats
	ld a, [wWhichPokemon] ; $cf92
	ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
	ld bc, $2c
	call AddNTimes
	ld e, l
	ld d, h
	push hl
	push bc
	ld bc, $22
	add hl, bc
	ld a, [hli]
	ld b, a
	ld c, [hl]
	ld hl, $cfbb
	ld a, [hld]
	sub c
	ld c, a
	ld a, [hl]
	sbc b
	ld b, a
	ld hl, $cf9a
	ld a, [hl]
	add c
	ld [hld], a
	ld a, [hl]
	adc b
	ld [hl], a
	dec hl
	pop bc
	call CopyData
	ld a, [$d0b5]
	ld [$d11e], a
	xor a
	ld [$cc49], a
	call Func_3af5b
	pop hl
	ld a, $42
	call Predef ; indirect jump to SetPartyMonTypes (5db5e (17:5b5e))
	ld a, [W_ISINBATTLE] ; $d057
	and a
	call z, Func_3af52
	ld a, $3a
	call Predef ; indirect jump to IndexToPokedex (41010 (10:5010))
	ld a, [$d11e]
	dec a
	ld c, a
	ld b, $1
	ld hl, wPokedexOwned ; $d2f7
	push bc
	call Func_3b057
	pop bc
	ld hl, wPokedexSeen ; $d30a
	call Func_3b057
	pop de
	pop hl
	ld a, [$cf98]
	ld [hl], a
	push hl
	ld l, e
	ld h, d
	jr Func_3aeda

Func_3aed9: ; 3aed9 (e:6ed9)
	inc hl

Func_3aeda: ; 3aeda (e:6eda)
	inc hl
	jp Func_3ad71

Func_3aede: ; 3aede (e:6ede)
	pop de
	pop bc
	pop hl
	pop af
	ld [$ffd7], a
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $32
	ret z
	ld a, [W_ISINBATTLE] ; $d057
	and a
	ret nz
	ld a, [$d121]
	and a
	call nz, Func_2307
	ret

Func_3aef7: ; 3aef7 (e:6ef7)
	ld a, [$d0b5]
	push af
	ld a, [$d0b8]
	ld [$d0b5], a
	call GetName
	pop af
	ld [$d0b5], a
	ld hl, $cd6d
	ld de, $cf4b
.asm_3af0e
	ld a, [de]
	inc de
	cp [hl]
	inc hl
	ret nz
	cp $50
	jr nz, .asm_3af0e
	ld a, [wWhichPokemon] ; $cf92
	ld bc, $b
	ld hl, W_PARTYMON1NAME ; $d2b5
	call AddNTimes
	push hl
	call GetName
	ld hl, $cd6d
	pop de
	jp CopyData

Func_3af2e: ; 3af2e (e:6f2e)
	ld hl, StoppedEvolvingText
	call PrintText
	call ClearScreen
	pop hl
	call Func_3af52
	jp asm_3ad2e

EvolvedText: ; 3af3e (e:6f3e)
	TX_FAR _EvolvedText
	db "@"

IntoText: ; 3af43 (e:6f43)
	TX_FAR _IntoText
	db "@"

StoppedEvolvingText: ; 3af48 (e:6f48)
	TX_FAR _StoppedEvolvingText
	db "@"

IsEvolvingText: ; 3af4d (e:6f4d)
	TX_FAR _IsEvolvingText
	db "@"

Func_3af52: ; 3af52 (e:6f52)
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $32
	ret z
	jp ReloadTilesetTilePatterns

Func_3af5b: ; 3af5b (e:6f5b)
	ld hl, EvosMovesPointerTable
	ld a, [$d11e]
	ld [$cf91], a
	dec a
	ld bc, $0
	ld hl, EvosMovesPointerTable
	add a
	rl b
	ld c, a
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
.asm_3af73
	ld a, [hli]
	and a
	jr nz, .asm_3af73
.asm_3af77
	ld a, [hli]
	and a
	jr z, .asm_3afb1
	ld b, a
	ld a, [W_CURENEMYLVL] ; $d127
	cp b
	ld a, [hli]
	jr nz, .asm_3af77
	ld d, a
	ld a, [$cc49]
	and a
	jr nz, .asm_3af96
	ld hl, W_PARTYMON1_MOVE1 ; $d173
	ld a, [wWhichPokemon] ; $cf92
	ld bc, $2c
	call AddNTimes
.asm_3af96
	ld b, $4
.asm_3af98
	ld a, [hli]
	cp d
	jr z, .asm_3afb1
	dec b
	jr nz, .asm_3af98
	ld a, d
	ld [$d0e0], a
	ld [$d11e], a
	call GetMoveName
	call CopyStringToCF4B
	ld a, $1b
	call Predef ; indirect jump to LearnMove (6e43 (1:6e43))
.asm_3afb1
	ld a, [$cf91]
	ld [$d11e], a
	ret

; writes the moves a mon has at level [W_CURENEMYLVL] to [de]
; move slots are being filled up sequentially and shifted if all slots are full
; [$cee9]: (?)
WriteMonMoves: ; 3afb8 (e:6fb8)
	call Load16BitRegisters
	push hl
	push de
	push bc
	ld hl, EvosMovesPointerTable
	ld b, $0
	ld a, [$cf91]  ; cur mon ID
	dec a
	add a
	rl b
	ld c, a
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
.skipEvoEntriesLoop
	ld a, [hli]
	and a
	jr nz, .skipEvoEntriesLoop
	jr .firstMove
.nextMove
	pop de
.nextMove2
	inc hl
.firstMove
	ld a, [hli]       ; read level of next move in learnset
	and a
	jp z, .done       ; end of list
	ld b, a
	ld a, [W_CURENEMYLVL] ; $d127
	cp b
	jp c, .done       ; mon level < move level (assumption: learnset is sorted by level)
	ld a, [$cee9]
	and a
	jr z, .skipMinLevelCheck
	ld a, [wWhichTrade] ; $cd3d (min move level)
	cp b
	jr nc, .nextMove2 ; min level >= move level
.skipMinLevelCheck
	push de
	ld c, $4
.moveAlreadyLearnedCheckLoop
	ld a, [de]
	inc de
	cp [hl]
	jr z, .nextMove
	dec c
	jr nz, .moveAlreadyLearnedCheckLoop
	pop de
	push de
	ld c, $4
.findEmptySlotLoop
	ld a, [de]
	and a
	jr z, .writeMoveToSlot2
	inc de
	dec c
	jr nz, .findEmptySlotLoop
	pop de                        ; no empty move slots found
	push de
	push hl
	ld h, d
	ld l, e
	call WriteMonMoves_ShiftMoveData ; shift all moves one up (deleting move 1)
	ld a, [$cee9]
	and a
	jr z, .writeMoveToSlot
	push de
	ld bc, $12
	add hl, bc
	ld d, h
	ld e, l
	call WriteMonMoves_ShiftMoveData ; shift all move PP data one up
	pop de
.writeMoveToSlot
	pop hl
.writeMoveToSlot2
	ld a, [hl]
	ld [de], a
	ld a, [$cee9]
	and a
	jr z, .nextMove
	push hl            ; write move PP value
	ld a, [hl]
	ld hl, $15
	add hl, de
	push hl
	dec a
	ld hl, Moves
	ld bc, $6
	call AddNTimes
	ld de, $cee9
	ld a, BANK(Moves)
	call FarCopyData
	ld a, [$ceee]
	pop hl
	ld [hl], a
	pop hl
	jr .nextMove
.done
	pop bc
	pop de
	pop hl
	ret

; shifts all move data one up (freeing 4th move slot)
WriteMonMoves_ShiftMoveData: ; 3b04e (e:704e)
	ld c, $3
.asm_3b050
	inc de
	ld a, [de]
	ld [hli], a
	dec c
	jr nz, .asm_3b050
	ret

Func_3b057: ; 3b057 (e:7057)
	ld a, $10
	jp Predef ; indirect jump to HandleBitArray (f666 (3:7666))

INCLUDE "data/evos_moves.asm"

HealEffect_: ; 3b9ec (e:79ec)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld de, W_PLAYERMONCURHP ; $d015
	ld hl, W_PLAYERMONMAXHP ; $d023
	ld a, [W_PLAYERMOVENUM] ; $cfd2
	jr z, .asm_3ba03
	ld de, W_ENEMYMONCURHP ; $cfe6
	ld hl, W_ENEMYMONMAXHP ; $cff4
	ld a, [W_ENEMYMOVENUM] ; $cfcc
.asm_3ba03
	ld b, a
	ld a, [de]
	cp [hl]
	inc de
	inc hl
	ld a, [de]
	sbc [hl]
	jp z, Func_3ba97
	ld a, b
	cp REST
	jr nz, .asm_3ba37
	push hl
	push de
	push af
	ld c, $32
	call DelayFrames
	ld hl, W_PLAYERMONSTATUS ; $d018
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3ba25
	ld hl, W_ENEMYMONSTATUS ; $cfe9
.asm_3ba25
	ld a, [hl]
	and a
	ld [hl], 2 ; Number of turns from Rest
	ld hl, StartedSleepingEffect ; $7aa2
	jr z, .asm_3ba31
	ld hl, FellAsleepBecameHealthyText ; $7aa7
.asm_3ba31
	call PrintText
	pop af
	pop de
	pop hl
.asm_3ba37
	ld a, [hld]
	ld [wHPBarMaxHP], a
	ld c, a
	ld a, [hl]
	ld [wHPBarMaxHP+1], a
	ld b, a
	jr z, .asm_3ba47
	srl b
	rr c
.asm_3ba47
	ld a, [de]
	ld [wHPBarOldHP], a
	add c
	ld [de], a
	ld [wHPBarNewHP], a
	dec de
	ld a, [de]
	ld [wHPBarOldHP+1], a
	adc b
	ld [de], a
	ld [wHPBarNewHP+1], a
	inc hl
	inc de
	ld a, [de]
	dec de
	sub [hl]
	dec hl
	ld a, [de]
	sbc [hl]
	jr c, .asm_3ba6f
	ld a, [hli]
	ld [de], a
	ld [wHPBarNewHP+1], a
	inc de
	ld a, [hl]
	ld [de], a
	ld [wHPBarNewHP], a
.asm_3ba6f
	ld hl, Func_3fba8 ; $7ba8
	call BankswitchEtoF
	ld a, [H_WHOSETURN] ; $fff3
	and a
	FuncCoord 10, 9 ; $c45e
	ld hl, Coord
	ld a, $1
	jr z, .asm_3ba83
	FuncCoord 2, 2 ; $c3ca
	ld hl, Coord
	xor a
.asm_3ba83
	ld [wListMenuID], a ; $cf94
	ld a, $48
	call Predef ; indirect jump to UpdateHPBar (fa1d (3:7a1d))
	ld hl, Func_3cd5a ; $4d5a
	call BankswitchEtoF
	ld hl, RegainedHealthText ; $7aac
	jp PrintText

Func_3ba97: ; 3ba97 (e:7a97)
	ld c, $32
	call DelayFrames
	ld hl, PrintButItFailedText_
	jp BankswitchEtoF

StartedSleepingEffect: ; 3baa2 (e:7aa2)
	TX_FAR _StartedSleepingEffect
	db "@"

FellAsleepBecameHealthyText: ; 3baa7 (e:7aa7)
	TX_FAR _FellAsleepBecameHealthyText
	db "@"

RegainedHealthText: ; 3baac (e:7aac)
	TX_FAR _RegainedHealthText
	db "@"

TransformEffect_: ; 3bab1 (e:7ab1)
	ld hl, W_PLAYERMONID
	ld de, $cfe5
	ld bc, W_ENEMYBATTSTATUS3 ; $d069
	ld a, [W_ENEMYBATTSTATUS1] ; $d067
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr nz, .asm_3bad1
	ld hl, $cfe5
	ld de, W_PLAYERMONID
	ld bc, W_PLAYERBATTSTATUS3 ; $d064
	ld [wPlayerMoveListIndex], a ; $cc2e
	ld a, [W_PLAYERBATTSTATUS1] ; $d062
.asm_3bad1
	bit 6, a ; is mon invulnerable to typical attacks? (fly/dig)
	jp nz, Func_3bb8c
	push hl
	push de
	push bc
	ld hl, W_PLAYERBATTSTATUS2 ; $d063
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3bae4
	ld hl, W_ENEMYBATTSTATUS2 ; $d068
.asm_3bae4
	bit 4, [hl]
	push af
	ld hl, Func_79747
	ld b, BANK(Func_79747)
	call nz, Bankswitch
	ld a, [W_OPTIONS] ; $d355
	add a
	ld hl, Func_3fba8 ; $7ba8
	ld b, BANK(Func_3fba8)
	jr nc, .asm_3baff
	ld hl, AnimationTransformMon
	ld b, BANK(AnimationTransformMon)
.asm_3baff
	call Bankswitch
	ld hl, Func_79771
	ld b, BANK(Func_79771)
	pop af
	call nz, Bankswitch
	pop bc
	ld a, [bc]
	set 3, a
	ld [bc], a
	pop de
	pop hl
	push hl
	ld a, [hl]
	ld [de], a
	ld bc, $5
	add hl, bc
	inc de
	inc de
	inc de
	inc de
	inc de
	inc bc
	inc bc
	call CopyData
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3bb32
	ld a, [de]
	ld [$cceb], a
	inc de
	ld a, [de]
	ld [$ccec], a
	dec de
.asm_3bb32
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hli]
	ld [de], a
	inc de
	inc hl
	inc hl
	inc hl
	inc de
	inc de
	inc de
	ld bc, $8
	call CopyData
	ld bc, $ffef
	add hl, bc
	ld b, $4
.asm_3bb4a
	ld a, [hli]
	and a
	jr z, .asm_3bb57
	ld a, $5
	ld [de], a
	inc de
	dec b
	jr nz, .asm_3bb4a
	jr .asm_3bb5d
.asm_3bb57
	xor a
	ld [de], a
	inc de
	dec b
	jr nz, .asm_3bb57
.asm_3bb5d
	pop hl
	ld a, [hl]
	ld [$d11e], a
	call GetMonName
	ld hl, $cd26
	ld de, $cd12
	call Func_3bb7d
	ld hl, wEnemyMonStatMods ; $cd2e
	ld de, wPlayerMonStatMods ; $cd1a
	call Func_3bb7d
	ld hl, TransformedText ; $7b92
	jp PrintText

Func_3bb7d: ; 3bb7d (e:7b7d)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3bb86
	push hl
	ld h, d
	ld l, e
	pop de
.asm_3bb86
	ld bc, $8
	jp CopyData

Func_3bb8c: ; 3bb8c (e:7b8c)
	ld hl, PrintButItFailedText_ ; $7b53
	jp BankswitchEtoF

TransformedText: ; 3bb92 (e:7b92)
	TX_FAR _TransformedText
	db "@"

ReflectLightScreenEffect_: ; 3bb97 (e:7b97)
	ld hl, W_PLAYERBATTSTATUS3 ; $d064
	ld de, W_PLAYERMOVEEFFECT ; $cfd3
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3bba8
	ld hl, W_ENEMYBATTSTATUS3 ; $d069
	ld de, W_ENEMYMOVEEFFECT ; $cfcd
.asm_3bba8
	ld a, [de]
	cp LIGHT_SCREEN_EFFECT
	jr nz, .reflect
	bit 1, [hl] ; is mon already protected by light screen?
	jr nz, .moveFailed
	set 1, [hl] ; mon is now protected by light screen
	ld hl, LightScreenProtectedText ; $7bd7
	jr .asm_3bbc1
.reflect
	bit 2, [hl] ; is mon already protected by reflect?
	jr nz, .moveFailed
	set 2, [hl] ; mon is now protected by reflect
	ld hl, ReflectGainedArmorText ; $7bdc
.asm_3bbc1
	push hl
	ld hl, Func_3fba8 ; $7ba8
	call BankswitchEtoF
	pop hl
	jp PrintText
.moveFailed
	ld c, $32
	call DelayFrames
	ld hl, PrintButItFailedText_ ; $7b53
	jp BankswitchEtoF

LightScreenProtectedText: ; 3bbd7 (e:7bd7)
	TX_FAR _LightScreenProtectedText
	db "@"

ReflectGainedArmorText: ; 3bbdc (e:7bdc)
	TX_FAR _ReflectGainedArmorText
	db "@"

BankswitchEtoF: ; 3bbe1 (e:7be1)
	ld b, BANK(BattleCore)
	jp Bankswitch

SECTION "bankF",ROMX,BANK[$F]

BattleCore:

; These are move effects (second value from the Moves table in bank $E).
EffectsArray1: ; 3c000 (f:4000)
	db CONVERSION_EFFECT
	db HAZE_EFFECT
	db SWITCH_AND_TELEPORT_EFFECT
	db MIST_EFFECT
	db FOCUS_ENERGY_EFFECT
	db CONFUSION_EFFECT
	db HEAL_EFFECT
	db TRANSFORM_EFFECT
	db LIGHT_SCREEN_EFFECT
	db REFLECT_EFFECT
	db POISON_EFFECT
	db PARALYZE_EFFECT
	db SUBSTITUTE_EFFECT
	db MIMIC_EFFECT
	db LEECH_SEED_EFFECT
	db SPLASH_EFFECT
	db -1
EffectsArray2: ; 3c011 (f:4011)
; moves that do damage but not through normal calculations
; e.g., Super Fang, Psywave
	db SUPER_FANG_EFFECT
	db SPECIAL_DAMAGE_EFFECT
	db -1
EffectsArray3: ; 3c014 (f:4014)
; non-damaging, stat‐affecting or status‐causing moves?
; e.g., Meditate, Bide, Hypnosis
	db $01
	db ATTACK_UP1_EFFECT
	db DEFENSE_UP1_EFFECT
	db SPEED_UP1_EFFECT
	db SPECIAL_UP1_EFFECT
	db ACCURACY_UP1_EFFECT
	db EVASION_UP1_EFFECT
	db ATTACK_DOWN1_EFFECT
	db DEFENSE_DOWN1_EFFECT
	db SPEED_DOWN1_EFFECT
	db SPECIAL_DOWN1_EFFECT
	db ACCURACY_DOWN1_EFFECT
	db EVASION_DOWN1_EFFECT
	db BIDE_EFFECT
	db SLEEP_EFFECT
	db ATTACK_UP2_EFFECT
	db DEFENSE_UP2_EFFECT
	db SPEED_UP2_EFFECT
	db SPECIAL_UP2_EFFECT
	db ACCURACY_UP2_EFFECT
	db EVASION_UP2_EFFECT
	db ATTACK_DOWN2_EFFECT
	db DEFENSE_DOWN2_EFFECT
	db SPEED_DOWN2_EFFECT
	db SPECIAL_DOWN2_EFFECT
	db ACCURACY_DOWN2_EFFECT
	db EVASION_DOWN2_EFFECT
	db -1
EffectsArray4: ; 3c030 (f:4030)
; Attacks that aren't finished after they faint the opponent.
	db DRAIN_HP_EFFECT
	db EXPLODE_EFFECT
	db DREAM_EATER_EFFECT
	db PAY_DAY_EFFECT
	db TWO_TO_FIVE_ATTACKS_EFFECT
	db $1E
	db ATTACK_TWICE_EFFECT
	db RECOIL_EFFECT
	db TWINEEDLE_EFFECT
	db RAGE_EFFECT
	db -1
EffectsArray5: ; 3c03b (f:403b)
	db DRAIN_HP_EFFECT
	db EXPLODE_EFFECT
	db DREAM_EATER_EFFECT
	db PAY_DAY_EFFECT
	db SWIFT_EFFECT
	db TWO_TO_FIVE_ATTACKS_EFFECT
	db $1E
	db CHARGE_EFFECT
	db SUPER_FANG_EFFECT
	db SPECIAL_DAMAGE_EFFECT
	db FLY_EFFECT
	db ATTACK_TWICE_EFFECT
	db JUMP_KICK_EFFECT
	db RECOIL_EFFECT
	; fallthrough to Next EffectsArray
EffectsArray5B: ; 3c049 (f:4049)
; moves that prevent the player from switching moves?
	db THRASH_PETAL_DANCE_EFFECT
	db TRAPPING_EFFECT
	db -1

Func_3c04c: ; 3c04c (f:404c)
	call Func_3ec92
	ld a, $1
	ld [$d125], a
	call DisplayTextBoxID
	FuncCoord 1, 5 ; $c405
	ld hl, Coord
	ld bc, $307
	call ClearScreenArea
	call DisableLCD
	call LoadFontTilePatterns
	call Func_3ee58
	ld hl, $9800
	ld bc, $400
.asm_3c06f
	ld a, $7f
	ld [hli], a
	dec bc
	ld a, b
	or c
	jr nz, .asm_3c06f
	ld hl, wTileMap
	ld de, $9800
	ld b, $12
.asm_3c07f
	ld c, $14
.asm_3c081
	ld a, [hli]
	ld [de], a
	inc e
	dec c
	jr nz, .asm_3c081
	ld a, $c
	add e
	ld e, a
	jr nc, .asm_3c08e
	inc d
.asm_3c08e
	dec b
	jr nz, .asm_3c07f
	call EnableLCD
	ld a, $90
	ld [$ffb0], a
	ld [rWY], a ; $ff4a
	xor a
	ld [$ffd7], a
	ld [$ffaf], a
	dec a
	ld [$cfcb], a
	call Delay3
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld b, $70
	ld c, $90
	ld a, c
	ld [$ffae], a
	call DelayFrame
	ld a, $e4
	ld [rBGP], a ; $ff47
	ld [rOBP0], a ; $ff48
	ld [rOBP1], a ; $ff49
.asm_3c0bb
	ld h, b
	ld l, $40
	call Func_3c110
	inc b
	inc b
	ld h, $0
	ld l, $60
	call Func_3c110
	call Func_3c0ff
	ld a, c
	ld [$ffae], a
	dec c
	dec c
	jr nz, .asm_3c0bb
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, $31
	ld [$ffe1], a
	FuncCoord 1, 5 ; $c405
	ld hl, Coord
	ld a, $1
	call Predef ; indirect jump to Func_3f0c6 (3f0c6 (f:70c6))
	xor a
	ld [$ffb0], a
	ld [rWY], a ; $ff4a
	inc a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Delay3
	ld b, $1
	call GoPAL_SET
	call ResetLCD_OAM
	ld hl, PrintBeginningBattleText
	ld b, BANK(PrintBeginningBattleText)
	jp Bankswitch

Func_3c0ff: ; 3c0ff (f:40ff)
	push bc
	ld hl, $c301
	ld c, $15
	ld de, $4
.asm_3c108
	dec [hl]
	dec [hl]
	add hl, de
	dec c
	jr nz, .asm_3c108
	pop bc
	ret

Func_3c110: ; 3c110 (f:4110)
	ld a, [$ff44]
	cp l
	jr nz, Func_3c110
	ld a, h
	ld [rSCX], a ; $ff43
.asm_3c118
	ld a, [$ff44]
	cp h
	jr z, .asm_3c118
	ret

Func_3c11e: ; 3c11e (f:411e)
	xor a
	ld [W_PLAYERMONSALIVEFLAGS], a
	ld [$ccf5], a
	ld [$cd6a], a
	inc a
	ld [$d11d], a
	ld hl, W_ENEMYMON1HP ; $d8a5
	ld bc, $2b
	ld d, $3
.asm_3c134
	inc d
	ld a, [hli]
	or [hl]
	jr nz, .asm_3c13c
	add hl, bc
	jr .asm_3c134
.asm_3c13c
	ld a, d
	ld [$cc3e], a
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	call nz, Func_3c92a
	ld c, $28
	call DelayFrames
	call SaveScreenTilesToBuffer1
.asm_3c14f
	call AnyPokemonAliveCheck
	ld a, d
	and a
	jp z, HandlePlayerBlackOut
	call LoadScreenTilesFromBuffer1
	ld a, [W_BATTLETYPE] ; $d05a
	and a
	jp z, Func_3c1ad
.asm_3c161
	call InitBattleMenu
	ret c
	ld a, [$cd6a]
	and a
	jr z, .asm_3c161
	ld a, [W_NUMSAFARIBALLS] ; $da47
	and a
	jr nz, .asm_3c17a
	call LoadScreenTilesFromBuffer1
	ld hl, OutOfSafariBallsText
	jp PrintText
.asm_3c17a
	callab PrintSafariZoneBattleText
	ld a, [$cffb]
	add a
	ld b, a
	jp c, asm_3c202
	ld a, [$cce9]
	and a
	jr z, .asm_3c194
	srl b
	srl b
.asm_3c194
	ld a, [$cce8]
	and a
	jr z, .asm_3c1a0
	sla b
	jr nc, .asm_3c1a0
	ld b, $ff
.asm_3c1a0
	call GenRandom
	cp b
	jr nc, .asm_3c14f
	jr asm_3c202

OutOfSafariBallsText: ; 3c1a8 (f:41a8)
	TX_FAR _OutOfSafariBallsText
	db "@"

Func_3c1ad: ; 3c1ad (f:41ad)
	xor a
	ld [wWhichPokemon], a ; $cf92
.asm_3c1b1
	call Func_3ca97
	jr nz, .asm_3c1bc
	ld hl, wWhichPokemon ; $cf92
	inc [hl]
	jr .asm_3c1b1
.asm_3c1bc
	ld a, [wWhichPokemon] ; $cf92
	ld [wPlayerMonNumber], a ; $cc2f
	inc a
	ld hl, W_NUMINPARTY ; $d163
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]
	ld [$cf91], a
	ld [$cfd9], a
	call LoadScreenTilesFromBuffer1
	FuncCoord 1, 5 ; $c405
	ld hl, Coord
	ld a, $9
	call Func_3c8df
	call SaveScreenTilesToBuffer1
	ld a, [wWhichPokemon] ; $cf92
	ld c, a
	ld b, $1
	push bc
	ld hl, W_PLAYERMONSALIVEFLAGS
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	ld hl, $ccf5
	pop bc
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	call Func_3cba6
	call LoadScreenTilesFromBuffer1
	call Func_3cc91
	jr MainInBattleLoop
asm_3c202: ; 3c202 (f:4202)
	call LoadScreenTilesFromBuffer1
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	ld hl, WildRanText
	jr nz, .asm_3c216
	xor a
	ld [$cf0b], a
	ld hl, EnemyRanText
.asm_3c216
	call PrintText
	ld a, (SFX_08_44 - SFX_Headers_08) / 3
	call PlaySoundWaitForCurrent
	xor a
	ld [H_WHOSETURN], a ; $fff3
	ld hl, AnimationSlideEnemyMonOut
	ld b, BANK(AnimationSlideEnemyMonOut)
	jp Bankswitch

WildRanText: ; 3c229 (f:4229)
	TX_FAR _WildRanText
	db "@"

EnemyRanText: ; 3c22e (f:422e)
	TX_FAR _EnemyRanText
	db "@"

MainInBattleLoop: ; 3c233 (f:4233)
	call ReadPlayerMonCurHPAndStatus
	ld hl, W_PLAYERMONCURHP
	ld a, [hli]
	or [hl]
	jp z, HandlePlayerMonFainted  ; test if current player mon is fainted
	ld hl, $cfe6
	ld a, [hli]
	or [hl]
	jp z, Func_3c525
	call SaveScreenTilesToBuffer1
	xor a
	ld [$d11d], a
	ld a, [$d063]
	and $60
	jr nz, .asm_3c2a6 ; 0x3c252 $52
	ld hl, $d067
	res 3, [hl]
	ld hl, $d062
	res 3, [hl]
	ld a, [hl]
	and $12
	jr nz, .asm_3c2a6 ; 0x3c261 $43
	call InitBattleMenu ; show battle menu
	ret c
	ld a, [$d078]
	and a
	ret nz
	ld a, [$d018]
	and $27
	jr nz, .asm_3c2a6 ; 0x3c271 $33
	ld a, [$d062]
	and $21
	jr nz, .asm_3c2a6 ; 0x3c278 $2c
	ld a, [$d067]
	bit 5, a
	jr z, .asm_3c288 ; 0x3c27f $7
	ld a, $ff
	ld [$ccdc], a
	jr .asm_3c2a6 ; 0x3c286 $1e
.asm_3c288
	ld a, [$cd6a]
	and a
	jr nz, .asm_3c2a6 ; 0x3c28c $18
	ld [$ccdb], a
	inc a
	ld [$d07c], a
	xor a
	ld [$cc35], a
	call MoveSelectionMenu
	push af
	call LoadScreenTilesFromBuffer1
	call Func_3cd5a
	pop af
	jr nz, MainInBattleLoop
.asm_3c2a6
	call SelectEnemyMove
	ld a, [W_ISLINKBATTLE]
	cp $4
	jr nz, .noLinkBattle
	ld a, [$cc3e]
	cp $f
	jp z, asm_3c202
	cp $e
	jr z, .noLinkBattle
	cp $d
	jr z, .noLinkBattle
	sub $4
	jr c, .noLinkBattle
	ld a, [$d062]
	bit 5, a
	jr z, .asm_3c2dd ; 0x3c2c9 $12
	ld a, [$cc2e]
	ld hl, W_PLAYERMONMOVES
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]
	cp $76
	jr nz, .asm_3c2dd ; 0x3c2d8 $3
	ld [wPlayerSelectedMove], a
.asm_3c2dd
	callab Func_3a74b
.noLinkBattle
	ld a, [wPlayerSelectedMove]
	cp QUICK_ATTACK
	jr nz, .playerDidNotUseQuickAttack
	ld a, [wEnemySelectedMove]
	cp QUICK_ATTACK
	jr z, .compareSpeed  ; both used Quick Attack
	jp .playerMovesFirst ; player used Quick Attack
.playerDidNotUseQuickAttack
	ld a, [wEnemySelectedMove]
	cp QUICK_ATTACK
	jr z, .enemyMovesFirst
	ld a, [wPlayerSelectedMove]
	cp COUNTER
	jr nz, .playerDidNotUseCounter
	ld a, [wEnemySelectedMove]
	cp COUNTER
	jr z, .compareSpeed ; both used Counter
	jr .enemyMovesFirst ; player used Counter
.playerDidNotUseCounter
	ld a, [wEnemySelectedMove]
	cp COUNTER
	jr z, .playerMovesFirst
.compareSpeed
	ld de, W_PLAYERMONSPEED ; player speed value
	ld hl, W_ENEMYMONSPEED ; enemy speed value
	ld c, $2
	call StringCmp ; compare speed values
	jr z, .speedEqual
	jr nc, .playerMovesFirst
	jr .enemyMovesFirst
.speedEqual
	ld a, [$ffaa]
	cp $2
	jr z, .invertOutcome
	call GenRandomInBattle
	cp $80
	jr c, .playerMovesFirst
	jr .enemyMovesFirst
.invertOutcome
	call GenRandomInBattle
	cp $80
	jr c, .enemyMovesFirst
	jr .playerMovesFirst
.enemyMovesFirst
	ld a, $1
	ld [H_WHOSETURN], a
	callab TrainerAI
	jr c, .AIActionUsedEnemyFirst
	call Func_3e6bc ; execute enemy move
	ld a, [$d078]
	and a
	ret nz
	ld a, b
	and a
	jp z, HandlePlayerMonFainted
.AIActionUsedEnemyFirst
	call HandlePoisonBurnLeechSeed
	jp z, Func_3c525
	call Func_3cd5a
	call Func_3d65e ; execute player move
	ld a, [$d078]
	and a
	ret nz
	ld a, b
	and a
	jp z, Func_3c525
	call HandlePoisonBurnLeechSeed
	jp z, HandlePlayerMonFainted
	call Func_3cd5a
	call Func_3c50f
	jp MainInBattleLoop
.playerMovesFirst
	call Func_3d65e ; execute player move
	ld a, [$d078]
	and a
	ret nz
	ld a, b
	and a
	jp z, Func_3c525
	call HandlePoisonBurnLeechSeed
	jp z, HandlePlayerMonFainted
	call Func_3cd5a
	ld a, $1
	ld [H_WHOSETURN], a
	callab TrainerAI
	jr c, .AIActionUsedPlayerFirst
	call Func_3e6bc ; execute enemy move
	ld a, [$d078]
	and a
	ret nz
	ld a, b
	and a
	jp z, HandlePlayerMonFainted
.AIActionUsedPlayerFirst
	call HandlePoisonBurnLeechSeed
	jp z, Func_3c525
	call Func_3cd5a
	call Func_3c50f
	jp MainInBattleLoop

HandlePoisonBurnLeechSeed: ; 3c3bd (f:43bd)
	ld hl, W_PLAYERMONCURHP ; $d015
	ld de, W_PLAYERMONSTATUS ; $d018
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .playersTurn
	ld hl, W_ENEMYMONCURHP ; $cfe6
	ld de, W_ENEMYMONSTATUS ; $cfe9
.playersTurn
	ld a, [de]
	and (1 << BRN) | (1 << PSN)
	jr z, .notBurnedOrPoisoned
	push hl
	ld hl, HurtByPoisonText
	ld a, [de]
	and 1 << BRN
	jr z, .poisoned
	ld hl, HurtByBurnText
.poisoned
	call PrintText
	xor a
	ld [$cc5b], a
	ld a,BURN_PSN_ANIM
	call PlayMoveAnimation   ; play burn/poison animation
	pop hl
	call HandlePoisonBurnLeechSeed_DecreaseOwnHP
.notBurnedOrPoisoned
	ld de, W_PLAYERBATTSTATUS2 ; $d063
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .playersTurn2
	ld de, W_ENEMYBATTSTATUS2 ; $d068
.playersTurn2
	ld a, [de]
	add a
	jr nc, .notLeechSeeded
	push hl
	ld a, [H_WHOSETURN] ; $fff3
	push af
	xor $1
	ld [H_WHOSETURN], a ; $fff3
	xor a
	ld [$cc5b], a
	ld a,ABSORB
	call PlayMoveAnimation ; play leech seed animation (from opposing mon)
	pop af
	ld [H_WHOSETURN], a ; $fff3
	pop hl
	call HandlePoisonBurnLeechSeed_DecreaseOwnHP
	call HandlePoisonBurnLeechSeed_IncreaseEnemyHP
	push hl
	ld hl, HurtByLeechSeedText
	call PrintText
	pop hl
.notLeechSeeded
	ld a, [hli]
	or [hl]
	ret nz          ; test if fainted
	call Func_3cd5a
	ld c, $14
	call DelayFrames
	xor a
	ret

HurtByPoisonText: ; 3c42e (f:442e)
	TX_FAR _HurtByPoisonText
	db "@"

HurtByBurnText: ; 3c433 (f:4433)
	TX_FAR _HurtByBurnText
	db "@"

HurtByLeechSeedText: ; 3c438 (f:4438)
	TX_FAR _HurtByLeechSeedText
	db "@"

; decreases the mon's current HP by 1/16 of the Max HP (multiplied by number of toxic ticks if active)
; note that the toxic ticks are considered even if the damage is not poison (hence the Leech Seed glitch)
; hl: HP pointer
; bc (out): total damage
HandlePoisonBurnLeechSeed_DecreaseOwnHP: ; 3c43d (f:443d)
	push hl
	push hl
	ld bc, $e      ; skip to max HP
	add hl, bc
	ld a, [hli]    ; load max HP
	ld [wHPBarMaxHP+1], a
	ld b, a
	ld a, [hl]
	ld [wHPBarMaxHP], a
	ld c, a
	srl b
	rr c
	srl b
	rr c
	srl c
	srl c         ; c = max HP/16 (assumption: HP < 1024)
	ld a, c
	and a
	jr nz, .nonZeroDamage
	inc c         ; damage is at least 1
.nonZeroDamage
	ld hl, W_PLAYERBATTSTATUS3 ; $d064
	ld de, W_PLAYERTOXICCOUNTER ; $d06c
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .playersTurn
	ld hl, W_ENEMYBATTSTATUS3 ; $d069
	ld de, W_ENEMYTOXICCOUNTER ; $d071
.playersTurn
	bit 0, [hl]
	jr z, .noToxic
	ld a, [de]    ; increment toxic counter
	inc a
	ld [de], a
	ld hl, $0000
.toxicTicksLoop
	add hl, bc
	dec a
	jr nz, .toxicTicksLoop
	ld b, h       ; bc = damage * toxic counter
	ld c, l
.noToxic
	pop hl
	inc hl
	ld a, [hl]    ; subtract total damage from current HP
	ld [wHPBarOldHP], a
	sub c
	ld [hld], a
	ld [wHPBarNewHP], a
	ld a, [hl]
	ld [wHPBarOldHP+1], a
	sbc b
	ld [hl], a
	ld [wHPBarNewHP+1], a
	jr nc, .noOverkill
	xor a         ; overkill: zero HP
	ld [hli], a
	ld [hl], a
	ld [wHPBarNewHP], a
	ld [wHPBarNewHP+1], a
.noOverkill
	call UpdateCurMonHPBar
	pop hl
	ret

; adds bc to enemy HP
HandlePoisonBurnLeechSeed_IncreaseEnemyHP: ; 3c4a3 (f:44a3)
	push hl
	ld hl, W_ENEMYMONMAXHP ; $cff4
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .playersTurn
	ld hl, W_PLAYERMONMAXHP ; $d023
.playersTurn
	ld a, [hli]
	ld [wHPBarMaxHP+1], a
	ld a, [hl]
	ld [wHPBarMaxHP], a
	ld de, $fff2
	add hl, de           ; skip back fomr max hp to current hp
	ld a, [hl]
	ld [wHPBarOldHP], a ; add bc to current HP
	add c
	ld [hld], a
	ld [wHPBarNewHP], a
	ld a, [hl]
	ld [wHPBarOldHP+1], a
	adc b
	ld [hli], a
	ld [wHPBarNewHP+1], a
	ld a, [wHPBarMaxHP]
	ld c, a
	ld a, [hld]
	sub c
	ld a, [wHPBarMaxHP+1]
	ld b, a
	ld a, [hl]
	sbc b
	jr c, .noOverfullHeal
	ld a, b                ; overfull heal, set HP to max HP
	ld [hli], a
	ld [wHPBarNewHP+1], a
	ld a, c
	ld [hl], a
	ld [wHPBarNewHP], a
.noOverfullHeal
	ld a, [H_WHOSETURN] ; $fff3
	xor $1
	ld [H_WHOSETURN], a ; $fff3
	call UpdateCurMonHPBar
	ld a, [H_WHOSETURN] ; $fff3
	xor $1
	ld [H_WHOSETURN], a ; $fff3
	pop hl
	ret

UpdateCurMonHPBar: ; 3c4f6 (f:44f6)
	FuncCoord 10, 9 ; $c45e
	ld hl, Coord    ; tile pointer to player HP bar
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, $1
	jr z, .playersTurn
	FuncCoord 2, 2 ; $c3ca
	ld hl, Coord    ; tile pointer to enemy HP bar
	xor a
.playersTurn
	push bc
	ld [wListMenuID], a ; $cf94
	ld a, $48
	call Predef ; indirect jump to UpdateHPBar (fa1d (3:7a1d))
	pop bc
	ret

Func_3c50f: ; 3c50f (f:450f)
	ld a, [$d06a]
	and a
	jr nz, .asm_3c51a
	ld hl, W_PLAYERBATTSTATUS1 ; $d062
	res 5, [hl]
.asm_3c51a
	ld a, [$d06f]
	and a
	ret nz
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	res 5, [hl]
	ret

Func_3c525: ; 3c525 (f:4525)
	xor a
	ld [$ccf0], a
	call FaintEnemyPokemon
	call AnyPokemonAliveCheck
	ld a, d
	and a
	jp z, HandlePlayerBlackOut
	ld hl, W_PLAYERMONCURHP ; $d015
	ld a, [hli]
	or [hl]
	call nz, Func_3cd60
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	ret z
	call Func_3c64f
	jp z, TrainerBattleVictory
	ld hl, W_PLAYERMONCURHP ; $d015
	ld a, [hli]
	or [hl]
	jr nz, .asm_3c555
	call Func_3c79b
	ret c
	call Func_3c7d8
.asm_3c555
	ld a, $1
	ld [$cd6a], a
	call Func_3c664
	jp z, asm_3c202
	xor a
	ld [$cd6a], a
	jp MainInBattleLoop

FaintEnemyPokemon ; 0x3c567
	call ReadPlayerMonCurHPAndStatus
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	jr z, .wild
	ld a, [W_ENEMYMONNUMBER] ; $cfe8
	ld hl, W_ENEMYMON1HP
	ld bc, $2c ; mon struct len
	call AddNTimes
	xor a
	ld [hli], a
	ld [hl], a
.wild
	ld hl, W_PLAYERBATTSTATUS1 ; $d062
	res 2, [hl]
	xor a
	ld [W_NUMHITS], a ; $d074
	ld hl, $d065 ; enemy statuses
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hl], a
	ld [W_ENEMYDISABLEDMOVE], a ; $d072
	ld [$ccef], a
	ld [$ccf3], a
	ld hl, $ccf1
	ld [hli], a
	ld [hl], a
	FuncCoord 12, 5 ; $c410
	ld hl, Coord
	FuncCoord 12, 6 ; $c424
	ld de, Coord
	call Func_3c893
	ld hl, wTileMap
	ld bc, $40b
	call ClearScreenArea
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	jr z, .wild_win
	xor a
	ld [$c0f1], a
	ld [$c0f2], a
	ld a, (SFX_08_48 - SFX_Headers_08) / 3 ; SFX_FALL?
	call PlaySoundWaitForCurrent
.sfxwait
	ld a, [$c02a]
	cp (SFX_08_48 - SFX_Headers_08) / 3
	jr z, .sfxwait
	ld a, (SFX_08_43 - SFX_Headers_08) / 3 ; SFX_DROP
	call PlaySound
	call WaitForSoundToFinish
	jr .sfxplayed
.wild_win
	call Func_3c643
	ld a, MUSIC_DEFEATED_WILD_MON
	call Func_3c6ee
.sfxplayed
	ld hl, W_PLAYERMONCURHP ; $d015
	ld a, [hli]
	or [hl]
	jr nz, .playermonnotfaint
	ld a, [$ccf0]
	and a
	jr nz, .playermonnotfaint
	call Func_3c741
.playermonnotfaint
	call AnyPokemonAliveCheck
	ld a, d
	and a
	ret z
	ld hl, EnemyMonFaintedText
	call PrintText
	call Func_3ee94
	call SaveScreenTilesToBuffer1
	xor a
	ld [$cf0b], a
	ld b, EXP__ALL
	call IsItemInBag
	push af
	jr z, .no_exp_all
	ld hl, $d002
	ld b, $7
.exp_all_loop
	srl [hl]
	inc hl
	dec b
	jr nz, .exp_all_loop
.no_exp_all
	xor a
	ld [$cc5b], a
	callab GainExperience
	pop af
	ret z
	ld a, $1
	ld [$cc5b], a
	ld a, [W_NUMINPARTY] ; $d163
	ld b, $0
.asm_3c62c
	scf
	rl b
	dec a
	jr nz, .asm_3c62c
	ld a, b
	ld [W_PLAYERMONSALIVEFLAGS], a
	ld hl, GainExperience
	ld b, BANK(GainExperience)
	jp Bankswitch

EnemyMonFaintedText: ; 0x3c63e
	TX_FAR _EnemyMonFaintedText
	db "@"

Func_3c643: ; 3c643 (f:4643)
	xor a
	ld [$d083], a
	ld [$c02a], a
	inc a
	ld [$ccf6], a
	ret

Func_3c64f: ; 3c64f (f:464f)
	ld a, [wEnemyPartyCount] ; $d89c
	ld b, a
	xor a
	ld hl, W_ENEMYMON1HP ; $d8a5
	ld de, $2c
.asm_3c65a
	or [hl]
	inc hl
	or [hl]
	dec hl
	add hl, de
	dec b
	jr nz, .asm_3c65a
	and a
	ret

Func_3c664: ; 3c664 (f:4664)
	ld hl, $cf1e
	ld e, $30
	call Func_3ce90
	callab DrawEnemyPokeballs
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr nz, .asm_3c687
	call Func_3d605
	ld a, [$cc3e]
	cp $f
	ret z
	call LoadScreenTilesFromBuffer1
.asm_3c687
	call EnemySendOut
	xor a
	ld [W_ENEMYMOVENUM], a ; $cfcc
	ld [$cd6a], a
	ld [$ccd5], a
	inc a
	ret

TrainerBattleVictory: ; 3c696 (f:4696)
	call Func_3c643
	ld b, MUSIC_DEFEATED_GYM_LEADER
	ld a, [W_GYMLEADERNO] ; $d05c
	and a
	jr nz, .gymleader
	ld b, MUSIC_DEFEATED_TRAINER
.gymleader
	ld a, [W_TRAINERCLASS] ; $d031
	cp SONY3 ; final battle against rival
	jr nz, .notrival
	ld b, MUSIC_DEFEATED_GYM_LEADER
	ld hl, W_FLAGS_D733
	set 1, [hl]
.notrival
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	ld a, b
	call nz, Func_3c6ee
	ld hl, TrainerDefeatedText
	call PrintText
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	ret z
	call ScrollTrainerPicAfterBattle
	ld c, $28
	call DelayFrames
	call Func_3381
	ld hl, MoneyForWinningText
	call PrintText
	ld de, wPlayerMoney + 2 ; $d349
	ld hl, $d07b
	ld c, $3
	ld a, $b
	jp Predef ; indirect jump to Func_f81d (f81d (3:781d))

MoneyForWinningText: ; 3c6e4 (f:46e4)
	TX_FAR _MoneyForWinningText
	db "@"

TrainerDefeatedText: ; 3c6e9 (f:46e9)
	TX_FAR _TrainerDefeatedText
	db "@"

Func_3c6ee: ; 3c6ee (f:46ee)
	push af
	ld a, $ff
	ld [$c0ee], a
	call PlaySoundWaitForCurrent
	ld c, BANK(Music_DefeatedTrainer)
	pop af
	call PlayMusic
	jp Delay3

HandlePlayerMonFainted: ; 3c700 (f:4700)
	ld a, $1
	ld [$ccf0], a
	call Func_3c741
	call AnyPokemonAliveCheck     ; test if any more mons are alive
	ld a, d
	and a
	jp z, HandlePlayerBlackOut
	ld hl, W_ENEMYMONCURHP ; $cfe6
	ld a, [hli]
	or [hl]
	jr nz, .enemyMonNotFainted
	call FaintEnemyPokemon
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	ret z            ; if wild encounter, battle is over
	call Func_3c64f
	jp z, TrainerBattleVictory
.enemyMonNotFainted
	call Func_3c79b
	ret c
	call Func_3c7d8
	jp nz, MainInBattleLoop
	ld a, $1
	ld [$cd6a], a
	call Func_3c664
	jp z, asm_3c202
	xor a
	ld [$cd6a], a
	jp MainInBattleLoop

Func_3c741: ; 3c741 (f:4741)
	ld a, [wPlayerMonNumber] ; $cc2f
	ld c, a
	ld hl, W_PLAYERMONSALIVEFLAGS ; clear fainted mon's alive flag
	ld b, $0
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	res 2, [hl]   ; reset "attacking multiple times" flag
	ld a, [$d083]
	bit 7, a      ; skip sound flag (red bar (?))
	jr z, .skipWaitForSound
	ld a, $ff
	ld [$d083], a
	call WaitForSoundToFinish
.skipWaitForSound
	ld hl, $cd05
	ld [hli], a
	ld [hl], a
	ld [W_PLAYERMONSTATUS], a ; $d018
	call ReadPlayerMonCurHPAndStatus
	FuncCoord 9, 7 ; $c435
	ld hl, Coord
	ld bc, $50b
	call ClearScreenArea
	FuncCoord 1, 10 ; $c469
	ld hl, Coord
	FuncCoord 1, 11 ; $c47d
	ld de, Coord
	call Func_3c893
	ld a, $1
	ld [$cf0b], a
	ld a, [$ccf0]
	and a
	ret z
	ld a, [W_PLAYERMONID]
	call PlayCry
	ld hl, PlayerMonFaintedText
	jp PrintText

PlayerMonFaintedText: ; 3c796 (f:4796)
	TX_FAR _PlayerMonFaintedText
	db "@"

Func_3c79b: ; 3c79b (f:479b)
	call Func_3ee94
	call SaveScreenTilesToBuffer1
	ld a, [W_ISINBATTLE] ; $d057
	and a
	dec a
	ret nz
	ld hl, UseNextMonText
	call PrintText
.asm_3c7ad
	FuncCoord 13, 9 ; $c461
	ld hl, Coord
	ld bc, $a0e
	ld a, $14
	ld [$d125], a
	call DisplayTextBoxID
	ld a, [$d12e]
	cp $2
	jr z, .asm_3c7c4
	and a
	ret
.asm_3c7c4
	ld a, [wCurrentMenuItem] ; $cc26
	and a
	jr z, .asm_3c7ad
	ld hl, W_PARTYMON1_SPEED ; $d193
	ld de, W_ENEMYMONSPEED
	jp Func_3cab9

UseNextMonText: ; 3c7d3 (f:47d3)
	TX_FAR _UseNextMonText
	db "@"

Func_3c7d8: ; 3c7d8 (f:47d8)
	ld a, $2
	ld [$d07d], a
	call DisplayPartyMenu
.asm_3c7e0
	jr nc, .asm_3c7e7
.asm_3c7e2
	call GoBackToPartyMenu
	jr .asm_3c7e0
.asm_3c7e7
	call Func_3ca97
	jr z, .asm_3c7e2
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr nz, .asm_3c7fa
	inc a
	ld [$cd6a], a
	call Func_3d605
.asm_3c7fa
	xor a
	ld [$cd6a], a
	call CleanLCD_OAM
	ld a, [wWhichPokemon] ; $cf92
	ld [wPlayerMonNumber], a ; $cc2f
	ld c, a
	ld hl, W_PLAYERMONSALIVEFLAGS
	ld b, $1
	push bc
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	pop bc
	ld hl, $ccf5
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	call Func_3cba6
	call GBPalWhiteOut
	call Func_3ee5b
	call LoadScreenTilesFromBuffer1
	call GoPAL_SET_CF1C
	call GBPalNormal
	call Func_3cc91
	ld hl, W_ENEMYMONCURHP ; $cfe6
	ld a, [hli]
	or [hl]
	ret

; called when player is out of usable mons.
; prints approriate lose message, sets carry flag if player blacked out (special case for initial rival fight)
HandlePlayerBlackOut: ; 3c837 (f:4837)
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr z, .notSony1Battle
	ld a, [W_CUROPPONENT] ; $d059
	cp $c8 + SONY1
	jr nz, .notSony1Battle
	ld hl, wTileMap  ; sony 1 battle
	ld bc, $815
	call ClearScreenArea
	call ScrollTrainerPicAfterBattle
	ld c, $28
	call DelayFrames
	ld hl, Sony1WinText
	call PrintText
	ld a, [W_CURMAP]
	cp OAKS_LAB
	ret z            ; starter battle in oak's lab: don't black out
.notSony1Battle
	ld b, $0
	call GoPAL_SET
	ld hl, PlayerBlackedOutText2
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr nz, .noLinkBattle
	ld hl, LinkBattleLostText
.noLinkBattle
	call PrintText
	ld a, [$d732]
	res 5, a
	ld [$d732], a
	call ClearScreen
	scf
	ret

Sony1WinText: ; 3c884 (f:4884)
	TX_FAR _Sony1WinText
	db "@"

PlayerBlackedOutText2: ; 3c889 (f:4889)
	TX_FAR _PlayerBlackedOutText2
	db "@"

LinkBattleLostText: ; 3c88e (f:488e)
	TX_FAR _LinkBattleLostText
	db "@"

Func_3c893: ; 3c893 (f:4893)
	ld a, [$d730]
	push af
	set 6, a
	ld [$d730], a
	ld b, $7
.asm_3c89e
	push bc
	push de
	push hl
	ld b, $6
.asm_3c8a3
	push bc
	push hl
	push de
	ld bc, $7
	call CopyData
	pop de
	pop hl
	ld bc, $ffec
	add hl, bc
	push hl
	ld h, d
	ld l, e
	add hl, bc
	ld d, h
	ld e, l
	pop hl
	pop bc
	dec b
	jr nz, .asm_3c8a3
	ld bc, $14
	add hl, bc
	ld de, SevenSpacesText
	call PlaceString
	ld c, $2
	call DelayFrames
	pop hl
	pop de
	pop bc
	dec b
	jr nz, .asm_3c89e
	pop af
	ld [$d730], a
	ret

SevenSpacesText: ; 3c8d7 (f:48d7)
	db "       @"

Func_3c8df: ; 3c8df (f:48df)
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld c, a
.asm_3c8e2
	push bc
	push hl
	ld b, $7
.asm_3c8e6
	push hl
	ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
	ld c, a
.asm_3c8ea
	ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
	cp $8
	jr z, .asm_3c8f5
	ld a, [hld]
	ld [hli], a
	inc hl
	jr .asm_3c8f8
.asm_3c8f5
	ld a, [hli]
	ld [hld], a
	dec hl
.asm_3c8f8
	dec c
	jr nz, .asm_3c8ea
	pop hl
	ld de, $14
	add hl, de
	dec b
	jr nz, .asm_3c8e6
	ld c, $2
	call DelayFrames
	pop hl
	pop bc
	dec c
	jr nz, .asm_3c8e2
	ret

; XXX this needs cleaning up. it's what runs when a juggler switches pokemon
EnemySendOut: ; 3c90e (f:490e)
	ld hl,W_PLAYERMONSALIVEFLAGS
	xor a
	ld [hl],a
	ld a,[$CC2F]
	ld c,a
	ld b,1
	push bc
	ld a,$10
	call Predef
	ld hl,$CCF5
	xor a
	ld [hl],a
	pop bc
	ld a,$10
	call Predef
Func_3c92a: ; 3c92a (f:492a)
	xor a
	ld hl,$D065
	ld [hli],a
	ld [hli],a
	ld [hli],a
	ld [hli],a
	ld [hl],a
	ld [$D072],a
	ld [$CCEF],a
	ld [$CCF3],a
	ld hl,$CCF1
	ld [hli],a
	ld [hl],a
	dec a
	ld [wAICount],a
	ld hl,W_PLAYERBATTSTATUS1
	res 5,[hl]
	FuncCoord 18, 0 ; $c3b2
	ld hl,Coord
	ld a,8
	call Func_3c8df
	call Func_3ee94
	call SaveScreenTilesToBuffer1
	ld a,[$D12B]
	cp 4
	jr nz,.next
	ld a,[$CC3E]
	sub 4
	ld [wWhichPokemon],a
	jr .next3
.next
	ld b,$FF
.next2
	inc b
	ld a,[$CFE8]
	cp b
	jr z,.next2
	ld hl,$D8A4
	ld a,b
	ld [wWhichPokemon],a
	push bc
	ld bc,$2C
	call AddNTimes
	pop bc
	inc hl
	ld a,[hli]
	ld c,a
	ld a,[hl]
	or c
	jr z,.next2
.next3
	ld a,[wWhichPokemon]
	ld hl,$D8C5
	ld bc,$2C
	call AddNTimes
	ld a,[hl]
	ld [$D127],a
	ld a,[wWhichPokemon]
	inc a
	ld hl,$D89C
	ld c,a
	ld b,0
	add hl,bc
	ld a,[hl]
	ld [W_ENEMYMONID],a
	ld [$CF91],a
	call Func_3eb01
	ld hl,$CFE6
	ld a,[hli]
	ld [$CCE3],a
	ld a,[hl]
	ld [$CCE4],a
	ld a,1
	ld [$CC26],a
	ld a,[$D11D]
	dec a
	jr z,.next4
	ld a,[W_NUMINPARTY]
	dec a
	jr z,.next4
	ld a,[$D12B]
	cp 4
	jr z,.next4
	ld a,[$D355]
	bit 6,a
	jr nz,.next4
	ld hl, TrainerAboutToUseText
	call PrintText
	FuncCoord 0, 7 ; $c42c
	ld hl,Coord
	ld bc,$0801
	ld a,$14
	ld [$D125],a
	call DisplayTextBoxID
	ld a,[$CC26]
	and a
	jr nz,.next4
	ld a,2
	ld [$D07D],a
	call DisplayPartyMenu
.next9
	ld a,1
	ld [$CC26],a
	jr c,.next7
	ld hl,$CC2F
	ld a,[wWhichPokemon]
	cp [hl]
	jr nz,.next6
	ld hl,AlreadyOutText
	call PrintText
.next8
	call GoBackToPartyMenu
	jr .next9
.next6
	call Func_3ca97
	jr z,.next8
	xor a
	ld [$CC26],a
.next7
	call GBPalWhiteOut
	call Func_3ee5b
	call LoadScreenTilesFromBuffer1
.next4
	call CleanLCD_OAM
	ld hl,wTileMap
	ld bc,$040B
	call ClearScreenArea
	ld b,1
	call GoPAL_SET
	call GBPalNormal
	ld hl,TrainerSentOutText
	call PrintText
	ld a,[W_ENEMYMONID]
	ld [$CF91],a
	ld [$D0B5],a
	call GetMonHeader
	ld de,$9000
	call LoadMonFrontSprite
	ld a,$CF
	ld [$FFE1],a
	FuncCoord 15, 6 ; $c427
	ld hl,Coord
	ld a,2
	call Predef
	ld a,[W_ENEMYMONID]
	call PlayCry
	call Func_3cdec
	ld a,[$CC26]
	and a
	ret nz
	xor a
	ld [W_PLAYERMONSALIVEFLAGS],a
	ld [$CCF5],a
	call SaveScreenTilesToBuffer1
	jp Func_3d1ba

TrainerAboutToUseText: ; 3ca79 (f:4a79)
	TX_FAR _TrainerAboutToUseText
	db "@"

TrainerSentOutText: ; 3ca7e (f:4a7e)
	TX_FAR _TrainerSentOutText
	db "@"

; tests if the player has any pokemon that are not fainted
; sets d = 0 if all fainted, d != 0 if some mons are still alive
AnyPokemonAliveCheck: ; 3ca83 (f:4a83)
	ld a, [W_NUMINPARTY] ; $d163
	ld e, a
	xor a
	ld hl, W_PARTYMON1_HP ; $d16c
	ld bc, W_PARTYMON2DATA - W_PARTYMON1DATA - 1
.partyMonsLoop
	or [hl]
	inc hl
	or [hl]
	add hl, bc
	dec e
	jr nz, .partyMonsLoop
	ld d, a
	ret

Func_3ca97: ; 3ca97 (f:4a97)
	ld a, [wWhichPokemon] ; $cf92
	ld hl, W_PARTYMON1_HP ; $d16c
	ld bc, $2c
	call AddNTimes
	ld a, [hli]
	or [hl]
	ret nz
	ld a, [$d11d]
	and a
	jr nz, .asm_3cab2
	ld hl, NoWillText
	call PrintText
.asm_3cab2
	xor a
	ret

NoWillText: ; 3cab4 (f:4ab4)
	TX_FAR _NoWillText
	db "@"

Func_3cab9: ; 3cab9 (f:4ab9)
	call IsGhostBattle
	jp z, .asm_3cb5c
	ld a, [W_BATTLETYPE] ; $d05a
	cp $2
	jp z, .asm_3cb5c
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jp z, .asm_3cb5c
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	jr nz, .asm_3cb4c
	ld a, [$d120]
	inc a
	ld [$d120], a
	ld a, [hli]
	ld [$ff97], a
	ld a, [hl]
	ld [$ff98], a
	ld a, [de]
	ld [$ff8d], a
	inc de
	ld a, [de]
	ld [$ff8e], a
	call LoadScreenTilesFromBuffer1
	ld de, $ff97
	ld hl, $ff8d
	ld c, $2
	call StringCmp
	jr nc, .asm_3cb5c
	xor a
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, $20
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	call Multiply
	ld a, [$ff97]
	ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	ld a, [$ff98]
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, [$ff8d]
	ld b, a
	ld a, [$ff8e]
	srl b
	rr a
	srl b
	rr a
	and a
	jr z, .asm_3cb5c
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld b, $2
	call Divide
	ld a, [$ff97]
	and a
	jr nz, .asm_3cb5c
	ld a, [$d120]
	ld c, a
.asm_3cb2b
	dec c
	jr z, .asm_3cb39
	ld b, $1e
	ld a, [$ff98]
	add b
	ld [$ff98], a
	jr c, .asm_3cb5c
	jr .asm_3cb2b
.asm_3cb39
	call GenRandomInBattle
	ld b, a
	ld a, [$ff98]
	cp b
	jr nc, .asm_3cb5c
	ld a, $1
	ld [$cd6a], a
	ld hl, CantEscapeText
	jr .asm_3cb4f
.asm_3cb4c
	ld hl, NoRunningText
.asm_3cb4f
	call PrintText
	ld a, $1
	ld [$d11f], a
	call SaveScreenTilesToBuffer1
	and a
	ret
.asm_3cb5c
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	ld a, $2
	jr nz, .asm_3cb81
	call SaveScreenTilesToBuffer1
	xor a
	ld [$cd6a], a
	ld a, $f
	ld [wPlayerMoveListIndex], a ; $cc2e
	call Func_3d605
	call LoadScreenTilesFromBuffer1
	ld a, [$cc3e]
	cp $f
	ld a, $2
	jr z, .asm_3cb81
	dec a
.asm_3cb81
	ld [$cf0b], a
	ld a, (SFX_08_44 - SFX_Headers_08) / 3
	call PlaySoundWaitForCurrent
	ld hl, GotAwayText
	call PrintText
	call WaitForSoundToFinish
	call SaveScreenTilesToBuffer1
	scf
	ret

CantEscapeText: ; 3cb97 (f:4b97)
	TX_FAR _CantEscapeText
	db "@"

NoRunningText: ; 3cb9c (f:4b9c)
	TX_FAR _NoRunningText
	db "@"

GotAwayText: ; 3cba1 (f:4ba1)
	TX_FAR _GotAwayText
	db "@"

Func_3cba6: ; 3cba6 (f:4ba6)
	ld a, [wWhichPokemon] ; $cf92
	ld bc, $2c
	ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
	call AddNTimes
	ld de, W_PLAYERMONID
	ld bc, $c
	call CopyData
	ld bc, $f
	add hl, bc
	ld de, W_PLAYERMONIVS
	ld bc, $2
	call CopyData
	ld de, W_PLAYERMONPP ; $d02d
	ld bc, $4
	call CopyData
	ld de, W_PLAYERMONLEVEL ; $d022
	ld bc, $b
	call CopyData
	ld a, [$cfd9]
	ld [$d0b5], a
	call GetMonHeader
	ld hl, W_PARTYMON1NAME ; $d2b5
	ld a, [wPlayerMonNumber] ; $cc2f
	call SkipFixedLengthTextEntries
	ld de, W_PLAYERMONNAME
	ld bc, $b
	call CopyData
	ld hl, W_PLAYERMONLEVEL ; $d022
	ld de, $cd0f
	ld bc, $b
	call CopyData
	call Func_3ed1a
	call Func_3ee19
	ld a, $7
	ld b, $8
	ld hl, wPlayerMonAttackMod ; $cd1a
.asm_3cc0e
	ld [hli], a
	dec b
	jr nz, .asm_3cc0e
	ret

Func_3cc13: ; 3cc13 (f:4c13)
	ld a, [wWhichPokemon] ; $cf92
	ld bc, $2c
	ld hl, wEnemyMons ; $d8a4
	call AddNTimes
	ld de, $cfe5
	ld bc, $c
	call CopyData
	ld bc, $f
	add hl, bc
	ld de, $cff1
	ld bc, $2
	call CopyData
	ld de, W_ENEMYMONPP ; $cffe
	ld bc, $4
	call CopyData
	ld de, W_ENEMYMONLEVEL ; $cff3
	ld bc, $b
	call CopyData
	ld a, [$cfe5]
	ld [$d0b5], a
	call GetMonHeader
	ld hl, $d9ee
	ld a, [wWhichPokemon] ; $cf92
	call SkipFixedLengthTextEntries
	ld de, W_ENEMYMONNAME
	ld bc, $b
	call CopyData
	ld hl, W_ENEMYMONLEVEL ; $cff3
	ld de, $cd23
	ld bc, $b
	call CopyData
	call Func_3ed1e
	ld hl, W_MONHBASESTATS
	ld de, $d002
	ld b, $5
.asm_3cc79
	ld a, [hli]
	ld [de], a
	inc de
	dec b
	jr nz, .asm_3cc79
	ld a, $7
	ld b, $8
	ld hl, wEnemyMonStatMods ; $cd2e
.asm_3cc86
	ld [hli], a
	dec b
	jr nz, .asm_3cc86
	ld a, [wWhichPokemon] ; $cf92
	ld [W_ENEMYMONNUMBER], a ; $cfe8
	ret

Func_3cc91: ; 3cc91 (f:4c91)
	callab SendOutMon
	ld hl, W_ENEMYMONCURHP ; $cfe6
	ld a, [hli]
	or [hl]
	jp z, Func_3cca4
	call Func_3cdec

Func_3cca4: ; 3cca4 (f:4ca4)
	call Func_3cd60
	ld a, $4
	call Predef ; indirect jump to LoadMonBackSprite (3f103 (f:7103))
	xor a
	ld [$ffe1], a
	ld hl, $cc2d
	ld [hli], a
	ld [hl], a
	ld [$cc5b], a
	ld [$d05b], a
	ld [W_PLAYERMOVENUM], a ; $cfd2
	ld hl, $ccf1
	ld [hli], a
	ld [hl], a
	ld hl, $d060
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hl], a
	ld [W_PLAYERDISABLEDMOVE], a ; $d06d
	ld [$ccee], a
	ld [$ccf7], a
	ld b, $1
	call GoPAL_SET
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	res 5, [hl]
	ld a, $1
	ld [H_WHOSETURN], a ; $fff3
	ld a, POOF_ANIM
	call PlayMoveAnimation
	FuncCoord 4, 11 ; $c480
	ld hl, Coord
	ld a, $2
	call Predef ; indirect jump to Func_3f073 (3f073 (f:7073))
	ld a, [$cf91]
	call PlayCry
	call Func_3ee94
	jp SaveScreenTilesToBuffer1

Func_3ccfa: ; 3ccfa (f:4cfa)
	FuncCoord 1, 5 ; $c405
	ld hl, Coord
	ld bc, $707
	call ClearScreenArea
	FuncCoord 3, 7 ; $c42f
	ld hl, Coord
	ld bc, $505
	xor a
	ld [$cd6c], a
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld a, $5
	call Predef ; indirect jump to Func_79aba (79aba (1e:5aba))
	ld c, $4
	call DelayFrames
	call Func_3cd3a
	FuncCoord 4, 9 ; $c458
	ld hl, Coord
	ld bc, $303
	ld a, $1
	ld [$cd6c], a
	xor a
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld a, $5
	call Predef ; indirect jump to Func_79aba (79aba (1e:5aba))
	call Delay3
	call Func_3cd3a
	ld a, $4c
	FuncCoord 5, 11 ; $c481
	ld [Coord], a

Func_3cd3a: ; 3cd3a (f:4d3a)
	FuncCoord 1, 5 ; $c405
	ld hl, Coord
	ld bc, $707
	jp ClearScreenArea

; reads player's current mon's HP into W_PLAYERMONCURHP
ReadPlayerMonCurHPAndStatus: ; 3cd43 (f:4d43)
	ld a, [wPlayerMonNumber] ; $cc2f
	ld hl, W_PARTYMON1_HP ; $d16c
	ld bc, W_PARTYMON2DATA - W_PARTYMON1DATA
	call AddNTimes
	ld d, h
	ld e, l
	ld hl, W_PLAYERMONCURHP ; $d015
	ld bc, $4               ; 2 bytes HP, 1 byte unknown (unused?), 1 byte status
	jp CopyData

Func_3cd5a: ; 3cd5a (f:4d5a)
	call Func_3cd60
	jp Func_3cdec

Func_3cd60: ; 3cd60 (f:4d60)
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	FuncCoord 9, 7 ; $c435
	ld hl, Coord
	ld bc, $50b
	call ClearScreenArea
	callab Func_3a902
	FuncCoord 18, 9 ; $c466
	ld hl, Coord
	ld [hl], $73
	ld de, W_PLAYERMONNAME
	FuncCoord 10, 7 ; $c436
	ld hl, Coord
	call Func_3ce9c
	call PlaceString
	ld hl, W_PLAYERMONID
	ld de, $cf98
	ld bc, $c
	call CopyData
	ld hl, W_PLAYERMONLEVEL ; $d022
	ld de, $cfb9
	ld bc, $b
	call CopyData
	FuncCoord 14, 8 ; $c44e
	ld hl, Coord
	push hl
	inc hl
	ld de, $cf9c
	call PrintStatusConditionNotFainted
	pop hl
	jr nz, .asm_3cdae
	call PrintLevel
.asm_3cdae
	ld a, [$cf98]
	ld [$cf91], a
	FuncCoord 10, 9 ; $c45e
	ld hl, Coord
	ld a, $5f
	call Predef ; indirect jump to Func_128ef (128ef (4:68ef))
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld hl, $cf1d
	call Func_3ce90
	ld hl, W_PLAYERMONCURHP ; $d015
	ld a, [hli]
	or [hl]
	jr z, .asm_3cdd9
	ld a, [$ccf6]
	and a
	ret nz
	ld a, [$cf1d]
	cp $2
	jr z, .asm_3cde6
.asm_3cdd9
	ld hl, $d083
	bit 7, [hl]
	ld [hl], $0
	ret z
	xor a
	ld [$c02a], a
	ret
.asm_3cde6
	ld hl, $d083
	set 7, [hl]
	ret

Func_3cdec: ; 3cdec (f:4dec)
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld hl, wTileMap
	ld bc, $40c
	call ClearScreenArea
	callab Func_3a919
	ld de, W_ENEMYMONNAME
	FuncCoord 1, 0 ; $c3a1
	ld hl, Coord
	call Func_3ce9c
	call PlaceString
	FuncCoord 4, 1 ; $c3b8
	ld hl, Coord
	push hl
	inc hl
	ld de, W_ENEMYMONSTATUS ; $cfe9
	call PrintStatusConditionNotFainted
	pop hl
	jr nz, .asm_3ce23
	ld a, [W_ENEMYMONLEVEL] ; $cff3
	ld [$cfb9], a
	call PrintLevel
.asm_3ce23
	ld hl, W_ENEMYMONCURHP ; $cfe6
	ld a, [hli]
	ld [$ff97], a
	ld a, [hld]
	ld [$ff98], a
	or [hl]
	jr nz, .asm_3ce36
	ld c, a
	ld e, a
	ld d, $6
	jp Func_3ce7f
.asm_3ce36
	xor a
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, $30
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	call Multiply
	ld hl, W_ENEMYMONMAXHP ; $cff4
	ld a, [hli]
	ld b, a
	ld a, [hl]
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld a, b
	and a
	jr z, .asm_3ce6a
	ld a, [H_REMAINDER] ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	srl b
	rr a
	srl b
	rr a
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld a, [$ff97]
	ld b, a
	srl b
	ld a, [$ff98]
	rr a
	srl b
	rr a
	ld [$ff98], a
	ld a, b
	ld [$ff97], a
.asm_3ce6a
	ld a, [$ff97]
	ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	ld a, [$ff98]
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, $2
	ld b, a
	call Divide
	ld a, [$ff98]
	ld e, a
	ld a, $6
	ld d, a
	ld c, a

Func_3ce7f: ; 3ce7f (f:4e7f)
	xor a
	ld [wListMenuID], a ; $cf94
	FuncCoord 2, 2 ; $c3ca
	ld hl, Coord
	call DrawHPBar
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld hl, $cf1e

Func_3ce90: ; 3ce90 (f:4e90)
	ld b, [hl]
	call Func_3df9
	ld a, [hl]
	cp b
	ret z
	ld b, $1
	jp GoPAL_SET

Func_3ce9c: ; 3ce9c (f:4e9c)
	push de
	inc hl
	inc hl
	ld b, $2
.asm_3cea1
	inc de
	ld a, [de]
	cp $50
	jr z, .asm_3ceb1
	inc de
	ld a, [de]
	cp $50
	jr z, .asm_3ceb1
	dec hl
	dec b
	jr nz, .asm_3cea1
.asm_3ceb1
	pop de
	ret

InitBattleMenu: ; 3ceb3 (f:4eb3)
	call LoadScreenTilesFromBuffer1 ; restore saved screen
	ld a, [W_BATTLETYPE] ; $d05a
	and a
	jr nz, .nonstandardbattle
	call Func_3cd5a ; redraw names and HP bars?
	call Func_3ee94
	call SaveScreenTilesToBuffer1
.nonstandardbattle
	ld a, [W_BATTLETYPE] ; $d05a
	cp $2 ; safari
	ld a, $b ; safari menu id
	jr nz, .menuselected
	ld a, $1b ; regular menu id
.menuselected
	ld [$d125], a
	call DisplayTextBoxID
	ld a, [W_BATTLETYPE] ; $d05a
	dec a
	jp nz, RegularBattleMenu ; regular battle
	; the following happens for the old man tutorial
	ld hl, W_PLAYERNAME ; $d158
	ld de, W_GRASSRATE ; $d887
	ld bc, $b
	call CopyData  ; temporarily save the player name in unused space,
	               ; which is supposed to get overwritten when entering a
	               ; map with wild pokémon. due to an oversight, the data
	               ; may not get overwritten (cinnabar) and the infamous
	               ; missingno. glitch can show up.
	ld hl, OldManName ; $4f12
	ld de, W_PLAYERNAME ; $d158
	ld bc, $b
	call CopyData
	; the following simulates the keystrokes by drawing menus on screen
	FuncCoord 9, 14 ; $c4c1
	ld hl, Coord
	ld [hl], "▶"
	ld c, $50
	call DelayFrames
	ld [hl], $7f
	FuncCoord 9, 16 ; $c4e9
	ld hl, Coord
	ld [hl], "▶"
	ld c, $32
	call DelayFrames
	ld [hl], $ec
	ld a, $2
	jp Func_3cfe8

OldManName: ; 3cf12 (f:4f12)
	db "OLD MAN@"

RegularBattleMenu: ; 3cf1a (f:4f1a)
	ld a, [$cc2d]
	ld [wCurrentMenuItem], a ; $cc26
	ld [wLastMenuItem], a ; $cc2a
	sub $2
	jr c, .leftcolumn
	ld [wCurrentMenuItem], a ; $cc26
	ld [wLastMenuItem], a ; $cc2a
	jr .rightcolumn
.leftcolumn
	ld a, [W_BATTLETYPE] ; $d05a
	cp $2
	ld a, " "
	jr z, .safaribattle
	FuncCoord 15, 14 ; $c4c7
	ld [Coord], a
	FuncCoord 15, 16 ; $c4ef
	ld [Coord], a
	ld b, $9
	jr .notsafari
.safaribattle
	FuncCoord 13, 14 ; $c4c5
	ld [Coord], a
	FuncCoord 13, 16 ; $c4ed
	ld [Coord], a
	FuncCoord 7, 14 ; $c4bf
	ld hl, Coord
	ld de, W_NUMSAFARIBALLS ; $da47
	ld bc, $102
	call PrintNumber
	ld b, $1
.notsafari
	ld hl, wTopMenuItemY ; $cc24
	ld a, $e
	ld [hli], a
	ld a, b
	ld [hli], a
	inc hl
	inc hl
	ld a, $1
	ld [hli], a
	ld [hl], $11
	call HandleMenuInput
	bit 4, a
	jr nz, .rightcolumn
	jr .selection
.rightcolumn
	ld a, [W_BATTLETYPE] ; $d05a
	cp $2
	ld a, " "
	jr z, .safarirightcolumn
	FuncCoord 9, 14 ; $c4c1
	ld [Coord], a
	FuncCoord 9, 16 ; $c4e9
	ld [Coord], a
	ld b, $f
	jr .notsafarirightcolumn
.safarirightcolumn
	FuncCoord 1, 14 ; $c4b9
	ld [Coord], a
	FuncCoord 1, 16 ; $c4e1
	ld [Coord], a
	FuncCoord 7, 14 ; $c4bf
	ld hl, Coord
	ld de, W_NUMSAFARIBALLS ; $da47
	ld bc, $102
	call PrintNumber
	ld b, $d
.notsafarirightcolumn
	ld hl, wTopMenuItemY ; $cc24
	ld a, $e
	ld [hli], a
	ld a, b
	ld [hli], a
	inc hl
	inc hl
	ld a, $1
	ld [hli], a
	ld a, $21
	ld [hli], a
	call HandleMenuInput
	bit 5, a
	jr nz, .leftcolumn
	ld a, [wCurrentMenuItem] ; $cc26
	add $2 ; if we're in the right column, the actual id is +2
	ld [wCurrentMenuItem], a ; $cc26
.selection
	call PlaceUnfilledArrowMenuCursor
	ld a, [W_BATTLETYPE] ; $d05a
	cp $2
	ld a, [wCurrentMenuItem] ; $cc26
	ld [$cc2d], a
	jr z, .asm_3cfd0
	cp $1
	jr nz, .asm_3cfcb
	inc a
	jr .asm_3cfd0
.asm_3cfcb
	cp $2 ; what
	jr nz, .asm_3cfd0
	dec a
.asm_3cfd0
	and a
	jr nz, Func_3cfe8
	; first option was selected...
	ld a, [W_BATTLETYPE] ; $d05a
	cp $2
	jr z, .safari1
	xor a
	ld [$d120], a
	jp LoadScreenTilesFromBuffer1 ; restore saved screen and return??
.safari1 ; safari first option??
	ld a, SAFARI_BALL
	ld [$cf91], a
	jr asm_3d05f

Func_3cfe8: ; 3cfe8 (f:4fe8)
	cp $2
	jp nz, Func_3d0ca
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr nz, .asm_3cffd
	ld hl, ItemsCantBeUsedHereText
	call PrintText
	jp InitBattleMenu
.asm_3cffd ; bag?
	call SaveScreenTilesToBuffer2 ; copy bg?
	ld a, [W_BATTLETYPE] ; $d05a
	cp $2
	jr nz, asm_3d00e
	ld a, SAFARI_BAIT
	ld [$cf91], a
	jr asm_3d05f
asm_3d00e: ; 3d00e (f:500e)
	call LoadScreenTilesFromBuffer1
	ld a, [W_BATTLETYPE] ; $d05a
	and a
	jr nz, .asm_3d01a
	call Func_3cd5a
.asm_3d01a
	ld a, [W_BATTLETYPE] ; $d05a
	dec a
	jr nz, Func_3d031
	ld hl, OldManItemList
	ld a, l
	ld [$cf8b], a
	ld a, h
	ld [$cf8c], a
	jr Func_3d03c

OldManItemList: ; 3d02d (f:502d)
	db $01, POKE_BALL, 50, $ff

Func_3d031
	ld hl, wNumBagItems ; $d31d
	ld a, l
	ld [$cf8b], a
	ld a, h
	ld [$cf8c], a
Func_3d03c
	xor a
	ld [$cf93], a
	ld a, $3
	ld [wListMenuID], a ; $cf94
	ld a, [$cc2c]
	ld [wCurrentMenuItem], a ; $cc26
	call DisplayListMenuID
	ld a, [wCurrentMenuItem] ; $cc26
	ld [$cc2c], a
	ld a, $0
	ld [$cc37], a
	ld [$cc35], a
	jp c, InitBattleMenu
asm_3d05f: ; 3d05f (f:505f)
	ld a, [$cf91]
	ld [$d11e], a
	call GetItemName
	call CopyStringToCF4B ; copy name
	xor a
	ld [$d152], a
	call UseItem
	call Func_3ee5b
	call CleanLCD_OAM
	xor a
	ld [wCurrentMenuItem], a ; $cc26
	ld a, [W_BATTLETYPE] ; $d05a
	cp $2
	jr z, .asm_3d09c
	ld a, [$cd6a]
	and a
	jp z, asm_3d00e
	ld a, [W_PLAYERBATTSTATUS1] ; $d062
	bit 5, a
	jr z, .asm_3d09c
	ld hl, $d06a
	dec [hl]
	jr nz, .asm_3d09c
	ld hl, W_PLAYERBATTSTATUS1 ; $d062
	res 5, [hl]
.asm_3d09c
	ld a, [$d11c]
	and a
	jr nz, .asm_3d0b7
	ld a, [W_BATTLETYPE] ; $d05a
	cp $2
	jr z, .asm_3d0b2
	call LoadScreenTilesFromBuffer1
	call Func_3cd5a ; redraw name and hp bar?
	call Delay3
.asm_3d0b2
	call GBPalNormal
	and a
	ret
.asm_3d0b7
	call GBPalNormal
	xor a
	ld [$d11c], a
	ld a, $2
	ld [$cf0b], a
	scf
	ret

ItemsCantBeUsedHereText: ; 3d0c5 (f:50c5)
	TX_FAR _ItemsCantBeUsedHereText
	db "@"

Func_3d0ca: ; 3d0ca (f:50ca)
	dec a
	jp nz, Func_3d1fa
	call SaveScreenTilesToBuffer2
	ld a, [W_BATTLETYPE] ; $d05a
	cp $2
	jr nz, Func_3d0e0
	ld a, SAFARI_ROCK
	ld [$cf91], a
	jp asm_3d05f

Func_3d0e0: ; 3d0e0 (f:50e0)
	call LoadScreenTilesFromBuffer1
	xor a
	ld [$d07d], a
	ld [$cc35], a
	call DisplayPartyMenu
asm_3d0ed: ; 3d0ed (f:50ed)
	jp nc, Func_3d119
asm_3d0f0: ; 3d0f0 (f:50f0)
	call CleanLCD_OAM
	call GBPalWhiteOut
	call Func_3ee5b
	call LoadScreenTilesFromBuffer2
	call GoPAL_SET_CF1C
	call GBPalNormal
	jp InitBattleMenu

Func_3d105: ; 3d105 (f:5105)
	FuncCoord 11, 11 ; $c487
	ld hl, Coord
	ld bc, $81
	ld a, $7f
	call FillMemory
	xor a
	ld [$d07d], a
	call GoBackToPartyMenu
	jr asm_3d0ed

Func_3d119: ; 3d119 (f:5119)
	ld a, $c
	ld [$d125], a
	call DisplayTextBoxID
	ld hl, wTopMenuItemY ; $cc24
	ld a, $c
	ld [hli], a
	ld [hli], a
	xor a
	ld [hli], a
	inc hl
	ld a, $2
	ld [hli], a
	ld a, $3
	ld [hli], a
	xor a
	ld [hl], a
	call HandleMenuInput
	bit 1, a
	jr nz, Func_3d105
	call PlaceUnfilledArrowMenuCursor
	ld a, [wCurrentMenuItem] ; $cc26
	cp $2
	jr z, asm_3d0f0
	and a
	jr z, .asm_3d18a
	xor a
	ld [$cc49], a
	ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
	call CleanLCD_OAM
	ld a, $36
	call Predef ; indirect jump to StatusScreen (12953 (4:6953))
	ld a, $37
	call Predef ; indirect jump to StatusScreen2 (12b57 (4:6b57))
	ld a, [W_ENEMYBATTSTATUS2] ; $d068
	bit 4, a
	ld hl, AnimationSubstitute
	jr nz, .asm_3d182
	ld a, [$ccf3]
	and a
	ld hl, AnimationMinimizeMon
	jr nz, .asm_3d182
	ld a, [$cfe5]
	ld [$cf91], a
	ld [$d0b5], a
	call GetMonHeader
	ld de, $9000
	call LoadMonFrontSprite
	jr .asm_3d187
.asm_3d182
	ld b, BANK(AnimationSubstitute) ; BANK(AnimationMinimizeMon)
	call Bankswitch
.asm_3d187
	jp Func_3d0e0
.asm_3d18a
	ld a, [wPlayerMonNumber] ; $cc2f
	ld d, a
	ld a, [wWhichPokemon] ; $cf92
	cp d
	jr nz, .asm_3d19d
	ld hl, AlreadyOutText
	call PrintText
	jp Func_3d105
.asm_3d19d
	call Func_3ca97
	jp z, Func_3d105
	ld a, $1
	ld [$cd6a], a
	call GBPalWhiteOut
	call CleanLCD_OAM
	call Func_3ee5b
	call LoadScreenTilesFromBuffer1
	call GoPAL_SET_CF1C
	call GBPalNormal

Func_3d1ba: ; 3d1ba (f:51ba)
	callab RetreatMon
	ld c, $32
	call DelayFrames
	call Func_3ccfa
	ld a, [wWhichPokemon] ; $cf92
	ld [wPlayerMonNumber], a ; $cc2f
	ld c, a
	ld b, $1
	push bc
	ld hl, W_PLAYERMONSALIVEFLAGS
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	pop bc
	ld hl, $ccf5
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	call Func_3cba6
	call Func_3cc91
	call SaveScreenTilesToBuffer1
	ld a, $2
	ld [wCurrentMenuItem], a ; $cc26
	and a
	ret

AlreadyOutText: ; 3d1f5 (f:51f5)
	TX_FAR _AlreadyOutText
	db "@"

Func_3d1fa: ; 3d1fa (f:51fa)
	call LoadScreenTilesFromBuffer1
	ld a, $3
	ld [wCurrentMenuItem], a ; $cc26
	ld hl, W_PLAYERMONSPEED
	ld de, W_ENEMYMONSPEED
	call Func_3cab9
	ld a, $0
	ld [$d11f], a
	ret c
	ld a, [$cd6a]
	and a
	ret nz
	jp InitBattleMenu

MoveSelectionMenu: ; 3d219 (f:5219)
	ld a, [wMoveMenuType]
	dec a
	jr z, .mimicmenu
	dec a
	jr z, .relearnmenu
	jr .regularmenu

.loadmoves
	ld de, $d0dc
	ld bc, $4
	call CopyData
	callab Func_39b87
	ret

.writemoves
	ld de, $d0e1
	ld a, [$fff6]
	set 2, a
	ld [$fff6], a
	call PlaceString
	ld a, [$fff6]
	res 2, a
	ld [$fff6], a
	ret

.regularmenu
	call Func_3d3f5
	ret z
	ld hl, W_PLAYERMONMOVES
	call .loadmoves
	FuncCoord 4, 12 ; $c494
	ld hl, Coord
	ld b, $4
	ld c, $e
	di
	call TextBoxBorder
	FuncCoord 4, 12 ; $c494
	ld hl, Coord
	ld [hl], $7a
	FuncCoord 10, 12 ; $c49a
	ld hl, Coord
	ld [hl], $7e
	ei
	FuncCoord 6, 13 ; $c4aa
	ld hl, Coord
	call .writemoves
	ld b, $5
	ld a, $c
	jr .menuset
.mimicmenu
	ld hl, W_ENEMYMONMOVES
	call .loadmoves
	FuncCoord 0, 7 ; $c42c
	ld hl, Coord
	ld b, $4
	ld c, $e
	call TextBoxBorder
	FuncCoord 2, 8 ; $c442
	ld hl, Coord
	call .writemoves
	ld b, $1
	ld a, $7
	jr .menuset
.relearnmenu
	ld a, [wWhichPokemon] ; $cf92
	ld hl, W_PARTYMON1_MOVE1 ; $d173
	ld bc, $2c
	call AddNTimes
	call .loadmoves
	FuncCoord 4, 7 ; $c430
	ld hl, Coord
	ld b, $4
	ld c, $e
	call TextBoxBorder
	FuncCoord 6, 8 ; $c446
	ld hl, Coord
	call .writemoves
	ld b, $5
	ld a, $7
.menuset
	ld hl, wTopMenuItemY ; $cc24
	ld [hli], a
	ld a, b
	ld [hli], a ; wTopMenuItemX
	ld a, [wMoveMenuType]
	cp $1
	jr z, .selectedmoveknown
	ld a, $1
	jr nc, .selectedmoveknown
	ld a, [wPlayerMoveListIndex] ; $cc2e
	inc a
.selectedmoveknown
	ld [hli], a ; wCurrentMenuItem
	inc hl ; wTileBehindCursor untouched
	ld a, [$cd6c]
	inc a
	inc a
	ld [hli], a ; wMaxMenuItem
	ld a, [wMoveMenuType]
	dec a
	ld b, $c1 ; can't use B
	jr z, .matchedkeyspicked
	dec a
	ld b, $c3
	jr z, .matchedkeyspicked
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr z, .matchedkeyspicked
	ld a, [W_FLAGS_D733]
	bit 0, a
	ld b, $c7
	jr z, .matchedkeyspicked
	ld b, $ff
.matchedkeyspicked
	ld a, b
	ld [hli], a ; wMenuWatchedKeys
	ld a, [wMoveMenuType]
	cp $1
	jr z, .movelistindex1
	ld a, [wPlayerMoveListIndex] ; $cc2e
	inc a
.movelistindex1
	ld [hl], a ; wLastMenuItem

Func_3d2fe: ; 3d2fe (f:52fe)
	ld a, [wMoveMenuType]
	and a
	jr z, .battleselect
	dec a
	jr nz, .select
	FuncCoord 1, 14 ; $c4b9
	ld hl, Coord
	ld de, WhichTechniqueString ; $53b8
	call PlaceString
	jr .select
.battleselect
	ld a, [W_FLAGS_D733]
	bit 0, a
	jr nz, .select
	call Func_3d4b6
	ld a, [$cc35]
	and a
	jr z, .select
	FuncCoord 5, 13 ; $c4a9
	ld hl, Coord
	dec a
	ld bc, $14
	call AddNTimes
	ld [hl], $ec
.select
	ld hl, $fff6
	set 1, [hl]
	call HandleMenuInput
	ld hl, $fff6
	res 1, [hl]
	bit 6, a
	jp nz, Func_3d3c9 ; up
	bit 7, a
	jp nz, Func_3d3dd ; down
	bit 2, a
	jp nz, Func_3d435 ; select
	bit 1, a ; B, but was it reset above?
	push af
	xor a
	ld [$cc35], a
	ld a, [wCurrentMenuItem] ; $cc26
	dec a
	ld [wCurrentMenuItem], a ; $cc26
	ld b, a
	ld a, [wMoveMenuType]
	dec a ; if not mimic
	jr nz, .nob
	pop af
	ret
.nob
	dec a
	ld a, b
	ld [wPlayerMoveListIndex], a ; $cc2e
	jr nz, .moveselected
	pop af
	ret
.moveselected
	pop af
	ret nz
	ld hl, W_PLAYERMONPP ; $d02d
	ld a, [wCurrentMenuItem] ; $cc26
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]
	and $3f
	jr z, .nopp
	ld a, [W_PLAYERDISABLEDMOVE] ; $d06d
	swap a
	and $f
	dec a
	cp c
	jr z, .disabled
	ld a, [W_PLAYERBATTSTATUS3] ; $d064
	bit 3, a ; transformed
	jr nz, .dummy ; game freak derp
.dummy
	ld a, [wCurrentMenuItem] ; $cc26
	ld hl, W_PLAYERMONMOVES
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]
	ld [wPlayerSelectedMove], a ; $ccdc
	xor a
	ret
.disabled
	ld hl, MoveDisabledText
	jr .print
.nopp
	ld hl, MoveNoPPText
.print
	call PrintText
	call LoadScreenTilesFromBuffer1
	jp MoveSelectionMenu

MoveNoPPText: ; 3d3ae (f:53ae)
	TX_FAR _MoveNoPPText
	db "@"

MoveDisabledText: ; 3d3b3 (f:53b3)
	TX_FAR _MoveDisabledText
	db "@"

WhichTechniqueString: ; 3d3b8 (f:53b8)
	db "WHICH TECHNIQUE?@"

Func_3d3c9: ; 3d3c9 (f:53c9)
	ld a, [wCurrentMenuItem] ; $cc26
	and a
	jp nz, Func_3d2fe
	call EraseMenuCursor
	ld a, [$cd6c]
	inc a
	ld [wCurrentMenuItem], a ; $cc26
	jp Func_3d2fe

Func_3d3dd: ; 3d3dd (f:53dd)
	ld a, [wCurrentMenuItem] ; $cc26
	ld b, a
	ld a, [$cd6c]
	inc a
	inc a
	cp b
	jp nz, Func_3d2fe
	call EraseMenuCursor
	ld a, $1
	ld [wCurrentMenuItem], a ; $cc26
	jp Func_3d2fe

Func_3d3f5: ; 3d3f5 (f:53f5)
	ld a, $a5
	ld [wPlayerSelectedMove], a ; $ccdc
	ld a, [W_PLAYERDISABLEDMOVE] ; $d06d
	and a
	ld hl, W_PLAYERMONPP ; $d02d
	jr nz, .asm_3d40e
	ld a, [hli]
	or [hl]
	inc hl
	or [hl]
	inc hl
	or [hl]
	and $3f
	ret nz
	jr .asm_3d423
.asm_3d40e
	swap a
	and $f
	ld b, a
	ld d, $5
	xor a
.asm_3d416
	dec d
	jr z, .asm_3d421
	ld c, [hl]
	inc hl
	dec b
	jr z, .asm_3d416
	or c
	jr .asm_3d416
.asm_3d421
	and a
	ret nz
.asm_3d423
	ld hl, NoMovesLeftText
	call PrintText
	ld c, $3c
	call DelayFrames
	xor a
	ret

NoMovesLeftText: ; 3d430 (f:5430)
	TX_FAR _NoMovesLeftText
	db "@"

Func_3d435: ; 3d435 (f:5435)
	ld a, [$cc35]
	and a
	jr z, asm_3d4ad
	ld hl, W_PLAYERMONMOVES
	call Func_3d493
	ld hl, W_PLAYERMONPP ; $d02d
	call Func_3d493
	ld hl, W_PLAYERDISABLEDMOVE ; $d06d
	ld a, [hl]
	swap a
	and $f
	ld b, a
	ld a, [wCurrentMenuItem] ; $cc26
	cp b
	jr nz, .asm_3d463
	ld a, [hl]
	and $f
	ld b, a
	ld a, [$cc35]
	swap a
	add b
	ld [hl], a
	jr .asm_3d474
.asm_3d463
	ld a, [$cc35]
	cp b
	jr nz, .asm_3d474
	ld a, [hl]
	and $f
	ld b, a
	ld a, [wCurrentMenuItem] ; $cc26
	swap a
	add b
	ld [hl], a
.asm_3d474
	ld hl, W_PARTYMON1_MOVE1 ; $d173
	ld a, [wPlayerMonNumber] ; $cc2f
	ld bc, $2c
	call AddNTimes
	push hl
	call Func_3d493
	pop hl
	ld bc, $15
	add hl, bc
	call Func_3d493
	xor a
	ld [$cc35], a
	jp MoveSelectionMenu

Func_3d493: ; 3d493 (f:5493)
	push hl
	ld a, [$cc35]
	dec a
	ld c, a
	ld b, $0
	add hl, bc
	ld d, h
	ld e, l
	pop hl
	ld a, [wCurrentMenuItem] ; $cc26
	dec a
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [de]
	ld b, [hl]
	ld [hl], a
	ld a, b
	ld [de], a
	ret
asm_3d4ad: ; 3d4ad (f:54ad)
	ld a, [wCurrentMenuItem] ; $cc26
	ld [$cc35], a
	jp MoveSelectionMenu

Func_3d4b6: ; 3d4b6 (f:54b6)
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	FuncCoord 0, 8 ; $c440
	ld hl, Coord
	ld b, $3
	ld c, $9
	call TextBoxBorder
	ld a, [W_PLAYERDISABLEDMOVE] ; $d06d
	and a
	jr z, .asm_3d4df
	swap a
	and $f
	ld b, a
	ld a, [wCurrentMenuItem] ; $cc26
	cp b
	jr nz, .asm_3d4df
	FuncCoord 1, 10 ; $c469
	ld hl, Coord
	ld de, DisabledText
	call PlaceString
	jr .asm_3d54e
.asm_3d4df
	ld hl, wCurrentMenuItem ; $cc26
	dec [hl]
	xor a
	ld [H_WHOSETURN], a ; $fff3
	ld hl, W_PLAYERMONMOVES
	ld a, [wCurrentMenuItem] ; $cc26
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]
	ld [wPlayerSelectedMove], a ; $ccdc
	ld a, [wPlayerMonNumber] ; $cc2f
	ld [wWhichPokemon], a ; $cf92
	ld a, $4
	ld [$cc49], a
	callab GetMaxPP
	ld hl, wCurrentMenuItem ; $cc26
	ld c, [hl]
	inc [hl]
	ld b, $0
	ld hl, W_PLAYERMONPP ; $d02d
	add hl, bc
	ld a, [hl]
	and $3f
	ld [$cd6d], a
	FuncCoord 1, 9 ; $c455
	ld hl, Coord
	ld de, TypeText
	call PlaceString
	FuncCoord 7, 11 ; $c483
	ld hl, Coord
	ld [hl], "/"
	FuncCoord 5, 9 ; $c459
	ld hl, Coord
	ld [hl], "/"
	FuncCoord 5, 11 ; $c481
	ld hl, Coord
	ld de, $cd6d
	ld bc, $102
	call PrintNumber
	FuncCoord 8, 11 ; $c484
	ld hl, Coord
	ld de, $d11e
	ld bc, $102
	call PrintNumber
	call GetCurrentMove
	FuncCoord 2, 10 ; $c46a
	ld hl, Coord
	ld a, $5d
	call Predef ; indirect jump to Func_27d98 (27d98 (9:7d98))
.asm_3d54e
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	jp Delay3

DisabledText: ; 3d555 (f:5555)
	db "disabled!@"

TypeText: ; 3d55f (f:555f)
	db "TYPE@"

SelectEnemyMove: ; 3d564 (f:5564)
	ld a, [W_ISLINKBATTLE]
	sub $4
	jr nz, .noLinkBattle
	call SaveScreenTilesToBuffer1
	call Func_3d605
	call LoadScreenTilesFromBuffer1
	ld a, [$cc3e]
	cp $e
	jp z, .asm_3d601
	cp $d
	jr z, .unableToMove
	cp $4
	ret nc
	ld [$cce2], a
	ld c, a
	ld hl, W_ENEMYMONMOVES
	ld b, $0
	add hl, bc
	ld a, [hl]
	jr .done
.noLinkBattle
	ld a, [W_ENEMYBATTSTATUS2]
	and $60     ; need to recharge or using rage
	ret nz
	ld hl, W_ENEMYBATTSTATUS1
	ld a, [hl]
	and $12     ; using multi-turn move or bide
	ret nz
	ld a, [W_ENEMYMONSTATUS]
	and SLP | 1 << FRZ ; sleeping or frozen
	ret nz
	ld a, [W_ENEMYBATTSTATUS1]
	and $21      ; using fly/dig or thrash/petal dance
	ret nz
	ld a, [W_PLAYERBATTSTATUS1]
	bit 5, a    ; caught in player's multi-turn move (e.g. wrap)
	jr z, .notCaughtInWrap
.unableToMove
	ld a, $ff
	jr .done
.notCaughtInWrap
	ld hl, W_ENEMYMONMOVES+1 ; 2nd enemy move
	ld a, [hld]
	and a
	jr nz, .atLeastTwoMovesAvailable
	ld a, [W_ENEMYDISABLEDMOVE]
	and a
	ld a, STRUGGLE ; struggle if the only move is disabled
	jr nz, .done
.atLeastTwoMovesAvailable
	ld a, [W_ISINBATTLE]
	dec a
	jr z, .chooseRandomMove ; wild encounter
	callab AIEnemyTrainerChooseMoves
.chooseRandomMove
	push hl
	call GenRandomInBattle ; get random
	ld b, $1
	cp $3f ; select move 1 in [0,3e] (63/256 chance)
	jr c, .moveChosen
	inc hl
	inc b
	cp $7f ; select move 1 in [3f,7e] (64/256 chance)
	jr c, .moveChosen
	inc hl
	inc b
	cp $be ; select move 1 in [7f,bd] (63/256 chance)
	jr c, .moveChosen
	inc hl
	inc b ; select move 4 in [be,ff] (66/256 chance)
.moveChosen
	ld a, b
	dec a
	ld [wEnemyMoveListIndex], a
	ld a, [W_ENEMYDISABLEDMOVE]
	swap a
	and $f
	cp b
	ld a, [hl]
	pop hl
	jr z, .chooseRandomMove ; move disabled, try again
	and a
	jr z, .chooseRandomMove ; move non-existant, try again
.done
	ld [wEnemySelectedMove], a
	ret
.asm_3d601
	ld a, $a5
	jr .done

Func_3d605: ; 3d605 (f:5605)
	ld a, $ff
	ld [$cc3e], a
	ld a, [wPlayerMoveListIndex] ; $cc2e
	cp $f
	jr z, .asm_3d630
	ld a, [$cd6a]
	and a
	jr nz, .asm_3d629
	ld a, [wPlayerSelectedMove] ; $ccdc
	cp $a5
	ld b, $e
	jr z, .asm_3d62f
	dec b
	inc a
	jr z, .asm_3d62f
	ld a, [wPlayerMoveListIndex] ; $cc2e
	jr .asm_3d630
.asm_3d629
	ld a, [wWhichPokemon] ; $cf92
	add $4
	ld b, a
.asm_3d62f
	ld a, b
.asm_3d630
	ld [$cc42], a
	callab PrintWaitingText
.asm_3d63b
	call Func_22c3
	call DelayFrame
	ld a, [$cc3e]
	inc a
	jr z, .asm_3d63b
	ld b, $a
.asm_3d649
	call DelayFrame
	call Func_22c3
	dec b
	jr nz, .asm_3d649
	ld b, $a
.asm_3d654
	call DelayFrame
	call Func_22ed
	dec b
	jr nz, .asm_3d654
	ret

Func_3d65e: ; 3d65e (f:565e)
	xor a
	ld [H_WHOSETURN], a ; $fff3
	ld a, [wPlayerSelectedMove] ; $ccdc
	inc a
	jp z, Func_3d80a
	xor a
	ld [W_MOVEMISSED], a ; $d05f
	ld [$cced], a
	ld [$ccf4], a
	ld a, $a
	ld [$d05b], a
	ld a, [$cd6a]
	and a
	jp nz, Func_3d80a
	call PrintGhostText
	jp z, Func_3d80a
	call Func_3d854
	jr nz, .asm_3d68a
	jp [hl]
.asm_3d68a
	call GetCurrentMove
	ld hl, W_PLAYERBATTSTATUS1 ; $d062
	bit 4, [hl]
	jr nz, asm_3d6a9
	call Func_3dc88
	jp z, Func_3d80a

Func_3d69a: ; 3d69a (f:569a)
	ld a, [W_PLAYERMOVEEFFECT] ; $cfd3
	cp CHARGE_EFFECT
	jp z, Func_3f132
	cp FLY_EFFECT
	jp z, Func_3f132
	jr asm_3d6b0

; in-battle stuff
asm_3d6a9: ; 3d6a9 (f:56a9)
	ld hl,W_PLAYERBATTSTATUS1
	res 4,[hl]
	res 6,[hl]
asm_3d6b0: ; 3d6b0 (f:56b0)
	call PrintMonName1Text
	ld hl,DecrementPP
	ld de,$CCDC ; pointer to the move just used
	ld b,BANK(DecrementPP)
	call Bankswitch
	ld a,[W_PLAYERMOVEEFFECT] ; effect of the move just used
	ld hl,EffectsArray1
	ld de,1
	call IsInArray
	jp c,Func_3f132
	ld a,[W_PLAYERMOVEEFFECT]
	ld hl,EffectsArray5B
	ld de,1
	call IsInArray
	call c,Func_3f132
asm_3d6dc: ; 3d6dc (f:56dc)
	ld a,[W_PLAYERMOVEEFFECT]
	ld hl,EffectsArray2
	ld de,1
	call IsInArray
	jp c,.asm_3d702
	call CriticalHitTest
	call HandleCounterMove
	jr z,asm_3d705
	call CalculateDamage
	call MoreCalculateDamage
	jp z,asm_3d74b
	call AdjustDamageForMoveType
	call Func_3e687
.asm_3d702
	call MoveHitTest
asm_3d705
	ld a,[W_MOVEMISSED]
	and a
	jr z,asm_3d714
	ld a,[W_PLAYERMOVEEFFECT]
	sub a,7
	jr z,asm_3d71e
	jr asm_3d74b ; 574B
asm_3d714
	ld a,[W_PLAYERMOVEEFFECT]
	and a
	ld a,4
	jr z,asm_3d71e
	ld a,5
asm_3d71e
	push af
	ld a,[W_PLAYERBATTSTATUS2]
	bit 4,a
	ld hl,Func_79747
	ld b,BANK(Func_79747)
	call nz,Bankswitch
	pop af
	ld [$CC5B],a
	ld a,[W_PLAYERMOVENUM]
	call PlayMoveAnimation
	call Func_3eed3
	call Func_3cd60
	ld a,[W_PLAYERBATTSTATUS2]
	bit 4,a
	ld hl,Func_79771
	ld b,BANK(Func_79771)
	call nz,Bankswitch
	jr asm_3d766
asm_3d74b
	ld c,$1E
	call DelayFrames
	ld a,[W_PLAYERMOVEEFFECT]
	cp a,FLY_EFFECT
	jr z,.next5
	cp a,CHARGE_EFFECT
	jr z,.next5
	jr asm_3d766
.next5
	xor a
	ld [$CC5B],a
	ld a,STATUS_AFFECTED_ANIM
	call PlayMoveAnimation
asm_3d766
	ld a,[W_PLAYERMOVEEFFECT]
	cp a,MIRROR_MOVE_EFFECT
	jr nz,.next6 ; 577A
	call MirrorMoveCopyMove
	jp z,Func_3d80a
	xor a
	ld [$CCED],a
	jp Func_3d69a
.next6
	cp a,METRONOME_EFFECT
	jr nz,.next7 ; 5784
	call MetronomePickMove
	jp Func_3d69a
.next7
	ld a,[W_PLAYERMOVEEFFECT]
	ld hl,EffectsArray3
	ld de,1
	call IsInArray
	jp c,Func_3f132
	ld a,[W_MOVEMISSED]
	and a
	jr z,.next8 ; 57A6
	call PrintMoveFailureText
	ld a,[W_PLAYERMOVEEFFECT]
	cp a,EXPLODE_EFFECT
	jr z,.next9 ; 57B9
	jp Func_3d80a
.next8
	call ApplyAttackToEnemyPokemon
	call Func_3dc5c
	callab DisplayEffectiveness
	ld a,1
	ld [$CCF4],a
.next9
	ld a,[W_PLAYERMOVEEFFECT]
	ld hl,EffectsArray4
	ld de,1
	call IsInArray
	call c,Func_3f132
	ld hl,$CFE6
	ld a,[hli]
	ld b,[hl]
	or b
	ret z
	call HandleBuildingRage

	ld hl,W_PLAYERBATTSTATUS1
	bit 2,[hl]
	jr z,.next10 ; 57EF
	ld a,[$D06A]
	dec a
	ld [$D06A],a
	jp nz,asm_3d714

	res 2,[hl]
	ld hl,MultiHitText
	call PrintText
	xor a
	ld [W_NUMHITS],a ; reset
.next10
	ld a,[W_PLAYERMOVEEFFECT]
	and a
	jp z,Func_3d80a
	ld hl,EffectsArray5
	ld de,1
	call IsInArray
	call nc,Func_3f132
	jp Func_3d80a

MultiHitText: ; 3d805 (f:5805)
	TX_FAR _MultiHitText
	db "@"

Func_3d80a: ; 3d80a (f:580a)
	xor a
	ld [$CD6A],a
	ld b,1
	ret

PrintGhostText: ; 3d811 (f:5811)
; print the ghost battle messages
	call IsGhostBattle
	ret nz
	ld a,[H_WHOSETURN]
	and a
	jr nz,.Ghost
	ld a,[W_PLAYERMONSTATUS] ; player’s turn
	and a,SLP | (1 << FRZ)
	ret nz
	ld hl,ScaredText
	call PrintText
	xor a
	ret
.Ghost ; ghost’s turn
	ld hl,GetOutText
	call PrintText
	xor a
	ret

ScaredText: ; 3d830 (f:5830)
	TX_FAR _ScaredText
	db "@"

GetOutText: ; 3d835 (f:5835)
	TX_FAR _GetOutText
	db "@"

IsGhostBattle: ; 3d83a (f:583a)
	ld a,[W_ISINBATTLE]
	dec a
	ret nz
	ld a,[W_CURMAP]
	cp a,POKEMONTOWER_1
	jr c,.next
	cp a,LAVENDER_HOUSE_1
	jr nc,.next
	ld b,SILPH_SCOPE
	call IsItemInBag ; $3493
	ret z
.next
	ld a,1
	and a
	ret

Func_3d854: ; 3d854 (f:5854)
	ld hl,W_PLAYERMONSTATUS
	ld a,[hl]
	and a,SLP
	jr z,.FrozenCheck ; to 5884

	dec a
	ld [W_PLAYERMONSTATUS],a ; decrement sleep count
	and a
	jr z,.WakeUp ; to 5874

	xor a
	ld [$CC5B],a
	ld a,SLP_ANIM - 1
	call PlayMoveAnimation
	ld hl,FastAsleepText
	call PrintText
	jr .sleepDone
.WakeUp
	ld hl,WokeUpText
	call PrintText
.sleepDone
	xor a
	ld [$CCF1],a
	ld hl,Func_3d80a
	jp Func_3da37

.FrozenCheck
	bit FRZ,[hl] ; frozen?
	jr z,.HeldInPlaceCheck ; to 5898
	ld hl,IsFrozenText
	call PrintText
	xor a
	ld [$CCF1],a
	ld hl,Func_3d80a
	jp Func_3da37

.HeldInPlaceCheck
	ld a,[W_ENEMYBATTSTATUS1]
	bit 5,a
	jp z,FlinchedCheck
	ld hl,CantMoveText
	call PrintText
	ld hl,Func_3d80a
	jp Func_3da37

FlinchedCheck: ; 3d8ac (f:58ac)
	ld hl,W_PLAYERBATTSTATUS1
	bit 3,[hl]
	jp z,HyperBeamCheck
	res 3,[hl]
	ld hl,FlinchedText
	call PrintText
	ld hl,Func_3d80a
	jp Func_3da37

HyperBeamCheck: ; 3d8c2 (f:58c2)
	ld hl,W_PLAYERBATTSTATUS2
	bit 5,[hl]
	jr z,.next ; 58D7
	res 5,[hl]
	ld hl,MustRechargeText
	call PrintText
	ld hl,Func_3d80a ; $580a
	jp Func_3da37
.next
	ld hl,$D06D
	ld a,[hl]
	and a
	jr z,.next2 ; 58EE
	dec a
	ld [hl],a
	and a,$F
	jr nz,.next2
	ld [hl],a
	ld [$CCEE],a
	ld hl,DisabledNoMoreText
	call PrintText
.next2
	ld a,[W_PLAYERBATTSTATUS1]
	add a
	jr nc,.next3 ; 5929
	ld hl,$D06B
	dec [hl]
	jr nz,.next4 ; 5907
	ld hl,W_PLAYERBATTSTATUS1
	res 7,[hl]
	ld hl,ConfusedNoMoreText
	call PrintText
	jr .next3
.next4
	ld hl,IsConfusedText
	call PrintText
	xor a
	ld [$CC5B],a
	ld a,CONF_ANIM - 1
	call PlayMoveAnimation
	call GenRandomInBattle
	cp a,$80
	jr c,.next3
	ld hl,W_PLAYERBATTSTATUS1
	ld a,[hl]
	and a,$80 ; confused
	ld [hl],a
	call PrintHurtItselfText
	jr .next5 ; 5952
.next3
	ld a,[$CCEE]
	and a
	jr z,.ParalysisCheck ; 593E
	ld hl,$CCDC
	cp [hl]
	jr nz,.ParalysisCheck
	call PrintMoveIsDisabledText
	ld hl,Func_3d80a ; $580a
	jp Func_3da37
.ParalysisCheck
	ld hl,W_PLAYERMONSTATUS
	bit PAR,[hl]
	jr z,.next7 ; 5975
	call GenRandomInBattle ; random number
	cp a,$3F
	jr nc,.next7
	ld hl,FullyParalyzedText
	call PrintText
.next5
	ld hl,W_PLAYERBATTSTATUS1
	ld a,[hl]
	and a,$CC
	ld [hl],a
	ld a,[W_PLAYERMOVEEFFECT]
	cp a,FLY_EFFECT
	jr z,.next8 ; 5966
	cp a,CHARGE_EFFECT
	jr z,.next8
	jr .next9 ; 596F
.next8
	xor a
	ld [$CC5B],a
	ld a,STATUS_AFFECTED_ANIM
	call PlayMoveAnimation
.next9
	ld hl,Func_3d80a ; $580a
	jp Func_3da37
.next7
	ld hl,W_PLAYERBATTSTATUS1
	bit 0,[hl]
	jr z,.next10 ; 59D0
	xor a
	ld [W_PLAYERMOVENUM],a
	ld hl,$D0D7
	ld a,[hli]
	ld b,a
	ld c,[hl]
	ld hl,$D075
	ld a,[hl]
	add c
	ld [hld],a
	ld a,[hl]
	adc b
	ld [hl],a
	ld hl,$D06A
	dec [hl]
	jr z,.next11 ; 599B
	ld hl,Func_3d80a ; $580a
	jp Func_3da37
.next11
	ld hl,W_PLAYERBATTSTATUS1
	res 0,[hl]
	ld hl,UnleashedEnergyText
	call PrintText
	ld a,1
	ld [$CFD4],a
	ld hl,$D075
	ld a,[hld]
	add a
	ld b,a
	ld [$D0D8],a
	ld a,[hl]
	rl a
	ld [$D0D7],a
	or b
	jr nz,.next12 ; 59C2
	ld a,1
	ld [W_MOVEMISSED],a
.next12
	xor a
	ld [hli],a
	ld [hl],a
	ld a,BIDE
	ld [W_PLAYERMOVENUM],a
	ld hl,asm_3d705 ; $5705
	jp Func_3da37
.next10
	bit 1,[hl]
	jr z,.next13 ; 59FF
	ld a,THRASH
	ld [W_PLAYERMOVENUM],a
	ld hl,ThrashingAboutText
	call PrintText
	ld hl,$D06A
	dec [hl]
	ld hl,asm_3d6dc ; $56dc
	jp nz,Func_3da37
	push hl
	ld hl,W_PLAYERBATTSTATUS1
	res 1,[hl]
	set 7,[hl]
	call GenRandomInBattle ; random number
	and a,3
	inc a
	inc a
	ld [$D06B],a
	pop hl
	jp Func_3da37
.next13
	bit 5,[hl]
	jp z,Func_3da1a
	ld hl,AttackContinuesText
	call PrintText
	ld a,[$D06A]
	dec a
	ld [$D06A],a
	ld hl,asm_3d714 ; $5714
	jp nz,Func_3da37
	jp Func_3da37

Func_3da1a: ; 3da1a (f:5a1a)
	ld a, [W_PLAYERBATTSTATUS2] ; $d063
	bit 6, a
	jp z, Func_3da39
	ld a, RAGE
	ld [$d11e], a
	call GetMoveName
	call CopyStringToCF4B
	xor a
	ld [W_PLAYERMOVEEFFECT], a ; $cfd3
	ld hl, asm_3d6b0 ; $56b0
	jp Func_3da37

Func_3da37: ; 3da37 (f:5a37)
	xor a
	ret

Func_3da39: ; 3da39 (f:5a39)
	ld a, $1
	and a
	ret

FastAsleepText: ; 3da3d (f:5a3d)
	TX_FAR _FastAsleepText
	db "@"

WokeUpText: ; 3da42 (f:5a42)
	TX_FAR _WokeUpText
	db "@"

IsFrozenText: ; 3da47 (f:5a47)
	TX_FAR _IsFrozenText
	db "@"

FullyParalyzedText: ; 3da4c (f:5a4c)
	TX_FAR _FullyParalyzedText
	db "@"

FlinchedText: ; 3da51 (f:5a51)
	TX_FAR _FlinchedText
	db "@"

MustRechargeText: ; 3da56 (f:5a56)
	TX_FAR _MustRechargeText
	db "@"

DisabledNoMoreText: ; 3da5b (f:5a5b)
	TX_FAR _DisabledNoMoreText
	db "@"

IsConfusedText: ; 3da60 (f:5a60)
	TX_FAR _IsConfusedText
	db "@"

HurtItselfText: ; 3da65 (f:5a65)
	TX_FAR _HurtItselfText
	db "@"

ConfusedNoMoreText: ; 3da6a (f:5a6a)
	TX_FAR _ConfusedNoMoreText
	db "@"

SavingEnergyText: ; 3da6f (f:5a6f)
	TX_FAR _SavingEnergyText
	db "@"

UnleashedEnergyText: ; 3da74 (f:5a74)
	TX_FAR _UnleashedEnergyText
	db "@"

ThrashingAboutText: ; 3da79 (f:5a79)
	TX_FAR _ThrashingAboutText
	db "@"

AttackContinuesText: ; 3da7e (f:5a7e)
	TX_FAR _AttackContinuesText
	db "@"

CantMoveText: ; 3da83 (f:5a83)
	TX_FAR _CantMoveText
	db "@"

PrintMoveIsDisabledText: ; 3da88 (f:5a88)
	ld hl, wPlayerSelectedMove ; $ccdc
	ld de, W_PLAYERBATTSTATUS1 ; $d062
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3da97
	inc hl
	ld de, W_ENEMYBATTSTATUS1 ; $d067
.asm_3da97
	ld a, [de]
	res 4, a
	ld [de], a
	ld a, [hl]
	ld [$d11e], a
	call GetMoveName
	ld hl, MoveIsDisabledText
	jp PrintText

MoveIsDisabledText: ; 3daa8 (f:5aa8)
	TX_FAR _MoveIsDisabledText
	db "@"

PrintHurtItselfText: ; 3daad (f:5aad)
	ld hl, HurtItselfText
	call PrintText
	ld hl, W_ENEMYMONDEFENSE ; $cff8
	ld a, [hli]
	push af
	ld a, [hld]
	push af
	ld a, [W_PLAYERMONDEF]
	ld [hli], a
	ld a, [$d028]
	ld [hl], a
	ld hl, W_PLAYERMOVEEFFECT ; $cfd3
	push hl
	ld a, [hl]
	push af
	xor a
	ld [hli], a
	ld [$d05e], a
	ld a, $28
	ld [hli], a
	xor a
	ld [hl], a
	call CalculateDamage
	call MoreCalculateDamage
	pop af
	pop hl
	ld [hl], a
	ld hl, $cff9
	pop af
	ld [hld], a
	pop af
	ld [hl], a
	xor a
	ld [$cc5b], a
	inc a
	ld [H_WHOSETURN], a ; $fff3
	call PlayMoveAnimation
	call Func_3cd60
	xor a
	ld [H_WHOSETURN], a ; $fff3
	jp ApplyDamageToPlayerPokemon

PrintMonName1Text: ; 3daf5 (f:5af5)
	ld hl, MonName1Text
	jp PrintText

MonName1Text: ; 3dafb (f:5afb)
	TX_FAR _MonName1Text
	db $08 ; asm
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, [W_PLAYERMOVENUM] ; $cfd2
	ld hl, $ccf1
	jr z, .asm_3db11
	ld a, [W_ENEMYMOVENUM] ; $cfcc
	ld hl, $ccf2
.asm_3db11
	ld [hl], a
	ld [$d11e], a
	call Func_3db85
	ld a, [$cced]
	and a
	ld hl, Used2Text
	ret nz
	ld a, [$d11e]
	cp DOUBLESLAP
	ld hl, Used2Text
	ret c
	ld hl, Used1Text
	ret

Used1Text: ; 3db2d (f:5b2d)
	TX_FAR _Used1Text
	db $08 ; asm
	jr PrintInsteadText

Used2Text: ; 3db34 (f:5b34)
	TX_FAR _Used2Text
	db $08 ; asm

PrintInsteadText: ; 3db39 (f:5b39)
	ld a, [$cced]
	and a
	jr z, PrintCF4BText
	ld hl, InsteadText
	ret

InsteadText: ; 3db43 (f:5b43)
	TX_FAR _InsteadText
	db $08 ; asm

PrintCF4BText: ; 3db48 (f:5b48)
	ld hl, CF4BText
	ret

CF4BText: ; 3db4c (f:5b4c)
	TX_FAR _CF4BText
	db $08 ; asm
	ld hl, ExclamationPointPointerTable
	ld a, [$d11e]
	add a
	push bc
	ld b, $0
	ld c, a
	add hl, bc
	pop bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ret

ExclamationPointPointerTable: ; 3db62 (f:5b62)
	dw ExclamationPoint1Text
	dw ExclamationPoint2Text
	dw ExclamationPoint3Text
	dw ExclamationPoint4Text
	dw ExclamationPoint5Text

ExclamationPoint1Text: ; 3db6c (f:5b6c)
	TX_FAR _ExclamationPoint1Text
	db "@"

ExclamationPoint2Text: ; 3db71 (f:5b71)
	TX_FAR _ExclamationPoint2Text
	db "@"

ExclamationPoint3Text: ; 3db76 (f:5b76)
	TX_FAR _ExclamationPoint3Text
	db "@"

ExclamationPoint4Text: ; 3db7b (f:5b7b)
	TX_FAR _ExclamationPoint4Text
	db "@"

ExclamationPoint5Text: ; 3db80 (f:5b80)
	TX_FAR _ExclamationPoint5Text
	db "@"

Func_3db85: ; 3db85 (f:5b85)
	push bc
	ld a, [$d11e] ; move number
	ld c, a
	ld b, $0
	ld hl, UnknownMovesList_3dba3 ; $5ba3
.asm_3db8f
	ld a, [hli]
	cp $ff
	jr z, .asm_3db9d
	cp c
	jr z, .asm_3db9d
	and a
	jr nz, .asm_3db8f
	inc b
	jr .asm_3db8f
.asm_3db9d
	ld a, b
	ld [$d11e], a
	pop bc
	ret

UnknownMovesList_3dba3: ; 3dba3 (f:5ba3)
	db SWORDS_DANCE, GROWTH
	db $00
	db RECOVER, BIDE, SELFDESTRUCT, AMNESIA
	db $00
	db MEDITATE, AGILITY, TELEPORT, MIMIC, DOUBLE_TEAM, BARRAGE
	db $00
	db POUND, SCRATCH, VICEGRIP, WING_ATTACK, FLY, BIND, SLAM, HORN_ATTACK, BODY_SLAM
	db WRAP, THRASH, TAIL_WHIP, LEER, BITE, GROWL, ROAR, SING, PECK, COUNTER
	db STRENGTH, ABSORB, STRING_SHOT, EARTHQUAKE, FISSURE, DIG, TOXIC, SCREECH, HARDEN
	db MINIMIZE, WITHDRAW, DEFENSE_CURL, METRONOME, LICK, CLAMP, CONSTRICT, POISON_GAS
	db LEECH_LIFE, BUBBLE, FLASH, SPLASH, ACID_ARMOR, FURY_SWIPES, REST, SHARPEN, SLASH, SUBSTITUTE
	db $00
	db $FF ; terminator

PrintMoveFailureText: ; 3dbe2 (f:5be2)
	ld de, W_PLAYERMOVEEFFECT ; $cfd3
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3dbed
	ld de, W_ENEMYMOVEEFFECT ; $cfcd
.asm_3dbed
	ld hl, DoesntAffectMonText ; $5c57
	ld a, [$d05b]
	and $7f
	jr z, .asm_3dc04
	ld hl, AttackMissedText ; $5c42
	ld a, [$d05e]
	cp $ff
	jr nz, .asm_3dc04
	ld hl, UnaffectedText ; $5c4c
.asm_3dc04
	push de
	call PrintText
	xor a
	ld [$d05e], a
	pop de
	ld a, [de]
	cp JUMP_KICK_EFFECT
	ret nz

	; if you get here, the mon used hi jump kick and missed
	ld hl, W_DAMAGE ; $d0d7
	ld a, [hli]
	ld b, [hl]
	srl a
	rr b
	srl a
	rr b
	srl a
	rr b
	ld [hl], b
	dec hl
	ld [hli], a
	or b
	jr nz, .asm_3dc2a
	inc a
	ld [hl], a
.asm_3dc2a
	ld hl, KeptGoingAndCrashedText ; $5c47
	call PrintText
	ld b, $4
	ld a, $24
	call Predef ; indirect jump to Func_48125 (48125 (12:4125))
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr nz, .asm_3dc3f
	jp ApplyDamageToPlayerPokemon
.asm_3dc3f
	jp ApplyDamageToEnemyPokemon

AttackMissedText: ; 3dc42 (f:5c42)
	TX_FAR _AttackMissedText
	db "@"

KeptGoingAndCrashedText: ; 3dc47 (f:5c47)
	TX_FAR _KeptGoingAndCrashedText
	db "@"

UnaffectedText: ; 3dc4c (f:5c4c)
	TX_FAR _UnaffectedText
	db "@"

PrintDoesntAffectText: ; 3dc51 (f:5c51)
	ld hl, DoesntAffectMonText ; $5c57
	jp PrintText

DoesntAffectMonText: ; 3dc57 (f:5c57)
	TX_FAR _DoesntAffectMonText
	db "@"

Func_3dc5c: ; 3dc5c (f:5c5c)
	ld a, [$d05e]
	and a
	jr z, .asm_3dc75
	dec a
	add a
	ld hl, CriticalOHKOTextPointers ; $5c7a
	ld b, $0
	ld c, a
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	call PrintText
	xor a
	ld [$d05e], a
.asm_3dc75
	ld c, $14
	jp DelayFrames

CriticalOHKOTextPointers: ; 3dc7a (f:5c7a)
	dw CriticalHitText
	dw OHKOText

CriticalHitText: ; 3dc7e (f:5c7e)
	TX_FAR _CriticalHitText
	db "@"

OHKOText: ; 3dc83 (f:5c83)
	TX_FAR _OHKOText
	db "@"

Func_3dc88: ; 3dc88 (f:5c88)
	xor a
	ld [$cced], a
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr nz, .asm_3dc97
	ld a, $1
	and a
	ret
.asm_3dc97
	ld hl, W_PARTYMON1_OTID ; $d177
	ld bc, $2c
	ld a, [wPlayerMonNumber] ; $cc2f
	call AddNTimes
	ld a, [wPlayerID] ; $d359
	cp [hl]
	jr nz, .asm_3dcb1
	inc hl
	ld a, [wPlayerID + 1] ; $d35a
	cp [hl]
	jp z, Func_3ddb0
.asm_3dcb1
; what level might disobey?
	ld hl, W_OBTAINEDBADGES
	bit 7, [hl]
	ld a, 101
	jr nz, .asm_3dcce
	bit 5, [hl]
	ld a, 70
	jr nz, .asm_3dcce
	bit 3, [hl]
	ld a, 50
	jr nz, .asm_3dcce
	bit 1, [hl]
	ld a, 30
	jr nz, .asm_3dcce
	ld a, 10
.asm_3dcce
	ld b, a
	ld c, a
	ld a, [W_PLAYERMONLEVEL] ; $d022
	ld d, a
	add b
	ld b, a
	jr nc, .asm_3dcda
	ld b, $ff
.asm_3dcda
	ld a, c
	cp d
	jp nc, Func_3ddb0
.asm_3dcdf
	call GenRandomInBattle
	swap a
	cp b
	jr nc, .asm_3dcdf
	cp c
	jp c, Func_3ddb0
.asm_3dceb
	call GenRandomInBattle
	cp b
	jr nc, .asm_3dceb
	cp c
	jr c, .asm_3dd3f
	ld a, d
	sub c
	ld b, a
	call GenRandomInBattle
	swap a
	sub b
	jr c, .asm_3dd0e
	cp b
	jr nc, .asm_3dd20
	ld hl, WontObeyText
	call PrintText
	call PrintHurtItselfText
	jp Func_3ddb4
.asm_3dd0e
	call GenRandomInBattle
	add a
	swap a
	and $7
	jr z, .asm_3dd0e
	ld [W_PLAYERMONSTATUS], a ; $d018
	ld hl, BeganToNapText
	jr .asm_3dd3a
.asm_3dd20
	call GenRandomInBattle
	and $3
	ld hl, LoafingAroundText
	and a
	jr z, .asm_3dd3a
	ld hl, WontObeyText
	dec a
	jr z, .asm_3dd3a
	ld hl, TurnedAwayText
	dec a
	jr z, .asm_3dd3a
	ld hl, IgnoredOrdersText
.asm_3dd3a
	call PrintText
	jr Func_3ddb4
.asm_3dd3f
	ld a, [$d01d]
	and a
	jr z, .asm_3dd20
	ld a, [$ccee]
	and a
	jr nz, .asm_3dd20
	ld a, [wPlayerSelectedMove] ; $ccdc
	cp $a5
	jr z, .asm_3dd20
	ld hl, W_PLAYERMONPP ; $d02d
	push hl
	ld a, [hli]
	and $3f
	ld b, a
	ld a, [hli]
	and $3f
	add b
	ld b, a
	ld a, [hli]
	and $3f
	add b
	ld b, a
	ld a, [hl]
	and $3f
	add b
	pop hl
	push af
	ld a, [wCurrentMenuItem] ; $cc26
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]
	and $3f
	ld b, a
	pop af
	cp b
	jr z, .asm_3dd20
	ld a, $1
	ld [$cced], a
	ld a, [wMaxMenuItem] ; $cc28
	ld b, a
	ld a, [wCurrentMenuItem] ; $cc26
	ld c, a
.asm_3dd86
	call GenRandomInBattle
	and $3
	cp b
	jr nc, .asm_3dd86
	cp c
	jr z, .asm_3dd86
	ld [wCurrentMenuItem], a ; $cc26
	ld hl, W_PLAYERMONPP ; $d02d
	ld e, a
	ld d, $0
	add hl, de
	ld a, [hl]
	and a
	jr z, .asm_3dd86
	ld a, [wCurrentMenuItem] ; $cc26
	ld c, a
	ld b, $0
	ld hl, W_PLAYERMONMOVES
	add hl, bc
	ld a, [hl]
	ld [wPlayerSelectedMove], a ; $ccdc
	call GetCurrentMove

Func_3ddb0: ; 3ddb0 (f:5db0)
	ld a, $1
	and a
	ret

Func_3ddb4: ; 3ddb4 (f:5db4)
	xor a
	ret

LoafingAroundText: ; 3ddb6 (f:5db6)
	TX_FAR _LoafingAroundText
	db "@"

BeganToNapText: ; 3ddbb (f:5dbb)
	TX_FAR _BeganToNapText
	db "@"

WontObeyText: ; 3ddc0 (f:5dc0)
	TX_FAR _WontObeyText
	db "@"

TurnedAwayText: ; 3ddc5 (f:5dc5)
	TX_FAR _TurnedAwayText
	db "@"

IgnoredOrdersText: ; 3ddca (f:5dca)
	TX_FAR _IgnoredOrdersText
	db "@"

CalculateDamage: ; 3ddcf (f:5dcf)
	xor a
	ld hl, W_DAMAGE ;damage to eventually inflict, intitialise to zero
	ldi [hl], a
	ld [hl], a
	ld hl, W_PLAYERMOVEPOWER
	ld a, [hli]     ;*read attack base power
	and a
	ld d, a         ;*D = attack base, used later
	ret z           ;return if attack is zero
	ld a, [hl]      ;*test attacking type
	cp a, $14       ;types >= $14 are all special
	jr nc, .specialAttack
.physicalAttack
	ld hl, W_ENEMYMONDEFENSE    ;opponent defense
	ld a, [hli]                 ;*BC = opponent defense used later
	ld b, a
	ld c, [hl]
	ld a, [W_ENEMYBATTSTATUS3]  ;test for reflect
	bit 2, a
	jr z, .next
.doubleDefense
	sla c  ;x2 defense if bit2 of D069 is set
	rl b
.next
	ld hl, W_PLAYERMONATK  ;attack pointer
	ld a, [$d05e]
	and a
	jr z, .next3
	ld c, 3
	call Func_3df1c
	ld a, [$ff97]
	ld b, a
	ld a, [$ff98]
	ld c, a
	push bc
	ld hl, $d18f
	ld a, [wPlayerMonNumber]
	ld bc, $002c
	call AddNTimes
	pop bc
	jr .next3
.specialAttack
	ld hl, W_ENEMYMONSPECIAL    ;opponent special
	ld a, [hli]                 ;*BC = opponent special defense used later
	ld b, a
	ld c, [hl]
	ld a, [W_ENEMYBATTSTATUS3]  ;test for lightscreen
	bit 1, a
	jr z, .next2
.doubleSpecialDefense
	sla c           ;x2 special defense if bit1 of D069 set
	rl b
.next2
	ld hl, W_PLAYERMONSPECIAL
	ld a, [$d05e]   ;XXX
	and a
	jr z, .next3  ;skip portion of code that pulls up inactive pokemon
.loadOtherPoke
	ld c, 5
	call Func_3df1c
	ld a, [$ff97]
	ld b, a
	ld a, [$ff98]
	ld c, a
	push bc
	ld hl, $d195
	ld a, [wPlayerMonNumber]
	ld bc, $002c
	call AddNTimes
	pop bc
.next3
	ld a, [hli]  ;HL: when this was taken
	ld l, [hl]
	ld h, a      ;*HL = attacker attack
	or b         ;is either attack or defense high byte nonzero?
	jr z, .next4
	srl b  ;[defense] BC /= 4 [this is just so it fits into a single byte, 10bits max]
	rr c
	srl b
	rr c
	srl h  ;[attack] HL /= 4 [to apply equal scaling]
	rr l
	srl h
	rr l
	ld a, l
	or h
	jr nz, .next4  ;is HL result zero?
	inc l            ;minimum HL = 1
.next4
	ld b, l        ;*B = attack [possibly scaled] [C contains defense]
	ld a, [$d022]  ;*E = level
	ld e, a
	ld a, [$d05e]  ;critical hit?
	and a
	jr z, .next5
	sla e    ;double level if it was a critical hit
.next5
	ld a, 1  ;return Z = 0
	and a
	ret

Func_3de75: ; 3de75 (f:5e75)
	ld hl, W_DAMAGE ; $d0d7
	xor a
	ld [hli], a
	ld [hl], a
	ld hl, W_ENEMYMOVEPOWER ; $cfce
	ld a, [hli]
	ld d, a
	and a
	ret z
	ld a, [hl]
	cp $14
	jr nc, .asm_3debc
	ld hl, W_PLAYERMONDEF
	ld a, [hli]
	ld b, a
	ld c, [hl]
	ld a, [W_PLAYERBATTSTATUS3] ; $d064
	bit 2, a
	jr z, .asm_3de98
	sla c
	rl b
.asm_3de98
	ld hl, W_ENEMYMONATTACK
	ld a, [$d05e]
	and a
	jr z, .asm_3deef
	ld hl, W_PARTYMON1_DEFENSE ; $d191
	ld a, [wPlayerMonNumber] ; $cc2f
	ld bc, $2c
	call AddNTimes
	ld a, [hli]
	ld b, a
	ld c, [hl]
	push bc
	ld c, $2
	call Func_3df1c
	ld hl, $ff97
	pop bc
	jr .asm_3deef
.asm_3debc
	ld hl, W_PLAYERMONSPECIAL
	ld a, [hli]
	ld b, a
	ld c, [hl]
	ld a, [W_PLAYERBATTSTATUS3] ; $d064
	bit 1, a
	jr z, .asm_3decd
	sla c
	rl b
.asm_3decd
	ld hl, W_ENEMYMONSPECIAL ; $cffc
	ld a, [$d05e]
	and a
	jr z, .asm_3deef
	ld hl, W_PARTYMON1_SPECIAL ; $d195
	ld a, [wPlayerMonNumber] ; $cc2f
	ld bc, $2c
	call AddNTimes
	ld a, [hli]
	ld b, a
	ld c, [hl]
	push bc
	ld c, $5
	call Func_3df1c
	ld hl, $ff97
	pop bc
.asm_3deef
	ld a, [hli]
	ld l, [hl]
	ld h, a
	or b
	jr z, .asm_3df0a
	srl b
	rr c
	srl b
	rr c
	srl h
	rr l
	srl h
	rr l
	ld a, l
	or h
	jr nz, .asm_3df0a
	inc l
.asm_3df0a
	ld b, l
	ld a, [W_ENEMYMONLEVEL] ; $cff3
	ld e, a
	ld a, [$d05e]
	and a
	jr z, .asm_3df17
	sla e
.asm_3df17
	ld a, $1
	and a
	and a
	ret

Func_3df1c: ; 3df1c (f:5f1c)
	push de
	push bc
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr nz, .asm_3df40
	ld hl, $d8c6
	dec c
	sla c
	ld b, $0
	add hl, bc
	ld a, [W_ENEMYMONNUMBER] ; $cfe8
	ld bc, $2c
	call AddNTimes
	ld a, [hli]
	ld [$ff97], a
	ld a, [hl]
	ld [$ff98], a
	pop bc
	pop de
	ret
.asm_3df40
	ld a, [W_ENEMYMONLEVEL] ; $cff3
	ld [W_CURENEMYLVL], a ; $d127
	ld a, [$cfe5]
	ld [$d0b5], a
	call GetMonHeader
	ld hl, $cff1
	ld de, $cfaf
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hl]
	ld [de], a
	pop bc
	ld b, $0
	ld hl, $cfa4
	call CalcStat
	pop de
	ret

MoreCalculateDamage: ; 3df65 (f:5f65)
; input:
;	b: attack
;	c: opponent defense
;	d: base power
;	e: level

	ld a, [$fff3] ; whose turn?
	and a
	ld a, [W_PLAYERMOVEEFFECT]
	jr z, .effect
	ld a, [$cfcd]
.effect

; EXPLODE_EFFECT halves defense.
	cp a, EXPLODE_EFFECT
	jr nz, .ok
	srl c
	jr nz, .ok
	inc c ; ...with a minimum value of 1 (used as a divisor later on)
.ok

; Multi-hit attacks may or may not have 0 bp.
	cp a, TWO_TO_FIVE_ATTACKS_EFFECT
	jr z, .skipbp
	cp a, $1e
	jr z, .skipbp

; Calculate OHKO damage based on remaining HP.
	cp a, OHKO_EFFECT
	jp z, Func_3e016

; Don't calculate damage for moves that don't do any.
	ld a, d ; base power
	and a
	ret z
.skipbp

	xor a
	ld hl, H_DIVIDEND
	ldi [hl], a
	ldi [hl], a
	ld [hl], a

; Multiply level by 2
	ld a, e ; level
	add a
	jr nc, .nc
	push af
	ld a, 1
	ld [hl], a
	pop af
.nc
	inc hl
	ldi [hl], a

; Divide by 5
	ld a, 5
	ldd [hl], a
	push bc
	ld b, 4
	call Divide
	pop bc

; Add 2
	inc [hl]
	inc [hl]

	inc hl ; multiplier

; Multiply by attack base power
	ld [hl], d
	call Multiply

; Multiply by attack stat
	ld [hl], b
	call Multiply

; Divide by defender's defense stat
	ld [hl], c
	ld b, 4
	call Divide

; Divide by 50
	ld [hl], 50
	ld b, 4
	call Divide

	ld hl, W_DAMAGE
	ld b, [hl]
	ld a, [H_QUOTIENT + 3]
	add b
	ld [H_QUOTIENT + 3], a
	jr nc, .asm_3dfd0

	ld a, [H_QUOTIENT + 2]
	inc a
	ld [H_QUOTIENT + 2], a
	and a
	jr z, .asm_3e004

.asm_3dfd0
	ld a, [H_QUOTIENT]
	ld b, a
	ld a, [H_QUOTIENT + 1]
	or a
	jr nz, .asm_3e004

	ld a, [H_QUOTIENT + 2]
	cp 998 / $100
	jr c, .asm_3dfe8
	cp 998 / $100 + 1
	jr nc, .asm_3e004
	ld a, [H_QUOTIENT + 3]
	cp 998 % $100
	jr nc, .asm_3e004

.asm_3dfe8
	inc hl
	ld a, [H_QUOTIENT + 3]
	ld b, [hl]
	add b
	ld [hld], a

	ld a, [H_QUOTIENT + 2]
	ld b, [hl]
	adc b
	ld [hl], a
	jr c, .asm_3e004

	ld a, [hl]
	cp 998 / $100
	jr c, .asm_3e00a
	cp 998 / $100 + 1
	jr nc, .asm_3e004
	inc hl
	ld a, [hld]
	cp 998 % $100
	jr c, .asm_3e00a

.asm_3e004
	ld a, 997 / $100
	ld [hli], a
	ld a, 997 % $100
	ld [hld], a

.asm_3e00a
	inc hl
	ld a, [hl]
	add 2
	ld [hld], a
	jr nc, .done
	inc [hl]
.done

	ld a, 1
	and a
	ret

Func_3e016: ; 3e016 (f:6016)
	call Func_3f132
	ld a, [W_MOVEMISSED] ; $d05f
	dec a
	ret


UnusedHighCriticalMoves: ; 3e01e (f:601e)
	db KARATE_CHOP
	db RAZOR_LEAF
	db CRABHAMMER
	db SLASH
	db $FF
; 3e023

; determines if attack is a critical hit
; azure heights claims "the fastest pokémon (who are,not coincidentally,
; among the most popular) tend to CH about 20 to 25% of the time."
CriticalHitTest: ; 3e023 (f:6023)
	xor a
	ld [$d05e], a
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, [$cfe5]
	jr nz, .asm_3e032
	ld a, [W_PLAYERMONID]
.asm_3e032
	ld [$d0b5], a
	call GetMonHeader
	ld a, [W_MONHBASESPEED]
	ld b, a
	srl b                        ; (effective (base speed/2))
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld hl, W_PLAYERMOVEPOWER ; $cfd4
	ld de, W_PLAYERBATTSTATUS2 ; $d063
	jr z, .calcCriticalHitProbability
	ld hl, W_ENEMYMOVEPOWER ; $cfce
	ld de, W_ENEMYBATTSTATUS2 ; $d068
.calcCriticalHitProbability      ; 0x3e04f
	ld a, [hld]                  ; read base power from RAM
	and a
	ret z                        ; do nothing if zero
	dec hl
	ld c, [hl]                   ; read move id
	ld a, [de]
	bit 2, a                     ; test for focus energy
	jr nz, .focusEnergyUsed      ; bug: using focus energy causes a shift to the right instead of left,
	                             ; resulting in 1/4 the usual crit chance
	sla b                        ; (effective (base speed/2)*2)
	jr nc, .noFocusEnergyUsed
	ld b, $ff                    ; cap at 255/256
	jr .noFocusEnergyUsed
.focusEnergyUsed
	srl b
.noFocusEnergyUsed
	ld hl, HighCriticalMoves      ; table of high critical hit moves
.Loop
	ld a, [hli]                  ; read move from move table
	cp c                         ; does it match the move about to be used?
	jr z, .HighCritical          ; if so, the move about to be used is a high critical hit ratio move
	inc a                        ; move on to the next move, FF terminates loop
	jr nz, .Loop                 ; check the next move in HighCriticalMoves
	srl b                        ; /2 for regular move (effective (base speed / 2))
	jr .SkipHighCritical         ; continue as a normal move
.HighCritical
	sla b                        ; *2 for high critical hit moves
	jr nc, .noCarry
	ld b, $ff                    ; cap at 255/256
.noCarry
	sla b                        ; *4 for high critical move (effective (base speed/2)*8))
	jr nc, .SkipHighCritical
	ld b, $ff
.SkipHighCritical
	call GenRandomInBattle       ; generates a random value, in "a"
	rlc a
	rlc a
	rlc a
	cp b                         ; check a against calculated crit rate
	ret nc                       ; no critical hit if no borrow
	ld a, $1
	ld [$d05e], a                ; set critical hit flag
	ret

; high critical hit moves
HighCriticalMoves: ; 3e08e (f:608e)
	db KARATE_CHOP
	db RAZOR_LEAF
	db CRABHAMMER
	db SLASH
	db $FF


; function to determine if Counter hits and if so, how much damage it does
HandleCounterMove: ; 3e093 (f:6093)
	ld a,[H_WHOSETURN] ; whose turn
	and a
; player's turn
	ld hl,wEnemySelectedMove
	ld de,W_ENEMYMOVEPOWER
	ld a,[wPlayerSelectedMove]
	jr z,.next
; enemy's turn
	ld hl,wPlayerSelectedMove
	ld de,W_PLAYERMOVEPOWER
	ld a,[wEnemySelectedMove]
.next
	cp a,COUNTER
	ret nz ; return if not using Counter
	ld a,$01
	ld [W_MOVEMISSED],a ; initialize the move missed variable to true (it is set to false below if the move hits)
	ld a,[hl]
	cp a,COUNTER
	ret z ; if the target also used Counter, miss
	ld a,[de]
	and a
	ret z ; if the move the target used has 0 power, miss
; check if the move the target used was Normal or Fighting type
	inc de
	ld a,[de]
	and a ; normal type
	jr z,.counterableType
	cp a,FIGHTING
	jr z,.counterableType
; if the move wasn't Normal or Fighting type, miss
	xor a
	ret
.counterableType
	ld hl,W_DAMAGE
	ld a,[hli]
	or [hl]
	ret z ; Counter misses if the target did no damage to the Counter user
; double the damage that the target did to the Counter user
	ld a,[hl]
	add a
	ldd [hl],a
	ld a,[hl]
	adc a
	ld [hl],a
	jr nc,.noCarry
; damage is capped at 0xFFFF
	ld a,$ff
	ld [hli],a
	ld [hl],a
.noCarry
	xor a
	ld [W_MOVEMISSED],a
	call MoveHitTest ; do the normal move hit test in addition to Counter's special rules
	xor a
	ret

ApplyAttackToEnemyPokemon: ; 3e0df (f:60df)
	ld a,[W_PLAYERMOVEEFFECT]
	cp a,OHKO_EFFECT
	jr z,ApplyDamageToEnemyPokemon
	cp a,SUPER_FANG_EFFECT
	jr z,.superFangEffect
	cp a,SPECIAL_DAMAGE_EFFECT
	jr z,.specialDamage
	ld a,[W_PLAYERMOVEPOWER]
	and a
	jp z,ApplyAttackToEnemyPokemonDone
	jr ApplyDamageToEnemyPokemon
.superFangEffect
; set the damage to half the target's HP
	ld hl,W_ENEMYMONCURHP
	ld de,W_DAMAGE
	ld a,[hli]
	srl a
	ld [de],a
	inc de
	ld b,a
	ld a,[hl]
	rr a
	ld [de],a
	or b
	jr nz,ApplyDamageToEnemyPokemon
; make sure Super Fang's damage is always at least 1
	ld a,$01
	ld [de],a
	jr ApplyDamageToEnemyPokemon
.specialDamage
	ld hl,W_PLAYERMONLEVEL
	ld a,[hl]
	ld b,a
	ld a,[W_PLAYERMOVENUM]
	cp a,SEISMIC_TOSS
	jr z,.storeDamage
	cp a,NIGHT_SHADE
	jr z,.storeDamage
	ld b,SONICBOOM_DAMAGE
	cp a,SONICBOOM
	jr z,.storeDamage
	ld b,DRAGON_RAGE_DAMAGE
	cp a,DRAGON_RAGE
	jr z,.storeDamage
; Psywave
	ld a,[hl]
	ld b,a
	srl a
	add b
	ld b,a ; b = level * 1.5
; loop until a random number in the range [1, b) is found
.loop
	call GenRandomInBattle ; random number
	and a
	jr z,.loop
	cp b
	jr nc,.loop
	ld b,a
.storeDamage
	ld hl,W_DAMAGE
	xor a
	ld [hli],a
	ld a,b
	ld [hl],a

ApplyDamageToEnemyPokemon: ; 3e142 (f:6142)
	ld hl,W_DAMAGE
	ld a,[hli]
	ld b,a
	ld a,[hl]
	or b
	jr z,ApplyAttackToEnemyPokemonDone ; we're done if damage is 0
	ld a,[W_ENEMYBATTSTATUS2]
	bit 4,a ; does the enemy have a substitute?
	jp nz,AttackSubstitute
; subtract the damage from the pokemon's current HP
; also, save the current HP at wHPBarOldHP
	ld a,[hld]
	ld b,a
	ld a,[W_ENEMYMONCURHP + 1]
	ld [wHPBarOldHP],a
	sub b
	ld [W_ENEMYMONCURHP + 1],a
	ld a,[hl]
	ld b,a
	ld a,[W_ENEMYMONCURHP]
	ld [wHPBarOldHP+1],a
	sbc b
	ld [W_ENEMYMONCURHP],a
	jr nc,.animateHpBar
; if more damage was done than the current HP, zero the HP and set the damage
; equal to how much HP the pokemon had before the attack
	ld a,[wHPBarOldHP+1]
	ld [hli],a
	ld a,[wHPBarOldHP]
	ld [hl],a
	xor a
	ld hl,W_ENEMYMONCURHP
	ld [hli],a
	ld [hl],a
.animateHpBar
	ld hl,W_ENEMYMONMAXHP
	ld a,[hli]
	ld [wHPBarMaxHP+1],a
	ld a,[hl]
	ld [wHPBarMaxHP],a
	ld hl,W_ENEMYMONCURHP
	ld a,[hli]
	ld [wHPBarNewHP+1],a
	ld a,[hl]
	ld [wHPBarNewHP],a
	FuncCoord 2, 2 ; $c3ca
	ld hl,Coord
	xor a
	ld [$cf94],a
	ld a,$48
	call Predef ; animate the HP bar shortening
ApplyAttackToEnemyPokemonDone: ; 3e19d (f:619d)
	jp Func_3cd5a ; redraw pokemon names and HP bars

ApplyAttackToPlayerPokemon: ; 3e1a0 (f:61a0)
	ld a,[W_ENEMYMOVEEFFECT]
	cp a,OHKO_EFFECT
	jr z,ApplyDamageToPlayerPokemon
	cp a,SUPER_FANG_EFFECT
	jr z,.superFangEffect
	cp a,SPECIAL_DAMAGE_EFFECT
	jr z,.specialDamage
	ld a,[W_ENEMYMOVEPOWER]
	and a
	jp z,ApplyAttackToPlayerPokemonDone
	jr ApplyDamageToPlayerPokemon
.superFangEffect
; set the damage to half the target's HP
	ld hl,W_PLAYERMONCURHP
	ld de,W_DAMAGE
	ld a,[hli]
	srl a
	ld [de],a
	inc de
	ld b,a
	ld a,[hl]
	rr a
	ld [de],a
	or b
	jr nz,ApplyDamageToPlayerPokemon
; make sure Super Fang's damage is always at least 1
	ld a,$01
	ld [de],a
	jr ApplyDamageToPlayerPokemon
.specialDamage
	ld hl,W_ENEMYMONLEVEL
	ld a,[hl]
	ld b,a
	ld a,[W_ENEMYMOVENUM]
	cp a,SEISMIC_TOSS
	jr z,.storeDamage
	cp a,NIGHT_SHADE
	jr z,.storeDamage
	ld b,SONICBOOM_DAMAGE
	cp a,SONICBOOM
	jr z,.storeDamage
	ld b,DRAGON_RAGE_DAMAGE
	cp a,DRAGON_RAGE
	jr z,.storeDamage
; Psywave
	ld a,[hl]
	ld b,a
	srl a
	add b
	ld b,a ; b = attacker's level * 1.5
; loop until a random number in the range [0, b) is found
; this differs from the range when the player attacks, which is [1, b)
; it's possible for the enemy to do 0 damage with Psywave, but the player always does at least 1 damage
.loop
	call GenRandomInBattle ; random number
	cp b
	jr nc,.loop
	ld b,a
.storeDamage
	ld hl,W_DAMAGE
	xor a
	ld [hli],a
	ld a,b
	ld [hl],a

ApplyDamageToPlayerPokemon: ; 3e200 (f:6200)
	ld hl,W_DAMAGE
	ld a,[hli]
	ld b,a
	ld a,[hl]
	or b
	jr z,ApplyAttackToPlayerPokemonDone ; we're done if damage is 0
	ld a,[W_PLAYERBATTSTATUS2]
	bit 4,a ; does the player have a substitute?
	jp nz,AttackSubstitute
; subtract the damage from the pokemon's current HP
; also, save the current HP at wHPBarOldHP and the new HP at wHPBarNewHP
	ld a,[hld]
	ld b,a
	ld a,[W_PLAYERMONCURHP + 1]
	ld [wHPBarOldHP],a
	sub b
	ld [W_PLAYERMONCURHP + 1],a
	ld [wHPBarNewHP],a
	ld b,[hl]
	ld a,[W_PLAYERMONCURHP]
	ld [wHPBarOldHP+1],a
	sbc b
	ld [W_PLAYERMONCURHP],a
	ld [wHPBarNewHP+1],a
	jr nc,.animateHpBar
; if more damage was done than the current HP, zero the HP and set the damage
; equal to how much HP the pokemon had before the attack
	ld a,[wHPBarOldHP+1]
	ld [hli],a
	ld a,[wHPBarOldHP]
	ld [hl],a
	xor a
	ld hl,W_PLAYERMONCURHP
	ld [hli],a
	ld [hl],a
	ld hl,wHPBarNewHP
	ld [hli],a
	ld [hl],a
.animateHpBar
	ld hl,W_PLAYERMONMAXHP
	ld a,[hli]
	ld [wHPBarMaxHP+1],a
	ld a,[hl]
	ld [wHPBarMaxHP],a
	FuncCoord 10, 9 ; $c45e
	ld hl,Coord
	ld a,$01
	ld [$cf94],a
	ld a,$48
	call Predef ; animate the HP bar shortening
ApplyAttackToPlayerPokemonDone
	jp Func_3cd5a ; redraw pokemon names and HP bars

AttackSubstitute: ; 3e25e (f:625e)
	ld hl,SubstituteTookDamageText
	call PrintText
; values for player turn
	ld de,wEnemySubstituteHP
	ld bc,W_ENEMYBATTSTATUS2
	ld a,[H_WHOSETURN]
	and a
	jr z,.applyDamageToSubstitute
; values for enemy turn
	ld de,wPlayerSubstituteHP
	ld bc,W_PLAYERBATTSTATUS2
.applyDamageToSubstitute
	ld hl,W_DAMAGE
	ld a,[hli]
	and a
	jr nz,.substituteBroke ; damage > 0xFF always breaks substitutes
; subtract damage from HP of substitute
	ld a,[de]
	sub [hl]
	ld [de],a
	ret nc
.substituteBroke
	ld h,b
	ld l,c
	res 4,[hl] ; unset the substitute bit
	ld hl,SubstituteBrokeText
	call PrintText
; flip whose turn it is for the next function call
	ld a,[H_WHOSETURN]
	xor a,$01
	ld [H_WHOSETURN],a
	callab Func_79747 ; animate the substitute breaking
; flip the turn back to the way it was
	ld a,[H_WHOSETURN]
	xor a,$01
	ld [H_WHOSETURN],a
	ld hl,W_PLAYERMOVEEFFECT ; value for player's turn
	and a
	jr z,.nullifyEffect
	ld hl,W_ENEMYMOVEEFFECT ; value for enemy's turn
.nullifyEffect
	xor a
	ld [hl],a ; zero the effect of the attacker's move
	jp Func_3cd5a ; redraw pokemon names and HP bars

SubstituteTookDamageText: ; 3e2ac (f:62ac)
	TX_FAR _SubstituteTookDamageText
	db "@"

SubstituteBrokeText: ; 3e2b1 (f:62b1)
	TX_FAR _SubstituteBrokeText
	db "@"

; this function raises the attack modifier of a pokemon using Rage when that pokemon is attacked
HandleBuildingRage: ; 3e2b6 (f:62b6)
; values for the player turn
	ld hl,W_ENEMYBATTSTATUS2
	ld de,wEnemyMonStatMods
	ld bc,W_ENEMYMOVENUM
	ld a,[H_WHOSETURN]
	and a
	jr z,.next
; values for the enemy turn
	ld hl,W_PLAYERBATTSTATUS2
	ld de,wPlayerMonStatMods
	ld bc,W_PLAYERMOVENUM
.next
	bit 6,[hl] ; is the pokemon being attacked under the effect of Rage?
	ret z ; return if not
	ld a,[de]
	cp a,$0d ; maximum stat modifier value
	ret z ; return if attack modifier is already maxed
	ld a,[H_WHOSETURN]
	xor a,$01 ; flip turn for the stat modifier raising function
	ld [H_WHOSETURN],a
; change the target pokemon's move to $00 and the effect to the one
; that causes the attack modifier to go up one stage
	ld h,b
	ld l,c
	ld [hl],$00 ; null move number
	inc hl
	ld [hl],ATTACK_UP1_EFFECT
	push hl
	ld hl,BuildingRageText
	call PrintText
	call StatModifierUpEffect ; stat modifier raising function
	pop hl
	xor a
	ldd [hl],a ; null move effect
	ld a,RAGE
	ld [hl],a ; restore the target pokemon's move number to Rage
	ld a,[H_WHOSETURN]
	xor a,$01 ; flip turn back to the way it was
	ld [H_WHOSETURN],a
	ret

BuildingRageText: ; 3e2f8 (f:62f8)
	TX_FAR _BuildingRageText
	db "@"

; copy last move for Mirror Move
; sets zero flag on failure and unsets zero flag on success
MirrorMoveCopyMove: ; 3e2fd (f:62fd)
	ld a,[H_WHOSETURN]
	and a
; values for player turn
	ld a,[$ccf2]
	ld hl,wPlayerSelectedMove
	ld de,W_PLAYERMOVENUM
	jr z,.next
; values for enemy turn
	ld a,[$ccf1]
	ld de,W_ENEMYMOVENUM
	ld hl,wEnemySelectedMove
.next
	ld [hl],a
	cp a,MIRROR_MOVE ; did the target pokemon also use Mirror Move?
	jr z,.mirrorMoveFailed
	and a ; null move?
	jr nz,ReloadMoveData
.mirrorMoveFailed
; Mirror Move fails on itself and null moves
	ld hl,MirrorMoveFailedText
	call PrintText
	xor a
	ret

MirrorMoveFailedText: ; 3e324 (f:6324)
	TX_FAR _MirrorMoveFailedText
	db "@"

; function used to reload move data for moves like Mirror Move and Metronome
ReloadMoveData: ; 3e329 (f:6329)
	ld [$d11e],a
	dec a
	ld hl,Moves
	ld bc,$0006
	call AddNTimes
	ld a,BANK(Moves)
	call FarCopyData ; copy the move's stats
	call IncrementMovePP
; the follow two function calls are used to reload the move name
	call GetMoveName
	call CopyStringToCF4B
	ld a,$01
	and a
	ret

; function that picks a random move for metronome
MetronomePickMove: ; 3e348 (f:6348)
	xor a
	ld [$cc5b],a
	ld a,METRONOME
	call PlayMoveAnimation ; play Metronome's animation
; values for player turn
	ld de,W_PLAYERMOVENUM
	ld hl,wPlayerSelectedMove
	ld a,[H_WHOSETURN]
	and a
	jr z,.pickMoveLoop
; values for enemy turn
	ld de,W_ENEMYMOVENUM
	ld hl,wEnemySelectedMove
; loop to pick a random number in the range [1, $a5) to be the move used by Metronome
.pickMoveLoop
	call GenRandomInBattle ; random number
	and a
	jr z,.pickMoveLoop
	cp a,NUM_MOVES + 1 ; max normal move number + 1 (this is Struggle's move number)
	jr nc,.pickMoveLoop
	cp a,METRONOME
	jr z,.pickMoveLoop
	ld [hl],a
	jr ReloadMoveData

; this function increments the current move's PP
; it's used to prevent moves that run another move within the same turn
; (like Mirror Move and Metronome) from losing 2 PP
IncrementMovePP: ; 3e373 (f:6373)
	ld a,[H_WHOSETURN]
	and a
; values for player turn
	ld hl,W_PLAYERMONPP
	ld de,W_PARTYMON1_MOVE1PP
	ld a,[wPlayerMoveListIndex]
	jr z,.next
; values for enemy turn
	ld hl,W_ENEMYMONPP
	ld de,$d8c1 ; enemy party pokemon 1 PP
	ld a,[wEnemyMoveListIndex]
.next
	ld b,$00
	ld c,a
	add hl,bc
	inc [hl] ; increment PP in the currently battling pokemon memory location
	ld h,d
	ld l,e
	add hl,bc
	ld a,[H_WHOSETURN]
	and a
	ld a,[wPlayerMonNumber] ; value for player turn
	jr z,.next2
	ld a,[W_ENEMYMONNUMBER] ; value for enemy turn
.next2
	ld bc,$002c
	call AddNTimes
	inc [hl] ; increment PP in the party memory location
	ret

; function to adjust the base damage of an attack to account for type effectiveness
AdjustDamageForMoveType: ; 3e3a5 (f:63a5)
; values for player turn
	ld hl,W_PLAYERMONTYPES
	ld a,[hli]
	ld b,a    ; b = type 1 of attacker
	ld c,[hl] ; c = type 2 of attacker
	ld hl,W_ENEMYMONTYPES
	ld a,[hli]
	ld d,a    ; d = type 1 of defender
	ld e,[hl] ; e = type 2 of defender
	ld a,[W_PLAYERMOVETYPE]
	ld [$d11e],a
	ld a,[H_WHOSETURN]
	and a
	jr z,.next
; values for enemy turn
	ld hl,W_ENEMYMONTYPES
	ld a,[hli]
	ld b,a    ; b = type 1 of attacker
	ld c,[hl] ; c = type 2 of attacker
	ld hl,W_PLAYERMONTYPES
	ld a,[hli]
	ld d,a    ; d = type 1 of defender
	ld e,[hl] ; e = type 2 of defender
	ld a,[W_ENEMYMOVETYPE]
	ld [$d11e],a
.next
	ld a,[$d11e] ; move type
	cp b ; does the move type match type 1 of the attacker?
	jr z,.sameTypeAttackBonus
	cp c ; does the move type match type 2 of the attacker?
	jr z,.sameTypeAttackBonus
	jr .skipSameTypeAttackBonus
.sameTypeAttackBonus
; if the move type matches one of the attacker's types
	ld hl,W_DAMAGE + 1
	ld a,[hld]
	ld h,[hl]
	ld l,a    ; hl = damage
	ld b,h
	ld c,l    ; bc = damage
	srl b
	rr c      ; bc = floor(0.5 * damage)
	add hl,bc ; hl = floor(1.5 * damage)
; store damage
	ld a,h
	ld [W_DAMAGE],a
	ld a,l
	ld [W_DAMAGE + 1],a
	ld hl,$d05b
	set 7,[hl]
.skipSameTypeAttackBonus
	ld a,[$d11e]
	ld b,a ; b = move type
	ld hl,TypeEffects
.loop
	ld a,[hli] ; a = "attacking type" of the current type pair
	cp a,$ff
	jr z,.done
	cp b ; does move type match "attacking type"?
	jr nz,.nextTypePair
	ld a,[hl] ; a = "defending type" of the current type pair
	cp d ; does type 1 of defender match "defending type"?
	jr z,.matchingPairFound
	cp e ; does type 2 of defender match "defending type"?
	jr z,.matchingPairFound
	jr .nextTypePair
.matchingPairFound
; if the move type matches the "attacking type" and one of the defender's types matches the "defending type"
	push hl
	push bc
	inc hl
	ld a,[$d05b]
	and a,$80
	ld b,a
	ld a,[hl] ; a = damage multiplier
	ld [H_MULTIPLIER],a
	add b
	ld [$d05b],a
	xor a
	ld [H_MULTIPLICAND],a
	ld hl,W_DAMAGE
	ld a,[hli]
	ld [H_MULTIPLICAND + 1],a
	ld a,[hld]
	ld [H_MULTIPLICAND + 2],a
	call Multiply
	ld a,10
	ld [H_DIVISOR],a
	ld b,$04
	call Divide
	ld a,[H_QUOTIENT + 2]
	ld [hli],a
	ld b,a
	ld a,[H_QUOTIENT + 3]
	ld [hl],a
	or b ; is damage 0?
	jr nz,.skipTypeImmunity
.typeImmunity
; if damage is 0, make the move miss
	inc a
	ld [W_MOVEMISSED],a
.skipTypeImmunity
	pop bc
	pop hl
.nextTypePair
	inc hl
	inc hl
	jp .loop
.done
	ret

; function to tell how effective the type of an enemy attack is on the player's current pokemon
; this doesn't take into account the effects that dual types can have
; (e.g. 4x weakness / resistance, weaknesses and resistances canceling)
; the result is stored in [$D11E]
; ($05 is not very effective, $10 is neutral, $14 is super effective)
; as far is can tell, this is only used once in some AI code to help decide which move to use
AIGetTypeEffectiveness: ; 3e449 (f:6449)
	ld a,[W_ENEMYMOVETYPE]
	ld d,a                 ; d = type of enemy move
	ld hl,W_PLAYERMONTYPES
	ld b,[hl]              ; b = type 1 of player's pokemon
	inc hl
	ld c,[hl]              ; c = type 2 of player's pokemon
	ld a,$10
	ld [$d11e],a           ; initialize [$D11E] to neutral effectiveness
	ld hl,TypeEffects
.loop
	ld a,[hli]
	cp a,$ff
	ret z
	cp d                   ; match the type of the move
	jr nz,.nextTypePair1
	ld a,[hli]
	cp b                   ; match with type 1 of pokemon
	jr z,.done
	cp c                   ; or match with type 2 of pokemon
	jr z,.done
	jr .nextTypePair2
.nextTypePair1
	inc hl
.nextTypePair2
	inc hl
	jr .loop
.done
	ld a,[hl]
	ld [$d11e],a           ; store damage multiplier
	ret

INCLUDE "data/type_effects.asm"

; some tests that need to pass for a move to hit
MoveHitTest: ; 3e56b (f:656b)
; player's turn
	ld hl,W_ENEMYBATTSTATUS1
	ld de,W_PLAYERMOVEEFFECT
	ld bc,W_ENEMYMONSTATUS
	ld a,[H_WHOSETURN]
	and a
	jr z,.dreamEaterCheck
; enemy's turn
	ld hl,W_PLAYERBATTSTATUS1
	ld de,W_ENEMYMOVEEFFECT
	ld bc,W_PLAYERMONSTATUS
.dreamEaterCheck
	ld a,[de]
	cp a,DREAM_EATER_EFFECT
	jr nz,.swiftCheck
	ld a,[bc]
	and a,$07 ; is the target pokemon sleeping?
	jp z,.moveMissed
.swiftCheck
	ld a,[de]
	cp a,SWIFT_EFFECT
	ret z ; Swift never misses (interestingly, Azure Heights lists this is a myth, but it appears to be true)
	call CheckTargetSubstitute ; substitute check (note that this overwrites a)
	jr z,.checkForDigOrFlyStatus
; this code is buggy. it's supposed to prevent HP draining moves from working on substitutes.
; since $7b79 overwrites a with either $00 or $01, it never works.
	cp a,DRAIN_HP_EFFECT ; $03
	jp z,.moveMissed
	cp a,DREAM_EATER_EFFECT ; $08
	jp z,.moveMissed
.checkForDigOrFlyStatus
	bit 6,[hl]
	jp nz,.moveMissed
	ld a,[H_WHOSETURN]
	and a
	jr nz,.enemyTurn
.playerTurn
; this checks if the move effect is disallowed by mist
	ld a,[W_PLAYERMOVEEFFECT]
	cp a,ATTACK_DOWN1_EFFECT
	jr c,.skipEnemyMistCheck
	cp a,BIDE_EFFECT
	jr c,.enemyMistCheck
	cp a,$3a
	jr c,.skipEnemyMistCheck
	cp a,POISON_EFFECT
	jr c,.enemyMistCheck
	jr .skipEnemyMistCheck
.enemyMistCheck
; if move effect is from $12 to $19 inclusive or $3a to $41 inclusive
; i.e. the following moves
; GROWL, TAIL WHIP, LEER, STRING SHOT, SAND-ATTACK, SMOKESCREEN, KINESIS,
; FLASH, CONVERSION, HAZE*, SCREECH, LIGHT SCREEN*, REFLECT*
; the moves that are marked with an asterisk are not affected since this
; function is not called when those moves are used
; XXX are there are any others like those three?
	ld a,[W_ENEMYBATTSTATUS2]
	bit 1,a ; is mon protected by mist?
	jp nz,.moveMissed
.skipEnemyMistCheck
	ld a,[W_PLAYERBATTSTATUS2]
	bit 0,a ; is the player using X Accuracy?
	ret nz ; if so, always hit regardless of accuracy/evasion
	jr .calcHitChance
.enemyTurn
	ld a,[W_ENEMYMOVEEFFECT]
	cp a,ATTACK_DOWN1_EFFECT
	jr c,.skipPlayerMistCheck
	cp a,BIDE_EFFECT
	jr c,.playerMistCheck
	cp a,$3a
	jr c,.skipPlayerMistCheck
	cp a,POISON_EFFECT
	jr c,.playerMistCheck
	jr .skipPlayerMistCheck
.playerMistCheck
; similar to enemy mist check
	ld a,[W_PLAYERBATTSTATUS2]
	bit 1,a ; is mon protected by mist?
	jp nz,.moveMissed
.skipPlayerMistCheck
	ld a,[W_ENEMYBATTSTATUS2]
	bit 0,a ; is the enemy using X Accuracy?
	ret nz ; if so, always hit regardless of accuracy/evasion
.calcHitChance
	call CalcHitChance ; scale the move accuracy according to attacker's accuracy and target's evasion
	ld a,[W_PLAYERMOVEACCURACY]
	ld b,a
	ld a,[H_WHOSETURN]
	and a
	jr z,.doAccuracyCheck
	ld a,[W_ENEMYMOVEACCURACY]
	ld b,a
.doAccuracyCheck
; if the random number generated is greater than or equal to the scaled accuracy, the move misses
; note that this means that even the highest accuracy is still just a 255/256 chance, not 100%
	call GenRandomInBattle ; random number
	cp b
	jr nc,.moveMissed
	ret
.moveMissed
	xor a
	ld hl,W_DAMAGE ; zero the damage
	ld [hli],a
	ld [hl],a
	inc a
	ld [W_MOVEMISSED],a
	ld a,[H_WHOSETURN]
	and a
	jr z,.playerTurn2
.enemyTurn2
	ld hl,W_ENEMYBATTSTATUS1
	res 5,[hl] ; end multi-turn attack e.g. wrap
	ret
.playerTurn2
	ld hl,W_PLAYERBATTSTATUS1
	res 5,[hl] ; end multi-turn attack e.g. wrap
	ret

; values for player turn
CalcHitChance: ; 3e624 (f:6624)
	ld hl,W_PLAYERMOVEACCURACY
	ld a,[H_WHOSETURN]
	and a
	ld a,[wPlayerMonAccuracyMod]
	ld b,a
	ld a,[wEnemyMonEvasionMod]
	ld c,a
	jr z,.next
; values for enemy turn
	ld hl,W_ENEMYMOVEACCURACY
	ld a,[wEnemyMonAccuracyMod]
	ld b,a
	ld a,[wPlayerMonEvasionMod]
	ld c,a
.next
	ld a,$0e
	sub c
	ld c,a ; c = 14 - EVASIONMOD (this "reflects" the value over 7, so that an increase in the target's evasion decreases the hit chance instead of increasing the hit chance)
; zero the high bytes of the multiplicand
	xor a
	ld [H_MULTIPLICAND],a
	ld [H_MULTIPLICAND + 1],a
	ld a,[hl]
	ld [H_MULTIPLICAND + 2],a ; set multiplicand to move accuracy
	push hl
	ld d,$02 ; loop has two iterations
; loop to do the calculations, the first iteration multiplies by the accuracy ratio and the second iteration multiplies by the evasion ratio
.loop
	push bc
	ld hl, StatModifierRatios  ; $76cb ; stat modifier ratios
	dec b
	sla b
	ld c,b
	ld b,$00
	add hl,bc ; hl = address of stat modifier ratio
	pop bc
	ld a,[hli]
	ld [H_MULTIPLIER],a ; set multiplier to the numerator of the ratio
	call Multiply
	ld a,[hl]
	ld [H_DIVISOR],a ; set divisor to the the denominator of the ratio (the dividend is the product of the previous multiplication)
	ld b,$04 ; number of bytes in the dividend
	call Divide
	ld a,[H_QUOTIENT + 3]
	ld b,a
	ld a,[H_QUOTIENT + 2]
	or b
	jp nz,.nextCalculation
; make sure the result is always at least one
	ld [H_QUOTIENT + 2],a
	ld a,$01
	ld [H_QUOTIENT + 3],a
.nextCalculation
	ld b,c
	dec d
	jr nz,.loop
	ld a,[H_QUOTIENT + 2]
	and a ; is the calculated hit chance over 0xFF?
	ld a,[H_QUOTIENT + 3]
	jr z,.storeAccuracy
; if calculated hit chance over 0xFF
	ld a,$ff ; set the hit chance to 0xFF
.storeAccuracy
	pop hl
	ld [hl],a ; store the hit chance in the move accuracy variable
	ret

Func_3e687: ; 3e687 (f:6687)
	ld hl, W_DAMAGE ; $d0d7
	ld a, [hli]
	and a
	jr nz, .asm_3e692
	ld a, [hl]
	cp $2
	ret c
.asm_3e692
	xor a
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	dec hl
	ld a, [hli]
	ld [$ff97], a
	ld a, [hl]
	ld [$ff98], a
.asm_3e69c
	call GenRandomInBattle
	rrca
	cp $d9
	jr c, .asm_3e69c
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	call Multiply
	ld a, $ff
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld b, $4
	call Divide
	ld a, [$ff97]
	ld hl, W_DAMAGE ; $d0d7
	ld [hli], a
	ld a, [$ff98]
	ld [hl], a
	ret

Func_3e6bc: ; 3e6bc (f:66bc)
	ld a, [wEnemySelectedMove] ; $ccdd
	inc a
	jp z, Func_3e88c
	call PrintGhostText
	jp z, Func_3e88c
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr nz, .asm_3e6dc
	ld b, $1
	ld a, [$cc3e]
	cp $e
	jr z, .asm_3e6dc
	cp $4
	ret nc
.asm_3e6dc
	ld hl, $ccd5
	inc [hl]
	xor a
	ld [W_MOVEMISSED], a ; $d05f
	ld [$ccf4], a
	ld a, $a
	ld [$d05b], a
	call Func_3e88f
	jr nz, .asm_3e6f2
	jp [hl]
.asm_3e6f2
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	bit 4, [hl]
	jr nz, asm_3e70b
	call GetCurrentMove

Func_3e6fc: ; 3e6fc (f:66fc)
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	cp CHARGE_EFFECT
	jp z, Func_3f132
	cp FLY_EFFECT
	jp z, Func_3f132
	jr asm_3e72b
asm_3e70b: ; 3e70b (f:670b)
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	res 4, [hl] ; no longer charging up for attack
	res 6, [hl] ; no longer invulnerable to typcial attacks
	ld a, [W_ENEMYMOVENUM] ; $cfcc
	ld [$d0b5], a
	ld a, $2c
	ld [$d0b7], a
	ld a, MOVE_NAME
	ld [W_LISTTYPE], a
	call GetName
	ld de, $cd6d
	call CopyStringToCF4B
asm_3e72b: ; 3e72b (f:672b)
	xor a
	ld [$cced], a
	call PrintMonName1Text
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	ld hl, EffectsArray1 ; $4000
	ld de, $1
	call IsInArray
	jp c, Func_3f132
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	ld hl, EffectsArray5B ; $4049
	ld de, $1
	call IsInArray
	call c, Func_3f132
asm_3e750: ; 3e750 (f:6750)
	call Func_3ec81
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	ld hl, EffectsArray2 ; $4011
	ld de, $1
	call IsInArray
	jp c, Func_3e77f
	call CriticalHitTest
	call HandleCounterMove
	jr z, asm_3e782
	call Func_3ec81
	call Func_3de75
	call Func_3ec81
	call MoreCalculateDamage
	jp z, Func_3e7d1
	call AdjustDamageForMoveType
	call Func_3e687

Func_3e77f: ; 3e77f (f:677f)
	call MoveHitTest
asm_3e782: ; 3e782 (f:6782)
	ld a, [W_MOVEMISSED] ; $d05f
	and a
	jr z, .asm_3e791
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	cp EXPLODE_EFFECT
	jr z, asm_3e7a0
	jr Func_3e7d1
.asm_3e791
	call Func_3ec81

Func_3e794: ; 3e794 (f:6794)
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	and a
	ld a, $1
	jr z, asm_3e7a4
	ld a, $2
	jr asm_3e7a4
asm_3e7a0: ; 3e7a0 (f:67a0)
	call Func_3ec81
	xor a
asm_3e7a4: ; 3e7a4 (f:67a4)
	push af
	ld a, [W_ENEMYBATTSTATUS2] ; $d068
	bit 4, a ; does mon have a substitute?
	ld hl, Func_79747
	ld b, BANK(Func_79747)
	call nz, Bankswitch
	pop af
	ld [$cc5b], a
	ld a, [W_ENEMYMOVENUM] ; $cfcc
	call PlayMoveAnimation
	call Func_3eed3
	call Func_3cdec
	ld a, [W_ENEMYBATTSTATUS2] ; $d068
	bit 4, a ; does mon have a substitute?
	ld hl, Func_79771
	ld b, BANK(Func_79771)
	call nz, Bankswitch ; slide the substitute's sprite out
	jr asm_3e7ef

Func_3e7d1: ; 3e7d1 (f:67d1)
	call Func_3ec81
	ld c, $1e
	call DelayFrames
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	cp FLY_EFFECT
	jr z, .asm_3e7e6
	cp CHARGE_EFFECT
	jr z, .asm_3e7e6
	jr asm_3e7ef
.asm_3e7e6
	xor a
	ld [$cc5b], a
	ld a,STATUS_AFFECTED_ANIM
	call PlayMoveAnimation
asm_3e7ef: ; 3e7ef (f:67ef)
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	cp MIRROR_MOVE_EFFECT
	jr nz, .notMirrorMoveEffect
	call MirrorMoveCopyMove
	jp z, Func_3e88c
	jp Func_3e6fc
.notMirrorMoveEffect
	cp METRONOME_EFFECT
	jr nz, .notMetronomeEffect
	call MetronomePickMove
	jp Func_3e6fc
.notMetronomeEffect
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	ld hl, EffectsArray3 ; $4014
	ld de, $1
	call IsInArray
	jp c, Func_3f132
	ld a, [W_MOVEMISSED] ; $d05f
	and a
	jr z, .asm_3e82b
	call PrintMoveFailureText
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	cp EXPLODE_EFFECT
	jr z, .asm_3e83e
	jp Func_3e88c
.asm_3e82b
	call ApplyAttackToPlayerPokemon
	call Func_3dc5c
	callab DisplayEffectiveness
	ld a, $1
	ld [$ccf4], a
.asm_3e83e
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	ld hl, EffectsArray4 ; $4030
	ld de, $1
	call IsInArray
	call c, Func_3f132
	ld hl, W_PLAYERMONCURHP ; $d015
	ld a, [hli]
	ld b, [hl]
	or b
	ret z
	call HandleBuildingRage
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	bit 2, [hl] ; is mon hitting multiple times? (example: double kick)
	jr z, .asm_3e873
	push hl
	ld hl, $d06f
	dec [hl]
	pop hl
	jp nz, Func_3e794
	res 2, [hl] ; mon is no longer hitting multiple times
	ld hl, HitXTimesText ; $6887
	call PrintText
	xor a
	ld [$cd05], a
.asm_3e873
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	and a
	jr z, Func_3e88c
	ld hl, EffectsArray5 ; $403b
	ld de, $1
	call IsInArray
	call nc, Func_3f132
	jr Func_3e88c

HitXTimesText: ; 3e887 (f:6887)
	TX_FAR _HitXTimesText
	db "@"

Func_3e88c: ; 3e88c (f:688c)
	ld b, $1
	ret

Func_3e88f: ; 3e88f (f:688f)
	ld hl, W_ENEMYMONSTATUS ; $cfe9
	ld a, [hl]
	and $7
	jr z, .asm_3e8bf
	dec a
	ld [W_ENEMYMONSTATUS], a ; $cfe9
	and a
	jr z, .asm_3e8af
	ld hl, FastAsleepText
	call PrintText
	xor a
	ld [$cc5b], a
	ld a,SLP_ANIM
	call PlayMoveAnimation
	jr .asm_3e8b5
.asm_3e8af
	ld hl, WokeUpText
	call PrintText
.asm_3e8b5
	xor a
	ld [$ccf2], a
	ld hl, Func_3e88c ; $688c
	jp Func_3eab8
.asm_3e8bf
	bit 5, [hl]
	jr z, .asm_3e8d3
	ld hl, IsFrozenText
	call PrintText
	xor a
	ld [$ccf2], a
	ld hl, Func_3e88c ; $688c
	jp Func_3eab8
.asm_3e8d3
	ld a, [W_PLAYERBATTSTATUS1] ; $d062
	bit 5, a
	jp z, Func_3e8e7
	ld hl, CantMoveText
	call PrintText
	ld hl, Func_3e88c ; $688c
	jp Func_3eab8

Func_3e8e7: ; 3e8e7 (f:68e7)
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	bit 3, [hl]
	jp z, Func_3e8fd
	res 3, [hl]
	ld hl, FlinchedText
	call PrintText
	ld hl, Func_3e88c ; $688c
	jp Func_3eab8

Func_3e8fd: ; 3e8fd (f:68fd)
	ld hl, W_ENEMYBATTSTATUS2 ; $d068
	bit 5, [hl]
	jr z, .asm_3e912
	res 5, [hl]
	ld hl, MustRechargeText
	call PrintText
	ld hl, Func_3e88c ; $688c
	jp Func_3eab8
.asm_3e912
	ld hl, W_ENEMYDISABLEDMOVE ; $d072
	ld a, [hl]
	and a
	jr z, .asm_3e929
	dec a
	ld [hl], a
	and $f
	jr nz, .asm_3e929
	ld [hl], a
	ld [$ccef], a
	ld hl, DisabledNoMoreText
	call PrintText
.asm_3e929
	ld a, [W_ENEMYBATTSTATUS1] ; $d067
	add a
	jp nc, Func_3e9aa
	ld hl, $d070
	dec [hl]
	jr nz, .asm_3e944
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	res 7, [hl]
	ld hl, ConfusedNoMoreText
	call PrintText
	jp Func_3e9aa
.asm_3e944
	ld hl, IsConfusedText
	call PrintText
	xor a
	ld [$cc5b], a
	ld a,CONF_ANIM
	call PlayMoveAnimation
	call GenRandomInBattle
	cp $80
	jr c, Func_3e9aa
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	ld a, [hl]
	and $80
	ld [hl], a
	ld hl, HurtItselfText
	call PrintText
	ld hl, W_PLAYERMONDEF
	ld a, [hli]
	push af
	ld a, [hld]
	push af
	ld a, [W_ENEMYMONDEFENSE] ; $cff8
	ld [hli], a
	ld a, [$cff9]
	ld [hl], a
	ld hl, W_ENEMYMOVEEFFECT ; $cfcd
	push hl
	ld a, [hl]
	push af
	xor a
	ld [hli], a
	ld [$d05e], a
	ld a, $28
	ld [hli], a
	xor a
	ld [hl], a
	call Func_3de75
	call MoreCalculateDamage
	pop af
	pop hl
	ld [hl], a
	ld hl, $d028
	pop af
	ld [hld], a
	pop af
	ld [hl], a
	xor a
	ld [$cc5b], a
	ld [H_WHOSETURN], a ; $fff3
	ld a, POUND
	call PlayMoveAnimation
	ld a, $1
	ld [H_WHOSETURN], a ; $fff3
	call ApplyDamageToEnemyPokemon
	jr asm_3e9d3

Func_3e9aa: ; 3e9aa (f:69aa)
	ld a, [$ccef]
	and a
	jr z, .asm_3e9bf
	ld hl, wEnemySelectedMove ; $ccdd
	cp [hl]
	jr nz, .asm_3e9bf
	call PrintMoveIsDisabledText
	ld hl, Func_3e88c ; $688c
	jp Func_3eab8
.asm_3e9bf
	ld hl, W_ENEMYMONSTATUS ; $cfe9
	bit 6, [hl]
	jr z, asm_3e9f6
	call GenRandomInBattle
	cp $3f
	jr nc, asm_3e9f6
	ld hl, FullyParalyzedText
	call PrintText
asm_3e9d3: ; 3e9d3 (f:69d3)
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	ld a, [hl]
	and $cc
	ld [hl], a
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
	cp FLY_EFFECT
	jr z, .asm_3e9e7
	cp CHARGE_EFFECT
	jr z, .asm_3e9e7
	jr .asm_3e9f0
.asm_3e9e7
	xor a
	ld [$cc5b], a
	ld a, STATUS_AFFECTED_ANIM
	call PlayMoveAnimation
.asm_3e9f0
	ld hl, Func_3e88c ; $688c
	jp Func_3eab8
asm_3e9f6: ; 3e9f6 (f:69f6)
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	bit 0, [hl] ; is mon using bide?
	jr z, .asm_3ea54
	xor a
	ld [W_ENEMYMOVENUM], a ; $cfcc
	ld hl, W_DAMAGE ; $d0d7
	ld a, [hli]
	ld b, a
	ld c, [hl]
	ld hl, $cd06
	ld a, [hl]
	add c
	ld [hld], a
	ld a, [hl]
	adc b
	ld [hl], a
	ld hl, $d06f
	dec [hl]
	jr z, .asm_3ea1c
	ld hl, Func_3e88c ; $688c
	jp Func_3eab8
.asm_3ea1c
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	res 0, [hl]
	ld hl, UnleashedEnergyText
	call PrintText
	ld a, $1
	ld [W_ENEMYMOVEPOWER], a ; $cfce
	ld hl, $cd06
	ld a, [hld]
	add a
	ld b, a
	ld [$d0d8], a
	ld a, [hl]
	rl a
	ld [W_DAMAGE], a ; $d0d7
	or b
	jr nz, .asm_3ea43
	ld a, $1
	ld [W_MOVEMISSED], a ; $d05f
.asm_3ea43
	xor a
	ld [hli], a
	ld [hl], a
	ld a, BIDE
	ld [W_ENEMYMOVENUM], a ; $cfcc
	call Func_3ec81
	ld hl, asm_3e782 ; $6782
	jp Func_3eab8
.asm_3ea54
	bit 1, [hl] ; is mon using thrash or petal dance?
	jr z, .asm_3ea83
	ld a, THRASH
	ld [W_ENEMYMOVENUM], a ; $cfcc
	ld hl, ThrashingAboutText
	call PrintText
	ld hl, $d06f
	dec [hl]
	ld hl, asm_3e750 ; $6750
	jp nz, Func_3eab8
	push hl
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	res 1, [hl] ; mon is no longer using thrash or petal dance
	set 7, [hl] ; mon is now confused
	call GenRandomInBattle
	and $3
	inc a
	inc a
	ld [$d070], a
	pop hl
	jp Func_3eab8
.asm_3ea83
	bit 5, [hl] ; is mon using multi-turn move?
	jp z, Func_3ea9b
	ld hl, AttackContinuesText
	call PrintText
	ld hl, $d06f
	dec [hl]
	ld hl, Func_3e794 ; $6794
	jp nz, Func_3eab8
	jp Func_3eab8

Func_3ea9b: ; 3ea9b (f:6a9b)
	ld a, [W_ENEMYBATTSTATUS2] ; $d068
	bit 6, a ; is mon using rage?
	jp z, Func_3eaba
	ld a, RAGE
	ld [$d11e], a
	call GetMoveName
	call CopyStringToCF4B
	xor a
	ld [W_ENEMYMOVEEFFECT], a ; $cfcd
	ld hl, asm_3e72b ; $672b
	jp Func_3eab8

Func_3eab8: ; 3eab8 (f:6ab8)
	xor a
	ret

Func_3eaba: ; 3eaba (f:6aba)
	ld a, $1
	and a
	ret

GetCurrentMove: ; 3eabe (f:6abe)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jp z, .player
	ld de, W_ENEMYMOVENUM ; $cfcc
	ld a, [wEnemySelectedMove] ; $ccdd
	jr .selected
.player
	ld de, W_PLAYERMOVENUM ; $cfd2
	ld a, [W_FLAGS_D733]
	bit 0, a
	ld a, [$ccd9]
	jr nz, .selected
	ld a, [wPlayerSelectedMove] ; $ccdc
.selected
	ld [$d0b5], a
	dec a
	ld hl, Moves ; $4000
	ld bc, $6
	call AddNTimes
	ld a, BANK(Moves)
	call FarCopyData
	ld a, $2c
	ld [$d0b7], a
	ld a, $2
	ld [W_LISTTYPE], a ; list type 2 = move name
	call GetName
	ld de, $cd6d
	jp CopyStringToCF4B

Func_3eb01: ; 3eb01 (f:6b01)
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jp z, Func_3cc13
	ld a, [W_ENEMYMONID]
	ld [$cfe5], a
	ld [$d0b5], a
	call GetMonHeader
	ld a, [W_ENEMYBATTSTATUS3] ; $d069
	bit 3, a
	ld hl, $cceb
	ld a, [hli]
	ld b, [hl]
	jr nz, .asm_3eb33
	ld a, [W_ISINBATTLE] ; $d057
	cp $2
	ld a, $98
	ld b, $88
	jr z, .asm_3eb33
	call GenRandomInBattle
	ld b, a
	call GenRandomInBattle
.asm_3eb33
	ld hl, $cff1
	ld [hli], a
	ld [hl], b
	ld de, W_ENEMYMONLEVEL ; $cff3
	ld a, [W_CURENEMYLVL] ; $d127
	ld [de], a
	inc de
	ld b, $0
	ld hl, W_ENEMYMONCURHP ; $cfe6
	push hl
	call CalcStats
	pop hl
	ld a, [W_ISINBATTLE] ; $d057
	cp $2
	jr z, .asm_3eb65
	ld a, [W_ENEMYBATTSTATUS3] ; $d069
	bit 3, a
	jr nz, .asm_3eb86
	ld a, [W_ENEMYMONMAXHP] ; $cff4
	ld [hli], a
	ld a, [W_ENEMYMONMAXHP+1]
	ld [hli], a
	xor a
	inc hl
	ld [hl], a
	jr .asm_3eb86
.asm_3eb65
	ld hl, W_ENEMYMON1HP ; $d8a5 (aliases: W_WATERMONS)
	ld a, [wWhichPokemon] ; $cf92
	ld bc, $2c
	call AddNTimes
	ld a, [hli]
	ld [W_ENEMYMONCURHP], a ; $cfe6
	ld a, [hli]
	ld [$cfe7], a
	ld a, [wWhichPokemon] ; $cf92
	ld [W_ENEMYMONNUMBER], a ; $cfe8
	inc hl
	ld a, [hl]
	ld [W_ENEMYMONSTATUS], a ; $cfe9
	jr .asm_3eb86
.asm_3eb86
	ld hl, W_MONHTYPES
	ld de, W_ENEMYMONTYPES ; $cfea
	ld a, [hli]            ; copy type 1
	ld [de], a
	inc de
	ld a, [hli]            ; copy type 2
	ld [de], a
	inc de
	ld a, [hli]            ; copy catch rate
	ld [de], a
	inc de
	ld a, [W_ISINBATTLE] ; $d057
	cp $2
	jr nz, .asm_3ebb0
	ld hl, $d8ac
	ld a, [wWhichPokemon] ; $cf92
	ld bc, $2c
	call AddNTimes
	ld bc, $4
	call CopyData
	jr .asm_3ebca
.asm_3ebb0
	ld hl, W_MONHMOVES
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hl]
	ld [de], a
	dec de
	dec de
	dec de
	xor a
	ld [$cee9], a
	ld a, $3e
	call Predef ; indirect jump to WriteMonMoves (3afb8 (e:6fb8))
.asm_3ebca
	ld hl, W_ENEMYMONMOVES
	ld de, $cffd
	ld a, $5e
	call Predef ; indirect jump to LoadMovePPs (f473 (3:7473))
	ld hl, W_MONHBASESTATS
	ld de, $d002
	ld b, $5
.asm_3ebdd
	ld a, [hli]
	ld [de], a
	inc de
	dec b
	jr nz, .asm_3ebdd
	ld hl, W_MONHCATCHRATE
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hl]     ; base exp
	ld [de], a
	ld a, [W_ENEMYMONID]
	ld [$d11e], a
	call GetMonName
	ld hl, $cd6d
	ld de, W_ENEMYMONNAME
	ld bc, $b
	call CopyData
	ld a, [W_ENEMYMONID]
	ld [$d11e], a
	ld a, $3a
	call Predef ; indirect jump to IndexToPokedex (41010 (10:5010))
	ld a, [$d11e]
	dec a
	ld c, a
	ld b, $1
	ld hl, wPokedexSeen ; $d30a
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	ld hl, W_ENEMYMONLEVEL ; $cff3
	ld de, $cd23
	ld bc, $b
	call CopyData
	ld a, $7
	ld b, $8
	ld hl, wEnemyMonStatMods ; $cd2e
.asm_3ec2d
	ld [hli], a
	dec b
	jr nz, .asm_3ec2d
	ret

Func_3ec32: ; 3ec32 (f:6c32)
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr nz, .asm_3ec4d
	xor a
	ld [wMenuJoypadPollCount], a ; $cc34
	callab Func_372d6
	ld a, $1
	ld [$cfcb], a
	call ClearScreen
.asm_3ec4d
	call DelayFrame
	ld a, $30
	call Predef ; indirect jump to Func_7096d (7096d (1c:496d))
	callab Func_3ee58
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, $ff
	ld [$cfcb], a
	call CleanLCD_OAM
	call ClearScreen
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld [$ffb0], a
	ld [rWY], a ; $ff4a
	ld [$ffd7], a
	ld hl, $d060
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hl], a
	ld [W_PLAYERDISABLEDMOVE], a ; $d06d
	ret

Func_3ec81: ; 3ec81 (f:6c81)
	push bc
	ld a, [W_PLAYERMONLEVEL] ; $d022
	ld b, a
	ld a, [W_ENEMYMONLEVEL] ; $cff3
	ld [W_PLAYERMONLEVEL], a ; $d022
	ld a, b
	ld [W_ENEMYMONLEVEL], a ; $cff3
	pop bc
	ret

Func_3ec92: ; 3ec92 (f:6c92)
	ld a, [W_BATTLETYPE] ; $d05a
	dec a
	ld de, RedPicBack ; $7e0a
	jr nz, .asm_3ec9e
	ld de, OldManPic ; $7e9a
.asm_3ec9e
	ld a, BANK(RedPicBack)
	call UncompressSpriteFromDE
	ld a, $3
	call Predef ; indirect jump to ScaleSpriteByTwo (2fe40 (b:7e40))
	ld hl, wOAMBuffer
	xor a
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld b, $7
	ld e, $a0
.asm_3ecb2
	ld c, $3
	ld d, $38
.asm_3ecb6
	ld [hl], d
	inc hl
	ld [hl], e
	ld a, $8
	add d
	ld d, a
	inc hl
	ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
	ld [hli], a
	inc a
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	inc hl
	dec c
	jr nz, .asm_3ecb6
	ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
	add $4
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld a, $8
	add e
	ld e, a
	dec b
	jr nz, .asm_3ecb2
	ld de, $9310
	call InterlaceMergeSpriteBuffers
	ld a, $a
	ld [$0], a
	xor a
	ld [$4000], a
	ld hl, $8000
	ld de, S_SPRITEBUFFER1
	ld a, [H_LOADEDROMBANK]
	ld b, a
	ld c, $31
	call CopyVideoData
	xor a
	ld [$0], a
	ld a, $31
	ld [$ffe1], a
	FuncCoord 1, 5 ; $c405
	ld hl, Coord
	ld a, $1
	jp Predef ; indirect jump to Func_3f0c6 (3f0c6 (f:70c6))

Func_3ed02: ; 3ed02 (f:6d02)
	callab Func_39680
	ld hl, Func_396a7
	ld b, BANK(Func_396a7)
	jp Bankswitch

ScrollTrainerPicAfterBattle: ; 3ed12 (f:6d12)
	ld hl, _ScrollTrainerPicAfterBattle
	ld b, BANK(_ScrollTrainerPicAfterBattle)
	jp Bankswitch

Func_3ed1a: ; 3ed1a (f:6d1a)
	ld a, $1
	jr asm_3ed1f

Func_3ed1e: ; 3ed1e (f:6d1e)
	xor a
asm_3ed1f: ; 3ed1f (f:6d1f)
	ld [H_WHOSETURN], a ; $fff3
	call Func_3ed27
	jp Func_3ed64

Func_3ed27: ; 3ed27 (f:6d27)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3ed48
	ld a, [W_PLAYERMONSTATUS] ; $d018
	and $40
	ret z
	ld hl, $d02a
	ld a, [hld]
	ld b, a
	ld a, [hl]
	srl a
	rr b
	srl a
	rr b
	ld [hli], a
	or b
	jr nz, .asm_3ed46
	ld b, $1
.asm_3ed46
	ld [hl], b
	ret
.asm_3ed48
	ld a, [W_ENEMYMONSTATUS] ; $cfe9
	and $40
	ret z
	ld hl, $cffb
	ld a, [hld]
	ld b, a
	ld a, [hl]
	srl a
	rr b
	srl a
	rr b
	ld [hli], a
	or b
	jr nz, .asm_3ed62
	ld b, $1
.asm_3ed62
	ld [hl], b
	ret

Func_3ed64: ; 3ed64 (f:6d64)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3ed81
	ld a, [W_PLAYERMONSTATUS] ; $d018
	and $10
	ret z
	ld hl, $d026
	ld a, [hld]
	ld b, a
	ld a, [hl]
	srl a
	rr b
	ld [hli], a
	or b
	jr nz, .asm_3ed7f
	ld b, $1
.asm_3ed7f
	ld [hl], b
	ret
.asm_3ed81
	ld a, [W_ENEMYMONSTATUS] ; $cfe9
	and $10
	ret z
	ld hl, $cff7
	ld a, [hld]
	ld b, a
	ld a, [hl]
	srl a
	rr b
	ld [hli], a
	or b
	jr nz, .asm_3ed97
	ld b, $1
.asm_3ed97
	ld [hl], b
	ret

Func_3ed99: ; 3ed99 (f:6d99)
	ld c, $0
.asm_3ed9b
	call Func_3eda5
	inc c
	ld a, c
	cp $4
	jr nz, .asm_3ed9b
	ret

Func_3eda5: ; 3eda5 (f:6da5)
	push bc
	push bc
	ld a, [$d11e]
	and a
	ld a, c
	ld hl, W_PLAYERMONATK
	ld de, $cd12
	ld bc, wPlayerMonAttackMod ; $cd1a
	jr z, .asm_3edc0
	ld hl, W_ENEMYMONATTACK
	ld de, $cd26
	ld bc, wEnemyMonStatMods ; $cd2e
.asm_3edc0
	add c
	ld c, a
	jr nc, .asm_3edc5
	inc b
.asm_3edc5
	ld a, [bc]
	pop bc
	ld b, a
	push bc
	sla c
	ld b, $0
	add hl, bc
	ld a, c
	add e
	ld e, a
	jr nc, .asm_3edd4
	inc d
.asm_3edd4
	pop bc
	push hl
	ld hl, StatModifierRatios ; $76cb
	dec b
	sla b
	ld c, b
	ld b, $0
	add hl, bc
	xor a
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, [de]
	ld [$ff97], a
	inc de
	ld a, [de]
	ld [$ff98], a
	ld a, [hli]
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	call Multiply
	ld a, [hl]
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld b, $4
	call Divide
	pop hl
	ld a, [$ff98]
	sub $e7
	ld a, [$ff97]
	sbc $3
	jp c, Func_3ee0c
	ld a, $3
	ld [$ff97], a
	ld a, $e7
	ld [$ff98], a

Func_3ee0c: ; 3ee0c (f:6e0c)
	ld a, [$ff97]
	ld [hli], a
	ld b, a
	ld a, [$ff98]
	ld [hl], a
	or b
	jr nz, .asm_3ee17
	inc [hl]
.asm_3ee17
	pop bc
	ret

Func_3ee19: ; 3ee19 (f:6e19)
	ld a, [W_ISLINKBATTLE]
	cp $4
	ret z
	ld a, [W_OBTAINEDBADGES]
	ld b, a
	ld hl, W_PLAYERMONATK
	ld c, $4
.asm_3ee28
	srl b
	call c, Func_3ee35
	inc hl
	inc hl
	srl b
	dec c
	jr nz, .asm_3ee28
	ret

Func_3ee35: ; 3ee35 (f:6e35)
	ld a, [hli]
	ld d, a
	ld e, [hl]
	srl d
	rr e
	srl d
	rr e
	srl d
	rr e
	ld a, [hl]
	add e
	ld [hld], a
	ld a, [hl]
	adc d
	ld [hli], a
	ld a, [hld]
	sub $e7
	ld a, [hl]
	sbc $3
	ret c
	ld a, $3
	ld [hli], a
	ld a, $e7
	ld [hld], a
	ret

Func_3ee58: ; 3ee58 (f:6e58)
	call LoadHpBarAndStatusTilePatterns

Func_3ee5b: ; 3ee5b (f:6e5b)
	ld a, [rLCDC] ; $ff40
	add a
	jr c, .asm_3ee7c
	ld hl, BattleHudTiles1 ; $6080
	ld de, $96d0
	ld bc, $18
	ld a, BANK(BattleHudTiles1)
	call FarCopyDataDouble
	ld hl, BattleHudTiles2 ; $6098
	ld de, $9730
	ld bc, $30
	ld a, BANK(BattleHudTiles2)
	jp FarCopyDataDouble
.asm_3ee7c
	ld de, BattleHudTiles1 ; $6080
	ld hl, $96d0
	ld bc, (BANK(BattleHudTiles1) << 8) + $03
	call CopyVideoDataDouble
	ld de, BattleHudTiles2 ; $6098
	ld hl, $9730
	ld bc, (BANK(BattleHudTiles2) << 8) + $06
	jp CopyVideoDataDouble

Func_3ee94: ; 3ee94 (f:6e94)
	ld hl, TerminatorText_3ee9a ; $6e9a
	jp PrintText

TerminatorText_3ee9a: ; 3ee9a (f:6e9a)
	db "@"

; generates a random number unless in link battle
; stores random number in A
GenRandomInBattle: ; 3ee9b (f:6e9b)
	ld a, [W_ISLINKBATTLE]
	cp $4
	jp nz, GenRandom
	push hl
	push bc
	ld a, [$ccde]
	ld c, a
	ld b, $0
	ld hl, $d148
	add hl, bc
	inc a
	ld [$ccde], a
	cp $9
	ld a, [hl]
	pop bc
	pop hl
	ret c
	push hl
	push bc
	push af
	xor a
	ld [$ccde], a
	ld hl, $d148
	ld b, $9
.asm_3eec5
	ld a, [hl]
	ld c, a
	add a
	add a
	add c
	inc a
	ld [hli], a
	dec b
	jr nz, .asm_3eec5 ; 0x3eecd $f6
	pop af
	pop bc
	pop hl
	ret

Func_3eed3: ; 3eed3 (f:6ed3)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld hl, W_ENEMYMONTYPE1 ; $cfea (aliases: W_ENEMYMONTYPES)
	ld de, W_ENEMYBATTSTATUS1 ; $d067
	ld a, [W_PLAYERMOVENUM] ; $cfd2
	jr z, .asm_3eeea
	ld hl, W_PLAYERMONTYPE1 ; $d019 (aliases: W_PLAYERMONTYPES)
	ld de, W_ENEMYBATTSTATUS1 ; $d067
	ld a, [W_ENEMYMOVENUM] ; $cfcc
.asm_3eeea
	cp SELFDESTRUCT
	jr z, .asm_3eef1
	cp EXPLOSION
	ret nz
.asm_3eef1
	ld a, [de]
	bit 6, a ; fly/dig
	ret nz
	ld a, [hli]
	cp GHOST
	ret z
	ld a, [hl]
	cp GHOST
	ret z
	ld a, [W_MOVEMISSED] ; $d05f
	and a
	ret nz
	ld a, MEGA_PUNCH
	ld [$cc5b], a

PlayMoveAnimation: ; 3ef07 (f:6f07)
	ld [$D07C],a
	call Delay3
	PREDEF_JUMP MoveAnimationPredef ; predef 8

InitBattle: ; 3ef12 (f:6f12)
	ld a, [W_CUROPPONENT] ; $d059
	and a
	jr z, asm_3ef23

Func_3ef18: ; 3ef18 (f:6f18)
	ld a, [W_CUROPPONENT] ; $d059
	ld [$cf91], a
	ld [W_ENEMYMONID], a
	jr asm_3ef3d
asm_3ef23: ; 3ef23 (f:6f23)
	ld a, [$d732]
	bit 1, a
	jr z, .asm_3ef2f
	ld a, [H_CURRENTPRESSEDBUTTONS]
	bit 1, a
	ret nz
.asm_3ef2f
	ld a, [$d13c]
	and a
	ret nz
	callab Func_13870
	ret nz
asm_3ef3d: ; 3ef3d (f:6f3d)
	ld a, [$d35d]
	push af
	ld hl, $d358
	ld a, [hl]
	push af
	res 1, [hl]
	callab Func_525af
	ld a, [W_ENEMYMONID]
	sub $c8
	jp c, InitWildBattle
	ld [W_TRAINERCLASS], a ; $d031
	call Func_3566
	callab ReadTrainer
	call Func_3ec32
	call _LoadTrainerPic
	xor a
	ld [W_ENEMYMONID], a
	ld [$ffe1], a
	dec a
	ld [wAICount], a ; $ccdf
	FuncCoord 12, 0 ; $c3ac
	ld hl, Coord
	ld a, $1
	call Predef ; indirect jump to Func_3f0c6 (3f0c6 (f:70c6))
	ld a, $ff
	ld [W_ENEMYMONNUMBER], a ; $cfe8
	ld a, $2
	ld [W_ISINBATTLE], a ; $d057
	jp Func_3efeb

InitWildBattle: ; 3ef8b (f:6f8b)
	ld a, $1
	ld [W_ISINBATTLE], a ; $d057
	call Func_3eb01
	call Func_3ec32
	ld a, [W_CUROPPONENT] ; $d059
	cp MAROWAK
	jr z, .isGhost
	call IsGhostBattle
	jr nz, .isNoGhost
.isGhost
	ld hl, W_MONHSPRITEDIM
	ld a, $66
	ld [hli], a   ; write sprite dimensions
	ld bc, GhostPic ; $66b5
	ld a, c
	ld [hli], a   ; write front sprite pointer
	ld [hl], b
	ld hl, W_ENEMYMONNAME  ; set name to "GHOST"
	ld a, "G"
	ld [hli], a
	ld a, "H"
	ld [hli], a
	ld a, "O"
	ld [hli], a
	ld a, "S"
	ld [hli], a
	ld a, "T"
	ld [hli], a
	ld [hl], "@"
	ld a, [$cf91]
	push af
	ld a, MON_GHOST
	ld [$cf91], a
	ld de, $9000
	call LoadMonFrontSprite ; load ghost sprite
	pop af
	ld [$cf91], a
	jr .spriteLoaded
.isNoGhost
	ld de, $9000
	call LoadMonFrontSprite ; load mon sprite
.spriteLoaded
	xor a
	ld [W_TRAINERCLASS], a ; $d031
	ld [$ffe1], a
	FuncCoord 12, 0 ; $c3ac
	ld hl, Coord
	ld a, $1
	call Predef ; indirect jump to Func_3f0c6 (3f0c6 (f:70c6))

Func_3efeb: ; 3efeb (f:6feb)
	ld b, $0
	call GoPAL_SET
	call Func_3c04c
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld hl, TerminatorText_3f04a
	call PrintText
	call SaveScreenTilesToBuffer1
	call ClearScreen
	ld a, $98
	ld [$ffbd], a
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Delay3
	ld a, $9c
	ld [$ffbd], a
	call LoadScreenTilesFromBuffer1
	FuncCoord 9, 7 ; $c435
	ld hl, Coord
	ld bc, $50a
	call ClearScreenArea
	FuncCoord 1, 0 ; $c3a1
	ld hl, Coord
	ld bc, $40a
	call ClearScreenArea
	call CleanLCD_OAM
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	call z, Func_3cdec
	call Func_3c11e
	callab Func_137aa
	pop af
	ld [$d358], a
	pop af
	ld [$d35d], a
	ld a, [$d0d4]
	ld [$ffd7], a
	scf
	ret

TerminatorText_3f04a: ; 3f04a (f:704a)
	db "@"

_LoadTrainerPic: ; 3f04b (f:704b)
; $d033-$d034 contain pointer to pic
	ld a, [$d033]
	ld e, a
	ld a, [$d034]
	ld d, a ; de contains pointer to trainer pic
	ld a, [W_ISLINKBATTLE] ; $d12b
	and a
	ld a, Bank(TrainerPics) ; this is where all the trainer pics are (not counting Red's)
	jr z, .loadSprite
	ld a, Bank(RedPicFront)
.loadSprite
	call UncompressSpriteFromDE
	ld de, $9000
	ld a, $77
	ld c, a
	jp LoadUncompressedSpriteData

Func_3f069: ; 3f069 (f:7069)
	xor a
	ld [$c0f1], a
	ld [$c0f2], a
	jp PlaySound

Func_3f073: ; 3f073 (f:7073)
	ld a, [$cc4f]
	ld h, a
	ld a, [$cc50]
	ld l, a
	ld a, [$ffe1]
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld b, $4c
	ld a, [W_ISINBATTLE] ; $d057
	and a
	jr z, .asm_3f0bc
	add b
	ld [hl], a
	call Delay3
	ld bc, $ffd7
	add hl, bc
	ld a, $1
	ld [$cd6c], a
	ld bc, $303
	ld a, $5
	call Predef ; indirect jump to Func_79aba (79aba (1e:5aba))
	ld c, $4
	call DelayFrames
	ld bc, $ffd7
	add hl, bc
	xor a
	ld [$cd6c], a
	ld bc, $505
	ld a, $5
	call Predef ; indirect jump to Func_79aba (79aba (1e:5aba))
	ld c, $5
	call DelayFrames
	ld bc, $ffd7
	jr .asm_3f0bf
.asm_3f0bc
	ld bc, $ff85
.asm_3f0bf
	add hl, bc
	ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
	add $31
	jr asm_3f0d0

Func_3f0c6: ; 3f0c6 (f:70c6)
	ld a, [$cc4f]
	ld h, a
	ld a, [$cc50]
	ld l, a
	ld a, [$ffe1]
asm_3f0d0: ; 3f0d0 (f:70d0)
	ld bc, $707
	ld de, $14
	push af
	ld a, [W_SPRITEFLIPPED]
	and a
	jr nz, .asm_3f0ed
	pop af
.asm_3f0de
	push bc
	push hl
.asm_3f0e0
	ld [hl], a
	add hl, de
	inc a
	dec c
	jr nz, .asm_3f0e0
	pop hl
	inc hl
	pop bc
	dec b
	jr nz, .asm_3f0de
	ret
.asm_3f0ed
	push bc
	ld b, $0
	dec c
	add hl, bc
	pop bc
	pop af
.asm_3f0f4
	push bc
	push hl
.asm_3f0f6
	ld [hl], a
	add hl, de
	inc a
	dec c
	jr nz, .asm_3f0f6
	pop hl
	dec hl
	pop bc
	dec b
	jr nz, .asm_3f0f4
	ret

; loads back sprite of mon to $8000
; assumes the corresponding mon header is already loaded
LoadMonBackSprite: ; 3f103 (f:7103)
	ld a, [$cfd9]
	ld [$cf91], a
	FuncCoord 1, 5 ; $c405
	ld hl, Coord
	ld b, $7
	ld c, $8
	call ClearScreenArea
	ld hl,  W_MONHBACKSPRITE - W_MONHEADER
	call UncompressMonSprite
	ld a, $3
	call Predef ; indirect jump to ScaleSpriteByTwo (2fe40 (b:7e40))
	ld de, $9310
	call InterlaceMergeSpriteBuffers ; combine the two buffers to a single 2bpp sprite
	ld hl, $8000
	ld de, $9310
	ld c, (2*SPRITEBUFFERSIZE)/16 ; count of 16-byte chunks to be copied
	ld a, [H_LOADEDROMBANK]
	ld b, a
	jp CopyVideoData

Func_3f132: ; 3f132 (f:7132)
	call JumpMoveEffect
	ld b, $1
	ret

JumpMoveEffect: ; 3f138 (f:7138)
	ld a, [$fff3]  ;whose turn?
	and a
	ld a, [W_PLAYERMOVEEFFECT]
	jr z, .next1
	ld a, [W_ENEMYMOVEEFFECT]
.next1
	dec a         ;subtract 1, there is no special effect for 00
	add a         ;x2, 16bit pointers
	ld hl, MoveEffectPointerTable
	ld b, 0
	ld c, a
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	jp [hl]       ;jump to special effect handler

MoveEffectPointerTable: ; 3f150 (f:7150)
	 dw SleepEffect               ; unused effect
	 dw PoisonEffect              ; POISON_SIDE_EFFECT1
	 dw DrainHPEffect             ; DRAIN_HP_EFFECT
	 dw FreezeBurnParalyzeEffect  ; BURN_SIDE_EFFECT1
	 dw FreezeBurnParalyzeEffect  ; FREEZE_SIDE_EFFECT
	 dw FreezeBurnParalyzeEffect  ; PARALYZE_SIDE_EFFECT1
	 dw ExplodeEffect             ; EXPLODE_EFFECT
	 dw DrainHPEffect             ; DREAM_EATER_EFFECT
	 dw $0000                     ; MIRROR_MOVE_EFFECT
	 dw StatModifierUpEffect      ; ATTACK_UP1_EFFECT
	 dw StatModifierUpEffect      ; DEFENSE_UP1_EFFECT
	 dw StatModifierUpEffect      ; SPEED_UP1_EFFECT
	 dw StatModifierUpEffect      ; SPECIAL_UP1_EFFECT
	 dw StatModifierUpEffect      ; ACCURACY_UP1_EFFECT
	 dw StatModifierUpEffect      ; EVASION_UP1_EFFECT
	 dw PayDayEffect              ; PAY_DAY_EFFECT
	 dw $0000                     ; SWIFT_EFFECT
	 dw StatModifierDownEffect    ; ATTACK_DOWN1_EFFECT
	 dw StatModifierDownEffect    ; DEFENSE_DOWN1_EFFECT
	 dw StatModifierDownEffect    ; SPEED_DOWN1_EFFECT
	 dw StatModifierDownEffect    ; SPECIAL_DOWN1_EFFECT
	 dw StatModifierDownEffect    ; ACCURACY_DOWN1_EFFECT
	 dw StatModifierDownEffect    ; EVASION_DOWN1_EFFECT
	 dw ConversionEffect          ; CONVERSION_EFFECT
	 dw HazeEffect                ; HAZE_EFFECT
	 dw BideEffect                ; BIDE_EFFECT
	 dw ThrashPetalDanceEffect    ; THRASH_PETAL_DANCE_EFFECT
	 dw SwitchAndTeleportEffect   ; SWITCH_AND_TELEPORT_EFFECT
	 dw TwoToFiveAttacksEffect    ; TWO_TO_FIVE_ATTACKS_EFFECT
	 dw TwoToFiveAttacksEffect    ; unused effect
	 dw FlichSideEffect           ; FLINCH_SIDE_EFFECT1
	 dw SleepEffect               ; SLEEP_EFFECT
	 dw PoisonEffect              ; POISON_SIDE_EFFECT2
	 dw FreezeBurnParalyzeEffect  ; BURN_SIDE_EFFECT2
	 dw FreezeBurnParalyzeEffect  ; unused effect
	 dw FreezeBurnParalyzeEffect  ; PARALYZE_SIDE_EFFECT2
	 dw FlichSideEffect           ; FLINCH_SIDE_EFFECT2
	 dw OneHitKOEffect            ; OHKO_EFFECT
	 dw ChargeEffect              ; CHARGE_EFFECT
	 dw $0000                     ; SUPER_FANG_EFFECT
	 dw $0000                     ; SPECIAL_DAMAGE_EFFECT
	 dw TrappingEffect            ; TRAPPING_EFFECT
	 dw ChargeEffect              ; FLY_EFFECT
	 dw TwoToFiveAttacksEffect    ; ATTACK_TWICE_EFFECT
	 dw $0000                     ; JUMP_KICK_EFFECT
	 dw MistEffect                ; MIST_EFFECT
	 dw FocusEnergyEffect         ; FOCUS_ENERGY_EFFECT
	 dw RecoilEffect              ; RECOIL_EFFECT
	 dw ConfusionEffect           ; CONFUSION_EFFECT
	 dw StatModifierUpEffect      ; ATTACK_UP2_EFFECT
	 dw StatModifierUpEffect      ; DEFENSE_UP2_EFFECT
	 dw StatModifierUpEffect      ; SPEED_UP2_EFFECT
	 dw StatModifierUpEffect      ; SPECIAL_UP2_EFFECT
	 dw StatModifierUpEffect      ; ACCURACY_UP2_EFFECT
	 dw StatModifierUpEffect      ; EVASION_UP2_EFFECT
	 dw HealEffect                ; HEAL_EFFECT
	 dw TransformEffect           ; TRANSFORM_EFFECT
	 dw StatModifierDownEffect    ; ATTACK_DOWN2_EFFECT
	 dw StatModifierDownEffect    ; DEFENSE_DOWN2_EFFECT
	 dw StatModifierDownEffect    ; SPEED_DOWN2_EFFECT
	 dw StatModifierDownEffect    ; SPECIAL_DOWN2_EFFECT
	 dw StatModifierDownEffect    ; ACCURACY_DOWN2_EFFECT
	 dw StatModifierDownEffect    ; EVASION_DOWN2_EFFECT
	 dw ReflectLightScreenEffect  ; LIGHT_SCREEN_EFFECT
	 dw ReflectLightScreenEffect  ; REFLECT_EFFECT
	 dw PoisonEffect              ; POISON_EFFECT
	 dw ParalyzeEffect            ; PARALYZE_EFFECT
	 dw StatModifierDownEffect    ; ATTACK_DOWN_SIDE_EFFECT
	 dw StatModifierDownEffect    ; DEFENSE_DOWN_SIDE_EFFECT
	 dw StatModifierDownEffect    ; SPEED_DOWN_SIDE_EFFECT
	 dw StatModifierDownEffect    ; SPECIAL_DOWN_SIDE_EFFECT
	 dw StatModifierDownEffect    ; unused effect
	 dw StatModifierDownEffect    ; unused effect
	 dw StatModifierDownEffect    ; unused effect
	 dw StatModifierDownEffect    ; unused effect
	 dw ConfusionSideEffect       ; CONFUSION_SIDE_EFFECT
	 dw TwoToFiveAttacksEffect    ; TWINEEDLE_EFFECT
	 dw $0000                     ; unused effect
	 dw SubstituteEffect          ; SUBSTITUTE_EFFECT
	 dw HyperBeamEffect           ; HYPER_BEAM_EFFECT
	 dw RageEffect                ; RAGE_EFFECT
	 dw MimicEffect               ; MIMIC_EFFECT
	 dw $0000                     ; METRONOME_EFFECT
	 dw LeechSeedEffect           ; LEECH_SEED_EFFECT
	 dw SplashEffect              ; SPLASH_EFFECT
	 dw DisableEffect             ; DISABLE_EFFECT

SleepEffect: ; 3f1fc (f:71fc)
	ld de, W_ENEMYMONSTATUS ; $cfe9
	ld bc, W_ENEMYBATTSTATUS2 ; $d068
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jp z, .asm_3f20e
	ld de, W_PLAYERMONSTATUS ; $d018
	ld bc, W_PLAYERBATTSTATUS2 ; $d063

.asm_3f20e
	ld a, [bc]
	bit 5, a ; does the mon need to recharge? (hyper beam)
	res 5, a ; mon no longer needs to recharge
	ld [bc], a
	jr nz, .asm_3f231
	ld a, [de]
	ld b, a
	and $7
	jr z, .asm_3f222
	ld hl, AlreadyAsleepText
	jp PrintText
.asm_3f222
	ld a, b
	and a
	jr nz, .asm_3f242
	push de
	call MoveHitTest
	pop de
	ld a, [W_MOVEMISSED] ; $d05f
	and a
	jr nz, .asm_3f242
.asm_3f231
	call GenRandomInBattle
	and $7
	jr z, .asm_3f231
	ld [de], a
	call Func_3fb89
	ld hl, FellAsleepText
	jp PrintText
.asm_3f242
	jp PrintDidntAffectText

FellAsleepText: ; 3f245 (f:7245)
	TX_FAR _FellAsleepText
	db "@"

AlreadyAsleepText: ; 3f24a (f:724a)
	TX_FAR _AlreadyAsleepText
	db "@"

PoisonEffect: ; 3f24f (f:724f)
	ld hl, W_ENEMYMONSTATUS ; $cfe9
	ld de, W_PLAYERMOVEEFFECT ; $cfd3
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f260
	ld hl, W_PLAYERMONSTATUS ; $d018
	ld de, W_ENEMYMOVEEFFECT ; $cfcd
.asm_3f260
	call CheckTargetSubstitute
	jr nz, .asm_3f2d3
	ld a, [hli]
	ld b, a
	and a
	jr nz, .asm_3f2d3
	ld a, [hli]
	cp $3
	jr z, .asm_3f2d3
	ld a, [hld]
	cp $3
	jr z, .asm_3f2d3
	ld a, [de]
	cp POISON_SIDE_EFFECT1
	ld b, $34 ; ~20% chance of poisoning
	jr z, .asm_3f290
	cp POISON_SIDE_EFFECT2
	ld b, $67 ; ~40% chance of poisoning
	jr z, .asm_3f290
	push hl
	push de
	call MoveHitTest
	pop de
	pop hl
	ld a, [W_MOVEMISSED] ; $d05f
	and a
	jr nz, .asm_3f2d7
	jr .asm_3f295
.asm_3f290
	call GenRandomInBattle
	cp b
	ret nc
.asm_3f295
	dec hl
	set 3, [hl]
	push de
	dec de
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld b, $c7
	ld hl, W_PLAYERBATTSTATUS3 ; $d064
	ld a, [de]
	ld de, W_PLAYERTOXICCOUNTER ; $d06c
	jr nz, .asm_3f2b0
	ld b, $a9
	ld hl, W_ENEMYBATTSTATUS3 ; $d069
	ld de, W_ENEMYTOXICCOUNTER ; $d071
.asm_3f2b0
	cp $5c
	jr nz, .asm_3f2bd
	set 0, [hl]
	xor a
	ld [de], a
	ld hl, BadlyPoisonedText
	jr .asm_3f2c0
.asm_3f2bd
	ld hl, PoisonedText
.asm_3f2c0
	pop de
	ld a, [de]
	cp POISON_EFFECT
	jr z, .asm_3f2cd
	ld a, b
	call Func_3fb96
	jp PrintText
.asm_3f2cd
	call Func_3fb89
	jp PrintText
.asm_3f2d3
	ld a, [de]
	cp POISON_EFFECT
	ret nz
.asm_3f2d7
	ld c, $32
	call DelayFrames
	jp PrintDidntAffectText

PoisonedText: ; 3f2df (f:72df)
	TX_FAR _PoisonedText
	db "@"

BadlyPoisonedText: ; 3f2e4 (f:72e4)
	TX_FAR _BadlyPoisonedText
	db "@"

DrainHPEffect: ; 3f2e9 (f:72e9)
	ld hl, DrainHPEffect_
	ld b, BANK(DrainHPEffect_)
	jp Bankswitch

ExplodeEffect: ; 3f2f1 (f:72f1)
	ld hl, W_PLAYERMONCURHP ; $d015
	ld de, W_PLAYERBATTSTATUS2 ; $d063
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f302
	ld hl, W_ENEMYMONCURHP ; $cfe6
	ld de, W_ENEMYBATTSTATUS2 ; $d068
.asm_3f302
	xor a
	ld [hli], a ; set the mon's HP to 0
	ld [hli], a
	inc hl
	ld [hl], a ; set mon's status to 0
	ld a, [de]
	res 7, a ; clear mon's leech seed status
	ld [de], a
	ret

FreezeBurnParalyzeEffect: ; 3f30c (f:730c)
	xor a
	ld [$cc5b], a
	call CheckTargetSubstitute         ;test bit 4 of d063/d068 flags [target has substitute flag]
	ret nz             ;return if they have a substitute, can't effect them
	ld a, [$fff3]  ;whose turn?
	and a
	jp nz, opponentAttacker
	ld a, [W_ENEMYMONSTATUS]
	and a
	jp nz, CheckDefrost
	;opponent has no existing status
	ld a, [W_PLAYERMOVETYPE]
	ld b, a
	ld a, [W_ENEMYMONTYPE1]
	cp b
	ret z  ;return if they match [can't freeze an ice type etc.]
	ld a, [W_ENEMYMONTYPE2]
	cp b
	ret z  ;return..
	ld a, [W_PLAYERMOVEEFFECT]
	cp a, 7         ;10% status effects are 04, 05, 06 so 07 will set carry for those
	ld b, $1a       ;[1A-1]/100 or [26-1]/256 = 9.8%~ chance
	jr c, .next1  ;branch ahead if this is a 10% chance effect..
	ld b, $4d       ;..or use [4D-1]/100 or [76-1]/256 = 29.7%~ chance
	sub a, $1e      ;subtract $1E to map to equivalent 10% chance effects
.next1
	push af     ;push effect...
	call GenRandomInBattle  ;get random 8bit value for probability test
	cp b        ;success?
	pop bc      ;...pop effect into C
	ret nc      ;do nothing if random value is >= 1A or 4D [no status applied]
	            ;the test passed
	ld a, b     ;what type of effect is this?
	cp a, BURN_SIDE_EFFECT1
	jr z, .burn
	cp a, FREEZE_SIDE_EFFECT
	jr z, .freeze
	ld a, 1 << PAR
	ld [W_ENEMYMONSTATUS], a
	call Func_3ed27  ;quarter speed of affected monster
	ld a, $a9
	call Func_3fbb9  ;animation
	jp PrintMayNotAttackText    ;print paralysis text
.burn
	ld a, 1 << BRN
	ld [W_ENEMYMONSTATUS], a
	call Func_3ed64
	ld a, $a9
	call Func_3fbb9  ;animation
	ld hl, BurnedText
	jp PrintText
.freeze
	call Func_3f9cf  ;resets bit 5 of the D063/D068 flags
	ld a, 1 << FRZ
	ld [W_ENEMYMONSTATUS], a
	ld a, $a9
	call Func_3fbb9  ;animation
	ld hl, FrozenText
	jp PrintText
opponentAttacker: ; 3f382 (f:7382)
	ld a, [W_PLAYERMONSTATUS]  ;this appears to the same as above with addresses swapped for opponent
	and a
	jp nz, CheckDefrost
	ld a, [W_ENEMYMOVETYPE]
	ld b, a
	ld a, [W_PLAYERMONTYPE1]
	cp b
	ret z
	ld a, [W_PLAYERMONTYPE2]
	cp b
	ret z
	ld a, [W_ENEMYMOVEEFFECT]
	cp a, 7
	ld b, $1a
	jr c, .next1
	ld b, $4d
	sub a, $1e
.next1
	push af
	call GenRandomInBattle
	cp b
	pop bc
	ret nc
	ld a, b
	cp a, BURN_SIDE_EFFECT1
	jr z, .burn
	cp a, FREEZE_SIDE_EFFECT
	jr z, .freeze
	ld a, 1 << PAR
	ld [W_PLAYERMONSTATUS], a
	call Func_3ed27
	jp PrintMayNotAttackText
.burn
	ld a, 1 << BRN
	ld [W_PLAYERMONSTATUS], a
	call Func_3ed64
	ld hl, BurnedText
	jp PrintText
.freeze
	ld a, 1 << FRZ
	ld [W_PLAYERMONSTATUS], a
	ld hl, FrozenText
	jp PrintText

BurnedText: ; 3f3d8 (f:73d8)
	TX_FAR _BurnedText
	db "@"

FrozenText: ; 3f3dd (f:73dd)
	TX_FAR _FrozenText
	db "@"

CheckDefrost: ; 3f3e2 (f:73e2)
	and a, 1 << FRZ			;are they frozen?
	ret z				;return if so
						;not frozen
	ld a, [$fff3]	;whose turn?
	and a
	jr nz, .opponent
	;player [attacker]
	ld a, [W_PLAYERMOVETYPE]
	sub a, FIRE
	ret nz		;return if it isn't fire
				;type is fire
	ld [W_ENEMYMONSTATUS], a		;set opponent status to 00 ["defrost" a frozen monster]
	ld hl, $d8a8					;status of first opponent monster in their roster
	ld a, [W_ENEMYMONNUMBER]
	ld bc, $002c		;$2C bytes per roster entry
	call AddNTimes
	xor a
	ld [hl], a			;clear status in roster
	ld hl, FireDefrostedText
	jr .common
.opponent
	ld a, [W_ENEMYMOVETYPE]		;same as above with addresses swapped
	sub a, FIRE
	ret nz
	ld [W_PLAYERMONSTATUS], a
	ld hl, $d16f
	ld a, [wPlayerMonNumber]
	ld bc, $002c
	call AddNTimes
	xor a
	ld [hl], a
	ld hl, FireDefrostedText
.common
	jp PrintText

FireDefrostedText: ; 3f423 (f:7423)
	TX_FAR _FireDefrostedText
	db "@"

StatModifierUpEffect: ; 3f428 (f:7428)
	ld hl, wPlayerMonStatMods ; $cd1a
	ld de, W_PLAYERMOVEEFFECT ; $cfd3
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f439
	ld hl, wEnemyMonStatMods ; $cd2e
	ld de, W_ENEMYMOVEEFFECT ; $cfcd
.asm_3f439
	ld a, [de]
	sub $a
	cp $8
	jr c, .asm_3f442
	sub $28
.asm_3f442
	ld c, a
	ld b, $0
	add hl, bc
	ld b, [hl]
	inc b
	ld a, $d
	cp b
	jp c, Func_3f522
	ld a, [de]
	cp $12
	jr c, .asm_3f45a
	inc b
	ld a, $d
	cp b
	jr nc, .asm_3f45a
	ld b, a
.asm_3f45a
	ld [hl], b
	ld a, c
	cp $4
	jr nc, asm_3f4ca
	push hl
	ld hl, $d026
	ld de, $cd12
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f472
	ld hl, $cff7
	ld de, $cd26
.asm_3f472
	push bc
	sla c
	ld b, $0
	add hl, bc
	ld a, c
	add e
	ld e, a
	jr nc, .asm_3f47e
	inc d
.asm_3f47e
	pop bc
	ld a, [hld]
	sub $e7
	jr nz, .asm_3f48a
	ld a, [hl]
	sbc $3
	jp z, Func_3f520
.asm_3f48a
	push hl
	push bc
	ld hl, StatModifierRatios ; $76cb
	dec b
	sla b
	ld c, b
	ld b, $0
	add hl, bc
	pop bc
	xor a
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, [de]
	ld [$ff97], a
	inc de
	ld a, [de]
	ld [$ff98], a
	ld a, [hli]
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	call Multiply
	ld a, [hl]
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld b, $4
	call Divide
	pop hl
	ld a, [$ff98]
	sub $e7
	ld a, [$ff97]
	sbc $3
	jp c, Func_3f4c3
	ld a, 999 / $100
	ld [$ff97], a
	ld a, 999 % $100
	ld [$ff98], a

Func_3f4c3: ; 3f4c3 (f:74c3)
	ld a, [$ff97]
	ld [hli], a
	ld a, [$ff98]
	ld [hl], a
	pop hl
asm_3f4ca: ; 3f4ca (f:74ca)
	ld b, c
	inc b
	call Func_3f688
	ld hl, W_PLAYERBATTSTATUS2 ; $d063
	ld de, W_PLAYERMOVENUM ; $cfd2
	ld bc, $ccf7
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f4e6
	ld hl, W_ENEMYBATTSTATUS2 ; $d068
	ld de, W_ENEMYMOVENUM ; $cfcc
	ld bc, $ccf3
.asm_3f4e6
	ld a, [de]
	cp MINIMIZE
	jr nz, .asm_3f4f9
	bit 4, [hl]
	push af
	push bc
	ld hl, Func_79747
	ld b, BANK(Func_79747)
	push de
	call nz, Bankswitch
	pop de
.asm_3f4f9
	call Func_3fba8
	ld a, [de]
	cp MINIMIZE
	jr nz, .asm_3f50e
	pop bc
	ld a, $1
	ld [bc], a
	ld hl, Func_79771
	ld b, BANK(Func_79771)
	pop af
	call nz, Bankswitch
.asm_3f50e
	ld a, [H_WHOSETURN] ; $fff3
	and a
	call z, Func_3ee19
	ld hl, MonsStatsRoseText
	call PrintText
	call Func_3ed27
	jp Func_3ed64

Func_3f520: ; 3f520 (f:7520)
	pop hl
	dec [hl]

Func_3f522: ; 3f522 (f:7522)
	ld hl, NothingHappenedText
	jp PrintText

MonsStatsRoseText: ; 3f528 (f:7528)
	TX_FAR _MonsStatsRoseText
	db $08 ; asm
	ld hl, GreatlyRoseText
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, [W_PLAYERMOVEEFFECT] ; $cfd3
	jr z, .asm_3f53b
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
.asm_3f53b
	cp ATTACK_DOWN1_EFFECT
	ret nc
	ld hl, RoseText
	ret

GreatlyRoseText: ; 3f542 (f:7542)
	db $0a
	TX_FAR _GreatlyRoseText

RoseText: ; 3f547 (f:7547)
	TX_FAR _RoseText
	db "@"

StatModifierDownEffect: ; 3f54c (f:754c)
	ld hl, wEnemyMonStatMods ; $cd2e
	ld de, W_PLAYERMOVEEFFECT ; $cfd3
	ld bc, W_ENEMYBATTSTATUS1 ; $d067
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f572
	ld hl, wPlayerMonStatMods ; $cd1a
	ld de, W_ENEMYMOVEEFFECT ; $cfcd
	ld bc, W_PLAYERBATTSTATUS1 ; $d062
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr z, .asm_3f572
	call GenRandomInBattle
	cp $40
	jp c, Func_3f65a
.asm_3f572
	call CheckTargetSubstitute
	jp nz, Func_3f65a
	ld a, [de]
	cp ATTACK_DOWN_SIDE_EFFECT
	jr c, .asm_3f58a
	call GenRandomInBattle
	cp SPLASH_EFFECT
	jp nc, Func_3f650
	ld a, [de]
	sub ATTACK_DOWN_SIDE_EFFECT
	jr .asm_3f5a9
.asm_3f58a
	push hl
	push de
	push bc
	call MoveHitTest
	pop bc
	pop de
	pop hl
	ld a, [W_MOVEMISSED] ; $d05f
	and a
	jp nz, Func_3f65a
	ld a, [bc]
	bit 6, a
	jp nz, Func_3f65a
	ld a, [de]
	sub $12
	cp $8
	jr c, .asm_3f5a9
	sub $28
.asm_3f5a9
	ld c, a
	ld b, $0
	add hl, bc
	ld b, [hl]
	dec b
	jp z, Func_3f650
	ld a, [de]
	cp $24
	jr c, .asm_3f5bf
	cp $44
	jr nc, .asm_3f5bf
	dec b
	jr nz, .asm_3f5bf
	inc b
.asm_3f5bf
	ld [hl], b
	ld a, c
	cp $4
	jr nc, asm_3f62c
	push hl
	push de
	ld hl, $cff7
	ld de, $cd26
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f5d8
	ld hl, $d026
	ld de, $cd12
.asm_3f5d8
	push bc
	sla c
	ld b, $0
	add hl, bc
	ld a, c
	add e
	ld e, a
	jr nc, .asm_3f5e4
	inc d
.asm_3f5e4
	pop bc
	ld a, [hld]
	sub $1
	jr nz, .asm_3f5ef
	ld a, [hl]
	and a
	jp z, Func_3f64d
.asm_3f5ef
	push hl
	push bc
	ld hl, StatModifierRatios ; $76cb
	dec b
	sla b
	ld c, b
	ld b, $0
	add hl, bc
	pop bc
	xor a
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, [de]
	ld [$ff97], a
	inc de
	ld a, [de]
	ld [$ff98], a
	ld a, [hli]
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	call Multiply
	ld a, [hl]
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld b, $4
	call Divide
	pop hl
	ld a, [$ff98]
	ld b, a
	ld a, [$ff97]
	or b
	jp nz, Func_3f624
	ld [$ff97], a
	ld a, $1
	ld [$ff98], a

Func_3f624: ; 3f624 (f:7624)
	ld a, [$ff97]
	ld [hli], a
	ld a, [$ff98]
	ld [hl], a
	pop de
	pop hl
asm_3f62c: ; 3f62c (f:762c)
	ld b, c
	inc b
	push de
	call Func_3f688
	pop de
	ld a, [de]
	cp $44
	jr nc, .asm_3f63b
	call Func_3fb89
.asm_3f63b
	ld a, [H_WHOSETURN] ; $fff3
	and a
	call nz, Func_3ee19
	ld hl, MonsStatsFellText
	call PrintText
	call Func_3ed27
	jp Func_3ed64

Func_3f64d: ; 3f64d (f:764d)
	pop de
	pop hl
	inc [hl]

Func_3f650: ; 3f650 (f:7650)
	ld a, [de]
	cp ATTACK_DOWN_SIDE_EFFECT
	ret nc
	ld hl, NothingHappenedText
	jp PrintText

Func_3f65a: ; 3f65a (f:765a)
	ld a, [de]
	cp $44
	ret nc
	jp Func_3fb4e

MonsStatsFellText: ; 3f661 (f:7661)
	TX_FAR _MonsStatsFellText
	db $08 ; asm
	ld hl, FellText
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, [W_PLAYERMOVEEFFECT] ; $cfd3
	jr z, .asm_3f674
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
.asm_3f674
	cp $1a
	ret c
	cp $44
	ret nc
	ld hl, GreatlyFellText
	ret

GreatlyFellText: ; 3f67e (f:767e)
	db $0a
	TX_FAR _GreatlyFellText

FellText: ; 3f683 (f:7683)
	TX_FAR _FellText
	db "@"

Func_3f688: ; 3f688 (f:7688)
	ld hl, StatsTextStrings
	ld c, $50
.asm_3f68d
	dec b
	jr z, .asm_3f696
.asm_3f690
	ld a, [hli]
	cp c
	jr z, .asm_3f68d
	jr .asm_3f690
.asm_3f696
	ld de, $cf4b
	ld bc, $a
	jp CopyData

StatsTextStrings: ; 3f69f (f:769f)
	db "ATTACK@"
	db "DEFENSE@"
	db "SPEED@"
	db "SPECIAL@"
	db "ACCURACY@"
	db "EVADE@"

StatModifierRatios: ; 3f6cb (f:76cb)
; first byte is numerator, second byte is denominator
	db 25, 100  ; 0.25
	db 28, 100  ; 0.28
	db 33, 100  ; 0.33
	db 40, 100  ; 0.40
	db 50, 100  ; 0.50
	db 66, 100  ; 0.66
	db  1,   1  ; 1.00
	db 15,  10  ; 1.50
	db  2,   1  ; 2.00
	db 25,  10  ; 2.50
	db  3,   1  ; 3.00
	db 35,  10  ; 3.50
	db  4,   1  ; 4.00

BideEffect: ; 3f6e5 (f:76e5)
	ld hl, W_PLAYERBATTSTATUS1
	ld de, W_NUMHITS
	ld bc, $d06a
	ld a, [H_WHOSETURN]
	and a
	jr z, .asm_3f6fc
	ld hl, W_ENEMYBATTSTATUS1
	ld de, $cd05
	ld bc, $d06f
.asm_3f6fc
	set 0, [hl] ; mon is now using bide
	xor a
	ld [de], a
	inc de
	ld [de], a
	ld [W_PLAYERMOVEEFFECT], a
	ld [W_ENEMYMOVEEFFECT], a
	call GenRandomInBattle
	and $1
	inc a
	inc a
	ld [bc], a
	ld a, [H_WHOSETURN]
	add $ae
	jp Func_3fb96

ThrashPetalDanceEffect: ; 3f717 (f:7717)
	ld hl, W_PLAYERBATTSTATUS1 ; $d062
	ld de, $d06a
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f728
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	ld de, $d06f
.asm_3f728
	set 1, [hl] ; mon is now using thrash/petal dance
	call GenRandomInBattle
	and $1
	inc a
	inc a
	ld [de], a
	ld a, [H_WHOSETURN] ; $fff3
	add $b0
	jp Func_3fb96

SwitchAndTeleportEffect: ; 3f739 (f:7739)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr nz, .asm_3f791
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	jr nz, .asm_3f77e
	ld a, [W_CURENEMYLVL] ; $d127
	ld b, a
	ld a, [W_PLAYERMONLEVEL] ; $d022
	cp b
	jr nc, .asm_3f76e
	add b
	ld c, a
	inc c
.asm_3f751
	call GenRandomInBattle
	cp c
	jr nc, .asm_3f751
	srl b
	srl b
	cp b
	jr nc, .asm_3f76e
	ld c, $32
	call DelayFrames
	ld a, [W_PLAYERMOVENUM] ; $cfd2
	cp TELEPORT
	jp nz, PrintDidntAffectText
	jp PrintButItFailedText_
.asm_3f76e
	call ReadPlayerMonCurHPAndStatus
	xor a
	ld [$cc5b], a
	inc a
	ld [$d078], a
	ld a, [W_PLAYERMOVENUM] ; $cfd2
	jr .asm_3f7e4
.asm_3f77e
	ld c, $32
	call DelayFrames
	ld hl, IsUnaffectedText
	ld a, [W_PLAYERMOVENUM] ; $cfd2
	cp TELEPORT
	jp nz, PrintText
	jp PrintButItFailedText_
.asm_3f791
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	jr nz, .asm_3f7d1
	ld a, [W_PLAYERMONLEVEL] ; $d022
	ld b, a
	ld a, [W_CURENEMYLVL] ; $d127
	cp b
	jr nc, .asm_3f7c1
	add b
	ld c, a
	inc c
.asm_3f7a4
	call GenRandomInBattle
	cp c
	jr nc, .asm_3f7a4
	srl b
	srl b
	cp b
	jr nc, .asm_3f7c1
	ld c, $32
	call DelayFrames
	ld a, [W_ENEMYMOVENUM] ; $cfcc
	cp TELEPORT
	jp nz, PrintDidntAffectText
	jp PrintButItFailedText_
.asm_3f7c1
	call ReadPlayerMonCurHPAndStatus
	xor a
	ld [$cc5b], a
	inc a
	ld [$d078], a
	ld a, [W_ENEMYMOVENUM] ; $cfcc
	jr .asm_3f7e4
.asm_3f7d1
	ld c, $32
	call DelayFrames
	ld hl, IsUnaffectedText
	ld a, [W_ENEMYMOVENUM] ; $cfcc
	cp TELEPORT
	jp nz, PrintText
	jp Func_3fb4e
.asm_3f7e4
	push af
	call Func_3fbb9
	ld c, $14
	call DelayFrames
	pop af
	ld hl, RanFromBattleText ; $7802
	cp TELEPORT
	jr z, .asm_3f7ff
	ld hl, RanAwayScaredText ; $7807
	cp ROAR
	jr z, .asm_3f7ff
	ld hl, WasBlownAwayText ; $780c
.asm_3f7ff
	jp PrintText

RanFromBattleText: ; 3f802 (f:7802)
	TX_FAR _RanFromBattleText
	db "@"

RanAwayScaredText: ; 3f807 (f:7807)
	TX_FAR _RanAwayScaredText
	db "@"

WasBlownAwayText: ; 3f80c (f:780c)
	TX_FAR _WasBlownAwayText
	db "@"

TwoToFiveAttacksEffect: ; 3f811 (f:7811)
	ld hl, W_PLAYERBATTSTATUS1 ; $d062
	ld de, $d06a
	ld bc, W_NUMHITS ; $d074
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f828
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	ld de, $d06f
	ld bc, $cd05
.asm_3f828
	bit 2, [hl] ; is mon attacking multiple times?
	ret nz
	set 2, [hl] ; mon is now attacking multiple times
	ld hl, W_PLAYERMOVEEFFECT ; $cfd3
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f838
	ld hl, W_ENEMYMOVEEFFECT ; $cfcd
.asm_3f838
	ld a, [hl]
	cp TWINEEDLE_EFFECT
	jr z, .asm_3f856
	cp ATTACK_TWICE_EFFECT
	ld a, $2
	jr z, .asm_3f853
	call GenRandomInBattle
	and $3
	cp $2
	jr c, .asm_3f851
	call GenRandomInBattle
	and $3
.asm_3f851
	inc a
	inc a
.asm_3f853
	ld [de], a
	ld [bc], a
	ret
.asm_3f856
	ld a, $2
	ld [hl], a
	jr .asm_3f853

FlichSideEffect: ; 3f85b (f:785b)
	call CheckTargetSubstitute
	ret nz
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	ld de, W_PLAYERMOVEEFFECT ; $cfd3
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f870
	ld hl, W_PLAYERBATTSTATUS1 ; $d062
	ld de, W_ENEMYMOVEEFFECT ; $cfcd
.asm_3f870
	ld a, [de]
	cp FLINCH_SIDE_EFFECT1
	ld b, $1a ; ~10% chance of flinch
	jr z, .asm_3f879
	ld b, $4d ; ~30% chance of flinch
.asm_3f879
	call GenRandomInBattle
	cp b
	ret nc
	set 3, [hl] ; set mon's status to flinching
	call Func_3f9cf
	ret

OneHitKOEffect: ; 3f884 (f:7884)
	ld hl, OneHitKOEffect_
	ld b, BANK(OneHitKOEffect_)
	jp Bankswitch

ChargeEffect: ; 3f88c (f:788c)
	ld hl, W_PLAYERBATTSTATUS1 ; $d062
	ld de, W_PLAYERMOVEEFFECT ; $cfd3
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld b, $ae
	jr z, .asm_3f8a1
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	ld de, W_ENEMYMOVEEFFECT ; $cfcd
	ld b, $af
.asm_3f8a1
	set 4, [hl]
	ld a, [de]
	dec de ; de contains enemy or player MOVENUM
	cp FLY_EFFECT
	jr nz, .asm_3f8ad
	set 6, [hl] ; mon is now invulnerable to typical attacks (fly/dig)
	ld b, $64
.asm_3f8ad
	ld a, [de]
	cp DIG
	jr nz, .asm_3f8b6
	set 6, [hl] ; mon is now invulnerable to typical attacks (fly/dig)
	ld b, $c0
.asm_3f8b6
	xor a
	ld [$cc5b], a
	ld a, b
	call Func_3fbb9
	ld a, [de]
	ld [wWhichTrade], a ; $cd3d
	ld hl, ChargeMoveEffectText ; $78c8
	jp PrintText

ChargeMoveEffectText: ; 3f8c8 (f:78c8)
	TX_FAR _ChargeMoveEffectText
	db $08 ; asm
	ld a, [wWhichTrade] ; $cd3d
	cp RAZOR_WIND
	ld hl, MadeWhirlwindText ; $78f9
	jr z, .asm_3f8f8
	cp SOLARBEAM
	ld hl, TookInSunlightText ; $78fe
	jr z, .asm_3f8f8
	cp SKULL_BASH
	ld hl, LoweredItsHeadText ; $7903
	jr z, .asm_3f8f8
	cp SKY_ATTACK
	ld hl, SkyAttackGlowingText ; $7908
	jr z, .asm_3f8f8
	cp FLY
	ld hl, FlewUpHighText ; $790d
	jr z, .asm_3f8f8
	cp DIG
	ld hl, DugAHoleText ; $7912
.asm_3f8f8
	ret

MadeWhirlwindText: ; 3f8f9 (f:78f9)
	TX_FAR _MadeWhirlwindText
	db "@"

TookInSunlightText: ; 3f8fe (f:78fe)
	TX_FAR _TookInSunlightText
	db "@"

LoweredItsHeadText: ; 3f903 (f:7903)
	TX_FAR _LoweredItsHeadText
	db "@"

SkyAttackGlowingText: ; 3f908 (f:7908)
	TX_FAR _SkyAttackGlowingText
	db "@"

FlewUpHighText: ; 3f90d (f:790d)
	TX_FAR _FlewUpHighText
	db "@"

DugAHoleText: ; 3f912 (f:7912)
	TX_FAR _DugAHoleText
	db "@"

TrappingEffect: ; 3f917 (f:7917)
	ld hl, W_PLAYERBATTSTATUS1 ; $d062
	ld de, $d06a
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f928
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	ld de, $d06f
.asm_3f928
	bit 5, [hl]
	ret nz
	call Func_3f9cf
	set 5, [hl]
	call GenRandomInBattle
	and $3
	cp $2
	jr c, .asm_3f93e
	call GenRandomInBattle
	and $3
.asm_3f93e
	inc a
	ld [de], a
	ret

MistEffect: ; 3f941 (f:7941)
	ld hl, MistEffect_
	ld b, BANK(MistEffect_)
	jp Bankswitch

FocusEnergyEffect: ; 3f949 (f:7949)
	ld hl, FocusEnergyEffect_
	ld b, BANK(FocusEnergyEffect_)
	jp Bankswitch

RecoilEffect: ; 3f951 (f:7951)
	ld hl, RecoilEffect_
	ld b, BANK(RecoilEffect_)
	jp Bankswitch

ConfusionSideEffect: ; 3f959 (f:7959)
	call GenRandomInBattle
	cp $19
	ret nc
	jr Func_3f96f

ConfusionEffect: ; 3f961 (f:7961)
	call CheckTargetSubstitute
	jr nz, Func_3f9a6
	call MoveHitTest
	ld a, [W_MOVEMISSED] ; $d05f
	and a
	jr nz, Func_3f9a6

Func_3f96f: ; 3f96f (f:796f)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld hl, W_ENEMYBATTSTATUS1 ; $d067
	ld bc, $d070
	ld a, [W_PLAYERMOVEEFFECT] ; $cfd3
	jr z, .asm_3f986
	ld hl, W_PLAYERBATTSTATUS1 ; $d062
	ld bc, $d06b
	ld a, [W_ENEMYMOVEEFFECT] ; $cfcd
.asm_3f986
	bit 7, [hl] ; is mon confused?
	jr nz, Func_3f9a6
	set 7, [hl] ; mon is now confused
	push af
	call GenRandomInBattle
	and $3
	inc a
	inc a
	ld [bc], a
	pop af
	cp CONFUSION_SIDE_EFFECT
	call nz, Func_3fb89
	ld hl, BecameConfusedText ; $79a1
	jp PrintText

BecameConfusedText: ; 3f9a1 (f:79a1)
	TX_FAR _BecameConfusedText
	db "@"

Func_3f9a6: ; 3f9a6 (f:79a6)
	cp CONFUSION_SIDE_EFFECT
	ret z
	ld c, $32
	call DelayFrames
	jp Func_3fb4e

ParalyzeEffect: ; 3f9b1 (f:79b1)
	ld hl, ParalyzeEffect_
	ld b, BANK(ParalyzeEffect_)
	jp Bankswitch

SubstituteEffect: ; 3f9b9 (f:79b9)
	ld hl, SubstituteEffectHandler
	ld b, BANK(SubstituteEffectHandler)
	jp Bankswitch

HyperBeamEffect: ; 3f9c1 (f:79c1)
	ld hl, W_PLAYERBATTSTATUS2 ; $d063
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f9cc
	ld hl, W_ENEMYBATTSTATUS2 ; $d068
.asm_3f9cc
	set 5, [hl] ; mon now needs to recharge
	ret

Func_3f9cf: ; 3f9cf (f:79cf)
	push hl
	ld hl, W_ENEMYBATTSTATUS2 ; $d068
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3f9db
	ld hl, W_PLAYERBATTSTATUS2 ; $d063
.asm_3f9db
	res 5, [hl] ; mon no longer needs to recharge
	pop hl
	ret

RageEffect: ; 3f9df (f:79df)
	ld hl, W_PLAYERBATTSTATUS2
	ld a, [H_WHOSETURN]
	and a
	jr z, .player
	ld hl, W_ENEMYBATTSTATUS2
.player
	set 6, [hl] ; mon is now in "rage" mode
	ret

MimicEffect: ; 3f9ed (f:79ed)
	ld c, $32
	call DelayFrames
	call MoveHitTest
	ld a, [W_MOVEMISSED]
	and a
	jr nz, .asm_3fa74
	ld a, [H_WHOSETURN]
	and a
	ld hl, W_PLAYERMONMOVES
	ld a, [W_PLAYERBATTSTATUS1]
	jr nz, .asm_3fa13
	ld a, [W_ISLINKBATTLE]
	cp $4
	jr nz, .asm_3fa3a
	ld hl, W_ENEMYMONMOVES
	ld a, [W_ENEMYBATTSTATUS1]
.asm_3fa13
	bit 6, a
	jr nz, .asm_3fa74
.asm_3fa17
	push hl
	call GenRandomInBattle
	and $3
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]
	pop hl
	and a
	jr z, .asm_3fa17
	ld d, a
	ld a, [H_WHOSETURN]
	and a
	ld hl, W_PLAYERMONMOVES
	ld a, [wPlayerMoveListIndex]
	jr z, .asm_3fa5f
	ld hl, W_ENEMYMONMOVES
	ld a, [wEnemyMoveListIndex]
	jr .asm_3fa5f
.asm_3fa3a
	ld a, [W_ENEMYBATTSTATUS1]
	bit 6, a
	jr nz, .asm_3fa74
	ld a, [wCurrentMenuItem]
	push af
	ld a, $1
	ld [wMoveMenuType], a
	call MoveSelectionMenu
	call LoadScreenTilesFromBuffer1
	ld hl, W_ENEMYMONMOVES
	ld a, [wCurrentMenuItem]
	ld c, a
	ld b, $0
	add hl, bc
	ld d, [hl]
	pop af
	ld hl, W_PLAYERMONMOVES
.asm_3fa5f
	ld c, a
	ld b, $0
	add hl, bc
	ld a, d
	ld [hl], a
	ld [$d11e], a
	call GetMoveName
	call Func_3fba8
	ld hl, MimicLearnedMoveText
	jp PrintText
.asm_3fa74
	jp PrintButItFailedText_

MimicLearnedMoveText: ; 3fa77 (f:7a77)
	TX_FAR _MimicLearnedMoveText
	db "@"

LeechSeedEffect: ; 3fa7c (f:7a7c)
	ld hl, LeechSeedEffect_
	ld b, BANK(LeechSeedEffect_)
	jp Bankswitch

SplashEffect: ; 3fa84 (f:7a84)
	call Func_3fba8
	jp PrintNoEffectText

DisableEffect: ; 3fa8a (f:7a8a)
	call MoveHitTest
	ld a, [W_MOVEMISSED] ; $d05f
	and a
	jr nz, .asm_3fb06
	ld de, W_ENEMYDISABLEDMOVE ; $d072
	ld hl, W_ENEMYMONMOVES
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_3faa4
	ld de, W_PLAYERDISABLEDMOVE ; $d06d
	ld hl, W_PLAYERMONMOVES
.asm_3faa4
	ld a, [de]
	and a
	jr nz, .asm_3fb06
.asm_3faa8
	push hl
	call GenRandomInBattle
	and $3
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]
	pop hl
	and a
	jr z, .asm_3faa8
	ld [$d11e], a
	push hl
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld hl, W_PLAYERMONPP ; $d02d
	jr nz, .asm_3facf
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	pop hl
	jr nz, .asm_3fae1
	push hl
	ld hl, W_ENEMYMONPP ; $cffe
.asm_3facf
	push hl
	ld a, [hli]
	or [hl]
	inc hl
	or [hl]
	inc hl
	or [hl]
	and $3f
	pop hl
	jr z, .asm_3fb05
	add hl, bc
	ld a, [hl]
	pop hl
	and a
	jr z, .asm_3faa8
.asm_3fae1
	call GenRandomInBattle
	and $7
	inc a
	inc c
	swap c
	add c
	ld [de], a
	call Func_3fb89
	ld hl, $ccee
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr nz, .asm_3faf8
	inc hl
.asm_3faf8
	ld a, [$d11e]
	ld [hl], a
	call GetMoveName
	ld hl, MoveWasDisabledText ; $7b09
	jp PrintText
.asm_3fb05
	pop hl
.asm_3fb06
	jp PrintButItFailedText_

MoveWasDisabledText: ; 3fb09 (f:7b09)
	TX_FAR _MoveWasDisabledText
	db "@"

PayDayEffect: ; 3fb0e (f:7b0e)
	ld hl, PayDayEffect_
	ld b, BANK(PayDayEffect_)
	jp Bankswitch

ConversionEffect: ; 3fb16 (f:7b16)
	ld hl, ConversionEffect_
	ld b, BANK(ConversionEffect_)
	jp Bankswitch

HazeEffect: ; 3fb1e (f:7b1e)
	ld hl, HazeEffect_
	ld b, BANK(HazeEffect_)
	jp Bankswitch

HealEffect: ; 3fb26 (f:7b26)
	ld hl, HealEffect_
	ld b, BANK(HealEffect_)
	jp Bankswitch

TransformEffect: ; 3fb2e (f:7b2e)
	ld hl, TransformEffect_
	ld b, BANK(TransformEffect_)
	jp Bankswitch

ReflectLightScreenEffect: ; 3fb36 (f:7b36)
	ld hl, ReflectLightScreenEffect_
	ld b, BANK(ReflectLightScreenEffect_)
	jp Bankswitch

NothingHappenedText: ; 3fb3e (f:7b3e)
	TX_FAR _NothingHappenedText
	db "@"

PrintNoEffectText: ; 3fb43 (f:7b43)
	ld hl, NoEffectText
	jp PrintText

NoEffectText: ; 3fb49 (f:7b49)
	TX_FAR _NoEffectText
	db "@"

Func_3fb4e: ; 3fb4e (f:7b4e)
	ld a, [$ccf4]
	and a
	ret nz

PrintButItFailedText_: ; 3fb53 (f:7b53)
	ld hl, ButItFailedText
	jp PrintText

ButItFailedText: ; 3fb59 (f:7b59)
	TX_FAR _ButItFailedText
	db "@"

PrintDidntAffectText: ; 3fb5e (f:7b5e)
	ld hl, DidntAffectText
	jp PrintText

DidntAffectText: ; 3fb64 (f:7b64)
	TX_FAR _DidntAffectText
	db "@"

IsUnaffectedText: ; 3fb69 (f:7b69)
	TX_FAR _IsUnaffectedText
	db "@"

PrintMayNotAttackText: ; 3fb6e (f:7b6e)
	ld hl, ParalyzedMayNotAttackText ; $7b74
	jp PrintText

ParalyzedMayNotAttackText: ; 3fb74 (f:7b74)
	TX_FAR _ParalyzedMayNotAttackText
	db "@"

CheckTargetSubstitute: ; 3fb79 (f:7b79)
	push hl
	ld hl, $d068
	ld a, [$fff3]   ;whose turn?
	and a
	jr z, .next1
	ld hl, $d063
.next1
	bit 4, [hl]         ;test bit 4 in d063/d068 flags
	pop hl
	ret

Func_3fb89: ; 3fb89 (f:7b89)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, [W_PLAYERMOVENUM] ; $cfd2
	jr z, .asm_3fb94
	ld a, [W_ENEMYMOVENUM] ; $cfcc
.asm_3fb94
	and a
	ret z

Func_3fb96: ; 3fb96 (f:7b96)
	ld [W_ANIMATIONID], a ; $d07c
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, $6
	jr z, .asm_3fba2
	ld a, $3
.asm_3fba2
	ld [$cc5b], a
	jp Func_3fbbc

Func_3fba8: ; 3fba8 (f:7ba8)
	xor a
	ld [$cc5b], a
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, [W_PLAYERMOVENUM] ; $cfd2
	jr z, .asm_3fbb7
	ld a, [W_ENEMYMOVENUM] ; $cfcc
.asm_3fbb7
	and a
	ret z

Func_3fbb9: ; 3fbb9 (f:7bb9)
	ld [W_ANIMATIONID], a ; $d07c

Func_3fbbc: ; 3fbbc (f:7bbc)
	push hl
	push de
	push bc
	ld a, $8
	call Predef ; indirect jump to MoveAnimation (78d5e (1e:4d5e))
	pop bc
	pop de
	pop hl
	ret

SECTION "bank10",ROMX,BANK[$10]

DisplayPokedexMenu_: ; 40000 (10:4000)
	call GBPalWhiteOut
	call ClearScreen
	call UpdateSprites ; move sprites
	ld a,[wListScrollOffset]
	push af
	xor a
	ld [wCurrentMenuItem],a
	ld [wListScrollOffset],a
	ld [wLastMenuItem],a
	inc a
	ld [$d11e],a
	ld [$ffb7],a
.setUpGraphics
	ld b,$08
	call GoPAL_SET
	callab LoadPokedexTilePatterns
.doPokemonListMenu
	ld hl,wTopMenuItemY
	ld a,3
	ld [hli],a ; top menu item Y
	xor a
	ld [hli],a ; top menu item X
	inc a
	ld [$cc37],a
	inc hl
	inc hl
	ld a,6
	ld [hli],a ; max menu item ID
	ld [hl],%00110011 ; menu watched keys (Left, Right, B button, A  button)
	call HandlePokedexListMenu
	jr c,.goToSideMenu ; if the player chose a pokemon from the list
.exitPokedex
	xor a
	ld [$cc37],a
	ld [wCurrentMenuItem],a
	ld [wLastMenuItem],a
	ld [$ffb7],a
	ld [$cd3a],a
	ld [$cd3b],a
	pop af
	ld [wListScrollOffset],a
	call GBPalWhiteOutWithDelay3
	call GoPAL_SET_CF1C
	jp ReloadMapData
.goToSideMenu
	call HandlePokedexSideMenu
	dec b
	jr z,.exitPokedex ; if the player chose Quit
	dec b
	jr z,.doPokemonListMenu ; if pokemon not seen or player pressed B button
	jp .setUpGraphics ; if pokemon data or area was shown

; handles the menu on the lower right in the pokedex screen
; OUTPUT:
; b = reason for exiting menu
; 00: showed pokemon data or area
; 01: the player chose Quit
; 02: the pokemon has not been seen yet or the player pressed the B button
HandlePokedexSideMenu: ; 4006d (10:406d)
	call PlaceUnfilledArrowMenuCursor
	ld a,[wCurrentMenuItem]
	push af
	ld b,a
	ld a,[wLastMenuItem]
	push af
	ld a,[wListScrollOffset]
	push af
	add b
	inc a
	ld [$d11e],a
	ld a,[$d11e]
	push af
	ld a,[$cd3d]
	push af
	ld hl,wPokedexSeen
	call IsPokemonBitSet
	ld b,2
	jr z,.exitSideMenu
	call PokedexToIndex
	ld hl,wTopMenuItemY
	ld a,10
	ld [hli],a ; top menu item Y
	ld a,15
	ld [hli],a ; top menu item X
	xor a
	ld [hli],a ; current menu item ID
	inc hl
	ld a,3
	ld [hli],a ; max menu item ID
	ld [hli],a ; menu watched keys (A button and B button)
	xor a
	ld [hli],a ; old menu item ID
	ld [$cc37],a
.handleMenuInput
	call HandleMenuInput
	bit 1,a ; was the B button pressed?
	ld b,2
	jr nz,.buttonBPressed
	ld a,[wCurrentMenuItem]
	and a
	jr z,.choseData
	dec a
	jr z,.choseCry
	dec a
	jr z,.choseArea
.choseQuit
	ld b,1
.exitSideMenu
	pop af
	ld [$cd3d],a
	pop af
	ld [$d11e],a
	pop af
	ld [wListScrollOffset],a
	pop af
	ld [wLastMenuItem],a
	pop af
	ld [wCurrentMenuItem],a
	push bc
	FuncCoord 0,3
	ld hl,Coord
	ld de,20
	ld bc,$7f0d ; 13 blank tiles
	call DrawTileLine ; cover up the menu cursor in the pokemon list
	pop bc
	ret
.buttonBPressed
	push bc
	FuncCoord 15,10
	ld hl,Coord
	ld de,20
	ld bc,$7f07 ; 7 blank tiles
	call DrawTileLine ; cover up the menu cursor in the side menu
	pop bc
	jr .exitSideMenu
.choseData
	call ShowPokedexDataInternal
	ld b,0
	jr .exitSideMenu
; play pokemon cry
.choseCry
	ld a,[$d11e]
	call GetCryData ; get cry data
	call PlaySound ; play sound
	jr .handleMenuInput
.choseArea
	ld a,$4a
	call Predef ; display pokemon areas
	ld b,0
	jr .exitSideMenu

; handles the list of pokemon on the left of the pokedex screen
; sets carry flag if player presses A, unsets carry flag if player presses B
HandlePokedexListMenu: ; 40111 (10:4111)
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a
; draw the horizontal line separating the seen and owned amounts from the menu
	FuncCoord 15,8
	ld hl,Coord
	ld a,$7a ; horizontal line tile
	ld [hli],a
	ld [hli],a
	ld [hli],a
	ld [hli],a
	ld [hli],a
	FuncCoord 14,0
	ld hl,Coord
	ld [hl],$71 ; vertical line tile
	FuncCoord 14,1
	ld hl,Coord
	call DrawPokedexVerticalLine
	FuncCoord 14,9
	ld hl,Coord
	call DrawPokedexVerticalLine
	ld hl,wPokedexSeen
	ld b,wPokedexSeenEnd - wPokedexSeen
	call CountSetBits
	ld de,$d11e
	FuncCoord 16,3
	ld hl,Coord
	ld bc,$0103
	call PrintNumber ; print number of seen pokemon
	ld hl,wPokedexOwned
	ld b,wPokedexOwnedEnd - wPokedexOwned
	call CountSetBits
	ld de,$d11e
	FuncCoord 16,6
	ld hl,Coord
	ld bc,$0103
	call PrintNumber ; print number of owned pokemon
	FuncCoord 16,2
	ld hl,Coord
	ld de,PokedexSeenText
	call PlaceString
	FuncCoord 16,5
	ld hl,Coord
	ld de,PokedexOwnText
	call PlaceString
	FuncCoord 1,1
	ld hl,Coord
	ld de,PokedexContentsText
	call PlaceString
	FuncCoord 16,10
	ld hl,Coord
	ld de,PokedexMenuItemsText
	call PlaceString
; find the highest pokedex number among the pokemon the player has seen
	ld hl,wPokedexSeenEnd - 1
	ld b,153
.maxSeenPokemonLoop
	ld a,[hld]
	ld c,8
.maxSeenPokemonInnerLoop
	dec b
	sla a
	jr c,.storeMaxSeenPokemon
	dec c
	jr nz,.maxSeenPokemonInnerLoop
	jr .maxSeenPokemonLoop
.storeMaxSeenPokemon
	ld a,b
	ld [$cd3d],a ; max seen pokemon
.loop
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a
	FuncCoord 4,2
	ld hl,Coord
	ld bc,$0e0a
	call ClearScreenArea
	FuncCoord 1,3
	ld hl,Coord
	ld a,[wListScrollOffset]
	ld [$d11e],a
	ld d,7
	ld a,[$cd3d]
	cp a,7
	jr nc,.printPokemonLoop
	ld d,a
	dec a
	ld [wMaxMenuItem],a
; loop to print pokemon pokedex numbers and names
; if the player has owned the pokemon, it puts a pokeball beside the name
.printPokemonLoop
	ld a,[$d11e]
	inc a
	ld [$d11e],a
	push af
	push de
	push hl
	ld de,-20
	add hl,de
	ld de,$d11e
	ld bc,$8103
	call PrintNumber ; print the pokedex number
	ld de,20
	add hl,de
	dec hl
	push hl
	ld hl,wPokedexOwned
	call IsPokemonBitSet
	pop hl
	ld a," "
	jr z,.writeTile
	ld a,$72 ; pokeball tile
.writeTile
	ld [hl],a ; put a pokeball next to pokemon that the player has owned
	push hl
	ld hl,wPokedexSeen
	call IsPokemonBitSet
	jr nz,.getPokemonName ; if the player has seen the pokemon
	ld de,.dashedLine ; print a dashed line in place of the name if the player hasn't seen the pokemon
	jr .skipGettingName
.dashedLine ; for unseen pokemon in the list
	db "----------@"
.getPokemonName
	call PokedexToIndex
	call GetMonName
.skipGettingName
	pop hl
	inc hl
	call PlaceString
	pop hl
	ld bc,2 * 20
	add hl,bc
	pop de
	pop af
	ld [$d11e],a
	dec d
	jr nz,.printPokemonLoop
	ld a,01
	ld [H_AUTOBGTRANSFERENABLED],a
	call Delay3
	call GBPalNormal
	call HandleMenuInput
	bit 1,a ; was the B button pressed?
	jp nz,.buttonBPressed
.checkIfUpPressed
	bit 6,a ; was Up pressed?
	jr z,.checkIfDownPressed
.upPressed ; scroll up one row
	ld a,[wListScrollOffset]
	and a
	jp z,.loop
	dec a
	ld [wListScrollOffset],a
	jp .loop
.checkIfDownPressed
	bit 7,a ; was Down pressed?
	jr z,.checkIfRightPressed
.downPressed ; scroll down one row
	ld a,[$cd3d]
	cp a,7
	jp c,.loop
	sub a,7
	ld b,a
	ld a,[wListScrollOffset]
	cp b
	jp z,.loop
	inc a
	ld [wListScrollOffset],a
	jp .loop
.checkIfRightPressed
	bit 4,a ; was Right pressed?
	jr z,.checkIfLeftPressed
.rightPressed ; scroll down 7 rows
	ld a,[$cd3d]
	cp a,7
	jp c,.loop
	sub a,6
	ld b,a
	ld a,[wListScrollOffset]
	add a,7
	ld [wListScrollOffset],a
	cp b
	jp c,.loop
	dec b
	ld a,b
	ld [wListScrollOffset],a
	jp .loop
.checkIfLeftPressed ; scroll up 7 rows
	bit 5,a ; was Left pressed?
	jr z,.buttonAPressed
.leftPressed
	ld a,[wListScrollOffset]
	sub a,7
	ld [wListScrollOffset],a
	jp nc,.loop
	xor a
	ld [wListScrollOffset],a
	jp .loop
.buttonAPressed
	scf
	ret
.buttonBPressed
	and a
	ret

DrawPokedexVerticalLine: ; 4028e (10:428e)
	ld c,9 ; height of line
	ld de,20 ; width of screen
	ld a,$71 ; vertical line tile
.loop
	ld [hl],a
	add hl,de
	xor a,1 ; toggle between vertical line tile and box tile
	dec c
	jr nz,.loop
	ret

PokedexSeenText: ; 4029d (10:429d)
	db "SEEN@"

PokedexOwnText: ; 402a2 (10:42a2)
	db "OWN@"

PokedexContentsText: ; 402a6 (10:42a6)
	db "CONTENTS@"

PokedexMenuItemsText: ; 402af (10:42af)
	db   "DATA"
	next "CRY"
	next "AREA"
	next "QUIT@"

; tests if a pokemon's bit is set in the seen or owned pokemon bit fields
; INPUT:
; [$d11e] = pokedex number
; hl = address of bit field
IsPokemonBitSet: ; 402c2 (10:42c2)
	ld a,[$d11e]
	dec a
	ld c,a
	ld b,2
	ld a,$10
	call Predef
	ld a,c
	and a
	ret

; function to display pokedex data from outside the pokedex
ShowPokedexData: ; 402d1 (10:42d1)
	call GBPalWhiteOutWithDelay3
	call ClearScreen
	call UpdateSprites
	callab LoadPokedexTilePatterns ; load pokedex tiles

; function to display pokedex data from inside the pokedex
ShowPokedexDataInternal: ; 402e2 (10:42e2)
	ld hl,$d72c
	set 1,[hl]
	ld a,$33 ; 3/7 volume
	ld [$ff24],a
	call GBPalWhiteOut ; zero all palettes
	call ClearScreen
	ld a,[$d11e] ; pokemon ID
	ld [$cf91],a
	push af
	ld b,04
	call GoPAL_SET
	pop af
	ld [$d11e],a
	ld a,[$ffd7]
	push af
	xor a
	ld [$ffd7],a
	FuncCoord 0,0
	ld hl,Coord
	ld de,1
	ld bc,$6414
	call DrawTileLine ; draw top border
	FuncCoord 0,17
	ld hl,Coord
	ld b,$6f
	call DrawTileLine ; draw bottom border
	FuncCoord 0,1
	ld hl,Coord
	ld de,20
	ld bc,$6610
	call DrawTileLine ; draw left border
	FuncCoord 19,1
	ld hl,Coord
	ld b,$67
	call DrawTileLine ; draw right border
	FuncCoord 0,0
	ld a,$63 ; upper left corner tile
	ld [Coord],a
	FuncCoord 19,0
	ld a,$65 ; upper right corner tile
	ld [Coord],a
	FuncCoord 0,17
	ld a,$6c ; lower left corner tile
	ld [Coord],a
	FuncCoord 19,17
	ld a,$6e ; lower right corner tile
	ld [Coord],a
	FuncCoord 0,9
	ld hl,Coord
	ld de,PokedexDataDividerLine
	call PlaceString ; draw horizontal divider line
	FuncCoord 9,6
	ld hl,Coord
	ld de,HeightWeightText
	call PlaceString
	call GetMonName
	FuncCoord 9,2
	ld hl,Coord
	call PlaceString
	ld hl,PokedexEntryPointers
	ld a,[$d11e]
	dec a
	ld e,a
	ld d,0
	add hl,de
	add hl,de
	ld a,[hli]
	ld e,a
	ld d,[hl] ; de = address of pokedex entry
	FuncCoord 9,4
	ld hl,Coord
	call PlaceString ; print species name
	ld h,b
	ld l,c
	push de
	ld a,[$d11e]
	push af
	call IndexToPokedex
	FuncCoord 2,8
	ld hl,Coord
	ld a, "№"
	ld [hli],a
	ld a,$f2
	ld [hli],a
	ld de,$d11e
	ld bc,$8103
	call PrintNumber ; print pokedex number
	ld hl,wPokedexOwned
	call IsPokemonBitSet
	pop af
	ld [$d11e],a
	ld a,[$cf91]
	ld [$d0b5],a
	pop de
	push af
	push bc
	push de
	push hl
	call Delay3
	call GBPalNormal
	call GetMonHeader ; load pokemon picture location
	FuncCoord 1,1
	ld hl,Coord
	call LoadFlippedFrontSpriteByMonIndex ; draw pokemon picture
	ld a,[$cf91]
	call PlayCry ; play pokemon cry
	pop hl
	pop de
	pop bc
	pop af
	ld a,c
	and a
	jp z,.waitForButtonPress ; if the pokemon has not been owned, don't print the height, weight, or description
	inc de ; de = address of feet (height)
	ld a,[de] ; reads feet, but a is overwritten without being used
	FuncCoord 12,6
	ld hl,Coord
	ld bc,$0102
	call PrintNumber ; print feet (height)
	ld a,$60 ; feet symbol tile (one tick)
	ld [hl],a
	inc de
	inc de ; de = address of inches (height)
	FuncCoord 15,6
	ld hl,Coord
	ld bc,$8102
	call PrintNumber ; print inches (height)
	ld a,$61 ; inches symbol tile (two ticks)
	ld [hl],a
; now print the weight (note that weight is stored in tenths of pounds internally)
	inc de
	inc de
	inc de ; de = address of upper byte of weight
	push de
; put weight in big-endian order at $ff8b
	ld hl,$ff8b
	ld a,[hl] ; save existing value of [$ff8b]
	push af
	ld a,[de] ; a = upper byte of weight
	ld [hli],a ; store upper byte of weight in [$ff8b]
	ld a,[hl] ; save existing value of [$ff8c]
	push af
	dec de
	ld a,[de] ; a = lower byte of weight
	ld [hl],a ; store lower byte of weight in [$ff8c]
	FuncCoord 11,8
	ld de,$ff8b
	ld hl,Coord
	ld bc,$0205 ; no leading zeroes, right-aligned, 2 bytes, 5 digits
	call PrintNumber ; print weight
	FuncCoord 14,8
	ld hl,Coord
	ld a,[$ff8c]
	sub a,10
	ld a,[$ff8b]
	sbc a,0
	jr nc,.next
	ld [hl],"0" ; if the weight is less than 10, put a 0 before the decimal point
.next
	inc hl
	ld a,[hli]
	ld [hld],a ; make space for the decimal point by moving the last digit forward one tile
	ld [hl],$f2 ; decimal point tile
	pop af
	ld [$ff8c],a ; restore original value of [$ff8c]
	pop af
	ld [$ff8b],a ; restore original value of [$ff8b]
	pop hl
	inc hl ; hl = address of pokedex description text
	FuncCoord 1,11
	ld bc,Coord
	ld a,2
	ld [$fff4],a
	call TextCommandProcessor ; print pokedex description text
	xor a
	ld [$fff4],a
.waitForButtonPress
	call GetJoypadStateLowSensitivity
	ld a,[$ffb5]
	and a,%00000011 ; A button and B button
	jr z,.waitForButtonPress
	pop af
	ld [$ffd7],a
	call GBPalWhiteOut
	call ClearScreen
	call GoPAL_SET_CF1C
	call LoadTextBoxTilePatterns
	call GBPalNormal
	ld hl,$d72c
	res 1,[hl]
	ld a,$77 ; max volume
	ld [$ff24],a
	ret

HeightWeightText: ; 40448 (10:4448)
	db "HT  ?",$60,"??",$61,$4E,"WT   ???lb@"

; XXX does anything point to this?
Unknown_4045D: ; 4045d (10:445d)
	db $54,$50

; horizontal line that divides the pokedex text description from the rest of the data
PokedexDataDividerLine: ; 4045f (10:445f)
	db $68,$69,$6B,$69,$6B
	db $69,$6B,$69,$6B,$6B
	db $6B,$6B,$69,$6B,$69
	db $6B,$69,$6B,$69,$6A
	db $50

; draws a line of tiles
; INPUT:
; b = tile ID
; c = number of tile ID's to write
; de = amount to destination address after each tile (1 for horizontal, 20 for vertical)
; hl = destination address
DrawTileLine: ; 40474 (10:4474)
	push bc
	push de
.loop
	ld [hl],b
	add hl,de
	dec c
	jr nz,.loop
	pop de
	pop bc
	ret

INCLUDE "data/pokedex_entries.asm"

PokedexToIndex: ; 40ff9 (10:4ff9)
	; converts the Pokédex number at $D11E to an index
	push bc
	push hl
	ld a,[$D11E]
	ld b,a
	ld c,0
	ld hl,PokedexOrder

.loop ; go through the list until we find an entry with a matching dex number
	inc c
	ld a,[hli]
	cp b
	jr nz,.loop

	ld a,c
	ld [$D11E],a
	pop hl
	pop bc
	ret

IndexToPokedex: ; 41010 (10:5010)
	; converts the indexédex number at $D11E to a Pokédex number
	push bc
	push hl
	ld a,[$D11E]
	dec a
	ld hl,PokedexOrder
	ld b,0
	ld c,a
	add hl,bc
	ld a,[hl]
	ld [$D11E],a
	pop hl
	pop bc
	ret

INCLUDE "data/pokedex_order.asm"

Func_410e2: ; 410e2 (10:50e2)
	ld a, [wWhichTrade] ; $cd3d
	ld [$cd5e], a
	ld a, [wTrainerEngageDistance]
	ld [$cd5f], a
	ld de, PointerIDs_41138 ; $5138
	jr Func_41102

Func_410f3: ; 410f3 (10:50f3)
	ld a, [wTrainerEngageDistance]
	ld [$cd5e], a
	ld a, [wTrainerSpriteOffset]
	ld [$cd5f], a
	ld de, PointerIDs_41149

Func_41102: ; 41102 (10:5102)
	ld a, [W_OPTIONS] ; $d355
	push af
	ld a, [$ffaf]
	push af
	ld a, [$ffae]
	push af
	xor a
	ld [W_OPTIONS], a ; $d355
	ld [$ffaf], a
	ld [$ffae], a
	push de
.asm_41115
	pop de
	ld a, [de]
	cp $ff
	jr z, .asm_4112d
	inc de
	push de
	ld hl, PointerTable_4115f ; $515f
	add a
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld de, .asm_41115 ; $5115
	push de
	jp [hl]
.asm_4112d
	pop af
	ld [$ffae], a
	pop af
	ld [$ffaf], a
	pop af
	ld [W_OPTIONS], a ; $d355
	ret

; these bytes refer to the $00th through $10th pointer of PointerTable_4115f
PointerIDs_41138: ; 41138 (10:5138)
	db $00,$01,$02,$03,$05,$07,$08,$09,$0A,$0B,$06,$08,$02,$04,$07,$0E,$FF

PointerIDs_41149: ; 41149 (10:5149)
	db $00,$08,$0D,$0B,$10,$05,$10,$08,$02,$04,$0F,$01,$02,$03,$10,$06,$10,$07,$08,$09,$0E,$FF

PointerTable_4115f: ; 4115f (10:515f)
	dw LoadTradingGFXAndMonNames
	dw Func_41245
	dw Func_41298
	dw Func_412d2
	dw Func_41336
	dw Func_41376
	dw Func_413c6
	dw Func_41181
	dw Func_415c8
	dw PrintTradeWentToText
	dw PrintTradeForSendsText
	dw PrintTradeFarewellText
	dw PrintTradeTakeCareText
	dw PrintTradeWillTradeText
	dw Func_4123b
	dw Func_415df
	dw Func_41217

Func_41181: ; 41181 (10:5181)
	ld c, $64
	jp DelayFrames

Func_41186: ; 41186 (10:5186)
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Delay3
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ret

Delay50: ; 41191 (10:5191)
	ld c, $50
	jp DelayFrames

Func_41196: ; 41196 (10:5196)
	ld hl, wTileMap
	ld bc, $168
	ld a, $7f
	jp FillMemory

LoadTradingGFXAndMonNames: ; 411a1 (10:51a1)
	call Func_41196
	call DisableLCD
	ld hl, TradingAnimationGraphics ; $69be
	ld de, $9310
	ld bc, $310
	ld a, BANK(TradingAnimationGraphics)
	call FarCopyData2
	ld hl, TradingAnimationGraphics2 ; $6cce
	ld de, $87c0
	ld bc, $40
	ld a, BANK(TradingAnimationGraphics2)
	call FarCopyData2
	ld hl, $9800
	ld bc, $800
	ld a, $7f
	call FillMemory
	call CleanLCD_OAM
	ld a, $ff
	ld [$cfcb], a
	ld hl, $d730
	set 6, [hl]
	ld a, [$cf1b]
	and a
	ld a, $e4
	jr z, .asm_411e5
	ld a, $f0
.asm_411e5
	ld [rOBP0], a ; $ff48
	call EnableLCD
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, [wWhichTrade] ; $cd3d
	ld [$d11e], a
	call GetMonName
	ld hl, $cd6d
	ld de, $cf4b
	ld bc, $b
	call CopyData
	ld a, [$cd3e]
	ld [$d11e], a
	jp GetMonName

Func_4120b: ; 4120b (10:520b)
	ld a, $d0
	ld [rOBP1], a ; $ff49
	ld b, BANK(Func_7176c)
	ld hl, Func_7176c
	jp Bankswitch

Func_41217: ; 41217 (10:5217)
	ld hl, W_PLAYERNAME
	ld de, wHPBarMaxHP
	ld bc, $000b
	call CopyData
	ld hl, W_GRASSRATE
	ld de, W_PLAYERNAME
	ld bc, $000b
	call CopyData
	ld hl, wHPBarMaxHP
	ld de, W_GRASSRATE
	ld bc, $000b
	jp CopyData

Func_4123b: ; 4123b (10:523b)
	xor a
	call LoadGBPal
	ld hl, $d730
	res 6, [hl]
	ret

Func_41245: ; 41245 (10:5245)
	ld a, $ab
	ld [rLCDC], a ; $ff40
	ld a, $50
	ld [$ffb0], a
	ld a, $86
	ld [rWX], a ; $ff4b
	ld [$ffae], a
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	FuncCoord 4, 0 ; $c3a4
	ld hl, Coord
	ld b, $6
	ld c, $a
	call TextBoxBorder
	call Func_42769
	ld b, $98
	call CopyScreenTileBufferToVRAM
	call ClearScreen
	ld a, [wWhichTrade] ; $cd3d
	call Func_415a4
	ld a, $7e
.asm_41273
	push af
	call DelayFrame
	pop af
	ld [rWX], a ; $ff4b
	ld [$ffae], a
	dec a
	dec a
	and a
	jr nz, .asm_41273
	call Delay50
	ld a, $ad
	call Func_41676
	ld a, $aa
	call Func_41676
	ld a, [wWhichTrade] ; $cd3d
	call PlayCry
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ret

Func_41298: ; 41298 (10:5298)
	call Func_41196
	ld b, $98
	call CopyScreenTileBufferToVRAM
	ld b, $8
	call GoPAL_SET
	ld hl, $9c8c
	call Func_414ae
	ld a, $a0
	ld [$ffae], a
	call DelayFrame
	ld a, $8b
	ld [rLCDC], a ; $ff40
	FuncCoord 6, 2 ; $c3ce
	ld hl, Coord
	ld b, $7
	call Func_41842
	call Func_41186
	ld a, (SFX_02_3d - SFX_Headers_02) / 3
	call PlaySound
	ld c, $14
.asm_412c8
	ld a, [$ffae]
	add $4
	ld [$ffae], a
	dec c
	jr nz, .asm_412c8
	ret

Func_412d2: ; 412d2 (10:52d2)
	ld a, $ab
	call Func_41676
	ld c, $a
	call DelayFrames
	ld a, $e4
	ld [rOBP0], a ; $ff48
	xor a
	ld [$d09f], a
	ld bc, $2060
.asm_412e7
	push bc
	xor a
	ld de, UnknownOAM_4132e ; $532e
	call WriteOAMBlock
	ld a, [$d09f]
	xor $1
	ld [$d09f], a
	add $7e
	ld hl, $c302
	ld de, $4
	ld c, e
.asm_41300
	ld [hl], a
	add hl, de
	dec c
	jr nz, .asm_41300
	call Delay3
	pop bc
	ld a, c
	add $4
	ld c, a
	cp $a0
	jr nc, .asm_41318
	ld a, (SFX_02_3c - SFX_Headers_02) / 3
	call PlaySound
	jr .asm_412e7
.asm_41318
	call CleanLCD_OAM
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call ClearScreen
	ld b, $98
	call CopyScreenTileBufferToVRAM
	call Delay3
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ret

UnknownOAM_4132e: ; 4132e (10:532e)
	db $7E,$00,$7E,$20
	db $7E,$40,$7E,$60

Func_41336: ; 41336 (10:5336)
	ld a, $ac
	call Func_41676
	call Func_415c8
	FuncCoord 4, 10 ; $c46c
	ld hl, Coord
	ld b, $6
	ld c, $a
	call TextBoxBorder
	call Func_427a7
	call Func_41186
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, [$cd3e]
	call Func_415a4
	ld a, $ad
	call Func_41676
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, [$cd3e]
	call PlayCry
	call Func_41181
	FuncCoord 4, 10 ; $c46c
	ld hl, Coord
	ld bc, $80c
	call ClearScreenArea
	jp PrintTradeTakeCareText

Func_41376: ; 41376 (10:5376)
	call Func_41411
	ld a, $1
	ld [$d08a], a
	ld a, $e4
	ld [rOBP0], a ; $ff48
	ld a, $54
	ld [W_BASECOORDX], a ; $d081
	ld a, $1c
	ld [W_BASECOORDY], a ; $d082
	ld a, [$cd5e]
	ld [$cd5d], a
	call Func_41505
	call Func_4142d
	call Func_41186
	call Func_4149f
	ld hl, $9c8c
	call Func_414ae
	ld b, $6
	call Func_414c5
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Func_4149f
	ld b, $4
	call Func_414c5
	call Func_4145c
	ld b, $6
	call Func_414c5
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Func_41525
	jp CleanLCD_OAM

Func_413c6: ; 413c6 (10:53c6)
	call Func_41411
	xor a
	ld [$d08a], a
	ld a, $64
	ld [W_BASECOORDX], a ; $d081
	ld a, $44
	ld [W_BASECOORDY], a ; $d082
	ld a, [$cd5f]
	ld [$cd5d], a
	call Func_41505
	call Func_4145c
	call Func_41186
	call Func_4149f
	ld hl, $9c94
	call Func_414ae
	call Func_41525
	ld b, $6
	call Func_414c5
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Func_4149f
	ld b, $4
	call Func_414c5
	call Func_4142d
	ld b, $6
	call Func_414c5
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	jp CleanLCD_OAM

Func_41411: ; 41411 (10:5411)
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call ClearScreen
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Func_4120b
	call DelayFrame
	ld a, $ab
	ld [rLCDC], a ; $ff40
	xor a
	ld [$ffae], a
	ld a, $90
	ld [$ffb0], a
	ret

Func_4142d: ; 4142d (10:542d)
	call Func_41196
	FuncCoord 11, 4 ; $c3fb
	ld hl, Coord
	ld a, $5d
	ld [hli], a
	ld a, $5e
	ld c, $8
.asm_4143a
	ld [hli], a
	dec c
	jr nz, .asm_4143a
	FuncCoord 5, 3 ; $c3e1
	ld hl, Coord
	ld b, $6
	call Func_41842
	FuncCoord 4, 12 ; $c494
	ld hl, Coord
	ld b, $2
	ld c, $7
	call TextBoxBorder
	FuncCoord 5, 14 ; $c4bd
	ld hl, Coord
	ld de, W_PLAYERNAME ; $d158
	call PlaceString
	jp DelayFrame

Func_4145c: ; 4145c (10:545c)
	call Func_41196
	FuncCoord 0, 4 ; $c3f0
	ld hl, Coord
	ld a, $5e
	ld c, $e
.asm_41466
	ld [hli], a
	dec c
	jr nz, .asm_41466
	ld a, $5f
	ld [hl], a
	ld de, $14
	add hl, de
	ld a, $61
	ld [hl], a
	add hl, de
	ld [hl], a
	add hl, de
	ld [hl], a
	add hl, de
	ld [hl], a
	add hl, de
	ld a, $60
	ld [hld], a
	ld a, $5d
	ld [hl], a
	FuncCoord 7, 8 ; $c447
	ld hl, Coord
	ld b, $6
	call Func_41842
	FuncCoord 6, 0 ; $c3a6
	ld hl, Coord
	ld b, $2
	ld c, $7
	call TextBoxBorder
	FuncCoord 7, 2 ; $c3cf
	ld hl, Coord
	ld de, W_GRASSRATE ; $d887
	call PlaceString
	jp DelayFrame

Func_4149f: ; 4149f (10:549f)
	call Func_41196
	FuncCoord 0, 4 ; $c3f0
	ld hl, Coord
	ld a, $5e
	ld c, $14
.asm_414a9
	ld [hli], a
	dec c
	jr nz, .asm_414a9
	ret

Func_414ae: ; 414ae (10:54ae)
	push hl
	FuncCoord 0, 4 ; $c3f0
	ld hl, Coord
	call ScheduleRowRedrawHelper
	pop hl
	ld a, h
	ld [$ffd2], a
	ld a, l
	ld [H_SCREENEDGEREDRAWADDR], a ; $ffd1
	ld a, $2
	ld [H_SCREENEDGEREDRAW], a ; $ffd0
	ld c, $a
	jp DelayFrames

Func_414c5: ; 414c5 (10:54c5)
	ld a, [$d08a]
	ld e, a
	ld d, $8
.asm_414cb
	ld a, e
	dec a
	jr z, .asm_414d5
	ld a, [$ffae]
	sub $2
	jr .asm_414d9
.asm_414d5
	ld a, [$ffae]
	add $2
.asm_414d9
	ld [$ffae], a
	call DelayFrame
	dec d
	jr nz, .asm_414cb
	call Func_414e8
	dec b
	jr nz, Func_414c5
	ret

Func_414e8: ; 414e8 (10:54e8)
	push de
	push bc
	push hl
	ld a, [rBGP] ; $ff47
	xor $3c
	ld [rBGP], a ; $ff47
	ld hl, $c302
	ld de, $4
	ld c, $14
.asm_414f9
	ld a, [hl]
	xor $40
	ld [hl], a
	add hl, de
	dec c
	jr nz, .asm_414f9
	pop hl
	pop bc
	pop de
	ret

Func_41505: ; 41505 (10:5505)
	callba Func_71882
	call Func_41558

Func_41510: ; 41510 (10:5510)
	ld hl, wOAMBuffer
	ld c, $14
.asm_41515
	ld a, [W_BASECOORDY] ; $d082
	add [hl]
	ld [hli], a
	ld a, [W_BASECOORDX] ; $d081
	add [hl]
	ld [hli], a
	inc hl
	inc hl
	dec c
	jr nz, .asm_41515
	ret

Func_41525: ; 41525 (10:5525)
	ld a, [$d08a]
	and a
	jr z, .asm_41536
	ld bc, $400
	call .asm_4153f
	ld bc, $a
	jr .asm_4153f
.asm_41536
	ld bc, $f6
	call .asm_4153f
	ld bc, $fc00
.asm_4153f
	ld a, b
	ld [W_BASECOORDX], a ; $d081
	ld a, c
	ld [W_BASECOORDY], a ; $d082
	ld d, $4
.asm_41549
	call Func_41510
	call Func_414e8
	ld c, $8
	call DelayFrames
	dec d
	jr nz, .asm_41549
	ret

Func_41558: ; 41558 (10:5558)
	ld hl, OAMPointers_41574 ; $5574
	ld c, $4
	xor a
.asm_4155e
	push bc
	ld e, [hl]
	inc hl
	ld d, [hl]
	inc hl
	ld c, [hl]
	inc hl
	ld b, [hl]
	inc hl
	push hl
	inc a
	push af
	call WriteOAMBlock
	pop af
	pop hl
	pop bc
	dec c
	jr nz, .asm_4155e
	ret

OAMPointers_41574: ; 41574 (10:5574)
	dw UnknownOAM_41584
	db $08,$08
	dw UnknownOAM_4158c
	db $18,$08
	dw UnknownOAM_41594
	db $08,$18
	dw UnknownOAM_4159c
	db $18,$18

UnknownOAM_41584: ; 41584 (10:5584)
	db $38,$10,$39,$10
	db $3A,$10,$3B,$10

UnknownOAM_4158c: ; 4158c (10:558c)
	db $39,$30,$38,$30
	db $3B,$30,$3A,$30

UnknownOAM_41594: ; 41594 (10:5594)
	db $3A,$50,$3B,$50
	db $38,$50,$39,$50

UnknownOAM_4159c: ; 4159c (10:559c)
	db $3B,$70,$3A,$70
	db $39,$70,$38,$70

Func_415a4: ; 415a4 (10:55a4)
	ld [$cf91], a
	ld [$d0b5], a
	ld [$cf1d], a
	ld b, $b
	ld c, $0
	call GoPAL_SET
	ld a, [H_AUTOBGTRANSFERENABLED] ; $ffba
	xor $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call GetMonHeader
	FuncCoord 7, 2 ; $c3cf
	ld hl, Coord
	call LoadFlippedFrontSpriteByMonIndex
	ld c, $a
	jp DelayFrames

Func_415c8: ; 415c8 (10:55c8)
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call ClearScreen
	ld a, $e3
	ld [rLCDC], a ; $ff40
	ld a, $7
	ld [rWX], a ; $ff4b
	xor a
	ld [$ffb0], a
	ld a, $90
	ld [$ffae], a
	ret

Func_415df: ; 415df (10:55df)
	ld c, $32
	call DelayFrames
.asm_415e4
	call DelayFrame
	ld a, [rWX] ; $ff4b
	inc a
	inc a
	ld [rWX], a ; $ff4b
	cp $a1
	jr nz, .asm_415e4
	call Func_41196
	ld c, $a
	call DelayFrames
	ld a, $7
	ld [rWX], a ; $ff4b
	ret

PrintTradeWentToText: ; 415fe (10:55fe)
	ld hl, TradeWentToText
	call PrintText
	ld c, $c8
	call DelayFrames
	jp Func_415df

TradeWentToText: ; 4160c (10:560c)
	TX_FAR _TradeWentToText
	db "@"

PrintTradeForSendsText: ; 41611 (10:5611)
	ld hl, TradeForText
	call PrintText
	call Delay50
	ld hl, TradeSendsText
	call PrintText
	jp Delay50

TradeForText: ; 41623 (10:5623)
	TX_FAR _TradeForText
	db "@"

TradeSendsText: ; 41628 (10:5628)
	TX_FAR _TradeSendsText
	db "@"

PrintTradeFarewellText: ; 4162d (10:562d)
	ld hl, TradeWavesFarewellText
	call PrintText
	call Delay50
	ld hl, TradeTransferredText
	call PrintText
	call Delay50
	jp Func_415df

TradeWavesFarewellText: ; 41642 (10:5642)
	TX_FAR _TradeWavesFarewellText
	db "@"

TradeTransferredText: ; 41647 (10:5647)
	TX_FAR _TradeTransferredText
	db "@"

PrintTradeTakeCareText: ; 4164c (10:564c)
	ld hl, TradeTakeCareText
	call PrintText
	jp Delay50

TradeTakeCareText: ; 41655 (10:5655)
	TX_FAR _TradeTakeCareText
	db "@"

PrintTradeWillTradeText: ; 4165a (10:565a)
	ld hl, TradeWillTradeText
	call PrintText
	call Delay50
	ld hl, TradeforText
	call PrintText
	jp Delay50

TradeWillTradeText: ; 4166c (10:566c)
	TX_FAR _TradeWillTradeText
	db "@"

TradeforText: ; 41671 (10:5671)
	TX_FAR _TradeforText
	db "@"

Func_41676: ; 41676 (10:5676)
	ld [W_ANIMATIONID], a ; $d07c
	xor a
	ld [$cc5b], a
	ld a, $8
	jp Predef ; indirect jump to MoveAnimation (78d5e (1e:4d5e))

PlayIntro: ; 41682 (10:5682)
	xor a
	ld [H_CURRENTPRESSEDBUTTONS], a
	inc a
	ld [H_AUTOBGTRANSFERENABLED], a
	call PlayShootingStar
	call PlayIntroScene
	call GBFadeOut2
	xor a
	ld [$ffae], a
	ld [H_AUTOBGTRANSFERENABLED], a
	call CleanLCD_OAM
	call DelayFrame
	ret

PlayIntroScene: ; 4169d (10:569d)
	ld b, $7
	call GoPAL_SET
	ld a, %11100100
	ld [rBGP], a
	ld [rOBP0], a
	ld [rOBP1], a
	xor a
	ld [$ffae], a
	ld b, $3
	call Func_4183f
	ld a, 0
	ld [W_BASECOORDX], a
	ld a, 80
	ld [W_BASECOORDY], a
	ld bc, $606
	call Func_417c7
	ld de, $28ff
	call Func_4180e
	ret c

; hip
	ld a, (SFX_1f_5f - SFX_Headers_1f) / 3
	call PlaySound
	xor a
	ld [$d09f], a
	ld de, IntroNidorinoAnimation1
	call AnimateIntroNidorino
; hop
	ld a, (SFX_1f_60 - SFX_Headers_1f) / 3
	call PlaySound
	ld de, IntroNidorinoAnimation2
	call AnimateIntroNidorino
	ld c, $a
	call CheckForUserInterruption
	ret c

; hip
	ld a, (SFX_1f_5f - SFX_Headers_1f) / 3
	call PlaySound
	ld de, IntroNidorinoAnimation1
	call AnimateIntroNidorino
; hop
	ld a, (SFX_1f_60 - SFX_Headers_1f) / 3
	call PlaySound
	ld de, IntroNidorinoAnimation2
	call AnimateIntroNidorino
	ld c, $1e
	call CheckForUserInterruption
	ret c

; raise
	ld b, $4
	call Func_4183f
	ld a, (SFX_1f_61 - SFX_Headers_1f) / 3
	call PlaySound
	ld de, $401
	call Func_4180e
	ld c, $1e
	call CheckForUserInterruption
	ret c

; slash
	ld b, $5
	call Func_4183f
	ld a, (SFX_1f_62 - SFX_Headers_1f) / 3
	call PlaySound
	ld de, $800
	call Func_4180e
; hip
	ld a, (SFX_1f_5f - SFX_Headers_1f) / 3
	call PlaySound
	ld a, $24
	ld [$d09f], a
	ld de, IntroNidorinoAnimation3
	call AnimateIntroNidorino
	ld c, $1e
	call CheckForUserInterruption
	ret c

	ld de, $401
	call Func_4180e
	ld b, $3
	call Func_4183f
	ld c, $3c
	call CheckForUserInterruption
	ret c

; hip
	ld a, (SFX_1f_5f - SFX_Headers_1f) / 3
	call PlaySound
	xor a
	ld [$d09f], a
	ld de, IntroNidorinoAnimation4 ; $5931
	call AnimateIntroNidorino
; hop
	ld a, (SFX_1f_60 - SFX_Headers_1f) / 3
	call PlaySound
	ld de, IntroNidorinoAnimation5 ; $593c
	call AnimateIntroNidorino
	ld c, $14
	call CheckForUserInterruption
	ret c

	ld a, $24
	ld [$d09f], a
	ld de, IntroNidorinoAnimation6 ; $5947
	call AnimateIntroNidorino
	ld c, $1e
	call CheckForUserInterruption
	ret c

; lunge
	ld a, (SFX_1f_5e - SFX_Headers_1f) / 3
	call PlaySound
	ld a, $48
	ld [$d09f], a
	ld de, IntroNidorinoAnimation7 ; $5950
	jp AnimateIntroNidorino

AnimateIntroNidorino: ; 41793 (10:5793)
	ld a, [de]
	cp $50
	ret z
	ld [W_BASECOORDY], a ; $d082
	inc de
	ld a, [de]
	ld [W_BASECOORDX], a ; $d081
	push de
	ld c, $24
	call Func_417ae
	ld c, 5
	call DelayFrames
	pop de
	inc de
	jr AnimateIntroNidorino

Func_417ae: ; 417ae (10:57ae)
	ld hl, wOAMBuffer
	ld a, [$d09f]
	ld d, a
.asm_417b5
	ld a, [W_BASECOORDY] ; $d082
	add [hl]
	ld [hli], a
	ld a, [W_BASECOORDX] ; $d081
	add [hl]
	ld [hli], a
	ld a, d
	ld [hli], a
	inc hl
	inc d
	dec c
	jr nz, .asm_417b5
	ret

Func_417c7: ; 417c7 (10:57c7)
	ld hl, wOAMBuffer
	ld d, $0
.asm_417cc
	push bc
	ld a, [W_BASECOORDY] ; $d082
	ld e, a
.asm_417d1
	ld a, e
	add $8
	ld e, a
	ld [hli], a
	ld a, [W_BASECOORDX] ; $d081
	ld [hli], a
	ld a, d
	ld [hli], a
	ld a, $80
	ld [hli], a
	inc d
	dec c
	jr nz, .asm_417d1
	ld a, [W_BASECOORDX] ; $d081
	add $8
	ld [W_BASECOORDX], a ; $d081
	pop bc
	dec b
	jr nz, .asm_417cc
	ret

Func_417f0: ; 417f0 (10:57f0)
	ld hl, $9c00
	ld bc, $240
	jr asm_417fe

Func_417f8: ; 417f8 (10:57f8)
	FuncCoord 0, 4 ; $c3f0
	ld hl, Coord
	ld bc, $c8
asm_417fe: ; 417fe (10:57fe)
	ld [hl], $0
	inc hl
	dec bc
	ld a, b
	or c
	jr nz, asm_417fe
	ret

Func_41807: ; 41807 (10:5807)
	ld a, $1
.asm_41809
	ld [hli], a
	dec c
	jr nz, .asm_41809
	ret

Func_4180e: ; 4180e (10:580e)
	ld a, e
	cp $ff
	jr z, .asm_4181d
	cp $1
	jr z, .asm_4182d
	ld a, [$ffae]
	dec a
	dec a
	jr .asm_41831
.asm_4181d
	push de
	ld a, $2
	ld [W_BASECOORDX], a ; $d081
	xor a
	ld [W_BASECOORDY], a ; $d082
	ld c, $24
	call Func_417ae
	pop de
.asm_4182d
	ld a, [$ffae]
	inc a
	inc a
.asm_41831
	ld [$ffae], a
	push de
	ld c, $2
	call CheckForUserInterruption
	pop de
	ret c
	dec d
	jr nz, Func_4180e
	ret

Func_4183f: ; 4183f (10:583f)
	FuncCoord 13, 7 ; $c439
	ld hl, Coord

Func_41842: ; 41842 (10:5842)
	ld c, $0
	ld a, $31
	jp Predef ; indirect jump to Func_79dda

Func_41849: ; 41849 (10:5849)
	ld a, $33
	call Predef ; indirect jump to Func_79869
	ld a, b
	jp PlaySound

LoadIntroGraphics: ; 41852 (10:5852)
	ld hl, FightIntroBackMon ; $5a99
	ld de, $9000
	ld bc, $600
	ld a, BANK(FightIntroBackMon)
	call FarCopyData2
	ld hl, GameFreakIntro ; $5959
	ld de, $9600
	ld bc, $140
	ld a, BANK(GameFreakIntro)
	call FarCopyData2
	ld hl, GameFreakIntro ; $5959
	ld de, $8800
	ld bc, $140
	ld a, BANK(GameFreakIntro)
	call FarCopyData2
	ld hl, FightIntroFrontMon ; $6099
	ld de, $8000
	ld bc, $6c0
	ld a, BANK(FightIntroFrontMon)
	jp FarCopyData2

PlayShootingStar: ; 4188a (10:588a)
	ld b, $c
	call GoPAL_SET
	callba Func_4538
	ld a, $e4
	ld [rBGP], a ; $ff47
	ld c, $b4
	call DelayFrames
	call ClearScreen
	call DisableLCD
	xor a
	ld [W_CUROPPONENT], a ; $d059
	call Func_418e9
	call LoadIntroGraphics
	call EnableLCD
	ld hl, rLCDC ; $ff40
	res 5, [hl]
	set 3, [hl]
	ld c, $40
	call DelayFrames
	callba AnimateShootingStar
	push af
	pop af
	jr c, .asm_418d0
	ld c, $28
	call DelayFrames
.asm_418d0
	ld a, Bank(Func_7d8ea)
	ld [$c0ef], a
	ld [$c0f0], a
	ld a, MUSIC_INTRO_BATTLE
	ld [$c0ee], a
	call PlaySound
	call Func_417f8
	call CleanLCD_OAM
	jp Delay3

Func_418e9: ; 418e9 (10:58e9)
	call Func_417f0
	ld hl, wTileMap
	ld c, $50
	call Func_41807
	FuncCoord 0, 14 ; $c4b8
	ld hl, Coord
	ld c, $50
	call Func_41807
	ld hl, $9c00
	ld c, $80
	call Func_41807
	ld hl, $9dc0
	ld c, $80
	jp Func_41807

Func_4190c: ; 4190c (10:590c)
	ret

IntroNidorinoAnimation0: ; 4190d (10:590d)
	db 0, 0
	db $50

IntroNidorinoAnimation1: ; 41910 (10:5910)
; This is a sequence of pixel movements for part of the Nidorino animation. This
; list describes how Nidorino should hop.
; First byte is y movement, second byte is x movement
	db  0, 0
	db -2, 2
	db -1, 2
	db  1, 2
	db  2, 2
	db $50 ; list terminator

IntroNidorinoAnimation2: ; 4191b (10:591b)
; This is a sequence of pixel movements for part of the Nidorino animation.
; First byte is y movement, second byte is x movement
	db  0,  0
	db -2, -2
	db -1, -2
	db  1, -2
	db  2, -2
	db $50 ; list terminator

IntroNidorinoAnimation3: ; 41926 (10:5926)
; This is a sequence of pixel movements for part of the Nidorino animation.
; First byte is y movement, second byte is x movement
	db   0, 0
	db -12, 6
	db  -8, 6
	db   8, 6
	db  12, 6
	db $50 ; list terminator

IntroNidorinoAnimation4: ; 41931 (10:5931)
; This is a sequence of pixel movements for part of the Nidorino animation.
; First byte is y movement, second byte is x movement
	db  0,  0
	db -8, -4
	db -4, -4
	db  4, -4
	db  8, -4
	db $50 ; list terminator

IntroNidorinoAnimation5: ; 4193c (10:593c)
; This is a sequence of pixel movements for part of the Nidorino animation.
; First byte is y movement, second byte is x movement
	db  0, 0
	db -8, 4
	db -4, 4
	db  4, 4
	db  8, 4
	db $50 ; list terminator

IntroNidorinoAnimation6: ; 41947 (10:5947)
; This is a sequence of pixel movements for part of the Nidorino animation.
; First byte is y movement, second byte is x movement
	db 0, 0
	db 2, 0
	db 2, 0
	db 0, 0
	db $50 ; list terminator

IntroNidorinoAnimation7: ; 41950 (10:5950)
; This is a sequence of pixel movements for part of the Nidorino animation.
; First byte is y movement, second byte is x movement
	db -8, -16
	db -7, -14
	db -6, -12
	db -4, -10
	db $50 ; list terminator

GameFreakIntro: ; 41959 (10:5959)
	INCBIN "gfx/gamefreak_intro.h8.2bpp"
	INCBIN "gfx/gamefreak_logo.2bpp"
	ds $10 ; blank tile

FightIntroBackMon: ; 41a99 (10:5a99)
	INCBIN "gfx/intro_fight.2bpp"

FightIntroFrontMon: ; 42099 (10:6099)

IF _RED
	INCBIN "gfx/red/intro_nido_1.6x6.2bpp"
	INCBIN "gfx/red/intro_nido_2.6x6.2bpp"
	INCBIN "gfx/red/intro_nido_3.6x6.2bpp"
	ds $10 ; blank tile
ENDC
IF _BLUE
	INCBIN "gfx/blue/intro_purin_1.6x6.2bpp"
	INCBIN "gfx/blue/intro_purin_2.6x6.2bpp"
	INCBIN "gfx/blue/intro_purin_3.6x6.2bpp"
	ds $10 ; blank tile
ENDC

; XXX what do these do
Func_42769: ; 42769 (10:6769)
	FuncCoord 5,0
	ld hl,Coord
	ld de,OTString67E5
	call PlaceString
	ld a,[$CD3D]
	ld [$D11E],a
	ld a,$3A
	call Predef
	FuncCoord 9, 0 ; $c3a9
	ld hl,Coord
	ld de,$D11E
	ld bc,$8103
	call PrintNumber
	FuncCoord 5,2
	ld hl,Coord
	ld de,$CF4B
	call PlaceString
	FuncCoord 8,4
	ld hl,Coord
	ld de,$CD41
	call PlaceString
	FuncCoord 8, 6 ; $c420
	ld hl,Coord
	ld de,$CD4C
	ld bc,$8205
	jp PrintNumber

Func_427a7: ; 427a7 (10:67a7)
	FuncCoord 5,10
	ld hl,Coord
	ld de,OTString67E5
	call PlaceString
	ld a,[$CD3E]
	ld [$D11E],a
	ld a,$3A
	call Predef
	FuncCoord 9, 10 ; $c471
	ld hl,Coord
	ld de,$D11E
	ld bc,$8103
	call PrintNumber
	FuncCoord 5,12
	ld hl,Coord
	ld de,$CD6D
	call PlaceString
	FuncCoord 8,14
	ld hl,Coord
	ld de,$CD4E
	call PlaceString
	FuncCoord 8, 16 ; $c4e8
	ld hl,Coord
	ld de,$CD59
	ld bc,$8205
	jp PrintNumber

OTString67E5: ; 427e5 (10:67e5)
	db "──",$74,$F2,$4E
	db $4E
	db "OT/",$4E
	db $73,"№",$F2,"@"

SECTION "bank11",ROMX,BANK[$11]

INCLUDE "data/mapHeaders/lavendertown.asm"

INCLUDE "data/mapObjects/lavendertown.asm"

LavenderTownBlocks: ; 44085 (11:4085)
	INCBIN "maps/lavendertown.blk"

ViridianPokecenterBlocks: ; 440df (11:40df)
	INCBIN "maps/viridianpokecenter.blk"

SafariZoneRestHouse1Blocks: ; 440fb (11:40fb)
SafariZoneRestHouse2Blocks: ; 440fb (11:40fb)
SafariZoneRestHouse3Blocks: ; 440fb (11:40fb)
SafariZoneRestHouse4Blocks: ; 440fb (11:40fb)
	INCBIN "maps/safarizoneresthouse1.blk"

INCLUDE "scripts/lavendertown.asm"

DisplayDexRating: ; 44169 (11:4169)
	ld hl, wPokedexSeen
	ld b, wPokedexSeenEnd - wPokedexSeen
	call CountSetBits
	ld a, [$D11E] ; result of CountSetBits (seen count)
	ld [$FFDB], a
	ld hl, wPokedexOwned
	ld b, wPokedexOwnedEnd - wPokedexOwned
	call CountSetBits
	ld a, [$D11E] ; result of CountSetBits (own count)
	ld [$FFDC], a
	ld hl, DexRatingsTable
.findRating
	ld a, [hli]
	ld b, a
	ld a, [$FFDC] ; number of pokemon owned
	cp b
	jr c, .foundRating
	inc hl
	inc hl
	jr .findRating
.foundRating
	ld a, [hli]
	ld h, [hl]
	ld l, a ; load text pointer into hl
	ld a, [$D747]
	bit 3, a
	res 3, a
	ld [$D747], a
	jr nz, .label3
	push hl
	ld hl, PokedexRatingText_441cc
	call PrintText
	pop hl
	call PrintText
	callba Func_7d13b
	jp WaitForTextScrollButtonPress ; wait for button press
.label3
	ld de, $CC5B
	ld a, [$FFDB]
	ld [de], a
	inc de
	ld a, [$FFDC]
	ld [de], a
	inc de
.label4
	ld a, [hli]
	cp a, $50
	jr z, .label5
	ld [de], a
	inc de
	jr .label4
.label5
	ld [de], a
	ret

PokedexRatingText_441cc: ; 441cc (11:41cc)
	TX_FAR _OaksLabText_441cc
	db "@"

DexRatingsTable: ; 441d1 (11:41d1)
	db 10
	dw PokedexRatingText_44201
	db 20
	dw PokedexRatingText_44206
	db 30
	dw PokedexRatingText_4420b
	db 40
	dw PokedexRatingText_44210
	db 50
	dw PokedexRatingText_44215
	db 60
	dw PokedexRatingText_4421a
	db 70
	dw PokedexRatingText_4421f
	db 80
	dw PokedexRatingText_44224
	db 90
	dw PokedexRatingText_44229
	db 100
	dw PokedexRatingText_4422e
	db 110
	dw PokedexRatingText_44233
	db 120
	dw PokedexRatingText_44238
	db 130
	dw PokedexRatingText_4423d
	db 140
	dw PokedexRatingText_44242
	db 150
	dw PokedexRatingText_44247
	db 152
	dw PokedexRatingText_4424c

PokedexRatingText_44201: ; 44201 (11:4201)
	TX_FAR _OaksLabText_44201
	db "@"

PokedexRatingText_44206: ; 44206 (11:4206)
	TX_FAR _OaksLabText_44206
	db "@"

PokedexRatingText_4420b: ; 4420b (11:420b)
	TX_FAR _OaksLabText_4420b
	db "@"

PokedexRatingText_44210: ; 44210 (11:4210)
	TX_FAR _OaksLabText_44210
	db "@"

PokedexRatingText_44215: ; 44215 (11:4215)
	TX_FAR _OaksLabText_44215
	db "@"

PokedexRatingText_4421a: ; 4421a (11:421a)
	TX_FAR _OaksLabText_4421a
	db "@"

PokedexRatingText_4421f: ; 4421f (11:421f)
	TX_FAR _OaksLabText_4421f
	db "@"

PokedexRatingText_44224: ; 44224 (11:4224)
	TX_FAR _OaksLabText_44224
	db "@"

PokedexRatingText_44229: ; 44229 (11:4229)
	TX_FAR _OaksLabText_44229
	db "@"

PokedexRatingText_4422e: ; 4422e (11:422e)
	TX_FAR _OaksLabText_4422e
	db "@"

PokedexRatingText_44233: ; 44233 (11:4233)
	TX_FAR _OaksLabText_44233
	db "@"

PokedexRatingText_44238: ; 44238 (11:4238)
	TX_FAR _OaksLabText_44238
	db "@"

PokedexRatingText_4423d: ; 4423d (11:423d)
	TX_FAR _OaksLabText_4423d
	db "@"

PokedexRatingText_44242: ; 44242 (11:4242)
	TX_FAR _OaksLabText_44242
	db "@"

PokedexRatingText_44247: ; 44247 (11:4247)
	TX_FAR _OaksLabText_44247
	db "@"

PokedexRatingText_4424c: ; 4424c (11:424c)
	TX_FAR _OaksLabText_4424c
	db "@"

INCLUDE "data/mapHeaders/viridianpokecenter.asm"

INCLUDE "scripts/viridianpokecenter.asm"

INCLUDE "data/mapObjects/viridianpokecenter.asm"

INCLUDE "data/mapHeaders/mansion1.asm"

INCLUDE "scripts/mansion1.asm"

INCLUDE "data/mapObjects/mansion1.asm"

Mansion1Blocks: ; 443fe (11:43fe)
	INCBIN "maps/mansion1.blk"

INCLUDE "data/mapHeaders/rocktunnel1.asm"

INCLUDE "scripts/rocktunnel1.asm"

INCLUDE "data/mapObjects/rocktunnel1.asm"

RockTunnel1Blocks: ; 44675 (11:4675)
	INCBIN "maps/rocktunnel1.blk"

INCLUDE "data/mapHeaders/seafoamislands1.asm"

INCLUDE "scripts/seafoamislands1.asm"

INCLUDE "data/mapObjects/seafoamislands1.asm"

SeafoamIslands1Blocks: ; 4489f (11:489f)
	INCBIN "maps/seafoamislands1.blk"

INCLUDE "data/mapHeaders/ssanne3.asm"

INCLUDE "scripts/ssanne3.asm"

INCLUDE "data/mapObjects/ssanne3.asm"

SSAnne3Blocks: ; 44956 (11:4956)
	INCBIN "maps/ssanne3.blk"

INCLUDE "data/mapHeaders/victoryroad3.asm"

INCLUDE "scripts/victoryroad3.asm"

INCLUDE "data/mapObjects/victoryroad3.asm"

VictoryRoad3Blocks: ; 44b37 (11:4b37)
	INCBIN "maps/victoryroad3.blk"

INCLUDE "data/mapHeaders/rockethideout1.asm"

INCLUDE "scripts/rockethideout1.asm"

INCLUDE "data/mapObjects/rockethideout1.asm"

RocketHideout1Blocks: ; 44d49 (11:4d49)
	INCBIN "maps/rockethideout1.blk"

INCLUDE "data/mapHeaders/rockethideout2.asm"

INCLUDE "scripts/rockethideout2.asm"

INCLUDE "data/mapObjects/rockethideout2.asm"

RocketHideout2Blocks: ; 45147 (11:5147)
	INCBIN "maps/rockethideout2.blk"

INCLUDE "data/mapHeaders/rockethideout3.asm"

INCLUDE "scripts/rockethideout3.asm"

INCLUDE "data/mapObjects/rockethideout3.asm"

RocketHideout3Blocks: ; 4537f (11:537f)
	INCBIN "maps/rockethideout3.blk"

INCLUDE "data/mapHeaders/rockethideout4.asm"

INCLUDE "scripts/rockethideout4.asm"

INCLUDE "data/mapObjects/rockethideout4.asm"

RocketHideout4Blocks: ; 45650 (11:5650)
	INCBIN "maps/rockethideout4.blk"

INCLUDE "data/mapHeaders/rockethideoutelevator.asm"

INCLUDE "scripts/rockethideoutelevator.asm"

INCLUDE "data/mapObjects/rockethideoutelevator.asm"

RocketHideoutElevatorBlocks: ; 457a8 (11:57a8)
	INCBIN "maps/rockethideoutelevator.blk"

INCLUDE "data/mapHeaders/silphcoelevator.asm"

INCLUDE "scripts/silphcoelevator.asm"

INCLUDE "data/mapObjects/silphcoelevator.asm"

SilphCoElevatorBlocks: ; 4585b (11:585b)
	INCBIN "maps/silphcoelevator.blk"

INCLUDE "data/mapHeaders/safarizoneeast.asm"

INCLUDE "scripts/safarizoneeast.asm"

INCLUDE "data/mapObjects/safarizoneeast.asm"

SafariZoneEastBlocks: ; 458dc (11:58dc)
	INCBIN "maps/safarizoneeast.blk"

INCLUDE "data/mapHeaders/safarizonenorth.asm"

INCLUDE "scripts/safarizonenorth.asm"

INCLUDE "data/mapObjects/safarizonenorth.asm"

SafariZoneNorthBlocks: ; 45a3e (11:5a3e)
	INCBIN "maps/safarizonenorth.blk"

INCLUDE "data/mapHeaders/safarizonecenter.asm"

INCLUDE "scripts/safarizonecenter.asm"

INCLUDE "data/mapObjects/safarizonecenter.asm"

SafariZoneCenterBlocks: ; 45c1e (11:5c1e)
	INCBIN "maps/safarizonecenter.blk"

INCLUDE "data/mapHeaders/safarizoneresthouse1.asm"

INCLUDE "scripts/safarizoneresthouse1.asm"

INCLUDE "data/mapObjects/safarizoneresthouse1.asm"

INCLUDE "data/mapHeaders/safarizoneresthouse2.asm"

INCLUDE "scripts/safarizoneresthouse2.asm"

INCLUDE "data/mapObjects/safarizoneresthouse2.asm"

INCLUDE "data/mapHeaders/safarizoneresthouse3.asm"

INCLUDE "scripts/safarizoneresthouse3.asm"

INCLUDE "data/mapObjects/safarizoneresthouse3.asm"

INCLUDE "data/mapHeaders/safarizoneresthouse4.asm"

INCLUDE "scripts/safarizoneresthouse4.asm"

INCLUDE "data/mapObjects/safarizoneresthouse4.asm"

INCLUDE "data/mapHeaders/unknowndungeon2.asm"

INCLUDE "scripts/unknowndungeon2.asm"

INCLUDE "data/mapObjects/unknowndungeon2.asm"

UnknownDungeon2Blocks: ; 45e5d (11:5e5d)
	INCBIN "maps/unknowndungeon2.blk"

INCLUDE "data/mapHeaders/unknowndungeon3.asm"

INCLUDE "scripts/unknowndungeon3.asm"

INCLUDE "data/mapObjects/unknowndungeon3.asm"

UnknownDungeon3Blocks: ; 45f58 (11:5f58)
	INCBIN "maps/unknowndungeon3.blk"

INCLUDE "data/mapHeaders/rocktunnel2.asm"

INCLUDE "scripts/rocktunnel2.asm"

INCLUDE "data/mapObjects/rocktunnel2.asm"

RockTunnel2Blocks: ; 461a1 (11:61a1)
	INCBIN "maps/rocktunnel2.blk"

INCLUDE "data/mapHeaders/seafoamislands2.asm"

INCLUDE "scripts/seafoamislands2.asm"

INCLUDE "data/mapObjects/seafoamislands2.asm"

SeafoamIslands2Blocks: ; 463be (11:63be)
	INCBIN "maps/seafoamislands2.blk"

INCLUDE "data/mapHeaders/seafoamislands3.asm"

INCLUDE "scripts/seafoamislands3.asm"

INCLUDE "data/mapObjects/seafoamislands3.asm"

SeafoamIslands3Blocks: ; 464fa (11:64fa)
	INCBIN "maps/seafoamislands3.blk"

INCLUDE "data/mapHeaders/seafoamislands4.asm"

INCLUDE "scripts/seafoamislands4.asm"

INCLUDE "data/mapObjects/seafoamislands4.asm"

SeafoamIslands4Blocks: ; 46706 (11:6706)
	INCBIN "maps/seafoamislands4.blk"

INCLUDE "data/mapHeaders/seafoamislands5.asm"

INCLUDE "scripts/seafoamislands5.asm"

INCLUDE "data/mapObjects/seafoamislands5.asm"

SeafoamIslands5Blocks: ; 468fa (11:68fa)
	INCBIN "maps/seafoamislands5.blk"

Func_46981: ; 46981 (11:6981)
	xor a
	ld [$d71e], a
	ld a, [$d72d]
	bit 4, a
	ret nz
	call ArePlayerCoordsInArray
	ret nc
	ld a, [wWhichTrade] ; $cd3d
	ld [$d71e], a
	ld hl, $d72d
	set 4, [hl]
	ld hl, $d732
	set 4, [hl]
	ret

Func_469a0: ; 469a0 (11:69a0)
	ld hl, $ffeb
	xor a
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hl], a
	ld de, $0
	ld hl, HiddenObjectMaps ; $6a40
.asm_469ae
	ld a, [hli]
	ld b, a
	cp $ff
	jr z, .asm_469fc
	ld a, [W_CURMAP] ; $d35e
	cp b
	jr z, .asm_469be
	inc de
	inc de
	jr .asm_469ae
.asm_469be
	ld hl, HiddenObjectPointers ; $6a96
	add hl, de
	ld a, [hli]
	ld h, [hl]
	ld l, a
	push hl
	ld hl, wWhichTrade ; $cd3d
	xor a
	ld [hli], a
	ld [hli], a
	ld [hl], a
	pop hl
.asm_469ce
	ld a, [hli]
	cp $ff
	jr z, .asm_469fc
	ld [$cd40], a
	ld b, a
	ld a, [hli]
	ld [$cd41], a
	ld c, a
	call Func_46a01
	ld a, [$ffea]
	and a
	jr z, .asm_469f0
	inc hl
	inc hl
	inc hl
	inc hl
	push hl
	ld hl, $cd3f
	inc [hl]
	pop hl
	jr .asm_469ce
.asm_469f0
	ld a, [hli]
	ld [wWhichTrade], a ; $cd3d
	ld a, [hli]
	ld [$cd3e], a
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ret
.asm_469fc
	ld a, $ff
	ld [$ffee], a
	ret

Func_46a01: ; 46a01 (11:6a01)
	ld a, [$c109]
	cp $4
	jr z, .asm_46a16
	cp $8
	jr z, .asm_46a25
	cp $c
	jr z, .asm_46a2b
	ld a, [W_YCOORD] ; $d361
	inc a
	jr .asm_46a1a
.asm_46a16
	ld a, [W_YCOORD] ; $d361
	dec a
.asm_46a1a
	cp b
	jr nz, .asm_46a3b
	ld a, [W_XCOORD] ; $d362
	cp c
	jr nz, .asm_46a3b
	jr .asm_46a38
.asm_46a25
	ld a, [W_XCOORD] ; $d362
	dec a
	jr .asm_46a2f
.asm_46a2b
	ld a, [W_XCOORD] ; $d362
	inc a
.asm_46a2f
	cp c
	jr nz, .asm_46a3b
	ld a, [W_YCOORD] ; $d361
	cp b
	jr nz, .asm_46a3b
.asm_46a38
	xor a
	jr .asm_46a3d
.asm_46a3b
	ld a, $ff
.asm_46a3d
	ld [$ffea], a
	ret

INCLUDE "data/hidden_objects.asm"

SECTION "bank12",ROMX,BANK[$12]

INCLUDE "data/mapHeaders/route7.asm"

INCLUDE "data/mapObjects/route7.asm"

Route7Blocks: ; 48051 (12:4051)
	INCBIN "maps/route7.blk"

CeladonPokecenterBlocks: ; 480ab (12:40ab)
RockTunnelPokecenterBlocks: ; 480ab (12:40ab)
MtMoonPokecenterBlocks: ; 480ab (12:40ab)
	INCBIN "maps/mtmoonpokecenter.blk"

Route18GateBlocks: ; 480c7 (12:40c7)
Route15GateBlocks: ; 480c7 (12:40c7)
Route11GateBlocks: ; 480c7 (12:40c7)
	INCBIN "maps/route11gate.blk"

Route18GateUpstairsBlocks: ; 480db (12:40db)
Route16GateUpstairsBlocks: ; 480db (12:40db)
Route12GateUpstairsBlocks: ; 480db (12:40db)
Route15GateUpstairsBlocks: ; 480db (12:40db)
Route11GateUpstairsBlocks: ; 480db (12:40db)
	INCBIN "maps/route11gateupstairs.blk"

Func_480eb: ; 480eb (12:40eb)
	call Load16BitRegisters
	ld a, [rBGP] ; $ff47
	or b
	ld [rBGP], a ; $ff47
	ld c, $4
	call DelayFrames
	ld a, [rBGP] ; $ff47
	and $fc
	ld [rBGP], a ; $ff47
	ret

Func_480ff: ; 480ff (12:40ff)
	call Load16BitRegisters
	ld a, $1
	ld [$d0a0], a
	xor a
.asm_48108
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	call Func_48119
	call Func_48119
	dec b
	ld a, b
	jr nz, .asm_48108
	xor a
	ld [$d0a0], a
	ret

Func_48119: ; 48119 (12:4119)
	ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
	xor b
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld [rWY], a ; $ff4a
	ld c, $3
	jp DelayFrames

Func_48125: ; 48125 (12:4125)
	call Load16BitRegisters
	xor a
.asm_48129
	ld [$ff97], a
	call Func_4813f
	ld c, $1
	call DelayFrames
	call Func_4813f
	dec b
	ld a, b
	jr nz, .asm_48129
	ld a, $7
	ld [rWX], a ; $ff4b
	ret

Func_4813f: ; 4813f (12:413f)
	ld a, [$ff97]
	xor b
	ld [$ff97], a
	bit 7, a
	jr z, .asm_48149
	xor a
.asm_48149
	add $7
	ld [rWX], a ; $ff4b
	ld c, $4
	jp DelayFrames

INCLUDE "scripts/route7.asm"

INCLUDE "data/mapHeaders/redshouse1f.asm"

INCLUDE "scripts/redshouse1f.asm"

INCLUDE "data/mapObjects/redshouse1f.asm"

RedsHouse1FBlocks: ; 48209 (12:4209)
	INCBIN "maps/redshouse1f.blk"

INCLUDE "data/mapHeaders/celadonmart3.asm"

INCLUDE "scripts/celadonmart3.asm"

INCLUDE "data/mapObjects/celadonmart3.asm"

CeladonMart3Blocks: ; 48322 (12:4322)
	INCBIN "maps/celadonmart3.blk"

INCLUDE "data/mapHeaders/celadonmart4.asm"

INCLUDE "scripts/celadonmart4.asm"

INCLUDE "data/mapObjects/celadonmart4.asm"

CeladonMart4Blocks: ; 483a1 (12:43a1)
	INCBIN "maps/celadonmart4.blk"

INCLUDE "data/mapHeaders/celadonmartroof.asm"

INCLUDE "scripts/celadonmartroof.asm"

INCLUDE "data/mapObjects/celadonmartroof.asm"

CeladonMartRoofBlocks: ; 485cc (12:45cc)
	INCBIN "maps/celadonmartroof.blk"

INCLUDE "data/mapHeaders/celadonmartelevator.asm"

INCLUDE "scripts/celadonmartelevator.asm"

INCLUDE "data/mapObjects/celadonmartelevator.asm"

CeladonMartElevatorBlocks: ; 48684 (12:4684)
	INCBIN "maps/celadonmartelevator.blk"

INCLUDE "data/mapHeaders/celadonmansion1.asm"

INCLUDE "scripts/celadonmansion1.asm"

INCLUDE "data/mapObjects/celadonmansion1.asm"

CeladonMansion1Blocks: ; 48716 (12:4716)
	INCBIN "maps/celadonmansion1.blk"

INCLUDE "data/mapHeaders/celadonmansion2.asm"

INCLUDE "scripts/celadonmansion2.asm"

INCLUDE "data/mapObjects/celadonmansion2.asm"

CeladonMansion2Blocks: ; 4876c (12:476c)
	INCBIN "maps/celadonmansion2.blk"

INCLUDE "data/mapHeaders/celadonmansion3.asm"

INCLUDE "scripts/celadonmansion3.asm"

INCLUDE "data/mapObjects/celadonmansion3.asm"

CeladonMansion3Blocks: ; 48847 (12:4847)
	INCBIN "maps/celadonmansion3.blk"

INCLUDE "data/mapHeaders/celadonmansion4.asm"

INCLUDE "scripts/celadonmansion4.asm"

INCLUDE "data/mapObjects/celadonmansion4.asm"

CeladonMansion4Blocks: ; 48894 (12:4894)
	INCBIN "maps/celadonmansion4.blk"

INCLUDE "data/mapHeaders/celadonpokecenter.asm"

INCLUDE "scripts/celadonpokecenter.asm"

INCLUDE "data/mapObjects/celadonpokecenter.asm"

INCLUDE "data/mapHeaders/celadongym.asm"

INCLUDE "scripts/celadongym.asm"

INCLUDE "data/mapObjects/celadongym.asm"

CeladonGymBlocks: ; 48b84 (12:4b84)
	INCBIN "maps/celadongym.blk"

INCLUDE "data/mapHeaders/celadongamecorner.asm"

INCLUDE "scripts/celadongamecorner.asm"

INCLUDE "data/mapObjects/celadongamecorner.asm"

CeladonGameCornerBlocks: ; 49003 (12:5003)
	INCBIN "maps/celadongamecorner.blk"

INCLUDE "data/mapHeaders/celadonmart5.asm"

INCLUDE "scripts/celadonmart5.asm"

INCLUDE "data/mapObjects/celadonmart5.asm"

CeladonMart5Blocks: ; 490bc (12:50bc)
	INCBIN "maps/celadonmart5.blk"

INCLUDE "data/mapHeaders/celadonprizeroom.asm"

INCLUDE "scripts/celadonprizeroom.asm"

INCLUDE "data/mapObjects/celadonprizeroom.asm"

CeladonPrizeRoomBlocks: ; 49131 (12:5131)
	INCBIN "maps/celadonprizeroom.blk"

INCLUDE "data/mapHeaders/celadondiner.asm"

INCLUDE "scripts/celadondiner.asm"

INCLUDE "data/mapObjects/celadondiner.asm"

CeladonDinerBlocks: ; 491ee (12:51ee)
	INCBIN "maps/celadondiner.blk"

INCLUDE "data/mapHeaders/celadonhouse.asm"

INCLUDE "scripts/celadonhouse.asm"

INCLUDE "data/mapObjects/celadonhouse.asm"

CeladonHouseBlocks: ; 4924d (12:524d)
	INCBIN "maps/celadonhouse.blk"

INCLUDE "data/mapHeaders/celadonhotel.asm"

INCLUDE "scripts/celadonhotel.asm"

INCLUDE "data/mapObjects/celadonhotel.asm"

CeladonHotelBlocks: ; 492a7 (12:52a7)
	INCBIN "maps/celadonhotel.blk"

INCLUDE "data/mapHeaders/mtmoonpokecenter.asm"

INCLUDE "scripts/mtmoonpokecenter.asm"

INCLUDE "data/mapObjects/mtmoonpokecenter.asm"

INCLUDE "data/mapHeaders/rocktunnelpokecenter.asm"

INCLUDE "scripts/rocktunnelpokecenter.asm"

INCLUDE "data/mapObjects/rocktunnelpokecenter.asm"

INCLUDE "data/mapHeaders/route11gate.asm"

INCLUDE "scripts/route11gate.asm"

INCLUDE "data/mapObjects/route11gate.asm"

INCLUDE "data/mapHeaders/route11gateupstairs.asm"

INCLUDE "scripts/route11gateupstairs.asm"

INCLUDE "data/mapObjects/route11gateupstairs.asm"

INCLUDE "data/mapHeaders/route12gate.asm"

INCLUDE "scripts/route12gate.asm"

INCLUDE "data/mapObjects/route12gate.asm"

Route12GateBlocks: ; 49540 (12:5540)
	INCBIN "maps/route12gate.blk"

INCLUDE "data/mapHeaders/route12gateupstairs.asm"

INCLUDE "scripts/route12gateupstairs.asm"

INCLUDE "data/mapObjects/route12gateupstairs.asm"

INCLUDE "data/mapHeaders/route15gate.asm"

INCLUDE "scripts/route15gate.asm"

INCLUDE "data/mapObjects/route15gate.asm"

INCLUDE "data/mapHeaders/route15gateupstairs.asm"

INCLUDE "scripts/route15gateupstairs.asm"

INCLUDE "data/mapObjects/route15gateupstairs.asm"

INCLUDE "data/mapHeaders/route16gate.asm"

INCLUDE "scripts/route16gate.asm"

INCLUDE "data/mapObjects/route16gate.asm"

Route16GateBlocks: ; 497e3 (12:57e3)
	INCBIN "maps/route16gate.blk"

INCLUDE "data/mapHeaders/route16gateupstairs.asm"

INCLUDE "scripts/route16gateupstairs.asm"

INCLUDE "data/mapObjects/route16gateupstairs.asm"

INCLUDE "data/mapHeaders/route18gate.asm"

INCLUDE "scripts/route18gate.asm"

INCLUDE "data/mapObjects/route18gate.asm"

INCLUDE "data/mapHeaders/route18gateupstairs.asm"

INCLUDE "scripts/route18gateupstairs.asm"

INCLUDE "data/mapObjects/route18gateupstairs.asm"

INCLUDE "data/mapHeaders/mtmoon1.asm"

INCLUDE "scripts/mtmoon1.asm"

INCLUDE "data/mapObjects/mtmoon1.asm"

MtMoon1Blocks: ; 49b97 (12:5b97)
	INCBIN "maps/mtmoon1.blk"

INCLUDE "data/mapHeaders/mtmoon3.asm"

INCLUDE "scripts/mtmoon3.asm"

INCLUDE "data/mapObjects/mtmoon3.asm"

MtMoon3Blocks: ; 4a041 (12:6041)
	INCBIN "maps/mtmoon3.blk"

INCLUDE "data/mapHeaders/safarizonewest.asm"

INCLUDE "scripts/safarizonewest.asm"

INCLUDE "data/mapObjects/safarizonewest.asm"

SafariZoneWestBlocks: ; 4a248 (12:6248)
	INCBIN "maps/safarizonewest.blk"

INCLUDE "data/mapHeaders/safarizonesecrethouse.asm"

INCLUDE "scripts/safarizonesecrethouse.asm"

INCLUDE "data/mapObjects/safarizonesecrethouse.asm"

SafariZoneSecretHouseBlocks: ; 4a37f (12:637f)
	INCBIN "maps/safarizonesecrethouse.blk"

SECTION "bank13",ROMX,BANK[$13]

TrainerPics:

YoungsterPic: ; 4c000 (13:4000)
	INCBIN "pic/trainer/youngster.pic"
BugCatcherPic: ; 4c0c6 (13:40c6)
	INCBIN "pic/trainer/bugcatcher.pic"
LassPic: ; 4c200 (13:4200)
	INCBIN "pic/trainer/lass.pic"
SailorPic: ; 4c2db (13:42db)
	INCBIN "pic/trainer/sailor.pic"
JrTrainerMPic: ; 4c450 (13:4450)
	INCBIN "pic/trainer/jr.trainerm.pic"
JrTrainerFPic: ; 4c588 (13:4588)
	INCBIN "pic/trainer/jr.trainerf.pic"
PokemaniacPic: ; 4c6c9 (13:46c9)
	INCBIN "pic/trainer/pokemaniac.pic"
SuperNerdPic: ; 4c7f1 (13:47f1)
	INCBIN "pic/trainer/supernerd.pic"
HikerPic: ; 4c8e7 (13:48e7)
	INCBIN "pic/trainer/hiker.pic"
BikerPic: ; 4cabe (13:4abe)
	INCBIN "pic/trainer/biker.pic"
BurglarPic: ; 4cc91 (13:4c91)
	INCBIN "pic/trainer/burglar.pic"
EngineerPic: ; 4ce0a (13:4e0a)
	INCBIN "pic/trainer/engineer.pic"
FisherPic: ; 4cf87 (13:4f87)
	INCBIN "pic/trainer/fisher.pic"
SwimmerPic: ; 4d133 (13:5133)
	INCBIN "pic/trainer/swimmer.pic"
CueBallPic: ; 4d24f (13:524f)
	INCBIN "pic/trainer/cueball.pic"
GamblerPic: ; 4d421 (13:5421)
	INCBIN "pic/trainer/gambler.pic"
BeautyPic: ; 4d5df (13:55df)
	INCBIN "pic/trainer/beauty.pic"
PsychicPic: ; 4d728 (13:5728)
	INCBIN "pic/trainer/psychic.pic"
RockerPic: ; 4d843 (13:5843)
	INCBIN "pic/trainer/rocker.pic"
JugglerPic: ; 4d97d (13:597d)
	INCBIN "pic/trainer/juggler.pic"
TamerPic: ; 4db4e (13:5b4e)
	INCBIN "pic/trainer/tamer.pic"
BirdKeeperPic: ; 4dcdb (13:5cdb)
	INCBIN "pic/trainer/birdkeeper.pic"
BlackbeltPic: ; 4de76 (13:5e76)
	INCBIN "pic/trainer/blackbelt.pic"
Rival1Pic: ; 4e049 (13:6049)
	INCBIN "pic/trainer/rival1.pic"
ProfOakPic: ; 4e15f (13:615f)
	INCBIN "pic/trainer/prof.oak.pic"
ChiefPic: ; 4e27d (13:627d)
ScientistPic: ; 4e27d (13:627d)
	INCBIN "pic/trainer/scientist.pic"
GiovanniPic: ; 4e3be (13:63be)
	INCBIN "pic/trainer/giovanni.pic"
RocketPic: ; 4e49f (13:649f)
	INCBIN "pic/trainer/rocket.pic"
CooltrainerMPic: ; 4e635 (13:6635)
	INCBIN "pic/trainer/cooltrainerm.pic"
CooltrainerFPic: ; 4e7be (13:67be)
	INCBIN "pic/trainer/cooltrainerf.pic"
BrunoPic: ; 4e943 (13:6943)
	INCBIN "pic/trainer/bruno.pic"
BrockPic: ; 4eb3e (13:6b3e)
	INCBIN "pic/trainer/brock.pic"
MistyPic: ; 4ec40 (13:6c40)
	INCBIN "pic/trainer/misty.pic"
LtSurgePic: ; 4ed30 (13:6d30)
	INCBIN "pic/trainer/lt.surge.pic"
ErikaPic: ; 4eeb5 (13:6eb5)
	INCBIN "pic/trainer/erika.pic"
KogaPic: ; 4efd6 (13:6fd6)
	INCBIN "pic/trainer/koga.pic"
BlainePic: ; 4f150 (13:7150)
	INCBIN "pic/trainer/blaine.pic"
SabrinaPic: ; 4f252 (13:7252)
	INCBIN "pic/trainer/sabrina.pic"
GentlemanPic: ; 4f3d0 (13:73d0)
	INCBIN "pic/trainer/gentleman.pic"
Rival2Pic: ; 4f4cf (13:74cf)
	INCBIN "pic/trainer/rival2.pic"
Rival3Pic: ; 4f623 (13:7623)
	INCBIN "pic/trainer/rival3.pic"
LoreleiPic: ; 4f779 (13:7779)
	INCBIN "pic/trainer/lorelei.pic"
ChannelerPic: ; 4f8a4 (13:78a4)
	INCBIN "pic/trainer/channeler.pic"
AgathaPic: ; 4fa71 (13:7a71)
	INCBIN "pic/trainer/agatha.pic"
LancePic: ; 4fba2 (13:7ba2)
	INCBIN "pic/trainer/lance.pic"

INCLUDE "data/mapHeaders/battlecenterm.asm"

INCLUDE "scripts/battlecenterm.asm"

INCLUDE "data/mapObjects/battlecenterm.asm"

BattleCenterMBlocks: ; 4fd5d (13:7d5d)
	INCBIN "maps/battlecenterm.blk"

INCLUDE "data/mapHeaders/tradecenterm.asm"

INCLUDE "scripts/tradecenterm.asm"

INCLUDE "data/mapObjects/tradecenterm.asm"

TradeCenterMBlocks: ; 4fd91 (13:7d91)
	INCBIN "maps/tradecenterm.blk"

_GivePokemon: ; 4fda5 (13:7da5)
	call EnableAutoTextBoxDrawing
	xor a
	ld [$ccd3], a
	ld a, [W_NUMINPARTY] ; $d163
	cp $6
	jr c, .asm_4fe01
	ld a, [W_NUMINBOX] ; $da80
	cp $14
	jr nc, .asm_4fdf9
	xor a
	ld [W_ENEMYBATTSTATUS3], a ; $d069
	ld a, [$cf91]
	ld [W_ENEMYMONID], a
	callab Func_3eb01
	call SetPokedexOwnedFlag
	callab Func_e7a4
	ld hl, $cf4b
	ld a, [$d5a0]
	and $7f
	cp $9
	jr c, .asm_4fdec
	sub $9
	ld [hl], $f7
	inc hl
	add $f6
	jr .asm_4fdee
.asm_4fdec
	add $f7
.asm_4fdee
	ld [hli], a
	ld [hl], $50
	ld hl, SetToBoxText
	call PrintText
	scf
	ret
.asm_4fdf9
	ld hl, BoxIsFullText
	call PrintText
	and a
	ret
.asm_4fe01
	call SetPokedexOwnedFlag
	call AddPokemonToParty
	ld a, $1
	ld [$cc3c], a
	ld [$ccd3], a
	scf
	ret

SetPokedexOwnedFlag: ; 4fe11 (13:7e11)
	ld a, [$cf91]
	push af
	ld [$d11e], a
	ld a, $3a
	call Predef ; indirect jump to IndexToPokedex (41010 (10:5010))
	ld a, [$d11e]
	dec a
	ld c, a
	ld hl, wPokedexOwned ; $d2f7
	ld b, $1
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	pop af
	ld [$d11e], a
	call GetMonName
	ld hl, GotMonText
	jp PrintText

GotMonText: ; 4fe39 (13:7e39)
	TX_FAR _GotMonText
	db $0b
	db "@"

SetToBoxText: ; 4fe3f (13:7e3f)
	TX_FAR _SetToBoxText
	db "@"

BoxIsFullText: ; 4fe44 (13:7e44)
	TX_FAR _BoxIsFullText
	db "@"

GetPredefPointer: ; 4fe49 (13:7e49)
; stores hl in $CC4F,$CC50
; stores de in $CC51,$CC52
; stores bc in $CC53,$CC54
; grabs a byte "n" from $CC4E,
;    and gets the nth (3-byte) pointer in PredefPointers
; stores the bank of said pointer in [$D0B7]
; stores the pointer in hl and returns
	; ld $CC4F,hl
	ld a,h
	ld [$CC4F],a
	ld a,l
	ld [$CC50],a

	; ld $CC51,de
	ld hl,$CC51
	ld a,d
	ld [hli],a
	ld a,e
	ld [hli],a

	; ld $CC53,bc
	ld a,b
	ld [hli],a
	ld [hl],c

	ld hl,PredefPointers
	ld de,0

	; de = 3 * [$CC4E]
	ld a,[$CC4E]
	ld e,a
	add a,a
	add a,e
	ld e,a
	jr nc,.next
	inc d

.next
	add hl,de
	ld d,h
	ld e,l

	; get bank of predef routine
	ld a,[de]
	ld [$D0B7],a

	; get pointer
	inc de
	ld a,[de]
	ld l,a
	inc de
	ld a,[de]
	ld h,a

	ret

PredefPointers: ; 4fe79 (13:7e79)
; these are pointers to ASM routines.
; they appear to be used in overworld map scripts.
	dbw BANK(Func_3cd60),Func_3cd60
	dbw BANK(Func_3f0c6),Func_3f0c6
	dbw BANK(Func_3f073),Func_3f073
	dbw BANK(ScaleSpriteByTwo), ScaleSpriteByTwo
	db BANK(LoadMonBackSprite) ; dbw macro gives an error for some reason
	dw LoadMonBackSprite
	dbw BANK(Func_79aba),Func_79aba
	dbw BANK(Func_f132),Func_f132
HealPartyPredef: ; 4fe8e (13:7e8e)
	dbw BANK(HealParty),HealParty
MoveAnimationPredef: ; 4fe91 (13:7e91)
	dbw BANK(MoveAnimation),MoveAnimation; 08 play move animation
	dbw BANK(Func_f71e),Func_f71e
	dbw BANK(Func_f71e),Func_f71e
	dbw BANK(Func_f81d),Func_f81d
	dbw BANK(Func_f836),Func_f836
	dbw BANK(Func_f71e),Func_f71e
	dbw BANK(Func_f71e),Func_f71e
	db BANK(InitializePlayerData)
	dw InitializePlayerData
	dbw BANK(HandleBitArray),HandleBitArray
	db BANK(RemoveMissableObject)
	dw RemoveMissableObject
	db BANK(IsMissableObjectHidden)
	dw IsMissableObjectHidden
	dbw BANK(Func_c69c),Func_c69c
	db BANK(AnyPokemonAliveCheck)
	dw AnyPokemonAliveCheck
	db BANK(AddMissableObject)
	dw AddMissableObject
	db BANK(AddMissableObject)
	dw AddMissableObject
	dbw BANK(Func_ee9e),Func_ee9e
	db BANK(InitializePlayerData)
	dw InitializePlayerData
	dbw BANK(Func_c754),Func_c754
	dbw BANK(Func_3af5b),Func_3af5b
	dbw BANK(LearnMove),LearnMove
	dbw BANK(Func_f8a5),Func_f8a5; 1C, used in Pokémon Tower
	dbw $03,Func_3eb5 ; for these two, the bank number is actually 0
	dbw $03,GiveItem
	dbw BANK(Func_480eb),Func_480eb
	dbw BANK(Func_f8ba),Func_f8ba
	dbw BANK(Func_480ff),Func_480ff
	dbw BANK(Func_f929),Func_f929
	dbw BANK(Func_f9a0),Func_f9a0
	dbw BANK(Func_48125),Func_48125
	dbw BANK(UpdateHPBar),UpdateHPBar
	dbw BANK(Func_f9dc),Func_f9dc
	dbw BANK(Func_5ab0),Func_5ab0
	dbw BANK(Func_3ed02),Func_3ed02
	db BANK(DisplayPokedexMenu_)
	dw DisplayPokedexMenu_
	dbw BANK(Func_3ad1c),Func_3ad1c
	dbw BANK(SaveSAVtoSRAM0),SaveSAVtoSRAM0
	dbw BANK(Func_3ef18),Func_3ef18
	dbw BANK(Func_5a5f),Func_5a5f
	dbw BANK(DrawBadges), DrawBadges
	dbw BANK(Func_410f3),Func_410f3
	dbw BANK(Func_7096d),Func_7096d
	dbw BANK(Func_79dda),Func_79dda
	dbw BANK(PlayIntro),PlayIntro
	dbw BANK(Func_79869),Func_79869
	dbw BANK(Func_70b5d),Func_70b5d
	dbw BANK(Func_c586),Func_c586
	dbw BANK(StatusScreen),StatusScreen ; 37 0x12953
	dbw BANK(StatusScreen2),StatusScreen2 ; 38
	dbw BANK(Func_410e2),Func_410e2
	db BANK(CheckEngagePlayer)
	dw CheckEngagePlayer
	dbw BANK(IndexToPokedex),IndexToPokedex
	dbw BANK(Predef3B),Predef3B; 3B display pic?
	dbw BANK(UsedCut),UsedCut
	dbw BANK(ShowPokedexData),ShowPokedexData
	dbw BANK(WriteMonMoves),WriteMonMoves
	dbw BANK(SaveSAV),SaveSAV
	db BANK(LoadSGBBorderAndPalettes)
	dw LoadSGBBorderAndPalettes
	dbw BANK(Func_f113),Func_f113
	dbw BANK(SetPartyMonTypes),SetPartyMonTypes
	db BANK(TestMonMoveCompatibility)
	dw TestMonMoveCompatibility
	dbw BANK(TMToMove),TMToMove
	dbw BANK(Func_71ddf),Func_71ddf
	db BANK(DisplayStarterMonDex)
	dw DisplayStarterMonDex; 46 load dex screen
	db BANK(_AddPokemonToParty)
	dw _AddPokemonToParty
	dbw BANK(UpdateHPBar),UpdateHPBar
	dbw BANK(Func_3cdec),Func_3cdec
	dbw BANK(LoadTownMap_Nest),LoadTownMap_Nest
	dbw BANK(Func_27d6b),Func_27d6b
	db BANK(PrintEmotionBubble)
	dw PrintEmotionBubble; 4C player exclamation
	dbw BANK(Func_5aaf),Func_5aaf; return immediately
	db BANK(AskForMonNickname)
	dw AskForMonNickname
	dbw BANK(Func_37ca1),Func_37ca1
	dbw BANK(SaveSAVtoSRAM2),SaveSAVtoSRAM2
	dbw BANK(LoadSAVCheckSum2),LoadSAVCheckSum2
	dbw BANK(LoadSAV),LoadSAV
	dbw BANK(SaveSAVtoSRAM1),SaveSAVtoSRAM1
	dbw BANK(Predef54),Predef54 ; 54 initiate trade
	db BANK(HallOfFameComputer)
	dw HallOfFameComputer
	dbw BANK(DisplayDexRating),DisplayDexRating
	db $1E ; uses wrong bank number
	dw _DoFlyOrTeleportAwayGraphics
	db $1E ; uses wrong bank number
	dw Func_70510
	dbw BANK(Func_c5be),Func_c5be
	dbw BANK(Func_c60b),Func_c60b
	db BANK(PrintUsedStrengthText)
	dw PrintUsedStrengthText
	dbw BANK(PickupItem),PickupItem
	dbw BANK(Func_27d98),Func_27d98
	dbw BANK(LoadMovePPs),LoadMovePPs
DrawHPBarPredef: ; 4ff96 (13:7f96)
	dbw BANK(Func_128ef),Func_128ef ; 5F draw HP bar
	dbw BANK(Func_128f6),Func_128f6
	dbw BANK(Func_1c9c6),Func_1c9c6
	dbw BANK(OaksAideScript),OaksAideScript

SECTION "bank14",ROMX,BANK[$14]

INCLUDE "data/mapHeaders/route22.asm"

INCLUDE "data/mapObjects/route22.asm"

Route22Blocks: ; 5003d (14:403d)
	INCBIN "maps/route22.blk"

INCLUDE "data/mapHeaders/route20.asm"

INCLUDE "data/mapObjects/route20.asm"

Route20Blocks: ; 5017d (14:417d)
	INCBIN "maps/route20.blk"

INCLUDE "data/mapHeaders/route23.asm"

INCLUDE "data/mapObjects/route23.asm"

Route23Blocks: ; 503b2 (14:43b2)
	INCBIN "maps/route23.blk"

INCLUDE "data/mapHeaders/route24.asm"

INCLUDE "data/mapObjects/route24.asm"

Route24Blocks: ; 506e7 (14:46e7)
	INCBIN "maps/route24.blk"

INCLUDE "data/mapHeaders/route25.asm"

INCLUDE "data/mapObjects/route25.asm"

Route25Blocks: ; 50810 (14:4810)
	INCBIN "maps/route25.blk"

INCLUDE "data/mapHeaders/indigoplateau.asm"

INCLUDE "scripts/indigoplateau.asm"

INCLUDE "data/mapObjects/indigoplateau.asm"

IndigoPlateauBlocks: ; 5094a (14:494a)
	INCBIN "maps/indigoplateau.blk"

INCLUDE "data/mapHeaders/saffroncity.asm"

INCLUDE "data/mapObjects/saffroncity.asm"

SaffronCityBlocks: ; 50a98 (14:4a98)
	INCBIN "maps/saffroncity.blk"

INCLUDE "scripts/saffroncity.asm"

INCLUDE "scripts/route20.asm"

INCLUDE "scripts/route22.asm"

INCLUDE "scripts/route23.asm"

INCLUDE "scripts/route24.asm"

INCLUDE "scripts/route25.asm"

INCLUDE "data/mapHeaders/victoryroad2.asm"

INCLUDE "scripts/victoryroad2.asm"

INCLUDE "data/mapObjects/victoryroad2.asm"

VictoryRoad2Blocks: ; 519af (14:59af)
	INCBIN "maps/victoryroad2.blk"

INCLUDE "data/mapHeaders/mtmoon2.asm"

INCLUDE "scripts/mtmoon2.asm"

INCLUDE "data/mapObjects/mtmoon2.asm"

MtMoon2Blocks: ; 51a91 (14:5a91)
	INCBIN "maps/mtmoon2.blk"

INCLUDE "data/mapHeaders/silphco7.asm"

INCLUDE "scripts/silphco7.asm"

INCLUDE "data/mapObjects/silphco7.asm"

SilphCo7Blocks: ; 51f57 (14:5f57)
	INCBIN "maps/silphco7.blk"

INCLUDE "data/mapHeaders/mansion2.asm"

INCLUDE "scripts/mansion2.asm"

INCLUDE "data/mapObjects/mansion2.asm"

Mansion2Blocks: ; 52110 (14:6110)
	INCBIN "maps/mansion2.blk"

INCLUDE "data/mapHeaders/mansion3.asm"

INCLUDE "scripts/mansion3.asm"

INCLUDE "data/mapObjects/mansion3.asm"

Mansion3Blocks: ; 52326 (14:6326)
	INCBIN "maps/mansion3.blk"

INCLUDE "data/mapHeaders/mansion4.asm"

INCLUDE "scripts/mansion4.asm"

INCLUDE "data/mapObjects/mansion4.asm"

Mansion4Blocks: ; 524dd (14:64dd)
	INCBIN "maps/mansion4.blk"

Func_525af: ; 525af (14:65af)
	ld a, [$ffd7]
	ld [$d0d4], a
	xor a
	ld [$cd6a], a
	ld [$cf0b], a
	ld hl, $cc2b
	ld [hli], a
	ld [hli], a
	ld [hli], a
	ld [hl], a
	ld [wListScrollOffset], a ; $cc36
	ld [$d05e], a
	ld [W_PLAYERMONID], a
	ld [W_PLAYERMONSALIVEFLAGS], a
	ld [wPlayerMonNumber], a ; $cc2f
	ld [$d078], a
	ld [$d35d], a
	ld hl, $cf1d
	ld [hli], a
	ld [hl], a
	ld hl, $ccd3
	ld b, $3c
.asm_525e1
	ld [hli], a
	dec b
	jr nz, .asm_525e1
	inc a
	ld [$ccd9], a
	ld a, [W_CURMAP] ; $d35e
	cp SAFARI_ZONE_EAST
	jr c, .asm_525f9
	cp SAFARI_ZONE_REST_HOUSE_1
	jr nc, .asm_525f9
	ld a, $2
	ld [W_BATTLETYPE], a ; $d05a
.asm_525f9
	ld hl, PlayBattleMusic
	ld b, BANK(PlayBattleMusic)
	jp Bankswitch

ParalyzeEffect_: ; 52601 (14:6601)
	ld hl, W_ENEMYMONSTATUS ; $cfe9
	ld de, W_PLAYERMOVETYPE ; $cfd5
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jp z, .asm_52613
	ld hl, W_PLAYERMONSTATUS ; $d018
	ld de, W_ENEMYMOVETYPE ; $cfcf

.asm_52613
	ld a, [hl]
	and a
	jr nz, .asm_52659
	ld a, [de]
	cp EVASION_DOWN1_EFFECT
	jr nz, .asm_5262a
	ld b, h
	ld c, l
	inc bc
	ld a, [bc]
	cp $4
	jr z, .asm_52666
	inc bc
	ld a, [bc]
	cp $4
	jr z, .asm_52666
.asm_5262a
	push hl
	callab MoveHitTest
	pop hl
	ld a, [W_MOVEMISSED] ; $d05f
	and a
	jr nz, .asm_52659
	set 6, [hl]
	callab Func_3ed27
	ld c, $1e
	call DelayFrames
	callab Func_3fba8
	ld hl, PrintMayNotAttackText
	ld b, BANK(PrintMayNotAttackText)
	jp Bankswitch
.asm_52659
	ld c, $32
	call DelayFrames
	ld hl, PrintDidntAffectText
	ld b, BANK(PrintDidntAffectText)
	jp Bankswitch
.asm_52666
	ld c, $32
	call DelayFrames
	ld hl, PrintDoesntAffectText
	ld b, BANK(PrintDoesntAffectText)
	jp Bankswitch

PrintCardKeyText: ; 52673 (14:6673)
	ld hl, SilphCoMapList
	ld a, [W_CURMAP]
	ld b, a
.asm_5267a
	ld a, [hli]
	cp $ff
	ret z
	cp b
	jr nz, .asm_5267a
	ld a, $35
	call Predef ; indirect jump to Func_c586 (c586 (3:4586))
	ld a, [$cfc6]
	cp $18
	jr z, .asm_5269c
	cp $24
	jr z, .asm_5269c
	ld b, a
	ld a, [W_CURMAP]
	cp SILPH_CO_11F
	ret nz
	ld a, b
	cp $5e
	ret nz
.asm_5269c
	ld b, CARD_KEY
	call IsItemInBag
	jr z, .asm_526dc
	call Func_526fd
	push de
	ld a, $1
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call PrintPredefTextID
	pop de
	srl d
	ld a, d
	ld b, a
	ld [$d73f], a
	srl e
	ld a, e
	ld c, a
	ld [$d740], a
	ld a, [W_CURMAP] ; $d35e
	cp SILPH_CO_11F
	jr nz, .asm_526c8
	ld a, $3
	jr .asm_526ca
.asm_526c8
	ld a, $e
.asm_526ca
	ld [$d09f], a
	ld a, $17
	call Predef ; indirect jump to Func_ee9e
	ld hl, $d126
	set 5, [hl]
	ld a, (SFX_1f_57 - SFX_Headers_1f) / 3
	jp PlaySound
.asm_526dc
	ld a, $2
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	jp PrintPredefTextID

SilphCoMapList: ; 526e3 (14:66e3)
	db SILPH_CO_2F
	db SILPH_CO_3F
	db SILPH_CO_4F
	db SILPH_CO_5F
	db SILPH_CO_6F
	db SILPH_CO_7F
	db SILPH_CO_8F
	db SILPH_CO_9F
	db SILPH_CO_10F
	db SILPH_CO_11F
	db $FF

CardKeySuccessText: ; 526ee (14:66ee)
	TX_FAR _CardKeySuccessText1
	db $0b
	TX_FAR _CardKeySuccessText2
	db "@"

CardKeyFailText: ; 526f8 (14:66f8)
	TX_FAR _CardKeyFailText
	db "@"

Func_526fd: ; 526fd (14:66fd)
	ld a, [W_YCOORD] ; $d361
	ld d, a
	ld a, [W_XCOORD] ; $d362
	ld e, a
	ld a, [$c109]
	and a
	jr nz, .asm_5270d
	inc d
	ret
.asm_5270d
	cp $4
	jr nz, .asm_52713
	dec d
	ret
.asm_52713
	cp $8
	jr nz, .asm_52719
	dec e
	ret
.asm_52719
	inc e
	ret

CeladonPrizeMenu: ; 5271b (14:671b)
	ld b,COIN_CASE
	call IsItemInBag
	jr nz,.havingCoinCase
	ld hl,RequireCoinCaseTextPtr
	jp PrintText
.havingCoinCase
	ld hl,$D730
	set 6,[hl]
	ld hl,ExchangeCoinsForPrizesTextPtr
	call PrintText
; the following are the menu settings
	xor a
	ld [$CC26],a
	ld [$CC2A],a
	ld a,$03
	ld [$CC29],a
	ld a,$03
	ld [$CC28],a
	ld a,$04
	ld [$CC24],a
	ld a,$01
	ld [$CC25],a
	call PrintPrizePrice ; 687A
	FuncCoord 0,2
	ld hl,Coord
	ld b,$08
	ld c,$10
	call TextBoxBorder
	call GetPrizeMenuId ;678E
	call UpdateSprites
	ld hl,WhichPrizeTextPtr
	call PrintText
	call HandleMenuInput ; menu choice handler
	bit 1,a ; keypress = B (Cancel)
	jr nz,.NoChoice
	ld a,[$CC26]
	cp a,$03 ; "NO,THANKS" choice
	jr z,.NoChoice
	call HandlePrizeChoice ; 14:68C6
.NoChoice
	ld hl,$D730
	res 6,[hl]
	ret

RequireCoinCaseTextPtr: ; 5277e (14:677e)
	TX_FAR _RequireCoinCaseText
	db $0D
	db "@"

ExchangeCoinsForPrizesTextPtr: ; 52784 (14:6784)
	TX_FAR _ExchangeCoinsForPrizesText
	db "@"

WhichPrizeTextPtr: ; 52789 (14:6789)
	TX_FAR _WhichPrizeText
	db "@"

GetPrizeMenuId: ; 5278e (14:678e)
; determine which one among the three
; prize-texts has been selected
; using the text ID (stored in [$FF8C])
; load the three prizes at $D13D-$D13F
; load the three prices at $D141-$D146
; display the three prizes' names
; (distinguishing between Pokemon names
; and Items (specifically TMs) names)
	ld a,[$FF8C]
	sub a,$03       ; prize-texts' id are 3, 4 and 5
	ld [$D12F],a    ; prize-texts' id (relative, i.e. 0, 1 or 2)
	add a
	add a
	ld d,$00
	ld e,a
	ld hl,PrizeDifferentMenuPtrs
	add hl,de
	ld a,[hli]
	ld d,[hl]
	ld e,a
	inc hl
	push hl
	ld hl,W_PRIZE1
	call CopyString      ; XXX what does this do
	pop hl
	ld a,[hli]
	ld h,[hl]
	ld l,a
	ld de,$D141
	ld bc,$0006
	call CopyData
	ld a,[$D12F]
	cp a,$02        ;is TM_menu?
	jr nz,.putMonName
	ld a,[W_PRIZE1]
	ld [$D11E],a
	call GetItemName
	FuncCoord 2,4
	ld hl,Coord
	call PlaceString
	ld a,[W_PRIZE2]
	ld [$D11E],a
	call GetItemName
	FuncCoord 2,6
	ld hl,Coord
	call PlaceString
	ld a,[W_PRIZE3]
	ld [$D11E],a
	call GetItemName
	FuncCoord 2,8
	ld hl,Coord
	call PlaceString
	jr .putNoThanksText
.putMonName ; 14:67EC
	ld a,[W_PRIZE1]
	ld [$D11E],a
	call GetMonName
	FuncCoord 2,4
	ld hl,Coord
	call PlaceString
	ld a,[W_PRIZE2]
	ld [$D11E],a
	call GetMonName
	FuncCoord 2,6
	ld hl,Coord
	call PlaceString
	ld a,[W_PRIZE3]
	ld [$D11E],a
	call GetMonName
	FuncCoord 2,8
	ld hl,Coord
	call PlaceString
.putNoThanksText ; 14:6819
	FuncCoord 2,10
	ld hl,Coord
	ld de,NoThanksText
	call PlaceString
; put prices on the right side of the textbox
	ld de,$D141
	FuncCoord 13,5
	ld hl,Coord
; reg. c:
; [low nybble] number of bytes
; [bit 765 = %100] space-padding (not zero-padding)
	ld c,(1 << 7 | 2)
; Function $15CD displays BCD value (same routine
; used by text-command $02)
	call PrintBCDNumber ; Print_BCD
	ld de,$D143
	FuncCoord 13,7
	ld hl,Coord
	ld c,(%1 << 7 | 2)
	call PrintBCDNumber
	ld de,$D145
	FuncCoord 13,9
	ld hl,Coord
	ld c,(1 << 7 | 2)
	jp PrintBCDNumber

INCLUDE "data/prizes.asm"

PrintPrizePrice: ; 5287a (14:687a)
	FuncCoord 11,0
	ld hl,Coord
	ld b,$01
	ld c,$07
	call TextBoxBorder
	call UpdateSprites      ; XXX save OAM?
	FuncCoord 12,0
	ld hl,Coord
	ld de,.CoinText
	call PlaceString
	FuncCoord 13,1
	ld hl,Coord
	ld de,.SixSpacesText
	call PlaceString
	FuncCoord 13,1
	ld hl,Coord
	ld de,wPlayerCoins
	ld c,%10000010
	call PrintBCDNumber
	ret

.CoinText ; 14:68A5
	db "COIN@"

.SixSpacesText ; 14:68AA
	db "      @"

LoadCoinsToSubtract: ; 528b1 (14:68b1)
	ld a,[$D139] ; backup of selected menu_entry
	add a
	ld d,$00
	ld e,a
	ld hl,$D141 ; first prize's price
	add hl,de ; get selected prize's price
	xor a
	ld [$FF9F],a
	ld a,[hli]
	ld [$FFA0],a
	ld a,[hl]
	ld [$FFA1],a
	ret

HandlePrizeChoice: ; 528c6 (14:68c6)
	ld a,[$CC26] ; selected menu_entry
	ld [$D139],a
	ld d,$00
	ld e,a
	ld hl,W_PRIZE1
	add hl,de
	ld a,[hl]
	ld [$D11E],a
	ld a,[$D12F]
	cp a,$02 ; is prize a TM?
	jr nz,.GetMonName
	call GetItemName
	jr .GivePrize
.GetMonName ; 14:68E3
	call GetMonName
.GivePrize ; 14:68E6
	ld hl,SoYouWantPrizeTextPtr
	call PrintText
	call YesNoChoice ; yes/no textbox
	ld a,[$CC26] ; yes/no answer (Y=0, N=1)
	and a
	jr nz,.PrintOhFineThen
	call LoadCoinsToSubtract
	call HasEnoughCoins
	jr c,.NotEnoughCoins
	ld a,[$D12F]
	cp a,$02
	jr nz,.GiveMon
	ld a,[$D11E]
	ld b,a
	ld a,1
	ld c,a
	call GiveItem ; GiveItem
	jr nc,.BagFull
	jr .SubtractCoins
.GiveMon ; 14:6912
	ld a,[$D11E]
	ld [$CF91],a
	push af
	call GetPrizeMonLevel ; 14:6977
	ld c,a
	pop af
	ld b,a
	call GivePokemon
	push af
	ld a,[$CCD3] ; XXX is there room?
	and a
	call z,WaitForTextScrollButtonPress
	pop af
	ret nc
.SubtractCoins ; 14:692C
	call LoadCoinsToSubtract
	ld hl,$FFA1
	ld de,wPlayerCoins + 1
	ld c,$02 ; how many bytes
	ld a,$0C
	call Predef ; subtract coins (BCD daa operations)
	jp PrintPrizePrice
.BagFull
	ld hl,PrizeRoomBagIsFullTextPtr
	jp PrintText
.NotEnoughCoins ; 14:6945
	ld hl,SorryNeedMoreCoinsText
	jp PrintText
.PrintOhFineThen ; 14:694B
	ld hl,OhFineThenTextPtr
	jp PrintText

UnknownData52951: ; 52951 (14:6951)
; XXX what's this?
	db $00,$01,$00,$01,$00,$01,$00,$00,$01

HereYouGoTextPtr: ; 5295a (14:695a)
	TX_FAR _HereYouGoText
	db $0D
	db "@"

SoYouWantPrizeTextPtr: ; 52960 (14:6960)
	TX_FAR _SoYouWantPrizeText
	db "@"

SorryNeedMoreCoinsText: ; 52965 (14:6965)
	TX_FAR _SorryNeedMoreCoinsText
	db $0D
	db "@"

PrizeRoomBagIsFullTextPtr: ; 5296b (14:696b)
	TX_FAR _OopsYouDontHaveEnoughRoomText
	db $0D
	db "@"

OhFineThenTextPtr: ; 52971 (14:6971)
	TX_FAR _OhFineThenText
	db $0D ; wait keypress (A/B) without blink
	db "@"

GetPrizeMonLevel: ; 52977 (14:6977)
	ld a,[$CF91]
	ld b,a
	ld hl,PrizeMonLevelDictionary
.loop ; 14:697E
	ld a,[hli]
	cp b
	jr z,.matchFound
	inc hl
	jr .loop
.matchFound ; 14:6985
	ld a,[hl]
	ld [$D127],a
	ret

INCLUDE "data/prize_mon_levels.asm"

Func_52996: ; 52996 (14:6996)
	call EnableAutoTextBoxDrawing
	ld a, $1
	ld [$cc3c], a
	ld a, [wTrainerSpriteOffset]
	jp PrintPredefTextID

TMNotebook: ; 529a4 (14:69a4)
	TX_FAR TMNotebookText
	db $0d
	db "@"

ViridianSchoolNotebook: ; 529aa (14:69aa)
	db $08 ; asm
	ld hl, ViridianSchoolNotebookText1
	call PrintText
	call TurnPageSchoolNotebook
	jr nz, .doneReading
	ld hl, ViridianSchoolNotebookText2
	call PrintText
	call TurnPageSchoolNotebook
	jr nz, .doneReading
	ld hl, ViridianSchoolNotebookText3
	call PrintText
	call TurnPageSchoolNotebook
	jr nz, .doneReading
	ld hl, ViridianSchoolNotebookText4
	call PrintText
	ld hl, ViridianSchoolNotebookText5
	call PrintText
.doneReading
	jp TextScriptEnd

TurnPageSchoolNotebook: ; 529db (14:69db)
	ld hl, TurnPageText
	call PrintText
	call YesNoChoice
	ld a, [wCurrentMenuItem]
	and a
	ret

TurnPageText: ; 529e9 (14:69e9)
	TX_FAR _TurnPageText
	db "@"

ViridianSchoolNotebookText5: ; 529ee (14:69ee)
	TX_FAR _ViridianSchoolNotebookText5
	db $0d
	db "@"

ViridianSchoolNotebookText1: ; 529f4 (14:69f4)
	TX_FAR _ViridianSchoolNotebookText1
	db "@"

ViridianSchoolNotebookText2: ; 529f9 (14:69f9)
	TX_FAR _ViridianSchoolNotebookText2
	db "@"

ViridianSchoolNotebookText3: ; 529fe (14:69fe)
	TX_FAR _ViridianSchoolNotebookText3
	db "@"

ViridianSchoolNotebookText4: ; 52a03 (14:6a03)
	TX_FAR _ViridianSchoolNotebookText4
	db "@"

Func_52a08: ; 52a08 (14:6a08)
	call EnableAutoTextBoxDrawing
	ld a, $37
	jp PrintPredefTextID

UnnamedText_52a10: ; 52a10 (14:6a10)
	TX_FAR _UnnamedText_52a10
	db "@"

Func_52a15: ; 52a15 (14:6a15)
	call EnableAutoTextBoxDrawing
	ld a, $38
	jp PrintPredefTextID

UnnamedText_52a1d: ; 52a1d (14:6a1d)
	TX_FAR _UnnamedText_52a1d
	db "@"

Func_52a22: ; 52a22 (14:6a22)
	call EnableAutoTextBoxDrawing
	ld a, $36
	jp PrintPredefTextID

FightingDojoText: ; 52a2a (14:6a2a)
	TX_FAR _FightingDojoText
	db "@"

Func_52a2f: ; 52a2f (14:6a2f)
	ld a, [$c109]
	cp $4
	ret nz
	call EnableAutoTextBoxDrawing
	ld a, $27
	jp PrintPredefTextID

IndigoPlateauHQText: ; 52a3d (14:6a3d)
	TX_FAR _IndigoPlateauHQText
	db "@"

SECTION "bank15",ROMX,BANK[$15]

INCLUDE "data/mapHeaders/route2.asm"

INCLUDE "data/mapObjects/route2.asm"

Route2Blocks: ; 5407e (15:407e)
	INCBIN "maps/route2.blk"

INCLUDE "data/mapHeaders/route3.asm"

INCLUDE "data/mapObjects/route3.asm"

Route3Blocks: ; 54255 (15:4255)
	INCBIN "maps/route3.blk"

INCLUDE "data/mapHeaders/route4.asm"

INCLUDE "data/mapObjects/route4.asm"

Route4Blocks: ; 543ec (15:43ec)
	INCBIN "maps/route4.blk"

INCLUDE "data/mapHeaders/route5.asm"

INCLUDE "data/mapObjects/route5.asm"

Route5Blocks: ; 545d2 (15:45d2)
	INCBIN "maps/route5.blk"

INCLUDE "data/mapHeaders/route9.asm"

INCLUDE "data/mapObjects/route9.asm"

Route9Blocks: ; 546fe (15:46fe)
	INCBIN "maps/route9.blk"

INCLUDE "data/mapHeaders/route13.asm"

INCLUDE "data/mapObjects/route13.asm"

Route13Blocks: ; 5488b (15:488b)
	INCBIN "maps/route13.blk"

INCLUDE "data/mapHeaders/route14.asm"

INCLUDE "data/mapObjects/route14.asm"

Route14Blocks: ; 54a12 (15:4a12)
	INCBIN "maps/route14.blk"

INCLUDE "data/mapHeaders/route17.asm"

INCLUDE "data/mapObjects/route17.asm"

Route17Blocks: ; 54ba8 (15:4ba8)
	INCBIN "maps/route17.blk"

INCLUDE "data/mapHeaders/route19.asm"

INCLUDE "data/mapObjects/route19.asm"

Route19Blocks: ; 54ef1 (15:4ef1)
	INCBIN "maps/route19.blk"

INCLUDE "data/mapHeaders/route21.asm"

INCLUDE "data/mapObjects/route21.asm"

Route21Blocks: ; 5506d (15:506d)
	INCBIN "maps/route21.blk"

VermilionHouse2Blocks: ; 5522f (15:522f)
Route12HouseBlocks: ; 5522f (15:522f)
DayCareMBlocks: ; 5522f (15:522f)
	INCBIN "maps/daycarem.blk"

FuchsiaHouse3Blocks: ; 5523f (15:523f)
	INCBIN "maps/fuchsiahouse3.blk"

GainExperience: ; 5524f (15:524f)
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	ret z
	call Func_5546c
	ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
	xor a
	ld [wWhichPokemon], a ; $cf92

Func_5525f: ; 5525f (15:525f)
	inc hl
	ld a, [hli]
	or [hl]
	jp z, Func_55436
	push hl
	ld hl, W_PLAYERMONSALIVEFLAGS
	ld a, [wWhichPokemon] ; $cf92
	ld c, a
	ld b, $2
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	ld a, c
	and a
	pop hl
	jp z, Func_55436
	ld de, $10
	add hl, de
	ld d, h
	ld e, l
	ld hl, $d002
	ld c, $5
.asm_55285
	ld a, [hli]
	ld b, a
	ld a, [de]
	add b
	ld [de], a
	jr nc, .asm_5529a
	dec de
	ld a, [de]
	inc a
	jr z, .asm_55295
	ld [de], a
	inc de
	jr .asm_5529a
.asm_55295
	ld a, $ff
	ld [de], a
	inc de
	ld [de], a
.asm_5529a
	dec c
	jr z, .asm_552a1
	inc de
	inc de
	jr .asm_55285
.asm_552a1
	xor a
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld [$ff97], a
	ld a, [$d008]
	ld [$ff98], a
	ld a, [W_ENEMYMONLEVEL] ; $cff3
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	call Multiply
	ld a, $7
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld b, $4
	call Divide
	ld hl, $fff2
	add hl, de
	ld b, [hl]
	inc hl
	ld a, [wPlayerID] ; $d359
	cp b
	jr nz, .asm_552d1
	ld b, [hl]
	ld a, [wPlayerID + 1] ; $d35a
	cp b
	ld a, $0
	jr z, .asm_552d6
.asm_552d1
	call Func_5549f
	ld a, $1
.asm_552d6
	ld [$cf4d], a
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	call nz, Func_5549f
	inc hl
	inc hl
	inc hl
	ld b, [hl]
	ld a, [$ff98]
	ld [$cf4c], a
	add b
	ld [hld], a
	ld b, [hl]
	ld a, [$ff97]
	ld [$cf4b], a
	adc b
	ld [hl], a
	jr nc, .asm_552f8
	dec hl
	inc [hl]
	inc hl
.asm_552f8
	inc hl
	push hl
	ld a, [wWhichPokemon] ; $cf92
	ld c, a
	ld b, $0
	ld hl, W_PARTYMON1 ; $d164
	add hl, bc
	ld a, [hl]
	ld [$d0b5], a
	call GetMonHeader
	ld d, $64
	callab CalcExperience
	ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
	ld b, a
	ld a, [$ff97]
	ld c, a
	ld a, [$ff98]
	ld d, a
	pop hl
	ld a, [hld]
	sub d
	ld a, [hld]
	sbc c
	ld a, [hl]
	sbc b
	jr c, .asm_5532e
	ld a, b
	ld [hli], a
	ld a, c
	ld [hli], a
	ld a, d
	ld [hld], a
	dec hl
.asm_5532e
	push hl
	ld a, [wWhichPokemon] ; $cf92
	ld hl, W_PARTYMON1NAME ; $d2b5
	call GetPartyMonName
	ld hl, GainedText
	call PrintText
	xor a
	ld [$cc49], a
	call LoadMonData
	pop hl
	ld bc, $13
	add hl, bc
	push hl
	callba Func_58f43
	pop hl
	ld a, [hl]
	cp d
	jp z, Func_55436
	ld a, [W_CURENEMYLVL] ; $d127
	push af
	push hl
	ld a, d
	ld [W_CURENEMYLVL], a ; $d127
	ld [hl], a
	ld bc, $ffdf
	add hl, bc
	ld a, [hl]
	ld [$d0b5], a
	ld [$d11e], a
	call GetMonHeader
	ld bc, $23
	add hl, bc
	push hl
	ld a, [hld]
	ld c, a
	ld b, [hl]
	push bc
	ld d, h
	ld e, l
	ld bc, $ffee
	add hl, bc
	ld b, $1
	call CalcStats
	pop bc
	pop hl
	ld a, [hld]
	sub c
	ld c, a
	ld a, [hl]
	sbc b
	ld b, a
	ld de, $ffe0
	add hl, de
	ld a, [hl]
	add c
	ld [hld], a
	ld a, [hl]
	adc b
	ld [hl], a
	ld a, [wPlayerMonNumber] ; $cc2f
	ld b, a
	ld a, [wWhichPokemon] ; $cf92
	cp b
	jr nz, .asm_553f7
	ld de, W_PLAYERMONCURHP ; $d015
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hl]
	ld [de], a
	ld bc, $1f
	add hl, bc
	push hl
	ld de, W_PLAYERMONLEVEL ; $d022
	ld bc, $b
	call CopyData
	pop hl
	ld a, [W_PLAYERBATTSTATUS3] ; $d064
	bit 3, a
	jr nz, .asm_553c8
	ld de, $cd0f
	ld bc, $b
	call CopyData
.asm_553c8
	xor a
	ld [$d11e], a
	callab Func_3ed99
	callab Func_3ed1a
	callab Func_3ee19
	callab Func_3cd60
	callab Func_3ee94
	call SaveScreenTilesToBuffer1
.asm_553f7
	ld hl, GrewLevelText
	call PrintText
	xor a
	ld [$cc49], a
	call LoadMonData
	ld d, $1
	callab PrintStatsBox
	call WaitForTextScrollButtonPress
	call LoadScreenTilesFromBuffer1
	xor a
	ld [$cc49], a
	ld a, [$d0b5]
	ld [$d11e], a
	ld a, $1a
	call Predef ; indirect jump to Func_3af5b (3af5b (e:6f5b))
	ld hl, $ccd3
	ld a, [wWhichPokemon] ; $cf92
	ld c, a
	ld b, $1
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	pop hl
	pop af
	ld [W_CURENEMYLVL], a ; $d127

Func_55436: ; 55436 (15:5436)
	ld a, [W_NUMINPARTY] ; $d163
	ld b, a
	ld a, [wWhichPokemon] ; $cf92
	inc a
	cp b
	jr z, .asm_55450
	ld [wWhichPokemon], a ; $cf92
	ld bc, $2c
	ld hl, W_PARTYMON1_NUM ; $d16b (aliases: W_PARTYMON1DATA)
	call AddNTimes
	jp Func_5525f
.asm_55450
	ld hl, W_PLAYERMONSALIVEFLAGS
	xor a
	ld [hl], a
	ld a, [wPlayerMonNumber] ; $cc2f
	ld c, a
	ld b, $1
	push bc
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	ld hl, $ccf5
	xor a
	ld [hl], a
	pop bc
	ld a, $10
	jp Predef ; indirect jump to HandleBitArray (f666 (3:7666))

Func_5546c: ; 5546c (15:546c)
	ld a, [W_PLAYERMONSALIVEFLAGS]
	ld b, a
	xor a
	ld c, $8
	ld d, $0
.asm_55475
	xor a
	srl b
	adc d
	ld d, a
	dec c
	jr nz, .asm_55475
	cp $2
	ret c
	ld [$d11e], a
	ld hl, $d002
	ld c, $7
.asm_55488
	xor a
	ld [H_DIVIDEND], a ; $ff95 (aliases: H_PRODUCT, H_PASTLEADINGZEROES, H_QUOTIENT)
	ld a, [hl]
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld a, [$d11e]
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	ld b, $2
	call Divide
	ld a, [$ff98]
	ld [hli], a
	dec c
	jr nz, .asm_55488
	ret

Func_5549f: ; 5549f (15:549f)
	ld a, [$ff97]
	ld b, a
	ld a, [$ff98]
	ld c, a
	srl b
	rr c
	add c
	ld [$ff98], a
	ld a, [$ff97]
	adc b
	ld [$ff97], a
	ret

GainedText: ; 554b2 (15:54b2)
	TX_FAR _GainedText
	db $08 ; asm
	ld a, [$cc5b]
	ld hl, WithExpAllText
	and a
	ret nz
	ld hl, ExpPointsText
	ld a, [$cf4d]
	and a
	ret z
	ld hl, BoostedText
	ret

WithExpAllText: ; 554cb (15:54cb)
	TX_FAR _WithExpAllText
	db $08 ; asm
	ld hl, ExpPointsText
	ret

BoostedText: ; 554d4 (15:54d4)
	TX_FAR _BoostedText

ExpPointsText: ; 554d8 (15:54d8)
	TX_FAR _ExpPointsText
	db "@"

GrewLevelText: ; 554dd (15:54dd)
	TX_FAR _GrewLevelText
	db $0b
	db "@"

INCLUDE "scripts/route2.asm"

INCLUDE "scripts/route3.asm"

INCLUDE "scripts/route4.asm"

INCLUDE "scripts/route5.asm"

INCLUDE "scripts/route9.asm"

INCLUDE "scripts/route13.asm"

INCLUDE "scripts/route14.asm"

INCLUDE "scripts/route17.asm"

INCLUDE "scripts/route19.asm"

INCLUDE "scripts/route21.asm"

INCLUDE "data/mapHeaders/vermilionhouse2.asm"

INCLUDE "scripts/vermilionhouse2.asm"

INCLUDE "data/mapObjects/vermilionhouse2.asm"

INCLUDE "data/mapHeaders/celadonmart2.asm"

INCLUDE "scripts/celadonmart2.asm"

INCLUDE "data/mapObjects/celadonmart2.asm"

CeladonMart2Blocks: ; 56148 (15:6148)
	INCBIN "maps/celadonmart2.blk"

INCLUDE "data/mapHeaders/fuchsiahouse3.asm"

INCLUDE "scripts/fuchsiahouse3.asm"

INCLUDE "data/mapObjects/fuchsiahouse3.asm"

INCLUDE "data/mapHeaders/daycarem.asm"

INCLUDE "scripts/daycarem.asm"

INCLUDE "data/mapObjects/daycarem.asm"

INCLUDE "data/mapHeaders/route12house.asm"

INCLUDE "scripts/route12house.asm"

INCLUDE "data/mapObjects/route12house.asm"

INCLUDE "data/mapHeaders/silphco8.asm"

INCLUDE "scripts/silphco8.asm"

INCLUDE "data/mapObjects/silphco8.asm"

SilphCo8Blocks: ; 5666d (15:666d)
	INCBIN "maps/silphco8.blk"

DisplayDiploma: ; 566e2 (15:66e2)
	call SaveScreenTilesToBuffer2
	call GBPalWhiteOutWithDelay3
	call ClearScreen
	xor a
	ld [$cfcb], a
	ld hl, $d730
	set 6, [hl]
	call DisableLCD
	ld hl, CircleTile ; $7d88
	ld de, $9700
	ld bc, $0010
	ld a, BANK(CircleTile)
	call FarCopyData2
	ld hl, wTileMap
	ld bc, $1012
	ld a, $27
	call Predef
	ld hl, DiplomaTextPointersAndCoords ; $6784
	ld c, $5
.asm_56715
	push bc
	ld a, [hli]
	ld e, a
	ld a, [hli]
	ld d, a
	ld a, [hli]
	push hl
	ld h, [hl]
	ld l, a
	call PlaceString
	pop hl
	inc hl
	pop bc
	dec c
	jr nz, .asm_56715 ; 0x56725 $ee
	FuncCoord 10, 4 ; $c3fa
	ld hl, Coord
	ld de, W_PLAYERNAME
	call PlaceString
	callba Func_44dd
	ld hl, $c301
	ld bc, $8028
.asm_5673e
	ld a, [hl]
	add $21
	ld [hli], a
	inc hl
	ld a, b
	ld [hli], a
	inc hl
	dec c
	jr nz, .asm_5673e ; 0x56747 $f5
	call EnableLCD
	callba LoadTrainerInfoTextBoxTiles
	ld b, $8
	call GoPAL_SET
	call Delay3
	call GBPalNormal
	ld a, $90
	ld [$ff48], a
	call WaitForTextScrollButtonPress
	ld hl, $d730
	res 6, [hl]
	call GBPalWhiteOutWithDelay3
	call Func_3dbe
	call Delay3
	jp GBPalNormal

Func_56777: ; 56777 (15:6777)
	ld hl, W_PLAYERNAME
	ld bc, $ff00
.asm_5677d
	ld a, [hli]
	cp $50
	ret z
	dec c
	jr .asm_5677d ; 0x56782 $f9

DiplomaTextPointersAndCoords: ; 56784 (15:6784)
	dw DiplomaText
	dw $c3cd
	dw DiplomaPlayer
	dw $c3f3
	dw DiplomaEmptyText
	dw $c3ff
	dw DiplomaCongrats
	dw $c41a
	dw DiplomaGameFreak
	dw $c4e9

DiplomaText:
	db $70,"Diploma",$70,"@"

DiplomaPlayer:
	db "Player@"

DiplomaEmptyText:
	db "@"

DiplomaCongrats:
	db   "Congrats! This"
	next "diploma certifies"
	next "that you have"
	next "completed your"
	next "#DEX.@"

DiplomaGameFreak:
	db "GAME FREAK@"

Func_567f9: ; 567f9 (15:67f9)
	ld hl, wSpriteStateData1
	ld de, $4
	ld a, [$cf13]
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call Func_56903
	ld a, [hli]
	ld [$ffeb], a
	inc hl
	ld a, [hl]
	ld [$ffec], a
	ld de, $fe
	add hl, de
	ld a, [hli]
	ld [$ffed], a
	ld a, [hl]
	ld [$ffee], a
	ret

Func_56819: ; 56819 (15:6819)
	ld hl, wSpriteStateData1
	ld de, $0004
	ld a, [$cf13]
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call Func_56903
	ld a, [hli]
	ld [$d130], a
	inc hl
	ld a, [hl]
	ld [$d131], a
	ld de, $00fe
	add hl, de
	ld a, [hli]
	ld [$d132], a
	ld a, [hl]
	ld [$d133], a
	ret

Func_5683d: ; 5683d (15:683d)
	ld hl, wSpriteStateData1
	ld de, $4
	ld a, [$cf13]
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call Func_56903
	ld a, [$ffeb]
	ld [hli], a
	inc hl
	ld a, [$ffec]
	ld [hl], a
	ld de, $fe
	add hl, de
	ld a, [$ffed]
	ld [hli], a
	ld a, [$ffee]
	ld [hl], a
	ret

Func_5685d: ; 5685d (15:685d)
	ld hl, wSpriteStateData1
	ld de, $0004
	ld a, [$cf13]
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	call Func_56903
	ld a, [$d130]
	ld [hli], a
	inc hl
	ld a, [$d131]
	ld [hl], a
	ld de, $00fe
	add hl, de
	ld a, [$d132]
	ld [hli], a
	ld a, [$d133]
	ld [hl], a
	ret

TrainerWalkUpToPlayer: ; 56881 (15:6881)
	ld a, [$cf13]
	swap a
	ld [wTrainerSpriteOffset], a ; $cd3d
	call ReadTrainerScreenPosition
	ld a, [wTrainerFacingDirection]
	and a
	jr z, .facingDown
	cp $4
	jr z, .facingUp
	cp $8
	jr z, .facingLeft
	jr .facingRight
.facingDown
	ld a, [wTrainerScreenY]
	ld b, a
	ld a, $3c           ; (fixed) player screen Y pos
	call CalcDifference
	cp $10              ; trainer is right above player
	ret z
	swap a
	dec a
	ld c, a             ; bc = steps yet to go to reach player
	xor a
	ld b, a           ; a = direction to go to
	jr .writeWalkScript
.facingUp
	ld a, [wTrainerScreenY]
	ld b, a
	ld a, $3c           ; (fixed) player screen Y pos
	call CalcDifference
	cp $10              ; trainer is right below player
	ret z
	swap a
	dec a
	ld c, a             ; bc = steps yet to go to reach player
	ld b, $0
	ld a, $40           ; a = direction to go to
	jr .writeWalkScript
.facingRight
	ld a, [wTrainerScreenX]
	ld b, a
	ld a, $40           ; (fixed) player screen X pos
	call CalcDifference
	cp $10              ; trainer is directly left of player
	ret z
	swap a
	dec a
	ld c, a             ; bc = steps yet to go to reach player
	ld b, $0
	ld a, $c0           ; a = direction to go to
	jr .writeWalkScript
.facingLeft
	ld a, [$cd41]
	ld b, a
	ld a, $40           ; (fixed) player screen X pos
	call CalcDifference
	cp $10              ; trainer is directly right of player
	ret z
	swap a
	dec a
	ld c, a             ; bc = steps yet to go to reach player
	ld b, $0
	ld a, $80           ; a = direction to go to
.writeWalkScript
	ld hl, $cc97
	ld de, $cc97
	call FillMemory     ; write the necessary steps to reach player
	ld [hl], $ff        ; write end of list sentinel
	ld a, [$cf13]
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	jp MoveSprite_

Func_56903: ; 56903 (15:6903)
	push de
	add hl, de
	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
	swap a
	ld d, $0
	ld e, a
	add hl, de
	pop de
	ret

; tests if this trainer is in the right position to engage the player and do so if she is.
CheckEngagePlayer: ; 5690f (15:690f)
	push hl
	push de
	ld a, [wTrainerSpriteOffset] ; $cd3d
	add $2
	ld d, $0
	ld e, a
	ld hl, wSpriteStateData1
	add hl, de
	ld a, [hl]             ; c1x2: sprite image index
	sub $ff
	jr nz, .spriteOnScreen ; test if sprite is on screen
	jp .noEngage
.spriteOnScreen
	ld a, [wTrainerSpriteOffset] ; $cd3d
	add $9
	ld d, $0
	ld e, a
	ld hl, wSpriteStateData1
	add hl, de
	ld a, [hl]             ; c1x9: facing direction
	ld [$cd3f], a
	call ReadTrainerScreenPosition
	ld a, [$cd40]          ; sprite screen Y pos
	ld b, a
	ld a, $3c
	cp b
	jr z, .linedUpY
	ld a, [$cd41]          ; sprite screen X pos
	ld b, a
	ld a, $40
	cp b
	jr z, .linedUpX
	xor a
	jp .noEngage
.linedUpY
	ld a, [$cd41]        ; sprite screen X pos
	ld b, a
	ld a, $40            ; (fixed) player X position
	call CalcDifference  ; calc distance
	jr z, .noEngage      ; exact same position as player
	call CheckSpriteCanSeePlayer
	jr c, .engage
	xor a
	jr .noEngage
.linedUpX
	ld a, [$cd40]        ; sprite screen Y pos
	ld b, a
	ld a, $3c            ; (fixed) player Y position
	call CalcDifference  ; calc distance
	jr z, .noEngage      ; exact same position as player
	call CheckSpriteCanSeePlayer
	jr c, .engage
	xor a
	jp .noEngage
.engage
	call CheckPlayerIsInFrontOfSprite
	ld a, [wTrainerSpriteOffset] ; $cd3d
	and a
	jr z, .noEngage
	ld hl, wFlags_0xcd60
	set 0, [hl]
	call EngageMapTrainer
	ld a, $ff
.noEngage: ; 56988 (15:6988)
	ld [wTrainerSpriteOffset], a ; $cd3d
	pop de
	pop hl
	ret

; reads trainer's Y position to $cd40 and X position to $cd41
ReadTrainerScreenPosition: ; 5698e (15:698e)
	ld a, [wTrainerSpriteOffset] ; $cd3d
	add $4
	ld d, $0
	ld e, a
	ld hl, wSpriteStateData1
	add hl, de
	ld a, [hl]
	ld [$cd40], a
	ld a, [wTrainerSpriteOffset] ; $cd3d
	add $6
	ld d, $0
	ld e, a
	ld hl, wSpriteStateData1
	add hl, de
	ld a, [hl]
	ld [$cd41], a
	ret

; checks if the sprite is properly lined up with the player with respect to the direction it's looking. Also checks the distance between player and sprite
; note that this does not necessarily mean the sprite is seeing the player, he could be behind it's back
; a: distance player to sprite
CheckSpriteCanSeePlayer: ; 569af (15:69af)
	ld b, a
	ld a, [wTrainerEngageDistance]  ; sprite line of sight (engage distance)
	cp b
	jr nc, .checkIfLinedUp
	jr .notInLine         ; player too far away
.checkIfLinedUp
	ld a, [$cd3f]         ; sprite facing direction
	cp $0                 ; down
	jr z, .checkXCoord
	cp $4                 ; up
	jr z, .checkXCoord
	cp $8                 ; left
	jr z, .checkYCoord
	cp $c                 ; right
	jr z, .checkYCoord
	jr .notInLine
.checkXCoord
	ld a, [$cd41]         ; sprite screen X position
	ld b, a
	cp $40
	jr z, .inLine
	jr .notInLine
.checkYCoord
	ld a, [$cd40]         ; sprite screen Y position
	ld b, a
	cp $3c
	jr nz, .notInLine
.inLine
	scf
	ret
.notInLine
	and a
	ret

; tests if the player is in front of the sprite (rather than behind it)
CheckPlayerIsInFrontOfSprite: ; 569e3 (15:69e3)
	ld a, [W_CURMAP] ; $d35e
	cp POWER_PLANT
	jp z, .engage       ; XXX not sure why bypass this for power plant (maybe to get voltorb fake items to work?)
	ld a, [wTrainerSpriteOffset] ; $cd3d
	add $4
	ld d, $0
	ld e, a
	ld hl, wSpriteStateData1
	add hl, de
	ld a, [hl]          ; c1x4 (sprite screen Y pos)
	cp $fc
	jr nz, .notOnTopmostTile ; special case if sprite is on topmost tile (Y = $fc (-4)), make it come down a block
	ld a, $c
.notOnTopmostTile
	ld [$cd40], a
	ld a, [wTrainerSpriteOffset] ; $cd3d
	add $6
	ld d, $0
	ld e, a
	ld hl, wSpriteStateData1
	add hl, de
	ld a, [hl]          ; c1x6 (sprite screen X pos)
	ld [$cd41], a
	ld a, [$cd3f]       ; facing direction
	cp $0
	jr nz, .notFacingDown
	ld a, [$cd40]       ; sprite screen Y pos
	cp $3c
	jr c, .engage       ; sprite above player
	jr .noEngage        ; sprite below player
.notFacingDown
	cp $4
	jr nz, .notFacingUp
	ld a, [$cd40]       ; sprite screen Y pos
	cp $3c
	jr nc, .engage      ; sprite below player
	jr .noEngage        ; sprite above player
.notFacingUp
	cp $8
	jr nz, .notFacingLeft
	ld a, [$cd41]       ; sprite screen X pos
	cp $40
	jr nc, .engage      ; sprite right of player
	jr .noEngage        ; sprite left of player
.notFacingLeft
	ld a, [$cd41]       ; sprite screen X pos
	cp $40
	jr nc, .noEngage    ; sprite right of player
.engage
	ld a, $ff
	jr .done
.noEngage
	xor a
.done
	ld [wTrainerSpriteOffset], a ; $cd3d
	ret

SECTION "bank16",ROMX,BANK[$16]

INCLUDE "data/mapHeaders/route6.asm"

INCLUDE "data/mapObjects/route6.asm"

Route6Blocks: ; 58079 (16:4079)
	INCBIN "maps/route6.blk"

INCLUDE "data/mapHeaders/route8.asm"

INCLUDE "data/mapObjects/route8.asm"

Route8Blocks: ; 581c6 (16:41c6)
	INCBIN "maps/route8.blk"

INCLUDE "data/mapHeaders/route10.asm"

INCLUDE "data/mapObjects/route10.asm"

Route10Blocks: ; 58356 (16:4356)
	INCBIN "maps/route10.blk"

INCLUDE "data/mapHeaders/route11.asm"

INCLUDE "data/mapObjects/route11.asm"

Route11Blocks: ; 5855f (16:455f)
	INCBIN "maps/route11.blk"

INCLUDE "data/mapHeaders/route12.asm"

INCLUDE "data/mapObjects/route12.asm"

Route12Blocks: ; 58710 (16:4710)
	INCBIN "maps/route12.blk"

INCLUDE "data/mapHeaders/route15.asm"

INCLUDE "data/mapObjects/route15.asm"

Route15Blocks: ; 589cc (16:49cc)
	INCBIN "maps/route15.blk"

INCLUDE "data/mapHeaders/route16.asm"

INCLUDE "data/mapObjects/route16.asm"

Route16Blocks: ; 58b84 (16:4b84)
	INCBIN "maps/route16.blk"

INCLUDE "data/mapHeaders/route18.asm"

INCLUDE "data/mapObjects/route18.asm"

Route18Blocks: ; 58c9c (16:4c9c)
	INCBIN "maps/route18.blk"

	INCBIN "maps/unusedblocks58d7d.blk"

PrintBeginningBattleText: ; 58d99 (16:4d99)
	ld a, [W_ISINBATTLE] ; $d057
	dec a
	jr nz, .trainerBattle
	ld a, [W_CURMAP] ; $d35e
	cp POKEMONTOWER_3
	jr c, .notPokemonTower
	cp LAVENDER_HOUSE_1
	jr c, .pokemonTower
.notPokemonTower
	ld a, [W_ENEMYMONID]
	call PlayCry
	ld hl, WildMonAppearedText
	ld a, [W_MOVEMISSED] ; $d05f
	and a
	jr z, .notFishing
	ld hl, HookedMonAttackedText
.notFishing
	jr .wildBattle
.trainerBattle
	call .playSFX
	ld c, $14
	call DelayFrames
	ld hl, TrainerWantsToFightText
.wildBattle
	push hl
	callab DrawAllPokeballs
	pop hl
	call PrintText
	jr .done
.pokemonTower
	ld b, SILPH_SCOPE
	call IsItemInBag
	ld a, [W_ENEMYMONID]
	ld [$cf91], a
	cp MAROWAK
	jr z, .isMarowak
	ld a, b
	and a
	jr z, .noSilphScope
	callab Func_3eb01
	jr .notPokemonTower
.noSilphScope
	ld hl, EnemyAppearedText
	call PrintText
	ld hl, GhostCantBeIDdText
	call PrintText
	jr .done
.isMarowak
	ld a, b
	and a
	jr z, .noSilphScope
	ld hl, EnemyAppearedText
	call PrintText
	ld hl, UnveiledGhostText
	call PrintText
	callab Func_3eb01
	callab Func_708ca
	ld hl, WildMonAppearedText
	call PrintText

.playSFX
	xor a
	ld [$c0f1], a
	ld a, $80
	ld [$c0f2], a
	ld a, (SFX_08_77 - SFX_Headers_08) / 3
	call PlaySound
	jp WaitForSoundToFinish
.done
	ret

WildMonAppearedText: ; 58e3b (16:4e3b)
	TX_FAR _WildMonAppearedText
	db "@"

HookedMonAttackedText: ; 58e40 (16:4e40)
	TX_FAR _HookedMonAttackedText
	db "@"

EnemyAppearedText: ; 58e45 (16:4e45)
	TX_FAR _EnemyAppearedText
	db "@"

TrainerWantsToFightText: ; 58e4a (16:4e4a)
	TX_FAR _TrainerWantsToFightText
	db "@"

UnveiledGhostText: ; 58e4f (16:4e4f)
	TX_FAR _UnveiledGhostText
	db "@"

GhostCantBeIDdText: ; 58e54 (16:4e54)
	TX_FAR _GhostCantBeIDdText
	db "@"

SendOutMon: ; 58e59 (16:4e59)
	ld hl, W_ENEMYMONCURHP ; $cfe6
	ld a, [hli]
	or [hl]
	ld hl, GoText
	jr z, .printText
	xor a
	ld [H_NUMTOPRINT], a ; $ff96 (aliases: H_MULTIPLICAND)
	ld hl, W_ENEMYMONCURHP ; $cfe6
	ld a, [hli]
	ld [$cce3], a
	ld [$ff97], a
	ld a, [hl]
	ld [$cce4], a
	ld [$ff98], a
	ld a, $19
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	call Multiply
	ld hl, W_ENEMYMONMAXHP ; $cff4
	ld a, [hli]
	ld b, [hl]
	srl a
	rr b
	srl a
	rr b
	ld a, b
	ld b, $4
	ld [H_REMAINDER], a ; $ff99 (aliases: H_DIVISOR, H_MULTIPLIER, H_POWEROFTEN)
	call Divide
	ld a, [$ff98]
	ld hl, GoText
	cp $46
	jr nc, .printText
	ld hl, DoItText
	cp $28
	jr nc, .printText
	ld hl, GetmText
	cp $a
	jr nc, .printText
	ld hl, EnemysWeakText
.printText
	jp PrintText

GoText: ; 58eae (16:4eae)
	TX_FAR _GoText
	db $08 ; asm
	jr PrintPlayerMon1Text

DoItText: ; 58eb5 (16:4eb5)
	TX_FAR _DoItText
	db $08 ; asm
	jr PrintPlayerMon1Text

GetmText: ; 58ebc (16:4ebc)
	TX_FAR _GetmText
	db $08 ; asm
	jr PrintPlayerMon1Text

EnemysWeakText: ; 58ec3 (16:4ec3)
	TX_FAR _EnemysWeakText
	db $08 ; asm

PrintPlayerMon1Text:
	ld hl, PlayerMon1Text
	ret

PlayerMon1Text: ; 58ecc (16:4ecc)
	TX_FAR _PlayerMon1Text
	db "@"

RetreatMon: ; 58ed1 (16:4ed1)
	ld hl, PlayerMon2Text
	jp PrintText

PlayerMon2Text: ; 58ed7 (16:4ed7)
	TX_FAR _PlayerMon2Text
	db $08 ; asm
	push de
	push bc
	ld hl, $cfe7
	ld de, $cce4
	ld b, [hl]
	dec hl
	ld a, [de]
	sub b
	ld [$ff98], a
	dec de
	ld b, [hl]
	ld a, [de]
	sbc b
	ld [$ff97], a
	ld a, $19
	ld [H_POWEROFTEN], a
	call Multiply
	ld hl, W_ENEMYMONMAXHP
	ld a, [hli]
	ld b, [hl]
	srl a
	rr b
	srl a
	rr b
	ld a, b
	ld b, $4
	ld [H_POWEROFTEN], a
	call Divide
	pop bc
	pop de
	ld a, [$ff98]
	ld hl, EnoughText
	and a
	ret z
	ld hl, ComeBackText
	cp $1e
	ret c
	ld hl, OKExclamationText
	cp $46
	ret c
	ld hl, GoodText
	ret

EnoughText: ; 58f25 (16:4f25)
	TX_FAR _EnoughText
	db $08 ; asm
	jr PrintComeBackText

OKExclamationText: ; 58f2c (16:4f2c)
	TX_FAR _OKExclamationText
	db $08 ; asm
	jr PrintComeBackText

GoodText: ; 58f33 (16:4f33)
	TX_FAR _GoodText
	db $08 ; asm
	jr PrintComeBackText

PrintComeBackText: ; 58f3a (16:4f3a)
	ld hl, ComeBackText
	ret

ComeBackText: ; 58f3e (16:4f3e)
	TX_FAR _ComeBackText
	db "@"

Func_58f43: ; 58f43 (16:4f43)
	ld a, [$cf98]
	ld [$d0b5], a
	call GetMonHeader
	ld d, $1
.asm_58f4e
	inc d
	call CalcExperience
	push hl
	ld hl, $cfa8
	ld a, [$ff98]
	ld c, a
	ld a, [hld]
	sub c
	ld a, [$ff97]
	ld c, a
	ld a, [hld]
	sbc c
	ld a, [H_NUMTOPRINT] ; $ff96 (aliases: H_MULTIPLICAND)
	ld c, a
	ld a, [hl]
	sbc c
	pop hl
	jr nc, .asm_58f4e
	dec d
	ret

; calculates the amount of experience needed for level d
CalcExperience: ; 58f6a (16:4f6a)
	ld a, [W_MONHGROWTHRATE]
	add a
	add a
	ld c, a
	ld b, $0
	ld hl, GrowthRateTable
	add hl, bc
	call CalcDSquared
	ld a, d
	ld [H_MULTIPLIER], a ; $ff99
	call Multiply
	ld a, [hl]
	and $f0
	swap a
	ld [H_MULTIPLIER], a ; $ff99
	call Multiply
	ld a, [hli]
	and $f
	ld [H_DIVISOR], a ; $ff99
	ld b, $4
	call Divide
	ld a, [H_MULTIPLICAND] ; $ff96 (aliases: H_NUMTOPRINT)
	push af
	ld a, [H_MULTIPLICAND+1]
	push af
	ld a, [H_MULTIPLICAND+2]
	push af
	call CalcDSquared
	ld a, [hl]
	and $7f
	ld [H_MULTIPLIER], a ; $ff99
	call Multiply
	ld a, [H_MULTIPLICAND] ; $ff96 (aliases: H_NUMTOPRINT)
	push af
	ld a, [H_MULTIPLICAND+1]
	push af
	ld a, [H_MULTIPLICAND+2]
	push af
	ld a, [hli]
	push af
	xor a
	ld [H_MULTIPLICAND], a ; $ff96
	ld [H_MULTIPLICAND+1], a
	ld a, d
	ld [H_MULTIPLICAND+2], a
	ld a, [hli]
	ld [H_MULTIPLIER], a
	call Multiply
	ld b, [hl]
	ld a, [H_MULTIPLICAND+2]
	sub b
	ld [H_MULTIPLICAND+2], a
	ld b, $0
	ld a, [H_MULTIPLICAND+1]
	sbc b
	ld [H_MULTIPLICAND+1], a
	ld a, [H_MULTIPLICAND] ; $ff96
	sbc b
	ld [H_MULTIPLICAND], a ; $ff96
	pop af
	and $80
	jr nz, .subtractSquaredTerm ; check sign
	pop bc
	ld a, [H_MULTIPLICAND+2]
	add b
	ld [H_MULTIPLICAND+2], a
	pop bc
	ld a, [H_MULTIPLICAND+1]
	adc b
	ld [H_MULTIPLICAND+1], a
	pop bc
	ld a, [H_MULTIPLICAND]
	adc b
	ld [H_MULTIPLICAND], a
	jr .addCubedTerm
.subtractSquaredTerm
	pop bc
	ld a, [H_MULTIPLICAND+2]
	sub b
	ld [H_MULTIPLICAND+2], a
	pop bc
	ld a, [H_MULTIPLICAND+1]
	sbc b
	ld [H_MULTIPLICAND+1], a
	pop bc
	ld a, [H_MULTIPLICAND]
	sbc b
	ld [H_MULTIPLICAND], a
.addCubedTerm
	pop bc
	ld a, [H_MULTIPLICAND+2]
	add b
	ld [H_MULTIPLICAND+2], a
	pop bc
	ld a, [H_MULTIPLICAND+1]
	adc b
	ld [H_MULTIPLICAND+1], a
	pop bc
	ld a, [H_MULTIPLICAND]
	adc b
	ld [H_MULTIPLICAND], a
	ret

; calculates d*d
CalcDSquared: ; 59010 (16:5010)
	xor a
	ld [H_MULTIPLICAND], a ; $ff96 (aliases: H_NUMTOPRINT)
	ld [H_MULTIPLICAND+1], a
	ld a, d
	ld [H_MULTIPLICAND+2], a
	ld [H_MULTIPLIER], a ; $ff99 (aliases: H_DIVISOR, H_REMAINDER, H_POWEROFTEN)
	jp Multiply

; each entry has the following scheme:
; %AAAABBBB %SCCCCCCC %DDDDDDDD %EEEEEEEE
; resulting in
;  (a*n^3)/b + sign*c*n^2 + d*n - e
; where sign = -1 <=> S=1
GrowthRateTable: ; 5901d (16:501d)
	db $11,$00,$00,$00 ; medium fast      n^3
	db $34,$0A,$00,$1E ; (unused?)    3/4 n^3 + 10 n^2         - 30
	db $34,$14,$00,$46 ; (unused?)    3/4 n^3 + 20 n^2         - 70
	db $65,$8F,$64,$8C ; medium slow: 6/5 n^3 - 15 n^2 + 100 n - 140
	db $45,$00,$00,$00 ; fast:        4/5 n^3
	db $54,$00,$00,$00 ; slow:        5/4 n^3

OaksAideScript ; 0x59035
	ld hl, OaksAideHiText
	call PrintText
	call YesNoChoice
	ld a, [$cc26]
	and a
	jr nz, .asm_59086 ; 0x59042 $42
	ld hl, wPokedexOwned
	ld b, wPokedexOwnedEnd - wPokedexOwned
	call CountSetBits
	ld a, [$d11e]
	ld [$ffdd], a
	ld b, a
	ld a, [$ffdb]
	cp b
	jr z, .asm_59059 ; 0x59055 $2
	jr nc, .asm_5907c ; 0x59057 $23
.asm_59059
	ld hl, OaksAideHereYouGoText
	call PrintText
	ld a, [$ffdc]
	ld b, a
	ld c, 1
	call GiveItem
	jr nc, .BagFull
	ld hl, OaksAideGotItemText
	call PrintText
	ld a, $1
	jr .asm_5908e ; 0x59071 $1b
.BagFull
	ld hl, OaksAideNoRoomText
	call PrintText
	xor a
	jr .asm_5908e ; 0x5907a $12
.asm_5907c
	ld hl, OaksAideUhOhText
	call PrintText
	ld a, $80
	jr .asm_5908e ; 0x59084 $8
.asm_59086
	ld hl, OaksAideComeBackText
	call PrintText
	ld a, $ff
.asm_5908e
	ld [$ffdb], a
	ret

OaksAideHiText: ; 59091 (16:5091)
	TX_FAR _OaksAideHiText
	db "@"

OaksAideUhOhText: ; 59096 (16:5096)
	TX_FAR _OaksAideUhOhText
	db "@"

OaksAideComeBackText: ; 5909b (16:509b)
	TX_FAR _OaksAideComeBackText
	db "@"

OaksAideHereYouGoText: ; 590a0 (16:50a0)
	TX_FAR _OaksAideHereYouGoText
	db "@"

OaksAideGotItemText: ; 590a5 (16:50a5)
	TX_FAR _OaksAideGotItemText
	db $0b
	db "@"

OaksAideNoRoomText: ; 590ab (16:50ab)
	TX_FAR _OaksAideNoRoomText
	db "@"

INCLUDE "scripts/route6.asm"

INCLUDE "scripts/route8.asm"

INCLUDE "scripts/route10.asm"

INCLUDE "scripts/route11.asm"

INCLUDE "scripts/route12.asm"

INCLUDE "scripts/route15.asm"

INCLUDE "scripts/route16.asm"

INCLUDE "scripts/route18.asm"

INCLUDE "data/mapHeaders/fanclub.asm"

INCLUDE "scripts/fanclub.asm"

INCLUDE "data/mapObjects/fanclub.asm"

FanClubBlocks: ; 59cd5 (16:5cd5)
	INCBIN "maps/fanclub.blk"

INCLUDE "data/mapHeaders/silphco2.asm"

INCLUDE "scripts/silphco2.asm"

INCLUDE "data/mapObjects/silphco2.asm"

SilphCo2Blocks: ; 59ec8 (16:5ec8)
	INCBIN "maps/silphco2.blk"

INCLUDE "data/mapHeaders/silphco3.asm"

INCLUDE "scripts/silphco3.asm"

INCLUDE "data/mapObjects/silphco3.asm"

SilphCo3Blocks: ; 5a0a6 (16:60a6)
	INCBIN "maps/silphco3.blk"

INCLUDE "data/mapHeaders/silphco10.asm"

INCLUDE "scripts/silphco10.asm"

INCLUDE "data/mapObjects/silphco10.asm"

SilphCo10Blocks: ; 5a25a (16:625a)
	INCBIN "maps/silphco10.blk"

INCLUDE "data/mapHeaders/lance.asm"

INCLUDE "scripts/lance.asm"

INCLUDE "data/mapObjects/lance.asm"

LanceBlocks: ; 5a3e9 (16:63e9)
	INCBIN "maps/lance.blk"

INCLUDE "data/mapHeaders/halloffameroom.asm"

INCLUDE "scripts/halloffameroom.asm"

INCLUDE "data/mapObjects/halloffameroom.asm"

HallofFameRoomBlocks: ; 5a58b (16:658b)
	INCBIN "maps/halloffameroom.blk"

RemoveGuardDrink: ; 5a59f (16:659f)
	ld hl, GuardDrinksList
.drinkLoop
	ld a, [hli]
	ld [$ffdb], a
	and a
	ret z
	push hl
	ld b, a
	call IsItemInBag
	pop hl
	jr z, .drinkLoop
	ld b, BANK(RemoveItemByID)
	ld hl, RemoveItemByID
	jp Bankswitch

GuardDrinksList: ; 5a5b7 (16:65b7)
	db FRESH_WATER, SODA_POP, LEMONADE, $00

SECTION "bank17",ROMX,BANK[$17]

SaffronMartBlocks: ; 5c000 (17:4000)
LavenderMartBlocks: ; 5c000 (17:4000)
CeruleanMartBlocks: ; 5c000 (17:4000)
VermilionMartBlocks: ; 5c000 (17:4000)
	INCBIN "maps/vermilionmart.blk"

CopycatsHouse2FBlocks: ; 5c010 (17:4010)
RedsHouse2FBlocks: ; 0x5c010 16?
	INCBIN "maps/redshouse2f.blk"

Museum1FBlocks: ; 5c020 (17:4020)
	INCBIN "maps/museum1f.blk"

Museum2FBlocks: ; 5c048 (17:4048)
	INCBIN "maps/museum2f.blk"

SaffronPokecenterBlocks: ; 5c064 (17:4064)
VermilionPokecenterBlocks: ; 5c064 (17:4064)
LavenderPokecenterBlocks: ; 5c064 (17:4064)
PewterPokecenterBlocks: ; 5c064 (17:4064)
	INCBIN "maps/pewterpokecenter.blk"

UndergroundPathEntranceRoute7Blocks: ; 5c080 (17:4080)
UndergroundPathEntranceRoute7CopyBlocks: ; 5c080 (17:4080)
UndergroundPathEntranceRoute6Blocks: ; 5c080 (17:4080)
UndergroundPathEntranceRoute5Blocks: ; 5c080 (17:4080)
	INCBIN "maps/undergroundpathentranceroute5.blk"

Route2GateBlocks: ; 5c090 (17:4090)
ViridianForestEntranceBlocks: ; 5c090 (17:4090)
ViridianForestExitBlocks: ; 5c090 (17:4090)
	INCBIN "maps/viridianforestexit.blk"

INCLUDE "data/mapHeaders/redshouse2f.asm"

INCLUDE "scripts/redshouse2f.asm"

INCLUDE "data/mapObjects/redshouse2f.asm"

; this function temporarily makes the starters (and Ivysaur) seen
; so that the full Pokedex information gets displayed in Oak's lab
DisplayStarterMonDex: ; 5c0dc (17:40dc)
	ld a, %01001011 ; set starter flags
	ld [wPokedexOwned], a ; $d2f7
	ld a, $3d
	call Predef ; indirect jump to ShowPokedexData (402d1 (10:42d1))
	xor a ; unset starter flags
	ld [wPokedexOwned], a ; $d2f7
	ret

INCLUDE "data/mapHeaders/museum1f.asm"

INCLUDE "scripts/museum1f.asm"

INCLUDE "data/mapObjects/museum1f.asm"

INCLUDE "data/mapHeaders/museum2f.asm"

INCLUDE "scripts/museum2f.asm"

INCLUDE "data/mapObjects/museum2f.asm"

INCLUDE "data/mapHeaders/pewtergym.asm"

INCLUDE "scripts/pewtergym.asm"

INCLUDE "data/mapObjects/pewtergym.asm"

PewterGymBlocks: ; 5c558 (17:4558)
	INCBIN "maps/pewtergym.blk"

INCLUDE "data/mapHeaders/pewterpokecenter.asm"

INCLUDE "scripts/pewterpokecenter.asm"

INCLUDE "data/mapObjects/pewterpokecenter.asm"

INCLUDE "data/mapHeaders/ceruleanpokecenter.asm"

INCLUDE "scripts/ceruleanpokecenter.asm"

INCLUDE "data/mapObjects/ceruleanpokecenter.asm"

CeruleanPokecenterBlocks: ; 5c68b (17:468b)
	INCBIN "maps/ceruleanpokecenter.blk"

INCLUDE "data/mapHeaders/ceruleangym.asm"

INCLUDE "scripts/ceruleangym.asm"

INCLUDE "data/mapObjects/ceruleangym.asm"

CeruleanGymBlocks: ; 5c866 (17:4866)
	INCBIN "maps/ceruleangym.blk"

INCLUDE "data/mapHeaders/ceruleanmart.asm"

INCLUDE "scripts/ceruleanmart.asm"

INCLUDE "data/mapObjects/ceruleanmart.asm"

INCLUDE "data/mapHeaders/lavenderpokecenter.asm"

INCLUDE "scripts/lavenderpokecenter.asm"

INCLUDE "data/mapObjects/lavenderpokecenter.asm"

INCLUDE "data/mapHeaders/lavendermart.asm"

INCLUDE "scripts/lavendermart.asm"

INCLUDE "data/mapObjects/lavendermart.asm"

INCLUDE "data/mapHeaders/vermilionpokecenter.asm"

INCLUDE "scripts/vermilionpokecenter.asm"

INCLUDE "data/mapObjects/vermilionpokecenter.asm"

INCLUDE "data/mapHeaders/vermilionmart.asm"

INCLUDE "scripts/vermilionmart.asm"

INCLUDE "data/mapObjects/vermilionmart.asm"

INCLUDE "data/mapHeaders/vermiliongym.asm"

INCLUDE "scripts/vermiliongym.asm"

INCLUDE "data/mapObjects/vermiliongym.asm"

VermilionGymBlocks: ; 5cc38 (17:4c38)
	INCBIN "maps/vermiliongym.blk"

INCLUDE "data/mapHeaders/copycatshouse2f.asm"

INCLUDE "scripts/copycatshouse2f.asm"

INCLUDE "data/mapObjects/copycatshouse2f.asm"

INCLUDE "data/mapHeaders/fightingdojo.asm"

INCLUDE "scripts/fightingdojo.asm"

INCLUDE "data/mapObjects/fightingdojo.asm"

FightingDojoBlocks: ; 5cfe3 (17:4fe3)
	INCBIN "maps/fightingdojo.blk"

INCLUDE "data/mapHeaders/saffrongym.asm"

INCLUDE "scripts/saffrongym.asm"

INCLUDE "data/mapObjects/saffrongym.asm"

SaffronGymBlocks: ; 5d3a3 (17:53a3)
	INCBIN "maps/saffrongym.blk"

INCLUDE "data/mapHeaders/saffronmart.asm"

INCLUDE "scripts/saffronmart.asm"

INCLUDE "data/mapObjects/saffronmart.asm"

INCLUDE "data/mapHeaders/silphco1.asm"

INCLUDE "scripts/silphco1.asm"

INCLUDE "data/mapObjects/silphco1.asm"

SilphCo1Blocks: ; 5d4a2 (17:54a2)
	INCBIN "maps/silphco1.blk"

INCLUDE "data/mapHeaders/saffronpokecenter.asm"

INCLUDE "scripts/saffronpokecenter.asm"

INCLUDE "data/mapObjects/saffronpokecenter.asm"

INCLUDE "data/mapHeaders/viridianforestexit.asm"

INCLUDE "scripts/viridianforestexit.asm"

INCLUDE "data/mapObjects/viridianforestexit.asm"

INCLUDE "data/mapHeaders/route2gate.asm"

INCLUDE "scripts/route2gate.asm"

INCLUDE "data/mapObjects/route2gate.asm"

INCLUDE "data/mapHeaders/viridianforestentrance.asm"

INCLUDE "scripts/viridianforestentrance.asm"

INCLUDE "data/mapObjects/viridianforestentrance.asm"

INCLUDE "data/mapHeaders/undergroundpathentranceroute5.asm"

INCLUDE "scripts/undergroundpathentranceroute5.asm"

INCLUDE "data/mapObjects/undergroundpathentranceroute5.asm"

INCLUDE "data/mapHeaders/undergroundpathentranceroute6.asm"

INCLUDE "scripts/undergroundpathentranceroute6.asm"

INCLUDE "data/mapObjects/undergroundpathentranceroute6.asm"

INCLUDE "data/mapHeaders/undergroundpathentranceroute7.asm"

INCLUDE "scripts/undergroundpathentranceroute7.asm"

INCLUDE "data/mapObjects/undergroundpathentranceroute7.asm"

INCLUDE "data/mapHeaders/undergroundpathentranceroute7copy.asm"

INCLUDE "scripts/undergroundpathentranceroute7copy.asm"

INCLUDE "data/mapObjects/undergroundpathentranceroute7copy.asm"

INCLUDE "data/mapHeaders/silphco9.asm"

INCLUDE "scripts/silphco9.asm"

INCLUDE "data/mapObjects/silphco9.asm"

SilphCo9Blocks: ; 5d989 (17:5989)
	INCBIN "maps/silphco9.blk"

INCLUDE "data/mapHeaders/victoryroad1.asm"

INCLUDE "scripts/victoryroad1.asm"

INCLUDE "data/mapObjects/victoryroad1.asm"

VictoryRoad1Blocks: ; 5db04 (17:5b04)
	INCBIN "maps/victoryroad1.blk"

; updates the types of a party mon (pointed to in hl) to the ones of the mon specified in $d11e
SetPartyMonTypes: ; 5db5e (17:5b5e)
	call Load16BitRegisters
	ld bc, W_PARTYMON1_TYPE1 - W_PARTYMON1DATA ; $5
	add hl, bc
	ld a, [$d11e]
	ld [$d0b5], a
	push hl
	call GetMonHeader
	pop hl
	ld a, [W_MONHTYPE1]
	ld [hli], a
	ld a, [W_MONHTYPE2]
	ld [hl], a
	ret

Func_5db79: ; 5db79 (17:5b79)
	call EnableAutoTextBoxDrawing
	ld a, $4
	jp PrintPredefTextID

RedBedroomSNESText: ; 5db81 (17:5b81)
	TX_FAR _RedBedroomSNESText
	db "@"

Func_5db86: ; 5db86 (17:5b86)
	call EnableAutoTextBoxDrawing
	ld a, $3
	jp PrintPredefTextID

Route15UpstairsLeftBinoculars: ; 5db8e (17:5b8e)
	db $fc
Func_5db8f: ; 5db8f (17:5b8f)
	ld a, [$c109]
	cp $4 ; i
	ret nz
	call EnableAutoTextBoxDrawing
	ld a, $a ; text id Route15UpstairsBinocularsText
	call PrintPredefTextID
	ld a, ARTICUNO
	ld [$cf91], a
	call PlayCry
	jp DisplayMonFrontSpriteInBox

Route15UpstairsBinocularsText: ; 5dba8 (17:5ba8)
	TX_FAR _Route15UpstairsBinocularsText
	db "@"

AerodactylFossil: ; 5dbad (17:5bad)
	ld a, FOSSIL_AERODACTYL
	ld [$cf91], a
	call DisplayMonFrontSpriteInBox
	call EnableAutoTextBoxDrawing
	ld a, $9
	call PrintPredefTextID
	ret

AerodactylFossilText: ; 5dbbe (17:5bbe)
	TX_FAR _AerodactylFossilText
	db "@"

KabutopsFossil: ; 5bdc3 (17:5bc3)
	ld a, FOSSIL_KABUTOPS
	ld [$cf91], a
	call DisplayMonFrontSpriteInBox
	call EnableAutoTextBoxDrawing
	ld a, $b
	call PrintPredefTextID
	ret

KabutopsFossilText: ; 5dbd4 (17:5bd4)
	TX_FAR _KabutopsFossilText
	db "@"

DisplayMonFrontSpriteInBox: ; 5dbd9 (17:5bd9)
; Displays a pokemon's front sprite in a pop-up window.
; [$cf91] = pokemon interal id number
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Delay3
	xor a
	ld [$ffb0], a
	call SaveScreenTilesToBuffer1
	ld a, $11
	ld [$d125], a
	call DisplayTextBoxID
	call UpdateSprites
	ld a, [$cf91]
	ld [$d0b5], a
	call GetMonHeader
	ld de, $8b10
	call LoadMonFrontSprite
	ld a, $80
	ld [$ffe1], a
	FuncCoord 10, 11 ; $c486
	ld hl, Coord
	ld a, $2
	call Predef ; indirect jump to Func_3f073 (3f073 (f:7073))
	call WaitForTextScrollButtonPress
	call LoadScreenTilesFromBuffer1
	call Delay3
	ld a, $90
	ld [$ffb0], a
	ret

Func_5dc1a: ; 5dc1a (17:5c1a)
	call EnableAutoTextBoxDrawing
	ld a, $1
	ld [$cc3c], a
	ld a, [$cd3d]
	call PrintPredefTextID
	ret

LinkCableHelp: ; 5dc29 (17:5c29)
	db $08 ; asm
	call SaveScreenTilesToBuffer1
	ld hl, LinkCableHelpText1
	call PrintText
	xor a
	ld [W_ANIMATIONID], a
	ld [wCurrentMenuItem], a
	ld [wLastMenuItem], a
	ld a, $3
	ld [wMenuWatchedKeys], a
	ld a, $3
	ld [wMaxMenuItem], a
	ld a, $2
	ld [wTopMenuItemY], a
	ld a, $1
	ld [wTopMenuItemX], a
.asm_5c51
	ld hl, $d730
	set 6, [hl]
	ld hl, wTileMap
	ld b, $8
	ld c, $d
	call TextBoxBorder
	ld hl, $c3ca
	ld de, HowToLinkText
	call PlaceString
	ld hl, LinkCableHelpText2
	call PrintText
	call HandleMenuInput
	bit 1, a
	jr nz, .asm_5dc93 ; 0x5dc74 $1d
	ld a, [wCurrentMenuItem]
	cp $3
	jr z, .asm_5dc93 ; 0x5dc7b $16
	ld hl, $d730
	res 6, [hl]
	ld hl, LinkCableInfoTexts
	add a
	ld d, $0
	ld e, a
	add hl, de
	ld a, [hli]
	ld h, [hl]
	ld l, a
	call PrintText
	jp .asm_5c51
.asm_5dc93
	ld hl, $d730
	res 6, [hl]
	call LoadScreenTilesFromBuffer1
	jp TextScriptEnd

LinkCableHelpText1: ; 5dc9e (17:5c9e)
	TX_FAR _LinkCableHelpText1
	db "@"

LinkCableHelpText2: ; 5dca3 (17:5ca3)
	TX_FAR _LinkCableHelpText2
	db "@"

HowToLinkText: ; 5dca8 (17:5ca8)
	db   "HOW TO LINK"
	next "COLOSSEUM"
	next "TRADE CENTER"
	next "STOP READING@"

LinkCableInfoTexts: ; 5dcd8 (17:5cd8)
	dw LinkCableInfoText1
	dw LinkCableInfoText2
	dw LinkCableInfoText3

LinkCableInfoText1: ; 5dcde (17:5cde)
	TX_FAR _LinkCableInfoText1
	db "@"

LinkCableInfoText2: ; 5dce3 (17:5ce3)
	TX_FAR _LinkCableInfoText2
	db "@"

LinkCableInfoText3: ; 5dce8 (17:5ce8)
	TX_FAR _LinkCableInfoText3
	db "@"

ViridianSchoolBlackboard: ; 5dced (17:5ced)
	db $08 ; asm
	call SaveScreenTilesToBuffer1
	ld hl, ViridianSchoolBlackboardText1
	call PrintText
	xor a
	ld [W_ANIMATIONID], a
	ld [wCurrentMenuItem], a
	ld [wLastMenuItem], a
	ld a, $33
	ld [wMenuWatchedKeys], a
	ld a, $2
	ld [wMaxMenuItem], a
	ld a, $2
	ld [wTopMenuItemY], a
	ld a, $1
	ld [wTopMenuItemX], a
.asm_5dd15
	ld hl, $d730
	set 6, [hl]
	ld hl, wTileMap
	ld bc, $060a
	call TextBoxBorder
	ld hl, $c3c9
	ld de, StatusAilmentText1
	call PlaceString
	ld hl, $c3ce
	ld de, StatusAilmentText2
	call PlaceString
	ld hl, ViridianSchoolBlackboardText2
	call PrintText
	call HandleMenuInput
	bit 1, a
	jr nz, .exitBlackboard
	bit 4, a
	jr z, .asm_5dd5c
	ld a, $2
	ld [wMaxMenuItem], a
	ld a, $2
	ld [wTopMenuItemY], a
	ld a, $6
	ld [wTopMenuItemX], a
	ld a, $3
	ld [W_ANIMATIONID], a
	jr .asm_5dd15
.asm_5dd5c
	bit 5, a
	jr z, .asm_5dd75
	ld a, $2
	ld [wMaxMenuItem], a
	ld a, $2
	ld [wTopMenuItemY], a
	ld a, $1
	ld [wTopMenuItemX], a
	xor a
	ld [W_ANIMATIONID], a
	jr .asm_5dd15
.asm_5dd75
	ld a, [wCurrentMenuItem]
	ld b, a
	ld a, [W_ANIMATIONID]
	add b
	cp $5
	jr z, .exitBlackboard
	ld hl, $d730
	res 6, [hl]
	ld hl, ViridianBlackboardStatusPointers
	add a
	ld d, $0
	ld e, a
	add hl, de
	ld a, [hli]
	ld h, [hl]
	ld l, a
	call PrintText
	jp .asm_5dd15
.exitBlackboard
	ld hl, $d730
	res 6, [hl]
	call LoadScreenTilesFromBuffer1
	jp TextScriptEnd

ViridianSchoolBlackboardText1: ; 5dda2 (17:5da2)
	TX_FAR _ViridianSchoolBlackboardText1
	db "@"

ViridianSchoolBlackboardText2: ; 5dda7 (17:5da7)
	TX_FAR _ViridianSchoolBlackboardText2
	db "@"

StatusAilmentText1: ; 5ddac (17:5dac)
	db   " SLP"
	next " PSN"
	next " PAR@"

StatusAilmentText2: ; 5ddbb (17:5dbb)
	db   " BRN"
	next " FRZ"
	next " QUIT@@"

ViridianBlackboardStatusPointers: ; 5ddcc (17:5ddc)
	dw ViridianBlackboardSleepText
	dw ViridianBlackboardPoisonText
	dw ViridianBlackbaordPrlzText
	dw ViridianBlackboardBurnText
	dw ViridianBlackboardFrozenText

ViridianBlackboardSleepText: ; 5ddd6 (17:5dd6)
	TX_FAR _ViridianBlackboardSleepText
	db "@"

ViridianBlackboardPoisonText: ; 5dddb (17:5ddb)
	TX_FAR _ViridianBlackboardPoisonText
	db "@"

ViridianBlackbaordPrlzText: ; 5dde0 (17:5de0)
	TX_FAR _ViridianBlackbaordPrlzText
	db "@"

ViridianBlackboardBurnText: ; 5dde5 (17:5de5)
	TX_FAR _ViridianBlackboardBurnText
	db "@"

ViridianBlackboardFrozenText: ; 5ddea (17:5dea)
	TX_FAR _ViridianBlackboardFrozenText
	db "@"

Func_5ddef: ; 5ddef (17:5def)
	call EnableAutoTextBoxDrawing
	ld a, $26
	jp PrintPredefTextID

VermilionGymTrashText: ; 5ddf7 (17:5df7)
	TX_FAR _VermilionGymTrashText
	db "@"

GymTrashScript: ; 5ddfc (17:5dfc)
	call EnableAutoTextBoxDrawing
	ld a, [wWhichTrade] ; $cd3d
	ld [$cd5b], a

; Don't do the trash can puzzle if it's already been done.
	ld a, [$d773]
	bit 0, a
	jr z, .ok

	ld a, $26 ; DisplayTextID $26 = VermilionGymTrashText (nothing in the trash)
	jp PrintPredefTextID

.ok
	bit 1, a
	jr nz, .trySecondLock

	ld a, [$d743]
	ld b, a
	ld a, [$cd5b]
	cp b
	jr z, .openFirstLock

	ld a, $26 ; DisplayTextID $26 = VermilionGymTrashText (nothing in the trash)
	jr .done

.openFirstLock
; Next can is trying for the second switch.
	ld hl, $d773
	set 1, [hl]

	ld hl, GymTrashCans ; $5e7d
	ld a, [$cd5b]
	; * 5
	ld b, a
	add a
	add a
	add b

	ld d, 0
	ld e, a
	add hl, de
	ld a, [hli]

	ld [$ffdb], a
	push hl
	call GenRandom
	swap a
	ld b, a
	ld a, [$ffdb]
	and b
	dec a
	pop hl

	ld d, 0
	ld e, a
	add hl, de
	ld a, [hl]
	and $f
	ld [$d744], a

	ld a, $3b ; DisplayTextID $3b = VermilionGymTrashSuccesText1 (first lock opened!)
	jr .done

.trySecondLock
	ld a, [$d744]
	ld b, a
	ld a, [$cd5b]
	cp b
	jr z, .openSecondLock

; Reset the cans.
	ld hl, $d773
	res 1, [hl]
	call GenRandom

	and $e
	ld [$d743], a

	ld a, $3e ; DisplayTextID $3e = VermilionGymTrashFailText (locks reset!)
	jr .done

.openSecondLock
; Completed the trash can puzzle.
	ld hl, $d773
	set 0, [hl]
	ld hl, $d126
	set 6, [hl]

	ld a, $3d ; DisplayTextID $3d = VermilionGymTrashSuccesText3 (2nd lock opened!)

.done
	jp PrintPredefTextID

GymTrashCans: ; 5de7d (17:5e7d)
	db 2,  1,  3,  0,  0 ; 0
	db 3,  0,  2,  4,  0 ; 1
	db 2,  1,  5,  0,  0 ; 2
	db 3,  0,  4,  6,  0 ; 3
	db 4,  1,  3,  5,  7 ; 4
	db 3,  2,  4,  8,  0 ; 5
	db 3,  3,  7,  9,  0 ; 6
	db 4,  4,  6,  8, 10 ; 7
	db 3,  5,  7, 11,  0 ; 8
	db 3,  6, 10, 12,  0 ; 9
	db 4,  7,  9, 11, 13 ; 10
	db 3,  8, 10, 14,  0 ; 11
	db 2,  9, 13,  0,  0 ; 12
	db 3, 10, 12, 14,  0 ; 13
	db 2, 11, 13,  0,  0 ; 14
; 5dec8

VermilionGymTrashSuccesText1: ; 5dec8 (17:5ec8)
	TX_FAR _VermilionGymTrashSuccesText1
	db $08 ; asm
	call WaitForSoundToFinish
	ld a, (SFX_02_49 - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	jp TextScriptEnd

VermilionGymTrashSuccesText2: ; 5dedb (17:5edb)
	TX_FAR _VermilionGymTrashSuccesText2
	db "@"

UnnamedText_5dee0: ; 5dee0 (17:5ee0)
	db $08 ; asm
	call WaitForSoundToFinish
	ld a, (SFX_02_49 - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	jp TextScriptEnd

VermilionGymTrashSuccesText3: ; 5deef (17:5eef)
	TX_FAR _VermilionGymTrashSuccesText3
	db $08 ; asm
	call WaitForSoundToFinish
	ld a, (SFX_02_57 - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	jp TextScriptEnd

VermilionGymTrashFailText: ; 5df02 (17:5f02)
	TX_FAR _VermilionGymTrashFailText
	db $08 ; asm
	call WaitForSoundToFinish
	ld a, (SFX_02_51 - SFX_Headers_02) / 3
	call PlaySound
	call WaitForSoundToFinish
	jp TextScriptEnd

SECTION "bank18",ROMX,BANK[$18]

ViridianForestBlocks: ; 60000 (18:4000)
	INCBIN "maps/viridianforest.blk"

UndergroundPathNSBlocks: ; 60198 (18:4198)
	INCBIN "maps/undergroundpathns.blk"

UndergroundPathWEBlocks: ; 601f4 (18:41f4)
	INCBIN "maps/undergroundpathwe.blk"

	INCBIN "maps/unusedblocks60258.blk"

SSAnne10Blocks: ; 603c0 (18:43c0)
SSAnne9Blocks: ; 603c0 (18:43c0)
	INCBIN "maps/ssanne9.blk"

INCLUDE "data/mapHeaders/pokemontower1.asm"

INCLUDE "scripts/pokemontower1.asm"

INCLUDE "data/mapObjects/pokemontower1.asm"

PokemonTower1Blocks: ; 6048c (18:448c)
	INCBIN "maps/pokemontower1.blk"

INCLUDE "data/mapHeaders/pokemontower2.asm"

INCLUDE "scripts/pokemontower2.asm"

INCLUDE "data/mapObjects/pokemontower2.asm"

PokemonTower2Blocks: ; 60666 (18:4666)
	INCBIN "maps/pokemontower2.blk"

INCLUDE "data/mapHeaders/pokemontower3.asm"

INCLUDE "scripts/pokemontower3.asm"

INCLUDE "data/mapObjects/pokemontower3.asm"

PokemonTower3Blocks: ; 60790 (18:4790)
	INCBIN "maps/pokemontower3.blk"

INCLUDE "data/mapHeaders/pokemontower4.asm"

INCLUDE "scripts/pokemontower4.asm"

INCLUDE "data/mapObjects/pokemontower4.asm"

PokemonTower4Blocks: ; 608cc (18:48cc)
	INCBIN "maps/pokemontower4.blk"

INCLUDE "data/mapHeaders/pokemontower5.asm"

INCLUDE "scripts/pokemontower5.asm"

INCLUDE "data/mapObjects/pokemontower5.asm"

PokemonTower5Blocks: ; 60a89 (18:4a89)
	INCBIN "maps/pokemontower5.blk"

INCLUDE "data/mapHeaders/pokemontower6.asm"

INCLUDE "scripts/pokemontower6.asm"

INCLUDE "data/mapObjects/pokemontower6.asm"

PokemonTower6Blocks: ; 60c95 (18:4c95)
	INCBIN "maps/pokemontower6.blk"

	INCBIN "maps/unusedblocks60cef.blk"

INCLUDE "data/mapHeaders/pokemontower7.asm"

INCLUDE "scripts/pokemontower7.asm"

INCLUDE "data/mapObjects/pokemontower7.asm"

PokemonTower7Blocks: ; 60f20 (18:4f20)
	INCBIN "maps/pokemontower7.blk"

INCLUDE "data/mapHeaders/celadonmart1.asm"

INCLUDE "scripts/celadonmart1.asm"

INCLUDE "data/mapObjects/celadonmart1.asm"

CeladonMart1Blocks: ; 60fde (18:4fde)
	INCBIN "maps/celadonmart1.blk"

GiveFossilToCinnabarLab: ; 61006 (18:5006)
	ld hl, $d730
	set 6, [hl]
	xor a
	ld [wCurrentMenuItem], a ; $cc26
	ld a, $3
	ld [wMenuWatchedKeys], a ; $cc29
	ld a, [$cd37]
	dec a
	ld [wMaxMenuItem], a ; $cc28
	ld a, $2
	ld [wTopMenuItemY], a ; $cc24
	ld a, $1
	ld [wTopMenuItemX], a ; $cc25
	ld a, [$cd37]
	dec a
	ld bc, $2
	ld hl, $3
	call AddNTimes
	dec l
	ld b, l
	ld c, $d
	ld hl, wTileMap
	call TextBoxBorder
	call UpdateSprites
	call Func_610c2
	ld hl, $d730
	res 6, [hl]
	call HandleMenuInput
	bit 1, a
	jr nz, .asm_610a7
	ld hl, $cc5b
	ld a, [wCurrentMenuItem] ; $cc26
	ld d, $0
	ld e, a
	add hl, de
	ld a, [hl]
	ld [$ffdb], a
	cp DOME_FOSSIL
	jr z, .choseDomeFossil
	cp HELIX_FOSSIL
	jr z, .choseHelixFossil
	ld b, AERODACTYL
	jr .fossilSelected
.choseHelixFossil
	ld b, OMANYTE
	jr .fossilSelected
.choseDomeFossil
	ld b, KABUTO
.fossilSelected
	ld [W_FOSSILITEM], a
	ld a, b
	ld [W_FOSSILMON], a
	call LoadFossilItemAndMonName
	ld hl, LabFossil_610ae
	call PrintText
	call YesNoChoice
	ld a, [wCurrentMenuItem] ; $cc26
	and a
	jr nz, .asm_610a7
	ld hl, LabFossil_610b3
	call PrintText
	ld a, [W_FOSSILITEM]
	ld [$ffdb], a
	callba RemoveItemByID
	ld hl, LabFossil_610b8
	call PrintText
	ld hl, $d7a3
	set 0, [hl]
	set 1, [hl]
	ret
.asm_610a7
	ld hl, LabFossil_610bd
	call PrintText
	ret

LabFossil_610ae: ; 610ae (18:50ae)
	TX_FAR _Lab4Text_610ae
	db "@"

LabFossil_610b3: ; 610b3 (18:50b3)
	TX_FAR _Lab4Text_610b3
	db "@"

LabFossil_610b8: ; 610b8 (18:50b8)
	TX_FAR _Lab4Text_610b8
	db "@"

LabFossil_610bd: ; 610bd (18:50bd)
	TX_FAR _Lab4Text_610bd
	db "@"

Func_610c2: ; 610c2 (18:50c2)
	ld hl, $cc5b
	xor a
	ld [$ffdb], a
.asm_610c8
	ld a, [hli]
	cp $ff
	ret z
	push hl
	ld [$d11e], a
	call GetItemName
	FuncCoord 2, 2 ; $c3ca
	ld hl, Coord
	ld a, [$ffdb]
	ld bc, $28
	call AddNTimes
	ld de, $cd6d
	call PlaceString
	ld hl, $ffdb
	inc [hl]
	pop hl
	jr .asm_610c8

; loads the names of the fossil item and the resulting mon
LoadFossilItemAndMonName: ; 610eb (18:50eb)
	ld a, [W_FOSSILMON]
	ld [$d11e], a
	call GetMonName
	call CopyStringToCF4B
	ld a, [W_FOSSILITEM]
	ld [$d11e], a
	call GetItemName
	ret

INCLUDE "data/mapHeaders/viridianforest.asm"

INCLUDE "scripts/viridianforest.asm"

INCLUDE "data/mapObjects/viridianforest.asm"

INCLUDE "data/mapHeaders/ssanne1.asm"

INCLUDE "scripts/ssanne1.asm"

INCLUDE "data/mapObjects/ssanne1.asm"

SSAnne1Blocks: ; 612df (18:52df)
	INCBIN "maps/ssanne1.blk"

INCLUDE "data/mapHeaders/ssanne2.asm"

INCLUDE "scripts/ssanne2.asm"

INCLUDE "data/mapObjects/ssanne2.asm"

SSAnne2Blocks: ; 6156e (18:556e)
	INCBIN "maps/ssanne2.blk"

INCLUDE "data/mapHeaders/ssanne4.asm"

INCLUDE "scripts/ssanne4.asm"

INCLUDE "data/mapObjects/ssanne4.asm"

SSAnne4Blocks: ; 61666 (18:5666)
	INCBIN "maps/ssanne4.blk"

INCLUDE "data/mapHeaders/ssanne5.asm"

INCLUDE "scripts/ssanne5.asm"

INCLUDE "data/mapObjects/ssanne5.asm"

SSAnne5Blocks: ; 61761 (18:5761)
	INCBIN "maps/ssanne5.blk"

INCLUDE "data/mapHeaders/ssanne6.asm"

INCLUDE "scripts/ssanne6.asm"

INCLUDE "data/mapObjects/ssanne6.asm"

SSAnne6Blocks: ; 61851 (18:5851)
	INCBIN "maps/ssanne6.blk"

INCLUDE "data/mapHeaders/ssanne7.asm"

INCLUDE "scripts/ssanne7.asm"

INCLUDE "data/mapObjects/ssanne7.asm"

SSAnne7Blocks: ; 6195e (18:595e)
	INCBIN "maps/ssanne7.blk"

INCLUDE "data/mapHeaders/ssanne8.asm"

INCLUDE "scripts/ssanne8.asm"

INCLUDE "data/mapObjects/ssanne8.asm"

SSAnne8Blocks: ; 61adf (18:5adf)
	INCBIN "maps/ssanne8.blk"

INCLUDE "data/mapHeaders/ssanne9.asm"

INCLUDE "scripts/ssanne9.asm"

INCLUDE "data/mapObjects/ssanne9.asm"

INCLUDE "data/mapHeaders/ssanne10.asm"

INCLUDE "scripts/ssanne10.asm"

INCLUDE "data/mapObjects/ssanne10.asm"

INCLUDE "data/mapHeaders/undergroundpathns.asm"

INCLUDE "scripts/undergroundpathns.asm"

INCLUDE "data/mapObjects/undergroundpathns.asm"

INCLUDE "data/mapHeaders/undergroundpathwe.asm"

INCLUDE "scripts/undergroundpathwe.asm"

INCLUDE "data/mapObjects/undergroundpathwe.asm"

INCLUDE "data/mapHeaders/diglettscave.asm"

INCLUDE "scripts/diglettscave.asm"

INCLUDE "data/mapObjects/diglettscave.asm"

DiglettsCaveBlocks: ; 61f86 (18:5f86)
	INCBIN "maps/diglettscave.blk"

INCLUDE "data/mapHeaders/silphco11.asm"

INCLUDE "scripts/silphco11.asm"

INCLUDE "data/mapObjects/silphco11.asm"

SilphCo11Blocks: ; 623c8 (18:63c8)
	INCBIN "maps/silphco11.blk"

GymStatues: ; 62419 (18:6419)
; if in a gym and have the corresponding badge, a = $D and jp PrintPredefTextID
; if in a gym and don’t have the corresponding badge, a = $C and jp PrintPredefTextID
; else ret
	call EnableAutoTextBoxDrawing
	ld a, [$c109]
	cp $4
	ret nz
	ld hl, .BadgeFlags
	ld a, [W_CURMAP]
	ld b, a
.asm_62429
	ld a, [hli]
	cp $ff
	ret z
	cp b
	jr z, .asm_62433 ; 0x6242e $3
	inc hl
	jr .asm_62429 ; 0x62431 $f6
.asm_62433
	ld b, [hl]
	ld a, [$d72a]
	and b
	cp b
	ld a, $d
	jr z, .asm_6243f ; 0x6243b $2
	ld a, $c
.asm_6243f
	jp PrintPredefTextID

.BadgeFlags: ; 62442 (18:6442)
	db PEWTER_GYM,   %00000001
	db CERULEAN_GYM, %00000010
	db VERMILION_GYM,%00000100
	db CELADON_GYM,  %00001000
	db FUCHSIA_GYM,  %00010000
	db SAFFRON_GYM,  %00100000
	db CINNABAR_GYM, %01000000
	db VIRIDIAN_GYM, %10000000
	db $ff

GymStatueText1: ; 62453 (18:6453)
	TX_FAR _GymStatueText1
	db "@"

GymStatueText2: ; 62458 (18:6458)
	TX_FAR _GymStatueText2
	db "@"

Func_6245d: ; 6245d (18:645d)
	call EnableAutoTextBoxDrawing
	ld hl, PokeCenterMapIDList
	ld a, [W_CURMAP]
	ld b, a
.asm_62467
	ld a, [hli]
	cp $ff
	ret z
	cp b
	jr z, .asm_62472
	inc hl
	inc hl
	jr .asm_62467
.asm_62472
	ld a, [hli]
	ld b, a
	ld a, [$c109]
	cp b
	jr nz, .asm_62467
	ld a, [hl]
	jp PrintPredefTextID

; format: db map id, 08, text id of PointerTable_3f22
PokeCenterMapIDList: ; 6247e (18:647e)
	db VIRIDIAN_POKECENTER,$08,$0F
	db PEWTER_POKECENTER,$08,$10
	db CERULEAN_POKECENTER,$08,$11
	db LAVENDER_POKECENTER,$08,$12
	db VERMILION_POKECENTER,$08,$13
	db CELADON_POKECENTER,$08,$14
	db CELADON_HOTEL,$08,$15
	db FUCHSIA_POKECENTER,$08,$16
	db CINNABAR_POKECENTER,$08,$17
	db SAFFRON_POKECENTER,$08,$18
	db MT_MOON_POKECENTER,$08,$19
	db ROCK_TUNNEL_POKECENTER,$08,$1A
	db $FF

ViridianCityPokecenterBenchGuyText: ; 624a3 (18:64a3)
	TX_FAR _ViridianCityPokecenterGuyText
	db "@"

PewterCityPokecenterBenchGuyText: ; 624a8 (18:64a8)
	TX_FAR _PewterCityPokecenterGuyText
	db "@"

CeruleanCityPokecenterBenchGuyText: ; 624ad (18:64ad)
	TX_FAR _CeruleanPokecenterGuyText
	db "@"

LavenderCityPokecenterBenchGuyText: ; 624b2 (18:64b2)
	TX_FAR _LavenderPokecenterGuyText
	db "@"

MtMoonPokecenterBenchGuyText: ; 624b7 (18:64b7)
	TX_FAR _MtMoonPokecenterBenchGuyText
	db "@"

RockTunnelPokecenterBenchGuyText: ; 624bc (18:64bc)
	TX_FAR _RockTunnelPokecenterGuyText
	db "@"

UnnamedText_624c1: ; 624c1 (18:64c1)
	TX_FAR _UnnamedText_624c1
	db "@"

UnnamedText_624c6: ; 624c6 (18:64c6)
	TX_FAR _UnnamedText_624c6
	db "@"

UnnamedText_624cb: ; 624cb (18:64cb)
	TX_FAR _UnnamedText_624cb
	db "@"

VermilionCityPokecenterBenchGuyText: ; 624d0 (18:64d0)
	TX_FAR _VermilionPokecenterGuyText
	db "@"

CeladonCityPokecenterBenchGuyText: ; 624d5 (18:64d5)
	TX_FAR _CeladonCityPokecenterGuyText
	db "@"

FuchsiaCityPokecenterBenchGuyText: ; 624da (18:64da)
	TX_FAR _FuchsiaCityPokecenterGuyText
	db "@"

CinnabarIslandPokecenterBenchGuyText: ; 624df (18:64df)
	TX_FAR _CinnabarPokecenterGuyText
	db "@"

SaffronCityPokecenterBenchGuyText: ; 624e4 (18:64e4)
	db $8 ; asm
	ld a, [$d838]
	bit 7, a
	ld hl, SaffronCityPokecenterBenchGuyText2
	jr nz, .asm_624f2 ; 0x624ed $3
	ld hl, SaffronCityPokecenterBenchGuyText1
.asm_624f2
	call PrintText
	jp TextScriptEnd

SaffronCityPokecenterBenchGuyText1: ; 624f8 (18:64f8)
	TX_FAR _SaffronCityPokecenterGuyText1
	db "@"

SaffronCityPokecenterBenchGuyText2: ; 624fd (18:64fd)
	TX_FAR _SaffronCityPokecenterGuyText2
	db "@"

CeladonCityHotelText: ; 62502 (18:6502)
	TX_FAR _CeladonCityHotelText
	db "@"

	ret

TerminatorText_62508: ; 62508 (18:6508)
	db "@"

Func_62509: ; 6509 (18:6509)
	call EnableAutoTextBoxDrawing
	ld a, $e
	jp PrintPredefTextID

BookcaseText: ; 62511 (18:6511)
	TX_FAR _BookcaseText
	db "@"

Func_62516: ; 62516 (18:6516)
	ld a, [$c109]
	cp $4 ; check to see if player is facing up
	ret nz
	call EnableAutoTextBoxDrawing
	ld a, $1
	ld [$cf0c], a
	ld a, $1f
	jp PrintPredefTextID

PredefText1f: ; 62529 (18:6529)
	db $F9

SECTION "bank19",ROMX,BANK[$19]

Overworld_GFX: ; 64000 (19:4000)
	INCBIN "gfx/tilesets/overworld.w128.t2.2bpp"
Overworld_Block: ; 645e0 (19:45e0)
	INCBIN "gfx/blocksets/overworld.bst"
RedsHouse1_GFX:
RedsHouse2_GFX: ; 64de0 (19:4de0)
	INCBIN "gfx/tilesets/reds_house.w128.t7.2bpp"
RedsHouse1_Block:
RedsHouse2_Block: ; 65270 (19:5270)
	INCBIN "gfx/blocksets/reds_house.bst"
House_GFX: ; 653a0 (19:53a0)
	INCBIN "gfx/tilesets/house.w128.t2.2bpp"
House_Block: ; 65980 (19:5980)
	INCBIN "gfx/blocksets/house.bst"
Mansion_GFX: ; 65bb0 (19:5bb0)
	INCBIN "gfx/tilesets/mansion.w128.t2.2bpp"
Mansion_Block: ; 66190 (19:6190)
	INCBIN "gfx/blocksets/mansion.bst"
ShipPort_GFX: ; 66610 (19:6610)
	INCBIN "gfx/tilesets/ship_port.w128.t2.2bpp"
ShipPort_Block: ; 66bf0 (19:6bf0)
	INCBIN "gfx/blocksets/ship_port.bst"
Interior_GFX: ; 66d60 (19:6d60)
	INCBIN "gfx/tilesets/interior.w128.t1.2bpp"
Interior_Block: ; 67350 (19:7350)
	INCBIN "gfx/blocksets/interior.bst"
Plateau_GFX: ; 676f0 (19:76f0)
	INCBIN "gfx/tilesets/plateau.w128.t10.2bpp"
Plateau_Block: ; 67b50 (19:7b50)
	INCBIN "gfx/blocksets/plateau.bst"

SECTION "bank1A",ROMX,BANK[$1A]

DecrementPP: ; 68000 (1a:4000)
; after using a move, decrement pp in battle and (if not transformed?) in party
	ld a, [de]
	cp a, STRUGGLE
	ret z                ; if the pokemon is using "struggle", there's nothing to do
	                     ; we don't decrement PP for "struggle"
	ld hl, W_PLAYERBATTSTATUS1
	ld a, [hli]          ; load the W_PLAYERBATTSTATUS1 pokemon status flags and increment hl to load the
	                     ; W_PLAYERBATTSTATUS2 status flags later
	and a, 7             ; check to see if bits 0, 1, or 2 are set
	ret nz               ; if any of these statuses are true, don't decrement PP
	bit 6, [hl]          ; check 6th bit status flag on W_PLAYERBATTSTATUS2
	ret nz               ; and return if it is set
	ld hl, $D02D         ; PP of first move (in battle)
	call .DecrementPP

	ld a, [$D064]        ; load pokemon status bits?
	bit 3, a             ; XXX transform status?
	ret nz               ; If it is, return.  Pokemon Red stores the "current pokemon's" PP
	                     ; separately from the "Pokemon in your party's" PP.  This is
	                     ; duplication -- in all cases *other* than Pokemon with Transform.
	                     ; Normally, this means we have to go on and make the same
	                     ; modification to the "party's pokemon" PP that we made to the
	                     ; "current pokemon's" PP.  But, if we're dealing with a Transformed
	                     ; Pokemon, it has separate PP for the move set that it copied from
	                     ; its opponent, which is *not* the same as its real PP as part of your
	                     ; party.  So we return, and don't do that part.

	ld hl, $D188         ; PP of first move (in party)
	ld a, [$CC2F]        ; which mon in party is active
	ld bc, $2C           ; XXX probably size of party pokemon's data structure
	call AddNTimes       ; calculate address of the mon to modify
.DecrementPP
	ld a, [$CC2E]        ; which move (0, 1, 2, 3) did we use?
	ld c, a
	ld b, 0
	add hl ,bc           ; calculate the address in memory of the PP we need to decrement
	                     ; based on the move chosen.
	dec [hl]             ; Decrement PP
	ret

Version_GFX: ; 6802f (1a:402f)
IF _RED
	INCBIN "gfx/red/redgreenversion.h8.1bpp"
	; 80 bytes
ENDC
IF _BLUE
	INCBIN "gfx/blue/blueversion.h8.1bpp"
	; 64 bytes
ENDC

Dojo_GFX:
Gym_GFX: ; 6807f (1a:407f)
	INCBIN "gfx/tilesets/gym.w128.2bpp"
Dojo_Block:
Gym_Block: ; 6867f (1a:467f)
	INCBIN "gfx/blocksets/gym.bst"
Mart_GFX:
Pokecenter_GFX: ; 68dbf (1a:4dbf)
	INCBIN "gfx/tilesets/pokecenter.w128.2bpp"
Mart_Block:
Pokecenter_Block: ; 693bf (1a:53bf)
	INCBIN "gfx/blocksets/pokecenter.bst"
ForestGate_GFX:
Museum_GFX:
Gate_GFX: ; 6960f (1a:560f)
	INCBIN "gfx/tilesets/gate.w128.t1.2bpp"
ForestGate_Block:
Museum_Block:
Gate_Block: ; 69bff (1a:5bff)
	INCBIN "gfx/blocksets/gate.bst"
Forest_GFX: ; 6a3ff (1a:63ff)
	INCBIN "gfx/tilesets/forest.w128.2bpp"
Forest_Block: ; 6a9ff (1a:69ff)
	INCBIN "gfx/blocksets/forest.bst"
Facility_GFX: ; 6b1ff (1a:71ff)
	INCBIN "gfx/tilesets/facility.w128.2bpp"
Facility_Block: ; 6b7ff (1a:77ff)
	INCBIN "gfx/blocksets/facility.bst"

SECTION "bank1B",ROMX,BANK[$1B]

Cemetery_GFX: ; 6c000 (1b:4000)
	INCBIN "gfx/tilesets/cemetery.w128.t4.2bpp"
Cemetery_Block: ; 6c5c0 (1b:45c0)
	INCBIN "gfx/blocksets/cemetery.bst"
Cavern_GFX: ; 6cca0 (1b:4ca0)
	INCBIN "gfx/tilesets/cavern.w128.t14.2bpp"
Cavern_Block: ; 6d0c0 (1b:50c0)
	INCBIN "gfx/blocksets/cavern.bst"
Lobby_GFX: ; 6d8c0 (1b:58c0)
	INCBIN "gfx/tilesets/lobby.w128.t2.2bpp"
Lobby_Block: ; 6dea0 (1b:5ea0)
	INCBIN "gfx/blocksets/lobby.bst"
Ship_GFX: ; 6e390 (1b:6390)
	INCBIN "gfx/tilesets/ship.w128.t6.2bpp"
Ship_Block: ; 6e930 (1b:6930)
	INCBIN "gfx/blocksets/ship.bst"
Lab_GFX: ; 6ed10 (1b:6d10)
	INCBIN "gfx/tilesets/lab.w128.t4.2bpp"
Lab_Block: ; 6f2d0 (1b:72d0)
	INCBIN "gfx/blocksets/lab.bst"
Club_GFX: ; 6f670 (1b:7670)
	INCBIN "gfx/tilesets/club.w128.t5.2bpp"
Club_Block: ; 6fb20 (1b:7b20)
	INCBIN "gfx/blocksets/club.bst"
Underground_GFX: ; 6fd60 (1b:7d60)
	INCBIN "gfx/tilesets/underground.w128.t7.2bpp"
Underground_Block: ; 6fef0 (1b:7ef0)
	INCBIN "gfx/blocksets/underground.bst"

SECTION "bank1C",ROMX,BANK[$1C]

LoadShootingStarGraphics: ; 70000 (1c:4000)
	ld a, $f9
	ld [rOBP0], a ; $ff48
	ld a, $a4
	ld [rOBP1], a ; $ff49
	ld de, AnimationTileset2 + $30 ; $471e ; star tile (top left quadrant)
	ld hl, $8a00
	ld bc, (BANK(AnimationTileset2) << 8) + $01
	call CopyVideoData
	ld de, AnimationTileset2 + $130 ; $481e ; star tile (bottom left quadrant)
	ld hl, $8a10
	ld bc, (BANK(AnimationTileset2) << 8) + $01
	call CopyVideoData
	ld de, FallingStar ; $4190
	ld hl, $8a20
	ld bc, (BANK(FallingStar) << 8) + $01
	call CopyVideoData
	ld hl, GameFreakLogoOAMData ; $4140
	ld de, wOAMBuffer + $60
	ld bc, $40
	call CopyData
	ld hl, GameFreakShootingStarOAMData ; $4180
	ld de, wOAMBuffer
	ld bc, $10
	jp CopyData

AnimateShootingStar: ; 70044 (1c:4044)
	call LoadShootingStarGraphics
	ld a, (SFX_1f_67 - SFX_Headers_1f) / 3
	call PlaySound
	ld hl, wOAMBuffer
	ld bc, $a004
.asm_70052
	push hl
	push bc
.asm_70054
	ld a, [hl]
	add $4
	ld [hli], a
	ld a, [hl]
	add $fc
	ld [hli], a
	inc hl
	inc hl
	dec c
	jr nz, .asm_70054
	ld c, $1
	call CheckForUserInterruption
	pop bc
	pop hl
	ret c
	ld a, [hl]
	cp $50
	jr nz, .asm_70070
	jr .asm_70052
.asm_70070
	cp b
	jr nz, .asm_70052
	ld hl, wOAMBuffer
	ld c, $4
	ld de, $4
.asm_7007b
	ld [hl], $a0
	add hl, de
	dec c
	jr nz, .asm_7007b
	ld b, $3
.asm_70083
	ld hl, rOBP0 ; $ff48
	rrc [hl]
	rrc [hl]
	ld c, $a
	call CheckForUserInterruption
	ret c
	dec b
	jr nz, .asm_70083
	ld de, wOAMBuffer
	ld a, $18
.asm_70098
	push af
	ld hl, OAMData_700ee ; $40ee
	ld bc, $4
	call CopyData
	pop af
	dec a
	jr nz, .asm_70098
	xor a
	ld [wWhichTrade], a ; $cd3d
	ld hl, PointerTable_700f2 ; $40f2
	ld c, $6
.asm_700af
	ld a, [hli]
	ld e, a
	ld a, [hli]
	ld d, a
	push bc
	push hl
	ld hl, wOAMBuffer + $50
	ld c, $4
.asm_700ba
	ld a, [de]
	cp $ff
	jr z, .asm_700d5
	ld [hli], a
	inc de
	ld a, [de]
	ld [hli], a
	inc de
	inc hl
	inc hl
	dec c
	jr nz, .asm_700ba
	ld a, [wWhichTrade] ; $cd3d
	cp $18
	jr z, .asm_700d5
	add $6
	ld [wWhichTrade], a ; $cd3d
.asm_700d5
	call Func_7011f
	push af
	ld hl, $c310
	ld de, wOAMBuffer
	ld bc, $50
	call CopyData
	pop af
	pop hl
	pop bc
	ret c
	dec c
	jr nz, .asm_700af
	and a
	ret

OAMData_700ee: ; 700ee (1c:40ee)
	db $00,$00,$A2,$90

PointerTable_700f2: ; 700f2 (1c:40f2)
	dw OAMData_700fe
	dw OAMData_70106
	dw OAMData_7010e
	dw OAMData_70116
	dw OAMData_7011e
	dw OAMData_7011e

; each entry is only half of an OAM tile
OAMData_700fe: ; 700fe (1c:40fe)
	db $68,$30
	db $68,$40
	db $68,$58
	db $68,$78

OAMData_70106: ; 70106 (1c:4106)
	db $68,$38
	db $68,$48
	db $68,$60
	db $68,$70

OAMData_7010e: ; 7010e (1c:410e)
	db $68,$34
	db $68,$4C
	db $68,$54
	db $68,$64

OAMData_70116: ; 70116 (1c:4116)
	db $68,$3C
	db $68,$5C
	db $68,$6C
	db $68,$74

OAMData_7011e: ; 7011e (1c:411e)
	db $FF

Func_7011f: ; 7011f (1c:411f)
	ld b, $8
.asm_70121
	ld hl, $c35c
	ld a, [wWhichTrade] ; $cd3d
	ld de, $fffc
	ld c, a
.asm_7012b
	inc [hl]
	add hl, de
	dec c
	jr nz, .asm_7012b
	ld a, [rOBP1] ; $ff49
	xor $a0
	ld [rOBP1], a ; $ff49
	ld c, $3
	call CheckForUserInterruption
	ret c
	dec b
	jr nz, .asm_70121
	ret

GameFreakLogoOAMData: ; 70140 (1c:4140)
	db $48,$50,$8D,$00
	db $48,$58,$8E,$00
	db $50,$50,$8F,$00
	db $50,$58,$90,$00
	db $58,$50,$91,$00
	db $58,$58,$92,$00
	db $60,$30,$80,$00
	db $60,$38,$81,$00
	db $60,$40,$82,$00
	db $60,$48,$83,$00
	db $60,$50,$93,$00
	db $60,$58,$84,$00
	db $60,$60,$85,$00
	db $60,$68,$83,$00
	db $60,$70,$81,$00
	db $60,$78,$86,$00

GameFreakShootingStarOAMData: ; 70180 (1c:4180)
	db $00,$A0,$A0,$10
	db $00,$A8,$A0,$30
	db $08,$A0,$A1,$10
	db $08,$A8,$A1,$30

FallingStar: ; 70190 (1c:4190)
	INCBIN "gfx/falling_star.2bpp"

AnimateHallOfFame: ; 701a0 (1c:41a0)
	call Func_70423
	call ClearScreen
	ld c, $64
	call DelayFrames
	call LoadFontTilePatterns
	call LoadTextBoxTilePatterns
	call DisableLCD
	ld hl, $9800
	ld bc, $800
	ld a, $7f
	call FillMemory
	call EnableLCD
	ld hl, rLCDC ; $ff40
	set 3, [hl]
	xor a
	ld hl, $cc5b
	ld bc, $60
	call FillMemory
	xor a
	ld [$cfcb], a
	ld [$ffd7], a
	ld [W_SPRITEFLIPPED], a
	ld [$d358], a
	ld [$cd40], a
	inc a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld hl, $d5a2
	ld a, [hl]
	inc a
	jr z, .asm_701eb
	inc [hl]
.asm_701eb
	ld a, $90
	ld [$ffb0], a
	ld c, BANK(Music_HallOfFame)
	ld a, MUSIC_HALL_OF_FAME
	call PlayMusic
	ld hl, W_PARTYMON1 ; $d164
	ld c, $ff
.asm_701fb
	ld a, [hli]
	cp $ff
	jr z, .asm_70241
	inc c
	push hl
	push bc
	ld [wWhichTrade], a ; $cd3d
	ld a, c
	ld [$cd3e], a
	ld hl, W_PARTYMON1_LEVEL ; $d18c
	ld bc, $2c
	call AddNTimes
	ld a, [hl]
	ld [$cd3f], a
	call Func_70278
	call Func_702e1
	ld c, $50
	call DelayFrames
	FuncCoord 2, 13 ; $c4a6
	ld hl, Coord
	ld b, $3
	ld c, $e
	call TextBoxBorder
	FuncCoord 4, 15 ; $c4d0
	ld hl, Coord
	ld de, HallOfFameText
	call PlaceString
	ld c, $b4
	call DelayFrames
	call GBFadeOut2
	pop bc
	pop hl
	jr .asm_701fb
.asm_70241
	ld a, c
	inc a
	ld hl, $cc5b
	ld bc, $10
	call AddNTimes
	ld [hl], $ff
	call Func_73b0d
	xor a
	ld [wWhichTrade], a ; $cd3d
	inc a
	ld [$cd40], a
	call Func_70278
	call Func_70377
	call Func_70423
	xor a
	ld [$ffb0], a
	ld hl, rLCDC ; $ff40
	res 3, [hl]
	ret

HallOfFameText: ; 7026b (1c:426b)
	db "HALL OF FAME@"

Func_70278: ; 70278 (1c:4278)
	call ClearScreen
	ld a, $d0
	ld [$ffaf], a
	ld a, $c0
	ld [$ffae], a
	ld a, [wWhichTrade] ; $cd3d
	ld [$cf91], a
	ld [$d0b5], a
	ld [$cfd9], a
	ld [$cf1d], a
	ld a, [$cd40]
	and a
	jr z, .asm_7029d
	call Func_7033e
	jr .asm_702ab
.asm_7029d
	FuncCoord 12, 5 ; $c410
	ld hl, Coord
	call GetMonHeader
	call LoadFrontSpriteByMonIndex
	ld a, $4
	call Predef ; indirect jump to LoadMonBackSprite (3f103 (f:7103))
.asm_702ab
	ld b, $b
	ld c, $0
	call GoPAL_SET
	ld a, $e4
	ld [rBGP], a ; $ff47
	ld c, $31
	call Func_7036d
	ld d, $a0
	ld e, $4
	ld a, [$cf1b]
	and a
	jr z, .asm_702c7
	sla e
.asm_702c7
	call .asm_702d5
	xor a
	ld [$ffaf], a
	ld c, a
	call Func_7036d
	ld d, $0
	ld e, $fc
.asm_702d5
	call DelayFrame
	ld a, [$ffae]
	add e
	ld [$ffae], a
	cp d
	jr nz, .asm_702d5
	ret

Func_702e1: ; 702e1 (1c:42e1)
	ld a, [$cd3e]
	ld hl, W_PARTYMON1NAME ; $d2b5
	call GetPartyMonName
	call Func_702f0
	jp Func_70404

Func_702f0: ; 702f0 (1c:42f0)
	FuncCoord 0, 2 ; $c3c8
	ld hl, Coord
	ld b, $9
	ld c, $a
	call TextBoxBorder
	FuncCoord 2, 6 ; $c41a
	ld hl, Coord
	ld de, HoFMonInfoText
	call PlaceString
	FuncCoord 1, 4 ; $c3f1
	ld hl, Coord
	ld de, $cd6d
	call PlaceString
	ld a, [$cd3f]
	FuncCoord 8, 7 ; $c434
	ld hl, Coord
	call PrintLevelCommon
	ld a, [wWhichTrade] ; $cd3d
	ld [$d0b5], a
	FuncCoord 3, 9 ; $c457
	ld hl, Coord
	ld a, $4b
	call Predef ; indirect jump to Func_27d6b (27d6b (9:7d6b))
	ld a, [wWhichTrade] ; $cd3d
	jp PlayCry

HoFMonInfoText: ; 70329 (1c:4329)
	db   "LEVEL/"
	next "TYPE1/"
	next "TYPE2/@"

Func_7033e: ; 7033e (1c:433e)
	ld de, RedPicFront ; $6ede
	ld a, BANK(RedPicFront)
	call UncompressSpriteFromDE
	ld hl, S_SPRITEBUFFER1
	ld de, $a000
	ld bc, $310
	call CopyData
	ld de, $9000
	call InterlaceMergeSpriteBuffers
	ld de, RedPicBack ; $7e0a
	ld a, BANK(RedPicBack)
	call UncompressSpriteFromDE
	ld a, $3
	call Predef ; indirect jump to ScaleSpriteByTwo (2fe40 (b:7e40))
	ld de, $9310
	call InterlaceMergeSpriteBuffers
	ld c, $1

Func_7036d: ; 7036d (1c:436d)
	ld b, $0
	FuncCoord 12, 5 ; $c410
	ld hl, Coord
	ld a, $31
	jp Predef ; indirect jump to Func_79dda (79dda (1e:5dda))

Func_70377: ; 70377 (1c:4377)
	ld hl, $d747
	set 3, [hl]
	ld a, $56
	call Predef ; indirect jump to DisplayDexRating (44169 (11:4169))
	FuncCoord 0, 4 ; $c3f0
	ld hl, Coord
	ld b, $6
	ld c, $a
	call TextBoxBorder
	FuncCoord 5, 0 ; $c3a5
	ld hl, Coord
	ld b, $2
	ld c, $9
	call TextBoxBorder
	FuncCoord 7, 2 ; $c3cf
	ld hl, Coord
	ld de, W_PLAYERNAME ; $d158
	call PlaceString
	FuncCoord 1, 6 ; $c419
	ld hl, Coord
	ld de, HoFPlayTimeText
	call PlaceString
	FuncCoord 5, 7 ; $c431
	ld hl, Coord
	ld de, $da41
	ld bc, $103
	call PrintNumber
	ld [hl], $6d
	inc hl
	ld de, $da43
	ld bc, $8102
	call PrintNumber
	FuncCoord 1, 9 ; $c455
	ld hl, Coord
	ld de, HoFMoneyText
	call PlaceString
	FuncCoord 4, 10 ; $c46c
	ld hl, Coord
	ld de, wPlayerMoney ; $d347
	ld c, $a3
	call PrintBCDNumber
	ld hl, DexSeenOwnedText
	call Func_703e2
	ld hl, DexRatingText
	call Func_703e2
	ld hl, $cc5d

Func_703e2: ; 703e2 (1c:43e2)
	call PrintText
	ld c, $78
	jp DelayFrames

HoFPlayTimeText: ; 703ea (1c:43ea)
	db "PLAY TIME@"

HoFMoneyText: ; 703f4 (1c:43f4)
	db "MONEY@"

DexSeenOwnedText: ; 703fa (1c:43fa)
	TX_FAR _DexSeenOwnedText
	db "@"

DexRatingText: ; 703ff (1c:43ff)
	TX_FAR _DexRatingText
	db "@"

Func_70404: ; 70404 (1c:4404)
	ld hl, $cc5b
	ld bc, $10
	ld a, [$cd3e]
	call AddNTimes
	ld a, [wWhichTrade] ; $cd3d
	ld [hli], a
	ld a, [$cd3f]
	ld [hli], a
	ld e, l
	ld d, h
	ld hl, $cd6d
	ld bc, $b
	jp CopyData

Func_70423: ; 70423 (1c:4423)
	ld a, $a
	ld [$cfc8], a
	ld [$cfc9], a
	ld a, $ff
	ld [wMusicHeaderPointer], a
	jp GBFadeOut2

AnimateHealingMachine: ; 70433 (1c:4433)
	ld de, PokeCenterFlashingMonitorAndHealBall ; $44b7
	ld hl, $87c0
	ld bc, (BANK(PokeCenterFlashingMonitorAndHealBall) << 8) + $03
	call CopyVideoData
	ld hl, $cfcb
	ld a, [hl]
	push af
	ld [hl], $ff
	push hl
	ld a, [rOBP1] ; $ff49
	push af
	ld a, $e0
	ld [rOBP1], a ; $ff49
	ld hl, $c384
	ld de, PokeCenterOAMData ; $44d7
	call Func_70503
	ld a, $4
	ld [wMusicHeaderPointer], a
	ld a, $ff
	ld [$c0ee], a
	call PlaySound
.asm_70464
	ld a, [wMusicHeaderPointer]
	and a
	jr nz, .asm_70464
	ld a, [W_NUMINPARTY] ; $d163
	ld b, a
.asm_7046e
	call Func_70503
	ld a, (SFX_02_4a - SFX_Headers_02) / 3
	call PlaySound
	ld c, $1e
	call DelayFrames
	dec b
	jr nz, .asm_7046e
	ld a, [$c0ef]
	cp $1f
	ld [$c0f0], a
	jr nz, .asm_70495
	ld a, $ff
	ld [$c0ee], a
	call PlaySound
	ld a, Bank(Func_9876)
	ld [$c0ef], a
.asm_70495
	ld a, MUSIC_PKMN_HEALED
	ld [$c0ee], a
	call PlaySound
	ld d, $28
	call Func_704f3
.asm_704a2
	ld a, [$c026]
	cp MUSIC_PKMN_HEALED
	jr z, .asm_704a2
	ld c, $20
	call DelayFrames
	pop af
	ld [rOBP1], a ; $ff49
	pop hl
	pop af
	ld [hl], a
	jp UpdateSprites

PokeCenterFlashingMonitorAndHealBall: ; 704b7 (1c:44b7)
	INCBIN "gfx/pokecenter_ball.2bpp"

PokeCenterOAMData: ; 704d7 (1c:44d7)
	db $24,$34,$7C,$10 ; heal machine monitor
	db $2B,$30,$7D,$10 ; pokeballs 1-6
	db $2B,$38,$7D,$30
	db $30,$30,$7D,$10
	db $30,$38,$7D,$30
	db $35,$30,$7D,$10
	db $35,$38,$7D,$30

Func_704f3: ; 704f3 (1c:44f3)
	ld b, $8
.asm_704f5
	ld a, [rOBP1] ; $ff49
	xor d
	ld [rOBP1], a ; $ff49
	ld c, $a
	call DelayFrames
	dec b
	jr nz, .asm_704f5
	ret

Func_70503: ; 70503 (1c:4503)
	ld a, [de]
	inc de
	ld [hli], a
	ld a, [de]
	inc de
	ld [hli], a
	ld a, [de]
	inc de
	ld [hli], a
	ld a, [de]
	inc de
	ld [hli], a
	ret

Func_70510: ; 70510 (1c:4510)
	call Func_706ef
	ld a, $ec
	ld [$c104], a
	call Delay3
	push hl
	call GBFadeIn2
	ld hl, W_FLAGS_D733
	bit 7, [hl]
	res 7, [hl]
	jr nz, .asm_70568
	ld a, (SFX_02_4c - SFX_Headers_02) / 3
	call PlaySound
	ld hl, $d732
	bit 4, [hl]
	res 4, [hl]
	pop hl
	jr nz, .asm_7055e
	call Func_705aa
	ld a, (SFX_02_4f - SFX_Headers_02) / 3
	call PlaySound
	call Func_70787
	ld a, b
	and a
	jr nz, .asm_7055b
	ld hl, wWhichTrade ; $cd3d
	xor a
	ld [hli], a
	inc a
	ld [hli], a
	ld a, $8
	ld [hli], a
	ld [hl], $ff
	ld hl, $cd48
	call Func_70730
.asm_70558
	call Func_2307
.asm_7055b
	jp Func_70772
.asm_7055e
	ld c, $32
	call DelayFrames
	call Func_705aa
	jr .asm_7055b
.asm_70568
	pop hl
	ld de, BirdSprite ; $4d80
	ld hl, $8000
	ld bc, (BANK(BirdSprite) << 8) + $0c
	call CopyVideoData
	call Func_706d7
	ld a, (SFX_02_50 - SFX_Headers_02) / 3
	call PlaySound
	ld hl, wWhichTrade ; $cd3d
	xor a
	ld [hli], a
	ld a, $c
	ld [hli], a
	ld [hl], $8
	ld de, FlyAnimationEnterScreenCoords ; $4592
	call Func_706ae
	call LoadPlayerSpriteGraphics
	jr .asm_70558

FlyAnimationEnterScreenCoords: ; 70592 (1c:4592)
; y, x pairs
; This is the sequence of screen coordinates used by the overworld
; Fly animation when the player is entering a map.
	db $05, $98
	db $0F, $90
	db $18, $88
	db $20, $80
	db $27, $78
	db $2D, $70
	db $32, $68
	db $36, $60
	db $39, $58
	db $3B, $50
	db $3C, $48
	db $3C, $40

Func_705aa: ; 705aa (1c:45aa)
	ld hl, wWhichTrade ; $cd3d
	ld a, $10
	ld [hli], a
	ld a, $3c
	ld [hli], a
	call Func_7077f
	ld [hl], a
	jp Func_70755

_DoFlyOrTeleportAwayGraphics: ; 705ba (1c:45ba)
	call Func_706ef
	call Func_70787
	ld a, b
	and a
	jr z, .asm_705ef
	dec a
	jp nz, Func_7067d
.asm_705c8
	ld a, (SFX_02_4b - SFX_Headers_02) / 3
	call PlaySound
	ld hl, wWhichTrade ; $cd3d
	ld a, $f0
	ld [hli], a
	ld a, $ec
	ld [hli], a
	call Func_7077f
	ld [hl], a
	call Func_70755
	call Func_70787
	ld a, b
	dec a
	jr z, .asm_705e9
	ld c, $a
	call DelayFrames
.asm_705e9
	call GBFadeOut2
	jp Func_70772
.asm_705ef
	ld a, $4
	call StopMusic
	ld a, [$d732]
	bit 6, a
	jr z, .asm_70610
	ld hl, wWhichTrade ; $cd3d
	ld a, $10
	ld [hli], a
	ld a, $ff
	ld [hli], a
	xor a
	ld [hli], a
	ld [hl], $a1
	ld hl, $cd48
	call Func_70730
	jr .asm_705c8
.asm_70610
	call Func_706d7
	ld hl, wWhichTrade ; $cd3d
	ld a, $ff
	ld [hli], a
	ld a, $8
	ld [hli], a
	ld [hl], $c
	call Func_706ae
	ld a, (SFX_02_50 - SFX_Headers_02) / 3
	call PlaySound
	ld hl, wWhichTrade ; $cd3d
	xor a
	ld [hli], a
	ld a, $c
	ld [hli], a
	ld [hl], $c
	ld de, FlyAnimationScreenCoords1 ; $464f
	call Func_706ae
	ld c, $28
	call DelayFrames
	ld hl, $cd3e
	ld a, $b
	ld [hli], a
	ld [hl], $8
	ld de, FlyAnimationScreenCoords2 ; $4667
	call Func_706ae
	call GBFadeOut2
	jp Func_70772

FlyAnimationScreenCoords1: ; 7064f (1c:464f)
; y, x pairs
; This is the sequence of screen coordinates used by the first part
; of the Fly overworld animation.
	db $3C, $48
	db $3C, $50
	db $3B, $58
	db $3A, $60
	db $39, $68
	db $37, $70
	db $37, $78
	db $33, $80
	db $30, $88
	db $2D, $90
	db $2A, $98
	db $27, $A0

FlyAnimationScreenCoords2: ; 70667 (1c:4667)
; y, x pairs
; This is the sequence of screen coordinates used by the second part
; of the Fly overworld animation.
	db $1A, $90
	db $19, $80
	db $17, $70
	db $15, $60
	db $12, $50
	db $0F, $40
	db $0C, $30
	db $09, $20
	db $05, $10
	db $00, $00

	db $F0, $00

Func_7067d: ; 7067d (1c:467d)
	ld a, $ff
	ld [$cfcb], a
	ld a, [$c302]
	ld [$c30a], a
	ld a, [$c306]
	ld [$c30e], a
	ld a, $a0
	ld [wOAMBuffer], a
	ld [$c304], a
	ld c, $2
	call DelayFrames
	ld a, $a0
	ld [$c308], a
	ld [$c30c], a
	call GBFadeOut2
	ld a, $1
	ld [$cfcb], a
	jp Func_70772

Func_706ae: ; 706ae (1c:46ae)
	ld a, [$cd3f]
	xor $1
	ld [$cd3f], a
	ld [$c102], a
	call Delay3
	ld a, [wWhichTrade] ; $cd3d
	cp $ff
	jr z, .asm_706cd
	ld hl, $c104
	ld a, [de]
	inc de
	ld [hli], a
	inc hl
	ld a, [de]
	inc de
	ld [hl], a
.asm_706cd
	ld a, [$cd3e]
	dec a
	ld [$cd3e], a
	jr nz, Func_706ae
	ret

Func_706d7: ; 706d7 (1c:46d7)
	ld de, BirdSprite ; $4d80
	ld hl, $8000
	ld bc, (BANK(BirdSprite) << 8) + $0c
	call CopyVideoData
	ld de, BirdSprite + $c0 ; $4e40 ; moving amination sprite
	ld hl, $8800
	ld bc, (BANK(BirdSprite) << 8) + $0c
	jp CopyVideoData

Func_706ef: ; 706ef (1c:46ef)
	ld a, [$c102]
	ld [$cd50], a
	ld a, [$c104]
	ld [$cd4f], a
	ld hl, PlayerSpinningFacingOrder ; $4713
	ld de, $cd48
	ld bc, $4
	call CopyData
	ld a, [$c102]
	ld hl, $cd48
.asm_7070d
	cp [hl]
	inc hl
	jr nz, .asm_7070d
	dec hl
	ret

PlayerSpinningFacingOrder: ; 70713 (1c:4713)
; The order of the direction the player's sprite is facing when teleporting
; away. Creates a spinning effect.
	db $00, $08, $04, $0C ; down, left, up, right

Func_70717: ; 70717 (1c:4717)
	ld a, [hl]
	ld [$c102], a
	push hl
	ld hl, $cd48
	ld de, $cd47
	ld bc, $4
	call CopyData
	ld a, [$cd47]
	ld [$cd4b], a
	pop hl
	ret

Func_70730: ; 70730 (1c:4730)
	call Func_70717
	ld a, [wWhichTrade] ; $cd3d
	ld c, a
	and $3
	jr nz, .asm_70743
	ld a, [$cd40]
	cp $ff
	call nz, PlaySound
.asm_70743
	ld a, [$cd3e]
	add c
	ld [wWhichTrade], a ; $cd3d
	ld c, a
	ld a, [$cd3f]
	cp c
	ret z
	call DelayFrames
	jr Func_70730

Func_70755: ; 70755 (1c:4755)
	call Func_70717
	ld a, [wWhichTrade] ; $cd3d
	ld c, a
	ld a, [$c104]
	add c
	ld [$c104], a
	ld c, a
	ld a, [$cd3e]
	cp c
	ret z
	ld a, [$cd3f]
	ld c, a
	call DelayFrames
	jr Func_70755

Func_70772: ; 70772 (1c:4772)
	ld a, [$cd4f]
	ld [$c104], a
	ld a, [$cd50]
	ld [$c102], a
	ret

Func_7077f: ; 7077f (1c:477f)
	ld a, [$cf1b]
	xor $1
	inc a
	inc a
	ret

Func_70787: ; 70787 (1c:4787)
	ld b, 0
	ld hl, DataTable_707a9 ; $47a9
	ld a, [W_CURMAPTILESET] ; $d367
	ld c, a
.asm_70790
	ld a, [hli]
	cp $ff
	jr z, .asm_707a4
	cp c
	jr nz, .asm_7079e
	FuncCoord 8, 9 ; $c45c
	ld a, [Coord]
	cp [hl]
	jr z, .asm_707a2
.asm_7079e
	inc hl
	inc hl
	jr .asm_70790
.asm_707a2
	inc hl
	ld b, [hl]
.asm_707a4
	ld a, b
	ld [$cd5b], a
	ret

; format: db tileset id, tile id, value to be put in $cd5b
DataTable_707a9: ; 707a9 (1c:47a9)
	db FACILITY, $20, 1 ; warp pad
	db FACILITY, $11, 2 ; hole
	db CAVERN,   $22, 2 ; hole
	db INTERIOR, $55, 1 ; warp pad
	db $FF

Func_707b6: ; 707b6 (1c:47b6)
	ld c, $a
	call DelayFrames
	ld hl, $d736
	set 6, [hl]
	ld de, RedSprite ; $4180
	ld hl, $8000
	ld bc, (BANK(RedSprite) << 8) + $0c
	call CopyVideoData
	ld a, $4
	ld hl, RedFishingTiles ; $4866
	call Func_71771
	ld a, [$c102]
	ld c, a
	ld b, $0
	ld hl, FishingRodGfxProperties ; $4856
	add hl, bc
	ld de, $c39c
	ld bc, $4
	call CopyData
	ld c, $64
	call DelayFrames
	ld a, [wWhichTrade] ; $cd3d
	and a
	ld hl, NoNibbleText
	jr z, .asm_70836
	cp $2
	ld hl, NothingHereText
	jr z, .asm_70836
	ld b, $a
.asm_707fe
	ld hl, $c104
	call Func_70842
	ld hl, $c39c
	call Func_70842
	call Delay3
	dec b
	jr nz, .asm_707fe
	ld a, [$c102]
	cp $4
	jr nz, .asm_7081c
	ld a, $a0
	ld [$c39c], a
.asm_7081c
	ld hl, $cd4f
	xor a
	ld [hli], a
	ld [hl], a
	ld a, $4c
	call Predef ; indirect jump to PrintEmotionBubble (17c47 (5:7c47))
	ld a, [$c102]
	cp $4
	jr nz, .asm_70833
	ld a, $44
	ld [$c39c], a
.asm_70833
	ld hl, ItsABiteText
.asm_70836
	call PrintText
	ld hl, $d736
	res 6, [hl]
	call LoadFontTilePatterns
	ret

Func_70842: ; 70842 (1c:4842)
	ld a, [hl]
	xor $1
	ld [hl], a
	ret

NoNibbleText: ; 70847 (1c:4847)
	TX_FAR _NoNibbleText
	db "@"

NothingHereText: ; 7084c (1c:484c)
	TX_FAR _NothingHereText
	db "@"

ItsABiteText: ; 70851 (1c:4851)
	TX_FAR _ItsABiteText
	db "@"

FishingRodGfxProperties: ; 70856 (1c:4856)
; specicies how the fishing rod should be drawn on the screen
; first byte = screen y coordinate
; second byte = screen x coordinate
; third byte = tile number
; fourth byte = sprite properties
	db $5B, $4C, $FD, $00 ; player facing down
	db $44, $4C, $FD, $00 ; player facing up
	db $50, $40, $FE, $00 ; player facing left
	db $50, $58, $FE, $20 ; player facing right ($20 means "horizontally flip the tile")

RedFishingTiles: ; 70866 (1c:4866)
	dw RedFishingTilesFront
	db $02, $1E
	dw $8020

	dw RedFishingTilesBack
	db $02, $1E
	dw $8060

	dw RedFishingTilesSide
	db $02, $1E
	dw $80A0

	dw RedFishingRodTiles
	db $03, $1E
	dw $8FD0

_HandleMidJump: ; 7087e (1c:487e)
	ld a, [$d714]
	ld c, a
	inc a
	cp $10
	jr nc, .asm_70895
	ld [$d714], a
	ld b, $0
	ld hl, PlayerJumpingYScreenCoords ; $48ba
	add hl, bc
	ld a, [hl]
	ld [$c104], a ; player's sprite y coordinate
	ret
.asm_70895
	ld a, [wWalkCounter] ; $cfc5
	cp $0
	ret nz
	call UpdateSprites
	call Delay3
	xor a
	ld [H_CURRENTPRESSEDBUTTONS], a
	ld [H_NEWLYPRESSEDBUTTONS], a
	ld [H_NEWLYRELEASEDBUTTONS], a
	ld [$d714], a
	ld hl, $d736
	res 6, [hl]
	ld hl, $d730
	res 7, [hl]
	xor a
	ld [wJoypadForbiddenButtonsMask], a
	ret

PlayerJumpingYScreenCoords: ; 708ba (1c:48ba)
; Sequence of y screen coordinates for player's sprite when jumping over a ledge.
	db $38, $36, $34, $32, $31, $30, $30, $30, $31, $32, $33, $34, $36, $38, $3C, $3C


Func_708ca: ; 708ca (1c:48ca)
	ld a, $e4
	ld [rOBP1], a ; $ff49
	call Func_7092a
	FuncCoord 12, 0 ; $c3ac
	ld hl, Coord
	ld bc, $707
	call ClearScreenArea
	call Delay3
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, $91
	ld [$cee9], a
	ld a, $1
	ld [H_WHOSETURN], a ; $fff3
	callab Func_79793
	ld d, $80
	call Func_704f3
.asm_708f6
	ld c, $a
	call DelayFrames
	ld a, [rOBP1] ; $ff49
	sla a
	sla a
	ld [rOBP1], a ; $ff49
	jr nz, .asm_708f6
	call CleanLCD_OAM
	call Func_7092a
	ld b, $e4
.asm_7090d
	ld c, $a
	call DelayFrames
	ld a, [rOBP1] ; $ff49
	srl b
	rra
	srl b
	rra
	ld [rOBP1], a ; $ff49
	ld a, b
	and a
	jr nz, .asm_7090d
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Delay3
	jp CleanLCD_OAM

Func_7092a: ; 7092a (1c:492a)
	ld de, $9000
	ld hl, $8000
	ld bc, $31
	call CopyVideoData
	ld a, $10
	ld [W_BASECOORDY], a ; $d082
	ld a, $70
	ld [W_BASECOORDX], a ; $d081
	ld hl, wOAMBuffer
	ld bc, $606
	ld d, $8
.asm_70948
	push bc
	ld a, [W_BASECOORDY] ; $d082
	ld e, a
.asm_7094d
	ld a, e
	add $8
	ld e, a
	ld [hli], a
	ld a, [W_BASECOORDX] ; $d081
	ld [hli], a
	ld a, d
	ld [hli], a
	ld a, $10
	ld [hli], a
	inc d
	dec c
	jr nz, .asm_7094d
	inc d
	ld a, [W_BASECOORDX] ; $d081
	add $8
	ld [W_BASECOORDX], a ; $d081
	pop bc
	dec b
	jr nz, .asm_70948
	ret

Func_7096d: ; 7096d (1c:496d)
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Delay3
	xor a
	ld [$ffb0], a
	dec a
	ld [$cfcb], a
	call DelayFrame
	ld hl, $c102
	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
	ld c, a
	ld b, $0
	ld de, $10
.asm_70989
	ld a, [hl]
	cp $ff
	jr z, .asm_7098f
	inc b
.asm_7098f
	add hl, de
	dec c
	jr nz, .asm_70989
	ld hl, $c310
	ld c, $9
.asm_70998
	ld a, b
	swap a
	cp l
	jr z, .asm_709a9
	push hl
	push bc
	ld bc, $10
	xor a
	call FillMemory
	pop bc
	pop hl
.asm_709a9
	ld de, $10
	add hl, de
	dec c
	jr nz, .asm_70998
	call Delay3
	call LoadBattleTransitionTile
	ld bc, $0
	ld a, [W_ISLINKBATTLE] ; $d12b
	cp $4
	jr z, .asm_709c9
	call Func_709e2
	call Func_709ef
	call Func_70a19
.asm_709c9
	ld hl, PointerTable_709d2 ; $49d2
	add hl, bc
	add hl, bc
	ld a, [hli]
	ld h, [hl]
	ld l, a
	jp [hl]

PointerTable_709d2: ; 709d2 (1c:49d2)
	dw Func_70d24
	dw Func_70a72
	dw Func_70ce4
	dw Func_70a72
	dw Func_70cb4
	dw Func_70b7f
	dw Func_70c7e
	dw Func_70bca

Func_709e2: ; 709e2 (1c:49e2)
	ld a, [W_CUROPPONENT] ; $d059
	cp $c8
	jr nc, .asm_709ec
	res 0, c
	ret
.asm_709ec
	set 0, c
	ret

Func_709ef: ; 709ef (1c:49ef)
	ld hl, W_PARTYMON1_HP ; $d16c
.asm_709f2
	ld a, [hli]
	or [hl]
	jr nz, .asm_709fc
	ld de, $2b
	add hl, de
	jr .asm_709f2
.asm_709fc
	ld de, $1f
	add hl, de
	ld a, [hl]
	add $3
	ld e, a
	ld a, [W_CURENEMYLVL] ; $d127
	sub e
	jr nc, .asm_70a12
	res 1, c
	ld a, $1
	ld [$cd47], a
	ret
.asm_70a12
	set 1, c
	xor a
	ld [$cd47], a
	ret

Func_70a19: ; 70a19 (1c:4a19)
	ld a, [W_CURMAP] ; $d35e
	ld e, a
	ld hl, MapIDList_70a3f ; $4a3f
.asm_70a20
	ld a, [hli]
	cp $ff
	jr z, .asm_70a2b
	cp e
	jr nz, .asm_70a20
.asm_70a28
	set 2, c
	ret
.asm_70a2b
	ld hl, MapIDList_70a44 ; $4a44
.asm_70a2e
	ld a, [hli]
	cp $ff
	jr z, .asm_70a3c
	ld d, a
	ld a, [hli]
	cp e
	jr c, .asm_70a2e
	ld a, e
	cp d
	jr nc, .asm_70a28
.asm_70a3c
	res 2, c
	ret

; Func_70a19 checks if W_CURMAP is equal to one of these maps
MapIDList_70a3f: ; 70a3f (1c:4a3f)
	db VIRIDIAN_FOREST
	db ROCK_TUNNEL_1
	db SEAFOAM_ISLANDS_1
	db ROCK_TUNNEL_2
	db $FF

; Func_70a19 checks if W_CURMAP is in between or equal to each pair of maps
MapIDList_70a44: ; 70a44 (1c:4a44)
	; all MT_MOON maps
	db MT_MOON_1
	db MT_MOON_3

	; all SS_ANNE maps, VICTORY_ROAD_1, LANCES_ROOM, and HALL_OF_FAME
	db SS_ANNE_1
	db HALL_OF_FAME

	; all POKEMONTOWER maps and Lavender Town buildings
	db LAVENDER_POKECENTER
	db LAVENDER_HOUSE_2

	; all SILPH_CO, MANSION, SAFARI_ZONE, and UNKNOWN_DUNGEON maps,
	; except for SILPH_CO_1F
	db SILPH_CO_2F
	db UNKNOWN_DUNGEON_1
	db $FF

LoadBattleTransitionTile: ; 70a4d (1c:4a4d)
	ld hl, $8ff0
	ld de, BattleTransitionTile ; $4a59
	ld bc, (BANK(BattleTransitionTile) << 8) + $01
	jp CopyVideoData

BattleTransitionTile: ; 70a59 (1c:4a59)
	INCBIN "gfx/battle_transition.2bpp"

Func_70a69: ; 70a69 (1c:4a69)
	ld a, $ff
	ld [rBGP], a ; $ff47
	ld [rOBP0], a ; $ff48
	ld [rOBP1], a ; $ff49
	ret

Func_70a72: ; 70a72 (1c:4a72)
	ld a, [$cd47]
	and a
	jr z, .asm_70a7d
	call Func_70aaa
	jr .asm_70a9f
.asm_70a7d
	FuncCoord 10, 10 ; $c472
	ld hl, Coord
	ld a, $3
	ld [$d09f], a
	ld a, l
	ld [$d09b], a
	ld a, h
	ld [$d09a], a
	ld b, $78
.asm_70a8f
	ld c, $3
.asm_70a91
	push bc
	call Func_70af9
	pop bc
	dec c
	jr nz, .asm_70a91
	call DelayFrame
	dec b
	jr nz, .asm_70a8f
.asm_70a9f
	call Func_70a69
	xor a
	ld [$d09b], a
	ld [$d09a], a
	ret

Func_70aaa: ; 70aaa (1c:4aaa)
	ld a, $7
	ld [wWhichTrade], a ; $cd3d
	ld hl, wTileMap
	ld c, $11
	ld de, $14
	call Func_70ae0
	inc c
	jr .asm_70ac3
.asm_70abd
	ld de, $14
	call Func_70ae0
.asm_70ac3
	inc c
	ld de, $1
	call Func_70ae0
	dec c
	dec c
	ld de, $ffec
	call Func_70ae0
	inc c
	ld de, rIE ; $ffff
	call Func_70ae0
	dec c
	dec c
	ld a, c
	and a
	jr nz, .asm_70abd
	ret

Func_70ae0: ; 70ae0 (1c:4ae0)
	push bc
.asm_70ae1
	ld [hl], $ff
	add hl, de
	push bc
	ld a, [wWhichTrade] ; $cd3d
	dec a
	jr nz, .asm_70af0
	call Func_70d19
	ld a, $7
.asm_70af0
	ld [wWhichTrade], a ; $cd3d
	pop bc
	dec c
	jr nz, .asm_70ae1
	pop bc
	ret

Func_70af9: ; 70af9 (1c:4af9)
	ld bc, $ffec
	ld de, $14
	ld a, [$d09b]
	ld l, a
	ld a, [$d09a]
	ld h, a
	ld a, [$d09f]
	cp $0
	jr z, .asm_70b25
	cp $1
	jr z, .asm_70b2f
	cp $2
	jr z, .asm_70b39
	cp $3
	jr z, .asm_70b43
.asm_70b1a
	ld [hl], $ff
.asm_70b1c
	ld a, l
	ld [$d09b], a
	ld a, h
	ld [$d09a], a
	ret
.asm_70b25
	dec hl
	ld a, [hl]
	cp $ff
	jr nz, .asm_70b4d
	inc hl
	add hl, bc
	jr .asm_70b1a
.asm_70b2f
	add hl, de
	ld a, [hl]
	cp $ff
	jr nz, .asm_70b4d
	add hl, bc
	dec hl
	jr .asm_70b1a
.asm_70b39
	inc hl
	ld a, [hl]
	cp $ff
	jr nz, .asm_70b4d
	dec hl
	add hl, de
	jr .asm_70b1a
.asm_70b43
	add hl, bc
	ld a, [hl]
	cp $ff
	jr nz, .asm_70b4d
	add hl, de
	inc hl
	jr .asm_70b1a
.asm_70b4d
	ld [hl], $ff
	ld a, [$d09f]
	inc a
	cp $4
	jr nz, .asm_70b58
	xor a
.asm_70b58
	ld [$d09f], a
	jr .asm_70b1c

Func_70b5d: ; 70b5d (1c:4b5d)
	ld hl, DataTable_70b72 ; $4b72
.asm_70b60
	ld a, [hli]
	cp $1
	jr z, .asm_70b6e
	ld [rBGP], a ; $ff47
	ld c, $2
	call DelayFrames
	jr .asm_70b60
.asm_70b6e
	dec b
	jr nz, Func_70b5d
	ret

DataTable_70b72: ; 70b72 (1c:4b72)
	db $F9,$FE,$FF,$FE,$F9,$E4,$90,$40,$00,$40,$90,$E4
	db $01 ; terminator

Func_70b7f: ; 70b7f (1c:4b7f)
	ld c, $9
.asm_70b81
	push bc
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	FuncCoord 0, 7 ; $c42c
	ld hl, Coord
	FuncCoord 0, 8 ; $c440
	ld de, Coord
	ld bc, $ffd8
	call Func_70c12
	FuncCoord 0, 10 ; $c468
	ld hl, Coord
	FuncCoord 0, 9 ; $c454
	ld de, Coord
	ld bc, $28
	call Func_70c12
	FuncCoord 8, 0 ; $c3a8
	ld hl, Coord
	FuncCoord 9, 0 ; $c3a9
	ld de, Coord
	ld bc, $fffe
	call Func_70c3f
	FuncCoord 11, 0 ; $c3ab
	ld hl, Coord
	FuncCoord 10, 0 ; $c3aa
	ld de, Coord
	ld bc, $2
	call Func_70c3f
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld c, $6
	call DelayFrames
	pop bc
	dec c
	jr nz, .asm_70b81
	call Func_70a69
	ld c, $a
	jp DelayFrames

Func_70bca: ; 70bca (1c:4bca)
	ld c, $9
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
.asm_70bcf
	push bc
	FuncCoord 0, 16 ; $c4e0
	ld hl, Coord
	FuncCoord 0, 17 ; $c4f4
	ld de, Coord
	ld bc, $ffd8
	call Func_70c12
	FuncCoord 0, 1 ; $c3b4
	ld hl, Coord
	ld de, wTileMap
	ld bc, $28
	call Func_70c12
	FuncCoord 18, 0 ; $c3b2
	ld hl, Coord
	FuncCoord 19, 0 ; $c3b3
	ld de, Coord
	ld bc, $fffe
	call Func_70c3f
	FuncCoord 1, 0 ; $c3a1
	ld hl, Coord
	ld de, wTileMap
	ld bc, $2
	call Func_70c3f
	call Func_70d19
	call Delay3
	pop bc
	dec c
	jr nz, .asm_70bcf
	call Func_70a69
	ld c, $a
	jp DelayFrames

Func_70c12: ; 70c12 (1c:4c12)
	ld a, c
	ld [wWhichTrade], a ; $cd3d
	ld a, b
	ld [$cd3e], a
	ld c, $8
.asm_70c1c
	push bc
	push hl
	push de
	ld bc, $14
	call CopyData
	pop hl
	pop de
	ld a, [wWhichTrade] ; $cd3d
	ld c, a
	ld a, [$cd3e]
	ld b, a
	add hl, bc
	pop bc
	dec c
	jr nz, .asm_70c1c
	ld l, e
	ld h, d
	ld a, $ff
	ld c, $14
.asm_70c3a
	ld [hli], a
	dec c
	jr nz, .asm_70c3a
	ret

Func_70c3f: ; 70c3f (1c:4c3f)
	ld a, c
	ld [wWhichTrade], a ; $cd3d
	ld a, b
	ld [$cd3e], a
	ld c, $9
.asm_70c49
	push bc
	push hl
	push de
	ld c, $12
.asm_70c4e
	ld a, [hl]
	ld [de], a
	ld a, e
	add $14
	jr nc, .asm_70c56
	inc d
.asm_70c56
	ld e, a
	ld a, l
	add $14
	jr nc, .asm_70c5d
	inc h
.asm_70c5d
	ld l, a
	dec c
	jr nz, .asm_70c4e
	pop hl
	pop de
	ld a, [wWhichTrade] ; $cd3d
	ld c, a
	ld a, [$cd3e]
	ld b, a
	add hl, bc
	pop bc
	dec c
	jr nz, .asm_70c49
	ld l, e
	ld h, d
	ld de, $14
	ld c, $12
.asm_70c77
	ld [hl], $ff
	add hl, de
	dec c
	jr nz, .asm_70c77
	ret

Func_70c7e: ; 70c7e (1c:4c7e)
	ld c, $12
	ld hl, wTileMap
	FuncCoord 1, 17 ; $c4f5
	ld de, Coord
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
.asm_70c89
	push bc
	push hl
	push de
	push de
	call Func_70caa
	pop hl
	call Func_70caa
	call Func_70d19
	pop hl
	ld bc, $ffec
	add hl, bc
	ld e, l
	ld d, h
	pop hl
	ld bc, $14
	add hl, bc
	pop bc
	dec c
	jr nz, .asm_70c89
	jp Func_70a69

Func_70caa: ; 70caa (1c:4caa)
	ld c, $a
.asm_70cac
	ld [hl], $ff
	inc hl
	inc hl
	dec c
	jr nz, .asm_70cac
	ret

Func_70cb4: ; 70cb4 (1c:4cb4)
	ld c, $14
	ld hl, wTileMap
	FuncCoord 19, 1 ; $c3c7
	ld de, Coord
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
.asm_70cbf
	push bc
	push hl
	push de
	push de
	call Func_70cd8
	pop hl
	call Func_70cd8
	call Func_70d19
	pop de
	pop hl
	pop bc
	inc hl
	dec de
	dec c
	jr nz, .asm_70cbf
	jp Func_70a69

Func_70cd8: ; 70cd8 (1c:4cd8)
	ld c, $9
	ld de, $28
.asm_70cdd
	ld [hl], $ff
	add hl, de
	dec c
	jr nz, .asm_70cdd
	ret

Func_70ce4: ; 70ce4 (1c:4ce4)
	call Func_70cfd
	ld bc, $000a
	ld hl, Unknown_70d61
	call Func_70d06
	ld c, $a
	ld b, $1
	ld hl, Unknown_70d93
	call Func_70d06
	jp Func_70a69

Func_70cfd: ; 70cfd (1c:4cfd)
	ld b, $3
	call Func_70b5d
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ret

Func_70d06: ; 70d06 (1c:4d06)
	push bc
	push hl
	ld a, b
	call Func_70d50
	pop hl
	ld bc, $0005
	add hl, bc
	call Func_70d19
	pop bc
	dec c
	jr nz, Func_70d06
	ret

Func_70d19: ; 70d19 (1c:4d19)
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Delay3
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ret

Func_70d24: ; 70d24 (1c:4d24)
	call Func_70cfd
	ld c, $a
	ld hl, Unknown_70d61 ; $4d61
	ld de, Unknown_70d93 ; $4d93
.asm_70d2f
	push bc
	push hl
	push de
	push de
	xor a
	call Func_70d50
	pop hl
	ld a, $1
	call Func_70d50
	pop hl
	ld bc, $5
	add hl, bc
	ld e, l
	ld d, h
	pop hl
	add hl, bc
	call Func_70d19
	pop bc
	dec c
	jr nz, .asm_70d2f
	jp Func_70a69

Func_70d50: ; 70d50 (1c:4d50)
	ld [wWhichTrade], a ; $cd3d
	ld a, [hli]
	ld [$cd3e], a
	ld a, [hli]
	ld e, a
	ld a, [hli]
	ld d, a
	ld a, [hli]
	ld h, [hl]
	ld l, a
	jp Func_70dc5

Unknown_70d61: ; 70d61 (1c:4d61)
	db $01
	dw Unknown_70dfe
	FuncCoord 18, 6
	dw Coord

	db $01
	dw Unknown_70e04
	FuncCoord 19, 3
	dw Coord

	db $01
	dw Unknown_70e0e
	FuncCoord 18, 0
	dw Coord

	db $01
	dw Unknown_70e20
	FuncCoord 14, 0
	dw Coord

	db $01
	dw Unknown_70e2e
	FuncCoord 10, 0
	dw Coord

	db $00
	dw Unknown_70e2e
	FuncCoord 9, 0
	dw Coord

	db $00
	dw Unknown_70e20
	FuncCoord 5, 0
	dw Coord

	db $00
	dw Unknown_70e0e
	FuncCoord 1, 0
	dw Coord

	db $00
	dw Unknown_70e04
	FuncCoord 0, 3
	dw Coord

	db $00
	dw Unknown_70dfe
	FuncCoord 1, 6
	dw Coord

Unknown_70d93: ; 70d93 (1c:4d93)
	db $00
	dw Unknown_70dfe
	FuncCoord 1, 11
	dw Coord

	db $00
	dw Unknown_70e04
	FuncCoord 0, 14
	dw Coord

	db $00
	dw Unknown_70e0e
	FuncCoord 1, 17
	dw Coord

	db $00
	dw Unknown_70e20
	FuncCoord 5, 17
	dw Coord

	db $00
	dw Unknown_70e2e
	FuncCoord 9, 17
	dw Coord

	db $01
	dw Unknown_70e2e
	FuncCoord 10, 17
	dw Coord

	db $01
	dw Unknown_70e20
	FuncCoord 14, 17
	dw Coord

	db $01
	dw Unknown_70e0e
	FuncCoord 18, 17
	dw Coord

	db $01
	dw Unknown_70e04
	FuncCoord 19, 14
	dw Coord

	db $01
	dw Unknown_70dfe
	FuncCoord 18, 11
	dw Coord

Func_70dc5: ; 70dc5 (1c:4dc5)
	push hl
	ld a, [de]
	ld c, a
	inc de
.asm_70dc9
	ld [hl], $ff
	ld a, [$cd3e]
	and a
	jr z, .asm_70dd4
	inc hl
	jr .asm_70dd5
.asm_70dd4
	dec hl
.asm_70dd5
	dec c
	jr nz, .asm_70dc9
	pop hl
	ld a, [wWhichTrade] ; $cd3d
	and a
	ld bc, $14
	jr z, .asm_70de5
	ld bc, $ffec
.asm_70de5
	add hl, bc
	ld a, [de]
	inc de
	cp $ff
	ret z
	and a
	jr z, Func_70dc5
	ld c, a
.asm_70def
	ld a, [$cd3e]
	and a
	jr z, .asm_70df8
	dec hl
	jr .asm_70df9
.asm_70df8
	inc hl
.asm_70df9
	dec c
	jr nz, .asm_70def
	jr Func_70dc5

Unknown_70dfe: ; 70dfe (1c:4dfe)
	db $02,$03,$05,$04,$09,$FF

Unknown_70e04: ; 70e04 (1c:4e04)
	db $01,$01,$02,$02,$04,$02,$04,$02,$03,$FF

Unknown_70e0e: ; 70e0e (1c:4e0e)
	db $02,$01,$03,$01,$04,$01,$04,$01,$04,$01,$03,$01,$02,$01,$01,$01,$01,$FF

Unknown_70e20: ; 70e20 (1c:4e20)
	db $04,$01,$04,$00,$03,$01,$03,$00,$02,$01,$02,$00,$01,$FF

Unknown_70e2e: ; 70e2e (1c:4e2e)
	db $04,$00,$03,$00,$03,$00,$02,$00,$02,$00,$01,$00,$01,$00,$01,$FF

DisplayTownMap: ; 70e3e (1c:4e3e)
	call LoadTownMap
	ld hl, $cfcb
	ld a, [hl]
	push af
	ld [hl], $ff
	push hl
	ld a, $1
	ld [$ffb7], a
	ld a, [W_CURMAP] ; $d35e
	push af
	ld b, $0
	call Func_711c4
	FuncCoord 1, 0 ; $c3a1
	ld hl, Coord
	ld de, $cd6d
	call PlaceString
	ld hl, wOAMBuffer
	ld de, wTileMapBackup
	ld bc, $10
	call CopyData
	ld hl, $8040
	ld de, TownMapCursor ; $4f40
	ld bc, (BANK(TownMapCursor) << 8) + $04
	call CopyVideoDataDouble
	xor a
	ld [wWhichTrade], a ; $cd3d
	pop af
	jr Func_70e92

Func_70e7e: ; 70e7e (1c:4e7e)
	ld hl, wTileMap
	ld bc, $114
	call ClearScreenArea
	ld hl, TownMapOrder ; $4f11
	ld a, [wWhichTrade] ; $cd3d
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]

Func_70e92: ; 70e92 (1c:4e92)
	ld de, $cee9
	call Func_712f1
	ld a, [de]
	push hl
	call Func_71258
	ld a, $4
	ld [$cd5b], a
	ld hl, $c310
	call Func_71279
	pop hl
	ld de, $cd6d
.asm_70eac
	ld a, [hli]
	ld [de], a
	inc de
	cp $50
	jr nz, .asm_70eac
	FuncCoord 1, 0 ; $c3a1
	ld hl, Coord
	ld de, $cd6d
	call PlaceString
	ld hl, $c310
	ld de, $c518
	ld bc, $10
	call CopyData
.asm_70ec8
	call Func_716c6
	call GetJoypadStateLowSensitivity
	ld a, [$ffb5]
	ld b, a
	and $c3
	jr z, .asm_70ec8
	ld a, (SFX_02_3c - SFX_Headers_02) / 3
	call PlaySound
	bit 6, b
	jr nz, .asm_70ef2
	bit 7, b
	jr nz, .asm_70f01
	xor a
	ld [$d09b], a
	ld [$ffb7], a
	ld [W_SUBANIMTRANSFORM], a ; $d08b
	call Func_711ab
	pop hl
	pop af
	ld [hl], a
	ret
.asm_70ef2
	ld a, [wWhichTrade] ; $cd3d
	inc a
	cp $2f
	jr nz, .asm_70efb
	xor a
.asm_70efb
	ld [wWhichTrade], a ; $cd3d
	jp Func_70e7e
.asm_70f01
	ld a, [wWhichTrade] ; $cd3d
	dec a
	cp $ff
	jr nz, .asm_70f0b
	ld a, $2e
.asm_70f0b
	ld [wWhichTrade], a ; $cd3d
	jp Func_70e7e

INCLUDE "data/town_map_order.asm"

TownMapCursor: ; 70f40 (1c:4f40)
	INCBIN "gfx/town_map_cursor.1bpp"

LoadTownMap_Nest: ; 70f60 (1c:4f60)
	call LoadTownMap
	ld hl, $cfcb
	ld a, [hl]
	push af
	ld [hl], $ff
	push hl
	call Func_711ef
	call GetMonName
	FuncCoord 1, 0 ; $c3a1
	ld hl, Coord
	call PlaceString
	ld h, b
	ld l, c
	ld de, MonsNestText
	call PlaceString
	call WaitForTextScrollButtonPress
	call Func_711ab
	pop hl
	pop af
	ld [hl], a
	ret

MonsNestText: ; 70f89 (1c:4f89)
	db "'s NEST@"

LoadTownMap_Fly: ; 70f90 (1c:4f90)
	call CleanLCD_OAM
	call LoadTownMap
	call LoadPlayerSpriteGraphics
	call LoadFontTilePatterns
	ld de, BirdSprite ; $4d80
	ld hl, $8040
	ld bc, (BANK(BirdSprite) << 8) + $0c
	call CopyVideoData
	ld de, TownMapUpArrow ; $5093
	ld hl, $8ed0
	ld bc, (BANK(TownMapUpArrow) << 8) + $01
	call CopyVideoDataDouble
	call Func_71070
	ld hl, $cfcb
	ld a, [hl]
	push af
	ld [hl], $ff
	push hl
	ld hl, wTileMap
	ld de, ToText
	call PlaceString
	ld a, [W_CURMAP] ; $d35e
	ld b, $0
	call Func_711c4
	ld hl, $cd3e
	FuncCoord 18, 0 ; $c3b2
	ld de, Coord

.townMapFlyLoop
	ld a, $7f
	ld [de], a
	push hl
	push hl
	FuncCoord 3, 0 ; $c3a3
	ld hl, Coord
	ld bc, $10f
	call ClearScreenArea
	pop hl
	ld a, [hl]
	ld b, $4
	call Func_711c4
	FuncCoord 3, 0 ; $c3a3
	ld hl, Coord
	ld de, $cd6d
	call PlaceString
	ld c, $f
	call DelayFrames
	FuncCoord 18, 0 ; $c3b2
	ld hl, Coord
	ld [hl], $ed
	FuncCoord 19, 0 ; $c3b3
	ld hl, Coord
	ld [hl], $ee
	pop hl
.asm_71004
	push hl
	call DelayFrame
	call GetJoypadStateLowSensitivity
	ld a, [$ffb5]
	ld b, a
	pop hl
	and $c3
	jr z, .asm_71004
	bit 0, b
	jr nz, .asm_71026
	ld a, (SFX_02_3c - SFX_Headers_02) / 3
	call PlaySound
	bit 6, b
	jr nz, .asm_71042
	bit 7, b
	jr nz, .asm_71058
	jr .asm_71037
.asm_71026
	ld a, (SFX_02_3e - SFX_Headers_02) / 3
	call PlaySound
	ld a, [hl]
	ld [$d71a], a
	ld hl, $d732
	set 3, [hl]
	inc hl
	set 7, [hl]
.asm_71037
	xor a
	ld [$d09b], a
	call GBPalWhiteOutWithDelay3
	pop hl
	pop af
	ld [hl], a
	ret
.asm_71042
	FuncCoord 18, 0 ; $c3b2
	ld de, Coord
	inc hl
	ld a, [hl]
	cp $ff
	jr z, .asm_71052
	cp $fe
	jr z, .asm_71042
	jp .townMapFlyLoop
.asm_71052
	ld hl, $cd3e
	jp .townMapFlyLoop
.asm_71058
	FuncCoord 19, 0 ; $c3b3
	ld de, Coord
	dec hl
	ld a, [hl]
	cp $ff
	jr z, .asm_71068
	cp $fe
	jr z, .asm_71058
	jp .townMapFlyLoop
.asm_71068
	ld hl, $cd49
	jr .asm_71058

ToText: ; 7106d (1c:506d)
	db "To@"

Func_71070: ; 71070 (1c:5070)
	ld hl, wWhichTrade ; $cd3d
	ld [hl], $ff
	inc hl
	ld a, [$d70b]
	ld e, a
	ld a, [$d70c]
	ld d, a
	ld bc, $b
.asm_71081
	srl d
	rr e
	ld a, $fe
	jr nc, .asm_7108a
	ld a, b
.asm_7108a
	ld [hl], a
	inc hl
	inc b
	dec c
	jr nz, .asm_71081
	ld [hl], $ff
	ret

TownMapUpArrow: ; 71093 (1c:5093)
	INCBIN "gfx/up_arrow.1bpp"

LoadTownMap: ; 7109b (1c:509b)
	call GBPalWhiteOutWithDelay3
	call ClearScreen
	call UpdateSprites
	ld hl, wTileMap
	ld b, $12
	ld c, $12
	call TextBoxBorder
	call DisableLCD
	ld hl, WorldMapTileGraphics ; $65a8
	ld de, $9600
	ld bc, $100
	ld a, BANK(WorldMapTileGraphics)
	call FarCopyData2
	ld hl, MonNestIcon ; $56be
	ld de, $8040
	ld bc, $8
	ld a, BANK(MonNestIcon)
	call FarCopyDataDouble
	ld hl, wTileMap
	ld de, CompressedMap ; $5100
.asm_710d3
	ld a, [de]
	and a
	jr z, .asm_710e9
	ld b, a
	and $f
	ld c, a
	ld a, b
	swap a
	and $f
	add $60
.asm_710e2
	ld [hli], a
	dec c
	jr nz, .asm_710e2
	inc de
	jr .asm_710d3
.asm_710e9
	call EnableLCD
	ld b, $2
	call GoPAL_SET
	call Delay3
	call GBPalNormal
	xor a
	ld [W_SUBANIMTRANSFORM], a ; $d08b
	inc a
	ld [$d09b], a
	ret

CompressedMap: ; 71100 (1c:5100)
; you can decompress this file with the redrle program in the extras/ dir
	INCBIN "gfx/town_map.rle"

Func_711ab: ; 711ab (1c:51ab)
	xor a
	ld [$d09b], a
	call GBPalWhiteOut
	call ClearScreen
	call CleanLCD_OAM
	call LoadPlayerSpriteGraphics
	call LoadFontTilePatterns
	call UpdateSprites
	jp GoPAL_SET_CF1C

Func_711c4: ; 711c4 (1c:51c4)
	push af
	ld a, b
	ld [$cd5b], a
	pop af
	ld de, $cee9
	call Func_712f1
	ld a, [de]
	push hl
	call Func_71258
	call Func_7126d
	pop hl
	ld de, $cd6d
.asm_711dc
	ld a, [hli]
	ld [de], a
	inc de
	cp $50
	jr nz, .asm_711dc
	ld hl, wOAMBuffer
	ld de, wTileMapBackup
	ld bc, $a0
	jp CopyData

Func_711ef: ; 711ef (1c:51ef)
	callba Func_e9cb
	call Func_712d9
	ld hl, wOAMBuffer
	ld de, $cee9
.asm_71200
	ld a, [de]
	cp $ff
	jr z, .asm_7121d
	and a
	jr z, .asm_7121a
	push hl
	call Func_712f1
	pop hl
	ld a, [de]
	cp $19
	jr z, .asm_7121a
	call Func_71258
	ld a, $4
	ld [hli], a
	xor a
	ld [hli], a
.asm_7121a
	inc de
	jr .asm_71200
.asm_7121d
	ld a, l
	and a
	jr nz, .asm_71236
	FuncCoord 1, 7 ; $c42d
	ld hl, Coord
	ld b, $2
	ld c, $f
	call TextBoxBorder
	FuncCoord 2, 9 ; $c456
	ld hl, Coord
	ld de, AreaUnknownText
	call PlaceString
	jr .asm_7123e
.asm_71236
	ld a, [W_CURMAP] ; $d35e
	ld b, $0
	call Func_711c4
.asm_7123e
	ld hl, wOAMBuffer
	ld de, wTileMapBackup
	ld bc, $a0
	jp CopyData

AreaUnknownText: ; 7124a (1c:524a)
	db " AREA UNKNOWN@"

Func_71258: ; 71258 (1c:5258)
	push af
	and $f0
	srl a
	add $18
	ld b, a
	ld [hli], a
	pop af
	and $f
	swap a
	srl a
	add $18
	ld c, a
	ld [hli], a
	ret

Func_7126d: ; 7126d (1c:526d)
	ld a, [$cd5b]
	and a
	ld hl, $c390
	jr z, Func_71279
	ld hl, $c380

Func_71279: ; 71279 (1c:5279)
	push hl
	ld hl, $fcfc
	add hl, bc
	ld b, h
	ld c, l
	pop hl

Func_71281: ; 71281 (1c:5281)
	ld de, $202
.asm_71284
	push de
	push bc
.asm_71286
	ld a, b
	ld [hli], a
	ld a, c
	ld [hli], a
	ld a, [$cd5b]
	ld [hli], a
	inc a
	ld [$cd5b], a
	xor a
	ld [hli], a
	inc d
	ld a, $8
	add c
	ld c, a
	dec e
	jr nz, .asm_71286
	pop bc
	pop de
	ld a, $8
	add b
	ld b, a
	dec d
	jr nz, .asm_71284
	ret

Func_712a6: ; 712a6 (1c:52a6)
	xor a
	ld [$cd5c], a
	ld de, $202
.asm_712ad
	push de
	push bc
.asm_712af
	ld a, b
	ld [hli], a
	ld a, c
	ld [hli], a
	ld a, [$cd5b]
	ld [hli], a
	ld a, [$cd5c]
	ld [hli], a
	xor $20
	ld [$cd5c], a
	inc d
	ld a, $8
	add c
	ld c, a
	dec e
	jr nz, .asm_712af
	pop bc
	pop de
	push hl
	ld hl, $cd5b
	inc [hl]
	inc [hl]
	pop hl
	ld a, $8
	add b
	ld b, a
	dec d
	jr nz, .asm_712ad
	ret

Func_712d9: ; 712d9 (1c:52d9)
	ld de, $cee9
.asm_712dc
	ld a, [de]
	inc de
	cp $ff
	ret z
	ld c, a
	ld l, e
	ld h, d
.asm_712e4
	ld a, [hl]
	cp $ff
	jr z, .asm_712dc
	cp c
	jr nz, .asm_712ee
	xor a
	ld [hl], a
.asm_712ee
	inc hl
	jr .asm_712e4

Func_712f1: ; 712f1 (1c:52f1)
	cp REDS_HOUSE_1F
	jr c, .asm_71304
	ld bc, $4
	ld hl, InternalMapEntries ; $5382
.asm_712fb
	cp [hl]
	jr c, .asm_71301
	add hl, bc
	jr .asm_712fb
.asm_71301
	inc hl
	jr .asm_7130d
.asm_71304
	ld hl, ExternalMapEntries ; $5313
	ld c, a
	ld b, $0
	add hl, bc
	add hl, bc
	add hl, bc
.asm_7130d
	ld a, [hli]
	ld [de], a
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ret

INCLUDE "data/town_map_entries.asm"

INCLUDE "text/map_names.asm"

MonNestIcon: ; 716be (1c:56be)
	INCBIN "gfx/mon_nest_icon.1bpp"

Func_716c6: ; 716c6 (1c:56c6)
	ld a, [W_SUBANIMTRANSFORM] ; $d08b
	inc a
	cp $19
	jr z, .asm_716e1
	cp $32
	jr nz, .asm_716f1
	ld hl, wTileMapBackup
	ld de, wOAMBuffer
	ld bc, $90
	call CopyData
	xor a
	jr .asm_716f1
.asm_716e1
	ld hl, wOAMBuffer
	ld b, $24
	ld de, $4
.asm_716e9
	ld [hl], $a0
	add hl, de
	dec b
	jr nz, .asm_716e9
	ld a, $19
.asm_716f1
	ld [W_SUBANIMTRANSFORM], a ; $d08b
	jp DelayFrame

AnimatePartyMon_ForceSpeed1: ; 716f7 (1c:56f7)
	xor a
	ld [wCurrentMenuItem], a ; $cc26
	ld b, a
	inc a
	jr GetAnimationSpeed

; $cf1f contains the party mon's health bar colors
; 0: green
; 1: yellow
; 2: red
AnimatePartyMon: ; 716ff (1c:56ff)
	ld hl, $cf1f
	ld a, [wCurrentMenuItem]
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hl]

GetAnimationSpeed: ; 7170a (1c:570a)
	ld c, a
	ld hl, PartyMonSpeeds
	add hl, bc
	ld a, [$cf1b]
	xor $1
	add [hl]
	ld c, a
	add a
	ld b, a
	ld a, [W_SUBANIMTRANSFORM] ; $d08b
	and a
	jr z, .resetSprites
	cp c
	jr z, .animateSprite
.incTimer
	inc a
	cp b
	jr nz, .resetTimer
	xor a
.resetTimer
	ld [W_SUBANIMTRANSFORM], a ; $d08b
	jp DelayFrame
.resetSprites
	push bc
	ld hl, $cc5b
	ld de, wOAMBuffer
	ld bc, $60
	call CopyData
	pop bc
	xor a
	jr .incTimer
.animateSprite
	push bc
	ld hl, $c302 ; OAM tile id
	ld bc, $10
	ld a, [wCurrentMenuItem]
	call AddNTimes
	ld c, $40 ; amount to increase the tile id by
	ld a, [hl]
	cp $4 ; tile ID for SPRITE_BALL_M
	jr z, .editCoords
	cp $8 ; tile ID for SPRITE_HELIX
	jr nz, .editTileIDS
; SPRITE_BALL_M and SPRITE_HELIX only shake up and down
.editCoords
	dec hl
	dec hl ; dec hl to the OAM y coord
	ld c, $1 ; amount to increase the y coord by
; otherwise, load a second sprite frame
.editTileIDS
	ld b, $4
	ld de, $4
.loop
	ld a, [hl]
	add c
	ld [hl], a
	add hl, de
	dec b
	jr nz, .loop
	pop bc
	ld a, c
	jr .incTimer

PartyMonSpeeds: ; 71769 (1c:5769)
	db $05,$10,$20

Func_7176c: ; 7176c (1c:576c)
	ld hl, MonOverworldSpritePointers ; $57c0
	ld a, $1c

Func_71771: ; 71771 (1c:5771)
	ld bc, $0
.asm_71774
	push af
	push bc
	push hl
	add hl, bc
	ld a, [hli]
	ld e, a
	ld a, [hli]
	ld d, a
	ld a, [hli]
	ld c, a
	ld a, [hli]
	ld b, a
	ld a, [hli]
	ld h, [hl]
	ld l, a
	call CopyVideoData
	pop hl
	pop bc
	ld a, $6
	add c
	ld c, a
	pop af
	dec a
	jr nz, .asm_71774
	ret

Func_71791: ; 71791 (1c:5791)
	call DisableLCD
	ld hl, MonOverworldSpritePointers ; $57c0
	ld a, $1c
	ld bc, $0
.asm_7179c
	push af
	push bc
	push hl
	add hl, bc
	ld a, [hli]
	ld e, a
	ld a, [hli]
	ld d, a
	push de
	ld a, [hli]
	ld c, a
	swap c
	ld b, $0
	ld a, [hli]
	ld e, [hl]
	inc hl
	ld d, [hl]
	pop hl
	call FarCopyData2
	pop hl
	pop bc
	ld a, $6
	add c
	ld c, a
	pop af
	dec a
	jr nz, .asm_7179c
	jp EnableLCD

MonOverworldSpritePointers: ; 717c0 (1c:57c0)
	dw SlowbroSprite + $c0
	db $40 / $10 ; 40 bytes
	db BANK(SlowbroSprite)
	dw $8000

	dw BallSprite
	db $80 / $10 ; $80 bytes
	db BANK(BallSprite)
	dw $8040

	dw ClefairySprite + $c0
	db $40 / $10 ; $40 bytes
	db BANK(ClefairySprite)
	dw $80C0

	dw BirdSprite + $c0
	db $40 / $10 ; $40 bytes
	db BANK(BirdSprite)
	dw $8100

	dw SeelSprite
	db $40 / $10 ; $40 bytes
	db BANK(SeelSprite)
	dw $8140

	dw MonOverworldSprites + $40
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $8180

	dw MonOverworldSprites + $50
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $81A0

	dw MonOverworldSprites + $60
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $81C0

	dw MonOverworldSprites + $70
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $81E0

	dw MonOverworldSprites + $80
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $8200

	dw MonOverworldSprites + $90
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $8220

	dw MonOverworldSprites + $A0
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $8240

	dw MonOverworldSprites + $B0
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $8260

	dw MonOverworldSprites + $100
	db $40 / $10 ; $40 bytes
	db BANK(MonOverworldSprites)
	dw $8380

	dw SlowbroSprite
	db $40 / $10 ; $40 bytes
	db BANK(SlowbroSprite)
	dw $8400

	dw BallSprite
	db $80 / $10 ; $80 bytes
	db BANK(BallSprite)
	dw $8440

	dw ClefairySprite
	db $40 / $10 ; $40 bytes
	db BANK(ClefairySprite)
	dw $84C0

	dw BirdSprite
	db $40 / $10 ; $40 bytes
	db BANK(BirdSprite)
	dw $8500

	dw SeelSprite + $C0
	db $40 / $10 ; $40 bytes
	db BANK(SeelSprite)
	dw $8540

	dw MonOverworldSprites
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $8580

	dw MonOverworldSprites + $10
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $85A0

	dw MonOverworldSprites + $20
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $85C0

	dw MonOverworldSprites + $30
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $85E0

	dw MonOverworldSprites + $C0
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $8600

	dw MonOverworldSprites + $D0
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $8620

	dw MonOverworldSprites + $E0
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $8640

	dw MonOverworldSprites + $F0
	db $10 / $10 ; $10 bytes
	db BANK(MonOverworldSprites)
	dw $8660

	dw MonOverworldSprites + $140
	db $40 / $10 ; $40 bytes
	db BANK(MonOverworldSprites)
	dw $8780

Func_71868: ; 71868 (1c:5868)
	push hl
	push de
	push bc
	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
	ld hl, W_PARTYMON1 ; $d164
	ld e, a
	ld d, $0
	add hl, de
	ld a, [hl]
	call GetPartyMonSpriteID
	ld [$cd5b], a
	call Func_718c3
	pop bc
	pop de
	pop hl
	ret

Func_71882: ; 71882 (1c:5882)
	xor a
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	ld a, [$cd5d]
	call GetPartyMonSpriteID
	ld [$cd5b], a
	jr Func_718c3

Func_71890: ; 71890 (1c:5890)
	ld a, [$cf91]
	call GetPartyMonSpriteID
	push af
	ld hl, $8000
	call Func_718ac
	pop af
	add $54
	ld hl, $8040
	call Func_718ac
	xor a
	ld [$cd5d], a
	jr Func_71882

Func_718ac: ; 718ac (1c:58ac)
	push hl
	add a
	ld c, a
	ld b, $0
	ld hl, MonOverworldSpritePointers
	add hl, bc
	add hl, bc
	add hl, bc
	ld a, [hli]
	ld e, a
	ld a, [hli]
	ld d, a
	ld a, [hli]
	ld c, a
	ld a, [hli]
	ld b, a
	pop hl
	jp CopyVideoData

Func_718c3: ; 718c3 (1c:58c3)
	push af
	ld c, $10
	ld h, $c3
	ld a, [H_DOWNARROWBLINKCNT2] ; $ff8c
	swap a
	ld l, a
	add $10
	ld b, a
	pop af
	cp $8
	jr z, .asm_718da
	call Func_712a6
	jr .asm_718dd
.asm_718da
	call Func_71281
.asm_718dd
	ld hl, wOAMBuffer
	ld de, $cc5b
	ld bc, $60
	jp CopyData

GetPartyMonSpriteID: ; 718e9 (1c:58e9)
	ld [$d11e], a
	ld a, $3a
	call Predef ; indirect jump to IndexToPokedex (41010 (10:5010))
	ld a, [$d11e]
	ld c, a
	dec a
	srl a
	ld hl, MonOverworldData ; $590d
	ld e, a
	ld d, $0
	add hl, de
	ld a, [hl]
	bit 0, c
	jr nz, .asm_71906
	swap a
.asm_71906
	and $f0
	srl a
	srl a
	ret

INCLUDE "data/mon_party_sprites.asm"

MonOverworldSprites: ; 71959 (1c:5959)
	INCBIN "gfx/mon_ow_sprites.2bpp"

Predef54: ; 71ad9 (1c:5ad9)
; trigger the trade offer/action specified by wWhichTrade
	call SaveScreenTilesToBuffer2
	ld hl,TradeMons
	ld a,[wWhichTrade]
	ld b,a
	swap a
	sub b
	sub b
	ld c,a
	ld b,$0
	add hl,bc
	ld a,[hli]
	ld [$cd0f],a
	ld a,[hli]
	ld [$cd34],a
	ld a,[hli]
	push af
	ld de,$cd29
	ld bc,$000b
	call CopyData
	pop af
	ld l,a
	ld h,$0
	ld de,InGameTradeTextPointers ; $5d64
	add hl,hl
	add hl,de
	ld a,[hli]
	ld [$cd10],a
	ld a,[hl]
	ld [$cd11],a
	ld a,[$cd0f]
	ld de,$cd13
	call Func_71b6a
	ld a,[$cd34]
	ld de,$cd1e
	call Func_71b6a
	ld hl,$d737
	ld a,[wWhichTrade]
	ld c,a
	ld b,$2
	ld a,$10
	call Predef
	ld a,c
	and a
	ld a,$4
	ld [$cd12],a
	jr nz,.asm_99bca ; 0x71b36 $20
	xor a
	ld [$cd12],a
	call .asm_99bca
	ld a,$1
	ld [$cd12],a
	call YesNoChoice
	ld a,[$cc26]
	and a
	jr nz,.asm_99bca ; 0x71b4b $b
	call Func_71c07
	jr c,.asm_99bca ; 0x71b50 $6
	ld hl, TradedForText
	call PrintText
.asm_99bca ; 0x71b58
	ld hl,$cd12
	ld a,[hld]
	ld e,a
	ld d,$0
	ld a,[hld]
	ld l,[hl]
	ld h,a
	add hl,de
	add hl,de
	ld a,[hli]
	ld h,[hl]
	ld l,a
	jp PrintText

Func_71b6a: ; 71b6a (1c:5b6a)
	push de
	ld [$d11e],a
	call GetMonName
	ld hl,$cd6d
	pop de
	ld bc,$b
	jp CopyData

INCLUDE "data/trades.asm"

Func_71c07: ; 71c07 (1c:5c07)
	xor a
	ld [$d07d],a
	dec a
	ld [$cfcb],a
	call DisplayPartyMenu
	push af
	call Func_71ca2
	pop af
	ld a,$1
	jp c,.asm_c4bc2
	ld a,[$cd0f]
	ld b,a
	ld a,[$cf91]
	cp b
	ld a,$2
	jr nz,.asm_c4bc2 ; 0x71c26 $75
	ld a,[wWhichPokemon]
	ld hl,$d18c
	ld bc,$002c
	call AddNTimes
	ld a,[hl]
	ld [$d127],a
	ld hl,$d737
	ld a,[wWhichTrade]
	ld c,a
	ld b,$1
	ld a,$10
	call Predef
	ld hl, ConnectCableText
	call PrintText
	ld a,[wWhichPokemon]
	push af
	ld a,[$d127]
	push af
	call LoadHpBarAndStatusTilePatterns
	call Func_71cc1
	ld a,$38
	call Predef
	pop af
	ld [$d127],a
	pop af
	ld [wWhichPokemon],a
	ld a,[$cd34]
	ld [$cf91],a
	xor a
	ld [$cc49],a
	ld [$cf95],a
	call RemovePokemon
	ld a,$80
	ld [$cc49],a
	call AddPokemonToParty
	call Func_71d19
	callab EvolveTradeMon
	call ClearScreen
	call Func_71ca2
	callba Func_eedc
	and a
	ld a,$3
	jr .asm_ee803 ; 0x71c9b $1
.asm_c4bc2 ; 0x71c9d
	scf
.asm_ee803 ; 0x71c9e
	ld [$cd12],a
	ret

Func_71ca2: ; 71ca2 (1c:5ca2)
	call GBPalWhiteOutWithDelay3
	call Func_3dbe
	call ReloadTilesetTilePatterns
	call LoadScreenTilesFromBuffer2
	call Delay3
	call LoadGBPal
	ld c, $a
	call DelayFrames
	ld b, BANK(LoadWildData)
	ld hl, LoadWildData
	jp Bankswitch

Func_71cc1: ; 71cc1 (1c:5cc1)
	ld hl, wWhichTrade ; $cd3d
	ld a, [$cd0f]
	ld [hli], a
	ld a, [$cd34]
	ld [hl], a
	ld hl, W_PARTYMON1OT ; $d273
	ld bc, $b
	ld a, [wWhichPokemon] ; $cf92
	call AddNTimes
	ld de, $cd41
	ld bc, $b
	call Func_71d11
	ld hl, String_71d59 ; $5d59
	ld de, $cd4e
	call Func_71d11
	ld de, W_GRASSRATE ; $d887
	call Func_71d11
	ld hl, W_PARTYMON1_OTID ; $d177
	ld bc, $2c
	ld a, [wWhichPokemon] ; $cf92
	call AddNTimes
	ld de, $cd4c
	ld bc, $2
	call Func_71d11
	call GenRandom
	ld hl, H_RAND1 ; $ffd3
	ld de, $cd59
	jp CopyData

Func_71d11: ; 71d11 (1c:5d11)
	push hl
	push bc
	call CopyData
	pop bc
	pop hl
	ret

Func_71d19: ; 71d19 (1c:5d19)
	ld hl, W_PARTYMON1NAME ; $d2b5
	ld bc, $b
	call Func_71d4f
	ld hl, $cd29
	ld bc, $b
	call CopyData
	ld hl, W_PARTYMON1OT ; $d273
	ld bc, $b
	call Func_71d4f
	ld hl, String_71d59 ; $5d59
	ld bc, $b
	call CopyData
	ld hl, W_PARTYMON1_OTID ; $d177
	ld bc, $2c
	call Func_71d4f
	ld hl, $cd59
	ld bc, $2
	jp CopyData

Func_71d4f: ; 71d4f (1c:5d4f)
	ld a, [W_NUMINPARTY] ; $d163
	dec a
	call AddNTimes
	ld e, l
	ld d, h
	ret

String_71d59: ; 71d59 (1c:5d59)
	; "TRAINER@@@@@@@@@@"
	db $5d, "@@@@@@@@@@"

InGameTradeTextPointers: ; 71d64 (1c:5d64)
	dw TradeTextPointers1
	dw TradeTextPointers2
	dw TradeTextPointers3

TradeTextPointers1: ; 71d6a (1c:5d6a)
	dw WannaTrade1Text
	dw NoTrade1Text
	dw WrongMon1Text
	dw Thanks1Text
	dw AfterTrade1Text

TradeTextPointers2: ; 71d74 (1c:5d74)
	dw WannaTrade2Text
	dw NoTrade2Text
	dw WrongMon2Text
	dw Thanks2Text
	dw AfterTrade2Text

TradeTextPointers3: ; 71d7e (1c:5d7e)
	dw WannaTrade3Text
	dw NoTrade3Text
	dw WrongMon3Text
	dw Thanks3Text
	dw AfterTrade3Text

ConnectCableText: ; 71d88 (1c:5d88)
	TX_FAR _ConnectCableText
	db "@"

TradedForText: ; 71d8d (1c:5d8d)
	TX_FAR _TradedForText
	db $11, $a, "@"

WannaTrade1Text: ; 71d94 (1c:5d94)
	TX_FAR _WannaTrade1Text
	db "@"

NoTrade1Text: ; 71d99 (1c:5d99)
	TX_FAR _NoTrade1Text
	db "@"

WrongMon1Text: ; 71d9e (1c:5d9e)
	TX_FAR _WrongMon1Text
	db "@"

Thanks1Text: ; 71da3 (1c:5da3)
	TX_FAR _Thanks1Text
	db "@"

AfterTrade1Text: ; 71da8 (1c:5da8)
	TX_FAR _AfterTrade1Text
	db "@"

WannaTrade2Text: ; 71dad (1c:5dad)
	TX_FAR _WannaTrade2Text
	db "@"

NoTrade2Text: ; 71db2 (1c:5db2)
	TX_FAR _NoTrade2Text
	db "@"

WrongMon2Text: ; 71db7 (1c:5db7)
	TX_FAR _WrongMon2Text
	db "@"

Thanks2Text: ; 71dbc (1c:5dbc)
	TX_FAR _Thanks2Text
	db "@"

AfterTrade2Text: ; 71dc1 (1c:5dc1)
	TX_FAR _AfterTrade2Text
	db "@"

WannaTrade3Text: ; 71dc6 (1c:5dc6)
	TX_FAR _WannaTrade3Text
	db "@"

NoTrade3Text: ; 71dcb (1c:5dcb)
	TX_FAR _NoTrade3Text
	db "@"

WrongMon3Text: ; 71dd0 (1c:5dd0)
	TX_FAR _WrongMon3Text
	db "@"

Thanks3Text: ; 71dd5 (1c:5dd5)
	TX_FAR _Thanks3Text
	db "@"

AfterTrade3Text: ; 71dda (1c:5dda)
	TX_FAR _AfterTrade3Text
	db "@"

Func_71ddf: ; 71ddf (1c:5ddf)
	call Load16BitRegisters
	ld a, b
	cp $ff
	jr nz, .asm_71dea
	ld a, [$cf1c]
.asm_71dea
	cp $fc
	jp z, Func_71fc2
	ld l, a
	ld h, $0
	add hl, hl
	ld de, PointerTable_71f73
	add hl, de
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ld de, Func_72156
	push de
	jp [hl]

SendPalPacket_Black: ; 71dff (1c:5dff)
	ld hl, PalPacket_Black
	ld de, BlkPacket_Battle
	ret

; uses PalPacket_Empty to build a packet based on mon IDs and health color
BuildBattlePalPacket: ; 71e06 (1c:5e06)
	ld hl, PalPacket_Empty
	ld de, $cf2d
	ld bc, $10
	call CopyData
	ld a, [W_PLAYERBATTSTATUS3]
	ld hl, W_PLAYERMONID
	call DeterminePaletteID
	ld b, a
	ld a, [W_ENEMYBATTSTATUS3]
	ld hl, W_ENEMYMONID
	call DeterminePaletteID
	ld c, a
	ld hl, $cf2e
	ld a, [$cf1d]
	add PAL_GREENBAR
	ld [hli], a
	inc hl
	ld a, [$cf1e]
	add PAL_GREENBAR
	ld [hli], a
	inc hl
	ld a, b
	ld [hli], a
	inc hl
	ld a, c
	ld [hl], a
	ld hl, $cf2d
	ld de, BlkPacket_Battle
	ld a, $1
	ld [$cf1c], a
	ret

SendPalPacket_TownMap: ; 71e48 (1c:5e48)
	ld hl, PalPacket_TownMap
	ld de, BlkPacket_WholeScreen
	ret

; uses PalPacket_Empty to build a packet based the mon ID
BuildStatusScreenPalPacket: ; 71e4f (1c:5e4f)
	ld hl, PalPacket_Empty
	ld de, $cf2d
	ld bc, $10
	call CopyData
	ld a, [$cf91]
	cp VICTREEBEL + 1
	jr c, .pokemon
	ld a, $1 ; not pokemon
.pokemon
	call DeterminePaletteIDOutOfBattle
	push af
	ld hl, $cf2e
	ld a, [$cf25]
	add $1f
	ld [hli], a
	inc hl
	pop af
	ld [hl], a
	ld hl, $cf2d
	ld de, BlkPacket_StatusScreen
	ret

SendPalPacket_PartyMenu: ; 71e7b (1c:5e7b)
	ld hl, PalPacket_PartyMenu
	ld de, $cf2e
	ret

SendPalPacket_Pokedex: ; 71e82 (1c:5e82)
	ld hl, PalPacket_Pokedex
	ld de, $cf2d
	ld bc, $10
	call CopyData
	ld a, [$cf91]
	call DeterminePaletteIDOutOfBattle
	ld hl, $cf30
	ld [hl], a
	ld hl, $cf2d
	ld de, BlkPacket_Pokedex
	ret

SendPalPacket_Slots: ; 71e9f (1c:5e9f)
	ld hl, PalPacket_Slots
	ld de, BlkPacket_Slots
	ret

SendPalPacket_Titlescreen: ; 71ea6 (1c:5ea6)
	ld hl, PalPacket_Titlescreen
	ld de, BlkPacket_Titlescreen
	ret

; used mostly for menus and the Oak intro
SendPalPacket_Generic: ; 71ead (1c:5ead)
	ld hl, PalPacket_Generic
	ld de, BlkPacket_WholeScreen
	ret

SendPalPacket_NidorinoIntro: ; 71eb4 (1c:5eb4)
	ld hl, PalPacket_NidorinoIntro
	ld de, BlkPacket_NidorinoIntro
	ret

SendPalPacket_GameFreakIntro: ; 71ebb (1c:5ebb)
	ld hl, PalPacket_GameFreakIntro
	ld de, BlkPacket_GameFreakIntro
	ld a, $8
	ld [$cf1c], a
	ret

; uses PalPacket_Empty to build a packet based on the current map
BuildOverworldPalPacket: ; 71ec7 (1c:5ec7)
	ld hl, PalPacket_Empty
	ld de, $cf2d
	ld bc, $10
	call CopyData
	ld a, [W_CURMAPTILESET]
	cp CEMETERY
	jr z, .PokemonTowerOrAgatha
	cp CAVERN
	jr z, .caveOrBruno
	ld a, [W_CURMAP]
	cp REDS_HOUSE_1F
	jr c, .townOrRoute
	cp UNKNOWN_DUNGEON_2
	jr c, .normalDungeonOrBuilding
	cp NAME_RATERS_HOUSE
	jr c, .caveOrBruno
	cp LORELEIS_ROOM
	jr z, .Lorelei
	cp BRUNOS_ROOM
	jr z, .caveOrBruno
.normalDungeonOrBuilding
	ld a, [wLastMap] ; town or route that current dungeon or building is located
.townOrRoute
	cp SAFFRON_CITY + 1
	jr c, .town
	ld a, PAL_ROUTE - 1
.town
	inc a ; a town's pallete ID is its map ID + 1
	ld hl, $cf2e
	ld [hld], a
	ld de, BlkPacket_WholeScreen
	ld a, $9
	ld [$cf1c], a
	ret
.PokemonTowerOrAgatha
	ld a, PAL_GREYMON - 1
	jr .town
.caveOrBruno
	ld a, PAL_CAVE - 1
	jr .town
.Lorelei
	xor a
	jr .town

; used when a Pokemon is the only thing on the screen
; such as evolution, trading and the Hall of Fame
SendPokemonPalette_WholeScreen: ; 71f17 (1c:5f17)
	push bc
	ld hl, PalPacket_Empty
	ld de, $cf2d
	ld bc, $10
	call CopyData
	pop bc
	ld a, c
	and a
	ld a, $1e
	jr nz, .asm_71f31
	ld a, [$cf1d]
	call DeterminePaletteIDOutOfBattle
.asm_71f31
	ld [$cf2e], a
	ld hl, $cf2d
	ld de, BlkPacket_WholeScreen
	ret

BuildTrainerCardPalPacket: ; 71f3b (1c:5f3b)
	ld hl, BlkPacket_TrainerCard
	ld de, $cc5b
	ld bc, $40
	call CopyData
	ld de, LoopCounts_71f8f
	ld hl, $cc5d
	ld a, [W_OBTAINEDBADGES]
	ld c, $8
.asm_71f52
	srl a
	push af
	jr c, .asm_71f62
	push bc
	ld a, [de]
	ld c, a
	xor a
.asm_71f5b
	ld [hli], a
	dec c
	jr nz, .asm_71f5b
	pop bc
	jr .asm_71f67
.asm_71f62
	ld a, [de]
.asm_71f63
	inc hl
	dec a
	jr nz, .asm_71f63
.asm_71f67
	pop af
	inc de
	dec c
	jr nz, .asm_71f52
	ld hl, PalPacket_TrainerCard
	ld de, $cc5b
	ret

PointerTable_71f73: ; 71f73 (1c:5f73)
	dw SendPalPacket_Black
	dw BuildBattlePalPacket
	dw SendPalPacket_TownMap
	dw BuildStatusScreenPalPacket
	dw SendPalPacket_Pokedex
	dw SendPalPacket_Slots
	dw SendPalPacket_Titlescreen
	dw SendPalPacket_NidorinoIntro
	dw SendPalPacket_Generic
	dw BuildOverworldPalPacket
	dw SendPalPacket_PartyMenu
	dw SendPokemonPalette_WholeScreen
	dw SendPalPacket_GameFreakIntro
	dw BuildTrainerCardPalPacket

; each byte is the number of loops to make in .asm_71f5b for each badge
LoopCounts_71f8f: ; 71f8f (1c:5f8f)
	db $06,$06,$06,$12,$06,$06,$06,$06

DeterminePaletteID: ; 71f97 (1c:5f97)
	bit 3, a                 ; bit 3 of battle status 3, set if current Pokemon is transformed
	ld a, PAL_GREYMON        ; if yes, use Ditto's palette
	ret nz
	ld a, [hl]
DeterminePaletteIDOutOfBattle: ; 71f9d (1c:5f9d)
	ld [$D11E], a
	and a
	jr z, .idZero
	push bc
	ld a, $3A
	call Predef               ; turn Pokemon ID number into Pokedex number
	pop bc
	ld a, [$D11E]
.idZero
	ld e, a
	ld d, $00
	ld hl, MonsterPalettes   ; not just for Pokemon, Trainers use it too
	add hl, de
	ld a, [hl]
	ret

SendBlkPacket_PartyMenu: ; 71fb6 (1c:5fb6)
	ld hl, BlkPacket_PartyMenu ; $62f4
	ld de, $cf2e
	ld bc, $30
	jp CopyData

Func_71fc2: ; 71fc2 (1c:5fc2)
	ld hl, $cf1f
	ld a, [$cf2d]
	ld e, a
	ld d, $0
	add hl, de
	ld e, l
	ld d, h
	ld a, [de]
	and a
	ld e, $5
	jr z, .asm_71fdb
	dec a
	ld e, $a
	jr z, .asm_71fdb
	ld e, $f
.asm_71fdb
	push de
	ld hl, $cf37
	ld bc, $6
	ld a, [$cf2d]
	call AddNTimes
	pop de
	ld [hl], e
	ret

SendSGBPacket: ; 71feb (1c:5feb)
;check number of packets
	ld a,[hl]
	and a,$07
	ret z
; store number of packets in B
	ld b,a
.loop2
; save B for later use
	push bc
; load a non-zero value in $fff9 to disable the routine that checks actual
; joypad input (said routine, located at $15f, does nothing if $fff9 is not
; zero)
	ld a,$01
	ld [$fff9],a
; send RESET signal (P14=LOW, P15=LOW)
	xor a
	ld [$ff00],a
; set P14=HIGH, P15=HIGH
	ld a,$30
	ld [$ff00],a
;load length of packets (16 bytes)
	ld b,$10
.nextByte
;set bit counter (8 bits per byte)
	ld e,$08
; get next byte in the packet
	ld a,[hli]
	ld d,a
.nextBit0
	bit 0,d
; if 0th bit is not zero set P14=HIGH,P15=LOW (send bit 1)
	ld a,$10
	jr nz,.next0
; else (if 0th bit is zero) set P14=LOW,P15=HIGH (send bit 0)
	ld a,$20
.next0
	ld [$ff00],a
; must set P14=HIGH,P15=HIGH between each "pulse"
	ld a,$30
	ld [$ff00],a
; rotation will put next bit in 0th position (so  we can always use command
; "bit 0,d" to fetch the bit that has to be sent)
	rr d
; decrease bit counter so we know when we have sent all 8 bits of current byte
	dec e
	jr nz,.nextBit0
	dec b
	jr nz,.nextByte
; send bit 1 as a "stop bit" (end of parameter data)
	ld a,$20
	ld [$ff00],a
; set P14=HIGH,P15=HIGH
	ld a,$30
	ld [$ff00],a
	xor a
	ld [$fff9],a
; wait for about 70000 cycles
	call Wait7000
; restore (previously pushed) number of packets
	pop bc
	dec b
; return if there are no more packets
	ret z
; else send 16 more bytes
	jr .loop2

LoadSGBBorderAndPalettes: ; 7202b (1c:602b)
	xor a
	ld [$cf1b], a
	call Func_7209b
	ret nc
	ld a, $1
	ld [$cf1b], a
	ld a, [$cf1a]
	and a
	jr z, .asm_7203f
	ret
.asm_7203f
	di
	call Func_72075
	ei
	ld a, $1
	ld [$cf2d], a
	ld de, PalPacket_72508
	ld hl, SGBBorderGraphics
	call Func_7210b
	xor a
	ld [$cf2d], a
	ld de, PalPacket_72518
	ld hl, BorderPalettes
	call Func_7210b
	xor a
	ld [$cf2d], a
	ld de, PalPacket_724d8
	ld hl, SuperPalettes
	call Func_7210b
	call ZeroVram
	ld hl, PalPacket_72538
	jp SendSGBPacket

Func_72075: ; 72075 (1c:6075)
	ld hl, PointerTable_72089
	ld c, $9
.asm_7207a
	push bc
	ld a, [hli]
	push hl
	ld h, [hl]
	ld l, a
	call SendSGBPacket
	pop hl
	inc hl
	pop bc
	dec c
	jr nz, .asm_7207a
	ret

PointerTable_72089: ; 72089 (1c:6089)
	dw PalPacket_72528
	dw PalPacket_72548
	dw PalPacket_72558
	dw PalPacket_72568
	dw PalPacket_72578
	dw PalPacket_72588
	dw PalPacket_72598
	dw PalPacket_725a8
	dw PalPacket_725b8

Func_7209b: ; 7209b (1c:609b)
	ld hl, PalPacket_724f8
	di
	call SendSGBPacket
	ld a, $1
	ld [$fff9], a
	ei
	call Wait7000
	ld a, [rJOYP] ; $ff0
	and $3
	cp $3
	jr nz, .asm_720fd
	ld a, $20
	ld [rJOYP], a ; $ff0
	ld a, [rJOYP] ; $ff0
	ld a, [rJOYP] ; $ff0
	call Wait7000
	call Wait7000
	ld a, $30
	ld [rJOYP], a ; $ff0
	call Wait7000
	call Wait7000
	ld a, $10
	ld [rJOYP], a ; $ff0
	ld a, [rJOYP] ; $ff0
	ld a, [rJOYP] ; $ff0
	ld a, [rJOYP] ; $ff0
	ld a, [rJOYP] ; $ff0
	ld a, [rJOYP] ; $ff0
	ld a, [rJOYP] ; $ff0
	call Wait7000
	call Wait7000
	ld a, $30
	ld [rJOYP], a ; $ff0
	ld a, [rJOYP] ; $ff0
	ld a, [rJOYP] ; $ff0
	ld a, [rJOYP] ; $ff0
	call Wait7000
	call Wait7000
	ld a, [rJOYP] ; $ff0
	and $3
	cp $3
	jr nz, .asm_720fd
	call Func_72102
	and a
	ret
.asm_720fd
	call Func_72102
	scf
	ret

Func_72102: ; 72102 (1c:6102)
	ld hl, PalPacket_724e8
	call SendSGBPacket
	jp Wait7000

Func_7210b: ; 7210b (1c:610b)
	di
	push de
	call DisableLCD
	ld a, $e4
	ld [rBGP], a ; $ff47
	ld de, $8800
	ld a, [$cf2d]
	and a
	jr z, .asm_72122
	call Func_72188
	jr .asm_72128
.asm_72122
	ld bc, $1000
	call CopyData
.asm_72128
	ld hl, $9800
	ld de, $c
	ld a, $80
	ld c, $d
.asm_72132
	ld b, $14
.asm_72134
	ld [hli], a
	inc a
	dec b
	jr nz, .asm_72134
	add hl, de
	dec c
	jr nz, .asm_72132
	ld a, $e3
	ld [rLCDC], a ; $ff40
	pop hl
	call SendSGBPacket
	xor a
	ld [rBGP], a ; $ff47
	ei
	ret

Wait7000: ; 7214a (1c:614a)
; each loop takes about 10 cycles so this routine actually loops through 70000
; cycles.
	ld de, 7000
.loop
	nop
	nop
	nop
	dec de
	ld a, d
	or e
	jr nz, .loop
	ret

Func_72156: ; 72156 (1c:6156)
	ld a, [$cf1a]
	and a
	jr z, .asm_72165
	push de
	call Func_7216d
	pop hl
	call Func_72187
	ret
.asm_72165
	push de
	call SendSGBPacket
	pop hl
	jp SendSGBPacket

Func_7216d: ; 7216d (1c:616d)
	ld a, $80
	ld [$ff68], a
	inc hl
	ld c, $20
.asm_72174
	ld a, [hli]
	inc hl
	add a
	add a
	add a
	ld de, SuperPalettes
	add e
	jr nc, .asm_72180
	inc d
.asm_72180
	ld a, [de]
	ld [$ff69], a
	dec c
	jr nz, .asm_72174
	ret

Func_72187: ; 72187 (1c:6187)
	ret

Func_72188: ; 72188 (1c:6188)
	ld b, $80
.asm_7218a
	ld c, $10
.asm_7218c
	ld a, [hli]
	ld [de], a
	inc de
	dec c
	jr nz, .asm_7218c
	ld c, $10
	xor a
.asm_72195
	ld [de], a
	inc de
	dec c
	jr nz, .asm_72195
	dec b
	jr nz, .asm_7218a
	ret

INCLUDE "data/sgb_packets.asm"

INCLUDE "data/mon_palettes.asm"

INCLUDE "data/super_palettes.asm"

INCLUDE "data/sgb_border.asm"

LoadSAV: ; 735e8 (1c:75e8)
;(if carry -> write
;"the file data is destroyed")
	call ClearScreen
	call LoadFontTilePatterns
	call LoadTextBoxTilePatterns
	call LoadSAVCheckSum
	jr c, .badsum
	call LoadSAVCheckSum1
	jr c, .badsum
	call LoadSAVCheckSum2
	jr c, .badsum
	ld a, $2 ; good checksum
	jr .goodsum
.badsum
	ld hl, $d730
	push hl
	set 6, [hl]
	ld hl, FileDataDestroyedText
	call PrintText
	ld c, $64
	call DelayFrames
	pop hl
	res 6, [hl]
	ld a, $1 ; bad checksum
.goodsum
	ld [$d088], a ; checksum flag
	ret

FileDataDestroyedText: ; 7361e (1c:761e)
	TX_FAR _FileDataDestroyedText
	db "@"

LoadSAVCheckSum: ; 73623 (1c:7623)
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	ld [$4000], a
	ld hl, $a598 ; hero name located in SRAM
	ld bc, $f8b ; but here checks the full SAV
	call SAVCheckSum
	ld c, a
	ld a, [$b523] ; SAV's checksum
	cp c
	jp z, .Func_73652
	ld hl, $a598
	ld bc, $f8b
	call SAVCheckSum
	ld c, a
	ld a, [$b523] ; SAV's checksum
	cp c
	jp nz, SAVBadCheckSum

.Func_73652 ; 73652 (1c:7652)
	ld hl, $a598
	ld de, W_PLAYERNAME ; $d158
	ld bc, $b
	call CopyData
	ld hl, $a5a3
	ld de, wPokedexOwned ; $d2f7
	ld bc, $789
	call CopyData
	ld hl, W_CURMAPTILESET ; $d367
	set 7, [hl]
	ld hl, $ad2c
	ld de, wSpriteStateData1
	ld bc, $200
	call CopyData
	ld a, [$b522]
	ld [$ffd7], a
	ld hl, $b0c0
	ld de, W_NUMINBOX ; $da80
	ld bc, $462
	call CopyData
	and a
	jp SAVGoodChecksum

LoadSAVCheckSum1: ; 73690 (1c:7690)
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	ld [$4000], a
	ld hl, $a598 ; hero name located in SRAM
	ld bc, $f8b  ; but here checks the full SAV
	call SAVCheckSum
	ld c, a
	ld a, [$b523] ; SAV's checksum
	cp c
	jr nz, SAVBadCheckSum
	ld hl, $b0c0
	ld de, W_NUMINBOX ; $da80
	ld bc, $462
	call CopyData
	and a
	jp SAVGoodChecksum

LoadSAVCheckSum2: ; 736bd (1c:76bd)
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	ld [$4000], a
	ld hl, $a598 ; hero name located in SRAM
	ld bc, $f8b  ; but here checks the full SAV
	call SAVCheckSum
	ld c, a
	ld a, [$b523] ; SAV's checksum
	cp c
	jp nz, SAVBadCheckSum
	ld hl, $af2c
	ld de, W_NUMINPARTY ; $d163
	ld bc, $194
	call CopyData
	ld hl, $a5a3
	ld de, wPokedexOwned ; $d2f7
	ld bc, wPokedexSeenEnd - wPokedexOwned
	call CopyData
	and a
	jp SAVGoodChecksum

SAVBadCheckSum: ; 736f7 (1c:76f7)
	scf

SAVGoodChecksum: ; 736f8 (1c:76f8)
	ld a, $0
	ld [$6000], a
	ld [$0], a
	ret

Func_73701: ; 0x73701
	call LoadSAVCheckSum
	call LoadSAVCheckSum1
	jp LoadSAVCheckSum2

SaveSAV: ;$770a
	callba PrintSaveScreenText
	ld hl,WouldYouLikeToSaveText
	call SaveSAVConfirm
	and a   ;|0 = Yes|1 = No|
	ret nz
	ld a,[$d088]
	dec a
	jr z,.save
	call SAVCheckRandomID
	jr z,.save
	ld hl,OlderFileWillBeErasedText
	call SaveSAVConfirm
	and a
	ret nz
.save        ;$772d
	call SaveSAVtoSRAM      ;$7848
	FuncCoord 1,13
	ld hl,Coord
	ld bc,$0412
	call ClearScreenArea ; clear area 4x12 starting at 13,1
	FuncCoord 1,14
	ld hl,Coord
	ld de,NowSavingString
	call PlaceString
	ld c,$78
	call DelayFrames
	ld hl,GameSavedText
	call PrintText
	ld a, (SFX_02_5d - SFX_Headers_02) / 3 ;sound for saved game
	call PlaySoundWaitForCurrent
	call WaitForSoundToFinish
	ld c,$1e
	jp DelayFrames

NowSavingString:
	db "Now saving...@"

SaveSAVConfirm: ; 73768 (1c:7768)
	call PrintText
	FuncCoord 0, 7
	ld hl,Coord
	ld bc,$0801     ;arrow's coordinates |b = Y|c = X|
	ld a,$14        ;one line shifting ($28 = 2 lines)
	ld [$d125],a
	call DisplayTextBoxID      ;handle Yes/No KeyPress
	ld a,[$cc26]
	ret

WouldYouLikeToSaveText: ; 0x7377d
	TX_FAR _WouldYouLikeToSaveText
	db "@"

GameSavedText: ; 73782 (1c:7782)
	TX_FAR _GameSavedText
	db "@"

OlderFileWillBeErasedText: ; 73787 (1c:7787)
	TX_FAR _OlderFileWillBeErasedText
	db "@"

SaveSAVtoSRAM0: ; 7378c (1c:778c)
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	ld [$4000], a
	ld hl, W_PLAYERNAME ; $d158
	ld de, $a598
	ld bc, $b
	call CopyData
	ld hl, wPokedexOwned ; $d2f7
	ld de, $a5a3
	ld bc, $789
	call CopyData
	ld hl, wSpriteStateData1 ; OAM?
	ld de, $ad2c
	ld bc, $200
	call CopyData
	ld hl, W_NUMINBOX ; $da80
	ld de, $b0c0
	ld bc, $462
	call CopyData
	ld a, [$ffd7]
	ld [$b522], a
	ld hl, $a598
	ld bc, $f8b
	call SAVCheckSum
	ld [$b523], a
	xor a
	ld [$6000], a
	ld [$0], a
	ret

SaveSAVtoSRAM1: ; 737e2 (1c:77e2)
; stored pokémon
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	ld [$4000], a
	ld hl, W_NUMINBOX ; $da80
	ld de, $b0c0
	ld bc, $462
	call CopyData
	ld hl, $a598
	ld bc, $f8b
	call SAVCheckSum
	ld [$b523], a
	xor a
	ld [$6000], a
	ld [$0], a
	ret

SaveSAVtoSRAM2: ; 7380f (1c:780f)
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	ld [$4000], a
	ld hl, W_NUMINPARTY ; $d163
	ld de, $af2c
	ld bc, $194
	call CopyData
	ld hl, wPokedexOwned ; pokédex only
	ld de, $a5a3
	ld bc, wPokedexSeenEnd - wPokedexOwned
	call CopyData
	ld hl, $a598
	ld bc, $f8b
	call SAVCheckSum
	ld [$b523], a
	xor a
	ld [$6000], a
	ld [$0], a
	ret

SaveSAVtoSRAM: ; 73848 (1c:7848)
	ld a, $2
	ld [$d088], a
	call SaveSAVtoSRAM0
	call SaveSAVtoSRAM1
	jp SaveSAVtoSRAM2

SAVCheckSum: ; 73856 (1c:7856)
;Check Sum (result[1 byte] is complemented)
	ld d, $0
.loop
	ld a, [hli]
	add d
	ld d, a
	dec bc
	ld a, b
	or c
	jr nz, .loop
	ld a, d
	cpl
	ret

Func_73863: ; 73863 (1c:7863)
	ld hl, $a000
	ld de, $ba4d
	ld b, $6
.asm_7386b
	push bc
	push de
	ld bc, $462
	call SAVCheckSum
	pop de
	ld [de], a
	inc de
	pop bc
	dec b
	jr nz, .asm_7386b
	ret

Func_7387b: ; 7387b (1c:787b)
	ld hl, PointerTable_73895 ; $7895
	ld a, [$d5a0]
	and $7f
	cp $6
	ld b, $2
	jr c, .asm_7388c
	inc b
	sub $6
.asm_7388c
	ld e, a
	ld d, $0
	add hl, de
	add hl, de
	ld a, [hli]
	ld h, [hl]
	ld l, a
	ret

PointerTable_73895: ; 73895 (1c:7895)
	dw $A000
	dw $A462
	dw $A8C4
	dw $AD26
	dw $B188
	dw $B5EA

Func_738a1:: ; 738a1 (1c:78a1)
	ld hl, WhenYouChangeBoxText
	call PrintText
	call YesNoChoice
	ld a, [wCurrentMenuItem] ; $cc26
	and a
	ret nz
	ld hl, $d5a0
	bit 7, [hl]
	call z, Func_73a29
	call Func_7393f
	call UpdateSprites
	ld hl, $fff6
	set 1, [hl]
	call HandleMenuInput
	ld hl, $fff6
	res 1, [hl]
	bit 1, a
	ret nz
	call Func_7387b
	ld e, l
	ld d, h
	ld hl, W_NUMINBOX ; $da80
	call Func_7390e
	ld a, [wCurrentMenuItem] ; $cc26
	set 7, a
	ld [$d5a0], a
	call Func_7387b
	ld de, W_NUMINBOX ; $da80
	call Func_7390e
	ld hl, W_MAPTEXTPTR ; $d36c
	ld de, wWhichTrade ; $cd3d
	ld a, [hli]
	ld [de], a
	inc de
	ld a, [hl]
	ld [de], a
	call Func_3f05
	call SaveSAVtoSRAM
	ld hl, wWhichTrade ; $cd3d
	call Func_3f0f
	ld a, (SFX_02_5d - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent
	call WaitForSoundToFinish
	ret

WhenYouChangeBoxText: ; 73909 (1c:7909)
	TX_FAR _WhenYouChangeBoxText
	db "@"

Func_7390e: ; 7390e (1c:790e)
	push hl
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	ld a, b
	ld [$4000], a
	ld bc, $462
	call CopyData
	pop hl
	xor a
	ld [hli], a
	dec a
	ld [hl], a
	ld hl, $a000
	ld bc, $1a4c
	call SAVCheckSum
	ld [$ba4c], a
	call Func_73863
	xor a
	ld [$6000], a
	ld [$0], a
	ret

Func_7393f: ; 7393f (1c:793f)
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, $3
	ld [wMenuWatchedKeys], a ; $cc29
	ld a, $b
	ld [wMaxMenuItem], a ; $cc28
	ld a, $1
	ld [wTopMenuItemY], a ; $cc24
	ld a, $c
	ld [wTopMenuItemX], a ; $cc25
	xor a
	ld [$cc37], a
	ld a, [$d5a0]
	and $7f
	ld [wCurrentMenuItem], a ; $cc26
	ld [wLastMenuItem], a ; $cc2a
	ld hl, wTileMap
	ld b, $2
	ld c, $9
	call TextBoxBorder
	ld hl, ChooseABoxText
	call PrintText
	FuncCoord 11, 0 ; $c3ab
	ld hl, Coord
	ld b, $c
	ld c, $7
	call TextBoxBorder
	ld hl, $fff6
	set 2, [hl]
	ld de, BoxNames ; $79d9
	FuncCoord 13, 1 ; $c3c1
	ld hl, Coord
	call PlaceString
	ld hl, $fff6
	res 2, [hl]
	ld a, [$d5a0]
	and $7f
	cp $9
	jr c, .asm_739a6
	sub $9
	FuncCoord 8, 2 ; $c3d0
	ld hl, Coord
	ld [hl], $f7
	add $f6
	jr .asm_739a8
.asm_739a6
	add $f7
.asm_739a8
	FuncCoord 9, 2 ; $c3d1
	ld [Coord], a
	FuncCoord 1, 2 ; $c3c9
	ld hl, Coord
	ld de, BoxNoText
	call PlaceString
	call Func_73a84
	FuncCoord 18, 1 ; $c3c6
	ld hl, Coord
	ld de, wWhichTrade ; $cd3d
	ld bc, $14
	ld a, $c
.asm_739c2
	push af
	ld a, [de]
	and a
	jr z, .asm_739c9
	ld [hl], $78
.asm_739c9
	add hl, bc
	inc de
	pop af
	dec a
	jr nz, .asm_739c2
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ret

ChooseABoxText: ; 739d4 (1c:79d4)
	TX_FAR _ChooseABoxText
	db "@"

BoxNames: ; 739d9 (1c:79d9)
	db   "BOX 1"
	next "BOX 2"
	next "BOX 3"
	next "BOX 4"
	next "BOX 5"
	next "BOX 6"
	next "BOX 7"
	next "BOX 8"
	next "BOX 9"
	next "BOX10"
	next "BOX11"
	next "BOX12@"

BoxNoText: ; 73a21 (1c:7a21)
	db "BOX No.@"

Func_73a29: ; 73a29 (1c:7a29)
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	ld a, $2
	ld [$4000], a
	call Func_73a4b
	ld a, $3
	ld [$4000], a
	call Func_73a4b
	xor a
	ld [$6000], a
	ld [$0], a
	ret

Func_73a4b: ; 73a4b (1c:7a4b)
	ld hl, $a000
	call Func_73a7f
	ld hl, $a462
	call Func_73a7f
	ld hl, $a8c4
	call Func_73a7f
	ld hl, $ad26
	call Func_73a7f
	ld hl, $b188
	call Func_73a7f
	ld hl, $b5ea
	call Func_73a7f
	ld hl, $a000
	ld bc, $1a4c
	call SAVCheckSum
	ld [$ba4c], a
	call Func_73863
	ret

Func_73a7f: ; 73a7f (1c:7a7f)
	xor a
	ld [hli], a
	dec a
	ld [hl], a
	ret

Func_73a84: ; 73a84 (1c:7a84)
	ld hl, wWhichTrade ; $cd3d
	push hl
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	ld a, $2
	ld [$4000], a
	call Func_73ab8
	ld a, $3
	ld [$4000], a
	call Func_73ab8
	xor a
	ld [$6000], a
	ld [$0], a
	pop hl
	ld a, [$d5a0]
	and $7f
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [W_NUMINBOX] ; $da80
	ld [hl], a
	ret

Func_73ab8: ; 73ab8 (1c:7ab8)
	ld a, [$a000]
	ld [hli], a
	ld a, [$a462]
	ld [hli], a
	ld a, [$a8c4]
	ld [hli], a
	ld a, [$ad26]
	ld [hli], a
	ld a, [$b188]
	ld [hli], a
	ld a, [$b5ea]
	ld [hli], a
	ret

SAVCheckRandomID: ;$7ad1
;checks if Sav file is the same by checking player's name 1st letter ($a598)
; and the two random numbers generated at game beginning
;(which are stored at $d359-d35a)
	ld a,$0a
	ld [$0000],a
	ld a,$01
	ld [$6000],a
	ld [$4000],a
	ld a,[$a598]
	and a
	jr z,.next
	ld hl,$a598
	ld bc,$0f8b
	call SAVCheckSum
	ld c,a
	ld a,[$b523]
	cp c
	jr nz,.next
	ld hl,$a605
	ld a,[hli]
	ld h,[hl]
	ld l,a
	ld a,[$d359]
	cp l
	jr nz,.next
	ld a,[$d35a]
	cp h
.next
	ld a,$00
	ld [$6000],a
	ld [$0000],a
	ret

Func_73b0d: ; 73b0d (1c:7b0d)
	ld a, [$d5a2]
	dec a
	cp $32
	jr nc, .asm_73b28
	ld hl, $a598
	ld bc, $60
	call AddNTimes
	ld e, l
	ld d, h
	ld hl, $cc5b
	ld bc, $60
	jr CopyToSRAM0
.asm_73b28
	ld hl, $a5f8
	ld de, $a598
	ld bc, $1260
	call CopyToSRAM0
	ld hl, $cc5b
	ld de, $b7f8
	ld bc, $60
	jr CopyToSRAM0

Func_73b3f: ; 73b3f (1c:7b3f)
	ld hl, $a598
	ld bc, $60
	ld a, [wWhichTrade] ; $cd3d
	call AddNTimes
	ld de, $cc5b
	ld bc, $60
	; fallthrough
CopyToSRAM0: ; 73b51 (1c:7b51)
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	xor a
	ld [$4000], a
	call CopyData
	xor a
	ld [$6000], a
	ld [$0], a
	ret

Func_73b6a: ; 73b6a (1c:7b6a)
	ld a, $a
	ld [$0], a
	ld a, $1
	ld [$6000], a
	xor a
	call PadSRAM_FF
	ld a, $1
	call PadSRAM_FF
	ld a, $2
	call PadSRAM_FF
	ld a, $3
	call PadSRAM_FF
	xor a
	ld [$6000], a
	ld [$0], a
	ret

PadSRAM_FF: ; 73b8f (1c:7b8f)
	ld [$4000], a
	ld hl, $a000
	ld bc, $2000
	ld a, $ff
	jp FillMemory

SECTION "bank1D",ROMX,BANK[$1D]

CopycatsHouse1FBlocks: ; 74000 (1d:4000)
	INCBIN "maps/copycatshouse1f.blk"

CinnabarMartBlocks: ; 74010 (1d:4010)
PewterMartBlocks: ; 74010 (1d:4010)
	INCBIN "maps/pewtermart.blk"

FuchsiaHouse1Blocks: ; 74020 (1d:4020)
	INCBIN "maps/fuchsiahouse1.blk"

CinnabarPokecenterBlocks: ; 74030 (1d:4030)
FuchsiaPokecenterBlocks: ; 74030 (1d:4030)
	INCBIN "maps/fuchsiapokecenter.blk"

CeruleanHouse2Blocks: ; 7404c (1d:404c)
	INCBIN "maps/ceruleanhouse2.blk"

HallOfFameComputer: ; 7405c (1d:405c)
	callba AnimateHallOfFame
	call ClearScreen
	ld c, $64
	call DelayFrames
	call DisableLCD
	ld hl, $8800
	ld bc, $400
	call Func_74171
	ld hl, $9600
	ld bc, $100
	call Func_74171
	ld hl, $97e0
	ld bc, $10
	ld a, $ff
	call FillMemory
	ld hl, wTileMap
	call Func_7417b
	FuncCoord 0, 14 ; $c4b8
	ld hl, Coord
	call Func_7417b
	ld a, $c0
	ld [rBGP], a ; $ff47
	call EnableLCD
	ld a, $ff
	call PlaySoundWaitForCurrent
	ld c, BANK(Music_Credits)
	ld a, MUSIC_CREDITS
	call PlayMusic
	ld c, $80
	call DelayFrames
	xor a
	ld [wWhichTrade], a ; $cd3d
	ld [$cd3e], a
	jp Credits

Func_740ba: ; 740ba (1d:40ba)
	ld hl, DataTable_74160 ; $4160
	ld b, $4
.asm_740bf
	ld a, [hli]
	ld [rBGP], a ; $ff47
	ld c, $5
	call DelayFrames
	dec b
	jr nz, .asm_740bf
	ret

DisplayCreditsMon: ; 740cb (1d:40cb)
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a
	call SaveScreenTilesToBuffer1
	call FillMiddleOfScreenWithWhite

	; display the next monster from CreditsMons
	ld hl,$CD3E
	ld c,[hl] ; how many monsters have we displayed so far?
	inc [hl]
	ld b,0
	ld hl,CreditsMons
	add hl,bc ; go that far in the list of monsters and get the next one
	ld a,[hl]
	ld [$CF91],a
	ld [$D0B5],a
	FuncCoord 8, 6 ; $c420
	ld hl,Coord
	call GetMonHeader
	call LoadFrontSpriteByMonIndex
	ld hl,$980C
	call Func_74164
	xor a
	ld [H_AUTOBGTRANSFERENABLED],a
	call LoadScreenTilesFromBuffer1
	ld hl,$9800
	call Func_74164
	ld a,$A7
	ld [$FF4B],a
	ld hl,$9C00
	call Func_74164
	call FillMiddleOfScreenWithWhite
	ld a,$FC
	ld [$FF47],a
	ld bc,7
.next
	call Func_74140
	dec c
	jr nz,.next
	ld c,$14
.next2
	call Func_74140
	ld a,[$FF4B]
	sub 8
	ld [$FF4B],a
	dec c
	jr nz,.next2
	xor a
	ld [$FFB0],a
	ld a,$C0
	ld [$FF47],a
	ret

INCLUDE "data/credit_mons.asm"

Func_74140: ; 74140 (1d:4140)
	ld h, b
	ld l, $20
	call Func_74152
	ld h, $0
	ld l, $70
	call Func_74152
	ld a, b
	add $8
	ld b, a
	ret

Func_74152: ; 74152 (1d:4152)
	ld a, [$ff44]
	cp l
	jr nz, Func_74152
	ld a, h
	ld [rSCX], a ; $ff43
.asm_7415a
	ld a, [$ff44]
	cp h
	jr z, .asm_7415a
	ret

DataTable_74160: ; 74160 (1d:4160)
	db $C0,$D0,$E0,$F0

Func_74164: ; 74164 (1d:4164)
	ld a, l
	ld [H_AUTOBGTRANSFERDEST], a ; $ffbc
	ld a, h
	ld [$ffbd], a
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	jp Delay3

Func_74171: ; 74171 (1d:4171)
	ld [hl], $0
	inc hl
	inc hl
	dec bc
	ld a, b
	or c
	jr nz, Func_74171
	ret

Func_7417b: ; 7417b (1d:417b)
	ld bc, $50
	ld a, $7e
	jp FillMemory

FillMiddleOfScreenWithWhite: ; 74183 (1d:4183)
	FuncCoord 0, 4 ; $c3f0
	ld hl, Coord
	ld bc, $c8 ; 10 rows of 20 tiles each
	ld a, $7f ; blank white tile
	jp FillMemory

Credits: ; 7418e (1d:418e)
	ld de, CreditsOrder ; $4243
	push de
.asm_74192
	pop de
	FuncCoord 9, 6 ; $c421
	ld hl, Coord
	push hl
	call FillMiddleOfScreenWithWhite
	pop hl
.asm_7419b
	ld a, [de]
	inc de
	push de
	cp $ff
	jr z, .asm_741d5
	cp $fe
	jr z, .asm_741dc
	cp $fd
	jr z, .asm_741e6
	cp $fc
	jr z, .asm_741ed
	cp $fb
	jr z, .asm_741f4
	cp $fa
	jr z, .showTheEnd
	push hl
	push hl
	ld hl, CreditsTextPointers ; $42c3
	add a
	ld c, a
	ld b, $0
	add hl, bc
	ld e, [hl]
	inc hl
	ld d, [hl]
	ld a, [de]
	inc de
	ld c, a
	ld b, $ff
	pop hl
	add hl, bc
	call PlaceString
	pop hl
	ld bc, $28
	add hl, bc
	pop de
	jr .asm_7419b
.asm_741d5
	call Func_740ba
	ld c, $5a
	jr .asm_741de
.asm_741dc
	ld c, $6e
.asm_741de
	call DelayFrames
	call DisplayCreditsMon
	jr .asm_74192
.asm_741e6
	call Func_740ba
	ld c, $78
	jr .asm_741ef
.asm_741ed
	ld c, $8c
.asm_741ef
	call DelayFrames
	jr .asm_74192
.asm_741f4
	push de
	callba Func_4541
	pop de
	pop de
	jr .asm_7419b
.showTheEnd
	ld c, $10
	call DelayFrames
	call FillMiddleOfScreenWithWhite
	pop de
	ld de, TheEndGfx
	ld hl, $9600
	ld bc, (BANK(TheEndGfx) << 8) + $0a
	call CopyVideoData
	FuncCoord 4, 8 ; $c444
	ld hl, Coord
	ld de, UnnamedText_74229 ; $4229
	call PlaceString
	FuncCoord 4, 9 ; $c458
	ld hl, Coord
	inc de
	call PlaceString
	jp Func_740ba

UnnamedText_74229: ; 74229 (1d:4229)
	db $60," ",$62," ",$64,"  ",$64," ",$66," ",$68,"@"
	db $61," ",$63," ",$65,"  ",$65," ",$67," ",$69,"@"

INCLUDE "data/credits_order.asm"

INCLUDE "text/credits_text.asm"

TheEndGfx: ; 7473e (1d:473e) ; 473E (473F on blue)
	INCBIN "gfx/theend.w40.interleave.2bpp"

PrintStatusAilment: ; 747de (1d:47de)
	ld a, [de]
	bit PSN, a
	jr nz, .psn
	bit BRN, a
	jr nz, .brn
	bit FRZ, a
	jr nz, .frz
	bit PAR, a
	jr nz, .par
	and SLP
	ret z
	ld a, "S"
	ld [hli], a
	ld a, "L"
	ld [hli], a
	ld [hl], "P"
	ret
.psn
	ld a, "P"
	ld [hli], a
	ld a, "S"
	ld [hli], a
	ld [hl], "N"
	ret
.brn
	ld a, "B"
	ld [hli], a
	ld a, "R"
	ld [hli], a
	ld [hl], "N"
	ret
.frz
	ld a, "F"
	ld [hli], a
	ld a, "R"
	ld [hli], a
	ld [hl], "Z"
	ret
.par
	ld a, "P"
	ld [hli], a
	ld a, "A"
	ld [hli], a
	ld [hl], "R"
	ret

HiddenItemNear: ; 7481f (1d:481f)
	ld hl, HiddenItemCoords
	ld b, $0
.asm_74824
	ld de, $0003
	ld a, [W_CURMAP]
	call IsInArrayCummulativeCount
	ret nc ; return if current map has no hidden items
	push bc
	push hl
	ld hl, $d6f0
	ld c, b
	ld b, $2
	ld a, $10
	call Predef ; indirect jump to HandleBitArray (f666 (3:7666))
	ld a, c
	pop hl
	pop bc
	inc b
	and a
	inc hl
	ld d, [hl]
	inc hl
	ld e, [hl]
	inc hl
	jr nz, .asm_74824 ; 0x74845 $dd
	ld a, [W_YCOORD]
	call Func_7486b
	cp d
	jr nc, .asm_74824 ; 0x7484e $d4
	ld a, [W_YCOORD]
	add $4
	cp d
	jr c, .asm_74824 ; 0x74856 $cc
	ld a, [W_XCOORD]
	call Func_7486b
	cp e
	jr nc, .asm_74824 ; 0x7485f $c3
	ld a, [W_XCOORD]
	add $5
	cp e
	jr c, .asm_74824 ; 0x74867 $bb
	scf
	ret

Func_7486b: ; 7486b (1d:486b)
	sub $5
	cp $f0
	ret c
	xor a
	ret

Func_74872: ; 74872 (1d:4872)
; code similar to this appears in a lot of banks; this particular
; one is called after you beat the Rocket that gives you TM28 DIG.
; the screen then fades out, he disappears, and fades back in
	call GBFadeIn1
	ld a, $07
	ld [$CC4D], a
	ld a, $15
	call Predef
	ld a, $09
	ld [$CC4D], a
	ld a, $11
	call Predef
	ld a, $06
	ld [$CC4D], a
	ld a, $11
	call Predef
	call GBFadeOut1
	ret

INCLUDE "data/mapHeaders/viridiangym.asm"

INCLUDE "scripts/viridiangym.asm"

INCLUDE "data/mapObjects/viridiangym.asm"

ViridianGymBlocks: ; 74c47 (1d:4c47)
	INCBIN "maps/viridiangym.blk"

INCLUDE "data/mapHeaders/pewtermart.asm"

INCLUDE "scripts/pewtermart.asm"

INCLUDE "data/mapObjects/pewtermart.asm"

INCLUDE "data/mapHeaders/unknowndungeon1.asm"

INCLUDE "scripts/unknowndungeon1.asm"

INCLUDE "data/mapObjects/unknowndungeon1.asm"

UnknownDungeon1Blocks: ; 74d76 (1d:4d76)
	INCBIN "maps/unknowndungeon1.blk"

INCLUDE "data/mapHeaders/ceruleanhouse2.asm"

INCLUDE "scripts/ceruleanhouse2.asm"

INCLUDE "data/mapObjects/ceruleanhouse2.asm"

VendingMachineMenu: ; 74ee0 (1d:4ee0)
	ld hl, VendingMachineText1
	call PrintText
	ld a, $13
	ld [$d125], a
	call DisplayTextBoxID
	xor a
	ld [wCurrentMenuItem], a ; $cc26
	ld [wLastMenuItem], a ; $cc2a
	ld a, $3
	ld [wMenuWatchedKeys], a ; $cc29
	ld a, $3
	ld [wMaxMenuItem], a ; $cc28
	ld a, $5
	ld [wTopMenuItemY], a ; $cc24
	ld a, $1
	ld [wTopMenuItemX], a ; $cc25
	ld hl, $d730
	set 6, [hl]
	FuncCoord 0, 3 ; $c3dc
	ld hl, Coord
	ld b, $8
	ld c, $c
	call TextBoxBorder
	call UpdateSprites
	FuncCoord 2, 5 ; $c406
	ld hl, Coord
	ld de, DrinkText
	call PlaceString
	FuncCoord 9, 6 ; $c421
	ld hl, Coord
	ld de, DrinkPriceText
	call PlaceString
	ld hl, $d730
	res 6, [hl]
	call HandleMenuInput
	bit 1, a
	jr nz, .asm_74f93
	ld a, [wCurrentMenuItem] ; $cc26
	cp $3
	jr z, .asm_74f93
	xor a
	ld [$ff9f], a
	ld [$ffa1], a
	ld a, $2
	ld [$ffa0], a
	call HasEnoughMoney
	jr nc, .enoughMoney
	ld hl, VendingMachineText4
	jp PrintText
.enoughMoney
	call Func_74fe7
	ld a, [$ffdb]
	ld b, a
	ld c, 1
	call GiveItem
	jr nc, .BagFull
	ld b, $3c ; number of times to play the "brrrrr" sound
.playDeliverySound ; 0x74f63
	ld c, $2
	call DelayFrames
	push bc
	ld a, (SFX_02_53 - SFX_Headers_02) / 3
	call PlaySound
	pop bc
	dec b
	jr nz, .playDeliverySound
.asm_74f72
	ld hl, VendingMachineText5
	call PrintText
	ld hl, $ffde
	ld de, wPlayerMoney + 2 ; $d349
	ld c, $3
	ld a, $c
	call Predef ; indirect jump to Func_f836 (f836 (3:7836))
	ld a, $13
	ld [$d125], a
	jp DisplayTextBoxID
.BagFull
	ld hl, VendingMachineText6
	jp PrintText
.asm_74f93
	ld hl, VendingMachineText7
	jp PrintText

VendingMachineText1: ; 74f99 (1d:4f99)
	TX_FAR _VendingMachineText1
	db "@"

DrinkText: ; 74f9e (1d:4f9e)
	db   "FRESH WATER"
	next "SODA POP"
	next "LEMONADE"
	next "CANCEL@"

DrinkPriceText: ; 74fc3 (1d:4fc3)
	db   "¥200"
	next "¥300"
	next "¥350",$4E,"@"

VendingMachineText4: ; 74fd3 (1d:4fd3)
	TX_FAR _VendingMachineText4
	db "@"

VendingMachineText5: ; 74fd8 (1d:4fd8)
	TX_FAR _VendingMachineText5
	db "@"

VendingMachineText6: ; 74fdd (1d:4fdd)
	TX_FAR _VendingMachineText6
	db "@"

VendingMachineText7: ; 74fe2 (1d:4fe2)
	TX_FAR _VendingMachineText7
	db "@"

Func_74fe7: ; 74fe7 (1d:4fe7)
	ld hl, VendingPrices
	ld a, [$cc26]
	add a
	add a
	ld d, $0
	ld e, a
	add hl, de
	ld a, [hli]
	ld [$ffdb], a
	ld a, [hli]
	ld [$ffdc], a
	ld a, [hli]
	ld [$ffdd], a
	ld a, [hl]
	ld [$ffde], a
	ret

VendingPrices: ; 75000 (1d:5000)
	db FRESH_WATER,$00,$02,$00
	db SODA_POP,   $00,$03,$00
	db LEMONADE,   $00,$03,$50

INCLUDE "data/mapHeaders/fuchsiahouse1.asm"

INCLUDE "scripts/fuchsiahouse1.asm"

INCLUDE "data/mapObjects/fuchsiahouse1.asm"

INCLUDE "data/mapHeaders/fuchsiapokecenter.asm"

INCLUDE "scripts/fuchsiapokecenter.asm"

INCLUDE "data/mapObjects/fuchsiapokecenter.asm"

INCLUDE "data/mapHeaders/fuchsiahouse2.asm"

INCLUDE "scripts/fuchsiahouse2.asm"

INCLUDE "data/mapObjects/fuchsiahouse2.asm"

FuchsiaHouse2Blocks: ; 751ad (1d:51ad)
	INCBIN "maps/fuchsiahouse2.blk"

INCLUDE "data/mapHeaders/safarizoneentrance.asm"

INCLUDE "scripts/safarizoneentrance.asm"

INCLUDE "data/mapObjects/safarizoneentrance.asm"

SafariZoneEntranceBlocks: ; 75425 (1d:5425)
	INCBIN "maps/safarizoneentrance.blk"

INCLUDE "data/mapHeaders/fuchsiagym.asm"

INCLUDE "scripts/fuchsiagym.asm"

INCLUDE "data/mapObjects/fuchsiagym.asm"

FuchsiaGymBlocks: ; 756aa (1d:56aa)
	INCBIN "maps/fuchsiagym.blk"

INCLUDE "data/mapHeaders/fuchsiameetingroom.asm"

INCLUDE "scripts/fuchsiameetingroom.asm"

INCLUDE "data/mapObjects/fuchsiameetingroom.asm"

FuchsiaMeetingRoomBlocks: ; 75722 (1d:5722)
	INCBIN "maps/fuchsiameetingroom.blk"

INCLUDE "data/mapHeaders/cinnabargym.asm"

INCLUDE "scripts/cinnabargym.asm"

INCLUDE "data/mapObjects/cinnabargym.asm"

CinnabarGymBlocks: ; 75b26 (1d:5b26)
	INCBIN "maps/cinnabargym.blk"

INCLUDE "data/mapHeaders/lab1.asm"

INCLUDE "scripts/lab1.asm"

INCLUDE "data/mapObjects/lab1.asm"

Lab1Blocks: ; 75bf1 (1d:5bf1)
	INCBIN "maps/lab1.blk"

INCLUDE "data/mapHeaders/lab2.asm"

INCLUDE "scripts/lab2.asm"

INCLUDE "data/mapObjects/lab2.asm"

Lab2Blocks: ; 75c6b (1d:5c6b)
	INCBIN "maps/lab2.blk"

INCLUDE "data/mapHeaders/lab3.asm"

INCLUDE "scripts/lab3.asm"

INCLUDE "data/mapObjects/lab3.asm"

Lab3Blocks: ; 75d15 (1d:5d15)
	INCBIN "maps/lab3.blk"

INCLUDE "data/mapHeaders/lab4.asm"

INCLUDE "scripts/lab4.asm"

INCLUDE "data/mapObjects/lab4.asm"

Lab4Blocks: ; 75e10 (1d:5e10)
	INCBIN "maps/lab4.blk"

INCLUDE "data/mapHeaders/cinnabarpokecenter.asm"

INCLUDE "scripts/cinnabarpokecenter.asm"

INCLUDE "data/mapObjects/cinnabarpokecenter.asm"

INCLUDE "data/mapHeaders/cinnabarmart.asm"

INCLUDE "scripts/cinnabarmart.asm"

INCLUDE "data/mapObjects/cinnabarmart.asm"

INCLUDE "data/mapHeaders/copycatshouse1f.asm"

INCLUDE "scripts/copycatshouse1f.asm"

INCLUDE "data/mapObjects/copycatshouse1f.asm"

INCLUDE "data/mapHeaders/gary.asm"

INCLUDE "scripts/gary.asm"

INCLUDE "data/mapObjects/gary.asm"

GaryBlocks: ; 7615f (1d:615f)
	INCBIN "maps/gary.blk"

INCLUDE "data/mapHeaders/lorelei.asm"

INCLUDE "scripts/lorelei.asm"

INCLUDE "data/mapObjects/lorelei.asm"

LoreleiBlocks: ; 762ac (1d:62ac)
	INCBIN "maps/lorelei.blk"

INCLUDE "data/mapHeaders/bruno.asm"

INCLUDE "scripts/bruno.asm"

INCLUDE "data/mapObjects/bruno.asm"

BrunoBlocks: ; 76403 (1d:6403)
	INCBIN "maps/bruno.blk"

INCLUDE "data/mapHeaders/agatha.asm"

INCLUDE "scripts/agatha.asm"

INCLUDE "data/mapObjects/agatha.asm"

AgathaBlocks: ; 76560 (1d:6560)
	INCBIN "maps/agatha.blk"

PKMNLeaguePC: ; 0x7657e
	ld hl, AccessedHoFPCText
	call PrintText
	ld hl, $D730
	set 6, [hl]
	push hl
	ld a, [$CFCB]
	push af
	ld a, [$ffD7]
	push af
	xor a
	ld [$ffD7], a
	ld [W_SPRITEFLIPPED], a
	ld [$CFCB], a
	ld [$CD41], a
	ld [$CD42], a
	ld a, [$D5A2]
	ld b, a
	cp a, $33
	jr c, .first
	ld b, $32
	sub b
	ld [$CD42], a
.first
	ld hl, $CD42
	inc [hl]
	push bc
	ld a, [$CD41]
	ld [$CD3D], a
	callba Func_73b3f
	call Func_765e5
	pop bc
	jr c, .second
	ld hl, $CD41
	inc [hl]
	ld a, [hl]
	cp b
	jr nz, .first
.second
	pop af
	ld [$ffD7], a
	pop af
	ld [$CFCB], a
	pop hl
	res 6, [hl]
	call GBPalWhiteOutWithDelay3
	call ClearScreen
	call GoPAL_SET_CF1C
	jp GBPalNormal

Func_765e5: ; 765e5 (1d:65e5)
	ld c, 6
.third
	push bc
	call Func_76610
	call WaitForTextScrollButtonPress
	ld a, [H_CURRENTPRESSEDBUTTONS]
	bit 1, a
	jr nz, .fifth
	ld hl, $CC6B
	ld de, $CC5B
	ld bc, $0050
	call CopyData
	pop bc
	ld a, [$CC5B]
	cp a, $FF
	jr z, .fourth
	dec c
	jr nz, .third
.fourth
	and a
	ret
.fifth
	pop bc
	scf
	ret

Func_76610: ; 76610 (1d:6610)
	call GBPalWhiteOutWithDelay3
	call ClearScreen
	ld hl, $CC5B
	ld a, [hli]
	ld [$CD3D], a
	ld [$CF91], a
	ld [$D0B5], a
	ld [$CFD9], a
	ld [$CF1D], a
	ld a, [hli]
	ld [$CD3F], a
	ld de, $CD6D
	ld bc, $000B
	call CopyData
	ld b, $0B
	ld c, 0
	call GoPAL_SET
	FuncCoord 12, 5 ; $c410
	ld hl, Coord
	call GetMonHeader
	call LoadFrontSpriteByMonIndex
	call GBPalNormal
	FuncCoord 0, 13 ; $c4a4
	ld hl, Coord
	ld b, 2
	ld c, $12
	call TextBoxBorder
	FuncCoord 1, 15 ; $c4cd
	ld hl, Coord
	ld de, HallOfFameNoText
	call PlaceString
	FuncCoord 16, 15 ; $c4dc
	ld hl, Coord
	ld de, $CD42
	ld bc, $0103
	call PrintNumber
	ld b, BANK(Func_702f0)
	ld hl, Func_702f0
	jp Bankswitch

HallOfFameNoText: ; 76670 (1d:6670)
	db "HALL OF FAME No   @"

AccessedHoFPCText: ; 76683 (1d:6683)
	TX_FAR _AccessedHoFPCText
	db "@"

HiddenItems: ; 76688 (1d:6688)
	ld hl, HiddenItemCoords
	call Func_76857
	ld [$cd41], a
	ld hl, $d6f0
	ld a, [$cd41]
	ld c, a
	ld b, $2
	ld a, $10
	call Predef
	ld a, c
	and a
	ret nz
	call EnableAutoTextBoxDrawing
	ld a, $1
	ld [$cc3c], a
	ld a, [$cd3d] ; item ID
	ld [$d11e], a
	call GetItemName
	ld a, $24
	jp PrintPredefTextID

INCLUDE "data/hidden_item_coords.asm"

FoundHiddenItemText: ; 7675b (1d:675b)
; XXX where is the pointer to this?
	TX_FAR _FoundHiddenItemText
	db $8
	ld a, [$cd3d] ; item ID
	ld b, a
	ld c, 1
	call GiveItem
	jr nc, .BagFull
	ld hl, $d6f0
	ld a, [$cd41]
	ld c, a
	ld b, $1
	ld a, $10
	call Predef
	ld a, (SFX_02_3b - SFX_Headers_02) / 3
	call PlaySoundWaitForCurrent ; play sound
	call WaitForSoundToFinish ; wait for sound to finish playing
	jp TextScriptEnd
.BagFull
	call WaitForTextScrollButtonPress ; wait for button press
	xor a
	ld [$cc3c], a
	ld hl, HiddenItemBagFullText
	call PrintText
	jp TextScriptEnd

HiddenItemBagFullText: ; 76794 (1d:6794)
	TX_FAR _HiddenItemBagFullText
	db "@"

HiddenCoins: ; 76799 (1d:6799)
	ld b, COIN_CASE
	ld a, $1c
	call Predef
	ld a, b
	and a
	ret z
	ld hl, HiddenCoinCoords
	call Func_76857
	ld [$cd41], a
	ld hl, $d6fe
	ld a, [$cd41]
	ld c, a
	ld b, $2
	ld a, $10
	call Predef
	ld a, c
	and a
	ret nz
	xor a
	ld [$ff9f], a
	ld [$ffa0], a
	ld [$ffa1], a
	ld a, [$cd3d]
	sub COIN
	cp 10
	jr z, .bcd10
	cp 20
	jr z, .bcd20
	cp 40
	jr z, .bcd20
	jr .bcd100
.bcd10
	ld a, $10
	ld [$ffa1], a
	jr .bcddone
.bcd20
	ld a, $20
	ld [$ffa1], a
	jr .bcddone
.bcd40 ; due to a typo, this is never used
	ld a, $40
	ld [$ffa1], a
	jr .bcddone
.bcd100
	ld a, $1
	ld [$ffa0], a
.bcddone
	ld de, $d5a5
	ld hl, $ffa1
	ld c, $2
	ld a, $b
	call Predef
	ld hl, $d6fe
	ld a, [$cd41]
	ld c, a
	ld b, $1
	ld a, $10
	call Predef
	call EnableAutoTextBoxDrawing
	ld a, [wPlayerCoins]
	cp $99
	jr nz, .RoomInCoinCase
	ld a, [wPlayerCoins + 1]
	cp $99
	jr nz, .RoomInCoinCase
	ld a, $2c
	jr .done
.RoomInCoinCase
	ld a, $2b
.done
	jp PrintPredefTextID

INCLUDE "data/hidden_coins.asm"

FoundHiddenCoinsText: ; 76847 (1d:6847)
	TX_FAR _FoundHiddenCoinsText
	db $10,"@"

DroppedHiddenCoinsText: ; 7684d (1d:684d)
	TX_FAR _FoundHiddenCoins2Text
	db $10
	TX_FAR _DroppedHiddenCoinsText
	db "@"

Func_76857: ; 76857 (1d:6857)
	ld a, [$cd40]
	ld d, a
	ld a, [$cd41]
	ld e, a
	ld a, [W_CURMAP]
	ld b, a
	ld c, $ff
.loop
	inc c
	ld a, [hli]
	cp $ff ; end of the list?
	ret z  ; if so, we're done here
	cp b
	jr nz, .asm_76877 ; 0x7686b $a
	ld a, [hli]
	cp d
	jr nz, .asm_76878 ; 0x7686f $7
	ld a, [hli]
	cp e
	jr nz, .loop
	ld a, c
	ret
.asm_76877
	inc hl
.asm_76878
	inc hl
	jr .loop

SECTION "bank1E",ROMX,BANK[$1E]

; Draws a "frame block". Frame blocks are blocks of tiles that are put
; together to form frames in battle animations.
DrawFrameBlock: ; 78000 (1e:4000)
	ld l,c
	ld h,b
	ld a,[hli]
	ld [W_NUMFBTILES],a
	ld a,[W_FBDESTADDR + 1]
	ld e,a
	ld a,[W_FBDESTADDR]
	ld d,a
	xor a
	ld [W_FBTILECOUNTER],a ; loop counter
.loop
	ld a,[W_FBTILECOUNTER]
	inc a
	ld [W_FBTILECOUNTER],a
	ld a,[W_SUBANIMTRANSFORM]
	dec a
	jr z,.flipHorizontalAndVertical   ; 1
	dec a
	jp z,.flipHorizontalTranslateDown ; 2
	dec a
	jr z,.flipBaseCoords              ; 3
.noTransformation
	ld a,[W_BASECOORDY]
	add [hl]
	ld [de],a ; store Y
	inc hl
	inc de
	ld a,[W_BASECOORDX]
	jr .finishCopying
.flipBaseCoords
	ld a,[W_BASECOORDY]
	ld b,a
	ld a,136
	sub b ; flip Y base coordinate
	add [hl] ; Y offset
	ld [de],a ; store Y
	inc hl
	inc de
	ld a,[W_BASECOORDX]
	ld b,a
	ld a,168
	sub b ; flip X base coordinate
.finishCopying ; finish copying values to OAM (when [W_SUBANIMTRANSFORM] not 1 or 2)
	add [hl] ; X offset
	ld [de],a ; store X
	inc hl
	inc de
	ld a,[hli]
	add a,$31 ; base tile ID for battle animations
	ld [de],a ; store tile ID
	inc de
	ld a,[hli]
	ld [de],a ; store flags
	inc de
	jp .nextTile
.flipHorizontalAndVertical
	ld a,[W_BASECOORDY]
	add [hl] ; Y offset
	ld b,a
	ld a,136
	sub b ; flip Y coordinate
	ld [de],a ; store Y
	inc hl
	inc de
	ld a,[W_BASECOORDX]
	add [hl] ; X offset
	ld b,a
	ld a,168
	sub b ; flip X coordinate
	ld [de],a ; store X
	inc hl
	inc de
	ld a,[hli]
	add a,$31 ; base tile ID for battle animations
	ld [de],a ; store tile ID
	inc de
; toggle horizontal and vertical flip
	ld a,[hli] ; flags
	and a
	ld b,OAM_VFLIP | OAM_HFLIP
	jr z,.storeFlags1
	cp a,OAM_HFLIP
	ld b,OAM_VFLIP
	jr z,.storeFlags1
	cp a,OAM_VFLIP
	ld b,OAM_HFLIP
	jr z,.storeFlags1
	ld b,0
.storeFlags1
	ld a,b
	ld [de],a
	inc de
	jp .nextTile
.flipHorizontalTranslateDown
	ld a,[W_BASECOORDY]
	add [hl]
	add a,40 ; translate Y coordinate downwards
	ld [de],a ; store Y
	inc hl
	inc de
	ld a,[W_BASECOORDX]
	add [hl]
	ld b,a
	ld a,168
	sub b ; flip X coordinate
	ld [de],a ; store X
	inc hl
	inc de
	ld a,[hli]
	add a,$31 ; base tile ID for battle animations
	ld [de],a ; store tile ID
	inc de
	ld a,[hli]
	bit 5,a ; is horizontal flip enabled?
	jr nz,.disableHorizontalFlip
.enableHorizontalFlip
	set 5,a
	jr .storeFlags2
.disableHorizontalFlip
	res 5,a
.storeFlags2
	ld [de],a
	inc de
.nextTile
	ld a,[W_FBTILECOUNTER]
	ld c,a
	ld a,[W_NUMFBTILES]
	cp c
	jp nz,.loop ; go back up if there are more tiles to draw
.afterDrawingTiles
	ld a,[W_FBMODE]
	cp a,2
	jr z,.advanceFrameBlockDestAddr; skip delay and don't clean OAM buffer
	ld a,[W_SUBANIMFRAMEDELAY]
	ld c,a
	call DelayFrames
	ld a,[W_FBMODE]
	cp a,3
	jr z,.advanceFrameBlockDestAddr ; skip cleaning OAM buffer
	cp a,4
	jr z,.done ; skip cleaning OAM buffer and don't advance the frame block destination address
	ld a,[W_ANIMATIONID]
	cp a,GROWL
	jr z,.resetFrameBlockDestAddr
	call AnimationCleanOAM
.resetFrameBlockDestAddr
	ld hl,wOAMBuffer ; OAM buffer
	ld a,l
	ld [W_FBDESTADDR + 1],a
	ld a,h
	ld [W_FBDESTADDR],a ; set destination address to beginning of OAM buffer
	ret
.advanceFrameBlockDestAddr
	ld a,e
	ld [W_FBDESTADDR + 1],a
	ld a,d
	ld [W_FBDESTADDR],a
.done
	ret

PlayAnimation: ; 780f1 (1e:40f1)
	xor a
	ld [$FF8B],a
	ld [W_SUBANIMTRANSFORM],a
	ld a,[W_ANIMATIONID] ; get animation number
	dec a
	ld l,a
	ld h,0
	add hl,hl
	ld de,AttackAnimationPointers  ; $607d ; animation command stream pointers
	add hl,de
	ld a,[hli]
	ld h,[hl]
	ld l,a
.animationLoop
	ld a,[hli]
	cp a,$FF
	jr z,.AnimationOver
	cp a,$C0 ; is this subanimation or a special effect?
	jr c,.playSubanimation
.doSpecialEffect
	ld c,a
	ld de,SpecialEffectPointers
.searchSpecialEffectTableLoop
	ld a,[de]
	cp c
	jr z,.foundMatch
	inc de
	inc de
	inc de
	jr .searchSpecialEffectTableLoop
.foundMatch
	ld a,[hli]
	cp a,$FF ; is there a sound to play?
	jr z,.skipPlayingSound
	ld [wAnimSoundID],a ; store sound
	push hl
	push de
	call Func_7986f
	call PlaySound
	pop de
	pop hl
.skipPlayingSound
	push hl
	inc de
	ld a,[de]
	ld l,a
	inc de
	ld a,[de]
	ld h,a
	ld de,.nextAnimationCommand
	push de
	jp [hl] ; jump to special effect function
.playSubanimation
	ld c,a
	and a,%00111111
	ld [W_SUBANIMFRAMEDELAY],a
	xor a
	sla c
	rla
	sla c
	rla
	ld [$D09F],a ; tile select
	ld a,[hli] ; sound
	ld [wAnimSoundID],a ; store sound
	ld a,[hli] ; subanimation ID
	ld c,l
	ld b,h
	ld l,a
	ld h,0
	add hl,hl
	ld de,SubanimationPointers
	add hl,de
	ld a,l
	ld [W_SUBANIMADDRPTR],a
	ld a,h
	ld [W_SUBANIMADDRPTR + 1],a
	ld l,c
	ld h,b
	push hl
	ld a,[rOBP0]
	push af
	ld a,[$CC79]
	ld [rOBP0],a
	call LoadAnimationTileset
	call LoadSubanimation
	call PlaySubanimation
	pop af
	ld [rOBP0],a
.nextAnimationCommand
	pop hl
	jr .animationLoop
.AnimationOver ; 417B
	ret

LoadSubanimation: ; 7817c (1e:417c)
	ld a,[W_SUBANIMADDRPTR + 1]
	ld h,a
	ld a,[W_SUBANIMADDRPTR]
	ld l,a
	ld a,[hli]
	ld e,a
	ld a,[hl]
	ld d,a ; de = address of subanimation
	ld a,[de]
	ld b,a
	and a,31
	ld [W_SUBANIMCOUNTER],a ; number of frame blocks
	ld a,b
	and a,%11100000
	cp a,5 << 5 ; is subanimation type 5?
	jr nz,.isNotType5
.isType5
	call GetSubanimationTransform2
	jr .saveTransformation
.isNotType5
	call GetSubanimationTransform1
.saveTransformation
; place the upper 3 bits of a into bits 0-2 of a before storing
	srl a
	swap a
	ld [W_SUBANIMTRANSFORM],a
	cp a,4 ; is the animation reversed?
	ld hl,0
	jr nz,.storeSubentryAddr
; if the animation is reversed, then place the initial subentry address at the end of the list of subentries
	ld a,[W_SUBANIMCOUNTER]
	dec a
	ld bc,3
.loop
	add hl,bc
	dec a
	jr nz,.loop
.storeSubentryAddr
	inc de
	add hl,de
	ld a,l
	ld [W_SUBANIMSUBENTRYADDR],a
	ld a,h
	ld [W_SUBANIMSUBENTRYADDR + 1],a
	ret

; called if the subanimation type is not 5
; sets the transform to 0 (i.e. no transform) if it's the player's turn
; sets the transform to the subanimation type if it's the enemy's turn
GetSubanimationTransform1: ; 781c2 (1e:41c2)
	ld b,a
	ld a,[H_WHOSETURN]
	and a
	ld a,b
	ret nz
	xor a
	ret

; called if the subanimation type is 5
; sets the transform to 2 (i.e. horizontal and vertical flip) if it's the player's turn
; sets the transform to 0 (i.e. no transform) if it's the enemy's turn
GetSubanimationTransform2: ; 781ca (1e:41ca)
	ld a,[H_WHOSETURN]
	and a
	ld a,2 << 5
	ret z
	xor a
	ret

; loads tile patterns for battle animations
LoadAnimationTileset: ; 781d2 (1e:41d2)
	ld a,[$D09F] ; tileset select
	add a
	add a
	ld hl,AnimationTilesetPointers
	ld e,a
	ld d,0
	add hl,de
	ld a,[hli]
	ld [$D07D],a ; number of tiles
	ld a,[hli]
	ld e,a
	ld a,[hl]
	ld d,a ; de = address of tileset
	ld hl,$8310 ; destination address in VRAM
	ld b, BANK(AnimationTileset1) ; ROM bank
	ld a,[$D07D]
	ld c,a ; number of tiles
	jp CopyVideoData ; load tileset

AnimationTilesetPointers: ; 781f2 (1e:41f2)
	db 79 ; number of tiles
	dw AnimationTileset1
	db $FF

	db 79 ; number of tiles
	dw AnimationTileset2
	db $FF

	db 64 ; number of tiles
	dw AnimationTileset1
	db $FF

AnimationTileset1: ; 781fe (1e:41fe)
	INCBIN "gfx/attack_anim_1.2bpp"

AnimationTileset2: ; 786ee (1e:46ee)
	INCBIN "gfx/attack_anim_2.2bpp"

SlotMachineTiles2: ; 78bde (1e:4bde)
IF _RED
	INCBIN "gfx/red/slotmachine2.2bpp"
ENDC
IF _BLUE
	INCBIN "gfx/blue/slotmachine2.2bpp"
ENDC

MoveAnimation: ; 78d5e (1e:4d5e)
	push hl
	push de
	push bc
	push af
	call WaitForSoundToFinish
	call Func_78e23
	ld a,[W_ANIMATIONID]
	and a
	jr z,.AnimationFinished

	; if throwing a Poké Ball, skip the regular animation code
	cp a,TOSS_ANIM
	jr nz,.MoveAnimation
	ld de,.AnimationFinished
	push de
	jp TossBallAnimation

.MoveAnimation
	; check if battle animations are disabled in the options
	ld a,[$D355]
	bit 7,a
	jr nz,.AnimationsDisabled
	call ShareMoveAnimations
	call PlayAnimation
	jr .next4
.AnimationsDisabled
	ld c,30
	call DelayFrames
.next4
	call Func_78dbd ; reload pic and flash the pic in and out (to show damage)
.AnimationFinished
	call WaitForSoundToFinish
	xor a
	ld [$D096],a
	ld [$D09B],a
	ld [$D08B],a
	dec a
	ld [$CF07],a
	pop af
	pop bc
	pop de
	pop hl
	ret

ShareMoveAnimations: ; 78da6 (1e:4da6)
; some moves just reuse animations from status conditions
	ld a,[H_WHOSETURN]
	and a
	ret z

	; opponent’s turn

	ld a,[W_ANIMATIONID]

	cp a,AMNESIA
	ld b,CONF_ANIM
	jr z,.Replace

	cp a,REST
	ld b,SLP_ANIM
	ret nz

.Replace
	ld a,b
	ld [W_ANIMATIONID],a
	ret

Func_78dbd: ; 78dbd (1e:4dbd)
	ld a,[$CC5B]
	and a
	ret z
	dec a
	add a
	ld c,a
	ld b,0
	ld hl,PointerTable_78dcf
	add hl,bc
	ld a,[hli]
	ld h,[hl]
	ld l,a
	jp [hl]

PointerTable_78dcf: ; 78dcf (1e:4dcf)
	dw Func_78ddb
	dw Func_78de3
	dw Func_78deb
	dw Func_78df0
	dw Func_78df6
	dw Func_78dfe

Func_78ddb: ; 78ddb (1e:4ddb)
	call Func_79e6a
	ld b, $8
	jp Func_79209

Func_78de3: ; 78de3 (1e:4de3)
	call Func_79e6a
	ld b, $8
	jp Func_79210

Func_78deb: ; 78deb (1e:4deb)
	ld bc, $602
	jr Func_78e01

Func_78df0: ; 78df0 (1e:4df0)
	call Func_79e6a
	jp AnimationBlinkEnemyMon

Func_78df6: ; 78df6 (1e:4df6)
	call Func_79e6a
	ld b, $2
	jp Func_79210

Func_78dfe: ; 78dfe (1e:4dfe)
	ld bc, $302

Func_78e01: ; 78e01 (1e:4e01)
	push bc
	push bc
.asm_78e03
	ld a, [rWX] ; $ff4b
	inc a
	ld [rWX], a ; $ff4b
	ld c, $2
	call DelayFrames
	dec b
	jr nz, .asm_78e03
	pop bc
.asm_78e11
	ld a, [rWX] ; $ff4b
	dec a
	ld [rWX], a ; $ff4b
	ld c, $2
	call DelayFrames
	dec b
	jr nz, .asm_78e11
	pop bc
	dec c
	jr nz, Func_78e01
	ret

Func_78e23: ; 78e23 (1e:4e23)
	ld a, [$cf1b]
	and a
	ld a, $e4
	jr z, .asm_78e47
	ld a, $f0
	ld [$cc79], a
	ld b, $e4
	ld a, [W_ANIMATIONID] ; $d07c
	cp $aa
	jr c, .asm_78e3f
	cp $ae
	jr nc, .asm_78e3f
	ld b, $f0
.asm_78e3f
	ld a, b
	ld [rOBP0], a ; $ff48
	ld a, $6c
	ld [rOBP1], a ; $ff49
	ret
.asm_78e47
	ld a, $e4
	ld [$cc79], a
	ld [rOBP0], a ; $ff48
	ld a, $6c
	ld [rOBP1], a ; $ff49
	ret

PlaySubanimation: ; 78e53 (1e:4e53)
	ld a,[wAnimSoundID]
	cp a,$FF
	jr z,.skipPlayingSound
	call Func_7986f
	call PlaySound ; play sound effect
.skipPlayingSound
	ld hl,wOAMBuffer ; base address of OAM buffer
	ld a,l
	ld [W_FBDESTADDR + 1],a
	ld a,h
	ld [W_FBDESTADDR],a
	ld a,[W_SUBANIMSUBENTRYADDR + 1]
	ld h,a
	ld a,[W_SUBANIMSUBENTRYADDR]
	ld l,a
.loop
	push hl
	ld c,[hl] ; frame block ID
	ld b,0
	ld hl,FrameBlockPointers
	add hl,bc
	add hl,bc
	ld a,[hli]
	ld c,a
	ld a,[hli]
	ld b,a
	pop hl
	inc hl
	push hl
	ld e,[hl] ; base coordinate ID
	ld d,0
	ld hl,FrameBlockBaseCoords  ; $7c85 ; base coordinate table
	add hl,de
	add hl,de
	ld a,[hli]
	ld [W_BASECOORDY],a
	ld a,[hl]
	ld [W_BASECOORDX],a
	pop hl
	inc hl
	ld a,[hl] ; frame block mode
	ld [W_FBMODE],a
	call DrawFrameBlock
	call DoSpecialEffectByAnimationId ; run animation-specific function (if there is one)
	ld a,[W_SUBANIMCOUNTER]
	dec a
	ld [W_SUBANIMCOUNTER],a
	ret z
	ld a,[W_SUBANIMSUBENTRYADDR + 1]
	ld h,a
	ld a,[W_SUBANIMSUBENTRYADDR]
	ld l,a
	ld a,[W_SUBANIMTRANSFORM]
	cp a,4 ; is the animation reversed?
	ld bc,3
	jr nz,.nextSubanimationSubentry
	ld bc,-3
.nextSubanimationSubentry
	add hl,bc
	ld a,h
	ld [W_SUBANIMSUBENTRYADDR + 1],a
	ld a,l
	ld [W_SUBANIMSUBENTRYADDR],a
	jp .loop

AnimationCleanOAM: ; 78ec8 (1e:4ec8)
	push hl
	push de
	push bc
	push af
	call DelayFrame
	call CleanLCD_OAM
	pop af
	pop bc
	pop de
	pop hl
	ret

; this runs after each frame block is drawn in a subanimation
; it runs a particular special effect based on the animation ID
DoSpecialEffectByAnimationId: ; 78ed7 (1e:4ed7)
	push hl
	push de
	push bc
	ld a,[W_ANIMATIONID]
	ld hl,AnimationIdSpecialEffects
	ld de,3
	call IsInArray
	jr nc,.done
	inc hl
	ld a,[hli]
	ld h,[hl]
	ld l,a
	ld de,.done
	push de
	jp [hl]
.done
	pop bc
	pop de
	pop hl
	ret

; Format: Animation ID (1 byte), Address (2 bytes)
AnimationIdSpecialEffects: ; 78ef5 (1e:4ef5)
	db MEGA_PUNCH
	dw AnimationFlashScreen

	db GUILLOTINE
	dw AnimationFlashScreen

	db MEGA_KICK
	dw AnimationFlashScreen

	db HEADBUTT
	dw AnimationFlashScreen

	db TAIL_WHIP
	dw Func_790d0

	db GROWL
	dw DoGrowlSpecialEffects

	db DISABLE
	dw AnimationFlashScreen

	db BLIZZARD
	dw DoBlizzardSpecialEffects

	db BUBBLEBEAM
	dw AnimationFlashScreen

	db HYPER_BEAM
	dw FlashScreenEveryFourFrameBlocks

	db THUNDERBOLT
	dw FlashScreenEveryEightFrameBlocks

	db REFLECT
	dw AnimationFlashScreen

	db SELFDESTRUCT
	dw DoExplodeSpecialEffects

	db SPORE
	dw AnimationFlashScreen

	db EXPLOSION
	dw DoExplodeSpecialEffects

	db ROCK_SLIDE
	dw DoRockSlideSpecialEffects

	db $AA
	dw Func_79041

	db $AB
	dw Func_7904c

	db $AC
	dw Func_7907c

	db TOSS_ANIM
	dw DoBallTossSpecialEffects

	db SHAKE_ANIM
	dw DoBallShakeSpecialEffects

	db POOF_ANIM
	dw DoPoofSpecialEffects

	db GREATTOSS_ANIM
	dw DoBallTossSpecialEffects

	db ULTRATOSS_ANIM
	dw DoBallTossSpecialEffects

	db $FF ; terminator

DoBallTossSpecialEffects: ; 78f3e (1e:4f3e)
	ld a,[$CF91]
	cp a,3 ; is it a Master Ball or Ultra Ball?
	jr nc,.skipFlashingEffect
.flashingEffect ; do a flashing effect if it's Master Ball or Ultra Ball
	ld a,[rOBP0]
	xor a,%00111100 ; complement colors 1 and 2
	ld [rOBP0],a
.skipFlashingEffect
	ld a,[W_SUBANIMCOUNTER]
	cp a,11 ; is it the beginning of the subanimation?
	jr nz,.skipPlayingSound
; if it is the beginning of the subanimation, play a sound
	ld a,(SFX_08_41 - SFX_Headers_08) / 3
	call PlaySound ; play sound
.skipPlayingSound
	ld a,[W_ISINBATTLE]
	cp a,02 ; is it a trainer battle?
	jr z,.isTrainerBattle
	ld a,[$d11e]
	cp a,$10 ; is the enemy pokemon the Ghost Marowak?
	ret nz
; if the enemy pokemon is the Ghost Marowak, make it dodge during the last 3 frames
	ld a,[W_SUBANIMCOUNTER]
	cp a,3
	jr z,.moveGhostMarowakLeft
	cp a,2
	jr z,.moveGhostMarowakLeft
	cp a,1
	ret nz
.moveGhostMarowakLeft
	FuncCoord 17,0
	ld hl,Coord
	ld de,20
	ld bc,$0707 ; 7 rows and 7 columns
.loop
	push hl
	push bc
	call Func_79862 ; move row of tiles left
	pop bc
	pop hl
	add hl,de
	dec b
	jr nz,.loop
	ld a,%00001000
	ld [$ff10],a ; Channel 1 sweep register
	ret
.isTrainerBattle ; if it's a trainer battle, shorten the animation by one frame
	ld a,[W_SUBANIMCOUNTER]
	cp a,3
	ret nz
	dec a
	ld [W_SUBANIMCOUNTER],a
	ret

DoBallShakeSpecialEffects: ; 78f96 (1e:4f96)
	ld a,[W_SUBANIMCOUNTER]
	cp a,4 ; is it the beginning of a shake?
	jr nz,.skipPlayingSound
; if it is the beginning of a shake, play a sound and wait 2/3 of a second
	ld a,(SFX_08_3c - SFX_Headers_08) / 3
	call PlaySound ; play sound
	ld c,40
	call DelayFrames
.skipPlayingSound
	ld a,[W_SUBANIMCOUNTER]
	dec a
	ret nz
; if it's the end of the ball shaking subanimation, check if more shakes are left and restart the subanimation
	ld a,[$cd3d] ; number of shakes
	dec a ; decrement number of shakes
	ld [$cd3d],a
	ret z
; if there are shakes left, restart the subanimation
	ld a,[W_SUBANIMSUBENTRYADDR]
	ld l,a
	ld a,[W_SUBANIMSUBENTRYADDR + 1]
	ld h,a
	ld de,-(4 * 3) ; 4 subentries and 3 bytes per subentry
	add hl,de
	ld a,l
	ld [W_SUBANIMSUBENTRYADDR],a
	ld a,h
	ld [W_SUBANIMSUBENTRYADDR + 1],a
	ld a,5 ; number of subentries in the ball shaking subanimation plus one
	ld [W_SUBANIMCOUNTER],a
	ret

; plays a sound after the second frame of the poof animation
DoPoofSpecialEffects: ; 78fce (1e:4fce)
	ld a,[W_SUBANIMCOUNTER]
	cp a,5
	ret nz
	ld a,(SFX_08_42 - SFX_Headers_08) / 3
	jp PlaySound

DoRockSlideSpecialEffects: ; 78fd9 (1e:4fd9)
	ld a,[W_SUBANIMCOUNTER]
	cp a,12
	ret nc
	cp a,8
	jr nc,.shakeScreen
	cp a,1
	jp z,AnimationFlashScreen ; if it's the end of the subanimation, flash the screen
	ret
; if the subaninmation counter is between 8 and 11, shake the screen horizontally and vertically
.shakeScreen
	ld b,1
	ld a,$24
	call Predef ; shake horizontally
	ld b,1
	ld a,$21
	jp Predef ; shake vertically

FlashScreenEveryEightFrameBlocks: ; 78ff7 (1e:4ff7)
	ld a,[W_SUBANIMCOUNTER]
	and a,7 ; is the subanimation counter exactly 8?
	call z,AnimationFlashScreen ; if so, flash the screen
	ret

; flashes the screen if the subanimation counter is divisible by 4
FlashScreenEveryFourFrameBlocks: ; 79000 (1e:5000)
	ld a,[W_SUBANIMCOUNTER]
	and a,3
	call z,AnimationFlashScreen
	ret

; used for Explosion and Selfdestruct
DoExplodeSpecialEffects: ; 79009 (1e:5009)
	ld a,[W_SUBANIMCOUNTER]
	cp a,1 ; is it the end of the subanimation?
	jr nz,FlashScreenEveryFourFrameBlocks
; if it's the end of the subanimation, make the attacking pokemon disappear
	FuncCoord 1, 5 ; $c405
	ld hl,Coord
	jp AnimationHideMonPic ; make pokemon disappear

; flashes the screen when subanimation counter is 1 modulo 4
DoBlizzardSpecialEffects: ; 79016 (1e:5016)
	ld a,[W_SUBANIMCOUNTER]
	cp a,13
	jp z,AnimationFlashScreen
	cp a,9
	jp z,AnimationFlashScreen
	cp a,5
	jp z,AnimationFlashScreen
	cp a,1
	jp z,AnimationFlashScreen
	ret

; flashes the screen at 3 points in the subanimation
; XXX is this unused?
Func_7902e: ; 7902e (1e:502e)
	ld a,[W_SUBANIMCOUNTER]
	cp a,14
	jp z,AnimationFlashScreen
	cp a,9
	jp z,AnimationFlashScreen
	cp a,2
	jp z,AnimationFlashScreen
	ret

; function to make the pokemon disappear at the beginning of the animation
; XXX probably a trade-related animation
Func_79041: ; 79041 (1e:5041)
	ld a,[W_SUBANIMCOUNTER]
	cp a,6
	ret nz
	ld a,$2F
	jp Func_7980c ; make pokemon disappear

; function to make a shaking pokeball jump up at the end of the animation
; XXX probably a trade-related animation
Func_7904c: ; 7904c (1e:504c)
	ld a,[W_SUBANIMCOUNTER]
	cp a,1
	ret nz
; if it's the end of the animation, make the ball jump up
	ld de,BallMoveDistances1
.loop
	ld hl,wOAMBuffer ; OAM buffer
	ld bc,4
.innerLoop
	ld a,[de]
	cp a,$ff
	jr z,.done
	add [hl] ; add to Y value of OAM entry
	ld [hl],a
	add hl,bc
	ld a,l
	cp a,4 * 4 ; there are 4 entries, each 4 bytes
	jr nz,.innerLoop
	inc de
	push bc
	call Delay3
	pop bc
	jr .loop
.done
	call AnimationCleanOAM
	ld a,(SFX_02_44 - SFX_Headers_02) / 3
	jp PlaySound ; play sound

BallMoveDistances1: ; 79078 (1e:5078)
	db -12,-12,-8
	db $ff ; terminator

; function to make the pokeball jump up
; XXX probably a trade-related animation
Func_7907c ; 507C
	ld de,BallMoveDistances2
.loop
	ld hl,wOAMBuffer ; OAM buffer
	ld bc,4
.innerLoop
	ld a,[de]
	cp a,$ff
	jp z,ClearScreen
	add [hl]
	ld [hl],a
	add hl,bc
	ld a,l
	cp a,4 * 4 ; there are 4 entries, each 4 bytes
	jr nz,.innerLoop
	inc de
	push de
	ld a,[de]
	cp a,12
	jr z,.playSound
	cp a,$ff
	jr nz,.skipPlayingSound
.playSound ; play sound if next move distance is 12 or this is the last one
	ld a,(SFX_08_58 - SFX_Headers_08) / 3
	call PlaySound
.skipPlayingSound
	push bc
	ld c,5
	call DelayFrames
	pop bc
	ld a,[$ffae] ; background scroll X
	sub a,8 ; scroll to the left
	ld [$ffae],a
	pop de
	jr .loop

BallMoveDistances2: ; 790b3 (1e:50b3)
	db 11,12,-12,-7,7,12,-8,8
	db $ff ; terminator

; this function copies the current musical note graphic
; so that there are two musical notes flying towards the defending pokemon
DoGrowlSpecialEffects: ; 790bc (1e:50bc)
	ld hl,wOAMBuffer ; OAM buffer
	ld de,$c310
	ld bc,$10
	call CopyData ; copy the musical note graphic
	ld a,[W_SUBANIMCOUNTER]
	dec a
	call z,AnimationCleanOAM ; clean up at the end of the subanimation
	ret

; this is associated with Tail Whip, but Tail Whip doesn't use any subanimations
Func_790d0: ; 790d0 (1e:50d0)
	ld a,1
	ld [W_SUBANIMCOUNTER],a
	ld c,20
	jp DelayFrames

; Format: Special Effect ID (1 byte), Address (2 bytes)
SpecialEffectPointers: ; 790da (1e:50da)
	db SE_DARK_SCREEN_FLASH ; $FE
	dw AnimationFlashScreen
	db SE_DARK_SCREEN_PALETTE ; $FD
	dw AnimationDarkScreenPalette
	db SE_RESET_SCREEN_PALETTE ; $FC
	dw AnimationResetScreenPalette
	db SE_SHAKE_SCREEN ; $FB
	dw AnimationShakeScreen
	db SE_WATER_DROPLETS_EVERYWHERE ; $FA
	dw AnimationWaterDropletsEverywhere
	db SE_DARKEN_MON_PALETTE ; $F9
	dw AnimationDarkenMonPalette
	db SE_FLASH_SCREEN_LONG ; $F8
	dw AnimationFlashScreenLong
	db SE_SLIDE_MON_UP ; $F7
	dw AnimationSlideMonUp
	db SE_SLIDE_MON_DOWN ; $F6
	dw AnimationSlideMonDown
	db SE_FLASH_MON_PIC ; $F5
	dw AnimationFlashMonPic
	db SE_SLIDE_MON_OUT ; $F4
	dw AnimationSlideMonOut
	db SE_BLINK_MON ; $F3
	dw AnimationBlinkMon
	db SE_MOVE_MON_HORIZONTALLY ; $F2
	dw AnimationMoveMonHorizontally
	db SE_RESET_MON_POSITION ; $F1
	dw AnimationResetMonPosition
	db SE_LIGHT_SCREEN_PALETTE ; $F0
	dw AnimationLightScreenPalette
	db SE_HIDE_MON_PIC ; $EF
	dw AnimationHideMonPic
	db SE_SQUISH_MON_PIC ; $EE
	dw AnimationSquishMonPic
	db SE_SHOOT_BALLS_UPWARD ; $ED
	dw AnimationShootBallsUpward
	db SE_SHOOT_MANY_BALLS_UPWARD ; $EC
	dw AnimationShootManyBallsUpward
	db SE_BOUNCE_UP_AND_DOWN ; $EB
	dw AnimationBoundUpAndDown
	db SE_MINIMIZE_MON ; $EA
	dw AnimationMinimizeMon
	db SE_SLIDE_MON_DOWN_AND_HIDE ; $E9
	dw AnimationSlideMonDownAndHide
	db SE_TRANSFORM_MON ; $E8
	dw AnimationTransformMon
	db SE_LEAVES_FALLING ; $E7
	dw AnimationLeavesFalling
	db SE_PETALS_FALLING ; $E6
	dw AnimationPetalsFalling
	db SE_SLIDE_MON_HALF_LEFT ; $E5
	dw AnimationSlideMonHalfLeft
	db SE_SHAKE_ENEMY_HUD ; $E4
	dw AnimationShakeEnemyHUD
	db SE_SHAKE_ENEMY_HUD_2 ; unused--same pointer as SE_SHAKE_ENEMY_HUD ($E4)
	dw AnimationShakeEnemyHUD
	db SE_SPIRAL_BALLS_INWARD ; $E2
	dw AnimationSpiralBallsInward
	db SE_DELAY_ANIMATION_10 ; $E1
	dw AnimationDelay10
	db SE_FLASH_ENEMY_MON_PIC ; unused--same as SE_FLASH_MON_PIC ($F5), but for the enemy mon
	dw AnimationFlashEnemyMonPic
	db SE_HIDE_ENEMY_MON_PIC ; $DF
	dw AnimationHideEnemyMonPic
	db SE_BLINK_ENEMY_MON ; $DE
	dw AnimationBlinkEnemyMon
	db SE_SHOW_MON_PIC ; $DD
	dw AnimationShowMonPic
	db SE_SHOW_ENEMY_MON_PIC ; $DC
	dw AnimationShowEnemyMonPic
	db SE_SLIDE_ENEMY_MON_OUT ; $DB
	dw AnimationSlideEnemyMonOut
	db SE_SHAKE_BACK_AND_FORTH ; $DA
	dw AnimationShakeBackAndForth
	db SE_SUBSTITUTE_MON ; $D9
	dw AnimationSubstitute
	db SE_WAVY_SCREEN ; $D8
	dw AnimationWavyScreen
	db $FF

AnimationDelay10: ; 79150 (1e:5150)
	ld c,10
	jp DelayFrames

; calls a function with the turn flipped from player to enemy or vice versa
; input - hl - address of function to call
CallWithTurnFlipped: ; 79155 (1e:5155)
	ld a,[H_WHOSETURN]
	push af
	xor a,1
	ld [H_WHOSETURN],a
	ld de,.returnAddress
	push de
	jp [hl]
.returnAddress
	pop af
	ld [H_WHOSETURN],a
	ret

; flashes the screen for an extended period (48 frames)
AnimationFlashScreenLong: ; 79165 (1e:5165)
	ld a,3 ; cycle through the palettes 3 times
	ld [$D08A],a
	ld a,[$cf1b] ; running on SGB?
	and a
	ld hl,FlashScreenLongMonochrome
	jr z,.loop
	ld hl,FlashScreenLongSGB
.loop
	push hl
.innerLoop
	ld a,[hli]
	cp a,$01 ; is it the end of the palettes?
	jr z,.endOfPalettes
	ld [rBGP],a
	call FlashScreenLongDelay
	jr .innerLoop
.endOfPalettes
	ld a,[$D08A]
	dec a
	ld [$D08A],a
	pop hl
	jr nz,.loop
	ret

; BG palettes
FlashScreenLongMonochrome: ; 7918e (1e:518e)
	db %11111001 ; 3, 3, 2, 1
	db %11111110 ; 3, 3, 3, 2
	db %11111111 ; 3, 3, 3, 3
	db %11111110 ; 3, 3, 3, 2
	db %11111001 ; 3, 3, 2, 1
	db %11100100 ; 3, 2, 1, 0
	db %10010000 ; 2, 1, 0, 0
	db %01000000 ; 1, 0, 0, 0
	db %00000000 ; 0, 0, 0, 0
	db %01000000 ; 1, 0, 0, 0
	db %10010000 ; 2, 1, 0, 0
	db %11100100 ; 3, 2, 1, 0
	db $01 ; terminator

; BG palettes
FlashScreenLongSGB: ; 7919b (1e:519b)
	db %11111000 ; 3, 3, 2, 0
	db %11111100 ; 3, 3, 3, 0
	db %11111111 ; 3, 3, 3, 3
	db %11111100 ; 3, 3, 3, 0
	db %11111000 ; 3, 3, 2, 0
	db %11100100 ; 3, 2, 1, 0
	db %10010000 ; 2, 1, 0, 0
	db %01000000 ; 1, 0, 0, 0
	db %00000000 ; 0, 0, 0, 0
	db %01000000 ; 1, 0, 0, 0
	db %10010000 ; 2, 1, 0, 0
	db %11100100 ; 3, 2, 1, 0
	db $01 ; terminator

; causes a delay of 2 frames for the first cycle
; causes a delay of 1 frame for the second and third cycles
FlashScreenLongDelay: ; 791a8 (1e:51a8)
	ld a,[$D08A]
	cp a,4 ; never true since [$D08A] starts at 3
	ld c,4
	jr z,.delayFrames
	cp a,3
	ld c,2
	jr z,.delayFrames
	cp a,2 ; nothing is done with this
	ld c,1
.delayFrames
	jp DelayFrames

AnimationFlashScreen: ; 791be (1e:51be)
	ld a,[rBGP]
	push af ; save initial palette
	ld a,%00011011 ; 0, 1, 2, 3 (inverted colors)
	ld [rBGP],a
	ld c,2
	call DelayFrames
	xor a ; white out background
	ld [rBGP],a
	ld c,2
	call DelayFrames
	pop af
	ld [rBGP],a ; restore initial palette
	ret

AnimationDarkScreenPalette: ; 791d6 (1e:51d6)
; Changes the screen's palette to a dark palette.
	ld bc, $6f6f
	jr Func_791fc

AnimationDarkenMonPalette: ; 791db (1e:51db)
; Darkens the mon sprite's palette.
	ld bc, $f9f4
	jr Func_791fc

Func_791e0: ; 791e0 (1e:51e0)
	ld bc, $fef8
	jr Func_791fc

Func_791e5: ; 791e5 (1e:51e5)
	ld bc, $ffff
	jr Func_791fc

AnimationResetScreenPalette: ; 791ea (1e:51ea)
; Restores the screen's palette to the normal palette.
	ld bc, $e4e4
	jr Func_791fc

Func_791ef: ; 791ef (1e:51ef)
	ld bc, $0000
	jr Func_791fc

AnimationLightScreenPalette: ; 791f4 (1e:51f4)
; Changes the screen to use a palette with light colors.
	ld bc, $9090
	jr Func_791fc

Func_791f9: ; 791f9 (1e:51f9)
	ld bc, $4040

Func_791fc: ; 791fc (1e:51fc)
	ld a, [$cf1b]
	and a
	ld a, b
	jr z, .asm_79204
	ld a, c
.asm_79204
	ld [rBGP], a ; $ff47
	ret

	ld b, $5

Func_79209: ; 79209 (1e:5209)
	ld a, $21
	jp Predef ; indirect jump to Func_480ff (480ff (12:40ff))

AnimationShakeScreen: ; 7920e (1e:520e)
; Shakes the screen for a while. Used in Earthquake/Fissure/etc. animations.
	ld b, $8

Func_79210: ; 79210 (1e:5210)
	ld a, $24
	jp Predef ; indirect jump to Func_48125 (48125 (12:4125))

AnimationWaterDropletsEverywhere: ; 79215 (1e:5215)
; Draws water droplets all over the screen and makes them
; scroll. It's hard to describe, but it's the main animation
; in Surf/Mist/Toxic.
	xor a
	ld [$d09f], a
	call LoadAnimationTileset
	ld d, $20
	ld a, $f0
	ld [W_BASECOORDX], a ; $d081
	ld a, $71
	ld [$d09f], a
.asm_79228
	ld a, $10
	ld [W_BASECOORDY], a ; $d082
	ld a, $0
	ld [$d08a], a
	call Func_79246
	ld a, $18
	ld [W_BASECOORDY], a ; $d082
	ld a, $20
	ld [$d08a], a
	call Func_79246
	dec d
	jr nz, .asm_79228
	ret

Func_79246: ; 79246 (1e:5246)
	ld hl, wOAMBuffer
.asm_79249
	ld a, [W_BASECOORDY] ; $d082
	ld [hli], a
	ld a, [W_BASECOORDX] ; $d081
	add $1b
	ld [W_BASECOORDX], a ; $d081
	ld [hli], a
	ld a, [$d09f]
	ld [hli], a
	xor a
	ld [hli], a
	ld a, [W_BASECOORDX] ; $d081
	cp $90
	jr c, .asm_79249
	sub $a8
	ld [W_BASECOORDX], a ; $d081
	ld a, [W_BASECOORDY] ; $d082
	add $10
	ld [W_BASECOORDY], a ; $d082
	cp $70
	jr c, .asm_79249
	call AnimationCleanOAM
	jp DelayFrame

AnimationSlideMonUp: ; 7927a (1e:527a)
; Slides the mon's sprite upwards.
	ld c, $7
	ld a, [H_WHOSETURN]
	and a
	ld hl, $c419
	ld de, $c405
	ld a, $30
	jr z, .asm_79291
	ld hl, $c3c0
	ld de, $c3ac
	ld a, $ff
.asm_79291
	ld [$d09f], a
	jp Func_792bf

AnimationSlideMonDown: ; 79297 (1e:5297)
; Slides the mon's sprite down out of the screen.
	xor a
	call Func_79842
.asm_7929b
	call Func_79820
	push bc
	push de
	call Func_79aae
	call Delay3
	call AnimationHideMonPic
	pop de
	pop bc
	dec b
	jr nz, .asm_7929b
	ret

AnimationSlideMonOut: ; 792af (1e:52af)
; Slides the mon's sprite out of the screen horizontally.
	ld e, $8
	ld a, $3
	ld [W_SUBANIMTRANSFORM], a ; $d08b
	jp Func_795f8

AnimationSlideEnemyMonOut: ; 792b9 (1e:52b9)
; Slides the enemy mon out of the screen horizontally.
	ld hl, AnimationSlideMonOut ; $52af
	jp CallWithTurnFlipped

Func_792bf: ; 792bf (1e:52bf)
	push de
	push hl
	push bc
	ld b, $6
.asm_792c4
	push bc
	push de
	push hl
	ld bc, $0007
	call CopyData
	pop de
	pop hl
	ld bc, $0028
	add hl, bc
	pop bc
	dec b
	jr nz, .asm_792c4
	ld a, [H_WHOSETURN]
	and a
	ld hl, $c47d
	jr z, .asm_792e2
	ld hl, $c424
.asm_792e2
	ld a, [$d09f]
	inc a
	ld [$d09f], a
	ld c, $7
.asm_792eb
	ld [hli], a
	add $7
	dec c
	jr nz, .asm_792eb
	ld c, $2
	call DelayFrames
	pop bc
	pop hl
	pop de
	dec c
	jr nz, Func_792bf
	ret

Func_792fd: ; 792fd (1e:52fd)
	ld a, $10
	ld [W_BASECOORDX], a
	ld a, $30
	ld [W_BASECOORDY], a
	ld hl, wOAMBuffer
	ld d, $0
	ld c, $7
.asm_7930e
	ld a, [W_BASECOORDY]
	ld e, a
	ld b, $5
.asm_79314
	call Func_79329
	inc d
	dec b
	jr nz, .asm_79314
	dec c
	ret z
	inc d
	inc d
	ld a, [W_BASECOORDX]
	add $8
	ld [W_BASECOORDX], a
	jr .asm_7930e

Func_79329: ; 79329 (1e:5329)
	ld a, e
	add $8
	ld e, a
	ld [hli], a
	ld a, [W_BASECOORDX] ; $d081
	ld [hli], a
	ld a, d
	ld [hli], a
	xor a
	ld [hli], a
	ret

Func_79337: ; 79337 (1e:5337)
	ld l, e
	ld h, d

Func_79339: ; 79339 (1e:5339)
	ld de, $4
.asm_7933c
	ld a, [$d08a]
	ld b, a
	ld a, [hl]
	add b
	cp $a8
	jr c, .asm_7934a
	dec hl
	ld a, $a0
	ld [hli], a
.asm_7934a
	ld [hl], a
	add hl, de
	dec c
	jr nz, .asm_7933c
	ret

Func_79350: ; 79350 (1e:5350)
	ld l, e
	ld h, d

Func_79352: ; 79352 (1e:5352)
	ld de, $4
.asm_79355
	ld a, [$d08a]
	ld b, a
	ld a, [hl]
	add b
	cp $70
	jr c, .asm_79363
	dec hl
	ld a, $a0
	ld [hli], a
.asm_79363
	ld [hl], a
	add hl, de
	dec c
	jr nz, .asm_79355
	ret

AnimationBlinkEnemyMon: ; 79369 (1e:5369)
; Make the enemy mon's sprite blink on and off for a second or two
	ld hl, AnimationBlinkMon ; $536f
	jp CallWithTurnFlipped

AnimationBlinkMon: ; 7936f (1e:536f)
; Make the mon's sprite blink on and off for a second or two.
	push af
	ld c, $6
.asm_79372
	push bc
	call AnimationHideMonPic
	ld c, $5
	call DelayFrames
	call AnimationShowMonPic
	ld c, $5
	call DelayFrames
	pop bc
	dec c
	jr nz, .asm_79372
	pop af
	ret

AnimationFlashMonPic: ; 79389 (1e:5389)
; Flashes the mon's sprite on and off
	ld a, [W_PLAYERMONID]
	ld [$ceea], a
	ld a, [$cfe5]
	ld [$cee9], a
	jp Func_79793

AnimationFlashEnemyMonPic: ; 79398 (1e:5398)
; Flashes the enemy mon's sprite on and off
	ld hl, AnimationFlashMonPic
	jp CallWithTurnFlipped

AnimationShowMonPic: ; 7939e (1e:539e)
	xor a
	call Func_79842
	call Func_79820
	call Func_79aae
	jp Delay3

AnimationShowEnemyMonPic: ; 793ab (1e:53ab)
; Shows the emenmy mon's front sprite. Used in animations like Seismic Toss
; to make the mon's sprite reappear after disappears offscreen.
	ld hl, AnimationShowMonPic
	jp CallWithTurnFlipped

AnimationShakeBackAndForth: ; 793b1 (1e:53b1)
; Shakes the mon's sprite back and forth rapidly. This is used in Double Team.
; The mon's sprite disappears after this animation.
	ld a, [H_WHOSETURN]
	and a
	ld hl, $c404
	ld de, $c406
	jr z, .asm_793c2
	ld hl, $c3ab
	ld de, $c3ad

.asm_793c2
	xor a
	ld c, $10
.asm_793c5
	push af
	push bc
	push de
	push hl
	push hl
	push de
	push af
	push hl
	push hl
	call Func_79842
	pop hl
	call Func_79aae
	call Delay3
	pop hl
	ld bc, $0709
	call ClearScreenArea
	pop af
	call Func_79842
	pop hl
	call Func_79aae
	call Delay3
	pop hl
	ld bc, $0709
	call ClearScreenArea
	pop hl
	pop de
	pop bc
	pop af
	dec c
	jr nz, .asm_793c5
	ret

AnimationMoveMonHorizontally: ; 793f9 (1e:53f9)
; Shifts the mon's sprite horizontally to a fixed location. Used by lots of
; animations like Tackle/Body Slam.
	call AnimationHideMonPic
	ld a, [H_WHOSETURN] ; $fff3
	and a
	FuncCoord 2, 5 ; $c406
	ld hl, Coord
	jr z, .asm_79407
	FuncCoord 11, 0 ; $c3ab
	ld hl, Coord
.asm_79407
	xor a
	push hl
	call Func_79842
	pop hl
	call Func_79aae
	ld c, $3
	jp DelayFrames

AnimationResetMonPosition: ; 79415 (1e:5415)
; Resets the mon's sprites to be located at the normal coordinates.
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, $66
	jr z, .asm_7941e
	ld a, $b
.asm_7941e
	call Func_7980c
	jp AnimationShowMonPic

AnimationSpiralBallsInward: ; 79424 (1e:5424)
; Creates an effect that looks like energy balls sprialing into the
; player mon's sprite.  Used in Focus Energy, for example.
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_79435
	ld a, $d8
	ld [$d08a], a
	ld a, $50
	ld [W_SUBANIMTRANSFORM], a ; $d08b
	jr .asm_7943c
.asm_79435
	xor a
	ld [$d08a], a
	ld [W_SUBANIMTRANSFORM], a ; $d08b
.asm_7943c
	ld d, $7a
	ld c, $3
	xor a
	call Func_797e8
	ld hl, SpiralBallAnimationCoordinates ; $5476
.asm_79447
	push hl
	ld c, $3
	ld de, wOAMBuffer
.asm_7944d
	ld a, [hl]
	cp $ff
	jr z, .asm_7946f
	ld a, [$d08a]
	add [hl]
	ld [de], a
	inc de
	inc hl
	ld a, [W_SUBANIMTRANSFORM] ; $d08b
	add [hl]
	ld [de], a
	inc hl
	inc de
	inc de
	inc de
	dec c
	jr nz, .asm_7944d
	ld c, $5
	call DelayFrames
	pop hl
	inc hl
	inc hl
	jr .asm_79447
.asm_7946f
	pop hl
	call AnimationCleanOAM
	jp AnimationFlashScreen

SpiralBallAnimationCoordinates: ; 79476 (1e:5476)
; y, x pairs
; This is the sequence of screen coordinates that the spiraling
; balls are positioned at.
	db $38, $28
	db $40, $18
	db $50, $10
	db $60, $18
	db $68, $28
	db $60, $38
	db $50, $40
	db $40, $38
	db $40, $28
	db $46, $1E
	db $50, $18
	db $5B, $1E
	db $60, $28
	db $5B, $32
	db $50, $38
	db $46, $32
	db $48, $28
	db $50, $20
	db $58, $28
	db $50, $30
	db $50, $28
	db $FF ; list terminator

AnimationSquishMonPic: ; 794a1 (1e:54a1)
; Squishes the mon's sprite horizontally making it
; disappear. Used by Teleport/Sky Attack animations.
	ld c, $4
.asm_794a3
	push bc
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_794b1
	FuncCoord 16, 0 ; $c3b0
	ld hl, Coord
	FuncCoord 14, 0 ; $c3ae
	ld de, Coord
	jr .asm_794b7
.asm_794b1
	FuncCoord 5, 5 ; $c409
	ld hl, Coord
	FuncCoord 3, 5 ; $c407
	ld de, Coord
.asm_794b7
	push de
	xor a
	ld [$d09f], a
	call Func_794d4
	pop hl
	ld a, $1
	ld [$d09f], a
	call Func_794d4
	pop bc
	dec c
	jr nz, .asm_794a3
	call AnimationHideMonPic
	ld c, $2
	jp DelayFrame

Func_794d4: ; 794d4 (1e:54d4)
	ld c, $7
.asm_794d6
	push bc
	push hl
	ld c, $3
	ld a, [$d09f]
	cp $0
	jr nz, .asm_794e7
	call Func_7985b
	dec hl
	jr .asm_794eb
.asm_794e7
	call Func_79862
	inc hl
.asm_794eb
	ld [hl], $7f
	pop hl
	ld de, $14
	add hl, de
	pop bc
	dec c
	jr nz, .asm_794d6
	jp Delay3

AnimationShootBallsUpward: ; 794f9 (1e:54f9)
; Shoots one pillar of "energy" balls upwards. Used in Teleport/Sky Attack
; animations.
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_79503
	ld bc, $80
	jr .asm_79506
.asm_79503
	ld bc, $3028
.asm_79506
	ld a, b
	ld [W_BASECOORDY], a ; $d082
	ld a, c
	ld [W_BASECOORDX], a ; $d081
	ld bc, $501
	call Func_79517
	jp AnimationCleanOAM

Func_79517: ; 79517 (1e:5517)
	push bc
	xor a
	ld [$d09f], a
	call LoadAnimationTileset
	pop bc
	ld d, $7a
	ld hl, wOAMBuffer
	push bc
	ld a, [W_BASECOORDY] ; $d082
	ld e, a
.asm_7952a
	call Func_79329
	dec b
	jr nz, .asm_7952a
	call DelayFrame
	pop bc
	ld a, b
	ld [$d08a], a
.asm_79538
	push bc
	ld hl, wOAMBuffer
.asm_7953c
	ld a, [W_BASECOORDY] ; $d082
	add $8
	ld e, a
	ld a, [hl]
	cp e
	jr z, .asm_7954b
	add $fc
	ld [hl], a
	jr .asm_79554
.asm_7954b
	ld [hl], $0
	ld a, [$d08a]
	dec a
	ld [$d08a], a
.asm_79554
	ld de, $4
	add hl, de
	dec b
	jr nz, .asm_7953c
	call DelayFrames
	pop bc
	ld a, [$d08a]
	and a
	jr nz, .asm_79538
	ret

AnimationShootManyBallsUpward: ; 79566 (1e:5566)
; Shoots several pillars of "energy" balls upward.
	ld a, [H_WHOSETURN]
	and a
	ld hl, UpwardBallsAnimXCoordinatesPlayerTurn
	ld a, $50 ; y coordinate for "energy" ball pillar
	jr z, .player
	ld hl, UpwardBallsAnimXCoordinatesEnemyTurn
	ld a, $28 ; y coordinate for "energy" ball pillar
.player
	ld [wTrainerSpriteOffset], a
.loop
	ld a, [wTrainerSpriteOffset]
	ld [W_BASECOORDY], a
	ld a, [hli]
	cp $ff
	jp z, AnimationCleanOAM
	ld [W_BASECOORDX], a
	ld bc, $0401
	push hl
	call Func_79517
	pop hl
	jr .loop

UpwardBallsAnimXCoordinatesPlayerTurn: ; 79591 (1e:5591)
; List of x coordinates for each pillar of "energy" balls in the
; AnimationShootManyBallsUpward animation. It's unused in the game.
	db $10, $40, $28, $18, $38, $30
	db $FF ; list terminator

UpwardBallsAnimXCoordinatesEnemyTurn: ; 79598 (1e:5598)
; List of x coordinates for each pillar of "energy" balls in the
; AnimationShootManyBallsUpward animation. It's unused in the game.
	db $60, $90, $78, $68, $88, $80
	db $FF ; list terminator

AnimationMinimizeMon: ; 7959f (1e:559f)
; Changes the mon's sprite to a mini black sprite. Used by the
; Minimize animation.
	ld hl, $c6e8
	push hl
	xor a
	ld bc, $310
	call FillMemory
	pop hl
	ld de, $194
	add hl, de
	ld de, MinimizedMonSprite ; $55c4
	ld c, $5
.asm_795b4
	ld a, [de]
	ld [hli], a
	ld [hli], a
	inc de
	dec c
	jr nz, .asm_795b4
	call Func_79652
	call Delay3
	jp AnimationShowMonPic

MinimizedMonSprite: ; 795c4 (1e:55c4)
	INCBIN "gfx/minimized_mon_sprite.1bpp"

AnimationSlideMonDownAndHide: ; 795c9 (1e:55c9)
; Slides the mon's sprite down and disappears. Used in Acid Armor.
	ld a, $1
	ld c, $2
.asm_795cd
	push bc
	push af
	call AnimationHideMonPic
	pop af
	push af
	call Func_79842
	call Func_79820
	call Func_79aae
	ld c, $8
	call DelayFrames
	pop af
	inc a
	pop bc
	dec c
	jr nz, .asm_795cd
	call AnimationHideMonPic
	ld hl, $c6e8
	ld bc, $0310
	xor a
	call FillMemory
	jp Func_79652

Func_795f8: ; 795f8 (1e:55f8)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_79602
	FuncCoord 12, 0 ; $c3ac
	ld hl, Coord
	jr .asm_79605
.asm_79602
	FuncCoord 0, 5 ; $c404
	ld hl, Coord
.asm_79605
	ld d, $8
.asm_79607
	push hl
	ld b, $7
.asm_7960a
	ld c, $8
.asm_7960c
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_79616
	call Func_7963c
	jr .asm_79619
.asm_79616
	call Func_79633
.asm_79619
	ld [hli], a
	dec c
	jr nz, .asm_7960c
	push de
	ld de, $c
	add hl, de
	pop de
	dec b
	jr nz, .asm_7960a
	ld a, [W_SUBANIMTRANSFORM] ; $d08b
	ld c, a
	call DelayFrames
	pop hl
	dec d
	dec e
	jr nz, .asm_79607
	ret

Func_79633: ; 79633 (1e:5633)
	ld a, [hl]
	add $7
	cp $61
	ret c
	ld a, $7f
	ret

Func_7963c: ; 7963c (1e:563c)
	ld a, [hl]
	sub $7
	cp $30
	ret c
	ld a, $7f
	ret

AnimationSlideMonHalfLeft: ; 79645 (1e:5645)
; Slides the mon's sprite halfway out of the screen. It's used in Softboiled.
	ld e, $4
	ld a, $4
	ld [W_SUBANIMTRANSFORM], a
	call Func_795f8
	jp Delay3

Func_79652: ; 79652 (1e:5652)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld hl, $9310
	jr z, .asm_7965d
	ld hl, $9000
.asm_7965d
	ld de, $c6e8
	ld bc, $31
	jp CopyVideoData

AnimationWavyScreen: ; 79666 (1e:5666)
; used in Psywave/Psychic etc.
	ld hl, $9800
	call Func_79e0d
	call Delay3
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a
	ld a, $90
	ld [$ffb0], a
	ld d, $80
	ld e, $8f
	ld c, $ff
	ld hl, WavyScreenLineOffsets
.asm_7967f
	push hl
.asm_79680
	call Func_796ae
	ld a, [$ff44]
	cp e
	jr nz, .asm_79680
	pop hl
	inc hl
	ld a, [hl]
	cp d
	jr nz, .asm_79691
	ld hl, WavyScreenLineOffsets
.asm_79691
	dec c
	jr nz, .asm_7967f
	xor a
	ld [$ffb0], a
	call SaveScreenTilesToBuffer2
	call ClearScreen
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a
	call Delay3
	call LoadScreenTilesFromBuffer2
	ld hl, $9c00
	call Func_79e0d
	ret

Func_796ae: ; 796ae (1e:56ae)
	ld a, [$ff41]
	and $3
	jr nz, Func_796ae
	ld a, [hl]
	ld [$ff43], a
	inc hl
	ld a, [hl]
	cp d
	ret nz
	ld hl, WavyScreenLineOffsets
	ret

WavyScreenLineOffsets: ; 796bf (1e:56bf)
; Sequence of horizontal line pixel offsets for the wavy screen animation.
; This sequence vaguely resembles a sine wave.
	db 0, 0, 0, 0, 0,  1,  1,  1,  2,  2,  2,  2,  2,  1,  1,  1
	db 0, 0, 0, 0, 0, -1, -1, -1, -2, -2, -2, -2, -2, -1, -1, -1
	db $80 ; terminator

AnimationSubstitute: ; 796e0 (1e:56e0)
; Changes the pokemon's sprite to the mini sprite
	ld hl, $c6e8
	xor a
	ld bc, $0310
	call FillMemory
	ld a, [$fff3]
	and a
	jr z, .asm_79715 ; 0x796ed $26
	ld hl, SlowbroSprite ; $4780       ; facing down sprite
	ld de, $c808
	call CopySlowbroSpriteData
	ld hl, SlowbroSprite + $10 ; $4790
	ld de, $c878
	call CopySlowbroSpriteData
	ld hl, SlowbroSprite + $20 ; $47a0
	ld de, $c818
	call CopySlowbroSpriteData
	ld hl, SlowbroSprite + $30 ; $47b0
	ld de, $c888
	call CopySlowbroSpriteData
	jr .asm_79739 ; 0x79713 $24
.asm_79715
	ld hl, SlowbroSprite + $40 ; $47c0 ; facing up sprite
	ld de, $c878
	call CopySlowbroSpriteData
	ld hl, SlowbroSprite + $50 ; $47d0
	ld de, $c8e8
	call CopySlowbroSpriteData
	ld hl, SlowbroSprite + $60 ; $47e0
	ld de, $c888
	call CopySlowbroSpriteData
	ld hl, SlowbroSprite + $70 ; $47f0
	ld de, $c8f8
	call CopySlowbroSpriteData
.asm_79739
	call Func_79652
	jp AnimationShowMonPic

CopySlowbroSpriteData: ; 7973f (1e:573f)
	ld bc, $0010
	ld a, BANK(SlowbroSprite)
	jp FarCopyData2

Func_79747: ; 79747 (1e:5747)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld hl, $ccf7
	ld a, [W_PLAYERBATTSTATUS2] ; $d063
	jr z, .asm_79758
	ld hl, $ccf3
	ld a, [W_ENEMYBATTSTATUS2] ; $d068
.asm_79758
	push hl
	bit 4, a
	jr nz, .asm_79762
	call AnimationSlideMonDown
	jr .asm_79765
.asm_79762
	call AnimationSlideMonOut
.asm_79765
	pop hl
	ld a, [hl]
	and a
	jp nz, AnimationMinimizeMon
	call AnimationFlashMonPic
	jp AnimationShowMonPic

Func_79771: ; 79771 (1e:5771)
	call AnimationSlideMonOut
	call AnimationSubstitute
	jp AnimationShowMonPic

AnimationBoundUpAndDown: ; 7977a (1e:577a)
; Bounces the mon's sprite up and down several times. It is used
; by Splash's animation.
	ld c, $5
.asm_7977c
	push bc
	call AnimationSlideMonDown
	pop bc
	dec c
	jr nz, .asm_7977c ; 0x79782 $f8
	jp AnimationShowMonPic

AnimationTransformMon: ; 79787 (1e:5787)
; Redraws this mon's sprite as the back/front sprite of the opposing mon.
; Used in Transform.
	ld a, [$cfe5]
	ld [$ceea], a
	ld a, [W_PLAYERMONID]
	ld [$cee9], a

Func_79793: ; 79793 (1e:5793)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_797b0
	ld a, [$cee9]
	ld [$cf91], a
	ld [$d0b5], a
	xor a
	ld [W_SPRITEFLIPPED], a
	call GetMonHeader
	FuncCoord 12, 0 ; $c3ac
	ld hl, Coord
	call LoadFrontSpriteByMonIndex
	jr .asm_797d3
.asm_797b0
	ld a, [$cfd9]
	push af
	ld a, [$ceea]
	ld [$cfd9], a
	ld [$d0b5], a
	call GetMonHeader
	ld a, $4
	call Predef ; indirect jump to LoadMonBackSprite (3f103 (f:7103))
	xor a
	call Func_79842
	call Func_79820
	call Func_79aae
	pop af
	ld [$cfd9], a
.asm_797d3
	ld b, $1
	jp GoPAL_SET

AnimationHideEnemyMonPic: ; 797d8 (1e:57d8)
; Hides the enemy mon's sprite
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld hl, AnimationHideMonPic ; $5801
	call CallWithTurnFlipped
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	jp Delay3

Func_797e8: ; 797e8 (1e:57e8)
	push bc
	push de
	ld [$d09f], a
	call LoadAnimationTileset
	pop de
	pop bc
	xor a
	ld e, a
	ld [W_BASECOORDX], a ; $d081
	ld hl, wOAMBuffer
.asm_797fa
	call Func_79329
	dec c
	jr nz, .asm_797fa
	ret

AnimationHideMonPic: ; 79801 (1e:5801)
; Hides the mon's sprite.
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr z, .asm_7980a
	ld a, $c
	jr Func_7980c
.asm_7980a
	ld a, $65

Func_7980c: ; 7980c (1e:580c)
	push hl
	push de
	push bc
	ld e, a
	ld d, $0
	ld hl, wTileMap
	add hl, de
	ld bc, $707
	call ClearScreenArea
	pop bc
	pop de
	pop hl
	ret

Func_79820: ; 79820 (1e:5820)
	push de
	ld a, [H_WHOSETURN] ; $fff3
	and a
	jr nz, .asm_7982a
	ld a, $65
	jr .asm_7982c
.asm_7982a
	ld a, $c
.asm_7982c
	ld hl, wTileMap
	ld e, a
	ld d, $0
	add hl, de
	ld a, $7
	sub b
	and a
	jr z, .asm_79840
	ld de, $14
.asm_7983c
	add hl, de
	dec a
	jr nz, .asm_7983c
.asm_79840
	pop de
	ret

Func_79842: ; 79842 (1e:5842)
	ld hl, PointerTable_79aea ; $5aea
	ld e, a
	ld d, $0
	add hl, de
	add hl, de
	add hl, de
	ld a, [hli]
	ld e, a
	ld a, [hli]
	ld d, a
	ld a, [hli]
	ld b, a
	and $f
	ld c, a
	ld a, b
	swap a
	and $f
	ld b, a
	ret

Func_7985b: ; 7985b (1e:585b)
	ld a, [hld]
	ld [hli], a
	inc hl
	dec c
	jr nz, Func_7985b
	ret

Func_79862: ; 79862 (1e:5862)
	ld a, [hli]
	ld [hld], a
	dec hl
	dec c
	jr nz, Func_79862
	ret

Func_79869: ; 79869 (1e:5869)
	ld a, b
	call Func_7986f
	ld b, a
	ret

Func_7986f: ; 7986f (1e:586f)
	ld hl,MoveSoundTable
	ld e,a
	ld d,0
	add hl,de
	add hl,de
	add hl,de
	ld a,[hli]
	ld b,a
	call IsCryMove
	jr nc,.NotCryMove
	ld a,[H_WHOSETURN]
	and a
	jr nz,.next
	ld a,[W_PLAYERMONID] ; get number of current monster
	jr .Continue
.next
	ld a,[$CFE5]
.Continue
	push hl
	call GetCryData
	ld b,a
	pop hl
	ld a,[$C0F1]
	add [hl]
	ld [$C0F1],a
	inc hl
	ld a,[$C0F2]
	add [hl]
	ld [$C0F2],a
	jr .done
.NotCryMove
	ld a,[hli]
	ld [$C0F1],a
	ld a,[hli]
	ld [$C0F2],a
.done
	ld a,b
	ret

IsCryMove: ; 798ad (1e:58ad)
; set carry if the move animation involves playing a monster cry
	ld a,[W_ANIMATIONID]
	cp a,GROWL
	jr z,.CryMove
	cp a,ROAR
	jr z,.CryMove
	and a ; clear carry
	ret
.CryMove
	scf
	ret

MoveSoundTable: ; 798bc (1e:58bc)
	db $a0,$00,$80
	db $a2,$10,$80
	db $b3,$00,$80
	db $a1,$01,$80
	db $a3,$00,$40
	db $e9,$00,$ff
	db $a3,$10,$60
	db $a3,$20,$80
	db $a3,$00,$a0
	db $a6,$00,$80
	db $a5,$20,$40
	db $a5,$00,$80
	db $a4,$00,$a0
	db $a7,$10,$c0
	db $a7,$00,$a0
	db $a8,$00,$c0
	db $a8,$10,$a0
	db $a9,$00,$e0
	db $a7,$20,$c0
	db $aa,$00,$80
	db $b9,$00,$80
	db $ab,$01,$80
	db $b7,$00,$80
	db $ad,$f0,$40
	db $b0,$00,$80
	db $ad,$00,$80
	db $b8,$10,$80
	db $b1,$01,$a0
	db $ae,$00,$80
	db $b4,$00,$60
	db $b4,$01,$40
	db $b6,$00,$a0
	db $b0,$10,$a0
	db $b7,$00,$c0
	db $aa,$10,$60
	db $b0,$00,$a0
	db $b9,$11,$c0
	db $b0,$20,$c0
	db $b8,$00,$80
	db $b1,$00,$80
	db $b1,$20,$c0
	db $af,$00,$80
	db $db,$ff,$40
	db $b4,$00,$80
	db $a1,$00,$c0
	db $a1,$00,$40
	db $e4,$00,$80
	db $bf,$40,$60
	db $bf,$00,$80
	db $bf,$ff,$40
	db $c7,$80,$c0
	db $af,$10,$a0
	db $af,$21,$e0
	db $c5,$00,$80
	db $bb,$20,$60
	db $c7,$00,$80
	db $cc,$00,$80
	db $c2,$40,$80
	db $c5,$f0,$e0
	db $cf,$00,$80
	db $c7,$f0,$60
	db $c2,$00,$80
	db $e6,$00,$80
	db $9d,$01,$a0
	db $a9,$f0,$20
	db $ba,$01,$c0
	db $ba,$00,$80
	db $b0,$00,$e0
	db $be,$01,$60
	db $be,$20,$40
	db $bb,$00,$80
	db $bb,$40,$c0
	db $b1,$03,$60
	db $bd,$11,$e0
	db $a8,$20,$e0
	db $d2,$00,$80
	db $b2,$00,$80
	db $b2,$11,$a0
	db $b2,$01,$c0
	db $a9,$14,$c0
	db $b1,$02,$a0
	db $c5,$f0,$80
	db $c5,$20,$c0
	db $d5,$00,$20
	db $d5,$20,$80
	db $d2,$12,$60
	db $be,$00,$80
	db $aa,$01,$e0
	db $c5,$0f,$e0
	db $c5,$11,$20
	db $a6,$10,$40
	db $a5,$10,$c0
	db $aa,$00,$20
	db $d8,$00,$80
	db $e4,$11,$18
	db $9f,$20,$c0
	db $9e,$20,$c0
	db $bd,$00,$10
	db $be,$f0,$20
	db $df,$f0,$c0
	db $a7,$f0,$e0
	db $9f,$f0,$40
	db $db,$00,$80
	db $df,$80,$40
	db $df,$00,$80
	db $aa,$11,$20
	db $aa,$22,$10
	db $b1,$f1,$ff
	db $a9,$f1,$ff
	db $aa,$33,$30
	db $dd,$40,$c0
	db $a4,$20,$20
	db $a4,$f0,$10
	db $a5,$f8,$10
	db $a7,$f0,$10
	db $bd,$00,$80
	db $ae,$00,$c0
	db $dd,$c0,$ff
	db $9f,$f2,$20
	db $e1,$00,$80
	db $e1,$00,$40
	db $9f,$00,$40
	db $a7,$10,$ff
	db $c7,$20,$20
	db $dd,$00,$80
	db $c5,$1f,$20
	db $bd,$2f,$80
	db $a5,$1f,$ff
	db $ca,$1f,$60
	db $be,$1e,$20
	db $be,$1f,$18
	db $aa,$0f,$80
	db $9f,$f8,$10
	db $9e,$18,$20
	db $dd,$08,$40
	db $ad,$01,$e0
	db $a7,$09,$ff
	db $e4,$42,$01
	db $b2,$00,$ff
	db $dd,$08,$e0
	db $bb,$00,$80
	db $9f,$88,$10
	db $bd,$48,$ff
	db $9e,$ff,$ff
	db $bb,$ff,$10
	db $9e,$ff,$04
	db $b2,$01,$ff
	db $a9,$f8,$ff
	db $a2,$f0,$f0
	db $a5,$08,$10
	db $a3,$f0,$ff
	db $b0,$f0,$ff
	db $e1,$10,$ff
	db $a4,$f0,$20
	db $ca,$f0,$60
	db $b8,$12,$10
	db $e6,$f0,$20
	db $b4,$12,$ff
	db $db,$80,$04
	db $df,$f0,$10
	db $c5,$f8,$ff
	db $be,$f0,$ff
	db $a7,$01,$ff
	db $cc,$d8,$04
	db $a1,$00,$80
	db $a1,$00,$80

Func_79aae: ; 79aae (1e:5aae)
	ld a, [H_WHOSETURN] ; $fff3
	and a
	ld a, $31
	jr z, .asm_79ab6
	xor a
.asm_79ab6
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	jr asm_79acb

Func_79aba: ; 79aba (1e:5aba)
	call Load16BitRegisters
	ld a, [$cd6c]
	and a
	jr nz, .asm_79ac8
	ld de, Unknown_79b02 ; $5b02
	jr asm_79acb
.asm_79ac8
	ld de, Unknown_79b1b ; $5b1b
asm_79acb: ; 79acb (1e:5acb)
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba

Func_79ace: ; 79ace (1e:5ace)
	push hl
.asm_79acf
	push bc
	push hl
	ld a, [H_DOWNARROWBLINKCNT1] ; $ff8b
	ld b, a
.asm_79ad4
	ld a, [de]
	add b
	inc de
	ld [hli], a
	dec c
	jr nz, .asm_79ad4
	pop hl
	ld bc, $14
	add hl, bc
	pop bc
	dec b
	jr nz, .asm_79acf
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	pop hl
	ret

PointerTable_79aea: ; 79aea (1e:5aea)
	dw Unknown_79b24
	db $77
	dw Unknown_79b55
	db $57
	dw Unknown_79b78
	db $37
	dw Unknown_79b8d
	db $77
	dw Unknown_79bbe
	db $77
	dw Unknown_79bef
	db $77
	dw Unknown_79c20
	db $86
	dw Unknown_79c50
	db $3C

Unknown_79b02: ; 79b02 (1e:5b02)
	db $31,$38,$46,$54,$5B,$32,$39,$47,$55,$5C,$34,$3B,$49,$57,$5E,$36,$3D,$4B,$59,$60,$37,$3E,$4C,$5A,$61

Unknown_79b1b: ; 79b1b (1e:5b1b)
	db $31,$46,$5B,$34,$49,$5E,$37,$4C,$61

Unknown_79b24: ; 79b24 (1e:5b24)
	db $00,$07,$0E,$15,$1C,$23,$2A,$01,$08,$0F,$16,$1D,$24,$2B,$02,$09,$10,$17,$1E,$25,$2C,$03,$0A,$11,$18,$1F,$26,$2D,$04,$0B,$12,$19,$20,$27,$2E,$05,$0C,$13,$1A,$21,$28,$2F,$06,$0D,$14,$1B,$22,$29,$30

Unknown_79b55: ; 79b55 (1e:5b55)
	db $00,$07,$0E,$15,$1C,$23,$2A,$01,$08,$0F,$16,$1D,$24,$2B,$03,$0A,$11,$18,$1F,$26,$2D,$04,$0B,$12,$19,$20,$27,$2E,$05,$0C,$13,$1A,$21,$28,$2F

Unknown_79b78: ; 79b78 (1e:5b78)
	db $00,$07,$0E,$15,$1C,$23,$2A,$02,$09,$10,$17,$1E,$25,$2C,$04,$0B,$12,$19,$20,$27,$2E

Unknown_79b8d: ; 79b8d (1e:5b8d)
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$19,$00,$02,$06,$0B,$10,$14,$1A,$00,$00,$07,$0C,$11,$15,$1B,$00,$03,$08,$0D,$12,$16,$1C,$00,$04,$09,$0E,$13,$17,$1D,$1F,$05,$0A,$0F,$01,$18,$1E,$20

Unknown_79bbe: ; 79bbe (1e:5bbe)
	db $00,$00,$00,$30,$00,$37,$00,$00,$00,$2B,$31,$34,$38,$3D,$21,$26,$2C,$01,$35,$39,$3E,$22,$27,$2D,$32,$36,$01,$00,$23,$28,$2E,$33,$01,$3A,$00,$24,$29,$2F,$01,$01,$3B,$00,$25,$2A,$01,$01,$01,$3C,$00

Unknown_79bef: ; 79bef (1e:5bef)
	db $00,$00,$00,$00,$00,$00,$00,$00,$00,$47,$4D,$00,$00,$00,$00,$00,$48,$4E,$52,$56,$5B,$3F,$43,$49,$4F,$53,$57,$5C,$40,$44,$4A,$50,$54,$58,$00,$41,$45,$4B,$51,$4C,$59,$5D,$42,$46,$4C,$4C,$55,$5A,$5E

Unknown_79c20: ; 79c20 (1e:5c20)
	db $31,$32,$32,$32,$32,$33,$34,$35,$36,$36,$37,$38,$34,$39,$3A,$3A,$3B,$38,$3C,$3D,$3E,$3E,$3F,$40,$41,$42,$43,$43,$44,$45,$46,$47,$43,$48,$49,$4A,$41,$43,$4B,$4C,$4D,$4E,$4F,$50,$50,$50,$51,$52

Unknown_79c50: ; 79c50 (1e:5c50)
	db $43,$55,$56,$53,$53,$53,$53,$53,$53,$53,$53,$53,$43,$57,$58,$54,$54,$54,$54,$54,$54,$54,$54,$54,$43,$59,$5A,$43,$43,$43,$43,$43,$43,$43,$43,$43

AnimationLeavesFalling: ; 79c74 (1e:5c74)
; Makes leaves float down from the top of the screen. This is used
; in Razor Leaf's animation.
	ld a, [$ff48]
	push af
	ld a, [$cc79]
	ld [$ff48], a
	ld d, $37
	ld a, $3
	ld [W_SUBANIMTRANSFORM], a
	call Func_79c97
	pop af
	ld [$ff48], a
	ret

AnimationPetalsFalling: ; 79c8a (1e:5c8a)
; Makes lots of petals fall down from the top of the screen. It's used in
; the animation for Petal Dance.
	ld d, $71
	ld a, $14
	ld [W_SUBANIMTRANSFORM], a
	call Func_79c97
	jp CleanLCD_OAM

Func_79c97: ; 79c97 (1e:5c97)
	ld c, a
	ld a, $1
	call Func_797e8
	call Func_79d2a
	call Func_79d52
	ld hl, wOAMBuffer
	ld [hl], $0
.asm_79ca8
	ld hl, wTrainerSpriteOffset
	ld de, $0000
	ld a, [W_SUBANIMTRANSFORM]
	ld c, a
.asm_79cb2
	push bc
	push hl
	push de
	ld a, [hl]
	ld [$d08a], a
	call Func_79d16
	call Func_79cdb
	pop de
	ld hl, $0004
	add hl, de
	ld e, l
	ld d, h
	pop hl
	ld a, [$d08a]
	ld [hli], a
	pop bc
	dec c
	jr nz, .asm_79cb2
	call Delay3
	ld hl, wOAMBuffer
	ld a, [hl]
	cp $68
	jr nz, .asm_79ca8
	ret

Func_79cdb: ; 79cdb (1e:5cdb)
	ld hl, wOAMBuffer
	add hl, de
	ld a, [hl]
	inc a
	inc a
	cp $70
	jr c, .asm_79ce8
	ld a, $a0
.asm_79ce8
	ld [hli], a
	ld a, [$d08a]
	ld b, a
	ld de, Unknown_79d0d
	and $7f
	add e
	jr nc, .asm_79cf6
	inc d
.asm_79cf6
	ld e, a
	ld a, b
	and $80
	jr nz, .asm_79d03
	ld a, [de]
	add [hl]
	ld [hli], a
	inc hl
	xor a
	jr .asm_79d0b
.asm_79d03
	ld a, [de]
	ld b, a
	ld a, [hl]
	sub b
	ld [hli], a
	inc hl
	ld a, $20
.asm_79d0b
	ld [hl], a
	ret

Unknown_79d0d: ; 79d0d (1e:5d0d)
	db $00,$01,$03,$05,$07,$09,$0B,$0D,$0F

Func_79d16: ; 79d16 (1e:5d16)
	ld a, [$d08a]
	inc a
	ld b, a
	and $7f
	cp $9
	ld a, b
	jr nz, .asm_79d26
	and $80
	xor $80
.asm_79d26
	ld [$d08a], a
	ret

Func_79d2a: ; 79d2a (1e:5d2a)
	ld hl, $c301
	ld de, Unknown_79d3e
	ld a, [W_SUBANIMTRANSFORM]
	ld c, a
.asm_79d34
	ld a, [de]
	ld [hli], a
	inc hl
	inc hl
	inc hl
	inc de
	dec c
	jr nz, .asm_79d34
	ret

Unknown_79d3e: ; 79d3e (1e:5d3e)
	db $38,$40,$50,$60,$70,$88,$90,$56,$67,$4A,$77,$84,$98,$32,$22,$5C,$6C,$7D,$8E,$99

Func_79d52: ; 79d52 (1e:5d52)
	ld hl, wTrainerSpriteOffset
	ld de, Unknown_79d63
	ld a, [W_SUBANIMTRANSFORM]
	ld c, a
.asm_79d5c
	ld a, [de]
	ld [hli], a
	inc de
	dec c
	jr nz, .asm_79d5c
	ret

Unknown_79d63: ; 79d63 (1e:5d63)
	db $00,$84,$06,$81,$02,$88,$01,$83,$05,$89,$09,$80,$07,$87,$03,$82,$04,$85,$08,$86

AnimationShakeEnemyHUD: ; 79d77 (1e:5d77)
	ld de, $9310
	ld hl, $8000
	ld bc, $0031
	call CopyVideoData
	xor a
	ld [$ffae], a
	ld hl, $9800
	call Func_79e0d
	ld a, $90
	ld [$ffb0], a
	ld hl, $9b20
	call Func_79e0d
	ld a, $38
	ld [$ffb0], a
	call Func_792fd
	ld hl, $9800
	call Func_79e0d
	call AnimationHideMonPic
	call Delay3
	ld de, $0208
	call Func_79de9
	call AnimationShowMonPic
	call CleanLCD_OAM
	ld a, $90
	ld [$ffb0], a
	ld hl, $9c00
	call Func_79e0d
	xor a
	ld [$ffb0], a
	call SaveScreenTilesToBuffer1
	ld hl, $9800
	call Func_79e0d
	call ClearScreen
	call Delay3
	call LoadScreenTilesFromBuffer1
	ld hl, $9c00
	jp Func_79e0d

Func_79dda: ; 79dda (1e:5dda)
	call Load16BitRegisters
	ld a, c
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld a, b
	push hl
	call Func_79842
	pop hl
	jp Func_79ace

Func_79de9: ; 79de9 (1e:5de9)
	ld a, [$ffae]
	ld [wTrainerSpriteOffset], a
.asm_79dee
	ld a, [wTrainerSpriteOffset]
	add d
	ld [$ffae], a
	ld c, $2
	call DelayFrames
	ld a, [wTrainerSpriteOffset]
	sub d
	ld [$ffae], a
	ld c, $2
	call DelayFrames
	dec e
	jr nz, .asm_79dee
	ld a, [wTrainerSpriteOffset]
	ld [$ffae], a
	ret

Func_79e0d: ; 79e0d (1e:5e0d)
	ld a, h
	ld [$ffbd], a
	ld a, l
	ld [H_AUTOBGTRANSFERDEST], a
	jp Delay3

TossBallAnimation: ; 79e16 (1e:5e16)
	ld a,[W_ISINBATTLE]
	cp a,2
	jr z,.BlockBall ; if in trainer battle, play different animation
	ld a,[$D11E]
	ld b,a

	; upper nybble: how many animations (from PokeBallAnimations) to play
	; this will be 4 for successful capture, 6 for breakout
	and a,$F0
	swap a
	ld c,a

	; lower nybble: number of shakes
	; store these for later
	ld a,b
	and a,$F
	ld [$CD3D],a

	ld hl,.PokeBallAnimations
	; choose which toss animation to use
	ld a,[$CF91]
	cp a,POKE_BALL
	ld b,TOSS_ANIM
	jr z,.done
	cp a,GREAT_BALL
	ld b,GREATTOSS_ANIM
	jr z,.done
	ld b,ULTRATOSS_ANIM
.done
	ld a,b
.PlayNextAnimation
	ld [W_ANIMATIONID],a
	push bc
	push hl
	call PlayAnimation
	pop hl
	ld a,[hli]
	pop bc
	dec c
	jr nz,.PlayNextAnimation
	ret

.PokeBallAnimations: ; 79e50 (1e:5e50)
; sequence of animations that make up the Poké Ball toss
	db POOF_ANIM,HIDEPIC_ANIM,$C2,POOF_ANIM,SHOWPIC_ANIM

.BlockBall ; 5E55
	ld a,$C1
	ld [W_ANIMATIONID],a
	call PlayAnimation
	ld a,(SFX_08_43 - SFX_Headers_08) / 3
	call PlaySound ; play sound effect
	ld a,BLOCKBALL_ANIM
	ld [W_ANIMATIONID],a
	jp PlayAnimation

Func_79e6a: ; 79e6a (1e:5e6a)
	call WaitForSoundToFinish
	ld a, [$d05b]
	and $7f
	ret z
	cp $a
	ld a, $20
	ld b, $30
	ld c, (SFX_08_50 - SFX_Headers_08) / 3
	jr z, .asm_79e8b
	ld a, $e0
	ld b, $ff
	ld c, (SFX_08_5a - SFX_Headers_08) / 3
	jr nc, .asm_79e8b
	ld a, $50
	ld b, $1
	ld c, (SFX_08_51 - SFX_Headers_08) / 3
.asm_79e8b
	ld [$c0f1], a
	ld a, b
	ld [$c0f2], a
	ld a, c
	jp PlaySound

Func_79e96: ; 79e96 (1e:5e96)
	ld a, [$cd4d]
	cp $52
	jr z, .asm_79ec8
	ld c, $8
.asm_79e9f
	push bc
	ld hl, $c391
	ld a, $1
	ld [$d08a], a
	ld c, $2
	call Func_79339
	ld hl, $c399
	ld a, $ff
	ld [$d08a], a
	ld c, $2
	call Func_79339
	ld a, [rOBP1] ; $ff49
	xor $64
	ld [rOBP1], a ; $ff49
	call DelayFrame
	pop bc
	dec c
	jr nz, .asm_79e9f
	ret
.asm_79ec8
	ld c, $2
.asm_79eca
	push bc
	ld c, $8
	call Func_79eed
	call Func_79f30
	ld c, $8
	call Func_79eed
	call Func_79f30
	ld hl, $c390
	ld a, $2
	ld [$d08a], a
	ld c, $4
	call Func_79352
	pop bc
	dec c
	jr nz, .asm_79eca
	ret

Func_79eed: ; 79eed (1e:5eed)
	push bc
	ld hl, $c391
	ld a, $1
	ld [$d08a], a
	ld c, $1
	call Func_79339
	ld hl, $c395
	ld a, $2
	ld [$d08a], a
	ld c, $1
	call Func_79339
	ld hl, $c399
	ld a, $fe
	ld [$d08a], a
	ld c, $1
	call Func_79339
	ld hl, $c39d
	ld a, $ff
	ld [$d08a], a
	ld c, $1
	call Func_79339
	ld a, [rOBP1] ; $ff49
	xor $64
	ld [rOBP1], a ; $ff49
	call DelayFrame
	pop bc
	dec c
	jr nz, Func_79eed
	ret

Func_79f30: ; 79f30 (1e:5f30)
	ld hl, $c390
	ld de, $cee9
	ld bc, $8
	call CopyData
	ld hl, $c398
	ld de, $c390
	ld bc, $8
	call CopyData
	ld hl, $cee9
	ld de, $c398
	ld bc, $8
	jp CopyData

Func_79f54: ; 79f54 (1e:5f54)
	ld a, $1
	ld [$cd50], a
	ld a, [$cfcb]
	push af
	ld a, $ff
	ld [$cfcb], a
	ld a, $e4
	ld [rOBP1], a ; $ff49
	call LoadSmokeTileFourTimes
	callba asm_f055
	ld c, $8
.asm_79f73
	push bc
	call Func_79f92
	ld bc, .asm_79f7e
	push bc
	ld c, $4
	jp [hl]
.asm_79f7e
	ld a, [rOBP1] ; $ff49
	xor $64
	ld [rOBP1], a ; $ff49
	call Delay3
	pop bc
	dec c
	jr nz, .asm_79f73
	pop af
	ld [$cfcb], a
	jp LoadPlayerSpriteGraphics

Func_79f92: ; 79f92 (1e:5f92)
	ld a, [$c109]
	ld hl, PointerTable_79fb0 ; $5fb0
	ld c, a
	ld b, $0
	add hl, bc
	ld a, [hli]
	ld [$d08a], a
	ld a, [hli]
	ld e, a
	ld a, [hli]
	ld h, [hl]
	ld l, a
	push hl
	ld hl, $c390
	ld d, $0
	add hl, de
	ld e, l
	ld d, h
	pop hl
	ret

PointerTable_79fb0: ; 79fb0 (1e:5fb0)
	db $FF,$00
	dw Func_79350

	db $01,$00
	dw Func_79350

	db $01,$01
	dw Func_79337

	db $FF,$01
	dw Func_79337

LoadSmokeTileFourTimes: ; 79fc0 (1e:5fc0)
	ld hl, $8fc0
	ld c, $4
.loop
	push bc
	push hl
	call LoadSmokeTile
	pop hl
	ld bc, $10
	add hl, bc
	pop bc
	dec c
	jr nz, .loop
	ret

LoadSmokeTile: ; 79fd4 (1e:5fd4)
	ld de, SSAnneSmokePuffTile ; $5fdd
	ld bc, (BANK(SSAnneSmokePuffTile) << 8) + $01
	jp CopyVideoData

SSAnneSmokePuffTile: ; 79fdd (1e:5fdd)
	INCBIN "gfx/ss_anne_smoke_puff.2bpp"

RedFishingTilesFront: ; 79fed (1e:5fed)
	INCBIN "gfx/red_fishing_tile_front.2bpp"

RedFishingTilesBack: ; 7a00d (1e:600d)
	INCBIN "gfx/red_fishing_tile_back.2bpp"

RedFishingTilesSide: ; 7a02d (1e:602d)
	INCBIN "gfx/red_fishing_tile_side.2bpp"

RedFishingRodTiles: ; 7a04d (1e:604d)
	INCBIN "gfx/red_fishingrod_tiles.2bpp"

INCLUDE "data/animations.asm"

Func_7bde9: ; 7bde9 (1e:7de9)
	push hl
	push de
	push bc
	ld a, [$cf91]
	push af
	ld a, [$d0b5]
	push af
	xor a
	ld [$d083], a
	ld [$c02a], a
	dec a
	ld [$c0ee], a
	call PlaySound
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, (SFX_08_3c - SFX_Headers_08) / 3
	call PlaySound
	call Delay3
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld [$ffd7], a
	ld a, [$cee9]
	ld [$cf1d], a
	ld c, $0
	call Func_7beb4
	ld a, [$ceea]
	ld [$cf91], a
	ld [$d0b5], a
	call Func_7beb9
	ld de, $9000
	ld hl, $9310
	ld bc, $31
	call CopyVideoData
	ld a, [$cee9]
	ld [$cf91], a
	ld [$d0b5], a
	call Func_7beb9
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	ld a, [$cee9]
	call PlayCry
	call WaitForSoundToFinish
	ld c, BANK(Music_SafariZone)
	ld a, MUSIC_SAFARI_ZONE
	call PlayMusic
	ld c, $50
	call DelayFrames
	ld c, $1
	call Func_7beb4
	ld bc, $110
.asm_7be63
	push bc
	call asm_7befa
	jr c, .asm_7bea9
	call asm_7bec2
	pop bc
	inc b
	dec c
	dec c
	jr nz, .asm_7be63
	xor a
	ld [$ceec], a
	ld a, $31
	ld [$ceeb], a
	call Func_7bed6
	ld a, [$ceea]
.asm_7be81
	ld [$cf1d], a
	ld a, $ff
	ld [$c0ee], a
	call PlaySound
	ld a, [$cf1d]
	call PlayCry
	ld c, $0
	call Func_7beb4
	pop af
	ld [$d0b5], a
	pop af
	ld [$cf91], a
	pop bc
	pop de
	pop hl
	ld a, [$ceec]
	and a
	ret z
	scf
	ret
.asm_7bea9
	pop bc
	ld a, $1
	ld [$ceec], a
	ld a, [$cee9]
	jr .asm_7be81

Func_7beb4: ; 7beb4 (1e:7eb4)
	ld b, $b
	jp GoPAL_SET

Func_7beb9: ; 7beb9 (1e:7eb9)
	call GetMonHeader
	FuncCoord 7, 2 ; $c3cf
	ld hl, Coord
	jp LoadFlippedFrontSpriteByMonIndex
asm_7bec2: ; 7bec2 (1e:7ec2)
	ld a, $31
	ld [$ceeb], a
	call Func_7bed6
	ld a, $cf
	ld [$ceeb], a
	call Func_7bed6
	dec b
	jr nz, asm_7bec2
	ret

Func_7bed6: ; 7bed6 (1e:7ed6)
	push bc
	xor a
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	FuncCoord 7, 2 ; $c3cf
	ld hl, Coord
	ld bc, $707
	ld de, $d
.asm_7bee3
	push bc
.asm_7bee4
	ld a, [$ceeb]
	add [hl]
	ld [hli], a
	dec c
	jr nz, .asm_7bee4
	pop bc
	add hl, de
	dec b
	jr nz, .asm_7bee3
	ld a, $1
	ld [H_AUTOBGTRANSFERENABLED], a ; $ffba
	call Delay3
	pop bc
	ret
asm_7befa: ; 7befa (1e:7efa)
	call DelayFrame
	push bc
	call GetJoypadStateLowSensitivity
	ld a, [$ffb5]
	pop bc
	and $2
	jr nz, .asm_7bf0d
.asm_7bf08
	dec c
	jr nz, asm_7befa
	and a
	ret
.asm_7bf0d
	ld a, [$ccd4]
	and a
	jr nz, .asm_7bf08
	scf
	ret

ShakeElevator: ; 7bf15 (1e:7f15)
	ld de, $ffe0
	call Func_7bf64
	ld de, $240
	call Func_7bf64
	call Delay3
	ld a, $ff
	call PlaySound
	ld a, [$ffaf]
	ld d, a
	ld e, $1
	; number of times to play collision sfx
	ld b, $64
.asm_7bf30
	ld a, e
	xor $fe
	ld e, a
	add d
	ld [$ffaf], a
	push bc
	ld c, BANK(SFX_02_5b)
	ld a, (SFX_02_5b - SFX_Headers_02) / 3
	call PlayMusic
	pop bc
	ld c, $2
	call DelayFrames
	dec b
	jr nz, .asm_7bf30
	ld a, d
	ld [$ffaf], a
	ld a, $ff
	call PlaySound
	ld c, BANK(SFX_02_5f)
	ld a, (SFX_02_5f - SFX_Headers_02) / 3
	call PlayMusic
.asm_7bf57
	ld a, [$c02a]
	cp $b9
	jr z, .asm_7bf57
	call UpdateSprites
	jp Func_2307

Func_7bf64: ; 7bf64 (1e:7f64)
	ld hl, $d527
	ld a, [hld]
	push af
	ld a, [hl]
	push af
	push hl
	push hl
	ld a, [hli]
	ld h, [hl]
	ld l, a
	add hl, de
	ld a, h
	and $3
	or $98
	ld d, a
	ld a, l
	pop hl
	ld [hli], a
	ld [hl], d
	call ScheduleNorthRowRedraw
	pop hl
	pop af
	ld [hli], a
	pop af
	ld [hl], a
	jp Delay3

GetMachinePrice: ; 7bf86 (1e:7f86)
	ld a, [$cf91]
	sub TM_01
	ret c
	ld d, a
	ld hl, TechnicalMachinePrices ; $7fa7
	srl a
	ld c, a
	ld b, 0
	add hl, bc
	ld a, [hl]
	srl d
	jr nc, .asm_7bf9d
	swap a
.asm_7bf9d
	and $f0
	ld [H_DOWNARROWBLINKCNT2], a ; $ff8c
	xor a
	ld [H_DOWNARROWBLINKCNT1], a ; $ff8b
	ld [$ff8d], a
	ret

INCLUDE "data/tm_prices.asm"