Skip to content

Add Item Sorting In Bag

voloved edited this page Jan 27, 2025 · 9 revisions

By devolov

Goal: Allow sorting items in the bag by pressing Start button.
sorting

------------------------- constants/ram_constants.asm -------------------------
index 756aaa68..aa7d829f 100644
@@ -6,9 +6,9 @@
 ; wMiscFlags
 	const_def
 	const BIT_SEEN_BY_TRAINER      ; 0
 	const BIT_BOULDER_DUST         ; 1
-	const BIT_TURNING              ; 2
+	const BIT_TURNING              ; 2 Also using for if item sorting is allowed
 	const BIT_USING_GENERIC_PC     ; 3
 	const BIT_NO_SPRITE_UPDATES    ; 4
 	const BIT_NO_MENU_BUTTON_SOUND ; 5
 	const BIT_TRIED_PUSH_BOULDER   ; 6
------------------------------ home/list_menu.asm ------------------------------
index 77e75012..db84931d 100644
@@ -49,9 +49,9 @@ DisplayListMenuID::
 	ld a, 4
 	ld [wTopMenuItemY], a
 	ld a, 5
 	ld [wTopMenuItemX], a
+	ld a, [[wMiscFlags]]
+	ld b, a
	ld a, A_BUTTON | B_BUTTON | SELECT
+	bit BIT_TURNING, b
+	jr z, .noSortingOption
+	or a, START
+.noSortingOption
 	ld [wMenuWatchedKeys], a
 	ld c, 10
 	call DelayFrames
 
@@ -171,8 +171,10 @@ DisplayListMenuIDLoop::
 	bit BIT_B_BUTTON, a
 	jp nz, ExitListMenu ; if so, exit the menu
 	bit BIT_SELECT, a
 	jp nz, HandleItemListSwapping ; if so, allow the player to swap menu entries
+	bit BIT_START, a
+	jp nz,.sortItems ; if so, allow the player to swap menu entries
 	ld b, a
 	bit BIT_D_DOWN, b
 	ld hl, wListScrollOffset
 	jr z, .upPressed
@@ -190,8 +192,12 @@ DisplayListMenuIDLoop::
 	and a
 	jp z, DisplayListMenuIDLoop
 	dec [hl]
 	jp DisplayListMenuIDLoop
+.sortItems
+	rra ; Sets the zero flag to 0 so the sorting function will happen
+	rla
+	jp BankswitchBack
 
 DisplayChooseQuantityMenu::
 ; text box dimensions/coordinates for just quantity
 	hlcoord 15, 9
----------------------- engine/menus/start_sub_menus.asm -----------------------
index 7dfb7dc3..1565c9c3 100644
@@ -306,8 +306,10 @@ StartMenu_Item::
 	ld hl, CannotUseItemsHereText
 	call PrintText
 	jr .exitMenu
 .notInCableClubRoom
+	ld hl, wMiscFlags
+	set BIT_TURNING, [hl]
 	ld bc, wNumBagItems
 	ld hl, wListPointer
 	ld a, c
 	ld [hli], a
@@ -318,12 +320,15 @@ StartMenu_Item::
 	ld [wListMenuID], a
 	ld a, [wBagSavedMenuItem]
 	ld [wCurrentMenuItem], a
 	call DisplayListMenuID
+	jp nz, .sortItems
 	ld a, [wCurrentMenuItem]
 	ld [wBagSavedMenuItem], a
 	jr nc, .choseItem
 .exitMenu
+	ld hl, wMiscFlags
+	res BIT_TURNING, [hl]
 	call LoadScreenTilesFromBuffer2 ; restore saved screen
 	call LoadTextBoxTilePatterns
 	call UpdateSprites
 	jp RedisplayStartMenu
@@ -436,8 +438,11 @@ StartMenu_Item::
 	ld hl, wNumBagItems
 	call TossItem
 .tossZeroItems
 	jp ItemMenuLoop
+.sortItems
+	callfar SortItems
+	jp ItemMenuLoop
 
 CannotUseItemsHereText:
 	text_far _CannotUseItemsHereText
 	text_end
------------------------- engine/menus/swap_items.asm -------------------------
index 2d506ce2..64e4acb6 100644
@@ -146,4 +146,254 @@ HandleItemListSwapping::
 	ld [wMenuItemToSwap], a ; 0 means no item is currently being swapped
 	pop de
 	pop hl
 	jp DisplayListMenuIDLoop
