[RELEASE][ESX] esx_xp

esx_xp

Adds an XP ranking system like the one found in GTA:O.

This is the ESX version of my framework agnostic XpM package.


Features

  • Designed to emulate the native GTA:O system
  • Saves and loads players XP / rank
  • Add / remove XP from your own script / job
  • Allows you listen for rank changes to reward players
  • Fully customisable UI
  • Integrated leaderboard

Demos

You can find an interactive demo here.

Increasing XP

Demo Image 1

Rank Up

Demo Image 2

Leaderboard


Requirements


Download & Installation

  • Download and extract the package: https://github.com/Mobius1/esx_xp/archive/master.zip
  • Rename the esx_xp-master directory to esx_xp
  • Drop the esx_xp directory into your resources directory on your server
  • Import the esx_xp.sql file into your db
  • Add ensure esx_xp in your server.cfg
  • Edit config.lua to your liking
  • Start your server

Functions

Setters

Set initial XP rank for player

exports.esx_xp:ESXP_SetInitial(xp --[[ integer ]])

Set Rank for player. This will add the required XP to advance the player to the given rank.

exports.esx_xp:ESXP_SetRank(rank --[[ integer ]])

Give player XP

exports.esx_xp:ESXP_Add(xp --[[ integer ]])

Remove XP from player

exports.esx_xp:ESXP_Remove(xp --[[ integer ]])

Getters

Get player’s current XP

exports.esx_xp:ESXP_GetXP()

Get player’s current rank

-- Get rank from current XP
exports.esx_xp:ESXP_GetRank()

-- or

-- Get rank from given XP
exports.esx_xp:ESXP_GetRank(xp --[[ integer ]])

Get XP required to advance the player to the next rank

exports.esx_xp:ESXP_GetXPToNextRank()

Get XP required to advance the player to the given rank

exports.esx_xp:ESXP_GetXPToRank(rank --[[ integer ]])

Get max attainable XP

exports.esx_xp:ESXP_GetMaxXP()

Get max attainable rank

exports.esx_xp:ESXP_GetMaxRank()

Get player XP and Rank from other ESX resources

If you want to access the players xp and / or rank in other ESX resources:

Client

local xPlayer = ESX.GetPlayerData()

local playerXP = xPlayer.xp
local playerRank = xPlayer.rank

Server

local xPlayer = ESX.GetPlayerFromId(source)

local playerXP = xPlayer.get("xp")
local playerRank = xPlayer.get("rank")

Client Event Listeners

Wait for esx_xp to be ready for use

AddEventHandler("esx_xp:ready", function(data --[[ table ]])
    local currentXP     = data.xp
    local currentRank   = data.rank
    local xPlayer       = data.player
    
    -- esx_xp is ready for use
end)

Listen for rank change events. These can be used to reward / punish the player for changing rank.

AddEventHandler("esx_xp:rankUp", function(newRank --[[ integer ]], previousRank --[[ integer ]])
    -- Do something when player ranks up
end)

AddEventHandler("esx_xp:rankDown", function(newRank --[[ integer ]], previousRank --[[ integer ]])
    -- Do something when player drops a rank
end)

Client Triggers

Wait for esx_xp to be ready:

TriggerEvent("esx_xp:isReady", cb)

Example:

ESXP = false

Citizen.CreateThread(function()
    while not ESXP do
        TriggerEvent("esx_xp:isReady", function(ready)
            ESXP = ready
        end)
        Citizen.Wait(10)
    end
    
    -- Do stuff with esx_xp
end)
-- SET INTITIAL XP
TriggerEvent('esx_xp:SetInitial', xp)

-- ADD XP
TriggerEvent('esx_xp:Add', xp)

-- REMOVE XP
TriggerEvent('esx_xp:Remove', xp)

-- SET RANK
TriggerEvent('esx_xp:SetRank', rank)

Server Triggers

-- SET INTITIAL XP
TriggerClientEvent('esx_xp:SetInitial', source, xp)

-- ADD XP
TriggerClientEvent('esx_xp:Add', source, xp)

-- REMOVE XP
TriggerClientEvent('esx_xp:Remove', source, xp)

-- SET RANK
TriggerClientEvent('esx_xp:SetRank', source, rank)

UI

The UI can be toggled with the Z key by default. The UI will fade out after the interval defined by Config.Timeout or you can close it immediately with the Z key.

You can customise the UI key with Config.UIKey in config.lua.

The data in the leaderboard is refreshed whenever it is opened so you get up-to-date information.


Further documentation available on the GitHub page.


Links

GitHub
Download


Other Releases

rprogress
FeedM
esx_collectables
esx_forklift

14 Likes

Would you be able to convert this one to vRP? :upside_down_face:

I’ve already made a framework agnostic version and a vRP version is in the works.

Error when im trying to lvl up.

I tryed manually to add exp with /ESXP_ADD and after that he didnt lvl up and this is an error:

and it doesent save in in db, so if you reconnect or restart a script u are backed to 0. No errors

How can I add experience by getting paid for a job? I did this but it doesn’t work

