Scripting Problem: Sequence Lock (solved)

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
User avatar
Shroom
Posts: 98
Joined: Tue Mar 27, 2012 6:37 pm
Location: UK

Re: Scripting Problem: Sequence Lock

Post by Shroom »

Have tested both of these other methods now with mixed results.

Lilltiger - I cant get yours to work :/ After correcting the spelling in line

Code: Select all

if( order[static_Step]::getLeverState() == "deactivated" ) then
to

Code: Select all

if( order[static_step]:getLeverState() == "deactivated" ) then
I get an error attempt to call method 'getLeverState' (a nill value) - Any ideas?

Montis - yours works great - the only thing to remember if using it, is it counts backwards, so your first plate must have the highest number - also you can not use the same plate twice.

Good stuff for learning :D
User avatar
Montis
Posts: 340
Joined: Sun Apr 15, 2012 1:25 am
Location: Grimrock II 2nd playthrough (hard/oldschool)

Re: Scripting Problem: Sequence Lock

Post by Montis »

I just had an idea how to improve my script, will try to update it as soon as it works.
When destiny calls, the chosen have no choice.

My completed dungeon (LoG1): Hypercube
User avatar
Montis
Posts: 340
Joined: Sun Apr 15, 2012 1:25 am
Location: Grimrock II 2nd playthrough (hard/oldschool)

Re: Scripting Problem: Sequence Lock

Post by Montis »

Following, I present you my new and greatly improved code:

Instructions:
Create a counter next to the a lua script_entity and set it to the number of inputs you want the player to make. The activation entities (e.g. buttons or levers) need to be named in the same pattern e.g. sequenceLock_1 to sequenceLock_4.
Name the counter you just placed myCustomSequenceCounter (or anything you wish, but alter that then in the code below). On activation of myCustomSequenceCounter, tell the door to open. Also add an additional connector to the counter itself so it resets after reaching zero.

Then connect each activation entity to the following lua script entity action on the "activate" event:
SpoilerShow

Code: Select all

function sequenceRiddle()
   -- change the following to what entity type you want to use for your riddle
   local triggerEntity = "lever"
   -- all entity IDs of your activation entities should start with the below, followed by a number
   local namingPattern = "sequenceLock_"
   -- define the sequence in which you want your entities to be activated
   local sequenceOfThings = {"1","2","4","2","3"}
   -- define the ID of your sequenceCounter
   -- important: this sequence counter needs to have the same initial value
   -- as the number of sequences you defined above
   local sequenceCounterID = "myCustomSequenceCounter"
   -- from here on, it shouldn't be needed to alter the rest of the code

   local curSeq = #sequenceOfThings+1-sequenceCounter:getValue()
   for i in entitiesAt(party.level, party.x, party.y) do
      if i.name == triggerEntity then
         if i.id == namingPattern..sequenceOfThings[curSeq] then
            findEntity(sequenceCounterID):decrement()
         else
            findEntity(sequenceCounterID):reset()
         end
      end
   end
end
The downside remains, that there mustn't be multiple activation entities in one square (like one on each side of the square) or else the lock will not work.
Last edited by Montis on Tue Sep 18, 2012 6:57 pm, edited 2 times in total.
When destiny calls, the chosen have no choice.

My completed dungeon (LoG1): Hypercube
User avatar
petri
Posts: 1917
Joined: Thu Mar 01, 2012 4:58 pm
Location: Finland

Re: Scripting Problem: Sequence Lock

Post by petri »

Note that table.getn() is a deprecated Lua function. It is recommended to use the # operator to get the size of the table. E.g. #t returns the number of items in table t. The only caveat is that # works only for tables without holes (e.g. it assumes that the table is a list). See Lua reference manual or Programming in Lua for more details.
User avatar
Montis
Posts: 340
Joined: Sun Apr 15, 2012 1:25 am
Location: Grimrock II 2nd playthrough (hard/oldschool)

Re: Scripting Problem: Sequence Lock

Post by Montis »

petri wrote:Note that table.getn() is a deprecated Lua function. It is recommended to use the # operator to get the size of the table. E.g. #t returns the number of items in table t. The only caveat is that # works only for tables without holes (e.g. it assumes that the table is a list). See Lua reference manual or Programming in Lua for more details.
Thanks! I'm new to lua and googled how I would return the number of list entries, but only found the table.getn(). I felt like there would be something else and more simple, but couldn't find anything.
Anyway, I edited my posts accordingly. :)
When destiny calls, the chosen have no choice.

