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

TFS 0.X Some console errors related to tasks and movement script, any help?

mRefaat

Marketing and Coding
Joined
Jan 18, 2014
Messages
854
Solutions
3
Reaction score
141
Location
Egypt
Hello

I am using otx 2 which is based on 0.3.7
I found these errors in my console, if someone can help to understand them and fix them.

First error
Code:
[30/5/2021 5:39:3] [Error - NpcScript Interface]
[30/5/2021 5:39:3] data/npc/scripts/tasks.lua:onCreatureSay
[30/5/2021 5:39:3] Description:
[30/5/2021 5:39:3] data/npc/scripts/tasks.lua:55: attempt to perform arithmetic on field '?' (a nil value)
[30/5/2021 5:39:3] stack traceback:
[30/5/2021 5:39:3]     data/npc/scripts/tasks.lua:55: in function 'callback'
[30/5/2021 5:39:3]     data/npc/lib/npcsystem/npchandler.lua:458: in function 'onCreatureSay'
[30/5/2021 5:39:3]     data/npc/scripts/tasks.lua:8: in function <data/npc/scripts/tasks.lua:8>

Here you are the tasks NPC
Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
 
function onCreatureAppear(cid)                          npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid)                       npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg)                  npcHandler:onCreatureSay(cid, type, msg) end
function onThink()                                      npcHandler:onThink() end

local choose = {}
local cancel = {}
local available = {}
function creatureSayCallback(cid, type, msg)

    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_PRIVATE and 0 or cid
    
    if isInArray({"tasks", "task", "mission"}, msg:lower()) then
        local can = getTasksByPlayer(cid)
        if #can > 0 then
            local text = ""
            local sep = ", "
            table.sort(can, (function(a, b) return (a < b) end))
            local t = 0
            for _, id in ipairs(can) do
                t = t + 1
                if t == #can - 1 then
                    sep = " and "
                elseif t == #can then
                    sep = "."
                end
                text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep
            end
            selfSay("The current task" .. (#can > 1 and "s" or "") .. " that you can choose " .. (#can > 1 and "are" or "is") .. " " .. text, cid)
            talkState[talkUser] = 0
        else
            selfSay("I don't have any task for you right now.", cid)
        end
    elseif msg ~= "" and canStartTask(cid, msg) then
        if #getPlayerStartedTasks(cid) >= tasksByPlayer then
            selfSay("Sorry, but you already started " .. tasksByPlayer .. " tasks.", cid)
            return true
        end
        local task = getTaskByName(msg)
        if task and getCreatureStorage(cid, QUESTSTORAGE_BASE + task) > 0 then
            return false
        end
        selfSay("In this task you must defeat " .. tasks[task].killsRequired .. " " .. tasks[task].raceName .. ". Are you sure that you want to start this task?", cid)
        choose[cid] = task
        talkState[talkUser] = 1
    elseif msg:lower() == "yes" and talkState[talkUser] == 1 then
        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + choose[cid], 1)
        selfSay("Excellent! You can check the status of your task saying report to me.", cid)
        choose[cid] = nil
        talkState[talkUser] = 0
    elseif msg:lower() == "report" then
        local started = getPlayerStartedTasks(cid)
        local finishedAtLeastOne = false
        local finished = 0
        if started and #started > 0 then
            for _, id in ipairs(started) do
                if getCreatureStorage(cid, KILLSSTORAGE_BASE + id) >= tasks[id].killsRequired then
                    for _, reward in ipairs(tasks[id].rewards) do
                        local deny = false
                        if reward.storage then
                            if getCreatureStorage(cid, reward.storage[1]) >= reward.storage[2] then
                                deny = true
                            end
                        end
                        if isInArray({REWARD_MONEY, "money"}, reward.type:lower()) and not deny then
                            doPlayerAddMoney(cid, reward.value[1])
                        elseif isInArray({REWARD_EXP, "exp", "experience"}, reward.type:lower()) and not deny then
                            doPlayerAddLevel(cid, reward.value[1])
                            doPlayerSendDefaultCancel(cid, "You gained " .. reward.value[1] .. " experience points.")
                        elseif isInArray({REWARD_ACHIEVEMENT, "achievement", "ach"}, reward.type:lower()) and not deny then
                            if doPlayerAddAchievement then
                                doPlayerAddAchievement(cid, reward.value[1], true)
                            end
                        elseif isInArray({REWARD_STORAGE, "storage", "stor"}, reward.type:lower()) and not deny then
                            doCreatureSetStorage(cid, reward.value[1], reward.value[2])
                        elseif isInArray({REWARD_POINT, "points", "point"}, reward.type:lower()) and not deny then
                            doCreatureSetStorage(cid, POINTSSTORAGE, getCreatureStorage(cid, POINTSSTORAGE) + reward.value[1])
                        elseif isInArray({REWARD_ITEM, "item", "items", "object"}, reward.type:lower()) and not deny then
                            doPlayerAddItem(cid, reward.value[1], reward.value[2])
                        end
                        
                        if reward.storage then
                            doCreatureSetStorage(cid, reward.storage[1], reward.storage[2])
                        end
                    end
                    
                    if tasks[id].norepeatable then
                        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + id, 2)
                    else
                        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + id, 0)
                    end
                    doCreatureSetStorage(cid, KILLSSTORAGE_BASE + id, 0)
                    if getCreatureStorage(cid, REPEATSTORAGE_BASE + id) < 1 then
                        doCreatureSetStorage(cid, REPEATSTORAGE_BASE + id, 0)
                    end
                    doCreatureSetStorage(cid, REPEATSTORAGE_BASE + id, getCreatureStorage(cid, REPEATSTORAGE_BASE + id) + 1)
                    finishedAtLeastOne = true
                    finished = finished + 1
                end
            end
            
            if not finishedAtLeastOne then
                selfSay("You haven't finished any task yet.", cid)
            else
                selfSay("Awesome! you finished " .. (finished > 1 and "various" or "a") .. " task" .. (finished > 1 and "s" or "") .. ". Talk to me again if you want to start a task.", cid)
            end
        else
            selfSay("You haven't started any task yet.", cid)
        end   
    elseif msg:lower() == "started" then
        local started = getPlayerStartedTasks(cid)
        if started and #started > 0 then
            local text = ""
            local sep = ", "
            table.sort(started, (function(a, b) return (a < b) end))
            local t = 0
            for _, id in ipairs(started) do
                t = t + 1
                if t == #started - 1 then
                    sep = " and "
                elseif t == #started then
                    sep = "."
                end
                text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep
            end
            
            selfSay("The current task" .. (#started > 1 and "s" or "") .. " that you started " .. (#started > 1 and "are" or "is") .. " " .. text, cid)
        else
            selfSay("You haven't started any task yet.", cid)
        end
    elseif msg:lower() == "cancel" then
        local started = getPlayerStartedTasks(cid)
        if started and #started > 0 then
            selfSay("Cancelling a task will make the count restart. Wich task you want to cancel?", cid)
            talkState[talkUser] = 2
        else
            selfSay("You haven't started any task yet.", cid)
        end
    elseif getTaskByName(msg) and talkState[talkUser] == 2 and isInArray(getPlayerStartedTasks(cid), getTaskByName(msg)) then
        local task = getTaskByName(msg)
        if getCreatureStorage(cid, KILLSSTORAGE_BASE + task) > 0 then
            selfSay("You currently killed " .. getCreatureStorage(cid, KILLSSTORAGE_BASE + task) .. "/" .. tasks[task].killsRequired .. " " .. tasks[task].raceName .. ". Cancelling this task will restart the count. Are you sure you want to cancel this task?", cid)
        else
            selfSay("Are you sure you want to cancel this task?", cid)
        end
        talkState[talkUser] = 3
        cancel[cid] = task
    elseif msg:lower() == "yes" and talkState[talkUser] == 3 then
        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + cancel[cid], -1)
        doCreatureSetStorage(cid, KILLSSTORAGE_BASE + cancel[cid], -1)
        selfSay("You have cancelled the task " .. (tasks[cancel[cid]].name or tasks[cancel[cid]].raceName) .. ".", cid)
        talkState[talkUser] = 0
    elseif isInArray({"points", "rank"}, msg:lower()) then
        selfSay("At this time, you have " .. getCreatureStorage(cid, POINTSSTORAGE) .. " Paw & Fur points. You " .. (getPlayerRank(cid) == 5 and "are an Elite Hunter" or getPlayerRank(cid) == 4 and "are a Trophy Hunter" or getPlayerRank(cid) == 3 and "are a Big Game Hunter" or getPlayerRank(cid) == 2 and "are a Ranger" or getPlayerRank(cid) == 1 and "are a Huntsman" or "haven't been ranked yet") .. ".", cid)
        talkState[talkUser] = 0
    end
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())


