[Script/puzzle]Random lever movement that has to be repeated
Posted: Sun Nov 02, 2014 12:20 am
Hi - so I've created a lever-based riddle lately which I wanted to share. If you make any interesting changes to the script, please post them here 
I. PIC
II. Entity list
III. Script description - lever placement and function description
IV. Connections and other editor stuff
V. Ideas
VI. Whole contents of script entity (for TL;DR and copy-paste)
I. PIC - Here's what it looks like. At the beginning all levers are blocked, button is accessible (to present new random sequence):
II. Here's what you need and what names you should give to entities to just copy-paste script:
III. Everything is in written in the lr_script:
1. Button placement (to fit them on the same wall along with wall text) and global flag for information if the riddle is already set. Tricky part is that you have to figure out the numbers yourself. For reference: I had my levers placed X:8, Y:22, Z:0:
2. Functions:
2.1 createRiddle() - responsible for chosing random lever (six times) and saving the combination in the array. Every time a lever is chosen it's toggled via the timer so the sequence actually plays.
2.2 resetRiddle() - reset globals and enable all the levers for player to toggle after the button is pressed
2.3 checkRiddle(sender)
2.4 disableLevers() - well, nothing fancy, just disable the levers after the player fails until new sequence is chosen
2.5 riddleEnd(status) - just a finishing function to finally block the levers and button either if: player completes the riddle OR players fails to complete the riddle for 3 times
IV. Connections (hooks):
V. Ideas - things I thought about but didn't put them actually in
VI. Whole contents of script_entity lr_script:
That would be it, if you think something could be done more efficiently - please say it.
Blichew
I. PIC
II. Entity list
III. Script description - lever placement and function description
IV. Connections and other editor stuff
V. Ideas
VI. Whole contents of script entity (for TL;DR and copy-paste)
I. PIC - Here's what it looks like. At the beginning all levers are blocked, button is accessible (to present new random sequence):
SpoilerShow