+
+SortItems::
+	push hl
+	push bc
+	ld hl, SortItemsText ; Display the text to ask to sort
+	call PrintText
+	call YesNoChoice
+	ld a, [wCurrentMenuItem]
+	and a
+	jp z, .beginSorting ; If yes
+	jr .done
+.finishedSwapping
+	ld a, [hSwapTemp] ; If not 0, then a swap of items did occur
+	cp 0
+	jr z, .nothingSorted
+	ld hl, SortComplete
+	jr .printResultText
+.nothingSorted
+	ld hl, NothingToSort
+.printResultText
+	call PrintText
+.done
+	xor a ; Zeroes a
+	pop bc
+	pop hl
+	ret
+.beginSorting
+	xor a
+	ld [hSwapTemp], a ; 1 if something in the bag got sorted
+	ld de, 0
+	ld hl, ItemSortList
+	ld b, [hl] ; This is the first item to check for
+	ld hl, wListPointer
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	inc hl
+	ld c, 0 ; Relative to wBagItems, this is where we'd like to begin swapping
+.loopCurrItemInBag
+	ld a, [hl] ; Load the value of hl to a (which is an item number) and Increments to the quantity
+	cp -1 ; See if the item number is $ff, which is 'cancel'
+	jr z, .findNextItem ; If it is cancel, then move onto the next item
+	cp b
+	jr z, .hasItem ; If it's not b, then go to the next item in the bag
+	inc hl ; increments past the quantity to the next item to check
+	inc hl
+	jr .loopCurrItemInBag
+.findNextItem
+	ld d, 0
+	inc e
+	ld hl, ItemSortList
+	add hl, de
+	ld b, [hl]
+	ld hl, wListPointer
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	inc hl ; Resets hl to start at the beginning of the bag
+	ld a, b
+	cp -1 ; Check if we got through all of the items, to the last one
+	jr z, .finishedSwapping
+	jr .loopCurrItemInBag
+.hasItem ; c contains where to swap to relative to the start of wBagItems
+		 ; hl contains where the item to swap is absolute.
+		 ; b contains the item ID
+	push de
+	ld d, h
+	ld e, l
+	ld hl, wListPointer
+	ld a, [hli]
+	ld h, [hl]
+	ld l, a
+	inc hl
+	ld a, b
+	ld b, 0
+	add hl, bc ; hl now holds where we'd like to swap to
+	ld b, a
+	ld a, [de]
+	cp [hl]
+	jr z, .cont ; If they're the same item
+	ld a, 1
+	ld [hSwapTemp], a
+	ld a, [hl]
+	ld [hSwapItemID],a ; [hSwapItemID] = second item ID
+	inc hl
+	ld a,[hld]
+	ld [hSwapItemQuantity],a ; [hSwapItemQuantity] = 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,[hSwapItemQuantity]
+	ld [de],a ; put second item quantity in first item slot
+	dec de
+	ld a,[hSwapItemID]
+	ld [de],a ; put second item ID in first item slot
+.cont
+	inc c
+	inc c
+	ld h, d
+	ld l, e
+	pop de
+	jr .findNextItem
+
+SortItemsText::
+	text_far _SortItemsText
+	db "@"
+
+SortComplete::
+	text_far _SortComplete
+	db "@"
+
+NothingToSort::
+	text_far _NothingToSort
+	db "@"
+
+ItemSortList::
+	; Used Key Items
+	db BICYCLE
+	db ITEMFINDER
+	db EXP_ALL
+	db TOWN_MAP
+	; Rods
+	db OLD_ROD
+	db GOOD_ROD
+	db SUPER_ROD
+	; Balls
+	db POKE_BALL
+	db GREAT_BALL
+	db ULTRA_BALL
+	db SAFARI_BALL
+	db MASTER_BALL
+	; Common Items
+	db REPEL
+	db SUPER_REPEL
+	db MAX_REPEL
+	db ESCAPE_ROPE
+	db POKE_DOLL
+	; Health
+	db POTION
+	db SUPER_POTION
+	db HYPER_POTION
+	db MAX_POTION
+	db FULL_RESTORE
+	db FRESH_WATER
+	db SODA_POP
+	db LEMONADE
+	; Revival
+	db REVIVE
+	db MAX_REVIVE
+	; Status
+	db ANTIDOTE
+	db BURN_HEAL
+	db ICE_HEAL
+	db AWAKENING
+	db PARLYZ_HEAL
+	db FULL_HEAL
+	db POKE_FLUTE
+	; PP
+	db ETHER
+	db MAX_ETHER
+	db ELIXER
+	db MAX_ELIXER
+	; Battle Raises
+	db X_ACCURACY
+	db X_ATTACK
+	db X_DEFEND
+	db X_SPEED
+	db X_SPECIAL
+	db GUARD_SPEC
+	db DIRE_HIT	
+	; Permanent Raises
+	db RARE_CANDY
+	db HP_UP
+	db PROTEIN
+	db IRON
+	db CARBOS
+	db CALCIUM
+	db PP_UP
+	; Stones
+	db LEAF_STONE
+	db FIRE_STONE
+	db THUNDER_STONE
+	db WATER_STONE
+	db MOON_STONE
+	; Money
+	db COIN_CASE
+	db COIN
+	db NUGGET
+	; Fossils
+	db DOME_FOSSIL
+	db HELIX_FOSSIL
+	db OLD_AMBER
+	; Maps and Items with No Use
+	db SAFARI_BAIT
+	db SAFARI_ROCK
+	db S_S_TICKET
+	; Key Items With No Use
+	db SECRET_KEY
+	db BIKE_VOUCHER
+	db CARD_KEY
+	db GOLD_TEETH
+	db OAKS_PARCEL
+	db LIFT_KEY
+	db SILPH_SCOPE
+	; TMs
+	db TM01
+	db TM01 + 1
+	db TM01 + 2
+	db TM01 + 3
+	db TM01 + 4
+	db TM01 + 5
+	db TM01 + 6
+	db TM01 + 7
+	db TM01 + 8
+	db TM01 + 9
+	db TM01 + 10
+	db TM01 + 11
+	db TM01 + 12
+	db TM01 + 13
+	db TM01 + 14
+	db TM01 + 15
+	db TM01 + 16
+	db TM01 + 17
+	db TM01 + 18
+	db TM01 + 19
+	db TM01 + 20
+	db TM01 + 21
+	db TM01 + 22
+	db TM01 + 23
+	db TM01 + 24
+	db TM01 + 25
+	db TM01 + 26
+	db TM01 + 27
+	db TM01 + 28
+	db TM01 + 29
+	db TM01 + 30
+	db TM01 + 31
+	db TM01 + 32
+	db TM01 + 33
+	db TM01 + 34
+	db TM01 + 35
+	db TM01 + 36
+	db TM01 + 37
+	db TM01 + 38
+	db TM01 + 39
+	db TM01 + 40
+	db TM01 + 41
+	db TM01 + 42
+	db TM01 + 43
+	db TM01 + 44
+	db TM01 + 45
+	db TM01 + 46
+	db TM01 + 47
+	db TM01 + 48
+	db TM01 + 49
+	; HMs
+	db HM01
+	db HM01 + 1
+	db HM01 + 2
+	db HM01 + 3
+	db HM01 + 4
+	db -1 ; end
----------------------------- data/text/text_4.asm -----------------------------
index 39c7ab91..fc673e4b 100644
@@ -228,4 +228,19 @@ ENDC
 	para "Please contact"
 	line "your friend and"
 	cont "come again!"
 	done
