[Script] Generic Lever/Button Sequence Puzzle
Posted: Fri Dec 07, 2012 2:18 am
Another puzzle scripting framework to drop into your dungeon if you want this kind of puzzle. This one was requested by LordYig with a view to creating a combination lock.
The idea is that there are a series of levers (or buttons) that must be activated in a strict sequence to open the door. For buttons you simply have to push them in the right order (and there can be duplicates). For levers you have to flip them in the right order and there can be duplicates, provided you note the correct activate/deactivate status.
As with my other generic puzzle scripts, this can be used multiple times in the same dungeon, provided you change the counter variable to a unique name. You could even re-use the same levers/buttons and have multiple combinations, however if you do so I would recommend you disable the sound played when an incorrect entry is made, as this could be confusing for a multi-solution setup.
You will need to place a door and a number of levers (or buttons) in your dungeon. Then add a script entity and paste in the following code.
Finally you will need to customise the following entries in the first few lines of the script:
counter_name = "lever_combo_counter_1"
replace the text lever_combo_counter_1 with a unique name for a counter. You do not need to place the counter in the dungeon, but you need to make sure that this ID is not used for anything else in your dungeon (and does not duplicate the ID of a counter in a subsequent copy of this script)
door_name = "lever_combo_door_1"
replace the text lever_combo_door_1 with the ID of the door you want to open with this puzzle. You must place this door somewhere in your dungeon.
activators = "lever"
put either lever OR button for this value, depending on whether you wish to use levers or buttons for this copy of the puzzle.
failure_sound = "scramble_writer"
The sound to play when a button/lever is activated out of sequence. A little 'warning' to the player that the puzzle has reset. Replace the text scramble_writer with the name of the sound you want to use (either an existing sound from the game, or a new one defined in sounds.lua). If you want to completely disable sound, simply leave the quotes empty, like "".
local lever_check = {"lever_6","lever_8","lever_7","lever_9","lever_9"}
replace the entries in this list with the IDs of the levers (OR buttons) that you placed in your dungeon. You can add as many entries here as you want and may duplicate them.
local lever_state = {"activated","activated","activated","activated","deactivated"}
If you are using buttons then this table is ignored, you can leave it as is or set it to an empty table e.g. local lever_state = {}
However, if you are using levers, you must replace the entries in this list with the states you require for the levers. They should be in the same order as the entries in levers above. So here, "lever_6" needs to be "activated" first (moved to the down position). When using duplicate levers, be careful of states as a lever must alternate between it's activated and deactivated state.
The idea is that there are a series of levers (or buttons) that must be activated in a strict sequence to open the door. For buttons you simply have to push them in the right order (and there can be duplicates). For levers you have to flip them in the right order and there can be duplicates, provided you note the correct activate/deactivate status.
As with my other generic puzzle scripts, this can be used multiple times in the same dungeon, provided you change the counter variable to a unique name. You could even re-use the same levers/buttons and have multiple combinations, however if you do so I would recommend you disable the sound played when an incorrect entry is made, as this could be confusing for a multi-solution setup.
You will need to place a door and a number of levers (or buttons) in your dungeon. Then add a script entity and paste in the following code.
Code: Select all
counter_name = "lever_combo_counter_1"
activators = "lever" -- button OR lever
door_name = "lever_combo_door_1"
failure_sound = "scramble_writer"
function checkLever(trigger)
local lever_check = {"lever_6","lever_8","lever_7","lever_9","lever_9"}
local lever_state = {"activated","activated","activated","activated","deactivated"}
if initialisation == 1 then
local unique_lever_check = removeDuplicates(lever_check)
for i=1,#unique_lever_check do
local lever_entity = findEntity(unique_lever_check[i])
if lever_entity == nil then
print(unique_lever_check[i] .. " is missing")
break
else
if activators == "lever" then
lever_entity:addConnector("any",self.id,"checkLever")
elseif activators == "button" then
lever_entity:addConnector("toggle",self.id,"checkLever")
end
end
end
end
local range = 0
if activators == "lever" then
range = math.min(#lever_check,#lever_state)
elseif activators == "button" then
range = #lever_check
end
local counter_entity = findEntity(counter_name)
local door_entity = findEntity(door_name)
if counter_entity == nil then
spawn("counter",self.level,self.x,self.y,self.facing,counter_name)
:setInitialValue(range)
:setValue(range)
:addConnector("activate",door_entity.id,"open")
:addConnector("deactivate",door_entity.id,"close")
end
local counter_entity = findEntity(counter_name)
local lever_index = range + 1 - counter_entity:getValue()
if trigger ~= nil then
if activators == "lever" then
if trigger.id == lever_check[lever_index] and trigger:getLeverState() == lever_state[lever_index] then
counter_entity:decrement()
return true
else
counter_entity:reset()
-- print(counter_entity:getValue())
if failure_sound ~= nil and failure_sound ~= "" then
playSound(failure_sound)
end
for _,v in pairs(lever_check) do
j = findEntity(v)
if j:getLeverState() == "activated" then
j:toggle()
end
end
return false
end
elseif activators == "button" then
if trigger.id == lever_check[lever_index] then
counter_entity:decrement()
return true
else
counter_entity:reset()
if failure_sound ~= nil and failure_sound ~= "" then
playSound(failure_sound)
end
end
end
end
if initialisation == 1 then
initialisation = 0
end
end
function isInTable(table, element)
for _,value in pairs(table) do
if value == element then
return true
end
end
return false
end
function removeDuplicates(t)
local t2 = {}
local idx = 1
for k,v in pairs(t) do
if not isInTable(t2,v) then
t2[idx] = v
idx = idx+1
end
end
return t2
end
initialisation = 1
checkLever()
counter_name = "lever_combo_counter_1"
replace the text lever_combo_counter_1 with a unique name for a counter. You do not need to place the counter in the dungeon, but you need to make sure that this ID is not used for anything else in your dungeon (and does not duplicate the ID of a counter in a subsequent copy of this script)
door_name = "lever_combo_door_1"
replace the text lever_combo_door_1 with the ID of the door you want to open with this puzzle. You must place this door somewhere in your dungeon.
activators = "lever"
put either lever OR button for this value, depending on whether you wish to use levers or buttons for this copy of the puzzle.
failure_sound = "scramble_writer"
The sound to play when a button/lever is activated out of sequence. A little 'warning' to the player that the puzzle has reset. Replace the text scramble_writer with the name of the sound you want to use (either an existing sound from the game, or a new one defined in sounds.lua). If you want to completely disable sound, simply leave the quotes empty, like "".
local lever_check = {"lever_6","lever_8","lever_7","lever_9","lever_9"}
replace the entries in this list with the IDs of the levers (OR buttons) that you placed in your dungeon. You can add as many entries here as you want and may duplicate them.
local lever_state = {"activated","activated","activated","activated","deactivated"}
If you are using buttons then this table is ignored, you can leave it as is or set it to an empty table e.g. local lever_state = {}
However, if you are using levers, you must replace the entries in this list with the states you require for the levers. They should be in the same order as the entries in levers above. So here, "lever_6" needs to be "activated" first (moved to the down position). When using duplicate levers, be careful of states as a lever must alternate between it's activated and deactivated state.