zMpyster Posted July 19, 2019 Share Posted July 19, 2019 playerOrDist = {} function getUberNear(cliente) tableUber = aclGroupListObjects(aclGetGroup("UBER")) for objects,name in pairs(tableUber)do player = getAccountPlayer(name) if (getElementType( player ) == "player" and player ~= cliente) then local jX, jY, jZ = getElementPosition (player) local pX, pY, pZ = getElementPosition (cliente) local dist = getDistanceBetweenPoints3D ( pX, pY, pZ, jX, jY, jZ) if distancia[cliente] == nil or distancia[cliente] == false then distancia[cliente] = dist..","..player else local playerOrDist = split(distancia[cliente], ',') if playerOrDist[1] > dist then distancia[cliente] = dist..","..player end end end end return distancia[cliente] end Fiz esse pequeno código, aonde retorna um trabalhador da UBER mais próximo de tal player, estou com uma pequena dúvida, ali na parte "if playerOrDist[1] > dist then", se dois players pedirem uber ao mesmo tempo, tem chance de um número sobrepor o outro ex: cliente(Danilo) - uber mais próximo(carlos) - km(1) cliente2(João) - uber mais próximo(Jorge) - km(6) o meu medo é de quando "Danilo" e "João" pedirem uber ao mesmo tempo, acabe bugando e ficando assim cliente(Danilo) - uber mais próximo(Jorge) - km(6) cliente2(João) - uber mais próximo(Jorge) - km(6) espero que tenham entendido, boa noite! Link to comment
Other Languages Moderators Lord Henry Posted July 19, 2019 Other Languages Moderators Share Posted July 19, 2019 (edited) Está faltando parte desse código. E tem falhas de lógica. Na sua linha 5, a função getAccountPlayer só funciona com argumento do tipo account, mas name é sempre um valor do tipo string. Você está usando uma table chamada distancia na linha 10, que não foi declarada em lugar nenhum. Mas vou supor que esteja declarada na parte que vc não mostrou. Na sua linha 13, você está usando uma variável local com nome de uma table global. Era melhor usar outro nome pra não entrar em conflito com a table. Edited July 19, 2019 by Lord Henry 1 Link to comment
zMpyster Posted July 19, 2019 Author Share Posted July 19, 2019 5 minutes ago, Lord Henry said: Está faltando parte desse código. E tem falhas de lógica. Na sua linha 5, a função getAccountPlayer só funciona com argumento do tipo account, mas name é sempre um valor do tipo string. Você está usando uma table chamada distancia na linha 10, que não foi declarada em lugar nenhum. Mas vou supor que esteja declarada na parte que vc não mostrou. Na sua linha 13, você está usando uma variável local com nome de uma table que não é local. Era melhor usar outro nome pra não entrar em conflito com a table. playerOrDist = {} distancia = {} function getUberNear(cliente) tableUber = aclGroupListObjects(aclGetGroup("UBER")) for objects,name in pairs(tableUber)do player = getAccountPlayer(getAccount(name)) if (getElementType( player ) == "player" and player ~= cliente) then local jX, jY, jZ = getElementPosition (player) local pX, pY, pZ = getElementPosition (cliente) local dist = getDistanceBetweenPoints3D ( pX, pY, pZ, jX, jY, jZ) if distancia[cliente] == nil or distancia[cliente] == false then distancia[cliente] = dist..","..player else local playerOrDist = split(distancia[cliente], ',') if playerOrDist[1] > dist then distancia[cliente] = dist..","..player end end end end return distancia[cliente] end a "distancia" eu tinha declarado lá em cima, sorry, na linha 5, eu acho que arrumei, o local na parte "local playerOrDist = split(distancia[cliente], ',')" eu coloquei por causa que o split, faz playerOrDist virar uma tabela contendo duas variáveis (distância e nome). Desculpe os erros bestas, não testei o mod Link to comment
Other Languages Moderators Lord Henry Posted July 19, 2019 Other Languages Moderators Share Posted July 19, 2019 Vc já testou o script com /debugscript 3 ligado? Link to comment
zMpyster Posted July 19, 2019 Author Share Posted July 19, 2019 playerOrDist = {} accountName = {} distancia = {} function getUberNear(cliente) tableUber = aclGroupListObjects(aclGetGroup("UBER")) for objects,name in pairs(tableUber)do local accountName = split(name, '.') local player = getAccountPlayer(getAccount(accountName[2])) if (getElementType( player ) == "player" and player ~= cliente) then local jX, jY, jZ = getElementPosition (player) local pX, pY, pZ = getElementPosition (cliente) local dist = getDistanceBetweenPoints3D ( pX, pY, pZ, jX, jY, jZ) if distancia[cliente] == nil or distancia[cliente] == false then distancia[cliente] = dist..","..player else local playerOrDist = split(distancia[cliente], ',') if playerOrDist[1] > dist then distancia[cliente] = dist..","..player end end end end return distancia[cliente] end Testei agr, pensava que no loop, "name" retornava a conta já, más, retorna "user.conta". Pelo oq vi agr ta tudo certo, não da pra testar muita coisa pq precisa de 2 players... Link to comment
Other Languages Moderators Lord Henry Posted July 19, 2019 Other Languages Moderators Share Posted July 19, 2019 Vc está cometendo o mesmo erro que mencionei anteriormente. Agora na linha 7, usando o mesmo nome de uma variável global em uma variável local. Link to comment
zMpyster Posted July 19, 2019 Author Share Posted July 19, 2019 Na vdd, se vc for testar no debug dessa forma não vai acusar erro, ou seja, não acho que seja um erro, o local pode ser chamado de desnecessário, más, eu coloco pq acostumei Link to comment
DNL291 Posted July 19, 2019 Share Posted July 19, 2019 Confuso o código, me parece um algoritmo não está eficiente e pode ser mais simplificado para o que você precisa. Aqui está as funções que você vai precisar para obter o jogador mais próximo: function obterUberMaisProximoDoCliente( thePlayer ) local tableUber = getPlayersInGroup( "UBER" ) if not tableUber then return end local px,py,pz = getElementPosition(thePlayer) local lastMinDis = 999999 local nearest = false local dist for i, uber in ipairs(tableUber) do local x,y,z = getElementPosition( uber ) local distance = getDistanceBetweenPoints3D( px,py,pz, x,y,z ) if distance < lastMinDis then lastMinDis = distance nearest = uber dist = distance end end return nearest, dist end -- https://wiki.multitheftauto.com/wiki/GetPlayersInGroup function getPlayersInGroup ( GroupName ) local aTable = {} assert ( tostring ( GroupName ) , "Bad Argument At Argument #1 Group Moust String" ) assert ( aclGetGroup ( tostring ( GroupName ) ) , "Bad Argument At Argument #1 Group not Found " ) for i , player_ in ipairs ( getElementsByType ( "player" ) ) do local TheAcc = getPlayerAccount ( player_ ) if not isGuestAccount ( TheAcc ) then if isObjectInACLGroup ( "user." ..getAccountName ( TheAcc ) , aclGetGroup ( tostring ( GroupName ) ) ) then table.insert ( aTable , player_ ) end end end return aTable end > local uberProximo, distancia = obterUberMaisProximoDoCliente( cliente ) 1 Link to comment
Other Languages Moderators Lord Henry Posted July 19, 2019 Other Languages Moderators Share Posted July 19, 2019 Na verdade é o accountName global que é desnecessário. 1 Link to comment
zMpyster Posted July 19, 2019 Author Share Posted July 19, 2019 6 minutes ago, DNL291 said: Confuso o código, me parece um algoritmo não está eficiente e pode ser mais simplificado para o que você precisa. Aqui está as funções que você vai precisar para obter o jogador mais próximo: function obterUberMaisProximoDoCliente( thePlayer ) local tableUber = getPlayersInGroup( "UBER" ) if not tableUber then return end local px,py,pz = getElementPosition(thePlayer) local lastMinDis = 999999 local nearest = false local dist for i, uber in ipairs(tableUber) do local x,y,z = getElementPosition( uber ) local distance = getDistanceBetweenPoints3D( px,py,pz, x,y,z ) if distance < lastMinDis then lastMinDis = distance nearest = uber dist = distance end end return nearest, dist end -- https://wiki.multitheftauto.com/wiki/GetPlayersInGroup function getPlayersInGroup ( GroupName ) local aTable = {} assert ( tostring ( GroupName ) , "Bad Argument At Argument #1 Group Moust String" ) assert ( aclGetGroup ( tostring ( GroupName ) ) , "Bad Argument At Argument #1 Group not Found " ) for i , player_ in ipairs ( getElementsByType ( "player" ) ) do local TheAcc = getPlayerAccount ( player_ ) if not isGuestAccount ( TheAcc ) then if isObjectInACLGroup ( "user." ..getAccountName ( TheAcc ) , aclGetGroup ( tostring ( GroupName ) ) ) then table.insert ( aTable , player_ ) end end end return aTable end > local uberProximo, distancia = obterUberMaisProximoDoCliente( cliente ) Realmente ficou bem mais simplificado, só que ainda persisto com a dúvida do inicio, se dois players chamassem o uber ao mesmo tempo, teria chance de bugar as distâncias? Link to comment
DNL291 Posted July 19, 2019 Share Posted July 19, 2019 Quanto ao que o Lord Henry mencionou, as tabela playerOrDist também é desnecessária no topo do código (assim como a accountName). Eu aconselho a largar esse costume, você vai alocar desnecessariamente na memória com aquela tabela global, e ela estará acessível em todo o resource podendo também dar algum conflito, e quando isso ocorre você fica perdido com a depuração, sem saber o que há de errado. EDIT: 2 minutes ago, zMpyster said: Realmente ficou bem mais simplificado, só que ainda persisto com a dúvida do inicio, se dois players chamassem o uber ao mesmo tempo, teria chance de bugar as distâncias? Se armazenar numa variável o primeiro jogador que chamou o Uber, e, fazer sempre uma verificação antes de chamar, não vai ter como 2 players chamarem ao mesmo tempo, vai dizer que alguém já chamou antes. @zMpyster 1 Link to comment
Other Languages Moderators Lord Henry Posted July 19, 2019 Other Languages Moderators Share Posted July 19, 2019 (edited) 7 minutes ago, zMpyster said: Realmente ficou bem mais simplificado, só que ainda persisto com a dúvida do inicio, se dois players chamassem o uber ao mesmo tempo, teria chance de bugar as distâncias? Cara, é extremamente raro de dois players chamarem simultaneamente. Levando em conta que leva menos de meio segundo pra completar a execução dessa função. Eu acho que não ocorre conflito entre os players. Ele vai chamar uma vez pra cada um e dai o thePlayer vai ser diferente em cada um deles. Edited July 19, 2019 by Lord Henry 1 Link to comment
zMpyster Posted July 19, 2019 Author Share Posted July 19, 2019 Vocês recomendam que eu armazene em uma variável, ou na hora de chamar a função eu coloque um timer? Link to comment
DNL291 Posted July 19, 2019 Share Posted July 19, 2019 Você tem essa opção também. Eu deixaria a variável, afinal vai precisar ter a verificação que o taxista já tem um cliente. Daí a variável já deverá valer desde o momento que o cliente chamou, caso desista/alguém saia/não dê certo ou quando finaliza a corrida reseta a variável. 1 Link to comment
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now