Second error
Code:
[29/5/2021 21:6:57] [Error - MoveEvents Interface]
[29/5/2021 21:6:57] data/movements/scripts/custom/items_attributes/items_attributes.lua:onEquip
[29/5/2021 21:6:57] Description:
[29/5/2021 21:6:57] (luaCallFunction) Item not found

And the script
Lua:
local config = {
    -- magic longsword
    [2390] = {
        attack_speed = 0,    -- attack speed %
        life_leech = 0,    -- life leech %
        mana_leech = 0,        -- mana leech %
        critical_chance = 1    -- critical hit chance %
    }
}

function onEquip(cid, item, slot, boolean)
    if boolean == false then
        if isPlayer(cid) then
            local item_id = config[item.id]
            if item_id then
                setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) + item_id.life_leech)    -- life leech
                setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) + item_id.mana_leech)    -- mana leech
                setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) + item_id.attack_speed)    -- attack speed
                setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) + item_id.critical_chance)    -- critical hit chance
            end
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end

function onDeEquip(cid, item, slot, boolean)
    if isPlayer(cid) then
        local item_id = config[item.id]
        if item_id then
            setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) - item_id.life_leech)    -- life leech
            setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) - item_id.mana_leech)    -- mana leech
            setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) - item_id.attack_speed)    -- attack speed
            setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) - item_id.critical_chance)    -- critical hit chance
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end

Any help?
 
lemme know if you got same/other errors
Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
 
function onCreatureAppear(cid)                          npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid)                       npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg)                  npcHandler:onCreatureSay(cid, type, msg) end
function onThink()                                      npcHandler:onThink() end

