Ir para conteúdo

Trader NPC


zipter98

Posts Recomendados

Olá,

O propósito principal desse NPC é facilitar a vida de quem quer fazer NPCs "traders". A configuração é muito fácil, e também há mais interação entre player-NPC (não, esse NPC não é por janelinha de trade). Você pode configurar a moeda usada nas negociações, os items que o NPC vende, e os que compra. Também há opções de ver as ofertas, e vender todas as unidades de determinado item apenas dizendo "all".

Com esse NPC, também é poupado tempo, pois, ao invés de ir comprando/vendendo de 100 em 100 unidades de tal item, ou ficar ajustando a "barra de rolagem" para a quantidade desejada, você pode simplesmente digitar a quantidade (podendo comprar/vender, por exemplo, 400 unidades do item de uma vez!).

 

Opções de fala: offers/buy/sell. Neste último, há a opção "all" para vender todas as unidades do item.

 

Testei esse NPC várias vezes, e todos os bugs que apareceram foram corrigidos. Porém, se vocês encontrarem algum que deixei passar, postem aqui.

As configurações estão indicadas no script, e, como mencionado antes, é MUITO fácil configurar o NPC.

 

Vá em data/npc/scripts, crie um arquivo com extensão .lua, nomeie-o tradernpc, e coloque o seguinte conteúdo:

 

 

--[[ 
        OMS #3, código postado 06/12/2013.
        Trading NPC, by zipter98.
 
--]]
local function doCorrectNumber(number)  --POG.
local n = tostring(number)
local correct = number
    for i = 1, n:len() do
        local letter = n:sub(i, i)
        local check = 0
        for a = 0, 9 do
            a = tostring(a)
            if letter ~= a then 
                check = check + 1
                if check > 9 then
                    local verdadeiro = n:gsub(letter, "")
                    correct = tonumber(verdadeiro)
                    break
                end
            end
        end
    end
    return correct
end
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(not npcHandler:isFocused(cid)) then
return false
end
 
local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
 
---------------------------------[[ Configurações! --]]----------------------------------------
 
--Configure aqui os items que o NPC vende.
local cfg_buy = {                 
    ["box 2"] = {5, 11639},       --["o que o player deverá falar"] = {preço do item, id do item},
    ["box 3"] = {5, 11640},
    ["box 4"] = {5, 11641},
    ["revive"] = {1, 12343},
    ["ultra ball"] = {1, 2392},
}
 
--Configure aqui os items que o NPC compra.
local cfg_sell = {                  
    ["box 2"] = {1, 11639},       --["o que o player deverá falar"] = {preço do item, id do item},
    ["box 3"] = {1, 11640},
    ["box 4"] = {1, 11641},
    ["revive"] = {1, 12343},
}
 
--Configure aqui o ID do item que será usado nas comercializações!
local id_item = 2145             
--Configure aqui a quantidade máxima de items que o jogador poderá comprar/vender.
local max_quantidade = 300
---------------------------------[[ Fim das configurações! ]]---------------------------------
 
local item_buy = cfg_buy[msg]
local item_sell = cfg_sell[msg]
 
local nome_buy = tostring(getPlayerStorageValue(cid, 102991))
local id_buy = tonumber(getPlayerStorageValue(cid, 102992))
local price_buy = tonumber(getPlayerStorageValue(cid, 102993))
local qnt_buy = tonumber(getPlayerStorageValue(cid, 102994))
 
local nome_sell = tostring(getPlayerStorageValue(cid, 102995))
local id_sell = tonumber(getPlayerStorageValue(cid, 102996))
local price_sell = tonumber(getPlayerStorageValue(cid, 102997))
local qnt_sell = tonumber(getPlayerStorageValue(cid, 102998))
local all_sell = tonumber(getPlayerStorageValue(cid, 102999))
 
local buy = {}
local sell = {}
 
    for a, b in pairs(cfg_buy) do
        table.insert(buy, a)
    end
    
    for c, d in pairs(cfg_sell) do
        table.insert(sell, c)
    end
    
