Ir para conteúdo

Npc shop offline


Poccnn

Posts Recomendados

Hail Xtibianos!

 

Trago um npc que vende seus items no jogo pelo preço que vocês quiserem oferta-lo.

Tu que tem um item e não quer ficar ofertando no canal de trade, ponha a venda com o npc, assim, quem quiser comprar um item seu, verifica as ofertas que tem naquele determinado npc (pois depende de onde ele estiver).

 

O sistema do npc consiste no seguinte:

 

  • O player põe o item na lista de ofertas (venda) com o npc.
  • O player pode cancelar sua's oferta's naquele npc em que foi feita a oferta.
  • O player pode comprar os items na lista, somente naquele local (pois é determinado pelo town).
  • O player recebe o valor do item, desde que tenha sido vendido. 

 

Bom... vamos ao que interessa; o código. 

Para usar esse npc, tu irás precisar usar a livraria xml criada por mim que se encontra nesse link.

 

Algumas funções extras que tu irás precisar por no seu servidor.

Citar

function getTownInArea(pos, ranger) --[[( Marcryzius )]]-- 
local ranger,townid,bloked = ranger or 200,1,{11,12} -- towns bloqueados. 
   while getTownName(townid) do 
   local get  = getTownTemplePosition(townid) 
      if not(isInArray(bloked,townid)) and ((pos.x >= get.x-ranger and pos.x <= get.x+ranger)and(pos.y >= get.y-ranger and pos.y <= get.y+ranger))then 
         return townid 
      else 
         townid = townid+1 
      end 
   end 
   return 0 --retorna 0 (zero) para servir como condição. 
end 

 

string.trade = function(str) --[[( Marcryzius )]]-- 
local tab,str = {},str:lower() 
   tab[1] = str:match('sell') or 'buy'  -- Retorna se vai comprar ou vender. 
   tab[2] = getCount(str) < 1 and 1 or getCount(str) -- Retorna a quantidade. 
   tab[3] = str:match(tab[1]..(str:match('(%d+)') and "%s%d+%s" or " ").."(.+)") -- Retorna o nome do item. 
   if not(tab[3])then 
   local name = '' 
      for nome in str:gmatch("(%a+)") do 
         if(nome)then 
            name = name..(name ~= '' and ' ' or '')..nome 
         end 
      end 
      tab[3] = name 
   end 
   return unpack(tab) 
end 

 

function getCount (s)

return tonumber (s) and s or tonumber (s:match ("%d+")) or 0

end

 

 

 

Npc.xml

Citar

<?xml version="1.0" encoding="UTF-8"?> 
<npc name="Ana" script="data/npc/scripts/Sell/logeiro.lua" walkinterval="2000" floorchange="0"> 
   <health now="100" max="100"/> 
   <look type="139" head="0" body="39" legs="39" feet="132" addons="3"/> 
   <voices> 
      <voice text="Ponha o seu item a venda comigo!" interval2="120" randomspectato="0" /> 
   </voices> 
   <parameters> 
      <parameter key="message_greet" value="Hola {|PLAYERNAME|}! Eu sou uma vendedora. gostaria de ver os 'items' que tenho a venda?." /> 
      <parameter key="message_decline" value="Volte sempre"/> 
        <parameter key="module_keywords" value="1" /> 
        <parameter key="keywords" value="help;job;trade;food;receive;parcel" /> 
        <parameter key="keyword_reply1" value="Caso queira (vender) algum item eu cobro uma taxa para por na (lista) de vendas, voce vai (receber) a quantia quando alguem (comprar) seu item, tambem podera (cancelar) sua venda." /> 
        <parameter key="keyword_reply2" value="Sou uma revendedora de items." /> 
        <parameter key="keyword_reply3" value="Para querer comprar ou vender items avulsos, fale com a npc Sellina." /> 
        <parameter key="keyword_reply4" value="Fale com o npc donald, lector ou frodo eles que vendem food." /> 
        <parameter key="keyword_reply5" value="Fale com o npc Rony ele que cuida das postagens." /> 
        <parameter key="keyword_reply6" value="Fale com o npc Rony ele que cuida das postagens." /> 
   </parameters> 
</npc>

 

Npc.lua

Citar