local choose = {}
local cancel = {}
local available = {}
function creatureSayCallback(cid, type, msg)

    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_PRIVATE and 0 or cid
   
    if isInArray({"tasks", "task", "mission"}, msg:lower()) then
        local can = getTasksByPlayer(cid)
        if #can > 0 then
            local text = ""
            local sep = ", "
            table.sort(can, (function(a, b) return (a < b) end))
            local t = 0
            for _, id in ipairs(can) do
                t = t + 1
                if t == #can - 1 then
                    sep = " and "
                elseif t == #can then
                    sep = "."
                end
                text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep
            end
            selfSay("The current task" .. (#can > 1 and "s" or "") .. " that you can choose " .. (#can > 1 and "are" or "is") .. " " .. text, cid)
            talkState[talkUser] = 0
        else
            selfSay("I don't have any task for you right now.", cid)
        end
    elseif msg ~= "" and canStartTask(cid, msg) then
        if #getPlayerStartedTasks(cid) >= tasksByPlayer then
            selfSay("Sorry, but you already started " .. tasksByPlayer .. " tasks.", cid)
            return true
        end
        local task = getTaskByName(msg)
        if task and getCreatureStorage(cid, QUESTSTORAGE_BASE + task) > 0 then
            return false
        end
        selfSay("In this task you must defeat " .. tasks[task].killsRequired .. " " .. tasks[task].raceName .. ". Are you sure that you want to start this task?", cid)
        choose[cid] = task
        talkState[talkUser] = 1
    elseif msg:lower() == "yes" and talkState[talkUser] == 1 then
        choose[cid] = task
    if QUESTSTORAGE_BASE and choose[cid] then
        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + choose[cid], 1)
        selfSay("Excellent! You can check the status of your task saying report to me.", cid)
        choose[cid] = nil
        talkState[talkUser] = 0
    else
        selfSay("Something went wrong! report that to ADM Oxygen", cid)
    end
    elseif msg:lower() == "report" then
        local started = getPlayerStartedTasks(cid)
        local finishedAtLeastOne = false
        local finished = 0
        if started and #started > 0 then
            for _, id in ipairs(started) do
                if getCreatureStorage(cid, KILLSSTORAGE_BASE + id) >= tasks[id].killsRequired then
                    for _, reward in ipairs(tasks[id].rewards) do
                        local deny = false
                        if reward.storage then
                            if getCreatureStorage(cid, reward.storage[1]) >= reward.storage[2] then
                                deny = true
                            end
                        end
                        if isInArray({REWARD_MONEY, "money"}, reward.type:lower()) and not deny then
                            doPlayerAddMoney(cid, reward.value[1])
                        elseif isInArray({REWARD_EXP, "exp", "experience"}, reward.type:lower()) and not deny then
                            doPlayerAddLevel(cid, reward.value[1])
                            doPlayerSendDefaultCancel(cid, "You gained " .. reward.value[1] .. " experience points.")
                        elseif isInArray({REWARD_ACHIEVEMENT, "achievement", "ach"}, reward.type:lower()) and not deny then
                            if doPlayerAddAchievement then
                                doPlayerAddAchievement(cid, reward.value[1], true)
                            end
                        elseif isInArray({REWARD_STORAGE, "storage", "stor"}, reward.type:lower()) and not deny then
                            doCreatureSetStorage(cid, reward.value[1], reward.value[2])
                        elseif isInArray({REWARD_POINT, "points", "point"}, reward.type:lower()) and not deny then
                            doCreatureSetStorage(cid, POINTSSTORAGE, getCreatureStorage(cid, POINTSSTORAGE) + reward.value[1])
                        elseif isInArray({REWARD_ITEM, "item", "items", "object"}, reward.type:lower()) and not deny then
                            doPlayerAddItem(cid, reward.value[1], reward.value[2])
                        end
                       
                        if reward.storage then
                            doCreatureSetStorage(cid, reward.storage[1], reward.storage[2])
                        end
                    end
                   
                    if tasks[id].norepeatable then
                        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + id, 2)
                    else
                        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + id, 0)
                    end
                    doCreatureSetStorage(cid, KILLSSTORAGE_BASE + id, 0)
                    if getCreatureStorage(cid, REPEATSTORAGE_BASE + id) < 1 then
                        doCreatureSetStorage(cid, REPEATSTORAGE_BASE + id, 0)
                    end
                    doCreatureSetStorage(cid, REPEATSTORAGE_BASE + id, getCreatureStorage(cid, REPEATSTORAGE_BASE + id) + 1)
                    finishedAtLeastOne = true
                    finished = finished + 1
                end
            end
           
            if not finishedAtLeastOne then
                selfSay("You haven't finished any task yet.", cid)
            else
                selfSay("Awesome! you finished " .. (finished > 1 and "various" or "a") .. " task" .. (finished > 1 and "s" or "") .. ". Talk to me again if you want to start a task.", cid)
            end
        else
            selfSay("You haven't started any task yet.", cid)
        end  
    elseif msg:lower() == "started" then
        local started = getPlayerStartedTasks(cid)
        if started and #started > 0 then
            local text = ""
            local sep = ", "
            table.sort(started, (function(a, b) return (a < b) end))
            local t = 0
            for _, id in ipairs(started) do
                t = t + 1
                if t == #started - 1 then
                    sep = " and "
                elseif t == #started then
                    sep = "."
                end
                text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep
            end
           
            selfSay("The current task" .. (#started > 1 and "s" or "") .. " that you started " .. (#started > 1 and "are" or "is") .. " " .. text, cid)
        else
            selfSay("You haven't started any task yet.", cid)
        end
    elseif msg:lower() == "cancel" then
        local started = getPlayerStartedTasks(cid)
        if started and #started > 0 then
            selfSay("Cancelling a task will make the count restart. Wich task you want to cancel?", cid)
            talkState[talkUser] = 2
        else
            selfSay("You haven't started any task yet.", cid)
        end
    elseif getTaskByName(msg) and talkState[talkUser] == 2 and isInArray(getPlayerStartedTasks(cid), getTaskByName(msg)) then
        local task = getTaskByName(msg)
        if getCreatureStorage(cid, KILLSSTORAGE_BASE + task) > 0 then
            selfSay("You currently killed " .. getCreatureStorage(cid, KILLSSTORAGE_BASE + task) .. "/" .. tasks[task].killsRequired .. " " .. tasks[task].raceName .. ". Cancelling this task will restart the count. Are you sure you want to cancel this task?", cid)
        else
            selfSay("Are you sure you want to cancel this task?", cid)
        end
        talkState[talkUser] = 3
        cancel[cid] = task
    elseif msg:lower() == "yes" and talkState[talkUser] == 3 then
        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + cancel[cid], -1)
        doCreatureSetStorage(cid, KILLSSTORAGE_BASE + cancel[cid], -1)
        selfSay("You have cancelled the task " .. (tasks[cancel[cid]].name or tasks[cancel[cid]].raceName) .. ".", cid)
        talkState[talkUser] = 0
    elseif isInArray({"points", "rank"}, msg:lower()) then
        selfSay("At this time, you have " .. getCreatureStorage(cid, POINTSSTORAGE) .. " Paw & Fur points. You " .. (getPlayerRank(cid) == 5 and "are an Elite Hunter" or getPlayerRank(cid) == 4 and "are a Trophy Hunter" or getPlayerRank(cid) == 3 and "are a Big Game Hunter" or getPlayerRank(cid) == 2 and "are a Ranger" or getPlayerRank(cid) == 1 and "are a Huntsman" or "haven't been ranked yet") .. ".", cid)
        talkState[talkUser] = 0
    end
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
Code:
local config = {
    -- magic longsword
    [2390] = {
        attack_speed = 0,    -- attack speed %
        life_leech = 0,    -- life leech %
        mana_leech = 0,        -- mana leech %
        critical_chance = 1    -- critical hit chance %
    }
}

function onEquip(cid, item, slot, boolean)
    if boolean == false and config[item.id] then
        if isPlayer(cid) then
            local item_id = config[item.id]
            if item_id then
                setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) + item_id.life_leech)    -- life leech
                setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) + item_id.mana_leech)    -- mana leech
                setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) + item_id.attack_speed)    -- attack speed
                setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) + item_id.critical_chance)    -- critical hit chance
            end
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end

function onDeEquip(cid, item, slot, boolean)
    if isPlayer(cid) and config [item.id] then
        local item_id = config[item.id]
        if item_id then
            setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) - item_id.life_leech)    -- life leech
            setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) - item_id.mana_leech)    -- mana leech
            setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) - item_id.attack_speed)    -- attack speed
            setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) - item_id.critical_chance)    -- critical hit chance
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end
 
Last edited by a moderator:
lemme know if you got same/other errors
Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
 
function onCreatureAppear(cid)                          npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid)                       npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg)                  npcHandler:onCreatureSay(cid, type, msg) end
function onThink()                                      npcHandler:onThink() end

