• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Lua Write a sequence on lever press

henkas

Well-Known Member
Joined
Jul 8, 2015
Messages
1,050
Solutions
5
Reaction score
62
TFS 1.2. So i wrote this code based on Xikini lever system with few adjustements, now im trying to write a lever press sequences for example have to be pressed accordingly for it to remove the object for example
Position(230, 365, 7), have to be pressed first
Position(220, 372, 7), this second
Position(240, 368, 7) this third
Position(233, 366, 7), this is last so its like a tricky puzzle
If they faill the sequence, the levers go back to their default preset which is left 20992 saying you failled, so they could repeat it again
LUA:
local levers = {left = 20992, right = 20993}
local leverActionIds = {4650, 4651, 4652, 4653}
local leverPositions = {
    Position(220, 372, 7),
    Position(230, 365, 7),
    Position(233, 366, 7),
    Position(240, 368, 7)
}

local targetPosition = Position(222, 366, 7)
local targetItemId = 1100
local resetTime = 1 * 60 * 1000 -- 1 minutes in milliseconds. Restore deleted object

local function areAllLeversClicked()
    for _, position in ipairs(leverPositions) do
        local tile = Tile(position)
        if not tile then
            return false
        end
        local lever = tile:getItemById(levers.right)
        if not lever then
            return false
        end
    end
    return true
end

local function resetLeversAndObject()
    for _, position in ipairs(leverPositions) do
        local tile = Tile(position)
        if tile then
            local lever = tile:getItemById(levers.right)
            if lever then
                lever:transform(levers.left)
            end
        end
    end

    local tile = Tile(targetPosition)
    if tile then
        Game.createItem(targetItemId, 1, targetPosition)
    end
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    item:transform(item.itemid == levers.left and levers.right or levers.left)

    if areAllLeversClicked() then
        local tile = Tile(targetPosition)
        if tile then
            local object = tile:getItemById(targetItemId)
            if object then
                object:remove()
                player:sendTextMessage(MESSAGE_INFO_DESCR, "The object has been removed.")
            else
                player:sendTextMessage(MESSAGE_INFO_DESCR, "Theres nothing to remove at the target position.")
            end
        else
            player:sendTextMessage(MESSAGE_INFO_DESCR, "The target position does not exist.")
        end

        addEvent(resetLeversAndObject, resetTime)
    end

    return true
end
 
okay, first of all you need to declare which lever is first, second etc, easiest way its iterate from position table from first to the last one, and here you have 2 method's


use customAttribute to save which lever its first, second etc or just set them in table based which iterate has id

that will be something like that (for customAttribute feature)


(Both Metods shouldbe handled as StartUp event)

LUA:
for i, v in ipairs(leverPositions) do

  local tile = Tile(v)

  local item =  tile:getItemById(id that map editor creating this lever)

  if not item

    print("Error, that lever not exsists, make sure you set all correctly")

    return true

  end

  ---here we have lets say "I == 1) - its a first iterate, so position number one shouldbe the first lever)
  -- "RANDOM_QUEST_NAME_LEVER_INDEX" - this can be global variable defined at begining of the script, its just an example of the key to read   which lever shouldbe used first  its literaly like storage key,  but string can be used.

   item:setCustomAttribute("RANDOM_QUEST_NAME_LEVER_INDEX," i)

end



version two, that your server have no custom attributes, since its quest we can store everything in table



LUA:
for i, v in ipairs(leverPositions) do

  local tile = Tile(v)

  local item =  tile:getItemById(id that map editor creating this lever)

  if not item

    print("Error, that lever not exsists, make sure you set all correctly")

    return true

  end



  if not RANDOM_QUEST_NAME_LEVER_INDEXES then

     RANDOM_QUEST_NAME_LEVER_INDEXES {}

  end



     RANDOM_QUEST_NAME_LEVER_INDEXES[v] = i

 end

