Page 1 of 1

Open door scripting question.

Posted: Sun Jan 06, 2013 10:15 pm
by Dochoppy
I am trying to tie opening a secret door to a specific item ID. But the script returns a nill value.

Basically if you put the EverlastingLight (An everburning torch) Into the everlastingholder I want it to open a secretdoor. If you remove the torch I want the door to close. Also, I do not want any other torch to activate the door, but to work in the holder as normal. I keep getting a error "Attempt to call method hasEverlastingLight (a Nil value)"

Code: Select all

--SecretDoorTorchScript

function opensecretdoor()
	if everlastingholder:hasEverlastingLight() == true 
	then
		secretlightdoor:open()
	else
		secretlightdoor:close()
	end
end

Re: Open door scripting question.

Posted: Sun Jan 06, 2013 10:22 pm
by Ixnatifual
Torch holders haven't a method/function called "hasEverlastingLight()." That's why you get the error. You can see which functions are available on a torch holder in the scripting reference.

As far as I can tell, there doesn't seem to be a way to accomplish what you want with the torch holder. You can ask if it has a torch, but not on the specific kind of torch.

Re: Open door scripting question.

Posted: Sun Jan 06, 2013 10:39 pm
by Dochoppy
I see what you mean. There must be a way to assign a variable to that command. Sort of like making a custom key....or away to check the item name before it runs the open script....

Re: Open door scripting question.

Posted: Sun Jan 06, 2013 10:43 pm
by Ixnatifual
Maybe some of the scripting gurus here (there are a few!) will come up with something if you wait a while. :)
A shame there's no function to return the item in the holder like there is with alcoves.

Re: Open door scripting question.

Posted: Sun Jan 06, 2013 10:50 pm
by Dochoppy
Yes as it would make at least some story telling elements useful.

Re: Open door scripting question.

Posted: Mon Jan 07, 2013 3:33 am
by Komag
There might be some way to fake it, but I can't think of how to do it, sorry

Re: Open door scripting question.

Posted: Mon Jan 07, 2013 4:04 am
by dasarby
I have one that kinda works. There is no way to get the torches that are in the holder directly, but we can get all torches at the location that contains the holder, including torches in the holder. A first approach would be something like:

When a torch is added, run a function that checks for at an everburning torch at the the location with the holder, just like checking an alcove. If we find one, open the door.

This has a big problem, though. There is no way to determine if the torch is in the holder or if it is just sitting on the ground and a normal torch was put in the holder.

We can fix this by getting a bit more complicated:
  • Find all everburning torches at the location of the holder
  • Destroy each torch, one at a time
  • Check if the torch holder is no longer activated
  • If the holder is empty, then the destroyed torch was in the holder, open the door
  • if the holder is still filled, then the destroyed torch was on the ground, move on to the next torch
  • Respawn the torch in the holder or on the ground as appropriate
I see a couple downsides to this. Firstly, it creates new torches, essentially wasting an Id. Secondly, I can't figure out a way to get the subtile offset for the torch when it is on the ground; so respawning on the ground causes the torch to appear to "jump"

Wire the following to a torch's activate event and change the torchDoor:open() to be your door:

Code: Select all

-- Lock to prevent adding/removing torches from causing a infinite loop.
locked = false

function CheckTorch(holder)
	-- Prevent an infinite loop
	if locked then
		return
	end

	-- Make a list of all torches at the holder's location.  We can't loop
	-- over the items directly because we are going to change the entities
	-- at the current cell
	local eTorches = {}
	for item in entitiesAt(holder.level, holder.x, holder.y) do
		if item.name == "torch_everburning" then
			table.insert(eTorches, item)
		end
	end

	locked = true
	-- Loop over the everburning torches at the location.
	for i, torch in ipairs(eTorches) do
		local torchFacing = torch.facing

		-- Destroy the torch. If the torch was in the holder, the holder
		-- should now be empty.
		torch:destroy()	
		if not holder:hasTorch() then
			-- holder is empty, the torch was in the holder.  We can
			-- then open the door, recreate the torch, and break out
			-- of the loop.
			torchDoor:open()
			holder:addItem(spawn("torch_everburning"))
			break
		else
			-- if the holder still has the torch, then the everburning torch
			-- was not in the holder.  we then create a new torch on the ground
			-- to replace the one we destroyed
			spawn("torch_everburning", holder.level, holder.x, holder.y, torchFacing)
		end
	end
	locked = false
end
Note that nothing fancy is needed for deactivation, just wire torch holder to close the door on deactivation.

Re: Open door scripting question.

Posted: Mon Jan 07, 2013 4:35 am
by Dochoppy
I wonder if I could clone both items and redefine them to have lock attributes?

Thanks for the replies though, I appreciate the responses!

I am using a test dungeon to try out ideas with in scripting, before I commence to the creation of my
adventure/dungeon.

Re: Open door scripting question.

Posted: Mon Jan 07, 2013 4:40 am
by Neikun
Idea: Use alcoves instead of locks and torch holders.
You get the activate/deactivate functionality of a container without the lose-item-on-use feature of a lock.
You will need to make an fx entity for the flame, though.