local choose = {}
local cancel = {}
local available = {}
function creatureSayCallback(cid, type, msg)

    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_PRIVATE and 0 or cid
  
    if isInArray({"tasks", "task", "mission"}, msg:lower()) then
        local can = getTasksByPlayer(cid)
        if #can > 0 then
            local text = ""
            local sep = ", "
            table.sort(can, (function(a, b) return (a < b) end))
            local t = 0
            for _, id in ipairs(can) do
                t = t + 1
                if t == #can - 1 then
                    sep = " and "
                elseif t == #can then
                    sep = "."
                end
                text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep
            end
            selfSay("The current task" .. (#can > 1 and "s" or "") .. " that you can choose " .. (#can > 1 and "are" or "is") .. " " .. text, cid)
            talkState[talkUser] = 0
        else
            selfSay("I don't have any task for you right now.", cid)
        end
    elseif msg ~= "" and canStartTask(cid, msg) then
        if #getPlayerStartedTasks(cid) >= tasksByPlayer then
            selfSay("Sorry, but you already started " .. tasksByPlayer .. " tasks.", cid)
            return true
        end
        local task = getTaskByName(msg)
        if task and getCreatureStorage(cid, QUESTSTORAGE_BASE + task) > 0 then
            return false
        end
        selfSay("In this task you must defeat " .. tasks[task].killsRequired .. " " .. tasks[task].raceName .. ". Are you sure that you want to start this task?", cid)
        choose[cid] = task
        talkState[talkUser] = 1
    elseif msg:lower() == "yes" and talkState[talkUser] == 1 then
        choose[cid] = task
    if QUESTSTORAGE_BASE and choose[cid] then
        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + choose[cid], 1)
        selfSay("Excellent! You can check the status of your task saying report to me.", cid)
        choose[cid] = nil
        talkState[talkUser] = 0
    else
        selfSay("Something went wrong! report that to ADM Oxygen", cid)
    end
    elseif msg:lower() == "report" then
        local started = getPlayerStartedTasks(cid)
        local finishedAtLeastOne = false
        local finished = 0
        if started and #started > 0 then
            for _, id in ipairs(started) do
                if getCreatureStorage(cid, KILLSSTORAGE_BASE + id) >= tasks[id].killsRequired then
                    for _, reward in ipairs(tasks[id].rewards) do
                        local deny = false
                        if reward.storage then
                            if getCreatureStorage(cid, reward.storage[1]) >= reward.storage[2] then
                                deny = true
                            end
                        end
                        if isInArray({REWARD_MONEY, "money"}, reward.type:lower()) and not deny then
                            doPlayerAddMoney(cid, reward.value[1])
                        elseif isInArray({REWARD_EXP, "exp", "experience"}, reward.type:lower()) and not deny then
                            doPlayerAddLevel(cid, reward.value[1])
                            doPlayerSendDefaultCancel(cid, "You gained " .. reward.value[1] .. " experience points.")
                        elseif isInArray({REWARD_ACHIEVEMENT, "achievement", "ach"}, reward.type:lower()) and not deny then
                            if doPlayerAddAchievement then
                                doPlayerAddAchievement(cid, reward.value[1], true)
                            end
                        elseif isInArray({REWARD_STORAGE, "storage", "stor"}, reward.type:lower()) and not deny then
                            doCreatureSetStorage(cid, reward.value[1], reward.value[2])
                        elseif isInArray({REWARD_POINT, "points", "point"}, reward.type:lower()) and not deny then
                            doCreatureSetStorage(cid, POINTSSTORAGE, getCreatureStorage(cid, POINTSSTORAGE) + reward.value[1])
                        elseif isInArray({REWARD_ITEM, "item", "items", "object"}, reward.type:lower()) and not deny then
                            doPlayerAddItem(cid, reward.value[1], reward.value[2])
                        end
                      
                        if reward.storage then
                            doCreatureSetStorage(cid, reward.storage[1], reward.storage[2])
                        end
                    end
                  
                    if tasks[id].norepeatable then
                        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + id, 2)
                    else
                        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + id, 0)
                    end
                    doCreatureSetStorage(cid, KILLSSTORAGE_BASE + id, 0)
                    if getCreatureStorage(cid, REPEATSTORAGE_BASE + id) < 1 then
                        doCreatureSetStorage(cid, REPEATSTORAGE_BASE + id, 0)
                    end
                    doCreatureSetStorage(cid, REPEATSTORAGE_BASE + id, getCreatureStorage(cid, REPEATSTORAGE_BASE + id) + 1)
                    finishedAtLeastOne = true
                    finished = finished + 1
                end
            end
          
            if not finishedAtLeastOne then
                selfSay("You haven't finished any task yet.", cid)
            else
                selfSay("Awesome! you finished " .. (finished > 1 and "various" or "a") .. " task" .. (finished > 1 and "s" or "") .. ". Talk to me again if you want to start a task.", cid)
            end
        else
            selfSay("You haven't started any task yet.", cid)
        end 
    elseif msg:lower() == "started" then
        local started = getPlayerStartedTasks(cid)
        if started and #started > 0 then
            local text = ""
            local sep = ", "
            table.sort(started, (function(a, b) return (a < b) end))
            local t = 0
            for _, id in ipairs(started) do
                t = t + 1
                if t == #started - 1 then
                    sep = " and "
                elseif t == #started then
                    sep = "."
                end
                text = text .. "{" .. (tasks[id].name or tasks[id].raceName) .. "}" .. sep
            end
          
            selfSay("The current task" .. (#started > 1 and "s" or "") .. " that you started " .. (#started > 1 and "are" or "is") .. " " .. text, cid)
        else
            selfSay("You haven't started any task yet.", cid)
        end
    elseif msg:lower() == "cancel" then
        local started = getPlayerStartedTasks(cid)
        if started and #started > 0 then
            selfSay("Cancelling a task will make the count restart. Wich task you want to cancel?", cid)
            talkState[talkUser] = 2
        else
            selfSay("You haven't started any task yet.", cid)
        end
    elseif getTaskByName(msg) and talkState[talkUser] == 2 and isInArray(getPlayerStartedTasks(cid), getTaskByName(msg)) then
        local task = getTaskByName(msg)
        if getCreatureStorage(cid, KILLSSTORAGE_BASE + task) > 0 then
            selfSay("You currently killed " .. getCreatureStorage(cid, KILLSSTORAGE_BASE + task) .. "/" .. tasks[task].killsRequired .. " " .. tasks[task].raceName .. ". Cancelling this task will restart the count. Are you sure you want to cancel this task?", cid)
        else
            selfSay("Are you sure you want to cancel this task?", cid)
        end
        talkState[talkUser] = 3
        cancel[cid] = task
    elseif msg:lower() == "yes" and talkState[talkUser] == 3 then
        doCreatureSetStorage(cid, QUESTSTORAGE_BASE + cancel[cid], -1)
        doCreatureSetStorage(cid, KILLSSTORAGE_BASE + cancel[cid], -1)
        selfSay("You have cancelled the task " .. (tasks[cancel[cid]].name or tasks[cancel[cid]].raceName) .. ".", cid)
        talkState[talkUser] = 0
    elseif isInArray({"points", "rank"}, msg:lower()) then
        selfSay("At this time, you have " .. getCreatureStorage(cid, POINTSSTORAGE) .. " Paw & Fur points. You " .. (getPlayerRank(cid) == 5 and "are an Elite Hunter" or getPlayerRank(cid) == 4 and "are a Trophy Hunter" or getPlayerRank(cid) == 3 and "are a Big Game Hunter" or getPlayerRank(cid) == 2 and "are a Ranger" or getPlayerRank(cid) == 1 and "are a Huntsman" or "haven't been ranked yet") .. ".", cid)
        talkState[talkUser] = 0
    end
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
Code:
local config = {
    -- magic longsword
    [2390] = {
        attack_speed = 0,    -- attack speed %
        life_leech = 0,    -- life leech %
        mana_leech = 0,        -- mana leech %
        critical_chance = 1    -- critical hit chance %
    }
}

function onEquip(cid, item, slot, boolean)
    if boolean == false and config[item.id] then
        if isPlayer(cid) then
            local item_id = config[item.id]
            if item_id then
                setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) + item_id.life_leech)    -- life leech
                setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) + item_id.mana_leech)    -- mana leech
                setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) + item_id.attack_speed)    -- attack speed
                setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) + item_id.critical_chance)    -- critical hit chance
            end
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end

