• 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 [TFS 1.3] Door requirements

SorketROrk

Well-Known Member
Joined
Oct 14, 2020
Messages
152
Solutions
1
Reaction score
69
Location
Sweden
Hey!

I'm looking for a script that will let the player enter a door "Gate of experience" when lvl 200 requirement is met but also if player has item "2145"

So if the player is lvl 200 and player has item 2145 > grant access and remove the item.

It sound simple but im having a hard time, all help is greatly appreciated!


Yours,
SRO
 
Solution
I see that problem.

Try:
Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local itemId = item:getId()
    
    local access = 0
    
    --quest door
    local qDoorAid = 1200 --to see description lvl 200 required
    local qdoorUid = 123456 -- your door uniqueId
    local qDoorItemReq = 2145 --item required
    local qDoorlvl = qDoorAid - 1000 --quest door lvl
    local qDoorStorage = qdoorUid --can be change for quest
    
    
        if item:getUniqueId() == qdoorUid then 
            if player:getStorageValue(qDoorStorage) >= 1 -- is alredy done?
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Access granted.")
                access = 1
            else
                if...
This door require change actionId.

data\actions\scripts\other\doors.lua

Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)

    local qDoorAid = 123456 --quest door actionid (anyway can be used for storageId)
    local qDoorItemReq = 2145 --item required
    local qDoorlvl = 200 --quest door lvl
    local qDoorStorage = qDoorAid --can be change for quest
    
    local itemId = item:getId()
    if table.contains(questDoors, itemId) then
    --
        if item.actionid == qDoorAid then --quest check
            if player:getStorageValue(qDoorStorage) >= 1 -- is alredy done?
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Access granted.")
                return false
            else
                if player:getLevel() >= qDoorlvl then -- check lvl
                    
                    if player:getItemCount(qDoorItemReq) >= 1 then -- check item
                        player:removeItem(qDoorItemReq, 1)    
                        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Access granted.")
                        player:setStorageValue(qDoorStorage, 1)
                        player:teleportTo(toPosition, true)
                    else
                            local itemName = getItemName(qDoorItemReq)
                            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Required item ".itemName.".")
                        return true
                    end
                else
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Required level ".qDoorlvl.".")
                    return true
                end
            end
        end    
    --
        if player:getStorageValue(item.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 table.contains(levelDoors, itemId) then
        if item.actionid > 0 and player:getLevel() >= item.actionid - actionIds.levelDoor then
            item:transform(itemId + 1)
            player:teleportTo(toPosition, true)
        else
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Only the worthy may pass.")
        end
        return true
    elseif table.contains(keys, itemId) then
        if target.actionid > 0 then
            if item.actionid == target.actionid and doors[target.itemid] then
                target:transform(doors[target.itemid])
                return true
            end
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "The key does not match.")
            return true
        end
        return false
        
    else
        return true    
    end

    if table.contains(horizontalOpenDoors, itemId) or table.contains(verticalOpenDoors, itemId) then
        local creaturePositionTable = {}
        local doorCreatures = Tile(toPosition):getCreatures()
        if doorCreatures and #doorCreatures > 0 then
            for _, doorCreature in pairs(doorCreatures) do
                local pushPosition = findPushPosition(doorCreature, 1)
                if not pushPosition then
                    player:sendCancelMessage(RETURNVALUE_NOTENOUGHROOM)
                    return true
                end
                table.insert(creaturePositionTable, {creature = doorCreature, position = pushPosition})
            end
            for _, tableCreature in ipairs(creaturePositionTable) do
                tableCreature.creature:teleportTo(tableCreature.position, true)
            end
        end

        if not table.contains(openSpecialDoors, itemId) then
            item:transform(itemId - 1)
        end
        return true
    end

    if doors[itemId] then
        if item.actionid == 0 then
            item:transform(doors[itemId])
        else
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It is locked.")
        end
        return true
    end
    return false
end

Added code:

