• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Lua Error on a upgrade system: attempt to index field '?' (a nil value)

1268995

Member
Joined
Sep 9, 2010
Messages
422
Reaction score
13
Hello, i am having this error on this upgrade system:

Code:
[13/07/2015 16:00:09] [Error - Action Interface]
[13/07/2015 16:00:09] data/actions/scripts/upgrade.lua:onUse
[13/07/2015 16:00:09] Description:
[13/07/2015 16:00:09] data/lib/upgradesystem.lua:60: attempt to index field '?' (a nil value)
[13/07/2015 16:00:09] stack traceback:
[13/07/2015 16:00:09]     data/lib/upgradesystem.lua:60: in function 'chance'
[13/07/2015 16:00:09]     data/lib/upgradesystem.lua:122: in function 'refine'
[13/07/2015 16:00:09]     data/actions/scripts/upgrade.lua:12: in function <data/actions/scripts/upgrade.lua:1>

upgrade.lua:
Code:
function onUse(cid, item, fromPosition, itemEx, toPosition)
    if isCreature(itemEx.uid) then 
        return doPlayerSendDefaultCancel(cid, RETURNVALUE_NOTPOSSIBLE)
    end

    local obj = UpgradeHandler:new(itemEx)

    if(obj == false) then
        return doPlayerSendCancel(cid, UpgradeHandler.message.notupgradeable)
    end

    local status = obj:refine(cid, item)
    if status == "success" then
        --doSendAnimatedText(toPosition, "Success!", COLOR_GREEN)
        doSendMagicEffect(toPosition, CONST_ME_MAGIC_GREEN)
    elseif status == "fail" then
        --doSendAnimatedText(toPosition, "Fail!", COLOR_RED)
        doSendMagicEffect(toPosition, CONST_ME_POFF)
    else
        doSendMagicEffect(toPosition, CONST_ME_POFF)
    end
    return true
end

upgradesystem.lua: (this is a lib)
Code:
--[[

    PERFECT UPGRADE SYSTEM
                2.0

    Criado por Oneshot

    É proibido a venda ou a cópia sem os devidos créditos desse script.

]]--

UpgradeHandler = {
    levels = {
        [1] = {100, false, false},
        [2] = {90, false, false},
        [3] = {75, false, false},
        [4] = {60, true, false},
        [5] = {45, true, false},
        [6] = {30, true, false},
        [7] = {25, true, false},
        [8] = {20, true, true},
        [9] = {15, true, true},
        [10] = {10, true, true},
        [11] = {10, true, true},
        [12] = {5, true, true}
    },
    broadcast = 7,
    attributes = {
        ["attack"] = 2,
        ["defense"] = 1,
        ["armor"] = 1
    },
    message = {
        console = "Trying to refine %s to level +%s with %s%% success rate.",
        success = "You have upgraded %s to level +%s",
        fail = "You have failed in upgrade of %s to level +%s",
        downgrade = "The upgrade level of %s has downgraded to +%s",
        erase = "The upgrade level of %s has been erased.",
        maxlevel = "The targeted %s is already on max upgrade level.",
        notupgradeable = "This item is not upgradeable.",
        broadcast = "The player %s was successful in upgrading %s to level +%s.\nCongratulations!!",
        invalidtool = "This is not a valid upgrade tool.",
        toolrange = "This upgrade tool can only be used in items with level between +%s and +%s"
    },
    tools = {
        [8306] = {range = {0, 10}, info = {chance = 0, removeable = true}},
    },

    isEquipment = function(self)
        local weaponType = self:getItemWeaponType()
        return ((weaponType > 0 and weaponType < 7) or self.item.armor ~= 0)
    end,

    setItemName = function(self, name)
        return doItemSetAttribute(self.item.uid, "name", name)
    end,

    chance = function(self)
        local chances = {}
        chances.upgrade = (self.levels[self.item.level + 1][1] or 100)
        chances.downgrade = (self.item.level * 5)
        chances.erase = (self.item.level * 3)

        return chances
    end
}