--[[( Marcryzius )]]-- 
local talkState = {} 
tabitems = {} 
local sell,buy,custo,arq,sell_obj,msgc = {},{},0,'data/npc/lib/logeiro.xml' 

local keywordHandler = KeywordHandler:new() 
local npcHandler = NpcHandler:new(keywordHandler) 
NpcSystem.parseParameters(npcHandler) 

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 loadTabeItems() -- testado. ok. 
local lerfile = xml:load(arq) 
   tabitems = lerfile:eval('items') 
end 

 

local function saveTabItems() --testado. ok. 
local novo = xml:new('objetos') 
   for _,tab in pairs(tabitems) do 
      if(tonumber(tab.vend) > 0 or tonumber(tab.count) > 0)then 
         novo:tag('items',{price = tab.price, itemid = tab.itemid, vend = tab.vend, count = tab.count, name = tab.name, townid = tab.townid}) 
      end 
   end 
   novo:save(arq) 
end 

 

local function listItems(cid,town,send) -- testado. ok. 
local str,tab,town = '',{},tonumber(town) and tonumber(town) or type(town) == 'string' and getTownIdByName(town) or '' 
   for k,v in pairs(tabitems) do 
      if(tonumber(v.townid) == town and tonumber(v.count) > 0)then 
         str = str..'\nid: ['..(#tab+1)..'] >> Item: "'..getItemNameById(v.itemid)..'" Valor: "'..v.price..'" Quantidade: "'..v.count..'"' 
         local t = {id=k} 
         for n,d in pairs(v) do 
            t[n] = d 
         end 
         table.insert(tab,t) 
      end 
   end 
   if not(send)then return tab,doPlayerPopupFYI(cid,'Diga {buy + id} do item desejado\n'..str) else return tab end 
end 

 

local function getPay(cid,town) -- testado. ok. 
local cid,town = getCreatureName(cid):lower(),tonumber(town) and tonumber(town) or type(town) == 'string' and getTownIdByName(town) or '' 
local cash,list,remover = 0,'',{} 
   for id, v in pairs(tabitems) do 
      if(tonumber(v.townid) == town and v.name:lower() == cid and tonumber(v.vend) > 0)then 
         cash,list = cash+(tonumber(v.price)*tonumber(v.vend)),list..(list == '' and '' or ', ')..v.vend..' '..getItemNameById(v.itemid) 
         tabitems[id].vend = 0 
      end 
   end 
   saveTabItems() 
   return cash,list 
end 

 

local function getListPerName(cid,town) -- testado. ok. 
local cid,tab,list,q,town = getCreatureName(cid),{},'',0,tonumber(town) and tonumber(town) or type(town) == 'string' and getTownIdByName(town) or 0 
   for id, v in pairs(tabitems) do 
      if(tonumber(v.townid) == town and v.name == cid and tonumber(v.vend) == 0)then 
         tab[getItemNameById(v.itemid):lower()] = {id=id,price=v.price,quant=v.count,itemid=v.itemid} 
         list = list..(list == '' and ' ' or ', ')..getItemNameById(v.itemid) 
         q = q+1 
      end 
   end 
   return tab,list,q 
end 

 

function creatureSayCallback(cid, typer, msg) 
local city = getTownInArea(getCreaturePosition(getNpcCid())) 
local msg = msg:lower() 
local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid 
local tipo,quan,item = msg:trade() 

if not(tabitems[1])then loadTabeItems() end 
if not(npcHandler:isFocused(cid)) then   return false   end 

-- venda de objetos 
-- mostra a lista de items postos a venda 
   if(msg:match('list') or msg:match('item'))then 
      listItems(cid,city) 
      npcHandler:say('Esses sao os items que eu tenho no momento.',cid) 
   elseif(msg:match('sell') or msg:match('vend'))then 
      sell[getCreatureName(cid)] = { 
         itemid       = type(item) == 'string' and getItemIdByName(item), 
         vend          = 0, 
         townid       = city, 
         count       = quan, 
         price          = 0, 
         name       = getCreatureName(cid) 
      } 
      sell_obj = sell[getCreatureName(cid)] 
      if(sell_obj.itemid)then 
         talkState[talkUser] = 1 
         npcHandler:say('Voce gostaria de vender '..sell_obj.count..' '..item..' por quantos Gps'..(sell_obj.count == 1 and "" or " cada")..'?',cid) 
      else 
         npcHandler:say('Qual o nome do item que voce quer vender?',cid) 
         talkState[talkUser] = 12 
      end 
-- preco 
   elseif(talkState[talkUser] == 1)then 
   local price = msg:match('%d+') 
      if(price)then 
         sell[getCreatureName(cid)].price = price 
         custo = (price/100 < 10) and (10*sell_obj.count) or ((price/100)*5)*sell_obj.count -- comissão de 5% do valor do produto para cada item. 
         npcHandler:say('Eu cobro '..custo..'Gps para poder oferta-lo; aceita?',cid) 
         talkState[talkUser] = 11 
      else 
         npcHandler:say('Desculpe nao entendi o valor.',cid) 
      end 
-- põe o item a venda 
   elseif(talkState[talkUser] == 11)then 
      if(msg:match('yes') or msg:match('sim'))then 
         if(getPlayerItemCount(cid,sell_obj.itemid) >= sell_obj.count and getPlayerMoney(cid) >= custo)then 
            if(doPlayerRemoveItem(cid,sell_obj.itemid,sell_obj.count,true) and doPlayerRemoveMoney(cid,custo))then 
               table.insert(tabitems,sell_obj) 
               saveTabItems() 
               npcHandler:say('Esta a venda seu '..getItemNameById(sell_obj.itemid)..'; Quando eu tiver vendido-o, venha buscar seu dinheiro.',cid) 
            else 
               npcHandler:say('Desculpe mas, ocorreu um erro ao autenticar a venda; desculpe pelo transtorno; volte mais tarde.',cid) 
            end 
         else 
            npcHandler:say('Desculpe, mas tu nao tem '..sell_obj.count..' '..getItemNameById(sell_obj.itemid)..' para poder oferta-la e, ou não tem '..custo..'Gps para po-la a venda.',cid) 
         end 
      else 
         npcHandler:say('Entao gostaria de comprar algo? consulte a lista de \'items\'.',cid) 
      end 
      talkState[talkUser] = 0 
   elseif(talkState[talkUser] == 12)then 
      if(item and item ~= '' and getItemIdByName(item))then 
         sell_obj.itemid = getItemIdByName(item) 
         talkState[talkUser] = 1 
         npcHandler:say('Voce gostaria de vender '..sell_obj.count..' '..item..' por quantos Gps'..(sell_obj.count == 1 and "" or " cada")..'?',cid) 
      else 
         npcHandler:say('Certifique-se que o nome do produto esteja correto.',cid) 
      end 
-- recebe o dinheiro do produto vendido 
   elseif(msg:match('pay') or msg:match('receb'))then 
   local cash,list = getPay(cid,city) 
      if(cash > 0)then 
         doPlayerAddMoney(cid,cash) 
         npcHandler:say('Obrigado; Tome seus '..cash..' Gps pela venda de: '..list..'; Tem algo mais que gostaria de vender?.',cid) 
      else 
         npcHandler:say('Desculpe, mas ainda não compraram nada seu e, ou voce nao tem nenhuma venda que possa ser cancelada.',cid) 
      end 
-- cancela alguma oferta (feita por ele) 
   elseif(msg:match('cancel'))then 
      local tab,list,quant = getListPerName(cid,city) 
      if(quant == 1)then 
         msgc = list:match('%s(.+)') 
         npcHandler:say('Voce gostaria de cancelar a venda do '..msgc..'?') 
         talkState[talkUser] = 2 
      elseif(quant > 1)then 
         npcHandler:say('Escolha o item que deseja remover da lista: '..list..'.') 
         talkState[talkUser] = 2 
      else 
         npcHandler:say('Voce nao tem items para ser cancelado.') 
      end 
   elseif(talkState[talkUser] == 2)then 
   local tab,list,quant = getListPerName(cid,city) 
      if(tab[msg] or msg:find('yes') or msg:find('sim'))then 
      local msg = tab[msg] and msg  or msgc 
         if(tabitems[tab[msg].id])then 
            table.remove(tabitems,tab[msg].id) 
            saveTabItems() 
            doPlayerAddItem(cid,tab[msg].itemid,tab[msg].quant) 
            npcHandler:say('Tome seu item de volta. Caso tenha algo mais a venda me informe.') 
         else 
            npcHandler:say('Desculpe, mas ocorreu um erro na autenticacao do cancelamento; volte mais tarde para efetivar seu cancelamento. Obrigado.') 
         end 
      else 
         npcHandler:say('Desculpe, mas nao entendi.') 
      end 
      talkState[talkUser] = 0 
-- compra items da lista 
   elseif(msg:match('buy') or msg:match('comp') or talkState[talkUser] == 31)then 
   local tabela = listItems(cid,city,true) 
   local func,id,quant = function(str) 
         local tab = {} 
            for qt in str:gmatch("(%d+)") do 
               table.insert(tab,tonumber(qt)) 
            end 
            if not(tab[2])then tab[2] = 1 end 
            return unpack(tab) 
         end 
         id,quant = func(msg) 
      if(tabela[id])then 
         buy = tabela[id] 
         if(quant <= tonumber(tabela[id].count))then 
            buy.quant = quant or 1 
            npcHandler:say('Gostaria de comprar '..buy.quant..' '..getItemNameById(buy.itemid)..' por '..(buy.price*buy.quant)..' Gps?',cid) 
         elseif(quant > tonumber(tabela[id].count))then 
            buy.quant = tonumber(tabela[id].count) 
            npcHandler:say('Desculpe, mas somente existe\'m '..buy.quant..' desse item; gostaria de comprar somente ele\'s?',cid) 
         end 
         talkState[talkUser] = 3 
      else 
         talkState[talkUser] = 31 
         npcHandler:say('Desculpe, mas qual e o id do produto?',cid) 
      end 
   elseif(talkState[talkUser] == 3)then 
      if(msg:match('yes') or msg:match('sim'))then 
         if(doPlayerRemoveMoney(cid,(buy.price*buy.quant)))then 
            doPlayerAddItem(cid,buy.itemid,buy.quant) 
            tabitems[buy.id].count = buy.count-buy.quant 
            tabitems[buy.id].vend = tabitems[buy.id].vend+buy.quant 
            npcHandler:say('Obrigado pela compra e pela preferencia',cid) 
            saveTabItems() 
         else 
            npcHandler:say('Desculpe, mas voce não tem dinheiro suficiente.',cid) 
         end 
      else 
         npcHandler:say('Então gostaria de escolher outro item?',cid) 
      end 
      talkState[talkUser] = 0 
   else 
      npcHandler:say('Desculpe, mas não entendi o que desejas!',cid) 
   end 
   return true 
end 
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) 
npcHandler:addModule(FocusModule:new()) 

 

