Welcome to xTibia - Sua comunidade de Otserv e Tibia

Registre-se para utilizar nossas ferramentas e baixar conteúdos. Quando registrado e logado em sua conta, lhe garantimos uma experiência incrível em nossa comunidade!

Poccnn

tfs 0.3 Tutorial Coroutine Lua

Fala Xtibianos. 
Nesse tutorial, gostaria de explicar um pouco sobre coroutine e seu uso. 

 

Irei começar com uma lista de funções da coroutine. 

Citar

coroutine.create (f)               cria uma nova coroutine com uma função lua valida. 
coroutine.yield (···)                suspende a execução da coroutine. 
coroutine.resume (co [, val1, ···])    passa os valores para a coroutine. 
coroutine.running ()                pega a coroutine que esteja em execução. 
coroutine.status (co)                return "suspended", "running" ou "dead"
coroutine.wrap (f)                   cria uma nova coroutine no corpo com uma função lua valida. 

 

Irei começa falando sobre a principal função da coroutine. 

Citar

coroutine.create (f) 

 

No corpo dessa função, voce precisa declarar pontos para "suspender" a execução da coroutine. 

 

Ao criar a coroutine, ela se encontra no estado "suspended", ou seja, parada/pausada. 


para iniciar a coroutine, voce precisa ativar ela usando a função: 

Citar

coroutine.resume (co [, val1, ···]) 

 

Além de ativar/reativar a coroutine, você passa valores para a função da coroutine. 
A primeira ativação da coroutine, os argumentos passados não poderão ser modificados, ficam estáticos nos parâmetros da função. 

 

Citar

 

co = coroutine.create(function(a,b) 
-- verificando o estatus da coroutine. 
   print(coroutine.status(coroutine.running())) -- "running" 
   coroutine.yield(a+b) -- primeira chamada 
   coroutine.yield(a-b) -- segunda chamada 
   return a,b,"Fim da coroutine." -- chamada final usando return (facultativo). 
end) 

 

-- verificando o estatus da coroutine. 
print(coroutine.status(co))       -- "suspended" 
print(coroutine.resume(co,5,2))    -- saida >> 7 >> 5+2 
print(coroutine.resume(co,1,8))    -- saida >> 3 >> ??? 1-8 = -7 
print(coroutine.resume(co,9,55))   -- saida >> 5,2, Fim da coroutine. >> veja que são os valores passados na primeira chamada. 
-- verificando o estatus da coroutine. 
print(coroutine.status(co))       -- "dead" 

 

 

Veja que o resultado da segunda chamada não coincidem com os valores passados. Isso se dá devido aos parâmetros da função impregada na coroutine, não modificar seus valores. uma vez declarados os valores, eles não poderão ser modificados. 

 

uma chamada de coroutine a mais da quantidade de yield's existente na coroutine.

Citar

print(coroutine.resume(co,9,55))   -- saida >> cannot resume dead coroutine

 

Como demonstrado acima, ao exceder a quantidade de yield's, ela retorna essa mensagem (sem disparar erro no console). 

 

Agora você deva estar se perguntando: Então como fazer para pegar os valores que são passados em cada ativação? 


Vou explicar agora: 

a função yield pega os valores fornecidos e retorna-os; então você pode pegar esses valores usando variaveis para armazena-los. 

Citar

 

co = coroutine.create(function(a,b) 
   b,c = coroutine.yield(a+b) -- primeira chamada 
   c,d = coroutine.yield(b-c) -- segunda chamada. veja que modifiquei os parametros usados. 
   return c,d,"Fim da coroutine." -- chamada final usando return (facultativo). 
end) 

print(coroutine.resume(co,5,2))    -- saida >> 7 >> 5+2 
print(coroutine.resume(co,1,8))    -- saida >> -7 >> 1-8 << agora o resultado está certo, pois foi usados os valores passados pela segunda chamada. 
print(coroutine.resume(co,9,55))   -- saida >> 9,55, Fim da coroutine. << os dois numerais, são os valores passados na ultima chamada.

 

 

 

Mas, no corpo da função criada para a coroutine, você pode fazer chamadas a funções, pegar valores de variaveis globais, etc; sempre usando a função yield para "suspender" a coroutine. 

 

Citar

 

function add(a,b) 
   return coroutine.yield(a+b,"Valor retornado pela função add()") 
end 

m,n = 2,3 

co = coroutine.create(function(a,b) 
   c,d = add(a,b) 
   e,f = add(m,n) 
   return e,f, "Fim da coroutine." -- retorna os valores da ultima chamada. 
end) 