local qDoorAid = 123456 --quest door actionid (anyway can be used for storageId)
local qDoorItemReq = 2145 --item required
local qDoorlvl = 200 --quest door lvl
local qDoorStorage = qDoorAid --can be change for quest

if item.actionid == qDoorAid then --quest check
if player:getStorageValue(qDoorStorage) >= 1 -- is alredy done?
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Access granted.")
return false
else
if player:getLevel() >= qDoorlvl then -- check lvl

if player:getItemCount(qDoorItemReq) >= 1 then -- check item
player:removeItem(qDoorItemReq, 1)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Access granted.")
player:setStorageValue(qDoorStorage, 1)
return false
else
local itemName = getItemName(qDoorItemReq)
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Required item ".itemName.".")
return true
end
else
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Required level ".qDoorlvl.".")
return true
end
end
end

Remember:
questDoors = {1223, 1225, 1241, 1243, 1255, 1257, 3542, 3551, 5105, 5114, 5123, 5132, 5288, 5290, 5745, 5748, 6202, 6204, 6259, 6261, 6898, 6907, 7040, 7049, 8551, 8553, 9175, 9177, 9277, 9279, 10278, 10280, 10475, 10484, 10782, 10791, 12097, 12104, 12193, 12202, 19847, 19856, 19987, 19996, 20280, 20289, 25162, 25164}

Reserved actionIds:
sandHole = 100, -- hidden sand hole
pickHole = 105, -- hidden mud hole
levelDoor = 1000, -- level door
citizenship = 30020, -- citizenship teleport
citizenshipLast = 30050, -- citizenship teleport last

Reserved storage ranges:
  • 300000 to 301000+ reserved for achievements
  • 20000 to 21000+ reserved for achievement progress
  • 10000000 to 20000000 reserved for outfits and mounts on source
 
Last edited:
This door require change actionId.



Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)

    local qDoorAid = 123456 --quest door actionid (anyway can be used for storageId)
    local qDoorItemReq = 2145 --item required
    local qDoorlvl = 200 --quest door lvl
    local qDoorStorage = qDoorAid --can be change for quest
   
    local itemId = item:getId()
    if table.contains(questDoors, itemId) then
    --
        if item.actionid == qDoorAid then --quest check
            if player:getStorageValue(qDoorStorage) >= 1 -- is alredy done?
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Access granted.")
                return false
            else
                if player:getLevel() >= qDoorlvl then -- check lvl
                   
                    if player:getItemCount(qDoorItemReq) >= 1 then -- check item
                        player:removeItem(qDoorItemReq, 1)   
                        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Access granted.")
                        player:setStorageValue(qDoorStorage, 1)
                        player:teleportTo(toPosition, true)
                    else
                            local itemName = getItemName(qDoorItemReq)
                            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Required item ".itemName.".")
                        return true
                    end
                else
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Required level ".qDoorlvl.".")
                    return true
                end
            end
        end   
    --
        if player:getStorageValue(item.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 table.contains(levelDoors, itemId) then
        if item.actionid > 0 and player:getLevel() >= item.actionid - actionIds.levelDoor then
            item:transform(itemId + 1)
            player:teleportTo(toPosition, true)
        else
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Only the worthy may pass.")
        end
        return true
    elseif table.contains(keys, itemId) then
        if target.actionid > 0 then
            if item.actionid == target.actionid and doors[target.itemid] then
                target:transform(doors[target.itemid])
                return true
            end
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "The key does not match.")
            return true
        end
        return false
       
    else
        return true   
    end

    if table.contains(horizontalOpenDoors, itemId) or table.contains(verticalOpenDoors, itemId) then
        local creaturePositionTable = {}
        local doorCreatures = Tile(toPosition):getCreatures()
        if doorCreatures and #doorCreatures > 0 then
            for _, doorCreature in pairs(doorCreatures) do
                local pushPosition = findPushPosition(doorCreature, 1)
                if not pushPosition then
                    player:sendCancelMessage(RETURNVALUE_NOTENOUGHROOM)
                    return true
                end
                table.insert(creaturePositionTable, {creature = doorCreature, position = pushPosition})
            end
            for _, tableCreature in ipairs(creaturePositionTable) do
                tableCreature.creature:teleportTo(tableCreature.position, true)
            end
        end

        if not table.contains(openSpecialDoors, itemId) then
            item:transform(itemId - 1)
        end
        return true
    end

    if doors[itemId] then
        if item.actionid == 0 then
            item:transform(doors[itemId])
        else
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It is locked.")
        end
        return true
    end
    return false
