summaryrefslogtreecommitdiff
path: root/engine/items
diff options
context:
space:
mode:
authormid-kid <esteve.varela@gmail.com>2018-03-14 13:28:36 +0100
committermid-kid <esteve.varela@gmail.com>2018-03-14 13:28:36 +0100
commit97c511cd2f271252cbc9e9746668081422231ca5 (patch)
tree35ef1cb72e871ef34e2b0011e514edae2b9cbcb7 /engine/items
parentbaa0dc5a963a79843b37888bcfe1d2dfe833ade9 (diff)
Organize the engine/ directory, take 2
Renamed `game` to `games` and `menu` to `menus`. Moved some functions from `engine/routines/` to their fitting subdirectories. Made two new subdirectories: * engine/rtc: Contains all RTC-related things. Menus, hardware, misc functions. * engine/items: Contains all item-related things. Pack, item effects, other item handlers.
Diffstat (limited to 'engine/items')
-rwxr-xr-xengine/items/buy_sell_toss.asm235
-rw-r--r--engine/items/item_effects.asm3118
-rwxr-xr-xengine/items/items.asm581
-rwxr-xr-xengine/items/mart.asm970
-rw-r--r--engine/items/pack.asm1711
-rw-r--r--engine/items/printitemdescription.asm31
-rwxr-xr-xengine/items/switch_items.asm274
-rwxr-xr-xengine/items/tmhm.asm49
-rw-r--r--engine/items/updateitemdescription.asm13
9 files changed, 6982 insertions, 0 deletions
diff --git a/engine/items/buy_sell_toss.asm b/engine/items/buy_sell_toss.asm
new file mode 100755
index 000000000..84481d030
--- /dev/null
+++ b/engine/items/buy_sell_toss.asm
@@ -0,0 +1,235 @@
+SelectQuantityToToss: ; 24fbf
+ ld hl, TossItem_MenuHeader
+ call LoadMenuHeader
+ call Toss_Sell_Loop
+ ret
+; 24fc9
+
+SelectQuantityToBuy: ; 24fc9
+ farcall GetItemPrice
+RooftopSale_SelectQuantityToBuy: ; 24fcf
+ ld a, d
+ ld [wBuffer1], a
+ ld a, e
+ ld [wBuffer2], a
+ ld hl, BuyItem_MenuHeader
+ call LoadMenuHeader
+ call Toss_Sell_Loop
+ ret
+; 24fe1
+
+SelectQuantityToSell: ; 24fe1
+ farcall GetItemPrice
+ ld a, d
+ ld [wBuffer1], a
+ ld a, e
+ ld [wBuffer2], a
+ ld hl, SellItem_MenuHeader
+ call LoadMenuHeader
+ call Toss_Sell_Loop
+ ret
+; 24ff9
+
+Toss_Sell_Loop: ; 24ff9
+ ld a, 1
+ ld [wItemQuantityChangeBuffer], a
+.loop
+ call BuySellToss_UpdateQuantityDisplay ; update display
+ call BuySellToss_InterpretJoypad ; joy action
+ jr nc, .loop
+ cp -1
+ jr nz, .nope ; pressed B
+ scf
+ ret
+
+.nope
+ and a
+ ret
+; 2500e
+
+BuySellToss_InterpretJoypad: ; 2500e
+ call JoyTextDelay_ForcehJoyDown ; get joypad
+ bit B_BUTTON_F, c
+ jr nz, .b
+ bit A_BUTTON_F, c
+ jr nz, .a
+ bit D_DOWN_F, c
+ jr nz, .down
+ bit D_UP_F, c
+ jr nz, .up
+ bit D_LEFT_F, c
+ jr nz, .left
+ bit D_RIGHT_F, c
+ jr nz, .right
+ and a
+ ret
+
+.b
+ ld a, -1
+ scf
+ ret
+
+.a
+ ld a, 0
+ scf
+ ret
+
+.down
+ ld hl, wItemQuantityChangeBuffer
+ dec [hl]
+ jr nz, .finish_down
+ ld a, [wItemQuantityBuffer]
+ ld [hl], a
+
+.finish_down
+ and a
+ ret
+
+.up
+ ld hl, wItemQuantityChangeBuffer
+ inc [hl]
+ ld a, [wItemQuantityBuffer]
+ cp [hl]
+ jr nc, .finish_up
+ ld [hl], 1
+
+.finish_up
+ and a
+ ret
+
+.left
+ ld a, [wItemQuantityChangeBuffer]
+ sub 10
+ jr c, .load_1
+ jr z, .load_1
+ jr .finish_left
+
+.load_1
+ ld a, 1
+
+.finish_left
+ ld [wItemQuantityChangeBuffer], a
+ and a
+ ret
+
+.right
+ ld a, [wItemQuantityChangeBuffer]
+ add 10
+ ld b, a
+ ld a, [wItemQuantityBuffer]
+ cp b
+ jr nc, .finish_right
+ ld b, a
+
+.finish_right
+ ld a, b
+ ld [wItemQuantityChangeBuffer], a
+ and a
+ ret
+; 25072
+
+BuySellToss_UpdateQuantityDisplay: ; 25072
+ call MenuBox
+ call MenuBoxCoord2Tile
+ ld de, SCREEN_WIDTH + 1
+ add hl, de
+ ld [hl], "×"
+ inc hl
+ ld de, wItemQuantityChangeBuffer
+ lb bc, PRINTNUM_LEADINGZEROS | 1, 2
+ call PrintNum
+ ld a, [wMenuDataPointer]
+ ld e, a
+ ld a, [wMenuDataPointer + 1]
+ ld d, a
+ ld a, [wMenuDataBank]
+ call FarCall_de
+ ret
+; 25097
+
+ret_25097: ; 25097
+ ret
+; 25098
+
+DisplayPurchasePrice: ; 25098
+ call BuySell_MultiplyPrice
+ call BuySell_DisplaySubtotal
+ ret
+; 2509f
+
+DisplaySellingPrice: ; 2509f
+ call BuySell_MultiplyPrice
+ call Sell_HalvePrice
+ call BuySell_DisplaySubtotal
+ ret
+; 250a9
+
+BuySell_MultiplyPrice: ; 250a9
+ xor a
+ ld [hMultiplicand + 0], a
+ ld a, [wBuffer1]
+ ld [hMultiplicand + 1], a
+ ld a, [wBuffer2]
+ ld [hMultiplicand + 2], a
+ ld a, [wItemQuantityChangeBuffer]
+ ld [hMultiplier], a
+ push hl
+ call Multiply
+ pop hl
+ ret
+; 250c1
+
+Sell_HalvePrice: ; 250c1
+ push hl
+ ld hl, hProduct + 1
+ ld a, [hl]
+ srl a
+ ld [hli], a
+ ld a, [hl]
+ rra
+ ld [hli], a
+ ld a, [hl]
+ rra
+ ld [hl], a
+ pop hl
+ ret
+; 250d1
+
+BuySell_DisplaySubtotal: ; 250d1
+ push hl
+ ld hl, hMoneyTemp
+ ld a, [hProduct + 1]
+ ld [hli], a
+ ld a, [hProduct + 2]
+ ld [hli], a
+ ld a, [hProduct + 3]
+ ld [hl], a
+ pop hl
+ inc hl
+ ld de, hMoneyTemp
+ lb bc, PRINTNUM_MONEY | 3, 6
+ call PrintNum
+ call WaitBGMap
+ ret
+; 250ed
+
+TossItem_MenuHeader: ; 0x250ed
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 15, 9, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw ret_25097
+ db 0 ; default option
+; 0x250f5
+
+BuyItem_MenuHeader: ; 0x250f5
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 15, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw DisplayPurchasePrice
+ db -1 ; default option
+; 0x250fd
+
+SellItem_MenuHeader: ; 0x250fd
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 15, SCREEN_WIDTH - 1, SCREEN_HEIGHT - 1
+ dw DisplaySellingPrice
+ db 0 ; default option
+; 0x25105
diff --git a/engine/items/item_effects.asm b/engine/items/item_effects.asm
new file mode 100644
index 000000000..0b5285608
--- /dev/null
+++ b/engine/items/item_effects.asm
@@ -0,0 +1,3118 @@
+_DoItemEffect:: ; e722
+ ld a, [wCurItem]
+ ld [wd265], a
+ call GetItemName
+ call CopyName1
+ ld a, 1
+ ld [wItemEffectSucceeded], a
+ ld a, [wCurItem]
+ dec a
+ ld hl, ItemEffects
+ rst JumpTable
+ ret
+; e73c
+
+
+ItemEffects: ; e73c
+; entries correspond to item ids
+ dw PokeBallEffect ; MASTER_BALL
+ dw PokeBallEffect ; ULTRA_BALL
+ dw NoEffect ; BRIGHTPOWDER
+ dw PokeBallEffect ; GREAT_BALL
+ dw PokeBallEffect ; POKE_BALL
+ dw TownMapEffect ; TOWN_MAP
+ dw BicycleEffect ; BICYCLE
+ dw EvoStoneEffect ; MOON_STONE
+ dw StatusHealingEffect ; ANTIDOTE
+ dw StatusHealingEffect ; BURN_HEAL
+ dw StatusHealingEffect ; ICE_HEAL
+ dw StatusHealingEffect ; AWAKENING
+ dw StatusHealingEffect ; PARLYZ_HEAL
+ dw FullRestoreEffect ; FULL_RESTORE
+ dw RestoreHPEffect ; MAX_POTION
+ dw RestoreHPEffect ; HYPER_POTION
+ dw RestoreHPEffect ; SUPER_POTION
+ dw RestoreHPEffect ; POTION
+ dw EscapeRopeEffect ; ESCAPE_ROPE
+ dw RepelEffect ; REPEL
+ dw RestorePPEffect ; MAX_ELIXER
+ dw EvoStoneEffect ; FIRE_STONE
+ dw EvoStoneEffect ; THUNDERSTONE
+ dw EvoStoneEffect ; WATER_STONE
+ dw NoEffect ; ITEM_19
+ dw VitaminEffect ; HP_UP
+ dw VitaminEffect ; PROTEIN
+ dw VitaminEffect ; IRON
+ dw VitaminEffect ; CARBOS
+ dw NoEffect ; LUCKY_PUNCH
+ dw VitaminEffect ; CALCIUM
+ dw RareCandyEffect ; RARE_CANDY
+ dw XAccuracyEffect ; X_ACCURACY
+ dw EvoStoneEffect ; LEAF_STONE
+ dw NoEffect ; METAL_POWDER
+ dw NoEffect ; NUGGET
+ dw PokeDollEffect ; POKE_DOLL
+ dw StatusHealingEffect ; FULL_HEAL
+ dw ReviveEffect ; REVIVE
+ dw ReviveEffect ; MAX_REVIVE
+ dw GuardSpecEffect ; GUARD_SPEC
+ dw SuperRepelEffect ; SUPER_REPEL
+ dw MaxRepelEffect ; MAX_REPEL
+ dw DireHitEffect ; DIRE_HIT
+ dw NoEffect ; ITEM_2D
+ dw RestoreHPEffect ; FRESH_WATER
+ dw RestoreHPEffect ; SODA_POP
+ dw RestoreHPEffect ; LEMONADE
+ dw XItemEffect ; X_ATTACK
+ dw NoEffect ; ITEM_32
+ dw XItemEffect ; X_DEFEND
+ dw XItemEffect ; X_SPEED
+ dw XItemEffect ; X_SPECIAL
+ dw CoinCaseEffect ; COIN_CASE
+ dw ItemfinderEffect ; ITEMFINDER
+ dw PokeFluteEffect ; POKE_FLUTE
+ dw NoEffect ; EXP_SHARE
+ dw OldRodEffect ; OLD_ROD
+ dw GoodRodEffect ; GOOD_ROD
+ dw NoEffect ; SILVER_LEAF
+ dw SuperRodEffect ; SUPER_ROD
+ dw RestorePPEffect ; PP_UP
+ dw RestorePPEffect ; ETHER
+ dw RestorePPEffect ; MAX_ETHER
+ dw RestorePPEffect ; ELIXER
+ dw NoEffect ; RED_SCALE
+ dw NoEffect ; SECRETPOTION
+ dw NoEffect ; S_S_TICKET
+ dw NoEffect ; MYSTERY_EGG
+ dw NoEffect ; CLEAR_BELL
+ dw NoEffect ; SILVER_WING
+ dw RestoreHPEffect ; MOOMOO_MILK
+ dw NoEffect ; QUICK_CLAW
+ dw StatusHealingEffect ; PSNCUREBERRY
+ dw NoEffect ; GOLD_LEAF
+ dw NoEffect ; SOFT_SAND
+ dw NoEffect ; SHARP_BEAK
+ dw StatusHealingEffect ; PRZCUREBERRY
+ dw StatusHealingEffect ; BURNT_BERRY
+ dw StatusHealingEffect ; ICE_BERRY
+ dw NoEffect ; POISON_BARB
+ dw NoEffect ; KINGS_ROCK
+ dw BitterBerryEffect ; BITTER_BERRY
+ dw StatusHealingEffect ; MINT_BERRY
+ dw NoEffect ; RED_APRICORN
+ dw NoEffect ; TINYMUSHROOM
+ dw NoEffect ; BIG_MUSHROOM
+ dw NoEffect ; SILVERPOWDER
+ dw NoEffect ; BLU_APRICORN
+ dw NoEffect ; ITEM_5A
+ dw NoEffect ; AMULET_COIN
+ dw NoEffect ; YLW_APRICORN
+ dw NoEffect ; GRN_APRICORN
+ dw NoEffect ; CLEANSE_TAG
+ dw NoEffect ; MYSTIC_WATER
+ dw NoEffect ; TWISTEDSPOON
+ dw NoEffect ; WHT_APRICORN
+ dw NoEffect ; BLACKBELT
+ dw NoEffect ; BLK_APRICORN
+ dw NoEffect ; ITEM_64
+ dw NoEffect ; PNK_APRICORN
+ dw NoEffect ; BLACKGLASSES
+ dw NoEffect ; SLOWPOKETAIL
+ dw NoEffect ; PINK_BOW
+ dw NoEffect ; STICK
+ dw NoEffect ; SMOKE_BALL
+ dw NoEffect ; NEVERMELTICE
+ dw NoEffect ; MAGNET
+ dw StatusHealingEffect ; MIRACLEBERRY
+ dw NoEffect ; PEARL
+ dw NoEffect ; BIG_PEARL
+ dw NoEffect ; EVERSTONE
+ dw NoEffect ; SPELL_TAG
+ dw RestoreHPEffect ; RAGECANDYBAR
+ dw NoEffect ; GS_BALL
+ dw BlueCardEffect ; BLUE_CARD
+ dw NoEffect ; MIRACLE_SEED
+ dw NoEffect ; THICK_CLUB
+ dw NoEffect ; FOCUS_BAND
+ dw NoEffect ; ITEM_78
+ dw EnergypowderEffect ; ENERGYPOWDER
+ dw EnergyRootEffect ; ENERGY_ROOT
+ dw HealPowderEffect ; HEAL_POWDER
+ dw RevivalHerbEffect ; REVIVAL_HERB
+ dw NoEffect ; HARD_STONE
+ dw NoEffect ; LUCKY_EGG
+ dw CardKeyEffect ; CARD_KEY
+ dw NoEffect ; MACHINE_PART
+ dw NoEffect ; EGG_TICKET
+ dw NoEffect ; LOST_ITEM
+ dw NoEffect ; STARDUST
+ dw NoEffect ; STAR_PIECE
+ dw BasementKeyEffect ; BASEMENT_KEY
+ dw NoEffect ; PASS
+ dw NoEffect ; ITEM_87
+ dw NoEffect ; ITEM_88
+ dw NoEffect ; ITEM_89
+ dw NoEffect ; CHARCOAL
+ dw RestoreHPEffect ; BERRY_JUICE
+ dw NoEffect ; SCOPE_LENS
+ dw NoEffect ; ITEM_8D
+ dw NoEffect ; ITEM_8E
+ dw NoEffect ; METAL_COAT
+ dw NoEffect ; DRAGON_FANG
+ dw NoEffect ; ITEM_91
+ dw NoEffect ; LEFTOVERS
+ dw NoEffect ; ITEM_93
+ dw NoEffect ; ITEM_94
+ dw NoEffect ; ITEM_95
+ dw RestorePPEffect ; MYSTERYBERRY
+ dw NoEffect ; DRAGON_SCALE
+ dw NoEffect ; BERSERK_GENE
+ dw NoEffect ; ITEM_99
+ dw NoEffect ; ITEM_9A
+ dw NoEffect ; ITEM_9B
+ dw SacredAshEffect ; SACRED_ASH
+ dw PokeBallEffect ; HEAVY_BALL
+ dw NoEffect ; FLOWER_MAIL
+ dw PokeBallEffect ; LEVEL_BALL
+ dw PokeBallEffect ; LURE_BALL
+ dw PokeBallEffect ; FAST_BALL
+ dw NoEffect ; ITEM_A2
+ dw NoEffect ; LIGHT_BALL
+ dw PokeBallEffect ; FRIEND_BALL
+ dw PokeBallEffect ; MOON_BALL
+ dw PokeBallEffect ; LOVE_BALL
+ dw NormalBoxEffect ; NORMAL_BOX
+ dw GorgeousBoxEffect ; GORGEOUS_BOX
+ dw EvoStoneEffect ; SUN_STONE
+ dw NoEffect ; POLKADOT_BOW
+ dw NoEffect ; ITEM_AB
+ dw NoEffect ; UP_GRADE
+ dw RestoreHPEffect ; BERRY
+ dw RestoreHPEffect ; GOLD_BERRY
+ dw SquirtbottleEffect ; SQUIRTBOTTLE
+ dw NoEffect ; ITEM_B0
+ dw PokeBallEffect ; PARK_BALL
+ dw NoEffect ; RAINBOW_WING
+ dw NoEffect ; ITEM_B3
+; e8a2
+
+
+PokeBallEffect: ; e8a2
+ ld a, [wBattleMode]
+ dec a
+ jp nz, UseBallInTrainerBattle
+
+ ld a, [wPartyCount]
+ cp PARTY_LENGTH
+ jr nz, .room_in_party
+
+ ld a, BANK(sBoxCount)
+ call GetSRAMBank
+ ld a, [sBoxCount]
+ cp MONS_PER_BOX
+ call CloseSRAM
+ jp z, Ball_BoxIsFullMessage
+
+.room_in_party
+ xor a
+ ld [wWildMon], a
+ ld a, [wCurItem]
+ cp PARK_BALL
+ call nz, ReturnToBattle_UseBall
+
+ ld hl, wOptions
+ res NO_TEXT_SCROLL, [hl]
+ ld hl, UsedItemText
+ call PrintText
+
+ ld a, [wEnemyMonCatchRate]
+ ld b, a
+ ld a, [wBattleType]
+ cp BATTLETYPE_TUTORIAL
+ jp z, .catch_without_fail
+ ld a, [wCurItem]
+ cp MASTER_BALL
+ jp z, .catch_without_fail
+ ld a, [wCurItem]
+ ld c, a
+ ld hl, BallMultiplierFunctionTable
+
+.get_multiplier_loop
+ ld a, [hli]
+ cp $ff
+ jr z, .skip_or_return_from_ball_fn
+ cp c
+ jr z, .call_ball_function
+ inc hl
+ inc hl
+ jr .get_multiplier_loop
+
+.call_ball_function
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, .skip_or_return_from_ball_fn
+ push de
+ jp hl
+
+.skip_or_return_from_ball_fn
+ ld a, [wCurItem]
+ cp LEVEL_BALL
+ ld a, b
+ jp z, .skip_hp_calc
+
+ ld a, b
+ ld [hMultiplicand + 2], a
+
+ ld hl, wEnemyMonHP
+ ld b, [hl]
+ inc hl
+ ld c, [hl]
+ inc hl
+ ld d, [hl]
+ inc hl
+ ld e, [hl]
+ sla c
+ rl b
+
+ ld h, d
+ ld l, e
+ add hl, de
+ add hl, de
+ ld d, h
+ ld e, l
+ ld a, d
+ and a
+ jr z, .okay_1
+
+ srl d
+ rr e
+ srl d
+ rr e
+ srl b
+ rr c
+ srl b
+ rr c
+
+ ld a, c
+ and a
+ jr nz, .okay_1
+ ld c, $1
+.okay_1
+ ld b, e
+
+ push bc
+ ld a, b
+ sub c
+ ld [hMultiplier], a
+ xor a
+ ld [hDividend + 0], a
+ ld [hMultiplicand + 0], a
+ ld [hMultiplicand + 1], a
+ call Multiply
+ pop bc
+
+ ld a, b
+ ld [hDivisor], a
+ ld b, $4
+ call Divide
+
+ ld a, [hQuotient + 2]
+ and a
+ jr nz, .statuscheck
+ ld a, 1
+.statuscheck
+; This routine is buggy. It was intended that SLP and FRZ provide a higher
+; catch rate than BRN/PSN/PAR, which in turn provide a higher catch rate than
+; no status effect at all. But instead, it makes BRN/PSN/PAR provide no
+; benefit.
+; Uncomment the line below to fix this.
+ ld b, a
+ ld a, [wEnemyMonStatus]
+ and 1 << FRZ | SLP
+ ld c, 10
+ jr nz, .addstatus
+ ; ld a, [wEnemyMonStatus]
+ and a
+ ld c, 5
+ jr nz, .addstatus
+ ld c, 0
+.addstatus
+ ld a, b
+ add c
+ jr nc, .max_1
+ ld a, $ff
+.max_1
+
+ ; BUG: farcall overwrites a, and GetItemHeldEffect takes b anyway.
+ ; This is probably the reason the HELD_CATCH_CHANCE effect is never used.
+ ; Uncomment the line below to fix.
+ ld d, a
+ push de
+ ld a, [wBattleMonItem]
+ ; ld b, a
+ farcall GetItemHeldEffect
+ ld a, b
+ cp HELD_CATCH_CHANCE
+ pop de
+ ld a, d
+ jr nz, .max_2
+ add c
+ jr nc, .max_2
+ ld a, $ff
+.max_2
+
+.skip_hp_calc
+ ld b, a
+ ld [wBuffer1], a
+ call Random
+
+ cp b
+ ld a, 0
+ jr z, .catch_without_fail
+ jr nc, .fail_to_catch
+
+.catch_without_fail
+ ld a, [wEnemyMonSpecies]
+
+.fail_to_catch
+ ld [wWildMon], a
+ ld c, 20
+ call DelayFrames
+
+ ld a, [wCurItem]
+ cp POKE_BALL + 1 ; Assumes Master/Ultra/Great come before
+ jr c, .not_kurt_ball
+ ld a, POKE_BALL
+.not_kurt_ball
+ ld [wBattleAnimParam], a
+
+ ld de, ANIM_THROW_POKE_BALL
+ ld a, e
+ ld [wFXAnimID], a
+ ld a, d
+ ld [wFXAnimID + 1], a
+ xor a
+ ld [hBattleTurn], a
+ ld [wBuffer2], a
+ ld [wNumHits], a
+ predef PlayBattleAnim
+
+ ld a, [wWildMon]
+ and a
+ jr nz, .caught
+ ld a, [wBuffer2]
+ cp $1
+ ld hl, Text_NoShake
+ jp z, .shake_and_break_free
+ cp $2
+ ld hl, Text_OneShake
+ jp z, .shake_and_break_free
+ cp $3
+ ld hl, Text_TwoShakes
+ jp z, .shake_and_break_free
+ cp $4
+ ld hl, Text_ThreeShakes
+ jp z, .shake_and_break_free
+.caught
+
+ ld hl, wEnemyMonStatus
+ ld a, [hli]
+ push af
+ inc hl
+ ld a, [hli]
+ push af
+ ld a, [hl]
+ push af
+ push hl
+ ld hl, wEnemyMonItem
+ ld a, [hl]
+ push af
+ push hl
+ ld hl, wEnemySubStatus5
+ ld a, [hl]
+ push af
+ set SUBSTATUS_TRANSFORMED, [hl]
+
+; This code is buggy. Any wild Pokémon that has Transformed will be
+; caught as a Ditto, even if it was something else like Mew.
+; To fix, do not set [wTempEnemyMonSpecies] to DITTO.
+ bit SUBSTATUS_TRANSFORMED, a
+ jr nz, .ditto
+ jr .not_ditto
+
+.ditto
+ ld a, DITTO
+ ld [wTempEnemyMonSpecies], a
+ jr .load_data
+
+.not_ditto
+ set SUBSTATUS_TRANSFORMED, [hl]
+ ld hl, wEnemyBackupDVs
+ ld a, [wEnemyMonDVs]
+ ld [hli], a
+ ld a, [wEnemyMonDVs + 1]
+ ld [hl], a
+
+.load_data
+ ld a, [wTempEnemyMonSpecies]
+ ld [wCurPartySpecies], a
+ ld a, [wEnemyMonLevel]
+ ld [wCurPartyLevel], a
+ farcall LoadEnemyMon
+
+ pop af
+ ld [wEnemySubStatus5], a
+
+ pop hl
+ pop af
+ ld [hl], a
+ pop hl
+ pop af
+ ld [hld], a
+ pop af
+ ld [hld], a
+ dec hl
+ pop af
+ ld [hl], a
+
+ ld hl, wEnemySubStatus5
+ bit SUBSTATUS_TRANSFORMED, [hl]
+ jr nz, .Transformed
+ ld hl, wWildMonMoves
+ ld de, wEnemyMonMoves
+ ld bc, NUM_MOVES
+ call CopyBytes
+
+ ld hl, wWildMonPP
+ ld de, wEnemyMonPP
+ ld bc, NUM_MOVES
+ call CopyBytes
+.Transformed:
+
+ ld a, [wEnemyMonSpecies]
+ ld [wWildMon], a
+ ld [wCurPartySpecies], a
+ ld [wd265], a
+ ld a, [wBattleType]
+ cp BATTLETYPE_TUTORIAL
+ jp z, .FinishTutorial
+
+ farcall StubbedTrainerRankings_WildMonsCaught
+
+ ld hl, Text_GotchaMonWasCaught
+ call PrintText
+
+ call ClearSprites
+
+ ld a, [wd265]
+ dec a
+ call CheckCaughtMon
+
+ ld a, c
+ push af
+ ld a, [wd265]
+ dec a
+ call SetSeenAndCaughtMon
+ pop af
+ and a
+ jr nz, .skip_pokedex
+
+ call CheckReceivedDex
+ jr z, .skip_pokedex
+
+ ld hl, Text_AddedToPokedex
+ call PrintText
+
+ call ClearSprites
+
+ ld a, [wEnemyMonSpecies]
+ ld [wd265], a
+ predef NewPokedexEntry
+
+.skip_pokedex
+ ld a, [wBattleType]
+ cp BATTLETYPE_CONTEST
+ jp z, .catch_bug_contest_mon
+ cp BATTLETYPE_CELEBI
+ jr nz, .not_celebi
+ ld hl, wBattleResult
+ set 6, [hl]
+.not_celebi
+
+ ld a, [wPartyCount]
+ cp PARTY_LENGTH
+ jr z, .SendToPC
+
+ xor a ; PARTYMON
+ ld [wMonType], a
+ call ClearSprites
+
+ predef TryAddMonToParty
+
+ farcall SetCaughtData
+
+ ld a, [wCurItem]
+ cp FRIEND_BALL
+ jr nz, .SkipPartyMonFriendBall
+
+ ld a, [wPartyCount]
+ dec a
+ ld hl, wPartyMon1Happiness
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+
+ ld a, FRIEND_BALL_HAPPINESS
+ ld [hl], a
+.SkipPartyMonFriendBall:
+
+ ld hl, Text_AskNicknameNewlyCaughtMon
+ call PrintText
+
+ ld a, [wCurPartySpecies]
+ ld [wd265], a
+ call GetPokemonName
+
+ call YesNoBox
+ jp c, .return_from_capture
+
+ ld a, [wPartyCount]
+ dec a
+ ld [wCurPartyMon], a
+ ld hl, wPartyMonNicknames
+ ld bc, MON_NAME_LENGTH
+ call AddNTimes
+
+ ld d, h
+ ld e, l
+ push de
+ xor a ; PARTYMON
+ ld [wMonType], a
+ ld b, 0
+ farcall NamingScreen
+
+ call RotateThreePalettesRight
+
+ call LoadStandardFont
+
+ pop hl
+ ld de, wStringBuffer1
+ call InitName
+
+ jp .return_from_capture
+
+.SendToPC:
+ call ClearSprites
+
+ predef SendMonIntoBox
+
+ farcall SetBoxMonCaughtData
+
+ ld a, BANK(sBoxCount)
+ call GetSRAMBank
+
+ ld a, [sBoxCount]
+ cp MONS_PER_BOX
+ jr nz, .BoxNotFullYet
+ ld hl, wBattleResult
+ set 7, [hl]
+.BoxNotFullYet:
+ ld a, [wCurItem]
+ cp FRIEND_BALL
+ jr nz, .SkipBoxMonFriendBall
+ ; The captured mon is now first in the box
+ ld a, FRIEND_BALL_HAPPINESS
+ ld [sBoxMon1Happiness], a
+.SkipBoxMonFriendBall:
+ call CloseSRAM
+
+ ld hl, Text_AskNicknameNewlyCaughtMon
+ call PrintText
+
+ ld a, [wCurPartySpecies]
+ ld [wd265], a
+ call GetPokemonName
+
+ call YesNoBox
+ jr c, .SkipBoxMonNickname
+
+ xor a
+ ld [wCurPartyMon], a
+ ld a, BOXMON
+ ld [wMonType], a
+ ld de, wMonOrItemNameBuffer
+ ld b, $0
+ farcall NamingScreen
+
+ ld a, BANK(sBoxMonNicknames)
+ call GetSRAMBank
+
+ ld hl, wMonOrItemNameBuffer
+ ld de, sBoxMonNicknames
+ ld bc, MON_NAME_LENGTH
+ call CopyBytes
+
+ ld hl, sBoxMonNicknames
+ ld de, wStringBuffer1
+ call InitName
+
+ call CloseSRAM
+
+.SkipBoxMonNickname:
+ ld a, BANK(sBoxMonNicknames)
+ call GetSRAMBank
+
+ ld hl, sBoxMonNicknames
+ ld de, wMonOrItemNameBuffer
+ ld bc, MON_NAME_LENGTH
+ call CopyBytes
+
+ call CloseSRAM
+
+ ld hl, Text_SentToBillsPC
+ call PrintText
+
+ call RotateThreePalettesRight
+ call LoadStandardFont
+ jr .return_from_capture
+
+.catch_bug_contest_mon
+ farcall BugContest_SetCaughtContestMon
+ jr .return_from_capture
+
+.FinishTutorial:
+ ld hl, Text_GotchaMonWasCaught
+
+.shake_and_break_free
+ call PrintText
+ call ClearSprites
+
+.return_from_capture
+ ld a, [wBattleType]
+ cp BATTLETYPE_TUTORIAL
+ ret z
+ cp BATTLETYPE_DEBUG
+ ret z
+ cp BATTLETYPE_CONTEST
+ jr z, .used_park_ball
+
+ ld a, [wWildMon]
+ and a
+ jr z, .toss
+
+ call ClearBGPalettes
+ call ClearTileMap
+
+.toss
+ ld hl, wNumItems
+ inc a
+ ld [wItemQuantityChangeBuffer], a
+ jp TossItem
+
+.used_park_ball
+ ld hl, wParkBallsRemaining
+ dec [hl]
+ ret
+; ec0a
+
+
+BallMultiplierFunctionTable:
+; table of routines that increase or decrease the catch rate based on
+; which ball is used in a certain situation.
+ dbw ULTRA_BALL, UltraBallMultiplier
+ dbw GREAT_BALL, GreatBallMultiplier
+ dbw SAFARI_BALL, SafariBallMultiplier ; Safari Ball, leftover from RBY
+ dbw HEAVY_BALL, HeavyBallMultiplier
+ dbw LEVEL_BALL, LevelBallMultiplier
+ dbw LURE_BALL, LureBallMultiplier
+ dbw FAST_BALL, FastBallMultiplier
+ dbw MOON_BALL, MoonBallMultiplier
+ dbw LOVE_BALL, LoveBallMultiplier
+ dbw PARK_BALL, ParkBallMultiplier
+ db -1 ; end
+
+UltraBallMultiplier:
+; multiply catch rate by 2
+ sla b
+ ret nc
+ ld b, $ff
+ ret
+
+SafariBallMultiplier:
+GreatBallMultiplier:
+ParkBallMultiplier:
+; multiply catch rate by 1.5
+ ld a, b
+ srl a
+ add b
+ ld b, a
+ ret nc
+ ld b, $ff
+ ret
+
+GetPokedexEntryBank:
+ push hl
+ push de
+ ld a, [wEnemyMonSpecies]
+ rlca
+ rlca
+ maskbits NUM_DEX_ENTRY_BANKS
+ ld hl, .PokedexEntryBanks
+ ld d, 0
+ ld e, a
+ add hl, de
+ ld a, [hl]
+ pop de
+ pop hl
+ ret
+
+.PokedexEntryBanks:
+ db BANK(PokedexEntries1)
+ db BANK(PokedexEntries2)
+ db BANK(PokedexEntries3)
+ db BANK(PokedexEntries4)
+
+HeavyBallMultiplier:
+; subtract 20 from catch rate if weight < 102.4 kg
+; else add 0 to catch rate if weight < 204.8 kg
+; else add 20 to catch rate if weight < 307.2 kg
+; else add 30 to catch rate if weight < 409.6 kg
+; else add 40 to catch rate (never happens)
+ ld a, [wEnemyMonSpecies]
+ ld hl, PokedexDataPointerTable
+ dec a
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ ld a, BANK(PokedexDataPointerTable)
+ call GetFarHalfword
+
+.SkipText:
+ call GetPokedexEntryBank
+ call GetFarByte
+ inc hl
+ cp "@"
+ jr nz, .SkipText
+
+ call GetPokedexEntryBank
+ push bc
+ inc hl
+ inc hl
+ call GetFarHalfword
+
+ srl h
+ rr l
+ ld b, h
+ ld c, l
+
+ rept 4
+ srl b
+ rr c
+ endr
+ call .subbc
+
+ srl b
+ rr c
+ call .subbc
+
+ ld a, h
+ pop bc
+ jr .compare
+
+.subbc
+ ; subtract bc from hl
+ push bc
+ ld a, b
+ cpl
+ ld b, a
+ ld a, c
+ cpl
+ ld c, a
+ inc bc
+ add hl, bc
+ pop bc
+ ret
+
+.compare
+ ld c, a
+ cp HIGH(1024) ; 102.4 kg
+ jr c, .lightmon
+
+ ld hl, .WeightsTable
+.lookup
+ ld a, c
+ cp [hl]
+ jr c, .heavymon
+ inc hl
+ inc hl
+ jr .lookup
+
+.heavymon
+ inc hl
+ ld a, b
+ add [hl]
+ ld b, a
+ ret nc
+ ld b, $ff
+ ret
+
+.lightmon
+ ld a, b
+ sub 20
+ ld b, a
+ ret nc
+ ld b, $1
+ ret
+
+.WeightsTable:
+; weight factor, boost
+ db HIGH(2048), 0
+ db HIGH(3072), 20
+ db HIGH(4096), 30
+ db HIGH(65280), 40
+
+LureBallMultiplier:
+; multiply catch rate by 3 if this is a fishing rod battle
+ ld a, [wBattleType]
+ cp BATTLETYPE_FISH
+ ret nz
+
+ ld a, b
+ add a
+ jr c, .max
+
+ add b
+ jr nc, .done
+.max
+ ld a, $ff
+.done
+ ld b, a
+ ret
+
+MoonBallMultiplier:
+; This function is buggy.
+; Intent: multiply catch rate by 4 if mon evolves with moon stone
+; Reality: no boost
+ push bc
+ ld a, [wTempEnemyMonSpecies]
+ dec a
+ ld c, a
+ ld b, 0
+ ld hl, EvosAttacksPointers
+ add hl, bc
+ add hl, bc
+ ld a, BANK(EvosAttacksPointers)
+ call GetFarHalfword
+ pop bc
+
+ push bc
+ ld a, BANK(EvosAttacks)
+ call GetFarByte
+ cp EVOLVE_ITEM
+ pop bc
+ ret nz
+
+ inc hl
+ inc hl
+ inc hl
+
+; Moon Stone's constant from Pokémon Red is used.
+; No Pokémon evolve with Burn Heal,
+; so Moon Balls always have a catch rate of 1×.
+ push bc
+ ld a, BANK(EvosAttacks)
+ call GetFarByte
+ cp MOON_STONE_RED ; BURN_HEAL
+ pop bc
+ ret nz
+
+ sla b
+ jr c, .max
+ sla b
+ jr nc, .done
+.max
+ ld b, $ff
+.done
+ ret
+
+LoveBallMultiplier:
+; This function is buggy.
+; Intent: multiply catch rate by 8 if mons are of same species, different sex
+; Reality: multiply catch rate by 8 if mons are of same species, same sex
+
+ ; does species match?
+ ld a, [wTempEnemyMonSpecies]
+ ld c, a
+ ld a, [wTempBattleMonSpecies]
+ cp c
+ ret nz
+
+ ; check player mon species
+ push bc
+ ld a, [wTempBattleMonSpecies]
+ ld [wCurPartySpecies], a
+ xor a ; PARTYMON
+ ld [wMonType], a
+ ld a, [wCurBattleMon]
+ ld [wCurPartyMon], a
+ farcall GetGender
+ jr c, .done1 ; no effect on genderless
+
+ ld d, 0 ; male
+ jr nz, .playermale
+ inc d ; female
+.playermale
+
+ ; check wild mon species
+ push de
+ ld a, [wTempEnemyMonSpecies]
+ ld [wCurPartySpecies], a
+ ld a, WILDMON
+ ld [wMonType], a
+ farcall GetGender
+ jr c, .done2 ; no effect on genderless
+
+ ld d, 0 ; male
+ jr nz, .wildmale
+ inc d ; female
+.wildmale
+
+ ld a, d
+ pop de
+ cp d
+ pop bc
+ ret nz ; for the intended effect, this should be "ret z"
+
+ sla b
+ jr c, .max
+ sla b
+ jr c, .max
+ sla b
+ ret nc
+.max
+ ld b, $ff
+ ret
+
+.done2
+ pop de
+
+.done1
+ pop bc
+ ret
+
+FastBallMultiplier:
+; This function is buggy.
+; Intent: multiply catch rate by 4 if enemy mon is in one of the three
+; FleeMons tables.
+; Reality: multiply catch rate by 4 if enemy mon is one of the first three in
+; the first FleeMons table.
+ ld a, [wTempEnemyMonSpecies]
+ ld c, a
+ ld hl, FleeMons
+ ld d, 3
+
+.loop
+ ld a, BANK(FleeMons)
+ call GetFarByte
+
+ inc hl
+ cp -1
+ jr z, .next
+ cp c
+ jr nz, .next ; for the intended effect, this should be "jr nz, .loop"
+ sla b
+ jr c, .max
+
+ sla b
+ ret nc
+
+.max
+ ld b, $ff
+ ret
+
+.next
+ dec d
+ jr nz, .loop
+ ret
+
+LevelBallMultiplier:
+; multiply catch rate by 8 if player mon level / 4 > enemy mon level
+; multiply catch rate by 4 if player mon level / 2 > enemy mon level
+; multiply catch rate by 2 if player mon level > enemy mon level
+ ld a, [wBattleMonLevel]
+ ld c, a
+ ld a, [wEnemyMonLevel]
+ cp c
+ ret nc ; if player is lower level, we're done here
+ sla b
+ jr c, .max
+
+ srl c
+ cp c
+ ret nc ; if player/2 is lower level, we're done here
+ sla b
+ jr c, .max
+
+ srl c
+ cp c
+ ret nc ; if player/4 is lower level, we're done here
+ sla b
+ ret nc
+
+.max
+ ld b, $ff
+ ret
+
+; These two texts were carried over from gen 1.
+; They are not used in gen 2, and are dummied out.
+
+Text_RBY_CatchMarowak: ; 0xedab
+ ; It dodged the thrown BALL! This #MON can't be caught!
+ text_jump UnknownText_0x1c5a5a
+ db "@"
+; 0xedb0
+
+Text_RBY_NoShake: ; 0xedb0
+ ; You missed the #MON!
+ text_jump UnknownText_0x1c5a90
+ db "@"
+; 0xedb5
+
+Text_NoShake: ; 0xedb5
+ ; Oh no! The #MON broke free!
+ text_jump UnknownText_0x1c5aa6
+ db "@"
+; 0xedba
+
+Text_OneShake: ; 0xedba
+ ; Aww! It appeared to be caught!
+ text_jump UnknownText_0x1c5ac3
+ db "@"
+; 0xedbf
+
+Text_TwoShakes: ; 0xedbf
+ ; Aargh! Almost had it!
+ text_jump UnknownText_0x1c5ae3
+ db "@"
+; 0xedc4
+
+Text_ThreeShakes: ; 0xedc4
+ ; Shoot! It was so close too!
+ text_jump UnknownText_0x1c5afa
+ db "@"
+; 0xedc9
+
+Text_GotchaMonWasCaught: ; 0xedc9
+ ; Gotcha! @ was caught!@ @
+ text_jump UnknownText_0x1c5b17
+ start_asm
+ call WaitSFX
+ push bc
+ ld de, MUSIC_NONE
+ call PlayMusic
+ call DelayFrame
+ ld de, MUSIC_CAPTURE
+ call PlayMusic
+ pop bc
+ ld hl, TextJump_Waitbutton
+ ret
+; ede6
+
+TextJump_Waitbutton: ; 0xede6
+ ; @
+ text_jump Text_Waitbutton_2
+ db "@"
+; 0xedeb
+
+Text_SentToBillsPC: ; 0xedeb
+ ; was sent to BILL's PC.
+ text_jump UnknownText_0x1c5b38
+ db "@"
+; 0xedf0
+
+Text_AddedToPokedex: ; 0xedf0
+ ; 's data was newly added to the #DEX.@ @
+ text_jump UnknownText_0x1c5b53
+ db "@"
+; 0xedf5
+
+Text_AskNicknameNewlyCaughtMon: ; 0xedf5
+ ; Give a nickname to @ ?
+ text_jump UnknownText_0x1c5b7f
+ db "@"
+; 0xedfa
+
+ReturnToBattle_UseBall: ; edfa (3:6dfa)
+ farcall _ReturnToBattle_UseBall
+ ret
+
+TownMapEffect: ; ee01
+ farcall PokegearMap
+ ret
+; ee08
+
+
+BicycleEffect: ; ee08
+ farcall BikeFunction
+ ret
+; ee0f
+
+
+EvoStoneEffect: ; ee0f
+ ld b, PARTYMENUACTION_EVO_STONE
+ call UseItem_SelectMon
+
+ jp c, .DecidedNotToUse
+
+ ld a, MON_ITEM
+ call GetPartyParamLocation
+
+ ld a, [hl]
+ cp EVERSTONE
+ jr z, .NoEffect
+
+ ld a, $1
+ ld [wForceEvolution], a
+ farcall EvolvePokemon
+
+ ld a, [wMonTriedToEvolve]
+ and a
+ jr z, .NoEffect
+
+ jp UseDisposableItem
+
+.NoEffect:
+ call WontHaveAnyEffectMessage
+
+.DecidedNotToUse:
+ xor a
+ ld [wItemEffectSucceeded], a
+ ret
+; ee3d
+
+
+VitaminEffect: ; ee3d
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+
+ jp c, RareCandy_StatBooster_ExitMenu
+
+ call RareCandy_StatBooster_GetParameters
+
+ call GetStatExpRelativePointer
+
+ ld a, MON_STAT_EXP
+ call GetPartyParamLocation
+
+ add hl, bc
+ ld a, [hl]
+ cp 100
+ jr nc, NoEffectMessage
+
+ add 10
+ ld [hl], a
+ call UpdateStatsAfterItem
+
+ call GetStatExpRelativePointer
+
+ ld hl, StatStrings
+ add hl, bc
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wStringBuffer2
+ ld bc, ITEM_NAME_LENGTH
+ call CopyBytes
+
+ call Play_SFX_FULL_HEAL
+
+ ld hl, Text_StatRose
+ call PrintText
+
+ ld c, HAPPINESS_USEDITEM
+ farcall ChangeHappiness
+
+ jp UseDisposableItem
+
+
+NoEffectMessage: ; ee83
+ ld hl, WontHaveAnyEffectText
+ call PrintText
+ jp ClearPalettes
+; ee8c
+
+
+UpdateStatsAfterItem: ; ee8c
+ ld a, MON_MAXHP
+ call GetPartyParamLocation
+ ld d, h
+ ld e, l
+ ld a, MON_STAT_EXP - 1
+ call GetPartyParamLocation
+ ld b, TRUE
+ predef_jump CalcMonStats
+; ee9f
+
+RareCandy_StatBooster_ExitMenu: ; ee9f
+ xor a
+ ld [wItemEffectSucceeded], a
+ jp ClearPalettes
+; eea6
+
+
+Text_StatRose: ; 0xeea6
+ ; 's @ rose.
+ text_jump UnknownText_0x1c5b9a
+ db "@"
+; 0xeeab
+
+
+StatStrings: ; eeab
+ dw .health
+ dw .attack
+ dw .defense
+ dw .speed
+ dw .special
+
+.health db "HEALTH@"
+.attack db "ATTACK@"
+.defense db "DEFENSE@"
+.speed db "SPEED@"
+.special db "SPECIAL@"
+; eed9
+
+
+GetStatExpRelativePointer: ; eed9
+ ld a, [wCurItem]
+ ld hl, Table_eeeb
+.next
+ cp [hl]
+ inc hl
+ jr z, .got_it
+ inc hl
+ jr .next
+
+.got_it
+ ld a, [hl]
+ ld c, a
+ ld b, 0
+ ret
+; eeeb
+
+Table_eeeb: ; eeeb
+ db HP_UP, MON_HP_EXP - MON_STAT_EXP
+ db PROTEIN, MON_ATK_EXP - MON_STAT_EXP
+ db IRON, MON_DEF_EXP - MON_STAT_EXP
+ db CARBOS, MON_SPD_EXP - MON_STAT_EXP
+ db CALCIUM, MON_SPC_EXP - MON_STAT_EXP
+; eef5
+
+
+RareCandy_StatBooster_GetParameters: ; eef5
+ ld a, [wCurPartySpecies]
+ ld [wCurSpecies], a
+ ld [wd265], a
+ ld a, MON_LEVEL
+ call GetPartyParamLocation
+ ld a, [hl]
+ ld [wCurPartyLevel], a
+ call GetBaseData
+ ld a, [wCurPartyMon]
+ ld hl, wPartyMonNicknames
+ call GetNick
+ ret
+; 0xef14
+
+
+RareCandyEffect: ; ef14
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+
+ jp c, RareCandy_StatBooster_ExitMenu
+
+ call RareCandy_StatBooster_GetParameters
+
+ ld a, MON_LEVEL
+ call GetPartyParamLocation
+
+ ld a, [hl]
+ cp MAX_LEVEL
+ jp nc, NoEffectMessage
+
+ inc a
+ ld [hl], a
+ ld [wCurPartyLevel], a
+ push de
+ ld d, a
+ farcall CalcExpAtLevel
+
+ pop de
+ ld a, MON_EXP
+ call GetPartyParamLocation
+
+ ld a, [hMultiplicand]
+ ld [hli], a
+ ld a, [hMultiplicand + 1]
+ ld [hli], a
+ ld a, [hMultiplicand + 2]
+ ld [hl], a
+
+ ld a, MON_MAXHP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld b, a
+ ld c, [hl]
+ push bc
+ call UpdateStatsAfterItem
+
+ ld a, MON_MAXHP + 1
+ call GetPartyParamLocation
+
+ pop bc
+ ld a, [hld]
+ sub c
+ ld c, a
+ ld a, [hl]
+ sbc b
+ ld b, a
+ dec hl
+ ld a, [hl]
+ add c
+ ld [hld], a
+ ld a, [hl]
+ adc b
+ ld [hl], a
+ farcall LevelUpHappinessMod
+
+ ld a, PARTYMENUTEXT_LEVEL_UP
+ call ItemActionText
+
+ xor a ; PARTYMON
+ ld [wMonType], a
+ predef CopyMonToTempMon
+
+ hlcoord 9, 0
+ ld b, 10
+ ld c, 9
+ call TextBox
+
+ hlcoord 11, 1
+ ld bc, 4
+ predef PrintTempMonStats
+
+ call WaitPressAorB_BlinkCursor
+
+ xor a ; PARTYMON
+ ld [wMonType], a
+ ld a, [wCurPartySpecies]
+ ld [wd265], a
+ predef LearnLevelMoves
+
+ xor a
+ ld [wForceEvolution], a
+ farcall EvolvePokemon
+
+ jp UseDisposableItem
+; efad
+
+
+HealPowderEffect: ; efad
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+
+ jp c, StatusHealer_ExitMenu
+
+ call UseStatusHealer
+
+ cp $0
+ jr nz, .asm_efc9
+ ld c, HAPPINESS_BITTERPOWDER
+ farcall ChangeHappiness
+
+ call LooksBitterMessage
+
+ ld a, $0
+
+.asm_efc9
+ jp StatusHealer_Jumptable
+; efcc
+
+
+StatusHealingEffect: ; efcc
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ jp c, StatusHealer_ExitMenu
+
+FullyHealStatus: ; efd4
+ call UseStatusHealer
+ jp StatusHealer_Jumptable
+; efda
+
+
+UseStatusHealer: ; efda (3:6fda)
+ call IsMonFainted
+ ld a, $1
+ ret z
+ call GetItemHealingAction
+ ld a, MON_STATUS
+ call GetPartyParamLocation
+ ld a, [hl]
+ and c
+ jr nz, .good
+ call IsItemUsedOnConfusedMon
+ ld a, $1
+ ret nc
+ ld b, PARTYMENUTEXT_HEAL_CONFUSION
+.good
+ xor a
+ ld [hl], a
+ ld a, b
+ ld [wPartyMenuActionText], a
+ call HealStatus
+ call Play_SFX_FULL_HEAL
+ call ItemActionTextWaitButton
+ call UseDisposableItem
+ ld a, $0
+ ret
+
+IsItemUsedOnConfusedMon: ; f009 (3:7009)
+ call IsItemUsedOnBattleMon
+ jr nc, .nope
+ ld a, [wPlayerSubStatus3]
+ bit SUBSTATUS_CONFUSED, a
+ jr z, .nope
+ ld a, c
+ cp $ff
+ jr nz, .nope
+ scf
+ ret
+
+.nope
+ and a
+ ret
+
+BattlemonRestoreHealth: ; f01e (3:701e)
+ call IsItemUsedOnBattleMon
+ ret nc
+ ld a, MON_HP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld [wBattleMonHP], a
+ ld a, [hld]
+ ld [wBattleMonHP + 1], a
+ ret
+
+HealStatus: ; f030 (3:7030)
+ call IsItemUsedOnBattleMon
+ ret nc
+ xor a
+ ld [wBattleMonStatus], a
+ ld hl, wPlayerSubStatus5
+ res SUBSTATUS_TOXIC, [hl]
+ ld hl, wPlayerSubStatus1
+ res SUBSTATUS_NIGHTMARE, [hl]
+ call GetItemHealingAction
+ ld a, c
+ cp %11111111
+ jr nz, .not_full_heal
+ ld hl, wPlayerSubStatus3
+ res SUBSTATUS_CONFUSED, [hl]
+.not_full_heal
+ push bc
+ farcall CalcPlayerStats
+ pop bc
+ ret
+
+GetItemHealingAction: ; f058 (3:7058)
+ push hl
+ ld a, [wCurItem]
+ ld hl, StatusHealingActions
+ ld bc, 3
+.next
+ cp [hl]
+ jr z, .found_it
+ add hl, bc
+ jr .next
+
+.found_it
+ inc hl
+ ld b, [hl]
+ inc hl
+ ld a, [hl]
+ ld c, a
+ cp %11111111
+ pop hl
+ ret
+; f071 (3:7071)
+
+INCLUDE "data/items/heal_status.asm"
+
+StatusHealer_Jumptable: ; f09e (3:709e)
+ ld hl, .dw
+ rst JumpTable
+ ret
+
+.dw ; f0a3 (3:70a3)
+ dw StatusHealer_ClearPalettes
+ dw StatusHealer_NoEffect
+ dw StatusHealer_ExitMenu
+
+
+RevivalHerbEffect: ; f0a9
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ jp c, StatusHealer_ExitMenu
+
+ call RevivePokemon
+ cp 0
+ jr nz, .asm_f0c5
+
+ ld c, HAPPINESS_REVIVALHERB
+ farcall ChangeHappiness
+ call LooksBitterMessage
+ ld a, 0
+
+.asm_f0c5
+ jp StatusHealer_Jumptable
+; f0c8
+
+
+ReviveEffect: ; f0c8
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ jp c, StatusHealer_ExitMenu
+
+ call RevivePokemon
+ jp StatusHealer_Jumptable
+; f0d6
+
+
+RevivePokemon: ; f0d6
+ call IsMonFainted
+ ld a, 1
+ ret nz
+ ld a, [wBattleMode]
+ and a
+ jr z, .skip_to_revive
+
+ ld a, [wCurPartyMon]
+ ld c, a
+ ld d, 0
+ ld hl, wBattleParticipantsIncludingFainted
+ ld b, CHECK_FLAG
+ predef SmallFarFlagAction
+ ld a, c
+ and a
+ jr z, .skip_to_revive
+
+ ld a, [wCurPartyMon]
+ ld c, a
+ ld hl, wBattleParticipantsNotFainted
+ ld b, SET_FLAG
+ predef SmallFarFlagAction
+
+.skip_to_revive
+ xor a
+ ld [wLowHealthAlarm], a
+ ld a, [wCurItem]
+ cp REVIVE
+ jr z, .revive_half_hp
+
+ call ReviveFullHP
+ jr .finish_revive
+
+.revive_half_hp
+ call ReviveHalfHP
+
+.finish_revive
+ call HealHP_SFX_GFX
+ ld a, PARTYMENUTEXT_REVIVE
+ ld [wPartyMenuActionText], a
+ call ItemActionTextWaitButton
+ call UseDisposableItem
+ ld a, 0
+ ret
+; f128
+
+
+FullRestoreEffect: ; f128
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ jp c, StatusHealer_ExitMenu
+
+ call IsMonFainted
+ jp z, StatusHealer_NoEffect
+
+ call IsMonAtFullHealth
+ jr c, .NotAtFullHealth
+
+ jp FullyHealStatus
+
+.NotAtFullHealth:
+ call .FullRestore
+ jp StatusHealer_Jumptable
+; f144
+
+
+.FullRestore: ; f144
+ xor a
+ ld [wLowHealthAlarm], a
+ call ReviveFullHP
+ ld a, MON_STATUS
+ call GetPartyParamLocation
+ xor a
+ ld [hli], a
+ ld [hl], a
+ call HealStatus
+ call BattlemonRestoreHealth
+ call HealHP_SFX_GFX
+ ld a, PARTYMENUTEXT_HEAL_HP
+ ld [wPartyMenuActionText], a
+ call ItemActionTextWaitButton
+ call UseDisposableItem
+ ld a, 0
+ ret
+; f16a
+
+
+BitterBerryEffect: ; f16a
+ ld hl, wPlayerSubStatus3
+ bit SUBSTATUS_CONFUSED, [hl]
+ ld a, 1
+ jr z, .done
+
+ res SUBSTATUS_CONFUSED, [hl]
+ xor a
+ ld [hBattleTurn], a
+ call UseItemText
+
+ ld hl, ConfusedNoMoreText
+ call StdBattleTextBox
+
+ ld a, 0
+
+.done
+ jp StatusHealer_Jumptable
+; f186
+
+
+RestoreHPEffect: ; f186
+ call ItemRestoreHP
+ jp StatusHealer_Jumptable
+; f18c
+
+
+EnergypowderEffect: ; f18c
+ ld c, HAPPINESS_BITTERPOWDER
+ jr EnergypowderEnergyRootCommon
+; f190
+
+EnergyRootEffect: ; f190
+ ld c, HAPPINESS_ENERGYROOT
+; f192
+
+EnergypowderEnergyRootCommon: ; f192
+ push bc
+ call ItemRestoreHP
+ pop bc
+ cp 0
+ jr nz, .skip_happiness
+
+ farcall ChangeHappiness
+ call LooksBitterMessage
+ ld a, 0
+
+.skip_happiness
+ jp StatusHealer_Jumptable
+; f1a9
+
+
+ItemRestoreHP: ; f1a9 (3:71a9)
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ ld a, 2
+ ret c
+
+ call IsMonFainted
+ ld a, 1
+ ret z
+
+ call IsMonAtFullHealth
+ ld a, 1
+ ret nc
+
+ xor a
+ ld [wLowHealthAlarm], a
+ call GetHealingItemAmount
+ call RestoreHealth
+ call BattlemonRestoreHealth
+ call HealHP_SFX_GFX
+ ld a, PARTYMENUTEXT_HEAL_HP
+ ld [wPartyMenuActionText], a
+ call ItemActionTextWaitButton
+ call UseDisposableItem
+ ld a, 0
+ ret
+
+HealHP_SFX_GFX: ; f1db (3:71db)
+ push de
+ ld de, SFX_POTION
+ call WaitPlaySFX
+ pop de
+ ld a, [wCurPartyMon]
+ hlcoord 11, 0
+ ld bc, SCREEN_WIDTH * 2
+ call AddNTimes
+ ld a, $2
+ ld [wWhichHPBar], a
+ predef_jump AnimateHPBar
+
+UseItem_SelectMon: ; f1f9 (3:71f9)
+ call .SelectMon
+ ret c
+
+ ld a, [wCurPartySpecies]
+ cp EGG
+ jr nz, .not_egg
+
+ call CantUseOnEggMessage
+ scf
+ ret
+
+.not_egg
+ and a
+ ret
+
+.SelectMon: ; f20b (3:720b)
+ ld a, b
+ ld [wPartyMenuActionText], a
+ push hl
+ push de
+ push bc
+ call ClearBGPalettes
+ call ChooseMonToUseItemOn
+ pop bc
+ pop de
+ pop hl
+ ret
+
+ChooseMonToUseItemOn: ; f21c (3:721c)
+ farcall LoadPartyMenuGFX
+ farcall InitPartyMenuWithCancel
+ farcall InitPartyMenuGFX
+ farcall WritePartyMenuTilemap
+ farcall PrintPartyMenuText
+ call WaitBGMap
+ call SetPalettes
+ call DelayFrame
+ farcall PartyMenuSelect
+ ret
+
+ItemActionText: ; f24a (3:724a)
+ ld [wPartyMenuActionText], a
+ ld a, [wCurPartySpecies]
+ push af
+ ld a, [wCurPartyMon]
+ push af
+ push hl
+ push de
+ push bc
+ farcall WritePartyMenuTilemap
+ farcall PrintPartyMenuActionText
+ call WaitBGMap
+ call SetPalettes
+ call DelayFrame
+ pop bc
+ pop de
+ pop hl
+ pop af
+ ld [wCurPartyMon], a
+ pop af
+ ld [wCurPartySpecies], a
+ ret
+
+ItemActionTextWaitButton: ; f279 (3:7279)
+ xor a
+ ld [hBGMapMode], a
+ hlcoord 0, 0
+ ld bc, wTileMapEnd - wTileMap
+ ld a, " "
+ call ByteFill
+ ld a, [wPartyMenuActionText]
+ call ItemActionText
+ ld a, $1
+ ld [hBGMapMode], a
+ ld c, 50
+ call DelayFrames
+ jp WaitPressAorB_BlinkCursor
+
+StatusHealer_NoEffect: ; f299 (3:7299)
+ call WontHaveAnyEffectMessage
+ jr StatusHealer_ClearPalettes
+
+StatusHealer_ExitMenu: ; f29e (3:729e)
+ xor a
+ ld [wItemEffectSucceeded], a
+StatusHealer_ClearPalettes: ; f2a2 (3:72a2)
+ call ClearPalettes
+ ret
+
+IsItemUsedOnBattleMon: ; f2a6 (3:72a6)
+ ld a, [wBattleMode]
+ and a
+ ret z
+ ld a, [wCurPartyMon]
+ push hl
+ ld hl, wCurBattleMon
+ cp [hl]
+ pop hl
+ jr nz, .nope
+ scf
+ ret
+
+.nope
+ xor a
+ ret
+
+ReviveHalfHP: ; f2ba (3:72ba)
+ call LoadHPFromBuffer1
+ srl d
+ rr e
+ jr ContinueRevive
+
+ReviveFullHP: ; f2c3 (3:72c3)
+ call LoadHPFromBuffer1
+ContinueRevive: ; f2c6 (3:72c6)
+ ld a, MON_HP
+ call GetPartyParamLocation
+ ld [hl], d
+ inc hl
+ ld [hl], e
+ jp LoadCurHPIntoBuffer5
+
+RestoreHealth: ; f2d1 (3:72d1)
+ ld a, MON_HP + 1
+ call GetPartyParamLocation
+ ld a, [hl]
+ add e
+ ld [hld], a
+ ld a, [hl]
+ adc d
+ ld [hl], a
+ jr c, .full_hp
+ call LoadCurHPIntoBuffer5
+ ld a, MON_HP + 1
+ call GetPartyParamLocation
+ ld d, h
+ ld e, l
+ ld a, MON_MAXHP + 1
+ call GetPartyParamLocation
+ ld a, [de]
+ sub [hl]
+ dec de
+ dec hl
+ ld a, [de]
+ sbc [hl]
+ jr c, .finish
+.full_hp
+ call ReviveFullHP
+.finish
+ ret
+
+RemoveHP: ; f2f9 (3:72f9)
+ ld a, MON_HP + 1
+ call GetPartyParamLocation
+ ld a, [hl]
+ sub e
+ ld [hld], a
+ ld a, [hl]
+ sbc d
+ ld [hl], a
+ jr nc, .okay
+ xor a
+ ld [hld], a
+ ld [hl], a
+.okay
+ call LoadCurHPIntoBuffer5
+ ret
+
+IsMonFainted: ; f30d (3:730d)
+ push de
+ call LoadMaxHPToBuffer1
+ call LoadCurHPToBuffer3
+ call LoadHPFromBuffer3
+ ld a, d
+ or e
+ pop de
+ ret
+
+IsMonAtFullHealth: ; f31b (3:731b)
+ call LoadHPFromBuffer3
+ ld h, d
+ ld l, e
+ call LoadHPFromBuffer1
+ ld a, l
+ sub e
+ ld a, h
+ sbc d
+ ret
+
+LoadCurHPIntoBuffer5: ; f328 (3:7328)
+ ld a, MON_HP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld [wBuffer6], a
+ ld a, [hl]
+ ld [wBuffer5], a
+ ret
+; f336 (3:7336)
+
+LoadHPIntoBuffer5: ; f336
+ ld a, d
+ ld [wBuffer6], a
+ ld a, e
+ ld [wBuffer5], a
+ ret
+; f33f
+
+LoadHPFromBuffer5: ; f33f
+ ld a, [wBuffer6]
+ ld d, a
+ ld a, [wBuffer5]
+ ld e, a
+ ret
+; f348
+
+LoadCurHPToBuffer3: ; f348 (3:7348)
+ ld a, MON_HP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld [wBuffer4], a
+ ld a, [hl]
+ ld [wBuffer3], a
+ ret
+
+LoadHPFromBuffer3: ; f356 (3:7356)
+ ld a, [wBuffer4]
+ ld d, a
+ ld a, [wBuffer3]
+ ld e, a
+ ret
+
+LoadMaxHPToBuffer1: ; f35f (3:735f)
+ push hl
+ ld a, MON_MAXHP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld [wBuffer2], a
+ ld a, [hl]
+ ld [wBuffer1], a
+ pop hl
+ ret
+
+LoadHPFromBuffer1: ; f36f (3:736f)
+ ld a, [wBuffer2]
+ ld d, a
+ ld a, [wBuffer1]
+ ld e, a
+ ret
+
+GetOneFifthMaxHP: ; f378 (3:7378)
+ push bc
+ ld a, MON_MAXHP
+ call GetPartyParamLocation
+ ld a, [hli]
+ ld [hDividend + 0], a
+ ld a, [hl]
+ ld [hDividend + 1], a
+ ld a, 5
+ ld [hDivisor], a
+ ld b, 2
+ call Divide
+ ld a, [hQuotient + 1]
+ ld d, a
+ ld a, [hQuotient + 2]
+ ld e, a
+ pop bc
+ ret
+
+GetHealingItemAmount: ; f395 (3:7395)
+ push hl
+ ld a, [wCurItem]
+ ld hl, HealingHPAmounts
+ ld d, a
+.next
+ ld a, [hli]
+ cp -1
+ jr z, .NotFound
+ cp d
+ jr z, .done
+ inc hl
+ inc hl
+ jr .next
+
+.NotFound:
+ scf
+.done
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ pop hl
+ ret
+; f3af (3:73af)
+
+INCLUDE "data/items/heal_hp.asm"
+
+Softboiled_MilkDrinkFunction: ; f3df (3:73df)
+; Softboiled/Milk Drink in the field
+ ld a, [wPartyMenuCursor]
+ dec a
+ ld b, a
+ call .SelectMilkDrinkRecipient ; select pokemon
+ jr c, .skip
+ ld a, b
+ ld [wCurPartyMon], a
+ call IsMonFainted
+ call GetOneFifthMaxHP
+ call RemoveHP
+ push bc
+ call HealHP_SFX_GFX
+ pop bc
+ call GetOneFifthMaxHP
+ ld a, c
+ ld [wCurPartyMon], a
+ call IsMonFainted
+ call RestoreHealth
+ call HealHP_SFX_GFX
+ ld a, PARTYMENUTEXT_HEAL_HP
+ call ItemActionText
+ call JoyWaitAorB
+.skip
+ ld a, b
+ inc a
+ ld [wPartyMenuCursor], a
+ ret
+
+.SelectMilkDrinkRecipient: ; f419 (3:7419)
+.loop
+ push bc
+ ld a, PARTYMENUACTION_HEALING_ITEM
+ ld [wPartyMenuActionText], a
+ call ChooseMonToUseItemOn
+ pop bc
+ jr c, .set_carry
+ ld a, [wPartyMenuCursor]
+ dec a
+ ld c, a
+ ld a, b
+ cp c
+ jr z, .cant_use ; chose the same mon as user
+ ld a, c
+ ld [wCurPartyMon], a
+ call IsMonFainted
+ jr z, .cant_use
+ call IsMonAtFullHealth
+ jr nc, .cant_use
+ xor a
+ ret
+
+.set_carry
+ scf
+ ret
+
+.cant_use
+ push bc
+ ld hl, .Text_CantBeUsed
+ call MenuTextBoxBackup
+ pop bc
+ jr .loop
+; f44a (3:744a)
+
+.Text_CantBeUsed: ; 0xf44a
+ ; That can't be used on this #MON.
+ text_jump UnknownText_0x1c5bac
+ db "@"
+; 0xf44f
+
+
+EscapeRopeEffect: ; f44f
+ xor a
+ ld [wItemEffectSucceeded], a
+ farcall EscapeRopeFunction
+
+ ld a, [wItemEffectSucceeded]
+ cp 1
+ call z, UseDisposableItem
+ ret
+; f462
+
+
+SuperRepelEffect: ; f462
+ ld b, 200
+ jr UseRepel
+; f466
+
+MaxRepelEffect: ; f466
+ ld b, 250
+ jr UseRepel
+; f466
+
+RepelEffect: ; f46a
+ ld b, 100
+; f46c
+
+UseRepel: ; f46c
+ ld a, [wRepelEffect]
+ and a
+ ld hl, TextJump_RepelUsedEarlierIsStillInEffect
+ jp nz, PrintText
+
+ ld a, b
+ ld [wRepelEffect], a
+ jp UseItemText
+
+
+TextJump_RepelUsedEarlierIsStillInEffect: ; 0xf47d
+ ; The REPEL used earlier is still in effect.
+ text_jump Text_RepelUsedEarlierIsStillInEffect
+ db "@"
+; 0xf482
+
+
+XAccuracyEffect: ; f482
+ ld hl, wPlayerSubStatus4
+ bit SUBSTATUS_X_ACCURACY, [hl]
+ jp nz, WontHaveAnyEffect_NotUsedMessage
+ set SUBSTATUS_X_ACCURACY, [hl]
+ jp UseItemText
+; f48f
+
+
+PokeDollEffect: ; f48f
+ ld a, [wBattleMode]
+ dec a
+ jr nz, .asm_f4a6
+ inc a
+ ld [wForcedSwitch], a
+ ld a, [wBattleResult]
+ and $c0
+ or $2
+ ld [wBattleResult], a
+ jp UseItemText
+
+.asm_f4a6
+ xor a
+ ld [wItemEffectSucceeded], a
+ ret
+; f4ab
+
+
+GuardSpecEffect: ; f4ab
+ ld hl, wPlayerSubStatus4
+ bit SUBSTATUS_MIST, [hl]
+ jp nz, WontHaveAnyEffect_NotUsedMessage
+ set SUBSTATUS_MIST, [hl]
+ jp UseItemText
+; f4b8
+
+
+DireHitEffect: ; f4b8
+ ld hl, wPlayerSubStatus4
+ bit SUBSTATUS_FOCUS_ENERGY, [hl]
+ jp nz, WontHaveAnyEffect_NotUsedMessage
+ set SUBSTATUS_FOCUS_ENERGY, [hl]
+ jp UseItemText
+; f4c5
+
+
+XItemEffect: ; f4c5
+ call UseItemText
+
+ ld a, [wCurItem]
+ ld hl, XItemStats
+
+.loop
+ cp [hl]
+ jr z, .got_it
+ inc hl
+ inc hl
+ jr .loop
+
+.got_it
+ inc hl
+ ld b, [hl]
+ xor a
+ ld [hBattleTurn], a
+ ld [wAttackMissed], a
+ ld [wEffectFailed], a
+ farcall CheckIfStatCanBeRaised
+ call WaitSFX
+
+ farcall BattleCommand_StatUpMessage
+ farcall BattleCommand_StatUpFailText
+
+ ld a, [wCurBattleMon]
+ ld [wCurPartyMon], a
+ ld c, HAPPINESS_USEDXITEM
+ farcall ChangeHappiness
+ ret
+; f504
+
+INCLUDE "data/items/x_stats.asm"
+
+
+PokeFluteEffect: ; f50c
+ ld a, [wBattleMode]
+ and a
+ jr nz, .dummy
+.dummy
+
+ xor a
+ ld [wd002], a
+
+ ld b, $ff ^ SLP
+
+ ld hl, wPartyMon1Status
+ call .CureSleep
+
+ ld a, [wBattleMode]
+ cp WILD_BATTLE
+ jr z, .skip_otrainer
+ ld hl, wOTPartyMon1Status
+ call .CureSleep
+.skip_otrainer
+
+ ld hl, wBattleMonStatus
+ ld a, [hl]
+ and b
+ ld [hl], a
+ ld hl, wEnemyMonStatus
+ ld a, [hl]
+ and b
+ ld [hl], a
+
+ ld a, [wd002]
+ and a
+ ld hl, .CatchyTune
+ jp z, PrintText
+ ld hl, .PlayedTheFlute
+ call PrintText
+
+ ld a, [wLowHealthAlarm]
+ and 1 << DANGER_ON_F
+ jr nz, .dummy2
+.dummy2
+ ld hl, .AllSleepingMonWokeUp
+ jp PrintText
+
+
+.CureSleep:
+ ld de, PARTYMON_STRUCT_LENGTH
+ ld c, PARTY_LENGTH
+
+.loop
+ ld a, [hl]
+ push af
+ and SLP
+ jr z, .not_asleep
+ ld a, 1
+ ld [wd002], a
+.not_asleep
+ pop af
+ and b
+ ld [hl], a
+ add hl, de
+ dec c
+ jr nz, .loop
+ ret
+; f56c
+
+
+.CatchyTune: ; 0xf56c
+ ; Played the # FLUTE. Now, that's a catchy tune!
+ text_jump UnknownText_0x1c5bf9
+ db "@"
+; 0xf571
+
+.AllSleepingMonWokeUp: ; 0xf571
+ ; All sleeping #MON woke up.
+ text_jump UnknownText_0x1c5c28
+ db "@"
+; 0xf576
+
+.PlayedTheFlute: ; 0xf576
+ ; played the # FLUTE.@ @
+ text_jump UnknownText_0x1c5c44
+ start_asm
+ ld a, [wBattleMode]
+ and a
+ jr nz, .battle
+
+ push de
+ ld de, SFX_POKEFLUTE
+ call WaitPlaySFX
+ call WaitSFX
+ pop de
+
+.battle
+ jp PokeFluteTerminatorCharacter
+; f58f
+
+
+BlueCardEffect: ; f58f
+ ld hl, .bluecardtext
+ jp MenuTextBoxWaitButton
+
+.bluecardtext
+ text_jump UnknownText_0x1c5c5e
+ db "@"
+; f59a
+
+
+CoinCaseEffect: ; f59a
+ ld hl, .coincasetext
+ jp MenuTextBoxWaitButton
+
+.coincasetext
+ text_jump UnknownText_0x1c5c7b
+ db "@"
+; f5a5
+
+
+OldRodEffect: ; f5a5
+ ld e, $0
+ jr UseRod
+; f5a9
+
+GoodRodEffect: ; f5a9
+ ld e, $1
+ jr UseRod
+; f5ad
+
+SuperRodEffect: ; f5ad
+ ld e, $2
+ jr UseRod
+; f5b1
+
+UseRod: ; f5b1
+ farcall FishFunction
+ ret
+; f5b8
+
+
+ItemfinderEffect: ; f5b8
+ farcall ItemFinder
+ ret
+; f5bf
+
+
+RestorePPEffect: ; f5bf
+ ld a, [wCurItem]
+ ld [wd002], a
+
+.loop
+ ; Party Screen opens to choose on which mon to use the Item
+ ld b, PARTYMENUACTION_HEALING_ITEM
+ call UseItem_SelectMon
+ jp c, PPRestoreItem_Cancel
+
+.loop2
+ ld a, [wd002]
+ cp MAX_ELIXER
+ jp z, Elixer_RestorePPofAllMoves
+ cp ELIXER
+ jp z, Elixer_RestorePPofAllMoves
+
+ ld hl, TextJump_RaiseThePPOfWhichMove
+ ld a, [wd002]
+ cp PP_UP
+ jr z, .ppup
+ ld hl, TextJump_RestoreThePPOfWhichMove
+
+.ppup
+ call PrintText
+
+ ld a, [wCurMoveNum]
+ push af
+ xor a
+ ld [wCurMoveNum], a
+ ld a, $2
+ ld [wMoveSelectionMenuType], a
+ farcall MoveSelectionScreen
+ pop bc
+
+ ld a, b
+ ld [wCurMoveNum], a
+ jr nz, .loop
+ ld hl, wPartyMon1Moves
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call GetMthMoveOfNthPartymon
+
+ push hl
+ ld a, [hl]
+ ld [wd265], a
+ call GetMoveName
+ call CopyName1
+ pop hl
+
+ ld a, [wd002]
+ cp PP_UP
+ jp nz, Not_PP_Up
+
+ ld a, [hl]
+ cp SKETCH
+ jr z, .CantUsePPUpOnSketch
+
+ ld bc, MON_PP - MON_MOVES
+ add hl, bc
+ ld a, [hl]
+ cp PP_UP_MASK
+ jr c, .do_ppup
+
+.CantUsePPUpOnSketch:
+.pp_is_maxed_out
+ ld hl, TextJump_PPIsMaxedOut
+ call PrintText
+ jr .loop2
+
+.do_ppup
+ ld a, [hl]
+ add PP_UP_ONE
+ ld [hl], a
+ ld a, $1
+ ld [wd265], a
+ call ApplyPPUp
+ call Play_SFX_FULL_HEAL
+
+ ld hl, TextJump_PPsIncreased
+ call PrintText
+
+FinishPPRestore: ; f64c
+ call ClearPalettes
+ jp UseDisposableItem
+; f652
+
+BattleRestorePP: ; f652
+ ld a, [wBattleMode]
+ and a
+ jr z, .not_in_battle
+ ld a, [wCurPartyMon]
+ ld b, a
+ ld a, [wCurBattleMon]
+ cp b
+ jr nz, .not_in_battle
+ ld a, [wPlayerSubStatus5]
+ bit SUBSTATUS_TRANSFORMED, a
+ jr nz, .not_in_battle
+ call .UpdateBattleMonPP
+
+.not_in_battle
+ call Play_SFX_FULL_HEAL
+ ld hl, UnknownText_0xf739
+ call PrintText
+ jr FinishPPRestore
+
+.UpdateBattleMonPP:
+ ld a, [wCurPartyMon]
+ ld hl, wPartyMon1Moves
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call AddNTimes
+ ld de, wBattleMonMoves
+ ld b, NUM_MOVES
+.loop
+ ld a, [de]
+ and a
+ jr z, .done
+ cp [hl]
+ jr nz, .next
+ push hl
+ push de
+ push bc
+ rept NUM_MOVES + 2 ; wBattleMonPP - wBattleMonMoves
+ inc de
+ endr
+ ld bc, MON_PP - MON_MOVES
+ add hl, bc
+ ld a, [hl]
+ ld [de], a
+ pop bc
+ pop de
+ pop hl
+
+.next
+ inc hl
+ inc de
+ dec b
+ jr nz, .loop
+
+.done
+ ret
+; f6a7
+
+Not_PP_Up: ; f6a7
+ call RestorePP
+ jr nz, BattleRestorePP
+ jp PPRestoreItem_NoEffect
+; f6af
+
+Elixer_RestorePPofAllMoves: ; f6af
+ xor a
+ ld hl, wMenuCursorY
+ ld [hli], a
+ ld [hl], a
+ ld b, NUM_MOVES
+.moveLoop
+ push bc
+ ld hl, wPartyMon1Moves
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call GetMthMoveOfNthPartymon
+ ld a, [hl]
+ and a
+ jr z, .next
+
+ call RestorePP
+ jr z, .next
+ ld hl, wMenuCursorX
+ inc [hl]
+
+.next
+ ld hl, wMenuCursorY
+ inc [hl]
+ pop bc
+ dec b
+ jr nz, .moveLoop
+ ld a, [wMenuCursorX]
+ and a
+ jp nz, BattleRestorePP
+
+PPRestoreItem_NoEffect: ; f6dd
+ call WontHaveAnyEffectMessage
+
+PPRestoreItem_Cancel: ; f6e0
+ call ClearPalettes
+ xor a
+ ld [wItemEffectSucceeded], a
+ ret
+; f6e8
+
+RestorePP: ; f6e8
+ xor a ; PARTYMON
+ ld [wMonType], a
+ call GetMaxPPOfMove
+ ld hl, wPartyMon1PP
+ ld bc, PARTYMON_STRUCT_LENGTH
+ call GetMthMoveOfNthPartymon
+ ld a, [wd265]
+ ld b, a
+ ld a, [hl]
+ and PP_MASK
+ cp b
+ jr nc, .dont_restore
+
+ ld a, [wd002]
+ cp MAX_ELIXER
+ jr z, .restore_all
+ cp MAX_ETHER
+ jr z, .restore_all
+
+ ld c, 5
+ cp MYSTERYBERRY
+ jr z, .restore_some
+
+ ld c, 10
+
+.restore_some
+ ld a, [hl]
+ and PP_MASK
+ add c
+ cp b
+ jr nc, .restore_all
+ ld b, a
+
+.restore_all
+ ld a, [hl]
+ and PP_UP_MASK
+ or b
+ ld [hl], a
+ ret
+
+.dont_restore
+ xor a
+ ret
+; f725
+
+TextJump_RaiseThePPOfWhichMove: ; 0xf725
+ ; Raise the PP of which move?
+ text_jump Text_RaiseThePPOfWhichMove
+ db "@"
+; 0xf72a
+
+TextJump_RestoreThePPOfWhichMove: ; 0xf72a
+ ; Restore the PP of which move?
+ text_jump Text_RestoreThePPOfWhichMove
+ db "@"
+; 0xf72f
+
+TextJump_PPIsMaxedOut: ; 0xf72f
+ ; 's PP is maxed out.
+ text_jump Text_PPIsMaxedOut
+ db "@"
+; 0xf734
+
+TextJump_PPsIncreased: ; 0xf734
+ ; 's PP increased.
+ text_jump Text_PPsIncreased
+ db "@"
+; 0xf739
+
+UnknownText_0xf739: ; 0xf739
+ ; PP was restored.
+ text_jump UnknownText_0x1c5cf1
+ db "@"
+; 0xf73e
+
+
+SquirtbottleEffect: ; f73e
+ farcall _Squirtbottle
+ ret
+; f745
+
+
+CardKeyEffect: ; f745
+ farcall _CardKey
+ ret
+; f74c
+
+
+BasementKeyEffect: ; f74c
+ farcall _BasementKey
+ ret
+; f753
+
+
+SacredAshEffect: ; f753
+ farcall _SacredAsh
+ ld a, [wItemEffectSucceeded]
+ cp $1
+ ret nz
+ call UseDisposableItem
+ ret
+; f763
+
+
+NormalBoxEffect: ; f763
+ ld c, DECOFLAG_SILVER_TROPHY_DOLL
+ jr OpenBox
+; f767
+
+GorgeousBoxEffect: ; f767
+ ld c, DECOFLAG_GOLD_TROPHY_DOLL
+OpenBox: ; f769
+ farcall SetSpecificDecorationFlag
+
+ ld hl, .text
+ call PrintText
+
+ jp UseDisposableItem
+; f778
+
+.text ; 0xf778
+ ; There was a trophy inside!
+ text_jump UnknownText_0x1c5d03
+ db "@"
+; 0xf77d
+
+NoEffect: ; f77d
+ jp IsntTheTimeMessage
+; f780
+
+
+Play_SFX_FULL_HEAL: ; f780
+ push de
+ ld de, SFX_FULL_HEAL
+ call WaitPlaySFX
+ pop de
+ ret
+; f789
+
+UseItemText: ; f789
+ ld hl, UsedItemText
+ call PrintText
+ call Play_SFX_FULL_HEAL
+ call WaitPressAorB_BlinkCursor
+UseDisposableItem: ; f795
+ ld hl, wNumItems
+ ld a, 1
+ ld [wItemQuantityChangeBuffer], a
+ jp TossItem
+; f7a0
+
+UseBallInTrainerBattle: ; f7a0
+ call ReturnToBattle_UseBall
+ ld de, ANIM_THROW_POKE_BALL
+ ld a, e
+ ld [wFXAnimID], a
+ ld a, d
+ ld [wFXAnimID + 1], a
+ xor a
+ ld [wBattleAnimParam], a
+ ld [hBattleTurn], a
+ ld [wNumHits], a
+ predef PlayBattleAnim
+ ld hl, BlockedTheBallText
+ call PrintText
+ ld hl, DontBeAThiefText
+ call PrintText
+ jr UseDisposableItem
+; f7ca
+
+WontHaveAnyEffect_NotUsedMessage: ; f7ca
+ ld hl, WontHaveAnyEffectText
+ call PrintText
+
+ ; Item wasn't used.
+ ld a, $2
+ ld [wItemEffectSucceeded], a
+ ret
+; f7d6
+
+LooksBitterMessage: ; f7d6
+ ld hl, LooksBitterText
+ jp PrintText
+; f7dc
+
+Ball_BoxIsFullMessage: ; f7dc
+ ld hl, Ball_BoxIsFullText
+ call PrintText
+
+ ; Item wasn't used.
+ ld a, $2
+ ld [wItemEffectSucceeded], a
+ ret
+; f7e8
+
+CantUseOnEggMessage: ; f7e8
+ ld hl, CantUseOnEggText
+ jr CantUseItemMessage
+
+IsntTheTimeMessage: ; f7ed
+ ld hl, IsntTheTimeText
+ jr CantUseItemMessage
+
+WontHaveAnyEffectMessage: ; f7f2
+ ld hl, WontHaveAnyEffectText
+ jr CantUseItemMessage
+
+BelongsToSomeoneElseMessage: ; f7f7
+ ld hl, BelongsToSomeoneElseText
+ jr CantUseItemMessage
+
+CyclingIsntAllowedMessage: ; f7fc
+ ld hl, CyclingIsntAllowedText
+ jr CantUseItemMessage
+
+CantGetOnYourBikeMessage: ; f801
+ ld hl, CantGetOnYourBikeText
+
+CantUseItemMessage: ; f804
+; Item couldn't be used.
+ xor a
+ ld [wItemEffectSucceeded], a
+ jp PrintText
+; f80b
+
+LooksBitterText: ; 0xf80b
+ ; It looks bitter…
+ text_jump UnknownText_0x1c5d3e
+ db "@"
+; 0xf810
+
+CantUseOnEggText: ; 0xf810
+ ; That can't be used on an EGG.
+ text_jump UnknownText_0x1c5d50
+ db "@"
+; 0xf815
+
+IsntTheTimeText: ; 0xf815
+ ; OAK: ! This isn't the time to use that!
+ text_jump UnknownText_0x1c5d6e
+ db "@"
+; 0xf81a
+
+BelongsToSomeoneElseText: ; 0xf81a
+ ; That belongs to someone else!
+ text_jump UnknownText_0x1c5d97
+ db "@"
+; 0xf81f
+
+WontHaveAnyEffectText: ; 0xf81f
+ ; It won't have any effect.
+ text_jump UnknownText_0x1c5db6
+ db "@"
+; 0xf824
+
+BlockedTheBallText: ; 0xf824
+ ; The trainer blocked the BALL!
+ text_jump UnknownText_0x1c5dd0
+ db "@"
+; 0xf829
+
+DontBeAThiefText: ; 0xf829
+ ; Don't be a thief!
+ text_jump UnknownText_0x1c5def
+ db "@"
+; 0xf82e
+
+CyclingIsntAllowedText: ; 0xf82e
+ ; Cycling isn't allowed here.
+ text_jump UnknownText_0x1c5e01
+ db "@"
+; 0xf833
+
+CantGetOnYourBikeText: ; 0xf833
+ ; Can't get on your @ now.
+ text_jump UnknownText_0x1c5e1d
+ db "@"
+; 0xf838
+
+Ball_BoxIsFullText: ; 0xf838
+ ; The #MON BOX is full. That can't be used now.
+ text_jump UnknownText_0x1c5e3a
+ db "@"
+; 0xf83d
+
+UsedItemText: ; 0xf83d
+ ; used the@ .
+ text_jump UnknownText_0x1c5e68
+ db "@"
+; 0xf842
+
+GotOnTheItemText: ; 0xf842
+ ; got on the@ .
+ text_jump UnknownText_0x1c5e7b
+ db "@"
+; 0xf847
+
+GotOffTheItemText: ; 0xf847
+ ; got off@ the @ .
+ text_jump UnknownText_0x1c5e90
+ db "@"
+; 0xf84c
+
+
+ApplyPPUp: ; f84c
+ ld a, MON_MOVES
+ call GetPartyParamLocation
+ push hl
+ ld de, wBuffer1
+ predef FillPP
+ pop hl
+ ld bc, MON_PP - MON_MOVES
+ add hl, bc
+ ld de, wBuffer1
+ ld b, 0
+.loop
+ inc b
+ ld a, b
+ cp NUM_MOVES + 1
+ ret z
+ ld a, [wd265]
+ dec a
+ jr nz, .use
+ ld a, [wMenuCursorY]
+ inc a
+ cp b
+ jr nz, .skip
+
+.use
+ ld a, [hl]
+ and PP_UP_MASK
+ ld a, [de] ; wasted cycle
+ call nz, ComputeMaxPP
+
+.skip
+ inc hl
+ inc de
+ jr .loop
+; f881
+
+
+
+ComputeMaxPP: ; f881
+ push bc
+ ; Divide the base PP by 5.
+ ld a, [de]
+ ld [hDividend + 3], a
+ xor a
+ ld [hDividend], a
+ ld [hDividend + 1], a
+ ld [hDividend + 2], a
+ ld a, 5
+ ld [hDivisor], a
+ ld b, 4
+ call Divide
+ ; Get the number of PP, which are bits 6 and 7 of the PP value stored in RAM.
+ ld a, [hl]
+ ld b, a
+ swap a
+ and $f
+ srl a
+ srl a
+ ld c, a
+ ; If this value is 0, we are done
+ and a
+ jr z, .NoPPUp
+
+.loop
+ ; Normally, a move with 40 PP would have 64 PP with three PP Ups.
+ ; Since this would overflow into bit 6, we prevent that from happening
+ ; by decreasing the extra amount of PP each PP Up provides, resulting
+ ; in a maximum of 61.
+ ld a, [hQuotient + 2]
+ cp $8
+ jr c, .okay
+ ld a, $7
+
+.okay
+ add b
+ ld b, a
+ ld a, [wd265]
+ dec a
+ jr z, .NoPPUp
+ dec c
+ jr nz, .loop
+
+.NoPPUp:
+ ld [hl], b
+ pop bc
+ ret
+; f8b9
+
+RestoreAllPP: ; f8b9
+ ld a, MON_PP
+ call GetPartyParamLocation
+ push hl
+ ld a, MON_MOVES
+ call GetPartyParamLocation
+ pop de
+ xor a ; PARTYMON
+ ld [wMenuCursorY], a
+ ld [wMonType], a
+ ld c, NUM_MOVES
+.loop
+ ld a, [hli]
+ and a
+ ret z
+ push hl
+ push de
+ push bc
+ call GetMaxPPOfMove
+ pop bc
+ pop de
+ ld a, [de]
+ and PP_UP_MASK
+ ld b, a
+ ld a, [wd265]
+ add b
+ ld [de], a
+ inc de
+ ld hl, wMenuCursorY
+ inc [hl]
+ pop hl
+ dec c
+ jr nz, .loop
+ ret
+; f8ec
+
+
+GetMaxPPOfMove: ; f8ec
+ ld a, [wStringBuffer1 + 0]
+ push af
+ ld a, [wStringBuffer1 + 1]
+ push af
+
+ ld a, [wMonType]
+ and a
+
+ ld hl, wPartyMon1Moves
+ ld bc, PARTYMON_STRUCT_LENGTH
+ jr z, .got_partymon ; PARTYMON
+
+ ld hl, wOTPartyMon1Moves
+ dec a
+ jr z, .got_partymon ; OTPARTYMON
+
+ ld hl, wTempMonMoves
+ dec a
+ jr z, .got_nonpartymon ; BOXMON
+
+ ld hl, wTempMonMoves ; Wasted cycles
+ dec a
+ jr z, .got_nonpartymon ; TEMPMON
+
+ ld hl, wBattleMonMoves ; WILDMON
+
+.got_nonpartymon ; BOXMON, TEMPMON, WILDMON
+ call GetMthMoveOfCurrentMon
+ jr .gotdatmove
+
+.got_partymon ; PARTYMON, OTPARTYMON
+ call GetMthMoveOfNthPartymon
+
+.gotdatmove
+ ld a, [hl]
+ dec a
+
+ push hl
+ ld hl, Moves + MOVE_PP
+ ld bc, MOVE_LENGTH
+ call AddNTimes
+ ld a, BANK(Moves)
+ call GetFarByte
+ ld b, a
+ ld de, wStringBuffer1
+ ld [de], a
+ pop hl
+
+ push bc
+ ld bc, MON_PP - MON_MOVES
+ ld a, [wMonType]
+ cp WILDMON
+ jr nz, .notwild
+ ld bc, wEnemyMonPP - wEnemyMonMoves
+.notwild
+ add hl, bc
+ ld a, [hl]
+ and PP_UP_MASK
+ pop bc
+
+ or b
+ ld hl, wStringBuffer1 + 1
+ ld [hl], a
+ xor a
+ ld [wd265], a
+ ld a, b ; this gets lost anyway
+ call ComputeMaxPP
+ ld a, [hl]
+ and PP_MASK
+ ld [wd265], a
+
+ pop af
+ ld [wStringBuffer1 + 1], a
+ pop af
+ ld [wStringBuffer1 + 0], a
+ ret
+; f963
+
+GetMthMoveOfNthPartymon: ; f963
+ ld a, [wCurPartyMon]
+ call AddNTimes
+
+GetMthMoveOfCurrentMon: ; f969
+ ld a, [wMenuCursorY]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ret
+; f971
diff --git a/engine/items/items.asm b/engine/items/items.asm
new file mode 100755
index 000000000..c07042aed
--- /dev/null
+++ b/engine/items/items.asm
@@ -0,0 +1,581 @@
+_ReceiveItem:: ; d1d5
+ call DoesHLEqualNumItems
+ jp nz, PutItemInPocket
+ push hl
+ call CheckItemPocket
+ pop de
+ ld a, [wItemAttributeParamBuffer]
+ dec a
+ ld hl, .Pockets
+ rst JumpTable
+ ret
+
+.Pockets: ; d1e9
+; entries correspond to item types
+ dw .Item
+ dw .KeyItem
+ dw .Ball
+ dw .TMHM
+
+.Item: ; d1f1
+ ld h, d
+ ld l, e
+ jp PutItemInPocket
+
+.KeyItem: ; d1f6
+ ld h, d
+ ld l, e
+ jp ReceiveKeyItem
+
+.Ball: ; d1fb
+ ld hl, wNumBalls
+ jp PutItemInPocket
+
+.TMHM: ; d201
+ ld h, d
+ ld l, e
+ ld a, [wCurItem]
+ ld c, a
+ call GetTMHMNumber
+ jp ReceiveTMHM
+
+_TossItem:: ; d20d
+ call DoesHLEqualNumItems
+ jr nz, .remove
+ push hl
+ call CheckItemPocket
+ pop de
+ ld a, [wItemAttributeParamBuffer]
+ dec a
+ ld hl, .Pockets
+ rst JumpTable
+ ret
+
+.Pockets:
+; entries correspond to item types
+ dw .Item
+ dw .KeyItem
+ dw .Ball
+ dw .TMHM
+
+.Ball: ; d228
+ ld hl, wNumBalls
+ jp RemoveItemFromPocket
+
+.TMHM: ; d22e
+ ld h, d
+ ld l, e
+ ld a, [wCurItem]
+ ld c, a
+ call GetTMHMNumber
+ jp TossTMHM
+
+.KeyItem: ; d23a
+ ld h, d
+ ld l, e
+ jp TossKeyItem
+
+.Item: ; d23f
+ ld h, d
+ ld l, e
+
+.remove
+ jp RemoveItemFromPocket
+
+_CheckItem:: ; d244
+ call DoesHLEqualNumItems
+ jr nz, .nope
+ push hl
+ call CheckItemPocket
+ pop de
+ ld a, [wItemAttributeParamBuffer]
+ dec a
+ ld hl, .Pockets
+ rst JumpTable
+ ret
+
+.Pockets:
+; entries correspond to item types
+ dw .Item
+ dw .KeyItem
+ dw .Ball
+ dw .TMHM
+
+.Ball: ; d25f
+ ld hl, wNumBalls
+ jp CheckTheItem
+
+.TMHM: ; d265
+ ld h, d
+ ld l, e
+ ld a, [wCurItem]
+ ld c, a
+ call GetTMHMNumber
+ jp CheckTMHM
+
+.KeyItem: ; d271
+ ld h, d
+ ld l, e
+ jp CheckKeyItems
+
+.Item: ; d276
+ ld h, d
+ ld l, e
+
+.nope
+ jp CheckTheItem
+
+DoesHLEqualNumItems: ; d27b
+ ld a, l
+ cp LOW(wNumItems)
+ ret nz
+ ld a, h
+ cp HIGH(wNumItems)
+ ret
+
+GetPocketCapacity: ; d283
+ ld c, MAX_ITEMS
+ ld a, e
+ cp LOW(wNumItems)
+ jr nz, .not_bag
+ ld a, d
+ cp HIGH(wNumItems)
+ ret z
+
+.not_bag
+ ld c, MAX_PC_ITEMS
+ ld a, e
+ cp LOW(wPCItems)
+ jr nz, .not_pc
+ ld a, d
+ cp HIGH(wPCItems)
+ ret z
+
+.not_pc
+ ld c, MAX_BALLS
+ ret
+
+PutItemInPocket: ; d29c
+ ld d, h
+ ld e, l
+ inc hl
+ ld a, [wCurItem]
+ ld c, a
+ ld b, 0
+.loop
+ ld a, [hli]
+ cp -1
+ jr z, .terminator
+ cp c
+ jr nz, .next
+ ld a, 99
+ sub [hl]
+ add b
+ ld b, a
+ ld a, [wItemQuantityChangeBuffer]
+ cp b
+ jr z, .ok
+ jr c, .ok
+
+.next
+ inc hl
+ jr .loop
+
+.terminator
+ call GetPocketCapacity
+ ld a, [de]
+ cp c
+ jr c, .ok
+ and a
+ ret
+
+.ok
+ ld h, d
+ ld l, e
+ ld a, [wCurItem]
+ ld c, a
+ ld a, [wItemQuantityChangeBuffer]
+ ld [wItemQuantityBuffer], a
+.loop2
+ inc hl
+ ld a, [hli]
+ cp -1
+ jr z, .terminator2
+ cp c
+ jr nz, .loop2
+ ld a, [wItemQuantityBuffer]
+ add [hl]
+ cp 100
+ jr nc, .newstack
+ ld [hl], a
+ jr .done
+
+.newstack
+ ld [hl], 99
+ sub 99
+ ld [wItemQuantityBuffer], a
+ jr .loop2
+
+.terminator2
+ dec hl
+ ld a, [wCurItem]
+ ld [hli], a
+ ld a, [wItemQuantityBuffer]
+ ld [hli], a
+ ld [hl], -1
+ ld h, d
+ ld l, e
+ inc [hl]
+
+.done
+ scf
+ ret
+
+RemoveItemFromPocket: ; d2ff
+ ld d, h
+ ld e, l
+ ld a, [hli]
+ ld c, a
+ ld a, [wCurItemQuantity]
+ cp c
+ jr nc, .ok ; memory
+ ld c, a
+ ld b, $0
+ add hl, bc
+ add hl, bc
+ ld a, [wCurItem]
+ cp [hl]
+ inc hl
+ jr z, .skip
+ ld h, d
+ ld l, e
+ inc hl
+
+.ok
+ ld a, [wCurItem]
+ ld b, a
+.loop
+ ld a, [hli]
+ cp b
+ jr z, .skip
+ cp -1
+ jr z, .nope
+ inc hl
+ jr .loop
+
+.skip
+ ld a, [wItemQuantityChangeBuffer]
+ ld b, a
+ ld a, [hl]
+ sub b
+ jr c, .nope
+ ld [hl], a
+ ld [wItemQuantityBuffer], a
+ and a
+ jr nz, .yup
+ dec hl
+ ld b, h
+ ld c, l
+ inc hl
+ inc hl
+.loop2
+ ld a, [hli]
+ ld [bc], a
+ inc bc
+ cp -1
+ jr nz, .loop2
+ ld h, d
+ ld l, e
+ dec [hl]
+
+.yup
+ scf
+ ret
+
+.nope
+ and a
+ ret
+
+CheckTheItem: ; d349
+ ld a, [wCurItem]
+ ld c, a
+.loop
+ inc hl
+ ld a, [hli]
+ cp -1
+ jr z, .done
+ cp c
+ jr nz, .loop
+ scf
+ ret
+
+.done
+ and a
+ ret
+
+ReceiveKeyItem: ; d35a
+ ld hl, wNumKeyItems
+ ld a, [hli]
+ cp MAX_KEY_ITEMS
+ jr nc, .nope
+ ld c, a
+ ld b, 0
+ add hl, bc
+ ld a, [wCurItem]
+ ld [hli], a
+ ld [hl], -1
+ ld hl, wNumKeyItems
+ inc [hl]
+ scf
+ ret
+
+.nope
+ and a
+ ret
+
+TossKeyItem: ; d374
+ ld a, [wCurItemQuantity]
+ ld e, a
+ ld d, 0
+ ld hl, wNumKeyItems
+ ld a, [hl]
+ cp e
+ jr nc, .ok
+ call .Toss
+ ret nc
+ jr .ok2
+
+.ok
+ dec [hl]
+ inc hl
+ add hl, de
+
+.ok2
+ ld d, h
+ ld e, l
+ inc hl
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp -1
+ jr nz, .loop
+ scf
+ ret
+
+.Toss: ; d396
+ ld hl, wNumKeyItems
+ ld a, [wCurItem]
+ ld c, a
+.loop3
+ inc hl
+ ld a, [hl]
+ cp c
+ jr z, .ok3
+ cp -1
+ jr nz, .loop3
+ xor a
+ ret
+
+.ok3
+ ld a, [wNumKeyItems]
+ dec a
+ ld [wNumKeyItems], a
+ scf
+ ret
+
+CheckKeyItems: ; d3b1
+ ld a, [wCurItem]
+ ld c, a
+ ld hl, wKeyItems
+.loop
+ ld a, [hli]
+ cp c
+ jr z, .done
+ cp -1
+ jr nz, .loop
+ and a
+ ret
+
+.done
+ scf
+ ret
+
+ReceiveTMHM: ; d3c4
+ dec c
+ ld b, 0
+ ld hl, wTMsHMs
+ add hl, bc
+ ld a, [wItemQuantityChangeBuffer]
+ add [hl]
+ cp 100
+ jr nc, .toomany
+ ld [hl], a
+ scf
+ ret
+
+.toomany
+ and a
+ ret
+
+TossTMHM: ; d3d8
+ dec c
+ ld b, 0
+ ld hl, wTMsHMs
+ add hl, bc
+ ld a, [wItemQuantityChangeBuffer]
+ ld b, a
+ ld a, [hl]
+ sub b
+ jr c, .nope
+ ld [hl], a
+ ld [wItemQuantityBuffer], a
+ jr nz, .yup
+ ld a, [wTMHMPocketScrollPosition]
+ and a
+ jr z, .yup
+ dec a
+ ld [wTMHMPocketScrollPosition], a
+
+.yup
+ scf
+ ret
+
+.nope
+ and a
+ ret
+
+CheckTMHM: ; d3fb
+ dec c
+ ld b, $0
+ ld hl, wTMsHMs
+ add hl, bc
+ ld a, [hl]
+ and a
+ ret z
+ scf
+ ret
+
+GetTMHMNumber:: ; d407
+; Return the number of a TM/HM by item id c.
+ ld a, c
+; Skip any dummy items.
+ cp ITEM_C3 ; TM04-05
+ jr c, .done
+ cp ITEM_DC ; TM28-29
+ jr c, .skip
+ dec a
+.skip
+ dec a
+.done
+ sub TM01
+ inc a
+ ld c, a
+ ret
+
+GetNumberedTMHM: ; d417
+; Return the item id of a TM/HM by number c.
+ ld a, c
+; Skip any gaps.
+ cp ITEM_C3 - (TM01 - 1)
+ jr c, .done
+ cp ITEM_DC - (TM01 - 1) - 1
+ jr c, .skip_one
+.skip_two
+ inc a
+.skip_one
+ inc a
+.done
+ add TM01
+ dec a
+ ld c, a
+ ret
+
+_CheckTossableItem:: ; d427
+; Return 1 in wItemAttributeParamBuffer and carry if wCurItem can't be removed from the bag.
+ ld a, ITEMATTR_PERMISSIONS
+ call GetItemAttr
+ bit CANT_TOSS_F, a
+ jr nz, ItemAttr_ReturnCarry
+ and a
+ ret
+
+CheckSelectableItem: ; d432
+; Return 1 in wItemAttributeParamBuffer and carry if wCurItem can't be selected.
+ ld a, ITEMATTR_PERMISSIONS
+ call GetItemAttr
+ bit CANT_SELECT_F, a
+ jr nz, ItemAttr_ReturnCarry
+ and a
+ ret
+
+CheckItemPocket:: ; d43d
+; Return the pocket for wCurItem in wItemAttributeParamBuffer.
+ ld a, ITEMATTR_POCKET
+ call GetItemAttr
+ and $f
+ ld [wItemAttributeParamBuffer], a
+ ret
+
+CheckItemContext: ; d448
+; Return the context for wCurItem in wItemAttributeParamBuffer.
+ ld a, ITEMATTR_HELP
+ call GetItemAttr
+ and $f
+ ld [wItemAttributeParamBuffer], a
+ ret
+
+CheckItemMenu: ; d453
+; Return the menu for wCurItem in wItemAttributeParamBuffer.
+ ld a, ITEMATTR_HELP
+ call GetItemAttr
+ swap a
+ and $f
+ ld [wItemAttributeParamBuffer], a
+ ret
+
+GetItemAttr: ; d460
+; Get attribute a of wCurItem.
+
+ push hl
+ push bc
+
+ ld hl, ItemAttributes
+ ld c, a
+ ld b, 0
+ add hl, bc
+
+ xor a
+ ld [wItemAttributeParamBuffer], a
+
+ ld a, [wCurItem]
+ dec a
+ ld c, a
+ ld a, ITEMATTR_STRUCT_LENGTH
+ call AddNTimes
+ ld a, BANK(ItemAttributes)
+ call GetFarByte
+
+ pop bc
+ pop hl
+ ret
+
+ItemAttr_ReturnCarry: ; d47f
+ ld a, 1
+ ld [wItemAttributeParamBuffer], a
+ scf
+ ret
+
+GetItemPrice: ; d486
+; Return the price of wCurItem in de.
+ push hl
+ push bc
+ ld a, ITEMATTR_PRICE
+ call GetItemAttr
+ ld e, a
+ ld a, ITEMATTR_PRICE_HI
+ call GetItemAttr
+ ld d, a
+ pop bc
+ pop hl
+ ret
diff --git a/engine/items/mart.asm b/engine/items/mart.asm
new file mode 100755
index 000000000..911251f65
--- /dev/null
+++ b/engine/items/mart.asm
@@ -0,0 +1,970 @@
+ const_def
+ const MARTTEXT_HOW_MANY
+ const MARTTEXT_COSTS_THIS_MUCH
+ const MARTTEXT_NOT_ENOUGH_MONEY
+ const MARTTEXT_BAG_FULL
+ const MARTTEXT_HERE_YOU_GO
+ const MARTTEXT_SOLD_OUT
+
+OpenMartDialog:: ; 15a45
+ call GetMart
+ ld a, c
+ ld [wEngineBuffer1], a
+ call LoadMartPointer
+ ld a, [wEngineBuffer1]
+ ld hl, .dialogs
+ rst JumpTable
+ ret
+; 15a57
+
+.dialogs
+ dw MartDialog
+ dw HerbShop
+ dw BargainShop
+ dw Pharmacist
+ dw RooftopSale
+; 15a61
+
+MartDialog: ; 15a61
+ ld a, 0
+ ld [wEngineBuffer1], a
+ xor a
+ ld [wEngineBuffer5], a
+ call StandardMart
+ ret
+; 15a6e
+
+HerbShop: ; 15a6e
+ call FarReadMart
+ call LoadStandardMenuHeader
+ ld hl, Text_HerbShop_Intro
+ call MartTextBox
+ call BuyMenu
+ ld hl, Text_HerbShop_ComeAgain
+ call MartTextBox
+ ret
+; 15a84
+
+BargainShop: ; 15a84
+ ld b, BANK(BargainShopData)
+ ld de, BargainShopData
+ call LoadMartPointer
+ call ReadMart
+ call LoadStandardMenuHeader
+ ld hl, Text_BargainShop_Intro
+ call MartTextBox
+ call BuyMenu
+ ld hl, wBargainShopFlags
+ ld a, [hli]
+ or [hl]
+ jr z, .skip_set
+ ld hl, wDailyFlags
+ set DAILYFLAGS_GOLDENROD_UNDERGROUND_BARGAIN_F, [hl]
+
+.skip_set
+ ld hl, Text_BargainShop_ComeAgain
+ call MartTextBox
+ ret
+; 15aae
+
+Pharmacist: ; 15aae
+ call FarReadMart
+ call LoadStandardMenuHeader
+ ld hl, Text_Pharmacist_Intro
+ call MartTextBox
+ call BuyMenu
+ ld hl, Text_Pharmacist_ComeAgain
+ call MartTextBox
+ ret
+; 15ac4
+
+RooftopSale: ; 15ac4
+ ld b, BANK(RooftopSaleMart1)
+ ld de, RooftopSaleMart1
+ ld hl, wStatusFlags
+ bit STATUSFLAGS_HALL_OF_FAME_F, [hl]
+ jr z, .ok
+ ld b, BANK(RooftopSaleMart2)
+ ld de, RooftopSaleMart2
+
+.ok
+ call LoadMartPointer
+ call ReadMart
+ call LoadStandardMenuHeader
+ ld hl, Text_Mart_HowMayIHelpYou
+ call MartTextBox
+ call BuyMenu
+ ld hl, Text_Mart_ComeAgain
+ call MartTextBox
+ ret
+; 15aee
+
+INCLUDE "data/items/rooftop_sale.asm"
+
+LoadMartPointer: ; 15b10
+ ld a, b
+ ld [wMartPointerBank], a
+ ld a, e
+ ld [wMartPointer], a
+ ld a, d
+ ld [wMartPointer + 1], a
+ ld hl, wCurMart
+ xor a
+ ld bc, 16
+ call ByteFill
+ xor a
+ ld [wEngineBuffer5], a
+ ld [wBargainShopFlags], a
+ ld [wFacingDirection], a
+ ret
+; 15b31
+
+GetMart: ; 15b31
+ ld a, e
+ cp (Marts.End - Marts) / 2
+ jr c, .IsAMart
+ ld b, BANK(DefaultMart)
+ ld de, DefaultMart
+ ret
+
+.IsAMart:
+ ld hl, Marts
+ add hl, de
+ add hl, de
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ld b, BANK(Marts)
+ ret
+; 15b47
+
+StandardMart: ; 15b47
+.loop
+ ld a, [wEngineBuffer5]
+ ld hl, .MartFunctions
+ rst JumpTable
+ ld [wEngineBuffer5], a
+ cp $ff
+ jr nz, .loop
+ ret
+
+.MartFunctions:
+ dw .HowMayIHelpYou
+ dw .TopMenu
+ dw .Buy
+ dw .Sell
+ dw .Quit
+ dw .AnythingElse
+; 15b62
+
+.HowMayIHelpYou: ; 15b62
+ call LoadStandardMenuHeader
+ ld hl, Text_Mart_HowMayIHelpYou
+ call PrintText
+ ld a, $1 ; top menu
+ ret
+; 15b6e
+
+.TopMenu: ; 15b6e
+ ld hl, MenuHeader_BuySell
+ call CopyMenuHeader
+ call VerticalMenu
+ jr c, .quit
+ ld a, [wMenuCursorY]
+ cp $1
+ jr z, .buy
+ cp $2
+ jr z, .sell
+.quit
+ ld a, $4 ; Come again!
+ ret
+.buy
+ ld a, $2 ; buy
+ ret
+.sell
+ ld a, $3 ; sell
+ ret
+; 15b8d
+
+.Buy: ; 15b8d
+ call ExitMenu
+ call FarReadMart
+ call BuyMenu
+ and a
+ ld a, $5 ; Anything else?
+ ret
+; 15b9a
+
+.Sell: ; 15b9a
+ call ExitMenu
+ call SellMenu
+ ld a, $5 ; Anything else?
+ ret
+; 15ba3
+
+.Quit: ; 15ba3
+ call ExitMenu
+ ld hl, Text_Mart_ComeAgain
+ call MartTextBox
+ ld a, $ff ; exit
+ ret
+; 15baf
+
+.AnythingElse: ; 15baf
+ call LoadStandardMenuHeader
+ ld hl, Text_Mart_AnythingElse
+ call PrintText
+ ld a, $1 ; top menu
+ ret
+; 15bbb
+
+FarReadMart: ; 15bbb
+ ld hl, wMartPointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld de, wCurMart
+.CopyMart:
+ ld a, [wMartPointerBank]
+ call GetFarByte
+ ld [de], a
+ inc hl
+ inc de
+ cp -1
+ jr nz, .CopyMart
+ ld hl, wMartItem1BCD
+ ld de, wCurMart + 1
+.ReadMartItem:
+ ld a, [de]
+ inc de
+ cp -1
+ jr z, .done
+ push de
+ call GetMartItemPrice
+ pop de
+ jr .ReadMartItem
+
+.done
+ ret
+; 15be5
+
+GetMartItemPrice: ; 15be5
+; Return the price of item a in BCD at hl and in tiles at wStringBuffer1.
+ push hl
+ ld [wCurItem], a
+ farcall GetItemPrice
+ pop hl
+
+GetMartPrice: ; 15bf0
+; Return price de in BCD at hl and in tiles at wStringBuffer1.
+ push hl
+ ld a, d
+ ld [wStringBuffer2], a
+ ld a, e
+ ld [wStringBuffer2 + 1], a
+ ld hl, wStringBuffer1
+ ld de, wStringBuffer2
+ lb bc, PRINTNUM_LEADINGZEROS | 2, 6 ; 6 digits
+ call PrintNum
+ pop hl
+
+ ld de, wStringBuffer1
+ ld c, 6 / 2 ; 6 digits
+.loop
+ call .CharToNybble
+ swap a
+ ld b, a
+ call .CharToNybble
+ or b
+ ld [hli], a
+ dec c
+ jr nz, .loop
+ ret
+; 15c1a
+
+.CharToNybble: ; 15c1a
+ ld a, [de]
+ inc de
+ cp " "
+ jr nz, .not_space
+ ld a, "0"
+
+.not_space
+ sub "0"
+ ret
+; 15c25
+
+ReadMart: ; 15c25
+; Load the mart pointer. Mart data is local (no need for bank).
+ ld hl, wMartPointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ push hl
+; set hl to the first item
+ inc hl
+ ld bc, wMartItem1BCD
+ ld de, wCurMart + 1
+.loop
+; copy the item to wCurMart + (ItemIndex)
+ ld a, [hli]
+ ld [de], a
+ inc de
+; -1 is the terminator
+ cp -1
+ jr z, .done
+
+ push de
+; copy the price to de
+ ld a, [hli]
+ ld e, a
+ ld a, [hli]
+ ld d, a
+; convert the price to 3-byte BCD at [bc]
+ push hl
+ ld h, b
+ ld l, c
+ call GetMartPrice
+ ld b, h
+ ld c, l
+ pop hl
+
+ pop de
+ jr .loop
+
+.done
+ pop hl
+ ld a, [hl]
+ ld [wCurMart], a
+ ret
+; 15c51
+
+INCLUDE "data/items/bargain_shop.asm"
+
+
+BuyMenu: ; 15c62
+ call FadeToMenu
+ farcall BlankScreen
+ xor a
+ ld [wMenuScrollPositionBackup], a
+ ld a, 1
+ ld [wMenuCursorBufferBackup], a
+.loop
+ call BuyMenuLoop ; menu loop
+ jr nc, .loop
+ call CloseSubmenu
+ ret
+; 15c7d
+
+LoadBuyMenuText: ; 15c7d
+; load text from a nested table
+; which table is in wEngineBuffer1
+; which entry is in register a
+ push af
+ call GetMartDialogGroup ; gets a pointer from GetMartDialogGroup.MartTextFunctionPointers
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ pop af
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ call PrintText
+ ret
+; 15c91
+
+MartAskPurchaseQuantity: ; 15c91
+ call GetMartDialogGroup ; gets a pointer from GetMartDialogGroup.MartTextFunctionPointers
+ inc hl
+ inc hl
+ ld a, [hl]
+ and a
+ jp z, StandardMartAskPurchaseQuantity
+ cp 1
+ jp z, BargainShopAskPurchaseQuantity
+ jp RooftopSaleAskPurchaseQuantity
+; 15ca3
+
+GetMartDialogGroup: ; 15ca3
+ ld a, [wEngineBuffer1]
+ ld e, a
+ ld d, 0
+ ld hl, .MartTextFunctionPointers
+ add hl, de
+ add hl, de
+ add hl, de
+ ret
+; 15cb0
+
+.MartTextFunctionPointers: ; 15cb0
+ dwb .StandardMartPointers, 0
+ dwb .HerbShopPointers, 0
+ dwb .BargainShopPointers, 1
+ dwb .PharmacyPointers, 0
+ dwb .StandardMartPointers, 2
+; 15cbf
+
+.StandardMartPointers: ; 15cbf
+ dw Text_Mart_HowMany
+ dw Text_Mart_CostsThisMuch
+ dw Text_Mart_InsufficientFunds
+ dw Text_Mart_BagFull
+ dw Text_Mart_HereYouGo
+ dw BuyMenuLoop
+
+.HerbShopPointers: ; 15ccb
+ dw Text_HerbShop_HowMany
+ dw Text_HerbShop_CostsThisMuch
+ dw Text_HerbShop_InsufficientFunds
+ dw Text_HerbShop_BagFull
+ dw Text_HerbShop_HereYouGo
+ dw BuyMenuLoop
+
+.BargainShopPointers: ; 15cd7
+ dw BuyMenuLoop
+ dw Text_BargainShop_CostsThisMuch
+ dw Text_BargainShop_InsufficientFunds
+ dw Text_BargainShop_BagFull
+ dw Text_BargainShop_HereYouGo
+ dw Text_BargainShop_SoldOut
+
+.PharmacyPointers: ; 15ce3
+ dw Text_Pharmacy_HowMany
+ dw Text_Pharmacy_CostsThisMuch
+ dw Text_Pharmacy_InsufficientFunds
+ dw Text_Pharmacy_BagFull
+ dw Text_Pharmacy_HereYouGo
+ dw BuyMenuLoop
+; 15cef
+
+
+BuyMenuLoop: ; 15cef
+ farcall PlaceMoneyTopRight
+ call UpdateSprites
+ ld hl, MenuHeader_Buy
+ call CopyMenuHeader
+ ld a, [wMenuCursorBufferBackup]
+ ld [wMenuCursorBuffer], a
+ ld a, [wMenuScrollPositionBackup]
+ ld [wMenuScrollPosition], a
+ call ScrollingMenu
+ ld a, [wMenuScrollPosition]
+ ld [wMenuScrollPositionBackup], a
+ ld a, [wMenuCursorY]
+ ld [wMenuCursorBufferBackup], a
+ call SpeechTextBox
+ ld a, [wMenuJoypad]
+ cp B_BUTTON
+ jr z, .set_carry
+ cp A_BUTTON
+ jr z, .useless_pointer
+
+.useless_pointer
+ call MartAskPurchaseQuantity
+ jr c, .cancel
+ call MartConfirmPurchase
+ jr c, .cancel
+ ld de, wMoney
+ ld bc, hMoneyTemp
+ ld a, $3 ; useless load
+ call CompareMoney
+ jr c, .insufficient_funds
+ ld hl, wNumItems
+ call ReceiveItem
+ jr nc, .insufficient_bag_space
+ ld a, [wMartItemID]
+ ld e, a
+ ld d, $0
+ ld b, SET_FLAG
+ ld hl, wBargainShopFlags
+ call FlagAction
+ call PlayTransactionSound
+ ld de, wMoney
+ ld bc, hMoneyTemp
+ call TakeMoney
+ ld a, MARTTEXT_HERE_YOU_GO
+ call LoadBuyMenuText
+ call JoyWaitAorB
+
+.cancel
+ call SpeechTextBox
+ and a
+ ret
+
+.set_carry
+ scf
+ ret
+
+.insufficient_bag_space
+ ld a, MARTTEXT_BAG_FULL
+ call LoadBuyMenuText
+ call JoyWaitAorB
+ and a
+ ret
+
+.insufficient_funds
+ ld a, MARTTEXT_NOT_ENOUGH_MONEY
+ call LoadBuyMenuText
+ call JoyWaitAorB
+ and a
+ ret
+; 15d83
+
+StandardMartAskPurchaseQuantity:
+ ld a, 99
+ ld [wItemQuantityBuffer], a
+ ld a, MARTTEXT_HOW_MANY
+ call LoadBuyMenuText
+ farcall SelectQuantityToBuy
+ call ExitMenu
+ ret
+; 15d97
+
+MartConfirmPurchase: ; 15d97
+ predef PartyMonItemName
+ ld a, MARTTEXT_COSTS_THIS_MUCH
+ call LoadBuyMenuText
+ call YesNoBox
+ ret
+; 15da5
+
+BargainShopAskPurchaseQuantity:
+ ld a, 1
+ ld [wItemQuantityChangeBuffer], a
+ ld a, [wMartItemID]
+ ld e, a
+ ld d, $0
+ ld b, CHECK_FLAG
+ ld hl, wBargainShopFlags
+ call FlagAction
+ ld a, c
+ and a
+ jr nz, .SoldOut
+ ld a, [wMartItemID]
+ ld e, a
+ ld d, $0
+ ld hl, wMartPointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ inc hl
+ add hl, de
+ add hl, de
+ add hl, de
+ inc hl
+ ld a, [hli]
+ ld [hMoneyTemp + 2], a
+ ld a, [hl]
+ ld [hMoneyTemp + 1], a
+ xor a
+ ld [hMoneyTemp], a
+ and a
+ ret
+
+.SoldOut:
+ ld a, MARTTEXT_SOLD_OUT
+ call LoadBuyMenuText
+ call JoyWaitAorB
+ scf
+ ret
+; 15de2
+
+RooftopSaleAskPurchaseQuantity:
+ ld a, MARTTEXT_HOW_MANY
+ call LoadBuyMenuText
+ call .GetSalePrice
+ ld a, 99
+ ld [wItemQuantityBuffer], a
+ farcall RooftopSale_SelectQuantityToBuy
+ call ExitMenu
+ ret
+; 15df9
+
+.GetSalePrice: ; 15df9
+ ld a, [wMartItemID]
+ ld e, a
+ ld d, 0
+ ld hl, wMartPointer
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ inc hl
+ add hl, de
+ add hl, de
+ add hl, de
+ inc hl
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ ret
+; 15e0e
+
+
+Text_Mart_HowMany: ; 0x15e0e
+ ; How many?
+ text_jump UnknownText_0x1c4bfd
+ db "@"
+; 0x15e13
+
+Text_Mart_CostsThisMuch: ; 0x15e13
+ ; @ (S) will be ¥@ .
+ text_jump UnknownText_0x1c4c08
+ db "@"
+; 0x15e18
+
+MenuHeader_Buy: ; 0x15e18
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 1, 3, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x15e20
+
+.MenuData ; 0x15e20
+ db SCROLLINGMENU_DISPLAY_ARROWS | SCROLLINGMENU_ENABLE_FUNCTION3 ; flags
+ db 4, 8 ; rows, columns
+ db 1 ; horizontal spacing
+ dbw 0, wCurMart
+ dba PlaceMenuItemName
+ dba .PrintBCDPrices
+ dba UpdateItemDescription
+; 15e30
+
+.PrintBCDPrices: ; 15e30
+ ld a, [wScrollingMenuCursorPosition]
+ ld c, a
+ ld b, 0
+ ld hl, wMartItem1BCD
+ add hl, bc
+ add hl, bc
+ add hl, bc
+ push de
+ ld d, h
+ ld e, l
+ pop hl
+ ld bc, SCREEN_WIDTH
+ add hl, bc
+ ld c, PRINTNUM_LEADINGZEROS | PRINTNUM_MONEY | 3
+ call PrintBCDNumber
+ ret
+; 15e4a (5:5e4a)
+
+Text_HerbShop_Intro: ; 0x15e4a
+ ; Hello, dear. I sell inexpensive herbal medicine. They're good, but a trifle bitter. Your #MON may not like them. Hehehehe…
+ text_jump UnknownText_0x1c4c28
+ db "@"
+; 0x15e4f
+
+Text_HerbShop_HowMany: ; 0x15e4f
+ ; How many?
+ text_jump UnknownText_0x1c4ca3
+ db "@"
+; 0x15e54
+
+Text_HerbShop_CostsThisMuch: ; 0x15e54
+ ; @ (S) will be ¥@ .
+ text_jump UnknownText_0x1c4cae
+ db "@"
+; 0x15e59
+
+Text_HerbShop_HereYouGo: ; 0x15e59
+ ; Thank you, dear. Hehehehe…
+ text_jump UnknownText_0x1c4cce
+ db "@"
+; 0x15e5e
+
+Text_HerbShop_BagFull: ; 0x15e5e
+ ; Oh? Your PACK is full, dear.
+ text_jump UnknownText_0x1c4cea
+ db "@"
+; 0x15e63
+
+Text_HerbShop_InsufficientFunds: ; 0x15e63
+ ; Hehehe… You don't have the money.
+ text_jump UnknownText_0x1c4d08
+ db "@"
+; 0x15e68
+
+Text_HerbShop_ComeAgain: ; 0x15e68
+ ; Come again, dear. Hehehehe…
+ text_jump UnknownText_0x1c4d2a
+ db "@"
+; 0x15e6d
+
+Text_BargainShop_Intro: ; 0x15e6d
+ ; Hiya! Care to see some bargains? I sell rare items that nobody else carries--but only one of each item.
+ text_jump UnknownText_0x1c4d47
+ db "@"
+; 0x15e72
+
+Text_BargainShop_CostsThisMuch: ; 0x15e72
+ ; costs ¥@ . Want it?
+ text_jump UnknownText_0x1c4db0
+ db "@"
+; 0x15e77
+
+Text_BargainShop_HereYouGo: ; 0x15e77
+ ; Thanks.
+ text_jump UnknownText_0x1c4dcd
+ db "@"
+; 0x15e7c
+
+Text_BargainShop_BagFull: ; 0x15e7c
+ ; Uh-oh, your PACK is chock-full.
+ text_jump UnknownText_0x1c4dd6
+ db "@"
+; 0x15e81
+
+Text_BargainShop_SoldOut: ; 0x15e81
+ ; You bought that already. I'm all sold out of it.
+ text_jump UnknownText_0x1c4df7
+ db "@"
+; 0x15e86
+
+Text_BargainShop_InsufficientFunds: ; 0x15e86
+ ; Uh-oh, you're short on funds.
+ text_jump UnknownText_0x1c4e28
+ db "@"
+; 0x15e8b
+
+Text_BargainShop_ComeAgain: ; 0x15e8b
+ ; Come by again sometime.
+ text_jump UnknownText_0x1c4e46
+ db "@"
+; 0x15e90
+
+Text_Pharmacist_Intro: ; 0x15e90
+ ; What's up? Need some medicine?
+ text_jump UnknownText_0x1c4e5f
+ db "@"
+; 0x15e95
+
+Text_Pharmacy_HowMany: ; 0x15e95
+ ; How many?
+ text_jump UnknownText_0x1c4e7e
+ db "@"
+; 0x15e9a
+
+Text_Pharmacy_CostsThisMuch: ; 0x15e9a
+ ; @ (S) will cost ¥@ .
+ text_jump UnknownText_0x1c4e89
+ db "@"
+; 0x15e9f
+
+Text_Pharmacy_HereYouGo: ; 0x15e9f
+ ; Thanks much!
+ text_jump UnknownText_0x1c4eab
+ db "@"
+; 0x15ea4
+
+Text_Pharmacy_BagFull: ; 0x15ea4
+ ; You don't have any more space.
+ text_jump UnknownText_0x1c4eb9
+ db "@"
+; 0x15ea9
+
+Text_Pharmacy_InsufficientFunds: ; 0x15ea9
+ ; Huh? That's not enough money.
+ text_jump UnknownText_0x1c4ed8
+ db "@"
+; 0x15eae
+
+Text_Pharmacist_ComeAgain: ; 0x15eae
+ ; All right. See you around.
+ text_jump UnknownText_0x1c4ef6
+ db "@"
+; 0x15eb3
+
+
+SellMenu: ; 15eb3
+ call DisableSpriteUpdates
+ farcall DepositSellInitPackBuffers
+.loop
+ farcall DepositSellPack
+ ld a, [wPackUsedItem]
+ and a
+ jp z, .quit
+ call .TryToSellItem
+ jr .loop
+
+.quit
+ call ReturnToMapWithSpeechTextbox
+ and a
+ ret
+; 15ed3
+
+.Unreferenced_NothingToSell:
+ ld hl, .NothingToSellText
+ call MenuTextBoxBackup
+ and a
+ ret
+; 15edb
+
+.NothingToSellText: ; 0x15edb
+ ; You don't have anything to sell.
+ text_jump UnknownText_0x1c4f12
+ db "@"
+; 0x15ee0
+
+
+.TryToSellItem: ; 15ee0
+ farcall CheckItemMenu
+ ld a, [wItemAttributeParamBuffer]
+ ld hl, .dw
+ rst JumpTable
+ ret
+; 15eee
+
+.dw ; 15eee
+ dw .try_sell
+ dw .cant_buy
+ dw .cant_buy
+ dw .cant_buy
+ dw .try_sell
+ dw .try_sell
+ dw .try_sell
+; 15efc
+
+.cant_buy ; 15efc
+ ret
+; 15efd
+
+
+.try_sell ; 15efd
+ farcall _CheckTossableItem
+ ld a, [wItemAttributeParamBuffer]
+ and a
+ jr z, .okay_to_sell
+ ld hl, TextMart_CantBuyFromYou
+ call PrintText
+ and a
+ ret
+
+.okay_to_sell
+ ld hl, Text_Mart_SellHowMany
+ call PrintText
+ farcall PlaceMoneyAtTopLeftOfTextbox
+ farcall SelectQuantityToSell
+ call ExitMenu
+ jr c, .declined
+ hlcoord 1, 14
+ lb bc, 3, 18
+ call ClearBox
+ ld hl, Text_Mart_ICanPayThisMuch
+ call PrintTextBoxText
+ call YesNoBox
+ jr c, .declined
+ ld de, wMoney
+ ld bc, hMoneyTemp
+ call GiveMoney
+ ld a, [wMartItemID]
+ ld hl, wNumItems
+ call TossItem
+ predef PartyMonItemName
+ hlcoord 1, 14
+ lb bc, 3, 18
+ call ClearBox
+ ld hl, Text_Mart_SoldForAmount
+ call PrintTextBoxText
+ call PlayTransactionSound
+ farcall PlaceMoneyBottomLeft
+ call JoyWaitAorB
+
+.declined
+ call ExitMenu
+ and a
+ ret
+; 15f73
+
+Text_Mart_SellHowMany: ; 0x15f73
+ ; How many?
+ text_jump UnknownText_0x1c4f33
+ db "@"
+; 0x15f78
+
+Text_Mart_ICanPayThisMuch: ; 0x15f78
+ ; I can pay you ¥@ . Is that OK?
+ text_jump UnknownText_0x1c4f3e
+ db "@"
+; 0x15f7d
+
+.UnusedString15f7d: ; 15f7d
+ db "!ダミー!@"
+
+Text_Mart_HowMayIHelpYou: ; 0x15f83
+ ; Welcome! How may I help you?
+ text_jump UnknownText_0x1c4f62
+ db "@"
+; 0x15f88
+
+MenuHeader_BuySell: ; 0x15f88
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 0, 0, 7, 8
+ dw .MenuData
+ db 1 ; default option
+; 0x15f90
+
+.MenuData ; 0x15f90
+ db STATICMENU_CURSOR ; strings
+ db 3 ; items
+ db "BUY@"
+ db "SELL@"
+ db "QUIT@"
+; 0x15f96
+
+Text_Mart_HereYouGo: ; 0x15fa0
+ ; Here you are. Thank you!
+ text_jump UnknownText_0x1c4f80
+ db "@"
+; 0x15fa5
+
+Text_Mart_InsufficientFunds: ; 0x15fa5
+ ; You don't have enough money.
+ text_jump UnknownText_0x1c4f9a
+ db "@"
+; 0x15faa
+
+Text_Mart_BagFull: ; 0x15faa
+ ; You can't carry any more items.
+ text_jump UnknownText_0x1c4fb7
+ db "@"
+; 0x15faf
+
+TextMart_CantBuyFromYou: ; 0x15faf
+ ; Sorry, I can't buy that from you.
+ text_jump UnknownText_0x1c4fd7
+ db "@"
+; 0x15fb4
+
+Text_Mart_ComeAgain: ; 0x15fb4
+ ; Please come again!
+ text_jump UnknownText_0x1c4ff9
+ db "@"
+; 0x15fb9
+
+Text_Mart_AnythingElse: ; 0x15fb9
+ text_jump UnknownText_0x1c500d
+ db "@"
+; 0x15fbe
+
+Text_Mart_SoldForAmount: ; 0x15fbe
+ text_jump UnknownText_0x1c502e
+ db "@"
+; 0x15fc3
+
+PlayTransactionSound: ; 15fc3
+ call WaitSFX
+ ld de, SFX_TRANSACTION
+ call PlaySFX
+ ret
+; 15fcd
+
+MartTextBox: ; 15fcd
+ call MenuTextBox
+ call JoyWaitAorB
+ call ExitMenu
+ ret
+; 15fd7
diff --git a/engine/items/pack.asm b/engine/items/pack.asm
new file mode 100644
index 000000000..ea3a051ac
--- /dev/null
+++ b/engine/items/pack.asm
@@ -0,0 +1,1711 @@
+; Pack.Jumptable and BattlePack.Jumptable indexes
+ const_def
+ const PACKSTATE_INITGFX ; 0
+ const PACKSTATE_INITITEMSPOCKET ; 1
+ const PACKSTATE_ITEMSPOCKETMENU ; 2
+ const PACKSTATE_INITBALLSPOCKET ; 3
+ const PACKSTATE_BALLSPOCKETMENU ; 4
+ const PACKSTATE_INITKEYITEMSPOCKET ; 5
+ const PACKSTATE_KEYITEMSPOCKETMENU ; 6
+ const PACKSTATE_INITTMHMPOCKET ; 7
+ const PACKSTATE_TMHMPOCKETMENU ; 8
+ const PACKSTATE_QUITNOSCRIPT ; 9
+ const PACKSTATE_QUITRUNSCRIPT ; 10
+
+Pack: ; 10000
+ ld hl, wOptions
+ set NO_TEXT_SCROLL, [hl]
+ call InitPackBuffers
+.loop
+ call JoyTextDelay
+ ld a, [wJumptableIndex]
+ bit 7, a
+ jr nz, .done
+ call .RunJumptable
+ call DelayFrame
+ jr .loop
+
+.done
+ ld a, [wCurrPocket]
+ ld [wLastPocket], a
+ ld hl, wOptions
+ res NO_TEXT_SCROLL, [hl]
+ ret
+; 10026
+
+.RunJumptable: ; 10026
+ ld a, [wJumptableIndex]
+ ld hl, .Jumptable
+ call Pack_GetJumptablePointer
+ jp hl
+
+; 10030
+
+.Jumptable: ; 10030 (4:4030)
+; entries correspond to PACKSTATE_* constants
+ dw .InitGFX ; 0
+ dw .InitItemsPocket ; 1
+ dw .ItemsPocketMenu ; 2
+ dw .InitBallsPocket ; 3
+ dw .BallsPocketMenu ; 4
+ dw .InitKeyItemsPocket ; 5
+ dw .KeyItemsPocketMenu ; 6
+ dw .InitTMHMPocket ; 7
+ dw .TMHMPocketMenu ; 8
+ dw Pack_QuitNoScript ; 9
+ dw Pack_QuitRunScript ; 10
+
+.InitGFX: ; 10046 (4:4046)
+ xor a
+ ld [hBGMapMode], a
+ call Pack_InitGFX
+ ld a, [wPackJumptableIndex]
+ ld [wJumptableIndex], a
+ call Pack_InitColors
+ ret
+
+.InitItemsPocket: ; 10056 (4:4056)
+ xor a ; ITEM_POCKET
+ ld [wCurrPocket], a
+ call ClearPocketList
+ call DrawPocketName
+ call WaitBGMap_DrawPackGFX
+ call Pack_JumptableNext
+ ret
+
+.ItemsPocketMenu: ; 10067 (4:4067)
+ ld hl, ItemsPocketMenuHeader
+ call CopyMenuHeader
+ ld a, [wItemsPocketCursor]
+ ld [wMenuCursorBuffer], a
+ ld a, [wItemsPocketScrollPosition]
+ ld [wMenuScrollPosition], a
+ call ScrollingMenu
+ ld a, [wMenuScrollPosition]
+ ld [wItemsPocketScrollPosition], a
+ ld a, [wMenuCursorY]
+ ld [wItemsPocketCursor], a
+ ld b, PACKSTATE_INITTMHMPOCKET ; left
+ ld c, PACKSTATE_INITBALLSPOCKET ; right
+ call Pack_InterpretJoypad
+ ret c
+ call .ItemBallsKey_LoadSubmenu
+ ret
+
+.InitKeyItemsPocket: ; 10094 (4:4094)
+ ld a, KEY_ITEM_POCKET
+ ld [wCurrPocket], a
+ call ClearPocketList
+ call DrawPocketName
+ call WaitBGMap_DrawPackGFX
+ call Pack_JumptableNext
+ ret
+
+.KeyItemsPocketMenu: ; 100a6 (4:40a6)
+ ld hl, KeyItemsPocketMenuHeader
+ call CopyMenuHeader
+ ld a, [wKeyItemsPocketCursor]
+ ld [wMenuCursorBuffer], a
+ ld a, [wKeyItemsPocketScrollPosition]
+ ld [wMenuScrollPosition], a
+ call ScrollingMenu
+ ld a, [wMenuScrollPosition]
+ ld [wKeyItemsPocketScrollPosition], a
+ ld a, [wMenuCursorY]
+ ld [wKeyItemsPocketCursor], a
+ ld b, PACKSTATE_INITBALLSPOCKET ; left
+ ld c, PACKSTATE_INITTMHMPOCKET ; right
+ call Pack_InterpretJoypad
+ ret c
+ call .ItemBallsKey_LoadSubmenu
+ ret
+
+.InitTMHMPocket: ; 100d3 (4:40d3)
+ ld a, TM_HM_POCKET
+ ld [wCurrPocket], a
+ call ClearPocketList
+ call DrawPocketName
+ xor a
+ ld [hBGMapMode], a
+ call WaitBGMap_DrawPackGFX
+ call Pack_JumptableNext
+ ret
+
+.TMHMPocketMenu: ; 100e8 (4:40e8)
+ farcall TMHMPocket
+ ld b, PACKSTATE_INITKEYITEMSPOCKET ; left
+ ld c, PACKSTATE_INITITEMSPOCKET ; right
+ call Pack_InterpretJoypad
+ ret c
+ farcall _CheckTossableItem
+ ld a, [wItemAttributeParamBuffer]
+ and a
+ jr nz, .use_quit
+ ld hl, .MenuHeader2
+ ld de, .Jumptable2
+ jr .load_jump
+
+.use_quit
+ ld hl, .MenuHeader1
+ ld de, .Jumptable1
+.load_jump
+ push de
+ call LoadMenuHeader
+ call VerticalMenu
+ call ExitMenu
+ pop hl
+ ret c
+ ld a, [wMenuCursorY]
+ dec a
+ call Pack_GetJumptablePointer
+ jp hl
+
+; 10124 (4:4124)
+.MenuHeader1: ; 0x10124
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 13, 7, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData_1
+ db 1 ; default option
+; 0x1012c
+
+.MenuData_1: ; 0x1012c
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 2 ; items
+ db "USE@"
+ db "QUIT@"
+; 0x10137
+
+.Jumptable1: ; 10137
+ dw .UseItem
+ dw QuitItemSubmenu
+
+; 1013b
+
+.MenuHeader2: ; 0x1013b
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 13, 5, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData_2
+ db 1 ; default option
+; 0x10143
+
+.MenuData_2: ; 0x10143
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 3 ; items
+ db "USE@"
+ db "GIVE@"
+ db "QUIT@"
+; 0x10153
+
+.Jumptable2: ; 10153
+ dw .UseItem
+ dw GiveItem
+ dw QuitItemSubmenu
+; 10159
+
+.UseItem: ; 10159
+ farcall AskTeachTMHM
+ ret c
+ farcall ChooseMonToLearnTMHM
+ jr c, .declined
+ ld hl, wOptions
+ ld a, [hl]
+ push af
+ res NO_TEXT_SCROLL, [hl]
+ farcall TeachTMHM
+ pop af
+ ld [wOptions], a
+.declined
+ xor a
+ ld [hBGMapMode], a
+ call Pack_InitGFX
+ call WaitBGMap_DrawPackGFX
+ call Pack_InitColors
+ ret
+
+.InitBallsPocket: ; 10186 (4:4186)
+ ld a, BALL_POCKET
+ ld [wCurrPocket], a
+ call ClearPocketList
+ call DrawPocketName
+ call WaitBGMap_DrawPackGFX
+ call Pack_JumptableNext
+ ret
+
+.BallsPocketMenu: ; 10198 (4:4198)
+ ld hl, BallsPocketMenuHeader
+ call CopyMenuHeader
+ ld a, [wBallsPocketCursor]
+ ld [wMenuCursorBuffer], a
+ ld a, [wBallsPocketScrollPosition]
+ ld [wMenuScrollPosition], a
+ call ScrollingMenu
+ ld a, [wMenuScrollPosition]
+ ld [wBallsPocketScrollPosition], a
+ ld a, [wMenuCursorY]
+ ld [wBallsPocketCursor], a
+ ld b, PACKSTATE_INITITEMSPOCKET ; left
+ ld c, PACKSTATE_INITKEYITEMSPOCKET ; right
+ call Pack_InterpretJoypad
+ ret c
+ call .ItemBallsKey_LoadSubmenu
+ ret
+
+.ItemBallsKey_LoadSubmenu: ; 101c5 (4:41c5)
+ farcall _CheckTossableItem
+ ld a, [wItemAttributeParamBuffer]
+ and a
+ jr nz, .tossable
+ farcall CheckSelectableItem
+ ld a, [wItemAttributeParamBuffer]
+ and a
+ jr nz, .selectable
+ farcall CheckItemMenu
+ ld a, [wItemAttributeParamBuffer]
+ and a
+ jr nz, .usable
+ jr .unusable
+
+.selectable
+ farcall CheckItemMenu
+ ld a, [wItemAttributeParamBuffer]
+ and a
+ jr nz, .selectable_usable
+ jr .selectable_unusable
+
+.tossable
+ farcall CheckSelectableItem
+ ld a, [wItemAttributeParamBuffer]
+ and a
+ jr nz, .tossable_selectable
+ jr .tossable_unselectable
+
+.usable
+ ld hl, MenuHeader_UsableKeyItem
+ ld de, Jumptable_UseGiveTossRegisterQuit
+ jr .build_menu
+
+.selectable_usable
+ ld hl, MenuHeader_UsableItem
+ ld de, Jumptable_UseGiveTossQuit
+ jr .build_menu
+
+.tossable_selectable
+ ld hl, MenuHeader_UnusableItem
+ ld de, Jumptable_UseQuit
+ jr .build_menu
+
+.tossable_unselectable
+ ld hl, MenuHeader_UnusableKeyItem
+ ld de, Jumptable_UseRegisterQuit
+ jr .build_menu
+
+.unusable
+ ld hl, MenuHeader_HoldableKeyItem
+ ld de, Jumptable_GiveTossRegisterQuit
+ jr .build_menu
+
+.selectable_unusable
+ ld hl, MenuHeader_HoldableItem
+ ld de, Jumptable_GiveTossQuit
+.build_menu
+ push de
+ call LoadMenuHeader
+ call VerticalMenu
+ call ExitMenu
+ pop hl
+ ret c
+ ld a, [wMenuCursorY]
+ dec a
+ call Pack_GetJumptablePointer
+ jp hl
+
+; 10249 (4:4249)
+MenuHeader_UsableKeyItem: ; 0x10249
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 13, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x10251
+
+.MenuData: ; 0x10251
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 5 ; items
+ db "USE@"
+ db "GIVE@"
+ db "TOSS@"
+ db "SEL@"
+ db "QUIT@"
+; 0x1026a
+
+Jumptable_UseGiveTossRegisterQuit: ; 1026a
+ dw UseItem
+ dw GiveItem
+ dw TossMenu
+ dw RegisterItem
+ dw QuitItemSubmenu
+; 10274
+
+MenuHeader_UsableItem: ; 0x10274
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 13, 3, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x1027c
+
+.MenuData: ; 0x1027c
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 4 ; items
+ db "USE@"
+ db "GIVE@"
+ db "TOSS@"
+ db "QUIT@"
+; 0x10291
+
+Jumptable_UseGiveTossQuit: ; 10291
+ dw UseItem
+ dw GiveItem
+ dw TossMenu
+ dw QuitItemSubmenu
+; 10299
+
+MenuHeader_UnusableItem: ; 0x10299
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 13, 7, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x102a1
+
+.MenuData: ; 0x102a1
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 2 ; items
+ db "USE@"
+ db "QUIT@"
+; 0x102ac
+
+Jumptable_UseQuit: ; 102ac
+ dw UseItem
+ dw QuitItemSubmenu
+; 102b0
+
+MenuHeader_UnusableKeyItem: ; 0x102b0
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 13, 5, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x102b8
+
+.MenuData: ; 0x102b8
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 3 ; items
+ db "USE@"
+ db "SEL@"
+ db "QUIT@"
+; 0x102c7
+
+Jumptable_UseRegisterQuit: ; 102c7
+ dw UseItem
+ dw RegisterItem
+ dw QuitItemSubmenu
+; 102cd
+
+MenuHeader_HoldableKeyItem: ; 0x102cd
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 13, 3, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x102d5
+
+.MenuData: ; 0x102d5
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 4 ; items
+ db "GIVE@"
+ db "TOSS@"
+ db "SEL@"
+ db "QUIT@"
+; 0x102ea
+
+Jumptable_GiveTossRegisterQuit: ; 102ea
+ dw GiveItem
+ dw TossMenu
+ dw RegisterItem
+ dw QuitItemSubmenu
+; 102f2
+
+MenuHeader_HoldableItem: ; 0x102f2
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 13, 5, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x102fa
+
+.MenuData: ; 0x102fa
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 3 ; items
+ db "GIVE@"
+ db "TOSS@"
+ db "QUIT@"
+; 0x1030b
+
+Jumptable_GiveTossQuit: ; 1030b
+ dw GiveItem
+ dw TossMenu
+ dw QuitItemSubmenu
+
+; 10311
+
+UseItem: ; 10311
+ farcall CheckItemMenu
+ ld a, [wItemAttributeParamBuffer]
+ ld hl, .dw
+ rst JumpTable
+ ret
+; 1031f
+
+.dw ; 1031f (4:431f)
+; entries correspond to ITEMMENU_* constants
+ dw .Oak ; ITEMMENU_NOUSE
+ dw .Oak
+ dw .Oak
+ dw .Oak
+ dw .Current ; ITEMMENU_CURRENT
+ dw .Party ; ITEMMENU_PARTY
+ dw .Field ; ITEMMENU_CLOSE
+; 1035c
+
+.Oak: ; 1032d (4:432d)
+ ld hl, Text_ThisIsntTheTime
+ call Pack_PrintTextNoScroll
+ ret
+
+.Current: ; 10334 (4:4334)
+ call DoItemEffect
+ ret
+
+.Party: ; 10338 (4:4338)
+ ld a, [wPartyCount]
+ and a
+ jr z, .NoPokemon
+ call DoItemEffect
+ xor a
+ ld [hBGMapMode], a
+ call Pack_InitGFX
+ call WaitBGMap_DrawPackGFX
+ call Pack_InitColors
+ ret
+
+.NoPokemon:
+ ld hl, TextJump_YouDontHaveAMon
+ call Pack_PrintTextNoScroll
+ ret
+
+.Field: ; 10355 (4:4355)
+ call DoItemEffect
+ ld a, [wItemEffectSucceeded]
+ and a
+ jr z, .Oak
+ ld a, PACKSTATE_QUITRUNSCRIPT
+ ld [wJumptableIndex], a
+ ret
+; 10364 (4:4364)
+
+TossMenu: ; 10364
+ ld hl, Text_ThrowAwayHowMany
+ call Pack_PrintTextNoScroll
+ farcall SelectQuantityToToss
+ push af
+ call ExitMenu
+ pop af
+ jr c, .finish
+ call Pack_GetItemName
+ ld hl, Text_ConfirmThrowAway
+ call MenuTextBox
+ call YesNoBox
+ push af
+ call ExitMenu
+ pop af
+ jr c, .finish
+ ld hl, wNumItems
+ ld a, [wCurItemQuantity]
+ call TossItem
+ call Pack_GetItemName
+ ld hl, Text_ThrewAway
+ call Pack_PrintTextNoScroll
+.finish
+ ret
+; 1039d
+
+Unreferenced_ResetPocketCursorPositions: ; 1039d
+ ld a, [wCurrPocket]
+ and a ; ITEM_POCKET
+ jr z, .items
+ dec a ; BALL_POCKET
+ jr z, .balls
+ dec a ; KEY_ITEM_POCKET
+ jr z, .key
+ ret
+
+.balls
+ xor a
+ ld [wBallsPocketCursor], a
+ ld [wBallsPocketScrollPosition], a
+ ret
+
+.items
+ xor a
+ ld [wItemsPocketCursor], a
+ ld [wItemsPocketScrollPosition], a
+ ret
+
+.key
+ xor a
+ ld [wKeyItemsPocketCursor], a
+ ld [wKeyItemsPocketScrollPosition], a
+ ret
+; 103c2
+
+RegisterItem: ; 103c2
+ farcall CheckSelectableItem
+ ld a, [wItemAttributeParamBuffer]
+ and a
+ jr nz, .cant_register
+ ld a, [wCurrPocket]
+ rrca
+ rrca
+ and $c0
+ ld b, a
+ ld a, [wCurItemQuantity]
+ inc a
+ and $3f
+ or b
+ ld [wWhichRegisteredItem], a
+ ld a, [wCurItem]
+ ld [wRegisteredItem], a
+ call Pack_GetItemName
+ ld de, SFX_FULL_HEAL
+ call WaitPlaySFX
+ ld hl, Text_RegisteredItem
+ call Pack_PrintTextNoScroll
+ ret
+
+.cant_register
+ ld hl, Text_CantRegister
+ call Pack_PrintTextNoScroll
+ ret
+; 103fd
+
+GiveItem: ; 103fd
+ ld a, [wPartyCount]
+ and a
+ jp z, .NoPokemon
+ ld a, [wOptions]
+ push af
+ res NO_TEXT_SCROLL, a
+ ld [wOptions], a
+ ld a, PARTYMENUACTION_GIVE_ITEM
+ ld [wPartyMenuActionText], a
+ call ClearBGPalettes
+ farcall LoadPartyMenuGFX
+ farcall InitPartyMenuWithCancel
+ farcall InitPartyMenuGFX
+.loop
+ farcall WritePartyMenuTilemap
+ farcall PrintPartyMenuText
+ call WaitBGMap
+ call SetPalettes
+ call DelayFrame
+ farcall PartyMenuSelect
+ jr c, .finish
+ ld a, [wCurPartySpecies]
+ cp EGG
+ jr nz, .give
+ ld hl, .Egg
+ call PrintText
+ jr .loop
+
+.give
+ ld a, [wJumptableIndex]
+ push af
+ ld a, [wPackJumptableIndex]
+ push af
+ call GetCurNick
+ ld hl, wStringBuffer1
+ ld de, wMonOrItemNameBuffer
+ ld bc, MON_NAME_LENGTH
+ call CopyBytes
+ call TryGiveItemToPartymon
+ pop af
+ ld [wPackJumptableIndex], a
+ pop af
+ ld [wJumptableIndex], a
+.finish
+ pop af
+ ld [wOptions], a
+ xor a
+ ld [hBGMapMode], a
+ call Pack_InitGFX
+ call WaitBGMap_DrawPackGFX
+ call Pack_InitColors
+ ret
+
+.NoPokemon: ; 10486 (4:4486)
+ ld hl, TextJump_YouDontHaveAMon
+ call Pack_PrintTextNoScroll
+ ret
+; 1048d (4:448d)
+.Egg: ; 0x1048d
+ ; An EGG can't hold an item.
+ text_jump Text_AnEGGCantHoldAnItem
+ db "@"
+; 0x10492
+
+QuitItemSubmenu: ; 10492
+ ret
+; 10493
+
+BattlePack: ; 10493
+ ld hl, wOptions
+ set NO_TEXT_SCROLL, [hl]
+ call InitPackBuffers
+.loop
+ call JoyTextDelay
+ ld a, [wJumptableIndex]
+ bit 7, a
+ jr nz, .end
+ call .RunJumptable
+ call DelayFrame
+ jr .loop
+
+.end
+ ld a, [wCurrPocket]
+ ld [wLastPocket], a
+ ld hl, wOptions
+ res NO_TEXT_SCROLL, [hl]
+ ret
+; 104b9
+
+.RunJumptable: ; 104b9
+ ld a, [wJumptableIndex]
+ ld hl, .Jumptable
+ call Pack_GetJumptablePointer
+ jp hl
+
+; 104c3
+
+.Jumptable: ; 104c3 (4:44c3)
+; entries correspond to PACKSTATE_* constants
+ dw .InitGFX ; 0
+ dw .InitItemsPocket ; 1
+ dw .ItemsPocketMenu ; 2
+ dw .InitBallsPocket ; 3
+ dw .BallsPocketMenu ; 4
+ dw .InitKeyItemsPocket ; 5
+ dw .KeyItemsPocketMenu ; 6
+ dw .InitTMHMPocket ; 7
+ dw .TMHMPocketMenu ; 8
+ dw Pack_QuitNoScript ; 9
+ dw Pack_QuitRunScript ; 10
+
+.InitGFX: ; 104d9 (4:44d9)
+ xor a
+ ld [hBGMapMode], a
+ call Pack_InitGFX
+ ld a, [wPackJumptableIndex]
+ ld [wJumptableIndex], a
+ call Pack_InitColors
+ ret
+
+.InitItemsPocket: ; 104e9 (4:44e9)
+ xor a ; ITEM_POCKET
+ ld [wCurrPocket], a
+ call ClearPocketList
+ call DrawPocketName
+ call WaitBGMap_DrawPackGFX
+ call Pack_JumptableNext
+ ret
+
+.ItemsPocketMenu: ; 104fa (4:44fa)
+ ld hl, ItemsPocketMenuHeader
+ call CopyMenuHeader
+ ld a, [wItemsPocketCursor]
+ ld [wMenuCursorBuffer], a
+ ld a, [wItemsPocketScrollPosition]
+ ld [wMenuScrollPosition], a
+ call ScrollingMenu
+ ld a, [wMenuScrollPosition]
+ ld [wItemsPocketScrollPosition], a
+ ld a, [wMenuCursorY]
+ ld [wItemsPocketCursor], a
+ ld b, PACKSTATE_INITTMHMPOCKET ; left
+ ld c, PACKSTATE_INITBALLSPOCKET ; right
+ call Pack_InterpretJoypad
+ ret c
+ call ItemSubmenu
+ ret
+
+.InitKeyItemsPocket: ; 10527 (4:4527)
+ ld a, KEY_ITEM_POCKET
+ ld [wCurrPocket], a
+ call ClearPocketList
+ call DrawPocketName
+ call WaitBGMap_DrawPackGFX
+ call Pack_JumptableNext
+ ret
+
+.KeyItemsPocketMenu: ; 10539 (4:4539)
+ ld hl, KeyItemsPocketMenuHeader
+ call CopyMenuHeader
+ ld a, [wKeyItemsPocketCursor]
+ ld [wMenuCursorBuffer], a
+ ld a, [wKeyItemsPocketScrollPosition]
+ ld [wMenuScrollPosition], a
+ call ScrollingMenu
+ ld a, [wMenuScrollPosition]
+ ld [wKeyItemsPocketScrollPosition], a
+ ld a, [wMenuCursorY]
+ ld [wKeyItemsPocketCursor], a
+ ld b, PACKSTATE_INITBALLSPOCKET ; left
+ ld c, PACKSTATE_INITTMHMPOCKET ; right
+ call Pack_InterpretJoypad
+ ret c
+ call ItemSubmenu
+ ret
+
+.InitTMHMPocket: ; 10566 (4:4566)
+ ld a, TM_HM_POCKET
+ ld [wCurrPocket], a
+ call ClearPocketList
+ call DrawPocketName
+ xor a
+ ld [hBGMapMode], a
+ call WaitBGMap_DrawPackGFX
+ ld hl, Text_PackEmptyString
+ call Pack_PrintTextNoScroll
+ call Pack_JumptableNext
+ ret
+
+.TMHMPocketMenu: ; 10581 (4:4581)
+ farcall TMHMPocket
+ ld b, PACKSTATE_INITKEYITEMSPOCKET ; left
+ ld c, PACKSTATE_INITITEMSPOCKET ; right
+ call Pack_InterpretJoypad
+ ret c
+ xor a
+ call TMHMSubmenu
+ ret
+
+.InitBallsPocket: ; 10594 (4:4594)
+ ld a, BALL_POCKET
+ ld [wCurrPocket], a
+ call ClearPocketList
+ call DrawPocketName
+ call WaitBGMap_DrawPackGFX
+ call Pack_JumptableNext
+ ret
+
+.BallsPocketMenu: ; 105a6 (4:45a6)
+ ld hl, BallsPocketMenuHeader
+ call CopyMenuHeader
+ ld a, [wBallsPocketCursor]
+ ld [wMenuCursorBuffer], a
+ ld a, [wBallsPocketScrollPosition]
+ ld [wMenuScrollPosition], a
+ call ScrollingMenu
+ ld a, [wMenuScrollPosition]
+ ld [wBallsPocketScrollPosition], a
+ ld a, [wMenuCursorY]
+ ld [wBallsPocketCursor], a
+ ld b, PACKSTATE_INITITEMSPOCKET ; left
+ ld c, PACKSTATE_INITKEYITEMSPOCKET ; right
+ call Pack_InterpretJoypad
+ ret c
+ call ItemSubmenu
+ ret
+
+ItemSubmenu: ; 105d3 (4:45d3)
+ farcall CheckItemContext
+ ld a, [wItemAttributeParamBuffer]
+TMHMSubmenu: ; 105dc (4:45dc)
+ and a
+ jr z, .NoUse
+ ld hl, .UsableMenuHeader
+ ld de, .UsableJumptable
+ jr .proceed
+
+.NoUse:
+ ld hl, .UnusableMenuHeader
+ ld de, .UnusableJumptable
+.proceed
+ push de
+ call LoadMenuHeader
+ call VerticalMenu
+ call ExitMenu
+ pop hl
+ ret c
+ ld a, [wMenuCursorY]
+ dec a
+ call Pack_GetJumptablePointer
+ jp hl
+
+; 10601 (4:4601)
+.UsableMenuHeader: ; 0x10601
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 13, 7, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .UsableMenuData
+ db 1 ; default option
+; 0x10609
+
+.UsableMenuData: ; 0x10609
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 2 ; items
+ db "USE@"
+ db "QUIT@"
+; 0x10614
+
+.UsableJumptable: ; 10614
+ dw .Use
+ dw .Quit
+; 10618
+
+.UnusableMenuHeader: ; 0x10618
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 13, 9, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .UnusableMenuData
+ db 1 ; default option
+; 0x10620
+
+.UnusableMenuData: ; 0x10620
+ db STATICMENU_CURSOR | STATICMENU_NO_TOP_SPACING ; flags
+ db 1 ; items
+ db "QUIT@"
+; 0x10627
+
+.UnusableJumptable: ; 10627
+ dw .Quit
+; 10629
+
+.Use: ; 10629
+ farcall CheckItemContext
+ ld a, [wItemAttributeParamBuffer]
+ ld hl, .ItemFunctionJumptable
+ rst JumpTable
+ ret
+
+.ItemFunctionJumptable: ; 10637 (4:4637)
+; entries correspond to ITEMMENU_* constants
+ dw .Oak ; ITEMMENU_NOUSE
+ dw .Oak
+ dw .Oak
+ dw .Oak
+ dw .Unused ; ITEMMENU_CURRENT
+ dw .BattleField ; ITEMMENU_PARTY
+ dw .BattleOnly ; ITEMMENU_CLOSE
+
+.Oak: ; 10645 (4:4645)
+ ld hl, Text_ThisIsntTheTime
+ call Pack_PrintTextNoScroll
+ ret
+
+.Unused: ; 1064c (4:464c)
+ call DoItemEffect
+ ld a, [wItemEffectSucceeded]
+ and a
+ jr nz, .ReturnToBattle
+ ret
+
+.BattleField: ; 10656 (4:4656)
+ call DoItemEffect
+ ld a, [wItemEffectSucceeded]
+ and a
+ jr nz, .quit_run_script
+ xor a
+ ld [hBGMapMode], a
+ call Pack_InitGFX
+ call WaitBGMap_DrawPackGFX
+ call Pack_InitColors
+ ret
+
+.ReturnToBattle: ; 1066c (4:466c)
+ call ClearBGPalettes
+ jr .quit_run_script
+
+.BattleOnly: ; 10671 (4:4671)
+ call DoItemEffect
+ ld a, [wItemEffectSucceeded]
+ and a
+ jr z, .Oak
+ cp $2
+ jr z, .didnt_use_item
+.quit_run_script ; 1067e (4:467e)
+ ld a, PACKSTATE_QUITRUNSCRIPT
+ ld [wJumptableIndex], a
+ ret
+
+.didnt_use_item ; 10684 (4:4684)
+ xor a
+ ld [wItemEffectSucceeded], a
+ ret
+; 10689 (4:4689)
+.Quit: ; 10689
+ ret
+; 1068a
+
+InitPackBuffers: ; 1068a
+ xor a
+ ld [wJumptableIndex], a
+ ; pocket id -> jumptable index
+ ld a, [wLastPocket]
+ maskbits NUM_POCKETS
+ ld [wCurrPocket], a
+ inc a
+ add a
+ dec a
+ ld [wPackJumptableIndex], a
+ xor a ; FALSE
+ ld [wPackUsedItem], a
+ xor a
+ ld [wSwitchItem], a
+ ret
+; 106a5
+
+DepositSellInitPackBuffers: ; 106a5
+ xor a
+ ld [hBGMapMode], a
+ ld [wJumptableIndex], a ; PACKSTATE_INITGFX
+ ld [wPackJumptableIndex], a ; PACKSTATE_INITGFX
+ ld [wCurrPocket], a ; ITEM_POCKET
+ ld [wPackUsedItem], a
+ ld [wSwitchItem], a
+ call Pack_InitGFX
+ call Pack_InitColors
+ ret
+; 106be
+
+DepositSellPack: ; 106be
+.loop
+ call .RunJumptable
+ call DepositSellTutorial_InterpretJoypad
+ jr c, .loop
+ ret
+; 106c7
+
+.RunJumptable: ; 106c7
+ ld a, [wJumptableIndex]
+ ld hl, .Jumptable
+ call Pack_GetJumptablePointer
+ jp hl
+
+; 106d1
+
+.Jumptable: ; 106d1 (4:46d1)
+; entries correspond to *_POCKET constants
+ dw .ItemsPocket
+ dw .BallsPocket
+ dw .KeyItemsPocket
+ dw .TMHMPocket
+
+.ItemsPocket: ; 106d9 (4:46d9)
+ xor a ; ITEM_POCKET
+ call InitPocket
+ ld hl, PC_Mart_ItemsPocketMenuHeader
+ call CopyMenuHeader
+ ld a, [wItemsPocketCursor]
+ ld [wMenuCursorBuffer], a
+ ld a, [wItemsPocketScrollPosition]
+ ld [wMenuScrollPosition], a
+ call ScrollingMenu
+ ld a, [wMenuScrollPosition]
+ ld [wItemsPocketScrollPosition], a
+ ld a, [wMenuCursorY]
+ ld [wItemsPocketCursor], a
+ ret
+
+.KeyItemsPocket: ; 106ff (4:46ff)
+ ld a, KEY_ITEM_POCKET
+ call InitPocket
+ ld hl, PC_Mart_KeyItemsPocketMenuHeader
+ call CopyMenuHeader
+ ld a, [wKeyItemsPocketCursor]
+ ld [wMenuCursorBuffer], a
+ ld a, [wKeyItemsPocketScrollPosition]
+ ld [wMenuScrollPosition], a
+ call ScrollingMenu
+ ld a, [wMenuScrollPosition]
+ ld [wKeyItemsPocketScrollPosition], a
+ ld a, [wMenuCursorY]
+ ld [wKeyItemsPocketCursor], a
+ ret
+
+.TMHMPocket: ; 10726 (4:4726)
+ ld a, TM_HM_POCKET
+ call InitPocket
+ call WaitBGMap_DrawPackGFX
+ farcall TMHMPocket
+ ld a, [wCurItem]
+ ld [wCurItem], a
+ ret
+
+.BallsPocket: ; 1073b (4:473b)
+ ld a, BALL_POCKET
+ call InitPocket
+ ld hl, PC_Mart_BallsPocketMenuHeader
+ call CopyMenuHeader
+ ld a, [wBallsPocketCursor]
+ ld [wMenuCursorBuffer], a
+ ld a, [wBallsPocketScrollPosition]
+ ld [wMenuScrollPosition], a
+ call ScrollingMenu
+ ld a, [wMenuScrollPosition]
+ ld [wBallsPocketScrollPosition], a
+ ld a, [wMenuCursorY]
+ ld [wBallsPocketCursor], a
+ ret
+
+InitPocket: ; 10762 (4:4762)
+ ld [wCurrPocket], a
+ call ClearPocketList
+ call DrawPocketName
+ call WaitBGMap_DrawPackGFX
+ ret
+
+DepositSellTutorial_InterpretJoypad: ; 1076f
+ ld hl, wMenuJoypad
+ ld a, [hl]
+ and A_BUTTON
+ jr nz, .a_button
+ ld a, [hl]
+ and B_BUTTON
+ jr nz, .b_button
+ ld a, [hl]
+ and D_LEFT
+ jr nz, .d_left
+ ld a, [hl]
+ and D_RIGHT
+ jr nz, .d_right
+ scf
+ ret
+
+.a_button
+ ld a, TRUE
+ ld [wPackUsedItem], a
+ and a
+ ret
+
+.b_button
+ xor a ; FALSE
+ ld [wPackUsedItem], a
+ and a
+ ret
+
+.d_left
+ ld a, [wJumptableIndex]
+ dec a
+ maskbits NUM_POCKETS
+ ld [wJumptableIndex], a
+ push de
+ ld de, SFX_SWITCH_POCKETS
+ call PlaySFX
+ pop de
+ scf
+ ret
+
+.d_right
+ ld a, [wJumptableIndex]
+ inc a
+ maskbits NUM_POCKETS
+ ld [wJumptableIndex], a
+ push de
+ ld de, SFX_SWITCH_POCKETS
+ call PlaySFX
+ pop de
+ scf
+ ret
+; 107bb
+
+TutorialPack: ; 107bb
+ call DepositSellInitPackBuffers
+ ld a, [wInputType]
+ or a
+ jr z, .loop
+ farcall _DudeAutoInput_RightA
+.loop
+ call .RunJumptable
+ call DepositSellTutorial_InterpretJoypad
+ jr c, .loop
+ xor a ; FALSE
+ ld [wPackUsedItem], a
+ ret
+; 107d7
+
+.RunJumptable: ; 107d7
+ ld a, [wJumptableIndex]
+ ld hl, .dw
+ call Pack_GetJumptablePointer
+ jp hl
+
+; 107e1
+
+.dw ; 107e1 (4:47e1)
+; entries correspond to *_POCKET constants
+ dw .Items
+ dw .Balls
+ dw .KeyItems
+ dw .TMHM
+
+.Items: ; 107e9 (4:47e9)
+ xor a ; ITEM_POCKET
+ ld hl, .ItemsMenuHeader
+ jr .DisplayPocket
+
+; 107ef (4:47ef)
+.ItemsMenuHeader: ; 0x107ef
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .ItemsMenuData
+ db 1 ; default option
+; 0x107f7
+
+.ItemsMenuData: ; 0x107f7
+ db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags
+ db 5, 8 ; rows, columns
+ db 2 ; horizontal spacing
+ dbw 0, wDudeNumItems
+ dba PlaceMenuItemName
+ dba PlaceMenuItemQuantity
+ dba UpdateItemDescription
+; 10807
+
+.KeyItems: ; 10807 (4:4807)
+ ld a, KEY_ITEM_POCKET
+ ld hl, .KeyItemsMenuHeader
+ jr .DisplayPocket
+
+; 1080e (4:480e)
+.KeyItemsMenuHeader: ; 0x1080e
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .KeyItemsMenuData
+ db 1 ; default option
+; 0x10816
+
+.KeyItemsMenuData: ; 0x10816
+ db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags
+ db 5, 8 ; rows, columns
+ db 1 ; horizontal spacing
+ dbw 0, wDudeNumKeyItems
+ dba PlaceMenuItemName
+ dba PlaceMenuItemQuantity
+ dba UpdateItemDescription
+; 10826
+
+.TMHM: ; 10826 (4:4826)
+ ld a, TM_HM_POCKET
+ call InitPocket
+ call WaitBGMap_DrawPackGFX
+ farcall TMHMPocket
+ ld a, [wCurItem]
+ ld [wCurItem], a
+ ret
+
+.Balls: ; 1083b (4:483b)
+ ld a, BALL_POCKET
+ ld hl, .BallsMenuHeader
+ jr .DisplayPocket
+
+; 10842 (4:4842)
+.BallsMenuHeader: ; 0x10842
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .BallsMenuData
+ db 1 ; default option
+; 0x1084a
+
+.BallsMenuData: ; 0x1084a
+ db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags
+ db 5, 8 ; rows, columns
+ db 2 ; horizontal spacing
+ dbw 0, wDudeNumBalls
+ dba PlaceMenuItemName
+ dba PlaceMenuItemQuantity
+ dba UpdateItemDescription
+; 1085a
+
+.DisplayPocket: ; 1085a (4:485a)
+ push hl
+ call InitPocket
+ pop hl
+ call CopyMenuHeader
+ call ScrollingMenu
+ ret
+
+Pack_JumptableNext: ; 10866 (4:4866)
+ ld hl, wJumptableIndex
+ inc [hl]
+ ret
+
+Pack_GetJumptablePointer: ; 1086b
+ ld e, a
+ ld d, 0
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ret
+; 10874
+
+Pack_QuitNoScript: ; 10874 (4:4874)
+ ld hl, wJumptableIndex
+ set 7, [hl]
+ xor a ; FALSE
+ ld [wPackUsedItem], a
+ ret
+
+Pack_QuitRunScript: ; 1087e (4:487e)
+ ld hl, wJumptableIndex
+ set 7, [hl]
+ ld a, TRUE
+ ld [wPackUsedItem], a
+ ret
+
+Pack_PrintTextNoScroll: ; 10889 (4:4889)
+ ld a, [wOptions]
+ push af
+ set NO_TEXT_SCROLL, a
+ ld [wOptions], a
+ call PrintText
+ pop af
+ ld [wOptions], a
+ ret
+
+WaitBGMap_DrawPackGFX: ; 1089a (4:489a)
+ call WaitBGMap
+DrawPackGFX: ; 1089d
+ ld a, [wCurrPocket]
+ maskbits NUM_POCKETS
+ ld e, a
+ ld d, $0
+ ld a, [wBattleType]
+ cp BATTLETYPE_TUTORIAL
+ jr z, .male_dude
+ ld a, [wPlayerGender]
+ bit PLAYERGENDER_FEMALE_F, a
+ jr nz, .female
+.male_dude
+ ld hl, PackGFXPointers
+ add hl, de
+ add hl, de
+ ld a, [hli]
+ ld e, a
+ ld d, [hl]
+ ld hl, vTiles2 tile $50
+ lb bc, BANK(PackGFX), 15
+ call Request2bpp
+ ret
+
+.female
+ farcall DrawKrisPackGFX
+ ret
+; 108cc
+
+PackGFXPointers: ; 108cc
+ dw PackGFX + (15 tiles) * 1 ; ITEM_POCKET
+ dw PackGFX + (15 tiles) * 3 ; BALL_POCKET
+ dw PackGFX + (15 tiles) * 0 ; KEY_ITEM_POCKET
+ dw PackGFX + (15 tiles) * 2 ; TM_HM_POCKET
+; 108d4
+
+Pack_InterpretJoypad: ; 108d4 (4:48d4)
+ ld hl, wMenuJoypad
+ ld a, [wSwitchItem]
+ and a
+ jr nz, .switching_item
+ ld a, [hl]
+ and A_BUTTON
+ jr nz, .a_button
+ ld a, [hl]
+ and B_BUTTON
+ jr nz, .b_button
+ ld a, [hl]
+ and D_LEFT
+ jr nz, .d_left
+ ld a, [hl]
+ and D_RIGHT
+ jr nz, .d_right
+ ld a, [hl]
+ and SELECT
+ jr nz, .select
+ scf
+ ret
+
+.a_button
+ and a
+ ret
+
+.b_button
+ ld a, PACKSTATE_QUITNOSCRIPT
+ ld [wJumptableIndex], a
+ scf
+ ret
+
+.d_left
+ ld a, b
+ ld [wJumptableIndex], a
+ ld [wPackJumptableIndex], a
+ push de
+ ld de, SFX_SWITCH_POCKETS
+ call PlaySFX
+ pop de
+ scf
+ ret
+
+.d_right
+ ld a, c
+ ld [wJumptableIndex], a
+ ld [wPackJumptableIndex], a
+ push de
+ ld de, SFX_SWITCH_POCKETS
+ call PlaySFX
+ pop de
+ scf
+ ret
+
+.select
+ farcall SwitchItemsInBag
+ ld hl, Text_MoveItemWhere
+ call Pack_PrintTextNoScroll
+ scf
+ ret
+
+.switching_item
+ ld a, [hl]
+ and A_BUTTON | SELECT
+ jr nz, .place_insert
+ ld a, [hl]
+ and B_BUTTON
+ jr nz, .end_switch
+ scf
+ ret
+
+.place_insert
+ farcall SwitchItemsInBag
+ ld de, SFX_SWITCH_POKEMON
+ call WaitPlaySFX
+ ld de, SFX_SWITCH_POKEMON
+ call WaitPlaySFX
+.end_switch
+ xor a
+ ld [wSwitchItem], a
+ scf
+ ret
+
+Pack_InitGFX: ; 10955
+ call ClearBGPalettes
+ call ClearTileMap
+ call ClearSprites
+ call DisableLCD
+ ld hl, PackMenuGFX
+ ld de, vTiles2
+ ld bc, $60 tiles
+ ld a, BANK(PackMenuGFX)
+ call FarCopyBytes
+; Background (blue if male, pink if female)
+ hlcoord 0, 1
+ ld bc, 11 * SCREEN_WIDTH
+ ld a, $24
+ call ByteFill
+; This is where the items themselves will be listed.
+ hlcoord 5, 1
+ lb bc, 11, 15
+ call ClearBox
+; ◀▶ POCKET ▼▲ ITEMS
+ hlcoord 0, 0
+ ld a, $28
+ ld c, SCREEN_WIDTH
+.loop
+ ld [hli], a
+ inc a
+ dec c
+ jr nz, .loop
+ call DrawPocketName
+ call PlacePackGFX
+; Place the textbox for displaying the item description
+ hlcoord 0, SCREEN_HEIGHT - 4 - 2
+ lb bc, 4, SCREEN_WIDTH - 2
+ call TextBox
+ call EnableLCD
+ call DrawPackGFX
+ ret
+; 109a5
+
+PlacePackGFX: ; 109a5
+ hlcoord 0, 3
+ ld a, $50
+ ld de, SCREEN_WIDTH - 5
+ ld b, 3
+.row
+ ld c, 5
+.column
+ ld [hli], a
+ inc a
+ dec c
+ jr nz, .column
+ add hl, de
+ dec b
+ jr nz, .row
+ ret
+; 109bb
+
+DrawPocketName: ; 109bb
+ ld a, [wCurrPocket]
+ ; * 15
+ ld d, a
+ swap a
+ sub d
+ ld d, 0
+ ld e, a
+ ld hl, .tilemap
+ add hl, de
+ ld d, h
+ ld e, l
+ hlcoord 0, 7
+ ld c, 3
+.row
+ ld b, 5
+.col
+ ld a, [de]
+ inc de
+ ld [hli], a
+ dec b
+ jr nz, .col
+ ld a, c
+ ld c, SCREEN_WIDTH - 5
+ add hl, bc
+ ld c, a
+ dec c
+ jr nz, .row
+ ret
+; 109e1
+
+.tilemap ; 109e1
+; ITEM_POCKET
+ db $00, $04, $04, $04, $01 ; top border
+ db $06, $07, $08, $09, $0a ; Items
+ db $02, $05, $05, $05, $03 ; bottom border
+; BALL_POCKET
+ db $00, $04, $04, $04, $01 ; top border
+ db $15, $16, $17, $18, $19 ; Balls
+ db $02, $05, $05, $05, $03 ; bottom border
+; KEY_ITEM_POCKET
+ db $00, $04, $04, $04, $01 ; top border
+ db $0b, $0c, $0d, $0e, $0f ; Key Items
+ db $02, $05, $05, $05, $03 ; bottom border
+; TM_HM_POCKET
+ db $00, $04, $04, $04, $01 ; top border
+ db $10, $11, $12, $13, $14 ; TM/HM
+ db $02, $05, $05, $05, $03 ; bottom border
+; 10a1d
+
+Pack_GetItemName: ; 10a1d
+ ld a, [wCurItem]
+ ld [wNamedObjectIndexBuffer], a
+ call GetItemName
+ call CopyName1
+ ret
+; 10a2a
+
+Unreferenced_Pack_ClearTilemap: ; 10a2a
+ hlcoord 0, 0
+ ld bc, SCREEN_WIDTH * SCREEN_HEIGHT
+ ld a, " "
+ call ByteFill
+ ret
+; 10a36
+
+ClearPocketList: ; 10a36 (4:4a36)
+ hlcoord 5, 2
+ lb bc, 10, SCREEN_WIDTH - 5
+ call ClearBox
+ ret
+
+Pack_InitColors: ; 10a40
+ call WaitBGMap
+ ld b, SCGB_PACKPALS
+ call GetSGBLayout
+ call SetPalettes
+ call DelayFrame
+ ret
+; 10a4f
+
+ItemsPocketMenuHeader: ; 0x10a4f
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x10a57
+
+.MenuData: ; 0x10a57
+ db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags
+ db 5, 8 ; rows, columns
+ db 2 ; horizontal spacing
+ dbw 0, wNumItems
+ dba PlaceMenuItemName
+ dba PlaceMenuItemQuantity
+ dba UpdateItemDescription
+; 10a67
+
+PC_Mart_ItemsPocketMenuHeader: ; 0x10a67
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x10a6f
+
+.MenuData: ; 0x10a6f
+ db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP ; flags
+ db 5, 8 ; rows, columns
+ db 2 ; horizontal spacing
+ dbw 0, wNumItems
+ dba PlaceMenuItemName
+ dba PlaceMenuItemQuantity
+ dba UpdateItemDescription
+; 10a7f
+
+KeyItemsPocketMenuHeader: ; 0x10a7f
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x10a87
+
+.MenuData: ; 0x10a87
+ db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags
+ db 5, 8 ; rows, columns
+ db 1 ; horizontal spacing
+ dbw 0, wNumKeyItems
+ dba PlaceMenuItemName
+ dba PlaceMenuItemQuantity
+ dba UpdateItemDescription
+; 10a97
+
+PC_Mart_KeyItemsPocketMenuHeader: ; 0x10a97
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x10a9f
+
+.MenuData: ; 0x10a9f
+ db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP ; flags
+ db 5, 8 ; rows, columns
+ db 1 ; horizontal spacing
+ dbw 0, wNumKeyItems
+ dba PlaceMenuItemName
+ dba PlaceMenuItemQuantity
+ dba UpdateItemDescription
+; 10aaf
+
+BallsPocketMenuHeader: ; 0x10aaf
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x10ab7
+
+.MenuData: ; 0x10ab7
+ db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP | STATICMENU_CURSOR ; flags
+ db 5, 8 ; rows, columns
+ db 2 ; horizontal spacing
+ dbw 0, wNumBalls
+ dba PlaceMenuItemName
+ dba PlaceMenuItemQuantity
+ dba UpdateItemDescription
+; 10ac7
+
+PC_Mart_BallsPocketMenuHeader: ; 0x10ac7
+ db MENU_BACKUP_TILES ; flags
+ menu_coords 7, 1, SCREEN_WIDTH - 1, TEXTBOX_Y - 1
+ dw .MenuData
+ db 1 ; default option
+; 0x10acf
+
+.MenuData: ; 0x10acf
+ db STATICMENU_ENABLE_SELECT | STATICMENU_ENABLE_LEFT_RIGHT | STATICMENU_ENABLE_START | STATICMENU_WRAP ; flags
+ db 5, 8 ; rows, columns
+ db 2 ; horizontal spacing
+ dbw 0, wNumBalls
+ dba PlaceMenuItemName
+ dba PlaceMenuItemQuantity
+ dba UpdateItemDescription
+; 10adf
+
+Text_PackNoItems: ; 0x10adf
+ ; No items.
+ text_jump UnknownText_0x1c0b9a
+ db "@"
+; 0x10ae4
+
+Text_ThrowAwayHowMany: ; 0x10ae4
+ ; Throw away how many?
+ text_jump UnknownText_0x1c0ba5
+ db "@"
+; 0x10ae9
+
+Text_ConfirmThrowAway: ; 0x10ae9
+ ; Throw away @ @ (S)?
+ text_jump UnknownText_0x1c0bbb
+ db "@"
+; 0x10aee
+
+Text_ThrewAway: ; 0x10aee
+ ; Threw away @ (S).
+ text_jump UnknownText_0x1c0bd8
+ db "@"
+; 0x10af3
+
+Text_ThisIsntTheTime: ; 0x10af3
+ ; OAK: ! This isn't the time to use that!
+ text_jump UnknownText_0x1c0bee
+ db "@"
+; 0x10af8
+
+TextJump_YouDontHaveAMon: ; 0x10af8
+ ; You don't have a #MON!
+ text_jump Text_YouDontHaveAMon
+ db "@"
+; 0x10afd
+
+Text_RegisteredItem: ; 0x10afd
+ ; Registered the @ .
+ text_jump UnknownText_0x1c0c2e
+ db "@"
+; 0x10b02
+
+Text_CantRegister: ; 0x10b02
+ ; You can't register that item.
+ text_jump UnknownText_0x1c0c45
+ db "@"
+; 0x10b07
+
+Text_MoveItemWhere: ; 0x10b07
+ ; Where should this be moved to?
+ text_jump UnknownText_0x1c0c63
+ db "@"
+; 0x10b0c
+
+Text_PackEmptyString: ; 0x10b0c
+ ;
+ text_jump UnknownText_0x1c0c83
+ db "@"
+; 0x10b11
+
+TextJump_YouCantUseItInABattle: ; 0x10b11
+ ; Doesn't seem to be used anywhere
+ ; "You can't use it in a battle."
+ text_jump Text_YouCantUseItInABattle
+ db "@"
+; 0x10b16
+
+PackMenuGFX:
+INCBIN "gfx/pack/pack_menu.2bpp"
+PackGFX:
+INCBIN "gfx/pack/pack.2bpp"
diff --git a/engine/items/printitemdescription.asm b/engine/items/printitemdescription.asm
new file mode 100644
index 000000000..2a9007b97
--- /dev/null
+++ b/engine/items/printitemdescription.asm
@@ -0,0 +1,31 @@
+PrintItemDescription: ; 0x1c8955
+; Print the description for item [wCurSpecies] at de.
+
+ ld a, [wCurSpecies]
+ cp TM01
+ jr c, .not_a_tm
+
+ ld [wCurItem], a
+ push de
+ farcall GetTMHMItemMove
+ pop hl
+ ld a, [wd265]
+ ld [wCurSpecies], a
+ predef PrintMoveDesc
+ ret
+
+.not_a_tm
+ push de
+ ld hl, ItemDescriptions
+ ld a, [wCurSpecies]
+ dec a
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ ld e, [hl]
+ inc hl
+ ld d, [hl]
+ pop hl
+ jp PlaceString
+; 0x1c8987
diff --git a/engine/items/switch_items.asm b/engine/items/switch_items.asm
new file mode 100755
index 000000000..77b635246
--- /dev/null
+++ b/engine/items/switch_items.asm
@@ -0,0 +1,274 @@
+SwitchItemsInBag: ; 2490c (9:490c)
+ ld a, [wSwitchItem]
+ and a
+ jr z, .init
+ ld b, a
+ ld a, [wScrollingMenuCursorPosition]
+ inc a
+ cp b
+ jr z, .trivial
+ ld a, [wScrollingMenuCursorPosition]
+ call ItemSwitch_GetNthItem
+ ld a, [hl]
+ cp -1
+ ret z
+ ld a, [wSwitchItem]
+ dec a
+ ld [wSwitchItem], a
+ call Function249a7
+ jp c, Function249d1
+ ld a, [wScrollingMenuCursorPosition]
+ ld c, a
+ ld a, [wSwitchItem]
+ cp c
+ jr c, .asm_2497a
+ jr .asm_2494a
+
+.init
+ ld a, [wScrollingMenuCursorPosition]
+ inc a
+ ld [wSwitchItem], a
+ ret
+
+.trivial
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+.asm_2494a
+ ld a, [wSwitchItem]
+ call Function24a40
+ ld a, [wScrollingMenuCursorPosition]
+ ld d, a
+ ld a, [wSwitchItem]
+ ld e, a
+ call Function24a6c
+ push bc
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ dec hl
+ push hl
+ call ItemSwitch_ConvertSpacingToDW
+ add hl, bc
+ ld d, h
+ ld e, l
+ pop hl
+ pop bc
+ call Function24aab
+ ld a, [wScrollingMenuCursorPosition]
+ call Function24a4d
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+.asm_2497a
+ ld a, [wSwitchItem]
+ call Function24a40
+ ld a, [wScrollingMenuCursorPosition]
+ ld d, a
+ ld a, [wSwitchItem]
+ ld e, a
+ call Function24a6c
+ push bc
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ ld d, h
+ ld e, l
+ call ItemSwitch_ConvertSpacingToDW
+ add hl, bc
+ pop bc
+ call CopyBytes
+ ld a, [wScrollingMenuCursorPosition]
+ call Function24a4d
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+Function249a7: ; 249a7 (9:49a7)
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ ld d, h
+ ld e, l
+ ld a, [wScrollingMenuCursorPosition]
+ call ItemSwitch_GetNthItem
+ ld a, [de]
+ cp [hl]
+ jr nz, .asm_249cd
+ ld a, [wScrollingMenuCursorPosition]
+ call Function24a97
+ cp 99
+ jr z, .asm_249cd
+ ld a, [wSwitchItem]
+ call Function24a97
+ cp 99
+ jr nz, .asm_249cf
+.asm_249cd
+ and a
+ ret
+
+.asm_249cf
+ scf
+ ret
+
+Function249d1: ; 249d1 (9:49d1)
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ inc hl
+ push hl
+ ld a, [wScrollingMenuCursorPosition]
+ call ItemSwitch_GetNthItem
+ inc hl
+ ld a, [hl]
+ pop hl
+ add [hl]
+ cp 100
+ jr c, .asm_24a01
+ sub 99
+ push af
+ ld a, [wScrollingMenuCursorPosition]
+ call ItemSwitch_GetNthItem
+ inc hl
+ ld [hl], 99
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ inc hl
+ pop af
+ ld [hl], a
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+.asm_24a01
+ push af
+ ld a, [wScrollingMenuCursorPosition]
+ call ItemSwitch_GetNthItem
+ inc hl
+ pop af
+ ld [hl], a
+ ld hl, wMenuData_ItemsPointerAddr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ ld a, [wSwitchItem]
+ cp [hl]
+ jr nz, .asm_24a25
+ dec [hl]
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ ld [hl], $ff
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+.asm_24a25
+ dec [hl]
+ call ItemSwitch_ConvertSpacingToDW
+ push bc
+ ld a, [wSwitchItem]
+ call ItemSwitch_GetNthItem
+ pop bc
+ push hl
+ add hl, bc
+ pop de
+.asm_24a34
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp $ff
+ jr nz, .asm_24a34
+ xor a
+ ld [wSwitchItem], a
+ ret
+
+Function24a40: ; 24a40 (9:4a40)
+ call ItemSwitch_GetNthItem
+ ld de, wd002
+ call ItemSwitch_ConvertSpacingToDW
+ call CopyBytes
+ ret
+
+Function24a4d: ; 24a4d (9:4a4d)
+ call ItemSwitch_GetNthItem
+ ld d, h
+ ld e, l
+ ld hl, wd002
+ call ItemSwitch_ConvertSpacingToDW
+ call CopyBytes
+ ret
+
+ItemSwitch_GetNthItem: ; 24a5c (9:4a5c)
+ push af
+ call ItemSwitch_ConvertSpacingToDW
+ ld hl, wMenuData_ItemsPointerAddr
+ ld a, [hli]
+ ld h, [hl]
+ ld l, a
+ inc hl
+ pop af
+ call AddNTimes
+ ret
+
+Function24a6c: ; 24a6c (9:4a6c)
+ push hl
+ call ItemSwitch_ConvertSpacingToDW
+ ld a, d
+ sub e
+ jr nc, .dont_negate
+ dec a
+ cpl
+.dont_negate
+ ld hl, 0
+ call AddNTimes
+ ld b, h
+ ld c, l
+ pop hl
+ ret
+
+ItemSwitch_ConvertSpacingToDW: ; 24a80 (9:4a80)
+; This function is absolutely idiotic.
+ push hl
+ ld a, [wMenuData_ScrollingMenuSpacing]
+ ld c, a
+ ld b, 0
+ ld hl, .spacing_dws
+ add hl, bc
+ add hl, bc
+ ld c, [hl]
+ inc hl
+ ld b, [hl]
+ pop hl
+ ret
+
+; 24a91 (9:4a91)
+
+.spacing_dws ; 24a91
+ dw 0, 1, 2
+; 24a97
+
+Function24a97: ; 24a97 (9:4a97)
+ push af
+ call ItemSwitch_ConvertSpacingToDW
+ ld a, c
+ cp 2
+ jr nz, .not_2
+ pop af
+ call ItemSwitch_GetNthItem
+ inc hl
+ ld a, [hl]
+ ret
+
+.not_2
+ pop af
+ ld a, $1
+ ret
+
+Function24aab: ; 24aab (9:4aab)
+.loop
+ ld a, [hld]
+ ld [de], a
+ dec de
+ dec bc
+ ld a, b
+ or c
+ jr nz, .loop
+ ret
diff --git a/engine/items/tmhm.asm b/engine/items/tmhm.asm
new file mode 100755
index 000000000..9db3dc291
--- /dev/null
+++ b/engine/items/tmhm.asm
@@ -0,0 +1,49 @@
+CanLearnTMHMMove: ; 11639
+ ld a, [wCurPartySpecies]
+ ld [wCurSpecies], a
+ call GetBaseData
+ ld hl, wBaseTMHM
+ push hl
+
+ ld a, [wPutativeTMHMMove]
+ ld b, a
+ ld c, 0
+ ld hl, TMHMMoves
+.loop
+ ld a, [hli]
+ and a
+ jr z, .end
+ cp b
+ jr z, .asm_11659
+ inc c
+ jr .loop
+
+.asm_11659
+ pop hl
+ ld b, CHECK_FLAG
+ push de
+ ld d, 0
+ predef SmallFarFlagAction
+ pop de
+ ret
+
+.end
+ pop hl
+ ld c, 0
+ ret
+; 1166a
+
+GetTMHMMove: ; 1166a
+ ld a, [wd265]
+ dec a
+ ld hl, TMHMMoves
+ ld b, 0
+ ld c, a
+ add hl, bc
+ ld a, [hl]
+ ld [wd265], a
+ ret
+; 1167a
+
+
+INCLUDE "data/moves/tmhm_moves.asm"
diff --git a/engine/items/updateitemdescription.asm b/engine/items/updateitemdescription.asm
new file mode 100644
index 000000000..fdb1e864d
--- /dev/null
+++ b/engine/items/updateitemdescription.asm
@@ -0,0 +1,13 @@
+UpdateItemDescription: ; 0x244c3
+ ld a, [wMenuSelection]
+ ld [wCurSpecies], a
+ hlcoord 0, 12
+ ld b, 4
+ ld c, SCREEN_WIDTH - 2
+ call TextBox
+ ld a, [wMenuSelection]
+ cp -1
+ ret z
+ decoord 1, 14
+ farcall PrintItemDescription
+ ret