• 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 dungeon lever error

zabuzo

Well-Known Member
Joined
Jun 10, 2016
Messages
238
Reaction score
54
is anybody know how to fix this error
Code:
[23:47:32.173] [Error - Action Interface]
[23:47:32.173] data/actions/scripts/dungeon_lever.lua:onUse
[23:47:32.173] Description:
[23:47:32.173] attempt to index a number value
[23:47:32.173] stack traceback:
[23:47:32.173]     [C]: in function 'getSpectators'
[23:47:32.173]     data/actions/scripts/dungeon_lever.lua:53: in function <data/actions/scripts/dungeon_lever.lua:51>

from this dungeon lever script?
Code:
local kickTo = {x = 956, y = 1039, z = 7} -- kick players after 15 minutes to this position
local centerPos = {x = 1000, y = 1000, z = 7}
local xRange = 5
local yRange = 4

-- positions and where go
local p = {
    [1] = {
        player = {
            position = {x = 952, y = 1039, z = 7},
            toPos = {x = 953, y = 1047, z = 6}
        }
    },
    [2] = {
        player = {
            position = {x = 953, y = 1039, z = 7},
            toPos = {x = 954, y = 1047, z = 6}
        }
    },
    [3] = {
        player = {
            position = {x = 954, y = 1039, z = 7},
            toPos = {x = 955, y = 1047, z = 6}
        }
    },
    [4] = {
        player = {
            position = {x = 955, y = 1039, z = 7},
            toPos = {x = 956, y = 1047, z = 6}
        }
    }
}

-- min lvl
local minLevel = 10
local maxLevel = 20

-- 3 how to: after enter in the dungeon, have 15 min to open the chest, if dont teleport to 956/1039/7
local function kickPlayers(players)
    local spectators = getSpectators(centerPos, false, true, 0, xRange, 0, yRange)
    for _, spec in ipairs(spectators) do
        local specName = getPlayerName(spec)
        for _, player in ipairs(players) do
            if getPlayerName(player) == specName then
                doTeleportThing(spec, kickTo, false)
            end
        end
    end
end