function UpgradeHandler:new(item)
    local obj, ret = {}
    obj.item = {}

    obj.item.level = 0
    obj.item.uid = item.uid
    for key, value in pairs(getItemInfo(item.itemid)) do
        obj.item[key] = value
    end

    ret = setmetatable(obj, {__index = function(self, index)
        if _G[index] then
            return (setmetatable({callback = _G[index]}, {__call = function(self, ...)
                return self.callback(item.uid, ...)
            end}))
        else
            return UpgradeHandler[index]
        end
    end})

    if ret:isEquipment() then
        ret:update()
        return ret
    end
    return false
end

function UpgradeHandler:update()
    self.item.level = (tonumber(self:getItemName():match("%+(%d+)")) or 0)
end

function UpgradeHandler:refine(uid, item)
    if not self.item then
        doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_BLUE, self.message.notupgradeable)
        return "miss"
    end 

    local tool = self.tools[item.itemid]

    if(tool == nil) then
        doPlayerSendTextMessage(uid, MESSAGE_EVENT_DEFAULT, self.message.invalidtool)
        return "miss"
    end

    if(self.item.level > #self.levels) then
        doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.maxlevel:format(self.item.name))
        return "miss"
    end

    if(self.item.level < tool.range[1] or self.item.level >= tool.range[2]) then
        doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.toolrange:format(unpack(tool.range)))
        return "miss"
    end

    local chance = (self:chance().upgrade + tool.info.chance)
    doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_BLUE, self.message.console:format(self.item.name, (self.item.level + 1), math.min(100, chance)))

    if(tool.info.removeable == true) then
        doRemoveItem(item.uid, 1)
    end

    if chance * 100 > math.random(1, 10000) then
        doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_ORANGE, self.message.success:format(self.item.name, (self.item.level + 1)))
        if (self.item.level + 1) >= self.broadcast then
            doBroadcastMessage(self.message.broadcast:format(getCreatureName(uid), self.item.name, (self.item.level + 1)))
        end

        self:setItemName((self.item.level > 0 and self:getItemName():gsub("%+(%d+)", "+".. (self.item.level + 1)) or (self:getItemName() .." +1")))
        for key, value in pairs(self.attributes) do
            if getItemAttribute(self.item.uid, key) ~= nil or self.item[key] ~= 0 then
                doItemSetAttribute(self.item.uid, key, (self.item.level > 0 and getItemAttribute(self.item.uid, key) or self.item[key]) + value)
            end
        end
        return "success"
    else
        if(self.levels[self.item.level][3] == true and (self:chance().erase * 100) > math.random(1, 10000)) then
            doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.erase:format(self.item.name))
            self:setItemName(self.item.name)
            for key, value in pairs(self.attributes) do
                if self.item[key] > 0 then
                    doItemSetAttribute(self.item.uid, key, self.item[key])
                end
            end
        elseif(self.levels[self.item.level][2] == true and (self:chance().downgrade * 100) > math.random(1, 10000)) then
            doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.downgrade:format(self.item.name, (self.item.level - 1)))
            self:setItemName((self.item.level == 1 and self.item.name or self:getItemName():gsub("%+(%d+)", "+".. (self.item.level - 1))))
            for key, value in pairs(self.attributes) do
                if getItemAttribute(self.item.uid, key) ~= nil or self.item[key] ~= 0 then
                    doItemSetAttribute(self.item.uid, key, (self.item[key] + value * (self.item.level - 1)))
                end
            end
        else
            doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.fail:format(self.item.name, (self.item.level + 1)))
        end
        return "fail"
    end
end
 
Last edited:
before that line do this:
print(self.levels[self.item.level + 1][1])

and tell me what you get.

I maded this way:
Code:
(...)
    print(self.levels[self.item.level + 1][1])
     chances.upgrade = (self.levels[self.item.level + 1][1] or 100)
(...)

And the same error appeared, and notthing appear on console. Only appear on console the same error.

I think the error are on upgrade.lua, line 12, that's the error gived on console
Code:
  local status = obj:refine(cid, item)  <- line 12
 
I maded this way:
Code:
(...)
    print(self.levels[self.item.level + 1][1])
     chances.upgrade = (self.levels[self.item.level + 1][1] or 100)
