This version utilises any number of levers and a single combination of up/down states. It requires either a pressure_plate or button to check the sequence and open a door.
This script can be used any number of times in a dungeon by pasting it into different script entities, (provided the counter variable in each version is changed to a unique value). You can even use some or all of the same levers in each version to allow multiple solutions. There is an option to punish the party for an incorrect sequence by spawning a poison cloud in the same space as the checking button/plate. This is turned on/off with a simple variable.
You will need to place levers in your dungeon and a button/plate to check the combination, but you do not need to create any connectors as the script will do that automatically.
Code: Select all
counter_name = "lever_counter_1"
door_name = "lever_door_1"
checker_name = "lever_button_1"
punish = 1
function checkLevers()
local lever_check = {
levers = {"lever_1","lever_2","lever_3","lever_4"},
states = {"activated", "activated", "deactivated", "activated"}}
if initialisation == 1 then
for i=1,#lever_check["levers"] do
local lever_entity = findEntity(lever_check["levers"][i])
if lever_entity == nil then
print(lever_check["levers"][i] .. " is missing")
return false
end
end
local checker_entity = findEntity(checker_name)
if checker_entity == nil then
print(checker_name .. " is missing")
return false
else
checker_entity:addConnector("activate",self.id,"checkLevers")
checker_entity:addConnector("toggle",self.id,"checkLevers")
end
end
local range = math.min(#lever_check["levers"],#lever_check["states"])
local door_entity = findEntity(door_name)
local counter_entity = findEntity(counter_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)
counter_entity:reset()
for i = 1,range do
local lever_entity = findEntity(lever_check["levers"][i])
if lever_entity ~= nil and lever_entity:getLeverState() == lever_check["states"][i] then
counter_entity:decrement()
end
end
-- if we get to here and the counter is not 0 we close the door and maybe punish the party
if counter_entity:getValue() ~= 0 then
door_entity:close()
if initialisation == 0 and punish ~= 0 then
local checker_entity = findEntity(checker_name)
spawn("poison_cloud",checker_entity.level,checker_entity.x,checker_entity.y,checker_entity.facing)
end
end
if initialisation == 1 then
initialisation = 0
end
end
initialisation = 1
checkLevers()
counter_name = "lever_counter_1"
replace the text lever_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_door_1"
replace the text lever_door_1 with the ID of the door you want to open with this puzzle. You must place this door somewhere in your dungeon.
checker_name = "lever_button_1"
replace the text lever_button_1 with the ID of the plate/button you want to use to check the sequence. You must place this plate or button somewhere in your dungeon.
punish = 0
If punish is set to 0, then the party will NOT be punished for an incorrect sequence, to change this, replace the 0 with 1
levers = {"lever_1","lever_2","lever_3","lever_4"},
replace the entries in this list with the IDs of the levers that you placed in your dungeon. You can add as many entries here as you want.
states = {"activated", "activated", "deactivated", "activated"}}
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_1" needs to be in the "activated" (or down) state etc.