Ir para conteúdo
Banner com Efeitos

Featured Replies

Postado
  • 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

giphy.gif

 

 

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 por skulls (veja o histórico de edições)

  • Respostas 15
  • Visualizações 1.2k
  • Created
  • Última resposta

Top Posters In This Topic

Most Popular Posts

  • Obrigado cara! Sempre me incomodou a facilidade de acertar o alvo no tíbia. Dessa forma fica mais facil de desviar e exige mais dedos do caster, xD.

  • Noamor getinterceptions tem um return getoposend na ultima linha. Da um enter pra esse end cair pra baixo.

Postado

51mutNo.png 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.

  • 3 weeks later...

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.

Visitante
Responder

Quem Está Navegando 0

  • Nenhum usuário registrado visualizando esta página.

Estatísticas dos Fóruns

  • Tópicos 96.9k
  • Posts 519.7k

Informação Importante

Confirmação de Termo