function onDeEquip(cid, item, slot, boolean)
    if isPlayer(cid) and config [item.id] then
        local item_id = config[item.id]
        if item_id then
            setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) - item_id.life_leech)    -- life leech
            setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) - item_id.mana_leech)    -- mana leech
            setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) - item_id.attack_speed)    -- attack speed
            setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) - item_id.critical_chance)    -- critical hit chance
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end
Still having these errors.
 
Still having these errors.
Error #1 is having an issue with QUESTSTORAGE_BASE since it is not defined in the script anywhere. hence the nil value issue.

Solution: define the storage value somewhere. local QUESTSTORAGE_BASE = 11111

Error #2 is probably related to lines 14 & 28. change item.id to item.itemid
 
Error #1 is having an issue with QUESTSTORAGE_BASE since it is not defined in the script anywhere. hence the nil value issue.

Solution: define the storage value somewhere. local QUESTSTORAGE_BASE = 11111

Error #2 is probably related to lines 14 & 28. change item.id to item.itemid
QUESTSTORAGE_BASE is defined in lib file into libs. (should be defined here too?)
Also item.itemid didn't fix the problem of item not found.
 
QUESTSTORAGE_BASE is defined in lib file into libs. (should be defined here too?)
Also item.itemid didn't fix the problem of item not found.
Can you show the line/lines in lib you've used? Also the file you've placed it into?

--
second issue, use this.
I've put the callFunction inside the boolean check, and removed boolean from onDeEquip, since I don't think deEquip even has the boolean parameter anyway.
Also removed the useless isPlayer check, since an npc / monster can't equip items.. it's always going to be true. lol

Lua:
local config = {
    -- magic longsword
    [2390] = {
        life_leech = 0,    -- life leech %
        mana_leech = 0,        -- mana leech %
        attack_speed = 0,    -- attack speed %
        critical_chance = 1    -- critical hit chance %
    }
}

function onEquip(cid, item, slot, boolean)
    if boolean == false then
        local item_id = config[item.itemid]
        if item_id then
            setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) + item_id.life_leech)    -- life leech
            setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) + item_id.mana_leech)    -- mana leech
            setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) + item_id.attack_speed)    -- attack speed
            setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) + item_id.critical_chance)    -- critical hit chance
        end
        return callFunction(cid, item.uid, slot, boolean)
    end
    return true
end

function onDeEquip(cid, item, slot)
    local item_id = config[item.itemid]
    if item_id then
        setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) - item_id.life_leech)    -- life leech
        setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) - item_id.mana_leech)    -- mana leech
        setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) - item_id.attack_speed)    -- attack speed
        setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) - item_id.critical_chance)    -- critical hit chance
    end
    return callFunction(cid, item.uid, slot)
end
 
Can you show the line/lines in lib you've used? Also the file you've placed it into?

--
second issue, use this.
I've put the callFunction inside the boolean check, and removed boolean from onDeEquip, since I don't think deEquip even has the boolean parameter anyway.
Also removed the useless isPlayer check, since an npc / monster can't equip items.. it's always going to be true. lol

Lua:
local config = {
    -- magic longsword
    [2390] = {
        life_leech = 0,    -- life leech %
        mana_leech = 0,        -- mana leech %
        attack_speed = 0,    -- attack speed %
        critical_chance = 1    -- critical hit chance %
    }
}

function onEquip(cid, item, slot, boolean)
    if boolean == false then
        local item_id = config[item.itemid]
        if item_id then
            setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) + item_id.life_leech)    -- life leech
            setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) + item_id.mana_leech)    -- mana leech
            setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) + item_id.attack_speed)    -- attack speed
            setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) + item_id.critical_chance)    -- critical hit chance
        end
        return callFunction(cid, item.uid, slot, boolean)
    end
    return true
end

function onDeEquip(cid, item, slot)
    local item_id = config[item.itemid]
    if item_id then
        setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) - item_id.life_leech)    -- life leech
        setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) - item_id.mana_leech)    -- mana leech
        setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) - item_id.attack_speed)    -- attack speed
        setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) - item_id.critical_chance)    -- critical hit chance
    end
    return callFunction(cid, item.uid, slot)
end
items issue (2nd issue)

now when you equip the item and it has stats from items.xml no work.
also when you sell an item which you are equipping, you get item not found error.
 
Alright, so first error again..

The problem is here
Lua:
        local task = getTaskByName(msg)
        if task and getCreatureStorage(cid, QUESTSTORAGE_BASE + task) > 0 then
            return false
        end
the function getTaskByName either returns a number, or false, if it can't find anything.

If this function returns false, it will get past this if statement and set itself into memory
Lua:
choose[cid] = task

At that point, when you say yes to start the task, you get the nil value arithmetic issue because you can't add false with a number.

So we just need to fix this issue.. and it should be good to go.

I believe this if statement is trying to determine if the task exists, and if it's been started previously.
I'm a bit confused, because it feels like the function canStartTask should already be checking this.. but no harm in checking again I guess.

Assuming that's what is intended.... separating these checks into their own if statements should be fine, and solve the issue.

Lua:
        local task = getTaskByName(msg)
        if not task or getCreatureStorage(cid, QUESTSTORAGE_BASE + task) > 0 then
            return false
        end

Done.
----
Okay.. this second issue.. ugh. xD

I can't remember how I solved this issue on my server... and I have no idea if we can even solve it for an otx server or not.

But.. 🤷‍♂️ we'll try.

Gonna add a bunch of prints to figure out wtf is going on. xD
Show us what happens in the console.

Lua:
local config = {
    -- magic longsword
    [2390] = {
        life_leech = 0,    -- life leech %
        mana_leech = 0,        -- mana leech %
        attack_speed = 0,    -- attack speed %
        critical_chance = 1    -- critical hit chance %
    }
}

