Lever Puzzle Help

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
Post Reply
thebigkev
Posts: 2
Joined: Fri May 01, 2020 1:00 pm

Lever Puzzle Help

Post by thebigkev » Sat May 02, 2020 11:02 am

Hi There,

I am really new to programming and modding in general and am using my first LoG2 map as a way to learn a bit about both. I am currently working on a sequence puzzle using scripts and levers, I've managed to figure out how to make it so the lever stays down and not clickable if it's pulled in the correct order but where I am stumped is trying to get the animations right for when you pull an incorrect lever. My goal is to have it spring back up but because the if statement is instantly resolved it doesn't even move the lever when you pull it.

I then tried using a delayed call which actually breaks the puzzle entirely (but does the animation correctly (Y)) as part of some nested IF statements. The only way I can get this to work is by using the delayed call as the first trigger, which then checks the if statement 0.45 seconds after the lever is activated. While this will work (pending extensive testing), it means that if you pull the levers quickly it can give you repeat messages which is not optimal.

I was wondering if I am missing something very obvious? No doubt there are better ways to script this puzzle and I'd love to hear them if you have them.

Here is my code:

Script 1 - all 4 levers use onActivate to trigger

Code: Select all

function checknews()
	
	delayedCall("lever_toggle",0.45,"newssequence")

end
Script 2 - checking sequence and printing messages

Code: Select all

function newssequence()
	if (news_lever_n.lever:isActivated() and news_lever_e.lever:isDeactivated() and news_lever_s.lever:isDeactivated() and news_lever_w.lever:isDeactivated()) then
		news_lever_n.clickable:disable()
		hudPrint("north switch active")
	elseif (news_lever_n.lever:isActivated() and news_lever_e.lever:isActivated() and news_lever_s.lever:isDeactivated() and news_lever_w.lever:isDeactivated()) then
		news_lever_e.clickable:disable()
		hudPrint("East switch active")
	elseif (news_lever_n.lever:isActivated() and news_lever_e.lever:isActivated() and news_lever_s.lever:isDeactivated() and news_lever_w.lever:isActivated()) then
		news_lever_w.clickable:disable()
		hudPrint("West switch active")
	elseif (news_lever_n.lever:isActivated() and news_lever_e.lever:isActivated() and news_lever_s.lever:isActivated() and news_lever_w.lever:isActivated()) then
		news_lever_s.clickable:disable()
		hudPrint("South switch active - puzzle complete")
	else
		news_lever_w.lever:setState("deactivated")		
		news_lever_w.clickable:enable()
		news_lever_n.lever:setState("deactivated")
		news_lever_n.clickable:enable()
		news_lever_e.lever:setState("deactivated")
		news_lever_e.clickable:enable()
		news_lever_s.lever:setState("deactivated")
		news_lever_s.clickable:enable()
		hudPrint("levers reset")
	end
end
Cheers,
thebigkev.

Zo Kath Ra
Posts: 827
Joined: Sat Apr 21, 2012 9:57 am
Location: Germany

Re: Lever Puzzle Help

Post by Zo Kath Ra » Sat May 02, 2020 1:50 pm

You could do it by reversing the function calls.

- Connect the levers to newssequence() instead of checknews()

- Change the beginning of the function to:

Code: Select all

function newssequence(caller)
- Always make the lever unclickable after activating it, even if it's the wrong lever:

Code: Select all

caller.go.clickable:disable()
- Put the code from the else-branch into a new function:

Code: Select all

function resetLevers()
	news_lever_w.lever:setState("deactivated")		
	news_lever_w.clickable:enable()
	news_lever_n.lever:setState("deactivated")
	news_lever_n.clickable:enable()
	news_lever_e.lever:setState("deactivated")
	news_lever_e.clickable:enable()
	news_lever_s.lever:setState("deactivated")
	news_lever_s.clickable:enable()
	hudPrint("levers reset")
end
- Make the else-branch delayed-call the new function:

Code: Select all

delayedCall(self.go.id, 0.45, "resetLevers")

thebigkev
Posts: 2
Joined: Fri May 01, 2020 1:00 pm

Re: Lever Puzzle Help

Post by thebigkev » Sat May 02, 2020 3:00 pm

Zo Kath Ra wrote:
Sat May 02, 2020 1:50 pm
You could do it by reversing the function calls.

- Connect the levers to newssequence() instead of checknews()

- Change the beginning of the function to:

Code: Select all

function newssequence(caller)
- Always make the lever unclickable after activating it, even if it's the wrong lever:

Code: Select all

caller.go.clickable:disable()
- Put the code from the else-branch into a new function:

Code: Select all

function resetLevers()
	news_lever_w.lever:setState("deactivated")		
	news_lever_w.clickable:enable()
	news_lever_n.lever:setState("deactivated")
	news_lever_n.clickable:enable()
	news_lever_e.lever:setState("deactivated")
	news_lever_e.clickable:enable()
	news_lever_s.lever:setState("deactivated")
	news_lever_s.clickable:enable()
	hudPrint("levers reset")
end
- Make the else-branch delayed-call the new function:

Code: Select all

delayedCall(self.go.id, 0.45, "resetLevers")
Amazing, thank you so much!

Post Reply