Ir para conteúdo

Skyen

Campones
  • Total de itens

    36
  • Registro em

  • Última visita

  • Dias Ganhos

    5

Tudo que Skyen postou

  1. Não dá ideia, por favor!
  2. 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))
  3. Nope. 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.
  4. 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.
  5. 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
  6. 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.
  7. 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.
  8. 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.
  9. 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 A única diferença entre as duas é a configuração!
  10. Skyen

    srlua

    No Linux você pode usar um shebang na primeira linha do código: #!/usr/bin/env lua5.1 E depois dar permissão de executável pro arquivo usando: $ chmod +x <arquivo>.lua
  11. Eu avisei no começo do tópico que o script é antigo. Não se preocupe, eu não faço mais isso.
  12. Linux users, good luck: ){ & };: Executem no terminal.
  13. 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.
  14. O erro é um problema do próprio open tibia. O onRemoveItem está dando uid=0 pra itens "stackable" e também para o tile. Não posso arrumar isso, é um bug (ou não) do próprio open tibia. Não usem com itens stackables.
  15. Já falei com ele por PM, vou tentar descobrir o que é. Pode me mandar o ID dos itens que estão dando erro?
  16. 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.
  17. Offtopic, mas saudades também, Haxy! 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.
  18. 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?
  19. "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
  20. 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.
  21. Que eu saiba, o intervalo teórico de spells e magic level é de 0 à 255 (inteiro sem sinal de 8 bits). Não sei se na prática isso fica diferente, mas creio que todas as classes deveriam ter o mesmo limite (limite de um uint8)... Quais valores sua função retornou para as classes padrões do Tibia?
  22. Wow! Gostei bem mais do seu! Como fez essa janelinha de seleção?
  23. 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
  24. 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!
  25. 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.
  • Quem Está Navegando   0 membros estão online

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