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

TFS 0.X NPC - Sell items by premium points

potinho

Advanced OT User
Joined
Oct 11, 2009
Messages
1,402
Solutions
17
Reaction score
150
Location
Brazil
Hello guys,

I'm trying to implement on my server an NPC that sells some stuff for premium points. I got this one from another post, but when I say "list" or "buy something" to him the console crashes and the server crashes. can you help me? I use Gesior 2012.

donatios.lua

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
 
function onCreatureAppear(cid)                npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid)            npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg)            npcHandler:onCreatureSay(cid, type, msg) end
function onThink()                    npcHandler:onThink() end
 
local function getPremiumPoints(cid)
    local res = db.getResult('SELECT premium_points FROM accounts WHERE account_id = '..getPlayerAccountId(cid))
    if(res:getID() == -1) then
       return 0
    end
    local ret = res:getDataInt("points")
    res:free()
    return tonumber(ret)
end
 
function creatureSayCallback(cid, type, msg)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
 
    local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
 
local items = {
    ["Premium Coin"] = {points = 1, itemid = 5263},    
    ["exp scrollt"] = {points = 2, itemid = 5161}
}
 
     local function addCptl(first, rest)
          return first:upper()..rest:lower()
    end
 
    local x = items[msg:gsub("(%a)([%w_']*)", addCptl)]
 
    local buy = (msgcontains(msg, 'buy'))
    if buy then
        selfSay('Which donate item would you like to buy?', cid)
        talkState[talkUser] = 2
    end
 
    if x and talkState[talkUser] >= 1 then
        selfSay('Do you want to buy 1 '..msg..' for '..x.points..' premium points?', cid)
        xmsg = msg
        talkState[talkUser] = 3
    end
    local agree = (msgcontains(msg, 'yes'))
    if agree and talkState[talkUser] == 3 then
        x = items[xmsg:gsub("(%a)([%w_']*)", addCptl)]
        if getPremiumPoints(cid) >= x.points then
            selfSay('Here you are, have fun with it.', cid)
             doPlayerAddItem(cid, x.itemid, 1)
            db.executeQuery('UPDATE accounts SET premium_points=points-'..x.points..' WHERE account_id=' .. getPlayerAccountId(cid))
            talkState[talkUser] = 1
        else
            selfSay('You don\'t have enough points.', cid)
            talkState[talkUser] = 1
        end
    end
 
    local list = (msgcontains(msg, 'list'))
    if list then
    text = 'Donation Items\n'
        for i, x in pairs(items) do
                text = text .. "\n" .. i .. " - "..x.points.." points"
        end
        doShowTextDialog(cid, 7391, "" .. text)
        talkState[talkUser] = 1
    end
 
    if not x and not list and not buy and not agree and talkState[talkUser] == 2 then
        selfSay('You can\'t buy this item from me, look in the {list} which items you can buy.', cid)
    elseif not x and not list and not buy and not agree and talkState[talkUser] ~= 2 then
        selfSay('What? I don\'t understand what you mean with '..msg..'.', cid)
    end
    return true
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

in lib-function i have:

Lua:
function getAccountPoints(cid)
    local res = db.getResult('select `premium_points` from accounts where name = \''..getPlayerAccount(cid)..'\'')
    if(res:getID() == -1) then
       return false
    end
    local ret = res:getDataInt("premium_points")
    res:free()
    return tonumber(ret)
end

function doAccountRemovePoints(cid, count)
        return db.executeQuery("UPDATE `accounts` SET `premium_points` = '".. getAccountPoints(cid) - count .."' WHERE `name` ='"..getPlayerAccount(cid).."'")
end
 
Solution
Solved with this script, thanks again @Alberto Cabrera

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
local talkItems = {}
 
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 onPlayerEndTrade(cid)              npcHandler:onPlayerEndTrade(cid)            end
function onPlayerCloseChannel(cid)          npcHandler:onPlayerCloseChannel(cid)...
Hello guys,

I'm trying to implement on my server an NPC that sells some stuff for premium points. I got this one from another post, but when I say "list" or "buy something" to him the console crashes and the server crashes. can you help me? I use Gesior 2012.

donatios.lua

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
 
function onCreatureAppear(cid)                npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid)            npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg)            npcHandler:onCreatureSay(cid, type, msg) end
function onThink()                    npcHandler:onThink() end
 
