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

Solved Door access when items are turned in issue

Joriku

Working in the mines, need something?
Joined
Jul 16, 2016
Messages
1,106
Solutions
15
Reaction score
390
Location
Sweden
YouTube
Joriku
Hi,
I am lost here..
no idea what I am doing wrong as of now, but the player gets access before the items are turned in.

Anyone got a clue why?

Lua:
local actions = {}

-- Configuration
local doorsConfig = {
    [9000] = {doorID = 6907, requiredItems = {9020}, useCount = 20, teleportPosition = Position(30998, 31642, 7), storageID = 10000, levelRequired = 50},
    [9001] = {doorID = 6907, requiredItems = {4033}, useCount = 20, teleportPosition = Position(31020, 31592, 7), storageID = 10001, levelRequired = 60},
    [9002] = {doorID = 6907, requiredItems = {29347}, useCount = 20, teleportPosition = Position(30923, 31636, 7), storageID = 10002, levelRequired = 70},
    [9003] = {doorID = 6907, requiredItems = {7425}, useCount = 20, teleportPosition = Position(31016, 31590, 7), storageID = 10003, levelRequired = 80},
    [9004] = {doorID = 6907, requiredItems = {9692}, useCount = 20, teleportPosition = Position(31045, 31821, 7), storageID = 10004, levelRequired = 90},
    [9005] = {doorID = 6898, requiredItems = {9017, 9383, 8820, 11701, 3206}, useCount = 20, teleportPosition = Position(30927, 31689, 7), storageID = 10005, levelRequired = 100, requireAllItems = true},
}

-- true for debugging mode
local deBug = false

function getItemCount(player, requiredItems, requireAll)
    local itemCount = 0
    for _, itemId in ipairs(requiredItems) do
        local count = player:getItemCount(itemId)
        if requireAll then
            itemCount = math.min(itemCount == 0 and count or itemCount, count)
        else
            itemCount = itemCount + count
        end
    end
    return itemCount
end

function removeRequiredItems(player, requiredItems, count, requireAll)
    for _, itemId in ipairs(requiredItems) do
        local removeCount = requireAll and count or math.min(player:getItemCount(itemId), count)
        player:removeItem(itemId, removeCount)
        count = count - removeCount
        if count <= 0 then break end
    end
end

local function onUse(player, item, fromPosition, target, toPosition, isHotkey, actionID)
    if deBug then
        player:sendTextMessage(18, "Attempting to use the door.")
        player:sendTextMessage(18, "Item ID: " .. item.itemid .. ", Action ID: " .. actionID)
    end
    
    local doorConfig = doorsConfig[actionID]

    if doorConfig then
        if deBug then
            player:sendTextMessage(18, "Configuration found for action ID: " .. actionID)
            player:sendTextMessage(18, "Door ID in config: " .. doorConfig.doorID .. ", Required Items: " .. table.concat(doorConfig.requiredItems, ", "))
        end
        
        if item.itemid == doorConfig.doorID then
            if deBug then
                player:sendTextMessage(18, "The door ID matches configuration.")
            end

            -- Check the player's level
            if player:getLevel() < doorConfig.levelRequired then
                player:sendTextMessage(18, "You need to be at least level " .. doorConfig.levelRequired .. " to use this door.")
                return false
            end

            -- Check if the door is already unlocked
            if player:getStorageValue(doorConfig.storageID) == 1 then
                player:sendTextMessage(18, "The door is already unlocked for you.")
                player:teleportTo(doorConfig.teleportPosition)
                doorConfig.teleportPosition:sendMagicEffect(CONST_ME_TELEPORT)
                return true
            end
            
            -- Get the current use count
            local currentUseCount = player:getStorageValue(doorConfig.storageID)
            if currentUseCount < 0 then
                currentUseCount = 0
            end

            -- Calculate the number of items the player has
            local itemCount = getItemCount(player, doorConfig.requiredItems, doorConfig.requireAllItems)

            if itemCount > 0 then
                -- Ensure only required amount of items is used
                local remainingItemsRequired = doorConfig.useCount - currentUseCount
                local itemsToUse = math.min(itemCount, remainingItemsRequired)

                -- Remove the used items from the player's inventory
                removeRequiredItems(player, doorConfig.requiredItems, itemsToUse, doorConfig.requireAllItems)

                -- Update the use count
                currentUseCount = currentUseCount + itemsToUse
                player:setStorageValue(doorConfig.storageID, currentUseCount)

                -- If the new use count meets or exceeds the required use count
                if currentUseCount >= doorConfig.useCount then
                    -- Set the storage value to mark the door as unlocked
                    player:setStorageValue(doorConfig.storageID, 1)
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have used the required items and the door is now permanently unlocked.")
                    player:teleportTo(doorConfig.teleportPosition)
                    doorConfig.teleportPosition:sendMagicEffect(CONST_ME_TELEPORT)
                    return true
                else
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have used some items. Use the door " .. (doorConfig.useCount - currentUseCount) .. " more times to permanently unlock it.")
                    return false
                end
            else
                player:sendTextMessage(18, "You need more items to use this door.")
                return false
            end
        else
            player:sendTextMessage(18, "The door ID does not match any configuration. Expected: " .. doorConfig.doorID .. ", Got: " .. item.itemid)
        end
    else
        player:sendTextMessage(18, "No configuration found for action ID: " .. actionID)
    end
    return false
