Hi all, I'm new to this game (started a week ago) and already addicted. I'm one of the players who simply collects everything and so I faced something which is annoying: when looting a chest I'm mostly clicking on "Take all". But after that the empty chest stays open and I have to press ESC for closing it. In my opinion it makes sense to close the window, if it's empty after pressing the button. Therefore I decided to create a mod, because it's just a simple "pane.dismiss()" command. Next step would be to check if the chest is really empty (perhaps the inventory is full) but first things first. So far I have two files: interface\chests\chest64.config.patch (starting with one chest size first) Code: [ {"op":"add","path":"/gui/clear/callback","value":"take_all_and_close"}, {"op":"add","path":"/scriptWidgetCallbacks","value":["take_all_and_close"]}, {"op":"add","path":"/scripts","value":["/scripts/take_all_and_close/take_all_and_close.lua"]} ] scripts\take_all_and_close\take_all_and_close.lua Code: function take_all_and_close() --takeAll() pane.dismiss() end The code works and closes the window, but of course the part with the "Take all" is missing. But I cannot find a hint in the original assets how this is done? I thought it would be a single function call, but I don't know which one? Can someone help me with that? Thank you and best regards!
I made some progress but could still need some help. This is my LUA-script: Code: function take_all_and_close() local container = pane.containerEntityId() local containerItems = world.containerItems(container) for index,item in pairs(containerItems) do player.giveItem(item) -- check if giveItem was successful, if not: cancel at this point (without closing the window) -- ... world.containerConsume(container, item) end pane.dismiss() end Now I need a way to check if "player.giveItem(item)" was successful because the inventory could be full. Currently if the inventory is full, the items fall to the ground. I prefer the transfer gets stopped if the inventory is full and the window should stay open. The documentation says the function "player.giveItem" doesn't have a return value. Does anyone have an idea? Or another solution? Thanks! BTW: are "player.giveItem" and "world.containerConsume" the correct functions for my case? I haven't tested it with all types of items yet.
The brute force thing would be to count all the items in the player's inventory (with stacks counting as the number of items stacked), and see if it changes after each `giveItem` call. Can you do something like that?
Thanks for your answer @chase000! I would be fine with doing it the complicated way but I can not find any lua function which returns me a number of all items of the players inventory at https://starbounder.org/Modding:Lua/Tables/Player. I don't know how to detect a full inventory before giving items to the player. There is only one lua function which could show me that the count of a specific item has changed: Code: unsigned player.hasCountOfItem(ItemDescriptor item, [bool exactMatch]) So if its count increases after "player.giveItem(item)" this would tell me if the last operation was successful. But if not, there is already one item at the floor next to the player. So that's too late. I want to have the same "Take-All"-behavior if the inventory is full like without my mod. Any idea? PS: tried it and it looks like this now. But it drops one item to the floor if inventory is full. Or can I revert/remove the object from the ground and putting it back to the container? And I'm not sure if it works with money. Code: function take_all_and_close() local container = pane.containerEntityId() local containerItems = world.containerItems(container) local isInventoryFull = false for index,item in pairs(containerItems) do local countBefore = player.hasCountOfItem(item, true) player.giveItem(item) world.containerConsume(container, item) local countAfter = player.hasCountOfItem(item, true) if countBefore == countAfter then isInventoryFull = true break end end if not isInventoryFull then pane.dismiss() end end
By the way, doesn't `world.containerTakeAll()` do what you need? Alternatively, can you treat the player as a container and use `world.containerItemsCanFit()`?
Thanks! Can you guide me how to "treat the player as container" for using "world.containerItemsCanFit"?
This unfortunately doesn't work as the function name suggests: it simply consumes/removes all items from the container, doesn't put anything in the players inventory and doesn't give me any result (always nil). Code: local container = pane.containerEntityId() local result = world.containerTakeAll(container) So can anyone show me how to work with "world.containerItemsCanFit" and the players inventory?