DarkRP looping through players and returning player with specific job?

Hello everyone as the title says im trying to return a player with a specific job.

I’ve attempted to try and do it with this code:


function findCurrentMayor()
	for k, v in pairs( player.GetAll() ) do
		if v:Team() == TEAM_MAYOR then
			currentMayor = v:Name()
		end

		if v:Team() != TEAM_MAYOR then
			currentMayor = "None"
		end
	end
	
end	

It works fine when im on a server alone, But if im on a server with more than 1 person it constantly says none.

How do i do this correctly?

It’s because you’re also checking if the players team does not equal mayor then it will say none and as this goes through all the players that means it will say none unless everyone is mayor.

Use this instead

Ah right. So how do i check if a player is on the team TEAM_MAYOR and if TEAM_MAYOR is empty then print none?

Try this



function findCurrentMayor()
	currentMayor = "None"
	for k, v in pairs( player.GetAll() ) do
		if v:Team() == TEAM_MAYOR then
			currentMayor = v:Name()
		end
	end
end


You can keep the none if you really want to, but highwon example is better because it sets a default but still has a minor flaw. When the mayor is found, it’ll continue through the loop ( max players 128, so it isn’t a major issue, but can be improved ). Add break; right after currentMayor = v:Name( );

break; will cause the loop to end, and putting it in the if will cause it to end as soon as the mayor is found. This turns a guaranteed n run-time expense for best and worst case to n for worst and 1 for best.

It can be improved even further down to O( 1 ) if you can only have 1 mayor maximum.


// Language support
language.Add( "nobody", "Nobody" );
currentMayor = currentMayor || language.GetPhrase( "nobody" );


//
// Find the current mayor, update the global variable ( although we don't need to do that when you have a function like this which can return the mayor without needing to loop ) with the mayor name
//
function findCurrentMayor( )
	// Reset the global var; not needed with this function...
	currentMayor = language.GetPhrase( "nobody" );

	// Grab all players on this team; if it is limited to a max of 1 player then we don't need to loop. Even if it isn't limited, we can still grab first in list unless there is support for something else...
	local _team_players = team.GetPlayers( TEAM_MAYOR );

	// Grab the first element in the list
	local _mayor = _team_players[ 1 ];

	// If it is valid, then we have a mayor
	if ( IsValid( _mayor ) ) then
		// Setup the name because we're using it twice
		local _name = _mayor:Name( );

		// Update the global var; not needed with this function
		currentMayor = _name;

		// Return the name; this is how it could work, so you can just use findCurrentMayor( ) and it'll return the name without needing to manage a global var
		return _name;
	end
end

He gave you the function to use, just use this
[lua]local mayor = team.GetPlayers( TEAM_MAYOR )[1][/lua]
Since team.GetPlayers returns a table with the players in the team you specify. If there’s only meant to be one player in that team then the only player will be in the first index of the table that function returns.
If there is no mayor “mayor” will be nil.

So, I ve got this:

[lua]function findCurrentMayor()

currentMayor = team.GetPlayers( TEAM_MAYOR )[1]
if currentMayor == null then
	currentMayor == "None"
end

elseif currentMayor != null then
	currentMayor = currentMayor
end

end [/lua]

However when somoene else becomes a mayor after i leave the job, It returns “None”

It displays my friends name when he is mayor, However if i go mayor when he isnt on, it displays my name, When he joins back it shows none,

The mayor is limited to one person

[lua]function findCurrentMayor()
local currentMayor = “None”
local currentMayorPlayerData = team.GetPlayers( TEAM_MAYOR )[1]
if currentMayorPlayerData ~= nil then
currentMayor = curentMayor:Nick()
end
return currentMayor
end

DPanel:SetText(findCurrentMayor())[/lua]

That should work flawlessly. PSEUDOCODEEE


function findCurrentMayor( )
	local _mayor = team.GetPlayers( TEAM_MAYOR )[ 1 ];
	if ( IsValid( _mayor ) ) then
		return _mayor:Name( );
	else
		return "None";
	end
end

local _mayor = findCurrentMayor( );
print( "The mayor is: " .. _mayor );

This is all that is needed… Essentially the minimum with the IsValid check… Can turn it into ternary and make it even shorter:


function findCurrentMayor( )
	local _mayor = team.GetPlayers( TEAM_MAYOR )[ 1 ];
	_mayor = ( IsValid( _mayor ) ) && _mayor:Name( ) || "None";

	return _mayor;
end

local _mayor = findCurrentMayor( );
print( "The mayor is: " .. _mayor );

Use IsValid instead of “null” ( which should be NULL; NULL means empty entity and entities show NULL for the player when they haven’t ever entered PVS yet ), or nil ( which means doesn’t exist, not set / not assigned ).

Add a break after the first if statement.

try this



local _Player = FindMetaTable("Player")
function _Player:FindCurrentMayor()
		for _, v in pairs( player.GetAll ) do
				if ( v:Team() == TEAM_MAYOR ) then
						print( v:Nick() ) -- to global the text v:ChatPrint( v:Nick().." is currently the mayor" )
			else
				if ( v:Team() != TEAM_MAYOR ) then
						print("There is no mayor")

			end
		end
	end
end
concommand.Add( "FindMayor", FindCurrentMayor)


It might work