Lwkass 1 #1 Posted August 15, 2011 (edited) ┌───────────────────────────────────────────────┐ │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: - Tiles com Delay e Condition independentes- Verificações e Mensagens próprias - Suporte a magias de area, direção, com target, de cura e/ou com condition 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 Edited August 16, 2011 by Lwkass tinha esquecido 2 funções riarairairia Share this post Link to post
Majesty 1,761 #2 Posted August 16, 2011 Obrigado pela sua contribuição, Aprovado. Remuneração: Biblioteca - 40 V$. Share this post Link to post
dalvorsn 46 #3 Posted August 18, 2011 Lwkass como sempre humilhando nos scripts ._. Quando eu crescer quero ser igual a vocẽ HEIEH' Cara muito foda essa lib, e tu mostra também formas de usar OO em lua de maneira útil #Majesty Sugestão, porque não convida o Lwkass para ser sub-mod da seção de scripts? O cara ta contribuindo pacas com a OTBr, além de ter muito conhecimento na área Share this post Link to post
Rules Violations 0 #4 Posted September 5, 2011 @lwkass mt maneirinha essa lib, gtz. @dalvorsn o bixinhu paga pau dos infernos o.O ... sem ofenssas ^^ Share this post Link to post
dalvorsn 46 #5 Posted September 5, 2011 @lwkassmt maneirinha essa lib, gtz. @dalvorsn o bixinhu paga pau dos infernos o.O ... sem ofenssas ^^ Brother fica na sua, quem é você para falar de mim? Existe uma coisa que chama merecimento, e o lwkass faz por merecer os elogios. Share this post Link to post
Geovani 0 #6 Posted September 6, 2011 @topic Antes de você trazer essa lib para o forum, tem alguma função para adicionar delay na spell - ex : exevo vis lux, efeito sobre o player - 3seg depois spell sai? @ToTopic Sem ofenças \o/? nem que seja ofença paga pal ..... não se fala mal até por que você não sabe "nada" sobre o @Dalvorsn e nem sequer sobre o @Lwkass o Dalvo tem todo direito de falar até por que ele é o cara que ta trazendo "tudo" TUDO de pokemon pro forum, novos systems tem feito por ele sem dizer que ele traz e simplismente não fala "Há cria isso.lua adicionar essa tag lá.. e deu ta feito so editar a seu gosto" ele traz com intuito de ensinar "copia isso e apartir disso faça do seu jeito.. para isso faça isso.. para mais adicione isso.." Ele tem direito sim de pedir sub-mod até por que ele e um cara que aprendeu de script e aprendeu muito rapido (sendo que ele fala que é intermediario) se ele é intermediario eu queria ver um advanced \o @lwkass cara que ta inovando o jeito POO e trazendo diversas maneiras de se ver editar tibiaot - No comments K.ISSO não é ser paga pal e sim "admitir que tem gente querendo sempre melhorar e claro com a melhora vem o "destaque" oque faz com que as pessoas se destaquem ainda mais,diferente de outras que vêem simples ato de bajulação essas não tem metade do cerebro de quem ta simplismente "pedindo para sub-mod" e nem 0,25 de quem ta inovando. Existe uma coisa que chama merecimento, e o lwkass faz por merecer os elogios.²Totalmente Correto- seja lwkass,raposão,urso,iuniX,Dalvorsn e todos do forum que tão ajudando. Share this post Link to post
Lwkass 1 #7 Posted September 6, 2011 Sem mais discussões no tópico. @Geovani: Para adicionar um delay pra sumir depois de um certo tempo, é só adicionar isso na spell: addEvent(doRemoveCondition, 3000, cid, CONDITION_LIGHT) Depois de 3 segundos vai remover a luz Mas vou ver se quando eu for modificar eu adiciono algo desse tipo direto na lib Share this post Link to post
Geovani 0 #8 Posted September 6, 2011 Thanks REP+ Pela lib e pela duvida ^^ Share this post Link to post
Rômulo Souza 14 #9 Posted May 4, 2012 Caramba, to revivendo um tópico extremo antigo. Mas creio que as regras do forum aceita reviver com dúvidas, né? enfim: Eu usando essa lib em talkaction, ele reconhece como mérito de tentativa de subir skill? de ml por exemplo. Share this post Link to post
Lwkass 1 #10 Posted May 30, 2012 Rômulo Souza: Mesmo sendo uma duvida de quase um mes atrás. Não, quando fiz essa lib não coloquei pra upar skill, se quiser, infelizmente, vai ter que adicionar uma linha pra upar ml. Share this post Link to post
Merfolk 0 #11 Posted May 31, 2012 gastou um tempão fazendo uma parada inútil, fico imaginando o tempo que você gasta fazendo coisas uteis! xD Share this post Link to post
Lwkass 1 #12 Posted May 31, 2012 Merfolk: um carro pode ser inútil se você não souber dirigir, muito menos como ligar ou trocar uma marcha. fica ai a dica e ah, qualquer coisinha que eu programe já me é útil :] Share this post Link to post