Lembrando que todos os códigos estão formatados em UTF8, converta para ANSI antes de usá-los.

 

Qualquer erro ou incompatibilidade no seu servidor, deixe nos comentarios.

Editado por Poccnn
Inserção de códigos
Link para o comentário
Compartilhar em outros sites

  • 2 weeks later...

perdoa minha ignorancia mas tenho duvidas...

no topico da livraria, eu coloco onde a "livraria"? na pasta libs? no 050-function? crio um .lua novo na libs?

 

onde colo as "funções extras que tu irás precisar por no seu servidor" ?

 

ta tudo muito confuso.. o nome do script do npc n condiz com o nome que vc sugeriu para colocar, ai dentro do script do npc tem isso " data/npc/lib/logeiro.xml " que eu nao sei como fazer

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

1 hora atrás, Pablobion disse:

perdoa minha ignorancia mas tenho duvidas...

 

no topico da livraria, eu coloco onde a "livraria"? na pasta libs? no 050-function? crio um .lua novo na libs?

 

onde colo as "funções extras que tu irás precisar por no seu servidor" ?

 

ta tudo muito confuso.. o nome do script do npc n condiz com o nome que vc sugeriu para colocar, ai dentro do script do npc tem isso " data/npc/lib/logeiro.xml " que eu nao sei como fazer

 