function onEquip(cid, item, slot, boolean)
    print("Equipping Item..")
    print("cid = " .. cid)
    print("item = " .. item.uid)
    print("itemid = " .. item.itemid)
    print("slot = " .. slot)
    print("boolean = " .. boolean)
    if boolean == false then
        print("checking if storages need to be altered..")
        local item_id = config[item.itemid]
        if item_id then
            setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) + item_id.life_leech)    -- life leech
            setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) + item_id.mana_leech)    -- mana leech
            setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) + item_id.attack_speed)    -- attack speed
            setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) + item_id.critical_chance)    -- critical hit chance
            print("altering storages..")
        end
        print("Successfully Equipped.")
    end
    return callFunction(cid, item.uid, slot, boolean)
end

function onDeEquip(cid, item, slot)
    print("DeEquipping Item..")
    print("cid = " .. cid)
    print("item = " .. item.uid)
    print("itemid = " .. item.itemid)
    print("slot = " .. slot)
    print("checking if storages need to be altered..")
    local item_id = config[item.itemid]
    if item_id then
        setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) - item_id.life_leech)    -- life leech
        setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) - item_id.mana_leech)    -- mana leech
        setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) - item_id.attack_speed)    -- attack speed
        setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) - item_id.critical_chance)    -- critical hit chance
        print("altering storages..")
    end
    print("Successfully DeEquipped.")
    return callFunction(cid, item.uid, slot)
end
 
Alright, so first error again..

The problem is here
Lua:
        local task = getTaskByName(msg)
        if task and getCreatureStorage(cid, QUESTSTORAGE_BASE + task) > 0 then
            return false
        end
the function getTaskByName either returns a number, or false, if it can't find anything.

If this function returns false, it will get past this if statement and set itself into memory
Lua:
choose[cid] = task

At that point, when you say yes to start the task, you get the nil value arithmetic issue because you can't add false with a number.

So we just need to fix this issue.. and it should be good to go.

I believe this if statement is trying to determine if the task exists, and if it's been started previously.
I'm a bit confused, because it feels like the function canStartTask should already be checking this.. but no harm in checking again I guess.

Assuming that's what is intended.... separating these checks into their own if statements should be fine, and solve the issue.

Lua:
        local task = getTaskByName(msg)
        if not task or getCreatureStorage(cid, QUESTSTORAGE_BASE + task) > 0 then
            return false
        end

Done.
----
Okay.. this second issue.. ugh. xD

I can't remember how I solved this issue on my server... and I have no idea if we can even solve it for an otx server or not.

But.. 🤷‍♂️ we'll try.

Gonna add a bunch of prints to figure out wtf is going on. xD
Show us what happens in the console.

Lua:
local config = {
    -- magic longsword
    [2390] = {
        life_leech = 0,    -- life leech %
        mana_leech = 0,        -- mana leech %
        attack_speed = 0,    -- attack speed %
        critical_chance = 1    -- critical hit chance %
    }
}

function onEquip(cid, item, slot, boolean)
    print("Equipping Item..")
    print("cid = " .. cid)
    print("item = " .. item.uid)
    print("itemid = " .. item.itemid)
    print("slot = " .. slot)
    print("boolean = " .. boolean)
    if boolean == false then
        print("checking if storages need to be altered..")
        local item_id = config[item.itemid]
        if item_id then
            setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) + item_id.life_leech)    -- life leech
            setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) + item_id.mana_leech)    -- mana leech
            setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) + item_id.attack_speed)    -- attack speed
            setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) + item_id.critical_chance)    -- critical hit chance
            print("altering storages..")
        end
        print("Successfully Equipped.")
    end
    return callFunction(cid, item.uid, slot, boolean)
end

function onDeEquip(cid, item, slot)
    print("DeEquipping Item..")
    print("cid = " .. cid)
    print("item = " .. item.uid)
    print("itemid = " .. item.itemid)
    print("slot = " .. slot)
    print("checking if storages need to be altered..")
    local item_id = config[item.itemid]
    if item_id then
        setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) - item_id.life_leech)    -- life leech
        setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) - item_id.mana_leech)    -- mana leech
        setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) - item_id.attack_speed)    -- attack speed
        setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) - item_id.critical_chance)    -- critical hit chance
        print("altering storages..")
    end
    print("Successfully DeEquipped.")
    return callFunction(cid, item.uid, slot)
end
First of all, thanks for trying to help.

Regarding first error:
I don't know how to reproduce it.
I made the change and will wait if i find this error in my console again or not and will give you feedback about it.

Regarding second error:
I don't know also how to reproduce it (OnEquip).
I added the checks and prints and got this error
Code:
Equipping Item..
cid = 268481052
item = 70027
itemid = 2390
slot = 6

[16:53:29.762] [Error - MoveEvents Interface]
[16:53:29.762] data/movements/scripts/custom/items_attributes/items_attributes - test.lua:onEquip
[16:53:29.767] Description:
[16:53:29.768] ...ipts/custom/items_attributes/items_attributes - test.lua:17: attempt to concatenate local 'boolean' (a boolean value)
[16:53:29.771] stack traceback:
[16:53:29.772]  ...ipts/custom/items_attributes/items_attributes - test.lua:17: in function <...ipts/custom/items_attributes/items_attributes - test.lua:11>
I commented the print of boolean and tested again, here is the result.
Code:
Equipping Item..
cid = 268481052
item = 70027
itemid = 2390
slot = 6
Equipping Item..
cid = 268481052
item = 70027
itemid = 2390
slot = 6
Equipping Item..
cid = 268481052
item = 70027
itemid = 2390
slot = 6
checking if storages need to be altered..
altering storages..
Successfully Equipped.
DeEquipping Item..
cid = 268481052
item = 70027
itemid = 2390
slot = 6
checking if storages need to be altered..
altering storages..
Successfully DeEquipped.

[16:56:39.584] [Error - MoveEvents Interface]
[16:56:39.585] data/movements/scripts/custom/items_attributes/items_attributes - test.lua:onDeEquip
[16:56:39.587] Description:
[16:56:39.587] (MoveEventScript::luaCallFunction) Item not found

After using this changes here: (the error of item not found related to onEquip disappeared but sometimes i find onDeEquip error)
Lua:
function onEquip(cid, item, slot, boolean)
    if boolean == false then
        if isPlayer(cid) then
            local item_id = config[item.itemid]
            if item_id then
                setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) + item_id.life_leech)    -- life leech
                setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) + item_id.mana_leech)    -- mana leech
                setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) + item_id.attack_speed)    -- attack speed
                setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) + item_id.critical_chance)    -- critical hit chance
            end
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end