if enTrabajo == true then
DrawMarker(2,punto_spawn.x,punto_spawn.y,punto_spawn.z, 0, 0, 0, 0, 0, 0, 1.5001, 1.5001, 0.6001,7, 35, 191, 50, 0, 0, 0, 0)
if GetDistanceBetweenCoords(punto_spawn.x, punto_spawn.y, punto_spawn.z, GetEntityCoords(GetPlayerPed(-1),true)) < 1 then
alert(‘Presiona ~g~E~s~ para obtener tu ~g~ vehiculo’, 2, 1, 0.5, 0.8, 0.6, 255, 255, 255, 255)
if IsControlJustPressed(1,38) then
paga = 700
TriggerEvent(‘esx_xp:Add’, 30)
exports.esx_xp:ESXP_Add(30 --[[ integer ]])
volverCasa = true
sigcasa = math.random(1,3)
px = puntos[sigcasa].x
py = puntos[sigcasa].y
pz = puntos[sigcasa].z
distancia = round(GetDistanceBetweenCoords(punto_terminar.x, punto_terminar.y, punto_terminar.z, px,py,pz))
spawnearCamion()
Iracasa(puntos,sigcasa)
end
end
end

I love it

I had no ideea, first time seeing stuff from you. Great one many thanks and keep up the good work!

can someone help me with js error?

https://forum.cfx.re/uploads/default/original/4X/a/c/c/accf13590bcab698d38068f9da73cd9bf122ca6c.png

Hello!

There are some kind of error when you turn OFF the “leaderboard” function on config.lua related with the error of this image:

https://forum.cfx.re/uploads/default/original/4X/a/c/c/accf13590bcab698d38068f9da73cd9bf122ca6c.png

This is a “udpateRank” dependence of “leaderboard” (leaderboard.updateRank(currentID, current):wink:

Can you solve this issue to move out the Leaderboard function?? Thank you so much and nice work!

Change to true the Leaderboard value on config.lua and add CSS property visibility: hidden on ui.html like this:

id=“xpm_leaderboard” visibility: hidden

Release 1.0.6

Fixes

  • Fixed JS reference error when leaderboard is disabled

Download

Amazing… It’s so amazing I am going to use it.

OMG this is amaaazing THANK YOU! MUCH LOVE!!!

v.1.1.0 Released

Fixes

  • Fixed timeout bug causing UI to be incorrectly hidden
  • Fixed demo notification error

Changes

  • Added pagination to leaderboard to prevent overflow - See issue
  • Added PerPage variable to Config.Leaderboard to control number of players displayed per page

Known Bugs

  • Current player sometimes missing from leaderboard

Download
Changelog

1 Like

Hoping this isn’t too dumb of a question but I’m incredibly new to scripting and only know the bare basics.

How would I go about making this so I can get xp for killing peds? Not just cops but peds overall?

v.1.1.1 Released

Fixes

  • Fixed leaderboard sorting (Chrome bug)
  • Fixed ESXP_RemoveFakePlayers command not working correctly

Changes

  • Added export ESXP_TimeoutUI
  • Added export ESXP_SortLeaderboard
  • Added ESXP_SortLeaderboard demo command

Known Bugs

  • Current player sometimes missing from leaderboard

Download
Changelog

2 Likes

How to setup this script with esx_joblisting

I would like to make sure that each job requires a certain amount of XP and if you don’t have as much XP shown as it takes to get a job in that job

1 Like

You’d need something like this:

config.lua

Config.LockedJobs = {
	airlines 		= 60000,
	banker 			= 10000,
	banksecurity 	= 1000,
	cardealer 		= 5000
}

client/main.lua

function ShowJobListingMenu()
	ESX.TriggerServerCallback('esx_joblisting:getJobsList', function(jobs)
		local elements = {}

		for i=1, #jobs, 1 do
			local element = {
				label = jobs[i].label,
				job   = jobs[i].job
			}

			-- Job requires XP
			if Config.LockedJobs[jobs[i].job] ~= nil then
				local jobXP 	= Config.LockedJobs[jobs[i].job]
				local playerXP 	= ESX.GetPlayerData().xp

				-- Player doesn't have required XP
				if playerXP < jobXP then
					element.locked 	= true
					element.xp 		= jobXP
					element.label 	= jobs[i].label .. ": <span style='color:red;'>Requires " .. jobXP .. "XP</span>"
				end
			end

			table.insert(elements, element)			
		end

		ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'joblisting', {
			title    = _U('job_center'),
			align    = 'top-left',
			elements = elements
		}, function(data, menu)
			-- Check if job is XP locked
			if data.current.locked then
				-- Player doesn't have required XP
				ESX.ShowNotification("~r~ERROR: ~w~You require ~b~" .. data.current.xp .. "XP ~w~to get this job!")
			else
				-- Player has required XP
				TriggerServerEvent('esx_joblisting:setJob', data.current.job)
				ESX.ShowNotification(_U('new_job'))
				menu.close()
			end
		end, function(data, menu)
			menu.close()
		end)
	end)
end
1 Like

@Mobius01 Nice releases

1 Like