A livraria fica na pasta lib; tu cria um novo arquivo com extensão lua dentro dessa pasta e insere o código dela.

 

As funções extras, tu põe no arquivo 050-functions.lua

 

Eu não coloquei nome nos arquivos lua e xml do npc devido às pessoas nomearem eles da forma que quiserem.

Onde está npc.lua é o arquivo lua do npc e npc.xml é o arquivo xml do npc.

Link para o comentário
Compartilhar em outros sites

8 horas atrás, Poccnn disse:

 

A livraria fica na pasta lib; tu cria um novo arquivo com extensão lua dentro dessa pasta e insere o código dela.

 

As funções extras, tu põe no arquivo 050-functions.lua

 

Eu não coloquei nome nos arquivos lua e xml do npc devido às pessoas nomearem eles da forma que quiserem.

Onde está npc.lua é o arquivo lua do npc e npc.xml é o arquivo xml do npc.

Muito obrigado, é...  data/npc/lib/logeiro.xml  preciso criar esse xml? la na lib do npc? 

 

aqui fala que o luaXML_lib.dll não é um aplicativo win32 valido? ;/: obs: baixei essa dll da internet porque nao achei onde encontrar no meu pc kkk se puder me passar.

 

desculpa mais uma vez sou mei lerdo.

Link para o comentário
Compartilhar em outros sites

