Jump to content

Lord Henry

Other Languages Moderators
  • Posts

    3,953
  • Joined

  • Last visited

  • Days Won

    177

Everything posted by Lord Henry

  1. Já tentou fazer oq a mensagem pede? Inicie o GTA SA quando essa mensagem aparecer. Basicamente o MTA não está encontrando o GTA SA (não pode ser a versão Definitive). Geralmente quando você instalou ele no lugar errado em vez do caminho padrão.
  2. Você precisa colocar seu user na ACL Group Admin. Caso já tenha feito isso, mostre seu acl.xml
  3. Não é possível setar via script o serial de uma conta. Delete ela e crie outra com o mesmo nome e com o novo serial. Ou então altere manualmente o serial da conta abrindo o banco de dados com o servidor desligado.
  4. Faça uma denúncia formal na Blacklist do MTA. Link aqui. As regras de como enviar a denúncia estão na última aba.
  5. Pra melhorar um pouco o FPS, deixe o dxCreateTexture fora da função, numa variável local. E ali no getElementsByType, faça assim pra pegar só os jogadores que estão sendo sincronizados pelo localPlayer. Não faz sentido pegar player que está muito longe. getElementsByType("player", root, true) Sobre o ângulo estranho, como a imagem sempre ficará voltada para a câmera, então é melhor voltar ao 2D mesmo. Uma coisa que você pode usar para calcular melhor a escala do dxDrawImage, é pegar 3 posições X,Y,Z ao redor da cabeça do jogador, onde começa e termina a imagem. Mas essas posições levam em consideração a rotação da câmera, sendo assim, não adianta simplesmente somar ou subtrair os valores, pois fazendo isso, as posições ficarão relativas ao cenário fixo. Para isso, você precisa criar um objeto qualquer invisível e sem colisão na cabeça do jogador (no osso). Depois disso você deve rotacionar esse objeto para sempre ficar apontado para a câmera utilizando a função útil findRotation3D. (o objeto não pode ser anexado no jogador, ele apenas tem sua posição setada na cabeça dele a cada frame.) Só depois de você ter um objeto invisível e sem colisão na cabeça do jogador sempre apontado para a câmera, utilize getElementMatrix para obter as posições do lado e em cima desse objeto, essas posições você usará no getScreenFromWorldPosition para desenhar o dxDrawImage final. Como eu faria: local texture = dxCreateTexture("Logo.png") -- Cria a textura. local objetos = {} -- Tabela onde os objetos invisíveis vão ficar. local options = { distance = 100, escala = 1, } addEventHandler("onClientRender", root, function() for _, player in pairs(getElementsByType("player", root, true)) do -- Para cada jogador sendo sincronizado por este cliente, faça: if isElement(player) then -- Se o jogador existe, então: (evita erros quando o player desconecta neste frame) if getElementData(player, "imortalp") then -- Se essa elementData não for false, então: local alpha = getElementAlpha(player) local px, py, pz = getElementPosition(player) local camX, camY, camZ = getCameraMatrix() local dist = getDistanceBetweenPoints3D(camX, camY, camZ, px, py, pz) if dist < options.distance then -- Se a distância da câmera para o jogador for menor que o limite, então: local headPosX, headPosY, headPosZ = getPedBonePosition(player, 4) -- Obtém a posição do osso da cabeça do jogador. if headPosX then -- Se obteve uma das posições (significa que obteve as outras também), então: if not isElement(objetos[player]) then -- Se ainda não existe o objeto invisível na cabeça desse jogador, então: objetos[player] = createObject (3003, headPosX, headPosY, headPosZ, 0, 0, 0, true) -- Cria um objeto sem colisão associado ao jogador. setElementAlpha(objetos[player], 0) -- Deixa o objeto invisível. else -- Se já existe o objeto, apenas mantém ele na cabeça do jogador a cada frame. setElementPosition(objetos[player], headPosX, headPosY, headPosZ) end local rx, ry, rz = findRotation3D(headPosX, headPosY, headPosZ, camX, camY, camZ) -- Encontra a rotação relativa do objeto com a câmera. setElementRotation(objetos[player], rx, ry, rz) -- Aponta o objeto para a câmera. local rightX, rightY, rightZ = getPositionFromElementOffset(objetos[player], options.escala / 2, 0, 0) -- Obtém a posição XYZ na direita da cabeça do jogador. local leftX, leftY, leftZ = getPositionFromElementOffset(objetos[player], (options.escala / 2) * -1, 0, 0) -- Obtém a posição XYZ na esquerda da cabeça do jogador. local screenX1, screenY1 = getScreenFromWorldPosition(rightX, rightY, rightZ) local screenX2 = getScreenFromWorldPosition(leftX, leftY, leftZ) local _, screenY3 = getScreenFromWorldPosition(headPosX, headPosY, headPosZ + options.escala) -- Apenas para testes -- dxDrawText("1", screenX1 or 0, screenY1 or 0) -- dxDrawText("2", screenX2 or 0, screenY1 or 0) -- dxDrawText("3", screenX2 or 0, screenY3 or 0) if screenX1 and screenX2 and screenY3 then local width, height = screenX2 - screenX1, screenY1 - screenY3 -- Calcula os tamanhos subtraindo as posições da tela. dxDrawImage(screenX1, screenY3, width, height, texture, 0, 0, 0, tocolor(255, 255, 0, alpha)) -- A imagem precisa ser quadrada, preferencialmente múltipla de 2. (16x16, 32x32, 64x64, 128x128, etc) end end elseif isElement(objetos[player]) then -- Se o jogador não está perto o suficiente e tem o objeto invisível em sua cabeça, então: destroyElement(objetos[player]) -- Destrói o objeto. objetos[player] = nil -- Limpa a variável dele para liberar espaço na memória. end end end end end) addEventHandler("onClientElementStreamOut", root, function() -- Ativa esse evento quando um elemento para de ser sincronizado por este client. if getElementType(source) == "player" then -- Se foi um jogador, então: if isElement(objetos[source]) then -- Se existe o objeto invisível daquele jogador, então: destroyElement(objetos[source]) -- Destrói o objeto. objetos[source] = nil -- Limpa a variável dele para liberar espaço na memória. end end end) -- Funções úteis. function findRotation3D(x1, y1, z1, x2, y2, z2) local rotx = math.atan2 (z2 - z1, getDistanceBetweenPoints2D (x2, y2, x1, y1)) rotx = math.deg(rotx) local rotz = -math.deg(math.atan2(x2 - x1, y2 - y1)) rotz = rotz < 0 and rotz + 360 or rotz return rotx, 0, rotz end function getPositionFromElementOffset(element,offX,offY,offZ) local m = getElementMatrix(element) local x = offX * m[1][1] + offY * m[2][1] + offZ * m[3][1] + m[4][1] local y = offX * m[1][2] + offY * m[2][2] + offZ * m[3][2] + m[4][2] local z = offX * m[1][3] + offY * m[2][3] + offZ * m[3][3] + m[4][3] return x, y, z end
  6. Suas imagens são inacessíveis. Coloque o erro em texto em vez de imagem.
  7. Utilize DxDrawMaterialLine3D (3D) em vez de DxDrawImage (2D). Não precisa usar ipairs quando a ordem dos elementos não importa. Utilize pairs que é levemente mais rápido. for _, player in pairs(getElementsByType("player")) do Se sua elementData só pode ter valores true ou false, não precisa verificar se ela é == true. Neste caso, só isso já serve: if getElementData(player, "imortalp") then -- Se for qualquer valor, passa na condição. Se for false, não passa.
  8. local accountName = getPlayerAccount (thePlayer) -- thePlayer precisa ser definido com algum eventHandler. -- Adicionar jogador numa ACL Group: aclGroupAddObject (aclGetGroup("Policial"), "user."..accountName) -- Remover jogador de uma ACL Group: aclGroupRemoveObject (aclGetGroup("Policial"), "user."..accountName) Obs: Vc ainda deve verificar se o jogador está logado antes de adicionar a conta dele na ACL Group. Se ele estiver deslogado (isGuestAccount) então não deve acontecer nada ao usar o comando.
  9. Não é possível. Esse arquivo é lido ao iniciar o servidor. Se mexer nele com o servidor ligado, ele não vai mudar nada. O que recomendo que você faça é um resource que faça o seguinte: Coloca uma senha no servidor para nenhum novo jogador entrar. Avisa todos os jogadores online com uma mensagem no centro da tela que o servidor será reiniciado e o tempo restante para o restart. Ao zerar o tempo restante, dá kick em todos os jogadores online. Remove a senha do servidor e dá shutdown. Depois faça as alterações no mtaserver.conf, salve e inicie o servidor novamente.
  10. Sugestão de nomes pras texturas: (todas elas são versões apagadas, a versão acesa fica separada numa pasta do resource) emerlights24A.png emerlights24B.png emerlights24C.png emerlights24D.png vehiclelights32Fog.png vehiclelights32Left.png vehiclelights32Rear.png vehiclelights32Right.png Versão acesa: emerlightsOn192.png vehiclelightsOn256.png
  11. Utilize a função útil GetPlayerFromPartialName. Ele converte tanto a pesquisa quanto os nomes dos jogadores em letra minúscula. (vale lembrar que funções úteis vc precisa incluir o código-fonte dela no seu script para funcionar)
  12. Para isso utiliza-se um shader simples de substituição de textura. O veículo no entanto precisa ser adaptado, as texturas das luzes precisam ter nomes diferentes da original, além de serem incluídos no TXD. Dai o shader basicamente substitui a textura apagada pela versão acesa. // replace.fx texture Tex0; // Textura que um script client.lua vai enviar por meio de um dxSetShaderValue(shader, "Tex0", texture) technique simple // Técnica simples que roda em qualquer PC. { pass P0 { Texture[0] = Tex0; // Substitui a textura pela Tex0. ColorOp[0] = SelectArg1; // Opcional. Faz a textura ficar muito clara. Delete essa linha se não quiser. } }
  13. Testei e está funcionando normalmente. addEventHandler ("onPlayerWeaponFire", root, function (weapon, endX, endY, endZ, hitElement, startX, startY, startZ) createExplosion(endX, endY, endZ, 2, source) iprint("teste") end) No entanto, você deve notar que a explosão não acontece onde o tiro colidiu e sim onde seria o final do tiro. Por exemplo, se você atira numa coisa a explosão normalmente vai acontecer atrás dessa coisa, onde o tiro iria acabar. Se você quer que a explosão aconteça exatamente onde o tiro colidiu (bala explosiva), você deve usar a versão client-side para isso. addEventHandler ("onClientPlayerWeaponFire", root, function (weapon, ammo, ammoInClip, hitX, hitY, hitZ) createExplosion(hitX, hitY, hitZ, 2) end)
  14. @portoxx se refere a isso?
  15. for k, player in pairs(getElementsByType("player", root, true)) do if (player ~= localPlayer) and (getElementAlpha (player) ~= 0) then -- Se o jogador não for ele mesmo e também não estiver invisível, então:
  16. Olá. Não há nada que possamos fazer. Apenas não jogue mais neste servidor.
  17. Aqui está: (client-side) -- Obs: Essa função ativa mesmo com o veículo blindado. -- Obs2: Essa função ativa mesmo que não haja dano no veículo, por exemplo ao arranhar o assoalho do veículo em algo. -- Se quer que a função ative somente ao dar dano no veículo, utilize onClientVehicleDamage (não ativará se o veículo estiver blindado) addEventHandler("onClientVehicleCollision", root, function() if source == getPedOccupiedVehicle(localPlayer) then -- Se o veículo que bateu for o que o localPlayer estiver dentro, então: local sx, sy, sz = getElementVelocity (source) -- Obtém a velocidade x, y, z do veículo. local kmhs = math.floor(((sx^2 + sy^2 + sz^2)^(0.5)*(1.61))*100) -- Calcula e converte a velocidade em km/h if kmhs >= 70 then -- Se estava a 70 km/h ou mais quando colidiu, então: local random = math.random(100) -- Gera um número pseudo-aleatório entre 1 e 100. print("Bateu com força. Random gerado: "..random) if random <= 40 then -- Se o número gerado for menor ou igual a 40, então: (40% de chance) local fl, rl, fr, rr = getVehicleWheelStates (source) -- Obtém o estado de todos os pneus do veículo. local pneus = {fl, rl, fr, rr} -- Cria uma tabela com os estados de cada pneu. local tire = math.random(4) -- Gera um número pseudo-aleatório entre 1 e 4. Vai determinar qual pneu será furado. if pneus[tire] == 0 then -- Se o estado do pneu escolhido for inflado, então: pneus[tire] = 1 -- Muda esse estado para furado. outputChatBox("Pneu "..tire.." do seu carro furou!") end setVehicleWheelStates (source, pneus[1], pneus[2], pneus[3], pneus[4]) -- Seta o novo estado dos pneus. end end end end) Obs: Uma batida pode furar vários pneus, pois essa função é ativada várias vezes numa única batida. Se quiser evitar, adicione um timer anti-spam na função para não funcionar durante X segundos após furar um pneu.
  18. onClientVehicleCollision não funciona server-side só funciona client-side.
  19. 2 coisas que vc precisa estar atento: Você declarou os parâmetros do setVehicleWheelStates incorretamente. Da forma que você fez, ele vai definir um estado aleatório do pneu dianteiro esquerdo, os demais nunca serão alterados pois sempre estarão no estado 0 (inflados). Esteja ciente de que onClientVehicleCollision não detecta colisões caso o objeto do cenário que o veículo bateu seja destruído. Ou seja, não detecta ao destruir postes, nem cercas ao colidir.
  20. De acordo com a Wiki do setElementBonePosition é necessário que você use a função dentro de um onClientPedsProcessed.
  21. Eu testei e funciona. Ele inicia o fogo para explodir, depois conserta, depois inicia o fogo e fica nesse loop até você descapotar o carro. Mas não explode.
  22. Tente isso: -- SERVER-SIDE function vehicleHPVerify(loss) if getElementHealth(source) - loss < 300 then -- setVehicleDamageProof (source, true) -- Neste caso não funciona. Faz com que este evento não seja mais acionado. setVehicleEngineState (source, false) setElementHealth(source, 300) local thePlayer = getVehicleController (source) if thePlayer then outputChatBox ("Seu veículo quebrou o motor. Chame um mecânico.", thePlayer) end cancelEvent() end end addEventHandler ("onVehicleDamage", root, vehicleHPVerify) function antiVehicleEngine (cmd) if cmd == "motor" then local theVehicle = getPlayerOccupiedVehicle (source) if theVehicle then if getPedOccupiedVehicleSeat (source) == 0 then if getElementHealth (theVehicle) <= 300 then setVehicleEngineState (theVehicle, false) cancelEvent() end end end end end addEventHandler ("onPlayerCommand", root, antiVehicleEngine) addEventHandler("onVehicleEnter", root, function(thePlayer) if getElementHealth(source) <= 300 then setVehicleEngineState(source, false) outputChatBox ("Este veículo está com o motor quebrado. Chame um mecânico.", thePlayer) end end)
×
×
  • Create New...