GiveItems:
	; in: #1: item, #2: quantity, #3: pocket
	; out: #result: unawardable count (0: OK), #1: awarded in pocket, #2: awarded in PC
	push #a
	push #b
	push #c
	push #d
	push #e
	set #a, #1
	set #b, #2
	set #c, #3
	set #d, #zero
	ifge #3, NUM_POCKETS, .try_PC
	set #1, #3
	call GetPocketData
	readbyte #1
	subtract #d, #result, #1
	ifeq #c, POCKET_KEY_ITEMS, .try_PC
	multiply #d, 99
	call .check_pocket
	add #d, #result
.try_PC
	set #1, PC_ITEM_STORAGE
	call GetPocketData
	readbyte #1
	subtract #e, #result, #1
	multiply #e, 99
	call .check_pocket
	add #e, #result
	add #1, #d, #e
	set #temp, #zero
	subborrow #result, #temp, #1, #b ;note that #temp = -1 if this borrows
	multiply #result, #temp
	set #1, #zero
	set #2, #zero
	jumpnz #temp, .done
	subborrow #e, #temp, #b, #d
	jumpz #temp, .quantity_OK
	set #e, #zero
	set #d, #b
.quantity_OK
	jumpz #d, .done_pocket_insertion
	set #1, #c
	call GetPocketData
	ifeq #c, POCKET_KEY_ITEMS, .insert_key_items
	set #1, #d
	call .give_pocket
	jump .done_pocket_insertion
.insert_key_items
	pushpos
	readbyte #1
	set #2, #d
	seekfwd #1
.key_item_loop
	writebyte #a
	decrement #2
	jumpnz #2, .key_item_loop
	writebyte 0xff
	poppos
	add #1, #d
	writebyte #1
.done_pocket_insertion
	set #1, PC_ITEM_STORAGE
	call GetPocketData
	set #1, #e
	callnz #1, .give_pocket
	set #1, ITEMS_OBTAINED_OFFSET
	call GetGameDataPointer
	seek #result
	set #1, #a
	decrement #1
	set #2, 1
	call FlagAction
	set #result, #zero
	set #1, #d
	set #2, #e
.done
	pop #e
	pop #d
	pop #c
	pop #b
	pop #a
	return

.check_pocket
	; initial numitems byte in #1, item still in #a
	set #result, #zero
.pocket_loop
	retz #1
	decrement #1
	readbyte #2
	readbyte #3
	ifne #2, #a, .pocket_loop
	subtract #temp, 99, #3
	add #result, #temp
	jump .pocket_loop

.give_pocket
	; quantity in #1, item still in #a
	pushpos
	readbyte #2
	set #3, #2
.increment_pocket_loop
	jumpz #1, .done_pocket
	jumpz #2, .expand_pocket
	readbyte #4
	readbyte #5
	decrement #2
	ifne #4, #a, .increment_pocket_loop
	subtract #6, 99, #5
	ifle #6, #1, .increment_OK
	set #6, #1
.increment_OK
	subtract #1, #6
	add #5, #6
	seekback 1
	writebyte #5
	jump .increment_pocket_loop
.expand_pocket
	increment #3
	set #2, 99
	ifle #2, #1, .expansion_OK
	set #2, #1
.expansion_OK
	writebyte #a
	writebyte #2
	subtract #1, #2
	jumpnz #1, .expand_pocket
	writebyte 0xff
.done_pocket
	poppos
	writebyte #3
	return

GetPocketData:
	; in: #1: pocket
	; out: #result: max, seeked: position
	ifle #1, NUM_POCKETS, .pocket_OK
	set #1, NUM_POCKETS
.pocket_OK
	set #temp, .data
	mulacum #temp, #1, 3
	gethalfwordinc #1, #temp
	call GetGameDataPointer
	seek #result
	getbyte #result, #temp
	return

.data
	dh ITEMS_COUNT_OFFSET
	db MAX_ITEMS
	dh BALLS_COUNT_OFFSET
	db MAX_BALLS
	dh KEY_ITEMS_COUNT_OFFSET
	db MAX_KEY_ITEMS
	dh PC_ITEMS_COUNT_OFFSET
	db MAX_PC_ITEMS

RemoveAllInstancesOfItem:
	; #1: item, #2: pocket; returns count
	push #r0
	push #r1
	set #r0, #1
	set #r1, #zero
	set #1, #2
	push #2
	call GetPocketData
	pop #1
	call .handle_pocket
	set #1, PC_ITEM_STORAGE
	call GetPocketData
	call .handle_pocket_contents
	set #1, .mon_callback
	call ApplyPartyPatches
	set #result, #r1
	pop #r1
	pop #r0
	return

.handle_pocket
	ifeq #1, POCKET_KEY_ITEMS, .handle_key_items
.handle_pocket_contents
	pushpos
	readbyte #1
	set #2, #1
.pocket_contents_loop
	jumpz #1, .done_pocket
	readbyte #3
	readbyte #4
	decrement #1
	ifne #3, #r0, .pocket_contents_loop
	seekback 2
	add #r1, #4
	push #1
	push #2
	shiftleft #1, 1
	increment #1
	set #2, 2
	call ShiftSaveDataBack
	pop #2
	pop #1
	decrement #2
	jump .pocket_contents_loop
.done_pocket
	poppos
	writebyte #2
	return

.handle_key_items
	pushpos
	readbyte #1
	set #2, #1
.key_items_loop
	jumpz #1, .done_pocket
	readbyte #3
	decrement #1
	ifne #3, #r0, .key_items_loop
	seekback 1
	push #1
	push #2
	increment #1
	set #2, 1
	call ShiftSaveDataBack
	pop #2
	pop #1
	increment #r1
	decrement #2
	jump .key_items_loop

.mon_callback
	increment #1
	seek #1
	getfilebyte #temp
	ifne #temp, #r0, .done_mon
	writebyte #zero
	increment #r1
.done_mon
	return

CountItems:
	; #1: item, #2: pocket
	push #r0
	push #r1
	set #r0, #1
	set #r1, #zero
	ifge #2, NUM_POCKETS, .PC_only
	set #1, #2
	push #2
	call GetPocketData
	pop #1
	call .handle_pocket
.PC_only
	set #1, PC_ITEM_STORAGE
	call GetPocketData
	call .handle_pocket_contents
	set #1, .mon_callback
	call ApplyPartyPatches
	set #result, #r1
	pop #r1
	pop #r0
	return

.handle_pocket
	ifeq #1, POCKET_KEY_ITEMS, .handle_key_items
.handle_pocket_contents
	readbyte #1
.pocket_loop
	retz #1
	readbyte #2
	readbyte #3
	decrement #1
	ifne #2, #r0, .pocket_loop
	add #r1, #3
	jump .pocket_loop

.handle_key_items
	readbyte #1
.key_item_loop
	retz #1
	readbyte #2
	decrement #1
	ifne #2, #r0, .key_item_loop
	increment #r1
	jump .key_item_loop

.mon_callback
	increment #1
	seek #1
	readbyte #1
	ifne #1, #r0, .done
	increment #r1
.done
	return
