Jump to content

Player mais próximo de um randomPlayer


Recommended Posts

Posted
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!

 

  • Other Languages Moderators
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
Posted
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

Posted
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...

  • Other Languages Moderators
Posted

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.

Posted

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

Posted

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
  • Other Languages Moderators
Posted

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

  • Like 1
Posted
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?

Posted

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
  • Other Languages Moderators
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
Posted

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

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...