function onUse(cid)
    -- 1 how to: if there is a team doing players cant go in
    local spectators = getSpectators(centerPos, false, true, 0, xRange, 0, yRange)
    for _, player in ipairs(spectators) do
        doPlayerSendCancel(cid, "There are still remaining players in the room.")
        return false
    end

    -- 2 how to: only accept different IPs
    local ipAddress = {}
    local questPlayers = {}
    local oldPlayers = {}
    local SORCERER, DRUID, PALADIN, KNIGHT = false, false, false, false

    for i = 1, #p do
        local pid = getTopCreature(p[i].player.position).uid  
        if isPlayer(pid) then
            local voc = getPlayerVocation(pid)
            if voc == 1 or voc == 5 or voc == 9 then
                SORCERER = true
            elseif voc == 2 or voc == 6 or voc == 10 then
                DRUID = true
            elseif voc == 3 or voc == 7 or voc == 11 then
                PALADIN = true
            elseif voc == 4 or voc == 8 or voc == 12 then
                KNIGHT = true
            end
           
            local newIp = getPlayerIp(pid)
            if getPlayerStorageValue(pid, 5824) >= os.time() then
                local exaustedMins = math.ceil(((getPlayerStorageValue(cid, 5824)) - os.time())/60)
                doPlayerSendCancel(cid, getPlayerName(pid) .. " have to wait " .. exaustedMins .. " minutes to do this dugeon again.")
                return false
            end

            for _, ip in ipairs(ipAddress) do
                if newIp == ip then
                    doPlayerSendCancel(cid, "Players with the same IP address detected.")
                    return false
                end
            end
            ipAddress[#ipAddress + 1] = newIp
           
            if not getPlayerLevel(pid) >= minLevel and not getPlayerLevel(pid) <= maxLevel then
                doPlayerSendCancel(cid, getCreatureName(pid) .. ", is not high enough in level, the level to enter have to be between " .. minLevel .. "~ " .. maxLevel .. ". ")
                return false
            end
            oldPlayers[#oldPlayers + 1] = pid
        else
            doPlayerSendCancel(cid, "A player is missing.")
            return false
        end
    end
   
    if SORCERER == false or DRUID == false or PALADIN == false or KNIGHT == false then
        doPlayerSendCancel(cid, "Four different vocations are required.")
        return false
    end
   
    for x = 1, #questPlayers do
        -- 4 how to: after go in have a exausted of 24 hours to go again
        setPlayerStorageValue(questPlayers[x], 5824, os.time() + 86400)
        doPlayerSendTextMessage(questPlayers[x], MESSAGE_INFO_DESCR, "Good luck!")
        doTeleportThing(questPlayers[x], p[x].player.toPos)
    end
   
    addEvent(kickPlayers, 900000, oldPlayers)
    return true
end

it's from sourcepack 0.4 Fir3element/3777 (https://github.com/Fir3element/3777/)
 
Last edited:
Solution
it's not teleporting the players
is it not teleporting them in or is it not teleporting them out, or both
edit: nevermind, it's not teleporting them in because it's using an empty table. you also didn't change the kickPlayers function to the one I posted earlier, so I've change that as well. try this:

Lua:
local kickTo = {x = 956, y = 1039, z = 7} -- kick players after 15 minutes to this position
local centerPos = {x = 1000, y = 1000, z = 7}
local xRange = 5
local yRange = 4

-- positions and where go
local p = {
    [1] = {
        player = {
            position = {x = 952, y = 1039, z = 7},
            toPos = {x = 953, y = 1047, z = 6}
        }
    },
    [2] = {
        player = {
            position = {x = 953, y = 1039...
Taka a look at the source code, at line 9595:
https://github.com/Fir3element/3777/blob/master/src/luascript.cpp#L9595
function getSpectators() takes less parameters than you have provided in script.
//getSpectators(centerPos, rangex, rangey[, multifloor = false])

So in line 53 of your script, instead of:
getSpectators(centerPos, false, true, 0, xRange, 0, yRange)
use:
getSpectators(centerPos, xRange, yRange)
 
Taka a look at the source code, at line 9595:
https://github.com/Fir3element/3777/blob/master/src/luascript.cpp#L9595
function getSpectators() takes less parameters than you have provided in script.
//getSpectators(centerPos, rangex, rangey[, multifloor = false])

So in line 53 of your script, instead of:
getSpectators(centerPos, false, true, 0, xRange, 0, yRange)
use:
getSpectators(centerPos, xRange, yRange)

why on this part dont have errors?
Code:
-- 3 how to: after enter in the dungeon, have 15 min to open the chest, if dont teleport to 956/1039/7
local function kickPlayers(players)
    local spectators = getSpectators(centerPos, false, true, 0, xRange, 0, yRange)
    for _, spec in ipairs(spectators) do
        local specName = getPlayerName(spec)
        for _, player in ipairs(players) do
            if getPlayerName(player) == specName then
                doTeleportThing(spec, kickTo, false)
            end
        end
    end
end
because it was not called?


i tried
Code:
local kickTo = {x = 956, y = 1039, z = 7} -- kick players after 15 minutes to this position
local centerPos = {x = 1000, y = 1000, z = 7}
local xRange = 5
local yRange = 4

-- positions and where go
local p = {
    [1] = {
        player = {
            position = {x = 952, y = 1039, z = 7},
            toPos = {x = 953, y = 1047, z = 6}
        }
    },
    [2] = {
        player = {
            position = {x = 953, y = 1039, z = 7},
            toPos = {x = 954, y = 1047, z = 6}
        }
    },
    [3] = {
        player = {
            position = {x = 954, y = 1039, z = 7},
            toPos = {x = 955, y = 1047, z = 6}
        }
    },
    [4] = {
        player = {
            position = {x = 955, y = 1039, z = 7},
            toPos = {x = 956, y = 1047, z = 6}
        }
    }
}

-- min lvl
local minLevel = 10
local maxLevel = 20

-- 3 how to: after enter in the dungeon, have 15 min to open the chest, if dont teleport to 956/1039/7
local function kickPlayers(players)
    local spectators = getSpectators(centerPos, false, true, 0, xRange, 0, yRange)
    for _, spec in ipairs(spectators) do
        local specName = getPlayerName(spec)
        for _, player in ipairs(players) do
            if getPlayerName(player) == specName then
                doTeleportThing(spec, kickTo, false)
            end
        end
    end
end

function onUse(cid)
    -- 1 how to: if there is a team doing players cant go in
    local spectators = getSpectators(centerPos, xRange, yRange)
    for _, player in ipairs(spectators) do
        doPlayerSendCancel(cid, "There are still remaining players in the room.")
        return false
    end
 
    -- 2 how to: only accept different IPs
    local ipAddress = {}
    local questPlayers = {}
    local oldPlayers = {}
    local SORCERER, DRUID, PALADIN, KNIGHT = false, false, false, false

    for i = 1, #p do
        local pid = getTopCreature(p[i].player.position).uid   
        if isPlayer(pid) then
            local voc = getPlayerVocation(pid)
            if voc == 1 or voc == 5 or voc == 9 then
                SORCERER = true
            elseif voc == 2 or voc == 6 or voc == 10 then
                DRUID = true
            elseif voc == 3 or voc == 7 or voc == 11 then
                PALADIN = true
            elseif voc == 4 or voc == 8 or voc == 12 then
                KNIGHT = true
            end
            
            local newIp = getPlayerIp(pid)
            if getPlayerStorageValue(pid, 5824) >= os.time() then
                local exaustedMins = math.ceil(((getPlayerStorageValue(cid, 5824)) - os.time())/60)
                doPlayerSendCancel(cid, getPlayerName(pid) .. " have to wait " .. exaustedMins .. " minutes to do this dugeon again.")
                return false
            end

            for _, ip in ipairs(ipAddress) do
                if newIp == ip then
                    doPlayerSendCancel(cid, "Players with the same IP address detected.")
                    return false
                end
            end
            ipAddress[#ipAddress + 1] = newIp
            
            if not getPlayerLevel(pid) >= minLevel and not getPlayerLevel(pid) <= maxLevel then
                doPlayerSendCancel(cid, getCreatureName(pid) .. ", is not high enough in level, the level to enter have to be between " .. minLevel .. "~ " .. maxLevel .. ". ")
                return false
            end
            oldPlayers[#oldPlayers + 1] = pid
        else
            doPlayerSendCancel(cid, "A player is missing.")
            return false
        end
    end
    
    if SORCERER == false or DRUID == false or PALADIN == false or KNIGHT == false then
        doPlayerSendCancel(cid, "Four different vocations are required.")
        return false
    end
    
    for x = 1, #questPlayers do
        -- 4 how to: after go in have a exausted of 24 hours to go again
        setPlayerStorageValue(questPlayers[x], 5824, os.time() + 86400)
        doPlayerSendTextMessage(questPlayers[x], MESSAGE_INFO_DESCR, "Good luck!")
        doTeleportThing(questPlayers[x], p[x].player.toPos)
    end
    
    addEvent(kickPlayers, 900000, oldPlayers)
    return true
end

but now shows new errors
Code:
[12:29:51.944] [Error - Action Interface] 
[12:29:51.944] data/actions/scripts/dungeon_lever.lua:onUse
[12:29:51.944] Description: 
[12:29:51.944] data/actions/scripts/dungeon_lever.lua:54: bad argument #1 to 'ipairs' (table expected, got nil)
[12:29:51.944] stack traceback:
[12:29:51.944]     [C]: in function 'ipairs'
[12:29:51.944]     data/actions/scripts/dungeon_lever.lua:54: in function <data/actions/scripts/dungeon_lever.lua:51>
 
Lua:
local spectators = getSpectators(centerPos, xRange, yRange)
    for _, player in ipairs(spectators) do
        doPlayerSendCancel(cid, "There are still remaining players in the room.")
        return false
    end
spectators is nil because nobody is in the area. I think this should work:
Lua:
local spectators = getSpectators(centerPos, xRange, yRange)
   if spectators then
        doPlayerSendCancel(cid, "There are still remaining players in the room.")
        return false
    end


as for
Lua:
-- 3 how to: after enter in the dungeon, have 15 min to open the chest, if dont teleport to 956/1039/7
local function kickPlayers(players)
    local spectators = getSpectators(centerPos, false, true, 0, xRange, 0, yRange)
    for _, spec in ipairs(spectators) do
        local specName = getPlayerName(spec)
        for _, player in ipairs(players) do
            if getPlayerName(player) == specName then
                doTeleportThing(spec, kickTo, false)
            end
        end
    end
end
yes, it wasn't called so it didn't error.
this instead should do what you need:

Lua:
-- 3 how to: after enter in the dungeon, have 15 min to open the chest, if dont teleport to 956/1039/7
local function kickPlayers(players)
    local spectators = getSpectators(centerPos, xRange, yRange)
    if spectators then
        for _, spec in ipairs(spectators) do
            local specName = getPlayerName(spec)
            for _, player in ipairs(players) do
                if getPlayerName(player) == specName then
                    doTeleportThing(spec, kickTo, false)
                end
            end
        end
    end
end
 
Last edited:
Lua:
local spectators = getSpectators(centerPos, xRange, yRange)
    for _, player in ipairs(spectators) do
        doPlayerSendCancel(cid, "There are still remaining players in the room.")
        return false
    end
spectators is nil because nobody is in the area. I think this should work:
Lua:
local spectators = getSpectators(centerPos, xRange, yRange)
   if spectators then
        doPlayerSendCancel(cid, "There are still remaining players in the room.")
        return false
    end


as for
Lua:
-- 3 how to: after enter in the dungeon, have 15 min to open the chest, if dont teleport to 956/1039/7
local function kickPlayers(players)
    local spectators = getSpectators(centerPos, false, true, 0, xRange, 0, yRange)
    for _, spec in ipairs(spectators) do
        local specName = getPlayerName(spec)
        for _, player in ipairs(players) do
            if getPlayerName(player) == specName then
                doTeleportThing(spec, kickTo, false)
            end
        end
    end
end
yes, it wasn't called so it didn't error.
this instead should do what you need:

Lua:
-- 3 how to: after enter in the dungeon, have 15 min to open the chest, if dont teleport to 956/1039/7
local function kickPlayers(players)
    local spectators = getSpectators(centerPos, xRange, yRange)
    if spectators then
        for _, spec in ipairs(spectators) do
            local specName = getPlayerName(spec)
            for _, player in ipairs(players) do
                if getPlayerName(player) == specName then
                    doTeleportThing(spec, kickTo, false)
                end
            end
        end
    end
end


there were some easy bugs to fix, i fix

Code:
local kickTo = {x = 956, y = 1039, z = 7} -- kick players after 15 minutes to this position
local centerPos = {x = 1000, y = 1000, z = 7}
local xRange = 5
local yRange = 4

-- positions and where go
local p = {
    [1] = {
        player = {
            position = {x = 952, y = 1039, z = 7},
            toPos = {x = 953, y = 1047, z = 6}
        }
    },
    [2] = {
        player = {
            position = {x = 953, y = 1039, z = 7},
            toPos = {x = 954, y = 1047, z = 6}
        }
    },
    [3] = {
        player = {
            position = {x = 954, y = 1039, z = 7},
            toPos = {x = 955, y = 1047, z = 6}
        }
    },
    [4] = {
        player = {
            position = {x = 955, y = 1039, z = 7},
            toPos = {x = 956, y = 1047, z = 6}
        }
    }
}

-- min lvl
local minLevel = 8
local maxLevel = 55

-- 3 how to: after enter in the dungeon, have 15 min to open the chest, if dont teleport to 956/1039/7
local function kickPlayers(players)
    local spectators = getSpectators(centerPos, false, true, 0, xRange, 0, yRange)
    for _, spec in ipairs(spectators) do
        local specName = getPlayerName(spec)
        for _, player in ipairs(players) do
            if getPlayerName(player) == specName then
                doTeleportThing(spec, kickTo, false)
            end
        end
    end
end

function onUse(cid)
    -- 1 how to: if there is a team doing players cant go in
    local spectators = getSpectators(centerPos, xRange, yRange)
    if spectators then
        doPlayerSendCancel(cid, "There are still remaining players in the room.")
        return false
    end
 
    -- 2 how to: only accept different IPs
    local ipAddress = {}
    local questPlayers = {}
    local oldPlayers = {}
    local SORCERER, DRUID, PALADIN, KNIGHT = false, false, false, false

    for i = 1, #p do
        local pid = getTopCreature(p[i].player.position).uid   
        if isPlayer(pid) then
            local voc = getPlayerVocation(pid)
            if voc == 1 or voc == 5 or voc == 9 then
                SORCERER = true
            elseif voc == 2 or voc == 6 or voc == 10 then
                DRUID = true
            elseif voc == 3 or voc == 7 or voc == 11 then
                PALADIN = true
            elseif voc == 4 or voc == 8 or voc == 12 then
                KNIGHT = true
            end
            
            local newIp = getPlayerIp(pid)
            if getPlayerStorageValue(pid, 5824) >= os.time() then
                local exaustedMins = math.ceil(((getPlayerStorageValue(cid, 5824)) - os.time())/60)
                doPlayerSendCancel(cid, getPlayerName(pid) .. " have to wait " .. exaustedMins .. " minutes to do this dugeon again.")
                return false
            end

            --for _, ip in ipairs(ipAddress) do
            --    if newIp == ip then
            --        doPlayerSendCancel(cid, "Players with the same IP address detected.")
            --        return false
            --    end
            --end
            ipAddress[#ipAddress + 1] = newIp
            
            if getPlayerLevel(pid) < minLevel or getPlayerLevel(pid) > maxLevel then
                doPlayerSendCancel(cid, getCreatureName(pid) .. ", is not high enough in level, the level to enter have to be between " .. minLevel .. "~ " .. maxLevel .. ". ")
                return false
            end
            oldPlayers[#oldPlayers + 1] = pid
        else
            doPlayerSendCancel(cid, "A player is missing. You need 4 players to do a dungeon. (1 knight, 1 paladin, 1 sorcerer, 1 druid)")
            return false
        end
    end
    
    if SORCERER == false or DRUID == false or PALADIN == false or KNIGHT == false then
        doPlayerSendCancel(cid, "Four different vocations are required.")
        return false
    end
    
    for x = 1, #questPlayers do
        -- 4 how to: after go in have a exausted of 24 hours to go again
        setPlayerStorageValue(questPlayers[x], 5824, os.time() + 86400)
        doPlayerSendTextMessage(questPlayers[x], MESSAGE_INFO_DESCR, "Good luck!")
        doTeleportThing(questPlayers[x], p[x].player.toPos)
    end
    
    addEvent(kickPlayers, 900000, oldPlayers)
    return true
end

now everything is working, its checking IP, vocations, but when everything is right

it's not teleporting the players

did u know why?
 
it's not teleporting the players
is it not teleporting them in or is it not teleporting them out, or both
edit: nevermind, it's not teleporting them in because it's using an empty table. you also didn't change the kickPlayers function to the one I posted earlier, so I've change that as well. try this:

Lua:
local kickTo = {x = 956, y = 1039, z = 7} -- kick players after 15 minutes to this position
local centerPos = {x = 1000, y = 1000, z = 7}
local xRange = 5
local yRange = 4

-- positions and where go
local p = {
    [1] = {
        player = {
            position = {x = 952, y = 1039, z = 7},
            toPos = {x = 953, y = 1047, z = 6}
        }
    },
    [2] = {
        player = {
            position = {x = 953, y = 1039, z = 7},
            toPos = {x = 954, y = 1047, z = 6}
        }
    },
    [3] = {
        player = {
            position = {x = 954, y = 1039, z = 7},
            toPos = {x = 955, y = 1047, z = 6}
        }
    },
    [4] = {
        player = {
            position = {x = 955, y = 1039, z = 7},
            toPos = {x = 956, y = 1047, z = 6}
        }
    }
}

-- min lvl
local minLevel = 8
local maxLevel = 55

-- 3 how to: after enter in the dungeon, have 15 min to open the chest, if dont teleport to 956/1039/7
local function kickPlayers(players)
    local spectators = getSpectators(centerPos, xRange, yRange)
    if spectators then
        for _, spec in ipairs(spectators) do
            local specName = getPlayerName(spec)
            for _, player in ipairs(players) do
                if getPlayerName(player) == specName then
                    doTeleportThing(spec, kickTo, false)
                end
            end
        end
    end
end

function onUse(cid)
    -- 1 how to: if there is a team doing players cant go in
    local spectators = getSpectators(centerPos, xRange, yRange)
    if spectators then
        doPlayerSendCancel(cid, "There are still remaining players in the room.")
        return false
    end

    -- 2 how to: only accept different IPs
    local ipAddress = {}
    local questPlayers = {}
    local oldPlayers = {}
    local SORCERER, DRUID, PALADIN, KNIGHT = false, false, false, false

    for i = 1, #p do
        local pid = getTopCreature(p[i].player.position).uid  
        if isPlayer(pid) then
            local voc = getPlayerVocation(pid)
            if voc == 1 or voc == 5 or voc == 9 then
                SORCERER = true
            elseif voc == 2 or voc == 6 or voc == 10 then
                DRUID = true
            elseif voc == 3 or voc == 7 or voc == 11 then
                PALADIN = true
            elseif voc == 4 or voc == 8 or voc == 12 then
                KNIGHT = true
            end
           
            local newIp = getPlayerIp(pid)
            if getPlayerStorageValue(pid, 5824) >= os.time() then
                local exaustedMins = math.ceil(((getPlayerStorageValue(cid, 5824)) - os.time())/60)
                doPlayerSendCancel(cid, getPlayerName(pid) .. " have to wait " .. exaustedMins .. " minutes to do this dugeon again.")
                return false
            end

            --for _, ip in ipairs(ipAddress) do
            --    if newIp == ip then
            --        doPlayerSendCancel(cid, "Players with the same IP address detected.")
            --        return false
            --    end
            --end
            ipAddress[#ipAddress + 1] = newIp
           
            if getPlayerLevel(pid) < minLevel or getPlayerLevel(pid) > maxLevel then
                doPlayerSendCancel(cid, getCreatureName(pid) .. ", is not high enough in level, the level to enter have to be between " .. minLevel .. "~ " .. maxLevel .. ". ")
                return false
            end
            oldPlayers[#oldPlayers + 1] = pid
        else
            doPlayerSendCancel(cid, "A player is missing. You need 4 players to do a dungeon. (1 knight, 1 paladin, 1 sorcerer, 1 druid)")
            return false
        end
    end
   
    if SORCERER == false or DRUID == false or PALADIN == false or KNIGHT == false then
        doPlayerSendCancel(cid, "Four different vocations are required.")
        return false
    end
   
    for x = 1, #oldPlayers do
        -- 4 how to: after go in have a exausted of 24 hours to go again
        setPlayerStorageValue(oldPlayers[x], 5824, os.time() + 86400)
        doPlayerSendTextMessage(oldPlayers[x], MESSAGE_INFO_DESCR, "Good luck!")
        doTeleportThing(oldPlayers[x], p[x].player.toPos)
    end
   
    addEvent(kickPlayers, 900000, oldPlayers)
    return true
end
 
Solution
in
after check everything and everything is right to start the dungeon, nothing happen
no errors, just not teleport the players inside

looks like it is not called
Code:
    for x = 1, #questPlayers do
        -- 4 how to: after go in have a exausted of 24 hours to go again
        setPlayerStorageValue(questPlayers[x], 5824, os.time() + 86400)
        doPlayerSendTextMessage(questPlayers[x], MESSAGE_INFO_DESCR, "Good luck!")
        doTeleportThing(questPlayers[x], p[x].player.toPos)
    end
 
in
after check everything and everything is right to start the dungeon, nothing happen
no errors, just not teleport the players inside

looks like it is not called
Code:
    for x = 1, #questPlayers do
        -- 4 how to: after go in have a exausted of 24 hours to go again
        setPlayerStorageValue(questPlayers[x], 5824, os.time() + 86400)
        doPlayerSendTextMessage(questPlayers[x], MESSAGE_INFO_DESCR, "Good luck!")
        doTeleportThing(questPlayers[x], p[x].player.toPos)
    end
yeah, check my edit above
 
Back
Top