print(coroutine.resume(co,5,2))    -- saida >> 7, "Valor retornado pela função add()" >> 5+2 
print(coroutine.resume(co,1,8))    -- saida >> 5 >> "Valor retornado pela função add()" >> valores pegos das variaveis externa 'm' e 'n' >> 2+3 
print(coroutine.resume(co,9,55))   -- saida >> 9,55, Fim da coroutine. << os dois numerais, são os valores passados na ultima chamada.

 

 

Agora só falta comentar sobre a função: 

Citar

coroutine.wrap(f)

 
Assim como coroutine.create, a função auxiliar coroutine.wrap cria uma nova co-rotina, mas ao invés de retornar uma referência para a co-rotina, retorna uma função que, quando chamada, (re)invoca a co- rotina. 


De forma geral, a função coroutine.wrap oferece uma maior conveniência que coroutine.create; ela provê exatamente o que é usualmente necessario: uma função para reativar uma co-rotina. Por outro lado, o uso das funções coroutine.create e coroutine.resume permite o gerenciamento de erros (funções estas que não podem ser usada por wrap). 

 

Citar

 

-- fatorar o valor 
function fatorar(n) 
   if n > 1 then 
      coroutine.yield(n) 
      fatorar(n/2) -- recursividade 
   end 
end 

-- iterador 
iterator = coroutine.wrap(function(value) 
      fatorar(value) 
   end) 

print(iterator(32)) -- 32 
print(iterator())   -- 16 
print(iterator())   -- 8 
print(iterator())   -- 4 
print(iterator())   -- 2 
print(iterator())   -- 1 
print(iterator())   -- Disparado erro com mensagem: "cannot resume dead coroutine". 

 


A função retornada por coroutine.wrap não captura erros; qualquer erro provocado pela execução da co-rotina é propagado a seu chamador. 

 

É isso ai pessoal, espero que tenham gostado. qualquer duvida, sugestão ou critica, deixem nos comentários. 
 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito bom @Poccnn, sempre trazendo boas novidades relacionada a área de lua.

 

Queria eu poder exercer, mas é tenso aprender só :S.

Compartilhar este post


Link para o post
Compartilhar em outros sites

@kttallan

Qual sua dificuldade em aprender? 

Compartilhar este post


Link para o post
Compartilhar em outros sites
2 horas atrás, Poccnn disse:

@kttallan

Qual sua dificuldade em aprender? 

Bom eu fazia codigos antigamente, participei da primeira escolinha de scripting do xtibia a qual o roksas era o professor aprendi tudo até criar funções, hoje sei da logica só que não sei muito sobre.

 

For, While e Repeat e Strings, Table, Creio que o resto eu saiba como criar funções etcs..

Compartilhar este post


Link para o post
Compartilhar em outros sites

O que é uma corrotina em lua? É tipo um thread?

Compartilhar este post


Link para o post
Compartilhar em outros sites

amigao vc e genial porem sou um pouco leigo na area de programação.. poderia me explicar oque seria coroutine e em que tipo de situação é aplicado?

Compartilhar este post


Link para o post
Compartilhar em outros sites
Em 08/12/2016 at 21:33, newFag disse:

O que é uma corrotina em lua? É tipo um thread?

 

Não é uma thread. É um processo executado em modo separado.

 

1 hora atrás, Everson Miranda disse:

amigao vc e genial porem sou um pouco leigo na area de programação.. poderia me explicar oque seria coroutine e em que tipo de situação é aplicado?

 

Coroutine é uma forma de criar um processo que oode parar sua execução a qualquer momento e podendo retornar a execução a pedido do sistema.

É difícil fazer uma implementação dela no mundo do ot server, mas eu fiz essa:

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Caro membro,

Seu tópico foi movido de

Registre-se para ver link(s).

 para

Registre-se para ver link(s).

.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!


Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.


