Jump to content

(solved) How do you get an opener for a container now?


Recommended Posts

Before

inst.components.container.opener

worked, but it doesn't anymore in beta which will be official update sometime.

 

Does anybody know what's used now instead to check for opener of a container cause I tried

inst.components.container.currentuser

and it doesn't seem to work and I can't figure it out by looking at the new container component

Edited by --- -.-
Link to comment
Share on other sites

I basically wanna try to get this code working all I need is the latest opener but for some reason this just isn't working at all I have no idea what's wrong.. it keeps crashing saying there is no opener even though I just opened it, putting a dotaskintime delay of 0 didnt help either :(

local function OnOpen(inst)
  local opener = inst.components.container.currentuser --inst.components.container.opener
  inst:ForceFacePoint(opener.Transform:GetWorldPosition())
end

inst.components.container.onopenfn = OnOpen

 

thanks for the help :)!

Link to comment
Share on other sites

I tried doing something like

local function OnOpen(inst, doer)
  local opener = doer
  inst:ForceFacePoint(doer.Transform:GetWorldPosition()) -- Crashed here
end

inst:ListenForEvent("onopen", OnOpen)

and got a crash

"attempt to index field 'Transform' (a nil value)"

 

this just so complicated compared to before :wilson_dead:

Link to comment
Share on other sites

20 minutes ago, penguin0616 said:

{doer = doer}

OnOpen is getting called with (inst, {doer = doer}), not (inst, doer).

This should work.

local function OnOpen(inst, data)
     inst:ForceFacePoint(data.doer.Transform:GetWorldPosition()) -- Crashed here
end

inst:ListenForEvent("onopen", OnOpen)

 

  • Thanks 1
Link to comment
Share on other sites

18 minutes ago, penguin0616 said:

This should work.

Thanks a lot! It seems to work just fine now, I wouldn't be able to figure out without you, haha :D!

 

Cause you smarter than me if you don't mind if I ask a few questions is there any point to use

inst.components.container.onopenfn = OnOpen

over

inst:ListenForEvent("onopen", OnOpen)

anymore? Cause it seems now onopenfn is just a less useful version of this event?

 

Also, would you know if there's any way anymore to get who's opening a container or it's not possible anymore without using onopen event and its data?

 

Cause I tried something like this with a periodictask of 1 second and it never worked even while I opened my container as Wilson.

local opener = inst.components.container.currentuser
    if opener and opener.prefab == "wilson" then
        opener.components.talker:Say("HELLO")
    end

 

Link to comment
Share on other sites

onopenfn does pretty much the same thing the event does, but the event is more reliable since it's less likely to get overriden.

4 minutes ago, --- -.- said:

Also, would you know if there's any way anymore to get who's opening a container or it's not possible anymore without using onopen event and its data?

I don't really understand what you are asking here. The event tells you who's opening a container, and if you need to know at any point who has a container open, you can use Container:GetOpeners().

Example:

local inst = ...
inst:DoPeriodicTask(1, function()
	for i,v in pairs(inst.components.container:GetOpeners()) do
		print("this container is opened by:", v)
	end
end)

 

Edited by penguin0616
provided an example
  • Thanks 1
Link to comment
Share on other sites

Do you know how you would use "Container:GetOpeners()"?

I'm looking at it and it seems very complicated I don't understand how I would use it to like check if a player with a certain tag or prefab has the container opened

 

Would it be used like this?

 local opener = inst.components.container:GetOpeners()
if opener and (opener.prefab == "wilson" or opener:HasTag("merm")) then
        opener.components.talker:Say("HELLO")
    end

 

Edit: I posted before there was an example lol, thanks a lot hopefully I can use that then :D!

Edited by --- -.-
  • Like 1
Link to comment
Share on other sites

Container:GetOpeners() returns an array of all the people who currently have the container open.

Something like this might be what you are trying to do.

-- assuming you have an inst variable already present
inst:DoPeriodicTask(1, function()
	for i,v in pairs(inst.components.container:GetOpeners()) do
		if v.prefab == "wilson" or v:HasTag("merm") then
			v.components.talker:Say("Hello!")
		end
	end
end)

 

Edited by penguin0616
  • Thanks 1
Link to comment
Share on other sites

Hey! I'm sorry again, but I can't take all the crashes and failed attempts anymore so I'm bothering you again sorry :wilson_ecstatic:!

 

So I realized my thing has another problem and I can't figure out how to make this work...

 

I have this code for the thing you already helped me with (it's basically like a shop container) when you give items to it supposed to give you gold back like it bought the item

local function BuyItem(inst, data)
	if data ~= nil and data.item ~= nil and data.item.buyable == nil then
		local stacksize = data.item.components.stackable ~= nil and data.item.components.stackable.stacksize
		local seller = data.prevowner --inst.components.container.opener
		
		inst:DoTaskInTime(0, function()
			if data.item.buyable == nil then -- Don't buy your own wares

				if data.item.buyable_price then
					if seller then
						local gold = SpawnPrefab("goldnugget")
						if stacksize then gold.components.stackable:SetStackSize((stacksize * data.item.buyable_price)) end
						seller.components.inventory:GiveItem(gold, nil, inst:GetPosition())
					end
				end
				
			end
		end)
	end
end

inst:ListenForEvent("itemget", BuyItem)

 

before the update this code worked fine cause I could use "inst.components.container.opener" as the "seller" to give gold to them when they sold an item to the container, but now with the new update since that doesn't work anymore I'm completely clueless how I'm going to get this working again :lol:...

 

I looked into container.lua component and I saw it has some pushevents for "itemget" which is what this function uses, but the data for data.prevowner doesn't seem to work either so I'm guessing that isn't pushed for the container, but the player instead.

 

I tried thinking if I can use the code you showed me to use


	for i,v in pairs(inst.components.container:GetOpeners()) do
		if v then
			
		end
	end

but I don't know if it will work even if I can make it work because now that multiple players can have a container open there's a problem that how will I be able to check which player gave the item to the container then the container shop can give gold to that player and not give gold to some random player? The only idea I have is for it to throw the gold on the floor when an item is sold to it, but that's very bad because the gold can then be stolen by other players...

 

Sorry, to bother you so much with this I'd understand if you don't wanna help with this too, haha :wilson_dorky:

Edited by --- -.-
Link to comment
Share on other sites

21 minutes ago, penguin0616 said:

What error are you getting?

:224: attempt to index upvalue 'seller' (a nil value)

if I remove the check to see if there's a "seller", if I don't then nothing happens so it seems "data.prevowner" does nothing?

Link to comment
Share on other sites

So since this approach will not work as Zark stated, you could try something like this.

local function BuyItem(inst, data)
	if data ~= nil and data.item ~= nil and data.item.buyable == nil then
		local stacksize = data.item.components.stackable ~= nil and data.item.components.stackable.stacksize
		local seller = inst.components.container.currentuser
		
		inst:DoTaskInTime(0, function()
			if data.item.buyable == nil then -- Don't buy your own wares

				if data.item.buyable_price then
					if seller then
						local gold = SpawnPrefab("goldnugget")
						if stacksize then gold.components.stackable:SetStackSize((stacksize * data.item.buyable_price)) end
						seller.components.inventory:GiveItem(gold, nil, inst:GetPosition())
					end
				end
				
			end
		end)
	end
end

inst:ListenForEvent("itemget", BuyItem)

 

  • Thanks 1
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...