local stt = table.concat(buy, ", ")
local skk = table.concat(sell, ", ")
    
    if msgcontains(msg, 'offer') or msgcontains(msg, 'oferta') or msgcontains(msg, 'offers') then
        selfSay("Well, I sell "..stt..". And buy "..skk..".")
        talkState[talkUser] = 0
        return true
    elseif msgcontains(msg, 'buy') then
        selfSay("Ok, what item do you want buy?")
        talkState[talkUser] = 1
        return true
    elseif talkState[talkUser] == 1 then
        if item_buy then
            selfSay("Ok, one "..msg.." will cost "..item_buy[1].." "..getItemNameById(id_item)..". How many, please?")
            setPlayerStorageValue(cid, 102991, getItemNameById(item_buy[2]))
            setPlayerStorageValue(cid, 102992, item_buy[2])
            setPlayerStorageValue(cid, 102993, item_buy[1])
            talkState[talkUser] = 2
            return true
        else
            selfSay("I don't sell this item.")
            talkState[talkUser] = 1
            return true
        end
    elseif talkState[talkUser] == 2 then
        if tonumber(msg) == nil then
            selfSay("I told you to tell me how many "..nome_buy.." do you want.")
            talkState[talkUser] = 2
            return true
        elseif doCorrectNumber(tonumber(msg)) > max_quantidade then
            selfSay("This quantity is bigger than the maximum you can buy {["..max_quantidade.."]}.")
            talkState[talkUser] = 7
            return true
        elseif doCorrectNumber(tonumber(msg)) < 1 then
            selfSay("Please, say a quantity between {1} and {"..max_quantidade.."}.")
            talkState[talkUser] = 7
            return true
        else
            local correct = doCorrectNumber(tonumber(msg))
            selfSay("Then, you want buy "..correct.." "..nome_buy.."? It will cost you "..(correct * price_buy).." "..getItemNameById(id_item)..".")
            setPlayerStorageValue(cid, 102994, correct)
            talkState[talkUser] = 3
            return true
        end
    elseif msgcontains(msg, 'yes') and talkState[talkUser] == 3 then
        if getPlayerItemCount(cid, id_item) >= price_buy * qnt_buy then
            selfSay("Thank you! Here your "..qnt_buy.." "..nome_buy..".")
            doPlayerRemoveItem(cid, id_item, tonumber(price_buy * qnt_buy))
            if not isItemStackable(id_buy) then
                for i = 1, (qnt_buy - 1) do
                    doPlayerAddItem(cid, id_buy, 1)
                end
            else
                doPlayerAddItem(cid, id_buy, qnt_buy)
            end
            doPlayerAddItem(cid, id_buy, tonumber(getPlayerStorageValue(cid, 102994)))
            talkState[talkUser] = 0
            return true
        else
            selfSay("You don't have "..tonumber(price_buy * qnt_buy).." "..getItemNameById(id_item)..".")
            talkState[talkUser] = 0
            return true
        end
    elseif msgcontains(msg, 'no') or msgcontains(msg, 'nao') and talkState[talkUser] == 3 then
        selfSay("Ok, then...")
        talkState[talkUser] = 0
        return true
    elseif msgcontains(msg, 'sell') then
        selfSay("Oh, I can see you want sell some items. Can you tell me the name?")
        talkState[talkUser] = 6
        return true
    elseif talkState[talkUser] == 6 then
        if item_sell then
            selfSay("Ok, I pay "..item_sell[1].." "..getItemNameById(id_item).." for one "..msg..". How many do you want sell?")
            setPlayerStorageValue(cid, 102995, getItemNameById(item_sell[2]))
            setPlayerStorageValue(cid, 102996, item_sell[2])
            setPlayerStorageValue(cid, 102997, item_sell[1])
            talkState[talkUser] = 7
            return true
        else
            selfSay("I don't buy this item.")
            talkState[talkUser] = 6
            return true
        end
    elseif msgcontains(msg, 'all') and talkState[talkUser] == 7 then
        local quantity = getPlayerItemCount(cid, id_sell)
        if getPlayerItemCount(cid, id_sell) > max_quantidade then
           quantity = 100
        end
        selfSay("Do you really want sell all of your "..nome_sell.."? I will pay you "..tonumber(quantity * price_sell).." "..getItemNameById(id_item)..".")
        setPlayerStorageValue(cid, all_sell, quantity)
        talkState[talkUser] = 9
        return true
    elseif msgcontains(msg, 'yes') and talkState[talkUser] == 9 then
        if getPlayerItemCount(cid, id_sell) > 0 then
            selfSay("Ok, here your "..tonumber(getPlayerStorageValue(cid, all_sell) * price_sell).." "..getItemNameById(id_item)..".")
            doPlayerAddItem(cid, id_item, tonumber(getPlayerStorageValue(cid, all_sell) * price_sell))
            if not isItemStackable(id_sell) then
                for i = 1, tonumber(getPlayerStorageValue(cid, all_sell)) do
                    doPlayerRemoveItem(cid, id_sell, 1)
                end
            else
                doPlayerRemoveItem(cid, id_sell, tonumber(getPlayerStorageValue(cid, all_sell))
            end
            talkState[talkUser] = 0
            return true
        else
            selfSay("You don't have any "..nome_sell..".")
            talkState[talkUser] = 0
            return true
        end
    elseif talkState[talkUser] == 7 then
        if tonumber(msg) == nil then
            selfSay("I told you to tell me how many "..nome_sell.." do you want sell.")
            talkState[talkUser] = 7
            return true
        elseif doCorrectNumber(tonumber(msg)) > max_quantidade then
            selfSay("This quantity is bigger than the maximum I sell {["..max_quantidade.."]}.")
            talkState[talkUser] = 7
            return true
        elseif doCorrectNumber(tonumber(msg)) < 1 then
            selfSay("Please, say a quantity between {1} and {"..max_quantidade.."}.")
            talkState[talkUser] = 7
            return true
        else
            local correct = doCorrectNumber(tonumber(msg))
            selfSay("Then, you want sell "..correct.." "..nome_sell.."? I will pay you "..(correct * price_sell).." "..getItemNameById(id_item)..".")
            setPlayerStorageValue(cid, 102998, correct)
            talkState[talkUser] = 8
            return true
        end
    elseif msgcontains(msg, 'yes') and talkState[talkUser] == 8 then
        if getPlayerItemCount(cid, id_sell) >= qnt_sell then
            selfSay("Thank you! Here your "..(price_sell * qnt_sell).." "..getItemNameById(id_item)..".")
            if not isItemStackable(id_sell) then
                for i = 1, (qnt_sell - 1) do
                    doPlayerRemoveItem(cid, id_sell)
                end
            else
                doPlayerRemoveItem(cid, id_sell, qnt_sell)
            end
            doPlayerAddItem(cid, id_item, tonumber(price_sell * qnt_sell))
            talkState[talkUser] = 0
            return true
        else
            selfSay("Hey, you don't have "..qnt_sell.." "..nome_sell.."! Come back when you got it.")
            talkState[talkUser] = 0
            return true
        end
    elseif msgcontains(msg, 'no') and talkState[talkUser] == 8 then
        selfSay("Ok, then...")
        talkState[talkUser] = 0
        return true
    end       
    return true
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

 

 

XML:
<?xml version="1.0" encoding="UTF-8"?>
 
<npc name="Trader" script="tradernpc.lua" walkinterval="0" floorchange="0" access="5" level="1" maglevel="1">
<health now="150" max="150"/>
<look type="523" head="114" body="119" legs="114" feet="114" corpse="2212"/>
 
<parameters>
<parameter key="message_greet" value="Hello |PLAYERNAME|, I {sell} and {buy} items. Do you want to see my {offers}?"/>
</parameters>
</npc>
#EDIT, 08/12/2013, 21:42. Agora, ao dizer offers é dito pelo NPC o quê é configurado no "o que o player deverá falar". Assim, são evitadas confusões que poderiam haver antes, como, por exemplo, o nome do item dito no offers sendo pokemon prize box +4, e estando configurado para ser dito pelo jogador box 4.
#EDIT, 22/01/2014, 17:02. Agora, você pode escolher a quantidade máxima que o jogador poderá comprar/vender. Também foi corrigido alguns erros no NPC. PS: Obrigado ao lordbug99 por indicá-los.
#EDIT, 29/01/2014, 18:08. Para corrigir alguns bugs, foi adicionada ao código uma nova função. Foram também corrigidos alguns erros que poderiam ser causados no all, juntamente com a correção de uma maneira de conseguir comprar/vender uma quantia maior de items que a programada.
Editado por zipter98
Link para o comentário
Compartilhar em outros sites

Substitua por esse:

 

 

--[[ 
        OMS #3, código postado 06/12/2013.
        Trading NPC, by zipter98.
 
--]]
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(not npcHandler:isFocused(cid)) then
return false
end
 
local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
 
---------------------------------[[ Configurações! --]]----------------------------------------
 
--Configure aqui os items que o NPC vende.
local cfg_buy = {                 
    ["box 2"] = {5, 11639},       --["o que o player deverá falar"] = {preço do item, id do item},
    ["box 3"] = {5, 11640},
    ["box 4"] = {5, 11641},
    ["revive"] = {1, 12343},
    ["ultra ball"] = {1, 2392},
}
 
--Configure aqui os items que o NPC compra.
local cfg_sell = {                  
    ["box 2"] = {1, 11639},       --["o que o player deverá falar"] = {preço do item, id do item},
    ["box 3"] = {1, 11640},
    ["box 4"] = {1, 11641},
    ["revive"] = {1, 12343},
}
 
--Configure aqui o ID do item que será usado nas comercializações!
local id_item = 2145             
 
---------------------------------[[ Fim das configurações! ]]---------------------------------
 
local stt = ""
local skk = ""
 
local item_buy = cfg_buy[msg]
local item_sell = cfg_sell[msg]
 
local nome_buy = tostring(getPlayerStorageValue(cid, 102991))
local id_buy = tonumber(getPlayerStorageValue(cid, 102992))
local price_buy = tonumber(getPlayerStorageValue(cid, 102993))
local qnt_buy = tonumber(getPlayerStorageValue(cid, 102994))
 
local nome_sell = tostring(getPlayerStorageValue(cid, 102995))
local id_sell = tonumber(getPlayerStorageValue(cid, 102996))
local price_sell = tonumber(getPlayerStorageValue(cid, 102997))
local qnt_sell = tonumber(getPlayerStorageValue(cid, 102998))
     
    for a, b in pairs(cfg_buy) do
        if stt == "" then
            stt = getItemDescriptionsById(b[2]).name
        else
            name = getItemDescriptionsById(b[2]).name
            stt = stt..", "..name           
        end
    end
    
    for c, d in pairs(cfg_sell) do
        if skk == "" then
            skk = getItemDescriptionsById(d[2]).name
        else
            name = getItemDescriptionsById(d[2]).name
            skk = skk..", "..name            
        end
    end
    
    if msgcontains(msg, 'offer') or msgcontains(msg, 'oferta') or msgcontains(msg, 'offers') then
        selfSay("Well, I sell "..stt..", and buy "..skk..".")
        talkState[talkUser] = 0
        return true
    elseif msgcontains(msg, 'buy') then
        selfSay("Ok, what item do you want buy?")
        talkState[talkUser] = 1
        return true
    elseif talkState[talkUser] == 1 then
        if item_buy then
            selfSay("Ok, one "..msg.." will cost "..item_buy[1].." "..getItemDescriptionsById(id_item).name..". How many, please?")
            setPlayerStorageValue(cid, 102991, getItemDescriptionsById(item_buy[2]).name)
            setPlayerStorageValue(cid, 102992, item_buy[2])
            setPlayerStorageValue(cid, 102993, item_buy[1])
            talkState[talkUser] = 2
            return true
        else
            selfSay("I don't sell this item.")
            talkState[talkUser] = 1
            return true
        end
    elseif talkState[talkUser] == 2 then
        if tonumber(msg) == nil then
            selfSay("I told you to tell me how many "..nome_buy.." do you want.")
            talkState[talkUser] = 2
            return true
        else
            selfSay("Then, you want buy "..msg.." "..nome_buy.."? It will cost you "..(msg * price_buy).." "..getItemDescriptionsById(id_item).name..".")
            setPlayerStorageValue(cid, 102994, tonumber(msg))
            talkState[talkUser] = 3
            return true
        end
    elseif msgcontains(msg, 'yes') and talkState[talkUser] == 3 then
        if getPlayerItemCount(cid, id_item) >= price_buy * qnt_buy then
            selfSay("Thank you! Here your "..qnt_buy.." "..nome_buy..".")
            doPlayerRemoveItem(cid, id_item, tonumber(price_buy * qnt_buy))
            if not isItemStackable(id_buy) then
                for i = 1, (qnt_buy - 1) do
                    doPlayerAddItem(cid, id_buy, 1)
                end
            else
                doPlayerAddItem(cid, id_buy, qnt_buy)
            end
            doPlayerAddItem(cid, id_buy, tonumber(getPlayerStorageValue(cid, 102994)))
            talkState[talkUser] = 0
            return true
        else
            selfSay("You don't have "..tonumber(price_buy * qnt_buy).." "..getItemDescriptionsById(id_item).name..".")
            talkState[talkUser] = 0
            return true
        end
    elseif msgcontains(msg, 'no') or msgcontains(msg, 'nao') and talkState[talkUser] == 3 then
        selfSay("Ok, then...")
        talkState[talkUser] = 0
        return true
    elseif msgcontains(msg, 'sell') then
        selfSay("Oh, I can see you want sell some items. Can you tell me the name?")
        talkState[talkUser] = 6
        return true
    elseif talkState[talkUser] == 6 then
        if item_sell then
            selfSay("Ok, I pay "..item_sell[1].." "..getItemDescriptionsById(id_item).name.." for one "..msg..". How many do you want sell?")
            setPlayerStorageValue(cid, 102995, getItemDescriptionsById(item_sell[2]).name)
            setPlayerStorageValue(cid, 102996, item_sell[2])
            setPlayerStorageValue(cid, 102997, item_sell[1])
            talkState[talkUser] = 7
            return true
        else
            selfSay("I don't buy this item.")
            talkState[talkUser] = 6
            return true
        end
    elseif msgcontains(msg, 'all') and talkState[talkUser] == 7 then
        selfSay("Do you really want sell all of your "..nome_sell.."? I will pay you "..tonumber(getPlayerItemCount(cid, id_sell) * price_sell).." "..getItemDescriptionsById(id_item).name..".")
        talkState[talkUser] = 9
        return true
    elseif msgcontains(msg, 'yes') and talkState[talkUser] == 9 then
        if getPlayerItemCount(cid, id_sell) >= 1 then
            selfSay("Ok, here your "..tonumber(getPlayerItemCount(cid, id_sell) * price_sell).." "..getItemDescriptionsById(id_item).name..".")
            doPlayerAddItem(cid, id_item, tonumber(getPlayerItemCount(cid, id_sell) * price_sell))
            if not isItemStackable(id_sell) then
                for i = 1, tonumber(getPlayerItemCount(cid, id_sell)) do
                    doPlayerRemoveItem(cid, id_sell, 1)
                end
            else
                doPlayerRemoveItem(cid, id_sell, tonumber(getPlayerItemCount(cid, id_sell)))
            end
            talkState[talkUser] = 0
            return true
        else
            selfSay("You don't have any "..nome_sell..".")
            talkState[talkUser] = 0
            return true
        end
    elseif talkState[talkUser] == 7 then
        if tonumber(msg) == nil then
            selfSay("I told you to tell me how many "..nome_sell.." do you want sell.")
            talkState[talkUser] = 7
            return true
        else
            selfSay("Then, you want sell "..msg.." "..nome_sell.."? I will pay you "..(msg * price_sell).." "..getItemDescriptionsById(id_item).name..".")
            setPlayerStorageValue(cid, 102998, tonumber(msg))
            talkState[talkUser] = 8
            return true
        end
    elseif msgcontains(msg, 'yes') and talkState[talkUser] == 8 then
        if getPlayerItemCount(cid, id_sell) >= qnt_sell then
            selfSay("Thank you! Here your "..(price_sell * qnt_sell).." "..getItemDescriptionsById(id_item).name..".")
            if not isItemStackable(id_sell) then
                for i = 1, (qnt_sell - 1) do
                    doPlayerRemoveItem(cid, id_sell)
                end
            else
                doPlayerRemoveItem(cid, id_sell, qnt_sell)
            end
            doPlayerAddItem(cid, id_item, tonumber(price_sell * qnt_sell))
            talkState[talkUser] = 0
            return true
        else
            selfSay("Hey, you don't have "..qnt_sell.." "..nome_sell.."! Come back when you got it.")
            talkState[talkUser] = 0
            return true
        end
    elseif msgcontains(msg, 'no') and talkState[talkUser] == 8 then
        selfSay("Ok, then...")
        talkState[talkUser] = 0
        return true
    end       
    return true
end
 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

 

 

Se o erro persistir, me mande por PM seu NPC configurado.

Editado por zipter98
Link para o comentário
Compartilhar em outros sites

(msg * price_sell) --stirng * nunber, vai da erro

 

é melhor coloca um limite na quantidade de compra, os player podem abusar disso com valores absurdos que podem gerar lag,ou até compra degraça(no caso dos estacaveis acho que ele n receberia tbm porque assim com a quantidade item a ser removida seria absurda a ser adicionada tbm é,mas no caso dos n estacaveis n porque vai ser adionado por aquele loop(que vai fica gigantesco))

 

e colocar pra n pode usar numeros negativos e decimais.

 

e poderia colocar na configurções pra poder vender em packs do item(mais de um por um valor,sendo imposivel compra 1/2 pack)

 

tipo 100 infernal bolt( pack) por 1 gold nuget(dinheiro)

 

assim poderia vender packs de potion,munições,ect.

 

 

 

 

ps: numeros absurdos me refiro a coisas do tipo 5e15 (isso é so um numero)

Link para o comentário
Compartilhar em outros sites

×
×
  • Criar Novo...