local function getPremiumPoints(cid)
    local res = db.getResult('SELECT premium_points FROM accounts WHERE account_id = '..getPlayerAccountId(cid))
    if(res:getID() == -1) then
       return 0
    end
    local ret = res:getDataInt("points")
    res:free()
    return tonumber(ret)
end
 
function creatureSayCallback(cid, type, msg)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
 
    local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
 
local items = {
    ["Premium Coin"] = {points = 1, itemid = 5263},   
    ["exp scrollt"] = {points = 2, itemid = 5161}
}
 
     local function addCptl(first, rest)
          return first:upper()..rest:lower()
    end
 
    local x = items[msg:gsub("(%a)([%w_']*)", addCptl)]
 
    local buy = (msgcontains(msg, 'buy'))
    if buy then
        selfSay('Which donate item would you like to buy?', cid)
        talkState[talkUser] = 2
    end
 
    if x and talkState[talkUser] >= 1 then
        selfSay('Do you want to buy 1 '..msg..' for '..x.points..' premium points?', cid)
        xmsg = msg
        talkState[talkUser] = 3
    end
    local agree = (msgcontains(msg, 'yes'))
    if agree and talkState[talkUser] == 3 then
        x = items[xmsg:gsub("(%a)([%w_']*)", addCptl)]
        if getPremiumPoints(cid) >= x.points then
            selfSay('Here you are, have fun with it.', cid)
             doPlayerAddItem(cid, x.itemid, 1)
            db.executeQuery('UPDATE accounts SET premium_points=points-'..x.points..' WHERE account_id=' .. getPlayerAccountId(cid))
            talkState[talkUser] = 1
        else
            selfSay('You don\'t have enough points.', cid)
            talkState[talkUser] = 1
        end
    end
 
    local list = (msgcontains(msg, 'list'))
    if list then
    text = 'Donation Items\n'
        for i, x in pairs(items) do
                text = text .. "\n" .. i .. " - "..x.points.." points"
        end
        doShowTextDialog(cid, 7391, "" .. text)
        talkState[talkUser] = 1
    end
 
    if not x and not list and not buy and not agree and talkState[talkUser] == 2 then
        selfSay('You can\'t buy this item from me, look in the {list} which items you can buy.', cid)
    elseif not x and not list and not buy and not agree and talkState[talkUser] ~= 2 then
        selfSay('What? I don\'t understand what you mean with '..msg..'.', cid)
    end
    return true
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

in lib-function i have:

Lua:
function getAccountPoints(cid)
    local res = db.getResult('select `premium_points` from accounts where name = \''..getPlayerAccount(cid)..'\'')
    if(res:getID() == -1) then
       return false
    end
    local ret = res:getDataInt("premium_points")
    res:free()
    return tonumber(ret)
end

function doAccountRemovePoints(cid, count)
        return db.executeQuery("UPDATE `accounts` SET `premium_points` = '".. getAccountPoints(cid) - count .."' WHERE `name` ='"..getPlayerAccount(cid).."'")
end
Now i have this functional script (thanks @Alberto Cabrera ), but want to make two improvements. I need to say "buy" first and then say the item, would I be able to say "buy premium coin" in the same sentence, for example? The other thing would be to buy in quantities, for example: "buy 100 premium coins", it only accepts buying 1 by 1.

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
local talkItems = {}
 
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 onPlayerEndTrade(cid)              npcHandler:onPlayerEndTrade(cid)            end
function onPlayerCloseChannel(cid)          npcHandler:onPlayerCloseChannel(cid)        end

local items = {
    -- lower case name
    ["premium coin"] = {points = 1, itemid = 5263, count = 1},
    ["exp scroll"] = {points = 2, itemid = 5161, count = 1}
}

local info_items = ""

for key, value in pairs(items) do
    info_items = info_items .. "x" .. value.count .. " " .. key .. ", Price: " .. value.points .. " points\n"
end
 
