diff options
-rw-r--r-- | constants.asm | 1 | ||||
-rwxr-xr-x | constants/item_data_constants.asm | 45 | ||||
-rw-r--r-- | constants/misc_constants.asm | 8 | ||||
-rwxr-xr-x | engine/items/inventory.asm | 658 | ||||
-rwxr-xr-x | home/items.asm | 8 | ||||
-rwxr-xr-x | home/tables.asm | 27 | ||||
-rw-r--r-- | shim.sym | 2 | ||||
-rw-r--r-- | wram.asm | 28 |
8 files changed, 753 insertions, 24 deletions
diff --git a/constants.asm b/constants.asm index 6a93ce6..9312d05 100644 --- a/constants.asm +++ b/constants.asm @@ -13,6 +13,7 @@ INCLUDE "constants/pokemon_constants.asm" INCLUDE "constants/pokemon_data_constants.asm" INCLUDE "constants/move_constants.asm" INCLUDE "constants/item_constants.asm" +INCLUDE "constants/item_data_constants.asm" INCLUDE "constants/trainer_constants.asm" INCLUDE "constants/trainer_data_constants.asm" INCLUDE "constants/sprite_constants.asm" diff --git a/constants/item_data_constants.asm b/constants/item_data_constants.asm new file mode 100755 index 0000000..297ffc5 --- /dev/null +++ b/constants/item_data_constants.asm @@ -0,0 +1,45 @@ +; item_attributes struct members (see data/items/attributes.asm)
+ const_def
+ const ITEMATTR_PRICE
+ const ITEMATTR_PRICE_HI
+ const ITEMATTR_EFFECT
+ const ITEMATTR_PARAM
+ const ITEMATTR_PERMISSIONS
+ const ITEMATTR_POCKET
+ const ITEMATTR_HELP
+ITEMATTR_STRUCT_LENGTH EQU const_value
+
+; item types
+ const_def 1
+ const ITEM ; 1
+ const KEY_ITEM ; 2
+ const BALL ; 3
+ const TM_HM ; 4
+
+; item menu types
+; UseItem.dw indexes (see engine/items/pack.asm)
+; UseRegisteredItem.SwitchTo indexes (see engine/overworld/select_menu.asm)
+ITEMMENU_NOUSE EQU 0
+ITEMMENU_CURRENT EQU 4
+ITEMMENU_PARTY EQU 5
+ITEMMENU_CLOSE EQU 6
+
+; item actions
+CANT_SELECT_F EQU 6
+CANT_TOSS_F EQU 7
+
+NO_LIMITS EQU 0
+CANT_SELECT EQU 1 << CANT_SELECT_F
+CANT_TOSS EQU 1 << CANT_TOSS_F
+
+; pack pockets
+ const_def
+ const ITEM_POCKET ; 0
+ const BALL_POCKET ; 1
+ const KEY_ITEM_POCKET ; 2
+ const TM_HM_POCKET ; 3
+NUM_POCKETS EQU const_value
+
+MAX_ITEMS EQU 20
+MAX_KEY_ITEMS EQU 20
+MAX_PC_ITEMS EQU 50
\ No newline at end of file diff --git a/constants/misc_constants.asm b/constants/misc_constants.asm index 05508e6..19deb8e 100644 --- a/constants/misc_constants.asm +++ b/constants/misc_constants.asm @@ -21,10 +21,4 @@ D_UP EQU 1 << D_UP_F D_DOWN EQU 1 << D_DOWN_F BUTTONS EQU A_BUTTON | B_BUTTON | SELECT | START -D_PAD EQU D_RIGHT | D_LEFT | D_UP | D_DOWN - -; backpack - - const_def 1 - const REGULAR_ITEM_POCKET - const KEY_ITEM_POCKET
\ No newline at end of file +D_PAD EQU D_RIGHT | D_LEFT | D_UP | D_DOWN
\ No newline at end of file diff --git a/engine/items/inventory.asm b/engine/items/inventory.asm new file mode 100755 index 0000000..4a95bac --- /dev/null +++ b/engine/items/inventory.asm @@ -0,0 +1,658 @@ +INCLUDE "constants.asm"
+
+SECTION "AddItemToInventory_", ROMX[$4AA1], BANK[$03]
+
+_ReceiveItem: ; 03:4AA1
+ call DoesHLEqualwNumBagItems
+ jp nz, PutItemInPocket
+ push hl
+ ld hl, CheckItemPocket
+ ld a, BANK(CheckItemPocket)
+ call FarCall_hl
+ ld a, [wItemAttributeParamBuffer]
+ dec a
+ ld hl, .Pockets
+ jp CallJumptable
+
+.Pockets: ; 03:4ABA
+ dw .Item
+ dw .KeyItem
+ dw .Ball
+ dw .TMHM
+
+.Item: ; 03:4AC2
+ pop hl
+ jp PutItemInPocket
+
+.KeyItem: ; 03:4AC6
+ pop hl
+ jp ReceiveKeyItem
+
+.Ball: ; 03:4ACA
+ pop hl
+ ld a, [wCurItem]
+ ld c, a
+ call GetBallIndex
+ jp ReceiveBall
+
+.TMHM: ; 03:4AD5
+ pop hl
+ ld a, [wCurItem]
+ ld c, a
+ call GetTMHMNumber
+ jp ReceiveTMHM
+
+
+_TossItem: ; 03:4AE0
+ call DoesHLEqualwNumBagItems
+ jr nz, .remove_item
+ push hl
+ ld hl, CheckItemPocket
+ ld a, BANK(CheckItemPocket)
+ call FarCall_hl
+ ld a, [wItemAttributeParamBuffer]
+ dec a
+ ld hl, .Pockets
+ jp CallJumptable
+
+.Pockets ; 03:4AF8
+ dw .Item
+ dw .KeyItem
+ dw .Ball
+ dw .TMHM
+
+.Ball ; 03:4B00
+ pop hl
+ ld a, [wCurItem]
+ ld c, a
+ call GetBallIndex
+ jp TossBall
+
+.TMHM ; 03:4B0B
+ pop hl
+ ld a, [wCurItem]
+ ld c, a
+ call GetTMHMNumber
+ jp TossTMHM
+
+.KeyItem ; 03:4B16
+ pop hl
+ jp TossKeyItem
+
+.Item ; 03:4B1A
+ pop hl
+
+.remove_item ; 03:4B1B
+ jp RemoveItemFromPocket
+
+
+_CheckItem: ; 03:4B1E
+ call DoesHLEqualwNumBagItems
+ jr nz, .not_bag
+ push hl
+ ld hl, CheckItemPocket
+ ld a, BANK(CheckItemPocket)
+ call FarCall_hl
+ ld a, [wItemAttributeParamBuffer]
+ dec a
+ ld hl, .Pockets
+ jp CallJumptable
+
+.Pockets ; 03:4B36
+ dw .Item
+ dw .KeyItem
+ dw .Ball
+ dw .TMHM
+
+.Ball ; 03:4B3E
+ pop hl
+ ld a, [wCurItem]
+ ld c, a
+ call GetBallIndex
+ jp CheckBall
+
+.TMHM ; 03:4B49
+ pop hl
+ ld a, [wCurItem]
+ ld c, a
+ call GetTMHMNumber
+ jp CheckTMHM
+
+.KeyItem ; 03:4B54
+ pop hl
+ jp CheckKeyItems
+
+.Item ; 03:4B58
+ pop hl
+
+.not_bag
+ jp CheckTheItem
+
+
+DoesHLEqualwNumBagItems: ; 03:4B5C
+ ld a, l
+ cp LOW(wNumBagItems)
+ ret nz
+ ld a, h
+ cp HIGH(wNumBagItems)
+ ret
+
+
+PutItemInPocket: ; 03:4B64
+ ld d, h
+ ld e, l
+ inc hl
+ ld a, [wCurItem]
+ ld c, a
+ ld b, 0
+
+; will add the item once the total
+; available space (b) exceeds the
+; amount being added
+.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, [wItemQuantity]
+ cp b
+ jr z, .can_add
+ jr c, .can_add
+
+.next
+ inc hl
+ jr .loop
+
+.terminator
+ call GetPocketCapacity
+ ld a, [de]
+ cp c
+ jr c, .can_add
+
+ and a
+ ret
+
+.can_add
+ ld h, d
+ ld l, e
+ ld a, [wCurItem]
+ ld c, a
+
+.loop2
+ inc hl
+ ld a, [hli]
+ cp a, -1
+ jr z, .terminator2
+ cp c
+ jr nz, .loop2
+
+ ld a, [wItemQuantity]
+ add [hl]
+ cp a, 100
+ jr nc, .set_max
+ ld [hl], a
+ jr .done
+
+; set this slot's quantity to 99,
+; and keep iterating through list
+; to add remaining amount
+.set_max
+ ld [hl], 99
+ sub 99
+ ld [wItemQuantity], a
+ jr .loop2
+
+.terminator2
+ dec hl
+ ld a, [wCurItem]
+ ld [hli], a
+ ld a, [wItemQuantity]
+ ld [hli], a
+ ld [hl], -1
+ ld h, d
+ ld l, e
+ inc [hl]
+
+.done
+ scf
+ ret
+
+
+GetPocketCapacity: ; 03:4BC1
+ ld c, MAX_ITEMS
+ ld a, e
+ cp a, LOW(wNumBagItems)
+ jr nz, .not_bag
+ ld a, d
+ cp HIGH(wNumBagItems)
+ ret z
+
+.not_bag
+ ld c, MAX_PC_ITEMS
+ ret
+
+
+RemoveItemFromPocket: ;03:4BCF
+ ld d, h
+ ld e, l
+ inc hl
+ ld a, [wItemIndex]
+ ld c, a
+ ld b, 0
+ add hl, bc
+ add hl, bc
+ inc hl
+ ld a, [wItemQuantity]
+ ld b, a
+ ld a, [hl]
+ sub b
+ jr c, .underflow
+
+ ld [hl], a
+ ld [wItemQuantityBuffer], a
+ and a
+ jr nz, .done
+
+; if the remaining quantity is zero
+; then erase the slot by shifting
+; the subsequent data upwards
+ dec hl
+ ld b, h
+ ld c, l
+ inc hl
+ inc hl
+
+.loop
+ ld a, [hli]
+ ld [bc], a
+ inc bc
+ cp -1
+ jr nz, .loop
+ ld h, d
+ ld l, e
+ dec [hl]
+
+.done
+ scf
+ ret
+
+.underflow
+ and a
+ ret
+
+
+CheckTheItem: ; 03:4BFD
+ ld a, [wCurItem]
+ ld c, a
+
+.loop
+ inc hl
+ ld a, [hli]
+ cp -1
+ jr z, .fail
+ cp c
+ jr nz, .loop
+
+ scf
+ ret
+
+.fail
+ and a
+ ret
+
+
+ReceiveKeyItem: ; 03:4C0E
+ ld hl, wNumKeyItems
+ ld a, [hli]
+ cp a, MAX_KEY_ITEMS
+ jr nc, .full_pack
+ 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
+
+.full_pack
+ and a
+ ret
+
+
+TossKeyItem: ; 03:4C28
+ ld hl, wNumKeyItems
+ dec [hl]
+ inc hl
+ ld a, [wItemIndex]
+ ld e, a
+ ld d, 0
+ add hl, de
+ ld d, h
+ ld e, l
+ inc hl
+
+; erase this item by shifting
+; all subsequent data upwards
+.loop
+ ld a, [hli]
+ ld [de], a
+ inc de
+ cp -1
+ jr nz, .loop
+ scf
+ ret
+
+
+CheckKeyItems: ; 03:4C40
+ 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
+
+
+; get index of ball item id c from BallItems
+GetBallIndex: ; 03:4C53
+ ld a, c
+ push hl
+ push de
+ push bc
+ ld hl, BallItems
+ ld de, 1
+ call FindItemInTable
+ ld a, b
+ pop bc
+ pop de
+ pop hl
+ ld c, a
+ ret
+
+
+; get ball item id at index c in BallItems
+GetBallByIndex: ; 03:4c66
+ push bc
+ push hl
+ ld b, 0
+ ld hl, BallItems
+ add hl, bc
+ ld a, [hl]
+ pop hl
+ pop bc
+ ld c, a
+ ret
+
+
+BallItems: ; 03:4C73
+ db ITEM_MASTER_BALL
+ db ITEM_ULTRA_BALL
+ db ITEM_GREAT_BALL
+ db ITEM_POKE_BALL
+ db -1
+
+
+; empties the ball pocket by setting the
+; terminator immediately after wNumBallItems
+
+ ; Note, the ball pocket appears to be
+ ; a fixed length, not -1 terminated
+EmptyBallPocket: ; 03:4C78
+ ld hl, wNumBallItems
+ xor a
+ ld [hli], a
+ ld [hl], -1
+ ret
+
+
+ReceiveBall: ; 03:4C80
+ ld hl, wBallQuantities
+ ld b, 0
+ add hl, bc
+ ld a, [wItemQuantity]
+ add [hl]
+ cp 100
+ jr nc, .overflow
+ ld b, a
+ ld a, [hl]
+ and a
+ jr nz, .done
+
+; increase the ball pocket size if
+; this ball's previous quantity was 0
+ ld a, [wNumBallItems]
+ inc a
+ ld [wNumBallItems], a
+
+.done
+ ld [hl], b
+ scf
+ ret
+
+.overflow
+ and a
+ ret
+
+
+TossBall: ; 03:4C9F
+ ld hl, wBallQuantities
+ ld b, 0
+ add hl, bc
+ ld a, [wItemQuantity]
+ ld b, a
+ ld a, [hl]
+ sub b
+ jr c, .underflow
+ jr nz, .done
+
+; increase the ball pocket size if
+; this ball's new quantity is 0
+ ld b, a
+ ld a, [wNumBallItems]
+ dec a
+ ld [wNumBallItems], a
+ ld a, b
+
+.done
+ ld [hl], a
+ ld [wItemQuantityBuffer], a
+ scf
+ ret
+
+.underflow
+ and a
+ ret
+
+
+CheckBall: ; 03:4CC0
+ ld hl, wBallQuantities
+ ld b, 0
+ add hl, bc
+ ld a, [hl]
+ and a
+ ret z
+ scf
+ ret
+
+
+ReceiveTMHM: ; 03:4CCB
+ ld b, 0
+ ld hl, wTMsHMs
+ add hl, bc
+ ld a, [wItemQuantity]
+ add [hl]
+ cp 100
+ jr nc, .overflow
+ ld [hl], a
+ scf
+ ret
+
+.overflow
+ and a
+ ret
+
+
+TossTMHM: ; 03:4CDE
+ ld b, 0
+ ld hl, wTMsHMs
+ add hl, bc
+ ld a, [wItemQuantity]
+ ld b, a
+ ld a, [hl]
+ sub b
+ jr c, .underflow
+
+ ld [hl], a
+ ld [wItemQuantityBuffer], a
+ scf
+ ret
+
+.underflow
+ and a
+ ret
+
+
+CheckTMHM: ; 03:4CF4
+ ld b, 0
+ ld hl, wTMsHMs
+ add hl, bc
+ ld a, [hl]
+ and a
+ ret z
+ scf
+ ret
+
+GetTMHMNumber: ; 03:4CFF
+ ld a, c
+ ld c, 0
+
+ sub ITEM_TM01
+ jr c, .not_machine
+
+ cp ITEM_C8 - ITEM_TM01
+ jr z, .not_machine
+ jr c, .finish
+
+ inc c
+ cp ITEM_E1 - ITEM_TM01
+ jr z, .not_machine
+
+ jr c, .finish
+ inc c
+
+; c represents the amount of non-TMs which
+; appear ahead of this item in the list
+; so subtract that value before exiting
+.finish
+ sub c
+ ld c, a
+ scf
+ ret
+
+.not_machine
+ and a
+ ret
+
+SECTION "_CheckTossableItem", ROMX[$53AD], BANK[$03]
+
+; Return 1 in wItemAttributeParamBuffer and carry if wCurItem can't be removed from the bag.
+_CheckTossableItem: ; 03:53AD
+ ld a, ITEMATTR_PERMISSIONS
+ call GetItemAttr
+ bit CANT_TOSS_F, a
+ jr nz, ItemAttr_ReturnCarry
+ and a
+ ret
+
+; Return 1 in wItemAttributeParamBuffer and carry if wCurItem can't be selected.
+CheckSelectableItem: ; 03:53B8
+ ld a, ITEMATTR_PERMISSIONS
+ call GetItemAttr
+ bit CANT_SELECT_F, a
+ jr nz, ItemAttr_ReturnCarry
+ and a
+ ret
+
+; Return the pocket for wCurItem in wItemAttributeParamBuffer.
+CheckItemPocket: ; 03:53C3
+ ld a, ITEMATTR_POCKET
+ call GetItemAttr
+ and $f
+ ld [wItemAttributeParamBuffer], a
+ ret
+
+; Return the context for wCurItem in wItemAttributeParamBuffer.
+CheckItemContext: ; 03:53CE
+ ld a, ITEMATTR_HELP
+ call GetItemAttr
+ and $f
+ ld [wItemAttributeParamBuffer], a
+ ret
+
+; Return the menu for wCurItem in wItemAttributeParamBuffer.
+CheckItemMenu: ; 03:53D9
+ ld a, ITEMATTR_HELP
+ call GetItemAttr
+ swap a
+ and $f
+ ld [wItemAttributeParamBuffer], a
+ ret
+
+; Get attribute a of wCurItem.
+GetItemAttr: ; 03:53E6
+ 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: ; 03:5405
+ ld a, 1
+ ld [wItemAttributeParamBuffer], a
+ scf
+ ret
+
+; Return the price of wCurItem in de.
+GetItemPrice: ; 03:540C
+ 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/home/items.asm b/home/items.asm index 496b685..0edd72b 100755 --- a/home/items.asm +++ b/home/items.asm @@ -10,17 +10,17 @@ AddItemToInventory:: ; 3259 ; function to add an item (in varying quantities) to the player's bag or PC box
; INPUT:
; HL = address of inventory (either wNumBagItems or wNumBoxItems)
-; [wcd76] = item ID
+; [wCurItem] = item ID
; [wItemQuantity] = item quantity
; sets carry flag if successful, unsets carry flag if unsuccessful
push bc
ldh a, [hROMBank]
push af
- ld a, BANK(AddItemToInventory_)
+ ld a, BANK(_ReceiveItem)
call Bankswitch
push hl
push de
- call AddItemToInventory_
+ call _ReceiveItem
pop de
pop hl
pop bc
@@ -41,7 +41,7 @@ GiveItem:: ; Return carry on success.
ld a, b
ld [wce37], a
- ld [wcd76], a
+ ld [wCurItem], a
ld a, c
ld [wItemQuantity], a
ld hl, wNumBagItems
diff --git a/home/tables.asm b/home/tables.asm new file mode 100755 index 0000000..dc9cebe --- /dev/null +++ b/home/tables.asm @@ -0,0 +1,27 @@ +INCLUDE "constants.asm"
+
+SECTION "FindItemInTable", ROM0[$35F8]
+
+; find value a from table hl with row length de
+; returns carry and row index b if successful
+FindItemInTable: ; 00:35F8
+ ld b, 0
+ ld c, a
+
+.loop
+ ld a, [hl]
+ cp -1
+ jr z, .fail
+ cp c
+ jr z, .success
+ inc b
+ add hl, de
+ jr .loop
+
+.fail
+ and a
+ ret
+
+.success
+ scf
+ ret
@@ -58,6 +58,7 @@ 01:6445 Function_6445 01:66B1 Function_66b1 01:6713 Function_6713 +01:68F3 ItemAttributes 02:4786 Function_8786 02:4098 _InitializeVisibleSprites @@ -71,7 +72,6 @@ 03:4791 DebugWarp 03:479F DebugWarp.Destinations -03:4AA1 AddItemToInventory_ 03:4D33 Function_cd33 03:4D6F Function_cd6f 03:4DE3 Function_cde3 @@ -346,18 +346,18 @@ wFarCallBCBuffer:: ; cd54 SECTION "CD76", WRAM0[$CD76] -wcd76:: ; cd76 - db - -wcd77:: ;cd77 - db - -wMonDexIndex: ds 1 ; cd78 +wCurItem:: db ; cd76 +wItemIndex:: db ;cd77 +wMonDexIndex: db ; cd78 SECTION "CD7D", WRAM0[$CD7D] -wItemQuantity:: ; cd7d - db +wItemQuantity:: db ; cd7d +wItemQuantityBuffer:: db ; cd7e + +SECTION "CDBA", WRAM0[$CDBA] + +wItemAttributeParamBuffer:: db ; cdba SECTION "CDBD", WRAM0[$CDBD] @@ -544,19 +544,23 @@ wTimeOfDayPalset:: db ; d158 wCurTimeOfDay:: db ; d159 +SECTION "D165", WRAM0[$D165] + +wTMsHMs:: db ; d165 + SECTION "D19E", WRAM0[$D19E] -wNumBagItems:: ; d19e - db +wNumBagItems:: db ; d19e SECTION "D1C8", WRAM0[$D1C8] wNumKeyItems:: db ; d1c8 +wKeyItems:: db ; d1c9 SECTION "D1DE", WRAM0[$D1DE] wNumBallItems:: db ; d1de - +wBallQuantities:: db ; d1df SECTION "D4AB", WRAM0[$D4AB] |