My completed dungeon (LoG1): Hypercube
Lilltiger
Posts: 95
Joined: Sun Sep 16, 2012 1:12 am

Re: Scripting Problem: Sequence Lock

Post by Lilltiger »

Shroom: ill fix it, probly some other typo i made, or LUA logic misstake, the issue with not testing the code ;)
User avatar
Green Cube
Posts: 6
Joined: Mon Sep 17, 2012 10:25 pm

Re: Scripting Problem: Sequence Lock

Post by Green Cube »

Thank you so much!

So I got Shroom's and Montis' script working. I was even able to modify Shroom's script making it close the door and being able to pull levers multiple times like so (for the sake of testing only three levers):

Code: Select all

function leverOne()

	if( p_special_counter:getValue() == 5 ) then
		p_special_counter:decrement()
		print(p_special_counter:getValue())
		
	elseif( p_special_counter:getValue() == 1 ) then
		p_special_counter:decrement()
		print(p_special_counter:getValue())
		
	else
		resetAll()
		
	end
	
end



function leverTwo()

	if( p_special_counter:getValue() == 3 ) then
		p_special_counter:decrement()
		print(p_special_counter:getValue())
		
	elseif( p_special_counter:getValue() == 2 ) then
		p_special_counter:decrement()
		print(p_special_counter:getValue())
		
	else
		resetAll()
		
	end
	
end



function leverThree()

	if( p_special_counter:getValue() == 4 ) then
		p_special_counter:decrement()
		print(p_special_counter:getValue())
		
	else
		resetAll()
		
	end
	
end



function resetAll()

	p_special_counter:reset()
	p_special_door:close()
	
end
Next step, modifying Montis' script and understanding Lillitiger's script, which is awesome to say way over my head. :D
Last edited by Green Cube on Tue Sep 18, 2012 5:44 pm, edited 1 time in total.
User avatar
Montis
Posts: 340
Joined: Sun Apr 15, 2012 1:25 am
Location: Grimrock II 2nd playthrough (hard/oldschool)

Re: Scripting Problem: Sequence Lock

Post by Montis »

With my new script you can actually make any sequence. E.g. pull lever 1,4,4,2,3,1,3,2,2,3,1 ...

if you want the door to close when "making a wrong move" you just need to add

Code: Select all

myDoorID:close()
right after

Code: Select all

findEntity(sequenceCounterID):reset()
When destiny calls, the chosen have no choice.

My completed dungeon (LoG1): Hypercube
User avatar
Green Cube
Posts: 6
Joined: Mon Sep 17, 2012 10:25 pm

Re: Scripting Problem: Sequence Lock

Post by Green Cube »

With my new script you can actually make any sequence. E.g. pull lever 1,4,4,2,3,1,3,2,2,3,1 ...
Don't worry, I love you all equally. :P

There is a problem with the script however. If you pull more than how many levers were determined by the counter the game crashes with a nil value error. I "fixed" it like this:

Code: Select all

function sequenceRiddle()

   local triggerEntity = "lever"
   local namingPattern = "lever_"
   local sequenceOfThings = {"1","2","3"}
   local sequenceCounterID = "myCustomSequenceCounter"

   local curSeq = #sequenceOfThings+1-myCustomSequenceCounter:getValue()

   for i in entitiesAt(party.level, party.x, party.y) do

      if i.name == triggerEntity then
		 if( myCustomSequenceCounter:getValue() == 0 ) then
		
			 	myCustomSequenceCounter:reset()
			 	sequence_door:close()
			
         elseif i.id == namingPattern..sequenceOfThings[curSeq] then
            findEntity(sequenceCounterID):decrement()

         end

      end

   end

end
Maybe it already worked though and I just screwed up.
Lilltiger
Posts: 95
Joined: Sun Sep 16, 2012 1:12 am

Re: Scripting Problem: Sequence Lock

Post by Lilltiger »

My code is now fixed, there where a few silly bugs:
  • The typo shroom pointed out
  • lever has no deactivation() function so changed to the prover function: lever:setLeverState("deactivated")
  • static_failed = false was not set when the step was reset
I also changed to use # for getting the size of a table, and added a timer function to deactivate the switches, only to make it look better.
Post Reply