Help with Equipment System refresh problem

Godot Version

Godot 4.5

Question

Hey there, I’ve been working on a JRPG system for months now, and currently, I’m having this issue with the pause menu. Like any other JRPG, it has a menu for the items and equipments, and I’ve made a function that is supposed to refresh the lists and create buttons for them if they’re pressed.

But for some reason, any time this function is called, it’ll make duplicate buttons for every piece of equipment, doesn’t matter if it’s by a button press or if it’s in the _ready function, I keep getting the same result. It still works as intended, but I want to remove those duplicated equiment buttons.

I tried looking into the function’s code to see if there’s anything that could be causing it, but so far, my mind has been a blank and I don’t know what’s causing it. If anyone could help me, it would be appreciated as I’m still a bit of an amateur.

func refreshEquipmentList():
	if InventorySystem.equipment:
		print(InventorySystem.equipment)
		for i in (InventorySystem.equipment.size() - 1):

            #Creates the button and its properties

			var button = Button.new()
			button.text = str(InventorySystem.equipment[i].Resource.name) + " " + str(InventorySystem.equipment[i].quantity)
			button.custom_minimum_size.y = 80
			button.alignment = HORIZONTAL_ALIGNMENT_LEFT
			button.icon = InventorySystem.equipment[i].Resource.icon
			button.expand_icon = true
			button.theme = preload("res://Themes/theme.tres")
		
#Connects the buttons to the appropriate signals.
      button.focus_entered.connect(showEquipmentDescription.bind(InventorySystem.equipment[i].Resource.description, button))
			button.focus_entered.connect(showFinalStats.bind(InventorySystem.equipment[i].Resource))
			button.focus_exited.connect(emptyDescription)

#Checks the equipment resource type and the accessory number to determine which menu it'll be added and which slot that resource will take. 
			if InventorySystem.equipment[i].Resource.type == "Grimoire Charm":
				button.pressed.connect(GameManager.activeParty[0].equip.bind(InventorySystem.equipment[i].Resource, GameManager.activeParty[0].WeaponTypeName))
				button.pressed.connect(hideMenus.bind(0))
				WeaponsList.add_child(button)
			elif InventorySystem.equipment[i].Resource.type == "Accessory":
				match AccessoryNo:
					0:
						button.pressed.connect(GameManager.activeParty[0].equip.bind(InventorySystem.equipment[i].Resource, \
						"Accessory 1"))
					1:
						button.pressed.connect(GameManager.activeParty[0].equip.bind(InventorySystem.equipment[i].Resource, \
						"Accessory 2"))
				button.pressed.connect(hideMenus.bind(1))
				button.pressed.connect(showEvaStats)
				AccessoryList.add_child(button)
			print("Button added")
			print(i)

I apologize if this doesn’t look too clean, as this is my first time trying to typing code-related stuff here, and I still haven’t refactored my code. But in general, any help with this function would be appreciated

I’m not seeing anything in this code that would cause duplicate entries, granted, I’m not the most experience programmer.

What is this script attached to? It seems like the script is running as intended, but being run twice. If it’s being called twice even in the _ready() function, you could have too many instances of the node it’s attached to.

Also, is print(InventorySystem.equipment) returning the correct info? If there are duplicates in the array, that could cause this issue. Also, I’d add print(InventorySystem.equipment.size()) and a counter to the loop to be sure the loop isn’t just running more than it should for some reason. If the problem is just the loop looping too much, that can be solved with math.

So this one small change will decrease the cognitive load of your code.

func refreshEquipmentList():
	if not InventorySystem.equipment:
		return
	print(InventorySystem.equipment)
	for i in (InventorySystem.equipment.size() - 1):
		#Creates the button and its properties
		var button = Button.new()
		button.text = str(InventorySystem.equipment[i].Resource.name) + " " + str(InventorySystem.equipment[i].quantity)
		button.custom_minimum_size.y = 80
		button.alignment = HORIZONTAL_ALIGNMENT_LEFT
		button.icon = InventorySystem.equipment[i].Resource.icon
		button.expand_icon = true
		button.theme = preload("res://Themes/theme.tres")
		
		#Connects the buttons to the appropriate signals.
		button.focus_entered.connect(showEquipmentDescription.bind(InventorySystem.equipment[i].Resource.description, button))
		button.focus_entered.connect(showFinalStats.bind(InventorySystem.equipment[i].Resource))
		button.focus_exited.connect(emptyDescription)

		#Checks the equipment resource type and the accessory number to determine which menu it'll be added and which slot that resource will take. 
		if InventorySystem.equipment[i].Resource.type == "Grimoire Charm":
			button.pressed.connect(GameManager.activeParty[0].equip.bind(InventorySystem.equipment[i].Resource, GameManager.activeParty[0].WeaponTypeName))
			button.pressed.connect(hideMenus.bind(0))
			WeaponsList.add_child(button)
		elif InventorySystem.equipment[i].Resource.type == "Accessory":
			match AccessoryNo:
				0:
					button.pressed.connect(GameManager.activeParty[0].equip.bind(InventorySystem.equipment[i].Resource, \
					"Accessory 1"))
				1:
					button.pressed.connect(GameManager.activeParty[0].equip.bind(InventorySystem.equipment[i].Resource, \
					"Accessory 2"))
			button.pressed.connect(hideMenus.bind(1))
			button.pressed.connect(showEvaStats)
			AccessoryList.add_child(button)
		print("Button added")
		print(i)

As for your problem - you are not deleting the original buttons when you make new ones. I can’t tell from your code where it needs to be, but you need something like this:

for control in get_children()
	if control is Button:
		control.queue_free()

Okay, I found where the problem was, and it’s on me. I screwed up something in the inventory system code that’s supposed to add the equipment to the equipment array and I somehow made it check the length of the items. So, it’s on me

2 Likes