mirror of
https://github.com/esx-framework/esx_core.git
synced 2026-08-29 02:01:31 +00:00
Add files
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937'
|
||||
|
||||
description 'ES Extended'
|
||||
|
||||
server_scripts {
|
||||
'@async/async.lua',
|
||||
'@mysql-async/lib/MySQL.lua',
|
||||
'config.lua',
|
||||
'server/common.lua',
|
||||
'server/classes/player.lua',
|
||||
'server/functions.lua',
|
||||
'server/main.lua',
|
||||
'server/commands.lua'
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'config.lua',
|
||||
'client/functions.lua',
|
||||
'client/main.lua'
|
||||
}
|
||||
|
||||
ui_page {
|
||||
'html/ui.html'
|
||||
}
|
||||
|
||||
files {
|
||||
|
||||
'html/ui.html',
|
||||
|
||||
'html/css/app.css',
|
||||
|
||||
'html/js/mustache.min.js',
|
||||
'html/js/app.js',
|
||||
|
||||
'html/fonts/pdown.ttf',
|
||||
'html/fonts/bankgothic.ttf',
|
||||
|
||||
'html/img/cursor.png',
|
||||
'html/img/keys/enter.png',
|
||||
'html/img/keys/return.png',
|
||||
|
||||
'html/img/accounts/bank.png',
|
||||
'html/img/accounts/black_money.png'
|
||||
}
|
||||
@@ -0,0 +1,781 @@
|
||||
local charset = {}
|
||||
|
||||
for i = 48, 57 do table.insert(charset, string.char(i)) end
|
||||
for i = 65, 90 do table.insert(charset, string.char(i)) end
|
||||
for i = 97, 122 do table.insert(charset, string.char(i)) end
|
||||
|
||||
ESX = {}
|
||||
ESX.CurrentRequestId = 0
|
||||
ESX.ServerCallbacks = {}
|
||||
ESX.TimeoutCallbacks = {}
|
||||
ESX.UI = {}
|
||||
ESX.UI.HUD = {}
|
||||
ESX.UI.HUD.RegisteredElements = {}
|
||||
ESX.UI.Menu = {}
|
||||
ESX.UI.Menu.RegisteredTypes = {}
|
||||
ESX.UI.Menu.Opened = {}
|
||||
ESX.Game = {}
|
||||
|
||||
ESX.GetRandomString = function(length)
|
||||
|
||||
math.randomseed(GetGameTimer())
|
||||
|
||||
if length > 0 then
|
||||
return ESX.GetRandomString(length - 1) .. charset[math.random(1, #charset)]
|
||||
else
|
||||
return ''
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ESX.SetTimeout = function(msec, cb)
|
||||
table.insert(ESX.TimeoutCallbacks, {
|
||||
time = GetGameTimer() + msec,
|
||||
cb = cb
|
||||
})
|
||||
end
|
||||
|
||||
ESX.ShowNotification = function(msg)
|
||||
SetNotificationTextEntry('STRING')
|
||||
AddTextComponentString(msg)
|
||||
DrawNotification(0,1)
|
||||
end
|
||||
|
||||
ESX.TriggerServerCallback = function(name, cb, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z)
|
||||
|
||||
ESX.ServerCallbacks[ESX.CurrentRequestId] = cb
|
||||
|
||||
TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z)
|
||||
|
||||
if ESX.CurrentRequestId < 65535 then
|
||||
ESX.CurrentRequestId = ESX.CurrentRequestId + 1
|
||||
else
|
||||
ESX.CurrentRequestId = 0
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ESX.UI.HUD.SetDisplay = function(opacity)
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'setHUDDisplay',
|
||||
opacity = opacity
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
ESX.UI.HUD.RegisterElement = function(name, index, priority, html, data)
|
||||
|
||||
local found = false
|
||||
|
||||
for i=1, #ESX.UI.HUD.RegisteredElements, 1 do
|
||||
if ESX.UI.HUD.RegisteredElements[i] == name then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if found then
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(ESX.UI.HUD.RegisteredElements, name)
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'insertHUDElement',
|
||||
name = name,
|
||||
index = index,
|
||||
priority = priority,
|
||||
html = html,
|
||||
data = data,
|
||||
})
|
||||
|
||||
ESX.UI.HUD.UpdateElement(name, data)
|
||||
|
||||
end
|
||||
|
||||
ESX.UI.HUD.RemoveElement = function(name)
|
||||
|
||||
for i=1, #ESX.UI.HUD.RegisteredElements, 1 do
|
||||
if ESX.UI.HUD.RegisteredElements[i] == name then
|
||||
table.remove(ESX.UI.HUD.RegisteredElements, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'deleteHUDElement',
|
||||
name = name
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
ESX.UI.HUD.UpdateElement = function(name, data)
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'updateHUDElement',
|
||||
name = name,
|
||||
data = data,
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
ESX.UI.Menu.RegisterType = function(type, open, close)
|
||||
|
||||
ESX.UI.Menu.RegisteredTypes[type] = {
|
||||
open = open,
|
||||
close = close,
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change)
|
||||
|
||||
local menu = {}
|
||||
|
||||
menu.type = type
|
||||
menu.namespace = namespace
|
||||
menu.name = name
|
||||
menu.data = data
|
||||
menu.submit = submit
|
||||
menu.cancel = cancel
|
||||
menu.change = change
|
||||
|
||||
menu.close = function()
|
||||
|
||||
ESX.UI.Menu.RegisteredTypes[type].close(namespace, name)
|
||||
|
||||
for i=1, #ESX.UI.Menu.Opened, 1 do
|
||||
if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then
|
||||
ESX.UI.Menu.Opened[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
menu.update = function(query, newData)
|
||||
|
||||
for i=1, #menu.data.elements, 1 do
|
||||
|
||||
local match = true
|
||||
|
||||
for k,v in pairs(query) do
|
||||
if menu.data.elements[i][k] ~= v then
|
||||
match = false
|
||||
end
|
||||
end
|
||||
|
||||
if match then
|
||||
for k,v in pairs(newData) do
|
||||
menu.data.elements[i][k] = v
|
||||
end
|
||||
end
|
||||
|
||||
ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
menu.setElement = function(i, key, val)
|
||||
menu.data.elements[i][key] = val
|
||||
end
|
||||
|
||||
table.insert(ESX.UI.Menu.Opened, menu)
|
||||
|
||||
ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, data)
|
||||
|
||||
end
|
||||
|
||||
ESX.UI.Menu.Close = function(type, namespace, name)
|
||||
|
||||
for i=1, #ESX.UI.Menu.Opened, 1 do
|
||||
if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then
|
||||
ESX.UI.Menu.Opened[i].close()
|
||||
ESX.UI.Menu.Opened[i] = nil
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ESX.UI.Menu.CloseAll = function()
|
||||
|
||||
for i=1, #ESX.UI.Menu.Opened, 1 do
|
||||
ESX.UI.Menu.Opened[i].close()
|
||||
ESX.UI.Menu.Opened[i] = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ESX.UI.Menu.GetOpened = function(type, namespace, name)
|
||||
|
||||
for i=1, #ESX.UI.Menu.Opened, 1 do
|
||||
if ESX.UI.Menu.Opened[i].type == type and ESX.UI.Menu.Opened[i].namespace == namespace and ESX.UI.Menu.Opened[i].name == name then
|
||||
return ESX.UI.Menu.Opened[i]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ESX.UI.Menu.IsOpen = function(type, namespace, name)
|
||||
return ESX.UI.Menu.GetOpened(type, namespace, name) ~= nil
|
||||
end
|
||||
|
||||
ESX.UI.ShowInventoryItemNotification = function(add, item, count)
|
||||
SendNUIMessage({
|
||||
action = 'inventoryNotification',
|
||||
add = add,
|
||||
item = item,
|
||||
count = count
|
||||
})
|
||||
end
|
||||
|
||||
ESX.GetWeaponList = function()
|
||||
return Config.Weapons
|
||||
end
|
||||
|
||||
ESX.GetWeaponLabel = function(name)
|
||||
|
||||
name = string.upper(name)
|
||||
local weapons = ESX.GetWeaponList()
|
||||
|
||||
for i=1, #weapons, 1 do
|
||||
if weapons[i].name == name then
|
||||
return weapons[i].label
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ESX.Game.GetPlayers = function()
|
||||
|
||||
local maxPlayers = Config.MaxPlayers
|
||||
local players = {}
|
||||
|
||||
for i=0, maxPlayers, 1 do
|
||||
|
||||
local ped = GetPlayerPed(i)
|
||||
|
||||
if DoesEntityExist(ped) then
|
||||
table.insert(players, i)
|
||||
end
|
||||
end
|
||||
|
||||
return players
|
||||
|
||||
end
|
||||
|
||||
ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb)
|
||||
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName))
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
|
||||
RequestModel(model)
|
||||
|
||||
while not HasModelLoaded(model) do
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
|
||||
local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false)
|
||||
|
||||
SetNetworkIdCanMigrate(id, true)
|
||||
SetEntityAsMissionEntity(vehicle, true, true)
|
||||
SetVehicleHasBeenOwnedByPlayer(vehicle, true)
|
||||
SetModelAsNoLongerNeeded(model)
|
||||
|
||||
RequestCollisionAtCoord(coords.x, coords.y, coords.z)
|
||||
|
||||
while not HasCollisionLoadedAroundEntity(vehicle) do
|
||||
RequestCollisionAtCoord(coords.x, coords.x, coords.x)
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
|
||||
local id = NetworkGetNetworkIdFromEntity(vehicle)
|
||||
|
||||
if cb ~= nil then
|
||||
cb(vehicle)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb)
|
||||
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName))
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
|
||||
RequestModel(model)
|
||||
|
||||
while not HasModelLoaded(model) do
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
|
||||
local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false)
|
||||
local id = NetworkGetNetworkIdFromEntity(vehicle)
|
||||
|
||||
SetNetworkIdCanMigrate(id, true)
|
||||
SetEntityAsMissionEntity(vehicle, true, true)
|
||||
SetVehicleHasBeenOwnedByPlayer(vehicle, true)
|
||||
SetModelAsNoLongerNeeded(model)
|
||||
|
||||
RequestCollisionAtCoord(coords.x, coords.y, coords.z)
|
||||
|
||||
while not HasCollisionLoadedAroundEntity(vehicle) do
|
||||
RequestCollisionAtCoord(coords.x, coords.x, coords.x)
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
|
||||
if cb ~= nil then
|
||||
cb(vehicle)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
ESX.Game.GetClosestPlayer = function()
|
||||
|
||||
local players = ESX.Game.GetPlayers()
|
||||
local closestDistance = -1
|
||||
local closestPlayer = -1
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
|
||||
for i=1, #players, 1 do
|
||||
|
||||
local target = GetPlayerPed(players[i])
|
||||
|
||||
-- if target ~= playerPed then
|
||||
|
||||
local targetCoords = GetEntityCoords(target)
|
||||
local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, playerCoords.x, playerCoords.y, playerCoords.z, true)
|
||||
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestPlayer = players[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
|
||||
-- end
|
||||
|
||||
end
|
||||
|
||||
return closestPlayer, closestDistance
|
||||
end
|
||||
|
||||
ESX.Game.GetPlayersInArea = function(coords, area)
|
||||
|
||||
local players = ESX.Game.GetPlayers()
|
||||
local playersInArea = {}
|
||||
|
||||
for i=1, #players, 1 do
|
||||
|
||||
local target = GetPlayerPed(players[i])
|
||||
local targetCoords = GetEntityCoords(target)
|
||||
local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true)
|
||||
|
||||
if distance <= area then
|
||||
table.insert(playersInArea, players[i])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return playersInArea
|
||||
end
|
||||
|
||||
ESX.Game.GetVehicleProperties = function(vehicle)
|
||||
|
||||
local colour1, colour2 = GetVehicleColours(vehicle)
|
||||
local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle)
|
||||
|
||||
return {
|
||||
|
||||
model = GetEntityModel(vehicle),
|
||||
|
||||
plate = GetVehicleNumberPlateText(vehicle),
|
||||
plateIndex = GetVehicleNumberPlateTextIndex(vehicle),
|
||||
|
||||
health = GetEntityHealth(vehicle),
|
||||
dirtLevel = GetVehicleDirtLevel(vehicle),
|
||||
|
||||
color1 = colour1,
|
||||
color2 = colour2,
|
||||
pearlescentColor = pearlescentColor,
|
||||
wheelColor = wheelColor,
|
||||
|
||||
wheels = GetVehicleWheelType(vehicle),
|
||||
windowTint = GetVehicleWindowTint(vehicle),
|
||||
|
||||
neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)),
|
||||
|
||||
modSpoilers = GetVehicleMod(vehicle, 0),
|
||||
modFrontBumper = GetVehicleMod(vehicle, 1),
|
||||
modRearBumper = GetVehicleMod(vehicle, 2),
|
||||
modSideSkirt = GetVehicleMod(vehicle, 3),
|
||||
modExhaust = GetVehicleMod(vehicle, 4),
|
||||
modFrame = GetVehicleMod(vehicle, 5),
|
||||
modGrille = GetVehicleMod(vehicle, 6),
|
||||
modHood = GetVehicleMod(vehicle, 7),
|
||||
modFender = GetVehicleMod(vehicle, 8),
|
||||
modRightFender = GetVehicleMod(vehicle, 9),
|
||||
modRoof = GetVehicleMod(vehicle, 10),
|
||||
|
||||
modEngine = GetVehicleMod(vehicle, 11),
|
||||
modBrakes = GetVehicleMod(vehicle, 12),
|
||||
modTransmission = GetVehicleMod(vehicle, 13),
|
||||
modHorns = GetVehicleMod(vehicle, 14),
|
||||
modSuspension = GetVehicleMod(vehicle, 15),
|
||||
modArmor = GetVehicleMod(vehicle, 16),
|
||||
|
||||
modTurbo = IsToggleModOn(vehicle, 18),
|
||||
modXenon = IsToggleModOn(vehicle, 22),
|
||||
|
||||
modFrontWheels = GetVehicleMod(vehicle, 23),
|
||||
modBackWheels = GetVehicleMod(vehicle, 24)
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
ESX.Game.SetVehicleProperties = function(vehicle, props)
|
||||
|
||||
SetVehicleModKit(vehicle, 0)
|
||||
|
||||
if props.plate ~= nil then
|
||||
SetVehicleNumberPlateText(vehicle, props.plate)
|
||||
end
|
||||
|
||||
if props.plateIndex ~= nil then
|
||||
SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex)
|
||||
end
|
||||
|
||||
if props.health ~= nil then
|
||||
SetEntityHealth(vehicle, props.health)
|
||||
end
|
||||
|
||||
if props.dirtLevel ~= nil then
|
||||
SetVehicleDirtLevel(vehicle, props.dirtLevel)
|
||||
end
|
||||
|
||||
if props.color1 ~= nil and props.color2 ~= nil then
|
||||
SetVehicleColours(vehicle, props.color1, props.color2)
|
||||
end
|
||||
|
||||
if props.pearlescentColor ~= nil and props.wheelColor ~= nil then
|
||||
SetVehicleExtraColours(vehicle, props.pearlescentColor, props.wheelColor)
|
||||
end
|
||||
|
||||
if props.wheels ~= nil then
|
||||
SetVehicleWheelType(vehicle, props.wheels)
|
||||
end
|
||||
|
||||
if props.windowTint ~= nil then
|
||||
SetVehicleWindowTint(vehicle, props.windowTint)
|
||||
end
|
||||
|
||||
if props.neonColor ~= nil then
|
||||
SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3])
|
||||
end
|
||||
|
||||
if props.modSpoilers ~= nil then
|
||||
SetVehicleMod(vehicle, 0, props.modSpoilers, false)
|
||||
end
|
||||
|
||||
if props.modFrontBumper ~= nil then
|
||||
SetVehicleMod(vehicle, 1, props.modFrontBumper, false)
|
||||
end
|
||||
|
||||
if props.modRearBumper ~= nil then
|
||||
SetVehicleMod(vehicle, 2, props.modRearBumper, false)
|
||||
end
|
||||
|
||||
if props.modSideSkirt ~= nil then
|
||||
SetVehicleMod(vehicle, 3, props.modSideSkirt, false)
|
||||
end
|
||||
|
||||
if props.modExhaust ~= nil then
|
||||
SetVehicleMod(vehicle, 4, props.modExhaust, false)
|
||||
end
|
||||
|
||||
if props.modFrame ~= nil then
|
||||
SetVehicleMod(vehicle, 5, props.modFrame, false)
|
||||
end
|
||||
|
||||
if props.modGrille ~= nil then
|
||||
SetVehicleMod(vehicle, 6, props.modGrille, false)
|
||||
end
|
||||
|
||||
if props.modHood ~= nil then
|
||||
SetVehicleMod(vehicle, 7, props.modHood, false)
|
||||
end
|
||||
|
||||
if props.modFender ~= nil then
|
||||
SetVehicleMod(vehicle, 8, props.modFender, false)
|
||||
end
|
||||
|
||||
if props.modRightFender ~= nil then
|
||||
SetVehicleMod(vehicle, 9, props.modRightFender, false)
|
||||
end
|
||||
|
||||
if props.modRoof ~= nil then
|
||||
SetVehicleMod(vehicle, 10, props.modRoof, false)
|
||||
end
|
||||
|
||||
if props.modEngine ~= nil then
|
||||
SetVehicleMod(vehicle, 11, props.modEngine, false)
|
||||
end
|
||||
|
||||
if props.modBrakes ~= nil then
|
||||
SetVehicleMod(vehicle, 12, props.modBrakes, false)
|
||||
end
|
||||
|
||||
if props.modTransmission ~= nil then
|
||||
SetVehicleMod(vehicle, 13, props.modTransmission, false)
|
||||
end
|
||||
|
||||
if props.modHorns ~= nil then
|
||||
SetVehicleMod(vehicle, 14, props.modHorns, false)
|
||||
end
|
||||
|
||||
if props.modSuspension ~= nil then
|
||||
SetVehicleMod(vehicle, 15, props.modSuspension, false)
|
||||
end
|
||||
|
||||
if props.modArmor ~= nil then
|
||||
SetVehicleMod(vehicle, 16, props.modArmor, false)
|
||||
end
|
||||
|
||||
if props.modTurbo ~= nil then
|
||||
ToggleVehicleMod(vehicle, 18, props.modTurbo)
|
||||
end
|
||||
|
||||
if props.modXenon ~= nil then
|
||||
ToggleVehicleMod(vehicle, 22, props.modXenon)
|
||||
end
|
||||
|
||||
if props.modFrontWheels ~= nil then
|
||||
SetVehicleMod(vehicle, 23, props.modFrontWheels, false)
|
||||
end
|
||||
|
||||
if props.modBackWheels ~= nil then
|
||||
SetVehicleMod(vehicle, 24, props.modBackWheels, false)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ESX.ShowInventory = function()
|
||||
|
||||
ESX.TriggerServerCallback('esx:getPlayerData', function(data)
|
||||
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
local elements = {}
|
||||
|
||||
table.insert(elements, {
|
||||
label = '[Cash] $' .. data.money,
|
||||
count = data.money,
|
||||
type = 'item_money',
|
||||
value = 'money',
|
||||
usable = false
|
||||
})
|
||||
|
||||
for i=1, #data.accounts, 1 do
|
||||
table.insert(elements, {
|
||||
label = '[' .. data.accounts[i].label .. '] $' .. data.accounts[i].money,
|
||||
count = data.accounts[i].money,
|
||||
type = 'item_account',
|
||||
value = data.accounts[i].name,
|
||||
usable = false
|
||||
})
|
||||
end
|
||||
|
||||
for i=1, #data.inventory, 1 do
|
||||
|
||||
if data.inventory[i].count > 0 then
|
||||
table.insert(elements, {
|
||||
label = data.inventory[i].label .. ' x' .. data.inventory[i].count,
|
||||
count = data.inventory[i].count,
|
||||
type = 'item_standard',
|
||||
value = data.inventory[i].name,
|
||||
usable = data.inventory[i].usable
|
||||
})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
for i=1, #Config.Weapons, 1 do
|
||||
|
||||
local weaponHash = GetHashKey(Config.Weapons[i].name)
|
||||
|
||||
if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then
|
||||
|
||||
local ammo = GetAmmoInPedWeapon(playerPed, weaponHash)
|
||||
|
||||
table.insert(elements, {
|
||||
label = Config.Weapons[i].label .. ' x1 [' .. ammo .. ']',
|
||||
count = 1,
|
||||
type = 'item_weapon',
|
||||
value = Config.Weapons[i].name,
|
||||
usable = false
|
||||
})
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
ESX.UI.Menu.CloseAll()
|
||||
|
||||
ESX.UI.Menu.Open(
|
||||
'default', GetCurrentResourceName(), 'inventory',
|
||||
{
|
||||
title = 'Inventaire',
|
||||
align = 'bottom-right',
|
||||
elements = elements,
|
||||
},
|
||||
function(data, menu)
|
||||
|
||||
menu.close()
|
||||
|
||||
local elements = {}
|
||||
|
||||
if data.current.usable then
|
||||
table.insert(elements, {label = 'Utiliser', action = 'use', type = data.current.type, value = data.current.value})
|
||||
end
|
||||
|
||||
table.insert(elements, {label = 'Donner', action = 'give', type = data.current.type, value = data.current.value})
|
||||
table.insert(elements, {label = 'Jeter', action = 'remove', type = data.current.type, value = data.current.value})
|
||||
table.insert(elements, {label = 'Retour', action = 'return'})
|
||||
|
||||
ESX.UI.Menu.Open(
|
||||
'default', GetCurrentResourceName(), 'inventory_item',
|
||||
{
|
||||
title = 'Inventaire',
|
||||
align = 'bottom-right',
|
||||
elements = elements,
|
||||
},
|
||||
function(data, menu)
|
||||
|
||||
local item = data.current.value
|
||||
local type = data.current.type
|
||||
|
||||
if data.current.action == 'give' then
|
||||
|
||||
if type == 'item_weapon' then
|
||||
TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1)
|
||||
else
|
||||
|
||||
ESX.UI.Menu.Open(
|
||||
'dialog', GetCurrentResourceName(), 'inventory_item_count_give',
|
||||
{
|
||||
title = 'Quantité'
|
||||
},
|
||||
function(data2, menu)
|
||||
|
||||
local quantity = tonumber(data2.value)
|
||||
local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer()
|
||||
|
||||
if closestPlayer == -1 or closestDistance > 3.0 then
|
||||
ESX.ShowNotification('Aucun joueur à proximité')
|
||||
else
|
||||
TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity)
|
||||
end
|
||||
|
||||
menu.close()
|
||||
end,
|
||||
function(data2, menu)
|
||||
menu.close()
|
||||
end
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
elseif data.current.action == 'remove' then
|
||||
|
||||
if type == 'item_weapon' then
|
||||
TriggerServerEvent('esx:removeInventoryItem', type, item, 1)
|
||||
else
|
||||
|
||||
ESX.UI.Menu.Open(
|
||||
'dialog', GetCurrentResourceName(), 'inventory_item_count_remove',
|
||||
{
|
||||
title = 'Quantité'
|
||||
},
|
||||
function(data2, menu)
|
||||
|
||||
local quantity = tonumber(data2.value)
|
||||
|
||||
if quantity == nil then
|
||||
ESX.ShowNotification('Montant invalide')
|
||||
else
|
||||
|
||||
menu.close()
|
||||
|
||||
TriggerServerEvent('esx:removeInventoryItem', type, item, quantity)
|
||||
|
||||
end
|
||||
|
||||
end,
|
||||
function(data2, menu)
|
||||
menu.close()
|
||||
end
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
elseif data.current.action == 'return' then
|
||||
ESX.UI.Menu.CloseAll()
|
||||
ESX.ShowInventory()
|
||||
end
|
||||
|
||||
end,
|
||||
function(data, menu)
|
||||
ESX.UI.Menu.CloseAll()
|
||||
ESX.ShowInventory()
|
||||
end
|
||||
)
|
||||
|
||||
end,
|
||||
function(data, menu)
|
||||
menu.close()
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
AddEventHandler('esx:getSharedObject', function(cb)
|
||||
cb(ESX)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:serverCallback')
|
||||
AddEventHandler('esx:serverCallback', function(requestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z)
|
||||
ESX.ServerCallbacks[requestId](a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z)
|
||||
ESX.ServerCallbacks[requestId] = nil
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:showNotification')
|
||||
AddEventHandler('esx:showNotification', function(msg)
|
||||
ESX.ShowNotification(msg)
|
||||
end)
|
||||
|
||||
-- SetTimeout
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
|
||||
Citizen.Wait(0)
|
||||
|
||||
local currTime = GetGameTimer()
|
||||
|
||||
for i=1, #ESX.TimeoutCallbacks, 1 do
|
||||
|
||||
if currTime >= ESX.TimeoutCallbacks[i].time then
|
||||
ESX.TimeoutCallbacks[i].cb()
|
||||
ESX.TimeoutCallbacks[i] = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,372 @@
|
||||
local Keys = {
|
||||
["ESC"] = 322, ["F1"] = 288, ["F2"] = 289, ["F3"] = 170, ["F5"] = 166, ["F6"] = 167, ["F7"] = 168, ["F8"] = 169, ["F9"] = 56, ["F10"] = 57,
|
||||
["~"] = 243, ["1"] = 157, ["2"] = 158, ["3"] = 160, ["4"] = 164, ["5"] = 165, ["6"] = 159, ["7"] = 161, ["8"] = 162, ["9"] = 163, ["-"] = 84, ["="] = 83, ["BACKSPACE"] = 177,
|
||||
["TAB"] = 37, ["Q"] = 44, ["W"] = 32, ["E"] = 38, ["R"] = 45, ["T"] = 245, ["Y"] = 246, ["U"] = 303, ["P"] = 199, ["["] = 39, ["]"] = 40, ["ENTER"] = 18,
|
||||
["CAPS"] = 137, ["A"] = 34, ["S"] = 8, ["D"] = 9, ["F"] = 23, ["G"] = 47, ["H"] = 74, ["K"] = 311, ["L"] = 182,
|
||||
["LEFTSHIFT"] = 21, ["Z"] = 20, ["X"] = 73, ["C"] = 26, ["V"] = 0, ["B"] = 29, ["N"] = 249, ["M"] = 244, [","] = 82, ["."] = 81,
|
||||
["LEFTCTRL"] = 36, ["LEFTALT"] = 19, ["SPACE"] = 22, ["RIGHTCTRL"] = 70,
|
||||
["HOME"] = 213, ["PAGEUP"] = 10, ["PAGEDOWN"] = 11, ["DELETE"] = 178,
|
||||
["LEFT"] = 174, ["RIGHT"] = 175, ["TOP"] = 27, ["DOWN"] = 173,
|
||||
["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118
|
||||
}
|
||||
|
||||
local GUI = {}
|
||||
GUI.Time = 0
|
||||
local PlayerLoaded = false
|
||||
local LoadoutLoaded = false
|
||||
local IsPaused = false
|
||||
local LastLoadout = {}
|
||||
|
||||
RegisterNetEvent('esx:playerLoaded')
|
||||
AddEventHandler('esx:playerLoaded', function(xPlayer)
|
||||
|
||||
PlayerLoaded = true
|
||||
|
||||
for i=1, #xPlayer.accounts, 1 do
|
||||
|
||||
local accountTpl = '<div><img src="img/accounts/' .. xPlayer.accounts[i].name .. '.png"/> {{money}}</div>'
|
||||
|
||||
ESX.UI.HUD.RegisterElement('account_' .. xPlayer.accounts[i].name, i-1, 0, accountTpl, {
|
||||
money = 0
|
||||
})
|
||||
|
||||
ESX.UI.HUD.UpdateElement('account_' .. xPlayer.accounts[i].name, {
|
||||
money = xPlayer.accounts[i].money
|
||||
})
|
||||
|
||||
end
|
||||
|
||||
local jobTpl = '<div>{{job_label}} - {{grade_label}}</div>'
|
||||
|
||||
if xPlayer.job.grade_label == '' then
|
||||
jobTpl = '<div>{{job_label}}</div>'
|
||||
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
|
||||
})
|
||||
|
||||
end)
|
||||
|
||||
AddEventHandler('playerSpawned', function()
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
|
||||
while not PlayerLoaded do
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
|
||||
ESX.TriggerServerCallback('esx:getPlayerData', function(data)
|
||||
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
|
||||
-- Restore position
|
||||
if data.lastPosition ~= nil then
|
||||
SetEntityCoords(playerPed, data.lastPosition.x, data.lastPosition.y, data.lastPosition.z)
|
||||
end
|
||||
|
||||
-- Restore loadout
|
||||
for i=1, #data.loadout, 1 do
|
||||
local weaponHash = GetHashKey(data.loadout[i].name)
|
||||
GiveWeaponToPed(playerPed, weaponHash, data.loadout[i].ammo, false, false)
|
||||
end
|
||||
|
||||
LoadoutLoaded = true
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
AddEventHandler('skinchanger:LoadDefaultModel', function()
|
||||
LoadoutLoaded = false
|
||||
end)
|
||||
|
||||
AddEventHandler('skinchanger:modelLoaded', function()
|
||||
|
||||
-- Restore loadout
|
||||
ESX.TriggerServerCallback('esx:getPlayerData', function(data)
|
||||
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
|
||||
for i=1, #data.loadout, 1 do
|
||||
local weaponHash = GetHashKey(data.loadout[i].name)
|
||||
GiveWeaponToPed(playerPed, weaponHash, data.loadout[i].ammo, false, false)
|
||||
end
|
||||
|
||||
LoadoutLoaded = true
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:setAccountMoney')
|
||||
AddEventHandler('esx:setAccountMoney', function(account)
|
||||
ESX.UI.HUD.UpdateElement('account_' .. account.name, {
|
||||
money = account.money
|
||||
})
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:addInventoryItem')
|
||||
AddEventHandler('esx:addInventoryItem', function(item, count)
|
||||
|
||||
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)
|
||||
|
||||
ESX.UI.ShowInventoryItemNotification(false, item, count)
|
||||
|
||||
if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then
|
||||
ESX.ShowInventory()
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:addWeapon')
|
||||
AddEventHandler('esx:addWeapon', function(weaponName, ammo)
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
local weaponHash = GetHashKey(weaponName)
|
||||
|
||||
GiveWeaponToPed(playerPed, weaponHash, ammo, false, false)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:removeWeapon')
|
||||
AddEventHandler('esx:removeWeapon', function(weaponName)
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
local weaponHash = GetHashKey(weaponName)
|
||||
|
||||
RemoveWeaponFromPed(playerPed, weaponHash)
|
||||
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(GetPlayerPed(-1)) do
|
||||
RequestCollisionAtCoord(pos.x, pos.y, pos.z)
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
|
||||
SetEntityCoords(GetPlayerPed(-1), pos.x, pos.y, pos.z)
|
||||
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:setJob')
|
||||
AddEventHandler('esx:setJob', function(job)
|
||||
ESX.UI.HUD.UpdateElement('job', {
|
||||
job_label = job.label,
|
||||
grade_label = job.grade_label
|
||||
})
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:loadIPL')
|
||||
AddEventHandler('esx:loadIPL', function(name)
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
LoadMpDlcMaps()
|
||||
EnableMpDlcMaps(true)
|
||||
RequestIpl(name)
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:unloadIPL')
|
||||
AddEventHandler('esx:unloadIPL', function(name)
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
RemoveIpl(name)
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:playAnim')
|
||||
AddEventHandler('esx:playAnim', function(dict, anim)
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
|
||||
local pid = PlayerPedId()
|
||||
|
||||
RequestAnimDict(dict)
|
||||
|
||||
while not HasAnimDictLoaded(dict) do
|
||||
Wait(0)
|
||||
end
|
||||
|
||||
TaskPlayAnim(pid, dict, anim, 1.0, -1.0, 20000, 0, 1, true, true, true)
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:playEmote')
|
||||
AddEventHandler('esx:playEmote', function(emote)
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
|
||||
TaskStartScenarioInPlace(playerPed, emote, 0, false);
|
||||
Wait(20000)
|
||||
ClearPedTasks(playerPed)
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:spawnVehicle')
|
||||
AddEventHandler('esx:spawnVehicle', function(model)
|
||||
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
local coords = GetEntityCoords(playerPed)
|
||||
|
||||
ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle)
|
||||
TaskWarpPedIntoVehicle(playerPed, vehicle, -1)
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
-- Pause menu disable HUD display
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
Citizen.Wait(1)
|
||||
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)
|
||||
|
||||
-- Save loadout
|
||||
Citizen.CreateThread(function()
|
||||
|
||||
while true do
|
||||
|
||||
Wait(0)
|
||||
|
||||
local playerPed = GetPlayerPed(-1)
|
||||
local loadout = {}
|
||||
local loadoutChanged = false
|
||||
|
||||
if IsPedDeadOrDying(playerPed) then
|
||||
LoadoutLoaded = false
|
||||
end
|
||||
|
||||
for i=1, #Config.Weapons, 1 do
|
||||
|
||||
local weaponHash = GetHashKey(Config.Weapons[i].name)
|
||||
|
||||
if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then
|
||||
|
||||
local ammo = GetAmmoInPedWeapon(playerPed, weaponHash)
|
||||
|
||||
if LastLoadout[Config.Weapons[i].name] == nil or LastLoadout[Config.Weapons[i].name] ~= ammo then
|
||||
loadoutChanged = true
|
||||
end
|
||||
|
||||
LastLoadout[Config.Weapons[i].name] = ammo
|
||||
|
||||
table.insert(loadout, {
|
||||
name = Config.Weapons[i].name,
|
||||
ammo = ammo,
|
||||
label = Config.Weapons[i].label
|
||||
})
|
||||
|
||||
else
|
||||
|
||||
if LastLoadout[Config.Weapons[i].name] ~= nil then
|
||||
loadoutChanged = true
|
||||
end
|
||||
|
||||
LastLoadout[Config.Weapons[i].name] = nil
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
if loadoutChanged and LoadoutLoaded then
|
||||
TriggerServerEvent('esx:updateLoadout', loadout)
|
||||
end
|
||||
|
||||
end
|
||||
end)
|
||||
|
||||
-- Menu interactions
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
|
||||
Wait(0)
|
||||
|
||||
if IsControlPressed(0, Keys["F2"]) and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') and (GetGameTimer() - GUI.Time) > 150 then
|
||||
ESX.ShowInventory()
|
||||
GUI.Time = GetGameTimer()
|
||||
end
|
||||
|
||||
end
|
||||
end)
|
||||
|
||||
-- Dot above head
|
||||
if Config.ShowDotAbovePlayer then
|
||||
|
||||
Citizen.CreateThread(function()
|
||||
while true do
|
||||
|
||||
Citizen.Wait(0)
|
||||
|
||||
local players = ESX.Game.GetPlayers()
|
||||
|
||||
for i = 1, #players, 1 do
|
||||
if players[i] ~= PlayerId() then
|
||||
local ped = GetPlayerPed(players[i])
|
||||
local headId = Citizen.InvokeNative(0xBFEFE3321A3F5015, ped, ('·'), false, false, '', false)
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
@@ -0,0 +1,89 @@
|
||||
Config = {}
|
||||
Config.MaxPlayers = 32
|
||||
Config.Accounts = {'bank', 'black_money'}
|
||||
Config.AccountLabels = {bank = 'Banque', black_money = 'Argent Sale'}
|
||||
Config.PaycheckInterval = 7 * 60000
|
||||
Config.ShowDotAbovePlayer = false
|
||||
Config.DisableWantedLevel = true
|
||||
Config.RemoveInventoryItemDelay = 5 * 60000
|
||||
|
||||
Config.Weapons = {
|
||||
|
||||
{name = 'WEAPON_KNIFE', label = 'Couteau'},
|
||||
{name = 'WEAPON_NIGHTSTICK', label = 'Matraque'},
|
||||
{name = 'WEAPON_HAMMER', label = 'Marteau'},
|
||||
{name = 'WEAPON_BAT', label = 'Bat'},
|
||||
{name = 'WEAPON_GOLFCLUB', label = 'Club de golfe'},
|
||||
{name = 'WEAPON_CROWBAR', label = 'Pied de biche'},
|
||||
{name = 'WEAPON_PISTOL', label = 'Pistolet'},
|
||||
{name = 'WEAPON_COMBATPISTOL', label = 'Pistolet de combat'},
|
||||
{name = 'WEAPON_APPISTOL', label = 'Pistolet automatique'},
|
||||
{name = 'WEAPON_PISTOL50', label = 'Pistolet calibre 50'},
|
||||
{name = 'WEAPON_MICROSMG', label = 'Micro SMG'},
|
||||
{name = 'WEAPON_SMG', label = 'SMG'},
|
||||
{name = 'WEAPON_ASSAULTSMG', label = 'SMG d\'assaut'},
|
||||
{name = 'WEAPON_ASSAULTRIFLE', label = 'Fusil d\'assaut'},
|
||||
{name = 'WEAPON_CARBINERIFLE', label = 'Carabine d\'assaut'},
|
||||
{name = 'WEAPON_ADVANCEDRIFLE', label = 'Fusil avancé'},
|
||||
{name = 'WEAPON_MG', label = 'Mitrailleuse'},
|
||||
{name = 'WEAPON_COMBATMG', label = 'Mitrailleuse de combat'},
|
||||
{name = 'WEAPON_PUMPSHOTGUN', label = 'Fusil à pompe'},
|
||||
{name = 'WEAPON_SAWNOFFSHOTGUN', label = 'Carabine à canon scié'},
|
||||
{name = 'WEAPON_ASSAULTSHOTGUN', label = 'Carabine d\'assaut'},
|
||||
{name = 'WEAPON_BULLPUPSHOTGUN', label = 'Carabine Bullpup'},
|
||||
{name = 'WEAPON_STUNGUN', label = 'Tazer'},
|
||||
{name = 'WEAPON_SNIPERRIFLE', label = 'Fusil de sniper'},
|
||||
{name = 'WEAPON_HEAVYSNIPER', label = 'Fusil de sniper lourd'},
|
||||
{name = 'WEAPON_REMOTESNIPER', label = 'Fusil de sniper à distance'},
|
||||
{name = 'WEAPON_GRENADELAUNCHER', label = 'Lance-grenade'},
|
||||
{name = 'WEAPON_RPG', label = 'Lance-rocket'},
|
||||
{name = 'WEAPON_STINGER', label = 'Lance-Missile Stinger'},
|
||||
{name = 'WEAPON_MINIGUN', label = 'Minigun'},
|
||||
{name = 'WEAPON_GRENADE', label = 'Grenade'},
|
||||
{name = 'WEAPON_STICKYBOMB', label = 'Bombe collante'},
|
||||
{name = 'WEAPON_SMOKEGRENADE', label = 'Grenade fumigène'},
|
||||
{name = 'WEAPON_BZGAS', 'Grenade à gaz BZ'},
|
||||
{name = 'WEAPON_MOLOTOV', 'Cocktail molotov'},
|
||||
{name = 'WEAPON_FIREEXTINGUISHER', 'Extincteur'},
|
||||
{name = 'WEAPON_PETROLCAN', 'Jerrican d\'essence'},
|
||||
{name = 'WEAPON_DIGISCANNER', 'Digiscanner'},
|
||||
{name = 'WEAPON_BALL', 'Balle'},
|
||||
{name = 'WEAPON_SNSPISTOL', label = 'Pistolet SNS'},
|
||||
{name = 'WEAPON_BOTTLE', label = 'Bouteille'},
|
||||
{name = 'WEAPON_GUSENBERG', label = 'Balayeuse Gusenberg'},
|
||||
{name = 'WEAPON_SPECIALCARBINE', label = 'Carabine spéciale'},
|
||||
{name = 'WEAPON_HEAVYPISTOL', label = 'Pistolet lourd'},
|
||||
{name = 'WEAPON_BULLPUPRIFLE', label = 'Fusil Bullpup'},
|
||||
{name = 'WEAPON_DAGGER', label = 'Poignard'},
|
||||
{name = 'WEAPON_VINTAGEPISTOL', label = 'Pistolet vintage'},
|
||||
{name = 'WEAPON_FIREWORK', label = 'Feu d\'artifice'},
|
||||
{name = 'WEAPON_MUSKET', label = 'Mousquet'},
|
||||
{name = 'WEAPON_HEAVYSHOTGUN', label = 'Fusil à pompe lourd'},
|
||||
{name = 'WEAPON_MARKSMANRIFLE', label = 'Fusil Marksman'},
|
||||
{name = 'WEAPON_HOMINGLAUNCHER', label = 'Lance tête-chercheuse'},
|
||||
{name = 'WEAPON_PROXMINE', label = 'Mine de proximité'},
|
||||
{name = 'WEAPON_SNOWBALL', label = 'Boule de neige'},
|
||||
{name = 'WEAPON_FLAREGUN', label = 'Lance fusée de détresse'},
|
||||
{name = 'WEAPON_GARBAGEBAG', label = 'Sac poubelle'},
|
||||
{name = 'WEAPON_HANDCUFFS', label = 'Menottes'},
|
||||
{name = 'WEAPON_COMBATPDW', label = 'Arme de défense personnelle'},
|
||||
{name = 'WEAPON_MARKSMANPISTOL', label = 'Pistolet Marksman'},
|
||||
{name = 'WEAPON_KNUCKLE', label = 'Poing américain'},
|
||||
{name = 'WEAPON_HATCHET', label = 'Hachette'},
|
||||
{name = 'WEAPON_RAILGUN', label = 'Canon éléctrique'},
|
||||
{name = 'WEAPON_MACHETE', label = 'Machetta'},
|
||||
{name = 'WEAPON_MACHINEPISTOL', label = 'Pistolet mitrailleur'},
|
||||
{name = 'WEAPON_SWITCHBLADE', label = 'Couteau à cran d\'arrêt'},
|
||||
{name = 'WEAPON_REVOLVER', label = 'Revolver'},
|
||||
{name = 'WEAPON_DBSHOTGUN', label = 'Fusil à pompe double canon'},
|
||||
{name = 'WEAPON_COMPACTRIFLE', label = 'Fusil compact'},
|
||||
{name = 'WEAPON_AUTOSHOTGUN', label = 'Fusil à pompe automatique'},
|
||||
{name = 'WEAPON_BATTLEAXE', label = 'Hache de combat'},
|
||||
{name = 'WEAPON_COMPACTLAUNCHER', label = 'Lanceur compact'},
|
||||
{name = 'WEAPON_MINISMG', label = 'Mini SMG'},
|
||||
{name = 'WEAPON_PIPEBOMB', label = 'Bombe tuyau'},
|
||||
{name = 'WEAPON_POOLCUE', label = 'Queue de billard'},
|
||||
{name = 'WEAPON_WRENCH', label = 'Clé'},
|
||||
{name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'},
|
||||
{name = 'GADGET_PARACHUTE', label = 'Parachute'},
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
@font-face {
|
||||
font-family: 'Pricedown';
|
||||
src: url('../fonts/pdown.ttf') /* TTF file for CSS3 browsers */
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'bankgothic';
|
||||
src: url('../fonts/bankgothic.ttf') /* TTF file for CSS3 browsers */
|
||||
}
|
||||
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#cursor {
|
||||
position: absolute;
|
||||
z-index: 999999;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#hud {
|
||||
position : absolute;
|
||||
font-family: 'Pricedown';
|
||||
font-size : 35px;
|
||||
color : white;
|
||||
padding : 4px;
|
||||
text-shadow:
|
||||
-1px -1px 0 #000,
|
||||
1px -1px 0 #000,
|
||||
-1px 1px 0 #000,
|
||||
1px 1px 0 #000;
|
||||
|
||||
text-align: right;
|
||||
top : 80;
|
||||
right : 40;
|
||||
}
|
||||
|
||||
#inventory_notifications {
|
||||
font-family: bankgothic;
|
||||
position : absolute;
|
||||
right : 40;
|
||||
bottom : 40;
|
||||
font-size : 2em;
|
||||
font-weight: bold;
|
||||
color : #FFF;
|
||||
text-shadow:
|
||||
-1px -1px 0 #000,
|
||||
1px -1px 0 #000,
|
||||
-1px 1px 0 #000,
|
||||
1px 1px 0 #000;
|
||||
}
|
||||
|
||||
.menu {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
min-width : 400px;
|
||||
min-height: : 250px;
|
||||
color : #fff;
|
||||
position : absolute;
|
||||
left : 40;
|
||||
top : 0;
|
||||
}
|
||||
|
||||
.menu .head {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
font-size: 28px;
|
||||
padding: 10px;
|
||||
background: #1A1A1A;
|
||||
border-bottom: 3px solid #BC1635;
|
||||
border-radius: 10px 10px 0 0;
|
||||
-webkit-border-radius: 10px 10px 0 0;
|
||||
-moz-border-radius: 10px 10px 0 0;
|
||||
-o-border-radius: 10px 10px 0 0;
|
||||
box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28);
|
||||
-webkit-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28);
|
||||
-moz-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28);
|
||||
-o-box-shadow: inset 0px 1px 0 rgba(255, 255, 255, 0.28);
|
||||
box-shadow: 1px 1px 10px 4px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.menu .head span {
|
||||
font-family: 'Pricedown';
|
||||
font-size: 28px;
|
||||
padding-left: 15px;
|
||||
padding-top: 6px;
|
||||
}
|
||||
|
||||
.menu .menu-items .menu-item {
|
||||
font-family : 'Open Sans', sans-serif;
|
||||
font-size : 14px;
|
||||
height : 40px;
|
||||
display : block;
|
||||
background-color: #f1f1f1;
|
||||
box-shadow : inset 1px 0px 0px 1px #b8b8b8;
|
||||
height : 32px;
|
||||
line-height : 32px;
|
||||
color : #3A3A3A;
|
||||
text-align : center;
|
||||
}
|
||||
|
||||
.menu .menu-items .menu-item.selected {
|
||||
background-color: #ccc;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1015 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 272 B |
Binary file not shown.
|
After Width: | Height: | Size: 941 B |
Binary file not shown.
|
After Width: | Height: | Size: 376 B |
@@ -0,0 +1,114 @@
|
||||
(() => {
|
||||
|
||||
ESX = {};
|
||||
ESX.HUDElements = [];
|
||||
|
||||
ESX.setHUDDisplay = function(opacity){
|
||||
$('#hud').css('opacity', opacity);
|
||||
}
|
||||
|
||||
ESX.insertHUDElement = function(name, index, priority, html, data){
|
||||
|
||||
ESX.HUDElements.push({
|
||||
name : name,
|
||||
index : index,
|
||||
priority : priority,
|
||||
html : html,
|
||||
data : data
|
||||
})
|
||||
|
||||
ESX.HUDElements.sort((a,b) => {
|
||||
return a.index - b.index || b.priority - a.priority;
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
ESX.updateHUDElement = function(name, data){
|
||||
|
||||
for(let i=0; i<ESX.HUDElements.length; i++)
|
||||
if(ESX.HUDElements[i].name == name)
|
||||
ESX.HUDElements[i].data = data;
|
||||
|
||||
ESX.refreshHUD();
|
||||
|
||||
}
|
||||
|
||||
ESX.deleteHUDElement = function(name){
|
||||
|
||||
for(let i=0; i<ESX.HUDElements.length; i++)
|
||||
if(ESX.HUDElements[i].name == name)
|
||||
ESX.HUDElements.splice(i, 1);
|
||||
|
||||
ESX.refreshHUD();
|
||||
}
|
||||
|
||||
ESX.refreshHUD = function(){
|
||||
|
||||
$('#hud').html('');
|
||||
|
||||
for(let i=0; i<ESX.HUDElements.length; i++){
|
||||
let html = Mustache.render(ESX.HUDElements[i].html, ESX.HUDElements[i].data);
|
||||
$('#hud').append(html);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ESX.inventoryNotification = function(add, item, count){
|
||||
|
||||
let notif = '';
|
||||
|
||||
if(add)
|
||||
notif += '+';
|
||||
else
|
||||
notif += '-';
|
||||
|
||||
notif += count + ' ' + item.label;
|
||||
|
||||
let elem = $('<div>' + notif + '</div>');
|
||||
|
||||
$('#inventory_notifications').append(elem);
|
||||
|
||||
$(elem).delay(3000).fadeOut(1000, function(){
|
||||
elem.remove();
|
||||
})
|
||||
}
|
||||
|
||||
window.onData = (data) => {
|
||||
|
||||
switch(data.action){
|
||||
|
||||
case 'setHUDDisplay' : {
|
||||
ESX.setHUDDisplay(data.opacity);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'insertHUDElement' : {
|
||||
ESX.insertHUDElement(data.name, data.index, data.priority, data.html, data.data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'updateHUDElement' : {
|
||||
ESX.updateHUDElement(data.name, data.data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'deleteHUDElement' : {
|
||||
ESX.deleteHUDElement(data.name);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'inventoryNotification' : {
|
||||
ESX.inventoryNotification(data.add, data.item, data.count)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
window.onload = function(e){
|
||||
window.addEventListener('message', (event) => {
|
||||
onData(event.data)
|
||||
});
|
||||
}
|
||||
|
||||
})()
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,16 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="css/app.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="hud"></div>
|
||||
<div id="inventory_notifications"></div>
|
||||
|
||||
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> -->
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
<script src="js/mustache.min.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,382 @@
|
||||
function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, lastPosition)
|
||||
|
||||
local self = {}
|
||||
|
||||
self.player = player
|
||||
self.accounts = accounts
|
||||
self.inventory = inventory
|
||||
self.job = job
|
||||
self.loadout = loadout
|
||||
self.name = name
|
||||
self.lastPosition = lastPosition
|
||||
|
||||
self.source = self.player.get('source')
|
||||
self.identifier = self.player.get('identifier')
|
||||
|
||||
self.setMoney = function(m)
|
||||
self.player.setMoney(m)
|
||||
end
|
||||
|
||||
self.getMoney = function()
|
||||
return self.player.get('money')
|
||||
end
|
||||
|
||||
self.setBankBalance = function(m)
|
||||
self.player.setBankBalance(m)
|
||||
end
|
||||
|
||||
self.getBank = function()
|
||||
return self.player.get('bank')
|
||||
end
|
||||
|
||||
self.getCoords = function()
|
||||
return self.player.get('coords')
|
||||
end
|
||||
|
||||
self.setCoords = function(x, y, z)
|
||||
self.player.coords = {x = x, y = y, z = z}
|
||||
end
|
||||
|
||||
self.kick = function(r)
|
||||
self.player.kick(r)
|
||||
end
|
||||
|
||||
self.addMoney = function(m)
|
||||
self.player.addMoney(m)
|
||||
end
|
||||
|
||||
self.removeMoney = function(m)
|
||||
self.player.removeMoney(m)
|
||||
end
|
||||
|
||||
self.addBank = function(m)
|
||||
self.player.addBank(m)
|
||||
end
|
||||
|
||||
self.removeBank = function(m)
|
||||
self.player.removeBank(m)
|
||||
end
|
||||
|
||||
self.displayMoney = function(m)
|
||||
self.player.displayMoney(m)
|
||||
end
|
||||
|
||||
self.displayBank = function(m)
|
||||
self.player.displayBank(m)
|
||||
end
|
||||
|
||||
self.setSessionVar = function(key, value)
|
||||
self.player.setSessionVar(key, value)
|
||||
end
|
||||
|
||||
self.getSessionVar = function(k)
|
||||
return self.player.getSessionVar(k)
|
||||
end
|
||||
|
||||
self.getPermissions = function()
|
||||
return self.player.getPermissions()
|
||||
end
|
||||
|
||||
self.setPermissions = function(p)
|
||||
self.player.setPermissions(p)
|
||||
end
|
||||
|
||||
self.getIdentifier = function()
|
||||
return self.player.getIdentifier()
|
||||
end
|
||||
|
||||
self.getGroup = function()
|
||||
return self.player.getGroup()
|
||||
end
|
||||
|
||||
self.set = function(k, v)
|
||||
self.player.set(k, v)
|
||||
end
|
||||
|
||||
self.get = function(k)
|
||||
return self.player.get(k)
|
||||
end
|
||||
|
||||
self.getPlayer = function()
|
||||
return self.player
|
||||
end
|
||||
|
||||
self.getAccounts = function()
|
||||
|
||||
local accounts = {}
|
||||
|
||||
for i=1, #Config.Accounts, 1 do
|
||||
|
||||
if Config.Accounts[i] == 'bank' then
|
||||
|
||||
table.insert(accounts, {
|
||||
name = 'bank',
|
||||
money = self.get('bank'),
|
||||
label = Config.AccountLabels['bank']
|
||||
})
|
||||
|
||||
else
|
||||
|
||||
for j=1, #self.accounts, 1 do
|
||||
if self.accounts[j].name == Config.Accounts[i] then
|
||||
table.insert(accounts, self.accounts[j])
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
return accounts
|
||||
|
||||
end
|
||||
|
||||
self.getAccount = function(a)
|
||||
|
||||
if a == 'bank' then
|
||||
|
||||
return {
|
||||
name = 'bank',
|
||||
money = self.get('bank'),
|
||||
label = Config.AccountLabels['bank']
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
for i=1, #self.accounts, 1 do
|
||||
if self.accounts[i].name == a then
|
||||
return self.accounts[i]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.getInventory = function()
|
||||
return self.inventory
|
||||
end
|
||||
|
||||
self.getJob = function()
|
||||
return self.job
|
||||
end
|
||||
|
||||
self.getLoadout = function()
|
||||
return self.loadout
|
||||
end
|
||||
|
||||
self.getName = function()
|
||||
return self.name
|
||||
end
|
||||
|
||||
self.getLastPosition = function()
|
||||
return self.lastPosition
|
||||
end
|
||||
|
||||
self.getMissingAccounts = function(cb)
|
||||
|
||||
MySQL.Async.fetchAll(
|
||||
'SELECT * FROM `user_accounts` WHERE `identifier` = @identifier',
|
||||
{
|
||||
['@identifier'] = self.getIdentifier()
|
||||
},
|
||||
function(result)
|
||||
|
||||
local missingAccounts = {};
|
||||
|
||||
for i=1, #Config.Accounts, 1 do
|
||||
|
||||
if Config.Accounts[i] ~= 'bank' then
|
||||
|
||||
local found = false
|
||||
|
||||
for j=1, #result, 1 do
|
||||
if Config.Accounts[i] == result[j].name then
|
||||
found = true
|
||||
end
|
||||
end
|
||||
|
||||
if not found then
|
||||
table.insert(missingAccounts, Config.Accounts[i])
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
cb(missingAccounts)
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
self.createAccounts = function(missingAccounts, cb)
|
||||
|
||||
for i=1, #missingAccounts, 1 do
|
||||
MySQL.Async.execute(
|
||||
'INSERT INTO `user_accounts` (identifier, name) VALUES (@identifier, @name)',
|
||||
{
|
||||
['@identifier'] = self.getIdentifier(),
|
||||
['@name'] = missingAccounts[i]
|
||||
},
|
||||
function(rowsChanged)
|
||||
if cb ~= nil then
|
||||
cb()
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
self.setAccountMoney = function(a, m)
|
||||
|
||||
local account = self.getAccount(a)
|
||||
local prevMoney = account.money
|
||||
local newMoney = m
|
||||
|
||||
account.money = newMoney
|
||||
|
||||
if a == 'bank' then
|
||||
self.set('bank', newMoney)
|
||||
end
|
||||
|
||||
TriggerClientEvent('esx:setAccountMoney', self.source, account)
|
||||
end
|
||||
|
||||
self.addAccountMoney = function(a, m)
|
||||
|
||||
local account = self.getAccount(a)
|
||||
local newMoney = account.money + m
|
||||
|
||||
account.money = newMoney
|
||||
|
||||
if a == 'bank' then
|
||||
self.set('bank', newMoney)
|
||||
end
|
||||
|
||||
TriggerClientEvent('esx:setAccountMoney', self.source, account)
|
||||
end
|
||||
|
||||
self.removeAccountMoney = function(a, m)
|
||||
local account = self.getAccount(a)
|
||||
local newMoney = account.money - m
|
||||
|
||||
account.money = newMoney
|
||||
|
||||
if a == 'bank' then
|
||||
self.set('bank', newMoney)
|
||||
end
|
||||
|
||||
TriggerClientEvent('esx:setAccountMoney', self.source, account)
|
||||
end
|
||||
|
||||
self.getInventoryItem = function(name)
|
||||
|
||||
for i=1, #self.inventory, 1 do
|
||||
if self.inventory[i].name == name then
|
||||
return self.inventory[i]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
self.addInventoryItem = function(name, count)
|
||||
|
||||
local item = self.getInventoryItem(name)
|
||||
local newCount = item.count + count
|
||||
item.count = newCount
|
||||
|
||||
TriggerEvent("esx:onAddInventoryItem", self.source, item, count)
|
||||
TriggerClientEvent("esx:addInventoryItem", self.source, item, count)
|
||||
|
||||
end
|
||||
|
||||
self.removeInventoryItem = function(name, count)
|
||||
|
||||
local item = self.getInventoryItem(name)
|
||||
local newCount = item.count - count
|
||||
item.count = newCount
|
||||
|
||||
TriggerEvent("esx:onRemoveInventoryItem", self.source, item, count)
|
||||
TriggerClientEvent("esx:removeInventoryItem", self.source, item, count)
|
||||
|
||||
end
|
||||
|
||||
self.setJob = function(name, grade)
|
||||
|
||||
MySQL.Async.fetchAll(
|
||||
'SELECT * FROM `jobs` WHERE `name` = @name',
|
||||
{
|
||||
['@name'] = name
|
||||
},
|
||||
function(result)
|
||||
|
||||
self.job['id'] = result[1].id
|
||||
self.job['name'] = result[1].name
|
||||
self.job['label'] = result[1].label
|
||||
|
||||
MySQL.Async.fetchAll(
|
||||
'SELECT * FROM `job_grades` WHERE `job_name` = @job_name AND `grade` = @grade',
|
||||
{
|
||||
['@job_name'] = name,
|
||||
['@grade'] = grade
|
||||
},
|
||||
function(result)
|
||||
|
||||
self.job['grade'] = grade
|
||||
self.job['grade_name'] = result[1].name
|
||||
self.job['grade_label'] = result[1].label
|
||||
self.job['grade_salary'] = result[1].salary
|
||||
|
||||
self.job['skin_male'] = nil
|
||||
self.job['skin_female'] = nil
|
||||
|
||||
if result[1].skin_male ~= nil then
|
||||
self.job['skin_male'] = json.decode(result[1].skin_male)
|
||||
end
|
||||
|
||||
if result[1].skin_female ~= nil then
|
||||
self.job['skin_female'] = json.decode(result[1].skin_female)
|
||||
end
|
||||
|
||||
TriggerClientEvent("esx:setJob", self.source, self.job)
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
self.addWeapon = function(weaponName, ammo)
|
||||
|
||||
local weaponLabel = weaponName
|
||||
|
||||
for i=1, #Config.Weapons, 1 do
|
||||
if Config.Weapons[i].name == weaponName then
|
||||
weaponLabel = Config.Weapons[i].label
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo)
|
||||
TriggerClientEvent("esx:addInventoryItem", self.source, {label = weaponLabel}, 1)
|
||||
end
|
||||
|
||||
self.removeWeapon = function(weaponName)
|
||||
|
||||
local weaponLabel = weaponName
|
||||
|
||||
for i=1, #Config.Weapons, 1 do
|
||||
if Config.Weapons[i].name == weaponName then
|
||||
weaponLabel = Config.Weapons[i].label
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
TriggerClientEvent('esx:removeWeapon', self.source, weaponName)
|
||||
TriggerClientEvent("esx:removeInventoryItem", self.source, {label = weaponLabel}, 1)
|
||||
end
|
||||
|
||||
return self
|
||||
|
||||
end
|
||||
@@ -0,0 +1,48 @@
|
||||
TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user)
|
||||
|
||||
TriggerClientEvent("esx:teleport", source, {
|
||||
x = tonumber(args[2]),
|
||||
y = tonumber(args[3]),
|
||||
z = tonumber(args[4])
|
||||
})
|
||||
|
||||
end, function(source, args, user)
|
||||
TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.")
|
||||
end)
|
||||
|
||||
TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user)
|
||||
local xPlayer = ESX.GetPlayerFromId(args[2])
|
||||
xPlayer.setJob(args[3], tonumber(args[4]))
|
||||
end, function(source, args, user)
|
||||
TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.")
|
||||
end, {help = 'Assigner job => setjob [id] [job] [grade_id]'})
|
||||
|
||||
TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user)
|
||||
TriggerClientEvent('esx:loadIPL', -1, args[2])
|
||||
end, function(source, args, user)
|
||||
TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.")
|
||||
end, {help = 'Charger ipl'})
|
||||
|
||||
TriggerEvent('es:addGroupCommand', 'unloadipl', 'admin', function(source, args, user)
|
||||
TriggerClientEvent('esx:unloadIPL', -1, args[2])
|
||||
end, function(source, args, user)
|
||||
TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.")
|
||||
end, {help = 'Décharger ipl'})
|
||||
|
||||
TriggerEvent('es:addGroupCommand', 'playanim', 'admin', function(source, args, user)
|
||||
TriggerClientEvent('esx:playAnim', -1, args[2], args[3])
|
||||
end, function(source, args, user)
|
||||
TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.")
|
||||
end, {help = 'Jouer animation'})
|
||||
|
||||
TriggerEvent('es:addGroupCommand', 'playemote', 'admin', function(source, args, user)
|
||||
TriggerClientEvent('esx:playEmote', -1, args[2])
|
||||
end, function(source, args, user)
|
||||
TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.")
|
||||
end, {help = 'Jouer emote'})
|
||||
|
||||
TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user)
|
||||
TriggerClientEvent('esx:spawnVehicle', source, args[2])
|
||||
end, function(source, args, user)
|
||||
TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.")
|
||||
end, {help = 'Spawn un véhicule'})
|
||||
@@ -0,0 +1,28 @@
|
||||
ESX = {}
|
||||
ESX.Players = {}
|
||||
ESX.UsableItemsCallbacks = {}
|
||||
ESX.Items = {}
|
||||
ESX.ServerCallbacks = {}
|
||||
|
||||
AddEventHandler('esx:getSharedObject', function(cb)
|
||||
cb(ESX)
|
||||
end)
|
||||
|
||||
AddEventHandler('onMySQLReady', function ()
|
||||
|
||||
MySQL.Async.fetchAll(
|
||||
'SELECT * FROM items',
|
||||
{},
|
||||
function(result)
|
||||
|
||||
for i=1, #result, 1 do
|
||||
ESX.Items[result[i].name] = {
|
||||
label = result[i].label,
|
||||
limit = result[i].limit
|
||||
}
|
||||
end
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
||||
@@ -0,0 +1,176 @@
|
||||
local charset = {}
|
||||
|
||||
for i = 48, 57 do table.insert(charset, string.char(i)) end
|
||||
for i = 65, 90 do table.insert(charset, string.char(i)) end
|
||||
for i = 97, 122 do table.insert(charset, string.char(i)) end
|
||||
|
||||
ESX.GetRandomString = function(length)
|
||||
|
||||
math.randomseed(os.time())
|
||||
|
||||
if length > 0 then
|
||||
return ESX.GetRandomString(length - 1) .. charset[math.random(1, #charset)]
|
||||
else
|
||||
return ''
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ESX.RegisterServerCallback = function(name, cb)
|
||||
ESX.ServerCallbacks[name] = cb
|
||||
end
|
||||
|
||||
ESX.TriggerServerCallback = function(name, requestId, source, cb, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z)
|
||||
ESX.ServerCallbacks[name](source, cb, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z)
|
||||
end
|
||||
|
||||
ESX.SavePlayer = function(xPlayer, cb)
|
||||
|
||||
local asyncTasks = {}
|
||||
xPlayer.lastPosition = xPlayer.get('coords')
|
||||
|
||||
-- User accounts
|
||||
for i=1, #xPlayer.accounts, 1 do
|
||||
|
||||
table.insert(asyncTasks, function(cb)
|
||||
|
||||
MySQL.Async.execute(
|
||||
'UPDATE user_accounts SET `money` = @money WHERE identifier = @identifier AND name = @name',
|
||||
{
|
||||
['@money'] = xPlayer.accounts[i].money,
|
||||
['@identifier'] = xPlayer.identifier,
|
||||
['@name'] = xPlayer.accounts[i].name
|
||||
},
|
||||
function(rowsChanged)
|
||||
cb()
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
-- Inventory items
|
||||
for i=1, #xPlayer.inventory, 1 do
|
||||
|
||||
table.insert(asyncTasks, function(cb)
|
||||
|
||||
MySQL.Async.execute(
|
||||
'UPDATE user_inventory SET `count` = @count WHERE identifier = @identifier AND item = @item',
|
||||
{
|
||||
['@count'] = xPlayer.inventory[i].count,
|
||||
['@identifier'] = xPlayer.identifier,
|
||||
['@item'] = xPlayer.inventory[i].name
|
||||
},
|
||||
function(rowsChanged)
|
||||
cb()
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
-- Job, loadout and position
|
||||
table.insert(asyncTasks, function(cb)
|
||||
|
||||
MySQL.Async.execute(
|
||||
'UPDATE users SET `job` = @job, `job_grade` = @job_grade, `loadout` = @loadout, `position` = @position WHERE identifier = @identifier',
|
||||
{
|
||||
['@job'] = xPlayer.job.name,
|
||||
['@job_grade'] = xPlayer.job.grade,
|
||||
['@loadout'] = json.encode(xPlayer.loadout),
|
||||
['@position'] = json.encode(xPlayer.lastPosition),
|
||||
['@identifier'] = xPlayer.identifier
|
||||
},
|
||||
function(rowsChanged)
|
||||
cb()
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
||||
|
||||
Async.parallel(asyncTasks, function(results)
|
||||
|
||||
RconPrint('[SAVED] ' .. xPlayer.name .. "\n")
|
||||
|
||||
if cb ~= nil then
|
||||
cb()
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
ESX.SavePlayers = function(cb)
|
||||
|
||||
local asyncTasks = {}
|
||||
local players = ESX.GetPlayers()
|
||||
|
||||
for k,v in pairs(players) do
|
||||
table.insert(asyncTasks, function(cb)
|
||||
ESX.SavePlayer(v, cb)
|
||||
end)
|
||||
end
|
||||
|
||||
Async.parallelLimit(asyncTasks, 15, function(results)
|
||||
|
||||
RconPrint('[SAVED] All players' .. "\n")
|
||||
|
||||
if cb ~= nil then
|
||||
cb()
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
ESX.StartDBSync = function()
|
||||
|
||||
function saveData()
|
||||
ESX.SavePlayers()
|
||||
SetTimeout(60000, saveData)
|
||||
end
|
||||
|
||||
SetTimeout(60000, saveData)
|
||||
|
||||
end
|
||||
|
||||
ESX.GetPlayers = function()
|
||||
return ESX.Players
|
||||
end
|
||||
|
||||
ESX.GetPlayerFromId = function(source)
|
||||
return ESX.Players[tonumber(source)]
|
||||
end
|
||||
|
||||
ESX.GetPlayerFromIdentifier = function(identifier)
|
||||
|
||||
for k,v in pairs(ESX.Players) do
|
||||
if v.identifier == identifier then
|
||||
return v
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
ESX.RegisterUsableItem = function(item, cb)
|
||||
ESX.UsableItemsCallbacks[item] = cb
|
||||
end
|
||||
|
||||
ESX.UseItem = function(source, item)
|
||||
ESX.UsableItemsCallbacks[item](source)
|
||||
end
|
||||
|
||||
RegisterServerEvent('esx:clientLog')
|
||||
AddEventHandler('esx:clientLog', function(msg)
|
||||
RconPrint(msg)
|
||||
end)
|
||||
|
||||
RegisterServerEvent('esx:triggerServerCallback')
|
||||
AddEventHandler('esx:triggerServerCallback', function(name, requestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z)
|
||||
local _source = source
|
||||
ESX.TriggerServerCallback(name, requestID, _source, function(a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z)
|
||||
TriggerClientEvent('esx:serverCallback', _source, requestId, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z)
|
||||
end, a, b, c, d, e, f, g ,h ,i ,j ,k, l, m, n, o, p, q, r, s, t, u ,v ,w, x ,y ,z)
|
||||
end)
|
||||
@@ -0,0 +1,524 @@
|
||||
AddEventHandler('es:playerLoaded', function(source, _player)
|
||||
|
||||
local _source = source
|
||||
local tasks = {}
|
||||
|
||||
local userData = {
|
||||
accounts = {},
|
||||
inventory = {},
|
||||
job = {},
|
||||
loadout = {},
|
||||
playerName = GetPlayerName(_source),
|
||||
lastPosition = nil
|
||||
}
|
||||
|
||||
TriggerEvent('es:getPlayerFromId', _source, function(player)
|
||||
|
||||
-- Update user name in DB
|
||||
table.insert(tasks, function(cb)
|
||||
|
||||
MySQL.Async.execute(
|
||||
'UPDATE `users` SET `name` = @name WHERE `identifier` = @identifier',
|
||||
{
|
||||
['@identifier'] = player.getIdentifier(),
|
||||
['@name'] = userData.playerName
|
||||
},
|
||||
function(rowsChanged)
|
||||
cb()
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
||||
|
||||
-- Get accounts
|
||||
table.insert(tasks, function(cb)
|
||||
|
||||
MySQL.Async.fetchAll(
|
||||
'SELECT * FROM `user_accounts` WHERE `identifier` = @identifier',
|
||||
{
|
||||
['@identifier'] = player.getIdentifier()
|
||||
},
|
||||
function(accounts)
|
||||
|
||||
for i=1, #Config.Accounts, 1 do
|
||||
for j=1, #accounts, 1 do
|
||||
if accounts[j].name == Config.Accounts[i] then
|
||||
table.insert(userData.accounts, {
|
||||
name = accounts[j].name,
|
||||
money = accounts[j].money,
|
||||
label = Config.AccountLabels[accounts[j].name]
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
cb()
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
||||
|
||||
-- Get Inventory
|
||||
table.insert(tasks, function(cb)
|
||||
|
||||
MySQL.Async.fetchAll(
|
||||
'SELECT * FROM `user_inventory` WHERE `identifier` = @identifier',
|
||||
{
|
||||
['@identifier'] = player.getIdentifier()
|
||||
},
|
||||
function(inventory)
|
||||
|
||||
for i=1, #inventory, 1 do
|
||||
table.insert(userData.inventory, {
|
||||
name = inventory[i].item,
|
||||
count = inventory[i].count,
|
||||
label = ESX.Items[inventory[i].item].label,
|
||||
limit = ESX.Items[inventory[i].item].limit,
|
||||
usable = ESX.UsableItemsCallbacks[inventory[i].item] ~= nil
|
||||
})
|
||||
end
|
||||
|
||||
for k,v in pairs(ESX.Items) do
|
||||
|
||||
local found = false
|
||||
|
||||
for j=1, #userData.inventory, 1 do
|
||||
if userData.inventory[j].name == k then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not found then
|
||||
|
||||
table.insert(userData.inventory, {
|
||||
name = k,
|
||||
count = 0,
|
||||
label = ESX.Items[k].label,
|
||||
limit = ESX.Items[k].limit,
|
||||
usable = ESX.UsableItemsCallbacks[k] ~= nil
|
||||
})
|
||||
|
||||
MySQL.Async.execute(
|
||||
'INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)',
|
||||
{
|
||||
['@identifier'] = player.getIdentifier(),
|
||||
['@item'] = k,
|
||||
['@count'] = 0
|
||||
}
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
table.sort(userData.inventory, function(a,b)
|
||||
return a.label < b.label
|
||||
end)
|
||||
|
||||
cb()
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
||||
|
||||
-- Get job and loadout
|
||||
table.insert(tasks, function(cb)
|
||||
|
||||
local tasks2 = {}
|
||||
|
||||
-- Get job name, grade and last position
|
||||
table.insert(tasks2, function(cb2)
|
||||
|
||||
MySQL.Async.fetchAll(
|
||||
'SELECT * FROM `users` WHERE `identifier` = @identifier',
|
||||
{
|
||||
['@identifier'] = player.getIdentifier()
|
||||
},
|
||||
function(result)
|
||||
|
||||
userData.job['name'] = result[1].job
|
||||
userData.job['grade'] = result[1].job_grade
|
||||
|
||||
if result[1].loadout ~= nil then
|
||||
userData.loadout = json.decode(result[1].loadout)
|
||||
end
|
||||
|
||||
if result[1].position ~= nil then
|
||||
userData.lastPosition = json.decode(result[1].position)
|
||||
end
|
||||
|
||||
cb2()
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
||||
|
||||
-- Get job label
|
||||
table.insert(tasks2, function(cb2)
|
||||
|
||||
MySQL.Async.fetchAll(
|
||||
'SELECT * FROM `jobs` WHERE `name` = @name',
|
||||
{
|
||||
['@name'] = userData.job.name
|
||||
},
|
||||
function(result)
|
||||
|
||||
userData.job['label'] = result[1].label
|
||||
|
||||
cb2()
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
||||
|
||||
-- Get job grade data
|
||||
table.insert(tasks2, function(cb2)
|
||||
|
||||
MySQL.Async.fetchAll(
|
||||
'SELECT * FROM `job_grades` WHERE `job_name` = @job_name AND `grade` = @grade',
|
||||
{
|
||||
['@job_name'] = userData.job.name,
|
||||
['@grade'] = userData.job.grade
|
||||
},
|
||||
function(result)
|
||||
|
||||
userData.job['grade_name'] = result[1].name
|
||||
userData.job['grade_label'] = result[1].label
|
||||
userData.job['grade_salary'] = result[1].salary
|
||||
|
||||
userData.job['skin_male'] = {}
|
||||
userData.job['skin_female'] = {}
|
||||
|
||||
if result[1].skin_male ~= nil then
|
||||
userData.job['skin_male'] = json.decode(result[1].skin_male)
|
||||
end
|
||||
|
||||
if result[1].skin_female ~= nil then
|
||||
userData.job['skin_female'] = json.decode(result[1].skin_female)
|
||||
end
|
||||
|
||||
cb2()
|
||||
|
||||
end
|
||||
)
|
||||
|
||||
end)
|
||||
|
||||
Async.series(tasks2, cb)
|
||||
|
||||
end)
|
||||
|
||||
-- Run Tasks
|
||||
Async.parallel(tasks, function(results)
|
||||
|
||||
local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.lastPosition)
|
||||
|
||||
xPlayer.getMissingAccounts(function(missingAccounts)
|
||||
|
||||
if #missingAccounts > 0 then
|
||||
|
||||
for i=1, #missingAccounts, 1 do
|
||||
table.insert(xPlayer.accounts, {
|
||||
name = missingAccounts[i],
|
||||
money = 0,
|
||||
label = Config.AccountLabels[missingAccounts[i]]
|
||||
})
|
||||
end
|
||||
|
||||
xPlayer.createAccounts(missingAccounts)
|
||||
end
|
||||
|
||||
ESX.Players[_source] = xPlayer
|
||||
|
||||
TriggerEvent('esx:playerLoaded', _source)
|
||||
|
||||
TriggerClientEvent('esx:playerLoaded', _source, {
|
||||
accounts = xPlayer.getAccounts(),
|
||||
inventory = xPlayer.getInventory(),
|
||||
job = xPlayer.getJob(),
|
||||
loadout = xPlayer.getLoadout(),
|
||||
lastPosition = xPlayer.getLastPosition(),
|
||||
money = xPlayer.player.get('money')
|
||||
})
|
||||
|
||||
xPlayer.player.displayMoney(xPlayer.get('money'))
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
AddEventHandler('playerDropped', function()
|
||||
|
||||
local _source = source
|
||||
local xPlayer = ESX.GetPlayerFromId(_source)
|
||||
|
||||
if xPlayer ~= nil then
|
||||
|
||||
TriggerEvent('esx:playerDropped', _source)
|
||||
|
||||
ESX.SavePlayer(xPlayer, function()
|
||||
ESX.Players[_source] = nil
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
RegisterServerEvent('esx:updateLoadout')
|
||||
AddEventHandler('esx:updateLoadout', function(loadout)
|
||||
local xPlayer = ESX.GetPlayerFromId(source)
|
||||
xPlayer.loadout = loadout
|
||||
end)
|
||||
|
||||
RegisterServerEvent('esx:giveInventoryItem')
|
||||
AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount)
|
||||
|
||||
local _source = source
|
||||
|
||||
local sourceXPlayer = ESX.GetPlayerFromId(_source)
|
||||
local targetXPlayer = ESX.GetPlayerFromId(target)
|
||||
|
||||
if type == 'item_standard' then
|
||||
|
||||
local sourceItem = sourceXPlayer.getInventoryItem(itemName)
|
||||
local targetItem = targetXPlayer.getInventoryItem(itemName)
|
||||
|
||||
if itemCount > 0 and sourceItem.count >= itemCount then
|
||||
|
||||
if targetItem.limit ~= -1 and (targetItem.count + sourceItem.count) > targetItem.limit then
|
||||
TriggerClientEvent('esx:showNotification', target, 'Action impossible, depassement de la limite d\'inventaire pour ~b~' .. targetXPlayer.name)
|
||||
else
|
||||
sourceXPlayer.removeInventoryItem(itemName, itemCount)
|
||||
targetXPlayer.addInventoryItem (itemName, itemCount)
|
||||
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. '~s~ à ~b~' .. targetXPlayer.name)
|
||||
TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. '~s~ par ~b~' .. sourceXPlayer.name)
|
||||
end
|
||||
|
||||
else
|
||||
TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~quantité invalide')
|
||||
end
|
||||
|
||||
elseif type == 'item_money' then
|
||||
|
||||
if itemCount > 0 and sourceXPlayer.player.get('money') >= itemCount then
|
||||
|
||||
sourceXPlayer.removeMoney(itemCount)
|
||||
targetXPlayer.addMoney(itemCount)
|
||||
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné ~g~$' .. itemCount .. '~s~ à ~b~' .. targetXPlayer.name)
|
||||
TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu ~g~$' .. itemCount .. '~s~ par ~b~' .. sourceXPlayer.name)
|
||||
|
||||
else
|
||||
TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~montant invalide')
|
||||
end
|
||||
|
||||
elseif type == 'item_account' then
|
||||
|
||||
if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then
|
||||
|
||||
sourceXPlayer.removeAccountMoney(itemName, itemCount)
|
||||
targetXPlayer.addAccountMoney(itemName, itemCount)
|
||||
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. '~s~ à ~b~' .. targetXPlayer.name)
|
||||
TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. '~s~ par ~b~' .. sourceXPlayer.name)
|
||||
|
||||
else
|
||||
TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~montant invalide')
|
||||
end
|
||||
|
||||
elseif type == 'item_weapon' then
|
||||
|
||||
sourceXPlayer.removeWeapon(itemName)
|
||||
targetXPlayer.addWeapon(itemName, itemCount)
|
||||
|
||||
local weaponLabel = itemName
|
||||
|
||||
for i=1, #Config.Weapons, 1 do
|
||||
if Config.Weapons[i].name == itemName then
|
||||
weaponLabel = Config.Weapons[i].label
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Vous avez donné x1 ' .. ' ~g~' .. weaponLabel .. '~s~ à ~b~' .. targetXPlayer.name)
|
||||
TriggerClientEvent('esx:showNotification', target, 'Vous avez reçu x1 ' .. ' ~g~' .. weaponLabel .. '~s~ par ~b~' .. sourceXPlayer.name)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
RegisterServerEvent('esx:removeInventoryItem')
|
||||
AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount)
|
||||
|
||||
local _source = source
|
||||
|
||||
if type == 'item_standard' then
|
||||
|
||||
if itemCount == nil or itemCount <= 0 then
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~quantité invalide')
|
||||
else
|
||||
|
||||
local xPlayer = ESX.GetPlayerFromId(source)
|
||||
local foundItem = nil
|
||||
|
||||
for i=1, #xPlayer.inventory, 1 do
|
||||
if xPlayer.inventory[i].name == itemName then
|
||||
foundItem = xPlayer.inventory[i]
|
||||
end
|
||||
end
|
||||
|
||||
if itemCount > foundItem.count then
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~quantité invalide')
|
||||
else
|
||||
|
||||
TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes')
|
||||
|
||||
SetTimeout(Config.RemoveInventoryItemDelay, function()
|
||||
|
||||
local remainingCount = xPlayer.getInventoryItem(itemName).count
|
||||
local total = itemCount
|
||||
|
||||
if remainingCount < itemCount then
|
||||
total = remainingCount
|
||||
end
|
||||
|
||||
if total > 0 then
|
||||
xPlayer.removeInventoryItem(itemName, total)
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ ' .. foundItem.label .. ' x' .. total)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
elseif type == 'item_money' then
|
||||
|
||||
if itemCount == nil or itemCount <= 0 then
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide')
|
||||
else
|
||||
|
||||
local xPlayer = ESX.GetPlayerFromId(source)
|
||||
|
||||
if itemCount > xPlayer.player.get('money') then
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide')
|
||||
else
|
||||
|
||||
TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes')
|
||||
|
||||
SetTimeout(Config.RemoveInventoryItemDelay, function()
|
||||
|
||||
local remainingCount = xPlayer.player.get('money')
|
||||
local total = itemCount
|
||||
|
||||
if remainingCount < itemCount then
|
||||
total = remainingCount
|
||||
end
|
||||
|
||||
if total > 0 then
|
||||
xPlayer.removeMoney(total)
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ [Cash] $' .. total)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
elseif type == 'item_account' then
|
||||
|
||||
if itemCount == nil or itemCount <= 0 then
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide')
|
||||
else
|
||||
|
||||
local xPlayer = ESX.GetPlayerFromId(source)
|
||||
|
||||
if itemCount > xPlayer.getAccount(itemName).money then
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide')
|
||||
else
|
||||
|
||||
TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes')
|
||||
|
||||
SetTimeout(Config.RemoveInventoryItemDelay, function()
|
||||
|
||||
local remainingCount = xPlayer.getAccount(itemName).money
|
||||
local total = itemCount
|
||||
|
||||
if remainingCount < itemCount then
|
||||
total = remainingCount
|
||||
end
|
||||
|
||||
if total > 0 then
|
||||
xPlayer.removeAccountMoney(itemName, total)
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ [Cash] $' .. total)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
elseif type == 'item_weapon' then
|
||||
|
||||
local weaponLabel = itemName
|
||||
|
||||
for i=1, #Config.Weapons, 1 do
|
||||
if Config.Weapons[i].name == itemName then
|
||||
weaponLabel = Config.Weapons[i].label
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
SetTimeout(Config.RemoveInventoryItemDelay, function()
|
||||
xPlayer.removeWeapon(itemName)
|
||||
TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ x1 ' .. ' ~g~' .. weaponLabel)
|
||||
end)
|
||||
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb)
|
||||
|
||||
local xPlayer = ESX.GetPlayerFromId(source)
|
||||
|
||||
cb({
|
||||
accounts = xPlayer.getAccounts(),
|
||||
inventory = xPlayer.getInventory(),
|
||||
job = xPlayer.getJob(),
|
||||
loadout = xPlayer.getLoadout(),
|
||||
lastPosition = xPlayer.getLastPosition(),
|
||||
money = xPlayer.player.get('money')
|
||||
})
|
||||
|
||||
end)
|
||||
|
||||
ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target)
|
||||
|
||||
local xPlayer = ESX.GetPlayerFromId(target)
|
||||
|
||||
cb({
|
||||
accounts = xPlayer.getAccounts(),
|
||||
inventory = xPlayer.getInventory(),
|
||||
job = xPlayer.getJob(),
|
||||
loadout = xPlayer.getLoadout(),
|
||||
lastPosition = xPlayer.getLastPosition(),
|
||||
money = xPlayer.player.get('money')
|
||||
})
|
||||
|
||||
end)
|
||||
|
||||
TriggerEvent("es:addGroup", "jobmaster", "user", function(group) end)
|
||||
|
||||
ESX.StartDBSync()
|
||||
Submodule
+1
Submodule resources/[esx]/[ui]/esx_menu_default added at 9954bec812
Submodule
+1
Submodule resources/[esx]/[ui]/esx_menu_dialog added at 73f0d5dd0e
Submodule
+1
Submodule resources/[esx]/[ui]/esx_menu_list added at 5bd0f9e9a5
Submodule
+1
Submodule resources/async added at 089dbcc1a5
Reference in New Issue
Block a user