Ir para conteúdo

Skyen

Campones
  • Total de itens

    36
  • Registro em

  • Última visita

  • Dias Ganhos

    5

Posts postados por Skyen

  1. function decrypt(message, exp, map)
       local inv = 1.0 / exp -- because f*ck root calculation
    
       local str = ""
       local byte = 0
    
       for i = 1, #message do
           byte = byte * 256 -- lazy lshift8
    
           if type(message) == "table" then
               byte = byte + message[i]
           else
               byte = byte + tostring(message):byte(i)
           end
    
           local char = map[byte ^ inv]
    
           if char then
               str = str .. char
               byte = 0
           end
       end
    
       return str
    end

     

    local map = {}
    
    -- map values between '0' and '9'
    for i = string.byte("0"), string.byte("9") do
       map[i] = string.char(i)
    end
    
    -- map values between 'A' and 'Z', and 'a' and 'z'
    for i = string.byte("A"), string.byte("Z") do
       map[i] = string.char(i)
       map[i + 32] = string.char(i + 32)
    end
    
    local encrypted = {39, 16, 36, 193, 45, 144, 54, 100, 48, 33}
    
    print(decrypt(encrypted, 2, map))

  2. encantos do pog

     

    Nope.

     

    str = ""..str..""..char..""

     

    2KC7XaB.jpg

     

    str = str .. char

     

    E isso não é gambiarra. Em linguagens de baixo/médio nível (C, C++, et cetera) o algoritmo é praticamente igual o seu. Essa solução também é mais eficiente do que a usada no open tibia. Você poderia deixar ela um pouco mais rápida gravando o caractere em uma string temporária e depois inserir essa string na tabela quando o separador ou o fim da string original fosse encontrado.

  3. GAMBIARRA É UMA COISA RUIM, SIM! Tirem da cabeça que fazer algo de forma absurda É bom. KISS Tem gente que prega o "POG" como coisa boa, que atÉ mesmo tenta fazer de propósito. SÉrio, vocês precisam parar com isso. De fato, existem situações onde não existe outra solução, então É um mal necessário, mas somente se você tiver certeza de que está fazendo a coisa certa, e isso leva muito tempo e conhecimento da ciência por trás do seu programa e linguagem. No geral, tente SEMPRE fazer um código simples de entender. Nada de fazer macarronada com o código. Vale a pena saber fazer? Vale. Vale a pena botar isso em prática? Não. E outra coisa: Número de linhas nunca foi indicador de qualidade de código. Um código de 100 linhas pode ser melhor ou pior que um código de 10 linhas.
    E como foi dito o poger e associado a quantidade de linhas. Mais nunca disse que a quantidade de linhas tem relação com a qualidade do script. Do mais. Eu não vejo as gambiarras como monstro.
    Desculpe, eu interpretei mal. Realmente, as "gambiarras" geralmente ocupam mais linhas do que uma solução que seria naturalmente mais simples. E quanto à ser um monstro, É o que eu falei: É um mal necessário. Se existe uma solução mais simples e limpa, por que fazer de forma absurda? Para ganhar a alcunha de "rei do pog"? Para obscurecer o código? Usando uma analogia bem ridícula: se você pode colocar o quadro na parede com um prego, por que usar durepoxy? Existem casos onde gambiarras são sim necessárias. Talvez porque não exista outra solução pro problema. Ou talvez seja um mÉtodo mais rápido de executar determinada rotina. Para estes casos eu concordo com você, mas o programador tem que ter certeza absoluta de que a solução É segura, eficiente, e a melhor possível para o problema. Para isso você precisa saber com o que está lidando, conhecer muito bem suas ferramentas (bibliotecas e linguagem), e mesmo assim deixar um comentário explicando como a magia negra funciona e por que ela foi necessária. Todo mundo faz gambiarra um dia, apenas tenha certeza de que está fazendo a coisa certa, e não fazendo só por graça. O trabalho dos programadores não É apenas encontrar soluções, mas sim encontrar as melhores soluções. O motivo do meu pânico em relação ao assunto É que muitos programadores incentivam os iniciantes a fazer gambiarra como se fosse normal, e isso continua com a pessoa por muito tempo, atÉ que ela atinja maturidade suficiente pra diferenciar uma solução boa de uma solução ruim. Me chame de egoísta se quiser, mas eu não quero mais ver novatos fazendo magia negra sem nem se dar o trabalho de procurar uma solução mais simples. São essas pessoas que fazem códigos com 9 loops aninhados e dificílimos de entender. Outra coisa: do jeito que eu falei talvez tenha parecido que eu estou depreciando seu trabalho. Se você entendeu isso, você tem minhas sinceras desculpas, não foi minha intenção. Eu apenas não quero que quem está começando a programar leia o tópico e seja encorajado a fazer gambiarra em todo lugar do código. Programação não É isso. Um bom programador faz um código limpo, legível e rápido, e gambiarra É justamente o contrário desses três adjetivos. Para provar que eu tambÉm faço absurdos e não estou só falando da boca pra fora, aqui está uma gambiarra que eu fiz não faz muito tempo:
    module("space", package.seeall) _T = "space" local __type__ = type function _G.type(value) if __type__(value) == "table" and value._T then return value._T end return __type__(value) end

     

    Mais como foi dito.

     

    Você "pelo que parece" e muito organizado;

    Na verdade não tenho organização nenhuma e isto e realmente um problema.

    Tanto que já perdi muita coisa por falta de organização.

     

    Depende muito do programador.

     

    [i]Tudo depende da pessoa.
    Se a pessoa gostar do que faz não há nada que impeça usar gambiarras.[/i]
    [i]Um programador acima de tudo deve gostar do que ele faz.[/i]
    

     

    O problema é que vocês não estão programando só para vocês mesmos. Principalmente se você for postar seus códigos, outras pessoas vão ler ele, e até mesmo tentar aprender programação lendo seus códigos. Se ninguém mais for ler, provavelmente outras pessoas vão querer se beneficiar do que o script oferece (jogando seu servidor que tem aquele script, por exemplo). Programação não é algo de uma pessoa só, você sempre faz para outra pessoa (E na verdade, todas as profissões são assim). Mesmo que ninguém mais vá ler seu código, você ainda precisa achar a melhor solução para o problema. Se você acha que está fazendo um script só para o seu servidor, você ainda precisa deixar ele rápido, e é ai que aquela gambiarra faz a diferença. É essa diferença que vai fazer seu servidor ser melhor que o do outro.

  4. GAMBIARRA É UMA COISA RUIM, SIM! Tirem da cabeça que fazer algo de forma absurda É bom. KISS Tem gente que prega o "POG" como coisa boa, que atÉ mesmo tenta fazer de propósito. SÉrio, vocês precisam parar com isso. De fato, existem situações onde não existe outra solução, então É um mal necessário, mas somente se você tiver certeza de que está fazendo a coisa certa, e isso leva muito tempo e conhecimento da ciência por trás do seu programa e linguagem. No geral, tente SEMPRE fazer um código simples de entender. Nada de fazer macarronada com o código. Vale a pena saber fazer? Vale. Vale a pena botar isso em prática? Não. E outra coisa: Número de linhas nunca foi indicador de qualidade de código. Um código de 100 linhas pode ser melhor ou pior que um código de 10 linhas.

     

    E como foi dito o poger e associado a quantidade de linhas.

    Mais nunca disse que a quantidade de linhas tem relação com a qualidade do script.

     

    Do mais.

    Eu não vejo as gambiarras como monstro.

     

    Desculpe, eu interpretei mal. Realmente, as "gambiarras" geralmente ocupam mais linhas do que uma solução que seria naturalmente mais simples.

     

    E quanto à ser um monstro, é o que eu falei: é um mal necessário. Se existe uma solução mais simples e limpa, por que fazer de forma absurda? Para ganhar a alcunha de "rei do pog"? Para obscurecer o código? Usando uma analogia bem ridícula: se você pode colocar o quadro na parede com um prego, por que usar durepoxy?

     

    Existem casos onde gambiarras são sim necessárias. Talvez porque não exista outra solução pro problema. Ou talvez seja um método mais rápido de executar determinada rotina. Para estes casos eu concordo com você, mas o programador tem que ter certeza absoluta de que a solução é segura, eficiente, e a melhor possível para o problema. Para isso você precisa saber com o que está lidando, conhecer muito bem suas ferramentas (bibliotecas e linguagem), e mesmo assim deixar um comentário explicando como a magia negra funciona e por que ela foi necessária. Todo mundo faz gambiarra um dia, apenas tenha certeza de que está fazendo a coisa certa, e não fazendo só por graça. O trabalho dos programadores não é apenas encontrar soluções, mas sim encontrar as melhores soluções.

     

    O motivo do meu pânico em relação ao assunto é que muitos programadores incentivam os iniciantes a fazer gambiarra como se fosse normal, e isso continua com a pessoa por muito tempo, até que ela atinja maturidade suficiente pra diferenciar uma solução boa de uma solução ruim. Me chame de egoísta se quiser, mas eu não quero mais ver novatos fazendo magia negra sem nem se dar o trabalho de procurar uma solução mais simples. São essas pessoas que fazem códigos com 9 loops aninhados e dificílimos de entender.

     

    Outra coisa: do jeito que eu falei talvez tenha parecido que eu estou depreciando seu trabalho. Se você entendeu isso, você tem minhas sinceras desculpas, não foi minha intenção. Eu apenas não quero que quem está começando a programar leia o tópico e seja encorajado a fazer gambiarra em todo lugar do código. Programação não é isso. Um bom programador faz um código limpo, legível e rápido, e gambiarra é justamente o contrário desses três adjetivos.

     

    Para provar que eu também faço absurdos e não estou só falando da boca pra fora, aqui está uma gambiarra que eu fiz não faz muito tempo:

    module("space", package.seeall)
    _T = "space"
    local __type__ = type
    function _G.type(value)
       if __type__(value) == "table" and value._T then
           return value._T
       end
       return __type__(value)
    end

  5. GAMBIARRA É UMA COISA RUIM, SIM!

    Tirem da cabeça que fazer algo de forma absurda é bom. KISS

    Tem gente que prega o "POG" como coisa boa, que até mesmo tenta fazer de propósito. Sério, vocês precisam parar com isso.

     

    De fato, existem situações onde não existe outra solução, então é um mal necessário, mas somente se você tiver certeza de que está fazendo a coisa certa, e isso leva muito tempo e conhecimento da ciência por trás do seu programa e linguagem.

     

    No geral, tente SEMPRE fazer um código simples de entender. Nada de fazer macarronada com o código. Vale a pena saber fazer? Vale. Vale a pena botar isso em prática? Não.

     

    E outra coisa: Número de linhas nunca foi indicador de qualidade de código. Um código de 100 linhas pode ser melhor ou pior que um código de 10 linhas.

  6. Eu sinceramente acho injustiça chamar um pacote com duas funções de biblioteca, mas...

     

    Isso foi uma ideia do Oneshot. Serve para rotacionar tabelas (por exemplo, se você quiser rotacionar uma área de uma magia). Eu sinceramente não vejo muita utilidade em open tibia, mas ele jura que serve para alguma coisa e me disse para postar, então aqui está:

     

    matrix.lua

    -- Copyright (c) 2013 Skyen Hasus
    --
    -- Permission is hereby granted, free of charge, to any person obtaining a copy
    -- of this software and associated documentation files (the "Software"), to deal
    -- in the Software without restriction, including without limitation the rights
    -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    -- copies of the Software, and to permit persons to whom the Software is
    -- furnished to do so, subject to the following conditions:
    --
    -- The above copyright notice and this permission notice shall be included in
    -- all copies or substantial portions of the Software.
    
    module("matrix", package.seeall)
    
    _G.DEGREES_0 = 0
    _G.DEGREES_90 = 90
    _G.DEGREES_180 = 180
    _G.DEGREES_270 = 270
    
    _G.DIRECTION_VERTICAL = 0
    _G.DIRECTION_HORIZONTAL = 1
    
    local function rotate_90(matrix)
    local ret = {}
    
    for y in ipairs(matrix) do
    	local w = #matrix[y]
    
    	for x, v in ipairs(matrix[y]) do
    		if not ret[w-x+1] then
    			ret[w-x+1] = {}
    		end
    
    		ret[w-x+1][y] = v
    	end
    end
    
    return ret
    end
    
    local function rotate_180(matrix)
    local ret = {}
    local h = #matrix
    
    for y in ipairs(matrix) do
    	local w = #matrix[y]
    
    	for x, v in ipairs(matrix[y]) do
    		if not ret[h-y+1] then
    			ret[h-y+1] = {}
    		end
    
    		ret[h-y+1][w-x+1] = v
    	end
    end
    
    return ret
    end
    
    local function rotate_270(matrix)
    local ret = {}
    local h = #matrix
    
    for y in ipairs(matrix) do
    	for x, v in ipairs(matrix[y]) do
    		if not ret[x] then
    			ret[x] = {}
    		end
    
    		ret[x][h-y+1] = v
    	end
    end
    
    return ret
    end
    
    local function mirror_v(matrix)
    local ret = {}
    local h = #matrix
    
    for y in ipairs(matrix) do
    	for x, v in ipairs(matrix[y]) do
    		if not ret[h-y+1] then
    			ret[h-y+1] = {}
    		end
    
    		ret[h-y+1][x] = v
    	end
    end
    
    return ret
    end
    
    local function mirror_h(matrix)
    local ret = {}
    
    for y in ipairs(matrix) do
    	local w = #matrix[y]
    
    	for x, v in ipairs(matrix[y]) do
    		if not ret[y] then
    			ret[y] = {}
    		end
    
    		ret[y][w-x+1] = v
    	end
    end
    
    return ret
    end
    
    function rotate(matrix, degrees)
    degrees = degrees % 360
    
    if degrees == DEGREES_0 then
    	return matrix
    elseif degrees == DEGREES_90 then
    	return rotate_90(matrix)
    elseif degrees == DEGREES_180 then
    	return rotate_180(matrix)
    elseif degrees == DEGREES_270 then
    	return rotate_270(matrix)
    end
    
    error("Invalid degree value to function 'rotate'.", 2)
    return false
    end
    
    function mirror(matrix, direction)
    if direction == DIRECTION_VERTICAL then
    	return mirror_v(matrix)
    elseif direction == DIRECTION_HORIZONTAL then
    	return mirror_h(matrix)
    end
    
    error("Invalid direction to function 'mirror'.", 2)
    return false
    end
    
    

     

    Exemplo de uso:

    require("matrix")
    
    local array = {
    {1, 1, 2},
    {0, 1, 0},
    {0, 1, 0},
    {3, 1, 4},
    }
    
    local array_vertical = matrix.mirror(array, DIRECTION_VERTICAL)
    local array_horizontal = matrix.mirror(array, DIRECTION_HORIZONTAL)
    
    local array_90 = matrix.rotate(array, DEGREES_90)
    local array_180 = matrix.rotate(array, DEGREES_180)
    local array_270 = matrix.rotate(array, DEGREES_270)
    
    local array_vertical = matrix.mirror(array, 0)
    local array_horizontal = matrix.mirror(array, 1)
    
    local array_90 = matrix.rotate(array, 90)
    local array_180 = matrix.rotate(array, 180)
    local array_270 = matrix.rotate(array, 270)
    
    

     

    Funções e parâmetros:

    (Apesar de conter sete funções, apenas duas delas são públicas e você pode usar.)

     

    matrix.rotate(matrix, degrees)

    Rotaciona uma matriz, onde matrix é a matriz a ser rotacionada e degrees é o ângulo da rotação. Apenas aceita ângulos "quadrados" (múltiplos de 90): -180, -90, 0, 90, 180, 270, 360, 450, e por ai vai... Você pode usar DEGREES_0, DEGREES_90, DEGREES_180 e DEGREES_270 também. A função retorna uma nova tabela, com a rotação aplicada.

     

    matrix.mirror(matrix, direction)

    Espelha uma matriz, onde matrix é a matriz a ser espelhada e direction é o sentido do espelhamento. Apenas aceita os valores DIRECTION_VERTICAL (0, vertical) e DIRECTION_HORIZONTAL (1, horizontal). A função retorna uma nova tabela, com o espelhamento aplicado.

     

    Você precisa dar o nome do arquivo de matrix.lua, por ser um módulo. Se for usar fora de open tibia, você precisa dar require("matrix") para importar o módulo. Se for usar no open tibia, basta jogar o matrix.lua na pasta lib.

  7. E incrível o sistema

    Você manipula a criatura de um jeito espetacular salvando a criatura com o pet:setit

    A única coisa chata seria as storages.

     

     

    Mais ta incrível

    Parabéns.

     

    Então, cara, eu até fiz enquanto na fase de desenvolvimento por querys na database. O problema é que se toda hora eu tenho que salvar o pet na database e obter dados dela, acabei notando o pequeno lag que se criava na execução dos comandos, aí fiz por storage.

     

    Obrigado a todos.

     

    Eu não li o código (muito extenso), apenas tenho uma ideia de como ele funciona, então posso estar falando uma grande besteira, mas vamos lá...

     

    Storages são armazenadas no banco de dados da mesma forma que seria se você criasse uma tabela especifica para os pets, então teoricamente (e provavelmente também na prática) o custo de salvar as informações é exatamente o mesmo. A diferença é quando salvar essas informações.

     

    Se toda vez que você alterasse a storage de um player alterasse diretamente no banco de dados, o custo seria bem mais alto. Da mesma forma aconteceria se você alterasse a tabela de pets diretamente.

     

    O motivo das storages serem mais rápidas é porque quando você altera uma storage, o banco de dados não é alterado imediatamente. A informação só é trocada na memória do servidor, de uma forma crua e rápida, e só é transmitida definitivamente ao banco de dados quando o player é salvo (quando é executado um save automático, quando o player sai do jogo, ou quando o servidor é fechado).

     

    Agora que já está tudo feito por storages, não compensa alterar só por esse detalhe, mas uma coisa interessante de se fazer seria sobrecarregar (no sentido Lua) a função de save do open tibia:

     

    __doPlayerSave__ = doPlayerSave
    function doPlayerSave(cid, shallow)
       get_pet(cid):save(shallow)
       return __doPlayerSave__(cid, shallow)
    end

     

    Uma coisa interessante seria fazer proveito do "shallow", indicando à sua função de save se ela deve salvar todas as informações ou apenas as mais cruciais (para evitar, por exemplo, clonamento de itens ou algo assim).

     

    O único problema de sobrecarregar a função Lua é que talvez ela não seja executada em todos os saves. Provavelmente quando o player sai do jogo ou o servidor desliga, uma função interna do open tibia é executada pra salvar o player, e não a função em Lua, então você teria que alterar diretamente no código fonte ou então criar um script que execute quando o player saia do jogo e quando o servidor feche, para que salvem o player.

     

    Ou então usar storages, já que o open tibia vai cuidar de tudo direitinho pra você. É, tudo isso que eu escrevi não serviu pra nada mesmo.

  8. cara ficou show essa spell mesma marcando no mapa

     

    o q eu queria saber

    é se tem como colocar pra depois de um tempo sumir as marcas do mapa

    sem vc ter q ir la remover

     

    e n sei pq essa ultimate detect life q marca no mapa

    n ta funcionando '.'

     

    Não tem como remover, porque ao menos em Lua não existe nenhuma rotina pra isso.

     

    E se a primeira funcionou, a segunda deveria estar funcionando também D:

    A única diferença entre as duas é a configuração!

  9. Eu ia falar a mesma coisa que o caotic: quando uma função retorna uma resposta parecida com "é" ou "não é", use booleanos. E deixe o nome das funções mais auto-explicativas, fica difícil adivinhar o que uma função faz quando o nome dela é "s". Dá pra deixar ela bem curtinha:

     

    function is_multiple(value, multiplier)
    return value % multiplier == 0
    end
    

     

    Eu ia dar um rep+, mas estourei a cota do dia, amanhã volto aqui.

  10. "Par" em inglês é "Even", "Ímpar" é "Odd". (-:

    Fica estranho misturar inglês com português no nome da função, "isEven" faz mais sentido.

     

    Outra coisa, não use "local" em funções que são para serem usadas em bibliotecas! Como a biblioteca vai ser usada por vários outros códigos, a função precisa ser global!

     

    E aqui vai minha versão:

    function isEven(value)
    return value % 2 == 0
    end
    
    function isOdd(value)
    return value % 2 ~= 0
    end
    
    

     

    Entendo.

    Não vejo a necessidade ser global mais enfim.

    Eu só coloquei a função em português para melhor entendimento.

     

    Se a função for usada só em um script, tudo bem ser local, mas se for uma função feita para ser usada em uma biblioteca, ela precisa ser global, ou então nada terá acesso à ela.

  11. Offtopic, mas saudades também, Haxy!

     

    estilo de programação é estilo de programação...

    meu "tab" tem 4 espaços em vez de 8, assim como também não vejo problema nenhum em fazer algo do tipo:

     

    if x <= 0 then return false end

     

    acho mais bonito uma função assim:

     

    function myFunctionName()

     

    do que:

     

    function my_function_name()

     

    mas o que eu sempre fiz foi seguir o padrão do tibia, que separa palavras usando letras maiúsculas

     

    O motivo de usar underscore é que o cérebro humano está mais acostumado a identificar espaços (muito bem representados por undescores). Para considerar a legibilidade de um código, sempre imagine-se lendo o código com sono.

     

    Imagine-se lendo as duas seguintes frases depois de 42 horas sem dormir:

     

    GitHubIsTheBestPlaceToShareCodeWithFriendsCoWorkersClassmatesAndCompleteStrangers.
    OverTwoMillionPeopleUseGitHubToBuildAmazingThingsTogether.

     

    github_is_the_best_place_to_share_code_with_friends_coworkers_classmates_and_complete_strangers.
    over_two_million_people_use_github_to_build_amazing_things_together.

     

    Mas como você disse, estilo é estilo. O importante é que seu estilo seja no mínimo legível e que você sempre siga ele, ao invés de misturar as coisas.

  12. eu adiciono no serve, mais o da chuva-eterna não funciona,não da nenhum erro mais também não funciona, poderia me ajudar ?

     

    mudei as coordenadas e nada....

    Sem erro fica muito difícil descobrir o que é. Como eu disse, esse script é antigo, é bem provável que tenha alguns bugs.

    Pode postar aqui o seu /data/globalevents/scripts/weather.lua modificado?

  13. "Par" em inglês é "Even", "Ímpar" é "Odd". (-:

    Fica estranho misturar inglês com português no nome da função, "isEven" faz mais sentido.

     

    Outra coisa, não use "local" em funções que são para serem usadas em bibliotecas! Como a biblioteca vai ser usada por vários outros códigos, a função precisa ser global!

     

    E aqui vai minha versão:

    function isEven(value)
    return value % 2 == 0
    end
    
    function isOdd(value)
    return value % 2 ~= 0
    end
    
    

  14. O raciocínio não é meu, essa é a técnica padrão pra trabalhar com conversão de data e hora, que é utilizada à muitos anos. Apenas expliquei como funciona, porque acho que todo programador vai ter esse problema um dia, e todos deveriam saber resolver de forma eficiente. (Eu já fiz conversão de data e hora com while também!)

     

    Agora pode parecer coisa besta, mas conforme você vai melhorando, começa a perceber que vários problemas teriam uma solução mais rápida, e começa a pensar na otimização do seu código. Um exemplo de experiência própria: estou fazendo uma biblioteca (que daqui uns dias vai ficar pronta e vou postar aqui), e entre uma das utilidades dela, possui uma função para gerar círculos à partir de uma posição central e o raio do círculo.

     

    A ideia inicial é pegar o raio, duplicar, e fazer dois fors percorrendo todas as posições dentro da área formada pelo dobro do raio. Para um círculo de raio 5, por exemplo, a função rodaria os loops 100 vezes ((5*2)*(5*2)). Pode não parecer, mas esse é um numero muito grande em questão de desempenho. Imagine um círculo de raio 500, seriam 1000000 iterações!! Seu servidor travaria por vários segundos (talvez até minutos), e provavelmente seria morto pelo sistema operacional por usar memória demais dependendo do que você estiver fazendo.

     

    Para quem não se importa com otimização, isso é suficiente. Mas quando você começa a se preocupar com otimização, algumas soluções bem mais fáceis e rápidas surgem em mente. Para resolver o problema acima, eu apenas espelhei um dos quadrantes do círculo. Afinal, ele é simétrico! Todos os quadrantes são iguais, apenas invertidos. Meu código ficou 4 vezes mais rápido, pois agora para um círculo de raio 5, eu percorro uma área apenas 5*5!

     

    Depois disso, pensei em uma outra otimização bem mais complexa, onde eu efetivamente só passo pelas posições que o circulo vai realmente ocupar. Ou seja, se meu círculo tem área 5, só vão ser executados 5 loops. Isso faz muita diferença, principalmente quando você possui 300 jogadores fazendo várias coisas. Cada milisegundo é importante.

  15. Skyen, você não sabe o quanto eu procurei esse script quando eu não sabia programar e ele não estava mais no outro fórum. Belo sistema parabéns por fazer códigos tão bons de ser lidos e muito funcionais, é ótimo ver você um pouco ativo no mundo dos OTS novamente. Olha uma versão que eu fiz do teu sistema:

     

    Wow! Gostei bem mais do seu! Como fez essa janelinha de seleção?

  16. Ou sabe o que ficaria legal? Se você juntasse esses seus scripts com aquele de exiva que aparece no minimap. Se conseguir fazer esse ganha outro REP+

    Ficaria assim, alem dele falar que tem os monstros e player por perto, ele ainda falaria aonde estão no mapa.

    vlws

     

    Isso é bem simples de fazer, mas vai dar muito lixo no mapa. Suponha que encontre 18 criaturas, vai adicionar 18 marcas no mapa...

    Bem, se mesmo assim quiser, aqui estão as versões modificadas:

     

    /data/spells/scripts/detect life.lua

    -- This script is part of Detect Life Spell
    -- Copyright (C) 2011 AbouTibia, Skyen Hasus
    --
    -- This program is free software: you can redistribute it and/or modify
    -- it under the terms of the GNU General Public License as published by
    -- the Free Software Foundation, either version 3 of the License, or
    -- (at your option) any later version.
    --
    -- This program is distributed in the hope that it will be useful,
    -- but WITHOUT ANY WARRANTY; without even the implied warranty of
    -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -- GNU General Public License for more details.
    --
    -- You should have received a copy of the GNU General Public License
    -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    -- Radius of floors that will be detected by the spell
    local floors = 0
    
    -- Magic effect shown on detected creatures
    local effect = CONST_ME_MAGIC_BLUE
    
    -- Message sent as a warning to detected players, false to deactivate
    local warn = "You feel like you're being watched."
    
    -- Message sent when no living creature is found nearby
    local nolife = "You detected no signs of life nearby."
    
    -- If true, the message will show in detail how many creatures of each type are in each direction.
    local detailed = false
    
    local area = {
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0},
    {0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0},
    {0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0},
    {0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0},
    {0, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 0},
    {0, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 0},
    {0, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 0},
    {7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3},
    {0, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 0},
    {0, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 0},
    {0, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 0},
    {0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0},
    {0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0},
    {0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0},
    {0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    }
    
    local keys = {
    [1] = "north",
    [2] = "northeast",
    [3] = "east",
    [4] = "southeast",
    [5] = "south",
    [6] = "southwest",
    [7] = "west",
    [8] = "northwest",
    }
    
    function is_index(t, index)
    for i, v in ipairs(t) do
    	if index == i then
    		return true
    	end
    end
    return false
    end
    
    local function get_message(life, keys)
    local msg
    local add = {}
    
    if life.total == 0 then
    	return false
    end
    
    for key, direction in ipairs(keys) do
    	local keymsg = ""
    	local keyadd = {}
    
    	if life[key].players == 1 then
    		if not msg then
    			msg = "There is "
    		end
    		table.insert(keyadd, "a player")
    	elseif life[key].players > 1 then
    		if not msg then
    			msg = "There are "
    		end
    		table.insert(keyadd, life[key].players .. " players")
    	end
    
    	if life[key].monsters == 1 then
    		if not msg then
    			msg = "There is "
    		end
    		table.insert(keyadd, "a monster")
    	elseif life[key].monsters > 1 then
    		if not msg then
    			msg = "There are "
    		end
    		table.insert(keyadd, life[key].monsters .. " monsters")
    	end
    
    	if life[key].npcs == 1 then
    		if not msg then
    			msg = "There is "
    		end
    		table.insert(keyadd, "a NPC")
    	elseif life[key].npcs > 1 then
    		if not msg then
    			msg = "There are "
    		end
    		table.insert(keyadd, life[key].npcs .. " NPCs")
    	end
    
    	for i = 1, #keyadd do
    		if i == #keyadd and #keyadd > 1 then
    			keymsg = keymsg .. " and "
    		elseif i ~= 1 then
    			keymsg = keymsg .. ", "
    		end
    		keymsg = keymsg .. keyadd[i]
    	end
    
    	if #keyadd > 0 then
    		table.insert(add, keymsg .. " by the " .. keys[key])
    	end
    end
    
    for i = 1, #add do
    	if i == #add and #add > 1 then
    		msg = msg .. " and "
    	elseif i ~= 1 then
    		msg = msg .. ", "
    	end
    	msg = msg .. add[i]
    end
    
    return msg .. "."
    end
    
    local function detect_life(cid, area, keys, pos, floors, effect, warn)
    local detected = {}
    local center = {}
    
    -- Make sure the area is large enought and has a center
    if #area < 1 or #area[1] < 1 or #area % 2 == 0 or #area[1] % 2 == 0 then
    	error("The size of the area is invalid.")
    	return false
    end
    
    center.y = math.ceil(#area / 2)
    center.x = math.ceil(#area[1] / 2)
    detected.total = 0
    
    for key, value in pairs(keys) do
    	detected[key] = {
    		players = 0,
    		monsters = 0,
    		npcs = 0,
    	}
    end
    
    for z = -floors, floors do
    	for y = 1, #area do
    		-- Make sure that the size of the area doesn't vary
    		if #area[y] ~= #area[1] then
    			error("The size of the area varies.")
    			return false
    		end
    		for x = 1, #area[y] do
    			local dpos = {}
    			local key = area[y][x]
    
    			dpos.x = pos.x - center.x + x
    			dpos.y = pos.y - center.y + y
    			dpos.z = pos.z + z
    			dpos.stackpos = STACKPOS_TOP_CREATURE
    
    			local thing = getThingFromPos(dpos, false)
    			if thing.uid ~= 0 and is_index(keys, key) and not isPlayerGhost(thing.uid) then
    				if isPlayer(thing.uid) then
    					if warn then
    						doPlayerSendTextMessage(thing.uid, MESSAGE_EVENT_ADVANCE, warn)
    					end
    					detected[key].players = detected[key].players + 1
    				elseif isMonster(thing.uid) then
    					detected[key].monsters = detected[key].monsters + 1
    				elseif isNpc(thing.uid) then
    					detected[key].npcs = detected[key].npcs + 1
    				end
    				detected.total = detected.total + 1
    				doSendMagicEffect(dpos, effect)
    				doPlayerAddMapMark(cid, dpos, MAPMARK_FLAG, getCreatureName(thing.uid))
    			end
    		end
    	end
    end
    return detected
    end
    
    function onCastSpell(cid, var)
    local pos = getThingPosition(cid)
    local life = detect_life(cid, area, keys, pos, floors, effect, warn)
    
    if not life then
    	return false
    end
    
    local message = "There " .. (life.total == 1 and "is " or "are ") .. life.total .. " creatures nearby."
    if detailed then
    	message = get_message(life, keys)
    end
    if life.total == 0 then
    	message = nolife
    end
    
    doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, message)
    
    return true
    end
    

     

    /data/spells/scripts/ultimate detect life.lua

    -- This script is part of Detect Life Spell
    -- Copyright (C) 2011 AbouTibia, Skyen Hasus
    --
    -- This program is free software: you can redistribute it and/or modify
    -- it under the terms of the GNU General Public License as published by
    -- the Free Software Foundation, either version 3 of the License, or
    -- (at your option) any later version.
    --
    -- This program is distributed in the hope that it will be useful,
    -- but WITHOUT ANY WARRANTY; without even the implied warranty of
    -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    -- GNU General Public License for more details.
    --
    -- You should have received a copy of the GNU General Public License
    -- along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
    -- Radius of floors that will be detected by the spell
    local floors = 1
    
    -- Magic effect shown on detected creatures
    local effect = CONST_ME_MAGIC_BLUE
    
    -- Message sent as a warning to detected players, false to deactivate
    local warn = false
    
    -- Message sent when no living creature is found nearby
    local nolife = "You detected no signs of life nearby."
    
    -- If true, the message will show in detail how many creatures of each type are in each direction.
    local detailed = true
    
    local area = {
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0},
    {0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0},
    {0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0},
    {0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0},
    {0, 0, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 0, 0},
    {0, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 0},
    {0, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 0},
    {0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 5, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 5, 5, 5, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3},
    {0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0},
    {0, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 0},
    {0, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 0},
    {0, 0, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 0, 0},
    {0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0},
    {0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0},
    {0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0},
    {0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    }
    
    local keys = {
    [1] = "north",
    [2] = "northeast",
    [3] = "east",
    [4] = "southeast",
    [5] = "south",
    [6] = "southwest",
    [7] = "west",
    [8] = "northwest",
    }
    
    function is_index(t, index)
    for i, v in ipairs(t) do
    	if index == i then
    		return true
    	end
    end
    return false
    end
    
    local function get_message(life, keys)
    local msg
    local add = {}
    
    if life.total == 0 then
    	return false
    end
    
    for key, direction in ipairs(keys) do
    	local keymsg = ""
    	local keyadd = {}
    
    	if life[key].players == 1 then
    		if not msg then
    			msg = "There is "
    		end
    		table.insert(keyadd, "a player")
    	elseif life[key].players > 1 then
    		if not msg then
    			msg = "There are "
    		end
    		table.insert(keyadd, life[key].players .. " players")
    	end
    
    	if life[key].monsters == 1 then
    		if not msg then
    			msg = "There is "
    		end
    		table.insert(keyadd, "a monster")
    	elseif life[key].monsters > 1 then
    		if not msg then
    			msg = "There are "
    		end
    		table.insert(keyadd, life[key].monsters .. " monsters")
    	end
    
    	if life[key].npcs == 1 then
    		if not msg then
    			msg = "There is "
    		end
    		table.insert(keyadd, "a NPC")
    	elseif life[key].npcs > 1 then
    		if not msg then
    			msg = "There are "
    		end
    		table.insert(keyadd, life[key].npcs .. " NPCs")
    	end
    
    	for i = 1, #keyadd do
    		if i == #keyadd and #keyadd > 1 then
    			keymsg = keymsg .. " and "
    		elseif i ~= 1 then
    			keymsg = keymsg .. ", "
    		end
    		keymsg = keymsg .. keyadd[i]
    	end
    
    	if #keyadd > 0 then
    		table.insert(add, keymsg .. " by the " .. keys[key])
    	end
    end
    
    for i = 1, #add do
    	if i == #add and #add > 1 then
    		msg = msg .. " and "
    	elseif i ~= 1 then
    		msg = msg .. ", "
    	end
    	msg = msg .. add[i]
    end
    
    return msg .. "."
    end
    
    local function detect_life(area, keys, pos, floors, effect, warn)
    local detected = {}
    local center = {}
    
    -- Make sure the area is large enought and has a center
    if #area < 1 or #area[1] < 1 or #area % 2 == 0 or #area[1] % 2 == 0 then
    	error("The size of the area is invalid.")
    	return false
    end
    
    center.y = math.ceil(#area / 2)
    center.x = math.ceil(#area[1] / 2)
    detected.total = 0
    
    for key, value in pairs(keys) do
    	detected[key] = {
    		players = 0,
    		monsters = 0,
    		npcs = 0,
    	}
    end
    
    for z = -floors, floors do
    	for y = 1, #area do
    		-- Make sure that the size of the area doesn't vary
    		if #area[y] ~= #area[1] then
    			error("The size of the area varies.")
    			return false
    		end
    		for x = 1, #area[y] do
    			local dpos = {}
    			local key = area[y][x]
    
    			dpos.x = pos.x - center.x + x
    			dpos.y = pos.y - center.y + y
    			dpos.z = pos.z + z
    			dpos.stackpos = STACKPOS_TOP_CREATURE
    
    			local thing = getThingFromPos(dpos, false)
    			if thing.uid ~= 0 and is_index(keys, key) then
    				if isPlayer(thing.uid) then
    					if warn then
    						doPlayerSendTextMessage(thing.uid, MESSAGE_STATUS_DEFAULT, warn)
    					end
    					detected[key].players = detected[key].players + 1
    				elseif isMonster(thing.uid) then
    					detected[key].monsters = detected[key].monsters + 1
    				elseif isNpc(thing.uid) then
    					detected[key].npcs = detected[key].npcs + 1
    				end
    				detected.total = detected.total + 1
    				doSendMagicEffect(dpos, effect)
    				doPlayerAddMapMark(cid, dpos, MAPMARK_FLAG, getCreatureName(thing.uid))
    			end
    		end
    	end
    end
    return detected
    end
    
    function onCastSpell(cid, var)
    local pos = getThingPosition(cid)
    local life = detect_life(cid, area, keys, pos, floors, effect, warn)
    
    if not life then
    	return false
    end
    
    local message = "There " .. (life.total == 1 and "is " or "are ") .. life.total .. " creatures nearby."
    if detailed then
    	message = get_message(life, keys)
    end
    if life.total == 0 then
    	message = nolife
    end
    
    doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, message)
    
    return true
    end
    

     

    ;)

  17. FYI, essa função é custosa (demora mais que o método ideal pra ser executada, ou seja, é lenta) por causa dos whiles. Imagine o seu exemplo com o os.time(). Só para calcular os anos, o while rodou 43 vezes.

     

    Existe um método melhor para converter esse tipo de dados, usando módulo (em Lua, é o operador %). O módulo retorna o resto de uma divisão, ou seja:

    8 % 3 => 2

    Significa que 8 dividido por 3 resta 2.

     

    Usando isso, podemos converter um número de segundos em minutos, horas, ou o que for, usando uma operação matemática, que pode ser executada "instantaneamente".

     

    Supondo que temos 100 segundos, que equivalem à 1 minuto e 40 segundos. Se dividirmos 100 por 60, obteremos 1.666... A parte fracionária desse número (0.666...) equivale aos outros 40 segundos. Se pegarmos somente e parte inteira (1), já temos o número de minutos! Mas agora precisamos ajustar o número de segundos que sobraram. Para isso, usamos o módulo para pegar o resto da divisão. Se pegarmos o resto da divisão de 100 por 60, dá 40. Com isso, podemos fazer o código que pega o número de minutos do os.time(), por exemplo.

    local seconds = os.time()
    
    local minutes = math.floor(seconds / 60) -- Pega o número de minutos em "seconds"
    seconds = seconds % 60 -- Ajusta os segundos que sobraram

     

    Para pegar o número de horas em tantos minutos, dias em tantas horas, meses em tantos dias, anos em tantos meses e et cetera, a ideia é exatamente a mesma.

    local seconds = os.time()
    local minutes, hours, days, months, years
    
    minutes = math.floor(seconds / 60)
    seconds = seconds % 60
    
    hours = math.floor(minutes / 60)
    minutes = minutes % 60
    
    days = math.floor(hours / 24)
    hours = hours % 24
    
    months = math.floor(days / 30)
    days = days % 30
    
    years = math.floor(months / 12)
    months = months % 12

     

    Edit: Só por curiosidade, o os.time() retorna o tempo do sistema, que geralmente é medido em número de segundos decorridos desde o "epoch" (no tempo POSIX). Ou seja, o número de segundos desde 1 de Janeiro de 1970. Por isso dá 43 anos. Estamos em 2013: 2013-1970=43!

     

    ;)

  18. Dizem que se você perguntar à 5 programadores qual seu editor favorito, você vai ouvir 7 respostas diferentes. Aos que estão se perguntando qual editor usar:

     

    De cara vou dizer qual eu uso, meu favorito: gedit.

    Ele é pra Linux, porém funciona no Windows também (mas acho que o modo de tratamento de abas dele no Windows é meio ruinzinho) e no Mac. É de longe o melhor editor que eu já usei. Ele possui suporte à plugins, o que torna ele melhor ainda (Se não me engano tem inclusive um plugin auto-completador, igual ao do OTScriptLive!, pra mostrar as funções). A única desvantagem que eu vejo nele é que ele não possui block folding, um recurso que te permite esconder blocos de código (igual no SciTE), mas já estão implementando isso na nova versão e não é algo realmente necessário.

     

    Mas claro, se você não vai com a cara do gedit, existem outras opções (Em minha ordem pessoal de preferência):

    • gedit
      Meu favorito. Editor padrão do GNOME e seus derivados. Para Linux, mas funciona em Windows e Mac.
    • SciTE
      Recomendo para quem está começando a aprender Lua, inclusive Lua não relacionado com Open Tibia. Funciona em Linux e Windows.
    • Sublime Text 2
      Segundo melhor editor que eu já vi. Realmente muito bom. Funciona em Linux, Windows e Mac.
    • Notepad++
      É um ótimo editor, mas não vou muito com a cara dele. Questão de gosto, use se preferir. Somente para Windows.
    • Vim
      Outro editor muito bom, mas não recomendo para iniciantes, é uma ferramenta muito complexa. Para Linux, mas funciona em Windows e Mac.
    • Emacs
      Mesma coisa que eu acho do Vim. Muito bom, mas muito complexo para iniciantes. Para Linux, mas funciona em Windows e Mac.
    • OTScriptLive!
      Não recomendo. Possui muitos bugs, e a única real vantagem é o seu auto-completador. Somente para Windows.
    • Kate
      Já usei algumas vezes, mas não gostei muito. é o editor padrão do KDE. é para Linux, mas não sei se funciona em Windows também.
    • Komodo Edit
      Já usei uma vez, mas também não gostei. Funciona em Linux, Windows e Mac.

     

    Se você está acessando uma máquina externa com Linux por SSH, recomendo usar "vi".

     

    Se quer hospedar seu código na web, recomendo o site http://pastebin.com/.

     

    Se estiver querendo editar código em grupo, recomendo o site http://sync.in/. A desvantagem dele é não possuir syntax highlight nem um compilador/interpretador embutido.

     

    Se estiver querendo editar e rodar um código pela web, recomendo o site http://ideone.com/.

     

    Se quiser descobrir outros editores de código bons, use o site http://alternativeto.net/. Esse site é um dos mais maravilhosos que existem. Você busca um programa que faça algo e ele mostra alternativas. Vamos supor que você esteja cansado de usar SciTE, por exemplo. Você busca por "SciTE" na barra de busca, e ele exibe programas que fazem a mesma coisa que o SciTE, mostrando em quais sistemas operacionais cada um funciona, quantas pessoas gostaram daquele programa, e et cetera. Você também pode filtrar os resultados para mostrar somente os programas que funcionam no seu sistema operacional, então também é muito bom para achar alternativas de software para Linux dos programas para Windows que não rodam em Linux.

     

    Se você precisa de um repositório para armazenar seus códigos com controle de versão, recomendo o https://github.com/. Na minha opinião, a ferramenta git é bem mais simples do que a Subversion, e possui bem menos bugs. Se você preferir Subversion, recomendo o http://code.google.com/.

     

    Acho que vale a pena você testar vários editores de código e ficar com aquele que você gosta mais. O que vale é a sua preferência pessoal.

     

    Fiquem com essa tirinha do xkcd.

    real_programmers.png

  • Quem Está Navegando   0 membros estão online

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