Jump to content

Inventory interaction (backpack and containers)


Recommended Posts

I want to rearrange items in inventory. After looking into parts of code and many mods with inventory interaction, I've found way to move items in player's inventory:

player.components.inventory.itemslots[i] = nil; -- this line will remove from game memory
player.HUD.controls.inv.inv[i]:SetTile(nil)  -- and this from HUD
player.components.inventory.itemslots[index] = item -- move item back to memory
player.HUD.controls.inv.inv[index]:SetTile(ItemTile(item)) -- show image at screen

But I can't do same thing with player backpack. While memory clearing still working:

backpack.components.container.slots[i] = nil; -- this line remove backpack's item from game memory 

I can't remove item picture from player HUD:

player.HUD.controls.inv.backpackinv[i]:SetTile(nil)  -- throws error about nil value

When I'm dumping player.HUD.controls.inv, it says that backpackinv is a table, not nil.

My question is how to remove item picture from backpack HUD? Tried to find solution by myself for few hourses but no luck.

And following question (if he has  different solution and somebody accidentally knows answer) is how to remove and hide item from container?

Thank you for attention.

Link to comment
Share on other sites

I assume "i" isn't a valid number for "backpackinv". So while backpackinv is not nil, backpackinv is nil.

You should ideally move the items via the inventory/container components, else the code will not be identical to the display.

Link to comment
Share on other sites

Thank you for answer.

As I understand, backpackinv is empty table, so pointer is not nil, while any of indexes of table will be nil.

I didn't understand your second advice completely. During my tests I came to conclusion that I anyway need to call some kind of update HUD function. Otherwise item is moved in memory, but not in HUD. This results in outdated inventory item order and "I can't do that" quote on click (if it was moved and nil on it place) or unexpected active item.

I've dug deeper and found what I've looking for:

local backpack = player.HUD:GetFirstOpenContainerWidget(); -- this will give HUD of opened backpack
for k, v in pairs( backpack.inv ) do print(k, v) end -- output as expected: 1-8 ItemSlot

Now I'm confused with GetFirstOpenContainerWidget() method. It is described in playerhud.lua as

function PlayerHud:GetFirstOpenContainerWidget()
    local k,v = next(self.controls.containers)
    return v
end

So, as I understand, this is just a call to next() function for "controls.containers" and I can use it separately as

local k, v = next(player.HUD.controls.containers)

But, unfortunally, v is nil and I don't understand why. While

player.HUD:GetFirstOpenContainerWidget()

still working as expected and result is 1-8 ItemSlot.

So, my current question is how to loop through all opened containers in HUD (which I suspect would be backpacks and chests)?

Link to comment
Share on other sites

Finally, after hours of experiments, I've figured it out. Seems like next() and GLOBAL.next() are different functions. Here is my solution and answers on my question:

Player inventory is in player.components.inventory, with two required fields:

player.components.inventory.maxslots -- max inventory slots
player.components.inventory.itemslots -- items array

Backpack and chest I've found with loop through player.components.inventory.opencontainers using GLOBAL.next(). Here order of opening\equipping is important, so better to confirm with string.match() prefab names (string field prefab).

    local backpack, chest
    backpack = GLOBAL.next(player.components.inventory.opencontainers)
    print(backpack.prefab)
    
    chest = GLOBAL.next(player.components.inventory.opencontainers, backpack)
    print(chest.prefab)

Both have two similar fields: .numslots - items count and .slots - items array. After that I've finally hide all items from HUD. Player inventory (hands):

for i = 1, player.components.inventory.maxslots do
        print(player.components.inventory.itemslots[i])
        player.HUD.controls.inv.inv[i]:SetTile(nil)
end

Player backpack:

for i = 1, backpack.components.container.numslots do 
	print(backpack.components.container.slots[i])
	player.HUD.controls.containers[backpack].inv[i]:SetTile(nil)
end

Opened chest:

for i = 1, chest.components.container.numslots do 
	print(chest.components.container.slots[i])
	player.HUD.controls.containers[chest].inv[i]:SetTile(nil)
end
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...