end

Added code:





Remember:
Hi, thanks for replying!

I'm having difficulties still, Im using door 5112 "gate of experience" but when I put action id and then try and look at the door it says "required level 27851" the action id ive used, seems its using it as level.. I even tried a different door 5101 but nothing happens.

How would I go about to set up the door with the script?

Im getting:
[Warning - Event::checkScript] Can not load script: scripts/other/doors.lua
data/actions/scripts/other/doors.lua:80: ')' expected near '.'

by commenting that part part out it shows no errors but im not able to enter the door still.
 
Hi, thanks for replying!

I'm having difficulties still, Im using door 5112 "gate of experience" but when I put action id and then try and look at the door it says "required level 27851" the action id ive used, seems its using it as level.. I even tried a different door 5101 but nothing happens.

How would I go about to set up the door with the script?

Im getting:
[Warning - Event::checkScript] Can not load script: scripts/other/doors.lua
data/actions/scripts/other/doors.lua:80: ')' expected near '.'

by commenting that part part out it shows no errors but im not able to enter the door still.
Here's my attempt at this.

Use the regular actionid for the levelDoor to facilitate level 200, but setup the Position and item requirements in the table at the top of the script.

Lua:
local levelDoorQuestItemsRequired = {
    {position = Position(1000, 1000, 7), itemid = 1111, amount = 1, remove = true}, -- if a levelDoor (gate of expertise) is on this position..
    {position = Position(1000, 1000, 7), itemid = 1111, amount = 1, remove = true}, -- it will first check the player level, and then it will check if the player has the correct item (and amount)
    {position = Position(1000, 1000, 7), itemid = 1111, amount = 1, remove = false} -- if remove = true, the item will be removed upon entry.
}

local positionOffsets = {
    Position(1, 0, 0), -- east
    Position(0, 1, 0), -- south
    Position(-1, 0, 0), -- west
    Position(0, -1, 0) -- north
}

--[[
When closing a door with a creature in it findPushPosition will find the most appropriate
adjacent position following a prioritization order.
The function returns the position of the first tile that fulfills all the checks in a round.
The function loops trough east -> south -> west -> north on each following line in that order.
In round 1 it checks if there's an unhindered walkable tile without any creature.
In round 2 it checks if there's a tile with a creature.
In round 3 it checks if there's a tile blocked by a movable tile-blocking item.
In round 4 it checks if there's a tile blocked by a magic wall or wild growth.
]]
local function findPushPosition(creature, round)
    local pos = creature:getPosition()
    for _, offset in ipairs(positionOffsets) do
        local offsetPosition = pos + offset
        local tile = Tile(offsetPosition)
        if tile then
            local creatureCount = tile:getCreatureCount()
            if round == 1 then
                if tile:queryAdd(creature) == RETURNVALUE_NOERROR and creatureCount == 0 then
                    if not tile:hasFlag(TILESTATE_PROTECTIONZONE) or (tile:hasFlag(TILESTATE_PROTECTIONZONE) and creature:canAccessPz()) then
                        return offsetPosition
                    end
                end
            elseif round == 2 then
                if creatureCount > 0 then
                    if not tile:hasFlag(TILESTATE_PROTECTIONZONE) or (tile:hasFlag(TILESTATE_PROTECTIONZONE) and creature:canAccessPz()) then
                        return offsetPosition
                    end
                end
            elseif round == 3 then
                local topItem = tile:getTopDownItem()
                if topItem then
                    if topItem:getType():isMovable() then
                        return offsetPosition
                    end
                end
            else
                if tile:getItemById(ITEM_MAGICWALL) or tile:getItemById(ITEM_WILDGROWTH) then
                    return offsetPosition
                end
            end
        end
    end
    if round < 4 then
        return findPushPosition(creature, round + 1)
    end