(you can dump this table, that will return something like Lever on x position = Index (our value which lever is first, second etc)
so based on this we can create Action that will try to read which lever is actualy clicked based on iterate that we do on startup, something like:

LUA:
local leverIndex = RANDOM_QUEST_NAME_LEVER_INDEXES[fromPosition]
-- that will return our index of lever, just from 1-4 lets say,


then you can easily, access which lever from which position its clicked, of course thats will require reading table or custom attribute, but yeah this way u can save the information about lever and use it as you need.


ps: yes i know its not full working solution, this post its not a target for ppl that using ctrl + ctrl v, you dont have to spam my private message what to do with this code (its for ppl that trying to do something alone, wanna learn etc)
 
Last edited:
Managed to achieve this which is quite fucked i would say even if you press in correct sequence it says wrong sequence. And instead it should have wait until all 4 levers clicked and than tell if its wrong sequence or correctt sequence if correct remove the object if its wrong send faill message, apply cooldown and reset levers to the left, but my code barely do any of these
LUA:
local levers = {left = 20992, right = 20993}
local leverActionIds = {4650, 4651, 4652, 4653}
local leverPositions = {
    Position(230, 365, 7), -- First lever
    Position(220, 372, 7), -- Second lever
    Position(240, 368, 7), -- Third lever
    Position(233, 366, 7)  -- Fourth lever
}

local targetPosition = Position(222, 366, 7)
local targetItemId = 1100
local resetTime = 5 * 60 * 1000 -- 5 minutes cooldown for second try if faill

local sequence = {}
local expectedSequence = {1, 2, 3, 4} -- Order of lever positions

local function areLeversInCorrectSequence()
    for i, leverIndex in ipairs(sequence) do
        if leverIndex ~= expectedSequence[i] then
            return false
        end
    end
    return true
end

local function resetLeversAndObject()
    sequence = {}

    for _, position in ipairs(leverPositions) do
        local tile = Tile(position)
        if tile then
            local lever = tile:getItemById(levers.right)
            if lever then
                lever:transform(levers.left)
            end
        end
    end

    local tile = Tile(targetPosition)
    if tile then
        Game.createItem(targetItemId, 1, targetPosition)
    end
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    item:transform(item.itemid == levers.left and levers.right or levers.left)

    local leverIndex
    for i, position in ipairs(leverPositions) do
        if toPosition == position then
            leverIndex = i
            break
        end
    end

    if not leverIndex then
        return true
    end

    table.insert(sequence, leverIndex)

    if not areLeversInCorrectSequence() then
        player:sendTextMessage(MESSAGE_INFO_DESCR, "Wrong sequence! The levers will reset.")
        addEvent(resetLeversAndObject, resetTime)
        return true
    end

    if #sequence == #expectedSequence then
        local tile = Tile(targetPosition)
        if tile then
            local object = tile:getItemById(targetItemId)
            if object then
                object:remove()
                player:sendTextMessage(MESSAGE_INFO_DESCR, "All levers are activated in the correct sequence! The object has been removed.")
            else
                player:sendTextMessage(MESSAGE_INFO_DESCR, "There's nothing to remove at the target position.")
            end
        else
            player:sendTextMessage(MESSAGE_INFO_DESCR, "The target position does not exist.")
        end

        addEvent(resetLeversAndObject, resetTime)
    end

    return true
end
 
Last edited:
Last edited:
Right now it adds +1 to some index whenever the right lever is pulled until you hit the right index number.

for _, position in ipairs(leverPositions) do
local tile = Tile(position)
if tile then
local lever = tile:getItemById(levers.right)
if lever then
lever:transform(levers.left)
end
end
end

I would rather check every time there if the levers are right now in the correct position and after the check if you pulled a wrong lever it resets(reset the lever or some value). So for example you are supposed to pull lever 1 so you check if all other levers are right. If not fail. After that you check all the 4 levers again if they are in the right position if not you save the fail.
 
Right now it adds +1 to some index whenever the right lever is pulled until you hit the right index number.

for _, position in ipairs(leverPositions) do
local tile = Tile(position)
if tile then
local lever = tile:getItemById(levers.right)
if lever then
lever:transform(levers.left)
end
end
end

I would rather check every time there if the levers are right now in the correct position and after the check if you pulled a wrong lever it resets(reset the lever or some value). So for example you are supposed to pull lever 1 so you check if all other levers are right. If not fail. After that you check all the 4 levers again if they are in the right position if not you save the fail.
Easier to tell, thats exactly what i was trying to achieve but failled
 
Back
Top