summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorentrpntr <12521136+entrpntr@users.noreply.github.com>2020-05-21 10:54:11 -0400
committerGitHub <noreply@github.com>2020-05-21 10:54:11 -0400
commitaf844aa35c0731bbee14039a274aa151e75a35d9 (patch)
tree635f15989510c45c080903ce7121d3fcbc5fb300
parentcf106d4545d6ecb08ad7434efa38ec61a38dbcb1 (diff)
parente9637cc9e67a7ebdbefdba9439e94930195fa50f (diff)
Merge pull request #34 from libjet/bank11
Disassemble bank $11
-rwxr-xr-xdata/items/fruit_trees.asm32
-rwxr-xr-xengine/battle/start_battle.asm144
-rwxr-xr-xengine/events/fruit_trees.asm116
-rwxr-xr-xengine/gfx/place_graphic.asm55
-rwxr-xr-xengine/pokemon/mail.asm565
-rw-r--r--main.asm28
-rw-r--r--wram.asm22
7 files changed, 924 insertions, 38 deletions
diff --git a/data/items/fruit_trees.asm b/data/items/fruit_trees.asm
new file mode 100755
index 00000000..9c4e4793
--- /dev/null
+++ b/data/items/fruit_trees.asm
@@ -0,0 +1,32 @@
+FruitTreeItems:
+; entries correspond to FRUITTREE_* constants
+ db BERRY ; ROUTE_29
+ db BERRY ; ROUTE_30_1
+ db BERRY ; ROUTE_38
+ db BERRY ; ROUTE_46_1
+ db PSNCUREBERRY ; ROUTE_30_2
+ db PSNCUREBERRY ; ROUTE_33
+ db BITTER_BERRY ; ROUTE_31
+ db BITTER_BERRY ; ROUTE_43
+ db PRZCUREBERRY ; VIOLET_CITY
+ db PRZCUREBERRY ; ROUTE_46_2
+ db MYSTERYBERRY ; ROUTE_35
+ db MYSTERYBERRY ; ROUTE_45
+ db ICE_BERRY ; ROUTE_36
+ db ICE_BERRY ; ROUTE_26
+ db MINT_BERRY ; ROUTE_39
+ db BURNT_BERRY ; ROUTE_44
+ db RED_APRICORN ; ROUTE_37_1
+ db BLU_APRICORN ; ROUTE_37_2
+ db BLK_APRICORN ; ROUTE_37_3
+ db WHT_APRICORN ; AZALEA_TOWN
+ db PNK_APRICORN ; ROUTE_42_1
+ db GRN_APRICORN ; ROUTE_42_2
+ db YLW_APRICORN ; ROUTE_42_3
+ db BERRY ; ROUTE_11
+ db PSNCUREBERRY ; ROUTE_2
+ db BITTER_BERRY ; ROUTE_1
+ db PRZCUREBERRY ; ROUTE_8
+ db ICE_BERRY ; PEWTER_CITY_1
+ db MINT_BERRY ; PEWTER_CITY_2
+ db BURNT_BERRY ; FUCHSIA_CITY
diff --git a/engine/battle/start_battle.asm b/engine/battle/start_battle.asm
new file mode 100755
index 00000000..7627a100
--- /dev/null
+++ b/engine/battle/start_battle.asm
@@ -0,0 +1,144 @@
+PlayBattleMusic:
+ push hl
+ push de
+ push bc
+
+ xor a
+ ld [wMusicFade], a
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ call MaxVolume
+
+ ; Are we fighting a trainer?
+ ld a, [wOtherTrainerClass]
+ and a
+ jr nz, .trainermusic
+
+ farcall RegionCheck
+ ld a, e
+ and a
+ jr nz, .kantowild
+
+ ld de, MUSIC_JOHTO_WILD_BATTLE
+ ld a, [wTimeOfDay]
+ 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
+
+ ; They should have included EXECUTIVEM, EXECUTIVEF, and SCIENTIST too...
+ ld de, MUSIC_ROCKET_BATTLE
+ cp GRUNTM
+ jr z, .done
+ cp GRUNTF
+ jr z, .done
+
+ ld de, MUSIC_KANTO_GYM_LEADER_BATTLE
+ farcall IsKantoGymLeader
+ jr c, .done
+
+ ; IsGymLeader also counts CHAMPION, RED, and the Kanto gym leaders
+ ; but they have been taken care of before this
+ ld de, MUSIC_JOHTO_GYM_LEADER_BATTLE
+ farcall IsGymLeader
+ jr c, .done
+
+ ld de, MUSIC_RIVAL_BATTLE
+ ld a, [wOtherTrainerClass]
+ cp RIVAL1
+ jr z, .done
+ cp RIVAL2
+ jr nz, .othertrainer
+
+ ld a, [wOtherTrainerID]
+ 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
+
+ farcall 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:
+ xor a
+ ld [wBattlePlayerAction], a
+ ld [wBattleResult], a
+
+ ld hl, wPartyMenuCursor
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+
+ ld [wMenuScrollPosition], a
+ ld [wCriticalHit], a
+ ld [wBattleMonSpecies], a
+ ld [wBattleParticipantsNotFainted], a
+ ld [wCurBattleMon], a
+ ld [wForcedSwitch], a
+ ld [wTimeOfDayPal], a
+ ld [wPlayerTurnsTaken], a
+ ld [wEnemyTurnsTaken], a
+ ld [wEvolvableFlags], a
+
+ ld hl, wPlayerHPPal
+ ld [hli], a
+ ld [hl], a
+
+ ld hl, wBattleMonDVs
+ ld [hli], a
+ ld [hl], a
+
+ ld hl, wEnemyMonDVs
+ ld [hli], a
+ ld [hl], a
+
+; Clear the entire BattleMons area
+ ld hl, wBattle
+ ld bc, wBattleEnd - wBattle
+ xor a
+ call ByteFill
+
+ callfar ResetEnemyStatLevels
+
+ call ClearWindowData
+
+ ld hl, hBGMapAddress
+ xor a ; LOW(vBGMap0)
+ ld [hli], a
+ ld [hl], HIGH(vBGMap0)
+ ret
diff --git a/engine/events/fruit_trees.asm b/engine/events/fruit_trees.asm
new file mode 100755
index 00000000..0177eb6f
--- /dev/null
+++ b/engine/events/fruit_trees.asm
@@ -0,0 +1,116 @@
+FruitTreeScript::
+ callasm GetCurTreeFruit
+ opentext
+ readmem wCurFruit
+ getitemname STRING_BUFFER_3, USE_SCRIPT_VAR
+ writetext FruitBearingTreeText
+ promptbutton
+ callasm TryResetFruitTrees
+ callasm CheckFruitTree
+ iffalse .fruit
+ writetext NothingHereText
+ waitbutton
+ sjump .end
+
+.fruit
+ writetext HeyItsFruitText
+ readmem wCurFruit
+ giveitem ITEM_FROM_MEM
+ iffalse .packisfull
+ promptbutton
+ writetext ObtainedFruitText
+ callasm PickedFruitTree
+ specialsound
+ itemnotify
+ sjump .end
+
+.packisfull
+ promptbutton
+ writetext FruitPackIsFullText
+ waitbutton
+
+.end
+ closetext
+ end
+
+GetCurTreeFruit:
+ ld a, [wCurFruitTree]
+ dec a
+ call GetFruitTreeItem
+ ld [wCurFruit], a
+ ret
+
+TryResetFruitTrees:
+ ld hl, wDailyFlags1
+ bit DAILYFLAGS1_ALL_FRUIT_TREES_F, [hl]
+ ret nz
+ jp ResetFruitTrees
+
+CheckFruitTree:
+ ld b, 2
+ call GetFruitTreeFlag
+ ld a, c
+ ld [wScriptVar], a
+ ret
+
+PickedFruitTree:
+ ld b, 1
+ jp GetFruitTreeFlag
+
+ResetFruitTrees:
+ xor a
+ ld hl, wFruitTreeFlags
+ ld [hli], a
+ ld [hli], a
+ ld [hli], a
+ ld [hl], a
+ ld hl, wDailyFlags1
+ set DAILYFLAGS1_ALL_FRUIT_TREES_F, [hl]
+ ret
+
+GetFruitTreeFlag:
+ push hl
+ push de
+ ld a, [wCurFruitTree]
+ dec a
+ ld e, a
+ ld d, 0
+ ld hl, wFruitTreeFlags
+ call FlagAction
+ pop de
+ pop hl
+ ret
+
+GetFruitTreeItem:
+ push hl
+ push de
+ ld e, a
+ ld d, 0
+ ld hl, FruitTreeItems
+ add hl, de
+ ld a, [hl]
+ pop de
+ pop hl
+ ret
+
+INCLUDE "data/items/fruit_trees.asm"
+
+FruitBearingTreeText:
+ text_far _FruitBearingTreeText
+ text_end
+
+HeyItsFruitText:
+ text_far _HeyItsFruitText
+ text_end
+
+ObtainedFruitText:
+ text_far _ObtainedFruitText
+ text_end
+
+FruitPackIsFullText:
+ text_far _FruitPackIsFullText
+ text_end
+
+NothingHereText:
+ text_far _NothingHereText
+ text_end
diff --git a/engine/gfx/place_graphic.asm b/engine/gfx/place_graphic.asm
new file mode 100755
index 00000000..4092ad35
--- /dev/null
+++ b/engine/gfx/place_graphic.asm
@@ -0,0 +1,55 @@
+PlaceGraphic:
+; Fill wBoxAlignment-aligned box width b height c
+; with iterating tile starting from hGraphicStartTile at hl.
+
+ ld de, SCREEN_WIDTH
+
+ ld a, [wBoxAlignment]
+ and a
+ jr nz, .right
+
+ ldh a, [hGraphicStartTile]
+.x1
+ push bc
+ push hl
+
+.y1
+ ld [hl], a
+ add hl, de
+ inc a
+ dec c
+ jr nz, .y1
+
+ pop hl
+ inc hl
+ pop bc
+ dec b
+ jr nz, .x1
+ ret
+
+.right
+; Right-aligned.
+ push bc
+ ld b, 0
+ dec c
+ add hl, bc
+ pop bc
+
+ ldh a, [hGraphicStartTile]
+.x2
+ push bc
+ push hl
+
+.y2
+ ld [hl], a
+ add hl, de
+ inc a
+ dec c
+ jr nz, .y2
+
+ pop hl
+ dec hl
+ pop bc
+ dec b
+ jr nz, .x2
+ ret
diff --git a/engine/pokemon/mail.asm b/engine/pokemon/mail.asm
new file mode 100755
index 00000000..9da39149
--- /dev/null
+++ b/engine/pokemon/mail.asm
@@ -0,0 +1,565 @@
+SendMailToPC:
+ ld a, MON_ITEM
+ call GetPartyParamLocation
+ ld d, [hl]
+ farcall ItemIsMail
+ jr nc, .full
+ call GetMailboxCount
+ cp MAILBOX_CAPACITY
+ jr nc, .full
+ ld bc, MAIL_STRUCT_LENGTH
+ ld hl, sMailbox
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld a, [wCurPartyMon]
+ ld bc, MAIL_STRUCT_LENGTH
+ ld hl, sPartyMail
+ call AddNTimes
+ push hl
+ ld a, BANK(sMailboxCount)
+ call OpenSRAM
+ ld bc, MAIL_STRUCT_LENGTH
+ call CopyBytes
+ pop hl
+ xor a
+ ld bc, MAIL_STRUCT_LENGTH
+ call ByteFill
+ ld a, MON_ITEM
+ call GetPartyParamLocation
+ ld [hl], 0
+ ld hl, sMailboxCount
+ inc [hl]
+ call CloseSRAM
+ xor a
+ ret
+
+.full
+ scf
+ ret
+
+DeleteMailFromPC:
+; Shift all mail messages in the mailbox
+ ld a, BANK(sMailboxCount)
+ call OpenSRAM
+ ld a, b
+ push bc
+ ld hl, sMailbox
+ ld bc, MAIL_STRUCT_LENGTH
+ call AddNTimes
+ push hl
+ add hl, bc
+ pop de
+ pop bc
+.loop
+ ld a, b
+ cp MAILBOX_CAPACITY - 1
+ jr z, .done
+ push bc
+ ld bc, MAIL_STRUCT_LENGTH
+ call CopyBytes
+ pop bc
+ inc b
+ jr .loop
+.done
+ ld h, d
+ ld l, e
+ xor a
+ ld bc, MAIL_STRUCT_LENGTH
+ call ByteFill
+ ld hl, sMailboxCount
+ dec [hl]
+ jp CloseSRAM
+
+ReadMailMessage:
+ ld a, b
+ ld hl, sMailbox
+ ld bc, MAIL_STRUCT_LENGTH
+ call AddNTimes
+ ld d, h
+ ld e, l
+ farcall ReadAnyMail
+ ret
+
+MoveMailFromPCToParty:
+ ld a, BANK(sMailboxCount)
+ call OpenSRAM
+ push bc
+ ld a, b
+ ld bc, MAIL_STRUCT_LENGTH
+ ld hl, sMailbox
+ call AddNTimes
+ push hl
+ ld a, [wCurPartyMon]
+ ld bc, MAIL_STRUCT_LENGTH
+ ld hl, sPartyMail
+ call AddNTimes
+ ld d, h
+ ld e, l
+ pop hl
+ push hl
+ ld bc, MAIL_STRUCT_LENGTH
+ call CopyBytes
+ pop hl
+ ld de, PARTYMON_STRUCT_LENGTH - MON_MOVES
+ add hl, de
+ ld d, [hl]
+ ld a, [wCurPartyMon]
+ ld hl, wPartyMon1Item
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+ ld [hl], d
+ call CloseSRAM
+ pop bc
+ jp DeleteMailFromPC
+
+GetMailboxCount:
+ ld a, BANK(sMailboxCount)
+ call OpenSRAM
+ ld a, [sMailboxCount]
+ ld c, a
+ jp CloseSRAM
+
+CheckPokeMail::
+ push bc
+ push de
+ farcall SelectMonFromParty
+ ld a, POKEMAIL_REFUSED
+ jr c, .pop_return
+
+ ld a, [wCurPartyMon]
+ ld hl, wPartyMon1Item
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+ ld d, [hl]
+ farcall ItemIsMail
+ ld a, POKEMAIL_NO_MAIL
+ jr nc, .pop_return
+
+ ld a, BANK(sPartyMail)
+ call OpenSRAM
+ ld a, [wCurPartyMon]
+ ld hl, sPartyMail
+ ld bc, MAIL_STRUCT_LENGTH
+ call AddNTimes
+ ld d, h
+ ld e, l
+ pop hl
+ pop bc
+
+; Compare the mail message, byte for byte, with the expected message.
+ ld a, MAIL_MSG_LENGTH
+ ld [wTempByteValue], a
+.loop
+ ld a, [de]
+ ld c, a
+ ld a, b
+ call GetFarByte
+ cp "@"
+ jr z, .done
+ cp c
+ ld a, POKEMAIL_WRONG_MAIL
+ jr nz, .close_sram_return
+ inc hl
+ inc de
+ ld a, [wTempByteValue]
+ dec a
+ ld [wTempByteValue], a
+ jr nz, .loop
+
+.done
+ farcall CheckCurPartyMonFainted
+ ld a, POKEMAIL_LAST_MON
+ jr c, .close_sram_return
+ xor a ; REMOVE_PARTY
+ ld [wPokemonWithdrawDepositParameter], a
+ farcall RemoveMonFromPartyOrBox
+ ld a, POKEMAIL_CORRECT
+
+.close_sram_return
+ call CloseSRAM
+ jr .return
+
+.pop_return
+ pop de
+ pop bc
+
+.return
+ ld [wScriptVar], a
+ ret
+
+GivePokeMail::
+ ld a, [wPartyCount]
+ dec a
+ push af
+ push bc
+ ld hl, wPartyMon1Item
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+ pop bc
+ ld [hl], b
+ pop af
+ push bc
+ push af
+ ld hl, sPartyMail
+ ld bc, MAIL_STRUCT_LENGTH
+ call AddNTimes
+ ld d, h
+ ld e, l
+ ld hl, wceed
+ ld bc, MAIL_MSG_LENGTH + 1
+ ld a, BANK(sPartyMail)
+ call OpenSRAM
+ call CopyBytes
+ pop af
+ push af
+ ld hl, wPartyMonOT
+ ld bc, NAME_LENGTH
+ call AddNTimes
+ ld bc, NAME_LENGTH - 1
+ call CopyBytes
+ pop af
+ ld hl, wPartyMon1ID
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+ ld a, [hli]
+ ld [de], a
+ inc de
+ ld a, [hl]
+ ld [de], a
+ inc de
+ ld a, [wCurPartySpecies]
+ ld [de], a
+ inc de
+ pop bc
+ ld a, b
+ ld [de], a
+ jp CloseSRAM
+
+BackupPartyMonMail:
+ ld a, BANK(sPartyMail)
+ call OpenSRAM
+ ld hl, sPartyMail
+ ld de, sPartyMailBackup
+ ld bc, 6 * MAIL_STRUCT_LENGTH
+ call CopyBytes
+ ld hl, sMailboxCount
+ ld de, sMailboxCountBackup
+ ld bc, 1 + 10 * MAIL_STRUCT_LENGTH
+ call CopyBytes
+ jp CloseSRAM
+
+RestorePartyMonMail:
+ ld a, BANK(sPartyMail)
+ call OpenSRAM
+ ld hl, sPartyMailBackup
+ ld de, sPartyMail
+ ld bc, 6 * MAIL_STRUCT_LENGTH
+ call CopyBytes
+ ld hl, sMailboxCountBackup
+ ld de, sMailboxCount
+ ld bc, 1 + 10 * MAIL_STRUCT_LENGTH
+ call CopyBytes
+ jp CloseSRAM
+
+DeletePartyMonMail:
+ ld a, BANK(sPartyMail)
+ call OpenSRAM
+ xor a
+ ld hl, sPartyMail
+ ld bc, 6 * MAIL_STRUCT_LENGTH
+ call ByteFill
+ xor a
+ ld hl, sMailboxCount
+ ld bc, 1 + 10 * MAIL_STRUCT_LENGTH
+ call ByteFill
+ jp CloseSRAM
+
+IsAnyMonHoldingMail:
+ ld a, [wPartyCount]
+ and a
+ jr z, .no_mons
+ ld e, a
+ ld hl, wPartyMon1Item
+.loop
+ ld d, [hl]
+ push hl
+ push de
+ farcall ItemIsMail
+ pop de
+ pop hl
+ ret c
+ ld bc, PARTYMON_STRUCT_LENGTH
+ add hl, bc
+ dec e
+ jr nz, .loop
+
+.no_mons
+ and a
+ ret
+
+_PlayerMailBoxMenu:
+ call InitMail
+ jr z, .nomail
+ call LoadStandardMenuHeader
+ call MailboxPC
+ jp CloseWindow
+
+.nomail
+ ld hl, .EmptyMailboxText
+ jp MenuTextboxBackup
+
+.EmptyMailboxText:
+ text_far _EmptyMailboxText
+ text_end
+
+InitMail:
+; initialize wMailboxCount and beyond with incrementing values, one per mail
+; set z if no mail
+ ld a, BANK(sMailboxCount)
+ call OpenSRAM
+ ld a, [sMailboxCount]
+ call CloseSRAM
+ ld hl, wMailboxCount
+ ld [hli], a
+ and a
+
+ jr z, .done ; if no mail, we're done
+
+ ; load values in memory with incrementing values starting at wMailboxCount
+ ld b, a
+ ld a, 1
+.loop
+ ld [hli], a
+ inc a
+ dec b
+ jr nz, .loop
+.done
+ ld [hl], -1 ; terminate
+
+ ld a, [wMailboxCount]
+ and a
+ ret
+
+MailboxPC_GetMailAuthor:
+ dec a
+ ld hl, sMailbox1Author
+ ld bc, MAIL_STRUCT_LENGTH
+ call AddNTimes
+ ld a, BANK(sMailboxCount)
+ call OpenSRAM
+ ld de, wStringBuffer2
+ push de
+ ld bc, NAME_LENGTH - 1
+ call CopyBytes
+ ld a, "@"
+ ld [de], a
+ call CloseSRAM
+ pop de
+ ret
+
+MailboxPC_PrintMailAuthor:
+ push de
+ ld a, [wMenuSelection]
+ call MailboxPC_GetMailAuthor
+ pop hl
+ jp PlaceString
+
+MailboxPC:
+ xor a
+ ld [wCurMessageScrollPosition], a
+ ld a, 1
+ ld [wCurMessageIndex], a
+.loop
+ call InitMail
+ ld hl, .TopMenuHeader
+ call CopyMenuHeader
+ xor a
+ ldh [hBGMapMode], a
+ call InitScrollingMenu
+ call UpdateSprites
+
+ ld a, [wCurMessageIndex]
+ ld [wMenuCursorBuffer], a
+ ld a, [wCurMessageScrollPosition]
+ ld [wMenuScrollPosition], a
+ call ScrollingMenu
+ ld a, [wMenuScrollPosition]
+ ld [wCurMessageScrollPosition], a
+ ld a, [wMenuCursorY]
+ ld [wCurMessageIndex], a
+
+ ld a, [wMenuJoypad]
+ cp B_BUTTON
+ jr z, .exit
+ call .Submenu
+ jr .loop
+
+.exit
+ xor a
+ ret
+
+.Submenu:
+ ld hl, .SubMenuHeader
+ call LoadMenuHeader
+ call VerticalMenu
+ call ExitMenu
+ jr c, .subexit
+ ld a, [wMenuCursorY]
+ dec a
+ ld hl, .JumpTable
+ rst JumpTable
+
+.subexit
+ ret
+
+.JumpTable:
+ dw .ReadMail
+ dw .PutInPack
+ dw .AttachMail
+ dw .Cancel
+
+.ReadMail:
+ call FadeToMenu
+ ld a, [wMenuSelection]
+ dec a
+ ld b, a
+ call ReadMailMessage
+ jp CloseSubmenu
+
+.PutInPack:
+ ld hl, .MailMessageLostText
+ call MenuTextbox
+ call YesNoBox
+ call ExitMenu
+ ret c
+ ld a, [wMenuSelection]
+ dec a
+ call .GetMailType
+ ld a, 1
+ ld [wItemQuantityChangeBuffer], a
+ ld hl, wNumItems
+ call ReceiveItem
+ jr c, .put_in_bag
+ ld hl, .MailPackFullText
+ jp MenuTextboxBackup
+
+.put_in_bag
+ ld a, [wMenuSelection]
+ dec a
+ ld b, a
+ call DeleteMailFromPC
+ ld hl, .MailClearedPutAwayText
+ jp MenuTextboxBackup
+
+.MailClearedPutAwayText:
+ text_far _MailClearedPutAwayText
+ text_end
+
+.MailPackFullText:
+ text_far _MailPackFullText
+ text_end
+
+.MailMessageLostText:
+ text_far _MailMessageLostText
+ text_end
+
+.GetMailType:
+ push af
+ ld a, BANK(sMailboxCount)
+ call OpenSRAM
+ pop af
+ ld hl, sMailbox1Type
+ ld bc, MAIL_STRUCT_LENGTH
+ call AddNTimes
+ ld a, [hl]
+ ld [wCurItem], a
+ jp CloseSRAM
+
+.AttachMail:
+ call FadeToMenu
+ xor a
+ ld [wPartyMenuActionText], a
+ call ClearBGPalettes
+.try_again
+ farcall LoadPartyMenuGFX
+ farcall InitPartyMenuWithCancel
+ farcall InitPartyMenuGFX
+ farcall WritePartyMenuTilemap
+ farcall PrintPartyMenuText
+ call WaitBGMap
+ call SetPalettes
+ call DelayFrame
+ farcall PartyMenuSelect
+ jr c, .exit2
+ ld a, [wCurPartySpecies]
+ cp EGG
+ jr z, .egg
+ ld a, MON_ITEM
+ call GetPartyParamLocation
+ ld a, [hl]
+ and a
+ jr z, .attach_mail
+ ld hl, .MailAlreadyHoldingItemText
+ call PrintText
+ jr .try_again
+
+.egg
+ ld hl, .MailEggText
+ call PrintText
+ jr .try_again
+
+.attach_mail
+ ld a, [wMenuSelection]
+ dec a
+ ld b, a
+ call MoveMailFromPCToParty
+ ld hl, .MailMovedFromBoxText
+ call PrintText
+
+.exit2
+ jp CloseSubmenu
+
+.MailAlreadyHoldingItemText:
+ text_far _MailAlreadyHoldingItemText
+ text_end
+
+.MailEggText:
+ text_far _MailEggText
+ text_end
+
+.MailMovedFromBoxText:
+ text_far _MailMovedFromBoxText
+ text_end
+
+.Cancel:
+ ret
+
+.TopMenuHeader:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 8, 1, SCREEN_WIDTH - 2, 10
+ dw .TopMenuData
+ db 1 ; default option
+
+.TopMenuData:
+ db SCROLLINGMENU_DISPLAY_ARROWS ; flags
+ db 4, 0 ; rows, columns
+ db SCROLLINGMENU_ITEMS_NORMAL ; item format
+ dbw 0, wMailboxCount ; text pointer
+ dba MailboxPC_PrintMailAuthor
+ dba NULL
+ dba NULL
+
+.SubMenuHeader:
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 0, 0, 13, 9
+ dw .SubMenuData
+ db 1 ; default option
+
+.SubMenuData:
+ db STATICMENU_CURSOR ; flags
+ db 4 ; items
+ db "READ MAIL@"
+ db "PUT IN PACK@"
+ db "ATTACH MAIL@"
+ db "CANCEL@"
diff --git a/main.asm b/main.asm
index 5f74bc3b..31eb277f 100644
--- a/main.asm
+++ b/main.asm
@@ -346,32 +346,12 @@ INCLUDE "engine/pokemon/evolve.asm"
SECTION "bank11", ROMX
-FruitTreeScript::
- dr $44000, $440c8
+INCLUDE "engine/events/fruit_trees.asm"
INCLUDE "engine/battle/ai/move.asm"
INCLUDE "engine/pokedex/pokedex_2.asm"
-PlayBattleMusic::
- dr $44556, $445f2
-ClearBattleRAM::
- dr $445f2, $44648
-PlaceGraphic::
- dr $44648, $44679
-SendMailToPC::
- dr $44679, $4475f
-CheckPokeMail::
- dr $4475f, $447d7
-GivePokeMail::
- dr $447d7, $44830
-BackupPartyMonMail::
- dr $44830, $44850
-RestorePartyMonMail::
- dr $44850, $44870
-DeletePartyMonMail::
- dr $44870, $4488c
-IsAnyMonHoldingMail::
- dr $4488c, $448ab
-_PlayerMailBoxMenu::
- dr $448ab, $44aa2
+INCLUDE "engine/battle/start_battle.asm"
+INCLUDE "engine/gfx/place_graphic.asm"
+INCLUDE "engine/pokemon/mail.asm"
SECTION "bank14", ROMX
diff --git a/wram.asm b/wram.asm
index 9c593d4f..c2b23477 100644
--- a/wram.asm
+++ b/wram.asm
@@ -599,7 +599,7 @@ wBattleAnimOAMPointerLo:: db ; ca18
ds 207
-wBattle: ; cae8
+wBattle:: ; cae8
wEnemyMoveStruct:: move_struct wEnemyMoveStruct
wPlayerMoveStruct:: move_struct wPlayerMoveStruct
@@ -2531,19 +2531,13 @@ wMomItemTriggerBalance:: ds 3 ; d963
wDailyResetTimer:: dw ; d966
wDailyFlags1:: db ; d968
wDailyFlags2:: db ; d969
-wd96a:: ds 1 ; d96a
-wd96b:: ds 1 ; d96b
-wd96c:: ds 1 ; d96c
-wTimerEventStartDay:: db ; d96d
-wd96e:: ds 1 ; d96e
-wd96f:: ds 1 ; d96f
-wd970:: ds 1 ; d970
-wd971:: ds 1 ; d971
-wd972:: ds 1 ; d972
-wd973:: ds 1 ; d973
-wd974:: ds 1 ; d974
-wd975:: ds 1 ; d975
-wd976:: ds 1 ; d976
+ ds 3
+wTimerEventStartDay:: db
+ ds 3
+
+wFruitTreeFlags:: flag_array NUM_FRUIT_TREES ; d971
+
+ ds 2
wLuckyNumberDayBuffer:: dw ; d977
wd979:: ds 1 ; d979