Tesumoto Posted January 8, 2019 Share Posted January 8, 2019 (edited) Hello everyone! Today I need your help again. Perhaps it will be very difficult, but I hope someone will be able to suggest something. I have this code: local function updateBackpack(inst) if not GLOBAL.TheWorld.ismastersim then return inst end if (inst.components.inventoryitem == nil) then inst:AddComponent("inventoryitem") end inst.components.inventoryitem.cangoincontainer = true end AddPrefabPostInit("backpack", updateBackpack) Thanks to this code, I can put a backpack in inventory or chest. But because of this, you can carry too many full backpacks. What do I want to change? I want to add a condition that only an empty backpack could be put in inventory and chests. Is it possible to somehow implement it? How to make the game check whether the backpack is empty? Thank you for your attention. Edited January 8, 2019 by Tezumoto Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 8, 2019 Share Posted January 8, 2019 (edited) I think you need an extra function that checks if it's empty when the container gets the event of getting or losing items. local function OnInventorySlotChanged(inst) local issomethinginhere = false for k, v in pairs(inst.components.containers.slots) do issomethinginhere = v ~= nil -- if something is here, set true end inst.components.inventoryitem.congoincontainer = not issomethinginhere end and tweak your PostInit function like this local function updateBackpack(inst) if not GLOBAL.TheWorld.ismastersim then return inst end if (inst.components.inventoryitem == nil) then inst:AddComponent("inventoryitem") end inst:ListenForEvent("itemget", OnInventorySlotChanged) inst:ListenForEvent("itemlose", OnInventorySlotChanged) OnInventorySlotChanged(inst) -- To get the initial state in case that is spawned from save data. end AddPrefabPostInit("backpack", updateBackpack) I might be wrong but you should try this code Edited January 8, 2019 by YakumoYukari Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 8, 2019 Share Posted January 8, 2019 inst.components.inventoryitem.congoincontainer = not issomethinginhere  Link to comment Share on other sites More sharing options...
Tesumoto Posted January 8, 2019 Author Share Posted January 8, 2019 (edited) 10 minutes ago, YakumoYukari said: inst.components.inventoryitem.congoincontainer = not issomethinginhere  I have this problem .-. This occurs during the crafting of the item or lifting it from the ground. Edited January 8, 2019 by Tezumoto Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 8, 2019 Share Posted January 8, 2019 local function OnInventorySlotChanged(inst) if not GLOBAL.TheWorld.ismastersim then return inst end local issomethinginhere = false for k, v in pairs(inst.components.containers.slots) do issomethinginhere = v ~= nil -- if something is here, set true end inst.components.inventoryitem.congoincontainer = not issomethinginhere end Maybe mastersim checking is needed on this function too. Link to comment Share on other sites More sharing options...
Tesumoto Posted January 8, 2019 Author Share Posted January 8, 2019 (edited) 9 minutes ago, YakumoYukari said: local function OnInventorySlotChanged(inst) if not GLOBAL.TheWorld.ismastersim then return inst end local issomethinginhere = false for k, v in pairs(inst.components.containers.slots) do issomethinginhere = v ~= nil -- if something is here, set true end inst.components.inventoryitem.congoincontainer = not issomethinginhere end Maybe mastersim checking is needed on this function too. [00:01:37]: [string "../mods/mod/modmain.lua"]:7: attempt to index field 'containers' (a nil value) LUA ERROR stack traceback: Â Â Â Â ../mods/mod/modmain.lua(7,1) in function 'OnInventorySlotChanged' Â Â Â Â ../mods/mod/modmain.lua(23,1) Â Â Â Â =(tail call) ? Â Â Â Â =[C] in function 'xpcall' Â Â Â Â scripts/mods.lua(158,1) in function 'mod' Â Â Â Â scripts/mainfunctions.lua(267,1) Â Â Â Â =[C] in function 'SpawnPrefab' Â Â Â Â scripts/mainfunctions.lua(306,1) in function 'SpawnPrefab' Â Â Â Â ../mods/workshop-836583293/scripts/widgets/iteminfo_desc.lua(687,1) in function 'UpdateInfo' Â Â Â Â ../mods/workshop-836583293/scripts/widgets/iteminfo_desc.lua(786,1) in function 'ShowInfo' Â Â Â Â ../mods/workshop-836583293/modmain.lua(80,1) in function 'OnGainFocus' Â Â Â Â scripts/widgets/widget.lua(613,1) in function 'SetFocusFromChild' Â Â Â Â scripts/widgets/widget.lua(621,1) in function 'SetFocusFromChild' Â Â Â Â scripts/widgets/widget.lua(649,1) in function 'SetFocus' Â Â Â Â scripts/frontend.lua(777,1) in function 'DoHoverFocusUpdate' Â Â Â Â scripts/frontend.lua(730,1) in function 'Update' Â Â Â Â scripts/update.lua(92,1) attempt to index field 'containers' (a nil value) -Â containers don't have value? Edited January 8, 2019 by Tesumoto Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 8, 2019 Share Posted January 8, 2019 oh the component name I write was wrong local function OnInventorySlotChanged(inst) local issomethinginhere = false for k, v in pairs(inst.components.container.slots) do issomethinginhere = v ~= nil -- if something is here, set true end inst.components.inventoryitem.congoincontainer = not issomethinginhere end it is container not containers Link to comment Share on other sites More sharing options...
Tesumoto Posted January 8, 2019 Author Share Posted January 8, 2019 (edited) 26 minutes ago, YakumoYukari said: oh the component name I write was wrong local function OnInventorySlotChanged(inst) local issomethinginhere = false for k, v in pairs(inst.components.container.slots) do issomethinginhere = v ~= nil -- if something is here, set true end inst.components.inventoryitem.congoincontainer = not issomethinginhere end it is container not containers Now no error, but the backpack behaves as usual, just falls to the ground. This happens when there is something in it and when it is completely empty. Maybe problem in true/false? Or issomethinginhere = v ~= nil -- if something is here, set true Edited January 8, 2019 by Tesumoto Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 8, 2019 Share Posted January 8, 2019 Ok, let's re-write the function. local function DropItemWhenFilled(inst, owner) owner = owner or inst.components.inventoryitem.owner if owner == nil then return end -- if it is not equipped return. for k, v in pairs(inst.components.containers.slots) do -- if find items in slot, owner.components.inventory:DropItem(inst, true, true) break end end local function updateBackpack(inst) if not GLOBAL.TheWorld.ismastersim then return inst end if (inst.components.inventoryitem == nil) then inst.components.inventoryitem.congoincontainer = true inst:AddComponent("inventoryitem") inst:ListenForEvent("onputininventory", DropItemWhenFilled) DropItemWhenFilled(inst) end end AddPrefabPostInit("backpack", updateBackpack) Â Link to comment Share on other sites More sharing options...
Tesumoto Posted January 8, 2019 Author Share Posted January 8, 2019 (edited) 18 minutes ago, YakumoYukari said: Ok, let's re-write the function. local function DropItemWhenFilled(inst, owner) owner = owner or inst.components.inventoryitem.owner if owner == nil then return end -- if it is not equipped return. for k, v in pairs(inst.components.containers.slots) do -- if find items in slot, owner.components.inventory:DropItem(inst, true, true) break end end local function updateBackpack(inst) if not GLOBAL.TheWorld.ismastersim then return inst end if (inst.components.inventoryitem == nil) then inst.components.inventoryitem.congoincontainer = true inst:AddComponent("inventoryitem") inst:ListenForEvent("onputininventory", DropItemWhenFilled) DropItemWhenFilled(inst) end end AddPrefabPostInit("backpack", updateBackpack)   for k, v in pairs(inst.components.containers.slots) do - need containers or container? Again this same -> The backpack behaves as usual, just falls to the ground. This happens when there is something in it and when it is completely empty. I fix (cangoincontainer) but stil don't work .-. congoincontainer Edited January 8, 2019 by Tesumoto Link to comment Share on other sites More sharing options...
Tesumoto Posted January 9, 2019 Author Share Posted January 9, 2019 I tried to use this code, but the backpack can always be put in inventory. How to enable tracking "inst.components.container: IsEmpty ()" or "not inst.components.container: IsEmpty ()"? local function updateBackpack(inst) if not GLOBAL.TheWorld.ismastersim then return inst end if inst.components.container and inst.components.container:IsEmpty() then if (inst.components.inventoryitem == nil) then inst:AddComponent("inventoryitem") end inst.components.inventoryitem.cangoincontainer = true elseif inst.components.container and not inst.components.container:IsEmpty() then inst:RemoveComponent("inventoryitem") inst.components.inventoryitem.cangoincontainer = false end end AddPrefabPostInit("backpack", updateBackpack) Â Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 9, 2019 Share Posted January 9, 2019 Oh right, you should add  inst:ListenForEvent("itemget", DropItemWhenFilled) inst:ListenForEvent("itemlose", DropItemWhenFilled) in updatebackpack too I think Link to comment Share on other sites More sharing options...
Tesumoto Posted January 9, 2019 Author Share Posted January 9, 2019 (edited) 15 minutes ago, YakumoYukari said: Oh right, you should add  inst:ListenForEvent("itemget", DropItemWhenFilled) inst:ListenForEvent("itemlose", DropItemWhenFilled) in updatebackpack too I think DropItemWhenFilled? This for it? local function DropItemWhenFilled(inst, owner) owner = owner or inst.components.inventoryitem.owner if owner == nil then return end -- if it is not equipped return. for k, v in pairs(inst.components.containers.slots) do -- if find items in slot, owner.components.inventory:DropItem(inst, true, true) break end end local function updateBackpack(inst) if not GLOBAL.TheWorld.ismastersim then return inst end if (inst.components.inventoryitem == nil) then inst.components.inventoryitem.congoincontainer = true inst:AddComponent("inventoryitem") inst:ListenForEvent("onputininventory", DropItemWhenFilled) DropItemWhenFilled(inst) end end AddPrefabPostInit("backpack", updateBackpack)  OMG, I think I did it ._. I need to check this code on the server with the caves! local function updateBackpack(inst) if not GLOBAL.TheWorld.ismastersim then return inst end if inst.components.container and inst.components.container:IsEmpty() then if (inst.components.inventoryitem == nil) then inst:AddComponent("inventoryitem") end inst.components.inventoryitem.cangoincontainer = true elseif inst.components.container and not inst.components.container:IsEmpty() then --inst:RemoveComponent("inventoryitem") inst.components.inventoryitem.cangoincontainer = false end inst:ListenForEvent("itemget", updateBackpack) inst:ListenForEvent("itemlose", updateBackpack) end AddPrefabPostInit("backpack", updateBackpack)  Edited January 9, 2019 by Tesumoto Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 9, 2019 Share Posted January 9, 2019 Oh, right. there's a method to check if the container is empty. It's better to separate out to a function that set cangoincontainer but anyway. Link to comment Share on other sites More sharing options...
Tesumoto Posted January 9, 2019 Author Share Posted January 9, 2019 (edited) 7 minutes ago, YakumoYukari said: Oh, right. there's a method to check if the container is empty. It's better to separate out to a function that set cangoincontainer but anyway. When the backpack is empty, it can be put in inventory.When there is something in the backpack, it falls to the ground.But there is a bug!If the backpack is in inventory, things can be put into it, so too many things can be carried.How to prohibit putting things in a backpack when it is in inventory or chest? And bug #2 There is no animation of the closing and opening of the backpack when player is wearing it. (This is not so important, but it would be nice to fix it too) Edited January 9, 2019 by Tesumoto Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 9, 2019 Share Posted January 9, 2019 (edited) You mean you can open the container(backpack) in inventory? I mean the inventory slot Edited January 9, 2019 by YakumoYukari Link to comment Share on other sites More sharing options...
Tesumoto Posted January 9, 2019 Author Share Posted January 9, 2019 (edited) 2 minutes ago, YakumoYukari said: You mean you can open the container(backpack) in inventory? Oh, the load on the server because of this is too big, the game hangs hard =( inst:ListenForEvent("itemget", updateBackpack) inst:ListenForEvent("itemlose", updateBackpack) No, can't open backpack in inventory but can put items in backpack when it in inventory .-. Edited January 9, 2019 by Tesumoto Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 9, 2019 Share Posted January 9, 2019 By holding items and right click into the container in inventory? Link to comment Share on other sites More sharing options...
Tesumoto Posted January 9, 2019 Author Share Posted January 9, 2019 1 minute ago, YakumoYukari said: By holding items and right click into the container in inventory? Yes. In this way, you can fill a backpack when it is in inventory. Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 9, 2019 Share Posted January 9, 2019 if inst.components.container and inst.components.container:IsEmpty() then if (inst.components.inventoryitem == nil) then inst:AddComponent("inventoryitem") end inst.components.inventoryitem.cangoincontainer = true inst.components.container.canbeopened = true inst.replica.container:SetCanBeOpened(true) elseif inst.components.container and not inst.components.container:IsEmpty() then --inst:RemoveComponent("inventoryitem") inst.components.inventoryitem.cangoincontainer = false inst.components.container.canbeopened = false inst.replica.container:SetCanBeOpened(false) end try this Link to comment Share on other sites More sharing options...
Tesumoto Posted January 9, 2019 Author Share Posted January 9, 2019 3 minutes ago, YakumoYukari said: if inst.components.container and inst.components.container:IsEmpty() then if (inst.components.inventoryitem == nil) then inst:AddComponent("inventoryitem") end inst.components.inventoryitem.cangoincontainer = true inst.components.container.canbeopened = true inst.replica.container:SetCanBeOpened(true) elseif inst.components.container and not inst.components.container:IsEmpty() then --inst:RemoveComponent("inventoryitem") inst.components.inventoryitem.cangoincontainer = false inst.components.container.canbeopened = false inst.replica.container:SetCanBeOpened(false) end try this I think I was able to optimize the code so that it don't have lags. local function UpdateBackpack(inst) if not GLOBAL.TheWorld.ismastersim then return inst end function CheckStatus(inst) if inst.components.container and inst.components.container:IsEmpty() then if (inst.components.inventoryitem == nil) then inst:AddComponent("inventoryitem") end inst.components.inventoryitem.cangoincontainer = true elseif inst.components.container and not inst.components.container:IsEmpty() then --inst:RemoveComponent("inventoryitem") inst.components.inventoryitem.cangoincontainer = false end end inst:ListenForEvent("itemget", CheckStatus) inst:ListenForEvent("itemlose", CheckStatus) end AddPrefabPostInit("backpack", UpdateBackpack)    inst:ListenForEvent("itemget", UpdateBackpack)    inst:ListenForEvent("itemlose", UpdateBackpack) This is too hard code. I add new function outside: if not GLOBAL.TheWorld.ismastersim then return inst end  Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 9, 2019 Share Posted January 9, 2019 You move CheckStatus out of UpdateBackpack so that It doesn't need to redefine everytime it is called Link to comment Share on other sites More sharing options...
Tesumoto Posted January 9, 2019 Author Share Posted January 9, 2019 1 minute ago, YakumoYukari said: You move CheckStatus out of UpdateBackpack so that It doesn't need to redefine everytime it is called inst.components.inventoryitem.cangoincontainer = false inst.components.container.canbeopened = false This don't help, I stil can put item in backpack when backpack in inventory, if I use right mouse button. I absolutely don't understand coding, but I figured out how to reduce the load =) But I have no idea how to blocked a putting items in a backpack when he is in a character's inventory or a chest =( Link to comment Share on other sites More sharing options...
YakumoYukari Posted January 9, 2019 Share Posted January 9, 2019 did you inst.replica.container:SetCanBeOpened(true) do this? Link to comment Share on other sites More sharing options...
Tesumoto Posted January 9, 2019 Author Share Posted January 9, 2019 (edited) 45 minutes ago, YakumoYukari said: did you inst.replica.container:SetCanBeOpened(true) do this? I use this full code: if inst.components.container and inst.components.container:IsEmpty() then if (inst.components.inventoryitem == nil) then inst:AddComponent("inventoryitem") end inst.components.inventoryitem.cangoincontainer = true inst.components.container.canbeopened = true inst.replica.container:SetCanBeOpened(true) elseif inst.components.container and not inst.components.container:IsEmpty() then --inst:RemoveComponent("inventoryitem") inst.components.inventoryitem.cangoincontainer = false inst.components.container.canbeopened = false inst.replica.container:SetCanBeOpened(false) end But this don't work for right mouse click, you don't open container when used right mouse click .-. Edited January 9, 2019 by Tesumoto Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now