-
Posts
4,003 -
Joined
-
Last visited
-
Days Won
184
Everything posted by Lord Henry
-
Problema com hands de drift farmar infinitamente
Lord Henry replied to Maaster's topic in Programação em Lua
Se você tiver um velocímetro qualquer, é só detectar quando o jogador está com velocidade baixa demais e cancelar o drift. Se não quer fazer por meio da velocidade, crie um marker invisível e fique setando a posição dele no veículo a cada segundo. Se o veículo do jogador não sair desse marker depois de tanto tempo, cancela o contador de drift. Se o veículo do jogador estiver em movimento, ele sempre vai ficar saindo de dentro desse marker, se o veículo estiver parado farmando drift, ele não vai sair de dentro do marker e dai vc detecta ele. Obs: Faça tudo client-side. -
onClientResourceStart
-
Faça o veículo com texturas customizadas nas setas. (a textura pode ser igual, mas tem que ter nome diferente). Nas setas esquerdas, coloquei uma textura com nome vehiclelights32Left, nas setas da direita, vehiclelights32Right. Então o shader basicamente só precisa substituir essas texturas pela versão acesa quando for pra acender e pela versão normal quando for apagar. Sobre o shader.fx usar, basta usar o shader simples de substituir texturas. Exemplo na Wiki: https://wiki.multitheftauto.com/wiki/Element/Shader#Simple Obs: Obviamente as texturas customizadas precisam estar incluídas no TXD do veículo.
-
Utilize a função útil PlayVideo
-
Também já percebi essa limitação. Mas nunca soube de onde vem. Talvez seja do próprio GTA.
-
Verificar se elemento possui element data
Lord Henry replied to Doongogar's topic in Programação em Lua
@SciptNovato na nova atualização 1.6 do MTA, a função getAllElementData passa a funcionar também client-side. -
Server-side local pendentes = {} -- Lista de players que tem solicitação de skin pendente. Formato: [playerElement] = skinID, local timersPendentes = {} -- Lista com os timers de cada solicitação. addCommandHandler("mudarskin", function(thePlayer, cmd, playerName, skinID) -- Comando para enviar a solicitação para o jogador. if not playerName or not skinID then outputChatBox("Sintaxe: /mudarskin <NomeJogador> <skinID>", thePlayer) return -- Se faltou especificar o nome do jogador ou o id da skin no comando, cancela a função e nada acontece. end local otherPlayer = getPlayerFromPartialName(playerName) -- Obtém o jogador pelo nome. if otherPlayer then -- Se encontrou o jogador, então: if pendentes[otherPlayer] then -- Se o jogador já tem uma solicitação na lista, então: outputChatBox("Este jogador já tem uma solicitação de skin pendente.", thePlayer) else -- Se o jogador ainda não tem uma solicitação na lista, então: pendentes[otherPlayer] = tonumber(skinID) -- Adiciona a solicitação dele na lista. outputChatBox("Você recebeu uma solicitação de skin "..skinID..". Digite /aceitarskin ou /recusarskin", otherPlayer) -- Manda isso pra ele. timersPendentes[otherPlayer] = setTimer(function() -- Depois de 10 segundos, expira a solicitação. pendentes[otherPlayer] = nil -- Remove a solicitação da lista. timersPendentes[otherPlayer] = nil -- Anula a variável do timer, removendo da lista de timers. outputChatBox("O jogador '"..playerName.."' não respondeu a sua solicitação e ela expirou.", thePlayer) end, 10000, 1) end else -- Se não encontrou o jogador pelo nome, então: outputChatBox("Não foi encontrado nenhum jogador com o nome '"..playerName.."'", thePlayer) end end) function getPlayerFromPartialName(name) -- Função útil que faz o mesmo que getPlayerFromName, mas o nome não precisa ser exato. local name = name and name:gsub("#%x%x%x%x%x%x", ""):lower() or nil if name then for _, player in ipairs(getElementsByType("player")) do local name_ = getPlayerName(player):gsub("#%x%x%x%x%x%x", ""):lower() if name_:find(name, 1, true) then return player end end end end function changeSkin(thePlayer, cmd) -- Função de aceitar ou recusar solicitações. if pendentes[thePlayer] then -- Se o jogador que executou o comando tem alguma solicitação na lista, então: if cmd == "aceitarskin" then -- Se ele usou o comando /aceitarskin então: setElementModel (thePlayer, pendentes[thePlayer]) -- Muda a skin dele. outputChatBox("Você aceitou a solicitação de skin.", thePlayer) else -- Se ele usou o comando /recusarskin então: outputChatBox("Você recusou a solicitação de skin.", thePlayer) end pendentes[thePlayer] = nil -- Remove a solicitação da lista. if isTimer(timersPendentes[thePlayer]) then -- Se existe o timer da solicitação, então: killTimer(timersPendentes[thePlayer]) -- Cancela o timer da solicitação. timersPendentes[thePlayer] = nil -- Remove o timer da lista de timers. end else -- Se o jogador que executou o comando não tem nenhuma solicitação na lista, então: outputChatBox("Você não tem nenhuma solicitação de skin para aceitar ou recusar.", thePlayer) end end addCommandHandler("aceitarskin", changeSkin) addCommandHandler("recusarskin", changeSkin)
-
getRootElement Retirado na nova versão
Lord Henry replied to Doongogar's topic in Programação em Lua
Por enquanto segue funcionando normalmente. Mas eu trocaria todos eles por root logo pois fica mais limpo o script. -
Randomizar resultados com mais eficiência
Lord Henry replied to Doongogar's topic in Programação em Lua
Você também pode usar a função útil math.randomDiff para nunca repetir o mesmo valor gerado anteriormente. Um dos exemplos inclusive faz ele gerar um valor numa série sem repetir nenhum até que a sequência inteira já tenha sido gerada. -
Multi Theft Auto: San Andreas 1.6 is ready for testing!
Lord Henry replied to myonlake's topic in News
I'm gonna test it right now. ?- 32 replies
-
- mtasa
- mtasa 1.6.x
-
(and 3 more)
Tagged with:
-
Pode reagir sim nos tópicos antigos, só é considerado reviver tópico se você comentar mais alguma coisa. Você também pode solicitar que tranquem o tópico depois que sua dúvida foi resolvida. Neste caso seria justificável você reviver o tópico para solicitar que tranquem ele. Mas somente se o tópico for seu.
-
Retangulos iguais com posições diferentes
Lord Henry replied to Doongogar's topic in Programação em Lua
Ali o i do for é o índice do retângulo. Se você quer que ao clicar no primeiro retângulo da tabela faça tal coisa, você coloca isso: if i == 1 then -- Code end Depois elseif i == 2 then pro segundo retângulo. E assim por diante nos próximos retângulos. -
Retangulos iguais com posições diferentes
Lord Henry replied to Doongogar's topic in Programação em Lua
Tipo assim: local screen = Vector2(guiGetScreenSize()) -- Obtém a resolução do jogador. retangulos = { -- posX, posY, tamanhoX, tamanhoY {screen.x/2 - 100, screen.y/2 - 100, 200, 20}, {screen.x/2 - 100, screen.y/2 - 60, 200, 20}, {screen.x/2 - 100, screen.y/2 - 20, 200, 20}, {screen.x/2 - 100, screen.y/2 + 20, 200, 20}, {screen.x/2 - 100, screen.y/2 + 60, 200, 20}, {screen.x/2 - 100, screen.y/2 + 100, 200, 20}, } function isMouseInPosition (x, y, width, height) -- Função útil. if (not isCursorShowing()) then return false end local sx, sy = guiGetScreenSize() local cx, cy = getCursorPosition() local cx, cy = (cx * sx), (cy * sy) return ((cx >= x and cx <= x + width) and (cy >= y and cy <= y + height)) end function renderPanel() -- Renderiza o painel. local cx, cy = getCursorPosition() for _, infos in pairs(retangulos) do -- Para cada item da tabela retangulos, faça: local x, y, sizeX, sizeY = unpack(infos) -- Obtém cada valor desse item e separa numa variável. if isMouseInPosition (x, y, sizeX, sizeY) then -- Se o mouse está em cima deste retângulo, então: dxDrawRectangle (x, y, sizeX, sizeY, 0xFFFFFFFF, true) -- Retângulo selecionado branco. else dxDrawRectangle (x, y, sizeX, sizeY, 0xFF0000FF, true) -- Retângulo normal azul. end end end addCommandHandler("eae", function(cmd) -- Mostra/oculta o painel. showCursor(not isCursorShowing()) if isCursorShowing() then addEventHandler("onClientRender", root, renderPanel) else removeEventHandler("onClientRender", root, renderPanel) end end) addEventHandler("onClientClick", root, function(button, state) -- Função que mostra qual botão foi clicado. if button == "left" and state == "down" then for i, infos in pairs(retangulos) do local x, y, sizeX, sizeY = unpack(infos) if isMouseInPosition (x, y, sizeX, sizeY) then outputChatBox("Você clicou no botão "..i) break -- Não precisa verificar os demais botões, pois já achou o que foi clicado. end end end end) -
Você pode pegar o colorPicker do painel F1 (freeroam). (deixe os arquivos dele dentro de uma pasta chamada "colorpicker" e deixe essa pasta dentro do seu resource) Aqui estão os arquivos dele: (clique com o botão direito em cima da imagem e depois vá em "Salvar como") Aqui está a parte que você precisa incluir no meta.xml do seu resource: <script src="colorpicker/colorpicker.lua" type="client" /> <file src="colorpicker/palette.png" /> <file src="colorpicker/alpha.png" /> E por fim, aqui está um exemplo que eu fiz para abrir, usar e fechar o colorPicker. client.lua (coloquei dentro de spoiler pq o código ficou grande) server.lua addEvent("getColorsFromClient", true) addEventHandler("getColorsFromClient", root, function(r1, g1, b1, r2, g2, b2, r3, g3, b3, r, g, b) if isElement(source) then setVehicleColor(source, r1, g1, b1, r2, g2, b2, r3, g3, b3) setVehicleHeadLightColor(source, r, g, b) end end) Resumo de funções usadas e sua utilidade: colorPicker.isSelectOpen() Retorna true se a janela do colorPicker está aberta e retorna false caso contrário. Não precisa de parâmetros. colorPicker.setValue() Seta uma cor RGBA na janela, use isso antes de abrir a janela se não quiser que ela abra na cor vermelha (padrão). Precisa de um único parâmetro que é uma tabela com os valores {r, g, b, a} respectivamente. colorPicker.updateTempColors() Retorna 4 valores inteiros, RGBA respectivamente. É a cor que está na janela do colorPicker. Basicamente é um getValue() da janela. Precisa estar dentro de um onClientRender para ficar obtendo a posição atual da seleção na janela. Não precisa de parâmetros. colorPicker.openSelect() Mostra a janela do colorPicker. (ela já foi criada ao iniciar o resource, mas fica oculta até ser chamada) Precisa ter um showCursor(true) antes para mostrar o ponteiro do mouse e interagir com o colorPicker. Não precisa de parâmetros. colorPicker.closeSelect() Oculta a janela do colorPicker. (ela não é destruída, apenas ocultada) Precisa ter um showCursor(false) depois para ocultar o ponteiro do mouse. A não ser que no seu resource tenha outra janela para interagir e por isso não precisaria ocultar o ponteiro ainda. Essa função é chamada automaticamente se clicar fora da janela do colorPicker. Não precisa de parâmetros. OBS: Esse colorPicker foi editado por Lord Henry para tradução e para desabilitar a cor 4 que não é utilizada.
-
passar a conta do jogador para o client
Lord Henry replied to Doongogar's topic in Programação em Lua
Não. Depende dos ifs e elses a quem eles pertencem. É comum eles ficarem em forma de escada no final das funções mas não é uma regra. -
-- Server-side addCommandHandler("tpcord", function(thePlayer, cmd, x, y, z) if not x or not y or not z then -- Se alguma coordenada não for declarada junto ao comando, então: outputChatBox("Erro de sintaxe: /tpcord <posX> <posY> <posZ>", thePlayer) return end local veh = getPedOccupiedVehicle(thePlayer) -- veh recebe o veículo que o jogador está. Será false se o jogador não estiver em um veículo. if veh then -- Se o jogador está em um veículo, então: setElementPosition(veh, tonumber(x), tonumber(y), tonumber(z)) -- Teleporta o veículo para essas coordenadas. -- OBS: tonumber converte o texto do comando para número. else -- Se o jogador não está em um veículo, então: setElementPosition(thePlayer, tonumber(x), tonumber(y), tonumber(z), true) -- Teleporta o jogador para essas coordenadas. -- OBS: O true serve para cancelar qualquer animação que o jogador esteja fazendo para evitar bugs. end end) Obs: Não use vírgulas no comando. Cada coordenada é separada por espaço.
- 1 reply
-
- 1
-
-
passar a conta do jogador para o client
Lord Henry replied to Doongogar's topic in Programação em Lua
Configure seu editor de código para sempre indentar com espaços ao apertar a tecla TAB. No notepad++ por exemplo dá pra fazer isso. Passo a passo de como indentar a função do meio: -
Sobre o type="shared" e a chamada da ACL
Lord Henry replied to Dekonpriv's topic in Programação em Lua
@Dekonpriv qualquer variável que você criar no arquivo shared.lua poderá ser lido tanto nos arquivos client.lua e no server.lua. Desde que você não crie a variável como local. É como se vc estivesse criando essa variável também no client.lua e no server.lua. -
Ativar colisão após o player parar de encostar no outro
Lord Henry replied to Doongogar's topic in Programação em Lua
Você precisa verificar se o player que entrou/saiu do marker é o localPlayer, senão quando um outro player aleatório entrar num marker, vai ativar neste client também e no client dos outros. Também dá pra juntar as duas funções numa só, já que são quase iguais e só mudam 1 linha. MarkerHP = createMarker(326.289, -1514.27, 36.039 - 1, "cylinder", 5, 255, 255, 255, 20) -- Não é necessário coordenadas com mais de 3 decimais. function MorteColisaoDesabilitar(thePlayer) if thePlayer == localPlayer then -- Evita de ativar essa função quando outro jogador próximo entrar/sair do marker. for _, players in pairs(getElementsByType("player")) do -- Não é necessário o loop ser com ipairs, pois a ordem dos players não importa nem seu índice. if players ~= localPlayer then -- Evita de mexer na colisão de si mesmo contra si mesmo. if eventName == "onClientMarkerHit" then -- As funções dos dois eventos fazem quase a mesma coisa, então diferenciamos apenas aqui. setElementCollidableWith(localPlayer, players, false) elseif eventName == "onClientMarkerLeave" then -- Aqui poderia ser apenas um else, mas deixei assim para facilitar o entendimento. setElementCollidableWith(localPlayer, players, true) end end end end end addEventHandler("onClientMarkerHit", MarkerHP, MorteColisaoDesabilitar) addEventHandler("onClientMarkerLeave", MarkerHP, MorteColisaoDesabilitar) -
Sua imagem está inacessível, na próxima vez upe ela no imgur e cole o link direto dela aqui.
-
local bases = { -- ["comando"] = {x, y, z, r, "nome"}, ["tpbloods"] = {2219.984, -1143.273, 25.797, 353.328, "Bloods"}, ["tpgrove"] = {2463.633, -1659.423, 13.311, 88.373, "Grove"}, ["tpcrips"] = {2183.58, -1761.268, 13.375, 359.602, "Crips"}, ["tpsiliciana"] = {2418.157, -2009.204, 13.396, 90.592, "Siliciana"}, } function teleBases(cmd, thePlayer) if isObjectInACLGroup("user." ..getAccountName(getPlayerAccount(thePlayer)), aclGetGroup("Staff")) then if getElementData(thePlayer, "Expediente-STAFF") == "Sim" then if not Flying[thePlayer] then Flying[thePlayer] = true setElementAlpha(thePlayer, 0) triggerClientEvent(thePlayer, "onClientFlyToggle", thePlayer) end local x, y, z, r, nome = unpack(bases[cmd]) setElementPosition(thePlayer, x, y, z) setElementRotation(thePlayer, 0, 0, r) showInfobox(thePlayer, "Você teleportou para a base "..nome, "success") else atendimento(thePlayer) end end end for cmd,item in pairs(bases) do addCommandHandler(cmd, teleBases) end ---------------------------------------------------------------------------------------------------------------------------- function showInfobox(element, message, tipo) exports["[HYPE]NOTIFY"]:addNotification(element, message, tipo) end atendimento = function (element) return triggerClientEvent(element, "HypeNotify", element, "Você não está em modo atendimento use /pro", "error") end Fiz de cabeça, não testado.
-
Tópico movido para a seção de Programação Lua. Na próxima vez, poste na área correta.
-
Verificar se elemento possui element data
Lord Henry replied to Doongogar's topic in Programação em Lua
ElementDatas só serão nil se você setar esse valor nele. ElementDatas que não existem, não vão aparecer ali no getAllElementData. Se você quer que tal elementData exista mas não esteja sendo usada, normalmente definimos valor false nela. Se for o caso de setar false na data, você faria a condição ali assim: if objeto then -- É o mesmo que if objeto ~= false then -
tutorial A diferença entre pairs e ipairs
Lord Henry replied to Lord Henry's topic in Tutoriais em geral
CURIOSIDADES Em questão de performance, a diferença entre eles é irrelevante. Mas se considerarmos casos extremos de tabelas gigantes com milhares de itens, a execução do pairs é um pouco mais leve do que ipairs, visto que ele não precisa obedecer ordem nenhuma em sua execução, enquanto que o ipairs precisa sempre verificar a cada execução se o próximo índice existe na tabela inteira. Por esse motivo, se você for obcecado por otimização, prefira usar o pairs. Para saber quantos itens uma tabela possui, geralmente usamos #NomeDaTabela. Mas vale ressaltar que o caractere # na verdade retorna o maior índice conhecido (veremos casos abaixo em que pode existir um índice maior, mas ele não é conhecido). Sendo assim, ele não funciona em tabelas cujos índices não sejam inteiros sequenciais e também retornará a quantidade errada de itens em tabelas que tenham algum índice da sequência faltando. Para contar itens numa tabela de índices aleatórios, usamos uma variável de contador, que vai aumentando em +1 a cada execução do loop e no final nos mostra quantas verificações foram feitas, indicando quantos itens tem na tabela. Vejamos alguns exemplos: local tabela1 = { [4] = "a", [2] = "b", [5] = "c", [1] = "d", [3] = "e" } print("Tabela1: "..#tabela1) -- Retornará 5. Pois é o maior índice conhecido. local tabela2 = { [1] = "a", [2] = "b", [3] = "c", [4] = "d", [6] = "e", } print("Tabela2: "..#tabela2) -- Retornará 6. Mesmo tendo apenas 5 itens, o índice 6 é o maior. local tabela3 = { ["um"] = "a", [22] = "b", ["3"] = "c", [1] = "d", [0] = "e" } print("Tabela3: "..#tabela3) -- Retornará 1. Ele começa a verificar a partir do índice 1, então o índice 0 seria ignorado de qualquer forma. -- Em tabelas que possuem somente índices inteiros, ele iria encontrar o 22. Mas se tiver outros tipos de índices, ele não sabe qual a sequência correta e não verifica os demais. local contador = 0 for _,v in pairs(tabela3) do -- Maneira correta de contar itens numa tabela onde o ipairs não funciona. contador = contador+1 end print("Tabela3 de novo: "..contador) -- Retornará 5. Independente dos índices.