end

function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local itemId = item:getId()
    if table.contains(questDoors, itemId) then
        if player:getStorageValue(item.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 table.contains(levelDoors, itemId) then
        if item.actionid > 0 and player:getLevel() >= item.actionid - actionIds.levelDoor then
            for i = 1, #levelDoorQuestItemsRequired do
                if toPosition == levelDoorQuestItemsRequired[i].position then
                    if player:getItemCount(levelDoorQuestItemsRequired[i].itemid) >= levelDoorQuestItemsRequired[i].amount then
                        if levelDoorQuestItemsRequired[i].remove then
                            player:removeItem(levelDoorQuestItemsRequired[i].itemid, levelDoorQuestItemsRequired[i].amount)  
                        end
                        break
                    else
                        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door requires an item to pass through it.")
                        return true
                    end
                end
            end
            item:transform(itemId + 1)
            player:teleportTo(toPosition, true)
        else
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Only the worthy may pass.")
        end
        return true
    elseif table.contains(keys, itemId) then
        if target.actionid > 0 then
            if item.actionid == target.actionid and doors[target.itemid] then
                target:transform(doors[target.itemid])
                return true
            end
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "The key does not match.")
            return true
        end
        return false
    end

    if table.contains(horizontalOpenDoors, itemId) or table.contains(verticalOpenDoors, itemId) then
        local creaturePositionTable = {}
        local doorCreatures = Tile(toPosition):getCreatures()
        if doorCreatures and #doorCreatures > 0 then
            for _, doorCreature in pairs(doorCreatures) do
                local pushPosition = findPushPosition(doorCreature, 1)
                if not pushPosition then
                    player:sendCancelMessage(RETURNVALUE_NOTENOUGHROOM)
                    return true
                end
                table.insert(creaturePositionTable, {creature = doorCreature, position = pushPosition})
            end
            for _, tableCreature in ipairs(creaturePositionTable) do
                tableCreature.creature:teleportTo(tableCreature.position, true)
            end
        end

        if not table.contains(openSpecialDoors, itemId) then
            item:transform(itemId - 1)
        end
        return true
    end

    if doors[itemId] then
        if item.actionid == 0 then
            item:transform(doors[itemId])
        else
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It is locked.")
        end
        return true
    end
    return false
end
 
I see that problem.