function onDeEquip(cid, item, slot, boolean)
    if isPlayer(cid) then
        local item_id = config[item.itemid]
        if item_id then
            setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) - item_id.life_leech)    -- life leech
            setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) - item_id.mana_leech)    -- mana leech
            setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) - item_id.attack_speed)    -- attack speed
            setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) - item_id.critical_chance)    -- critical hit chance
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end
Error: (i can make this error appear by selling the item i wear using a key)
Code:
[11:32:46.177] [Error - MoveEvents Interface]
[11:32:46.177] data/movements/scripts/custom/items_attributes/items_attributes.lua:onDeEquip
[11:32:46.177] Description:
[11:32:46.177] (luaCallFunction) Item not found
 
First of all, thanks for trying to help.

Regarding first error:
I don't know how to reproduce it.
I made the change and will wait if i find this error in my console again or not and will give you feedback about it.

Regarding second error:
I don't know also how to reproduce it (OnEquip).
I added the checks and prints and got this error
Code:
Equipping Item..
cid = 268481052
item = 70027
itemid = 2390
slot = 6

[16:53:29.762] [Error - MoveEvents Interface]
[16:53:29.762] data/movements/scripts/custom/items_attributes/items_attributes - test.lua:onEquip
[16:53:29.767] Description:
[16:53:29.768] ...ipts/custom/items_attributes/items_attributes - test.lua:17: attempt to concatenate local 'boolean' (a boolean value)
[16:53:29.771] stack traceback:
[16:53:29.772]  ...ipts/custom/items_attributes/items_attributes - test.lua:17: in function <...ipts/custom/items_attributes/items_attributes - test.lua:11>
I commented the print of boolean and tested again, here is the result.
Code:
Equipping Item..
cid = 268481052
item = 70027
itemid = 2390
slot = 6
Equipping Item..
cid = 268481052
item = 70027
itemid = 2390
slot = 6
Equipping Item..
cid = 268481052
item = 70027
itemid = 2390
slot = 6
checking if storages need to be altered..
altering storages..
Successfully Equipped.
DeEquipping Item..
cid = 268481052
item = 70027
itemid = 2390
slot = 6
checking if storages need to be altered..
altering storages..
Successfully DeEquipped.

[16:56:39.584] [Error - MoveEvents Interface]
[16:56:39.585] data/movements/scripts/custom/items_attributes/items_attributes - test.lua:onDeEquip
[16:56:39.587] Description:
[16:56:39.587] (MoveEventScript::luaCallFunction) Item not found

After using this changes here: (the error of item not found related to onEquip disappeared but sometimes i find onDeEquip error)
Lua:
function onEquip(cid, item, slot, boolean)
    if boolean == false then
        if isPlayer(cid) then
            local item_id = config[item.itemid]
            if item_id then
                setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) + item_id.life_leech)    -- life leech
                setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) + item_id.mana_leech)    -- mana leech
                setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) + item_id.attack_speed)    -- attack speed
                setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) + item_id.critical_chance)    -- critical hit chance
            end
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end

function onDeEquip(cid, item, slot, boolean)
    if isPlayer(cid) then
        local item_id = config[item.itemid]
        if item_id then
            setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) - item_id.life_leech)    -- life leech
            setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) - item_id.mana_leech)    -- mana leech
            setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) - item_id.attack_speed)    -- attack speed
            setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) - item_id.critical_chance)    -- critical hit chance
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end
Error: (i can make this error appear by selling the item i wear using a key)
Code:
[11:32:46.177] [Error - MoveEvents Interface]
[11:32:46.177] data/movements/scripts/custom/items_attributes/items_attributes.lua:onDeEquip
[11:32:46.177] Description:
[11:32:46.177] (luaCallFunction) Item not found
Alright, I'm fairly convinced onDeEquip doesn't require the call function.

Try changing that to return true instead of return callFunction
 
Alright, I'm fairly convinced onDeEquip doesn't require the call function.

Try changing that to return true instead of return callFunction
Using return true made the error disappear but another problem happened (if the item has attributes from items.xml and you take it off, the attributes effect still there and you have to relog to remove this effect)
I found this problem before and that's why i used callFunction
 
@Xikini
Regarding to error 1, i never saw it again after your edit.
Regarding to error 2, still having it and it shows OnEquip error and OnDeEquip errors
The script i am using

Lua:
local config = {
    -- magic longsword
    [2390] = {
        attack_speed = 0,    -- attack speed %
        life_leech = 0,    -- life leech %
        mana_leech = 0,        -- mana leech %
        critical_chance = 1    -- critical hit chance %
    }
}

function onEquip(cid, item, slot, boolean)
    if boolean == false then
        if isPlayer(cid) then
            local item_id = config[item.itemid]
            if item_id then
                setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) + item_id.life_leech)    -- life leech
                setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) + item_id.mana_leech)    -- mana leech
                setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) + item_id.attack_speed)    -- attack speed
                setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) + item_id.critical_chance)    -- critical hit chance
            end
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end

function onDeEquip(cid, item, slot, boolean)
    if isPlayer(cid) then
        local item_id = config[item.itemid]
        if item_id then
            setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) - item_id.life_leech)    -- life leech
            setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) - item_id.mana_leech)    -- mana leech
            setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) - item_id.attack_speed)    -- attack speed
            setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) - item_id.critical_chance)    -- critical hit chance
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end

---------------------
Another bug i got here with tasks system and it happens rarely but i don't know why (the kills reset when you are doing the task)
Code:
15:43 334/500 Amumus and Teemos already killed.
 15:43 1/500 Amumus and Teemos already killed.

The on kill script
Lua:
 function onKill(cid, target, lastHit)
    local started = getPlayerStartedTasks(cid)
    if isPlayer(target) then
        return true
    end
    if started and #started > 0 then
        for _, id in ipairs(started) do
            if isInArray(tasks[id].creatures, getCreatureName(target):lower()) then
                if getCreatureStorage(cid, KILLSSTORAGE_BASE + id) == -1 then
                    doCreatureSetStorage(cid, KILLSSTORAGE_BASE + id, 0)
                end
                if getCreatureStorage(cid, KILLSSTORAGE_BASE + id) < tasks[id].killsRequired then
                    doCreatureSetStorage(cid, KILLSSTORAGE_BASE + id, getCreatureStorage(cid, KILLSSTORAGE_BASE + id) + 1)
                    doPlayerSendChannelMessage(cid, '', getCreatureStorage(cid, KILLSSTORAGE_BASE + id) .. "/" .. tasks[id].killsRequired .. " " .. tasks[id].raceName .. " already killed.", TALKTYPE_CHANNEL_O, 10)
                end
            end
        end
    end
    return true
end
 
