Jump to content

Search the Community

Showing results for tags 'lwkass'.



More search options

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • A Cidade OTBR
    • OTServ Brasil
    • Atendimento
    • Taverna
  • OpenTibia
    • Promoted Projects
    • Notícias e Discussões
    • Suporte - Dúvidas, Bugs, Erros
    • Downloads
    • Tutoriais
    • Show-Off
    • Divulgação de Servidores
  • Outros
    • Design

Found 7 results

  1. Lumberjack - Lenhador

    ┌──────────────────────────────────────────────────┐ │Nome: Lumberjack │Versão do script: 2.0.0 │Tipo do script: Action │Servidor Testado: The Forgotten Server 0.4 Doomed Elderberry │Autor: Lwkass └──────────────────────────────────────────────────┘ Características : Versão 2.0 Changelog : Instalação : By: Lwkass,Grato~
  2. Lib Spell (POO) !

    ┌───────────────────────────────────────────────┐ │Nome: Spell System │Versão do script: 1.0.0 │Tipo do script: System/Lib │Servidor Testado: The Forgotten Server 0.4.0 Crying Damson │Autor: Lwkass └───────────────────────────────────────────────┘ Bem, é uma lib que criei para criação de spells, também para mostrar um sistema com "POO" em lua, já vou dizendo que não é super super útil (talvez seja para alguns), mas como eu estava com vontade de fazer pode acabar ajudando a diminuir codes também. Caracteristicas: Script: Apenas um script, crie um arquivo Lua com o nome de Spell-class.lua na pasta data/lib: --[[ @ Spell System By Lwkass form OTServerBrasil ! @ Version: 1.0.0 - Any questions (msn): [email protected] ]] ----------===================------------- ---- CONFIGURATIONS ----------===================------------- SpellOptions = { sendCastSay = true, -- true = Vai mandar uma mensagem sempre que usar uma spell showAnimatedValues = true, -- true = Ativa efeito animado onlySpellOwnerSeeAnimation = true -- true = Apenas o usuario da spell ve a animacao } ---- Constantes SPELL_TYPE_DIRECTION = 0 SPELL_TYPE_AREA = 1 ----------===================------------- ---- GENERAL FUNCTIONS ----------===================------------- function getPosByArea(area, topleftpos) arr = {} for y, a in pairs(area) do arr[y] = {} for x, tile in pairs(a) do arr[y][x] = {x=(x-1)+topleftpos.x, y=(y-1)+topleftpos.y, z=topleftpos.z} end end return arr end function rotateArea(area, angle) final = {} angle = math.rad(angle) for y, a in pairs(area) do for x, tile in pairs(a) do temp = {x = (x * math.cos(angle) + y * math.sin(angle)), y = (x * (-math.sin(angle)) + y * math.cos(angle))} e_x, e_y = (temp.x < 0 and #a + (temp.x) + 1 or temp.x), ((temp.y < 0 and #area + (temp.y) + 1 or temp.y)) final[e_y] = final[e_y] or {} table.insert(final[e_y], e_x, tile or 0) end end return final end ----------===================------------- SpellTile = {} function SpellTile:create(combat, effect, damage) --[[ - Cria uma SpellTile Param: #1 (combat) = combat para o tile, válido todos os combats do tibia (exemplo: COMBAT_PHYSICALDAMAGE, COMBAT_ENERGYDAMAGE, COMBAT_MANADRAIN, etc...) #2 (effect) = efeito para o tile, válido todos os efeitos do tibia (exemplo: CONST_ME_DRAWBLOOD, CONST_ME_LOSEENERGY, CONST_ME_POOF, etc...) #3 (damage) = tabela de dano, que deve seguir esse modelo: {min = -dano_minimo, max = -dano_maximo} ]] return setmetatable({ combat = combat, effect = effect, damage = damage }, { __index = self }) end function SpellTile:setCondition(condition) --[[ - Define uma condição para o SpellTile e retorna uma cópia do próprio SpellTile Param: #1 (condition) = Precisa ser uma condition válida do tibia, exemplo: condition = createConditionObject(CONDITION_POISON) setConditionParam(condition, CONDITION_PARAM_DELAYED, 1) addDamageCondition(condition, 10, 2000, -10) ]] copy = SpellTile:create(self.combat, self.effect, self.damage) copy.delay = self.delay copy.center = self.center copy.condition = condition return copy end function SpellTile:setSpellCenter() --[[ - Define que esse SpellTile é o centro da magia e retorna uma cópia do próprio SpellTile ]] copy = SpellTile:create(self.combat, self.effect, self.damage) copy.delay = self.delay copy.center = true return copy end function SpellTile:delay(mili) --[[ - Define um delay para lançar o spelltile e retorna uma cópia do próprio SpellTile Param: #1 (mili) = Tempo em milisegundos até lançar o spelltile ]] copy = SpellTile:create(self.combat, self.effect, self.damage) copy.delay = mili return copy end ----------===================------------- --[[ @ Spell System By Lwkass form OTServerBrasil ! @ Version: 1.0.0 - Any questions (msn): [email protected] ]] ----------===================------------- Spell = {} -- Construtor function Spell:create(spellwords, spelltype, options) --[[ - Cria uma nova spell Param: #1 (spellwords) = Palavras mágicas da spell #2 (spelltype) = Tipo da spell, é necessário utilizar os valores que estão no Spell-class.lua, por exemplo: SPELL_TYPE_DIRECTION (para spell com direção) ou SPELL_TYPE_AREA (para spell com area) #3 (options) = uma tabela com opções da spell, pode possuir esses valores (não é necessário colocar todos !): options = { level = 1, -- Level necessario maglevel = 1, -- Magic Level necessario mana = 100, -- Mana necessaria maxDistance = 3, -- Distancia máxima needWeapon = true, -- Se precisa estar usando alguma arma vocation = {1,2,3,4,5}, -- Vocações que podem usar a magia sex = 0, -- Sexo que pode usar a magia group = 2 -- Group minimo para usar a magia } ]] return setmetatable({ spellwords = spellwords, spelltype = spelltype, level = options and options.level or 0, maglevel = options and options.maglevel or 0, mana = options and options.mana or 0, options = options or {} }, { __index = self }) end -- Setters & Getters function Spell:setArea(area) --[[ - Define a area da spell Param: #1 (area) = Uma tabela que segue o modelo padrão de magias (exemplo: {{1,1,1},{1,1,1},{0,3,1}}) ]] self.area = area end function Spell:setOption(option, value) --[[ - Define as opções Param: #1 (option) = opção (exemplo: mana, level...) #2 (value) = valor ou novo valor ]] self.options = self.options or {} self.options[option] = value end function Spell:setMaxDistance(n) --[[ - Define a distancia máxima para usar a spell, pode-se definir direto através da tabela options também (maxDistance = distancia) Param: #1 (n) = Distancia máxima ]] self:setOption("maxDistance", n) end function Spell:setDefaultTile(tile) --[[ - Define a spellTile padrão para a spell (usa-se a marcação 1 na area) Param: #1 (tile) = precisa ser um spellTile ]] self.dftTile = tile end -- Others function Spell:getCreatureMark() --[[ - Procura e retorna a posição do tile que seja igual a 3 ou que esteja com a marcação tile.center = true ]] for y, b in pairs(self.area) do for x, d in pairs( do if ((type(d) == "table" and d.center) or d == 3) then return {x = x,y = y} end end end end -- Main Function function Spell:cast(cid, target) --[[ - Lança a magia Param: #1 (cid) = usuario da magia #2 (target) = alvo da magia (se necessário) ]] if (not isCreature(cid)) then return print('[spellClass - Warning / "'.. self.spellwords ..'"]: The cid must be a creature !') end -- Target checks if (target) then if (not isCreature(target)) then -- Target is not selected return doPlayerSendCancel(cid, "You need a target.") end if (self.spelltype == SPELL_TYPE_DIRECTION) then return print('[spellClass - Warning / "'.. self.spellwords ..'"]: Set the spelltype to SPELL_TYPE_AREA or remove the param target from the method \'cast\' !') end end -- Options for option, value in pairs(self.options) do if (target and option == "maxDistance" and type(value) == "number") then if (getDistanceBetween(getThingPos(cid), getThingPos(target)) > value) then return doPlayerSendCancel(cid, "Target too far.") end elseif (option == "needWeapon" and value) then if (getPlayerWeapon(cid).uid == 0) then return doPlayerSendCancel(cid, "You need be using a weapon.") end elseif (option == "vocation" and type(value) == "table") then if (not isInArray(value, getPlayerVocation(cid))) then return doPlayerSendCancel(cid, "Your vocation can't use this spell.") end elseif (option == "sex" and type(value) == "number") then if (not getPlayerSex(cid) == value) then return doPlayerSendCancel(cid, "Your sex can't use this spell.") end elseif (option == "group" and type(value) == "number") then if (not getPlayerGroupId(cid) >= value) then return doPlayerSendCancel(cid, "You can't use this spell.") end end end -- Cid checks if (isPlayer(cid)) then if (getPlayerLevel(cid) >= self.level) then if (getPlayerMagLevel(cid) >= self.maglevel) then if (getCreatureMana(cid) >= self.mana) then doCreatureAddMana(cid, -(self.mana)) if (SpellOptions.showAnimatedValues) then doSendAnimatedText(getThingPos(cid), self.mana, COLOR_PURPLE, (SpellOptions.onlySpellOwnerSeeAnimation and cid or false)) end else return doPlayerSendCancel(cid, "You need " .. self.mana .. " of mana to use this spell.") end else return doPlayerSendCancel(cid, "You need magic level " .. self.maglevel .. " or greater to use this spell.") end else return doPlayerSendCancel(cid, "You need level " .. self.level .. " or greater to use this spell.") end end -- Direction change if (self.spelltype == SPELL_TYPE_DIRECTION) then local dir = {[0] = 0, [1] = 270, [2] = 180, [3] = 90} self:setArea(rotateArea(self.area, dir[getCreatureLookDirection(cid)])) end -- Main local playerPos, player = getThingPos((target or cid)), self:getCreatureMark() local theArea = getPosByArea(self.area, {x=playerPos.x - player.x + 1, y=playerPos.y - player.y + 1, z=playerPos.z}) if (SpellOptions.sendCastSay) then doCreatureSay(cid, getCreatureName(cid) .. " casts " .. self.spellwords .. " !", TALKTYPE_MONSTER) end for y, b in pairs(self.area) do for x, _tile in pairs( do local tilePos = theArea[y][x] local tile = ((_tile == 1) and self.dftTile or _tile) if (tile ~= 0 and tile ~= 3) then if (tile.condition) then doAreaCombatCondition(cid, tilePos, {1}, tile.condition, tile.conditionEffect or CONST_ME_NONE) end addEvent(doAreaCombatHealth, tile.delay or -1, cid, tile.combat, tilePos, {1}, tile.damage.min, tile.damage.max, tile.effect) end end end return true end --[[ @ Spell System By Lwkass form OTServerBrasil ! @ Version: 1.0.0 - Any questions (msn): [email protected] ]] Caso seu server não carregue automaticamente o script, tente adicionar essa linha a qualquer outro arquivo lua da pasta lib: dofile('data/lib/Spell-class.lua') Pronto ! Aqui um exemplo de spell com esse sistema: function onCastSpell(cid, var) spell = Spell:create("spell", SPELL_TYPE_DIRECTION, {mana = 100, level = 10, maglevel = 5}) tile = SpellTile:create(COMBAT_PHYSICALDAMAGE, 15, {min = -1, max = -2}):delay(500) spell:setArea({ {tile, tile, tile}, {0, tile, 0}, {0, tile, 0}, {0, 3, 0} }) spell:cast(cid) end Usos: Você pode usar assim também a area se quiser: spell:setArea({ {tile:delay(10), tile, tile:delay(620)}, {0, tile:delay(100), 0}, {0, tile, 0}, {0, 3, 0} }) Cada spelltile vai aparecer no delay que estiver ali marcado e os que não estiverem aparecerão no delay = 500 (que está definido em 'tile'). ---- Para adicionar conditions pode ser feito assim: local condition = createConditionObject(CONDITION_FIRE) setConditionParam(condition, CONDITION_PARAM_DELAYED, 1) addDamageCondition(condition, 10, 2000, -10) spell:setArea({ {tile:delay(10), tile, tile:delay(620)}, {0, tile:delay(100):setCondition(condition), 0}, {0, tile, 0}, {0, 3, 0} }) Apenas o tile que está com o setCondition vai receber a condition ! ---- Para uma spell de area que é lançada em um alvo é necessário deixar a spell dessa maneira: function onCastSpell(cid, var) spell = Spell:create("spell", SPELL_TYPE_AREA, {mana = 100, level = 10, maglevel = 5}) tile = SpellTile:create(COMBAT_PHYSICALDAMAGE, 15, {min = -1, max = -2}):delay(500) spell:setArea({ {tile, tile, tile}, {0, tile, 0}, {0, tile:setSpellCenter(), 0} }) spell:cast(cid, getCreatureTarget(cid)) end ---- Mas caso você queira definir um spelltile como padrão para a spell (Sempre que usar o 1 na area esse spelltile será chamado), você pode fazer assim: function onCastSpell(cid, var) spell = Spell:create("spell", SPELL_TYPE_DIRECTION, {mana = 100, level = 10, maglevel = 5}) spell:setDefaultTile(SpellTile:create(COMBAT_ENERGYDAMAGE, 30, {min = -1, max = -2})) -- Define o tile padrão tile = SpellTile:create(COMBAT_PHYSICALDAMAGE, 15, {min = -1, max = -2}):delay(500) spell:setArea({ {tile, tile, tile}, {1, 1, 1}, {1, tile, 1}, {0, 3, 0} }) spell:cast(cid) end Então sempre que usar o numero 1 na area ele será substituido pelo spelltile padrão ! Todas as funções estão comentadas, em caso de dúvida sobre como usar uma função, leia o código-fonte ou pergunte aqui mesmo
  3. 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 ^^
  4. 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 !
  5. ┌──────────────────────────────────────────────────┐ │Nome: Limit Break │Versão do script: 2.0.0 │Tipo do script: Creature Script │Servidor Testado: The Forgotten Server 0.4 Doomed Elderberry │Autor: Lwkass └──────────────────────────────────────────────────┘ O Script é simples e baseado em um sistema do FF7, a cada hit que o player levar, ele carrega uma porcentagem de limit break e quando chegar a 100% o próximo hit melee (melee = ataque normal) liberará o Limit Break. Caracteristicas: Scripts: Na pasta data/creaturescripts/scripts, salve os dois scripts abaixo: limitbreaker.lua ------------------------------------------------ -- Limit Breaker System -- By: Lwkass from OTServBrasil dofile("data/lib/limitBreakerLib.lua") function onStatsChange(cid, attacker, type, combat, value) if (combat == COMBAT_HEALING) then return true end multiplier = (combat == COMBAT_PHYSICALDAMAGE and 1 or 1.5) limitBreak = LimitBreak:get(cid) if (limitBreak.percent < 100) then limitBreak(limitBreak.percent + math.ceil(((value*100)/(getCreatureMaxHealth(cid)*0.7)) * multiplier)) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, 'You charged +' .. math.ceil(((value*100)/(getCreatureMaxHealth(cid)*0.7)) * multiplier) .. '% of Limit Break [' .. limitBreak.percent .. '%/100%]' .. (isCreature(attacker) and (' by a attack of ' .. getCreatureName(attacker)) or '') .. '.') else doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Your Limit Break is full !") doSendMagicEffect(getThingPos(cid), CONST_ME_MAGIC_RED) end return true end -- By: Lwkass from OTServBrasil -- limitbreaker_release.lua ------------------------------------------------ -- Limit Breaker System -- By: Lwkass from OTServBrasil dofile("data/lib/limitBreakerLib.lua") function onAttack(cid, target) limitBreak = LimitBreak:get(cid) if (limitBreak.percent >= 100) then if (getDistanceBetween(getThingPos(cid), getThingPos(target)) <= 1) then doCreatureSay(cid, "Arghh!", TALKTYPE_MONSTER) doSendMagicEffect(getThingPos(cid), CONST_ME_MAGIC_RED) limitBreak:cast(target) limitBreak(0) limitBreak:addExp(1) else doPlayerSendDefaultCancel(cid, RETURNVALUE_DESTINATIONOUTOFREACH) end end return true end -- By: Lwkass from OTServBrasil Agora no arquivo creaturescripts.xml da pasta data/creaturescripts, adicione: <event type="statschange" name="limitbreaker" event="script" value="limitbreaker.lua"/> <event type="attack" name="limitbreaker_release" event="script" value="limitbreaker_release.lua"/> Aproveitando, na pasta data/creaturescripts/scripts, no arquivo login.lua do seu servidor, adicione essas linhas antes do return: registerCreatureEvent(cid, "limitbreaker") registerCreatureEvent(cid, "limitbreaker_release") Só mais uma coisinha, na pasta data/lib (caso não exista a pasta lib, crie) crie um arquivo com o nome limitBreakerLib.lua e salve isso dentro: ------------------------------------------------ -- Limit Breaker System -- By: Lwkass from OTServBrasil local config = { OPTION_CAST_SPELL = false, -- Cast spell when limit break is full EXP_RATING = 1, -- Exp rating of limit break exp || (exp * rating). STORAGE_LIMIT_PERCENT = 13015, STORAGE_LIMIT_LEVEL = 13016, STORAGE_LIMIT_EXP = 13017 } ------------------------------------------------ LimitBreak = {} function LimitBreak:get(cid) _lb = setmetatable({ player = cid, level = getPlayerStorageValue(cid, config.STORAGE_LIMIT_LEVEL), percent = getPlayerStorageValue(cid, config.STORAGE_LIMIT_PERCENT) }, { __index = self, __call = function(t, p) if (p > 100) then p = 100 end rawset(t, 'percent', p); setPlayerStorageValue(cid, config.STORAGE_LIMIT_PERCENT, p) end }) if (config.OPTION_CAST_SPELL) then -- spell limitBreak_spell = Spell:create("Limit Break", SPELL_TYPE_AREA, { maxDistance = 1 }) local weapon = (getPlayerWeapon(cid).uid > 0 and (((getItemInfo(getPlayerWeapon(cid).itemid)["attack"]) + getItemInfo(getPlayerWeapon(cid).itemid)["extraAttack"])*0.8) or 1) limitBreak_spell:setDefaultTile(SpellTile:create(COMBAT_PHYSICALDAMAGE, 34, {min = -(getPlayerLevel(cid)*3.6 + weapon), max = -(getPlayerLevel(cid)*4.9 + weapon)})) limitBreak_spell:setArea({ {1, 1, 1}, {1, 3, 1}, {1, 1, 1} }) _lb:setSpell(limitBreak_spell) end return _lb end function LimitBreak:getSpell() return self.spell end function LimitBreak:setSpell(spell) self.spell = spell end function LimitBreak:cast(target) if (self:getLevel() < 0) then self:setLevel(1) end if (self:getExp() < 0) then self:setExp(0) end if (config.OPTION_CAST_SPELL and self:getSpell()) then self:getSpell():cast(self.player) else local weapon = (getPlayerWeapon(self.player).uid > 0 and (((getItemInfo(getPlayerWeapon(self.player).itemid)["attack"]) + getItemInfo(getPlayerWeapon(self.player).itemid)["extraAttack"])*0.8) or 0) doTargetCombatHealth(self.player, target, COMBAT_PHYSICALDAMAGE, -(getPlayerLevel(self.player) * 2.5 + weapon + self:getLevel() * 3.6), -(getPlayerLevel(self.player) * 3.5 + weapon + self:getLevel() * 4.9), 34) end end function LimitBreak:setLevel(lvl) setPlayerStorageValue(self.player, config.STORAGE_LIMIT_LEVEL, lvl) end function LimitBreak:getLevel() return getPlayerStorageValue(self.player, config.STORAGE_LIMIT_LEVEL) end function LimitBreak:addLevel(n) n = n or 1; self:setLevel(self:getLevel() + n) end function LimitBreak:setExp(xp) setPlayerStorageValue(self.player, config.STORAGE_LIMIT_EXP, xp) end function LimitBreak:getExp() return getPlayerStorageValue(self.player, config.STORAGE_LIMIT_EXP) end function LimitBreak:addExp(xp) xp = (xp or 1) * config.EXP_RATING self:setExp(self:getExp() + xp) if (self:getExp() >= (self:getLevel() * 2)) then self:setExp(0) self:addLevel() doPlayerSendTextMessage(self.player, MESSAGE_EVENT_ORANGE, "Your Limit Break is level " .. self:getLevel() .. " now.") doSendMagicEffect(getThingPos(self.player), CONST_ME_MAGIC_GREEN) end end -- By: Lwkass from OTServBrasil Fiz uma lib pra ficar mais organizado. A spell deve ser definida no arquivo limitBreakerLib.lua onde está marcado "--spell", funciona apenas com a minha Lib de Spell, mas, por padrão está definida uma magia que pega em volta do player (foto abaixo). Precisa também ir na parte das configurações do Limit Break e definir OPTION_CAST_SPELL como true (na linha 6 do limitBreakerLib.lua) ---- Screenshot: Mensagem quando se leva algum hit. Limit Break como Dano Melee. Limit Break como Spell. ChangeLog: Prontinho Qualquer dúvida/sugestão só falar Ta simplesinho o sistema, mas é provável que eu adicione mais coisas depois
  6. 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
  7. Steal Spell~

    ┌────────────────────────────────────────┐ │Nome: Steal Spell │Versão: 8.4x │Tipo do script: Spell │Servidor Testado: The Forgotten Server 0.3.3 │Autor: Lwkass └────────────────────────────────────────┘ Comentário: Essa magia é simples mas ajuda a diferenciar a mesmice de magia que eu vejo(pelomenos eu). Este script é uma spell que tem uma pequena chance em porcentagem de roubar metade do dinheiro(pode ser outros itens também) de um player, o dano da magia é fraco por ter essa chance de roubar. Abra a pasta data/spells/script e adicione isso em um arquivo lua (Sugestão: steal.lua) : Lua: Legenda Lua: ■ Esse numero é porcentagem de chance de conseguir roubar um item. ■ São os itens que podem ser roubados, se não quiser dinheiro é só colocar os ids que você quer. (Obs: Ali está 2148 = Gold Coin, 2152 = Platinum Coin e 2160 = Crystal Coin). ■ Se você quiser que roube todo o dinheiro(ou item), ou seja que não roube só a metade, então tire os dois ' -- ' e adicione ' -- ' para a parte em Roxo Adicione essa linha no spells.xml Xml: LegendaXml:: ■ É aonde fica o nome das vocações que podem utilizar essa magia. ■ É o nome da vocação que pode utilizar essa magia. ■ Nome do arquivo lua da magia. --- Bom esse foi meu 2º script postado aqui na otnet, me desculpe por qualquer erro que eu fiz aqui, caso haja dúvidas é só postar aqui. Espero que gostem e possivelmente eu posto outros scripts. By: Lwkass, Grato~
×