Venha conhecer o Xtibia!

Bem Vindo ao 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
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

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

    • Como Faço para quando o pokemon atacar mudar a outfit? [POKETIBIA]
      Por charllesrt2
      Queria que quando um certo pokemon atacasse mudasse de outfit
       
      EX: O Typhlosion, ele normal seria sem o fogo nas costas, mas quando ele atacar o fogo na costa dele apareceria xD como uma troca de outfit mesmo
    • Nova livraria lua para xml
      Por Poccnn
      Fala XTibianos!
      Vim disponibilizar e ensinar como usar a livraria xml em lua, desenvolvida por mim. 
       
      Ela foi desenvolvida para substituir a livraria padrão disponibilizada por lua para trabalhar com dados xml.
      Essa livraria não requer a dll-xml necessária para a livraria padrão lua.
       
      Aqui tem o tutorial criado por mim para demonstrar as funções e suas implementações da livraria luaxml.

      Registre-se para ver link(s).
       
      Vamos lá.
      Primeiro, a livraria: 
      --[=[ ################################################################################################################# ## LibXml desenvolvida por Marcryzius ## ## Terminado na data: 23 de Julho de 2016 ## ## Ultima modificação: 7 de setembro de 2016 ## ## Livre para quem queira usa-la ou modifica-la (caso modifique, favor postar suas modificações para ajudar outros). ## ################################################################################################################# ]=] xml = {} -- carrega o arquivo e retornar um objeto para os metametodos ou uma string para outros fins. function xml:load(dir) local open,read_open = io.open(dir,'r') if(open)then read_open = open:read(-1) open:close() else read_open = "<?xml version=\"1.0\"?>\n<!-- file \"",dir, "\", criado por LuaXML system desenvolvido por Marcryzius -->\n\n" end return setmetatable({},{__index = xml, __tostring = function() return read_open end}) end -- Converte strings formatadas em xml para tabelas com parametros validos em lua. retornar uma tabela. function xml:eval(tag,head) local tab,index,tag = {},0,type(tag) == 'string' and tag or tostring(self) if(string.match(tag,'<.-/>'))then --<tag name="carrot" quant="914"/> for head,corpser in string.gmatch(tag,'<(%a+) (.-)/>') do if not(tab[index+1])then tab[index+1] = { head = head, _M = 'tag' } end for k,v in string.gmatch(corpser,'(%a+).-"(.-)"') do tab[index+1][k] = v end index = index+1 end elseif(string.match(tag,'<.->'))then if(string.match(tag,'<(%a+)>'))then --<bloco> </bloco> tab.head = string.match(tag,'<(%a+)>') tab._M = 'bloco' for ke,v in pairs(xml:eval(head)) do tab[ke] = v end elseif(string.match(tag,'<(%a+).->'))then --<string id="author"> Corpo com string </string> tab.head = string.match(tag,'<(%a+).->') tab._M = 'tagBloco' for ke,v in string.gmatch(string.match(tag,'<%a+ (.-)>'),'(%a+).-"(.-)"') do tab[ke] = v end for ke,v in pairs(xml:eval(head)) do tab[ke] = v end end end return tab end -- converte tabelas e parametros com argumentos pre-determinados para xml, em uma string formatada em xml. retornar uma string. function xml:str() local str = '' if(self._M == 'tag')then --<tag name="carrot" quant="914"/> str = '\n<'..(self.tag or '')..' ' for k,v in pairs(self) do if not(k == '_M') and not(k == 'head') and not(k == 'tag') and not(type(v) == 'table') and not(tonumber(k)) then str = str..k..'="'..v..'" ' end end str = str..'/>' elseif(self._M == 'tagBloco')then local taghead,corpo = '','' --<string id="author"> Corpo com string </string> for k,v in pairs(self) do if not(type(v) == 'table')then if not(k == '_M') and not(k == 'head') and not(tonumber(k)) then taghead = taghead..' '..k..'="'..v..'"' elseif(k == '_string')then corpo = corpo..' '..v end elseif(type(v) == 'table')then corpo = corpo..xml.str(v) end end str = '\n<'..(self.head or 'tag')..taghead..'>'..corpo..'\n</'..(self.head or 'tag')..'>' elseif(self._M == 'bloco')then --<bloco> </bloco> local corpo = '' str = '<'..self.head..'>' for k,v in pairs(self) do if(tonumber(k) and type(v) == 'table')then corpo = corpo..xml.str(v) end end str = str..corpo..'\n</'..self.head..'>' end return str end -- Busca um bloco xml atraves dos argumentos fornecidos. retornar um objeto para os metametodos ou uma string para outros fins. function xml:find(headTag,param,value) local tab = {} local tag,head = nil,nil if not(headTag) or type(headTag) ~= 'string' then return false elseif not(string.find(tostring(self),'<?xml version="1.0".-?>'))then --<?xml version="1.0" encoding="UTF-8"?> return false,'Versao do arquivo xml nao aceita ou desconhecida - use versao 1.0' elseif not(param and value)then tag,head = string.match(tostring(self),'(<'..headTag..'>)(.-)</'..headTag..'>') if not(tag)then tag,head = string.match(tostring(self),'(<'..headTag..'.->)(.-)</'..headTag..'>') end elseif tostring(param) then for tg,hd in string.gmatch(tostring(self),'(<'..headTag..'.->)(.-)</'..headTag..'>') do if(string.find(tg,param..'="'..value..'"'))then tag,head = tg,hd end end end if(tag and head)then tab = xml:eval(tag,head) end return setmetatable(tab,{__index = xml, __tostring = xml.str}) end -- Cria um novo objeto xml com o nome da taghead inserido. function xml:new(arg) return setmetatable({head = arg or 'xmltag', _M = 'bloco'},{__index = xml, __tostring = xml.str}) end -- Essa função não é equivalente a da libluaxml que modificar o nome da taghead. -- Essa função cria uma tag do tipo >> <tagExemplo valor="1" novo="new"/> function xml:tag(arg,param) -- arg, seria o nome da tag (<tagExemplo .../>) -- param, seria uma tabela contendo todos os valores que serão postos na tag ({valor=1,novo="new"}). if(type(arg) ~= 'string')then return print(type(param) == 'string' and param or type(param)) end local tab = {tag=arg,_M='tag'} if(type(param) == 'table')then for k,v in pairs(param) do tab[k] = v end end table.insert(self,tab) end -- Essa função não é equivalente a da libluaxml. -- Essa função cria uma tag do tipo >> <tagExemplo pode="ter" valores="aqui" opcional=":)">valores inseridos aqui tambem (obs. com uso de metametodos)</tagExemplo> function xml:append(arg,param) -- arg, seria o nome da tag (<tagExemplo .../>) -- param, seria uma tabela contendo todos os valores que serão postos na tag ({valor=1,novo="new"}). local tab = {head=arg,_M='tagBloco'} if(type(param) == 'table')then for k,v in pairs(param) do tab[k] = v end end if(type(param) == 'string')then table.insert(tab,param) end table.insert(self,tab) return setmetatable(tab,{__index = xml, __tostring = xml.str}) end -- salva os dados em um arquivo xml -- Se, já existir o arquivo, ele será substituido. function xml:save(dir) local dir = type(dir) == 'string' and #dir > 6 and dir or 'newFileByXmlGenerator.xml' if not(string.find(dir,'.xml'))then dir = dir..'.xml' end local file = io.open(dir,"w") file:write("<?xml version=\"1.0\"?>\n<!-- file \"",dir, "\", criado por LuaXML system desenvolvido por Marcryzius -->\n\n") file:write(self:str()) file:close() end  
       
      Vou ensinar como usar ela. 
      Vou usar como exemplo uma parte do arquivo vocations.xml: 
         
      Registre-se para ver spoiler(s).
       
      Obs. Os codigos estão codificados em utf8, converta para ansi antes de usa-los.
       
      É isso ae pessoal, espero que gostem.
       
    • Launcher para OTCliente/Classico com AutoUpdate sem Host
      Por saviomu
      => Bom,o titulo diz tudo né? Esse é um launcher com autoupdate para OTCliente ou para cliente Clássico(CIPSOFT), com o seguinte detalhe, ele utiliza arquivos upados no GitHub, ou seja,não é necessário uma hospedagem e muito menos que seja o cliente postado em seu WebSite.
      => Foi codado em C# usando o WPF.

      Registre-se para ver attachment(s).

      Registre-se para ver attachment(s).

      Registre-se para ver attachment(s).

      Registre-se para ver attachment(s).
      O vídeo abaixo ensina a configurar tudo passo a passo, bonitinho para que não ocorra erros.
       
      Para configurar a execução do cliente, fique atento as seguintes condições:
      Para Cliente Padrão, o nome do mesmo deve ser -> padrao.exe Para OTCliente DX, o nome deve ser -> dx.exe Para OTCliente OpenGL, o nome deve ser -> opengl.exe  
      CASO SEU TIBIA.SPR FOR MAIOR QUE 100MB SIGA O TUTO ABAIXO, CASO CONTRARIO APENAS PULE:
      1 => Selecione seu arquivo tibia.spr e comprima-o em zip separando ele em partes (Deixe o arquivo comprimido dentro da pasta original onde fica o tibia.spr ein!!!!), como a imagem abaixo.
      Registre-se para ver attachment(s).
       
      Configurações Extras (Que não estão no vídeo):
      <!-- LAYOUT --> Background -> Nome da imagem Background do Launcher BtnFechar -> Nome da imagem do Botão Fechar BtnMinimizar -> Nome da imagem do Botão Minimizar EsquemaCores -> Muda o esquema de cores do Launcher (Código em Hexadecimal de Cores) <!-- MUSICAS --> ->Apenas mude o arquivo dentro de musicas/principal.mp3. ->Caso não deseje musica apenas delete a pasta. <!-- CASO SPR MAIOR QUE 100MB --> DirSprite -> Coloque o caminho onde se encontra sua pasta. ->Caso esteja na raiz do cliente, deixe em branco. ->Caso esteja dentro de alguma pasta coloque da seguinte forma: pasta1/pasta2/pasta3/ => A ultima pasta precisa ter uma / ein. Changelog:
      -------------01/12/2016------------------ *Correção de Erros; e *Adicionada Música na execução do launcher. -------------05/11/2016------------------ *Otimização dos Codes (Muito Menos Gambs :D); *Melhor Gerenciamento do Esquema de Cores; *Arquivo de Configurações mais Clean; *Suporte para o spr maior que 100MB. -------------04/11/2016------------------ *Adicionada personalização no arquivo de configurações para o esquema de cores do launcher; *Melhorias de códigos inuteis(gambiarras) que haviam dentro do mesmo. -------------20/10/2016------------------ *Adicionado personalização no arquivo de configurações para imagens de background e botões de minimizar e fechar. Créditos:
      ME -> Por ter feito :S Dalvo rsrsrsrnrnrsnrnrnnrnn -> Por ter me ensinado a usar o github bash,serio eu não sabia usar só usava o desktop. Ah e também por mostrar essa api maravilhosa. Senha:
      www.xtibia.com Link para repositório do launcher.
      https://github.com/f1nal1ty/LauncherWPFOTC  
       
       
       

      Registre-se para ver attachment(s).
    • Como extender o OLD cliente [ VIDEO FULL HD ]
      Por Punchlines Nemmo
      Salve galera blz ? bom trago pra voces mais um video no meu canal dessa vez vou ensinar a extender o OLD clienten se gostarem do meu video como sempre deixem aquele REP+ pra me ajuda que vou gostar bastante e sem mais delongas assistam o video <3
      v
    • Script de npc função de "wait"
      Por Zync
      Eu tenho um script de um npc que luta contra o jogador, e tenho ele a dizer umas frases antes do duelo, só que da forma que tenho ele fala tudo de uma vez e solta logo o pokemon, o que não da tempo ao player der ler as mensagens, eu queria uma função que fizesse o npc esperar x segundos entre cada mensagem
      Eu tentei usar esta função:
      local function wait(seconds) local start = os.time() repeat until os.time() > start + seconds end (...) selfSay("O meu nome é X, eu quero duelar com vc!") wait(2) selfSay("Espero que esteja preparado mlk!") wait(2) selfSay("Vamos a isso!") (...) Mas não teve o resultado que eu esperava, o npc fica calado durante algum tempo e depois fala as msgs e solta logo o pokemon tupo no mesmo instante, tem alguma forma que funcione de fazer isso?

Anuncie no Xtibia!

Anuncie para obter mais acessos em seu servidor, entre em contato conosco: [email protected].