Entrar Agora

  • Conteúdo Similar

    • Por Poccnn
      MALLEUS MALEFICARUM
       
      O Martelo das Bruxas ou O Martelo das Feiticeiras é um livro que foi escrito e publicado em 1486 ou 1487 pelos dominicanos Heinrich Kraemer (também conhecido por Heinrich Institoris) e James Sprenger, na Alemanha, em cumprimento à bula papal Summis Desiderantis Affectibus de Inocêncio VIII, que os autorizava criar um manual de combate aos praticantes de heresias - e que veio a se tornar o guia dos inquisidores pelo restante do século XV e seguintes; embora outros manuais tenham sido escritos no período, este é dos mais "perversos e cruéis", verdadeiro "manual de ódio, de tortura e morte".
       

       
      Devido a heresia cometidas pelas pessoas que renegaram a fé um dia obtida e pactuando sua vida com o diabo, trouxeram para si a ira de Deus.
      Negaram a fé, negaram a igreja, negaram Deus e prestaram culto ao diabo.

       
       
       
       
      A ARTE DO PENTAGRAMA
       
      As Bruxas são mulheres que praticam culto ao diabo e se satisfazem de seu poder para suas feitiçarias, encantos e adivinhações. 
      Devido a suas capacidade de conhecerem as artes da magia negra, os Bruxos conseguem causar pânico por onde passam e onde atuam.
      O pentagrama é o simbolo chave para a Bruxaria; é dele que dizem que as forças do mal emanam e os Bruxos o usam para suas artes malignas.
       

       
       
      Não era para ser uma quest esse sistema, mas eu adaptei para poder publica-lo.
       
      Inicialmente foi desenvolvido apenas como forma de punição pela sentença dada pela inquisição aos acusados de bruxaria; agora ele se tornou uma quest.
       
      Adicionando o sistema.
       
      data/movements/movements.xml
      Registre-se para ver spoiler(s).
      mapa:

      Registre-se para ver attachment(s).
       
    • Por leozinpbb
      Esta dando esse probleminha aqui agora , e também não consigo atacar mais ninguém.

      Registre-se para ver attachment(s).
    • Por Poccnn
      Hail Xtibianos.
       
      Trago a vós uma serie de funções que eu uso no meu servidor e que pode ser úteis ao seu.
      Lembrando que algumas funções podem fazer uso de uma livraria xml criado por mim e posta nesse tópico.
       
       
      Essa função tem por objetivo criar uma data formatada (00:00:00) de um intervalo de tempo.
       
      function intervalClockFormat(ini,fim) --[[( Marcryzius )]]-- local ini,fim = tonumber(ini),tonumber(fim) if not(ini or fim)then return "error",print('function intervalClock erro: type de variaveis invalidas') end local tienpo = fim-ini -- existe o parametro de dia, mas não está sendo retornado (usado). local day,hour,minu,seco  = tienpo/60/60/23%30,math.floor(tienpo/60/60%23), math.floor(tienpo/60%60),math.floor(tienpo%60)     return (hour < 10 and "0"..hour or hour)..":"..(minu < 10 and "0"..minu or minu)..":"..(seco < 10 and "0"..seco or seco) end Ex:  print(intervalClockFormat(os.time(),os.time()+98)) >> 00:01:38 print(intervalClockFormat(os.time(),os.time()+6598)) >> 01:49:58
      Essas funções tem por objetivo salvar as informações de uma determinada quest e saber se o player tem essa quest salva em seu histórico. 
      function saveQuestsInfor(uid,name,cid,other) --[[( Marcryzius )]]-- --[[     uid = Item.uid usado no bau(entre outros) para receber o item da Quest     name = nome do item dado ao player ou nome da quest     cid = identificacao do player     other = informacoes adicionais para serem salvas junto a quest ]]-- if not(db.executeQuery("SELECT * FROM `server_quests`;"))then -- caso a table não exista, será criada     db.executeQuery("CREATE TABLE `server_quests` (`uid` INTEGER, `name` VARCHAR(255), `name_player` VARCHAR(255), `pos` VARCHAR(255), `other` TEXT);") end -- caso o parametro uid seja numero, se pega a posição do item ou, caso não, se pega a posição do player. local other,pos2 = other or '','' local pos = type(uid) == 'number' and getThingPos(uid) or getCreaturePosition(cid)     pos2 = 'x='..pos.x..', y='..pos.y..', z='..pos.z          -- verifica se tudo está correto.     if not(type(name) == 'string') or not(tonumber(cid))then          return false, print('Funcao requer parametros: name,cid')      end          -- salva as informações na database.     db.executeQuery("INSERT INTO `server_quests` (`uid`, `name`, `name_player`,`pos`,`other`) VALUES ("..(uid or tonumber(pos.x..''..pos.y..''..pos.z))..",'"..name.."', '"..getCreatureName(cid).."','"..pos2.."','"..other.."');")     return true end function getSaveQuestsInfor(uid,cid) --[[( Marcryzius )]]-- local str = false     if(tonumber(uid))then         str = db.getResult("SELECT * FROM `server_quests` WHERE `uid` = '"..uid.."' AND `name_player` = ".. db.escapeString(getCreatureName(cid))..";")     elseif(type(uid) == 'string')then         str = db.getResult("SELECT * FROM `server_quests` WHERE `name_player` = " ..db.escapeString(getCreatureName(cid)).. " AND `name` = '"..uid.."';")     else         return false,print('getSaveQuestInfor: tipo de uid invalido > '..tostring(type(uid)))     end     return (str:getID() == -1) and true or false  end  
      Essa função serve para por a primeira letra de cada palavra da 'msg' em maiúscula.
      function upperPrimer(msg) --[[( Marcryzius )]]-- local txt = ''     for k in string.gmatch(msg,'%a+') do         if(#k > 1)then             txt = txt..' '..k:gsub("^%a", function(s) return s:upper() end)         else             txt = txt..' '..k         end     end     return txt:sub(2,-1) end Ex: print(upperPrimer("toda primeira letra de cada palavra desse texto foi colocada em maiusculo")) >> Toda Primeira Letra De Cada Palavra Desse Texto Foi Colocada Em Maiusculo  
      Função criada para determinar o valor inteiro mais próximo de uma fração.
      function math.proxInteger(value) --[[( Marcryzius )]]--  local value = tonumber(value)     if not(value)then return 0,print('Function error: math.proxInteger() > valor => '..type(value)) end     return value-math.floor(value) < 0.5 and math.floor(value) or math.ceil(value) end  
      Essa função converte a 'string' em números e devolve a soma de todos os números.
      function getStoreString(str) --[[( Marcryzius )]]-- local store = 0     if(type(str) == 'string')then         for pos = 1,#str do             store = store+str:sub(pos,pos):byte()         end     elseif(type(str) == 'number')then         return str     else         print('function getStoreString adverte: tipo de parametro invalido. ('..type(str)..')')     end     return store end Ex: print(getStoreString("lua")) >> 322  
      Pega o level necessário para usar a arma dentro do arquivo weapons.xml
      function getLevelNeedToWeaponById(itemid) --[[( Marcryzius )]]-- local xfile = xml:load("data/weapons/weapons.xml"):find('%a+','id',itemid)     return tonumber(xfile and xfile.level) or 0 end
      Essa função faz uma verificação se há um town em uma determinada área.
      function getTownInArea(pos, ranger) --[[( Marcryzius )]]-- local ranger,townid,bloked = ranger or 200,1,{getTownId('Gods Island'),getTownId('Isle of Destiny')} -- towns suprimidos     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
      Pega o nome e o level do top
      function getTopLevel() --[[( Marcryzius )]]-- local target,name,level = db.getResult("SELECT `name`, `level` FROM `players` WHERE `group_id` <= 2 ORDER BY 'level' DESC;"),"",0     if(target:getID() ~= -1) then          repeat         local glevel = target:getDataInt("level")                 if(level < glevel)then                 name,level = target:getDataString("name"),    glevel             end         until not(target:next())      end     target:free()     return name,level end  
      Verifica se existe o nome de um player mesmo ele estando offline.
      function playerExistName(nome) --[[( Marcryzius )]]-- local db = db.getResult("SELECT `name` FROM `players` WHERE `id` = " ..getPlayerGUIDByName(nome).. ";")     if not(db:getID() == -1) then         return db:getDataString("name")     end     return false end  
      Retorna o tempo vigente apenas em segundos
      function HorasParaSegundos() --[[( Marcryzius )]]--     local hour,minu,second = tostring(os.date("%H:%M:%S")):match('(%d+):(%d+):(%d+)')     return ((tonumber(hour) or 0)*3600)+((tonumber(minu) or 0)*60)+second end  
    • Por Poccnn
      Hail Xtibianos.
      Eu estava/estou atualizando alguns scripts meus bem antigos, então resolvi compartilhar para vocês que priorizam um jogo mais ao estilo: segunda vida na idade média. 
       
      Bom... tu terás que fazer uma sala parecida como essa e com esses ids (pois já foram implementados no código).

       
      Agora vamos implementar os códigos:
      Vá em data/actions.xml e insira essas tags:
       
      Em data/actions/scripts/tools; insira todos esses códigos cada um com seus respectivos nomes:
       
      ferreiro.lua
      --[[> Marcryzius Devil <]]-- forja = { [2406] = { {5880,2148,2148, result = 2395, fail = 2234}, {5880,5880,5880, result = 2413, fail = 2234}, {5880,2144,5880,2144,5880, result = 7385, fail = 2234} }, [2376] = { {5880, result = 2397, fail = 2234}, }, [2412] = { {2144,2143, result = 2438, fail = 2234}, {5880, 5880, 2149,2149, result = 2419, fail = 2234}, }, [2413] = { {5880,5880,5880,2152, result = 2377, fail = 2234}, }, [2384] = { {5880,5880,7760,5880,7760,7760,7760, result = 2392, fail = 2234}, {5880,5880, 5880, result = 2385, fail = 2234}, }, [2385] = { {5880, 2144, result = 2412, fail = 2234}, }, [2395] = { {2396,2396,2396,2157,2396, result = 2407, fail = 2234}, }, [2383] = { {5880,2145,2145,2145, result = 7449, fail = 2234}, }, [2379] = { {5880, result = 2376, fail = 2234}, {1294,1294,5880, result = 2420, fail = 2234}, {2151,5880,2151,2149, result = 2411, fail = 0}, }, [2420] = { {5880, 5880, result = 2443, fail = 2234}, {5880, 2149,5880,2149, result = 2419, fail = 2234}, }, [2402] = { {5880, result = 2384, fail = 2234}, }, [2403] = { {5880, result = 2406, fail = 0}, {5880,2151,2151, result = 2402, fail = 0}, }, [2404] = { {5880, result = 2395, fail = 2234}, {2143,5880,2143, result = 2379, fail = 0}, }, -- axes [2380] = { {5901,5901,5901, result = 2381, fail = 2559}, {5880, result = 2386, fail = 2559}, {2144, result = 2388, fail = 2559}, }, [2386] = { {5880, 1294, 5880, 1294, result = 8601, fail = 2559}, {2143, 5880, 5880, 2143, result = 2387, fail = 2559}, {2388,2144, 5880, 2144, result = 2430, fail = 2559}, }, [2416] = { {5880,5880,5901, result = 2422, fail = 2416}, }, [2225] = { -- knife {5880,2151, result = 2403, fail = 0}, {5880,2143, result = 2404, fail = 0}, {5880,2144, result = 2379, fail = 0}, -- axe {5880,5901, result = 2380, fail = 0}, -- hammer {5880,1294, result = 2416, fail = 0}, }, } function skill(cid) -- verifica o skill(ferreiro) do player usando store. return (getPlayerStorageValue(cid,getStoreString('_FERREIRO_SKILL')) < 0) and 0 or getPlayerStorageValue(cid,getStoreString('_FERREIRO_SKILL')) end function formatFerreiroLevel(valor) return math.floor(valor/20) end function getPiece(str) local obj = { itemid = str.itemid, actionid = str.actionid, uid = str.uid, type = getItemWeaponType(str.uid), time = 0, extra = getItemAttribute(str.uid,'extraattack') or getItemAttribute(str.uid,'extradefense') or 0, quant = 0, count = 0, max_count = getItemInfo(str.itemid).attack == 0 and getItemInfo(str.itemid).defense or getItemInfo(str.itemid).attack or 5, stack = 0, step = {} } if not(self)then self = setmetatable(obj,self) self.__index = self self.__call = function(self,uid,obj) if uid and not self[uid] then self[uid] = { __index = obj} setmetatable(self[uid], self[uid]) return self[uid] elseif(self[uid])then return self[uid] end end end return self.__call(self,str.actionid == 0 and str.uid or str.actionid,obj) end function onUse(cid, item, fromPosition, itemEx, toPos) local obj = nil local pos_item = {x=toPos.x,y=toPos.y,z=toPos.z,stackpos=1} local get = getThingFromPos(pos_item) local anvil = getThingFromPos({x=toPos.x,y=toPos.y,z=toPos.z,stackpos=2}) -- bigorna if(isCreature(itemEx.uid))then return true elseif not(anvil) or not(anvil.itemid == 2555)then -- bigorna return true,doPlayerSendCancel(cid,"use seu martelo em algum item em cima de uma bigorna.") elseif not(get) or not(isInArray({1,3,4},getItemWeaponType(get.uid)) or get.itemid == 2225) then return true else if(itemEx.actionid == 0)then doItemSetAttribute(itemEx.uid,"aid",itemEx.uid) end obj = getPiece(itemEx) -- pega o item para refinamento. end if(obj.type ~= 4 and obj.time+(obj.count*10) < os.time())then obj.count = 0 doPlayerSendCancel(cid,"Ponha sua arma na fornalha.") elseif((skill(cid)/20)%2 == 0 or (skill(cid)/20)%2 == 1)then doPlayerSendTextMessage(cid,20,"voce avançou para o level "..formatFerreiroLevel(skill(cid)).." na profissao de (Ferreiro).") doSendMagicEffect(toPos,3) else -- Verificações necessarias para adicionar um extraAtaque ou extraDefesa no item. local number = math.random(1,obj.max_count+((obj.extra == 0 and 1 or obj.extra)*10)) if(formatFerreiroLevel(skill(cid)) > number) then if(obj.quant >= obj.max_count)then if(obj.stack > 0)then table.insert(obj.step,obj.stack) obj.stack = 1 local result = nil for _, list in pairs(forja[obj.itemid]) do local parar = nil for k,passo in ipairs(obj.step)do result = not(passo == list[k]) and list.fail or nil if(#obj.step == k and not result)then if(#obj.step == #list)then result = list.result end parar = true end end if(parar)then break end end if(result)then obj.stack = 0 if(result == 0)then doRemoveItem(itemEx.uid) else doItemSetAttribute(itemEx.uid,"aid",itemEx.uid) doTransformItem(itemEx.uid, result) end doSendMagicEffect(toPos,5) return end end if(obj.type == 1 or obj.type == 3)then doItemSetAttribute(itemEx.uid,"extraattack",obj.extra+1) elseif(obj.type == 4)then doItemSetAttribute(itemEx.uid,"extradefense",obj.extra+1) end obj.count = 0 obj.quant = 0 doSendMagicEffect(toPos,14) return end obj.quant = obj.quant+1 doSendMagicEffect(toPos,13) doSendMagicEffect(toPos,3) elseif(formatFerreiroLevel(skill(cid)) < math.random(1,20))then doCreatureAddHealth(cid,-5) doPlayerSendCancel(cid,"você se machucou com seu martelo.") doSendMagicEffect(toPos,2) else doSendMagicEffect(toPos,3) end end return true,setPlayerStorageValue(cid,getStoreString('_FERREIRO_SKILL'),skill(cid)+1) end wood.lua
      --[[> Marcryzius Devil <]]-- function onUse(cid, item, fPos, itemEx, toPos) local number = math.random(1,10) if(itemEx.itemid == 8642)then if (skill(cid)/20 >= number)then doRemoveItem(item.uid, 1) doTransformItem(itemEx.uid,8641) doItemSetAttribute(itemEx.uid,"aid",itemEx.uid) doSendMagicEffect(toPos,6) doSendMagicEffect(toPos,15) doSendMagicEffect(toPos,36) addEvent(function(pos) local item_pos = getThingFromPos(pos) doSendMagicEffect(pos,2) doTransformItem(item_pos.uid,8642) end,60000*math.random(1,2),toPos) else if(math.random(1,10) == 1)then doCreatureSay(cid,"Aaaai!",1) doCreatureAddHealth(cid,-5) doSendMagicEffect(getCreaturePosition(cid),15) doPlayerSendCancel(cid,"você se queimou.") else doSendMagicEffect(toPos,2) doSendMagicEffect(toPos,5) end end setPlayerStorageValue(cid,getStoreString('_FERREIRO_SKILL'),skill(cid)+1) -- cana de açucar elseif(itemEx.itemid == 5471)then if(math.random(1,10) == 10)then doRemoveItem(item.uid) end doTransformItem(itemEx.uid,5465) doDecayItem(itemEx.uid) else doPlayerSendTextMessage(cid,20,"use o fogo na fornalha ou no canavial.") end return true end bellow.lua
      --[[> Marcryzius Devil <]]-- local retardo,effe_index,add = 0, 1,0 local function passEffect(pos,...) local effe = {...} doSendMagicEffect(pos,effe[effe_index] or 15) effe_index = effe_index+1 return coroutine.yield() end local crucible_bellow = function(pos,...) local a = {passEffect(pos,...)} local b = {passEffect(unpack(a))} local c = {passEffect(unpack(b))} passEffect(unpack(c)) effe_index = 1 return end function onUse(cid, item, fpos, itemEx, toPos) local crucible,mesa = nil,fpos for X = -1,1 do for Y = -1,1 do local npos = {x=X+fpos.x,y=Y+fpos.y,z=fpos.z,stackpos=1} local weapon = {x=X+fpos.x,y=Y+fpos.y,z=fpos.z,stackpos=2} local get = assert(getThingFromPos(npos)) if(get and get.itemid == 8641 or get.itemid == 8642)then crucible = getPiece(get) if not(crucible.pos)then crucible.pos = npos end if not(crucible.co)then crucible.co = coroutine.create(crucible_bellow) end elseif(get and get.itemid == 10967)then local get = assert(getThingFromPos(weapon)) if(isInArray({1,3,4},getItemWeaponType(get.uid)) or get.itemid == 2225)then mesa = weapon else add = get.itemid doRemoveItem(get.uid) doSendMagicEffect(weapon,5) end end end end local peg = getThingFromPos(mesa) local attack_item = peg and (getItemInfo(peg.itemid).attack < 5 and 5 or getItemInfo(peg.itemid).attack) or 5 if(crucible and retardo <= os.time())then retardo = os.time()+1 -- intervalo de uso em segundos. if(crucible.itemid == 8642 and crucible.actionid > 0)then local co = coroutine.resume(crucible.co,crucible.pos,6,15,36) if not(co)then local item_pos = getThingFromPos(crucible.pos) crucible.co = coroutine.create(crucible_bellow) doSendMagicEffect(fpos,2) crucible.itemid = 8641 doTransformItem(item_pos.uid,8641) if(crucible.count > math.random(3,5))then doItemSetAttribute(item_pos.uid,"aid",0); crucible.actionid = 0 end addEvent(function(obj) local item_pos = getThingFromPos(obj.pos) obj.count = obj.count+1 obj.itemid = 8642 doSendMagicEffect(obj.pos,CONST_ME_POFF) doTransformItem(item_pos.uid,8642) end,60000*math.random(4,5),crucible) end elseif(crucible.itemid == 8641 and type(mesa) == 'table' and math.random(1,attack_item*3) <= skill(cid))then local get_weapon = getThingFromPos(mesa) if(get_weapon.actionid == 0)then doItemSetAttribute(get_weapon.uid,"aid",get_weapon.uid) end local obj = getPiece(get_weapon) obj.time = os.time() obj.stack = obj.stack > 1 and obj.stack or add if(obj.count <= attack_item)then obj.count = obj.count+1 else doRemoveItem(get_weapon.uid) doSendMagicEffect(toPos,5) return end else doSendMagicEffect(crucible.pos,2) return true end doSendMagicEffect(mesa or crucible.pos,15) doSendMagicEffect(crucible.pos,5) doSendMagicEffect(fpos,67) end return true end Pronto. Instalados os scripts; agora irei explicar como funciona o sistema.
       
      Para acender o crucible, você precisa usar o fire bug (5468) no crucible (8642) até ele acender.

       
      Agora você põe a arma em cima da bancada e clica no bellow para ele 'aquecer' a arma para forja.

       
      Depois de 'esquentar' a arma, voce forja ela no anvil (bigorna de id 2555) por um tempo (tempo esse determinado pelo uso do crucible).

       
      Se o crucible 'apagar', voce clica no bellow até ele voltar a 'acender', mas isso só pode ser feito algumas vezes.
       

       
      Se você clicar muitas vezes e ele não 'acender', então tu terás que usar o fire bug de novo no crucible.
       
      Novo sistema de forja adicionado.
      Agora tu poderás adicionar materiais a forja para obter outros items.
       
      Explicação desse novo sistema:
      Primeiro tu põe a arma base para adição de novos compostos na mesa.
       

      Registre-se para ver attachment(s).
       
      adicione o item em cima da arma.
      Clique no bellow e o item de adição desaparecera.
       

       
      Leve o item "aquecido" para a bigorna.
      Use a marreta nele até sair um efeito verde.
       

       
      Caso ele peça para por de volta na fornalha a arma, não adicione outro item, apenas aqueça-o.
       
      Faça esse mesmo procedimento adicionando compostos até que o item seja criado.
       

       
      aqui um manual de forja feito a parti da tabela forja no script ferreiro.lua
      Registre-se para ver spoiler(s).
       
      Tu poderás adicionar mais compostos para obter outros items a seu critério.
       
      É isso pessoal, depois posto mais scripts atualizados meu; espero que gostem; qualquer erro ou dúvida deixem no comentário abaixo.
    • Por Insaend
      Spriting a Arte do pontinho.
      Seu mundo de muitos pontos
      Apresentação:
       

      Meu nome e Insaend ( Wanderson Carlos D. S. ) sou sprite a algum tempo frequento o xtibia a um bom tempo porem aprendi muitas das coisas que sei no fórum da Perspective45.org. Não venho fazer propaganda do fórum mas acho errado que aqueles que passaram por la o ignorem pois ele foi um marco na minha vida assim como o Xtibia foi para as outras áreas que gosto de fazer em relação ao Otserve. Venho por meio deste tópico mostrar e ensinar o que sei para todos os usuários ou não usuários do fórum. Não sou o melhor do brasil nem do meu estado não acho que eu nem vocês podemos dizer que não damos conta de chegar perto de quem admiramos
       
      Proposta:
      Quero ajudar todos os usuários a entender que a arte de pixel não e nada alem de dedicação e treinamento com orientação correta. Um pixel arte (Spriting/Sprite) nada mais e do que um retrato desenhado com pequenos detalhes que para o olho humano forma uma grande arte (desafio). Tendo em mente que teremos um longo caminho eu iniciarei esse trabalho assim como também iniciei a minha caminhada. Sim como pequenos itens e suas formas para que possamos depois melhorar ainda mais para outros itens (sprite)
       
      Spriteing “perspectiva 45ª”
      A forma com que vou tratar o trabalho da spriter e em perspectiva 45 graus então peço que tentem sempre acompanhar todo o contexto e absorver o máximo de informações que forem lhes passadas para que não percam tempo com outros tipo de sprite confundido assim suas mentes!

      Trabalhos/Tutoriais
       
      1 - Iremos iniciar com tutorias sobre itens:
      Registre-se para ver link(s).

      Registre-se para ver link(s).

      Registre-se para ver link(s).

      Registre-se para ver link(s).

      Registre-se para ver link(s).

       
      PS: no tutorial estarei mostrando como fazer e não como colocá-las em seus projetos e Arquivos de jogos, fica para uma próxima!

       
       
      2 - Trabalharemos o cenário com isso teremos que fazer vários tutorias essa no mais sera a parte mais complicada pois abrange muitos tipos de sprites e cada um com seu mode de fazer em um geral todos dentro de um só objetivo.
       
      Registre-se para ver link(s).

      2.02 - Outline (Em construção)
      2.03 - Iluminação/Sombreamento
      2.04 - Volume
      2.05 - Tons
      2.06 - Textura
      · Trabalharemos em cenário com os temas:
      Piso(floor), natureza”plantas, arvores, relevos, pedras, paredes de pedras e terra”(nature), itens para enfeite(items for garnish).
      PS: no tutorial estarei mostrando como fazer e não como colocá-las em seus projetos e Arquivos de jogos, fica para uma próxima!

      PS: muitas das imagens contida nessa gif não são de minha autoria tendo
      vários membros do perspectiva45 como autores!
       
      3 - Criaturas/monstros, estaremos trabalhando como fazer criaturas sejam elas monstros personagens: personagem para jogar (character), Monstros (creaturas)...
       
      3.01 - Perspectiva
      3.02 - Outline
      3.03 - Anatomia
      3.04 - Iluminação/Sombreamento
      3.05 - Volume
      3.06 - Tons
      3.07 - Textura
      3.08 - Movimento
      · Dentre muitas coisas pequenas que iremos trabalhar abordando ainda o tema de Criatura com toda certeza o mais complexo de todos devido cada individuo ter diferentes tipos de serem feitos e trabalhados.
      PS: no tutorial estarei mostrando como fazer e não como colocá-las em seus projetos e Arquivos de jogos, fica para uma próxima!

       
       
      Conclusão
      Espero ajudar o máximo de pessoas com os tutorias e peço que nas paginas que forem feitas com os tutorias cada um que tenha um duvida postem a no tópico correspondente que sempre que eu tiver um tempo ou puder ajudar eu ajudarei, não estarei respondendo perguntas por PM pois sua duvida também pode ser a de seu amigo usuário, não darei dicas fora dos tópicos e não responderem perguntas off!
      Estarei postando os link se assim for preciso com atualização deste tópico na primeira pagina sendo assim logo abaixo do agradecimento!
       
      Obrigado e aproveitem.
       

      ATT Insaend
       
       
       
      Links já upados:

      Registre-se para ver link(s).

      Registre-se para ver link(s).

      Registre-se para ver link(s).

      Registre-se para ver link(s).

      Registre-se para ver link(s).
       
       
      Registre-se para ver link(s).

      A arte do Pontinho - Outline 2.02 (Em construção)
       
      Aguardem Mais link's...