Sign in to follow this  
zMpyster

Player mais próximo de um randomPlayer

Recommended Posts

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!

 

Share this post


Link to post
Posted (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 by Lord Henry
  • Confused 1

Share this post


Link to post
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

Share this post


Link to post

Vc já testou o script com /debugscript 3 ligado?

Share this post


Link to post
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...

Share this post


Link to post

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.

Share this post


Link to post

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 :D

Share this post


Link to post

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 )

 

  • Thanks 1

Share this post


Link to post

Na verdade é o accountName global que é desnecessário.

  • Like 1

Share this post


Link to post
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?

Share this post


Link to post

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

  • Thanks 1

Share this post


Link to post
Posted (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 by Lord Henry
  • Like 1

Share this post


Link to post

Vocês recomendam que eu armazene em uma variável, ou na hora de chamar a função eu coloque um timer?

 

 

Share this post


Link to post

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.

  • Thanks 1

Share this post


Link to post

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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.