function creatureSayCallback(cid, type, msg)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
 
    local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
 
    if msgcontains(msg, 'buy') then
        selfSay('Which donate item would you like to buy?', cid)
        talkState[talkUser] = 1
    elseif msgcontains(msg, 'list') then
        doShowTextDialog(cid, 7391, "Donation Iems\n\n" .. info_items)
    elseif talkState[talkUser] == 1 and not items[msg:lower()] then
        selfSay('This item does not exist in the shopping list, to know the list of available items, type list.', cid)
    elseif talkState[talkUser] == 1 and items[msg:lower()] then
        local value = items[msg:lower()]
        talkState[talkUser] = 2
        talkItems[talkUser] = { value.itemid, value.count, value.points }
        selfSay(('Do you want to buy %d %s for %d premium points?'):format(value.count, msg, value.points), cid)
    elseif talkState[talkUser] == 2 and msgcontains(msg, 'no') then
        selfSay('Ok, then?', cid)
        talkState[talkUser] = nil
        talkItems[talkUser] = nil
    elseif talkState[talkUser] == 2 and msgcontains(msg, 'yes') then
        if getAccountPoints(cid) < talkItems[talkUser][3] then
            selfSay('You don\'t have enough points.', cid)
            talkState[talkUser] = nil
            talkItems[talkUser] = nil
            return false
        end
        doAccountRemovePoints(cid, talkItems[talkUser][3])
        doPlayerAddItem(cid, talkItems[talkUser][1], talkItems[talkUser][2])
        selfSay('Here you are, have fun with it.', cid)
        talkState[talkUser] = nil
        talkItems[talkUser] = nil
    end
    return true
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Solved with this script, thanks again @Alberto Cabrera

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
local talkItems = {}
 
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 onPlayerEndTrade(cid)              npcHandler:onPlayerEndTrade(cid)            end
function onPlayerCloseChannel(cid)          npcHandler:onPlayerCloseChannel(cid)        end

local items = {
    -- lower case name
    ["premium coin"] = {points = 1, itemid = 5263, count = 1},
    ["exp scroll"] = {points = 2, itemid = 5161, count = 1}
}

local info_items = ""

for key, value in pairs(items) do
    info_items = info_items .. "x" .. value.count .. " " .. key .. ", Price: " .. value.points .. " point" .. (value.points > 1 and 's' or '') .. "\n"
end
 
function creatureSayCallback(cid, type, msg)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
 
    local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
 
    if msgcontains(msg, 'buy') then
        selfSay('Which donate item would you like to buy?', cid)
        talkState[talkUser] = 1
    elseif msgcontains(msg, 'list') then
        doShowTextDialog(cid, 7391, "Donation Items\n\n" .. info_items)
    elseif talkState[talkUser] == 1 and not items[msg:lower()] then
        selfSay('This item does not exist in the shopping list, to know the list of available items, type list.', cid)
    elseif talkState[talkUser] == 1 and items[msg:lower()] then
        local value = items[msg:lower()]
        talkState[talkUser] = 2
        talkItems[talkUser] = {value.itemid, value.points}
        selfSay('How much do you want to buy?', cid)
        -- talkItems[talkUser] = { value.itemid, value.count, value.points }
        -- selfSay(('Do you want to buy %d %s for %d premium points?'):format(value.count, msg, value.points), cid)
    elseif talkState[talkUser] == 2 and msg then
        if not tonumber(msg) then
            return selfSay('You can only type numbers', cid)
        elseif tonumber(msg) < 1 or tonumber(msg) > 100 then
            return selfSay('You can only enter a number between the range 1-100', cid)
        end
        talkState[talkUser] = 3
        talkItems[talkUser][3] = tonumber(msg)
        selfSay(('Do you want to buy %d %s for %d premium point%s?'):format(talkItems[talkUser][3], getItemNameById(talkItems[talkUser][1]), talkItems[talkUser][2] * talkItems[talkUser][3], tonumber(msg) > 1 and 's' or ''), cid)
    elseif talkState[talkUser] == 3 and msgcontains(msg, 'no') then
        selfSay('Ok, then?', cid)
        talkState[talkUser] = nil
        talkItems[talkUser] = nil
    elseif talkState[talkUser] == 3 and msgcontains(msg, 'yes') then
        local count = talkItems[talkUser][3] * talkItems[talkUser][2]
        if getAccountPoints(cid) < count then
            selfSay('You don\'t have enough points.', cid)
            talkState[talkUser] = nil
            talkItems[talkUser] = nil
            return false
        end
        doAccountRemovePoints(cid, count)
        if isItemStackable(talkItems[talkUser][1]) then
            doPlayerAddItem(cid, talkItems[talkUser][1], talkItems[talkUser][3])
        else
            for i = 1, talkItems[talkUser][3] do
                doPlayerAddItem(cid, talkItems[talkUser][1], i)
            end
        end
        selfSay('Here you are, have fun with it.', cid)
        talkState[talkUser] = nil
        talkItems[talkUser] = nil
    end
    return true
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())
 