SpoilerShow
1. 6x lever and 1x wall_button placed exactly on one wall, facing East. IDs: lr_1 lr_2 lr_3 lr_4 lr_5 lr_6 lr_button
2. 1x dungeon_wall_text placed on the tile next to it. ID: lr_wt. Text -
3. 1x counter. ID: lr_counter
4. 1x script_entity. ID: lr_script
5. 1x timer. ID: lr_timer - Interval set on 0.5. DISABLED at start.
6. Treasure (not included in script:) )
2. 1x dungeon_wall_text placed on the tile next to it. ID: lr_wt. Text -
Code: Select all
Press the button above
to start playing the sequence
4. 1x script_entity. ID: lr_script
5. 1x timer. ID: lr_timer - Interval set on 0.5. DISABLED at start.
6. Treasure (not included in script:) )
1. Button placement (to fit them on the same wall along with wall text) and global flag for information if the riddle is already set. Tricky part is that you have to figure out the numbers yourself. For reference: I had my levers placed X:8, Y:22, Z:0:
SpoilerShow
Code: Select all
lr_1:setWorldPosition(26.9999,-0.49,29.5,0)
lr_2:setWorldPosition(26.9999,-0.49,29.1,0)
lr_3:setWorldPosition(26.9999,-0.49,28.7,0)
lr_4:setWorldPosition(26.9999,-0.49,28.3,0)
lr_5:setWorldPosition(26.9999,-0.49,27.9,0)
lr_6:setWorldPosition(26.9999,-0.49,27.5,0)
lr_button:setWorldPositionY(0.6)
riddleSet = 0
2.1 createRiddle() - responsible for chosing random lever (six times) and saving the combination in the array. Every time a lever is chosen it's toggled via the timer so the sequence actually plays.
SpoilerShow
Code: Select all
function createRiddle()
lr_button.clickable:disable()
if riddle_index < 7 then
riddle[riddle_index] = math.random(6)
local lever = findEntity("lr_"..riddle[riddle_index])
lever.lever:toggle()
else
if riddle_index > 9 then
for i=1,6 do
local l = findEntity("lr_"..i)
if l.lever:isActivated() then
l.lever:toggle()
end
end
hudPrint("Please enter correct combination to proceed. "..lr_trials.counter:getValue().." attempt(s) left")
lr_wt.walltext:setWallText(lr_trials.counter:getValue().." attempt(s) left")
--print("COMB: "..riddle[1]..", "..riddle[2]..", "..riddle[3]..", "..riddle[4]..", "..riddle[5]..", "..riddle[6]..".")
lr_timer.timer:stop()
lr_button.clickable:disable()
riddleSet = 1
end
end
riddle_index = riddle_index + 1
endSpoilerShow
Code: Select all
function resetRiddle()
riddle = {}
riddle_index = 1
check_index = 1
riddleSet = 0
for i=1,6 do
local l = findEntity("lr_"..i)
l.clickable:enable()
end
endSpoilerShow
Code: Select all
function checkRiddle(sender)
if riddleSet == 1 and check_index < 7 then
local seq_lever = findEntity("lr_"..riddle[check_index])
-- DEBUG print("SEQ["..check_index.."]: "..seq_lever.id.." , PRESSED: "..sender.go.id)
if seq_lever.id == sender.go.id then
if check_index == 6 then
riddleEnd(1)
else
hudPrint(check_index.." out of 6 levers moved in correct order. Keep going")
check_index = check_index + 1
end
else
lr_trials.counter:decrement()
lr_button.clickable:enable()
riddleSet = 0
disableLevers()
if lr_trials.counter:getValue() == 0 then
riddleEnd(0)
else
if riddleSet == 1 then
hudPrint("Wrong. Try again with new combination.")
end
end
end
else
end
endSpoilerShow
Code: Select all
function disableLevers()
for i=1,6 do
local l = findEntity("lr_"..i)
l.clickable:disable()
if l.lever:isActivated() then
l.lever:toggle()
end
end
endSpoilerShow
Code: Select all
function riddleEnd(status)
if status == 1 then
lr_button.clickable:disable()
disableLevers()
hudPrint("Combination entered succesfully. Congratulations.")
lr_wt.walltext:setWallText("Combination entered succesfully.")
riddleSet = 0
-- PUT YOUR REWARD HERE
else
lr_button.clickable:disable()
hudPrint("That was your last attempt. Sorry.")
lr_wt.walltext:setWallText(lr_trials.counter:getValue().." attempt(s) left")
end
endSpoilerShow
1. lr_1 lr_2 lr_3 lr_4 lr_5 lr_6 :onToggle - lr_script:checkRiddle()
2. lr_button:onActivate - lr_script:resetRiddle()
3. lr_button:onActivate - lr_timer:start
4. lr_timer:onActivate - lr_script:createRiddle()
2. lr_button:onActivate - lr_script:resetRiddle()
3. lr_button:onActivate - lr_timer:start
4. lr_timer:onActivate - lr_script:createRiddle()
SpoilerShow
1. Adding bossfight entity to show progress if the correct lever is moved by the player
2. Number of lever movements and max attempts are fixed - 6 and 3. They could be dependant on counters for easier configuration.
3. After unsuccessfull attempt player is punished just by subst. 1 attempt from the total 3. Spawner with fireball could be added in example
2. Number of lever movements and max attempts are fixed - 6 and 3. They could be dependant on counters for easier configuration.
3. After unsuccessfull attempt player is punished just by subst. 1 attempt from the total 3. Spawner with fireball could be added in example
SpoilerShow
Code: Select all
lr_1:setWorldPosition(26.9999,-0.49,29.5,0)
lr_2:setWorldPosition(26.9999,-0.49,29.1,0)
lr_3:setWorldPosition(26.9999,-0.49,28.7,0)
lr_4:setWorldPosition(26.9999,-0.49,28.3,0)
lr_5:setWorldPosition(26.9999,-0.49,27.9,0)
lr_6:setWorldPosition(26.9999,-0.49,27.5,0)
lr_button:setWorldPositionY(0.6)
riddleSet = 0
function createRiddle()
lr_button.clickable:disable()
if riddle_index < 7 then
riddle[riddle_index] = math.random(6)
local lever = findEntity("lr_"..riddle[riddle_index])
lever.lever:toggle()
else
if riddle_index > 9 then
for i=1,6 do
local l = findEntity("lr_"..i)
if l.lever:isActivated() then
l.lever:toggle()
end
end
hudPrint("Please enter correct combination to proceed. "..lr_trials.counter:getValue().." attempt(s) left")
lr_wt.walltext:setWallText(lr_trials.counter:getValue().." attempt(s) left")
--print("COMB: "..riddle[1]..", "..riddle[2]..", "..riddle[3]..", "..riddle[4]..", "..riddle[5]..", "..riddle[6]..".")
lr_timer.timer:stop()
lr_button.clickable:disable()
riddleSet = 1
end
end
riddle_index = riddle_index + 1
end
function resetRiddle()
riddle = {}
riddle_index = 1
check_index = 1
riddleSet = 0
for i=1,6 do
local l = findEntity("lr_"..i)
l.clickable:enable()
end
end
function checkRiddle(sender)
if riddleSet == 1 and check_index < 7 then
local seq_lever = findEntity("lr_"..riddle[check_index])
print("SEQ["..check_index.."]: "..seq_lever.id.." , PRESSED: "..sender.go.id)
if seq_lever.id == sender.go.id then
if check_index == 6 then
riddleEnd(1)
else
hudPrint(check_index.." out of 6 levers moved in correct order. Keep going")
check_index = check_index + 1
end
else
lr_trials.counter:decrement()
lr_button.clickable:enable()
riddleSet = 0
disableLevers()
if lr_trials.counter:getValue() == 0 then
riddleEnd(0)
else
if riddleSet == 1 then
hudPrint("Wrong. Try again with new combination.")
end
end
end
else
end
end
function disableLevers()
for i=1,6 do
local l = findEntity("lr_"..i)
l.clickable:disable()
if l.lever:isActivated() then
l.lever:toggle()
end
end
end
function riddleEnd(status)
if status == 1 then
lr_button.clickable:disable()
disableLevers()
hudPrint("Combination entered succesfully. Congratulations.")
lr_wt.walltext:setWallText("Combination entered succesfully.")
riddleSet = 0
-- PUT YOUR REWARD HERE
else
lr_button.clickable:disable()
hudPrint("That was your last attempt. Sorry.")
lr_wt.walltext:setWallText(lr_trials.counter:getValue().." attempt(s) left")
end
end
Blichew