summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
Diffstat (limited to 'engine')
-rw-r--r--engine/battle_transition.asm (renamed from engine/battle_start.asm)9
-rw-r--r--engine/caught_data.asm247
-rw-r--r--engine/check_nick_errors.asm74
-rw-r--r--engine/check_time.asm19
-rw-r--r--engine/collision_stdscripts.asm29
-rw-r--r--engine/consume_held_item.asm80
-rwxr-xr-xengine/crystal_colors.asm10
-rw-r--r--engine/european_mail.asm129
-rw-r--r--engine/experience.asm162
-rw-r--r--engine/init_map.asm103
-rw-r--r--engine/map_objects.asm2
-rw-r--r--engine/map_objects_2.asm70
-rw-r--r--engine/map_palettes.asm86
-rw-r--r--engine/menu_2.asm263
-rw-r--r--engine/mon_stats.asm486
-rw-r--r--engine/player_gfx.asm263
-rw-r--r--engine/pokedex_3.asm162
-rw-r--r--engine/pokerus.asm160
-rw-r--r--engine/pokerus_tick.asm26
-rw-r--r--engine/square_root.asm30
-rw-r--r--engine/start_battle.asm197
-rw-r--r--engine/timeofdaypals.asm4
-rw-r--r--engine/trainer_scripts.asm31
-rw-r--r--engine/unused_correct_party.asm229
24 files changed, 2869 insertions, 2 deletions
diff --git a/engine/battle_start.asm b/engine/battle_transition.asm
index 9546980c2..f8756649b 100644
--- a/engine/battle_start.asm
+++ b/engine/battle_transition.asm
@@ -862,3 +862,12 @@ endm
jr nz, .row
ret
; 8c7c9 (23:47c9)
+
+Function8c7c9:
+; XXX
+ ld a, $1
+ ld [hBGMapMode], a
+ call WaitBGMap
+ xor a
+ ld [hBGMapMode], a
+ ret
diff --git a/engine/caught_data.asm b/engine/caught_data.asm
new file mode 100644
index 000000000..c079009ae
--- /dev/null
+++ b/engine/caught_data.asm
@@ -0,0 +1,247 @@
+CheckPartyFullAfterContest: ; 4d9e5
+ ld a, [wContestMon]
+ and a
+ jp z, .DidntCatchAnything
+ ld [CurPartySpecies], a
+ ld [CurSpecies], a
+ call GetBaseData
+ ld hl, PartyCount
+ ld a, [hl]
+ cp 6
+ jp nc, .TryAddToBox
+ inc a
+ ld [hl], a
+ ld c, a
+ ld b, $0
+ add hl, bc
+ ld a, [wContestMon]
+ ld [hli], a
+ ld [CurSpecies], a
+ ld a, $ff
+ ld [hl], a
+ ld hl, PartyMon1Species
+ ld a, [PartyCount]
+ dec a
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld hl, wContestMon
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call CopyBytes
+ ld a, [PartyCount]
+ dec a
+ ld hl, PartyMonOT
+ call SkipNames
+ ld d, h
+ ld e, l
+ ld hl, PlayerName
+ call CopyBytes
+ ld a, [CurPartySpecies]
+ ld [wd265], a
+ call GetPokemonName
+ ld hl, StringBuffer1
+ ld de, wMonOrItemNameBuffer
+ ld bc, PKMN_NAME_LENGTH
+ call CopyBytes
+ call GiveANickname_YesNo
+ jr c, .Party_SkipNickname
+ ld a, [PartyCount]
+ dec a
+ ld [CurPartyMon], a
+ xor a
+ ld [MonType], a
+ ld de, wMonOrItemNameBuffer
+ callab InitNickname
+
+.Party_SkipNickname:
+ ld a, [PartyCount]
+ dec a
+ ld hl, PartyMonNicknames
+ call SkipNames
+ ld d, h
+ ld e, l
+ ld hl, wMonOrItemNameBuffer
+ call CopyBytes
+ ld a, [PartyCount]
+ dec a
+ ld hl, PartyMon1Level
+ call GetPartyLocation
+ ld a, [hl]
+ ld [CurPartyLevel], a
+ call SetCaughtData
+ ld a, [PartyCount]
+ dec a
+ ld hl, PartyMon1CaughtLocation
+ call GetPartyLocation
+ ld a, [hl]
+ and $80
+ ld b, $13
+ or b
+ ld [hl], a
+ xor a
+ ld [wContestMon], a
+ and a
+ ld [ScriptVar], a
+ ret
+
+.TryAddToBox: ; 4daa3
+ ld a, BANK(sBoxCount)
+ call GetSRAMBank
+ ld hl, sBoxCount
+ ld a, [hl]
+ cp MONS_PER_BOX
+ call CloseSRAM
+ jr nc, .BoxFull
+ xor a
+ ld [CurPartyMon], a
+ ld hl, wContestMon
+ ld de, wBufferMon
+ ld bc, BOXMON_STRUCT_LENGTH
+ call CopyBytes
+ ld hl, PlayerName
+ ld de, wBufferMonOT
+ ld bc, NAME_LENGTH
+ call CopyBytes
+ callab InsertPokemonIntoBox
+ ld a, [CurPartySpecies]
+ ld [wd265], a
+ call GetPokemonName
+ call GiveANickname_YesNo
+ ld hl, StringBuffer1
+ jr c, .Box_SkipNickname
+ ld a, BOXMON
+ ld [MonType], a
+ ld de, wMonOrItemNameBuffer
+ callab InitNickname
+ ld hl, wMonOrItemNameBuffer
+
+.Box_SkipNickname:
+ ld a, BANK(sBoxMonNicknames)
+ call GetSRAMBank
+ ld de, sBoxMonNicknames
+ ld bc, PKMN_NAME_LENGTH
+ call CopyBytes
+ call CloseSRAM
+
+.BoxFull:
+ ld a, BANK(sBoxMon1Level)
+ call GetSRAMBank
+ ld a, [sBoxMon1Level]
+ ld [CurPartyLevel], a
+ call CloseSRAM
+ call SetBoxMonCaughtData
+ ld a, BANK(sBoxMon1CaughtLocation)
+ call GetSRAMBank
+ ld hl, sBoxMon1CaughtLocation
+ ld a, [hl]
+ and $80
+ ld b, $13
+ or b
+ ld [hl], a
+ call CloseSRAM
+ xor a
+ ld [wContestMon], a
+ ld a, $1
+ ld [ScriptVar], a
+ ret
+
+.DidntCatchAnything: ; 4db35
+ ld a, $2
+ ld [ScriptVar], a
+ ret
+
+GiveANickname_YesNo: ; 4db3b
+ ld hl, TextJump_GiveANickname
+ call PrintText
+ jp YesNoBox
+
+TextJump_GiveANickname: ; 0x4db44
+ ; Give a nickname to the @ you received?
+ text_jump UnknownText_0x1c12fc
+ db "@"
+
+SetCaughtData: ; 4db49
+ ld a, [PartyCount]
+ dec a
+ ld hl, PartyMon1CaughtLevel
+ call GetPartyLocation
+SetBoxmonOrEggmonCaughtData: ; 4db53
+ ld a, [TimeOfDay]
+ inc a
+ rrca
+ rrca
+ ld b, a
+ ld a, [CurPartyLevel]
+ or b
+ ld [hli], a
+ ld a, [MapGroup]
+ ld b, a
+ ld a, [MapNumber]
+ ld c, a
+ cp MAP_POKECENTER_2F
+ jr nz, .NotPokecenter2F
+ ld a, b
+ cp GROUP_POKECENTER_2F
+ jr nz, .NotPokecenter2F
+
+ ld a, [BackupMapGroup]
+ ld b, a
+ ld a, [BackupMapNumber]
+ ld c, a
+
+.NotPokecenter2F:
+ call GetWorldMapLocation
+ ld b, a
+ ld a, [PlayerGender]
+ rrca
+ or b
+ ld [hl], a
+ ret
+
+SetBoxMonCaughtData: ; 4db83
+ ld a, BANK(sBoxMon1CaughtLevel)
+ call GetSRAMBank
+ ld hl, sBoxMon1CaughtLevel
+ call SetBoxmonOrEggmonCaughtData
+ call CloseSRAM
+ ret
+
+SetGiftBoxMonCaughtData: ; 4db92
+ push bc
+ ld a, BANK(sBoxMon1CaughtLevel)
+ call GetSRAMBank
+ ld hl, sBoxMon1CaughtLevel
+ pop bc
+ call SetGiftMonCaughtData
+ call CloseSRAM
+ ret
+
+SetGiftPartyMonCaughtData: ; 4dba3
+ ld a, [PartyCount]
+ dec a
+ ld hl, PartyMon1CaughtLevel
+ push bc
+ call GetPartyLocation
+ pop bc
+SetGiftMonCaughtData: ; 4dbaf
+ xor a
+ ld [hli], a
+ ld a, $7e
+ rrc b
+ or b
+ ld [hl], a
+ ret
+
+SetEggMonCaughtData: ; 4dbb8 (13:5bb8)
+ ld a, [CurPartyMon]
+ ld hl, PartyMon1CaughtLevel
+ call GetPartyLocation
+ ld a, [CurPartyLevel]
+ push af
+ ld a, $1
+ ld [CurPartyLevel], a
+ call SetBoxmonOrEggmonCaughtData
+ pop af
+ ld [CurPartyLevel], a
+ ret
diff --git a/engine/check_nick_errors.asm b/engine/check_nick_errors.asm
new file mode 100644
index 000000000..1cedca420
--- /dev/null
+++ b/engine/check_nick_errors.asm
@@ -0,0 +1,74 @@
+CheckNickErrors:: ; 669f
+; error-check monster nick before use
+; must be a peace offering to gamesharkers
+
+; input: de = nick location
+
+ push bc
+ push de
+ ld b, PKMN_NAME_LENGTH
+
+.checkchar
+; end of nick?
+ ld a, [de]
+ cp "@" ; terminator
+ jr z, .end
+
+; check if this char is a text command
+ ld hl, .textcommands
+ dec hl
+.loop
+; next entry
+ inc hl
+; reached end of commands table?
+ ld a, [hl]
+ cp -1
+ jr z, .done
+
+; is the current char between this value (inclusive)...
+ ld a, [de]
+ cp [hl]
+ inc hl
+ jr c, .loop
+; ...and this one?
+ cp [hl]
+ jr nc, .loop
+
+; replace it with a "?"
+ ld a, "?"
+ ld [de], a
+ jr .loop
+
+.done
+; next char
+ inc de
+; reached end of nick without finding a terminator?
+ dec b
+ jr nz, .checkchar
+
+; change nick to "?@"
+ pop de
+ push de
+ ld a, "?"
+ ld [de], a
+ inc de
+ ld a, "@"
+ ld [de], a
+.end
+; if the nick has any errors at this point it's out of our hands
+ pop de
+ pop bc
+ ret
+
+.textcommands ; 66cf
+; table defining which characters are actually text commands
+; format:
+ ; ≥ <
+ db "<START>", TX_BOX + 1
+ db "<PLAY_G>", $18 + 1
+ db $1d, "%" + 1
+ db $35, "<GREEN>" + 1
+ db "<ENEMY>", "<ENEMY>" + 1
+ db "<MOM>", "<TM>" + 1
+ db "<ROCKET>", "┘" + 1
+ db -1 ; end
diff --git a/engine/check_time.asm b/engine/check_time.asm
new file mode 100644
index 000000000..615b51d29
--- /dev/null
+++ b/engine/check_time.asm
@@ -0,0 +1,19 @@
+CheckTime:: ; c000
+ ld a, [TimeOfDay]
+ ld hl, TimeOfDayTable
+ ld de, 2
+ call IsInArray
+ inc hl
+ ld c, [hl]
+ ret c
+
+ xor a
+ ld c, a
+ ret
+
+TimeOfDayTable: ; c012
+ db MORN_F, MORN
+ db DAY_F, DAY
+ db NITE_F, NITE
+ db NITE_F, NITE
+ db -1
diff --git a/engine/collision_stdscripts.asm b/engine/collision_stdscripts.asm
new file mode 100644
index 000000000..17b1e49b2
--- /dev/null
+++ b/engine/collision_stdscripts.asm
@@ -0,0 +1,29 @@
+CheckFacingTileForStd:: ; 1365b
+; Checks to see if the tile you're facing has a std script associated with it. If so, executes the script and returns carry.
+ ld a, c
+ ld de, 3
+ ld hl, TileCollisionStdScripts
+ call IsInArray
+ jr nc, .notintable
+
+ ld a, jumpstd_command
+ ld [wJumpStdScriptBuffer], a
+ inc hl
+ ld a, [hli]
+ ld [wJumpStdScriptBuffer + 1], a
+ ld a, [hli]
+ ld [wJumpStdScriptBuffer + 2], a
+ ld a, BANK(Script_JumpStdFromRAM)
+ ld hl, Script_JumpStdFromRAM
+ call CallScript
+ scf
+ ret
+
+.notintable
+ xor a
+ ret
+
+INCLUDE "data/collision_stdscripts.asm"
+
+Script_JumpStdFromRAM: ; 0x1369a
+ jump wJumpStdScriptBuffer
diff --git a/engine/consume_held_item.asm b/engine/consume_held_item.asm
new file mode 100644
index 000000000..52d7894cd
--- /dev/null
+++ b/engine/consume_held_item.asm
@@ -0,0 +1,80 @@
+ConsumeHeldItem: ; 27192
+ push hl
+ push de
+ push bc
+ ld a, [hBattleTurn]
+ and a
+ ld hl, OTPartyMon1Item
+ ld de, EnemyMonItem
+ ld a, [CurOTMon]
+ jr z, .theirturn
+ ld hl, PartyMon1Item
+ ld de, BattleMonItem
+ ld a, [CurBattleMon]
+
+.theirturn
+ push hl
+ push af
+ ld a, [de]
+ ld b, a
+ callba GetItemHeldEffect
+ ld hl, .ConsumableEffects
+.loop
+ ld a, [hli]
+ cp b
+ jr z, .ok
+ inc a
+ jr nz, .loop
+ pop af
+ pop hl
+ pop bc
+ pop de
+ pop hl
+ ret
+
+.ok
+ xor a
+ ld [de], a
+ pop af
+ pop hl
+ call GetPartyLocation
+ ld a, [hBattleTurn]
+ and a
+ jr nz, .ourturn
+ ld a, [wBattleMode]
+ dec a
+ jr z, .done
+
+.ourturn
+ ld [hl], $0
+
+.done
+ pop bc
+ pop de
+ pop hl
+ ret
+
+.ConsumableEffects: ; 271de
+; Consumable items?
+ db HELD_BERRY
+ db HELD_2
+ db HELD_5
+ db HELD_HEAL_POISON
+ db HELD_HEAL_FREEZE
+ db HELD_HEAL_BURN
+ db HELD_HEAL_SLEEP
+ db HELD_HEAL_PARALYZE
+ db HELD_HEAL_STATUS
+ db HELD_30
+ db HELD_ATTACK_UP
+ db HELD_DEFENSE_UP
+ db HELD_SPEED_UP
+ db HELD_SP_ATTACK_UP
+ db HELD_SP_DEFENSE_UP
+ db HELD_ACCURACY_UP
+ db HELD_EVASION_UP
+ db HELD_38
+ db HELD_71
+ db HELD_ESCAPE
+ db HELD_CRITICAL_UP
+ db -1
diff --git a/engine/crystal_colors.asm b/engine/crystal_colors.asm
index 125fee8bc..25b831f01 100755
--- a/engine/crystal_colors.asm
+++ b/engine/crystal_colors.asm
@@ -612,3 +612,13 @@ InitMG_Mobile_LinkTradePalMap: ; 49856
call _InitMG_Mobile_LinkTradePalMap
ret
; 4985a
+
+Unknown_4985a: ; unreferenced
+ db $ab, $03, $57, $24, $ac, $0e, $13, $32
+ db $be, $30, $5b, $4c, $47, $60, $ed, $f2
+ db $ab, $03, $55, $26, $aa, $0a, $13, $3a
+ db $be, $28, $33, $24, $6e, $71, $df, $b0
+ db $a8, $00, $e5, $e0, $9a, $fc, $f4, $2c
+ db $fe, $4c, $a3, $5e, $c6, $3a, $ab, $4d
+ db $a8, $00, $b5, $b0, $de, $e8, $fc, $1c
+ db $ba, $66, $f7, $0e, $ba, $5e, $43, $bd
diff --git a/engine/european_mail.asm b/engine/european_mail.asm
new file mode 100644
index 000000000..8f037cc43
--- /dev/null
+++ b/engine/european_mail.asm
@@ -0,0 +1,129 @@
+IsMailEuropean: ; 1de5c8
+; return 1 if French
+; return 2 if German
+; return 3 if Italian
+; return 4 if Spanish
+; return 0 if none of the above
+ ld c, $0
+ ld hl, sPartyMon1MailAuthorNationality - sPartyMon1Mail
+ add hl, de
+ ld a, [hli]
+ cp "E"
+ ret nz
+ ld a, [hli]
+ inc c
+ cp "F"
+ ret z
+ inc c
+ cp "G"
+ ret z
+ inc c
+ cp "I"
+ ret z
+ inc c
+ cp "S"
+ ret z
+ ld c, $0
+ ret
+
+; The regular font.
+StandardEnglishFont: ; 1de5e6
+INCBIN "gfx/font/english.1bpp"
+
+; An extended font.
+FrenchGermanFont: ; 1de9e6
+INCBIN "gfx/font/french_german.1bpp"
+
+; An even more extended font.
+SpanishItalianFont: ; 1dede6
+INCBIN "gfx/font/spanish_italian.1bpp"
+
+HandleFrenchGermanMail: ; 1df1e6
+; called if mail is french or german
+; fix 's 't 'v
+ ld b, sPartyMon1MailAuthor - sPartyMon1Mail
+ ld h, d
+ ld l, e
+.loop
+ ld a, [hl]
+ cp $dc ; 's in french/german font
+ jr nz, .check_intermediate_chars
+ ld a, "'s"
+ jr .replace
+
+.check_intermediate_chars
+ sub "'s"
+ jr c, .dont_replace
+ cp "'v" - "'s" + 1
+ jr nc, .dont_replace
+ add $cd
+
+.replace
+ ld [hl], a
+
+.dont_replace
+ inc hl
+ dec b
+ jr nz, .loop
+ ret
+
+LireLeCourrierAnglais:
+DeutenEnglischenPost: ; 1df203
+; Cette fonction convertit certains des caractères anglais pour
+; leur équivalent dans le jeu de caractères français.
+; Diese Funktion wandelt bestimmte englische Zeichen, um ihre
+; Entsprechung in der Deutschen-Zeichensatz.
+ ld b, sPartyMon1MailAuthor - sPartyMon1Mail
+ ld h, d
+ ld l, e
+.loop
+ ld a, [hl]
+ cp "'s"
+ jr nz, .check_intermediate_chars
+ ld a, $dc
+ jr .replace
+
+.check_intermediate_chars
+ sub $cd
+ jr c, .dont_replace
+ cp "'v" - "'s" + 1
+ jr nc, .dont_replace
+ add "'s"
+
+.replace
+ ld [hl], a
+
+.dont_replace
+ inc hl
+ dec b
+ jr nz, .loop
+ ret
+
+HandleSpanishItalianMail: ; 1df220
+LeerCorreosIngleses:
+LeggiPostaInglese:
+; This function converts certain characters between
+; the English and Spanish/Italian character sets.
+; Esta función convierte ciertos caracteres entre
+; el juego de caracteres Inglés y Español.
+; Questa funzione converte alcuni caratteri tra
+; l'inglese e il set di caratteri italiani.
+ ld b, sPartyMon1MailAuthor - sPartyMon1Mail
+ ld h, d
+ ld l, e
+.loop
+ ld a, [hl]
+ and $f0
+ cp $d0
+ jr nz, .dont_replace
+ ld a, [hl]
+ add $8
+ and $f
+ or $d0
+ ld [hl], a
+
+.dont_replace
+ inc hl
+ dec b
+ jr nz, .loop
+ ret
diff --git a/engine/experience.asm b/engine/experience.asm
new file mode 100644
index 000000000..c33aaf02a
--- /dev/null
+++ b/engine/experience.asm
@@ -0,0 +1,162 @@
+CalcLevel: ; 50e1b
+ ld a, [TempMonSpecies]
+ ld [CurSpecies], a
+ call GetBaseData
+ ld d, 1
+.next_level
+ inc d
+ ld a, d
+ cp (MAX_LEVEL + 1) % $100
+ jr z, .got_level
+ call CalcExpAtLevel
+ push hl
+ ld hl, TempMonExp + 2
+ ld a, [hProduct + 3]
+ ld c, a
+ ld a, [hld]
+ sub c
+ ld a, [hProduct + 2]
+ ld c, a
+ ld a, [hld]
+ sbc c
+ ld a, [hProduct + 1]
+ ld c, a
+ ld a, [hl]
+ sbc c
+ pop hl
+ jr nc, .next_level
+
+.got_level
+ dec d
+ ret
+
+CalcExpAtLevel: ; 50e47
+; (a/b)*n**3 + c*n**2 + d*n - e
+ ld a, [BaseGrowthRate]
+ add a
+ add a
+ ld c, a
+ ld b, 0
+ ld hl, GrowthRates
+ add hl, bc
+; Cube the level
+ call .LevelSquared
+ ld a, d
+ ld [hMultiplier], a
+ call Multiply
+
+; Multiply by a
+ ld a, [hl]
+ and $f0
+ swap a
+ ld [hMultiplier], a
+ call Multiply
+; Divide by b
+ ld a, [hli]
+ and $f
+ ld [hDivisor], a
+ ld b, 4
+ call Divide
+; Push the cubic term to the stack
+ ld a, [hQuotient + 0]
+ push af
+ ld a, [hQuotient + 1]
+ push af
+ ld a, [hQuotient + 2]
+ push af
+; Square the level and multiply by the lower 7 bits of c
+ call .LevelSquared
+ ld a, [hl]
+ and $7f
+ ld [hMultiplier], a
+ call Multiply
+; Push the absolute value of the quadratic term to the stack
+ ld a, [hProduct + 1]
+ push af
+ ld a, [hProduct + 2]
+ push af
+ ld a, [hProduct + 3]
+ push af
+ ld a, [hli]
+ push af
+; Multiply the level by d
+ xor a
+ ld [hMultiplicand + 0], a
+ ld [hMultiplicand + 1], a
+ ld a, d
+ ld [hMultiplicand + 2], a
+ ld a, [hli]
+ ld [hMultiplier], a
+ call Multiply
+; Subtract e
+ ld b, [hl]
+ ld a, [hProduct + 3]
+ sub b
+ ld [hMultiplicand + 2], a
+ ld b, $0
+ ld a, [hProduct + 2]
+ sbc b
+ ld [hMultiplicand + 1], a
+ ld a, [hProduct + 1]
+ sbc b
+ ld [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
+ ld a, [hProduct + 3]
+ add b
+ ld [hMultiplicand + 2], a
+ pop bc
+ ld a, [hProduct + 2]
+ adc b
+ ld [hMultiplicand + 1], a
+ pop bc
+ ld a, [hProduct + 1]
+ adc b
+ ld [hMultiplicand], a
+ jr .done_quadratic
+
+.subtract
+; Subtract c*n**2 from (d*n - e)
+ pop bc
+ ld a, [hProduct + 3]
+ sub b
+ ld [hMultiplicand + 2], a
+ pop bc
+ ld a, [hProduct + 2]
+ sbc b
+ ld [hMultiplicand + 1], a
+ pop bc
+ ld a, [hProduct + 1]
+ sbc b
+ ld [hMultiplicand], a
+
+.done_quadratic
+; Add (a/b)*n**3 to (d*n - e +/- c*n**2)
+ pop bc
+ ld a, [hProduct + 3]
+ add b
+ ld [hMultiplicand + 2], a
+ pop bc
+ ld a, [hProduct + 2]
+ adc b
+ ld [hMultiplicand + 1], a
+ pop bc
+ ld a, [hProduct + 1]
+ adc b
+ ld [hMultiplicand], a
+ ret
+
+.LevelSquared: ; 50eed
+ xor a
+ ld [hMultiplicand + 0], a
+ ld [hMultiplicand + 1], a
+ ld a, d
+ ld [hMultiplicand + 2], a
+ ld [hMultiplier], a
+ jp Multiply
+
+INCLUDE "data/growth_rates.asm"
diff --git a/engine/init_map.asm b/engine/init_map.asm
new file mode 100644
index 000000000..5dd6c7b8a
--- /dev/null
+++ b/engine/init_map.asm
@@ -0,0 +1,103 @@
+ReanchorBGMap_NoOAMUpdate:: ; 6454
+ call DelayFrame
+ ld a, [hOAMUpdate]
+ push af
+
+ ld a, $1
+ ld [hOAMUpdate], a
+ ld a, [hBGMapMode]
+ push af
+ xor a
+ ld [hBGMapMode], a
+
+ call .ReanchorBGMap
+
+ pop af
+ ld [hBGMapMode], a
+ pop af
+ ld [hOAMUpdate], a
+ ld hl, VramState
+ set 6, [hl]
+ ret
+
+.ReanchorBGMap:
+ xor a
+ ld [hLCDCPointer], a
+ ld [hBGMapMode], a
+ ld a, $90
+ ld [hWY], a
+ call OverworldTextModeSwitch
+ ld a, VBGMap1 / $100
+ call .LoadBGMapAddrIntoHRAM
+ call _OpenAndCloseMenu_HDMATransferTileMapAndAttrMap
+ callba LoadOW_BGPal7
+ callba ApplyPals
+ ld a, $1
+ ld [hCGBPalUpdate], a
+ xor a
+ ld [hBGMapMode], a
+ ld [hWY], a
+ callba HDMATransfer_FillBGMap0WithBlack ; no need to farcall
+ ld a, VBGMap0 / $100
+ call .LoadBGMapAddrIntoHRAM
+ xor a
+ ld [wBGMapAnchor], a
+ ld a, VBGMap0 / $100
+ ld [wBGMapAnchor + 1], a
+ xor a
+ ld [hSCX], a
+ ld [hSCY], a
+ call ApplyBGMapAnchorToObjects
+ ret
+
+.LoadBGMapAddrIntoHRAM: ; 64b9
+ ld [hBGMapAddress + 1], a
+ xor a
+ ld [hBGMapAddress], a
+ ret
+
+LoadFonts_NoOAMUpdate:: ; 64bf
+ ld a, [hOAMUpdate]
+ push af
+ ld a, $1
+ ld [hOAMUpdate], a
+
+ call .LoadGFX
+
+ pop af
+ ld [hOAMUpdate], a
+ ret
+
+.LoadGFX:
+ call LoadFontsExtra
+ ld a, $90
+ ld [hWY], a
+ call SafeUpdateSprites
+ call LoadStandardFont
+ ret
+
+HDMATransfer_FillBGMap0WithBlack: ; 64db
+ ld a, [rSVBK]
+ push af
+ ld a, $6
+ ld [rSVBK], a
+
+ ld a, "<BLACK>" ; $60
+ ld hl, wDecompressScratch
+ ld bc, wScratchAttrMap - wDecompressScratch
+ call ByteFill
+ ld a, wDecompressScratch / $100
+ ld [rHDMA1], a
+ ld a, wDecompressScratch % $100
+ ld [rHDMA2], a
+ ld a, (VBGMap0 % $8000) / $100
+ ld [rHDMA3], a
+ ld a, (VBGMap0 % $8000) % $100
+ ld [rHDMA4], a
+ ld a, $3f
+ ld [hDMATransfer], a
+ call DelayFrame
+
+ pop af
+ ld [rSVBK], a
+ ret
diff --git a/engine/map_objects.asm b/engine/map_objects.asm
index 162ea22df..4b8adb75f 100644
--- a/engine/map_objects.asm
+++ b/engine/map_objects.asm
@@ -1,7 +1,5 @@
-
INCLUDE "data/facings.asm"
-
INCLUDE "data/map_objects.asm"
diff --git a/engine/map_objects_2.asm b/engine/map_objects_2.asm
new file mode 100644
index 000000000..3c9a9773c
--- /dev/null
+++ b/engine/map_objects_2.asm
@@ -0,0 +1,70 @@
+LoadObjectMasks: ; 2454f
+ ld hl, wObjectMasks
+ xor a
+ ld bc, NUM_OBJECTS
+ call ByteFill
+ nop
+ ld bc, MapObjects
+ ld de, wObjectMasks
+ xor a
+.loop
+ push af
+ push bc
+ push de
+ call GetObjectTimeMask
+ jr c, .next
+ call CheckObjectFlag
+.next
+ pop de
+ ld [de], a
+ inc de
+ pop bc
+ ld hl, OBJECT_LENGTH
+ add hl, bc
+ ld b, h
+ ld c, l
+ pop af
+ inc a
+ cp NUM_OBJECTS
+ jr nz, .loop
+ ret
+
+CheckObjectFlag: ; 2457d (9:457d)
+ ld hl, MAPOBJECT_SPRITE
+ add hl, bc
+ ld a, [hl]
+ and a
+ jr z, .masked
+ ld hl, MAPOBJECT_EVENT_FLAG
+ add hl, bc
+ ld a, [hli]
+ ld e, a
+ ld a, [hl]
+ ld d, a
+ cp -1
+ jr nz, .check
+ ld a, e
+ cp -1
+ jr z, .unmasked
+ jr .masked
+.check
+ ld b, CHECK_FLAG
+ call EventFlagAction
+ ld a, c
+ and a
+ jr nz, .masked
+.unmasked
+ xor a
+ ret
+
+.masked
+ ld a, -1
+ scf
+ ret
+
+GetObjectTimeMask: ; 245a7 (9:45a7)
+ call CheckObjectTime
+ ld a, -1
+ ret c
+ xor a
+ ret
diff --git a/engine/map_palettes.asm b/engine/map_palettes.asm
new file mode 100644
index 000000000..ffeef7bf6
--- /dev/null
+++ b/engine/map_palettes.asm
@@ -0,0 +1,86 @@
+SwapTextboxPalettes:: ; 4c000
+ hlcoord 0, 0
+ decoord 0, 0, AttrMap
+ ld b, SCREEN_HEIGHT
+.loop
+ push bc
+ ld c, SCREEN_WIDTH
+.innerloop
+ ld a, [hl]
+ push hl
+ srl a
+ jr c, .UpperNybble
+ ld hl, TilesetPalettes
+ add [hl]
+ ld l, a
+ ld a, [TilesetPalettes + 1]
+ adc $0
+ ld h, a
+ ld a, [hl]
+ and $f
+ jr .next
+
+.UpperNybble:
+ ld hl, TilesetPalettes
+ add [hl]
+ ld l, a
+ ld a, [TilesetPalettes + 1]
+ adc $0
+ ld h, a
+ ld a, [hl]
+ swap a
+ and $f
+
+.next
+ pop hl
+ ld [de], a
+ res 7, [hl]
+ inc hl
+ inc de
+ dec c
+ jr nz, .innerloop
+ pop bc
+ dec b
+ jr nz, .loop
+ ret
+
+ScrollBGMapPalettes:: ; 4c03f
+ ld hl, BGMapBuffer
+ ld de, BGMapPalBuffer
+.loop
+ ld a, [hl]
+ push hl
+ srl a
+ jr c, .UpperNybble
+
+; .LowerNybble
+ ld hl, TilesetPalettes
+ add [hl]
+ ld l, a
+ ld a, [TilesetPalettes + 1]
+ adc $0
+ ld h, a
+ ld a, [hl]
+ and $f
+ jr .next
+
+.UpperNybble:
+ ld hl, TilesetPalettes
+ add [hl]
+ ld l, a
+ ld a, [TilesetPalettes + 1]
+ adc $0
+ ld h, a
+ ld a, [hl]
+ swap a
+ and $f
+
+.next
+ pop hl
+ ld [de], a
+ res 7, [hl]
+ inc hl
+ inc de
+ dec c
+ jr nz, .loop
+ ret
diff --git a/engine/menu_2.asm b/engine/menu_2.asm
new file mode 100644
index 000000000..13568f3c5
--- /dev/null
+++ b/engine/menu_2.asm
@@ -0,0 +1,263 @@
+PlaceMenuItemName: ; 0x24ab4
+ push de
+ ld a, [MenuSelection]
+ ld [wNamedObjectIndexBuffer], a
+ call GetItemName
+ pop hl
+ call PlaceString
+ ret
+
+PlaceMenuItemQuantity: ; 0x24ac3
+ push de
+ ld a, [MenuSelection]
+ ld [CurItem], a
+ callba _CheckTossableItem
+ ld a, [wItemAttributeParamBuffer]
+ pop hl
+ and a
+ jr nz, .done
+ ld de, $15
+ add hl, de
+ ld [hl], "×"
+ inc hl
+ ld de, MenuSelectionQuantity
+ lb bc, 1, 2
+ call PrintNum
+
+.done
+ ret
+
+PlaceMoneyTopRight: ; 24ae8
+ ld hl, MenuDataHeader_0x24b15
+ call CopyMenuDataHeader
+ jr PlaceMoneyDataHeader
+
+PlaceMoneyBottomLeft: ; 24af0
+ ld hl, MenuDataHeader_0x24b1d
+ call CopyMenuDataHeader
+ jr PlaceMoneyDataHeader
+
+PlaceMoneyAtTopLeftOfTextbox: ; 24af8
+ ld hl, MenuDataHeader_0x24b15
+ lb de, 0, 11
+ call OffsetMenuDataHeader
+
+PlaceMoneyDataHeader: ; 24b01
+ call MenuBox
+ call MenuBoxCoord2Tile
+ ld de, SCREEN_WIDTH + 1
+ add hl, de
+ ld de, Money
+ lb bc, PRINTNUM_MONEY | 3, 6
+ call PrintNum
+ ret
+
+MenuDataHeader_0x24b15: ; 0x24b15
+ db $40 ; flags
+ db 00, 11 ; start coords
+ db 02, 19 ; end coords
+ dw NULL
+ db 1 ; default option
+
+MenuDataHeader_0x24b1d: ; 0x24b1d
+ db $40 ; flags
+ db 11, 00 ; start coords
+ db 13, 08 ; end coords
+ dw NULL
+ db 1 ; default option
+
+Special_DisplayCoinCaseBalance: ; 24b25
+ ; Place a text box of size 1x7 at 11, 0.
+ hlcoord 11, 0
+ ld b, 1
+ ld c, 7
+ call TextBox
+ hlcoord 12, 0
+ ld de, CoinString
+ call PlaceString
+ hlcoord 17, 1
+ ld de, ShowMoney_TerminatorString
+ call PlaceString
+ ld de, Coins
+ lb bc, 2, 4
+ hlcoord 13, 1
+ call PrintNum
+ ret
+
+Special_DisplayMoneyAndCoinBalance: ; 24b4e
+ hlcoord 5, 0
+ ld b, 3
+ ld c, 13
+ call TextBox
+ hlcoord 6, 1
+ ld de, MoneyString
+ call PlaceString
+ hlcoord 12, 1
+ ld de, Money
+ lb bc, PRINTNUM_MONEY | 3, 6
+ call PrintNum
+ hlcoord 6, 3
+ ld de, CoinString
+ call PlaceString
+ hlcoord 15, 3
+ ld de, Coins
+ lb bc, 2, 4
+ call PrintNum
+ ret
+
+MoneyString: ; 24b83
+ db "MONEY@"
+CoinString: ; 24b89
+ db "COIN@"
+ShowMoney_TerminatorString: ; 24b8e
+ db "@"
+
+Function24b8f: ; 24b8f
+; unreferenced, related to safari?
+ ld hl, Options
+ ld a, [hl]
+ push af
+ set NO_TEXT_SCROLL, [hl]
+ hlcoord 0, 0
+ ld b, 3
+ ld c, 7
+ call TextBox
+ hlcoord 1, 1
+ ld de, wSafariTimeRemaining
+ lb bc, 2, 3
+ call PrintNum
+ hlcoord 4, 1
+ ld de, .slash_500
+ call PlaceString
+ hlcoord 1, 3
+ ld de, .booru_ko
+ call PlaceString
+ hlcoord 5, 3
+ ld de, wSafariBallsRemaining
+ lb bc, 1, 2
+ call PrintNum
+ pop af
+ ld [Options], a
+ ret
+
+.slash_500 ; 24bcf
+ db "/500@"
+.booru_ko ; 24bd4
+ db "ボール こ@"
+
+StartMenu_DrawBugContestStatusBox: ; 24bdc
+ hlcoord 0, 0
+ ld b, 5
+ ld c, 17
+ call TextBox
+ ret
+
+StartMenu_PrintBugContestStatus: ; 24be7
+ ld hl, Options
+ ld a, [hl]
+ push af
+ set NO_TEXT_SCROLL, [hl]
+ call StartMenu_DrawBugContestStatusBox
+ hlcoord 1, 5
+ ld de, .Balls_EN
+ call PlaceString
+ hlcoord 8, 5
+ ld de, wParkBallsRemaining
+ lb bc, PRINTNUM_RIGHTALIGN | 1, 2
+ call PrintNum
+ hlcoord 1, 1
+ ld de, .CAUGHT
+ call PlaceString
+ ld a, [wContestMon]
+ and a
+ ld de, .None
+ jr z, .no_contest_mon
+ ld [wd265], a
+ call GetPokemonName
+
+.no_contest_mon
+ hlcoord 8, 1
+ call PlaceString
+ ld a, [wContestMon]
+ and a
+ jr z, .skip_level
+ hlcoord 1, 3
+ ld de, .LEVEL
+ call PlaceString
+ ld a, [wContestMonLevel]
+ ld h, b
+ ld l, c
+ inc hl
+ ld c, 3
+ call Print8BitNumRightAlign
+
+.skip_level
+ pop af
+ ld [Options], a
+ ret
+
+.Balls_JP: ; 24c43
+ db "ボール こ@"
+.CAUGHT: ; 24c4b
+ db "CAUGHT@"
+.Balls_EN: ; 24c52
+ db "BALLS:@"
+.None: ; 24c59
+ db "None@"
+.LEVEL: ; 24c5e
+ db "LEVEL@"
+
+FindApricornsInBag: ; 24c64
+; Checks the bag for Apricorns.
+ ld hl, Buffer1
+ xor a
+ ld [hli], a
+ dec a
+ ld bc, 10
+ call ByteFill
+
+ ld hl, .ApricornBalls
+.loop
+ ld a, [hl]
+ cp -1
+ jr z, .done
+ push hl
+ ld [CurItem], a
+ ld hl, NumItems
+ call CheckItem
+ pop hl
+ jr nc, .nope
+ ld a, [hl]
+ call .addtobuffer
+.nope
+ inc hl
+ inc hl
+ jr .loop
+
+.done
+ ld a, [Buffer1]
+ and a
+ ret nz
+ scf
+ ret
+
+.addtobuffer ; 24c94
+ push hl
+ ld hl, Buffer1
+ inc [hl]
+ ld e, [hl]
+ ld d, 0
+ add hl, de
+ ld [hl], a
+ pop hl
+ ret
+
+.ApricornBalls: ; 24ca0
+ db RED_APRICORN, LEVEL_BALL
+ db BLU_APRICORN, LURE_BALL
+ db YLW_APRICORN, MOON_BALL
+ db GRN_APRICORN, FRIEND_BALL
+ db WHT_APRICORN, FAST_BALL
+ db BLK_APRICORN, HEAVY_BALL
+ db PNK_APRICORN, LOVE_BALL
+ db -1
diff --git a/engine/mon_stats.asm b/engine/mon_stats.asm
new file mode 100644
index 000000000..ec468be16
--- /dev/null
+++ b/engine/mon_stats.asm
@@ -0,0 +1,486 @@
+DrawPlayerHP: ; 50b0a
+ ld a, $1
+ jr DrawHP
+
+DrawEnemyHP: ; 50b0e
+ ld a, $2
+
+DrawHP: ; 50b10
+ ld [wWhichHPBar], a
+ push hl
+ push bc
+ ; box mons have full HP
+ ld a, [MonType]
+ cp BOXMON
+ jr z, .at_least_1_hp
+
+ ld a, [TempMonHP]
+ ld b, a
+ ld a, [TempMonHP + 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, [TempMonMaxHP]
+ ld d, a
+ ld a, [TempMonMaxHP + 1]
+ ld e, a
+ ld a, [MonType]
+ 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, TempMonHP
+ ld a, [MonType]
+ cp BOXMON
+ jr nz, .not_boxmon_2
+ ld de, TempMonMaxHP
+.not_boxmon_2
+ lb bc, 2, 3
+ call PrintNum
+
+ ld a, "/"
+ ld [hli], a
+
+; Print max HP
+ ld de, TempMonMaxHP
+ lb bc, 2, 3
+ call PrintNum
+ pop hl
+ pop de
+ ret
+
+PrintTempMonStats: ; 50b7b
+; Print TempMon'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, TempMonAttack
+ lb bc, 2, 3
+ call .PrintStat
+ ld de, TempMonDefense
+ call .PrintStat
+ ld de, TempMonSpclAtk
+ call .PrintStat
+ ld de, TempMonSpclDef
+ call .PrintStat
+ ld de, TempMonSpeed
+ jp PrintNum
+
+.PrintStat: ; 50bab
+ push hl
+ call PrintNum
+ pop hl
+ ld de, SCREEN_WIDTH * 2
+ add hl, de
+ ret
+
+.StatNames: ; 50bb5
+ db "ATTACK"
+ next "DEFENSE"
+ next "SPCL.ATK"
+ next "SPCL.DEF"
+ next "SPEED"
+ next "@"
+
+GetGender: ; 50bdd
+; Return the gender of a given monster (CurPartyMon/CurOTMon/CurWildMon).
+; When calling this function, a should be set to an appropriate MonType 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, PartyMon1DVs
+ ld bc, PARTYMON_STRUCT_LENGTH
+ ld a, [MonType]
+ and a
+ jr z, .PartyMon
+
+; 1: OTPartyMon
+ ld hl, OTPartyMon1DVs
+ dec a
+ jr z, .PartyMon
+
+; 2: sBoxMon
+ ld hl, sBoxMon1DVs
+ ld bc, BOXMON_STRUCT_LENGTH
+ dec a
+ jr z, .sBoxMon
+
+; 3: Unknown
+ ld hl, TempMonDVs
+ dec a
+ jr z, .DVs
+
+; else: WildMon
+ ld hl, EnemyMonDVs
+ jr .DVs
+
+; Get our place in the party/box.
+
+.PartyMon:
+.sBoxMon
+ ld a, [CurPartyMon]
+ call AddNTimes
+
+.DVs:
+
+; sBoxMon data is read directly from SRAM.
+ ld a, [MonType]
+ cp BOXMON
+ ld a, 1
+ call z, GetSRAMBank
+
+; 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, [MonType]
+ cp BOXMON
+ call z, CloseSRAM
+
+; We need the gender ratio to do anything with this.
+ push bc
+ ld a, [CurPartySpecies]
+ 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 GENDERLESS
+ 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: ; 50c50
+ ld a, [wNumMoves]
+ inc a
+ ld c, a
+ ld a, NUM_MOVES
+ sub c
+ ld b, a
+ push hl
+ ld a, [Buffer1]
+ 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, TempMonMoves
+ 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
+ callab GetMaxPPOfMove
+ pop hl
+ pop af
+ ld [hl], a
+ pop de
+ pop hl
+ push hl
+ ld bc, TempMonPP - (TempMonMoves + 1)
+ add hl, bc
+ ld a, [hl]
+ and $3f
+ ld [StringBuffer1 + 4], a
+ ld h, d
+ ld l, e
+ push hl
+ ld de, StringBuffer1 + 4
+ lb bc, 1, 2
+ call PrintNum
+ ld a, "/"
+ ld [hli], a
+ ld de, wd265
+ lb bc, 1, 2
+ call PrintNum
+ pop hl
+ ld a, [Buffer1]
+ 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 ; 50cc9
+ ld [hli], a
+ ld [hld], a
+ add hl, de
+ dec c
+ jr nz, .load_loop
+ ret
+
+Function50cd0: ; 50cd0
+; XXX
+.loop
+ ld [hl], $32
+ inc hl
+ ld [hl], $3e
+ dec hl
+ add hl, de
+ dec c
+ jr nz, .loop
+ ret
+
+Predef22: ; unreferenced predef
+ push hl
+ push hl
+ ld hl, PartyMonNicknames
+ ld a, [CurPartyMon]
+ call GetNick
+ pop hl
+ call PlaceString
+ call CopyPkmnToTempMon
+ pop hl
+ ld a, [CurPartySpecies]
+ 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: ; 50d0a
+ 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: ; 50d22
+ db "FNT@"
+
+CopyStatusString: ; 50d25
+ ld a, [de]
+ inc de
+ ld [hli], a
+ ld a, [de]
+ inc de
+ ld [hli], a
+ ld a, [de]
+ ld [hl], a
+ ret
+
+PlaceNonFaintStatus: ; 50d2e
+ 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: ; 50d6f
+; List moves at hl, spaced every [Buffer1] 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 [CurSpecies], a
+ ld a, MOVE_NAME
+ ld [wNamedObjectTypeBuffer], a
+ call GetName
+ ld de, StringBuffer1
+ pop hl
+ push bc
+ call PlaceString
+ pop bc
+ ld a, b
+ ld [wNumMoves], a
+ inc b
+ pop hl
+ push bc
+ ld a, [Buffer1]
+ 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, [Buffer1]
+ 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/player_gfx.asm b/engine/player_gfx.asm
new file mode 100644
index 000000000..1af444d73
--- /dev/null
+++ b/engine/player_gfx.asm
@@ -0,0 +1,263 @@
+Function88248: ; 88248
+; XXX
+ ld c, CAL
+ ld a, [PlayerGender]
+ bit 0, a
+ jr z, .okay
+ ld c, KAREN
+
+.okay
+ ld a, c
+ ld [TrainerClass], a
+ ret
+
+MovePlayerPicRight: ; 88258
+ hlcoord 6, 4
+ ld de, 1
+ jr MovePlayerPic
+
+MovePlayerPicLeft: ; 88260
+ hlcoord 13, 4
+ ld de, -1
+ ; fallthrough
+
+MovePlayerPic: ; 88266
+; Move player pic at hl by de * 7 tiles.
+ ld c, $8
+.loop
+ push bc
+ push hl
+ push de
+ xor a
+ ld [hBGMapMode], a
+ lb bc, 7, 7
+ predef PlaceGraphic
+ xor a
+ ld [hBGMapThird], a
+ call WaitBGMap
+ call DelayFrame
+ pop de
+ pop hl
+ add hl, de
+ pop bc
+ dec c
+ ret z
+ push hl
+ push bc
+ ld a, l
+ sub e
+ ld l, a
+ ld a, h
+ sbc d
+ ld h, a
+ lb bc, 7, 7
+ call ClearBox
+ pop bc
+ pop hl
+ jr .loop
+
+ShowPlayerNamingChoices: ; 88297
+ ld hl, ChrisNameMenuHeader
+ ld a, [PlayerGender]
+ bit 0, a
+ jr z, .GotGender
+ ld hl, KrisNameMenuHeader
+.GotGender:
+ call LoadMenuDataHeader
+ call VerticalMenu
+ ld a, [wMenuCursorY]
+ dec a
+ call CopyNameFromMenu
+ call CloseWindow
+ ret
+
+ChrisNameMenuHeader: ; 882b5
+ db $40 ; flags
+ db 00, 00 ; start coords
+ db 11, 10 ; end coords
+ dw .MaleNames
+ db 1 ; ????
+ db 0 ; default option
+
+.MaleNames: ; 882be
+ db $91 ; flags
+ db 5 ; items
+ db "NEW NAME@"
+MalePlayerNameArray: ; 882c9
+ db "CHRIS@"
+ db "MAT@"
+ db "ALLAN@"
+ db "JON@"
+ db 2 ; displacement
+ db " NAME @" ; title
+
+KrisNameMenuHeader: ; 882e5
+ db $40 ; flags
+ db 00, 00 ; start coords
+ db 11, 10 ; end coords
+ dw .FemaleNames
+ db 1 ; ????
+ db 0 ; default option
+
+.FemaleNames: ; 882ee
+ db $91 ; flags
+ db 5 ; items
+ db "NEW NAME@"
+FemalePlayerNameArray: ; 882f9
+ db "KRIS@"
+ db "AMANDA@"
+ db "JUANA@"
+ db "JODI@"
+ db 2 ; displacement
+ db " NAME @" ; title
+
+GetPlayerNameArray: ; 88318 This Function is never called
+ ld hl, PlayerName
+ ld de, MalePlayerNameArray
+ ld a, [PlayerGender]
+ bit 0, a
+ jr z, .done
+ ld de, FemalePlayerNameArray
+
+.done
+ call InitName
+ ret
+
+GetPlayerIcon: ; 8832c
+; Get the player icon corresponding to gender
+
+; Male
+ ld de, ChrisSpriteGFX
+ ld b, BANK(ChrisSpriteGFX)
+
+ ld a, [PlayerGender]
+ bit 0, a
+ jr z, .done
+
+; Female
+ ld de, KrisSpriteGFX
+ ld b, BANK(KrisSpriteGFX)
+
+.done
+ ret
+
+GetCardPic: ; 8833e
+ ld hl, ChrisCardPic
+ ld a, [PlayerGender]
+ bit 0, a
+ jr z, .GotClass
+ ld hl, KrisCardPic
+.GotClass:
+ ld de, VTiles2 tile $00
+ ld bc, $23 tiles
+ ld a, BANK(ChrisCardPic) ; BANK(KrisCardPic)
+ call FarCopyBytes
+ ld hl, CardGFX
+ ld de, VTiles2 tile $23
+ ld bc, 6 tiles
+ ld a, BANK(CardGFX)
+ call FarCopyBytes
+ ret
+
+ChrisCardPic: ; 88365
+INCBIN "gfx/trainer_card/chris_card.2bpp"
+
+KrisCardPic: ; 88595
+INCBIN "gfx/trainer_card/kris_card.2bpp"
+
+CardGFX: ; 887c5
+INCBIN "gfx/trainer_card/trainer_card.2bpp"
+
+GetPlayerBackpic: ; 88825
+ ld a, [PlayerGender]
+ bit 0, a
+ jr z, GetChrisBackpic
+ call GetKrisBackpic
+ ret
+
+GetChrisBackpic: ; 88830
+ ld hl, ChrisBackpic
+ ld b, BANK(ChrisBackpic)
+ ld de, VTiles2 tile $31
+ ld c, 7 * 7
+ predef DecompressPredef
+ ret
+
+HOF_LoadTrainerFrontpic: ; 88840
+ call WaitBGMap
+ xor a
+ ld [hBGMapMode], a
+ ld e, 0
+ ld a, [PlayerGender]
+ bit 0, a
+ jr z, .GotClass
+ ld e, 1
+
+.GotClass:
+ ld a, e
+ ld [TrainerClass], a
+ ld de, ChrisPic
+ ld a, [PlayerGender]
+ bit 0, a
+ jr z, .GotPic
+ ld de, KrisPic
+
+.GotPic:
+ ld hl, VTiles2
+ ld b, BANK(ChrisPic) ; BANK(KrisPic)
+ ld c, 7 * 7
+ call Get2bpp
+ call WaitBGMap
+ ld a, $1
+ ld [hBGMapMode], a
+ ret
+
+DrawIntroPlayerPic: ; 88874
+; Draw the player pic at (6,4).
+
+; Get class
+ ld e, CHRIS
+ ld a, [PlayerGender]
+ bit 0, a
+ jr z, .GotClass
+ ld e, KRIS
+.GotClass:
+ ld a, e
+ ld [TrainerClass], a
+
+; Load pic
+ ld de, ChrisPic
+ ld a, [PlayerGender]
+ bit 0, a
+ jr z, .GotPic
+ ld de, KrisPic
+.GotPic:
+ ld hl, VTiles2
+ ld b, BANK(ChrisPic) ; BANK(KrisPic)
+ ld c, 7 * 7 ; dimensions
+ call Get2bpp
+
+; Draw
+ xor a
+ ld [hGraphicStartTile], a
+ hlcoord 6, 4
+ lb bc, 7, 7
+ predef PlaceGraphic
+ ret
+
+ChrisPic: ; 888a9
+INCBIN "gfx/player/chris.2bpp"
+
+KrisPic: ; 88bb9
+INCBIN "gfx/player/kris.2bpp"
+
+GetKrisBackpic: ; 88ec9
+; Kris's backpic is uncompressed.
+ ld de, KrisBackpic
+ ld hl, VTiles2 tile $31
+ lb bc, BANK(KrisBackpic), 7 * 7 ; dimensions
+ call Get2bpp
+ ret
+
+KrisBackpic: ; 88ed6
+INCBIN "gfx/player/kris_back.2bpp"
diff --git a/engine/pokedex_3.asm b/engine/pokedex_3.asm
new file mode 100644
index 000000000..3414252c1
--- /dev/null
+++ b/engine/pokedex_3.asm
@@ -0,0 +1,162 @@
+LoadSGBPokedexGFX: ; 1ddf1c
+ ld hl, SGBPokedexGFX_LZ
+ ld de, VTiles2 tile $31
+ call Decompress
+ ret
+
+LoadSGBPokedexGFX2: ; 1ddf26 (77:5f26)
+ ld hl, SGBPokedexGFX_LZ
+ ld de, VTiles2 tile $31
+ lb bc, BANK(SGBPokedexGFX_LZ), $3a
+ call DecompressRequest2bpp
+ ret
+
+SGBPokedexGFX_LZ: ; 1ddf33
+INCBIN "gfx/pokedex/sgb.2bpp.lz"
+
+LoadQuestionMarkPic: ; 1de0d7
+ ld hl, .QuestionMarkLZ
+ ld de, sScratch
+ call Decompress
+ ret
+
+.QuestionMarkLZ: ; 1de0e1
+INCBIN "gfx/pics/questionmark/front.2bpp.lz"
+
+DrawPokedexListWindow: ; 1de171 (77:6171)
+ ld a, $32
+ hlcoord 0, 17
+ ld bc, 12
+ call ByteFill
+ hlcoord 0, 1
+ lb bc, 15, 11
+ call ClearBox
+ ld a, $34
+ hlcoord 0, 0
+ ld bc, 11
+ call ByteFill
+ ld a, $39
+ hlcoord 0, 16
+ ld bc, 11
+ call ByteFill
+ hlcoord 5, 0
+ ld [hl], $3f
+ hlcoord 5, 16
+ ld [hl], $40
+ ld a, [wCurrentDexMode]
+ cp DEXMODE_OLD
+ jr z, .OldMode
+; scroll bar
+ hlcoord 11, 0
+ ld [hl], $50
+ ld a, $51
+ hlcoord 11, 1
+ ld b, SCREEN_HEIGHT - 3
+ call Bank77_FillColumn
+ ld [hl], $52
+ jr .Done
+
+.OldMode:
+; no scroll bar
+ hlcoord 11, 0
+ ld [hl], $66
+ ld a, $67
+ hlcoord 11, 1
+ ld b, SCREEN_HEIGHT - 3
+ call Bank77_FillColumn
+ ld [hl], $68
+.Done:
+ ret
+
+DrawPokedexSearchResultsWindow: ; 1de1d1 (77:61d1)
+ ld a, $34
+ hlcoord 0, 0
+ ld bc, 11
+ call ByteFill
+ ld a, $39
+ hlcoord 0, 10
+ ld bc, 11
+ call ByteFill
+ hlcoord 5, 0
+ ld [hl], $3f
+ hlcoord 5, 10
+ ld [hl], $40
+ hlcoord 11, 0
+ ld [hl], $66
+ ld a, $67
+ hlcoord 11, 1
+ ld b, SCREEN_HEIGHT / 2
+ call Bank77_FillColumn
+ ld [hl], $68
+ ld a, $34
+ hlcoord 0, 11
+ ld bc, 11
+ call ByteFill
+ ld a, $39
+ hlcoord 0, 17
+ ld bc, 11
+ call ByteFill
+ hlcoord 11, 11
+ ld [hl], $66
+ ld a, $67
+ hlcoord 11, 12
+ ld b, 5
+ call Bank77_FillColumn
+ ld [hl], $68
+ hlcoord 0, 12
+ lb bc, 5, 11
+ call ClearBox
+ ld de, .esults_D
+ hlcoord 0, 12
+ call PlaceString
+ ret
+
+.esults_D ; 1de23c
+; (SEARCH R)
+ db "ESULTS"
+ next ""
+; (### FOUN)
+ next "D!@"
+
+DrawDexEntryScreenRightEdge: ; 1de247
+ ld a, [hBGMapAddress]
+ ld l, a
+ ld a, [hBGMapAddress + 1]
+ ld h, a
+ push hl
+ inc hl
+ ld a, l
+ ld [hBGMapAddress], a
+ ld a, h
+ ld [hBGMapAddress + 1], a
+ hlcoord 19, 0
+ ld [hl], $66
+ hlcoord 19, 1
+ ld a, $67
+ ld b, 15
+ call Bank77_FillColumn
+ ld [hl], $68
+ hlcoord 19, 17
+ ld [hl], $3c
+ xor a
+ ld b, SCREEN_HEIGHT
+ hlcoord 19, 0, AttrMap
+ call Bank77_FillColumn
+ call WaitBGMap2
+ pop hl
+ ld a, l
+ ld [hBGMapAddress], a
+ ld a, h
+ ld [hBGMapAddress + 1], a
+ ret
+
+Bank77_FillColumn: ; 1de27f
+ push de
+ ld de, SCREEN_WIDTH
+.loop
+ ld [hl], a
+ add hl, de
+ dec b
+ jr nz, .loop
+ pop de
+ ret
diff --git a/engine/pokerus.asm b/engine/pokerus.asm
new file mode 100644
index 000000000..3e5e094e4
--- /dev/null
+++ b/engine/pokerus.asm
@@ -0,0 +1,160 @@
+GivePokerusAndConvertBerries: ; 2ed44
+ call ConvertBerriesToBerryJuice
+ ld hl, PartyMon1PokerusStatus
+ ld a, [PartyCount]
+ ld b, a
+ ld de, PARTYMON_STRUCT_LENGTH
+; Check to see if any of your Pokemon already has Pokerus.
+; If so, sample its spread through your party.
+; This means that you cannot get Pokerus de novo while
+; a party member has an active infection.
+.loopMons
+ ld a, [hl]
+ and $f
+ jr nz, .TrySpreadPokerus
+ add hl, de
+ dec b
+ jr nz, .loopMons
+
+; If we haven't been to Goldenrod City at least once,
+; prevent the contraction of Pokerus.
+ ld hl, StatusFlags2
+ bit 6, [hl]
+ ret z
+ call Random
+ ld a, [hRandomAdd]
+ and a
+ ret nz
+ ld a, [hRandomSub]
+ cp $3
+ ret nc ; 3/65536 chance (00 00, 00 01 or 00 02)
+ ld a, [PartyCount]
+ ld b, a
+.randomMonSelectLoop
+ call Random
+ and $7
+ cp b
+ jr nc, .randomMonSelectLoop
+ ld hl, PartyMon1PokerusStatus
+ call GetPartyLocation ; get pokerus byte of random mon
+ ld a, [hl]
+ and $f0
+ ret nz ; if it already has pokerus, do nothing
+.randomPokerusLoop ; Simultaneously sample the strain and duration
+ call Random
+ and a
+ jr z, .randomPokerusLoop
+ ld b, a
+ and $f0
+ jr z, .load_pkrs
+ ld a, b
+ and $7
+ inc a
+.load_pkrs
+ ld b, a ; this should come before the label
+ swap b
+ and $3
+ inc a
+ add b
+ ld [hl], a
+ ret
+
+.TrySpreadPokerus:
+ call Random
+ cp 1 + 33 percent
+ ret nc ; 1/3 chance
+
+ ld a, [PartyCount]
+ cp 1
+ ret z ; only one mon, nothing to do
+
+ ld c, [hl]
+ ld a, b
+ cp 2
+ jr c, .checkPreviousMonsLoop ; no more mons after this one, go backwards
+
+ call Random
+ cp 1 + 50 percent
+ jr c, .checkPreviousMonsLoop ; 1/2 chance, go backwards
+.checkFollowingMonsLoop
+ add hl, de
+ ld a, [hl]
+ and a
+ jr z, .infectMon
+ ld c, a
+ and $3
+ ret z ; if mon has cured pokerus, stop searching
+ dec b ; go on to next mon
+ ld a, b
+ cp 1
+ jr nz, .checkFollowingMonsLoop ; no more mons left
+ ret
+
+.checkPreviousMonsLoop
+ ld a, [PartyCount]
+ cp b
+ ret z ; no more mons
+ ld a, l
+ sub e
+ ld l, a
+ ld a, h
+ sbc d
+ ld h, a
+ ld a, [hl]
+ and a
+ jr z, .infectMon
+ ld c, a
+ and $3
+ ret z ; if mon has cured pokerus, stop searching
+ inc b ; go on to next mon
+ jr .checkPreviousMonsLoop
+
+.infectMon
+ ld a, c
+ and $f0
+ ld b, a
+ ld a, c
+ swap a
+ and $3
+ inc a
+ add b
+ ld [hl], a
+ ret
+
+; any berry held by a Shuckle may be converted to berry juice
+ConvertBerriesToBerryJuice: ; 2ede6
+ ld hl, StatusFlags2
+ bit 6, [hl]
+ ret z
+ call Random
+ cp $10
+ ret nc ; 1/16 chance
+ ld hl, PartyMons
+ ld a, [PartyCount]
+.partyMonLoop
+ push af
+ push hl
+ ld a, [hl]
+ cp SHUCKLE
+ jr nz, .loopMon
+ ld bc, MON_ITEM
+ add hl, bc
+ ld a, [hl]
+ cp BERRY
+ jr z, .convertToJuice
+
+.loopMon
+ pop hl
+ ld bc, PARTYMON_STRUCT_LENGTH
+ add hl, bc
+ pop af
+ dec a
+ jr nz, .partyMonLoop
+ ret
+
+.convertToJuice
+ ld a, BERRY_JUICE
+ ld [hl], a
+ pop hl
+ pop af
+ ret
diff --git a/engine/pokerus_tick.asm b/engine/pokerus_tick.asm
new file mode 100644
index 000000000..3c97fdc5e
--- /dev/null
+++ b/engine/pokerus_tick.asm
@@ -0,0 +1,26 @@
+ApplyPokerusTick: ; 13988
+; decreases all pokemon's pokerus counter by b. if the lower nybble reaches zero, the pokerus is cured.
+ ld hl, PartyMon1PokerusStatus ; PartyMon1 + MON_PKRS
+ ld a, [PartyCount]
+ and a
+ ret z ; make sure it's not wasting time on an empty party
+ ld c, a
+.loop
+ ld a, [hl]
+ and $f ; lower nybble is the number of days remaining
+ jr z, .next ; if already 0, skip
+ sub b ; subtract the number of days
+ jr nc, .ok ; max(result, 0)
+ xor a
+.ok
+ ld d, a ; back up this value because we need to preserve the strain (upper nybble)
+ ld a, [hl]
+ and $f0
+ add d
+ ld [hl], a ; this prevents a cured pokemon from recontracting pokerus
+.next
+ ld de, PARTYMON_STRUCT_LENGTH
+ add hl, de
+ dec c
+ jr nz, .loop
+ ret
diff --git a/engine/square_root.asm b/engine/square_root.asm
new file mode 100644
index 000000000..496f66c83
--- /dev/null
+++ b/engine/square_root.asm
@@ -0,0 +1,30 @@
+GetSquareRoot: ; 13b87
+; Return the square root of de in b.
+
+; Rather than calculating the result, we take the index of the
+; first value in a table of squares that isn't lower than de.
+
+ ld hl, Squares
+ ld b, 0
+.loop
+; Make sure we don't go past the end of the table.
+ inc b
+ ld a, b
+ cp $ff
+ ret z
+
+; Iterate over the table until b**2 >= de.
+ ld a, [hli]
+ sub e
+ ld a, [hli]
+ sbc d
+
+ jr c, .loop
+ ret
+
+Squares: ; 13b98
+root set 1
+ rept $ff
+ dw root*root
+root set root+1
+ endr
diff --git a/engine/start_battle.asm b/engine/start_battle.asm
new file mode 100644
index 000000000..51f46b3f2
--- /dev/null
+++ b/engine/start_battle.asm
@@ -0,0 +1,197 @@
+ShowLinkBattleParticipants: ; 2ee18
+; If we're not in a communications room,
+; we don't need to be here.
+ ld a, [wLinkMode]
+ and a
+ ret z
+
+ callba _ShowLinkBattleParticipants
+ ld c, 150
+ call DelayFrames
+ call ClearTileMap
+ call ClearSprites
+ ret
+
+FindFirstAliveMonAndStartBattle: ; 2ee2f
+ xor a
+ ld [hMapAnims], a
+ call DelayFrame
+ ld b, 6
+ ld hl, PartyMon1HP
+ ld de, PARTYMON_STRUCT_LENGTH - 1
+
+.loop
+ ld a, [hli]
+ or [hl]
+ jr nz, .okay
+ add hl, de
+ dec b
+ jr nz, .loop
+
+.okay
+ ld de, MON_LEVEL - MON_HP
+ add hl, de
+ ld a, [hl]
+ ld [BattleMonLevel], a
+ predef Predef_StartBattle
+ callba _LoadBattleFontsHPBar
+ ld a, 1
+ ld [hBGMapMode], a
+ call ClearSprites
+ call ClearTileMap
+ xor a
+ ld [hBGMapMode], a
+ ld [hWY], a
+ ld [rWY], a
+ ld [hMapAnims], a
+ ret
+
+PlayBattleMusic: ; 2ee6c
+ push hl
+ push de
+ push bc
+
+ xor a
+ ld [MusicFade], a
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ call MaxVolume
+
+ ld a, [BattleType]
+ cp BATTLETYPE_SUICUNE
+ ld de, MUSIC_SUICUNE_BATTLE
+ jp z, .done
+ cp BATTLETYPE_ROAMING
+ jp z, .done
+
+ ; Are we fighting a trainer?
+ ld a, [OtherTrainerClass]
+ and a
+ jr nz, .trainermusic
+
+ callba RegionCheck
+ ld a, e
+ and a
+ jr nz, .kantowild
+
+ ld de, MUSIC_JOHTO_WILD_BATTLE
+ ld a, [TimeOfDay]
+ cp NITE_F
+ jr nz, .done
+ ld de, MUSIC_JOHTO_WILD_BATTLE_NIGHT
+ jr .done
+
+.kantowild
+ ld de, MUSIC_KANTO_WILD_BATTLE
+ jr .done
+
+.trainermusic
+ ld de, MUSIC_CHAMPION_BATTLE
+ cp CHAMPION
+ jr z, .done
+ cp RED
+ jr z, .done
+
+ ; really, they should have included admins and scientists here too...
+ ld de, MUSIC_ROCKET_BATTLE
+ cp GRUNTM
+ jr z, .done
+ cp GRUNTF
+ jr z, .done
+
+ ld de, MUSIC_KANTO_GYM_LEADER_BATTLE
+ callba IsKantoGymLeader
+ jr c, .done
+
+ ld de, MUSIC_JOHTO_GYM_LEADER_BATTLE
+ callba IsJohtoGymLeader
+ jr c, .done
+
+ ld de, MUSIC_RIVAL_BATTLE
+ ld a, [OtherTrainerClass]
+ cp RIVAL1
+ jr z, .done
+ cp RIVAL2
+ jr nz, .othertrainer
+
+ ld a, [OtherTrainerID]
+ cp RIVAL2_2_CHIKORITA ; Rival in Indigo Plateau
+ jr c, .done
+ ld de, MUSIC_CHAMPION_BATTLE
+ jr .done
+
+.othertrainer
+ ld a, [wLinkMode]
+ and a
+ jr nz, .johtotrainer
+
+ callba RegionCheck
+ ld a, e
+ and a
+ jr nz, .kantotrainer
+
+.johtotrainer
+ ld de, MUSIC_JOHTO_TRAINER_BATTLE
+ jr .done
+
+.kantotrainer
+ ld de, MUSIC_KANTO_TRAINER_BATTLE
+
+.done
+ call PlayMusic
+
+ pop bc
+ pop de
+ pop hl
+ ret
+
+ClearBattleRAM: ; 2ef18
+ xor a
+ ld [wPlayerAction], a
+ ld [wBattleResult], a
+
+ ld hl, wPartyMenuCursor
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+
+ ld [wMenuScrollPosition], a
+ ld [CriticalHit], a
+ ld [BattleMonSpecies], a
+ ld [wBattleParticipantsNotFainted], a
+ ld [CurBattleMon], a
+ ld [wForcedSwitch], a
+ ld [TimeOfDayPal], a
+ ld [PlayerTurnsTaken], a
+ ld [EnemyTurnsTaken], a
+ ld [EvolvableFlags], a
+
+ ld hl, PlayerHPPal
+ ld [hli], a
+ ld [hl], a
+
+ ld hl, BattleMonDVs
+ ld [hli], a
+ ld [hl], a
+
+ ld hl, EnemyMonDVs
+ ld [hli], a
+ ld [hl], a
+
+; Clear the entire BattleMons area
+ ld hl, wBattle
+ ld bc, wBattleEnd - wBattle
+ xor a
+ call ByteFill
+
+ callab ResetEnemyStatLevels
+
+ call ClearWindowData
+
+ ld hl, hBGMapAddress
+ xor a
+ ld [hli], a
+ ld [hl], VBGMap0 / $100
+ ret
diff --git a/engine/timeofdaypals.asm b/engine/timeofdaypals.asm
index 90ff9141c..a4a07bc4d 100644
--- a/engine/timeofdaypals.asm
+++ b/engine/timeofdaypals.asm
@@ -1,3 +1,7 @@
+Predef35: ; 8c000
+Predef36:
+ ret
+
UpdateTimeOfDayPal:: ; 8c001
call UpdateTime
ld a, [TimeOfDay]
diff --git a/engine/trainer_scripts.asm b/engine/trainer_scripts.asm
new file mode 100644
index 000000000..33dab3b9e
--- /dev/null
+++ b/engine/trainer_scripts.asm
@@ -0,0 +1,31 @@
+TalkToTrainerScript:: ; 0xbe66a
+ faceplayer
+ trainerflagaction CHECK_FLAG
+ iftrue AlreadyBeatenTrainerScript
+ loadmemtrainer
+ encountermusic
+ jump StartBattleWithMapTrainerScript
+
+SeenByTrainerScript:: ; 0xbe675
+ loadmemtrainer
+ encountermusic
+ showemote EMOTE_SHOCK, LAST_TALKED, 30
+ callasm TrainerWalkToPlayer
+ applymovement2 MovementBuffer
+ writepersonxy LAST_TALKED
+ faceperson PLAYER, LAST_TALKED
+ jump StartBattleWithMapTrainerScript
+
+StartBattleWithMapTrainerScript: ; 0xbe68a
+ opentext
+ trainertext $0
+ waitbutton
+ closetext
+ loadmemtrainer
+ startbattle
+ reloadmapafterbattle
+ trainerflagaction SET_FLAG
+ loadvar wRunningTrainerBattleScript, -1
+
+AlreadyBeatenTrainerScript:
+ scripttalkafter
diff --git a/engine/unused_correct_party.asm b/engine/unused_correct_party.asm
new file mode 100644
index 000000000..dd2e1111c
--- /dev/null
+++ b/engine/unused_correct_party.asm
@@ -0,0 +1,229 @@
+CorrectErrorsInPlayerParty: ; unreferenced
+ ld hl, PartyCount
+ ld a, [hl]
+ and a
+ ret z
+
+ cp PARTY_LENGTH + 1
+ jr c, .party_length_okay
+ ld a, PARTY_LENGTH
+ ld [hl], a
+.party_length_okay
+ inc hl
+
+ ld b, a
+ ld c, 0
+.loop1
+ ld a, [hl]
+ and a
+ jr z, .invalid_species
+ cp NUM_POKEMON + 1
+ jr z, .invalid_species
+ cp EGG + 1
+ jr c, .next_species
+
+.invalid_species
+ ld [hl], SMEARGLE
+ push hl
+ push bc
+ ld a, c
+ ld hl, PartyMon1Species
+ call GetPartyLocation
+ ld [hl], SMEARGLE
+ pop bc
+ pop hl
+
+.next_species
+ inc hl
+ inc c
+ dec b
+ jr nz, .loop1
+ ld [hl], $ff
+
+ ld hl, PartyMon1
+ ld a, [PartyCount]
+ ld d, a
+ ld e, 0
+.loop2
+ push de
+ push hl
+ ld b, h
+ ld c, l
+ ld a, [hl]
+ and a
+ jr z, .invalid_species_2
+ cp NUM_POKEMON + 1
+ jr c, .check_level
+
+.invalid_species_2
+ ld [hl], SMEARGLE
+ push de
+ ld d, 0
+ ld hl, PartySpecies
+ add hl, de
+ pop de
+ ld a, SMEARGLE
+ ld [hl], a
+
+.check_level
+ ld [CurSpecies], a
+ call GetBaseData
+ ld hl, MON_LEVEL
+ add hl, bc
+ ld a, [hl]
+ cp MIN_LEVEL
+ ld a, MIN_LEVEL
+ jr c, .invalid_level
+ ld a, [hl]
+ cp MAX_LEVEL
+ jr c, .load_level
+ ld a, MAX_LEVEL
+.invalid_level
+ ld [hl], a
+.load_level
+ ld [CurPartyLevel], a
+
+ ld hl, MON_MAXHP
+ add hl, bc
+ ld d, h
+ ld e, l
+ ld hl, MON_STAT_EXP - 1
+ add hl, bc
+ ld b, $1
+ predef CalcPkmnStats
+ pop hl
+ ld bc, PARTYMON_STRUCT_LENGTH
+ add hl, bc
+ pop de
+ inc e
+ dec d
+ jr nz, .loop2
+
+ ld de, PartyMonNicknames
+ ld a, [PartyCount]
+ ld b, a
+ ld c, 0
+.loop3
+ push bc
+ call .GetLengthOfStringWith6CharCap
+ push de
+ callba CheckStringForErrors
+ pop hl
+ pop bc
+ jr nc, .valid_nickname
+
+ push bc
+ push hl
+ ld hl, PartySpecies
+ push bc
+ ld b, 0
+ add hl, bc
+ pop bc
+ ld a, [hl]
+ cp EGG
+ ld hl, .TAMAGO
+ jr z, .got_nickname
+ ld [wd265], a
+ call GetPokemonName
+ ld hl, StringBuffer1
+.got_nickname
+ pop de
+ ld bc, PKMN_NAME_LENGTH
+ call CopyBytes
+ pop bc
+
+.valid_nickname
+ inc c
+ dec b
+ jr nz, .loop3
+
+ ld de, PartyMonOT
+ ld a, [PartyCount]
+ ld b, a
+ ld c, 0
+.loop4
+ push bc
+ call .GetLengthOfStringWith6CharCap
+ push de
+ callba CheckStringForErrors
+ pop hl
+ jr nc, .valid_ot_name
+ ld d, h
+ ld e, l
+ ld hl, PlayerName
+ ld bc, NAME_LENGTH
+ call CopyBytes
+.valid_ot_name
+ pop bc
+ inc c
+ dec b
+ jr nz, .loop4
+
+ ld hl, PartyMon1Moves
+ ld a, [PartyCount]
+ ld b, a
+.loop5
+ push hl
+ ld c, NUM_MOVES
+ ld a, [hl]
+ and a
+ jr z, .invalid_move
+ cp NUM_ATTACKS + 1
+ jr c, .moves_loop
+.invalid_move
+ ld [hl], POUND
+
+.moves_loop
+ ld a, [hl]
+ and a
+ jr z, .fill_invalid_moves
+ cp NUM_ATTACKS + 1
+ jr c, .next_move
+
+.fill_invalid_moves
+ xor a
+ ld [hli], a
+ dec c
+ jr nz, .fill_invalid_moves
+ jr .next_pokemon
+
+.next_move
+ inc hl
+ dec c
+ jr nz, .moves_loop
+
+.next_pokemon
+ pop hl
+ push bc
+ ld bc, PARTYMON_STRUCT_LENGTH
+ add hl, bc
+ pop bc
+ dec b
+ jr nz, .loop5
+ ret
+; 13b6b
+
+.TAMAGO: ; 13b6b
+ db "タマゴ@@@"
+; 13b71
+
+.GetLengthOfStringWith6CharCap: ; 13b71
+ push de
+ ld c, 1
+ ld b, NAME_LENGTH_JAPANESE
+.search_loop
+ ld a, [de]
+ cp "@"
+ jr z, .done
+ inc de
+ inc c
+ dec b
+ jr nz, .search_loop
+ dec c
+ dec de
+ ld a, "@"
+ ld [de], a
+.done
+ pop de
+ ret
+; 13b87