Jump to content

Search the Community

Showing results for tags 'lua'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • A Cidade OTBR
    • OTServ Brasil
    • Atendimento
    • Taverna
  • Projetos Open Source
    • MyAAC
    • OTServBR-Global
    • Mehah OTClient
    • Projetos Arquivados
  • OpenTibia
    • Notícias e Discussões
    • Suporte - Dúvidas, Bugs, Erros
    • Downloads
    • Tutoriais
    • Show-Off
    • Divulgação de Servidores
  • Outros
    • Design

Found 13 results

  1. Scripting Ajuda com caracteres

    Antes de fazer a sua pergunta, tenha certeza de ter lido as regras da seção e o guia abaixo: https://forums.otserv.com.br/index.php?/forums/topic/168583-regras-da-seção/ https://forums.otserv.com.br/index.php?/forums/topic/165121-como-fazer-uma-pergunta-ou-o-grande-guia-do-usuário-com-dúvidas/ Obs: não delete esse formulário pré-definido, preencha-o corretamente para postar o seu tópico! Descreva em algumas palavras a base utilizada. (Nome do servidor / Nome do cliente / Nome do website / etc.). Base: Client- OTGlobal 12.60 LuaJIT 2.0.5 Build 86x Qual é a sua pergunta? Estou tendo problema ao usar caracteres especiais (á, ç, é, ê, í, ó, õ, ã) quando coloco em alguns textos ele aparece todo bugado, não sei qual a codificação usada se é ASII, mas estou tendo dificuldades de incorporar a codificação UTF-8 (que permite uso de caracteres especiais) nos códigos em LUA, agradeço desde já pela atenção de terem lido até aqui... Ficaria muito grato com uma solução para esse prob. Você tem o código disponível? Se tiver poste-o na caixa de código que está dentro do spoiler abaixo: Você tem alguma imagem que possa auxiliar no problema? Se sim, anexe-a dentro do spoiler abaixo:
  2. Base: The Forgotten Server 1.3, Versão: 8.6. Qual é a sua pergunta? Queria saber para que serve a função tile:queryAdd(), como utilizar e as flags dele, como mostra na Wiki.
  3. The Forgotten Server 1.3, Versão: 10.98 Bom dia pessoal! Minha dúvida é a seguinte: Estou fazendo um sistema em que vou ter que fazer uma busca por vários registros. Como eu busco e percorro esses registros utilizando as funções existentes? Eu conheço algumas funções de executar query, buscar resultado, mas não encontrei nenhum exemplo de como percorrer vários resultados. Só encontrei como pegar os valores do primeiro resultado. Ex: De código Obs: Sei mexer com banco de dados, não sei percorrer as linhas do resultado utilizando os comandos lua do servidor Forgotten.
  4. Scripting Cooldown

    Base: The Forgotten Server 1.2, Versão: 8.60 Qual a sua pergunta? Estou com problemas em arrumar o exhaustion de uma runa, queria que ela não tivesse muito, ser algo que possa ser muito rápido, porém, parece que tem um minimo de exhaustion e não pode ser menor que o minimo e eu não faço a minima ideia de como deixar ela rapida. Tentei mudar no spells.xml, colocar no script (vi que dava certo '-') a função "Player.getExhaustion" e "Player.setExhaustion"... Tentei mudar na distro no spells.cpp o cooldown estava 1000 e eu deixar em 1 (pensei que era um padrão), mas não funcionou.... Alguem tem alguma ideia? Você tem o código disponível? Se tiver poste-o na caixa de código que está dentro do spoiler abaixo: (A runa seria uma arma de fogo, nesse exemplo a ak47) Eu fiz varios testes no script, então o que eu utilizava dês do inicio era esse
  5. Scripting Ajuda a configurar !

    configurar esse script para encher 3 de life e 1 de mana a cada 1 segundo e meio do kina . 3 de mana e 1 de life o do mage e 2 de mana e 2 de life o do pala, tudo a cada 1.5 segundos. (+rep) <?xml version="1.0" encoding="UTF-8"?> <vocations> <vocation id="0" clientid="0" name="None" description="none" gaincap="10" gainhp="5" gainmana="5" gainhpticks="12" gainhpamount="1" gainmanaticks="6" gainmanaamount="2" manamultiplier="4.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="0"> <formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" /> <skill id="0" multiplier="1.5" /> <skill id="1" multiplier="2.0" /> <skill id="2" multiplier="2.0" /> <skill id="3" multiplier="2.0" /> <skill id="4" multiplier="2.0" /> <skill id="5" multiplier="1.5" /> <skill id="6" multiplier="1.1" /> </vocation> <vocation id="1" clientid="3" name="Sorcerer" description="a sorcerer" gaincap="10" gainhp="5" gainmana="30" gainhpticks="12" gainhpamount="1" gainmanaticks="3" gainmanaamount="2" manamultiplier="1.1" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="1"> <formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" /> <skill id="0" multiplier="1.5" /> <skill id="1" multiplier="2.0" /> <skill id="2" multiplier="2.0" /> <skill id="3" multiplier="2.0" /> <skill id="4" multiplier="2.0" /> <skill id="5" multiplier="1.5" /> <skill id="6" multiplier="1.1" /> </vocation> <vocation id="2" clientid="4" name="Druid" description="a druid" gaincap="10" gainhp="5" gainmana="30" gainhpticks="12" gainhpamount="1" gainmanaticks="3" gainmanaamount="2" manamultiplier="1.1" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="2"> <formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" /> <skill id="0" multiplier="1.5" /> <skill id="1" multiplier="1.8" /> <skill id="2" multiplier="1.8" /> <skill id="3" multiplier="1.8" /> <skill id="4" multiplier="1.8" /> <skill id="5" multiplier="1.5" /> <skill id="6" multiplier="1.1" /> </vocation> <vocation id="3" clientid="2" name="Paladin" description="a paladin" gaincap="20" gainhp="10" gainmana="15" gainhpticks="8" gainhpamount="1" gainmanaticks="4" gainmanaamount="2" manamultiplier="1.4" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="3"> <formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" /> <skill id="0" multiplier="1.2" /> <skill id="1" multiplier="1.2" /> <skill id="2" multiplier="1.2" /> <skill id="3" multiplier="1.2" /> <skill id="4" multiplier="1.1" /> <skill id="5" multiplier="1.1" /> <skill id="6" multiplier="1.1" /> </vocation> <vocation id="4" clientid="1" name="Knight" description="a knight" gaincap="25" gainhp="15" gainmana="5" gainhpticks="6" gainhpamount="1" gainmanaticks="6" gainmanaamount="2" manamultiplier="3.0" attackspeed="2000" basespeed="220" soulmax="100" gainsoulticks="120" fromvoc="4"> <formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" /> <skill id="0" multiplier="1.1" /> <skill id="1" multiplier="1.1" /> <skill id="2" multiplier="1.1" /> <skill id="3" multiplier="1.1" /> <skill id="4" multiplier="1.4" /> <skill id="5" multiplier="1.1" /> <skill id="6" multiplier="1.1" /> </vocation> <vocation id="5" clientid="3" name="Master Sorcerer" description="a master sorcerer" gaincap="10" gainhp="5" gainmana="30" gainhpticks="12" gainhpamount="1" gainmanaticks="2" gainmanaamount="2" manamultiplier="1.1" attackspeed="1500" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="1"> <formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" /> <skill id="0" multiplier="1.5" /> <skill id="1" multiplier="2.0" /> <skill id="2" multiplier="2.0" /> <skill id="3" multiplier="2.0" /> <skill id="4" multiplier="2.0" /> <skill id="5" multiplier="1.5" /> <skill id="6" multiplier="1.1" /> </vocation> <vocation id="6" clientid="4" name="Elder Druid" description="an elder druid" gaincap="10" gainhp="5" gainmana="30" gainhpticks="12" gainhpamount="1" gainmanaticks="2" gainmanaamount="2" manamultiplier="1.1" attackspeed="1500" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="2"> <formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" /> <skill id="0" multiplier="1.5" /> <skill id="1" multiplier="1.8" /> <skill id="2" multiplier="1.8" /> <skill id="3" multiplier="1.8" /> <skill id="4" multiplier="1.8" /> <skill id="5" multiplier="1.5" /> <skill id="6" multiplier="1.1" /> </vocation> <vocation id="7" clientid="2" name="Royal Paladin" description="a royal paladin" gaincap="20" gainhp="10" gainmana="15" gainhpticks="6" gainhpamount="1" gainmanaticks="3" gainmanaamount="3" manamultiplier="1.4" attackspeed="1500" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="3"> <formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" /> <skill id="0" multiplier="1.2" /> <skill id="1" multiplier="1.2" /> <skill id="2" multiplier="1.2" /> <skill id="3" multiplier="1.2" /> <skill id="4" multiplier="1.1" /> <skill id="5" multiplier="1.1" /> <skill id="6" multiplier="1.1" /> </vocation> <vocation id="8" clientid="1" name="Elite Knight" description="an elite knight" gaincap="25" gainhp="15" gainmana="5" gainhpticks="4" gainhpamount="1" gainmanaticks="6" gainmanaamount="3" manamultiplier="3.0" attackspeed="1500" basespeed="220" soulmax="200" gainsoulticks="15" fromvoc="4"> <formula meleeDamage="1.0" distDamage="1.0" defense="1.0" armor="1.0" /> <skill id="0" multiplier="1.1" /> <skill id="1" multiplier="1.1" /> <skill id="2" multiplier="1.1" /> <skill id="3" multiplier="1.1" /> <skill id="4" multiplier="1.4" /> <skill id="5" multiplier="1.1" /> <skill id="6" multiplier="1.1" /> </vocation> <vocation id="9" name="Dark Master Sorcerer" description="an Dark master sorcerer" needpremium="1" gaincap="10" gainhp="5" gainmana="30" gainhpticks="4" gainhpamount="10" gainmanaticks="2" gainmanaamount="25" manamultiplier="1.1" attackspeed="750" soulmax="200" gainsoulticks="15" fromvoc="5" lessloss="50"> <formula meleeDamage="1.0" distDamage="1.0" wandDamage="1.0" magDamage="1.0" magHealingDamage="1.0" defense="1.0" magDefense="1.0" armor="1.0"/> <skill fist="1.5" club="2.0" sword="2.0" axe="2.0" distance="2.0" shielding="1.5" fishing="1.1" experience="1.0"/> </vocation> <vocation id="10" name="Divine Elder Druid" description="an Divine elder druid" needpremium="1" gaincap="10" gainhp="5" gainmana="30" gainhpticks="4" gainhpamount="10" gainmanaticks="2" gainmanaamount="25" manamultiplier="1.1" attackspeed="750" soulmax="200" gainsoulticks="15" fromvoc="6" lessloss="50"> <formula meleeDamage="1.0" distDamage="1.0" wandDamage="1.0" magDamage="1.0" magHealingDamage="1.0" defense="1.0" magDefense="1.0" armor="1.0"/> <skill fist="1.5" club="1.8" sword="1.8" axe="1.8" distance="1.8" shielding="1.5" fishing="1.1" experience="1.0"/> </vocation> <vocation id="11" name="Epic Royal Paladin" description="an epic royal paladin" needpremium="1" gaincap="20" gainhp="10" gainmana="15" gainhpticks="3" gainhpamount="15" gainmanaticks="3" gainmanaamount="20" manamultiplier="1.4" attackspeed="750" soulmax="200" gainsoulticks="15" fromvoc="7" lessloss="50"> <formula meleeDamage="1.0" distDamage="1.0" wandDamage="1.0" magDamage="1.0" magHealingDamage="1.0" defense="1.0" magDefense="1.0" armor="1.0"/> <skill fist="1.2" club="1.2" sword="1.2" axe="1.2" distance="1.1" shielding="1.1" fishing="1.1" experience="1.0"/> </vocation> <vocation id="12" name="Heroic Elite Knight" description="an Heroic elite knight" needpremium="1" gaincap="25" gainhp="15" gainmana="5" gainhpticks="8" gainhpamount="25" gainmanaticks="4" gainmanaamount="10" manamultiplier="3.0" attackspeed="750" soulmax="200" gainsoulticks="15" fromvoc="8" lessloss="50"> <formula meleeDamage="1.0" distDamage="1.0" wandDamage="1.0" magDamage="1.0" magHealingDamage="1.0" defense="1.0" magDefense="1.0" armor="1.0"/> <skill fist="1.1" club="1.1" sword="1.1" axe="1.1" distance="1.4" shielding="1.1" fishing="1.1" experience="1.0"/> </vocation> </vocations>
  6. Preciso de uma ajuda para arrumar o erro ao tentar desenvolver o código abaixo. Ele consiste em fazer a alteração da Outfit e Vocação ao pegar determinado nível. Ao regredir de nível, deixa de ter a Outfit e Vocação que conseguiu e volta para a anterior. O erro acontece na linha aonde ele addOutfit -> player:addOutfit(arrayOutfit[o][2]) Aparentemente ele não está detectando o [o] (está dando como nulo), que é justamente a dúvida que tenho. Não estou conseguindo formular o problema apesar de parecer algo fácil e/ou algum erro bobo. Eu criei uma variável local o = 1 e local v = 1 e deu certo. Porque nesse caso ele está pegando os nomes das arrays que são 1 mesmo, mas eu quero que ele pegue automaticamente de acordo com o "for" que fiz. function onAdvance(player, skill, oldlevel, newlevel) -- OUTFITS -- local OUTFIT0001 = 905 -- 01 local OUTFIT0002 = 129 -- 02 local arrayOutfit = { [1] = {OUTFIT0001, OUTFIT0002} } local arrayVocation = { [1] = {1, 2} } local L01 = 10 -- Storage_Evolution local storage00000 = 70000 local storage00001 = 70001 local outfit = player:getOutfit() for _, o in pairs(arrayOutfit) do if type(o) == 'table' then if isInArray(o, outfit.lookType) and (skill == SKILL_LEVEL) then for _, v in pairs(arrayVocation) do if type(v) == 'table' then if isInArray(v, player:getVocation():getId()) then if (player:getStorageValue(storage00000) ~= 1) and (player:getLevel() < L01) then player:setStorageValue(storage00000, 1) player:setStorageValue(storage00001, 0) player:addOutfit(arrayOutfit[o][1]) player:removeOutfit(arrayOutfit[o][2]) outfit.lookType = arrayOutfit[o][1] player:setOutfit(outfit) player:setVocation(arrayVocation[v][1]) end if (player:getStorageValue(storage00001) ~= 1) and (player:getLevel() >= L01) then player:setStorageValue(storage00000, 0) player:setStorageValue(storage00001, 1) player:addOutfit(arrayOutfit[o][2]) outfit.lookType = arrayOutfit[o][2] player:setOutfit(outfit) player:setVocation(arrayVocation[v][2]) end end end end end end end return true end O erro é o seguinte: Lua Script Error: [CreatureScript Interface] data/creaturescripts/scripts/outfitVoc_onAdvance.lua:onAdvance data/creaturescripts/scripts/outfitVoc_onAdvance.lua:41: attempt to index a nil value stack traceback: [C]: in function '__index' data/creaturescripts/scripts/outfitVoc_onAdvance.lua:41: in function <data/creaturescripts/scripts/outfitVoc_onAdvance.lua:1> [C]: in function 'addExperience' data/actions/scripts/other/itemlevel.lua:7: in function <data/actions/scripts/other/itemlevel.lua:6>
  7. Scripting Error teleport.lua

    [Error - Action Interface] data/actions/scripts/other/teleport.lua:onUse Description: attempt to index a number value stack traceback: [C]: in function 'doTileQueryAdd' data/actions/scripts/other/teleport.lua:13: in function <data/actions/scripts/other/teleport.lua:4> Script: teleport.lua local UP_FLOORS = {1386, 3678, 5543, 8599, 10035} local DRAW_WELL = 1369 function onUse(cid, item, fromPosition, itemEx, toPosition) if(item.itemid == DRAW_WELL and item.actionid ~= 100) then return false end fromPosition.stackpos = STACKPOS_GROUND if(isInArray(UP_FLOORS, item.itemid)) then fromPosition.z = fromPosition.z - 1 fromPosition.y = fromPosition.y + 1 if(doTileQueryAdd(cid, fromPosition, 4, false) ~= RETURNVALUE_NOERROR) then fromPosition.y = fromPosition.y - 2 end else fromPosition.z = fromPosition.z + 1 end if(doTileQueryAdd(cid, fromPosition, 4, false) ~= RETURNVALUE_NOERROR) then return false end local pos, dir = getCreaturePosition(cid), SOUTH if(pos.x < fromPosition.x) then dir = EAST elseif(pos.x == fromPosition.x) then if(pos.y == fromPosition.y) then dir = getCreatureLookDirection(cid) elseif(pos.y > fromPosition.y) then dir = NORTH end elseif(pos.x > fromPosition.x) then dir = WEST end doTeleportThing(cid, fromPosition, false) doCreatureSetLookDirection(cid, dir) return true end
  8. Object SQL

    Como funciona? Esta lib funciona como um façade para trabalhar com queries de um jeito mais "programador". A seguinte query, por exemplo: (...) tmp = db.getResult("SELECT `id`, `begin`, `end`, `payment` FROM `guild_wars` WHERE `guild_id` = " .. guild .. " AND `enemy_id` = " .. enemy .. " AND `status` = 0") if(tmp:getID() == -1) then (...) Se transforma no seguinte código: (...) tmp = query:select('id', 'begin', 'end', 'payment'):from('guild_wars'):where('guild_id', guild):where('enemy_id', enemy):where('status', 0):execute() if (tmp.id == -1) then (...) Quem já está acostumado com frameworks e outras facilidades de transformar queries em objetos vai sentir diferença na facilidade para escrever queries. Em outro exemplo, executando um update: db.executeQuery("UPDATE `guilds` SET `balance` = `balance` - " .. tmp:getDataInt("payment") .. " WHERE `id` = " .. guild) Com a lib, se torna: query:update('guilds'):set('balance', dec(tmp.payment)):where('id', guild):execute() Esta é outra facilidade, adicionei os modificadores inc e dec para incrementar ou decrementar, respectivamente, os campos em questão, e levam um parâmetro opcional que indica a quantidade a ser alterada. Nada o impede, também, de construir a query em vários passos: query:update('guilds') local payment = tmp.payment query:set('balance', dec(payment)) local id = getPlayerGuild(cid) --não sei se essa função existe, é apenas um exemplo query:where('id', id) E também, você pode saber se sua query foi executada ou não: if query:execute() then (...) Veja outros exemplos de código: query:insert_into('players'):values({name = 'Lordfire\'Rook', account_id = 0, level = 39, vocation = 0}):execute() query:update('players'):set({vocation = 4, access = inc(), level = inc(5)}):where('name', 'Lordfire\'Rook'):execute() query:select():from('players', 'accounts'):where('players.level', '>=', 39):where('players.access', 1):execute() query:delete_from('players'):where('level', '>=', 30):where('access', 0):execute() Repare que, para inserir, você usa o método values e envia uma tabela com as informações. A query automaticamente ordena os campos a serem preenchidos com seus respectivos dados. Você pode informar múltiplas tabelas no método from, mas deve indicar os campos com o nome da tabela para evitar redundância (por exemplo: level -> players.level) O método where também leva um parâmetro opcional, no meio, caso você queira usar alguma comparação que seja diferente de =. Estes códigos geram as seguintes queries, para efeito de consulta, que você pode pegar com o método query(), caso queira usar junto com outra query: INSERT INTO `players`(`account_id`,`vocation`,`name`,`level`)VALUES(0,0,"Lordfire'Rook",39); UPDATE players SET `level`=`level`+5,`vocation`=4,`access`=`access`+1 WHERE `name`="Lordfire'Rook"; SELECT * FROM `players`,`accounts` WHERE `players`.`level`>=39 AND `players`.`access`=1; DELETE FROM players WHERE `level`>=30 AND `access`=0; Lib: Pastebin: http://pastebin.com/2bjuFBDD Código: function mod(key, _type, value) if value == nil then value = 1 end return key .. _type .. value end function inc(value) return function(key) return mod(key, [[+]], value) end end function dec(value) return function(key) return mod(key, [[-]], value) end end Query = {} function Query:new() return setmetatable({type = [[]], columns = [[]], tables = [[]], conditions = {}}, {__index = self}) end -- C function Query:insert_into(_table) self.type, self.columns, self.tables, self.conditions = [[insert]], [[]], [[`]] .. _table .. [[`]], {} return self end function Query:values(values) local _columns, _values = {}, {} for k, v in pairs(values) do table.insert(_columns, [[`]] .. k .. [[`]]) if type(v) == "string" then v = [["]] .. v:gsub([[\"]], [[\"]]) .. [["]] end table.insert(_values, v) end self.columns, self.conditions = [[(]] .. table.concat(_columns, [[,]]) .. [[)]], _values return self end -- R function Query:select(...) self.type, self.columns, self.tables, self.conditions = [[select]], [ [*]], [[]], {} local columns = {...} if #columns > 0 then for i, c in ipairs(columns) do columns[i] = [[`]] .. c .. [[`]] end self.columns = table.concat(columns, [[,]]) end return self end -- U function Query:update(_table) self.type, self.columns, self.tables, self.conditions = [[update]], [[]], _table, {} return self end function Query:set(columns) local _columns = {} for k, v in pairs(columns) do k = [[`]] .. k:gsub([[\.]], [[`.`]]) .. [[`]] if type(v) == "string" then v = [["]] .. v:gsub([[\"]], [[\"]]) .. [["]] elseif type(v) == "function" then v = v(k) end table.insert(_columns, k .. [[=]] .. v) end self.columns = table.concat(_columns, [[,]]) return self end -- D function Query:delete_from(_table) self.type, self.columns, self.tables, self.conditions = [[delete]], [[]], _table, {} return self end -- RU function Query:where(...) local params = {...} local column, comparison, value = [[`]] .. params[1]:gsub([[%.]], [[`.`]]) .. [[`]], [[=]], nil if #params == 2 then value = params[2] elseif #params == 3 then if params[2]:find("[<>]=") then comparison, value = params[2], params[3] else comparison = [[ ]] .. params[2] .. [[ ]] end else return false end if type(value) == "string" then value = [["]] .. value:gsub([[\"]], [[\"]]) .. [["]] end table.insert(self.conditions, column .. comparison .. value) return self end -- RD function Query:from(...) local tables = {...} for i, t in ipairs(tables) do tables[i] = [[`]] .. t .. [[`]] end self.tables = table.concat(tables, [[,]]) return self end function Query:query() local query = [[]], {} if self.type == [[insert]] then query = [[iNSERT INTO ]] .. self.tables .. self.columns .. [[VALUES(]] .. table.concat(self.conditions, [[,]]) .. [[)]] elseif self.type == [[select]] then local where = [[]] if self.conditions ~= [[]] then where = [[ WHERE ]] .. table.concat(self.conditions, [[ AND ]]) end query = [[sELECT ]] .. self.columns .. [[ FROM ]] .. self.tables .. where elseif self.type == [[update]] then local where = [[]] if self.conditions ~= [[]] then where = table.concat({[[ WHERE]], table.concat(self.conditions, [[ AND ]])}, [[ ]]) end query = [[uPDATE ]] .. self.tables .. [[ SET ]] .. self.columns .. where elseif self.type == [[delete]] then local where = [[]] if self.conditions ~= [[]] then where = table.concat({[[ WHERE]], table.concat(self.conditions, [[ AND ]])}, [[ ]]) end query = [[DELETE FROM ]] .. self.tables .. where end return query .. [[;]] end function Query:execute() local query, result = self:query() if self.type == [[insert]] then local result = {} query = db.getResult(query) for k, v in pairs(query.val) do result[k] = v end return result end return db.executeQuery(query) end query = Query:new() Avisos: Isso não é uma biblioteca completa de MVC ou qualquer coisa parecida. É apenas um "wrapper" para construir queries de um jeito mais dinâmico, organizado e sem se preocupar com concatenação e afins. Não há sanitização de strings, testes para verificar se as funções existem ou coisa do tipo, portanto, tome cuidado. A biblioteca ainda está em fase de testes, não cheguei a usar ela num servidor com muitos players online. Se alguém puder fazer isso, ficarei agradecido. Posso transformar as queries para a sintaxe da biblioteca, se necessário.
  9. Funções iteradoras em Lua

    Iteradores são funções especiais criadas para iterar, ou seja, percorrer, listas, vetores (arrays), matrizes, tabelas ou o que quisermos. Nós criamos iteradores para usar na função for. Um exemplo de iterador que você já deve conhecer é o pairs. Vamos supor que eu tenha a seguinte tabela: k = {1, 2, 3, 4, 5} E eu queira iterar por todos eles imprimindo o seu quadrado. Como faríamos isso? Casualmente, o código seria este: for i = 1, 5 do print(i ^ 2) end Mas e se eu quiser fazer isso várias vezes? Com uma lista que não segue um padrão? Então criamos um iterador, mas primeiro, vamos entender a estrutura de um em pseudocódigo Lua: function iterator(values) local pos = 0 --posição do iterador na lista return function() pos = pos + 1 if values[pos] ~= nil then return values[pos] end return nil end end Perceba que eu não retorno um valor especifico ao chamar a função iterator(), eu retorno uma nova função. Essa função será chamada pelo for até que seu retorno seja nil, onde Lua assume que o iterador acabou. E como eu sei quando acaba? Simples, há uma variável (chamei, neste caso, de pos) que armazena a posição dentro do array values do próximo valor a ser retornado. A cada iteração, o valor aumenta em 1 dentro da função. Quando eu acessar um índice dentro do array que não existe, seu valor (values[pos]) será nil, portanto eu testo essa condição. Parece bastante complexo, mas vamos voltar ao exemplo do quadrado. Chamarei minha função iteradora de square: function square(numbers) local pos = 0 return function() pos = pos + 1 if values[pos] ~= nil then return values[pos] ^ 2 end return nil end end A cada chamada da função de retorno, eu aumento a posição e retorno este elemento elevado ao quadrado. Então, usarei a função assim: for i in square(k) do print(i) end Que funciona como o esperado: O que mais podemos fazer com iteradores? Podemos, por exemplo, bloquear uma palavra usando a função onTalk do xotservx (pesquise no Google): local palavra = "jujuba" function splitWords(phrase) local pos = 0, words = phrase:gmatch("%w+") return function() pos = pos + 1 if words[pos] ~= nil then return words[pos] end return nil end end function onTalk(cid, type, text, position) for w in splitWords(text) do if w = palavra then return false end end return true end Claro que esse exemplo é bastante simplório, mas demonstra a utilidade dos iteradores. Neste caso, eu testo todas as palavras que o player falou para encontrar uma palavra especifica que eu defini. Podemos transformar isso tudo em um loop while, para você entender um pouco melhor: local words = splitWords(text) while w = words() do if w == nil then break end if w = palavra then return false end end end return true Usando o iterador, ganhamos organização no código e o controle do for. Espero que façam bom uso de iteradores para organizar seus códigos
  10. The Zodiac ~

    ┌──────────────────────────────────────────────────┐ │Nome: Sign of Zodiac │Versão do script: 1.0.0 │Tipo do script: Sistema (Creature Script, Talkaction e Lib) │Servidor Testado: The Forgotten Server 0.4.0 Doomed Elderberry │Autor: Lwkass └──────────────────────────────────────────────────┘ Por mais que o feedback do meu ultimo post (Lib para criar Spell) tenha sido pouco, vou postar mais um script... É um sistema de Signo do Zodíaco, onde cada signo da um bônus (por enquanto apenas 2), a ideia está bem inicial, mas pretende continua-lo. - Características: - Explicando: Para escolher o signo o player deve colocar o dia e o mês do aniversário e o sistema automaticamente coloca o signo, comando: Só para deixar claro como o sistema funciona, usando de exemplo o signo de Leão (Leo) que é do elemento Fire: * Se receber um dano do elemento Fire, absorve 5% (modificável) do dano total, ou seja, o dano seria igual a 95% do que seria (dano absorvido indicado por animatedText). * Se matar um monstro que tenha uma defesa contra Fire maior que 0% ganha bônus de 10% (modificável) da exp total, ou seja, ganha-se 110% (exp extra indicada por animatedText). Se o signo fosse do elemento Earth, então seria a mesma coisa só que com o elemento Earth, se fosse Ice ou Lighting a mesma coisa. Pode-se usar o comando !zodiac info para informações. - Script: Primeiro, na pasta data/lib (caso a pasta não exista, crie) do seu servidor crie um arquivo Lua com o nome zodiac-Lib.lua (Lib com maiúscula) e salve com isso dentro: --[[ Sign of Zodiac System v1.0.0 by: Lwkass ([email protected]) ]] Zodiac = { constant = { OPTION_PERCENT_BLOCK = 5, -- In Percent OPTION_EXTRA_EXP_RATE = 10, -- In Percent STORAGE_SIGN = 16161, elements = { ["Fire"] = { combat = COMBAT_FIREDAMAGE, color = COLOR_ORANGE }, ["Earth"] = { combat = COMBAT_EARTHDAMAGE, color = COLOR_LIGHTGREEN }, ["Lighting"] = { combat = COMBAT_ENERGYDAMAGE, color = COLOR_TEAL }, ["Ice"] = { combat = COMBAT_ICEDAMAGE, color = COLOR_LIGHTBLUE } } }, signs = { ["Aries"] = { date = {"21/03", "20/04"}, element = "Fire" }, ["Taurus"] = { date = {"21/04", "20/05"}, element = "Earth" }, ["Gemini"] = { date = {"21/05", "20/06"}, element = "Lighting" }, ["Cancer"] = { date = {"21/06", "21/07"}, element = "Ice" }, ["Leo"] = { date = {"22/07", "22/08"}, element = "Fire" }, ["Virgo"] = { date = {"23/08", "22/09"}, element = "Earth" }, ["Libra"] = { date = {"23/09", "22/10"}, element = "Lighting" }, ["Scorpio"] = { date = {"23/10", "21/11"}, element = "Ice" }, ["Sagittarius"] = { date = {"22/11", "21/12"}, element = "Fire" }, ["Capricorn"] = { date = {"22/12", "20/01"}, element = "Earth" }, ["Aquarius"] = { date = {"21/01", "19/02"}, element = "Lighting" }, ["Pisces"] = { date = {"20/02", "20/03"}, element = "Ice" } }, getSignInfo = function (signName) return Zodiac.signs[signName] end, set = function (cid, signName) setPlayerStorageValue(cid, Zodiac.constant.STORAGE_SIGN, signName) end, get = function (cid) return getPlayerStorageValue(cid, Zodiac.constant.STORAGE_SIGN), Zodiac.getSignInfo(getPlayerStorageValue(cid, Zodiac.constant.STORAGE_SIGN)) or 0 end, getElement = function (cid) return Zodiac.getSignInfo(getPlayerStorageValue(cid, Zodiac.constant.STORAGE_SIGN)).element end, getSign = function (cid, day, month) for sign, info in pairs(Zodiac.signs) do _, _, beginDay, beginMonth = info.date[1]:find("(%d+)/(%d+)") _, _, endDay, endMonth = info.date[2]:find("(%d+)/(%d+)") beginDay, beginMonth, endDay, endMonth = tonumber(beginDay), tonumber(beginMonth), tonumber(endDay), tonumber(endMonth) if ((month == beginMonth and day >= beginDay) or (month == endMonth and day <= endDay)) then return sign, info end end end } Agora na pasta data/creaturescripts/scripts: No arquivo login.lua adicione isso antes do return: -- Zodiac registerCreatureEvent(cid, "zodiacKill") registerCreatureEvent(cid, "zodiacStats") if (getPlayerLastLogin(cid) <= 0 or getPlayerStorageValue(cid, 16160) == 1) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Please, when is your birthday date ? (Example: !zodiac day/month = !zodiac 1/2, !zodiac 23/7,...)") setPlayerStorageValue(cid, 16160, 1) -- Talk state else doPlayerSetSpecialDescription(cid, ", sign of " .. getPlayerStorageValue(cid, 16161)) end E crie esses arquivos: zodiacKill.lua dofile('data/lib/zodiac-Lib.lua') function getMonsterPath(monstername) f = io.open ("data/monster/monsters.xml", 'r') for line in f:lines() do _, _, name, path, file_name = string.find(line, '<monster name="(.+)" file="(.+)/(.+).xml"/>') if (name and path and file_name and name:lower() == monstername:lower()) then f:close() return path .. "/" .. file_name .. ".xml" end end end function getMonsterElementDefense(monstername, element) f = io.open ("data/monster/" .. getMonsterPath(monstername), 'r') for line in f:lines() do if (string.find(line, '</elements>')) then break end _, _, n = string.find(line, '<element '.. element:lower() ..'Percent="([-%d]+)"/>') if (n) then f:close() return tonumber(n) end end f:close() return 0 end ------- function onKill(cid, target, lastHit) if (isMonster(target) and getMonsterElementDefense(getCreatureName(target), (Zodiac.getElement(cid) == "Lighting" and "Energy" or Zodiac.getElement(cid))) > 0) then local exp_bonus = math.ceil(getMonsterInfo(getCreatureName(target)).experience * (Zodiac.constant.OPTION_EXTRA_EXP_RATE/100)) doSendAnimatedText(getThingPos(cid), exp_bonus, COLOR_GREY) doPlayerAddExperience(cid, exp_bonus) end return true end zodiacStats.lua dofile('data/lib/zodiac-Lib.lua') function onStatsChange(cid, attacker, type, combat, value) playerSign = Zodiac.get(cid) if (combat == Zodiac.constant.elements[Zodiac.getElement(cid)].combat) then valuem = math.ceil(value*(Zodiac.constant.OPTION_PERCENT_BLOCK/100)) doCreatureAddHealth(cid, valuem) doSendAnimatedText(getThingPos(cid), "+"..valuem, Zodiac.constant.elements[Zodiac.getElement(cid)].color) end return true end Certo, agora no arquivo data/creaturescripts/creaturescripts.xml, adicione isso: <event type="statschange" name="zodiacStats" event="script" value="zodiacStats.lua"/> <event type="kill" name="zodiacKill" event="script" value="zodiacKill.lua"/> Na pasta data/talkactions/scripts, adicione um arquivo Lua com o nome de zodiacTalk.lua: dofile('data/lib/zodiac-Lib.lua') function onSay(cid, words, param, channel) if (param:len() == 0) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You can use '!zodiac day/month' or '!zodiac info'") return true end playerSign, Info = Zodiac.get(cid) if (type(playerSign) == "string" and param:lower() == "info") then doPlayerPopupFYI(cid, [[ Zodiac Informations ~ ------------------------------- * Sign: ]] .. playerSign .. [[ * Element: ]] .. Info.element .. [[ * Bonus: +]] .. Zodiac.constant.OPTION_EXTRA_EXP_RATE .. [[% experience of ]] .. Zodiac.getElement(cid) .. [[ monsters +]] .. Zodiac.constant.OPTION_PERCENT_BLOCK .. [[% of defense in attacks with ]] .. Zodiac.getElement(cid) .. [[ element ]]) elseif (getPlayerStorageValue(cid, 16160) == 1) then _, _, day, month = string.find(param, "(%d+)/(%d+)") day, month = tonumber(day), tonumber(month) if (day and month and day > 0 and day <= 31 and month > 0 and month <= 12) then Zodiac.set(cid, Zodiac.getSign(cid, day, month)) playerSign = Zodiac.get(cid) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, param) doSendMagicEffect(getThingPos(cid), math.random(28, 30)) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You sign of zodiac is " .. playerSign .. " which is of element " .. Zodiac.getElement(cid) .. " !") doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You can see more information saying '!zodiac info', remember this...") setPlayerStorageValue(cid, 16160, -1) else doPlayerSendCancel(cid, "You put a invalid date.") end end return true end Coloque essa tag no arquivo data/talkactions/talkactions.xml <talkaction words="!zodiac" event="script" value="zodiacTalk.lua"/> ChangeLog: E é isso ! Qualquer dúvida, sugestão, critica só dizer ^^
  11. Patterns

    Pattern Pattern ("Padrão" em pt-br) é uma poderosa funcionalidade para manipulação de strings (caso você não saiba o que é uma "string", busque saber antes de continuar, recomendo também ter um certo domínio sobre a biblioteca string), e usada para buscar um padrão de texto pré-definido. Porque aprender ? Possui recursos indispensáveis quando se precisa trabalhar com strings, alta aplicabilidade em scripts direcionados a otserv (talkactions), não que se vá usar isso a todo o momento, mas é altamente recomendado que se saiba trabalhar com patterns, é extremamente útil as vezes. Funções Algumas funções da biblioteca padrão string que aceitam pattern em seus parâmetros: string.find(string, pattern) – Procura a primeira instância da pattern na string string.gfind(string, pattern) – Quando for chamada repetidamente, retorna cada instância da pattern na string string.gsub(string, pattern, replace) – Retorna uma string em que todas as instâncias da pattern foram substituidas por replace string.match(string, pattern, init) – Retorna uma lista de ocorrências da pattern na string, começando em init (1 significa o primeiro caractere da string, 2 o segundo, assim por diante) Conjuntos Quando se constrói uma pattern, se utiliza alguns caracteres, cada um representando um conjunto diferente: x (onde "x" não é um caractere mágico ^$()%.[]*+-?) → Representa o caractere "x" mesmo; . → Representa todos os caracteres; %a → Representa todas as letras; %c → Representa todos os caracteres de controle; %d → Representa todos os dígitos; %l → Representa todas as letras minusculas; %p → Representa todos os caracteres de pontuação; %s → Representa todos os caracteres de espaço; %u → Representa todas as letras maiúsculas; %w → Representa todos os caracteres alfanuméricos; %x → Representa todos os dígitos hexadecimais; %z → Representa o caractere com a representação do 0 (zero). Ao usar zeros na pattern ela não irá funciona, use esta nesse caso; Ao usar letra maiúscula, isso faz representar o contrário (Exemplo: %A → Representa tudo que não for letras; %D → Representa tudo que não for um digito; assim por diante...). Como dito anteriormente, para se criar uma pattern é necessário utilizar esses conjuntos, uma pattern é feita de uma sequência desses conjuntos. Se você quisesse criar uma pattern para encontrar uma certa string em um texto, por exemplo, para encontrar os números da string "23otserv", você teria que usar esta pattern "%d%dotserv", assim você estaria definindo que quer os numeros que estão ao lado da palavra ‘otserv’. Mas e se tivesse que encontrar um numero com 10 "casas" ? Por isso existe os modificadores, para evitar essa repetição desnecessária. Modificadores Servem principalmente para poupar serviço e são quatro, entenda 'x' como sendo algum conjunto (%a, %c, %d, ...): x* → Retorna 0 ou mais repetições do conjunto x. Sempre retornará a maior cadeia possível encontrada; x+ → Retorna 1 ou mais repetições do conjunto x. Sempre retornará a maior cadeia possível encontrada; x- → Retorna 0 ou mais repetições do conjunto x. Sempre retornará a menor cadeia possível encontrada; x? → Retorna 0 ou 1 ocorrência de x; Elementos especiais Existe também quatro elementos especiais: %n → Sendo n um numero entre 1 e 9, busca a enésima captura (apenas vi sendo usada na função string.gsub); %bxy → Procura uma string que inicia com x e termina com y; ^ → Quando está no começo da pattern, força a pattern a ser encontrada no começo da string; $ → Quando está no final da pattern, força a pattern a ser encontrada no fim da string; Nota: Se ^ ou $ estiverem em outros lugares da pattern, não fazem nada, apenas representam eles mesmos. Construindo uma pattern Vamos construir algumas patterns com os elementos citados acima. Primeiro alguns exemplos e depois uma explicação mais detalhada de cada elemento da pattern: String para as patterns: "Exemplo lua de pattern lua feito em lua" exemplos toscos, a gente se vê por aqui Pattern: (%a+) lua Capturaria: Exemplo lua de pattern lua feito em lua Ele só retornará o primeiro caso que corresponder com a pattern. Agora, ao invés de usar o "%a" fosse usado o "." (que captura tudo), aconteceria isso: Pattern: (.+) lua Capturaria: Exemplo lua de pattern lua feito em lua Como "%a" captura apenas letras e não o "espaço", foi por isso que no primeiro exemplo só capturou a palavra "Exemplo" e no segundo exemplo, como foi usado o "." que captura tudo, capturou uma parte maior (ai que vêm a parte do modificador) por causa do modificador "+" que sempre vai buscar a maior cadeia possivel, agora veja um exemplo usando o "-": Pattern: (.-) lua Capturaria: Exemplo lua de pattern lua feito em lua O modificador "-", como dito anteriormente, captura a menor cadeia e por isso capturaria apenas o "Exemplo". Todos os modificadores são importantes. Um exemplo maior: Pattern: (%a+) lua (.-) lua (.+) Capturaria: Exemplo lua de pattern lua feito em lua Para quem não entendeu Explicação passo a passo: (%d+) Captura → O parenteses define que você quer que retorne essa captura. Conjunto → No caso é o de digitos. Modificador → No caso mostra que é para obter a maior cadeia possivel com 1 ou mais repetições do conjunto. Um exemplo mais avançado Agora usando de exemplo a pattern da função string.trim, que remove os espaços em branco do lado esquerdo e direito da string. function string.trim(str) -- Function by Colandus return ([b]string.gsub(str, "^%s*(.-)%s*$", "%1")[/b]) end string.gsub(str, "^%s*(.-)%s*$", "%1") str → Uma string qualquer; ^ → Força o começo da pattern ser encontrada no começo de str; %s* → Conjunto de espaços, podendo ter 0 ou mais repetições; (.-) → A captura principal, a que vai ser retornada, podendo ser digitos, letras, espaço, etc; $ → Força o final da pattern ser encontrada no fim de str; %1 → Retorna a 1ª captura da pattern e usa como parametro da função (Esse é um dos elementos especiais, %n); Dessa forma será removido os espaços apenas no começo e no fim da string ! Complemento Depois de dominar e entender como funciona as patterns, vamos aplica-las em funções, vou mostrar um exemplo de cada função (as que foram citadas no começo). string.find: [b]init[/b], [b]end[/b], [b]case1[/b], [b]case2[/b] = string.find("minha string123", "(%a+) (.+)") init → Onde inicia a captura encontrada (nesse caso, init = 1); end → Onde termina a captura encontrada (end = 15); case1 → Primeira captura que equivale a pattern (%a+) (case1 = minha); case2 → Segunda captura que equivale a pattern (.+) (case2 = string123); string.gfind: for [b]occ[/b] in string.gfind("a1a2a3a4a5", "(%a%d)") do print([b]occ[/b]) end occ → Terá um valor para cada instância da pattern (%a%d) encontrada, então irá printar a1, a2, a3, a4 e a5. string.match: [b]case1[/b], [b]case2 [/b]= string.match("Eu tenho 50 reais", "(%d+) (%a+)") case1 → Primeira captura que equivale a pattern (%d+) (case1 = 50); case2 → Segunda captura que equivale a pattern (%a+) (case2 = reais); Referência http://www.lua.org/manual/5.1/pt/manual.html#5.4.1 http://lua-users.org/wiki/PatternsTutorial Então é isso, espero ter sido o mais claro possivel, Qualquer dúvida, erro ou sugestão, poste !
  12. Inicio no Löve ;b

    Então, depois que o Socket postou sobre o Löve e como eu já estava interessado em criar algum jogo e também como raramente me vem alguma ideia de script decente na cabeça, decidi criar algo usando o Löve pra saber como ele funciona, eu já estava fazendo um jogo em Java, mas é um pouco (muito) desanimador fazer tudo sozinho... Enfim, ai está os códigos lua que criei ontem pra passar o tempo (no final eu coloquei tudo pra download, como é usado um sprite sheet vai ser necessário baixar para rodar, o sprite sheet usado eu peguei em um site e só organizei do jeito que queria) e acho que vou continuar até ter uma aparência de jogo mesmo Por enquanto o que dá pra fazer é movimentar o personagem pra frente e pra trás apenas, mas conta com animação do player parado e andando (só andando pra frente), ou seja quando anda troca de animação, é bem simples, mas quis fazer para principalmente aprender a criar animação e talvez incentivar mais pessoas :] Para testar é necessário ter o Löve ! Caso você não tenha o Löve instalado, é só seguir o que tem nessa página (em inglês) http://love2d.org/wiki/Getting_Started explica tudo que precisar main.lua require("system/imageSheet.lua") require("system/animation.lua") require("system/player.lua") framesPassed, player = 0 function table.exist(table, n) for i = 1, #table do if (table[i] == n) then return i end end return false end ------ function love.load() player = Player:new() player:setGraphics({ stopped = ImageSheet:new("player.png", 25, 48, 3), walking = ImageSheet:new("player.png", 48, 49, 16,0,49) }) player:setAnimation("stopped", Animation:new(player:getGraphic("stopped"), 90)) player:setAnimation("walking", Animation:new(player:getGraphic("walking"), 20)) player:setPosition(30, 60) love.graphics.setFont(font) end function love.draw() --love.keyboard.setKeyRepeat(10, 200) player:getAnimation(player:getAction()):Draw(player:getPosition().x, player:getPosition().y) love.graphics.print("- Infos -", 20, 7) love.graphics.print("FPS: "..love.timer.getFPS(), 10, 20) love.graphics.print("Delta: "..love.timer.getDelta(), 10, 35) love.graphics.print("Frames Passed: "..framesPassed, 10, 50) love.graphics.print("Player Action: "..player:getAction(), 10, 70) end -- logics animationTime = 0 function love.keyreleased(key, unicode) if (player:getAction() == 'walking') then player:setAction('stopped') end end function love.update(dt) fps = love.timer.getFPS() if (love.keyboard.isDown('right')) then player:setPosition(player:getPosition().x + 0.5) player:setAction('walking') elseif (love.keyboard.isDown('left')) then player:setPosition(player:getPosition().x - 0.5) player:setAction('walking') end player:getAnimation(player:getAction()):Update() if (framesPassed >= fps) then framesPassed = 0 else framesPassed = framesPassed + 1 end end system/imageSheet.lua ImageSheet = {} function ImageSheet:new(name, spriteWidth, spriteHeight, nSprites, initX, initY) sheet = {} img = love.graphics.newImage(string.format("data/images/%s", name)) initX = initX or 0; initY = initY or 0 for y = 0, math.ceil(img:getHeight()/spriteHeight) - 1 do for x = 0, math.ceil(img:getWidth()/spriteWidth) - 1 do if (not nSprites or #sheet < nSprites) then sheet[x+1] = love.graphics.newQuad(initX+spriteWidth*x, initY+spriteHeight*y, spriteWidth, spriteHeight, img:getWidth(), img:getHeight()) end end end return setmetatable({ batch = love.graphics.newSpriteBatch(img, spriteWidth * spriteHeight), sheet = sheet, image = img }, {__index = self}) end function ImageSheet:getSheet(n) return (n and self.sheet[n] or self.sheet) end function ImageSheet:getBatch() return self.batch end function ImageSheet:getSheetLength() return #self.sheet end function ImageSheet:Draw(frame, x, y) self:getBatch():clear() self:getBatch():addq(self:getSheet(frame), x, y) love.graphics.draw(self:getBatch(), x, y) end system/animation.lua require("system/imageSheet.lua") Animation = {} function Animation:new(imagesheet, delay) return setmetatable({imgsheet = imagesheet, frame = 1, delay = delay, time = 0}, {__index = self}) end function Animation:nextFrame() self.frame = self.frame == self.imgsheet:getSheetLength() and 1 or self.frame + 1 end function Animation:Update() if (self.time >= self.delay) then self:nextFrame() self.time = 0 end self.time = self.time + 1 end function Animation:Draw(x, y) self.pos = {x=x,y=y} self.imgsheet:Draw(self.frame, self.pos.x, self.pos.y) end system/player.lua Player = {} function Player:new() return setmetatable({ position = { x = 0, y = 0 }, action = 'stopped', graphics = { } }, {__index = self}) end --- function Player:getPosition() return self.position end function Player:setPosition(x, y) self.position.x = x or self.position.x; self.position.y = y or self.position.y; end function Player:getAction() return self.action end function Player:setAction(action) self.action = action end --- function Player:setGraphics(graphics) for a, b in pairs(graphics) do self.graphics[a] = {imgxt = b} end end function Player:getGraphic(graphic) return self.graphics[graphic].imgxt end function Player:getAnimation(action) return self.graphics[action].animation end function Player:setAnimation(action, animation) self.graphics[action].animation = animation end O Sprite Sheet (pra quem não sabe significa "folha de sprites", seria um conjunto de sprites em um só arquivo) que eu usei foi pego nesse link: http://www.spriters-resource.com/ds/cstlevniadawnofsorrow/sheet/19037 E eu adicionei só o necessário reorganizei do meu jeito e ficou dessa maneira: http://img850.imageshack.us/img850/3083/playerb.png ----- Caso tenha se interessado: Aqui explica como instalar e executar scripts feitos para o Löve: http://love2d.org/wiki/Getting_Started Tutoriais: http://love2d.org/wiki/Category:Tutorials ----- Eu vi lá que tem como mandar como executável mas mudei a extensão e mesmo assim não consegui fazer aqui :s então está como .rar mesmo
  13. Desafio Decodificação

    Eu desenvolvi uma função que codificou uma frase (string) qualquer nisto: 010101100110111101100011111010100010000001100100011001010111001101100011011011110110001001110010011010010111010100100000001110100110111100101100001000000111000001100001011100100110000101100010111010010110111001110011001011000010000001100001011100110010000001101100011001010111010001110010011000010111001100100000011000010010000001110011011001010110011101110101011010010111001000100000011100111110001101101111001000000111001111110011001000000111000001110010011000010010000001100110011010010110001101100001011100100010000001101101011000010110100101110011001000000110010011101101011001100110100101100011011010010110110000111010001000000110000101101100011000010110111101101100011000010110110001100001011010000111010101100101011010000111010101110101011010000111010101110101011010000111010101100101011011000110010101110100011100100110000101101000011001010110100001100101011010000110010101101000011001010110100001100101 A tarefa de vocês é desenvolver uma que decodifique isso, e descobrir a frase inteira que eu codifiquei, a função que voce fez tem que estar junta pra provar que alguem não fez por você, etc, etc, etc ... Dicas (vou colocando aos poucos) B inary Dig IT 8 bits 1 byte É bem fácil mesmo, se você pensar em uma coisa obvia, é isso ... Quem descobrir primeiro e postar a função junto com a frase leva 50V$ :coolface: (pode ser qualquer função, de qualquer maneira menos pog, desde que ela funcione) PS: Mock, ou qualquer um dos avançados, nao acabem com a graça por favor ._.
×