summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorentrpntr <12521136+entrpntr@users.noreply.github.com>2020-05-26 14:28:16 -0400
committerGitHub <noreply@github.com>2020-05-26 14:28:16 -0400
commit418ac97a9c2142aae82051e6bdb149c9103b7282 (patch)
treecf004df596ca9099dda5dc4ce8e924643e7c8207
parenta831702736defce904078495b013a4cdd55b9b41 (diff)
parentdac5598524c04c5ac220e7c9616484c01da70d60 (diff)
Merge pull request #37 from libjet/bank14
Disassemble bank $14
-rwxr-xr-xdata/growth_rates.asm19
-rwxr-xr-xdata/party_menu_qualities.asm35
-rwxr-xr-xdata/pokemon/unused_pic_banks.asm17
-rwxr-xr-xdata/text/unused_gen1_trainer_names.asm71
-rwxr-xr-xdata/types/names.asm50
-rwxr-xr-xengine/battle/unreferenced_getgen1trainerclassname.asm21
-rwxr-xr-xengine/events/basement_key.asm32
-rwxr-xr-xengine/events/card_key.asm37
-rwxr-xr-xengine/events/fishing_gfx.asm24
-rwxr-xr-xengine/events/poisonstep.asm154
-rwxr-xr-xengine/events/sacred_ash.asm68
-rwxr-xr-xengine/events/squirtbottle.asm45
-rwxr-xr-xengine/events/sweet_scent.asm65
-rwxr-xr-xengine/link/init_list.asm55
-rwxr-xr-xengine/pokemon/experience.asm162
-rwxr-xr-xengine/pokemon/mon_stats.asm475
-rwxr-xr-xengine/pokemon/party_menu.asm783
-rw-r--r--engine/pokemon/stats_screen.asm868
-rwxr-xr-xengine/pokemon/switchpartymons.asm145
-rwxr-xr-xengine/pokemon/tempmon.asm127
-rwxr-xr-xengine/pokemon/types.asm92
-rw-r--r--main.asm98
-rw-r--r--wram.asm7
23 files changed, 3371 insertions, 79 deletions
diff --git a/data/growth_rates.asm b/data/growth_rates.asm
new file mode 100755
index 00000000..aee2a16e
--- /dev/null
+++ b/data/growth_rates.asm
@@ -0,0 +1,19 @@
+growth_rate: MACRO
+; [1]/[2]*n**3 + [3]*n**2 + [4]*n - [5]
+ dn \1, \2
+ if \3 & $80 ; signed
+ db -\3 | $80
+ else
+ db \3
+ endc
+ db \4, \5
+ENDM
+
+GrowthRates:
+; entries correspond to GROWTH_* (see constants/pokemon_data_constants.asm)
+ growth_rate 1, 1, 0, 0, 0 ; Medium Fast
+ growth_rate 3, 4, 10, 0, 30 ; Slightly Fast
+ growth_rate 3, 4, 20, 0, 70 ; Slightly Slow
+ growth_rate 6, 5, -15, 100, 140 ; Medium Slow
+ growth_rate 4, 5, 0, 0, 0 ; Fast
+ growth_rate 5, 4, 0, 0, 0 ; Slow
diff --git a/data/party_menu_qualities.asm b/data/party_menu_qualities.asm
new file mode 100755
index 00000000..0f8b19bf
--- /dev/null
+++ b/data/party_menu_qualities.asm
@@ -0,0 +1,35 @@
+; WritePartyMenuTilemap.Jumptable indexes (see engine/party_menu.asm)
+ const_def
+ const PARTYMENUQUALITY_NICKNAMES
+ const PARTYMENUQUALITY_HP_BAR
+ const PARTYMENUQUALITY_HP_DIGITS
+ const PARTYMENUQUALITY_LEVEL
+ const PARTYMENUQUALITY_STATUS
+ const PARTYMENUQUALITY_TMHM_COMPAT
+ const PARTYMENUQUALITY_EVO_STONE_COMPAT
+ const PARTYMENUQUALITY_GENDER
+
+partymenuqualities: MACRO
+rept _NARG
+ db PARTYMENUQUALITY_\1
+ shift
+endr
+ db -1 ; end
+ENDM
+
+PartyMenuQualityPointers:
+; entries correspond to PARTYMENUACTION_* constants
+ dw .Default ; PARTYMENUACTION_CHOOSE_POKEMON
+ dw .Default ; PARTYMENUACTION_HEALING_ITEM
+ dw .Default ; PARTYMENUACTION_SWITCH
+ dw .TMHM ; PARTYMENUACTION_TEACH_TMHM
+ dw .Default ; PARTYMENUACTION_MOVE
+ dw .EvoStone ; PARTYMENUACTION_EVO_STONE
+ dw .Gender ; PARTYMENUACTION_GIVE_MON
+ dw .Gender ; PARTYMENUACTION_GIVE_MON_FEMALE
+ dw .Default ; PARTYMENUACTION_GIVE_ITEM
+
+.Default: partymenuqualities NICKNAMES, HP_BAR, HP_DIGITS, LEVEL, STATUS
+.TMHM: partymenuqualities NICKNAMES, TMHM_COMPAT, LEVEL, STATUS
+.EvoStone: partymenuqualities NICKNAMES, EVO_STONE_COMPAT, LEVEL, STATUS
+.Gender: partymenuqualities NICKNAMES, GENDER, LEVEL, STATUS
diff --git a/data/pokemon/unused_pic_banks.asm b/data/pokemon/unused_pic_banks.asm
new file mode 100755
index 00000000..2ede9c3f
--- /dev/null
+++ b/data/pokemon/unused_pic_banks.asm
@@ -0,0 +1,17 @@
+; This was a table of Pokémon sprite banks in the 1997 G/S prototype.
+; See pokegold-spaceworld's gfx/pokemon/pkmn_pic_banks.asm.
+
+Unreferenced_MonPicBanks:
+ ; last mon in bank, bank #
+ db RAICHU, $15 + 0
+ db DUGTRIO, $15 + 1
+ db GRAVELER, $15 + 2
+ db KRABBY, $15 + 3
+ db STARMIE, $15 + 4
+ db ARTICUNO, $15 + 5
+ db ARIADOS, $15 + 6 ; JARANRA in pokegold-spaceworld
+ db ESPEON, $15 + 7 ; KOUNYA in pokegold-spaceworld
+ db OCTILLERY, $15 + 8 ; BOMBSEEKER in pokegold-spaceworld
+ db LARVITAR, $15 + 9 ; NYULA in pokegold-spaceworld
+ db $ff, $15 + 10
+ db $ff, $15 + 11
diff --git a/data/text/unused_gen1_trainer_names.asm b/data/text/unused_gen1_trainer_names.asm
new file mode 100755
index 00000000..fa839f36
--- /dev/null
+++ b/data/text/unused_gen1_trainer_names.asm
@@ -0,0 +1,71 @@
+Gen1TrainerClassNames:
+; Untranslated trainer class names from Red.
+ dw .Youngster
+ dw .BugCatcher
+ dw .Lass
+ dw wOTClassName ; sailor
+ dw .JrTrainerM
+ dw .JrTrainerF
+ dw .Pokemaniac
+ dw .SuperNerd
+ dw wOTClassName ; hiker
+ dw wOTClassName ; biker
+ dw .Burglar
+ dw .Engineer
+ dw .Jack
+ dw wOTClassName ; fisher
+ dw .Swimmer
+ dw wOTClassName ; cue ball
+ dw wOTClassName ; gambler
+ dw .Beauty
+ dw wOTClassName ; psychic
+ dw .Rocker
+ dw .Juggler
+ dw wOTClassName ; tamer
+ dw wOTClassName ; bird keeper
+ dw .Blackbelt
+ dw wOTClassName ; rival1
+ dw .ProfOak
+ dw .Chief
+ dw .Scientist
+ dw wOTClassName ; giovanni
+ dw .Rocket
+ dw .CooltrainerM
+ dw .CooltrainerF
+ dw wOTClassName ; bruno
+ dw wOTClassName ; brock
+ dw wOTClassName ; misty
+ dw wOTClassName ; lt.surge
+ dw wOTClassName ; erika
+ dw wOTClassName ; koga
+ dw wOTClassName ; blaine
+ dw wOTClassName ; sabrina
+ dw wOTClassName ; gentleman
+ dw wOTClassName ; rival2
+ dw wOTClassName ; rival3
+ dw wOTClassName ; lorelei
+ dw wOTClassName ; channeler
+ dw wOTClassName ; agatha
+ dw wOTClassName ; lance
+
+.Youngster: db "たんパン@"
+.BugCatcher: db "むしとり@"
+.Lass: db "ミニスカ@"
+.JrTrainerM: db "ボーイ@"
+.JrTrainerF: db "ガール@"
+.Pokemaniac: db "マニア@"
+.SuperNerd: db "りかけい@"
+.Burglar: db "どろぼう@"
+.Engineer: db "オヤジ@"
+.Jack: db "ジャック@"
+.Swimmer: db "かいパン@"
+.Beauty: db "おねえさん@"
+.Rocker: db "グループ@"
+.Juggler: db "ジャグラー@"
+.Blackbelt: db "からて@"
+.ProfOak: db "オーキド@"
+.Chief: db "チーフ@"
+.Scientist: db "けんきゅういん@"
+.Rocket: db "だんいん@"
+.CooltrainerM: db "エりート♂@"
+.CooltrainerF: db "エりート♀@"
diff --git a/data/types/names.asm b/data/types/names.asm
new file mode 100755
index 00000000..62d8e13b
--- /dev/null
+++ b/data/types/names.asm
@@ -0,0 +1,50 @@
+TypeNames:
+; entries correspond to types (see constants/type_constants.asm)
+ dw Normal
+ dw Fighting
+ dw Flying
+ dw Poison
+ dw Ground
+ dw Rock
+ dw Bird
+ dw Bug
+ dw Ghost
+ dw Steel
+ dw Normal
+ dw Normal
+ dw Normal
+ dw Normal
+ dw Normal
+ dw Normal
+ dw Normal
+ dw Normal
+ dw Normal
+ dw CurseType
+ dw Fire
+ dw Water
+ dw Grass
+ dw Electric
+ dw Psychic
+ dw Ice
+ dw Dragon
+ dw Dark
+
+Normal: db "NORMAL@"
+Fighting: db "FIGHTING@"
+Flying: db "FLYING@"
+Poison: db "POISON@"
+CurseType: db "???@"
+Fire: db "FIRE@"
+Water: db "WATER@"
+Grass: db "GRASS@"
+Electric: db "ELECTRIC@"
+Psychic: db "PSYCHIC@"
+Ice: db "ICE@"
+Ground: db "GROUND@"
+Rock: db "ROCK@"
+Bird: db "BIRD@"
+Bug: db "BUG@"
+Ghost: db "GHOST@"
+Steel: db "STEEL@"
+Dragon: db "DRAGON@"
+Dark: db "DARK@"
diff --git a/engine/battle/unreferenced_getgen1trainerclassname.asm b/engine/battle/unreferenced_getgen1trainerclassname.asm
new file mode 100755
index 00000000..04532523
--- /dev/null
+++ b/engine/battle/unreferenced_getgen1trainerclassname.asm
@@ -0,0 +1,21 @@
+Unreferenced_GetGen1TrainerClassName:
+ ld hl, Gen1TrainerClassNames
+ ld a, [wTrainerClass]
+ 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, wStringBuffer1
+.copy
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp "@"
+ jr nz, .copy
+ ret
+
+INCLUDE "data/text/unused_gen1_trainer_names.asm"
diff --git a/engine/events/basement_key.asm b/engine/events/basement_key.asm
new file mode 100755
index 00000000..ab8c39ce
--- /dev/null
+++ b/engine/events/basement_key.asm
@@ -0,0 +1,32 @@
+_BasementKey:
+; Are we even in the right map to use this?
+ ld a, [wMapGroup]
+ cp GROUP_GOLDENROD_UNDERGROUND
+ jr nz, .nope
+
+ ld a, [wMapNumber]
+ cp MAP_GOLDENROD_UNDERGROUND
+ jr nz, .nope
+; Are we on the tile in front of the door?
+ call GetFacingTileCoord
+ ld a, d
+ cp 22
+ jr nz, .nope
+ ld a, e
+ cp 10
+ jr nz, .nope
+; Let's use the Basement Key
+ ld hl, .BasementKeyScript
+ call QueueScript
+ ld a, TRUE
+ ld [wItemEffectSucceeded], a
+ ret
+
+.nope
+ ld a, FALSE
+ ld [wItemEffectSucceeded], a
+ ret
+
+.BasementKeyScript:
+ closetext
+ farsjump BasementDoorScript
diff --git a/engine/events/card_key.asm b/engine/events/card_key.asm
new file mode 100755
index 00000000..c15b1def
--- /dev/null
+++ b/engine/events/card_key.asm
@@ -0,0 +1,37 @@
+_CardKey:
+; Are we even in the right map to use this?
+ ld a, [wMapGroup]
+ cp GROUP_RADIO_TOWER_3F
+ jr nz, .nope
+
+ ld a, [wMapNumber]
+ cp MAP_RADIO_TOWER_3F
+ jr nz, .nope
+; Are we facing the slot?
+ ld a, [wPlayerDirection]
+ and %1100
+ cp OW_UP
+ jr nz, .nope
+
+ call GetFacingTileCoord
+ ld a, d
+ cp 18
+ jr nz, .nope
+ ld a, e
+ cp 6
+ jr nz, .nope
+; Let's use the Card Key.
+ ld hl, .CardKeyScript
+ call QueueScript
+ ld a, TRUE
+ ld [wItemEffectSucceeded], a
+ ret
+
+.nope
+ ld a, FALSE
+ ld [wItemEffectSucceeded], a
+ ret
+
+.CardKeyScript:
+ closetext
+ farsjump CardKeySlotScript
diff --git a/engine/events/fishing_gfx.asm b/engine/events/fishing_gfx.asm
new file mode 100755
index 00000000..c4a0b9fa
--- /dev/null
+++ b/engine/events/fishing_gfx.asm
@@ -0,0 +1,24 @@
+LoadFishingGFX:
+ ld de, FishingGFX
+ ld hl, vTiles0 tile $02
+ lb bc, BANK(FishingGFX), 2
+ call Get2bpp
+
+ ld de, FishingGFX tile $02
+ ld hl, vTiles0 tile $06
+ lb bc, BANK(FishingGFX), 2
+ call Get2bpp
+
+ ld de, FishingGFX tile $04
+ ld hl, vTiles0 tile $0a
+ lb bc, BANK(FishingGFX), 2
+ call Get2bpp
+
+ ld de, FishingGFX tile $06
+ ld hl, vTiles0 tile $fc
+ lb bc, BANK(FishingGFX), 2
+ call Get2bpp
+ ret
+
+FishingGFX:
+INCBIN "gfx/overworld/chris_fish.2bpp"
diff --git a/engine/events/poisonstep.asm b/engine/events/poisonstep.asm
new file mode 100755
index 00000000..98a6e25a
--- /dev/null
+++ b/engine/events/poisonstep.asm
@@ -0,0 +1,154 @@
+DoPoisonStep::
+ ld a, [wPartyCount]
+ and a
+ jr z, .no_faint
+
+ xor a
+ ld c, wPoisonStepDataEnd - wPoisonStepData
+ ld hl, wPoisonStepData
+.loop_clearPoisonStepData
+ ld [hli], a
+ dec c
+ jr nz, .loop_clearPoisonStepData
+
+ xor a
+ ld [wCurPartyMon], a
+.loop_check_poison
+ call .DamageMonIfPoisoned
+ jr nc, .not_poisoned
+; the output flag is stored in c, copy it to [wPoisonStepPartyFlags + [wCurPartyMon]]
+; and set the corresponding flag in wPoisonStepFlagSum
+ ld a, [wCurPartyMon]
+ ld e, a
+ ld d, 0
+ ld hl, wPoisonStepPartyFlags
+ add hl, de
+ ld [hl], c
+ ld a, [wPoisonStepFlagSum]
+ or c
+ ld [wPoisonStepFlagSum], a
+
+.not_poisoned
+ ld a, [wPartyCount]
+ ld hl, wCurPartyMon
+ inc [hl]
+ cp [hl]
+ jr nz, .loop_check_poison
+
+ ld a, [wPoisonStepFlagSum]
+ and %10
+ jr nz, .someone_has_fainted
+ ld a, [wPoisonStepFlagSum]
+ and %01
+ jr z, .no_faint
+ call .PlayPoisonSFX
+ xor a
+ ret
+
+.someone_has_fainted
+ ld a, BANK(.Script_MonFaintedToPoison)
+ ld hl, .Script_MonFaintedToPoison
+ call CallScript
+ scf
+ ret
+
+.no_faint
+ xor a
+ ret
+
+.DamageMonIfPoisoned:
+; check if mon is poisoned, return if not
+ ld a, MON_STATUS
+ call GetPartyParamLocation
+ ld a, [hl]
+ and 1 << PSN
+ ret z
+
+; check if mon is already fainted, return if so
+ ld a, MON_HP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ or c
+ ret z
+
+; do 1 HP damage
+ dec bc
+ ld [hl], c
+ dec hl
+ ld [hl], b
+
+; check if mon has fainted as a result of poison damage
+ ld a, b
+ or c
+ jr nz, .not_fainted
+
+; the mon has fainted, reset its status, set carry, and return %10
+ ld a, MON_STATUS
+ call GetPartyParamLocation
+ ld [hl], 0
+ ld c, %10
+ scf
+ ret
+
+.not_fainted
+; set carry and return %01
+ ld c, %01
+ scf
+ ret
+
+.PlayPoisonSFX:
+ ld de, SFX_POISON
+ call PlaySFX
+ ld b, $2
+ predef LoadPoisonBGPals
+ call DelayFrame
+ ret
+
+.Script_MonFaintedToPoison:
+ callasm .PlayPoisonSFX
+ opentext
+ callasm .CheckWhitedOut
+ iffalse .whiteout
+ closetext
+ end
+
+.whiteout
+ farsjump Script_OverworldWhiteout
+
+.CheckWhitedOut:
+ xor a
+ ld [wCurPartyMon], a
+ ld de, wPoisonStepPartyFlags
+.party_loop
+ push de
+ ld a, [de]
+ and %10
+ jr z, .mon_not_fainted
+ ld c, HAPPINESS_POISONFAINT
+ farcall ChangeHappiness
+ farcall GetPartyNick
+ ld hl, .PoisonFaintText
+ call PrintText
+
+.mon_not_fainted
+ pop de
+ inc de
+ ld hl, wCurPartyMon
+ inc [hl]
+ ld a, [wPartyCount]
+ cp [hl]
+ jr nz, .party_loop
+ predef CheckPlayerPartyForFitMon
+ ld a, d
+ ld [wScriptVar], a
+ ret
+
+.PoisonFaintText:
+ text_far _PoisonFaintText
+ text_end
+
+.PoisonWhiteoutText:
+ text_far _PoisonWhiteoutText
+ text_end
diff --git a/engine/events/sacred_ash.asm b/engine/events/sacred_ash.asm
new file mode 100755
index 00000000..d105b2fb
--- /dev/null
+++ b/engine/events/sacred_ash.asm
@@ -0,0 +1,68 @@
+_SacredAsh:
+ ld a, $0
+ ld [wItemEffectSucceeded], a
+ call CheckAnyFaintedMon
+ ret nc
+
+ ld hl, SacredAshScript
+ call QueueScript
+ ld a, $1
+ ld [wItemEffectSucceeded], a
+ ret
+
+CheckAnyFaintedMon:
+ ld de, PARTYMON_STRUCT_LENGTH
+ ld bc, wPartySpecies
+ ld hl, wPartyMon1HP
+ ld a, [wPartyCount]
+ and a
+ ret z
+
+.loop
+ push af
+ push hl
+ ld a, [bc]
+ inc bc
+ cp EGG
+ jr z, .next
+
+ ld a, [hli]
+ or [hl]
+ jr z, .done
+
+.next
+ pop hl
+ add hl, de
+ pop af
+ dec a
+ jr nz, .loop
+ xor a
+ ret
+
+.done
+ pop hl
+ pop af
+ scf
+ ret
+
+SacredAshScript:
+ special HealParty
+ reloadmappart
+ playsound SFX_WARP_TO
+ special FadeOutPalettes
+ special FadeInPalettes
+ special FadeOutPalettes
+ special FadeInPalettes
+ special FadeOutPalettes
+ special FadeInPalettes
+ waitsfx
+ writetext .UseSacredAshText
+ playsound SFX_CAUGHT_MON
+ waitsfx
+ waitbutton
+ closetext
+ end
+
+.UseSacredAshText:
+ text_far _UseSacredAshText
+ text_end
diff --git a/engine/events/squirtbottle.asm b/engine/events/squirtbottle.asm
new file mode 100755
index 00000000..411b5c2e
--- /dev/null
+++ b/engine/events/squirtbottle.asm
@@ -0,0 +1,45 @@
+_Squirtbottle:
+ ld hl, .SquirtbottleScript
+ call QueueScript
+ ld a, $1
+ ld [wItemEffectSucceeded], a
+ ret
+
+.SquirtbottleScript:
+ reloadmappart
+ special UpdateTimePals
+ callasm .CheckCanUseSquirtbottle
+ iffalse .SquirtbottleNothingScript
+ farsjump WateredWeirdTreeScript
+
+.SquirtbottleNothingScript:
+ jumptext .SquirtbottleNothingText
+
+.SquirtbottleNothingText:
+ text_far _SquirtbottleNothingText
+ text_end
+
+.CheckCanUseSquirtbottle:
+ ld a, [wMapGroup]
+ cp GROUP_ROUTE_36
+ jr nz, .nope
+
+ ld a, [wMapNumber]
+ cp MAP_ROUTE_36
+ jr nz, .nope
+
+ farcall GetFacingObject
+ jr c, .nope
+
+ ld a, d
+ cp SPRITEMOVEDATA_SUDOWOODO
+ jr nz, .nope
+
+ ld a, 1
+ ld [wScriptVar], a
+ ret
+
+.nope
+ xor a
+ ld [wScriptVar], a
+ ret
diff --git a/engine/events/sweet_scent.asm b/engine/events/sweet_scent.asm
new file mode 100755
index 00000000..9b99a256
--- /dev/null
+++ b/engine/events/sweet_scent.asm
@@ -0,0 +1,65 @@
+SweetScentFromMenu:
+ ld hl, .SweetScent
+ call QueueScript
+ ld a, $1
+ ld [wFieldMoveSucceeded], a
+ ret
+
+.SweetScent:
+ reloadmappart
+ special UpdateTimePals
+ callasm GetPartyNick
+ writetext UseSweetScentText
+ waitbutton
+ callasm SweetScentEncounter
+ iffalse SweetScentNothing
+ checkflag ENGINE_BUG_CONTEST_TIMER
+ iftrue .BugCatchingContest
+ randomwildmon
+ startbattle
+ reloadmapafterbattle
+ end
+
+.BugCatchingContest:
+ farsjump BugCatchingContestBattleScript
+
+SweetScentNothing:
+ writetext SweetScentNothingText
+ waitbutton
+ closetext
+ end
+
+SweetScentEncounter:
+ farcall CanUseSweetScent
+ jr nc, .no_battle
+ ld hl, wStatusFlags2
+ bit STATUSFLAGS2_BUG_CONTEST_TIMER_F, [hl]
+ jr nz, .not_in_bug_contest
+ farcall GetMapEncounterRate
+ ld a, b
+ and a
+ jr z, .no_battle
+ farcall ChooseWildEncounter
+ jr nz, .no_battle
+ jr .start_battle
+
+.not_in_bug_contest
+ farcall ChooseWildEncounter_BugContest
+
+.start_battle
+ ld a, $1
+ ld [wScriptVar], a
+ ret
+
+.no_battle
+ xor a
+ ld [wScriptVar], a
+ ret
+
+UseSweetScentText:
+ text_far _UseSweetScentText
+ text_end
+
+SweetScentNothingText:
+ text_far _SweetScentNothingText
+ text_end
diff --git a/engine/link/init_list.asm b/engine/link/init_list.asm
new file mode 100755
index 00000000..b85cf001
--- /dev/null
+++ b/engine/link/init_list.asm
@@ -0,0 +1,55 @@
+InitList:
+; This entire function is useless.
+ ld a, [wInitListType]
+
+ cp INIT_ENEMYOT_LIST
+ jr nz, .check_party_ot_name
+ ld hl, wOTPartyCount
+ ld de, wOTPartyMonOT
+ ld a, ENEMY_OT_NAME
+ jr .done
+
+.check_party_ot_name
+ cp INIT_PLAYEROT_LIST
+ jr nz, .check_mon_name
+ ld hl, wPartyCount
+ ld de, wPartyMonOT
+ ld a, PARTY_OT_NAME
+ jr .done
+
+.check_mon_name
+ cp INIT_MON_LIST
+ jr nz, .check_item_name
+ ld hl, wCurMart
+ ld de, PokemonNames
+ ld a, MON_NAME
+ jr .done
+
+.check_item_name
+ cp INIT_BAG_ITEM_LIST
+ jr nz, .check_ob_item_name
+ ld hl, wNumItems
+ ld de, ItemNames
+ ld a, ITEM_NAME
+ jr .done
+
+.check_ob_item_name
+ ld hl, wCurMart
+ ld de, ItemNames
+ ld a, ITEM_NAME
+.done
+ ld [wNamedObjectTypeBuffer], a
+ ld a, l
+ ld [wListPointer], a
+ ld a, h
+ ld [wListPointer + 1], a
+ ld a, e
+ ld [wUnusedCFFE], a
+ ld a, d
+ ld [wUnusedCFFE + 1], a
+ ld bc, ItemAttributes
+ ld a, c
+ ld [wItemAttributesPtr], a
+ ld a, b
+ ld [wItemAttributesPtr + 1], a
+ ret
diff --git a/engine/pokemon/experience.asm b/engine/pokemon/experience.asm
new file mode 100755
index 00000000..7d026704
--- /dev/null
+++ b/engine/pokemon/experience.asm
@@ -0,0 +1,162 @@
+CalcLevel:
+ ld a, [wTempMonSpecies]
+ ld [wCurSpecies], a
+ call GetBaseData
+ ld d, 1
+.next_level
+ inc d
+ ld a, d
+ cp LOW(MAX_LEVEL + 1)
+ jr z, .got_level
+ call CalcExpAtLevel
+ push hl
+ ld hl, wTempMonExp + 2
+ ldh a, [hProduct + 3]
+ ld c, a
+ ld a, [hld]
+ sub c
+ ldh a, [hProduct + 2]
+ ld c, a
+ ld a, [hld]
+ sbc c
+ ldh a, [hProduct + 1]
+ ld c, a
+ ld a, [hl]
+ sbc c
+ pop hl
+ jr nc, .next_level
+
+.got_level
+ dec d
+ ret
+
+CalcExpAtLevel:
+; (a/b)*n**3 + c*n**2 + d*n - e
+ ld a, [wBaseGrowthRate]
+ add a
+ add a
+ ld c, a
+ ld b, 0
+ ld hl, GrowthRates
+ add hl, bc
+; Cube the level
+ call .LevelSquared
+ ld a, d
+ ldh [hMultiplier], a
+ call Multiply
+
+; Multiply by a
+ ld a, [hl]
+ and $f0
+ swap a
+ ldh [hMultiplier], a
+ call Multiply
+; Divide by b
+ ld a, [hli]
+ and $f
+ ldh [hDivisor], a
+ ld b, 4
+ call Divide
+; Push the cubic term to the stack
+ ldh a, [hQuotient + 1]
+ push af
+ ldh a, [hQuotient + 2]
+ push af
+ ldh a, [hQuotient + 3]
+ push af
+; Square the level and multiply by the lower 7 bits of c
+ call .LevelSquared
+ ld a, [hl]
+ and $7f
+ ldh [hMultiplier], a
+ call Multiply
+; Push the absolute value of the quadratic term to the stack
+ ldh a, [hProduct + 1]
+ push af
+ ldh a, [hProduct + 2]
+ push af
+ ldh a, [hProduct + 3]
+ push af
+ ld a, [hli]
+ push af
+; Multiply the level by d
+ xor a
+ ldh [hMultiplicand + 0], a
+ ldh [hMultiplicand + 1], a
+ ld a, d
+ ldh [hMultiplicand + 2], a
+ ld a, [hli]
+ ldh [hMultiplier], a
+ call Multiply
+; Subtract e
+ ld b, [hl]
+ ldh a, [hProduct + 3]
+ sub b
+ ldh [hMultiplicand + 2], a
+ ld b, 0
+ ldh a, [hProduct + 2]
+ sbc b
+ ldh [hMultiplicand + 1], a
+ ldh a, [hProduct + 1]
+ sbc b
+ ldh [hMultiplicand], a
+; If bit 7 of c is set, c is negative; otherwise, it's positive
+ pop af
+ and $80
+ jr nz, .subtract
+; Add c*n**2 to (d*n - e)
+ pop bc
+ ldh a, [hProduct + 3]
+ add b
+ ldh [hMultiplicand + 2], a
+ pop bc
+ ldh a, [hProduct + 2]
+ adc b
+ ldh [hMultiplicand + 1], a
+ pop bc
+ ldh a, [hProduct + 1]
+ adc b
+ ldh [hMultiplicand], a
+ jr .done_quadratic
+
+.subtract
+; Subtract c*n**2 from (d*n - e)
+ pop bc
+ ldh a, [hProduct + 3]
+ sub b
+ ldh [hMultiplicand + 2], a
+ pop bc
+ ldh a, [hProduct + 2]
+ sbc b
+ ldh [hMultiplicand + 1], a
+ pop bc
+ ldh a, [hProduct + 1]
+ sbc b
+ ldh [hMultiplicand], a
+
+.done_quadratic
+; Add (a/b)*n**3 to (d*n - e +/- c*n**2)
+ pop bc
+ ldh a, [hProduct + 3]
+ add b
+ ldh [hMultiplicand + 2], a
+ pop bc
+ ldh a, [hProduct + 2]
+ adc b
+ ldh [hMultiplicand + 1], a
+ pop bc
+ ldh a, [hProduct + 1]
+ adc b
+ ldh [hMultiplicand], a
+ ret
+
+.LevelSquared:
+ xor a
+ ldh [hMultiplicand + 0], a
+ ldh [hMultiplicand + 1], a
+ ld a, d
+ ldh [hMultiplicand + 2], a
+ ldh [hMultiplier], a
+ jp Multiply
+
+INCLUDE "data/growth_rates.asm"
diff --git a/engine/pokemon/mon_stats.asm b/engine/pokemon/mon_stats.asm
new file mode 100755
index 00000000..04285f87
--- /dev/null
+++ b/engine/pokemon/mon_stats.asm
@@ -0,0 +1,475 @@
+DrawPlayerHP:
+ ld a, 1
+ jr DrawHP
+
+DrawEnemyHP:
+ ld a, 2
+
+DrawHP:
+ ld [wWhichHPBar], a
+ push hl
+ push bc
+ ; box mons have full HP
+ ld a, [wMonType]
+ cp BOXMON
+ jr z, .at_least_1_hp
+
+ ld a, [wTempMonHP]
+ ld b, a
+ ld a, [wTempMonHP + 1]
+ ld c, a
+
+; Any HP?
+ or b
+ jr nz, .at_least_1_hp
+
+ xor a
+ ld c, a
+ ld e, a
+ ld a, 6
+ ld d, a
+ jp .fainted
+
+.at_least_1_hp
+ ld a, [wTempMonMaxHP]
+ ld d, a
+ ld a, [wTempMonMaxHP + 1]
+ ld e, a
+ ld a, [wMonType]
+ cp BOXMON
+ jr nz, .not_boxmon
+
+ ld b, d
+ ld c, e
+
+.not_boxmon
+ predef ComputeHPBarPixels
+ ld a, 6
+ ld d, a
+ ld c, a
+
+.fainted
+ ld a, c
+ pop bc
+ ld c, a
+ pop hl
+ push de
+ push hl
+ push hl
+ call DrawBattleHPBar
+ pop hl
+
+; Print HP
+ bccoord 1, 1, 0
+ add hl, bc
+ ld de, wTempMonHP
+ ld a, [wMonType]
+ cp BOXMON
+ jr nz, .not_boxmon_2
+ ld de, wTempMonMaxHP
+.not_boxmon_2
+ lb bc, 2, 3
+ call PrintNum
+
+ ld a, "/"
+ ld [hli], a
+
+; Print max HP
+ ld de, wTempMonMaxHP
+ lb bc, 2, 3
+ call PrintNum
+ pop hl
+ pop de
+ ret
+
+INCLUDE "engine/pokemon/stats_screen.asm"
+
+PrintTempMonStats:
+; Print wTempMon's stats at hl, with spacing bc.
+ push bc
+ push hl
+ ld de, .StatNames
+ call PlaceString
+ pop hl
+ pop bc
+ add hl, bc
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld de, wTempMonAttack
+ lb bc, 2, 3
+ call .PrintStat
+ ld de, wTempMonDefense
+ call .PrintStat
+ ld de, wTempMonSpclAtk
+ call .PrintStat
+ ld de, wTempMonSpclDef
+ call .PrintStat
+ ld de, wTempMonSpeed
+ jp PrintNum
+
+.PrintStat:
+ push hl
+ call PrintNum
+ pop hl
+ ld de, SCREEN_WIDTH * 2
+ add hl, de
+ ret
+
+.StatNames:
+ db "ATTACK"
+ next "DEFENSE"
+ next "SPCL.ATK"
+ next "SPCL.DEF"
+ next "SPEED"
+ next "@"
+
+GetGender:
+; Return the gender of a given monster (wCurPartyMon/wCurOTMon/wCurWildMon).
+; When calling this function, a should be set to an appropriate wMonType value.
+
+; return values:
+; a = 1: f = nc|nz; male
+; a = 0: f = nc|z; female
+; f = c: genderless
+
+; This is determined by comparing the Attack and Speed DVs
+; with the species' gender ratio.
+
+; Figure out what type of monster struct we're looking at.
+
+; 0: PartyMon
+ ld hl, wPartyMon1DVs
+ ld bc, PARTYMON_STRUCT_LENGTH
+ ld a, [wMonType]
+ and a
+ jr z, .PartyMon
+
+; 1: OTPartyMon
+ ld hl, wOTPartyMon1DVs
+ dec a
+ jr z, .PartyMon
+
+; 2: sBoxMon
+ ld hl, sBoxMon1DVs
+ ld bc, BOXMON_STRUCT_LENGTH
+ dec a
+ jr z, .sBoxMon
+
+; 3: Unknown
+ ld hl, wTempMonDVs
+ dec a
+ jr z, .DVs
+
+; else: WildMon
+ ld hl, wEnemyMonDVs
+ jr .DVs
+
+; Get our place in the party/box.
+
+.PartyMon:
+.sBoxMon
+ ld a, [wCurPartyMon]
+ call AddNTimes
+
+.DVs:
+; sBoxMon data is read directly from SRAM.
+ ld a, [wMonType]
+ cp BOXMON
+ ld a, BANK(sBox)
+ call z, OpenSRAM
+
+; Attack DV
+ ld a, [hli]
+ and $f0
+ ld b, a
+; Speed DV
+ ld a, [hl]
+ and $f0
+ swap a
+
+; Put our DVs together.
+ or b
+ ld b, a
+
+; Close SRAM if we were dealing with a sBoxMon.
+ ld a, [wMonType]
+ cp BOXMON
+ call z, CloseSRAM
+
+; We need the gender ratio to do anything with this.
+ push bc
+ ld a, [wCurPartySpecies]
+ dec a
+ ld hl, BaseData + BASE_GENDER
+ ld bc, BASE_DATA_SIZE
+ call AddNTimes
+ pop bc
+
+ ld a, BANK(BaseData)
+ call GetFarByte
+
+; The higher the ratio, the more likely the monster is to be female.
+
+ cp GENDER_UNKNOWN
+ jr z, .Genderless
+
+ and a ; GENDER_F0?
+ jr z, .Male
+
+ cp GENDER_F100
+ jr z, .Female
+
+; Values below the ratio are male, and vice versa.
+ cp b
+ jr c, .Male
+
+.Female:
+ xor a
+ ret
+
+.Male:
+ ld a, 1
+ and a
+ ret
+
+.Genderless:
+ scf
+ ret
+
+ListMovePP:
+ ld a, [wNumMoves]
+ inc a
+ ld c, a
+ ld a, NUM_MOVES
+ sub c
+ ld b, a
+ push hl
+ ld a, [wBuffer1]
+ ld e, a
+ ld d, $0
+ ld a, $3e ; P
+ call .load_loop
+ ld a, b
+ and a
+ jr z, .skip
+ ld c, a
+ ld a, "-"
+ call .load_loop
+
+.skip
+ pop hl
+ inc hl
+ inc hl
+ inc hl
+ ld d, h
+ ld e, l
+ ld hl, wTempMonMoves
+ ld b, 0
+.loop
+ ld a, [hli]
+ and a
+ jr z, .done
+ push bc
+ push hl
+ push de
+ ld hl, wMenuCursorY
+ ld a, [hl]
+ push af
+ ld [hl], b
+ push hl
+ callfar GetMaxPPOfMove
+ pop hl
+ pop af
+ ld [hl], a
+ pop de
+ pop hl
+ push hl
+ ld bc, wTempMonPP - (wTempMonMoves + 1)
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ ld [wStringBuffer1 + 4], a
+ ld h, d
+ ld l, e
+ push hl
+ ld de, wStringBuffer1 + 4
+ lb bc, 1, 2
+ call PrintNum
+ ld a, "/"
+ ld [hli], a
+ ld de, wTempPP
+ lb bc, 1, 2
+ call PrintNum
+ pop hl
+ ld a, [wBuffer1]
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld d, h
+ ld e, l
+ pop hl
+ pop bc
+ inc b
+ ld a, b
+ cp NUM_MOVES
+ jr nz, .loop
+
+.done
+ ret
+
+.load_loop
+ ld [hli], a
+ ld [hld], a
+ add hl, de
+ dec c
+ jr nz, .load_loop
+ ret
+
+Unused_PlaceEnemyHPLevel:
+ push hl
+ push hl
+ ld hl, wPartyMonNicknames
+ ld a, [wCurPartyMon]
+ call GetNick
+ pop hl
+ call PlaceString
+ call CopyMonToTempMon
+ pop hl
+ ld a, [wCurPartySpecies]
+ cp EGG
+ jr z, .egg
+ push hl
+ ld bc, -12
+ add hl, bc
+ ld b, $0
+ call DrawEnemyHP
+ pop hl
+ ld bc, 5
+ add hl, bc
+ push de
+ call PrintLevel
+ pop de
+
+.egg
+ ret
+
+PlaceStatusString:
+ push de
+ inc de
+ inc de
+ ld a, [de]
+ ld b, a
+ inc de
+ ld a, [de]
+ or b
+ pop de
+ jr nz, PlaceNonFaintStatus
+ push de
+ ld de, FntString
+ call CopyStatusString
+ pop de
+ ld a, $1
+ and a
+ ret
+
+FntString:
+ db "FNT@"
+
+CopyStatusString:
+ ld a, [de]
+ inc de
+ ld [hli], a
+ ld a, [de]
+ inc de
+ ld [hli], a
+ ld a, [de]
+ ld [hl], a
+ ret
+
+PlaceNonFaintStatus:
+ push de
+ ld a, [de]
+ ld de, PsnString
+ bit PSN, a
+ jr nz, .place
+ ld de, BrnString
+ bit BRN, a
+ jr nz, .place
+ ld de, FrzString
+ bit FRZ, a
+ jr nz, .place
+ ld de, ParString
+ bit PAR, a
+ jr nz, .place
+ ld de, SlpString
+ and SLP
+ jr z, .no_status
+
+.place
+ call CopyStatusString
+ ld a, $1
+ and a
+
+.no_status
+ pop de
+ ret
+
+SlpString: db "SLP@"
+PsnString: db "PSN@"
+BrnString: db "BRN@"
+FrzString: db "FRZ@"
+ParString: db "PAR@"
+
+ListMoves:
+; List moves at hl, spaced every [wBuffer1] tiles.
+ ld de, wListMoves_MoveIndicesBuffer
+ ld b, $0
+.moves_loop
+ ld a, [de]
+ inc de
+ and a
+ jr z, .no_more_moves
+ push de
+ push hl
+ push hl
+ ld [wCurSpecies], a
+ ld a, MOVE_NAME
+ ld [wNamedObjectTypeBuffer], a
+ call GetName
+ ld de, wStringBuffer1
+ pop hl
+ push bc
+ call PlaceString
+ pop bc
+ ld a, b
+ ld [wNumMoves], a
+ inc b
+ pop hl
+ push bc
+ ld a, [wBuffer1]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ pop bc
+ pop de
+ ld a, b
+ cp NUM_MOVES
+ jr z, .done
+ jr .moves_loop
+
+.no_more_moves
+ ld a, b
+.nonmove_loop
+ push af
+ ld [hl], "-"
+ ld a, [wBuffer1]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ pop af
+ inc a
+ cp NUM_MOVES
+ jr nz, .nonmove_loop
+
+.done
+ ret
diff --git a/engine/pokemon/party_menu.asm b/engine/pokemon/party_menu.asm
new file mode 100755
index 00000000..93f9b93b
--- /dev/null
+++ b/engine/pokemon/party_menu.asm
@@ -0,0 +1,783 @@
+SelectMonFromParty:
+ call DisableSpriteUpdates
+ xor a
+ ld [wPartyMenuActionText], a
+ call ClearBGPalettes
+ call InitPartyMenuLayout
+ call WaitBGMap
+ call SetPalettes
+ call DelayFrame
+ call PartyMenuSelect
+ call ReturnToMapWithSpeechTextbox
+ ret
+
+SelectTradeOrDayCareMon:
+ ld a, b
+ ld [wPartyMenuActionText], a
+ call DisableSpriteUpdates
+ call ClearBGPalettes
+ call InitPartyMenuLayout
+ call WaitBGMap
+ ld b, SCGB_PARTY_MENU
+ call GetSGBLayout
+ call SetPalettes
+ call DelayFrame
+ call PartyMenuSelect
+ call ReturnToMapWithSpeechTextbox
+ ret
+
+InitPartyMenuLayout:
+ call LoadPartyMenuGFX
+ call InitPartyMenuWithCancel
+ call InitPartyMenuGFX
+ call WritePartyMenuTilemap
+ call PrintPartyMenuText
+ ret
+
+LoadPartyMenuGFX:
+ call LoadFontsBattleExtra
+ callfar InitPartyMenuPalettes ; engine/color.asm
+ callfar ClearSpriteAnims2
+ ret
+
+WritePartyMenuTilemap:
+ ld hl, wOptions
+ ld a, [hl]
+ push af
+ set NO_TEXT_SCROLL, [hl]
+ xor a
+ ldh [hBGMapMode], a
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, " "
+ call ByteFill ; blank the tilemap
+ call GetPartyMenuQualityIndexes
+.loop
+ ld a, [hli]
+ cp -1
+ jr z, .end
+ push hl
+ ld hl, .Jumptable
+ rst JumpTable
+ pop hl
+ jr .loop
+.end
+ pop af
+ ld [wOptions], a
+ ret
+
+.Jumptable:
+; entries correspond to PARTYMENUQUALITY_* constants
+ dw PlacePartyNicknames
+ dw PlacePartyHPBar
+ dw PlacePartyMenuHPDigits
+ dw PlacePartyMonLevel
+ dw PlacePartyMonStatus
+ dw PlacePartyMonTMHMCompatibility
+ dw PlacePartyMonEvoStoneCompatibility
+ dw PlacePartyMonGender
+
+PlacePartyNicknames:
+ hlcoord 3, 1
+ ld a, [wPartyCount]
+ and a
+ jr z, .end
+ ld c, a
+ ld b, 0
+.loop
+ push bc
+ push hl
+ push hl
+ ld hl, wPartyMonNicknames
+ ld a, b
+ call GetNick
+ pop hl
+ call PlaceString
+ pop hl
+ ld de, 2 * SCREEN_WIDTH
+ add hl, de
+ pop bc
+ inc b
+ dec c
+ jr nz, .loop
+
+.end
+ dec hl
+ dec hl
+ ld de, .CANCEL
+ call PlaceString
+ ret
+
+.CANCEL:
+ db "CANCEL@"
+
+PlacePartyHPBar:
+ xor a
+ ld [wSGBPals], a
+ ld a, [wPartyCount]
+ and a
+ ret z
+ ld c, a
+ ld b, 0
+ hlcoord 11, 2
+.loop
+ push bc
+ push hl
+ call PartyMenuCheckEgg
+ jr z, .skip
+ push hl
+ call PlacePartymonHPBar
+ pop hl
+ ld d, $6
+ ld b, $0
+ call DrawBattleHPBar
+ ld hl, wHPPals
+ ld a, [wSGBPals]
+ ld c, a
+ ld b, $0
+ add hl, bc
+ call SetHPPal
+ ld b, SCGB_PARTY_MENU_HP_PALS
+ call GetSGBLayout
+.skip
+ ld hl, wSGBPals
+ inc [hl]
+ pop hl
+ ld de, 2 * SCREEN_WIDTH
+ add hl, de
+ pop bc
+ inc b
+ dec c
+ jr nz, .loop
+ ld b, SCGB_PARTY_MENU
+ call GetSGBLayout
+ ret
+
+PlacePartymonHPBar:
+ ld a, b
+ ld bc, PARTYMON_STRUCT_LENGTH
+ ld hl, wPartyMon1HP
+ call AddNTimes
+ ld a, [hli]
+ or [hl]
+ jr nz, .not_fainted
+ xor a
+ ld e, a
+ ld c, a
+ ret
+
+.not_fainted
+ dec hl
+ ld a, [hli]
+ ld b, a
+ ld a, [hli]
+ ld c, a
+ ld a, [hli]
+ ld d, a
+ ld a, [hli]
+ ld e, a
+ predef ComputeHPBarPixels
+ ret
+
+PlacePartyMenuHPDigits:
+ ld a, [wPartyCount]
+ and a
+ ret z
+ ld c, a
+ ld b, 0
+ hlcoord 13, 1
+.loop
+ push bc
+ push hl
+ call PartyMenuCheckEgg
+ jr z, .next
+ push hl
+ ld a, b
+ ld bc, PARTYMON_STRUCT_LENGTH
+ ld hl, wPartyMon1HP
+ call AddNTimes
+ ld e, l
+ ld d, h
+ pop hl
+ push de
+ lb bc, 2, 3
+ call PrintNum
+ pop de
+ ld a, "/"
+ ld [hli], a
+ inc de
+ inc de
+ lb bc, 2, 3
+ call PrintNum
+
+.next
+ pop hl
+ ld de, 2 * SCREEN_WIDTH
+ add hl, de
+ pop bc
+ inc b
+ dec c
+ jr nz, .loop
+ ret
+
+PlacePartyMonLevel:
+ ld a, [wPartyCount]
+ and a
+ ret z
+ ld c, a
+ ld b, 0
+ hlcoord 8, 2
+.loop
+ push bc
+ push hl
+ call PartyMenuCheckEgg
+ jr z, .next
+ push hl
+ ld a, b
+ ld bc, PARTYMON_STRUCT_LENGTH
+ ld hl, wPartyMon1Level
+ call AddNTimes
+ ld e, l
+ ld d, h
+ pop hl
+ ld a, [de]
+ cp 100 ; This is distinct from MAX_LEVEL.
+ jr nc, .ThreeDigits
+ ld a, "<LV>"
+ ld [hli], a
+ lb bc, PRINTNUM_LEFTALIGN | 1, 2
+ ; jr .okay
+.ThreeDigits:
+ lb bc, PRINTNUM_LEFTALIGN | 1, 3
+; .okay
+ call PrintNum
+
+.next
+ pop hl
+ ld de, SCREEN_WIDTH * 2
+ add hl, de
+ pop bc
+ inc b
+ dec c
+ jr nz, .loop
+ ret
+
+PlacePartyMonStatus:
+ ld a, [wPartyCount]
+ and a
+ ret z
+ ld c, a
+ ld b, 0
+ hlcoord 5, 2
+.loop
+ push bc
+ push hl
+ call PartyMenuCheckEgg
+ jr z, .next
+ push hl
+ ld a, b
+ ld bc, PARTYMON_STRUCT_LENGTH
+ ld hl, wPartyMon1Status
+ call AddNTimes
+ ld e, l
+ ld d, h
+ pop hl
+ call PlaceStatusString
+
+.next
+ pop hl
+ ld de, SCREEN_WIDTH * 2
+ add hl, de
+ pop bc
+ inc b
+ dec c
+ jr nz, .loop
+ ret
+
+PlacePartyMonTMHMCompatibility:
+ ld a, [wPartyCount]
+ and a
+ ret z
+ ld c, a
+ ld b, 0
+ hlcoord 12, 2
+.loop
+ push bc
+ push hl
+ call PartyMenuCheckEgg
+ jr z, .next
+ push hl
+ ld hl, wPartySpecies
+ ld e, b
+ ld d, 0
+ add hl, de
+ ld a, [hl]
+ ld [wCurPartySpecies], a
+ predef CanLearnTMHMMove
+ pop hl
+ call .PlaceAbleNotAble
+ call PlaceString
+
+.next
+ pop hl
+ ld de, SCREEN_WIDTH * 2
+ add hl, de
+ pop bc
+ inc b
+ dec c
+ jr nz, .loop
+ ret
+
+.PlaceAbleNotAble:
+ ld a, c
+ and a
+ jr nz, .able
+ ld de, .string_not_able
+ ret
+
+.able
+ ld de, .string_able
+ ret
+
+.string_able
+ db "ABLE@"
+
+.string_not_able
+ db "NOT ABLE@"
+
+PlacePartyMonEvoStoneCompatibility:
+ ld a, [wPartyCount]
+ and a
+ ret z
+ ld c, a
+ ld b, 0
+ hlcoord 12, 2
+.loop
+ push bc
+ push hl
+ call PartyMenuCheckEgg
+ jr z, .next
+ push hl
+ ld a, b
+ ld bc, PARTYMON_STRUCT_LENGTH
+ ld hl, wPartyMon1Species
+ call AddNTimes
+ ld a, [hl]
+ dec a
+ ld e, a
+ ld d, 0
+ ld hl, EvosAttacksPointers
+ add hl, de
+ add hl, de
+ call .DetermineCompatibility
+ pop hl
+ call PlaceString
+
+.next
+ pop hl
+ ld de, 2 * SCREEN_WIDTH
+ add hl, de
+ pop bc
+ inc b
+ dec c
+ jr nz, .loop
+ ret
+
+.DetermineCompatibility:
+ ld de, wStringBuffer1
+ ld a, BANK(EvosAttacksPointers)
+ ld bc, 2
+ call FarCopyBytes
+ ld hl, wStringBuffer1
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wStringBuffer1
+ ld a, BANK("Evolutions and Attacks")
+ ld bc, 10
+ call FarCopyBytes
+ ld hl, wStringBuffer1
+.loop2
+ ld a, [hli]
+ and a
+ jr z, .nope
+ inc hl
+ inc hl
+ cp EVOLVE_ITEM
+ jr nz, .loop2
+ dec hl
+ dec hl
+ ld a, [wCurItem]
+ cp [hl]
+ inc hl
+ inc hl
+ jr nz, .loop2
+ ld de, .string_able
+ ret
+
+.nope
+ ld de, .string_not_able
+ ret
+
+.string_able
+ db "ABLE@"
+.string_not_able
+ db "NOT ABLE@"
+
+PlacePartyMonGender:
+ ld a, [wPartyCount]
+ and a
+ ret z
+ ld c, a
+ ld b, 0
+ hlcoord 12, 2
+.loop
+ push bc
+ push hl
+ call PartyMenuCheckEgg
+ jr z, .next
+ ld [wCurPartySpecies], a
+ push hl
+ ld a, b
+ ld [wCurPartyMon], a
+ xor a
+ ld [wMonType], a
+ call GetGender
+ ld de, .unknown
+ jr c, .got_gender
+ ld de, .male
+ jr nz, .got_gender
+ ld de, .female
+
+.got_gender
+ pop hl
+ call PlaceString
+
+.next
+ pop hl
+ ld de, 2 * SCREEN_WIDTH
+ add hl, de
+ pop bc
+ inc b
+ dec c
+ jr nz, .loop
+ ret
+
+.male
+ db "♂…MALE@"
+
+.female
+ db "♀…FEMALE@"
+
+.unknown
+ db "…UNKNOWN@"
+
+PartyMenuCheckEgg:
+ ld a, LOW(wPartySpecies)
+ add b
+ ld e, a
+ ld a, HIGH(wPartySpecies)
+ adc 0
+ ld d, a
+ ld a, [de]
+ cp EGG
+ ret
+
+GetPartyMenuQualityIndexes:
+ ld a, [wPartyMenuActionText]
+ and $f0
+ jr nz, .skip
+ ld a, [wPartyMenuActionText]
+ and $f
+ ld e, a
+ ld d, 0
+ ld hl, PartyMenuQualityPointers
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ret
+
+.skip
+ ld hl, PartyMenuQualityPointers.Default
+ ret
+
+INCLUDE "data/party_menu_qualities.asm"
+
+InitPartyMenuGFX:
+ ld hl, wPartyCount
+ ld a, [hli]
+ and a
+ ret z
+ ld c, a
+ xor a
+ ldh [hObjectStructIndexBuffer], a
+.loop
+ push bc
+ push hl
+ ld hl, LoadMenuMonIcon
+ ld a, BANK(LoadMenuMonIcon)
+ ld e, MONICON_PARTYMENU
+ rst FarCall
+ ldh a, [hObjectStructIndexBuffer]
+ inc a
+ ldh [hObjectStructIndexBuffer], a
+ pop hl
+ pop bc
+ dec c
+ jr nz, .loop
+ callfar PlaySpriteAnimations
+ ret
+
+InitPartyMenuWithCancel:
+; with cancel
+ xor a
+ ld [wSwitchMon], a
+ ld de, PartyMenuAttributes
+ call SetMenuAttributes
+ ld a, [wPartyCount]
+ inc a
+ ld [w2DMenuNumRows], a ; list length
+ dec a
+ ld b, a
+ ld a, [wPartyMenuCursor]
+ and a
+ jr z, .skip
+ inc b
+ cp b
+ jr c, .done
+
+.skip
+ ld a, 1
+
+.done
+ ld [wMenuCursorY], a
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuJoypadFilter], a
+ ret
+
+InitPartyMenuNoCancel:
+; no cancel
+ ld de, PartyMenuAttributes
+ call SetMenuAttributes
+ ld a, [wPartyCount]
+ ld [w2DMenuNumRows], a ; list length
+ ld b, a
+ ld a, [wPartyMenuCursor]
+ and a
+ jr z, .skip
+ inc b
+ cp b
+ jr c, .done
+.skip
+ ld a, 1
+.done
+ ld [wMenuCursorY], a
+ ld a, A_BUTTON | B_BUTTON
+ ld [wMenuJoypadFilter], a
+ ret
+
+PartyMenuAttributes:
+; cursor y
+; cursor x
+; num rows
+; num cols
+; bit 6: animate sprites bit 5: wrap around
+; ?
+; distance between items (hi: y, lo: x)
+; allowed buttons (mask)
+ db 1, 0
+ db 0, 1
+ db $60, $00
+ dn 2, 0
+ db 0
+
+PartyMenuSelect:
+; sets carry if exitted menu.
+ call StaticMenuJoypad
+ call PlaceHollowCursor
+ ld a, [wPartyCount]
+ inc a
+ ld b, a
+ ld a, [wMenuCursorY] ; menu selection?
+ cp b
+ jr z, .exitmenu ; CANCEL
+ ld [wPartyMenuCursor], a
+ ldh a, [hJoyLast]
+ ld b, a
+ bit B_BUTTON_F, b
+ jr nz, .exitmenu ; B button
+ ld a, [wMenuCursorY]
+ dec a
+ ld [wCurPartyMon], a
+ ld c, a
+ ld b, $0
+ ld hl, wPartySpecies
+ add hl, bc
+ ld a, [hl]
+ ld [wCurPartySpecies], a
+
+ ld de, SFX_READ_TEXT_2
+ call PlaySFX
+ call WaitSFX
+ and a
+ ret
+
+.exitmenu
+ ld de, SFX_READ_TEXT_2
+ call PlaySFX
+ call WaitSFX
+ scf
+ ret
+
+PrintPartyMenuText:
+ hlcoord 0, 14
+ lb bc, 2, 18
+ call Textbox
+ ld a, [wPartyCount]
+ and a
+ jr nz, .haspokemon
+ ld de, YouHaveNoPKMNString
+ jr .gotstring
+.haspokemon
+ ld a, [wPartyMenuActionText]
+ and $f ; drop high nibble
+ ld hl, PartyMenuStrings
+ ld e, a
+ ld d, $0
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld d, [hl]
+ ld e, a
+.gotstring
+ ld a, [wOptions]
+ push af
+ set NO_TEXT_SCROLL, a
+ ld [wOptions], a
+ hlcoord 1, 16 ; Coord
+ call PlaceString
+ pop af
+ ld [wOptions], a
+ ret
+
+PartyMenuStrings:
+ dw ChooseAMonString
+ dw UseOnWhichPKMNString
+ dw WhichPKMNString
+ dw TeachWhichPKMNString
+ dw MoveToWhereString
+ dw UseOnWhichPKMNString
+ dw ChooseAMonString ; Probably used to be ChooseAFemalePKMNString
+ dw ChooseAMonString ; Probably used to be ChooseAMalePKMNString
+ dw ToWhichPKMNString
+
+ChooseAMonString:
+ db "Choose a #MON.@"
+
+UseOnWhichPKMNString:
+ db "Use on which <PK><MN>?@"
+
+WhichPKMNString:
+ db "Which <PK><MN>?@"
+
+TeachWhichPKMNString:
+ db "Teach which <PK><MN>?@"
+
+MoveToWhereString:
+ db "Move to where?@"
+
+ChooseAFemalePKMNString:
+; unused
+ db "Choose a ♀<PK><MN>.@"
+
+ChooseAMalePKMNString:
+; unused
+ db "Choose a ♂<PK><MN>.@"
+
+ToWhichPKMNString:
+ db "To which <PK><MN>?@"
+
+YouHaveNoPKMNString:
+ db "You have no <PK><MN>!@"
+
+PrintPartyMenuActionText:
+ ld a, [wCurPartyMon]
+ ld hl, wPartyMonNicknames
+ call GetNick
+ ld a, [wPartyMenuActionText]
+ and $f
+ ld hl, .MenuActionTexts
+ call .PrintText
+ ret
+
+.MenuActionTexts:
+; entries correspond to PARTYMENUTEXT_* constants
+ dw .CuredOfPoisonText
+ dw .BurnWasHealedText
+ dw .WasDefrostedText
+ dw .WokeUpText
+ dw .RidOfParalysisText
+ dw .RecoveredSomeHPText
+ dw .HealthReturnedText
+ dw .RevitalizedText
+ dw .GrewToLevelText
+ dw .CameToItsSensesText
+
+.RecoveredSomeHPText:
+ text_far _RecoveredSomeHPText
+ text_end
+
+.CuredOfPoisonText:
+ text_far _CuredOfPoisonText
+ text_end
+
+.RidOfParalysisText:
+ text_far _RidOfParalysisText
+ text_end
+
+.BurnWasHealedText:
+ text_far _BurnWasHealedText
+ text_end
+
+.WasDefrostedText:
+ text_far _WasDefrostedText
+ text_end
+
+.WokeUpText:
+ text_far _WokeUpText
+ text_end
+
+.HealthReturnedText:
+ text_far _HealthReturnedText
+ text_end
+
+.RevitalizedText:
+ text_far _RevitalizedText
+ text_end
+
+.GrewToLevelText:
+ text_far _GrewToLevelText
+ text_end
+
+.CameToItsSensesText:
+ text_far _CameToItsSensesText
+ text_end
+
+.PrintText:
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wOptions]
+ push af
+ set NO_TEXT_SCROLL, a
+ ld [wOptions], a
+ call PrintText
+ pop af
+ ld [wOptions], a
+ ret
diff --git a/engine/pokemon/stats_screen.asm b/engine/pokemon/stats_screen.asm
new file mode 100644
index 00000000..a2345f37
--- /dev/null
+++ b/engine/pokemon/stats_screen.asm
@@ -0,0 +1,868 @@
+ const_def 1
+ const PINK_PAGE ; 1
+ const GREEN_PAGE ; 2
+ const BLUE_PAGE ; 3
+
+StatsScreenInit:
+ ldh a, [hMapAnims]
+ push af
+ xor a
+ ldh [hMapAnims], a ; disable overworld tile animations
+
+ ld c, 1
+ call StatsScreenMain
+
+ ; restore old values
+ pop af
+ ldh [hMapAnims], a
+ ret
+
+StatsScreenMain:
+ push bc
+ ld a, [wMonType]
+ cp TEMPMON
+ jr nz, .not_tempmon
+ ld a, [wBufferMonSpecies]
+ ld [wCurSpecies], a
+ call GetBaseData
+ ld hl, wBufferMon
+ ld de, wTempMon
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call CopyBytes
+ jr .got_stats
+
+.not_tempmon
+ call CopyMonToTempMon
+ ld a, [wCurPartySpecies]
+ cp EGG
+ jp z, .got_stats
+ ld a, [wMonType]
+ cp BOXMON
+ jr c, .got_stats
+ call CalcTempmonStats
+
+.got_stats
+ call ClearBGPalettes
+ call ClearTilemap
+ call UpdateSprites
+ callfar StatsScreen_LoadFont
+
+ pop bc
+ ld a, [wCurPartySpecies]
+ cp EGG
+ jp z, EggStatsInit
+ call StatsScreen_InitUpperHalf
+ ld b, 0
+ jp StatsScreen_JumpToLoadPageFunction
+
+StatsScreen_LoadPage:
+ push bc
+ ld de, .done_loading
+ push de
+; first jump to LoadPage function in jumptable
+ jp hl
+
+; return here after LoadPage function finishes
+.done_loading
+ pop bc
+ ld b, 1
+
+.joypad_loop
+ call GetJoypad
+ ld a, [wMonType]
+ cp TEMPMON
+ jr nz, .not_tempmon
+ push hl
+ push de
+ push bc
+ farcall StatsScreenDPad
+ pop bc
+ pop de
+ pop hl
+ ld a, [wMenuJoypad]
+ and D_DOWN | D_UP
+ jr nz, StatsScreenMain
+ ld a, [wMenuJoypad]
+ jr .joypad_action
+
+.not_tempmon
+ ldh a, [hJoyPressed]
+
+.joypad_action
+ and D_DOWN | D_UP | D_LEFT | D_RIGHT | A_BUTTON | B_BUTTON
+ jr z, .joypad_loop
+ bit B_BUTTON_F, a
+ jp nz, StatsScreen_Exit
+ bit D_LEFT_F, a
+ jr nz, .d_left
+ bit D_RIGHT_F, a
+ jr nz, .d_right
+ bit A_BUTTON_F, a
+ jr nz, .a_button
+ bit D_UP_F, a
+ jr nz, .d_up
+
+; .d_down
+ ld a, [wMonType]
+ cp BOXMON
+ jr nc, .joypad_loop
+ and a
+ ld a, [wPartyCount]
+ jr z, .next_mon
+ ld a, [wOTPartyCount]
+.next_mon
+ ld b, a
+ ld a, [wCurPartyMon]
+ inc a
+ cp b
+ jr z, .joypad_loop
+ ld [wCurPartyMon], a
+ ld b, a
+ ld a, [wMonType]
+ and a
+ jr nz, .load_mon
+ ld a, b
+ inc a
+ ld [wPartyMenuCursor], a
+ jr .load_mon
+
+.d_up
+ ld a, [wCurPartyMon]
+ and a
+ jr z, .joypad_loop
+ dec a
+ ld [wCurPartyMon], a
+ ld b, a
+ ld a, [wMonType]
+ and a
+ jr nz, .load_mon
+ ld a, b
+ inc a
+ ld [wPartyMenuCursor], a
+; fall through
+.load_mon
+ jp StatsScreenMain
+
+.a_button
+ ld a, c
+ cp BLUE_PAGE ; last page
+ jr z, StatsScreen_Exit
+
+.d_right
+ inc c
+ ld a, BLUE_PAGE ; last page
+ cp c
+ jr nc, StatsScreen_JumpToLoadPageFunction
+ ld c, PINK_PAGE ; first page
+ jr StatsScreen_JumpToLoadPageFunction
+
+.d_left
+ dec c
+ jr nz, StatsScreen_JumpToLoadPageFunction
+ ld c, BLUE_PAGE ; last page
+; fall through
+
+StatsScreen_JumpToLoadPageFunction:
+ ld hl, StatsScreen_LoadPageJumptable
+ push bc
+ dec c
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ pop bc
+ jp StatsScreen_LoadPage
+
+EggStatsInit:
+ push bc
+ call EggStatsScreen
+ pop bc
+; fall through
+
+EggStats_JoypadLoop:
+ call GetJoypad
+ ld a, [wMonType]
+ cp TEMPMON
+ jr nz, .not_tempmon
+; .tempmon
+ push hl
+ push de
+ push bc
+ farcall StatsScreenDPad
+ pop bc
+ pop de
+ pop hl
+ ld a, [wMenuJoypad]
+ and D_DOWN | D_UP
+ jp nz, StatsScreenMain
+ ld a, [wMenuJoypad]
+ jr .joypad_action
+
+.not_tempmon
+ ldh a, [hJoyPressed]
+.joypad_action
+ and D_DOWN | D_UP | A_BUTTON | B_BUTTON
+ jr z, EggStats_JoypadLoop
+ bit A_BUTTON_F, a
+ jr nz, StatsScreen_Exit
+ bit B_BUTTON_F, a
+ jr nz, StatsScreen_Exit
+ bit D_UP_F, a
+ jr nz, EggStats_UpAction
+ bit D_DOWN_F, a
+ jp EggStats_DownAction
+
+StatsScreen_Exit:
+ call ClearBGPalettes
+ call ClearTilemap
+ ret
+
+EggStats_DownAction:
+ ld a, [wMonType]
+ cp BOXMON
+ jr nc, EggStats_JoypadLoop
+ and a
+ ld a, [wPartyCount]
+ jr z, .next_mon
+ ld a, [wOTPartyCount]
+.next_mon
+ ld b, a
+ ld a, [wCurPartyMon]
+ inc a
+ cp b
+ jr z, EggStats_JoypadLoop
+ ld [wCurPartyMon], a
+ ld b, a
+ ld a, [wMonType]
+ and a
+ jr nz, EggStats_ScrollToLoadMon
+ ld a, b
+ inc a
+ ld [wPartyMenuCursor], a
+ jr EggStats_ScrollToLoadMon
+
+EggStats_UpAction:
+ ld a, [wCurPartyMon]
+ and a
+ jr z, EggStats_JoypadLoop
+ dec a
+ ld [wCurPartyMon], a
+ ld b, a
+ ld a, [wMonType]
+ and a
+ jr nz, EggStats_ScrollToLoadMon
+ ld a, b
+ inc a
+ ld [wPartyMenuCursor], a
+; fall through
+
+EggStats_ScrollToLoadMon:
+ jp StatsScreenMain
+
+StatsScreen_LoadPageJumptable:
+; entries correspond to *_PAGE constants
+ dw LoadPinkPage
+ dw LoadGreenPage
+ dw LoadBluePage
+
+StatsScreen_InitUpperHalf:
+ push bc
+ xor a
+ ldh [hBGMapMode], a
+ ld a, [wBaseDexNo]
+ ld [wDeciramBuffer], a
+ ld [wCurSpecies], a
+ hlcoord 8, 0
+ ld [hl], "№"
+ inc hl
+ ld [hl], "."
+ inc hl
+ ld de, wDeciramBuffer
+ lb bc, PRINTNUM_LEADINGZEROS | 1, 3
+ call PrintNum
+ hlcoord 14, 0
+ call PrintLevel
+ ld hl, .NicknamePointers
+ call GetNicknamePointer
+; Nickname
+ ld a, [wMonType]
+ cp BOXMON
+ ld a, BANK(sBoxMonNicknames)
+ call z, OpenSRAM
+ ld d, h
+ ld e, l
+ hlcoord 8, 2
+ call PlaceString
+ ld a, [wMonType]
+ cp BOXMON
+ call z, CloseSRAM
+; Gender character
+ call GetGender
+ jr c, .next
+ ld a, "♂"
+ jr nz, .got_gender
+ ld a, "♀"
+.got_gender
+ hlcoord 18, 0
+ ld [hl], a
+.next
+ hlcoord 9, 4
+ ld a, "/"
+ ld [hli], a
+ ld a, [wBaseDexNo]
+ ld [wNamedObjectIndexBuffer], a
+ call GetPokemonName
+ call PlaceString
+ call StatsScreen_PlaceHorizontalDivider
+ call StatsScreen_PlacePageSwitchArrows
+ call StatsScreen_PlaceShinyIcon
+; Place HP bar
+ ld hl, wTempMonHP
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ ld hl, wTempMonMaxHP
+ ld a, [hli]
+ ld d, a
+ ld e, [hl]
+ callfar ComputeHPBarPixels
+ ld hl, wCurHPPal
+ call SetHPPal
+ ld b, SCGB_STATS_SCREEN_HP_PALS
+ call GetSGBLayout
+ pop bc
+ ret
+
+.NicknamePointers:
+ dw wPartyMonNicknames
+ dw wOTPartyMonNicknames
+ dw sBoxMonNicknames
+ dw wBufferMonNick
+
+LoadPinkPage:
+ push bc
+ push bc
+ xor a
+ ldh [hBGMapMode], a
+ ld a, [wBaseDexNo]
+ ld [wDeciramBuffer], a
+ ld [wCurSpecies], a
+ ld b, PINK_PAGE
+ call StatsScreen_LoadPageIndicators
+
+; Load graphics
+ hlcoord 0, 8
+ lb bc, 10, 20
+ call ClearBox
+ hlcoord 0, 9
+ ld b, 0
+ call DrawPlayerHP
+ hlcoord 8, 9
+ ld [hl], $41 ; right HP/exp bar end cap
+ hlcoord 0, 12
+ ld de, .Status_Type
+ call PlaceString
+ ld a, [wTempMonPokerusStatus]
+ ld b, a
+ and $f
+ jr nz, .HasPokerus
+ ld a, b
+ and $f0
+ jr z, .NotImmuneToPkrs
+ hlcoord 8, 8
+ ld [hl], "." ; Pokérus immunity dot
+.NotImmuneToPkrs:
+ ld a, [wMonType]
+ cp BOXMON
+ jr z, .StatusOK
+ hlcoord 6, 13
+ push hl
+ ld de, wTempMonStatus
+ call PlaceStatusString
+ pop hl
+ jr .StatusOK
+.HasPokerus:
+ ld de, .PkrsStr
+ hlcoord 1, 13
+ call PlaceString
+ jr .done_status
+.StatusOK:
+ ld de, .OK_str
+ call z, PlaceString
+.done_status
+ hlcoord 1, 15
+ call PrintMonTypes
+ ld bc, 9
+ decoord 0, 16
+ hlcoord 0, 17
+ call CopyBytes
+ ld a, " "
+ ld bc, 9
+ hlcoord 0, 17
+ call ByteFill
+ hlcoord 9, 8
+ ld de, SCREEN_WIDTH
+ ld b, 10
+ ld a, $31 ; vertical divider
+.vertical_divider
+ ld [hl], a
+ add hl, de
+ dec b
+ jr nz, .vertical_divider
+ hlcoord 10, 9
+ ld de, .ExpPointStr
+ call PlaceString
+; print next level
+ ld a, [wTempMonLevel]
+ push af
+ cp MAX_LEVEL
+ jr z, .got_level
+ inc a
+ ld [wTempMonLevel], a
+.got_level
+ hlcoord 17, 14
+ call PrintLevel
+ pop af
+ ld [wTempMonLevel], a
+ ld de, wTempMonExp
+ hlcoord 13, 10
+ lb bc, 3, 7
+ call PrintNum
+; level-up graphics and strings
+ call .CalcExpToNextLevel
+ ld de, wBuffer1
+ hlcoord 13, 13
+ lb bc, 3, 7
+ call PrintNum
+ hlcoord 10, 12
+ ld de, .LevelUpStr
+ call PlaceString
+ hlcoord 14, 14
+ ld de, .ToStr
+ call PlaceString
+ ld a, [wTempMonLevel]
+ ld b, a
+ ld de, wTempMonExp + 2
+ hlcoord 11, 16
+ predef FillInExpBar
+ hlcoord 10, 16
+ ld [hl], $40 ; left exp bar end cap
+ hlcoord 19, 16
+ ld [hl], $41 ; right exp bar end cap
+
+; Load palettes / place frontpic
+ pop bc
+ farcall LoadStatsScreenPals
+ call WaitBGMap
+ ld a, 1
+ ldh [hBGMapMode], a
+ pop bc
+ ld a, b
+ and a
+ jp z, StatsScreen_PlaceFrontpic
+ ret
+
+.CalcExpToNextLevel:
+ ld a, [wTempMonLevel]
+ cp MAX_LEVEL
+ jr z, .AlreadyAtMaxLevel
+ inc a
+ ld d, a
+ call CalcExpAtLevel
+ ld hl, wTempMonExp + 2
+ ld hl, wTempMonExp + 2
+ ldh a, [hQuotient + 3]
+ sub [hl]
+ dec hl
+ ld [wBuffer3], a
+ ldh a, [hQuotient + 2]
+ sbc [hl]
+ dec hl
+ ld [wBuffer2], a
+ ldh a, [hQuotient + 1]
+ sbc [hl]
+ ld [wBuffer1], a
+ ret
+
+.AlreadyAtMaxLevel:
+ ld hl, wBuffer1
+ xor a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ret
+
+.Status_Type:
+ db "STATUS/"
+ next "TYPE/@"
+
+.OK_str:
+ db "OK @"
+
+.ExpPointStr:
+ db "EXP POINTS@"
+
+.LevelUpStr:
+ db "LEVEL UP@"
+
+.ToStr:
+ db "TO@"
+
+.PkrsStr:
+ db "#RUS@"
+
+Unreferenced_Function50f4d:
+ hlcoord 7, 0
+ ld bc, SCREEN_WIDTH
+ ld d, SCREEN_HEIGHT
+.loop
+ ld a, $31 ; vertical divider
+ ld [hl], a
+ add hl, bc
+ dec d
+ jr nz, .loop
+ ret
+
+StatsScreen_PlaceHorizontalDivider:
+ hlcoord 0, 7
+ ld b, SCREEN_WIDTH
+ ld a, $62 ; horizontal divider (empty HP/exp bar)
+.loop
+ ld [hli], a
+ dec b
+ jr nz, .loop
+ ret
+
+StatsScreen_PlacePageSwitchArrows:
+ hlcoord 12, 6
+ ld [hl], "◀"
+ hlcoord 19, 6
+ ld [hl], "▶"
+ ret
+
+StatsScreen_PlaceShinyIcon:
+ ld bc, wTempMonDVs
+ callfar CheckShininess
+ ret nc
+ hlcoord 19, 0
+ ld [hl], "⁂"
+ ret
+
+LoadGreenPage:
+ push bc
+ push bc
+ xor a
+ ldh [hBGMapMode], a
+ ld b, GREEN_PAGE
+ call StatsScreen_LoadPageIndicators
+
+; Load graphics
+ hlcoord 0, 8
+ lb bc, 10, 20
+ call ClearBox
+; item info
+ hlcoord 0, 8
+ ld de, .Item
+ call PlaceString
+ ld a, [wTempMonItem]
+ and a
+ ld de, .ThreeDashes
+ jr z, .got_item_name
+ ld b, a
+ farcall TimeCapsule_ReplaceTeruSama
+ ld a, b
+ ld [wNamedObjectIndexBuffer], a
+ call GetItemName
+.got_item_name
+ hlcoord 6, 8
+ call PlaceString
+; move info
+ ld hl, wTempMonMoves
+ ld de, wListMoves_MoveIndicesBuffer
+ ld bc, NUM_MOVES
+ call CopyBytes
+ hlcoord 0, 10
+ ld de, .Move
+ call PlaceString
+ hlcoord 8, 10
+ ld a, SCREEN_WIDTH * 2
+ ld [wBuffer1], a
+ call ListMoves
+ hlcoord 12, 11
+ ld a, SCREEN_WIDTH * 2
+ ld [wBuffer1], a
+ call ListMovePP
+
+; Load palettes / place frontpic
+ pop bc
+ farcall LoadStatsScreenPals
+ call WaitBGMap
+ ld a, 1
+ ldh [hBGMapMode], a
+ pop bc
+ ld a, b
+ and a
+ jp z, StatsScreen_PlaceFrontpic
+ ret
+
+.Item:
+ db "ITEM@"
+
+.ThreeDashes:
+ db "---@"
+
+.Move:
+ db "MOVE@"
+
+LoadBluePage:
+ push bc
+ push bc
+ xor a
+ ldh [hBGMapMode], a
+ ld b, BLUE_PAGE
+ call StatsScreen_LoadPageIndicators
+
+; Load graphics
+ hlcoord 0, 8
+ lb bc, 10, 20
+ call ClearBox
+ call .PlaceOTInfo
+ hlcoord 10, 8
+ ld de, SCREEN_WIDTH
+ ld b, 10
+ ld a, $31 ; vertical divider
+.vertical_divider
+ ld [hl], a
+ add hl, de
+ dec b
+ jr nz, .vertical_divider
+ hlcoord 11, 8
+ ld bc, 6
+ call PrintTempMonStats
+
+; Load palettes / place frontpic
+ pop bc
+ farcall LoadStatsScreenPals
+ call WaitBGMap
+ ld a, 1
+ ldh [hBGMapMode], a
+ pop bc
+ ld a, b
+ and a
+ jp z, StatsScreen_PlaceFrontpic
+ ret
+
+.PlaceOTInfo:
+ hlcoord 0, 9
+ ld de, IDNoString
+ call PlaceString
+ hlcoord 0, 12
+ ld de, OTString
+ call PlaceString
+ hlcoord 2, 10
+ ld de, wTempMonID
+ lb bc, PRINTNUM_LEADINGZEROS | 2, 5
+ call PrintNum
+ ld hl, .OTNamePointers
+ call GetNicknamePointer
+; OT name
+ ld a, [wMonType]
+ cp BOXMON
+ ld a, BANK(sBoxMonOT)
+ call z, OpenSRAM
+ ld de, wStringBuffer1
+ push de
+ ld bc, NAME_LENGTH
+ call CopyBytes
+ pop de
+ ld a, [wMonType]
+ cp BOXMON
+ call z, CloseSRAM
+ callfar CorrectNickErrors
+ push de
+
+; Adjust coordinate of OT name based on index of nickname terminator
+ lb bc, 0, -1
+.loop
+ inc c
+ ld a, [de]
+ inc de
+ cp "@"
+ jr nz, .loop
+; remove left padding if name was 8-10 chars (somehow?)
+ ld a, NAME_LENGTH - 1
+ sub c
+ cp 3 ; NAME_LENGTH - PLAYER_NAME_LENGTH
+; otherwise, use 2 spaces of left padding
+ jr c, .ok
+ ld a, 2 ; NAME_LENGTH - PLAYER_NAME_LENGTH - 1
+.ok
+ ld c, a
+ hlcoord 0, 13
+ add hl, bc
+; that's finally over ... place string, quit forever
+ pop de
+ call PlaceString
+ ret
+
+.OTNamePointers:
+ dw wPartyMonOT
+ dw wOTPartyMonOT
+ dw sBoxMonOT
+ dw wBufferMonOT
+
+IDNoString:
+ db "<ID>№.@"
+
+OTString:
+ db "OT/@"
+
+StatsScreen_PlaceFrontpic:
+ push bc
+ call SetPalettes
+ ld hl, wTempMonDVs
+ call GetUnownLetter
+ hlcoord 0, 0
+ ld a, [wCurPartySpecies]
+ cp UNOWN
+ jr z, .unown
+
+ call PrepMonFrontpic
+ jr .play_cry
+
+.unown
+ xor a
+ ld [wBoxAlignment], a
+ call _PrepMonFrontpic
+
+.play_cry
+ ld a, [wCurPartySpecies]
+ call PlayMonCry
+ pop bc
+ ld b, 1
+ ret
+
+EggStatsScreen:
+ ld hl, wCurHPPal
+ call SetHPPal
+ ld b, SCGB_STATS_SCREEN_HP_PALS
+ call GetSGBLayout
+ call StatsScreen_PlaceHorizontalDivider
+ hlcoord 8, 1
+ ld de, EggString
+ call PlaceString
+ hlcoord 8, 3
+ ld de, IDNoString
+ call PlaceString
+ hlcoord 8, 5
+ ld de, OTString
+ call PlaceString
+ hlcoord 11, 3
+ ld de, FiveQMarkString
+ call PlaceString
+ hlcoord 11, 5
+ ld de, FiveQMarkString
+ call PlaceString
+ ld a, [wTempMonHappiness] ; egg status
+ ld de, EggSoonString
+ cp $6
+ jr c, .picked
+ ld de, EggCloseString
+ cp $b
+ jr c, .picked
+ ld de, EggMoreTimeString
+ cp $29
+ jr c, .picked
+ ld de, EggALotMoreTimeString
+.picked
+ hlcoord 1, 9
+ call PlaceString
+ call WaitBGMap
+ ld a, 1
+ ldh [hBGMapMode], a
+ call SetPalettes ; pals
+ hlcoord 0, 0
+ call PrepMonFrontpic
+ ld a, [wTempMonHappiness]
+ cp 6
+ ret nc
+ ld de, SFX_2_BOOPS
+ call PlaySFX
+ call WaitSFX
+ ret
+
+EggString:
+ db "EGG@"
+
+FiveQMarkString:
+ db "?????@"
+
+EggSoonString:
+ db "It's making sounds"
+ next "inside. It's going"
+ next "to hatch soon!@"
+
+EggCloseString:
+ db "It moves around"
+ next "inside sometimes."
+ next "It must be close"
+ next "to hatching.@"
+
+EggMoreTimeString:
+ db "Wonder what's"
+ next "inside? It needs"
+ next "more time, though.@"
+
+EggALotMoreTimeString:
+ db "This EGG needs a"
+ next "lot more time to"
+ next "hatch.@"
+
+StatsScreen_LoadPageIndicators:
+ hlcoord 13, 5
+ ld a, $36 ; first of 4 small square tiles
+ call .load_square
+ hlcoord 15, 5
+ ld a, $36 ; " " " "
+ call .load_square
+ hlcoord 17, 5
+ ld a, $36 ; " " " "
+ call .load_square
+ ld a, b
+ cp GREEN_PAGE
+ ld a, $3a ; first of 4 large square tiles
+ hlcoord 13, 5 ; PINK_PAGE (< GREEN_PAGE)
+ jr c, .load_square
+ hlcoord 15, 5 ; GREEN_PAGE (= GREEN_PAGE)
+ jr z, .load_square
+ hlcoord 17, 5 ; BLUE_PAGE (> GREEN_PAGE)
+.load_square
+ ld [hli], a
+ inc a
+ ld [hld], a
+ push bc
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ pop bc
+ inc a
+ ld [hli], a
+ inc a
+ ld [hl], a
+ ret
+
+GetNicknamePointer:
+ ld a, [wMonType]
+ add a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wMonType]
+ cp TEMPMON
+ ret z
+ ld a, [wCurPartyMon]
+ jp SkipNames
diff --git a/engine/pokemon/switchpartymons.asm b/engine/pokemon/switchpartymons.asm
new file mode 100755
index 00000000..24d19df6
--- /dev/null
+++ b/engine/pokemon/switchpartymons.asm
@@ -0,0 +1,145 @@
+_SwitchPartyMons:
+ ld a, [wSwitchMon]
+ dec a
+ ld [wBuffer3], a
+ ld b, a
+ ld a, [wMenuCursorY]
+ dec a
+ ld [wBuffer2], a
+ cp b
+ jr z, .skip
+ call .SwapMonAndMail
+ ld a, [wBuffer3]
+ call .ClearSprite
+ ld a, [wBuffer2]
+ call .ClearSprite
+.skip
+ ret
+
+.ClearSprite:
+ push af
+ hlcoord 0, 1
+ ld bc, 2 * SCREEN_WIDTH
+ call AddNTimes
+ ld bc, 2 * SCREEN_WIDTH
+ ld a, " "
+ call ByteFill
+ pop af
+ ld hl, wVirtualOAMSprite00
+ ld bc, 4 * SPRITEOAMSTRUCT_LENGTH
+ call AddNTimes
+ ld de, SPRITEOAMSTRUCT_LENGTH
+ ld c, 4
+.gfx_loop
+ ld [hl], SCREEN_WIDTH_PX ; y (off-screen)
+ add hl, de
+ dec c
+ jr nz, .gfx_loop
+ ld de, SFX_SWITCH_POKEMON
+ call WaitPlaySFX
+ ret
+
+.SwapMonAndMail:
+ push hl
+ push de
+ push bc
+ ld bc, wPartySpecies
+ ld a, [wBuffer2]
+ ld l, a
+ ld h, $0
+ add hl, bc
+ ld d, h
+ ld e, l
+ ld a, [wBuffer3]
+ ld l, a
+ ld h, $0
+ add hl, bc
+ ld a, [hl]
+ push af
+ ld a, [de]
+ ld [hl], a
+ pop af
+ ld [de], a
+ ld a, [wBuffer2]
+ ld hl, wPartyMon1Species
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+ push hl
+ ld de, wceed
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call CopyBytes
+ ld a, [wBuffer3]
+ ld hl, wPartyMon1
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+ pop de
+ push hl
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call CopyBytes
+ pop de
+ ld hl, wceed
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call CopyBytes
+ ld a, [wBuffer2]
+ ld hl, wPartyMonOT
+ call SkipNames
+ push hl
+ call .CopyNameTowceed
+ ld a, [wBuffer3]
+ ld hl, wPartyMonOT
+ call SkipNames
+ pop de
+ push hl
+ call .CopyName
+ pop de
+ ld hl, wceed
+ call .CopyName
+ ld hl, wPartyMonNicknames
+ ld a, [wBuffer2]
+ call SkipNames
+ push hl
+ call .CopyNameTowceed
+ ld hl, wPartyMonNicknames
+ ld a, [wBuffer3]
+ call SkipNames
+ pop de
+ push hl
+ call .CopyName
+ pop de
+ ld hl, wceed
+ call .CopyName
+ ld hl, sPartyMail
+ ld a, [wBuffer2]
+ ld bc, MAIL_STRUCT_LENGTH
+ call AddNTimes
+ push hl
+ ld de, wceed
+ ld bc, MAIL_STRUCT_LENGTH
+ ld a, BANK(sPartyMail)
+ call OpenSRAM
+ call CopyBytes
+ ld hl, sPartyMail
+ ld a, [wBuffer3]
+ ld bc, MAIL_STRUCT_LENGTH
+ call AddNTimes
+ pop de
+ push hl
+ ld bc, MAIL_STRUCT_LENGTH
+ call CopyBytes
+ pop de
+ ld hl, wceed
+ ld bc, MAIL_STRUCT_LENGTH
+ call CopyBytes
+ call CloseSRAM
+ pop bc
+ pop de
+ pop hl
+ ret
+
+.CopyNameTowceed:
+ ld de, wceed
+
+.CopyName:
+ ld bc, NAME_LENGTH
+ call CopyBytes
+ ret
diff --git a/engine/pokemon/tempmon.asm b/engine/pokemon/tempmon.asm
new file mode 100755
index 00000000..97ce1ee7
--- /dev/null
+++ b/engine/pokemon/tempmon.asm
@@ -0,0 +1,127 @@
+CopyMonToTempMon:
+; gets the BaseData of a mon
+; and copies the party_struct to wTempMon
+
+ ld a, [wCurPartyMon]
+ ld e, a
+ call GetMonSpecies
+ ld a, [wCurPartySpecies]
+ ld [wCurSpecies], a
+ call GetBaseData
+
+ ld a, [wMonType]
+ ld hl, wPartyMon1Species
+ ld bc, PARTYMON_STRUCT_LENGTH
+ and a
+ jr z, .copywholestruct
+ ld hl, wOTPartyMon1Species
+ ld bc, PARTYMON_STRUCT_LENGTH
+ cp OTPARTYMON
+ jr z, .copywholestruct
+ ld bc, BOXMON_STRUCT_LENGTH
+ callfar CopyBoxmonToTempMon
+ jr .done
+
+.copywholestruct
+ ld a, [wCurPartyMon]
+ call AddNTimes
+ ld de, wTempMon
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call CopyBytes
+
+.done
+ ret
+
+CalcBufferMonStats:
+ ld bc, wBufferMon
+ jr _TempMonStatsCalculation
+
+CalcTempmonStats:
+ ld bc, wTempMon
+_TempMonStatsCalculation:
+ ld hl, MON_LEVEL
+ add hl, bc
+ ld a, [hl]
+ ld [wCurPartyLevel], a
+ ld hl, MON_MAXHP
+ add hl, bc
+ ld d, h
+ ld e, l
+ ld hl, MON_STAT_EXP - 1
+ add hl, bc
+ push bc
+ ld b, TRUE
+ predef CalcMonStats
+ pop bc
+ ld hl, MON_HP
+ add hl, bc
+ ld d, h
+ ld e, l
+ ld a, [wCurPartySpecies]
+ cp EGG
+ jr nz, .not_egg
+ xor a
+ ld [de], a
+ inc de
+ ld [de], a
+ jr .zero_status
+
+.not_egg
+ push bc
+ ld hl, MON_MAXHP
+ add hl, bc
+ ld bc, 2
+ call CopyBytes
+ pop bc
+
+.zero_status
+ ld hl, MON_STATUS
+ add hl, bc
+ xor a
+ ld [hli], a
+ ld [hl], a
+ ret
+
+GetMonSpecies:
+; [wMonType] has the type of the mon
+; e = Nr. of mon (i.e. [wCurPartyMon])
+
+ ld a, [wMonType]
+ and a ; PARTYMON
+ jr z, .partymon
+ cp OTPARTYMON
+ jr z, .otpartymon
+ cp BOXMON
+ jr z, .boxmon
+ cp TEMPMON
+ jr z, .breedmon
+ ; WILDMON
+
+.partymon
+ ld hl, wPartySpecies
+ jr .done
+
+.otpartymon
+ ld hl, wOTPartySpecies
+ jr .done
+
+.boxmon
+ ld a, BANK(sBoxSpecies)
+ call OpenSRAM
+ ld hl, sBoxSpecies
+ call .done
+ call CloseSRAM
+ ret
+
+.breedmon
+ ld a, [wBreedMon1Species]
+ jr .done2
+
+.done
+ ld d, 0
+ add hl, de
+ ld a, [hl]
+
+.done2
+ ld [wCurPartySpecies], a
+ ret
diff --git a/engine/pokemon/types.asm b/engine/pokemon/types.asm
new file mode 100755
index 00000000..3c9d28cd
--- /dev/null
+++ b/engine/pokemon/types.asm
@@ -0,0 +1,92 @@
+PrintMonTypes:
+; Print one or both types of [wCurSpecies]
+; on the stats screen at hl.
+
+ push hl
+ call GetBaseData
+ pop hl
+
+ push hl
+ ld a, [wBaseType1]
+ call .Print
+
+ ; Single-typed monsters really
+ ; have two of the same type.
+ ld a, [wBaseType1]
+ ld b, a
+ ld a, [wBaseType2]
+ cp b
+ pop hl
+ jr z, .hide_type_2
+
+ ld bc, $28
+ add hl, bc
+
+.Print:
+ ld b, a
+ jr PrintType
+
+.hide_type_2
+ ; Erase any type name that was here before.
+ ; Seems to be pointless in localized versions.
+ ld a, " "
+ ld bc, SCREEN_WIDTH - 3
+ add hl, bc
+ ld [hl], a
+ inc bc
+ add hl, bc
+ ld bc, NAME_LENGTH_JAPANESE - 1
+ jp ByteFill
+
+PrintMoveType:
+; Print the type of move b at hl.
+
+ push hl
+ ld a, b
+ dec a
+ ld bc, MOVE_LENGTH
+ ld hl, Moves
+ call AddNTimes
+ ld de, wStringBuffer1
+ ld a, BANK(Moves)
+ call FarCopyBytes
+ ld a, [wStringBuffer1 + MOVE_TYPE]
+ pop hl
+
+ ld b, a
+
+PrintType:
+; Print type b at hl.
+
+ ld a, b
+
+ push hl
+ add a
+ ld hl, TypeNames
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld a, [hli]
+ ld e, a
+ ld d, [hl]
+ pop hl
+
+ jp PlaceString
+
+GetTypeName:
+; Copy the name of type [wNamedObjectIndexBuffer] to wStringBuffer1.
+
+ ld a, [wNamedObjectIndexBuffer]
+ ld hl, TypeNames
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wStringBuffer1
+ ld bc, MOVE_NAME_LENGTH
+ jp CopyBytes
+
+INCLUDE "data/types/names.asm"
diff --git a/main.asm b/main.asm
index 3fda5410..126e6bfa 100644
--- a/main.asm
+++ b/main.asm
@@ -356,83 +356,27 @@ INCLUDE "engine/pokemon/mail.asm"
SECTION "bank14", ROMX
-SelectMonFromParty::
- dr $50000, $5001d
-SelectTradeOrDayCareMon::
- dr $5001d, $5004f
-LoadPartyMenuGFX::
- dr $5004f, $5005f
-WritePartyMenuTilemap::
- dr $5005f, $50355
-InitPartyMenuGFX::
- dr $50355, $5037a
-InitPartyMenuWithCancel::
- dr $5037a, $503a2
-InitPartyMenuNoCancel::
- dr $503a2, $503cc
-PartyMenuSelect::
- dr $503cc, $5040f
-PrintPartyMenuText::
- dr $5040f, $504db
-PrintPartyMenuActionText::
- dr $504db, $5054f
-LoadFishingGFX::
- dr $5054f, $50610
-DoPoisonStep::
- dr $50610, $506f2
-SweetScentFromMenu::
- dr $506f2, $50763
-_Squirtbottle::
- dr $50763, $507ac
-_CardKey::
- dr $507ac, $507e7
-_BasementKey::
- dr $507e7, $50819
-_SacredAsh::
- dr $50819, $5087d
-CopyMonToTempMon::
- dr $5087d, $50940
-PrintMonTypes::
- dr $50940, $5096d
-PrintMoveType::
- dr $5096d, $50986
-PrintType::
- dr $50986, $50997
-GetTypeName::
- dr $50997, $50b3d
-DrawPlayerHP::
- dr $50b3d, $50b41
-DrawEnemyHP::
- dr $50b41, $50bae
-StatsScreenInit::
- dr $50bae, $5128f
-
-PrintTempMonStats::
- dr $5128f, $512f1
-GetGender::
- dr $512f1, $51364
-ListMovePP::
- dr $51364, $513e4
-Unused_PlaceEnemyHPLevel::
- dr $513e4, $51437
-PlaceNonFaintStatus::
- dr $51437, $51478
-ListMoves::
- dr $51478, $514c2
-InitList::
- dr $514c2, $51524
-CalcLevel::
- dr $51524, $51550
-CalcExpAtLevel::
- dr $51550, $5161b
-_SwitchPartyMons::
- dr $5161b, $51749
+
+INCLUDE "engine/pokemon/party_menu.asm"
+INCLUDE "engine/events/fishing_gfx.asm"
+INCLUDE "engine/events/poisonstep.asm"
+INCLUDE "engine/events/sweet_scent.asm"
+INCLUDE "engine/events/squirtbottle.asm"
+INCLUDE "engine/events/card_key.asm"
+INCLUDE "engine/events/basement_key.asm"
+INCLUDE "engine/events/sacred_ash.asm"
+INCLUDE "engine/pokemon/tempmon.asm"
+INCLUDE "engine/pokemon/types.asm"
+INCLUDE "engine/battle/unreferenced_getgen1trainerclassname.asm"
+INCLUDE "engine/pokemon/mon_stats.asm"
+INCLUDE "engine/link/init_list.asm"
+INCLUDE "engine/pokemon/experience.asm"
+INCLUDE "engine/pokemon/switchpartymons.asm"
INCLUDE "engine/gfx/load_pics.asm"
INCLUDE "engine/pokemon/move_mon_wo_mail.asm"
INCLUDE "data/pokemon/base_stats.asm"
+INCLUDE "data/pokemon/unused_pic_banks.asm"
-Unknown53a6b::
- dr $53a6b, $53a83
EggPic::
INCBIN "gfx/pokemon/egg/front.2bpp.lz"
@@ -705,8 +649,10 @@ _DepositPKMN::
_WithdrawPKMN::
dr $e2d71, $e2f47
_MovePKMNWithoutMail::
- dr $e2f47, $e3d25
+ dr $e2f47, $e3773
+StatsScreenDPad::
+ dr $e3773, $e3d25
_ChangeBox::
dr $e3d25, $e3f74
@@ -756,7 +702,9 @@ _LoadFontsBattleExtra::
LoadBattleFontsHPBar::
dr $f8066, $f8081
LoadHPBar::
- dr $f8081, $f80d9
+ dr $f8081, $f80a6
+StatsScreen_LoadFont::
+ dr $f80a6, $f80d9
LoadStatsScreenPageTilesGFX::
dr $f80d9, $f8bb2
EnemyHPBarBorderGFX::
diff --git a/wram.asm b/wram.asm
index c2b23477..949d0425 100644
--- a/wram.asm
+++ b/wram.asm
@@ -1583,15 +1583,14 @@ wMailboxItems:: ds MAILBOX_CAPACITY
wMailboxEnd::
ENDU ; cffc
-wcffc:: ds 1 ; cffc
-wcffd:: ds 1 ; cffd
+wListPointer:: dw ; cffc
wUnusedCFFE:: dw ; cffe
SECTION "WRAM 1", WRAMX
-wd000:: ds 1 ; d000
-wd001:: ds 1 ; d001
+wItemAttributesPtr:: dw ; d000
+
wCurItem:: db ; d002
wCurItemQuantity:: ; d003
wMartItemID::