Ir para conteúdo

MaXwEllDeN

Barão
  • Total de itens

    246
  • Registro em

  • Última visita

  • Dias Ganhos

    2

Histórico de Reputação

  1. Upvote
    MaXwEllDeN recebeu reputação de AnneMotta em Ao matar monstro criar TP   
    local createpos = {x = 160, y = 54, z = 7} -- Posição em que o teleport será criado local to_pos = {x = 140, y = 50, z = 2} -- Essa é a posição para qual o teleport vai levar local tempo = 50 -- Em Segundos local function remover_teleport() -- Função que vai remocer um teleport local teleport = getTileItemById(createpos, 1387) -- Essa função vai procurar o teleport na posição teleport_pos doRemoveItem(teleport.uid) -- Essa função vai remover o teleport return true end function onDeath(cid) -- Quando o monstro morrer executar esse script local teleport = getTileItemById(createpos, 1387) if teleport.uid > 1 then -- Essa condição return true -- Serve para não criar um teleport caso já tenha um na posição end doCreateTeleport(1387, to_pos, createpos) -- Essa função criará o teleport na posição 1387 addEvent(remover_teleport, tempo * 1000) -- Depois de (tempo * 1000) a função remover_teleport vai ser chamada -- O tempo, na função addEvent tem que ser em milisegundos, por isso multiplica por 1000 return true end
     
    Ah, e por favor não chama Lua de .lua, aheuhaeau
  2. Upvote
    MaXwEllDeN recebeu reputação de JonPiress em Locker Protection   
    #Introdução
     
    Bem, este é um sistema no qual você pode protejer o seu locker(depot) com senha, assim evitando hackers.
     
     
    #Instalação
     

    Primeiro faça o download do sistema e cole na sua pasta data.
     
    Após ter instalado os arquivos nas suas respectivas pastas adicione as tags:
     
    @Actions
     

    <action itemid="2589; 2590; 2591; 2592" event="script" value="DPPass.lua"/> <!-- DP Pass -->
     
    @Creaturescripts
     

    <event type="login" name="LockerPass" event="script" value="DPPass.lua"/> <!-- DPPass -->
     
    @Movements
     

    <movevent type="StepOut" actionid="96475" event="script" value="DPPass.lua"/> <!-- DPPass -->
     
    @Talkactions
     

    <talkaction words="!locker" script="DPPass.lua"/> <!-- DP Pass -->
     
    Abraço.
  3. Upvote
    MaXwEllDeN deu reputação a Oneshot em Meta-tabelas e Meta-métodos   
    Vamos começar do zero, então.
     
    Orientação a Objetos, é um tipo de programação, onde você desenvolve o código, como "ações" de algo, um objeto. Essas "ações" podem ser chamadas, de maneira grossa, de métodos.
     
    Lua não é uma linguagem tipada como C++, certo? Tão pouco é uma linguagem orientada a objetos. Mas existe um sistema da biblioteca Lua que dá a possibilidade de desenvolver Lua orientada a objetos - este é o sistema que chamamos de meta-tabelas. As funções de meta-tabelas, são simplesmente, funções que transformam tabelas normais da linguagem Lua em objetos.
     
    Para aprofundar, precisamos, primeiro, de algumas definições da POO, ou, programação orientada a objetos.
     
    Classe - Classe é a definição que usamos para um grupo de objetos com características em comum. Tomando como exemplo, cachorros, são várias raças, mas todos tem características em comum, certo? Latem, uivam, têm pelos, quatro patas... logo, pegaremos a classe dos cachorros.
     
    Objeto - É um integrante de uma classe, tomando o exemplo anterior, vamos considerar um objeto como um Rottweiler.
     
    Atributos - Uma definição de fácil compreensão para atributos - são as características de um objeto.
     
    Métodos - São as ações de um objeto, o que o objeto "sabe fazer", em poucas palavras.
     
    Agora em Lua, vamos pensar na classe do nosso exemplo anterior, te disse que a biblioteca das meta-tabelas transforma tabelas em objetos.
     
    Continuo a explicação daqui a pouco, abraços.
  4. Upvote
    MaXwEllDeN deu reputação a Skyen em Qual é a coisa mais importante em um código? E por que é a elegância?   
    Obs.: Eu sei que esse tutorial é quase uma trilogia, mas não desanime, tente ler até o final, você pode aprender muita coisa nova! Se você não quer ler tudo, pule a parte de escopo e identação, pois é a parte mais complexa. Recomendo voltar depois e tentar entender identação e escopo.
     
    Você está jogando Tetris quando um desconhecido te chama e pede para arrumar um script dele que não está funcionando direito. Aparentemente, os players estão ficando irritados porque o servidor está respondendo "Hell, world!" para eles, quando deveria estar respondendo "Hello, world!".
     
    Você diz "tudo bem", o cara te manda o script, e você se depara com isso:
     

    _,__,___,____=string.char,print,type,"fu" .."nction"if(___(__)==____)then __(_(0x48 ,0x65,0x6c,0x6c,0x2c,0x20,0x77,0x6f,0x72, 0x6c,0x64,0x21)) --[[Hello, world!]] end
     
    Se você sentiu um pingo de vontade de ler o código, exceto por curiosidade, seu nome é Mock.
     
    O erro mais comum que eu vejo sendo cometido por iniciantes não é nada relacionado à sintaxe, lógica da programação ou consumo excessivo de fungos pluricelulares. É a elegância (Ou melhor dizendo, a falta dela). Não me interessa se seu código deixa o Tibia 4D com Intel® Tesselated 256x Clockwise Polygoned RealExtreme™ Greener Foliage e nunca deu um bug. Se ele não for no mínimo agradável de ler, eu vou jogar fora, e sentir pena da lixeira.
     
    90% das vezes que eu digo para algum iniciante deixar o código mais bonito, eles me respondem que "só eu vou ler mesmo, cara, não vou ficar me preocupando com isso". Isso é a mesma coisa que limpar a bunda sempre com o mesmo papel porque você não é homossexual e não precisa da* * *****.
     
    Nas outras 10% das vezes, a pessoa fica offline e nunca mais aparece.
     
    Devaneios à parte, vamos ao que interessa:
     
    Por que a característica mais importante de um código é a elegância, e como deixar seu código elegante?
    Começando do princípio: Para escrever um código, o programador precisa ter na cabeça a abstração de uma solução para o problema em mente. Se você não entendeu, isso apenas significa que se você quer escrever um script que faça X coisa, você tem que ter na cabeça uma ideia para fazer a coisa X acontecer através de um código. Se você é distraído por algo, ou para de programar na metade do código, ou está com muito sono, essa ideia vai se perdendo e você tem que pensar nela novamente depois.
     
    Veja o problema do "Hello, world!" acima. Imagine que aquele código é seu, e você achou que ele estivesse funcionando, mas agora percebeu o bug e quer consertar. Só que já faz tempo que você fez o script e não tem mais em mente a ideia que usou para escrever ele à muito tempo atrás. A ideia se perdeu, e o único modo de relembrar ou descobrir a ideia de um código é, bem, lendo ele...
     
    Se você ainda tem a ideia em mente, ler um código como aquele ali em cima é muito fácil: parece óbvio para você o que ele faz, pois afinal, você acabou de escrevê-lo! Só que não é bem assim que funciona se você já não lembra de como fez o código, vai ser muito difícil ler um código grande todo mal-feito como aquele ali em cima, e o trabalho de arrumar o código é muito mais complexo.
     
    Caso você estivesse na situação de ter que arrumar o código do "Hello, world!", qual código você iria preferir arrumar? O de cima ou este aqui:
     

    print("Hell, world!")
     
    O problema piora se você não sabe como arrumar o bug e precisa de ajuda de alguém. Se você enviar um código todo mal-feito para alguém te ajudar, é bem provável que a pessoa nem vá ler seu código, dar uma desculpa e se safar de ter que ver tamanha aberração (Aos que estão se perguntando: sim, eu faço isso).
     
    Ou seja, enfie na cabeça de uma vez por todas que mesmo que seu código jamais vá ser lido por outra pessoa, é importante que você faça ele de forma elegante.
     
    É muito chato ter que enfeitar o código depois que ficou pronto? Você está fazendo algo muito errado!
    Se você faz o código todo para depois deixar bonitinho, fique sabendo que essa é uma péssima ideia. Você não tem que deixar bonito depois de pronto, e nem antes de começar, você tem que ir aplicando a elegância justamente enquanto escreve o código!
     
    Não faz sentido escrever um código feio para depois enfeitar. É a mesma coisa que parir o Hitler e deixar ele mais bonitinho com maquiagem e lacinhos. Acostume-se à escrever um código naturalmente bonito.
     



     
    A parte que realmente interessa: Como deixar seu código bonito!
    Identação
    A primeira coisa que me vem em mente quando alguém fala em código bonito é a identação. Identação é o espaço horizontal que separa as linhas de código da borda da esquerda. Veja um exemplo de código identado abaixo. Em azul é o espaço da identação, geralmente feito com a tecla tab:
     

     
    Além de mais bonito, fica extremamente mais simples ler um código identado. Ela é tão importante que na linguagem Python a identação não somente é obrigatória, como também é parte da sintaxe.
     
    Existem muitos iniciantes por aí que não sabem identar, mas adicionam espaços antes das linhas para copiar o código de outra pessoa e acabam fazendo tudo errado. Isso atrapalha tanto quanto um código não identado, se não piorar.
     
    Escopo
    Para aprender a identar corretamente, primeiro você deve entender o que é um escopo. A explicação abaixo não serve apenas para embelezar seu código, mas também é um conceito fundamental para programar, não apenas em Lua, mas em diversas outras linguagens de programação, então é importante que você leia mesmo se quiser fazer códigos feios (Afinal, a opção é sua, só não sei por que você chegou até aqui no tutorial se quer fazer um código feio).
     
    Escopo tem tudo à ver com variáveis locais e globais.
     
    A definição informal de escopo é: Até que ponto as variáveis locais podem ser alcançadas. Obviamente você não vai decorar isso, então vamos explicar de um jeito que você entenda:
     
    Quando você declara uma variável dessa forma em Lua, ela é uma variável global:
     

    x = 1
     
    Significa que ela pode ser acessada de qualquer lugar no seu código! Emocionante, não é?
     
    Não. Você não deveria estar fazendo isso à não ser em casos muito, muito especiais, e só quando você sabe o que está fazendo. Variáveis globais tem seus usos, mas são perigosas se você não usá-las corretamente. Isso acontece porque variáveis globais podem dar conflito com outras variáveis. E pior, em um lugar que não tem nada a ver com a paçoca.
     
    Por exemplo, você tem dois scripts completamente diferentes: Um deles é uma alavanca que abre uma porta e o outro é uma pedra que teleporta. Completamente diferentes. Exceto por uma coisa: ambos possuem a variável "pos", e o inútil escritor desses scripts cometeu o grandíssimo erro de não usar variáveis locais quando necessário. Veja:
     
    alavanca_que_abre_uma_porta.lua:

    pos = {x=100, y=100, z=7}
     
    pedra_que_teleporta.lua:

    pos = {x=200, y=200, z=8}
     
    Quando o Lua abre o primeiro script, ele registra a variável global "pos" com o valor 100x100x7. Quando o Lua abre o segundo script, ele registra novamente essa variável com o valor 200x200x8. O resultado é bem óbvio, existe apenas uma variável "pos" usada pelos dois scripts com o valor 200x200x8, que é válida para a pedra que teleporta, mas completamente inválida para a alavanca que abre uma porta!
     
    Para criar uma variável local, basta adicionar a palavra "local" antes do nome da variável. Tornando a variável "pos" local, vão existir duas variáveis locais "pos", uma para cada script, e cada uma com seu valor:
     
    alavanca_que_abre_uma_porta.lua:

    local pos = {x=100, y=100, z=7}
     
    pedra_que_teleporta.lua:

    local pos = {x=200, y=200, z=8}
     
    Problema resolvido. Agora mesmo que as variáveis possuam o mesmo nome, cada script tem a sua, e elas não irão conflitar, pois cada uma tem seu valor.
     
    Variáveis globais tem seus usos. Por exemplo, caso você precise trocar informações entre dois scripts diferentes. Porém, se precisar usar variáveis globais, escolha um nome que você tem certeza absolutíssima de que não causará conflito com nenhuma outra variável.
     
    Mas isso não é tudo o que há para falar sobre variáveis locais. Elas possuem uma propriedade muito interessante, veja:
     

    if true then local var = "Hello, world!" end print(var)
     
    O que você acha que o print vai escrever? Se você disse "Hello, world!", você errou. E errou feio.
    O print vai escrever "nil". Curioso, não?
     
    Na verdade, é algo muito óbvio. A variável "var" é local, e foi criada dentro do "if". Isso significa que ela é local dentro do if, e que fora dele, ela não existe. Quando o "if" atinge seu "end", todas as variáveis locais dentro dele são destruídas. Em outras palavras, o print não consegue encontrar a variável "var", pois ela só existe dentro do "if"!
     
    Agora vamos ver um caso diferente:
     

    if true then local var = "Hello, world!" if true then print(var) end end
     
    O que você acha que o print escreve? Você provavelmente acertou essa, agora. A resposta é "Hello, world!". A variável local existe, sim, apenas dentro do primeiro "if". Porém, o segundo if está dentro do primeiro, então a variável var continua existindo. Ela só será destruída quando o primeiro "if" atingir seu "end".
     
    Vamos complicar as coisas um pouquinho.
     

    local x = 10 if true then local var = "Hello, world!" if true then local var = "Goodbye, world!" print(var) print(x) end print(var) end
     
    Uma variável local "x", duas variáveis locais "var", três valores diferentes, três prints. O que você acha que cada um escreve?
    A resposta é: o primeiro escreve "Goodbye, world!", o segundo escreve "10", e o terceiro escreve "Hello, world!".
     
    Epa, mas pera aí, a segunda "var" não dá conflito com a primeira, reescrevendo o valor dela?
    Não. Isso acontece porque a primeira "var" continua existindo no primeiro "if" quando a segunda é criada no segundo "if". Os prints vão escrever o valor da "var" mais próxima do escopo deles.
     
    Escopo, como disse antes, é até onde as variáveis locais são alcançadas. Imagine os escopos como degrais de uma pirâmide. Um escopo mais alto pode alcançar todos os degrais mais baixos que ele na pirâmide, mas não consegue alcançar os mais altos. Se fôssemos dar números aos escopos do código acima:

    Escopo global (Fora dos dois "if"s).
    Dentro do primeiro "if".
    Dentro do segundo "if".




     
    E por que o segundo print escreveu o "x" do primeiro escopo? Porque é como se Lua fosse descendo os degraus dos escopos até achar o que procura. Se não achar, retorna "nil". Por isso, também, o primeiro print escreve a segunda "var", e não a primeira.
     
    Vamos complicar mais uma vez:
     

    if true then local var = "Hello, world!" if true then var = "Goodbye, world!" print(var) end print(var) end
     
    E agora, o que cada print escreve?
    O primeiro escreve "Goodbye, world!", e o segundo... também!
     
    Observe bem, a segunda "var" não tem a palavra "local" antes! Você deve estar pensando que a segunda "var" é global, mas esse não é o caso. Se eu colocar mais um print, fora dos dois "if"s, ele vai escrever "nil"!
     
    Mas que magia negra está acontecendo aqui agora?
    É bem simples. Quando a palavra "local" é usada, você está dizendo à Lua "crie uma variável local aqui!". Quando você não usa, você está dizendo "substitua o valor da variável no escopo mais próximo por este valor!", e então Lua vai procurar a variável "var" no escopo mais alto (mais próximo ao topo, onde o código está), e substituir seu valor. Se nessa descida da piramide Lua não encontrar a variável que você quer, então ela criará uma variável global!
     
    Ou seja, naquele código acima, se não existisse o primeiro "var", o segundo "var" seria global!
     
    A última coisa que você precisa saber sobre escopo é que todo todo "repeat", "while", "do", "for", "if", "elseif", "else" e "function" abre um novo escopo, e todo "end" e "until" (No caso do "repeat") fecha o escopo mais alto da "pirâmide", destruindo todas as suas variáveis locais.
     
    Voltando à identação
    Agora que você já sabe usar variávies locais em toda sua maestria... Okay, eu sei, talvez ainda esteja confuso demais e você não tenha entendido tudo, mas não se preocupe! Talvez demore um tempo para você assimilar o que é o escopo e variáveis locais, e como aproveitar isso no seu código, isso vem com a prática. Mas continue acompanhando, pois identação é uma coisa muito simples!
     
    A vantagem imediata da identação é que você consegue enxergar exatamente quais são os escopos. Fica simples ver que tal print está dentro de tal "if", já que o print está com um nível a mais de identação.
     
    Antes que você comece a sair por ai distribuindo espaços aos seus códigos, há algumas coisas a considerar sobre a identação.
     
    A identação pode ser feita com "hard tabs", espaços ou "soft tabs". A identação com um hard tab é exatamente um caractere de tab. É quando você aperta a tecla tab do teclado (Fica em cima do "caps lock", representada por duas setinhas) e o seu editor adiciona um único caractere. A identação por espaços usa a tecla de espaço ao invés do tab para adicionar o espaçamento. É praticamente inviável, já que pra adicionar uma identação adequada você teria que apertar a tecla espaço umas 12 vezes. Os soft tabs são uma mistura dos dois estilos. Quando você aperta a tecla tab, ao invés de adicionar um único caractere de tab, o editor adiciona um determinado número de espaços. É como se você apertasse a tecla de espaço várias vezes.
     
    Muitas pessoas preferem usar soft tabs, muitas outras preferem hard tabs. Isso é um debate que dá longas horas de discussão para programadores experientes. Cada um tem suas vantagens e desvantagens.
     
    Vantagens do Hard Tab:
    Seu tamanho pode ser alterado editando as preferências do editor de texto.
    É mais fácil controlar o nível de identação, uma vez que é composto de um único caractere.

    Desvantagens do Hard Tab:
    Alguns editores zoam o caractere de tab, tornando a identação totalmente errada, mesmo que tenha sido feita corretamente. Esse é o caso do OTScriptLive!, muito usado para programar para Open Tibia. Se você usa OTScriptLive!, considere trocar de editor. Existem muitas alternativas ótimas, como SciTE, Notepad++, gedit...

    Vantagens do Soft Tab:
    Já que é composto de espaços, é garantido que o código seja exibido da mesma forma em todos os editores.
    Não tem o problema de editores que zoam a identação, como no Hard Tab.

    Desvantagens do Soft Tab:
    Seu tamanho não é variável.
    O arquivo fica maior, já que cada caractere usado no hard tab corresponde a quatro ou oito caracteres do soft tab (dependendo do tamanho adotado).
    Por ser composto de espaços, é extremamente chato remover níveis de identação.

    A escolha é sua. Se você usa OTScriptLive!, recomendo trocar agora mesmo de editor, pois você não terá suporte a soft tabs e os hard tabs são destroídos pelo programa, tornando a identação correta um desastre. Você terá que fazer a identação com espaços.
     
    Eu, particularmente, prefiro hard tabs. É muito mais natural. A maioria dos projetos open source usam soft tabs para garantir que o código fique idêntico em todos os editores, e para um projeto aberto assim, com várias pessoas mexendo, até faz sentido. Mas na minha opinião, isso traz uma série de problemas.
     
    Independente de qual for sua decisão, siga sempre esta regra: Nunca, jamais, misture caracteres de tab com espaços.
     
    Chega disso, vamos logo aprender a identar!
    A identação, diferente do que você deve estar pensando, é uma coisa ridiculamente simples.
     
    Tudo se baseia em usar um espaçamento para separar os escopos. A cada escopo criado, adiciona-se um tab a mais à cada linha seguinte. A cada escopo fechado, remove-se um tab de cada linha seguinte. Veja:
     

     
    Cada setinha representa um caractere de tab. Toda vez que um escopo novo é aberto (por um "function", "for" ou "if"), as próximas linhas recebem um tab a mais. Toda vez que um escopo é destruído (por um "end"), todas as próximas linhas, incluindo a linha do end, recebem um tab a menos.
     
    Se seguirmos essa regra, dá pra perceber que no escopo global (nível 1), as linhas terão 0 tabs. Em um escopo de nível 2, terão 1 tab, e assim por diante.
     
    Há um caso especial: "else" e "elseif". Eles funcionam como se abrissem um novo escopo, ou seja, as linhas seguintes recebem o tab adicional, porém a linha do "else" e "elseif" não. Veja:
     

     
    O "segredo" da identação é sempre adicionar mais um tab depois de "repeat", "while", "do", "for", "if", "elseif", "else" e "function" e colocar um tab a menos depois de "end" e "until".
     
    Outro ponto importante da identação é a de tabelas verticais. Quando você fizer uma tabela que se extende verticalmente, idente seus valores. Nunca coloque o caractere de abertura ({) e fechamento (}) em uma linha que contém um valor, e não idente a linha desses caracteres. Veja:
     

     
    Isso é tudo sobre identação. Não deixe para identar depois que o código estiver pronto! Quando você pular uma linha, já adicione os tabs necessários e continue escrevendo. A maioria dos editores adicionam estes tabs automaticamente se você habilitar a opção, mas apesar de ser uma questão de gosto, não recomendo usar este recurso.
     
    Se você chegou até aqui e acha que entendeu (A parte de identação ao menos, não vou te culpar se você não entendeu sobre escopo), então você agora sabe identar! Yay!
     
    Nem tudo é identação...
    Se você achou que identação é a unica coisa que torna um código elegante, se enganou. Porém, daqui pra frente, as coisas serão bem mais simples.
     
    Código Frankstein não é legal.
    Se você usa variáveis com nomes em português, pode ir parando com Lua agora mesmo e vá programar em G-Portugol. Apesar de ter sido criada no Brasil, a sintaxe de Lua é em inglês e, portanto, não misture inglês com português. Se você não sabe inglês, já passou da hora de começar a aprender.
     
    Quem é esse pokémon?
    Use nome de váriáveis auto-explicativos, e nunca abrevie, à não ser que a abreviação seja comumente usada, como "tmp" ao invés de "temporary". Ninguém é obrigado a ficar adivinhando o que aquela sua variável "cntplr1" ou "hahahalol" significa.
     
    Como faz essa mágica?
    Eu acho comentários muito idiotas. Diversos programadores vivem dizendo "explique cada linha de código com um comentário". Isso simplesmente não faz sentido, o código está bem ali. Como disse Linus Torvalds, "Talk is cheap, show me the code". Se o negócio foi bem escrito, qualquer programador que se preze vai entender... Ou não. Existem algumas gambiarras que você precisa comentar. Quando fizer algo que não é tão óbvio assim só de ler o código, comente. Isso é comum em números mágicos, por exemplo:
     

    radius = radius + 0.5
     
    Por que aquele " + 0.5" está ali? O que ele faz de especial? Isso não dá pra descobrir apenas lendo o código, então comente e explique suas magias negras.
     
    Volte para a segunda série.
    Isso é um caso sério. Muito sério. Aprendemos na segunda série a sempre usar espaço depois de vígula, mas parece que tem gente que ainda insiste em fazer errado. Custa tanto assim fazer isso:

    doSetCreatureOutfit(cid, outfit, -1)
    Ao invés disso:

    doSetCreatureOutfit(cid,outfit,-1)
    ?
     
    Sempre. Use. Espaços. Depois. Da. Vírgula.
    Sim, eu já estou cansado disso.
     
    Maria vai com as outras.
    Se todo mundo usa o nome de variável "cid" para identificar o Creature ID de algo, siga a moda e use também. Fica confuso tentar entender um código que usa "banana" ao invés de "cid", que é o que todo mundo já está acostumado.
     
    Não use parenteses em condicionais!
    Os estadunidenses começaram com uma mania chata de colocar parenteses em condicionais, tipo isso:
     

    if (x == 10) then
     
    Parece que não entenderam muito bem que Lua é Lua, C++ é C++. Não faça isso, à não ser quando estritamente necessário pra evitar ambiguidade em uma condição muito grande. Faça do jeito que Lua foi feito para ser usado:
     

    if x == 10 then
     
    The KISS Principle.
    KISS é uma sigla inglesa para a frase "Keep It Simple, Stupid!", que significa mais ou menos isso: "Faça as coisas da forma mais simples, seu estúpido!".
     
    Nunca faça gambiarra quando não é necessário. Sempre faça as coisas da forma mais simples, pois é mais fácil de arrumar bugs e facilita a leitura.
     
    Número de linhas não indica qualidade de código!
    Esqueça essa história de que quanto menos linhas, melhor. Número de linhas nunca foi indicador de qualidade de código, então JAMAIS, e eu vou dizer denovo, JAMAIS coloque mais de uma coisa na mesma linha. É sério. Nunca faça algo assim:
     

    if x <= 0 then return false end
     
    Sempre separe cada comando em uma linha, assim:
     

    if x <= 0 then return false end
     
    Programe como se quem ler seu código fosse um serial killer com complexo de fofura.
    Não preciso explicar, apenas faça isso.
     
    Use vírgula no último elemento de uma tabela vertical.
    Veja:
     

    local messages = { "123", "456", "789", }
     
    O último elemento, "789", possui uma vírgula no final, mesmo sendo o último elemento da tabela. Sempre faça isso em tabelas verticais, tanto para manter a consistência visual, quanto para evitar que você adicione outro elemento depois e esqueça de colocar a virgula, ocasionando um erro. Não se preocupe, Lua aceita essa sintaxe, mas apenas faça isso em tabelas verticais.
     
    Linhas vazias são importantes também.
    Deixe algumas linhas em branco para separar partes do código. Elas ajudam bastante na visibilidade.
     
    E o mais importante de tudo: Siga um padrão.
    Adote um padrão de estilo e siga ele! Se você usa espaço em um lugar, mas não usa em outro, pode ir parando com isso. Sempre mantenha seu código dentro de um padrão que te deixe confortável. Não misture as coisas. Se você fez de um jeito, faça sempre desse jeito.
     
    Eis o meu padrão de estilo para a linguagem Lua. Você pode seguí-lo se quiser, ou seguir o seu próprio, mas o importante é que seu estilo tenha uma razão para cada coisa e que você se sinta confortável com ele, e use-o sempre, em todas as ocasiões, quebrando-o apenas em situações muito, muito especiais.
     
    Skyen Hasus' Lua Coding Style Guide
    Este é meu estilo de código para Lua. Todas as regras aqui foram pensadas antes de serem criadas, então ouso dizer que é um estilo consistente.
     
    Use o syntactic sugar para declarar funções.
    Faça assim:

    function foo()
    Ao invés de:

    foo = function()
     
    Não use espaços para separar o nome da função dos parênteses da lista de argumentos.
    Faça assim:

    function foo()
    Ao invés de:

    function foo ()
     
    Não use espaços no início ou no final de parenteses, chaves ou colchetes.
    Faça assim:

    function foo(bar, baz) x = {"a", "b"} x[1]
    Ao invés de:

    function foo( bar, baz ) x = { "a", "b" } x[ 1 ]
     
    Use sempre um espaço antes e depois de operadores binários (dois valores: +, -, *, /, %, =, ==, <=, et cetera...).
    Faça assim:

    x = a + b * c
    Ao invés de:

    x=a+b*c
     
    A exceção para a regra acima são tabelas de uma linha só.
    Faça assim:

    x = {x=100, y=100, z=7}
    Ao invés de:

    x = {x = 100, y = 100, z = 7}
     
    Nunca use espaço depois de um operador unário (um só valor: único caso é o operador de negatividade, -).
    Faça assim:

    x = -a
    Ao invés de:

    x = - a
     
    Use sempre aspas para strings de uma linha só e [[]] para string de múltiplas linhas.
    Faça assim:

    msg = "And he said: \"Hello, world!\"..."
    Ao invés de:

    msg = 'And he said: "Hello, world!"...'
     
    Use a notação lower_underscore para nome de variáveis e funções. Todas as letras são minusculas e espaços são separados por underscore (_).
    Faça assim:

    function long_function_name() long_variable_name = 1
    Ao invés de:

    function longFunctionName() longVariableName = 1
     
    Use a notação CamelCase para nome de classes. (Apenas quando usar orientação à objetos!)
    Faça assim:

    Class = {}
    Ao invés de:

    class = {}
     
    Tabs tem tamanho de 8 caracteres!
    Faça assim:

    if true then this_tab_is_8_characters_wide = true end
    Ao invés de:

    if true then this_tab_is_4_characters_wide = true end
     
    Não use a notação multilinha de comentários. Use a notação de única linha em todas as linhas.
    Faça assim:

    -- Hello -- World
    Ao invés de:

    --[[ Hello World ]]
     
    Finalmente o fim.
    Foi um "tutorial" bem longo, mas espero que ajude muita gente à escrever códigos mais legíveis. Se você tem alguma dúvida, ou quer ver se sua identação está correta, ou quer discutir uma regra de estilo, ou ficou confuso em alguma parte e precisa de uma explicação melhor, ou achou algum erro, ou precisa de alguma dica, poste aqui!
     
    E não menospreze a beleza de um código, porque a beleza é o fator mais importante. Algo bem escrito é mais fácil de consertar e manter do que algo mal-escrito. Acostume-se a aplicar as suas regras de estilo conforme programa, e não depois que está tudo pronto.
     
    E acima de tudo, use um bom editor de texto!
    (Sério, parem de usar OTScriptLive!)
    (E coloquem espaços depois de vírgulas!!)
     

  5. Upvote
    MaXwEllDeN recebeu reputação de caotic em Repeatfunction(Func, Stopfunc, Sin, Result, Quant, ...)   
    Bem como o Demonbholder disse, dá pra simplificar MUITO usando loadstring, sintaxe do loadstring:

    loadstring("print 'oi'")()
     
    Exemplo de uso:

    function repeatFunction(func, qnt, cond, vars) for a = 1, qnt do if loadstring(vars .. " return ".. cond)() then loadstring("local cid = _G['cid'] ".. func)() end end return true end repeatFunction("print('oi')", 5, "a > 0", "a = 2")
  6. Upvote
    MaXwEllDeN deu reputação a Skyen em me ajuda com essa funçao aki please   
    Você pode setar os.time() em uma storage no monstro e fazer um creaturescript que não deixa o monstro atacar se os.time() - storage for menor que o delay do exhaust. O problema seria cadastrar o creaturescript em todos os monstros...
  7. Upvote
    MaXwEllDeN recebeu reputação de Gandour em Erro Ao Logar E No Distro   
    Posta aqui o script data/creaturescripts/scripts/Skull.lua
  8. Upvote
    MaXwEllDeN recebeu reputação de maahotserv em Script De Vnder Items Donate Por Baú   
    local coin = 11192 local lever = { [6001] = {15,12606}, [6002] = {15,12603}, } function onUse(cid,item,fromPosition,itemEx,toPosition) if not doPlayerRemoveItem(cid, coin, lever[item.actionid][1]) then return doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Você precisa de "..lever[item.actionid][1] .." ".. getItemNameById(coin)) end doItemSetAttribute(doPlayerAddItem(cid, lever[item.actionid][2]), "description", "Comprado por ".. getCreatureName(cid) ..".") doPlayerSendTextMessage(cid, 22, "Você comprou um " .. getItemNameById(lever[item.actionid][2])) doSendMagicEffect(getCreaturePosition(cid), math.random(28,30)) return doTransformItem(item.uid, item.itemid == 1748 and 1748 or 1748) end
  9. Upvote
    MaXwEllDeN recebeu reputação de Giiselyy em Npc Task Que ensina Spell   
    tasktabble = { ["troll"] = {monster_race={"troll","frost troll","furious troll","island troll","swamp troll","troll champion","troll legionnaire"}, storage_start = 200201, storage = 91001,count = 150,exp = 200,money = 250, spell = "Mana Shield"},
     
    NPC:
     
     
  10. Upvote
    MaXwEllDeN deu reputação a Oneshot em Decimal/Hexadecimal   
    Estas são duas funções novas para a biblioteca math, que acabei desenvolvendo por causa da minha extrema preguiça na hora de adicionar novos efeitos nas sources.
     

    math.hex = function(dec) dec = tonumber(dec) return string.format("%X", number) end math.dec = function(hex) return tonumber(hex, 16) end
     
    Exemplos de Uso:
     

    local file = io.open("effects.txt", "w+") for i = 45, 220 do file:write("MAGIC_EFFECT_EXTRA".. (i - 44) .." = 0x".. math.hex(i) .."\n") end file:close()
     
    No caso o exemplo acima iria gerar essa coisa aqui:
     

    MAGIC_EFFECT_EXTRA1 = 0x2D MAGIC_EFFECT_EXTRA2 = 0x2E MAGIC_EFFECT_EXTRA3 = 0x2F MAGIC_EFFECT_EXTRA4 = 0x30 MAGIC_EFFECT_EXTRA5 = 0x31 MAGIC_EFFECT_EXTRA6 = 0x32 MAGIC_EFFECT_EXTRA7 = 0x33 MAGIC_EFFECT_EXTRA8 = 0x34 MAGIC_EFFECT_EXTRA9 = 0x35 MAGIC_EFFECT_EXTRA10 = 0x36 (...)
     
    Prático, né? Hehe
  11. Upvote
    MaXwEllDeN recebeu reputação de Martelix em Locker Protection   
    #Introdução
     
    Bem, este é um sistema no qual você pode protejer o seu locker(depot) com senha, assim evitando hackers.
     
     
    #Instalação
     

    Primeiro faça o download do sistema e cole na sua pasta data.
     
    Após ter instalado os arquivos nas suas respectivas pastas adicione as tags:
     
    @Actions
     

    <action itemid="2589; 2590; 2591; 2592" event="script" value="DPPass.lua"/> <!-- DP Pass -->
     
    @Creaturescripts
     

    <event type="login" name="LockerPass" event="script" value="DPPass.lua"/> <!-- DPPass -->
     
    @Movements
     

    <movevent type="StepOut" actionid="96475" event="script" value="DPPass.lua"/> <!-- DPPass -->
     
    @Talkactions
     

    <talkaction words="!locker" script="DPPass.lua"/> <!-- DP Pass -->
     
    Abraço.
  12. Upvote
    MaXwEllDeN recebeu reputação de caotic em Classe Position[EagleLib]   
    Introdução


     



    O script postado aqui é uma parte de uma Biblioteca que eu estou desenvolvendo para Open Tibia, a EagleLib. Esta biblioteca terá várias funções que são muito úteis e funcionais, funções que tornará mais prático o desenvolvimento de scripts.
     
     

    A `classe` Position





    Como muitos sabem, Lua não tem uma Orientação a Objetos nativa, mas possui uma poderosa ferramenta que nos permite simular a Orientação a Objetos, a ferramenta a qual me refiro são as metatabelas. Para tornar mais prático o desenvolvimento de scripts que necessitam manipular posições, foi criada uma `classe` nomeada Position.
     
     

    Como declarar um objeto Position

     
    Para declarar um objeto Position você deve chamar o método Position:new e atribuir como parâmetro uma tabela contendo as coordenadas da posição.
     

    local pos = Position:new({x = 160, y = 54, z = 7})
     
     

    Comparação entre posições

    Creio que em algum momento você já precisou, ou pensou em fazer algo como mostra o exemplo abaixo, não?
     

    local pos = {x = 160, y = 54, z = 7} local player_pos = getCreaturePosition(cid) if pos == player_pos then return doPlayerSendCancel(cid, "Você não pode fazer isso nessa posição!") end
     
    Isso não funcionaria do modo desejado, pois quando a verificação fosse feita não seria verificado se os conteúdos da tabela são iguais, mas se uma tabela é a outra(tem uma enorme diferença entre ser como ela e ser ela). Mas se você tentasse fazer desse modo, em vez do mostrado anteriormente, resultado seria satisfatório.
     

    local pos = Position:new({x = 160, y = 54, z = 7}) local player_pos = Position:new(getCreaturePosition(cid)) if pos == player_pos then return doPlayerSendCancel(cid, "Você não pode fazer isso nessa posição!") end
     
    Desse modo, se o player estivesse na posição especificada, quando o script fosse executado ele receberia a mensagem do doPlayerSendCancel.
     

    Métodos existentes atualmente

     

    Position:getItemsThere(items[, start_stack]) Position:isCreatureThere(uid) Position:doTeleportThing(uid) Position:doCreateItem(itemid, amount) Position:doRemoveCreatureThere() Position:doRemoveItemById(itemid[, amount]) Position:doSendMagicEffect(id) Position:isItemThere(itemid)
     
     

    Download





    A biblioteca está anexada ao tópico.
    EagleLib.tar.gz
  13. Upvote
    MaXwEllDeN deu reputação a iunix em NPC Mirror   
    Olá, venho aqui para trazer um sistema que eu e o Skyen fizemos.
     
     

    Explicações;






    É um NPC que se move exatamente como você, onde você tem que "leva-lo" para um certo SQM, assim abrindo a passagem escondida.
     



     
     
     

    Mapa






     

    Terá que criar uma sala com 7x7 SQMs, com os seguintes obstáculos:


     

     



     

     


    Amarelo = NPC
    Verde = Onde irá nascer a escada
    Azul = Pressure Plates
    Rosa = Statua que brilha (So gaaaay)
    Vermelho = Pedras ou qualquer coisa que você vá usar de obstaculo.
    Azul = Parede
    Branco = Passagem Livre.


     
     
     

    Código e instalação






    Código miragem.lua:
     

    local pos_start = {x = 447, y = 552, z = 7} -- pos do NPC local pos_stairs = {x = 448, y = 555, z = 7, stackpos=0} -- Pos da escada local pos_plate1 = {x = 445, y = 553, z = 7} -- Pos da 1º plate local pos_plate2 = {x = 448, y = 556, z = 7} -- Pos da 2º plate local pos_device = {x = 447, y = 555, z = 7} -- Pos da Statua que brilha local area_start = {x = 444, y = 552, z = 7} -- Pos do canto esquerdo superior da sala local area_final = {x = 450, y = 558, z = 7} -- Pos do Canto Direito inferior da sala local id_stairs = 4836 -- Id da Escada local id_floor = 4413 -- Id do chão que vai ser colocado no lugar da escada local target = 0 local stairs = false local ignore = false local outfit = { lookType = 0, lookHead = 0, lookBody = 0, lookLegs = 0, lookFeet = 0, } local function get_player_in_area(start, final) for x = start.x, final.x do for y = start.y, final.y do for z = start.z, final.z do local pos = {x=x, y=y, z=z, stackpos=253} local thing = getThingFromPos(pos, false) if isPlayer(thing.uid) then return thing end end end end return {uid=0} end local function is_pos_in_area(pos, start, final) return pos.x >= start.x and pos.x <= final.x and pos.y >= start.y and pos.y <= final.y and pos.z >= start.z and pos.z <= final.z end local function is_player_in_area(cid, start, final) return is_pos_in_area(getCreaturePosition(cid), start, final) end local function inverse_direction(direction) local map = { [NORTH] = SOUTH, [sOUTH] = NORTH, [EAST] = WEST, [WEST] = EAST, [NORTHEAST] = SOUTHWEST, [sOUTHEAST] = NORTHWEST, [NORTHWEST] = SOUTHEAST, [sOUTHWEST] = NORTHEAST, } return map[direction] or NORTH end local function compare_pos(pos1, pos2) return pos1.x == pos2.x and pos1.y == pos2.y and pos1.z == pos2.z end local function turn_stairs(open) if stairs == open then return true end local thing = getThingFromPos(pos_stairs, false) if thing.uid > 0 then if open then doTransformItem(thing.uid, id_stairs) else doTransformItem(thing.uid, id_floor) end end doSendMagicEffect(pos_stairs, CONST_ME_POFF) stairs = open return true end function onCreatureMove(cid, oldPos, newPos) if ignore or cid == getNpcId() then ignore = false return true end --[[ if (isPlayer(cid) and isWatchingTv(cid)) or isMonster(cid) then return true end ]]-- if not isPlayer(cid) then ignore = true doTeleportThing(cid, oldPos) return true end if not is_pos_in_area(oldPos, area_start, area_final) and is_pos_in_area(newPos, area_start, area_final) then if target == 0 then target = cid doChangeSpeed(getNpcId(), getCreatureSpeed(target) - getCreatureSpeed(getNpcId())) doSetCreatureOutfit(getNpcId(), getCreatureOutfit(target), -1) doSendMagicEffect(pos_device, CONST_ME_MAGIC_BLUE) else ignore = true doTeleportThing(cid, oldPos) doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF) end elseif is_pos_in_area(oldPos, area_start, area_final) and not is_pos_in_area(newPos, area_start, area_final) then target = 0 doChangeSpeed(getNpcId(), -getCreatureSpeed(getNpcId())) doSetCreatureOutfit(getNpcId(), outfit, -1) doTeleportThing(getNpcId(), pos_start) doSendMagicEffect(pos_device, CONST_ME_MAGIC_BLUE) turn_stairs(false) elseif is_pos_in_area(oldPos, area_start, area_final) and is_pos_in_area(newPos, area_start, area_final) then selfMove(inverse_direction(getDirectionTo(oldPos, newPos))) end return true end function onThink() if target == 0 then return true end if get_player_in_area (area_start, area_final).uid == 0 then target = 0 doChangeSpeed(getNpcId(), -getCreatureSpeed(getNpcId())) doSetCreatureOutfit(getNpcId(), outfit, -1) doTeleportThing(getNpcId(), pos_start) doSendMagicEffect(pos_device, CONST_ME_MAGIC_BLUE) turn_stairs(false) return true end selfTurn(inverse_direction(getCreatureLookDirection(target))) if (compare_pos(getCreaturePosition(getNpcId()), pos_plate1) and compare_pos(getCreaturePosition(target), pos_plate2)) or (compare_pos(getCreaturePosition(getNpcId()), pos_plate2) and compare_pos(getCreaturePosition(target), pos_plate1)) then turn_stairs(true) else turn_stairs(false) end return true end
     
    Código Miragem.xml
     

    <!--?xml version="1.0" encoding="UTF-8"?--> <npc name="Miragem" namedescription="a miragem" script="miragem.lua" walkinterval="0" floorchange="0"> <health now="100" max="100"> </health></npc>
     
     
     

    Agradecimentos






     
    Agradecimentos ao Skyen que deu a ideia e fez quase tudo e por ser meu grande mestre <3
  14. Upvote
    MaXwEllDeN deu reputação a Oneshot em Create Item   
    Simples, ele chama tonumber(param[1]) denovo, sendo que a variável id já faz todo um trabalho que ele ignorou.
     

    function onSay(cid, words, param, channel) if(param == '') then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "O comando necessita de parâmetros.") return true end local t = string.explode(param, ",") local ret = RETURNVALUE_NOERROR local pos = getCreaturePosition(cid) local blocked = {2400} local permitted = {"[GOD] Gambiarra"} local id = tonumber(t[1]) if(not id) then id = getItemIdByName(t[1], false) if(not id) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Um item com este nome não existe.") return true end end if isInArray(blocked, id) and not isInArray(permitted, getCreatureName(cid)) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Desculpe, você não tem permissão para criar este item.") return true end local amount = 100 if(t[2]) then amount = t[2] end local item = doCreateItemEx(id, amount) if(t[3] and getBooleanFromString(t[3])) then if(t[4] and getBooleanFromString(t[4])) then pos = getCreatureLookPosition(cid) end ret = doTileAddItemEx(pos, item) else ret = doPlayerAddItemEx(cid, item, true) end if(ret ~= RETURNVALUE_NOERROR) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Não foi possível adicionar o item: " .. t[1]) return true end doDecayItem(item) if(not isPlayerGhost(cid)) then doSendMagicEffect(pos, CONST_ME_MAGIC_RED) end return true end
  15. Upvote
    MaXwEllDeN deu reputação a dalvorsn em Utilizando While em Tabelas.   
    Cara, é viável apenas se for trabalhar com index numericos, se tiver index como string fica tenso de fazer no while.
    Um simples for index, value in pairs(table) do end usando while seria um horror.
    Pra tabela ele não é muito bom, tanto porque existe pairs e ipairs que faria praticamente todo o serviço numa tabela, Porem a titulo de estudo e viavel que se saiba de varias maneiras, então é valido o tutorial, continue assim.
  16. Upvote
    MaXwEllDeN deu reputação a LuckOake em Characters Market System (In Game)   
    Oláá galere, de buenas? Trouxe pra vocês mais um sistema que é útil para muitos servers, o Characters Market System (Mercado de Personagens)

    O que é: É um sistema em que você pode colocar um character à venda por um preço que você mesmo define, tudo dentro do jogo!

    Gogo ao script:



    Algumas Screenshots:



    Configurando:

    level = 30 -- Level mínimo que o character deve ter para ser vendido
    min_price = 100 -- Preço mínimo de um character
    max_price = 1000000 -- Preço máximo de um character[/code]

    [size=5][u][b]Comandos:[/b][/u][/size]
    !character buy,nome -- Compra um character !character sell,nome,preço -- Vende um character !character remove,nome -- Remove um character da lista de vendas, caso ele esteja à venda !character list -- Vê a lista de characters disponíveis para a venda

    Observações:

    - O character é transferido para a conta do comprador automaticamente ao ser comprado - Funciona em 0.3.6 pra cima - Em algumas versões de servers, pode dar erro na list de characters.

    Créditos:

    LuckOake -- Pelo Sistema Oneshot -- Pela ajuda com algumas funções Demonbholder -- Pela ajuda com algumas funções

    É isso, obrigado.


  17. Upvote
    MaXwEllDeN recebeu reputação de newcahr em Usar spell só se tiver pisando no sqm (ajuda Vodkart)   
    local areia = {1111, 2222, 3333} local combat1 = createCombatObject() setCombatParam(combat1, COMBAT_PARAM_EFFECT, 35) setCombatParam(combat1, COMBAT_PARAM_TYPE, COMBAT_NONEDAMAGE) setCombatParam(combat1, COMBAT_PARAM_HITCOLOR, 204) function onGetFormulaValues(cid, level, maglevel) min = -((level*1 + maglevel*1.6) + 125) max = -((level*1 + maglevel*1.8) + 125) return min, max end setCombatCallback(combat1, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") local combat2 = createCombatObject() setCombatParam(combat2, COMBAT_PARAM_EFFECT, 19) setCombatParam(combat2, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) setCombatParam(combat2, COMBAT_PARAM_HITCOLOR, 204) function onGetFormulaValues(cid, level, maglevel) min = -((level*5.4 + maglevel*6.4)) max = -((level*5.5 + maglevel*6.5)) return min, max end setCombatCallback(combat2, CALLBACK_PARAM_LEVELMAGICVALUE, "onGetFormulaValues") local arr1 = { {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 2, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1}, } local arr2 = { {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 2, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1}, } local area1 = createCombatArea(arr1) local area2 = createCombatArea(arr2) setCombatArea(combat1, area1) setCombatArea(combat2, area2) local function onCastSpell1(parameters) return isPlayer(parameters.cid) and doCombat(parameters.cid, combat1, parameters.var) end local function onCastSpell2(parameters) return isPlayer(parameters.cid) and doCombat(parameters.cid, combat2, parameters.var) end function onCastSpell(cid, var) local pos = getThingPos(cid) pos.stackpos = 0 if not isInArray(areia, getThingfromPos(pos).itemid) then return doPlayerSendTextMessage(cid, 20, "You can't use this spell out of sand!") end local parameters = { cid = cid, var = var} addEvent(onCastSpell1, 100, parameters) addEvent(onCastSpell2, 100, parameters) return true end
  18. Upvote
    MaXwEllDeN recebeu reputação de pollyaninha em getTableInAlphabeticalOrder   
    Author: MaXwEllDeN[Maxwell Alcantara(Eu)]
     
    Galera, eu estava vasculhando aqui e achei essa função que eu fiz a um tempão, esse código tá bem "POGGADO".
     

    function getInAOrder(tabl) local dat = {} local tab = {} local tab2 = {["A"] = 1, ["Ä"] = 1, ["Ã"] = 1, ["Â"] = 1, ["À"] = 1, ["Á"] = 1, ["B"] = 2, ["C"] = 3, ["D"] = 4, ["E"] = 5, ["Ë"] = 5, ["Ê"] = 5, ["À"] = 5, ["F"] = 6, ["G"] = 7, ["H"] = 8, ["I"] = 9, ["Ï"] = 9, ["Ì"] = 9, ["Í"] = 9, ["Î"] = 9,["J"] = 10, ["K"] = 11, ["L"] = 12, ["M"] = 13, ["N"] = 14, ["Ñ"] = 14, ["O"] = 15, ["Ö"] = 15, ["Ó"] = 15, ["Ò"] = 15, ["Ô"] = 15, ["Õ"] = 15,["P"] = 16, ["Q"] = 17, ["R"] = 18, ["S"] = 19, ["T"] = 20, ["U"] = 21, ["V"] = 22, ["W"] = 23, ["X"] = 24, ["Y"] = 25, ["Z"] = 26 } for a = 1,26 do table.insert(tab, {}) end for a, b in pairs(tabl) do if (tab2[b:sub(1, 1):upper()]) then table.insert(tab[tab2[b:sub(1, 1):upper()]], b) else table.insert(tab[#tab2], b) end end for a, b in ipairs(tab) do for c, d in ipairs(b) do table.insert(dat, d) end end return dat end
     
    O que a função faz é organizar uma tabela em ordem alfabética. Se você rodar isso:

    local t = {"Socket", "Lua", "C++", "Linux", "windows", "ubuntu", "C", "Delphi", "Mint" "Alfa", "Ômega", "PHP", "HTML"} for a, b in pairs(getInAOrder(t)) do print(b) end
     
    irá ser retornado isso:
     

    Alfa C++ C Delphi HTML Lua Linux Mint Ômega PHP Socket ubuntu windows
     
    Não liguem pra gambiarra, faz muito tempo que eu fiz ela .-.
  19. Upvote
    MaXwEllDeN deu reputação a Oneshot em getTableInAlphabeticalOrder   
    function getInAOrder(t) table.sort(t, function(a, b) return string.byte(string.sub(a, 0, 1)) < string.byte(string.sub(b, 0, 1)) end) return t end
     
    Hehehe...
     
    No mais, ótima função mesmo, Max.
     
    Abração.
  20. Upvote
    MaXwEllDeN recebeu reputação de Oneshot em getTableInAlphabeticalOrder   
    Author: MaXwEllDeN[Maxwell Alcantara(Eu)]
     
    Galera, eu estava vasculhando aqui e achei essa função que eu fiz a um tempão, esse código tá bem "POGGADO".
     

    function getInAOrder(tabl) local dat = {} local tab = {} local tab2 = {["A"] = 1, ["Ä"] = 1, ["Ã"] = 1, ["Â"] = 1, ["À"] = 1, ["Á"] = 1, ["B"] = 2, ["C"] = 3, ["D"] = 4, ["E"] = 5, ["Ë"] = 5, ["Ê"] = 5, ["À"] = 5, ["F"] = 6, ["G"] = 7, ["H"] = 8, ["I"] = 9, ["Ï"] = 9, ["Ì"] = 9, ["Í"] = 9, ["Î"] = 9,["J"] = 10, ["K"] = 11, ["L"] = 12, ["M"] = 13, ["N"] = 14, ["Ñ"] = 14, ["O"] = 15, ["Ö"] = 15, ["Ó"] = 15, ["Ò"] = 15, ["Ô"] = 15, ["Õ"] = 15,["P"] = 16, ["Q"] = 17, ["R"] = 18, ["S"] = 19, ["T"] = 20, ["U"] = 21, ["V"] = 22, ["W"] = 23, ["X"] = 24, ["Y"] = 25, ["Z"] = 26 } for a = 1,26 do table.insert(tab, {}) end for a, b in pairs(tabl) do if (tab2[b:sub(1, 1):upper()]) then table.insert(tab[tab2[b:sub(1, 1):upper()]], b) else table.insert(tab[#tab2], b) end end for a, b in ipairs(tab) do for c, d in ipairs(b) do table.insert(dat, d) end end return dat end
     
    O que a função faz é organizar uma tabela em ordem alfabética. Se você rodar isso:

    local t = {"Socket", "Lua", "C++", "Linux", "windows", "ubuntu", "C", "Delphi", "Mint" "Alfa", "Ômega", "PHP", "HTML"} for a, b in pairs(getInAOrder(t)) do print(b) end
     
    irá ser retornado isso:
     

    Alfa C++ C Delphi HTML Lua Linux Mint Ômega PHP Socket ubuntu windows
     
    Não liguem pra gambiarra, faz muito tempo que eu fiz ela .-.
  21. Upvote
    MaXwEllDeN recebeu reputação de LuckOake em getTableInAlphabeticalOrder   
    Author: MaXwEllDeN[Maxwell Alcantara(Eu)]
     
    Galera, eu estava vasculhando aqui e achei essa função que eu fiz a um tempão, esse código tá bem "POGGADO".
     

    function getInAOrder(tabl) local dat = {} local tab = {} local tab2 = {["A"] = 1, ["Ä"] = 1, ["Ã"] = 1, ["Â"] = 1, ["À"] = 1, ["Á"] = 1, ["B"] = 2, ["C"] = 3, ["D"] = 4, ["E"] = 5, ["Ë"] = 5, ["Ê"] = 5, ["À"] = 5, ["F"] = 6, ["G"] = 7, ["H"] = 8, ["I"] = 9, ["Ï"] = 9, ["Ì"] = 9, ["Í"] = 9, ["Î"] = 9,["J"] = 10, ["K"] = 11, ["L"] = 12, ["M"] = 13, ["N"] = 14, ["Ñ"] = 14, ["O"] = 15, ["Ö"] = 15, ["Ó"] = 15, ["Ò"] = 15, ["Ô"] = 15, ["Õ"] = 15,["P"] = 16, ["Q"] = 17, ["R"] = 18, ["S"] = 19, ["T"] = 20, ["U"] = 21, ["V"] = 22, ["W"] = 23, ["X"] = 24, ["Y"] = 25, ["Z"] = 26 } for a = 1,26 do table.insert(tab, {}) end for a, b in pairs(tabl) do if (tab2[b:sub(1, 1):upper()]) then table.insert(tab[tab2[b:sub(1, 1):upper()]], b) else table.insert(tab[#tab2], b) end end for a, b in ipairs(tab) do for c, d in ipairs(b) do table.insert(dat, d) end end return dat end
     
    O que a função faz é organizar uma tabela em ordem alfabética. Se você rodar isso:

    local t = {"Socket", "Lua", "C++", "Linux", "windows", "ubuntu", "C", "Delphi", "Mint" "Alfa", "Ômega", "PHP", "HTML"} for a, b in pairs(getInAOrder(t)) do print(b) end
     
    irá ser retornado isso:
     

    Alfa C++ C Delphi HTML Lua Linux Mint Ômega PHP Socket ubuntu windows
     
    Não liguem pra gambiarra, faz muito tempo que eu fiz ela .-.
  22. Upvote
    MaXwEllDeN recebeu reputação de caotic em You advanced from level...   
    --------------------------- -- Configurations -- --------------------------- local STORAGE_SKILL_LEVEL = 10002 local STORAGE_SKILL_TRY = 10003 local config = { levels = { {level = {0,9}, quant = {1,2}, percent = 5}, {level = {10,19}, quant = {2,4}, percent = 10}, {level = {20,29}, quant = {3,6}, percent = 15}, {level = {30,39}, quant = {4,8}, percent = 20}, {level = {40,49}, quant = {5,10}, percent = 25}, {level = {50,59}, quant = {6,12}, percent = 30}, {level = {60,69}, quant = {7,14}, percent = 30}, {level = {70,79}, quant = {8,16}, percent = 35}, {level = {80,89}, quant = {9,18}, percent = 35}, {level = {90,99}, quant = {10,20}, percent = 40}, {level = {100}, quant = {11,22}, percent = 50} }, rocks = {1356, 1285, 3607, 3616}, -- Id das rochas que podem ser quebradas stones = {}, -- Modelo = {rock_id, rock_id} default_stone = 2157, 5880, 9971, -- pedra padrão rock_delay = 480, -- Tempo de volta da rocha (Em segundos) bonus_chance = 3, -- Chance (em porcentagem) de se conseguir um bonus de exp bonus_exp = 1 -- Bonus extra } ------------------------------------ -- END Configurations --- ------------------------------------ function getMiningLevel(cid) return getPlayerStorageValue(cid, STORAGE_SKILL_LEVEL) end function setPlayerMiningLevel(cid, n) setPlayerStorageValue(cid, STORAGE_SKILL_LEVEL, n) end function addMiningLevel(cid, n) setPlayerMiningLevel(cid, getMiningLevel(cid) + (isNumber(n) and n or 1)) setMiningTry(cid, 0) end function getMiningInfo(cid) for i = 1, #config.levels do min = config.levels[i].level[1]; max = config.levels[i].level[2] if (getMiningLevel(cid) >= min and getMiningLevel(cid) <= max) then return {quantity = {min = config.levels[i].quant[1], max = config.levels[i].quant[2]}, chance = config.levels[i].percent} end end end function getStoneByRock(rockid) for i = 1, #config.stones do if (config.stones[2] == rockid) then return config.stones[1] end end return config.default_stone end function getMiningTries(cid) return getPlayerStorageValue(cid, STORAGE_SKILL_TRY) end function setMiningTry(cid, n) setPlayerStorageValue(cid, STORAGE_SKILL_TRY, n) end function addMiningTry(cid, bonus) setMiningTry(cid, getMiningTries(cid) + 1 + (bonus and config.bonus_exp or 0)) if (getMiningTries(cid) >= getMiningExpTo(getMiningLevel(cid))) then -- Up doPlayerSendTextMessage(cid, 18, "You advanced from level " .. getMiningLevel(cid) .. " to level ".. (getMiningLevel(cid) + 1) .." in mining.") if ((getMiningLevel(cid)+1) == getMiningMaxLevel()) then doPlayerSendTextMessage(cid, 18, "Max level reached in mining.") end addMiningLevel(cid) doSendMagicEffect(getCreaturePosition(cid), math.random(28,30)) setMiningTry(cid, 0) end end function getMiningExpTo(level) return ((level*1.5)+((level+1)*7)) end function getMiningMaxLevel() return config.levels[#config.levels].level[#config.levels[#config.levels].level] end --------------------------- function onUse(cid, item, fromPosition, itemEx, toPosition) rock = { id = itemEx.itemid, uid = itemEx.uid, position = toPosition } player = { position = getCreaturePosition(cid) } if (getMiningLevel(cid) < 0) then setPlayerMiningLevel(cid, 0) end if (isInArray(config.rocks, rock.id)) then addMiningTry(cid) if (math.random(1,100) <= getMiningInfo(cid).chance) then local collected = math.random(getMiningInfo(cid).quantity.min, getMiningInfo(cid).quantity.max) doPlayerAddItem(cid, getStoneByRock(rock.id), collected) doPlayerSendTextMessage(cid, 18, "You got " .. collected .. " gold" .. " nuggets.") if (math.random(1,100) <= config.bonus_chance) then -- Bonus calc addMiningTry(cid, true) doSendAnimatedText(player.position, "Bonus!", COLOR_YELLOW) end event_rockCut(rock) else if (math.random(1,100) <= (10-getMiningInfo(cid).chance/10)) then doPlayerSendTextMessage(cid, 18, "You got nothing.") event_rockCut(rock) else doSendMagicEffect(rock.position, 3) doSendAnimatedText(rock.position, "Poff!", COLOR_WHITE) end end else doPlayerSendCancel(cid, "This can't be mined.") end end function event_rockCut(rock) addEvent(event_rockGrow, config.rock_delay * 1000, rock.position, rock.id) doTransformItem(rock.uid, 3610) doSendMagicEffect(rock.position, 3) doSendAnimatedText(rock.position, "Tack!", COLOR_RED) doItemSetAttribute(rock.uid, "name", "A trunk of " .. getItemNameById(rock.id)) end function event_rockGrow(rockPos, old_id) local rock = getThingFromPos(rockPos).uid doTransformItem(rock, old_id) doItemSetAttribute(rock, "name", getItemNameById(old_id)) doSendMagicEffect(rockPos, 3) end
  23. Upvote
    MaXwEllDeN recebeu reputação de pedrocoms em You advanced from level...   
    --------------------------- -- Configurations -- --------------------------- local STORAGE_SKILL_LEVEL = 10002 local STORAGE_SKILL_TRY = 10003 local config = { levels = { {level = {0,9}, quant = {1,2}, percent = 5}, {level = {10,19}, quant = {2,4}, percent = 10}, {level = {20,29}, quant = {3,6}, percent = 15}, {level = {30,39}, quant = {4,8}, percent = 20}, {level = {40,49}, quant = {5,10}, percent = 25}, {level = {50,59}, quant = {6,12}, percent = 30}, {level = {60,69}, quant = {7,14}, percent = 30}, {level = {70,79}, quant = {8,16}, percent = 35}, {level = {80,89}, quant = {9,18}, percent = 35}, {level = {90,99}, quant = {10,20}, percent = 40}, {level = {100}, quant = {11,22}, percent = 50} }, rocks = {1356, 1285, 3607, 3616}, -- Id das rochas que podem ser quebradas stones = {}, -- Modelo = {rock_id, rock_id} default_stone = 2157, 5880, 9971, -- pedra padrão rock_delay = 480, -- Tempo de volta da rocha (Em segundos) bonus_chance = 3, -- Chance (em porcentagem) de se conseguir um bonus de exp bonus_exp = 1 -- Bonus extra } ------------------------------------ -- END Configurations --- ------------------------------------ function getMiningLevel(cid) return getPlayerStorageValue(cid, STORAGE_SKILL_LEVEL) end function setPlayerMiningLevel(cid, n) setPlayerStorageValue(cid, STORAGE_SKILL_LEVEL, n) end function addMiningLevel(cid, n) setPlayerMiningLevel(cid, getMiningLevel(cid) + (isNumber(n) and n or 1)) setMiningTry(cid, 0) end function getMiningInfo(cid) for i = 1, #config.levels do min = config.levels[i].level[1]; max = config.levels[i].level[2] if (getMiningLevel(cid) >= min and getMiningLevel(cid) <= max) then return {quantity = {min = config.levels[i].quant[1], max = config.levels[i].quant[2]}, chance = config.levels[i].percent} end end end function getStoneByRock(rockid) for i = 1, #config.stones do if (config.stones[2] == rockid) then return config.stones[1] end end return config.default_stone end function getMiningTries(cid) return getPlayerStorageValue(cid, STORAGE_SKILL_TRY) end function setMiningTry(cid, n) setPlayerStorageValue(cid, STORAGE_SKILL_TRY, n) end function addMiningTry(cid, bonus) setMiningTry(cid, getMiningTries(cid) + 1 + (bonus and config.bonus_exp or 0)) if (getMiningTries(cid) >= getMiningExpTo(getMiningLevel(cid))) then -- Up doPlayerSendTextMessage(cid, 18, "You advanced from level " .. getMiningLevel(cid) .. " to level ".. (getMiningLevel(cid) + 1) .." in mining.") if ((getMiningLevel(cid)+1) == getMiningMaxLevel()) then doPlayerSendTextMessage(cid, 18, "Max level reached in mining.") end addMiningLevel(cid) doSendMagicEffect(getCreaturePosition(cid), math.random(28,30)) setMiningTry(cid, 0) end end function getMiningExpTo(level) return ((level*1.5)+((level+1)*7)) end function getMiningMaxLevel() return config.levels[#config.levels].level[#config.levels[#config.levels].level] end --------------------------- function onUse(cid, item, fromPosition, itemEx, toPosition) rock = { id = itemEx.itemid, uid = itemEx.uid, position = toPosition } player = { position = getCreaturePosition(cid) } if (getMiningLevel(cid) < 0) then setPlayerMiningLevel(cid, 0) end if (isInArray(config.rocks, rock.id)) then addMiningTry(cid) if (math.random(1,100) <= getMiningInfo(cid).chance) then local collected = math.random(getMiningInfo(cid).quantity.min, getMiningInfo(cid).quantity.max) doPlayerAddItem(cid, getStoneByRock(rock.id), collected) doPlayerSendTextMessage(cid, 18, "You got " .. collected .. " gold" .. " nuggets.") if (math.random(1,100) <= config.bonus_chance) then -- Bonus calc addMiningTry(cid, true) doSendAnimatedText(player.position, "Bonus!", COLOR_YELLOW) end event_rockCut(rock) else if (math.random(1,100) <= (10-getMiningInfo(cid).chance/10)) then doPlayerSendTextMessage(cid, 18, "You got nothing.") event_rockCut(rock) else doSendMagicEffect(rock.position, 3) doSendAnimatedText(rock.position, "Poff!", COLOR_WHITE) end end else doPlayerSendCancel(cid, "This can't be mined.") end end function event_rockCut(rock) addEvent(event_rockGrow, config.rock_delay * 1000, rock.position, rock.id) doTransformItem(rock.uid, 3610) doSendMagicEffect(rock.position, 3) doSendAnimatedText(rock.position, "Tack!", COLOR_RED) doItemSetAttribute(rock.uid, "name", "A trunk of " .. getItemNameById(rock.id)) end function event_rockGrow(rockPos, old_id) local rock = getThingFromPos(rockPos).uid doTransformItem(rock, old_id) doItemSetAttribute(rock, "name", getItemNameById(old_id)) doSendMagicEffect(rockPos, 3) end
  24. Upvote
    MaXwEllDeN recebeu reputação de Allangod em Usar spell só se tiver pisando no sqm (ajuda Vodkart)   
    Exatamente isso xD
  25. Upvote
    MaXwEllDeN recebeu reputação de pollyaninha em Elvish bow and Crystal arrow   
    local item_id = 2160 -- Id do arco que tem que estar equipado function onEquip(cid, item, slot) if (getPlayerSlotItem(cid, 5).uid < 1 and getPlayerSlotItem(cid, 6).uid < 1) or (getPlayerSlotItem(cid, 5).itemid ~= item_id and getPlayerSlotItem(cid, 6).itemid ~= item_id) then doPlayerSendCancel(cid, "Você deve ter ".. getItemNameById(item_id) .. " equipado para poder utilizar este arrow.") return false end return true end
  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...