Postado Fevereiro 15, 2016 9 anos Este é um post popular. Boa noite galera, tudo bem? Venho compartilhar com vocês hoje um sisteminha que desenvolvi para as magias do tipo "shoot'. Foi feito inicialmente para funcionar com magias que usam a posição do mouse como referência e adaptei para cipclientes poderem usar em runas e magias de tiro. O funcionamento do sistema é simples: Ao usar uma runa ou castar uma magia "shoot" com esse sistema criaturas e objetos no caminho irão interferir na trajetória, isto é, receberão o combate no lugar do alvo inicial. Ilustrativo: Spoiler Bom, vamos ao que interessa. Vá em data/lib/ e crie um novo arquivo chamado spellsLib.lua (pode-se utilizar também o arquivo spells.lua contido em data/spells/lib). Dentro dele inclua as seguintes funções: IsWalkable (by Nord) Spoiler function isWalkable(pos, creature, proj, pz)-- by Nord if getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid == 0 then return false end if getTopCreature(pos).uid > 0 and creature then return false end if getTileInfo(pos).protection and pz then return false, true end local n = not proj and 3 or 2 for i = 0, 255 do pos.stackpos = i local tile = getTileThingByPos(pos) if tile.itemid ~= 0 and not isCreature(tile.uid) then if hasProperty(tile.uid, n) or hasProperty(tile.uid, 7) then return false end end end return true end GetPositionsAround (by Skulls) Spoiler function getPositionsAround(pos) return { [1] = {x = pos.x, y = pos.y - 1, z = pos.z, stackpos = 0}, [2] = {x = pos.x + 1, y = pos.y - 1, z = pos.z, stackpos = 0}, [3] = {x = pos.x + 1, y = pos.y, z = pos.z, stackpos = 0}, [4] = {x = pos.x + 1, y = pos.y + 1, z = pos.z, stackpos = 0}, [5] = {x = pos.x, y = pos.y + 1, z = pos.z, stackpos = 0}, [6] = {x = pos.x - 1, y = pos.y + 1, z = pos.z, stackpos = 0}, [7] = {x = pos.x - 1, y = pos.y, z = pos.z, stackpos = 0}, [8] = {x = pos.x - 1, y = pos.y - 1, z = pos.z, stackpos = 0} } end CheckInterceptions (by Skulls) Spoiler function checkInterceptions(cid, pos, toPos, cond) local p = pos local dir = getDirectionTo(pos, toPos) local d = getDistanceBetween(pos, toPos) if dir < SOUTHWEST then while d > 0 do dir = getDirectionTo(p, toPos) p = getPosByDir(p, dir, 1) d = getDistanceBetween(p, toPos) if not isWalkable(p, true, true, true) then return p end end else local creature = cond or true local nextPositions = {pos} local tam = 1 while d > 0 do local i = tam if tam > 2 then tam = 2 end local positions = getPositionsAround(nextPositions[tam]) if (dir == SOUTHWEST and (nextPositions[tam].x < toPos.x or nextPositions[tam].y > toPos.y)) or (dir == NORTHEAST and (nextPositions[tam].x > toPos.x or nextPositions[tam].y < toPos.y)) then positions = getPositionsAround(nextPositions[tam+1]) end if dir == SOUTHEAST and (nextPositions[tam].x > toPos.x or nextPositions[tam].y > toPos.y) or (dir == NORTHWEST and (nextPositions[tam].x < toPos.x or nextPositions[tam].y < toPos.y)) then positions = getPositionsAround(nextPositions[tam-1]) end d = getDistanceBetween(nextPositions[tam], toPos) tam = 0 if d == 0 then break end local sum = 0 if dir == SOUTHWEST then sum = 4 elseif dir == SOUTHEAST then sum = 2 elseif dir == NORTHWEST then sum = 6 elseif dir == SOUTHEAST then sum = 0 end for j=1, 3 do local index = j+sum local check = 0 if index > #positions then index = 1 end if dir == SOUTHWEST and (positions[index].x < toPos.x or positions[index].y > toPos.y) or (dir == SOUTHEAST and (positions[index].x > toPos.x or positions[index].y > toPos.y)) or (dir == NORTHWEST and (positions[index].x < toPos.x or positions[index].y < toPos.y)) or (dir == NORTHEAST and (positions[index].x > toPos.x or positions[index].y < toPos.y)) then check = 1 end local dx, dy = math.abs(positions[index].x - toPos.x) , math.abs(positions[index].y - toPos.y) if dx == dy and (positions[index].x == pos.x or positions[index].y == pos.y) and ((getDistanceBetween(positions[index], pos) > 1 and getDistanceBetween(positions[index], toPos) > 1) or getDistanceBetween(positions[index], pos) > 5 and getDistanceBetween(positions[index], toPos) > 0)then check = 1 end if getDistanceBetween(positions[index], toPos) == 0 then return toPos end if getDistanceBetween(positions[index], toPos) < d and check == 0 then if not isWalkable(positions[index], creature, true, true) then return positions[index] end tam = tam + 1 nextPositions[tam] = positions[index] end end end end return toPos end SetSpellTarget (by Skulls) Spoiler function setSpellTarget(cid, var) if var.pos then var.pos = checkInterceptions(cid, getPlayerPosition(cid), var.pos) end if isCreature(var.number) then var.pos = checkInterceptions(cid, getPlayerPosition(cid), getCreaturePosition(var.number))--getMousePos(cid) var.pos.stackpos = STACKPOS_TOP_MOVABLE_ITEM_OR_CREATURE if getDistanceBetween(var.pos, getCreaturePosition(var.number)) ~= 0 and isCreature(getThingFromPos(var.pos).uid) then var.number = getThingFromPos(var.pos).uid elseif not isCreature(getThingFromPos(var.pos).uid) then var.number = 0 doPlayerSendCancel(cid, "Target not reachable.") end end return var end Feito isso, está tudo configurado. Basta agora adicionar às magias que você queira. Abra o .lua da magia, por exemplo death strike.lua. Lá você terá, entre outras coisas, a função onCastSpell como abaixo: function onCastSpell(cid, var) return doCombat(cid, combat, var) end Substitua isso por: function onCastSpell(cid, var) return doCombat(cid, combat, setSpellTarget(cid, var)) end Pronto, a sua magia "Exori Mort" será parada por criaturas ou obstáculos (qualquer item que não seja móvel). Bom é isso, espero que gostem. Queria agradecer ao @xWhiteWolf e ao Caronte pelas ajudas tentando entender alguns parâmetros e me dando algumas luzes. Ao Lobo, fica ainda, um agradecimento especial pela maravilhosa lib dele *-*. Abraços, Editado Março 3, 2016 9 anos por skulls (veja o histórico de edições)
Postado Fevereiro 15, 2016 9 anos Parabéns, seu tópico de conteúdo foi aprovado! Muito obrigado pela sua contribuição, nós do Tibia King agradecemos. Seu conteúdo com certeza ajudará à muitos outros, você recebeu +1 REP.
Postado Fevereiro 15, 2016 9 anos Aqui o CheckInterceptions e o SetSpellTarget estão com o mesma coisa que eu falei pra você no outro fórum, aquele errinho no final do script.
Participe da conversa
Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.