itemlist get index of item or get the list/array of items

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Visterface


i have a question regarding the ItemList-Node. Is there a way to get a list of all the items or remove an item without the index (like the erase-function from arrays)?

I´m working on an inventory system. I got two ItemList-Nodes, one for the inventory and one for the equipment. If i want to equip an item from the inventory to an occupied equipmentslot the items should swap. For example, i want to equip an chest-item from the inventory to the equipment. The old equipment-chest-item should go from the equipmentlist to the inventorylist and the new one from inventory to equipment.
Problem is, i can´t remove the old equiped item because i got no index and i can´t find a method to get the index. The item_selected-Signal won´t work because i never select the item. If i could access the actual list i think i could manage to find the item-index with a for loop or something but the ItemList-Node doesn´t seem to have a list/array-property to access.

If someone could help me with this i would be glad.

:bust_in_silhouette: Reply From: jgodfrey

While I haven’t used ItemList, looking at the docs, these look helpful for your situation…

  • get_item_at_position() - Takes a Vector2 and returns the index of the item at the specified position (or, optionally, the item closest to the specified position).
  • get_item_count() - Returns the number of items in the list. I assume you could use this (minus 1) to iterate through all items in the list via a loop…

Do those not solve your issue?


first, thanks for youre reply.
I don´t realy know how to work with the first option. I guess i could get the position of each item if i could access the itemList, but i can´t. Same problem with the second option, i can´t access the list, so i can´t loop through it. At least i don´t know how.
I guess the ItemList-Node work intern with a List or Array but the doc doesn´t mention how to access this list/array directly. Accessing this intern list would solve my problem i guess.

Visterface | 2022-09-23 15:40

The first option takes a Vector2 - so that’s intended to work with, say, a mouse-position. So, the item you’re mouse is near/over.

For the second option, once you have the number of items in the list (via get_item_count(), there are lots of other get_* method calls to retrieve various details of each item. Untested, but I’d expect something like this to be useful:

for i in $ItemList.get_item_count():

That should print the text property of each item in the list. There are similar get_* functions for other details as well…

jgodfrey | 2022-09-23 15:48

Hello again,

sadly that wasn´t working for me. There is no get_* function which could achieve what i needed.
I managed to get an ugly workaround. I created two arrays (items_equiped, items_in_inventar). Whenever i add/remove something to the ItemList-Nodes i also do it with the arrays. Then i can get the index from those arrays and use them with the ItemList-Nodes. For Example:


Where equipment is the ItemList-Node and items_equiped is the array i created.
I´m really not happy with that solution because it´s hard to read and follow but i don´t know what else i could do.
But anyway thanks for youre help and effort.

Visterface | 2022-09-23 17:49

When you say wasn’t working for me, does that mean you can’t get my sample code to iterate through your list of items or that it does iterate through the items, but that doesn’t help you to resolve the problem?

Maybe I’m missing the point, but I really don’t understand what it is you need that can’t be accomplished by one of the things I’ve mentioned above…

jgodfrey | 2022-09-23 17:59

So after thinking about it trice i figured you where right all along :smiley:
I completely reworked my code and could handle it with get_metadata. Metadata was a property i wasn´t using before. I did use my arrays to store item values. So after switching to metadata the rest was easy enough.

Here is my solution if someone is interested:

extends Control

onready var inventory = $ItemList
onready var equipment = $Equipment
var slots = {
	main_hand = false,
	off_hand = false,
	helmet = false,
	chest = false,
	leg = false,
	foot = false

# Called when the node enters the scene tree for the first time.
func _ready():
	SignalHandler.connect("item_collected",self, "handle_item_collected")

func handle_item_collected(stats, icon):
	icon = "res://Assets/Icons/"+icon
	inventory.set_item_metadata(inventory.get_item_count()-1, stats)
	inventory.set_item_tooltip(inventory.get_item_count()-1, str(stats))

func check_if_slot_is_occupied(slot):
	return slots.get(slot)

func _on_EquipButton_pressed():
	if inventory.get_selected_items().size() > 0:
		var selected_item 
		var slot
		selected_item = inventory.get_selected_items()[0]
		slot = inventory.get_item_metadata(selected_item).slot
		if check_if_slot_is_occupied(slot):
			var old_item
			for i in equipment.get_item_count():
				if equipment.get_item_metadata(i).slot == inventory.get_item_metadata(selected_item).slot:
					old_item = i
			inventory.set_item_metadata(inventory.get_item_count()-1, equipment.get_item_metadata(old_item))
			inventory.set_item_tooltip(inventory.get_item_count()-1, equipment.get_item_tooltip(old_item))
			equipment.set_item_metadata(equipment.get_item_count()-1, inventory.get_item_metadata(selected_item))
			equipment.set_item_tooltip(equipment.get_item_count()-1, inventory.get_item_tooltip(selected_item))
			equipment.set_item_metadata(equipment.get_item_count()-1, inventory.get_item_metadata(selected_item))
			equipment.set_item_tooltip(equipment.get_item_count()-1, inventory.get_item_tooltip(selected_item))
			slots[slot] = true

Thanks again for youre time and effort.

Visterface | 2022-09-23 19:49