• 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 1.X+ [TFS 1.3]data/npc/lib/npc.lua:20: attempt to call method 'addItem' (a nil value)

Eduardo170

Well-Known Member
Joined
Jan 7, 2014
Messages
422
Solutions
3
Reaction score
66
Location
Caracas, Venezuela
This happen with all npcs, when I try buy but something.
Update: The problem happens when you enable option "buy with backpack" in trade window.

puff.png
I have vanilla TFS1.3

Code:
-- Including the Advanced NPC System
dofile('data/npc/lib/npcsystem/npcsystem.lua')

function msgcontains(message, keyword)
    local message, keyword = message:lower(), keyword:lower()
    if message == keyword then
        return true
    end

    return message:find(keyword) and not message:find('(%w+)' .. keyword)
end

function doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)
    local amount = amount or 1
    local subType = subType or 0
    local item = 0
    if ItemType(itemid):isStackable() then
        if inBackpacks then
            stuff = Game.createItem(backpack, 1)
            item = stuff:addItem(itemid, math.min(100, amount))
        else
            stuff = Game.createItem(itemid, math.min(100, amount))
        end
        return Player(cid):addItemEx(stuff, ignoreCap) ~= RETURNVALUE_NOERROR and 0 or amount, 0
    end

    local a = 0
    if inBackpacks then
        local container, b = Game.createItem(backpack, 1), 1
        for i = 1, amount do
            local item = container:addItem(itemid, subType)
            if table.contains({(ItemType(backpack):getCapacity() * b), amount}, i) then
                if Player(cid):addItemEx(container, ignoreCap) ~= RETURNVALUE_NOERROR then
                    b = b - 1
                    break
                end

                a = i
                if amount > i then
                    container = Game.createItem(backpack, 1)
                    b = b + 1
                end
            end
        end
        return a, b
    end

    for i = 1, amount do -- normal method for non-stackable items
        local item = Game.createItem(itemid, subType)
        if Player(cid):addItemEx(item, ignoreCap) ~= RETURNVALUE_NOERROR then
            break
        end
        a = i
    end
    return a, 0
end

local func = function(cid, text, type, e, pcid)
    if Player(pcid):isPlayer() then
        local creature = Creature(cid)
        creature:say(text, type, false, pcid, creature:getPosition())
        e.done = true
    end
end

function doCreatureSayWithDelay(cid, text, type, delay, e, pcid)
    if Player(pcid):isPlayer() then
        e.done = false
        e.event = addEvent(func, delay < 1 and 1000 or delay, cid, text, type, e, pcid)
    end
end

function doPlayerSellItem(cid, itemid, count, cost)
    local player = Player(cid)
    if player:removeItem(itemid, count) then
        if not player:addMoney(cost) then
            error('Could not add money to ' .. player:getName() .. '(' .. cost .. 'gp)')
        end
        return true
    end
    return false
end

function doPlayerBuyItemContainer(cid, containerid, itemid, count, cost, charges)
    local player = Player(cid)
    if not player:removeTotalMoney(cost) then
        return false
    end

    for i = 1, count do
        local container = Game.createItem(containerid, 1)
        for x = 1, ItemType(containerid):getCapacity() do
            container:addItem(itemid, charges)
        end

        if player:addItemEx(container, true) ~= RETURNVALUE_NOERROR then
            return false
        end
    end
    return true
end

function getCount(string)
    local b, e = string:find("%d+")
    return b and e and tonumber(string:sub(b, e)) or -1
end

function Player.removeTotalMoney(self, amount)
    local moneyCount = self:getMoney()
    local bankCount = self:getBankBalance()

    if amount <= moneyCount then
        self:removeMoney(amount)
        return true

    elseif amount <= (moneyCount + bankCount) then
        if moneyCount ~= 0 then
            self:removeMoney(moneyCount)
            local remains = amount - moneyCount
            self:setBankBalance(bankCount - remains)
            self:sendTextMessage(MESSAGE_INFO_DESCR, ("Paid %d from inventory and %d gold from bank account. Your account balance is now %d gold."):format(moneyCount, amount - moneyCount, self:getBankBalance()))
            return true
        else
            self:setBankBalance(bankCount - amount)
            self:sendTextMessage(MESSAGE_INFO_DESCR, ("Paid %d gold from bank account. Your account balance is now %d gold."):format(amount, self:getBankBalance()))
            return true
        end
    end
    return false
end

function Player.getTotalMoney(self)
    return self:getMoney() + self:getBankBalance()
end
 
Last edited:
Try this:

Lua:
function doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)
    local amount = amount or 1
    local subType = subType or 0
    local item = 0
    if ItemType(itemid):isStackable() then
        local stuff
        if inBackpacks then
            stuff = Game.createItem(backpack, 1)
            item = stuff:addItem(itemid, math.min(100, amount))
        else
            stuff = Game.createItem(itemid, math.min(100, amount))
        end
        return Player(cid):addItemEx(stuff, ignoreCap) ~= RETURNVALUE_NOERROR and 0 or amount, 0
    end

    local a = 0
    if inBackpacks then
        local container, b = Game.createItem(backpack, 1), 1
        for i = 1, amount do
            local item = container:addItem(itemid, subType)
            if table.contains({(ItemType(backpack):getCapacity() * b), amount}, i) then
                if Player(cid):addItemEx(container, ignoreCap) ~= RETURNVALUE_NOERROR then
                    b = b - 1
                    break
                end

                a = i
                if amount > i then
                    container = Game.createItem(backpack, 1)
                    b = b + 1
                end
            end
        end
        return a, b
    end

    for i = 1, amount do -- normal method for non-stackable items
        local item = Game.createItem(itemid, subType)
        if Player(cid):addItemEx(item, ignoreCap) ~= RETURNVALUE_NOERROR then
            break
        end
        a = i
    end
    return a, 0
end
 
Last edited:
Last edited:
Solution
Make sure you are passing proper value as backpack Id (newer tfs uses shopping bag, but it does not exist in 8.6) to the method. Looks like the backpack is never created which results in that error.
Ready I did. Thank you.


Change:
Code:
ITEM_SHOPPING_BAG
to
Code:
1988
example:
doNpcSellItem(cid, ITEM_LABEL, shop_amount[cid], shop_subtype[cid], true, false, 1988)
 
Last edited:
Back
Top