Jump to content

Lord Henry

Other Languages Moderators
  • Posts

    3,969
  • Joined

  • Last visited

  • Days Won

    179

Everything posted by Lord Henry

  1. 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.
  2. 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.
  3. 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.
  4. 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)
  5. 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.
  6. 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.
  7. -- 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.
  8. 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:
  9. @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.
  10. 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)
  11. Sua imagem está inacessível, na próxima vez upe ela no imgur e cole o link direto dela aqui.
  12. 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.
  13. Tópico movido para a seção de Programação Lua. Na próxima vez, poste na área correta.
  14. 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
  15. 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.
  16. Neste tutorial irei explicar qual a diferença entre um loop usando pairs e um loop usando ipairs. Mas antes de prosseguir, é necessário entender o que é uma tabela indexada e uma tabela não indexada. Tabela indexada é aquela cujos itens tem seu índice declarado. Os índices podem ser números, textos ou elementos. Tabela não indexada é aquela cujos itens não tem seu índice declarado. Porém a linguagem Lua automaticamente indexará essas tabelas com inteiros sequenciais. local tabela = {"1", 2, "três", 0.4, false, 0} -- Tabela não indexada. -- O MTA vai considerar a tabela acima dessa forma: local tabela = { -- Tabela indexada com inteiros sequenciais. [1] = "1", [2] = 2, [3] = "três", [4] = 0.4, [5] = false, [6] = 0 } -- Escrevi a tabela na vertical para facilitar a leitura, não faz diferença escrever tudo na mesma linha. É importante saber disso pois ipairs leva em consideração os índices dos itens de uma tabela, como veremos a seguir. CONCEITO Tanto o pairs quanto o ipairs são utilizados para fazer loops que percorrem uma tabela usando o laço de repetição for. Mas existem situações em que um ipairs não funciona e também há situações em que o pairs não atende ao objetivo que o scripter precisa. Basicamente, o pairs percorre os itens de uma tabela mas não garante a mesma ordem em que eles foram declarados e nem a sequência de seus índices. Sem qualquer ordem específica, ele não exige que a tabela seja indexada por inteiros sequenciais, já que ele não leva em consideração a ordem dos índices da tabela. Enquanto o ipairs (significado: index-value pairs) percorre os itens de uma tabela sempre seguindo a sequência de seus índices. Verificando primeiro o item de índice 1, depois o item de índice 2 e assim por diante. Se um índice da sequência estiver faltando, ele não percorrerá o resto e vai parar de verificar. Também não importa a ordem em que os índices são declarados. Se você declara o item de índice 2 e depois o item de índice 1, mesmo assim ele vai ler o item de índice 1 primeiro e depois o item de índice 2. O ipairs também não é capaz de verificar itens cujo índice não seja um inteiro, pois ele não sabe a sequência que ele pertence, portanto itens de índice string não são verificados pelo ipairs. EXEMPLOS Usando o pairs: (note que o exemplo é server-side, mas tanto o pairs quanto o ipairs podem ser usados client-side também) Server-side addCommandHandler("eae", function(thePlayer, cmd) -- Vamos setar algumas elementDatas em si mesmo só para testes. setElementData(thePlayer, "vida", 100) setElementData(thePlayer, "colete", 90) -- (Datas fictícias, não alteram de verdade a vida nem colete do jogador). setElementData(thePlayer, "vivo", true) setElementData(thePlayer, "procurado", false) setElementData(thePlayer, "emprego", "Mecânico") local datas = getAllElementData(thePlayer) -- Obtém uma tabela com todas as elementDatas do jogador que executou o comando /eae -- A tabela retornada seria assim: (supondo que o jogador não tenha outras elementDatas setadas nele) --[[ local datas = { ["vida"] = 100, ["colete"] = 90, ["vivo"] = true, ["procurado"] = false, -- Este é o único jeito de saber se uma elementData false existe mesmo. ["emprego"] = "Mecânico" } --]] -- Para verificar cada item dessa tabela, o pairs precisa ser usado pois os índices são strings enquanto o ipairs só funciona com índices inteiros sequenciais. for name, value in pairs(datas) do print(name.." = "..tostring(value)) end -- Não há qualquer garantia de que os itens sejam verificados na mesma ordem em que foram declarados. Consideramos isso aleatório. end) Obs: O pairs também funciona em tabelas com índices inteiros sequenciais como o ipairs, porém percorre de maneira aleatória enquanto o ipairs segue a sequência dos índices. 1) Se trocar o pairs por um ipairs, nenhum item será verificado. Pois não foi encontrado o índice 1. Obs2: Mesmo se você definir uma elementData com nome "1", o índice continuará sendo uma string, não sendo lido pelo ipairs. Vimos acima um exemplo que precisa usar pairs pois o ipairs não funcionaria. Agora veremos um exemplo onde o ipairs seria mais adequado. Client-side local palavras = { [1] = "Neste ", [2] = "caso ", [3] = "a ", [4] = "ordem ", [6] = "importa " -- Esqueci do índice 5 de propósito. } local mensagem = "" for i, v in ipairs(palavras) do mensagem = mensagem..v end print(mensagem) Faça os seguintes testes: 1) Execute o código acima do jeito que está, veremos que a mensagem final aparece incompleta. Pois ele não encontrou o índice 5 e parou de verificar o resto dos itens. Retornando a mensagem "Neste caso a ordem " 2) Se trocarmos o ipairs por um pairs, veremos que a mensagem ficará bagunçada, pois os itens foram verificados de maneira aleatória. Porém desta vez todas as palavras serão verificadas, pois o índice não é levado em consideração pelo pairs, somente pelo ipairs. 3) Troque o pairs pelo ipairs de volta e substitua o índice 6 por 5. A mensagem aparecerá completa e com as palavras em ordem. Já que não haverá nenhum índice faltando na sequência. 4) Troque a ordem dos itens da tabela dessa forma: (preste atenção na vírgula, ela é obrigatória em todos os itens, exceto no último) local palavras = { [4] = "ordem ", [2] = "caso ", [5] = "importa ", [1] = "Neste ", [3] = "a " } Veremos que o ipairs continuará verificando cada item na ordem correta. Já que o que importa para ele são os índices e não a ordem em que os itens foram declarados na tabela.
  17. Não funcionaria, pois você está usando ipairs que só serve para tabelas indexadas com inteiros sequenciais. Perceba que no exemplo da wiki do getAllElementData ele usa pairs.
  18. Só server-side pra conseguir obter as datas sem saber os nomes.
  19. local texture = dxCreateTexture("info.png", "argb", true, "clamp") -- MTA San Andreas 1.5\MTA\cgui\images\info.png addEventHandler("onClientRender", root, function() local x, y, z = getElementPosition(localPlayer) local cx, cy, cz = getCameraMatrix() local sx, sy = getScreenFromWorldPosition (x, y, z+1, 0, false) -- Exemplo 1 dxDrawMaterialLine3D (x, y, z+1.08, x, y, z+0.9, false, texture, 0.17, 0xFFFFFFFF, false, cx, cy, cz) -- Tamanho fixo no mundo (fica menor se afastar a câmera e maior se aproximar a câmera) -- Exemplo 2 if sx then dxDrawImage (sx-21, sy, 42, 42, texture) -- Tamanho fixo na tela (mantém o tamanho igual mesmo se afastar a câmera) end end) Lembrando que vc pode mudar a câmera usando a tecla V.
  20. Não, vc teria que ficar usando o getElementPosition para obter a posição do player e depois ficar dando dxDrawImage3D com essa posição XYZ do player. Obs: Optei por usar o dxDrawMaterialLine3D pois a função útil dxDrawImage3D não tem os parâmetros de faceToward para apontar para a câmera.
  21. Não funciona pois os blips foram criados nos clientes dos policiais e não no servidor. OnPlayerWasted é server-side. Tente usar essa função client-side, mas usando o evento onClientPlayerWasted.
  22. Normalmente no client espera-se que você já saiba quais elementDatas um elemento pode ter. Nesse caso você cria primeiro uma tabela com os nomes de todas as datas que o elemento possa ter e verifica com um loop quais datas o elemento possui, ou se não possui tal data específica. local datas = { "dataName1", "dataName2", "dataName3", } function checkData(elemento) for _, data in pairs(datas) do -- Para cada nome de data que está na tabela datas, faça: local value = getElementData(elemento, data) -- Obtém o valor dessa elementData no elemento, se não existir retorna false. if not value then -- Se o elemento NÃO TEM essa data, então: -- faz algo -- OBS: Se a data existir mas estiver definida com valor false, vai ser o mesmo que não existir. end end end
×
×
  • Create New...