0 votes

I have a hotbar that shares the first few slots of a dictionary with my main inventory. The problem is that when an item is moved to an empty slot, like merging two items together:

Inventory Before Merge

Inventory After Merge

In the hotbar, the original item stays there and never goes away. But it's not really there, just its image is leftover:

Hotbar before merge
Hotbar after merge

Here's my code:
For the inentory:

extends Node2D

const SLOT_CLASS = preload("res://UI/SlotScript.gd")

onready var inventorySlots = $InventoryContainer

var holdingItem = null

var tempItem
var stackSize
var ableToAdd


func _ready():
    var slots = inventorySlots.get_children()
    for i in range(slots.size()):
#       slots[i].connect("gui_input", self, "_slot_gui_input", [slots[i]])
        slots[i].slotIndex = i
        slots[i].slotType = SLOT_CLASS.SLOT_TYPE.INVENTORY

    _initialize_inventory()


func _initialize_inventory():
    var slots = inventorySlots.get_children()
    for i in range(slots.size()):
        if PlayerInventoryScript.inventory.has(i):
            slots[i]._initialize_item(PlayerInventoryScript.inventory[i][0], PlayerInventoryScript.inventory[i][1])

For the hotbar:

extends Node2D

const SLOT_CLASS = preload("res://UI/SlotScript.gd")

onready var inventorySlots = $HotbarContainer

var holdingItem = null

var tempItem
var stackSize
var ableToAdd


func _process(_delta):
    var slots = inventorySlots.get_children()
    for i in range(slots.size()):
#       slots[i].connect("gui_input", self, "_slot_gui_input", [slots[i]])
        slots[i].slotIndex = i
        slots[i].slotType = SLOT_CLASS.SLOT_TYPE.HOTBAR

    _initialize_inventory()


func _initialize_inventory():
    var slots = inventorySlots.get_children()
    for i in range(slots.size()):
        if PlayerInventoryScript.inventory.has(i):
            slots[i]._initialize_item(PlayerInventoryScript.inventory[i][0], PlayerInventoryScript.inventory[i][1])

For the dictionary:

var inventory = {
    0: ["Axe", 1],
    1: ["Tree Branch", 5],
    2: ["Weeds", 98],
    3: ["Weeds", 18],
    4: ["Weeds", 45],
    5: ["Rock", 2],
    6: ["Rock", 19],
    }

And, for the slots:

extends Panel

onready var itemScene = find_node("ItemScript.gd")
var defaultTexture = preload("res://UI/PeriwinkleBtn.png")
var emptyTexture = preload("res://UI/EmptyPeriwinkleBtn.png")
var selectedTexture = preload("res://UI/HotbarSlot.png")
var itemClass = preload("res://Items/ItemScene.tscn")

var defaultStyle: StyleBoxTexture = null
var emptyStyle: StyleBoxTexture = null
var selectedStyle: StyleBoxTexture = null

var item = null

var inventoryNode
var slotIndex
var slotType

enum SLOT_TYPE{
    HOTBAR = 0,
    INVENTORY}


func _ready():
    defaultStyle = StyleBoxTexture.new()
    emptyStyle = StyleBoxTexture.new()
    selectedStyle = StyleBoxTexture.new()
    defaultStyle.texture = defaultTexture
    emptyStyle.texture = emptyTexture
    selectedStyle.texture = selectedTexture

#   if randi() % 2 == 0:
#       item = itemClass.instance()
#       add_child(item) 

    _refresh_style()


func _refresh_style():
    if SLOT_TYPE.HOTBAR == slotType and PlayerInventoryScript.activeItemSlot == slotIndex:
        set('custom_styles/panel', selectedStyle)
    elif item == null:
        set('custom_styles/panel', emptyStyle)
    else:
        set('custom_styles/panel', defaultStyle)


func _pick_from_slot():
    remove_child(item)
    inventoryNode = find_parent("UserInterfaceGroup")
    inventoryNode.add_child(item)
    item = null
    _refresh_style()


func _put_into_slot(newItem):
    item = newItem
    item.position = Vector2(0,0)
    inventoryNode = find_parent("UserInterfaceGroup")
    inventoryNode.remove_child(item)
    add_child(item)
    _refresh_style()


func _initialize_item(itemName, itemQuantity):
    if item == null:
        item = itemClass.instance() 
        add_child(item)
        #print(itemQuantity)
        item._set_item(itemName, itemQuantity)
        item._set_item(itemName, itemQuantity)
    else:
        pass
        item._set_item(itemName,itemQuantity)

    _refresh_style()

Any input would be appreciated.

Godot version 3.4 stable
in Engine by (14 points)

1 Answer

+1 vote

To be honest I didn't read all these code
Dictionary works fine, You just need a method to let UI know whenever a change occured in it. Design some kind of signal, that will fire when dictionary is changed, connect it to both bars, and let them use the same method to visualize changes.
Hint : signals introduced and kept in Autoload script don't need hard references to be connected

by (7,753 points)

Thank you! I'll see what I come up with and write what works.

Yeah :)
Remember to start designing it on dictionary, not on Inventory or UI bars. They all share this one variable, so it will require much less code this way.
good luck :)

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.