(...)

And the same error appeared, and notthing appear on console. Only appear on console the same error.

I think the error are on upgrade.lua, line 12, that's the error gived on console
Code:
  local status = obj:refine(cid, item)  <- line 12
The console lists where the error originates in order of execution. The error occurs at line 60, because the function at line 60 is called at line 122, which is called at line 12 of the other script. So line 60 is where the error is. It would be helpful if it would tell us which value is nil, but basically it's probably an issue with the table. replace the print with this one:
Code:
print(self.levels[self.item.level + 1])
And post the full error again
 
The console lists where the error originates in order of execution. The error occurs at line 60, because the function at line 60 is called at line 122, which is called at line 12 of the other script. So line 60 is where the error is. It would be helpful if it would tell us which value is nil, but basically it's probably an issue with the table. replace the print with this one:
Code:
print(self.levels[self.item.level + 1])
And post the full error again

i maded:

Code:
(...)
  print(self.levels[self.item.level + 1])
  chances.upgrade = (self.levels[self.item.level + 1][1] or 100)
(...)

And on console appear the error (the same?):

Code:
[13/07/2015 19:04:29] [Error - Action Interface]
[13/07/2015 19:04:29] data/actions/scripts/upgrade.lua:onUse
[13/07/2015 19:04:29] Description:
[13/07/2015 19:04:29] data/lib/upgradesystem.lua:61: attempt to index field '?' (a nil value)
[13/07/2015 19:04:29] stack traceback:
[13/07/2015 19:04:29]     data/lib/upgradesystem.lua:61: in function 'chance'
[13/07/2015 19:04:29]     data/lib/upgradesystem.lua:123: in function 'refine'
[13/07/2015 19:04:29]     data/actions/scripts/upgrade.lua:12: in function <data/actions/scripts/upgrade.lua:1>
 
nothing above the error in the console?
21dn137.jpg
 
at line 121 (or 122 now) just before
Code:
local chance = (self:chance().upgrade + tool.info.chance)
put
Code:
print(self.item.level)

I did:
Code:
(...)
    print(self.item.level)
    local chance = (self:chance().upgrade + tool.info.chance)
(...)

And appear on console ' 0 ' + the error .
 
Honestly, I have no idea. Looking at the code, it should be fine. it would be basically:
chances.upgrade = 100
self.levels is valid, self.levels at index 1 is valid, self.levels at index 1, at index 1 is valid
and chances.upgrade is a valid statement as well.

After reading through the script like 10 times, I'm not seeing why it's getting an error. Usually the error would mean you're trying to access an index that doesn't exist, but everything seems to exist in that function.
 
Honestly, I have no idea. Looking at the code, it should be fine. it would be basically:
chances.upgrade = 100
self.levels is valid, self.levels at index 1 is valid, self.levels at index 1, at index 1 is valid
and chances.upgrade is a valid statement as well.

After reading through the script like 10 times, I'm not seeing why it's getting an error. Usually the error would mean you're trying to access an index that doesn't exist, but everything seems to exist in that function.

Really thanks anyway!!!!

I also dont know why are giving this error >.<
 
This is a old script from other forum. His owner do not enter in the forum in like a year. Maybe @Limos has something to say :confused:
Well, you're not really supposed to tag individual users in the support forum. If anything, I would recommend upgrading to TFS 1.x if you haven't already, and use a different system, since there's plenty with the same features and more available around here
 
Well, you're not really supposed to tag individual users in the support forum. If anything, I would recommend upgrading to TFS 1.x if you haven't already, and use a different system, since there's plenty with the same features and more available around here

Ops sorry for that. Sorry limos xd

I cant update to tfs 1.x, my server are already online about 2 months, 15 player online +/- >.<

But thanks for ur time, help and attentions Buddy!

Maybe someone have another idea, i will wait!
 
razor solved your problem, but you did not change you code.

your
self.levels[self.item.level + 1]
is not table value.

now remove the prints and replace the error line with this.
(im not sure does value 0 means it will be 100% hopefully it does)

chances.upgrade = (self.levels[self.item.level] or 100)
 
Back
Top