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