Page 2 of 3

Re: Lever Puzzle Scripting Help

Posted: Thu Jan 03, 2013 2:28 pm
by Grimwold
I think you're right... I was thinking you'd need to set the flags for the levers either side as well (which I had in the script before I edited it just now).

Re: Lever Puzzle Scripting Help

Posted: Thu Jan 03, 2013 2:57 pm
by Grimwold
Here's a single function that should work just by linking each lever to it.

Code: Select all

function leverToggle(trigger)
  local plate_entity = findEntity("plate_" .. string.sub(trigger.id,-1))
  local numer = tonumber(string.sub(trigger.id,-1))
  local numup = numer + 1
  local numdn = numer - 1
  if plate_entity ~=nil and plate_entity:isDown() then
    if numup < 6 then
      local lever_entity = findEntity("lever_" .. tostring(numup))
      if lever_entity ~= nil then
        lever_entity:toggle()
      end
    end
    if numdn > 0 then
      local lever_entity = findEntity("lever_" .. tostring(numdn))
      if lever_entity ~= nil then
        lever_entity:toggle()
      end
    end
  end
  if lever_1:getLeverState() == "activated" and lever_2:getLeverState() == "activated"  and lever_3:getLeverState() == "activated"  and lever_4:getLeverState() == "activated"  and lever_5:getLeverState() == "activated" then
    door_1:open()
  else
    door_1:close()
  end
end
each hidden plate should be:
plate_1 to plate_5

each lever should be:
lever_1 to lever_5

you could use different IDs, but certain parts of the script would need modifying to reflect the different naming convention. And in particular, if you need to use double digits for plates and levers, you'd need to change the -1 in the string.sub() functions to -2

Note I added in a basic check for if all the levers are in the right position... which will open door_1


edit - ok I tested it with plate_10 to plate_14 and lever_10 to lever_14 with the above modifications (since I already had levers 1 to 9 in my test dungeon) and it worked well... though there is an easy solution from the get go (when you know what to expect).

Re: Lever Puzzle Scripting Help

Posted: Fri Jan 04, 2013 1:29 am
by Babby Tutel
These replies have been amazingly helpful. After a long day, this is a sight for sore eyes.

I'll be testing Grimwold's script momentarily, thank you both for going to the work of actually assembling it.

Re: Lever Puzzle Scripting Help

Posted: Fri Jan 04, 2013 1:47 am
by Babby Tutel
It works beautifully. I would never expect this to require such a lengthy script; the more you know, right?

I want to once again say thank you. If there's anything I could give in return, just ask.

Re: Lever Puzzle Scripting Help

Posted: Fri Jan 04, 2013 2:27 am
by Grimwold
Cool. Glad it worked out. :D

Re: Lever Puzzle Scripting Help

Posted: Fri Jan 04, 2013 2:29 am
by dasarby
If you use a single lock item, then you don't need the plates.

The idea is to set the lock when a lever is pulled, then toggle the adjacent switches, then turn the lock back off. Other toggle functions only run if the lock is not set.

Additionally, moving the check function as a call in the lever pull function will prevent redundant state checks.

Here is an adaptation using locks, with a function for each lever:

Code: Select all

locked = false

function Lever1Pull()
	if not locked then
	 	locked = true
	 	lever2:toggle()
	 	locked = false
	 	CheckLeverStates()
	end 
end

function Lever2Pull()
	if not locked then
	 	locked = true
	 	lever1:toggle()
	 	lever3:toggle()
		locked = false
		CheckLeverStates()
	end
end

function Lever3Pull()
	if not locked then
	 	locked = true
	 	lever2:toggle()
	 	lever4:toggle()
		locked = false
		CheckLeverStates()
	end
end

function Lever4Pull()
	if not locked then
	 	locked = true
	 	lever3:toggle()
	 	lever5:toggle()
		locked = false
		CheckLeverStates()
	end
end


function Lever5Pull()
	if not locked then
	 	locked = true
	 	lever4:toggle()
	 	locked = false
	 	CheckLeverStates()
	end 
end

function CheckLeverStates()
 if lever1:getLeverState() == "activated" and lever2:getLeverState() == "activated" and lever3:getLeverState() == "activated" and lever4:getLeverState() == "activated" and lever5:getLeverState() == "activated" then
 	eg_door:open()
 end
end

Re: Lever Puzzle Scripting Help

Posted: Fri Jan 04, 2013 2:33 am
by Babby Tutel
Thanks for the other script, dasarby but the hidden plate script functions fine, so I have no need to change it. I will, however, save yours-- it'll be helpful in the future when I don't need to beg for scripting help. :)

Re: Lever Puzzle Scripting Help

Posted: Fri Jan 04, 2013 2:35 am
by Komag
have you tested that? sometimes the order of things is tricky

Re: Lever Puzzle Scripting Help

Posted: Fri Jan 04, 2013 3:17 am
by dasarby
Yes, I tested it, seems to be working right. There would probably be a race condition if the player moves to a new switch and flips it before the lock is unlocked; but the toggles are damn near instantaneous.

This seems like a common enough puzzle I'd thought it would be useful to make it a bit more generic. This is in the flavor of Grimwold's, where each lever should trigger the same funcion, LeverPull. When all levers are down (activated), the Solved function is called, if any lever is not down, UnSolved is called. Just set them to whatever actions you need (i.e. open/close doors)

Which levers activate which other levers is mapped in the "levers" table. Set each lever's id to a list of the other levers that should be toggled. The following example is the simple case of "toggle levers next to the one that is pulled":

Code: Select all

locked = false

levers = {
	lever1={"lever2"},
	lever2={"lever1", "lever3"},
	lever3={"lever2", "lever4"},
	lever4={"lever3", "lever5"},
	lever5={"lever4"}
}

function Solved()
	eg_door:open()
end

function UnSolved()
	eg_door:close()
end

function PullLever(trigger)
	if not locked then
		locked = true
		if levers[trigger.id] then
			for _, id in ipairs(levers[trigger.id]) do
				findEntity(id):toggle()
			end
		end
		locked = false

		local solved = true
		for id, _ in pairs(levers) do
			solved = solved and findEntity(id):getLeverState() == "activated"
		end
		if solved then
			Solved()
		else
			UnSolved()
		end
	end
end
This should be pretty easy to extend to any number of levers, with arbitrary connection (ie in a circle, or toggle to two adjacent, etc)

I tested this one too, and it seems to be pretty good. Feedback appreciated.

Re: Lever Puzzle Scripting Help

Posted: Fri Jan 04, 2013 3:56 am
by Komag
looks good, would be a good addition to the script repository :)