• 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!
  • New resources must be posted under Resources tab. A discussion thread will be created automatically, you can't open threads manually anymore.

NPC That sell player items when he is offline/hunt for TFS 0.3

Gesior.pl

Mega Noob&LOL 2012
Senator
Joined
Sep 18, 2007
Messages
2,987
Solutions
102
Reaction score
3,436
Location
Poland
GitHub
gesior
elitedeath posted good idea for NPC. I tried to make this NPC.
Player can give this NPC items and set price for each item type.
Other player can come and say:
offer of Player Name - show offer of player with nick XX in 'trade' window
search Item Name - show 5 cheapest offers of item with name XX in form:
19:59 Cheapest offers of stone skin amulet:
50 gp (charges: 15) - Banatoorooo
1000000 gp (charges: 5) - Banatoorooo
All commands and how to use NPC say when player say "how to use":
19:59 GOD Gesior [150]: how to use
19:59 Shopper: What you want to do? Say {add my item to offer}, {get my item from offer}, {check how much money from items I have}, {get my cash from items}, {change price ofitem in offer}, {buy item of other player} or {search item}.
19:59 GOD Gesior [150]: add my item to offer
19:59 Shopper: First put your item in left hand (under BP slot), then say {add item xx} where xx is number of items that you want add to offer, then NPC will ask you for price, say{price yy}, where yy is price for 1 item.
-----------------------------------
NPC lua script:
PHP:
-- shop system
function getOfferOfPlayer(name)
    local offer = {}
    local result_items = db.getResult("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `name` = " .. db.escapeString(name) .. " AND `count` > '0' AND `itemid` != '66'")
    if(result_items:getID() ~= -1) then
        while(true) do
            table.insert(offer, {id = result_items:getDataInt("id"), name = result_items:getDataString("name"), item_name = result_items:getDataString("item_name"), itemid = result_items:getDataInt("itemid"), subType = result_items:getDataInt("subType"), count = result_items:getDataInt("count"), price = result_items:getDataInt("price")})
                if not(result_items:next()) then
                    break
                end
        end
        result_items:free()
    end
    return offer
end

function getOfferOfItem(item_name)
    local offer = {}
    result_items = db.getResult("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `item_name` = " .. db.escapeString(item_name) .. " AND `count` > '0' AND `itemid` != '66' ORDER BY `price` ASC LIMIT 5")
    if(result_items:getID() ~= -1) then
        while(true) do
            table.insert(offer, {id = result_items:getDataInt("id"), name = result_items:getDataString("name"), item_name = result_items:getDataString("item_name"), itemid = result_items:getDataInt("itemid"), subType = result_items:getDataInt("subType"), count = result_items:getDataInt("count"), price = result_items:getDataInt("price")})
                if not(result_items:next()) then
                    break
                end
        end
        result_items:free()
    end
    return offer
end

