• 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!

Doors.lua and teleport.lua error

shisus420

New Member
Joined
Jan 20, 2017
Messages
16
Reaction score
2
Hi, I can't use doors, ladders etc.
Screenshot of errors:
XynaBIQ.png


And scripts:
1. doors.lua
Code:
unlockedDoors = { }

local function isDoorLocked(keyId, position)
    if keyId == 0 then
        return false
    end

    if unlockedDoors[keyId] then
        for i = 1, #unlockedDoors[keyId] do
            if position == unlockedDoors[keyId][i] then
                return false
            end
        end
    end

    return true
end

local function toggleDoorLock(doorItem, locked)
    local doorId = doorItem:getId()
    local keyId = doorItem:getActionId()
    local doorPosition = doorItem:getPosition()

    if locked then
        for i = #unlockedDoors[keyId], 1, -1 do
            if unlockedDoors[keyId][i] == doorPosition then
                table.remove(unlockedDoors[keyId], i)
            end
        end

        if not doors[doorId] then
            doorItem:transform(doorId - 1)
        end
        return
    end

    if not unlockedDoors[keyId] then
        unlockedDoors[keyId] = {}
    end

    doorItem:transform(doors[doorId])
    unlockedDoors[keyId][#unlockedDoors[keyId] + 1] = doorPosition
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local itemId, actionId = item:getId(), item:getActionId()
    if isInArray(questDoors, itemId) then
        if player:getStorageValue(actionId) ~= -1 then
            item:transform(itemId + 1)
            player:teleportTo(toPosition, true)
        else
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door seems to be sealed against unwanted intruders.")
        end
        return true

    elseif isInArray(levelDoors, itemId) then
        if actionId > 0 and player:getLevel() >= actionId - 1000 then
            item:transform(itemId + 1)
            player:teleportTo(toPosition, true)
        else
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Only the worthy may pass.")
        end
        return true

    elseif isInArray(keys, itemId) then
        if not target
                or not target:isItem()
                or not target:getType():isDoor()
                or Tile(toPosition):getHouse() then
            return false
        end

        local targetId = target:getId()
        if isInArray(openSpecialDoors, targetId)
                or isInArray(questDoors, targetId)
                or isInArray(levelDoors, targetId) then
            return false
        end

        local targetActionId = target:getActionId()
        if targetActionId > 0 and actionId == targetActionId then
            if not isDoorLocked(targetActionId, toPosition) then
                toggleDoorLock(target, true)
            elseif doors[targetId] then
                toggleDoorLock(target, false)
            end
        else
            player:sendCancelMessage("The key does not match.")
        end

        return true
    end

    if isInArray(horizontalOpenDoors, itemId) or isInArray(verticalOpenDoors, itemId) then
        local doorCreature = Tile(toPosition):getTopCreature()
        if doorCreature then
            toPosition.x = toPosition.x + 1
            local query = Tile(toPosition):queryAdd(doorCreature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING))
            if query ~= RETURNVALUE_NOERROR then
                toPosition.x = toPosition.x - 1
                toPosition.y = toPosition.y + 1
                query = Tile(toPosition):queryAdd(doorCreature, bit.bor(FLAG_IGNOREBLOCKCREATURE, FLAG_PATHFINDING))
            end

            if query ~= RETURNVALUE_NOERROR then
                player:sendCancelMessage(query)
                return true
            end

            doorCreature:teleportTo(toPosition, true)
        end
        if not isInArray(openSpecialDoors, itemId) then
            item:transform(itemId - 1)
        end
        return true
    end

    if doors[itemId] then
        if not isDoorLocked(actionId, toPosition) then
            item:transform(doors[itemId])
        else
            player:sendTextMessage(MESSAGE_INFO_DESCR, "It is locked.")
        end
        return true
    end

    return false
end

teleport.lua

Code:
local upFloorIds = {1386, 3678, 5543, 22845, 22846}
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if isInArray(upFloorIds, item.itemid) then
        fromPosition:moveUpstairs()
    else
        fromPosition.z = fromPosition.z + 1
    end
    player:teleportTo(fromPosition, false)
    return true
end
 
Solution
Hi, I added these lines to my global.lua
Lua:
table.contains = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end

isInArray = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end

I don't know if it's the correct way of fixing it but I managed to solve it using this way
provide tfs version on all threads for future reference, it's included in the rules
are you using the latest 1.3?
 
idk about otx i dont bother following the project
but isInArray was changed to table.contains in TFS so maybe OTX doesn't have a compat for it
go to lib/compat/compat.lua and put
Lua:
isInArray = table.contains
 
Hi, I added these lines to my global.lua
Lua:
table.contains = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end

isInArray = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end

I don't know if it's the correct way of fixing it but I managed to solve it using this way
 
Solution
idk about otx i dont bother following the project
but isInArray was changed to table.contains in TFS so maybe OTX doesn't have a compat for it
go to lib/compat/compat.lua and put

I added this line to compat.lua and now I got this error:
Code:
Lua Script Error: [Action Interface]
data/actions/scripts/other/doors.lua:onUse
data/lib/core/tables.lua:17: bad argument #1 to 'pairs' (table expected, got number)
stack traceback:
        [C]: in ?
        [C]: in function 'pairs'
        data/lib/core/tables.lua:17: in function 'isInArray'
        data/actions/scripts/other/doors.lua:47: in function <data/actions/scripts/other/doors.lua:45>

Hi, I added these lines to my global.lua

It works! Thanks!
 
Last edited by a moderator:
Hi, I added these lines to my global.lua
Lua:
table.contains = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end

isInArray = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end

I don't know if it's the correct way of fixing it but I managed to solve it using this way
the way i did it is the ideal way
that way both functions have the same memory address instead of two different ones for the same function
 
idk about otx i dont bother following the project
but isInArray was changed to table.contains in TFS so maybe OTX doesn't have a compat for it
go to lib/compat/compat.lua and put
Lua:
isInArray = table.contains
using your solution, trow me other error.
table contains a number value #
how i can fix it?

ops
function isInArray(array, value) return table.contains(array, value) end
 
Last edited by a moderator:
nop only work with
Code:
table.contains = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end
isInArray = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end
 
nop only work with
Code:
table.contains = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end
isInArray = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end

what a waste of memory.
 
nop only work with
Code:
table.contains = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end
isInArray = function (array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end
table.contains should already be predefined if you're using 1.3
if not then use
Lua:
table.contains = function(array, value)
    for _, targetColumn in pairs(array) do
        if targetColumn == value then
            return true
        end
    end
    return false
end

isInArray = table.contains
what a waste of memory.
it's not like it's a massive waste of memory, it's just not smart to create 2 different functions that do the same thing and pointing them to different memory addresses
 
@Xeraphus im aware that it ain't using Mbits of memory but what i meant was that it's a bad practice. Imagine that person copying and pasting similar blocks here and there causing lots of memory usage in the end :D
 
@Xeraphus im aware that it ain't using Mbits of memory but what i meant was that it's a bad practice. Imagine that person copying and pasting similar blocks here and there causing lots of memory usage in the end :D
the situation you described would almost never happen lol
the only thing is just that it's bad practice
 
Back
Top