local isLoadoutLoaded, isPaused, isPlayerSpawned, isDead = false, false, false, false local lastLoadout, pickups = {}, {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) ESX.PlayerLoaded = true ESX.PlayerData = xPlayer if Config.EnableHud then for k,v in ipairs(xPlayer.accounts) do local accountTpl = '
 {{money}}
' ESX.UI.HUD.RegisterElement('account_' .. v.name, k - 1, 0, accountTpl, { money = 0 }) ESX.UI.HUD.UpdateElement('account_' .. v.name, { money = ESX.Math.GroupDigits(v.money) }) end local jobTpl = '
{{job_label}} - {{grade_label}}
' if xPlayer.job.grade_label == '' then jobTpl = '
{{job_label}}
' end ESX.UI.HUD.RegisterElement('job', #xPlayer.accounts, 0, jobTpl, { job_label = '', grade_label = '' }) ESX.UI.HUD.UpdateElement('job', { job_label = xPlayer.job.label, grade_label = xPlayer.job.grade_label }) else TriggerEvent('es:setMoneyDisplay', 0.0) end end) RegisterNetEvent('esx:setMaxWeight') AddEventHandler('esx:setMaxWeight', function(newMaxWeight) ESX.PlayerData.maxWeight = newMaxWeight end) RegisterNetEvent('esx:createMissingPickups') AddEventHandler('esx:createMissingPickups', function(missingPickups) for pickupId,v in pairs(missingPickups) do ESX.Game.SpawnLocalObject('prop_money_bag_01', v.coords, function(obj) SetEntityAsMissionEntity(obj, true, false) PlaceObjectOnGroundProperly(obj) pickups[pickupId] = { id = pickupId, obj = obj, label = v.label, inRange = false, coords = v.coords } end) end end) AddEventHandler('playerSpawned', function() while not ESX.PlayerLoaded do Citizen.Wait(1) end local playerPed = PlayerPedId() -- Restore position if ESX.PlayerData.lastPosition then SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.lastPosition.z) end TriggerEvent('esx:restoreLoadout') -- restore loadout isLoadoutLoaded, isPlayerSpawned, isDead = true, true, false if Config.EnablePvP then SetCanAttackFriendly(playerPed, true, false) NetworkSetFriendlyFireOption(true) end end) AddEventHandler('esx:onPlayerDeath', function() isDead = true end) AddEventHandler('skinchanger:loadDefaultModel', function() isLoadoutLoaded = false end) AddEventHandler('skinchanger:modelLoaded', function() while not ESX.PlayerLoaded do Citizen.Wait(1) end TriggerEvent('esx:restoreLoadout') end) AddEventHandler('esx:restoreLoadout', function() local playerPed = PlayerPedId() local ammoTypes = {} RemoveAllPedWeapons(playerPed, true) for k,v in ipairs(ESX.PlayerData.loadout) do local weaponName = v.name local weaponHash = GetHashKey(weaponName) GiveWeaponToPed(playerPed, weaponHash, 0, false, false) local ammoType = GetPedAmmoTypeFromWeapon(playerPed, weaponHash) for k2,v2 in ipairs(v.components) do local componentHash = ESX.GetWeaponComponent(weaponName, v2).hash GiveWeaponComponentToPed(playerPed, weaponHash, componentHash) end if not ammoTypes[ammoType] then AddAmmoToPed(playerPed, weaponHash, v.ammo) ammoTypes[ammoType] = true end end isLoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') AddEventHandler('esx:setAccountMoney', function(account) for k,v in ipairs(ESX.PlayerData.accounts) do if v.name == account.name then ESX.PlayerData.accounts[k] = account break end end if Config.EnableHud then ESX.UI.HUD.UpdateElement('account_' .. account.name, { money = ESX.Math.GroupDigits(account.money) }) end end) RegisterNetEvent('es:activateMoney') AddEventHandler('es:activateMoney', function(money) ESX.PlayerData.money = money end) RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count) for k,v in ipairs(ESX.PlayerData.inventory) do if v.name == item.name then ESX.PlayerData.inventory[k] = item break end end ESX.UI.ShowInventoryItemNotification(true, item, count) if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() end end) RegisterNetEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(item, count) for k,v in ipairs(ESX.PlayerData.inventory) do if v.name == item.name then ESX.PlayerData.inventory[k] = item break end end ESX.UI.ShowInventoryItemNotification(false, item, count) if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() end end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) ESX.PlayerData.job = job end) RegisterNetEvent('esx:addWeapon') AddEventHandler('esx:addWeapon', function(weaponName, ammo) local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) GiveWeaponToPed(playerPed, weaponHash, ammo, false, false) --AddAmmoToPed(playerPed, weaponHash, ammo) possibly not needed end) RegisterNetEvent('esx:addWeaponComponent') AddEventHandler('esx:addWeaponComponent', function(weaponName, weaponComponent) local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) local componentHash = ESX.GetWeaponComponent(weaponName, weaponComponent).hash GiveWeaponComponentToPed(playerPed, weaponHash, componentHash) end) RegisterNetEvent('esx:setWeaponAmmo') AddEventHandler('esx:setWeaponAmmo', function(weaponName, weaponAmmo) local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) SetPedAmmo(playerPed, weaponHash, weaponAmmo) end) RegisterNetEvent('esx:removeWeapon') AddEventHandler('esx:removeWeapon', function(weaponName, ammo) local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) RemoveWeaponFromPed(playerPed, weaponHash) if ammo then local pedAmmo = GetAmmoInPedWeapon(playerPed, weaponHash) local finalAmmo = math.floor(pedAmmo - ammo) SetPedAmmo(playerPed, weaponHash, finalAmmo) else SetPedAmmo(playerPed, weaponHash, 0) -- remove leftover ammo end end) RegisterNetEvent('esx:removeWeaponComponent') AddEventHandler('esx:removeWeaponComponent', function(weaponName, weaponComponent) local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) local componentHash = ESX.GetWeaponComponent(weaponName, weaponComponent).hash RemoveWeaponComponentFromPed(playerPed, weaponHash, componentHash) end) -- Commands RegisterNetEvent('esx:teleport') AddEventHandler('esx:teleport', function(pos) pos.x = pos.x + 0.0 pos.y = pos.y + 0.0 pos.z = pos.z + 0.0 RequestCollisionAtCoord(pos.x, pos.y, pos.z) while not HasCollisionLoadedAroundEntity(PlayerPedId()) do RequestCollisionAtCoord(pos.x, pos.y, pos.z) Citizen.Wait(1) end SetEntityCoords(PlayerPedId(), pos.x, pos.y, pos.z) end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) if Config.EnableHud then ESX.UI.HUD.UpdateElement('job', { job_label = job.label, grade_label = job.grade_label }) end end) RegisterNetEvent('esx:spawnVehicle') AddEventHandler('esx:spawnVehicle', function(vehicle) local model = (type(vehicle) == 'number' and vehicle or GetHashKey(vehicle)) if IsModelInCdimage(model) then local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) else TriggerEvent('chat:addMessage', { args = { '^1SYSTEM', 'Invalid vehicle model.' } }) end end) RegisterNetEvent('esx:pickup') AddEventHandler('esx:pickup', function(id, label, player) local ped = GetPlayerPed(GetPlayerFromServerId(player)) local coords = GetEntityCoords(ped) local forward = GetEntityForwardVector(ped) local x, y, z = table.unpack(coords + forward * -2.0) ESX.Game.SpawnLocalObject('prop_money_bag_01', { x = x, y = y, z = z - 2.0, }, function(obj) SetEntityAsMissionEntity(obj, true, false) PlaceObjectOnGroundProperly(obj) pickups[id] = { id = id, obj = obj, label = label, inRange = false, coords = {x = x, y = y, z = z} } end) end) RegisterNetEvent('esx:removePickup') AddEventHandler('esx:removePickup', function(id) ESX.Game.DeleteObject(pickups[id].obj) pickups[id] = nil end) RegisterNetEvent('esx:pickupWeapon') AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName, ammo) local playerPed = PlayerPedId() local pickupCoords = GetOffsetFromEntityInWorldCoords(playerPed, 2.0, 0.0, 0.5) local weaponHash = GetHashKey(weaponPickup) CreateAmbientPickup(weaponHash, pickupCoords, 0, ammo, 1, false, true) end) RegisterNetEvent('esx:deleteVehicle') AddEventHandler('esx:deleteVehicle', function(radius) local playerPed = PlayerPedId() if radius and tonumber(radius) then radius = tonumber(radius) + 0.01 local vehicles = ESX.Game.GetVehiclesInArea(GetEntityCoords(playerPed), radius) for k,entity in ipairs(vehicles) do local attempt = 0 while not NetworkHasControlOfEntity(entity) and attempt < 100 and DoesEntityExist(entity) do Citizen.Wait(100) NetworkRequestControlOfEntity(entity) attempt = attempt + 1 end if DoesEntityExist(entity) and NetworkHasControlOfEntity(entity) then ESX.Game.DeleteVehicle(entity) end end else local vehicle, attempt = ESX.Game.GetVehicleInDirection(), 0 if IsPedInAnyVehicle(playerPed, true) then vehicle = GetVehiclePedIsIn(playerPed, false) end while not NetworkHasControlOfEntity(vehicle) and attempt < 100 and DoesEntityExist(vehicle) do Citizen.Wait(100) NetworkRequestControlOfEntity(vehicle) attempt = attempt + 1 end if DoesEntityExist(vehicle) and NetworkHasControlOfEntity(vehicle) then ESX.Game.DeleteVehicle(vehicle) end end end) -- Pause menu disable HUD display if Config.EnableHud then Citizen.CreateThread(function() while true do Citizen.Wait(300) if IsPauseMenuActive() and not isPaused then isPaused = true TriggerEvent('es:setMoneyDisplay', 0.0) ESX.UI.HUD.SetDisplay(0.0) elseif not IsPauseMenuActive() and isPaused then isPaused = false TriggerEvent('es:setMoneyDisplay', 1.0) ESX.UI.HUD.SetDisplay(1.0) end end end) end -- Save loadout Citizen.CreateThread(function() while true do Citizen.Wait(5000) local playerPed = PlayerPedId() local loadout = {} local loadoutChanged = false for k,v in ipairs(Config.Weapons) do local weaponName = v.name local weaponHash = GetHashKey(weaponName) local weaponComponents = {} if HasPedGotWeapon(playerPed, weaponHash, false) and weaponName ~= 'WEAPON_UNARMED' then local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) for k2,v2 in ipairs(v.components) do if HasPedGotWeaponComponent(playerPed, weaponHash, v2.hash) then table.insert(weaponComponents, v2.name) end end if not lastLoadout[weaponName] or lastLoadout[weaponName] ~= ammo then loadoutChanged = true end lastLoadout[weaponName] = ammo table.insert(loadout, { name = weaponName, ammo = ammo, label = v.label, components = weaponComponents }) else if lastLoadout[weaponName] then loadoutChanged = true end lastLoadout[weaponName] = nil end end if loadoutChanged and isLoadoutLoaded then ESX.PlayerData.loadout = loadout TriggerServerEvent('esx:updateLoadout', loadout) end end end) -- Menu interactions Citizen.CreateThread(function() while true do Citizen.Wait(0) if IsControlJustReleased(0, 289) and IsInputDisabled(0) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() end end end) -- Disable wanted level if Config.DisableWantedLevel then Citizen.CreateThread(function() while true do Citizen.Wait(0) local playerId = PlayerId() if GetPlayerWantedLevel(playerId) ~= 0 then SetPlayerWantedLevel(playerId, 0, false) SetPlayerWantedLevelNow(playerId, false) end end end) end -- Pickups Citizen.CreateThread(function() while true do Citizen.Wait(0) local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) -- if there's no nearby pickups we can wait a bit to save performance if next(pickups) == nil then Citizen.Wait(500) end for k,v in pairs(pickups) do local distance = GetDistanceBetweenCoords(coords, v.coords.x, v.coords.y, v.coords.z, true) local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if distance <= 5.0 then ESX.Game.Utils.DrawText3D({ x = v.coords.x, y = v.coords.y, z = v.coords.z + 0.25 }, v.label) end if (closestDistance == -1 or closestDistance > 3) and distance <= 1.0 and not v.inRange and IsPedOnFoot(playerPed) then TriggerServerEvent('esx:onPickup', v.id) PlaySoundFrontend(-1, 'PICK_UP', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) v.inRange = true end end end end) -- Last position Citizen.CreateThread(function() while true do Citizen.Wait(1000) local playerPed = PlayerPedId() if ESX.PlayerLoaded and isPlayerSpawned then local coords = GetEntityCoords(playerPed) if not IsEntityDead(playerPed) then ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} end end if IsEntityDead(playerPed) and isPlayerSpawned then isPlayerSpawned = false end end end)