end

for actionID, config in pairs(doorsConfig) do
    actions[actionID] = Action()
    actions[actionID].onUse = function(player, item, fromPosition, target, toPosition, isHotkey)
        return onUse(player, item, fromPosition, target, toPosition, isHotkey, actionID)
    end
    actions[actionID]:aid(actionID)
    actions[actionID]:register()
end
 
Solution
I just edited the version which @abdala ragab provided (not tested)
Sorry to tell you this, but your edits are not working
This version seems to work, closed thread.
I helped you and my script is working well I should get the best answer
Your new code only added 20 items in exchange for permanent access. Anyway, here is a clean code
Lua:
-- Configuration
local doorsConfig = {
    [9000] = {doorID = 6907, requiredItems = {9020}, useCount = 20, teleportPosition = Position(30998, 31642, 7), levelRequired = 50, unlockStorageID = 30000},
    [9001] = {doorID = 6907, requiredItems = {4033}, useCount = 20, teleportPosition = Position(31020, 31592, 7), levelRequired = 60, unlockStorageID = 30001},
    [9002] = {doorID = 6907, requiredItems...
here work fine
Lua:
local actions = {}

-- Configuration
local doorsConfig = {
    [9000] = {doorID = 6907, requiredItems = {9020}, teleportPosition = Position(30998, 31642, 7), levelRequired = 50},
    [9001] = {doorID = 6907, requiredItems = {4033}, teleportPosition = Position(31020, 31592, 7), levelRequired = 60},
    [9002] = {doorID = 6907, requiredItems = {29347}, teleportPosition = Position(30923, 31636, 7), levelRequired = 70},
    [9003] = {doorID = 6907, requiredItems = {7425}, teleportPosition = Position(31016, 31590, 7), levelRequired = 80},
    [9004] = {doorID = 6907, requiredItems = {9692}, teleportPosition = Position(31045, 31821, 7), levelRequired = 90},
    [9005] = {doorID = 6898, requiredItems = {9017, 9383, 8820, 11701, 3206}, teleportPosition = Position(30927, 31689, 7), levelRequired = 100, requireAllItems = true},
}

-- true for debugging mode
local deBug = false

function getItemCount(player, requiredItems, requireAll)
    local itemCount = 0
    for _, itemId in ipairs(requiredItems) do
        local count = player:getItemCount(itemId)
        if requireAll then
            itemCount = math.min(itemCount == 0 and count or itemCount, count)
        else
            itemCount = itemCount + count
        end
    end
    return itemCount
end

function removeRequiredItems(player, requiredItems, count, requireAll)
    for _, itemId in ipairs(requiredItems) do
        local removeCount = requireAll and count or math.min(player:getItemCount(itemId), count)
        player:removeItem(itemId, removeCount)
        count = count - removeCount
        if count <= 0 then break end
    end
end

local function onUse(player, item, fromPosition, target, toPosition, isHotkey, actionID)
    if deBug then
        player:sendTextMessage(18, "Attempting to use the door.")
        player:sendTextMessage(18, "Item ID: " .. item.itemid .. ", Action ID: " .. actionID)
    end
    
    local doorConfig = doorsConfig[actionID]

    if doorConfig then
        if deBug then
            player:sendTextMessage(18, "Configuration found for action ID: " .. actionID)
            player:sendTextMessage(18, "Door ID in config: " .. doorConfig.doorID .. ", Required Items: " .. table.concat(doorConfig.requiredItems, ", "))
        end
        
        if item.itemid == doorConfig.doorID then
            if deBug then
                player:sendTextMessage(18, "The door ID matches configuration.")
            end

            -- Check the player's level
            if player:getLevel() < doorConfig.levelRequired then
                player:sendTextMessage(18, "You need to be at least level " .. doorConfig.levelRequired .. " to use this door.")
                return false
            end

            -- Calculate the number of items the player has
            local itemCount = getItemCount(player, doorConfig.requiredItems, doorConfig.requireAllItems)

            if itemCount > 0 then
                -- Remove the required items from the player's inventory
                removeRequiredItems(player, doorConfig.requiredItems, itemCount, doorConfig.requireAllItems)

                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have used the required items and the door opens.")
                player:teleportTo(doorConfig.teleportPosition)
                doorConfig.teleportPosition:sendMagicEffect(CONST_ME_TELEPORT)
                return true
            else
                player:sendTextMessage(18, "You need more items to use this door.")
                return false
            end
        else
            player:sendTextMessage(18, "The door ID does not match any configuration. Expected: " .. doorConfig.doorID .. ", Got: " .. item.itemid)
        end
    else
        player:sendTextMessage(18, "No configuration found for action ID: " .. actionID)
    end
    return false
end

for actionID, config in pairs(doorsConfig) do
    actions[actionID] = Action()
    actions[actionID].onUse = function(player, item, fromPosition, target, toPosition, isHotkey)
        return onUse(player, item, fromPosition, target, toPosition, isHotkey, actionID)
    end
    actions[actionID]:aid(actionID)
    actions[actionID]:register()
end
Post automatically merged:

 
Last edited:
Lua:
for actionID, config in pairs(doorsConfig) do
    actions[actionID] = Action()
    actions[actionID].onUse = function(player, item, fromPosition, target, toPosition, isHotkey)
        return onUse(player, item, fromPosition, target, toPosition, isHotkey, actionID)
    end
    actions[actionID]:aid(actionID)
    actions[actionID]:register()
end
I'm absolutely stunned you should get an award for this!
In all my years this is the most creative and at the same time the worst way of registering a revscript 😂

I just edited the version which @abdala ragab provided (not tested)
Lua:
-- Configuration
local doorsConfig = {
    [9000] = {doorID = 6907, requiredItems = {9020}, teleportPosition = Position(30998, 31642, 7), levelRequired = 50},
    [9001] = {doorID = 6907, requiredItems = {4033}, teleportPosition = Position(31020, 31592, 7), levelRequired = 60},
    [9002] = {doorID = 6907, requiredItems = {29347}, teleportPosition = Position(30923, 31636, 7), levelRequired = 70},
    [9003] = {doorID = 6907, requiredItems = {7425}, teleportPosition = Position(31016, 31590, 7), levelRequired = 80},
    [9004] = {doorID = 6907, requiredItems = {9692}, teleportPosition = Position(31045, 31821, 7), levelRequired = 90},
    [9005] = {doorID = 6898, requiredItems = {9017, 9383, 8820, 11701, 3206}, teleportPosition = Position(30927, 31689, 7), levelRequired = 100, requireAllItems = true},
}

-- true for debugging mode
local deBug = false

function getItemCount(player, requiredItems, requireAll)
    local itemCount = 0
    for _, itemId in ipairs(requiredItems) do
        local count = player:getItemCount(itemId)
        if requireAll then
            itemCount = math.min(itemCount == 0 and count or itemCount, count)
        else
            itemCount = itemCount + count
        end
    end
    return itemCount
end

function removeRequiredItems(player, requiredItems, count, requireAll)
    for _, itemId in ipairs(requiredItems) do
        local removeCount = requireAll and count or math.min(player:getItemCount(itemId), count)
        player:removeItem(itemId, removeCount)
        count = count - removeCount
        if count <= 0 then break end
    end
end

local action = Action()

function action.onUse(player, item, fromPosition, target, toPosition, isHotkey, actionID)
    if deBug then
        player:sendTextMessage(18, "Attempting to use the door.")
        player:sendTextMessage(18, "Item ID: " .. item.itemid .. ", Action ID: " .. actionID)
    end
    local doorConfig = doorsConfig[actionID]
    if doorConfig then
        if deBug then
            player:sendTextMessage(18, "Configuration found for action ID: " .. actionID)
            player:sendTextMessage(18, "Door ID in config: " .. doorConfig.doorID .. ", Required Items: " .. table.concat(doorConfig.requiredItems, ", "))
        end
        if item.itemid == doorConfig.doorID then
            if deBug then
                player:sendTextMessage(18, "The door ID matches configuration.")
            end
            -- Check the player's level
            if player:getLevel() < doorConfig.levelRequired then
                player:sendTextMessage(18, "You need to be at least level " .. doorConfig.levelRequired .. " to use this door.")
                return false
            end
            -- Calculate the number of items the player has
            local itemCount = getItemCount(player, doorConfig.requiredItems, doorConfig.requireAllItems)
            if itemCount > 0 then
                -- Remove the required items from the player's inventory
                removeRequiredItems(player, doorConfig.requiredItems, itemCount, doorConfig.requireAllItems)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have used the required items and the door opens.")
                player:teleportTo(doorConfig.teleportPosition)
                doorConfig.teleportPosition:sendMagicEffect(CONST_ME_TELEPORT)
                return true
            else
                player:sendTextMessage(18, "You need more items to use this door.")
                return false
            end
        else
            player:sendTextMessage(18, "The door ID does not match any configuration. Expected: " .. doorConfig.doorID .. ", Got: " .. item.itemid)
        end
    else
        player:sendTextMessage(18, "No configuration found for action ID: " .. actionID)
    end
    return false
end

for actionID, config in pairs(doorsConfig) do
    action:aid(actionID)
end

action:register()
 
I'm absolutely stunned you should get an award for this!
In all my years this is the most creative and at the same time the worst way of registering a revscript 😂

I just edited the version which @abdala ragab provided (not tested)
Lua:
-- Configuration
local doorsConfig = {
    [9000] = {doorID = 6907, requiredItems = {9020}, teleportPosition = Position(30998, 31642, 7), levelRequired = 50},
    [9001] = {doorID = 6907, requiredItems = {4033}, teleportPosition = Position(31020, 31592, 7), levelRequired = 60},
    [9002] = {doorID = 6907, requiredItems = {29347}, teleportPosition = Position(30923, 31636, 7), levelRequired = 70},
    [9003] = {doorID = 6907, requiredItems = {7425}, teleportPosition = Position(31016, 31590, 7), levelRequired = 80},
    [9004] = {doorID = 6907, requiredItems = {9692}, teleportPosition = Position(31045, 31821, 7), levelRequired = 90},
    [9005] = {doorID = 6898, requiredItems = {9017, 9383, 8820, 11701, 3206}, teleportPosition = Position(30927, 31689, 7), levelRequired = 100, requireAllItems = true},
}

-- true for debugging mode
local deBug = false

function getItemCount(player, requiredItems, requireAll)
    local itemCount = 0
    for _, itemId in ipairs(requiredItems) do
        local count = player:getItemCount(itemId)
        if requireAll then
            itemCount = math.min(itemCount == 0 and count or itemCount, count)
        else
            itemCount = itemCount + count
        end
    end
    return itemCount
end

function removeRequiredItems(player, requiredItems, count, requireAll)
    for _, itemId in ipairs(requiredItems) do
        local removeCount = requireAll and count or math.min(player:getItemCount(itemId), count)
        player:removeItem(itemId, removeCount)
        count = count - removeCount
        if count <= 0 then break end
    end
end

local action = Action()

function action.onUse(player, item, fromPosition, target, toPosition, isHotkey, actionID)
    if deBug then
        player:sendTextMessage(18, "Attempting to use the door.")
        player:sendTextMessage(18, "Item ID: " .. item.itemid .. ", Action ID: " .. actionID)
    end
    local doorConfig = doorsConfig[actionID]
    if doorConfig then
        if deBug then
            player:sendTextMessage(18, "Configuration found for action ID: " .. actionID)
            player:sendTextMessage(18, "Door ID in config: " .. doorConfig.doorID .. ", Required Items: " .. table.concat(doorConfig.requiredItems, ", "))
        end
        if item.itemid == doorConfig.doorID then
            if deBug then
                player:sendTextMessage(18, "The door ID matches configuration.")
            end
            -- Check the player's level
            if player:getLevel() < doorConfig.levelRequired then
                player:sendTextMessage(18, "You need to be at least level " .. doorConfig.levelRequired .. " to use this door.")
                return false
            end
            -- Calculate the number of items the player has
            local itemCount = getItemCount(player, doorConfig.requiredItems, doorConfig.requireAllItems)
            if itemCount > 0 then
                -- Remove the required items from the player's inventory
                removeRequiredItems(player, doorConfig.requiredItems, itemCount, doorConfig.requireAllItems)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have used the required items and the door opens.")
                player:teleportTo(doorConfig.teleportPosition)
                doorConfig.teleportPosition:sendMagicEffect(CONST_ME_TELEPORT)
                return true
            else
                player:sendTextMessage(18, "You need more items to use this door.")
                return false
            end
        else
            player:sendTextMessage(18, "The door ID does not match any configuration. Expected: " .. doorConfig.doorID .. ", Got: " .. item.itemid)
        end
    else
        player:sendTextMessage(18, "No configuration found for action ID: " .. actionID)
    end
    return false
end

for actionID, config in pairs(doorsConfig) do
    action:aid(actionID)
end

action:register()
Thank you, having fun with it =)
This is the result of your version.
04:30 The door seems to be sealed against unwanted intruders.

This version seems to work, closed thread.
Lua:
-- Configuration
local doorsConfig = {
    [9000] = {doorID = 6907, requiredItems = {9020}, useCount = 20, teleportPosition = Position(30998, 31642, 7), levelRequired = 50, unlockStorageID = 30000},
    [9001] = {doorID = 6907, requiredItems = {4033}, useCount = 20, teleportPosition = Position(31020, 31592, 7), levelRequired = 60, unlockStorageID = 30001},
    [9002] = {doorID = 6907, requiredItems = {29347}, useCount = 20, teleportPosition = Position(30923, 31636, 7), levelRequired = 70, unlockStorageID = 30002},
    [9003] = {doorID = 6907, requiredItems = {7425}, useCount = 20, teleportPosition = Position(31016, 31590, 7), levelRequired = 80, unlockStorageID = 30003},
    [9004] = {doorID = 6907, requiredItems = {9692}, useCount = 20, teleportPosition = Position(31045, 31821, 7), levelRequired = 90, unlockStorageID = 30004},
    [9005] = {doorID = 6898, requiredItems = {9017, 9383, 8820, 11701, 3206}, useCount = 20, teleportPosition = Position(30927, 31689, 7), levelRequired = 100, requireAllItems = true, unlockStorageID = 30005},
}

-- Debugging mode
local deBug = false

function getItemCount(player, requiredItems, requireAll)
    if requireAll then
        local minCount = nil
        for _, itemId in ipairs(requiredItems) do
            local count = player:getItemCount(itemId)
            if not minCount or count < minCount then
                minCount = count
            end
        end
        return minCount or 0
    else
        local itemCount = 0
        for _, itemId in ipairs(requiredItems) do
            itemCount = itemCount + player:getItemCount(itemId)
        end
        return itemCount
    end
end

function removeRequiredItems(player, requiredItems, count, requireAll)
    if requireAll then
        for _, itemId in ipairs(requiredItems) do
            player:removeItem(itemId, count)
        end
    else
        for _, itemId in ipairs(requiredItems) do
            local removeCount = math.min(player:getItemCount(itemId), count)
            player:removeItem(itemId, removeCount)
            count = count - removeCount
            if count <= 0 then break end
        end
    end
end

local function onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local actionID = item.actionid

    if deBug then
        player:sendTextMessage(18, "Attempting to use the door.")
        player:sendTextMessage(18, "Item ID: " .. item.itemid .. ", Action ID: " .. actionID)
    end

    local doorConfig = doorsConfig[actionID]

    if doorConfig then
        if deBug then
            player:sendTextMessage(18, "Configuration found for action ID: " .. actionID)
            player:sendTextMessage(18, "Door ID in config: " .. doorConfig.doorID .. ", Required Items: " .. table.concat(doorConfig.requiredItems, ", "))
        end

        if item.itemid == doorConfig.doorID then
            if deBug then
                player:sendTextMessage(18, "The door ID matches configuration.")
            end

            -- Check the player's level
            if player:getLevel() < doorConfig.levelRequired then
                player:sendTextMessage(18, "You need to be at least level " .. doorConfig.levelRequired .. " to use this door.")
                return false
            end

            -- Check if the door is already unlocked permanently
            if player:getStorageValue(doorConfig.unlockStorageID) == 1 then
                player:sendTextMessage(18, "You have been granted access.")
                player:teleportTo(doorConfig.teleportPosition)
                doorConfig.teleportPosition:sendMagicEffect(CONST_ME_TELEPORT)
                return true
            end

            -- Calculate the number of items the player has
            local itemCount = getItemCount(player, doorConfig.requiredItems, doorConfig.requireAllItems)
            local currentUseCount = player:getStorageValue(actionID)
            if currentUseCount < 0 then
                currentUseCount = 0
            end

            if itemCount > 0 then
                local remainingItemsRequired = doorConfig.useCount - currentUseCount
                local itemsToUse = math.min(itemCount, remainingItemsRequired)

                -- Remove the used items from the player's inventory
                removeRequiredItems(player, doorConfig.requiredItems, itemsToUse, doorConfig.requireAllItems)

                -- Update the use count
                currentUseCount = currentUseCount + itemsToUse
                player:setStorageValue(actionID, currentUseCount)

                -- If the new use count meets or exceeds the required use count
                if currentUseCount >= doorConfig.useCount then
                    player:setStorageValue(doorConfig.unlockStorageID, 1) -- Mark as permanently unlocked
                    player:setStorageValue(actionID, 1)
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have used the required items and the door is now permanently unlocked.")
                    player:teleportTo(doorConfig.teleportPosition)
                    doorConfig.teleportPosition:sendMagicEffect(CONST_ME_TELEPORT)
                    return true
                else
                    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have used some items. Use the door " .. (doorConfig.useCount - currentUseCount) .. " more times to permanently unlock it.")
                    return false
                end
            else
                player:sendTextMessage(18, "You need more items to use this door.")
                return false
            end
        else
            player:sendTextMessage(18, "The door ID does not match any configuration. Expected: " .. doorConfig.doorID .. ", Got: " .. item.itemid)
        end
    else
        player:sendTextMessage(18, "No configuration found for action ID: " .. actionID)
    end
    return false
end

local function registerActions()
    for actionID in pairs(doorsConfig) do
        local action = Action()
        action.onUse = function(player, item, fromPosition, target, toPosition, isHotkey)
            return onUse(player, item, fromPosition, target, toPosition, isHotkey)
        end
        action:aid(actionID)
        action:register()
    end
end

registerActions()
 
I just edited the version which @abdala ragab provided (not tested)
Sorry to tell you this, but your edits are not working
This version seems to work, closed thread.
I helped you and my script is working well I should get the best answer
Your new code only added 20 items in exchange for permanent access. Anyway, here is a clean code
Lua:
-- Configuration
local doorsConfig = {
    [9000] = {doorID = 6907, requiredItems = {9020}, useCount = 20, teleportPosition = Position(30998, 31642, 7), levelRequired = 50, unlockStorageID = 30000},
    [9001] = {doorID = 6907, requiredItems = {4033}, useCount = 20, teleportPosition = Position(31020, 31592, 7), levelRequired = 60, unlockStorageID = 30001},
    [9002] = {doorID = 6907, requiredItems = {29347}, useCount = 20, teleportPosition = Position(30923, 31636, 7), levelRequired = 70, unlockStorageID = 30002},
    [9003] = {doorID = 6907, requiredItems = {7425}, useCount = 20, teleportPosition = Position(31016, 31590, 7), levelRequired = 80, unlockStorageID = 30003},
    [9004] = {doorID = 6907, requiredItems = {9692}, useCount = 20, teleportPosition = Position(31045, 31821, 7), levelRequired = 90, unlockStorageID = 30004},
    [9005] = {doorID = 6898, requiredItems = {9017, 9383, 8820, 11701, 3206}, useCount = 20, teleportPosition = Position(30927, 31689, 7), levelRequired = 100, requireAllItems = true, unlockStorageID = 30005},
}

-- Function to calculate item count
local calculateItemCount = function(player, requiredItems, requireAll)
    if requireAll then
        local minCount
        for _, itemId in ipairs(requiredItems) do
            local count = player:getItemCount(itemId)
            if not minCount or count < minCount then
                minCount = count
            end
        end
        return minCount or 0
    else
        local itemCount = 0
        for _, itemId in ipairs(requiredItems) do
            itemCount = itemCount + player:getItemCount(itemId)
        end
        return itemCount
    end
end

-- Function to remove required items
local removeRequiredItems = function(player, requiredItems, count, requireAll)
    if requireAll then
        for _, itemId in ipairs(requiredItems) do
            player:removeItem(itemId, count)
        end
    else
        for _, itemId in ipairs(requiredItems) do
            local removeCount = math.min(player:getItemCount(itemId), count)
            player:removeItem(itemId, removeCount)
            count = count - removeCount
            if count <= 0 then break end
        end
    end
end

-- Main function to handle door usage
local onUse = function(player, item, fromPosition, target, toPosition, isHotkey)
    local actionID = item.actionid
    local doorConfig = doorsConfig[actionID]

    if doorConfig and item.itemid == doorConfig.doorID then
        if player:getLevel() < doorConfig.levelRequired then
            player:sendTextMessage(18, "You need to be at least level " .. doorConfig.levelRequired .. " to use this door.")
            return false
        end

        if player:getStorageValue(doorConfig.unlockStorageID) == 1 then
            player:sendTextMessage(18, "You have been granted access.")
            player:teleportTo(doorConfig.teleportPosition)
            doorConfig.teleportPosition:sendMagicEffect(CONST_ME_TELEPORT)
            return true
        end

        local itemCount = calculateItemCount(player, doorConfig.requiredItems, doorConfig.requireAllItems)
        local currentUseCount = player:getStorageValue(actionID) or 0

        if itemCount > 0 then
            local remainingItemsRequired = doorConfig.useCount - currentUseCount
            local itemsToUse = math.min(itemCount, remainingItemsRequired)
            removeRequiredItems(player, doorConfig.requiredItems, itemsToUse, doorConfig.requireAllItems)
            currentUseCount = currentUseCount + itemsToUse
            player:setStorageValue(actionID, currentUseCount)

            if currentUseCount >= doorConfig.useCount then
                player:setStorageValue(doorConfig.unlockStorageID, 1)
                player:setStorageValue(actionID, 1)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have used the required items and the door is now permanently unlocked.")
                player:teleportTo(doorConfig.teleportPosition)
                doorConfig.teleportPosition:sendMagicEffect(CONST_ME_TELEPORT)
                return true
            else
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have used some items. Use the door " .. (doorConfig.useCount - currentUseCount) .. " more times to permanently unlock it.")
                return false
            end
        else
            player:sendTextMessage(18, "You need more items to use this door.")
            return false
        end
    else
        player:sendTextMessage(18, "No configuration found for action ID: " .. actionID)
    end
    return false
end

-- Register actions
for actionID in pairs(doorsConfig) do
    local action = Action()
    action.onUse = function(player, item, fromPosition, target, toPosition, isHotkey)
        return onUse(player, item, fromPosition, target, toPosition, isHotkey)
    end
    action:aid(actionID)
    action:register()
end
 
Solution
Glad that @abdala ragab solved it. However, Evil said I have to agree. I took @Evil Hero script, made some small corrections, and tested it perfectly. His script is cleaner and better in terms of syntax, just that.

It is correct to use the code. See how to change it in a simple way and understand it better.
Lua:
-- Register actions
for actionID in pairs(doorsConfig) do
    local action = Action()
    action.onUse = function(player, item, fromPosition, target, toPosition, isHotkey)
        return onUse(player, item, fromPosition, target, toPosition, isHotkey)
    end
    action:aid(actionID)
    action:register()
end
chang to:
Lua:
for index, _ in pairs(doorsConfig) do
    action:aid(index)
end

action:register()
This table that I mentioned above is capable of checking the actionId in the doorsConfig table from 9000 to 90001 onwards.
This local action = Action() should always be above the function action.onUse(player, item, fromPosition, target, toPosition, isHotkey), and it cannot be at the top
1717426365288.png

So, in the end, check out the result of the script!
Lua:
local doorsConfig = {
    [9000] = {doorID = 6907, requiredItems = {{id = 9020, count = 2}}, teleportPosition = Position(1024, 991, 7), levelRequired = 50},
    [9001] = {doorID = 6907, requiredItems = {{id = 4033, count = 1}}, teleportPosition = Position(31020, 31592, 7), levelRequired = 60},
    [9002] = {doorID = 6907, requiredItems = {{id = 29347, count = 1}}, teleportPosition = Position(30923, 31636, 7), levelRequired = 70},
    [9003] = {doorID = 6907, requiredItems = {{id = 7425, count = 1}}, teleportPosition = Position(31016, 31590, 7), levelRequired = 80},
    [9004] = {doorID = 6907, requiredItems = {{id = 9692, count = 1}}, teleportPosition = Position(31045, 31821, 7), levelRequired = 90},
    [9005] = {doorID = 6898, requiredItems = {{id = 9017, count = 1}, {id = 9383, count = 1}, {id = 8820, count = 1}, {id = 11701, count = 1}, {id = 3206, count = 1}}, teleportPosition = Position(30927, 31689, 7), levelRequired = 100, requireAllItems = true},
}

local deBug = false

function getItemCount(player, requiredItems, requireAll)
    for _, item in ipairs(requiredItems) do
        local count = player:getItemCount(item.id)
        if requireAll and count < item.count then
            return 0
        elseif not requireAll and count >= item.count then
            return item.count
        end
    end
    return requireAll and 1 or 0
end

function removeRequiredItems(player, requiredItems, requireAll)
    for _, item in ipairs(requiredItems) do
        local removeCount = requireAll and item.count or math.min(player:getItemCount(item.id), item.count)
        player:removeItem(item.id, removeCount)
    end
end

local function getMissingItems(player, requiredItems)
    local missingItems = {}
    for _, item in ipairs(requiredItems) do
        local count = player:getItemCount(item.id)
        if count < item.count then
            table.insert(missingItems, {name = ItemType(item.id):getName(), needed = item.count - count})
        end
    end
    return missingItems
end

local action = Action()

function action.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    local actionID = item.actionid
    if deBug then
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Attempting to use the door.")
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Item ID: " .. item.itemid .. ", Action ID: " .. actionID)
    end
    local doorConfig = doorsConfig[actionID]
    if doorConfig then
        if deBug then
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Configuration found for action ID: " .. actionID)
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Door ID in config: " .. doorConfig.doorID .. ", Required Items: " .. table.concat(doorConfig.requiredItems, ", "))
        end
        if item.itemid == doorConfig.doorID then
            if deBug then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door ID matches configuration.")
            end
            -- Check the player's level
            if player:getLevel() < doorConfig.levelRequired then
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You need to be at least level " .. doorConfig.levelRequired .. " to use this door.")
                return false
            end
            -- Calculate the number of items the player has
            local itemCount = getItemCount(player, doorConfig.requiredItems, doorConfig.requireAllItems)
            if itemCount > 0 then
                -- Remove the required items from the player's inventory
                removeRequiredItems(player, doorConfig.requiredItems, doorConfig.requireAllItems)
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You have used the required items and the door opens.")
                player:teleportTo(doorConfig.teleportPosition)
                doorConfig.teleportPosition:sendMagicEffect(CONST_ME_TELEPORT)
                return true
            else
                local missingItems = getMissingItems(player, doorConfig.requiredItems)
                local missingMessage = "You need the following items to use this door:\n"
                for _, item in ipairs(missingItems) do
                    missingMessage = missingMessage .. item.name .. " x" .. item.needed .. "\n"
                end
                player:sendTextMessage(MESSAGE_EVENT_ADVANCE, missingMessage)
                return false
            end
        else
            player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "The door ID does not match any configuration. Expected: " .. doorConfig.doorID .. ", Got: " .. item.itemid)
        end
    else
        player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "No configuration found for action ID: " .. actionID)
    end
    return false
end

for index, _ in pairs(doorsConfig) do
    action:aid(index)
end

action:register()




gm.gif
 
Back
Top