Jump to content

Munição traçante para MTA


Recommended Posts

Estou fazendo um traçante para MTA, porem... O dx é criado da ponta da arma "getPedWeaponPuzzlePosition" até o final da bala disparada, como todos sabem, o traçante é um efeito/luz que acompanha a bala. Porem não sei como fazer isso, vi que é com uma interpolação, porem infelizmente eu não sei usar isso, está aqui meu código

 

 

function OnPlayerFire(w,a,aC,hX,hY,hZ,hE)
 local sx,sy,sz = getPedWeaponMuzzlePosition(source)
 Position = {sx,sy,sz,hX,hY,hZ} 
 removeEventHandler("onClientRender",root,onRender)
 addEventHandler("onClientRender",root,onRender)
setTimer ( function()
        removeEventHandler("onClientRender",root,onRender)
    end, 100, 1 )
end 
addEventHandler("onClientPlayerWeaponFire",root,OnPlayerFire)

function onRender() 
 if Position then 
  local startX,startY,startZ,endX,endY,endZ = unpack(Position)
  dxDrawLine3D( startX,startY,startZ,endX,endY,endZ,tocolor(255,162,0,150),2.3) 
 end 
end

Link to comment
  • Other Languages Moderators

O interpolateBetween é uma função onde você consegue obter o "meio" de dois valores inserindo o começo e o final e especificando qual a posição deste meio entre 0 e 1.
Por exemplo: Se você tem a coordenada do início do trajeto da bala e a coordenada do final da bala (coordenada onde ela atingiu), se você especificar o valor 0.5 entre eles em um interpolateBetween, você vai obter a coordenada do meio entre elas.

local laserShoots = {} -- Tabela que vai armazenar as infos de cada laser.
local contador, limite = 0, 20 -- Índice do laser atual | Número máximo de lasers que este jogador pode ver ao mesmo tempo.
-- Ao atingir este limite, os lasers mais antigos serão substituídos pelos novos. Limites altos demais causarão lag.
local tamanho, velocidadeLaser = 0.05, 0.16 -- Comprimento do laser | Velocidade do laser. (o tiro real continua na mesma velocidade)

function onPlayerShoot(w,a,aC,hX,hY,hZ,hE)
    local sx, sy, sz = getPedWeaponMuzzlePosition(source) -- Obtém a posição de onde sai o tiro.
    if (sx) then -- Se o jogador atirou com uma arma de fogo (existe a posição do início do tiro), então:
        contador = contador + 1 -- Contador de 0 vai pra 1, depois vai pra 2 e assim por diante.
        if (contador > limite) then -- Se o contador passou do limite, então volta pro 1.
            contador = 1
        end
        laserShoots[contador] = {0, sx, sy, sz, hX, hY, hZ} -- Adiciona as posições de início e final do tiro. O zero indica a posição do tiro ainda não percorreu seu traçado, 0 é no começo e 1 é no final.
    end
end 
addEventHandler("onClientPlayerWeaponFire", root, onPlayerShoot) -- Ativa essa função quando algum player atirar.
addEventHandler("onClientPedWeaponFire", root, onPlayerShoot) -- Ativa essa função quando algum NPC atirar. (opcional)

function renderLaserShoots()
    for i, tiro in pairs (laserShoots) do -- Para cada tiro faça:
        local percorrido, startX, startY, startZ, endX, endY, endZ = unpack(tiro) -- Obtém as infos do tiro.
        percorrido = percorrido + velocidadeLaser -- Adiciona a velocidade ao percorrido. Isso faz com que quanto maior a velocidade, mais o laser percorre a cada frame.
        if (percorrido > 1) then -- Se o laser chegou ao seu destino, então:
            laserShoots[i] = nil -- Remove ele da tabela de lasers.
        else -- Se o laser ainda não chegou no destino, então:
            laserShoots[i] = {percorrido, startX, startY, startZ, endX, endY, endZ} -- Atualiza a nova posição percorrida do laser na tabela.
            local px1, py1, pz1, px2, py2, pz2
            
            if (percorrido - tamanho >= 0) then -- Isso serve para dar comprimento ao laser, em vez de ser um ponto, ele será um traço.
                px1, py1, pz1 = interpolateBetween (startX, startY, startZ, endX, endY, endZ, percorrido - tamanho, "Linear") -- Obtém a posição um pouco atrás do tiro.
            else
                px1, py1, pz1 = interpolateBetween (startX, startY, startZ, endX, endY, endZ, 0, "Linear") -- Considera como 0 as posições abaixo de 0 para evitar erros.
            end
            
            if (percorrido + tamanho <= 1) then
                px2, py2, pz2 = interpolateBetween (startX, startY, startZ, endX, endY, endZ, percorrido + tamanho, "Linear") -- Obtém a posição um pouco na frente do tiro.
            else
                px2, py2, pz2 = interpolateBetween (startX, startY, startZ, endX, endY, endZ, 1, "Linear") -- Considera como 1 as posições acima de 1 para evitar erros.
            end
            dxDrawLine3D (px1, py1, pz1, px2, py2, pz2, tocolor(0,162,0,150), 2.3) -- Cria um traço entre a posição um pouco na frente e um pouco atrás da posição simulada do tiro com a cor e espessura especificados. (cria o laser)
        end
    end
end
addEventHandler("onClientRender", root, renderLaserShoots) -- Executa essa função a cada frame.

Caso queira testar com um NPC:

Adicione isso no final do client-side:

-- ============ Apenas para testes ===========
setTimer (function ()
    for i, thePed in pairs (getElementsByType("ped")) do -- Para cada NPC, faça:
        if (getElementData (thePed, "autoShot")) then -- Se o NPC tem essa elementData, então:
            setPedAimTarget (thePed, 2488, -1670, 12.3) -- Faz ele mirar no meio do chão da Grove Street. (se não tiver isso, os lasers não aparecem pois não existe posição final do tiro)
            setPedControlState (thePed, "fire", true) -- Faz ele ficar atirando.
        end
    end
end, 500, 1) -- Executa isso meio segundo depois que iniciar este resource.


E coloque isso server-side:

-- ============== Apenas para testes =================
randomPed = createPed (0, 2510, -1670, 13.55, 90) -- Cria um NPC na Grove Street.
giveWeapon (randomPed, 30, 9999, true) -- Dá uma AK-47 com 9999 de munição pra ele.
setElementData (randomPed, "autoShot", true) -- Coloca essa data nele só pra diferenciá-lo de outros NPCs.

 

Edited by Lord Henry
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...