Esx_society hire / set job distance

Is there any way to set the distance of esx_society when setting a players job within the boss menu ? I dont want to have the full player list getting pulled only players being nearby

Yes there is.
Here is the esx_society/server/main.lua file. This is where we will make changes. Specifically the esx_society:getOnlinePlayers server callback.

I like to account for changes I make, usually in cases like this by creating a config option to enable or disable my alterations. So let’s do that. I will also create a config option to allow you to tweak the distance it will check for players nearby. Let’s add both of those to the config.lua file.

Config.RecruitNearbyOnly = true -- Only show nearby players in hire menu
Config.RecruitDistance = 10.0 -- How far can nearby players be to hire?

If you want to undo the changes we are making, you just need to change Config.RecruitNearbyOnly to false. You don’t need to revert the code, etc.

Now we will edit the server callback function. Here is the new version;

ESX.RegisterServerCallback('esx_society:getOnlinePlayers', function(source, cb)
	if getOnlinePlayers == false and next(onlinePlayers) == nil then -- Prevent multiple xPlayer loops from running in quick succession
		getOnlinePlayers, onlinePlayers = true, {}
		local coords = GetEntityCoords(source)
		local xPlayers = ESX.GetExtendedPlayers()
		for _, xPlayer in pairs(xPlayers) do
			if not Config.RecruitNearbyOnly or #(coords - GetEntityCoords(xPlayer.source)) <= Config.RecruitDistance then
				table.insert(onlinePlayers, {
					source = xPlayer.source,
					identifier = xPlayer.identifier,
					name = xPlayer.name,
					job = xPlayer.job
				})
			end
		end
		cb(onlinePlayers)
		getOnlinePlayers = false
		Citizen.Wait(1000) -- For the next second any extra requests will receive the cached list
		onlinePlayers = {}
		return
	end
	while getOnlinePlayers do Citizen.Wait(10) end -- Wait for the xPlayer loop to finish
	cb(onlinePlayers)
end)

What we have done in that callback function is grab the coordinates of the player that opened the boss menu, then IF the config option to only get nearby players is set to true, we will compare every player’s coordinates to the player calling the function and if they are inside that distance we set in the config, then they get added to the table. If you have the config set to false, then all players will be added.

This was achieved by adding;

local coords = GetEntityCoords(source)

And then wrapping the table insert function in a conditional statement;

if not Config.RecruitNearbyOnly or #(coords - GetEntityCoords(xPlayer.source)) <= Config.RecruitDistance then
	-- Add if RecruitNearbyOnly is false or player is within RecruitDistance
end

Not too bad, right? Fairly simple, if you know what you’re doing. Please mark this response as the solution so that others can benefit from it too! :spades:

1 Like

Awesome ! Thank you so much for taking the time to response this in-depth :slight_smile:

seems like im getting this

Hmmmm. Sometimes it loses the source of the player that called the server event.
Let’s try the usual fix…

Add the following;

local _source = source

Right above this line;

if getOnlinePlayers == false and next(onlinePlayers) == nil then -- Prevent multiple xPlayer loops from running in quick succession

Then change the line;

local coords = GetEntityCoords(source)

To;

local coords = GetEntityCoords(_source)

So the complete callback should be;

ESX.RegisterServerCallback('esx_society:getOnlinePlayers', function(source, cb)
	local _source = source
	if getOnlinePlayers == false and next(onlinePlayers) == nil then -- Prevent multiple xPlayer loops from running in quick succession
		getOnlinePlayers, onlinePlayers = true, {}
		local coords = GetEntityCoords(_source)
		local xPlayers = ESX.GetExtendedPlayers()
		for _, xPlayer in pairs(xPlayers) do
			if not Config.RecruitNearbyOnly or #(coords - GetEntityCoords(xPlayer.source)) <= Config.RecruitDistance then
				table.insert(onlinePlayers, {
					source = xPlayer.source,
					identifier = xPlayer.identifier,
					name = xPlayer.name,
					job = xPlayer.job
				})
			end
		end
		cb(onlinePlayers)
		getOnlinePlayers = false
		Citizen.Wait(1000) -- For the next second any extra requests will receive the cached list
		onlinePlayers = {}
		return
	end
	while getOnlinePlayers do Citizen.Wait(10) end -- Wait for the xPlayer loop to finish
	cb(onlinePlayers)
end)

I would test this stuff for you, but I am at work usually, when replying to these posts. So :crossed_fingers:

Hmm that doesnt seem to fix it