function addItemToOffer(name, itemid, subType, count)
    local inDB_id = 0
    local result_offers = db.getResult("SELECT `id`, `count` FROM `ots_playersshopsystem` WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'")
    if(result_offers:getID() ~= -1) then
        inDB_id = result_offers:getDataInt("id")
        result_offers:free()
    end
    if inDB_id ~= 0 then
        db.executeQuery("UPDATE `ots_playersshopsystem` SET `count` = `ots_playersshopsystem`.`count` + " .. count .." WHERE `id` = '" .. inDB_id .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'")
    else
        db.executeQuery("INSERT INTO `ots_playersshopsystem` (`id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price`) VALUES (NULL, " .. db.escapeString(name) .. ", " .. db.escapeString(getItemNameById(itemid)) .. ", '" .. itemid .. "', '" .. subType .. "', '" .. count .. "', 1000000)")
    end
    return true
end

function removeItemsFromOffer(name, itemid, subType, count)
    db.executeQuery("UPDATE `ots_playersshopsystem` SET `count` = `ots_playersshopsystem`.`count` - " .. count .." WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'")
    return true
end

function changePriceOfItem(name, itemid, subType, price)
    db.executeQuery("UPDATE `ots_playersshopsystem` SET `price` = " .. price .." WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'")
    return true
end

function getItemWithId(id)
    local item = {id=0}
    local result_items = db.getResult("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `id` = '" .. id .. "' AND `count` > 0 AND `itemid` != '66'")
    if (result_items:getID() ~= -1) then
        item = {id = result_items:getDataInt("id"), name = result_items:getDataString("name"), item_name = result_items:getDataString("item_name"), itemid = result_items:getDataInt("itemid"), subType = result_items:getDataInt("subType"), count = result_items:getDataInt("count"), price = result_items:getDataInt("price")}
        result_items:free()
    end
    return item
end

function getItemWithItemId(name, itemid, subType)
    local item = {id=0, subType=0}
    local result_items = db.getResult("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `count` > 0 AND `itemid` != '66'")
    if(result_items:getID() ~= -1) then
        item = {id = result_items:getDataInt("id"), name = result_items:getDataString("name"), item_name = result_items:getDataString("item_name"), itemid = result_items:getDataInt("itemid"), subType = result_items:getDataInt("subType"), count = result_items:getDataInt("count"), price = result_items:getDataInt("price")}
        result_items:free()
    end
    return item
end

function getCash(name)
    local cash = 0
    local result_items = db.getResult("SELECT `id`, `count` FROM `ots_playersshopsystem` WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '66'")
    if(result_items:getID() ~= -1) then
        cash = result_items:getDataInt("count")
        result_items:free()
    else
        db.executeQuery("INSERT INTO `ots_playersshopsystem` (`id`, `name`, `item_name`, `itemid`, `count`, `price`) VALUES ('', " .. db.escapeString(name) .. ", 'Player Cash', '66', '0', '0')")
    end
    return cash
end

function setCash(name, count)
    db.executeQuery("UPDATE `ots_playersshopsystem` SET `count` = " .. count ..", `price` = " .. count .." WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '66'")
    return true
end

function addPlayerItemFromShop(cid, itemid, amount, subType)
    local amount = amount or 1
    local subType = subType or 0
    if(isItemStackable(itemid) == TRUE) then
        local item = doCreateItemEx(itemid, amount)
        local ret = doPlayerAddItemEx(cid, item)
        if(ret ~= RETURNVALUE_NOERROR) then
            return {}, 0
        end
        return {item}, amount
    end
    local items = {}
    local ret = 0
    local a = 0
    for i = 1, amount do
        items[i] = doCreateItemEx(itemid, subType)
        ret = doPlayerAddItemEx(cid, items[i])
        if(ret ~= RETURNVALUE_NOERROR) then
            break
        end
        a = a + 1
    end
    return items, a
end


local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
shop_offers = {}
shop_last_item = {}
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(not npcHandler:isFocused(cid)) then
        return false
    end
    npcHandler:say('I don\'t understand. Ask me for {how to use} to get available actions.', cid)
end

function onBuyItemNPC(cid, itemid, subType, amount)
    if(isItemRune(itemid) ~= TRUE and isItemStackable(itemid) ~= TRUE) then
        subType = 0
    end
    if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
        npcHandler.talkStart[cid] = os.time()
    else
        npcHandler.talkStart = os.time()
    end
    local offers = shop_offers[cid]
    local item = {id=0}
    for i = 1, #offers do
        if itemid == offers[i].itemid and subType == offers[i].subType then
            item = getItemWithId(offers[i].id)
            break
        end
    end
    if (not (item.id > 0)) then
        npcHandler:say('This item is not available in this player offer.', cid)
        closeShopWindow(cid)
        return true
    end
    local amount2 = amount
    if amount2 > item.count then
        amount2 = item.count
    end
    if item.name == getCreatureName(cid) then
        local boughtItems, i = addPlayerItemFromShop(cid, item.itemid, amount2, item.subType)
        if i == item.count then
            closeShopWindow(cid)
        end
        if(i < amount) then
            if(i > 0) then
                removeItemsFromOffer(item.name, item.itemid, item.subType, i)
                if amount == amount2 then
                    npcHandler:say('Here you are your ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ', because you do not have enought capacity for all.', cid)
                else
                    npcHandler:say('Here you are your ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ', because I do not have more your items of this type.', cid)
                end
            else
                npcHandler:say('You do not have capacity for this item.', cid)
            end
        else
            removeItemsFromOffer(item.name, item.itemid, item.subType, i)
            npcHandler:say('Here you are your ' .. amount .. ' ' .. item.item_name .. '.', cid)
        end
    else
        if (getPlayerMoney(cid) < amount * item.price) then
            if(amount == 1) then
                npcHandler:say(item.item_name .. ' cost ' .. item.price .. ' gp, you got only ' .. getPlayerMoney(cid) .. ' gp.', cid)
            else
                npcHandler:say(amount .. ' ' .. item.item_name ..'s cost ' .. amount * item.price .. ' gp, you got only ' .. getPlayerMoney(cid) .. ' gp.', cid)
            end
            return true
        end
        local boughtItems, i = addPlayerItemFromShop(cid, item.itemid, amount2, item.subType)
        if i == item.count then
            closeShopWindow(cid)
        end
        if(i < amount) then
            if(i > 0) then
                removeItemsFromOffer(item.name, item.itemid, item.subType, i)
                doPlayerRemoveMoney(cid, i * item.price)
                setCash(item.name, getCash(item.name)+i * item.price)
                if amount == amount2 then
                    npcHandler:say('Here you are ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ' for ' .. i * item.price .. ' gp, because you do not have enought capacity for all.', cid)
                else
                    npcHandler:say('Here you are ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ' for ' .. i * item.price .. ' gp, because I do not have more for sell.', cid)
                end
                doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You bought " .. i .. "x " .. item.item_name .. ".")
            else
                npcHandler:say('You do not have capacity for this item.', cid)
            end
        else
            removeItemsFromOffer(item.name, item.itemid, item.subType, i)
            doPlayerRemoveMoney(cid, i * item.price)
            setCash(item.name, getCash(item.name)+i * item.price)
            npcHandler:say('Here you are ' .. amount .. ' ' .. item.item_name .. ' for ' .. i * item.price .. ' gp.', cid)
            doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You bought " .. i .. "x " .. item.item_name .. ".")
        end
    end
    return true
end

function onSellItemNPC(cid, itemid, subType, amount)
    return true
end

function showOfferOfPlayerNPC(cid, message, keywords, parameters, node)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local name = ''
    if keywords[1] == 'my offer' or keywords[1] == 'get item' then
        name = getCreatureName(cid)
        npcHandler:say('You can take your items if you don\'t want sell them.', cid)
    else
        name = string.sub(message, 10)
        npcHandler:say('Offer of ' .. name .. '.', cid)
    end
    local offer = getOfferOfPlayer(name)
    shop_offers[cid] = offer
    local itemWindow = {}
    local item = {}
    for i = 1, #offer do
        if keywords[1] == 'my offer' or keywords[1] == 'get item' then
            item = {id = offer[i].itemid, buy = 1, sell = 0, subType = offer[i].subType, name = offer[i].item_name .. "(" .. offer[i].count .. ")"}
        else
            item = {id = offer[i].itemid, buy = offer[i].price, sell = 0, subType = offer[i].subType, name = offer[i].item_name .. "(" .. offer[i].count .. ")"}
        end
        table.insert(itemWindow, item)
    end
    closeShopWindow(cid)
    openShopWindow(cid, itemWindow, function(cid, itemid, subType, amount) onBuyItemNPC(cid, itemid, subType, amount) end, function(cid, itemid, subType, amount) onSellItemNPC(cid, itemid, subType, amount) end)
    npcHandler:resetNpc()
    return true
end

function showOfferOfItemNPC(cid, message, keywords, parameters, node)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local item_name = string.sub(message, 8)
    local offer = getOfferOfItem(item_name)
    local msg = ''
    if #offer == 0 then
        msg = "Can\'t find offer of item with name >" .. item_name .. "<"
    else
        msg = "Cheapest offers of " .. item_name .. ":\n"
        for i = 1, #offer do
            if offer[i].subType > 0 then
                msg = msg .. offer[i].price .. " gp (charges: " .. offer[i].subType .. ") - " .. offer[i].name
            else
                msg = msg .. offer[i].price .. " gp - " .. offer[i].name
            end
            if #offer ~= i then
                msg = msg .. "\n"
            end
        end
    end
    selfSay(msg, cid)
    npcHandler:resetNpc()
    return true
end

function addItemToOfferNPC(cid, message, keywords, parameters, node)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local number = 0
    for word in string.gmatch(tostring(message), "(%w+)") do
        if tostring(tonumber(word)) == word then
            number = tonumber(word)
        end
    end
    if (parameters.setprice == true) then
        local item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
        if number < 1 then
            number = 1
        end
        changePriceOfItem(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType, number)
        item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
        if tonumber(item_db.subType) > 0 then
            npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
        else
            npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
        end
        shop_last_item[cid] = {}
        npcHandler:resetNpc()
    elseif (parameters.setprice == false) then
        item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
        npcHandler:say('Ok. I do not change price for ' .. getItemNameById(shop_last_item[cid].itemid) ..'. It is ' .. item_db.price .. ' gp/each now.', cid)
        shop_last_item[cid] = {}
        npcHandler:resetNpc()
    else
        local item = getPlayerSlotItem(cid, 5)
        if (item.itemid == 0) then
            npcHandler:say('Your left hand (under BP slot) is empty.', cid)
            npcHandler:resetNpc()
            return true
        end
        if (isItemContainer(item.itemid) == TRUE and getContainerItem(uid, 0).uid > 0) then
            npcHandler:say('In your left hand (under BP slot) is not empty container. You can add to offer only items and empty containers.', cid)
            npcHandler:resetNpc()
            return true
        end
        if number < 1 then
            number = 1
        end
        if (item.type > 0 and not(isItemStackable(item.itemid) == TRUE)) then
            number = 1
            doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You can\'t sell more then one ' .. getItemNameById(item.itemid) .. ' (charges: ' .. item.type .. '). Sorry.')
        end
        local to_remove = number
        if (number > getPlayerItemCount(cid, item.itemid)) then
            number = getPlayerItemCount(cid, item.itemid)
        end
        if (isItemStackable(item.itemid) == TRUE) then
            item.type = 0
        end
        if (number == 1) and (isItemStackable(item.itemid) == TRUE) then
            doRemoveItem(item.uid, number)
        elseif (number == 1) and not(isItemStackable(item.itemid) == TRUE) then
            doRemoveItem(item.uid, 1)
        else
            doPlayerRemoveItem(cid, item.itemid, number)
        end
        addItemToOffer(getCreatureName(cid), item.itemid, item.type, number)
        item_db = getItemWithItemId(getCreatureName(cid), item.itemid, item.type)
        shop_last_item[cid] = {itemid = item.itemid, subType = item.type}
        if item.type > 0 then
            npcHandler:say('Added ' .. number .. ' ' .. getItemNameById(item.itemid) .. ' (charges: ' .. item.type .. ') to your offer. Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is ' .. item_db.price .. '. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
        else
            npcHandler:say('Added ' .. number .. ' ' .. getItemNameById(item.itemid) .. ' to your offer. Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is ' .. item_db.price .. '. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
        end
    end
    return true
end

function setItemPriceNPC(cid, message, keywords, parameters, node)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local number = 0
    for word in string.gmatch(tostring(message), "(%w+)") do
        if tostring(tonumber(word)) == word then
            number = tonumber(word)
        end
    end
    if (parameters.setprice == true) then
        local item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
        if number < 1 then
            number = 1
        end
        changePriceOfItem(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType, number)
        item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
        if item_db.subType > 0 then
            npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
        else
            npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
        end
        shop_last_item[cid] = {}
        npcHandler:resetNpc()
    else
        if number > 0 then -- player said offer ID
            local item_db = getItemWithId(number)
            if item_db.id == 0 then
                npcHandler:say('I don\'t know offer with ID >' .. number .. '<, say {set price} to view list of your items IDs.', cid)
                npcHandler:resetNpc()
                return true
            end
            if item_db.name ~= getCreatureName(cid) then
                npcHandler:say('It\'s not offer of your item, say {set price} to view list of your items IDs.', cid)
                npcHandler:resetNpc()
                return true
            end
            if item_db.subType > 0 then
                npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is ' .. item_db.price .. ' gp. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
            else
                npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is ' .. item_db.price .. ' gp. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
            end
            shop_last_item[cid] = {itemid = item_db.itemid, subType = item_db.subType}
        else -- player ask for ID
            local offer = getOfferOfPlayer(getCreatureName(cid))
            if #offer == 0 then
                npcHandler:say('You don\'t have any item in offer. You can\'t change price.', cid)
            else
                selfSay("Your offers info:\n", cid)
                for i = 1, #offer do
                    if offer[i].subType > 0 then
                        selfSay(offer[i].count .. "x " .. offer[i].item_name .. " (charges: " .. offer[i].subType .. ") - price: " .. offer[i].price .. " gp/each - offer ID: " .. offer[i].id, cid)
                    else
                        selfSay(offer[i].count .. "x " .. offer[i].item_name .. " - price: " .. offer[i].price .. " gp/each - offer ID: " .. offer[i].id, cid)
                    end
                end
                npcHandler:say('To change price of item say {set price xx}. Where xx is ID of item.', cid)
            end
            npcHandler:resetNpc()
        end
    end
    return true
end

function getCashBalanceFromItemsNPC(cid, message, keywords, parameters, node)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
    npcHandler:say('I have ' .. getCash(getCreatureName(cid)) .. ' gp for you.', cid)
    return true
end

function getCashFromItemsNPC(cid, message, keywords, parameters, node)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
    local player_cash = getCash(getCreatureName(cid))
    if player_cash > 0 then
        if doPlayerAddMoney(cid, player_cash) ~= TRUE then
            npcHandler:say('I can\'t give you cash. Try again.', cid)
        else
            setCash(getCreatureName(cid), 0)
            npcHandler:say(player_cash ..' for you. It was a pleasure doing business with you.', cid)
        end
    else
        npcHandler:say('I don\'t have cash for you.', cid)
    end
    return true
end


local sellitemprice1 = KeywordNode:new({'no'}, addItemToOfferNPC, {setprice = false})
local sellitemprice2 = KeywordNode:new({'price'}, addItemToOfferNPC, {setprice = true})
local sellitemprice3 = KeywordNode:new({'gp'}, addItemToOfferNPC, {setprice = true})

local setitemprice1 = KeywordNode:new({'no'}, setItemPriceNPC, {setprice = false})
local setitemprice2 = KeywordNode:new({'price'}, setItemPriceNPC, {setprice = true})
local setitemprice3 = KeywordNode:new({'gp'}, setItemPriceNPC, {setprice = true})

keywordHandler:addKeyword({'offer of'}, showOfferOfPlayerNPC, {})
keywordHandler:addKeyword({'search'}, showOfferOfItemNPC, {})
local node = keywordHandler:addKeyword({'add item'}, addItemToOfferNPC, {})
    node:addChildKeywordNode(sellitemprice1)
    node:addChildKeywordNode(sellitemprice2)
    node:addChildKeywordNode(sellitemprice3)
local node = keywordHandler:addKeyword({'set price'}, setItemPriceNPC, {setprice = false})
    node:addChildKeywordNode(setitemprice1)
    node:addChildKeywordNode(setitemprice2)
    node:addChildKeywordNode(setitemprice3)
local node = keywordHandler:addKeyword({'change price'}, setItemPriceNPC, {setprice = false})
    node:addChildKeywordNode(setitemprice1)
    node:addChildKeywordNode(setitemprice2)
    node:addChildKeywordNode(setitemprice3)
keywordHandler:addKeyword({'my offer'}, showOfferOfPlayerNPC, {})
keywordHandler:addKeyword({'get item'}, showOfferOfPlayerNPC, {})
keywordHandler:addKeyword({'balance'}, getCashBalanceFromItemsNPC, {})
keywordHandler:addKeyword({'get cash'}, getCashFromItemsNPC, {})
keywordHandler:addKeyword({'withdraw'}, getCashFromItemsNPC, {})
local node = keywordHandler:addKeyword({'how to use'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'What you want to do? Say {add my item to offer}, {get my item from offer}, {check how much money from items I have}, {get my cash from items}, {change price of item in offer}, {buy item of other player} or {search item}.'})
    node:addChildKeyword({'add my item to offer'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'First put your item in left hand (under BP slot), then say {add item xx} where xx is number of items that you want add to offer, then NPC will ask you for price, say {price yy}, where yy is price for 1 item.'})
    node:addChildKeyword({'get my item from offer'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {my offer} or {get item} to view list of your items, all items will have price 1 gp, but when you press "Buy" you will get your item for free.'})
    node:addChildKeyword({'check how mu'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {balance} to view how much money NPC has for you.'})
    node:addChildKeyword({'get my cash'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {get cash} or {withdraw} to get your cash from NPC.'})
    node:addChildKeyword({'change price of item in offer'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {change price} or {set price} to view list of your items, prices and offer IDs. Say {change price xx} or {set price xx}, where xx is item offer ID, then NPC will show you item name and ask for new price, say {price yy}, where yy is new price.'})
    node:addChildKeyword({'buy item of other player'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {offer of Xx Yy}, where Xx Yy is name of player. NPC will show you offer of this player in trade window.'})
    node:addChildKeyword({'search item'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {search Xxx Yyy}, where Xxx Yyy is name of item. Npc will show you few cheapest offers and names of players. That say {offer of Xxx}, where Xxx is name of player to view his offer and buy item.'})
npcHandler:setMessage(MESSAGE_GREET, "Greetings |PLAYERNAME|. I can trade your items with other players. Say {how to use} if you don\'t know commands.")

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
NPC xml file:
PHP:
<?xml version="1.0" encoding="UTF-8"?>
<npc name="Shopper" script="data/npc/scripts/shopper.lua" walkinterval="2000" floorchange="0">
	<health now="100" max="100"/>
	<look type="290" head="39" body="122" legs="125" feet="57" addons="0"/>
	<parameters />
</npc>
Post bugs in this thread. NPC only for TFS 0.3.x engine.
Database strupture:
PHP:
CREATE TABLE `ots_playersshopsystem` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(255) NOT NULL,
  `item_name` varchar(255) NOT NULL,
  `itemid` int(11) NOT NULL,
  `subType` int(11) NOT NULL,
  `count` int(11) NOT NULL,
  `price` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
 
Last edited:
Idk i have theese bugs :/
Code:
[16/10/2008  19:54:57] data/global.lua:1129: attempt to call field 'getResult' (a nil value)
[16/10/2008  19:54:57] stack traceback:
[16/10/2008  19:54:57] 	data/global.lua:1129: in function 'getOfferOfItem'
[16/10/2008  19:54:57] 	data/npc/scripts/asdasd.lua:138: in function 'callback'
[16/10/2008  19:54:57] 	data/npc/lib/npcsystem/keywordhandler.lua:40: in function 'processMessage'
[16/10/2008  19:54:57] 	data/npc/lib/npcsystem/keywordhandler.lua:168: in function 'processNodeMessage'
[16/10/2008  19:54:57] 	data/npc/lib/npcsystem/keywordhandler.lua:135: in function 'processMessage'
[16/10/2008  19:54:57] 	data/npc/lib/npcsystem/npchandler.lua:371: in function 'onCreatureSay'
[16/10/2008  19:54:57] 	data/npc/scripts/asdasd.lua:8: in function <data/npc/scripts/asdasd.lua:8>

[16/10/2008  19:55:24] Lua Script Error: [Npc interface] 
[16/10/2008  19:55:24] data/npc/scripts/asdasd.lua:onCreatureSay

[16/10/2008  19:55:24] data/npc/lib/npcsystem/npchandler.lua:309: attempt to call global 'getPlayerName' (a nil value)
[16/10/2008  19:55:24] stack traceback:
[16/10/2008  19:55:24] 	data/npc/lib/npcsystem/npchandler.lua:309: in function 'unGreet'
[16/10/2008  19:55:24] 	data/npc/lib/npcsystem/npchandler.lua:516: in function 'onFarewell'
[16/10/2008  19:55:24] 	data/npc/lib/npcsystem/modules.lua:216: in function 'callback'
[16/10/2008  19:55:24] 	data/npc/lib/npcsystem/keywordhandler.lua:40: in function 'processMessage'
[16/10/2008  19:55:24] 	data/npc/lib/npcsystem/keywordhandler.lua:168: in function 'processNodeMessage'
[16/10/2008  19:55:24] 	data/npc/lib/npcsystem/keywordhandler.lua:128: in function 'processMessage'
[16/10/2008  19:55:24] 	data/npc/lib/npcsystem/npchandler.lua:371: in function 'onCreatureSay'
[16/10/2008  19:55:24] 	data/npc/scripts/asdasd.lua:8: in function <data/npc/scripts/asdasd.lua:8>

[16/10/2008  19:56:12] Lua Script Error: [Npc interface] 
[16/10/2008  19:56:12] data/npc/scripts/asdasd.lua:onThink

[16/10/2008  19:56:12] data/npc/lib/npcsystem/npchandler.lua:309: attempt to call global 'getPlayerName' (a nil value)
[16/10/2008  19:56:12] stack traceback:
[16/10/2008  19:56:12] 	data/npc/lib/npcsystem/npchandler.lua:309: in function 'unGreet'
[16/10/2008  19:56:12] 	data/npc/lib/npcsystem/npchandler.lua:466: in function 'onThink'
[16/10/2008  19:56:12] 	data/npc/scripts/asdasd.lua:9: in function <data/npc/scripts/asdasd.lua:9>

Btw. Very nice idea =]

@ Ok now is good.. sorry for this.
 
Last edited:
thanks ;d very nice release ;] btw, is there any way to make it show ALL items which was offered by players? like "show all"
 
[18/10/2008 22:02:19] Lua Script Error: [Npc interface]
[18/10/2008 22:02:19] data/npc/scripts/gtn.lua:eek:nCreatureSay

[18/10/2008 22:02:19] data/global.lua:637: attempt to index global 'db' (a nil value)
[18/10/2008 22:02:19] stack traceback:
[18/10/2008 22:02:19] data/global.lua:637: in function 'addItemToOffer'
[18/10/2008 22:02:19] data/npc/scripts/gtn.lua:223: in function 'callback'
[18/10/2008 22:02:19] data/npc/lib/npcsystem/keywordhandler.lua:40: in function 'processMessage'
[18/10/2008 22:02:19] data/npc/lib/npcsystem/keywordhandler.lua:168: in function 'processNodeMessage'
[18/10/2008 22:02:19] data/npc/lib/npcsystem/keywordhandler.lua:135: in function 'processMessage'
[18/10/2008 22:02:19] data/npc/lib/npcsystem/npchandler.lua:371: in function 'onCreatureSay'
[18/10/2008 22:02:19] data/npc/scripts/gtn.lua:8: in function <data/npc/scripts/gtn.lua:8>

[18/10/2008 22:02:27] Lua Script Error: [Npc interface]
[18/10/2008 22:02:27] data/npc/scripts/gtn.lua:eek:nCreatureSay

[18/10/2008 22:02:27] data/global.lua:672: attempt to index global 'db' (a nil value)
[18/10/2008 22:02:27] stack traceback:
[18/10/2008 22:02:27] data/global.lua:672: in function 'getItemWithItemId'
[18/10/2008 22:02:27] data/npc/scripts/gtn.lua:171: in function 'callback'
[18/10/2008 22:02:27] data/npc/lib/npcsystem/keywordhandler.lua:40: in function 'processMessage'
[18/10/2008 22:02:27] data/npc/lib/npcsystem/keywordhandler.lua:168: in function 'processNodeMessage'
[18/10/2008 22:02:27] data/npc/lib/npcsystem/keywordhandler.lua:122: in function 'processMessage'
[18/10/2008 22:02:27] data/npc/lib/npcsystem/npchandler.lua:371: in function 'onCreatureSay'
[18/10/2008 22:02:27] data/npc/scripts/gtn.lua:8: in function <data/npc/scripts/gtn.lua:8>

this are all mine errors.
But already i like it:)
 
In fact... yeah, its great idea. Basicly, buying part would work great with shop window : >
I'll fix it up and post everything before merging with my banker.

@Gesior: why there's dofile('config.lua')? :p
 
Doesnt work proprety~, if a player buy my mpa for example, I can withdraw cash cuz I dont get any cash <.<
 
Doesnt work proprety~, if a player buy my mpa for example, I can withdraw cash cuz I dont get any cash <.<
Stupid bug. 'name' in place of 'item.name' in few places. I'll post today fixed version for tfs 0.3.4/0.3.5 (beta).
Elf said:
@Gesior: why there's dofile('config.lua')? :p
It was NPC for TFS 0.2 and it was needed for TFS 0.2 luaSQL scripts.
TFS 0.3.4 (maybe 0.3.1, 0.3.2 and 0.3.3 too) lua script:
PHP:
-- shop system
function getOfferOfPlayer(name)
    local offer = {}
    local result_items = db.getResult("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `name` = " .. db.escapeString(name) .. " AND `count` > '0' AND `itemid` != '66'")
    if(result_items:getID() ~= -1) then
        while(true) do
            table.insert(offer, {id = result_items:getDataInt("id"), name = result_items:getDataString("name"), item_name = result_items:getDataString("item_name"), itemid = result_items:getDataInt("itemid"), subType = result_items:getDataInt("subType"), count = result_items:getDataInt("count"), price = result_items:getDataInt("price")})
                if not(result_items:next()) then
                    break
                end
        end
        result_items:free()
    end
    return offer
end

function getOfferOfItem(item_name)
    local offer = {}
    result_items = db.getResult("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `item_name` = " .. db.escapeString(item_name) .. " AND `count` > '0' AND `itemid` != '66' ORDER BY `price` ASC LIMIT 5")
    if(result_items:getID() ~= -1) then
        while(true) do
            table.insert(offer, {id = result_items:getDataInt("id"), name = result_items:getDataString("name"), item_name = result_items:getDataString("item_name"), itemid = result_items:getDataInt("itemid"), subType = result_items:getDataInt("subType"), count = result_items:getDataInt("count"), price = result_items:getDataInt("price")})
                if not(result_items:next()) then
                    break
                end
        end
        result_items:free()
    end
    return offer
end

function addItemToOffer(name, itemid, subType, count)
    local inDB_id = 0
    local result_offers = db.getResult("SELECT `id`, `count` FROM `ots_playersshopsystem` WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'")
    if(result_offers:getID() ~= -1) then
        inDB_id = result_offers:getDataInt("id")
        result_offers:free()
    end
    if inDB_id ~= 0 then
        db.executeQuery("UPDATE `ots_playersshopsystem` SET `count` = `ots_playersshopsystem`.`count` + " .. count .." WHERE `id` = '" .. inDB_id .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'")
    else
        db.executeQuery("INSERT INTO `ots_playersshopsystem` (`id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price`) VALUES (NULL, " .. db.escapeString(name) .. ", " .. db.escapeString(getItemNameById(itemid)) .. ", '" .. itemid .. "', '" .. subType .. "', '" .. count .. "', 1000000)")
    end
    return true
end

function removeItemsFromOffer(name, itemid, subType, count)
    db.executeQuery("UPDATE `ots_playersshopsystem` SET `count` = `ots_playersshopsystem`.`count` - " .. count .." WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'")
    return true
end

function changePriceOfItem(name, itemid, subType, price)
    db.executeQuery("UPDATE `ots_playersshopsystem` SET `price` = " .. price .." WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `itemid` != '66'")
    return true
end

function getItemWithId(id)
    local item = {id=0}
    local result_items = db.getResult("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `id` = '" .. id .. "' AND `count` > 0 AND `itemid` != '66'")
    if (result_items:getID() ~= -1) then
        item = {id = result_items:getDataInt("id"), name = result_items:getDataString("name"), item_name = result_items:getDataString("item_name"), itemid = result_items:getDataInt("itemid"), subType = result_items:getDataInt("subType"), count = result_items:getDataInt("count"), price = result_items:getDataInt("price")}
        result_items:free()
    end
    return item
end

function getItemWithItemId(name, itemid, subType)
    local item = {id=0, subType=0}
    local result_items = db.getResult("SELECT `id`, `name`, `item_name`, `itemid`, `subType`, `count`, `price` FROM `ots_playersshopsystem` WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '" .. itemid .. "' AND `subType` = '" .. subType .. "' AND `count` > 0 AND `itemid` != '66'")
    if(result_items:getID() ~= -1) then
        item = {id = result_items:getDataInt("id"), name = result_items:getDataString("name"), item_name = result_items:getDataString("item_name"), itemid = result_items:getDataInt("itemid"), subType = result_items:getDataInt("subType"), count = result_items:getDataInt("count"), price = result_items:getDataInt("price")}
        result_items:free()
    end
    return item
end

function getCash(name)
    local cash = 0
    local result_items = db.getResult("SELECT `id`, `count` FROM `ots_playersshopsystem` WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '66'")
    if(result_items:getID() ~= -1) then
        cash = result_items:getDataInt("count")
        result_items:free()
    else
        db.executeQuery("INSERT INTO `ots_playersshopsystem` (`id`, `name`, `item_name`, `itemid`, `count`, `price`) VALUES ('', " .. db.escapeString(name) .. ", 'Player Cash', '66', '0', '0')")
    end
    return cash
end

function setCash(name, count)
    db.executeQuery("UPDATE `ots_playersshopsystem` SET `count` = " .. count ..", `price` = " .. count .." WHERE `name` = " .. db.escapeString(name) .. " AND `itemid` = '66'")
    return true
end

function addPlayerItemFromShop(cid, itemid, amount, subType)
    local amount = amount or 1
    local subType = subType or 0
    if(isItemStackable(itemid) == TRUE) then
        local item = doCreateItemEx(itemid, amount)
        local ret = doPlayerAddItemEx(cid, item)
        if(ret ~= RETURNVALUE_NOERROR) then
            return {}, 0
        end
        return {item}, amount
    end
    local items = {}
    local ret = 0
    local a = 0
    for i = 1, amount do
        items[i] = doCreateItemEx(itemid, subType)
        ret = doPlayerAddItemEx(cid, items[i])
        if(ret ~= RETURNVALUE_NOERROR) then
            break
        end
        a = a + 1
    end
    return items, a
end


local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
shop_offers = {}
shop_last_item = {}
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(not npcHandler:isFocused(cid)) then
		return false
	end
	npcHandler:say('I don\'t understand. Ask me for {how to use} to get available actions.', cid)
end

function onBuyItemNPC(cid, itemid, subType, amount)
	if(isItemRune(itemid) ~= TRUE and isItemStackable(itemid) ~= TRUE) then
		subType = 0
	end
	if(NPCHANDLER_CONVBEHAVIOR ~= CONVERSATION_DEFAULT) then
		npcHandler.talkStart[cid] = os.time()
	else
		npcHandler.talkStart = os.time()
	end
	local offers = shop_offers[cid]
	local item = {id=0}
	for i = 1, #offers do
		if itemid == offers[i].itemid and subType == offers[i].subType then
			item = getItemWithId(offers[i].id)
			break
		end
	end
	if (not (item.id > 0)) then
		npcHandler:say('This item is not available in this player offer.', cid)
		closeShopWindow(cid)
		return true
	end
	local amount2 = amount
	if amount2 > item.count then
		amount2 = item.count
	end
	if item.name == getCreatureName(cid) then
		local boughtItems, i = addPlayerItemFromShop(cid, item.itemid, amount2, item.subType)
		if i == item.count then
			closeShopWindow(cid)
		end
		if(i < amount) then
			if(i > 0) then
				removeItemsFromOffer(item.name, item.itemid, item.subType, i)
				if amount == amount2 then
					npcHandler:say('Here you are your ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ', because you do not have enought capacity for all.', cid)
				else
					npcHandler:say('Here you are your ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ', because I do not have more your items of this type.', cid)
				end
			else
				npcHandler:say('You do not have capacity for this item.', cid)
			end
		else
			removeItemsFromOffer(item.name, item.itemid, item.subType, i)
			npcHandler:say('Here you are your ' .. amount .. ' ' .. item.item_name .. '.', cid)
		end
	else
		if (getPlayerMoney(cid) < amount * item.price) then
			if(amount == 1) then
				npcHandler:say(item.item_name .. ' cost ' .. item.price .. ' gp, you got only ' .. getPlayerMoney(cid) .. ' gp.', cid)
			else
				npcHandler:say(amount .. ' ' .. item.item_name ..'s cost ' .. amount * item.price .. ' gp, you got only ' .. getPlayerMoney(cid) .. ' gp.', cid)
			end
			return true
		end
		local boughtItems, i = addPlayerItemFromShop(cid, item.itemid, amount2, item.subType)
		if i == item.count then
			closeShopWindow(cid)
		end
		if(i < amount) then
			if(i > 0) then
				removeItemsFromOffer(item.name, item.itemid, item.subType, i)
				doPlayerRemoveMoney(cid, i * item.price)
				setCash(item.name, getCash(item.name)+i * item.price)
				if amount == amount2 then
					npcHandler:say('Here you are ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ' for ' .. i * item.price .. ' gp, because you do not have enought capacity for all.', cid)
				else
					npcHandler:say('Here you are ' .. i .. ' of requested ' .. amount .. ' ' .. item.item_name .. ' for ' .. i * item.price .. ' gp, because I do not have more for sell.', cid)
				end
				doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You bought " .. i .. "x " .. item.item_name .. ".")
			else
				npcHandler:say('You do not have capacity for this item.', cid)
			end
		else
			removeItemsFromOffer(item.name, item.itemid, item.subType, i)
			doPlayerRemoveMoney(cid, i * item.price)
			setCash(item.name, getCash(item.name)+i * item.price)
			npcHandler:say('Here you are ' .. amount .. ' ' .. item.item_name .. ' for ' .. i * item.price .. ' gp.', cid)
			doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You bought " .. i .. "x " .. item.item_name .. ".")
		end
	end
	return true
end

function onSellItemNPC(cid, itemid, subType, amount)
	return true
end

function showOfferOfPlayerNPC(cid, message, keywords, parameters, node)
	if(not npcHandler:isFocused(cid)) then
		return false
	end
	local name = ''
	if keywords[1] == 'my offer' or keywords[1] == 'get item' then
		name = getCreatureName(cid)
		npcHandler:say('You can take your items if you don\'t want sell them.', cid)
	else
		name = string.sub(message, 10)
		npcHandler:say('Offer of ' .. name .. '.', cid)
	end
	local offer = getOfferOfPlayer(name)
	shop_offers[cid] = offer
	local itemWindow = {}
	local item = {}
	for i = 1, #offer do
		if keywords[1] == 'my offer' or keywords[1] == 'get item' then
			item = {id = offer[i].itemid, buy = 1, sell = 0, subType = offer[i].subType, name = offer[i].item_name .. "(" .. offer[i].count .. ")"}
		else
			item = {id = offer[i].itemid, buy = offer[i].price, sell = 0, subType = offer[i].subType, name = offer[i].item_name .. "(" .. offer[i].count .. ")"}
		end
		table.insert(itemWindow, item)
	end
	closeShopWindow(cid)
	openShopWindow(cid, itemWindow, function(cid, itemid, subType, amount) onBuyItemNPC(cid, itemid, subType, amount) end, function(cid, itemid, subType, amount) onSellItemNPC(cid, itemid, subType, amount) end)
	npcHandler:resetNpc()
	return true
end

function showOfferOfItemNPC(cid, message, keywords, parameters, node)
	if(not npcHandler:isFocused(cid)) then
		return false
	end
	local item_name = string.sub(message, 8)
	local offer = getOfferOfItem(item_name)
	local msg = ''
	if #offer == 0 then
		msg = "Can\'t find offer of item with name >" .. item_name .. "<"
	else
		msg = "Cheapest offers of " .. item_name .. ":\n"
		for i = 1, #offer do
			if offer[i].subType > 0 then
				msg = msg .. offer[i].price .. " gp (charges: " .. offer[i].subType .. ") - " .. offer[i].name
			else
				msg = msg .. offer[i].price .. " gp - " .. offer[i].name
			end
			if #offer ~= i then
				msg = msg .. "\n"
			end
		end
	end
	selfSay(msg, cid)
	npcHandler:resetNpc()
	return true
end

function addItemToOfferNPC(cid, message, keywords, parameters, node)
	if(not npcHandler:isFocused(cid)) then
		return false
	end
	local number = 0
	for word in string.gmatch(tostring(message), "(%w+)") do
		if tostring(tonumber(word)) == word then
			number = tonumber(word)
		end
	end
	if (parameters.setprice == true) then
		local item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
		if number < 1 then
			number = 1
		end
		changePriceOfItem(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType, number)
		item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
		if tonumber(item_db.subType) > 0 then
			npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
		else
			npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
		end
		shop_last_item[cid] = {}
		npcHandler:resetNpc()
	elseif (parameters.setprice == false) then
		item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
		npcHandler:say('Ok. I do not change price for ' .. getItemNameById(shop_last_item[cid].itemid) ..'. It is ' .. item_db.price .. ' gp/each now.', cid)
		shop_last_item[cid] = {}
		npcHandler:resetNpc()
	else
		local item = getPlayerSlotItem(cid, 5)
		if (item.itemid == 0) then
			npcHandler:say('Your left hand (under BP slot) is empty.', cid)
			npcHandler:resetNpc()
			return true
		end
		if (isItemContainer(item.itemid) == TRUE and getContainerItem(uid, 0).uid > 0) then
			npcHandler:say('In your left hand (under BP slot) is not empty container. You can add to offer only items and empty containers.', cid)
			npcHandler:resetNpc()
			return true
		end
		if number < 1 then
			number = 1
		end
		if (item.type > 0 and not(isItemStackable(item.itemid) == TRUE)) then
			number = 1
			doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You can\'t sell more then one ' .. getItemNameById(item.itemid) .. ' (charges: ' .. item.type .. '). Sorry.')
		end
		local to_remove = number
		if (number > getPlayerItemCount(cid, item.itemid)) then
			number = getPlayerItemCount(cid, item.itemid)
		end
		if (isItemStackable(item.itemid) == TRUE) then
			item.type = 0
		end
		if (number == 1) and (isItemStackable(item.itemid) == TRUE) then
			doRemoveItem(item.uid, number)
		elseif (number == 1) and not(isItemStackable(item.itemid) == TRUE) then
			doRemoveItem(item.uid, 1)
		else
			doPlayerRemoveItem(cid, item.itemid, number)
		end
		addItemToOffer(getCreatureName(cid), item.itemid, item.type, number)
		item_db = getItemWithItemId(getCreatureName(cid), item.itemid, item.type)
		shop_last_item[cid] = {itemid = item.itemid, subType = item.type}
		if item.type > 0 then
			npcHandler:say('Added ' .. number .. ' ' .. getItemNameById(item.itemid) .. ' (charges: ' .. item.type .. ') to your offer. Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is ' .. item_db.price .. '. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
		else
			npcHandler:say('Added ' .. number .. ' ' .. getItemNameById(item.itemid) .. ' to your offer. Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is ' .. item_db.price .. '. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
		end
	end
	return true
end

function setItemPriceNPC(cid, message, keywords, parameters, node)
	if(not npcHandler:isFocused(cid)) then
		return false
	end
	local number = 0
	for word in string.gmatch(tostring(message), "(%w+)") do
		if tostring(tonumber(word)) == word then
			number = tonumber(word)
		end
	end
	if (parameters.setprice == true) then
		local item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
		if number < 1 then
			number = 1
		end
		changePriceOfItem(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType, number)
		item_db = getItemWithItemId(getCreatureName(cid), shop_last_item[cid].itemid, shop_last_item[cid].subType)
		if item_db.subType > 0 then
			npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
		else
			npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is now ' .. item_db.price .. ' gp. Say {set price} to change price of items.', cid)
		end
		shop_last_item[cid] = {}
		npcHandler:resetNpc()
	else
		if number > 0 then -- player said offer ID
			local item_db = getItemWithId(number)
			if item_db.id == 0 then
				npcHandler:say('I don\'t know offer with ID >' .. number .. '<, say {set price} to view list of your items IDs.', cid)
				npcHandler:resetNpc()
				return true
			end
			if item_db.name ~= getCreatureName(cid) then
				npcHandler:say('It\'s not offer of your item, say {set price} to view list of your items IDs.', cid)
				npcHandler:resetNpc()
				return true
			end
			if item_db.subType > 0 then
				npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' (charges: ' .. item_db.subType .. ') in offer, price for each is ' .. item_db.price .. ' gp. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
			else
				npcHandler:say('Actually you have ' .. item_db.count ..' ' .. item_db.item_name .. ' in offer, price for each is ' .. item_db.price .. ' gp. Do you want to change price? Say {no} or {price xxx}, where xxx is number of gp.', cid)
			end
			shop_last_item[cid] = {itemid = item_db.itemid, subType = item_db.subType}
		else -- player ask for ID
			local offer = getOfferOfPlayer(getCreatureName(cid))
			if #offer == 0 then
				npcHandler:say('You don\'t have any item in offer. You can\'t change price.', cid)
			else
				selfSay("Your offers info:\n", cid)
				for i = 1, #offer do
					if offer[i].subType > 0 then
						selfSay(offer[i].count .. "x " .. offer[i].item_name .. " (charges: " .. offer[i].subType .. ") - price: " .. offer[i].price .. " gp/each - offer ID: " .. offer[i].id, cid)
					else
						selfSay(offer[i].count .. "x " .. offer[i].item_name .. " - price: " .. offer[i].price .. " gp/each - offer ID: " .. offer[i].id, cid)
					end
				end
				npcHandler:say('To change price of item say {set price xx}. Where xx is ID of item.', cid)
			end
			npcHandler:resetNpc()
		end
	end
	return true
end

function getCashBalanceFromItemsNPC(cid, message, keywords, parameters, node)
	if(not npcHandler:isFocused(cid)) then
		return false
	end
	npcHandler:say('I have ' .. getCash(getCreatureName(cid)) .. ' gp for you.', cid)
	return true
end

function getCashFromItemsNPC(cid, message, keywords, parameters, node)
	if(not npcHandler:isFocused(cid)) then
		return false
	end
	local player_cash = getCash(getCreatureName(cid))
	if player_cash > 0 then
		if doPlayerAddMoney(cid, player_cash) ~= TRUE then
			npcHandler:say('I can\'t give you cash. Try again.', cid)
		else
			setCash(getCreatureName(cid), 0)
			npcHandler:say(player_cash ..' for you. It was a pleasure doing business with you.', cid)
		end
	else
		npcHandler:say('I don\'t have cash for you.', cid)
	end
	return true
end


local sellitemprice1 = KeywordNode:new({'no'}, addItemToOfferNPC, {setprice = false})
local sellitemprice2 = KeywordNode:new({'price'}, addItemToOfferNPC, {setprice = true})
local sellitemprice3 = KeywordNode:new({'gp'}, addItemToOfferNPC, {setprice = true})

local setitemprice1 = KeywordNode:new({'no'}, setItemPriceNPC, {setprice = false})
local setitemprice2 = KeywordNode:new({'price'}, setItemPriceNPC, {setprice = true})
local setitemprice3 = KeywordNode:new({'gp'}, setItemPriceNPC, {setprice = true})

keywordHandler:addKeyword({'offer of'}, showOfferOfPlayerNPC, {})
keywordHandler:addKeyword({'search'}, showOfferOfItemNPC, {})
local node = keywordHandler:addKeyword({'add item'}, addItemToOfferNPC, {})
	node:addChildKeywordNode(sellitemprice1)
	node:addChildKeywordNode(sellitemprice2)
	node:addChildKeywordNode(sellitemprice3)
local node = keywordHandler:addKeyword({'set price'}, setItemPriceNPC, {setprice = false})
	node:addChildKeywordNode(setitemprice1)
	node:addChildKeywordNode(setitemprice2)
	node:addChildKeywordNode(setitemprice3)
local node = keywordHandler:addKeyword({'change price'}, setItemPriceNPC, {setprice = false})
	node:addChildKeywordNode(setitemprice1)
	node:addChildKeywordNode(setitemprice2)
	node:addChildKeywordNode(setitemprice3)
keywordHandler:addKeyword({'my offer'}, showOfferOfPlayerNPC, {})
keywordHandler:addKeyword({'get item'}, showOfferOfPlayerNPC, {})
keywordHandler:addKeyword({'balance'}, getCashBalanceFromItemsNPC, {})
keywordHandler:addKeyword({'get cash'}, getCashFromItemsNPC, {})
keywordHandler:addKeyword({'withdraw'}, getCashFromItemsNPC, {})
local node = keywordHandler:addKeyword({'how to use'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'What you want to do? Say {add my item to offer}, {get my item from offer}, {check how much money from items I have}, {get my cash from items}, {change price of item in offer}, {buy item of other player} or {search item}.'})
	node:addChildKeyword({'add my item to offer'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'First put your item in left hand (under BP slot), then say {add item xx} where xx is number of items that you want add to offer, then NPC will ask you for price, say {price yy}, where yy is price for 1 item.'})
	node:addChildKeyword({'get my item from offer'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {my offer} or {get item} to view list of your items, all items will have price 1 gp, but when you press "Buy" you will get your item for free.'})
	node:addChildKeyword({'check how mu'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {balance} to view how much money NPC has for you.'})
	node:addChildKeyword({'get my cash'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {get cash} or {withdraw} to get your cash from NPC.'})
	node:addChildKeyword({'change price of item in offer'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {change price} or {set price} to view list of your items, prices and offer IDs. Say {change price xx} or {set price xx}, where xx is item offer ID, then NPC will show you item name and ask for new price, say {price yy}, where yy is new price.'})
	node:addChildKeyword({'buy item of other player'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {offer of Xx Yy}, where Xx Yy is name of player. NPC will show you offer of this player in trade window.'})
	node:addChildKeyword({'search item'}, StdModule.say, {npcHandler = npcHandler, onlyFocus = true, text = 'Say {search Xxx Yyy}, where Xxx Yyy is name of item. Npc will show you few cheapest offers and names of players. That say {offer of Xxx}, where Xxx is name of player to view his offer and buy item.'})
npcHandler:setMessage(MESSAGE_GREET, "Greetings |PLAYERNAME|. I can trade your items with other players. Say {how to use} if you don\'t know commands.")

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Last edited:
I've found little bug with both versions you posted. You can add items without any problem, but when you want to get your items back it won't give it back. Npc says: "11:16 Shopper: Say my offer or get item to view list of your items, all items will have price 1 gp, but when you press "Buy" you will get your item for free." but there's no way to buy items.

2rdwyuw.jpg


No error's been shown in console.

How should I fix it?
 
Where do i put this:

Code:
CREATE TABLE `ots_playersshopsystem` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(255) NOT NULL,
  `item_name` varchar(255) NOT NULL,
  `itemid` int(11) NOT NULL,
  `subType` int(11) NOT NULL,
  `count` int(11) NOT NULL,
  `price` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

EDIT: where in htdocs ?
 
Last edited:
Back
Top