Try:
Lua:
function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local itemId = item:getId()
    
    local access = 0
    
    --quest door
    local qDoorAid = 1200 --to see description lvl 200 required
    local qdoorUid = 123456 -- your door uniqueId
    local qDoorItemReq = 2145 --item required
    local qDoorlvl = qDoorAid - 1000 --quest door lvl
    local qDoorStorage = qdoorUid --can be change for quest
    
    
        if item:getUniqueId() == qdoorUid then 
            if player:getStorageValue(qDoorStorage) >= 1 -- is alredy done?
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Access granted.")
                access = 1
            else
                if player:getLevel() >= qDoorlvl then -- check lvl
                    if player:getItemCount(qDoorItemReq) >= 1 then -- check item
                        player:removeItem(qDoorItemReq, 1)    
                        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Access granted.")
                        player:setStorageValue(qDoorStorage, 1)
                        access = 1
                    else
                        local itemName = getItemName(qDoorItemReq)
                        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Required item ".itemName.".")
                        return true
                    end
                else
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Required level ".qDoorlvl.".")
                    return true
                end
            end
        end    
    --    
    

    if table.contains(questDoors, itemId) then
        if (player:getStorageValue(item.actionid) ~= -1 ) || access == 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 table.contains(levelDoors, itemId) then
        if (item.actionid > 0 and player:getLevel() >= item.actionid - actionIds.levelDoor) || access == 1 then
            item:transform(itemId + 1)
            player:teleportTo(toPosition, true)
        else
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Only the worthy may pass.")
        end
        return true
    elseif table.contains(keys, itemId) then
        if (target.actionid > 0 ) then
            if item.actionid == target.actionid and doors[target.itemid] then
                target:transform(doors[target.itemid])
                return true
            end
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "The key does not match.")
            return true
        end
        return false
        
    else
        return true    
    end

    if table.contains(horizontalOpenDoors, itemId) or table.contains(verticalOpenDoors, itemId) then
        local creaturePositionTable = {}
        local doorCreatures = Tile(toPosition):getCreatures()
        if doorCreatures and #doorCreatures > 0 then
            for _, doorCreature in pairs(doorCreatures) do
                local pushPosition = findPushPosition(doorCreature, 1)
                if not pushPosition then
                    player:sendCancelMessage(RETURNVALUE_NOTENOUGHROOM)
                    return true
                end
                table.insert(creaturePositionTable, {creature = doorCreature, position = pushPosition})
            end
            for _, tableCreature in ipairs(creaturePositionTable) do
                tableCreature.creature:teleportTo(tableCreature.position, true)
            end
        end

        if not table.contains(openSpecialDoors, itemId) then
            item:transform(itemId - 1)
        end
        return true
    end

    if doors[itemId] then
        if item.actionid == 0 then
            item:transform(doors[itemId])
        else
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "It is locked.")
        end
        return true
    end
    return false
end

It will works with lvl doors and quest doors
I change actionId to uniqueId

Doors should looks like :
door actionid = 1200 for lvl 200
door uniqueId = 123456
 
Solution
Thank you guys, @Xikini's solution works.

But for learning purposes I would like to get this solved also, if you have time @Chev
Im getting this:
[Warning - Event::checkScript] Can not load script: scripts/other/doors.lua
data/actions/scripts/other/doors.lua:40: 'then' expected near '|'

I see "then" at line 40, whats causing this? :eek:
 
Thank you guys, @Xikini's solution works.

But for learning purposes I would like to get this solved also, if you have time @Chev
Im getting this:
[Warning - Event::checkScript] Can not load script: scripts/other/doors.lua
data/actions/scripts/other/doors.lua:40: 'then' expected near '|'

I see "then" at line 40, whats causing this? :eek:
Can you post the current script you are getting that error with?
It's to hard to see what 'line 40' is otherwise.
 
Its the one from Post #5
Ah. It looks like they mistakenly mixed Lua coding and c++ coding together.

As far as I know the character | has no use inside of Lua, but in c++ it's used as an 'or' syntax.

You'd want to change it to this, in order to resolve that issue.

Lua:
if (player:getStorageValue(item.actionid) ~= -1 ) or access == 1 then
 
It solved the error but this still remains

[Warning - Event::checkScript] Can not load script: scripts/other/doors.lua
data/actions/scripts/other/doors.lua:27: ')' expected near '.'

When i comment these lines: 27 & 31 it gives no errors but item will not be removed.

It does however let me access the door and messages "Access granted" appears.
 
It solved the error but this still remains

[Warning - Event::checkScript] Can not load script: scripts/other/doors.lua
data/actions/scripts/other/doors.lua:27: ')' expected near '.'

When i comment these lines: 27 & 31 it gives no errors but item will not be removed.

It does however let me access the door and messages "Access granted" appears.
Need 2 dots instead of 1 dot, when grabbing information in that fashion

change those lines, to these
Lua:
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Required item "..itemName..".")
Lua:
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Required level "..qDoorlvl..".")
 
Back
Top