+
+_SortItemsText::
+	text "Would you like to"
+	next "sort items?"
+	done
+
+_SortComplete::
+	text "Sorting is"
+	next "complete!"
+	prompt
+
+_NothingToSort::
+	text "There are no items"
+	next "to sort."
+	prompt
------------------------- engine/menus/players_pc.asm -------------------------
index 402275b5..55610744 100644
@@ -72,8 +72,9 @@ ExitPlayerPC:
 	call WaitForSoundToFinish
 .next
 	ld hl, wMiscFlags
 	res BIT_NO_MENU_BUTTON_SOUND, [hl]
+	res BIT_TURNING, [hl]
 	call LoadScreenTilesFromBuffer2
 	xor a
 	ld [wListScrollOffset], a
 	ld [wBagSavedMenuItem], a
@@ -93,8 +94,10 @@ PlayerPCDeposit:
 	ld hl, NothingToDepositText
 	call PrintText
 	jp PlayerPCMenu
 .loop
+	ld hl, wMiscFlags
+	set BIT_TURNING, [hl]
 	ld hl, WhatToDepositText
 	call PrintText
 	ld hl, wNumBagItems
 	ld a, l
@@ -105,8 +108,9 @@ PlayerPCDeposit:
 	ld [wPrintItemPrices], a
 	ld a, ITEMLISTMENU
 	ld [wListMenuID], a
 	call DisplayListMenuID