The on kill script
Lua:
 function onKill(cid, target, lastHit)
    local started = getPlayerStartedTasks(cid)
    if isPlayer(target) then
        return true
    end
    if started and #started > 0 then
        for _, id in ipairs(started) do
            if isInArray(tasks[id].creatures, getCreatureName(target):lower()) then
                if getCreatureStorage(cid, KILLSSTORAGE_BASE + id) == -1 then
                    doCreatureSetStorage(cid, KILLSSTORAGE_BASE + id, 0)
                end
                if getCreatureStorage(cid, KILLSSTORAGE_BASE + id) < tasks[id].killsRequired then
                    doCreatureSetStorage(cid, KILLSSTORAGE_BASE + id, getCreatureStorage(cid, KILLSSTORAGE_BASE + id) + 1)
                    doPlayerSendChannelMessage(cid, '', getCreatureStorage(cid, KILLSSTORAGE_BASE + id) .. "/" .. tasks[id].killsRequired .. " " .. tasks[id].raceName .. " already killed.", TALKTYPE_CHANNEL_O, 10)
                end
            end
        end
    end
    return true
end
Start with making the script more readable:
Lua:
function onKill(cid, target, lastHit)
    if isPlayer(target) then
        return true
    end
    local started = getPlayerStartedTasks(cid)
    for _, id in ipairs(started) do
        if isInArray(tasks[id].creatures, getCreatureName(target):lower()) then
            local taskId = KILLSSTORAGE_BASE + id
            local task = tasks[id]
            local killedStor = getCreatureStorage(cid, taskId)
            if killedStor == -1 then
                doCreatureSetStorage(cid, taskId, 0)
            end
            if getCreatureStorage(cid, taskId) < task.killsRequired then
                doCreatureSetStorage(cid, taskId, killedStor + 1)
                doPlayerSendChannelMessage(cid, '', (killedStor + 1) .. "/" .. task.killsRequired .. " " .. task.raceName .. " already killed.", TALKTYPE_CHANNEL_O, 10)
            end
        end
    end
    return true
end

Check player's started tasks after checking the target. No need to waste resources on pointless operations.
You don't need to check if started if you dont return nil. You probably return {} if player has no started tasks so no need to check.
Save killed monsters storage in variable to not read it few times.
Reseting storage to 1 probably is in other script.
 
Start with making the script more readable:
Lua:
function onKill(cid, target, lastHit)
    if isPlayer(target) then
        return true
    end
    local started = getPlayerStartedTasks(cid)
    for _, id in ipairs(started) do
        if isInArray(tasks[id].creatures, getCreatureName(target):lower()) then
            local taskId = KILLSSTORAGE_BASE + id
            local task = tasks[id]
            local killedStor = getCreatureStorage(cid, taskId)
            if killedStor == -1 then
                doCreatureSetStorage(cid, taskId, 0)
            end
            if getCreatureStorage(cid, taskId) < task.killsRequired then
                doCreatureSetStorage(cid, taskId, killedStor + 1)
                doPlayerSendChannelMessage(cid, '', (killedStor + 1) .. "/" .. task.killsRequired .. " " .. task.raceName .. " already killed.", TALKTYPE_CHANNEL_O, 10)
            end
        end
    end
    return true
end

Check player's started tasks after checking the target. No need to waste resources on pointless operations.
You don't need to check if started if you dont return nil. You probably return {} if player has no started tasks so no need to check.
Save killed monsters storage in variable to not read it few times.
Reseting storage to 1 probably is in other script.
Thanks for helping.
But no other scripts using this storage and here is the only place resetting the kills while you make on kill event so i moved this line doCreatureSetStorage(cid, KILLSSTORAGE_BASE + choose[cid], 0) to npc script when you take the task so you start from 0 not -1
Post automatically merged:

@Xikini
Regarding to error 1, i never saw it again after your edit.
Regarding to error 2, still having it and it shows OnEquip error and OnDeEquip errors
The script i am using

Lua:
local config = {
    -- magic longsword
    [2390] = {
        attack_speed = 0,    -- attack speed %
        life_leech = 0,    -- life leech %
        mana_leech = 0,        -- mana leech %
        critical_chance = 1    -- critical hit chance %
    }
}

function onEquip(cid, item, slot, boolean)
    if boolean == false then
        if isPlayer(cid) then
            local item_id = config[item.itemid]
            if item_id then
                setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) + item_id.life_leech)    -- life leech
                setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) + item_id.mana_leech)    -- mana leech
                setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) + item_id.attack_speed)    -- attack speed
                setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) + item_id.critical_chance)    -- critical hit chance
            end
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end

function onDeEquip(cid, item, slot, boolean)
    if isPlayer(cid) then
        local item_id = config[item.itemid]
        if item_id then
            setPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.life_leech_storage) - item_id.life_leech)    -- life leech
            setPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage, getPlayerStorageValue(cid, PlayerStorageKeys.mana_leech_storage) - item_id.mana_leech)    -- mana leech
            setPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage, getPlayerStorageValue(cid, PlayerStorageKeys.attack_speed_storage) - item_id.attack_speed)    -- attack speed
            setPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage, getPlayerStorageValue(cid, PlayerStorageKeys.critical_chance_storage) - item_id.critical_chance)    -- critical hit chance
        end
    end
    return callFunction(cid, item.uid, slot, boolean)
end

---------------------
Another bug i got here with tasks system and it happens rarely but i don't know why (the kills reset when you are doing the task)
Code:
15:43 334/500 Amumus and Teemos already killed.
 15:43 1/500 Amumus and Teemos already killed.

The on kill script
Lua:
 function onKill(cid, target, lastHit)
    local started = getPlayerStartedTasks(cid)
    if isPlayer(target) then
        return true
    end
    if started and #started > 0 then
        for _, id in ipairs(started) do
            if isInArray(tasks[id].creatures, getCreatureName(target):lower()) then
                if getCreatureStorage(cid, KILLSSTORAGE_BASE + id) == -1 then
                    doCreatureSetStorage(cid, KILLSSTORAGE_BASE + id, 0)
                end
                if getCreatureStorage(cid, KILLSSTORAGE_BASE + id) < tasks[id].killsRequired then
                    doCreatureSetStorage(cid, KILLSSTORAGE_BASE + id, getCreatureStorage(cid, KILLSSTORAGE_BASE + id) + 1)
                    doPlayerSendChannelMessage(cid, '', getCreatureStorage(cid, KILLSSTORAGE_BASE + id) .. "/" .. tasks[id].killsRequired .. " " .. tasks[id].raceName .. " already killed.", TALKTYPE_CHANNEL_O, 10)
                end
            end
        end
    end
    return true
end
Update about how to reproduce the both errors (OnEquip and OnDeEquip)

OnEquip appear when you make a quest for example:
(armor) it goes to your backpack in these cases.
first case: if you are not wearing armor, error appears.
second case: if you are wearing armor, no error.
Small note: if you did a quest with item which are not used in this script it goes to your slot not backpack.

OnDeEquip appear when you are wearing (armor) and remove it (i am using a key which is used to sell items that's how armor removed)

Update,
Error 1 still there 😢🤷🤦‍♂️
 
Last edited:

Similar threads

Back
Top