2 horas atrás, Pablobion disse:

Muito obrigado, é...  data/npc/lib/logeiro.xml  preciso criar esse xml? la na lib do npc? 

 

aqui fala que o luaXML_lib.dll não é um aplicativo win32 valido? ;/: obs: baixei essa dll da internet porque nao achei onde encontrar no meu pc kkk se puder me passar.

 

desculpa mais uma vez sou mei lerdo.

Tu não precisa criar esse arquivo, o sistema ja faz isso.

Tu estás usando a livraria errada. Usa a livraria que está no tópico. 

Link para o comentário
Compartilhar em outros sites

41 minutos atrás, Poccnn disse:

Tu não precisa criar esse arquivo, o sistema ja faz isso.

Tu estás usando a livraria errada. Usa a livraria que está no tópico. 

verdade, acabei me confundindo com os links..

 

 

quando eu vou falar com npc da esses erros, o que mais fiz de errado?

fdgdf.png

fdgdf.png.e2a6c104be8cefb4896764350ae28279.png

Link para o comentário
Compartilhar em outros sites

11 minutos atrás, Poccnn disse:

@Pablobion 

Muitos otservers já vem com essa função então achei desnecessário po-la.

 

 

puts pelo visto acho que nao vai dar então, cada etapa e avanço aparece mais erro de falta  de function :/

esse aparece quando vou setar o valor do item

errors.png

errors.png.d3e0a3d802a21759cd9ac49423f7a36e.png

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

Esse erro não é por falta de função e sim por um empecilho no código da função. 

Fiz essa mudança;  tenta agora. 

Citar


function getCount (s)
 return tonumber(s) and s or s:match ("%d+") or 0
end

 

Não use essa função de cima, pois Recreio código. 

Use essa.

Citar

function getCount (s)
 return tonumber(s) and s or tonumber(s:match ("%d+")) or 0
end

 

@Pablobion

Link para o comentário
Compartilhar em outros sites

11 minutos atrás, Poccnn disse:

Esse erro não é por falta de função e sim por um empecilho no código da função. 

Fiz essa mudança;  tenta agora. 

 

Não use essa função de cima, pois Recreio código. 

Use essa.

 

@Pablobion

perdão meu bom, ainda continua com mesmo erro, tava analisando aqui do pouco que sei esses negocios da 050 function muda do 0.4 para 1.x né? to achando que a versao dos tfs sao diferentes.. nao entendo muito bem mas "str:match('sell') or 'buy'" isso me lembra scripts de tfs 1.0... posso ta falando besteira mas enfim.

Link para o comentário
Compartilhar em outros sites

Mas não é. Meu servidor é 0.3.6 e eu fiz ele para essa versão. 

Troca ela por essa:

Citar

function getCount (s)
 return tonumber(s) and tonumber(s) or tonumber(s:match ("%d+")) or 0
end

 

Link para o comentário
Compartilhar em outros sites

40 minutos atrás, Poccnn disse:

Mas não é. Meu servidor é 0.3.6 e eu fiz ele para essa versão. 

Troca ela por essa:

 

obrigado agora funcionou... quando fala "items" é para aparecer o pop-up dizendo "buy + id"? ou era para estar aparecendo a lista de itens disponiveis?

Link para o comentário
Compartilhar em outros sites

×
×
  • Criar Novo...