Jump to content

Condition to perform the function


Recommended Posts

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 by Tezumoto
Link to comment
Share on other sites

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 by YakumoYukari
Link to comment
Share on other sites

10 minutes ago, YakumoYukari said:

inst.components.inventoryitem.congoincontainer = not issomethinginhere

 

I have this problem .-.123.thumb.png.26800b917d26638cd6e9ea5668ad4962.png

This occurs during the crafting of the item or lifting it from the ground.

Edited by Tezumoto
Link to comment
Share on other sites

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

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 by Tesumoto
Link to comment
Share on other sites

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 :p

Link to comment
Share on other sites

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 :p

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 by Tesumoto
Link to comment
Share on other sites

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

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 by Tesumoto
Link to comment
Share on other sites

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

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 by Tesumoto
Link to comment
Share on other sites

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 by Tesumoto
Link to comment
Share on other sites

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 by Tesumoto
Link to comment
Share on other sites

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

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

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

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 by Tesumoto
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...