swap_items.asm 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. HandleItemListSwapping:
  2. ld a, [wListMenuID]
  3. cp ITEMLISTMENU
  4. jp nz, DisplayListMenuIDLoop ; only rearrange item list menus
  5. push hl
  6. ld hl, wListPointer
  7. ld a, [hli]
  8. ld h, [hl]
  9. ld l, a
  10. inc hl ; hl = beginning of list entries
  11. ld a, [wCurrentMenuItem]
  12. ld b, a
  13. ld a, [wListScrollOffset]
  14. add b
  15. add a
  16. ld c, a
  17. ld b, 0
  18. add hl, bc ; hl = address of currently selected item entry
  19. ld a, [hl]
  20. pop hl
  21. inc a
  22. jp z, DisplayListMenuIDLoop ; ignore attempts to swap the Cancel menu item
  23. ld a, [wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
  24. and a ; has the first item to swap already been chosen?
  25. jr nz, .swapItems
  26. ; if not, set the currently selected item as the first item
  27. ld a, [wCurrentMenuItem]
  28. inc a
  29. ld b, a
  30. ld a, [wListScrollOffset] ; index of top (visible) menu item within the list
  31. add b
  32. ld [wMenuItemToSwap], a ; ID of item chosen for swapping (counts from 1)
  33. ld c, 20
  34. call DelayFrames
  35. jp DisplayListMenuIDLoop
  36. .swapItems
  37. ld a, [wCurrentMenuItem]
  38. inc a
  39. ld b, a
  40. ld a, [wListScrollOffset]
  41. add b
  42. ld b, a
  43. ld a, [wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
  44. cp b ; is the currently selected item the same as the first item to swap?
  45. jp z, DisplayListMenuIDLoop ; ignore attempts to swap an item with itself
  46. dec a
  47. ld [wMenuItemToSwap], a ; ID of item chosen for swapping (counts from 1)
  48. ld c, 20
  49. call DelayFrames
  50. push hl
  51. push de
  52. ld hl, wListPointer
  53. ld a, [hli]
  54. ld h, [hl]
  55. ld l, a
  56. inc hl ; hl = beginning of list entries
  57. ld d, h
  58. ld e, l ; de = beginning of list entries
  59. ld a, [wCurrentMenuItem]
  60. ld b, a
  61. ld a, [wListScrollOffset]
  62. add b
  63. add a
  64. ld c, a
  65. ld b, 0
  66. add hl, bc ; hl = address of currently selected item entry
  67. ld a, [wMenuItemToSwap] ; ID of item chosen for swapping (counts from 1)
  68. add a
  69. add e
  70. ld e, a
  71. jr nc, .noCarry
  72. inc d
  73. .noCarry ; de = address of first item to swap
  74. ld a, [de]
  75. ld b, a
  76. ld a, [hli]
  77. cp b
  78. jr z, .swapSameItemType
  79. .swapDifferentItems
  80. ld [$ff95], a ; [$ff95] = second item ID
  81. ld a, [hld]
  82. ld [$ff96], a ; [$ff96] = second item quantity
  83. ld a, [de]
  84. ld [hli], a ; put first item ID in second item slot
  85. inc de
  86. ld a, [de]
  87. ld [hl], a ; put first item quantity in second item slot
  88. ld a, [$ff96]
  89. ld [de], a ; put second item quantity in first item slot
  90. dec de
  91. ld a, [$ff95]
  92. ld [de], a ; put second item ID in first item slot
  93. xor a
  94. ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
  95. pop de
  96. pop hl
  97. jp DisplayListMenuIDLoop
  98. .swapSameItemType
  99. inc de
  100. ld a, [hl]
  101. ld b, a
  102. ld a, [de]
  103. add b ; a = sum of both item quantities
  104. cp 100 ; is the sum too big for one item slot?
  105. jr c, .combineItemSlots
  106. ; swap enough items from the first slot to max out the second slot if they can't be combined
  107. sub 99
  108. ld [de], a
  109. ld a, 99
  110. ld [hl], a
  111. jr .done
  112. .combineItemSlots
  113. ld [hl], a ; put the sum in the second item slot
  114. ld hl, wListPointer
  115. ld a, [hli]
  116. ld h, [hl]
  117. ld l, a
  118. dec [hl] ; decrease the number of items
  119. ld a, [hl]
  120. ld [wListCount], a ; update number of items variable
  121. cp 1
  122. jr nz, .skipSettingMaxMenuItemID
  123. ld [wMaxMenuItem], a ; if the number of items is only one now, update the max menu item ID
  124. .skipSettingMaxMenuItemID
  125. dec de
  126. ld h, d
  127. ld l, e
  128. inc hl
  129. inc hl ; hl = address of item after first item to swap
  130. .moveItemsUpLoop ; erase the first item slot and move up all the following item slots to fill the gap
  131. ld a, [hli]
  132. ld [de], a
  133. inc de
  134. inc a ; reached the $ff terminator?
  135. jr z, .afterMovingItemsUp
  136. ld a, [hli]
  137. ld [de], a
  138. inc de
  139. jr .moveItemsUpLoop
  140. .afterMovingItemsUp
  141. xor a
  142. ld [wListScrollOffset], a
  143. ld [wCurrentMenuItem], a
  144. .done
  145. xor a
  146. ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
  147. pop de
  148. pop hl
  149. jp DisplayListMenuIDLoop