Jump to content

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!

 

Link to comment
  • Other Languages Moderators

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
Link to comment
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
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
  • Moderators

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
Link to comment
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
  • Moderators

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
Link to comment
  • Other Languages Moderators
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
Link to comment
  • Moderators

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

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...