Help with fixing item logic in inventory

Godot Version

Godot 4.5.1

Hello , so i have made an inventory for my game using resources , so every item is an resource and it is stored in the inv array and fom there it goes to slots in the inventory ui and i can equip them drop them etc . I also made an bonefire which you can put items in for example wood or sticks to make it burn longer , but when puting the items inside the bonfire they are still the same ones i have in my inventory , so when i for example put 2 logs in the bonefire , and collect 1 more , i have 3 instead of 1.I have really big trouble with this and i just dont know how to fix it. The durability is also a big problem with this, because that means every stick etc will have the same durability , im trying to work around it so dont mind it now im still working on it.

This is my inventory code:

extends Resource

class_name inventory
signal updated

@export var inv: Array[invItem]
@export var hotbarr: hotbar

func insert(item: invItem):
	for i in range(inv.size()):
		if inv[i] == item:
			item.amount += 1
			updated.emit()
			return

	for i in range(inv.size()):
		if !inv[i]:
			for j in range(hotbarr.hot_bar.size()):
				if !hotbarr.hot_bar[j]:
					inv[i] = item
					item.amount += 1
					updated.emit()
					return
				if hotbarr.hot_bar[j] == item:
					hotbarr.hot_bar[j] = item
					hotbarr.hot_bar[j].amount += 1
					hotbarr.hotbar_updated.emit()
					return
	updated.emit()
	hotbarr.hotbar_updated.emit()

func insert_from_hotbar(item: invItem):
	for i in range(inv.size()):
		if inv[i] == null:
			inv[i] = item
			inv[i].amount = item.amount
			updated.emit()
			return
		elif inv[i] == item:
			inv[i].amount += item.amount
			updated.emit()
			return
	updated.emit()
	
func remove(item: invItem):
	for i in range(inv.size()):
		if !inv[i]:
			pass
		if inv[i] != item:
			pass
		if inv[i]==item:
			inv[i].amount -= 1
			updated.emit()
			return
		

this is my inventory slot code:

extends Panel

@onready var item_sprite: Sprite2D = $CenterContainer/Panel/itemSprite
@onready var amount_label: Label = $CenterContainer/Panel/amountlabel
@onready var item_menu = $"../../../item_menu"

var is_menu_open = false
var current_item: invItem

func _ready():
	amount_label.visible = false
	item_sprite.visible = false
	item_menu.visible = false

func update(item):
	current_item = item
	if !item:
		item_sprite.visible = false
		amount_label.visible = false
	else:
		if item.amount > 0:
			item_sprite.visible = true
			amount_label.visible = true
		else:
			item_sprite.visible = false
			amount_label.visible = false
		amount_label.text = str(item.amount)
		item_sprite.texture = item.texture

func _on_button_pressed():
	if current_item:
		item_menu.global_position = self.global_position + Vector2(40, 0)
		item_menu.set_item(current_item)
		if !is_menu_open:
			is_menu_open = true
			item_menu.visible = true
		else:
			is_menu_open = false
			item_menu.item_menu_close()

			

invItem resource script:

extends Resource

class_name invItem

@export var texture: Texture2D
@export var name: String = ""
@export var amount: int
@export var max_dur: int
@export var durability: int = 1
@export var description : String
@export_enum("COOK", "FUEL", "NONE") var cookable = ""
@export_enum("NEVER", "ONCE", "INFINITE") var usable_type = ""
@export_enum("INVENTORY", "PLAYER") var inv_type = ""
@export var item_scene: PackedScene
@export_enum("USED", "TOOL", "NONE") var interact_type = "NONE"
@export var compatible_interact_items: Array[invItem]

func check_dur():
	if durability != null:
		if durability <= 0:
			durability = max_dur
			return true
		else:
			return false
func use(_player):
	pass

bone fire script:

extends Control

@onready var raw_slot = $NinePatchRect/raw_slot
@onready var cooked_slot = $NinePatchRect/cooked_slot
@onready var fuel_slot = $NinePatchRect/fuel_slot
@onready var cook_progess_bar = $NinePatchRect/ProgressBar
@onready var cook_timer = $CookTimer
@onready var life_bar = $NinePatchRect/lifeBar
var cook_progress = 0
var cooking = false
var cooked_item: invItem
var bone_fire
var Player

func _ready():
	Player = get_tree().get_first_node_in_group("Player")
	bone_fire = get_tree().get_first_node_in_group("bonef")
	self.visible = false
func _process(_delta):
	#life_bar.value = bone_fire.life_span
	cook_progess_bar.value = cook_progress
	if raw_slot.current_item and fuel_slot.current_item and !cooking:
		cook()
		cooking = true
	
func set_raw_item(item: invItem):
	raw_slot.current_item = item
	raw_slot.update(item)
	cooked_item = raw_slot.current_item.cooked_item
func set_fuel_item(item: invItem):
	fuel_slot.current_item = item
	fuel_slot.update(item)

func cook():
	cook_timer.start()

func _on_cook_timer_timeout():
	if cook_progress < 10:
		cook_progress +=1
		cook_timer.start()
	else:
		cooking = false
		cook_timer.stop()
		cook_progress = 0
		raw_slot.current_item.amount -=1
		fuel_slot.current_item.amount -=1
		raw_slot.update(raw_slot.current_item)
		fuel_slot.update(fuel_slot.current_item)
		Player.inv.insert(cooked_item)
		if raw_slot.current_item.amount <= 0:
			raw_slot.current_item = null
		if fuel_slot.current_item.amount <= 0:
			fuel_slot.current_item = null


		

and the bone fire slot works pretty much the same as the inventory slot, only without the item menu, im really sorry if any of this looks messy , i tried to come up with everything myself so it wont be that pretty lol , thanks in advance for any help!

You probably need to duplicate your item resources to make them unique in each container.

1 Like

thank you that really helped! do you maybe know if there is a way to send that item back to the inventory?

If you want to keep this duplicate around you can assign a variable as you did before, this is called “referencing” rather than “copying” the resource.

Your insert function seems like a good candidate but probably doesn’t work with duplicate items, this expects the exact same resource for == to work.

You could modify it to compare the resource name or save path if your items are created in the filesystem.

thanks for your help!