+	jr nz, .sortItems
 	jp c, PlayerPCMenu
 	call IsKeyItem
 	ld a, 1
 	ld [wItemQuantity], a
@@ -119,8 +123,10 @@ PlayerPCDeposit:
 	call DisplayChooseQuantityMenu
 	cp $ff
 	jp z, .loop
 .next
+	ld hl, wMiscFlags
+	res BIT_TURNING, [hl]
 	ld hl, wNumBoxItems
 	call AddItemToInventory
 	jr c, .roomAvailable
 	ld hl, NoRoomToStoreText
@@ -135,8 +141,11 @@ PlayerPCDeposit:
 	call WaitForSoundToFinish
 	ld hl, ItemWasStoredText
 	call PrintText
 	jp .loop
+.sortItems
+	callfar SortItems
+	jr .loop
 
 PlayerPCWithdraw:
 	xor a
 	ld [wCurrentMenuItem], a
@@ -147,8 +156,10 @@ PlayerPCWithdraw:
 	ld hl, NothingStoredText
 	call PrintText
 	jp PlayerPCMenu
 .loop
+	ld hl, wMiscFlags
+	set BIT_TURNING, [hl]
 	ld hl, WhatToWithdrawText
 	call PrintText
 	ld hl, wNumBoxItems
 	ld a, l
@@ -159,8 +170,9 @@ PlayerPCWithdraw:
 	ld [wPrintItemPrices], a
 	ld a, ITEMLISTMENU
 	ld [wListMenuID], a
 	call DisplayListMenuID
+	jr nz, .sortItems
 	jp c, PlayerPCMenu
 	call IsKeyItem
 	ld a, 1
 	ld [wItemQuantity], a
@@ -173,8 +185,10 @@ PlayerPCWithdraw:
 	call DisplayChooseQuantityMenu
 	cp $ff
 	jp z, .loop
 .next
+	ld hl, wMiscFlags
+	res BIT_TURNING, [hl]
 	ld hl, wNumBagItems
 	call AddItemToInventory
 	jr c, .roomAvailable
 	ld hl, CantCarryMoreText
@@ -189,8 +203,11 @@ PlayerPCWithdraw:
 	call WaitForSoundToFinish
 	ld hl, WithdrewItemText
 	call PrintText
 	jp .loop
+.sortItems
+	callfar SortItems
+	jr .loop
 
 PlayerPCToss:
 	xor a
 	ld [wCurrentMenuItem], a
@@ -201,8 +218,10 @@ PlayerPCToss:
 	ld hl, NothingStoredText
 	call PrintText
 	jp PlayerPCMenu
 .loop
+	ld hl, wMiscFlags
+	set BIT_TURNING, [hl]
 	ld hl, WhatToTossText
 	call PrintText
 	ld hl, wNumBoxItems
 	ld a, l
@@ -215,8 +234,9 @@ PlayerPCToss:
 	ld [wListMenuID], a
 	push hl
 	call DisplayListMenuID
 	pop hl
+	jr nz, .sortItems
 	jp c, PlayerPCMenu
 	push hl
 	call IsKeyItem
 	pop hl
@@ -236,10 +256,15 @@ PlayerPCToss:
 	pop hl
 	cp $ff
 	jp z, .loop
 .next
+	ld hl, wMiscFlags
+	res BIT_TURNING, [hl]
 	call TossItem ; disallows tossing key items
 	jp .loop
+.sortItems
+	callfar SortItems
+	jr .loop
 
 PlayersPCMenuEntries:
 	db   "WITHDRAW ITEM"
 	next "DEPOSIT ITEM"
Clone this wiki locally