• 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.2 - Can not sell items to NPCs

Dartedchaos

New Member
Joined
Jul 24, 2009
Messages
16
Reaction score
0
Code:
Druid: sell ham
Willie: Do you want to buy 1 ham for 8 gold coins?
Willie: Yeah, bye Druid Sample.

It will allow players to buy from NPC I just can not sell - works on other servers (the NPC)
 
Happy birthday

without a script we can not help you :D
Thank you :D assuming you are wanting NPC handler


NPC.lua
Lua:
-- 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 isItemStackable(itemid) then
        if inBackpacks then
            stuff = doCreateItemEx(backpack, 1)
            item = doAddContainerItem(stuff, itemid, math.min(100, amount))
        else
            stuff = doCreateItemEx(itemid, math.min(100, amount))
        end
        return doPlayerAddItemEx(cid, stuff, ignoreCap) ~= RETURNVALUE_NOERROR and 0 or amount, 0
    end

    local a = 0
    if inBackpacks then
        local container, b = doCreateItemEx(backpack, 1), 1
        for i = 1, amount do
            local item = doAddContainerItem(container, itemid, subType)
            if isInArray({(getContainerCapById(backpack) * b), amount}, i) then
                if doPlayerAddItemEx(cid, container, ignoreCap) ~= RETURNVALUE_NOERROR then
                    b = b - 1
                    break
                end

                a = i
                if amount > i then
                    container = doCreateItemEx(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 = doCreateItemEx(itemid, subType)
        if doPlayerAddItemEx(cid, item, ignoreCap) ~= RETURNVALUE_NOERROR then
            break
        end
        a = i
    end
    return a, 0
end

local func = function(cid, text, type, e, pcid)
    if isPlayer(pcid) then
        doCreatureSay(cid, text, type, false, pcid, getCreaturePosition(cid))
        e.done = TRUE
    end
end

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

function doPlayerTakeItem(cid, itemid, count)
    if getPlayerItemCount(cid,itemid) < count then
        return false
    end

    while count > 0 do
        local tempcount = 0
        if isItemStackable(itemid) then
            tempcount = math.min (100, count)
        else
            tempcount = 1
        end

        local ret = doPlayerRemoveItem(cid, itemid, tempcount)
        if ret ~= false then
            count = count - tempcount
        else
            return false
        end
    end

    if count ~= 0 then
        return false
    end
    return true
end

function doPlayerSellItem(cid, itemid, count, cost)
    if doPlayerTakeItem(cid, itemid, count) == true then
        if not doPlayerAddMoney(cid, cost) then
            error('Could not add money to ' .. getPlayerName(cid) .. '(' .. cost .. 'gp)')
        end
        return true
    end
    return false
end

function doPlayerBuyItemContainer(cid, containerid, itemid, count, cost, charges)
    if not doPlayerRemoveMoney(cid, cost) then
        return false
    end

    for i = 1, count do
        local container = doCreateItemEx(containerid, 1)
        for x = 1, getContainerCapById(containerid) do
            doAddContainerItem(container, itemid, charges)
        end

        if doPlayerAddItemEx(cid, 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

KeywordHandler.lua
Lua:
-- Advanced NPC System by Jiddo

if KeywordHandler == nil then
    KeywordNode = {
        keywords = nil,
        callback = nil,
        parameters = nil,
        children = nil,
        parent = nil
    }

    -- Created a new keywordnode with the given keywords, callback function and parameters and without any childNodes.
    function KeywordNode:new(keys, func, param)
        local obj = {}
        obj.keywords = keys
        obj.callback = func
        obj.parameters = param
        obj.children = {}
        setmetatable(obj, self)
        self.__index = self
        return obj
    end

    -- Calls the underlying callback function if it is not nil.
    function KeywordNode:processMessage(cid, message)
        return (self.callback == nil or self.callback(cid, message, self.keywords, self.parameters, self))
    end

    -- Returns true if message contains all patterns/strings found in keywords.
    function KeywordNode:checkMessage(message)
        if self.keywords.callback ~= nil then
            return self.keywords.callback(self.keywords, message)
        end

        for _, v in ipairs(self.keywords) do
            if type(v) == 'string' then
                local a, b = string.find(message, v)
                if a == nil or b == nil then
                    return false
                end
            end
        end
        return true
    end

    -- Returns the parent of this node or nil if no such node exists.
    function KeywordNode:getParent()
        return self.parent
    end

    -- Returns an array of the callback function parameters assosiated with this node.
    function KeywordNode:getParameters()
        return self.parameters
    end

    -- Returns an array of the triggering keywords assosiated with this node.
    function KeywordNode:getKeywords()
        return self.keywords
    end

    -- Adds a childNode to this node. Creates the childNode based on the parameters (k = keywords, c = callback, p = parameters)
    function KeywordNode:addChildKeyword(keywords, callback, parameters)
        local new = KeywordNode:new(keywords, callback, parameters)
        return self:addChildKeywordNode(new)
    end

    -- Adds a pre-created childNode to this node. Should be used for example if several nodes should have a common child.
    function KeywordNode:addChildKeywordNode(childNode)
        self.children[#self.children + 1] = childNode
        childNode.parent = self
        return childNode
    end

    KeywordHandler = {
        root = nil,
        lastNode = nil
    }

    -- Creates a new keywordhandler with an empty rootnode.
    function KeywordHandler:new()
        local obj = {}
        obj.root = KeywordNode:new(nil, nil, nil)
        obj.lastNode = {}
        setmetatable(obj, self)
        self.__index = self
        return obj
    end

    -- Resets the lastNode field, and this resetting the current position in the node hierarchy to root.
    function KeywordHandler:reset(cid)
        if self.lastNode[cid] then
            self.lastNode[cid] = nil
        end
    end

    -- Makes sure the correct childNode of lastNode gets a chance to process the message.
    function KeywordHandler:processMessage(cid, message)
        local node = self:getLastNode(cid)
        if node == nil then
            error('No root node found.')
            return false
        end

        local ret = self:processNodeMessage(node, cid, message)
        if ret then
            return true
        end

        if node:getParent() then
            node = node:getParent() -- Search through the parent.
            local ret = self:processNodeMessage(node, cid, message)
            if ret then
                return true
            end
        end

        if node ~= self:getRoot() then
            node = self:getRoot() -- Search through the root.
            local ret = self:processNodeMessage(node, cid, message)
            if ret then
                return true
            end
        end
        return false
    end

    -- Tries to process the given message using the node parameter's children and calls the node's callback function if found.
    --    Returns the childNode which processed the message or nil if no such node was found.
    function KeywordHandler:processNodeMessage(node, cid, message)
        local messageLower = string.lower(message)
        for i, childNode in pairs(node.children) do
            if childNode:checkMessage(messageLower) then
                local oldLast = self.lastNode[cid]
                self.lastNode[cid] = childNode
                childNode.parent = node -- Make sure node is the parent of childNode (as one node can be parent to several nodes).
                if childNode:processMessage(cid, message) then
                    return true
                end
                self.lastNode[cid] = oldLast
            end
        end
        return false
    end

    -- Returns the root keywordnode
    function KeywordHandler:getRoot()
        return self.root
    end

    -- Returns the last processed keywordnode or root if no last node is found.
    function KeywordHandler:getLastNode(cid)
        return self.lastNode[cid] or self:getRoot()
    end

    -- Adds a new keyword to the root keywordnode. Returns the new node.
    function KeywordHandler:addKeyword(keys, callback, parameters)
        return self:getRoot():addChildKeyword(keys, callback, parameters)
    end

    -- Moves the current position in the keyword hierarchy steps upwards. Steps defalut value = 1.
    function KeywordHandler:moveUp(cid, steps)
        if steps == nil or type(steps) ~= "number" then
            steps = 1
        end

        for i = 1, steps do
            if self.lastNode[cid] == nil then
                return nil
            end
            self.lastNode[cid] = self.lastNode[cid]:getParent() or self:getRoot()
        end
        return self.lastNode[cid]
    end
end

I have tried replacing the NPC System but they do not work for me even with corrections of right paths for including the scripts.


Here is Billy xml
XML:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Billy" script="Billy.lua" walkinterval="2000" floorchange="0">
    <health now="100" max="100" />
    <look type="153" head="78" body="63" legs="58" feet="115" addons="1" />
    <parameters>
        <parameter key="module_shop" value="1" />
        <parameter key="shop_buyable" value="bread,2689,3;cheese,2696,5;ham,2671,8;meat,2666,5" />
        <parameter key="shop_sellable" value="bread,2689,1;cheese,2696,2;ham,2671,4;meat,2666,2;carrot,2684,1;cherry,2679,1;egg,2328,1;salmon,2668,2;dead rat,2813,2" />
    </parameters>
</npc>


And here is the lua for him
Code:
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

function creatureSayCallback(cid, type, msg)
    if(npcHandler.focus ~= cid) then
        return false
    end

    -- NPC Billy feito por Rodrigo (Nottinghster)
    
    if msgcontains(msg, 'pan') then
    npcHandler:say('Have you found a pan for me?')
    talk_state = 1
    
    elseif msgcontains(msg, 'yes') and talk_state == 1 and getPlayerItemCount(cid, 2563) >= 1 then
    npcHandler:say('A pan! At last! Take this in case you eat something my cousin has cooked.')
    doPlayerRemoveItem(cid, 2563, 1)
    doPlayerAddItem(cid, 2266, 1)
setPlayerStorageValue(cid,3035,1)

    talk_state = 0
    
    elseif msgcontains(msg, 'yes') and talk_state == 1 and getPlayerItemCount(cid, 2563) == 0 then
    npcHandler:say('Hey! You don\'t have it!')
    talk_state = 0
    
    elseif msgcontains(msg, 'no') and talk_state == 1 then
    npcHandler:say('$&*@!')
    talk_state = 0
    
end
return true
end

local shopModule = ShopModule:new()
npcHandler:addModule(shopModule)

shopModule:addBuyableItem({'white mushroom'}, 2787, 6, 'white mushroom')
shopModule:addBuyableItem({'red mushroom'}, 2788, 12, 'red mushroom')
shopModule:addBuyableItem({'brown mushroom'}, 2789, 10, 'brown mushroom')
shopModule:addBuyableItem({'red apple'}, 2674, 3, 'red apple')
shopModule:addBuyableItem({'brown bread'}, 2691, 3, 'brown bread')
shopModule:addBuyableItem({'meat'}, 2666, 5, 'meat')
shopModule:addBuyableItem({'fish'}, 2667, 5, 'fish')
shopModule:addBuyableItem({'salmon'}, 2668, 5, 'salmon')
shopModule:addBuyableItem({'ham'}, 2671, 8, 'ham')
shopModule:addBuyableItem({'pear'}, 2673, 4, 'pear')
shopModule:addBuyableItem({'orange'}, 2675, 10, 'orange')
shopModule:addBuyableItem({'blueberry'}, 2677, 1, 'blueberry')
shopModule:addBuyableItem({'cherry'}, 2679, 1, 'cherry')
shopModule:addBuyableItem({'strawberry'}, 2680, 1, 'strawberry')
shopModule:addBuyableItem({'grape'}, 2680, 3, 'grape')
shopModule:addBuyableItem({'melon'}, 2682, 8, 'melon')
shopModule:addBuyableItem({'pumpkin'}, 2683, 10, 'pumpkin')
shopModule:addBuyableItem({'carrot'}, 2684, 3, 'carrot')
shopModule:addBuyableItem({'tomato'}, 2685, 5, 'tomato')
shopModule:addBuyableItem({'corncob'}, 2686, 3, 'corncob')
shopModule:addBuyableItem({'cookie'}, 2687, 2, 'cookie')
shopModule:addBuyableItem({'bread'}, 2689, 4, 'bread')
shopModule:addBuyableItem({'roll'}, 2690, 2, 'roll')
shopModule:addBuyableItem({'egg'}, 2695, 2, 'egg')
shopModule:addBuyableItem({'cookbook'}, 2347, 150, 'cookbook')

npcHandler:addModule(FocusModule:new())
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

The server mentions the map needs updated items.otb - but I don't think this has anything to do with the problem facing. As the items.xml ids match everything correctly for all my NPCs.
 
Back
Top