Solution
Solved with this script, thanks again @Alberto Cabrera

Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
local talkItems = {}
 
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 onPlayerEndTrade(cid)              npcHandler:onPlayerEndTrade(cid)            end
function onPlayerCloseChannel(cid)          npcHandler:onPlayerCloseChannel(cid)        end

local items = {
    -- lower case name
    ["premium coin"] = {points = 1, itemid = 5263, count = 1},
    ["exp scroll"] = {points = 2, itemid = 5161, count = 1}
}

local info_items = ""

for key, value in pairs(items) do
    info_items = info_items .. "x" .. value.count .. " " .. key .. ", Price: " .. value.points .. " point" .. (value.points > 1 and 's' or '') .. "\n"
end
 
function creatureSayCallback(cid, type, msg)
    if(not npcHandler:isFocused(cid)) then
        return false
    end
 
    local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
 
    if msgcontains(msg, 'buy') then
        selfSay('Which donate item would you like to buy?', cid)
        talkState[talkUser] = 1
    elseif msgcontains(msg, 'list') then
        doShowTextDialog(cid, 7391, "Donation Items\n\n" .. info_items)
    elseif talkState[talkUser] == 1 and not items[msg:lower()] then
        selfSay('This item does not exist in the shopping list, to know the list of available items, type list.', cid)
    elseif talkState[talkUser] == 1 and items[msg:lower()] then
        local value = items[msg:lower()]
        talkState[talkUser] = 2
        talkItems[talkUser] = {value.itemid, value.points}
        selfSay('How much do you want to buy?', cid)
        -- talkItems[talkUser] = { value.itemid, value.count, value.points }
        -- selfSay(('Do you want to buy %d %s for %d premium points?'):format(value.count, msg, value.points), cid)
    elseif talkState[talkUser] == 2 and msg then
        if not tonumber(msg) then
            return selfSay('You can only type numbers', cid)
        elseif tonumber(msg) < 1 or tonumber(msg) > 100 then
            return selfSay('You can only enter a number between the range 1-100', cid)
        end
        talkState[talkUser] = 3
        talkItems[talkUser][3] = tonumber(msg)
        selfSay(('Do you want to buy %d %s for %d premium point%s?'):format(talkItems[talkUser][3], getItemNameById(talkItems[talkUser][1]), talkItems[talkUser][2] * talkItems[talkUser][3], tonumber(msg) > 1 and 's' or ''), cid)
    elseif talkState[talkUser] == 3 and msgcontains(msg, 'no') then
        selfSay('Ok, then?', cid)
        talkState[talkUser] = nil
        talkItems[talkUser] = nil
    elseif talkState[talkUser] == 3 and msgcontains(msg, 'yes') then
        contagem local = talkItems [talkUser] [3] * talkItems [talkUser] [2]
        if getAccountPoints (cid) <count then
            selfSay ('Você não tem pontos suficientes.', cid)
            talkState [talkUser] = nulo
            talkItems [talkUser] = nulo
            retorna falso
        fim
        doAccountRemovePoints(cid, count)
        if isItemStackable (talkItems [talkUser] [1]) então
            doPlayerAddItem(cid, talkItems[talkUser][1], talkItems[talkUser][3])
        outro
            para i = 1, talkItems [talkUser] [3] fazem
                doPlayerAddItem(cid, talkItems[talkUser][1], i)
            fim
        fim
        selfSay ('Aqui está, divirta-se com isso.', cid)
        talkState [talkUser] = nulo
        talkItems [talkUser] = nulo
    fim
    retornar verdadeiro
fim
 
npcHandler: setCallback (CALLBACK_MESSAGE_DEFAULT, criaturaSayCallback)
npcHandler: addModule (FocusModule: new ())
[/CÓDIGO]
[/QUOTE]

Ei como está tudo? Você usa o Nostalrius como base? Você poderia compartilhar seu Exp Scroll?
 
Back
Top