From 0c6b4af7c43c2f791a3f8431c2061dc8757e928c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:41:59 +0200 Subject: [PATCH 001/672] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..fb128760 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# fxserver-es_extended +FXServer ES Extended From 7aeae4820957198efac7b78eb8d77c81fff349d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:52:06 +0200 Subject: [PATCH 002/672] Add files --- .../[essential]/es_extended/__resource.lua | 44 + .../es_extended/client/functions.lua | 781 ++++++++++++++++++ .../[essential]/es_extended/client/main.lua | 372 +++++++++ resources/[essential]/es_extended/config.lua | 89 ++ .../[essential]/es_extended/html/css/app.css | 101 +++ .../es_extended/html/fonts/bankgothic.ttf | Bin 0 -> 36272 bytes .../es_extended/html/fonts/pdown.ttf | Bin 0 -> 151512 bytes .../es_extended/html/img/accounts/bank.png | Bin 0 -> 1015 bytes .../html/img/accounts/black_money.png | Bin 0 -> 1030 bytes .../es_extended/html/img/cursor.png | Bin 0 -> 272 bytes .../es_extended/html/img/keys/enter.png | Bin 0 -> 941 bytes .../es_extended/html/img/keys/return.png | Bin 0 -> 376 bytes .../[essential]/es_extended/html/js/app.js | 114 +++ .../es_extended/html/js/mustache.min.js | 1 + .../[essential]/es_extended/html/ui.html | 16 + .../es_extended/server/classes/player.lua | 382 +++++++++ .../es_extended/server/commands.lua | 48 ++ .../[essential]/es_extended/server/common.lua | 28 + .../es_extended/server/functions.lua | 176 ++++ .../[essential]/es_extended/server/main.lua | 524 ++++++++++++ resources/[esx]/[ui]/esx_menu_default | 1 + resources/[esx]/[ui]/esx_menu_dialog | 1 + resources/[esx]/[ui]/esx_menu_list | 1 + resources/async | 1 + 24 files changed, 2680 insertions(+) create mode 100644 resources/[essential]/es_extended/__resource.lua create mode 100644 resources/[essential]/es_extended/client/functions.lua create mode 100644 resources/[essential]/es_extended/client/main.lua create mode 100644 resources/[essential]/es_extended/config.lua create mode 100644 resources/[essential]/es_extended/html/css/app.css create mode 100644 resources/[essential]/es_extended/html/fonts/bankgothic.ttf create mode 100644 resources/[essential]/es_extended/html/fonts/pdown.ttf create mode 100644 resources/[essential]/es_extended/html/img/accounts/bank.png create mode 100644 resources/[essential]/es_extended/html/img/accounts/black_money.png create mode 100644 resources/[essential]/es_extended/html/img/cursor.png create mode 100644 resources/[essential]/es_extended/html/img/keys/enter.png create mode 100644 resources/[essential]/es_extended/html/img/keys/return.png create mode 100644 resources/[essential]/es_extended/html/js/app.js create mode 100644 resources/[essential]/es_extended/html/js/mustache.min.js create mode 100644 resources/[essential]/es_extended/html/ui.html create mode 100644 resources/[essential]/es_extended/server/classes/player.lua create mode 100644 resources/[essential]/es_extended/server/commands.lua create mode 100644 resources/[essential]/es_extended/server/common.lua create mode 100644 resources/[essential]/es_extended/server/functions.lua create mode 100644 resources/[essential]/es_extended/server/main.lua create mode 160000 resources/[esx]/[ui]/esx_menu_default create mode 160000 resources/[esx]/[ui]/esx_menu_dialog create mode 160000 resources/[esx]/[ui]/esx_menu_list create mode 160000 resources/async diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua new file mode 100644 index 00000000..4157559d --- /dev/null +++ b/resources/[essential]/es_extended/__resource.lua @@ -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' +} \ No newline at end of file diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua new file mode 100644 index 00000000..8e52a0b2 --- /dev/null +++ b/resources/[essential]/es_extended/client/functions.lua @@ -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) \ No newline at end of file diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua new file mode 100644 index 00000000..a2e1adb1 --- /dev/null +++ b/resources/[essential]/es_extended/client/main.lua @@ -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 = '
 {{money}}
' + + 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 = '
{{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 + }) + +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 \ No newline at end of file diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua new file mode 100644 index 00000000..22f1c7c9 --- /dev/null +++ b/resources/[essential]/es_extended/config.lua @@ -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'}, +} \ No newline at end of file diff --git a/resources/[essential]/es_extended/html/css/app.css b/resources/[essential]/es_extended/html/css/app.css new file mode 100644 index 00000000..2f72814b --- /dev/null +++ b/resources/[essential]/es_extended/html/css/app.css @@ -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; +} diff --git a/resources/[essential]/es_extended/html/fonts/bankgothic.ttf b/resources/[essential]/es_extended/html/fonts/bankgothic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f3d8049b052a1f9cfd27557eb3675bc85ce4b9fc GIT binary patch literal 36272 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 D`#l06 literal 0 HcmV?d00001 diff --git a/resources/[essential]/es_extended/html/fonts/pdown.ttf b/resources/[essential]/es_extended/html/fonts/pdown.ttf new file mode 100644 index 0000000000000000000000000000000000000000..69c76cf3f2a6bbc93f570124554fec06d7bbac25 GIT binary patch literal 151512 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 literal 0 HcmV?d00001 diff --git a/resources/[essential]/es_extended/html/img/accounts/bank.png b/resources/[essential]/es_extended/html/img/accounts/bank.png new file mode 100644 index 0000000000000000000000000000000000000000..eb36dc8e70242136858874dc04024f41a4a0ffe4 GIT binary patch literal 1015 zcmV(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZowVTiq@}o(XxOP=4eyC973P=U1kRsFroRJ#! z(58{#776h;aLEM;L{SeVNSr|QQXy1+3PCF$LRAh>$;D}$6yr9(+&K1ncOM65H{N(1 z#D$Kuhc`R(oq6-#%=d|SpP}3h7iYue{}eqbkx7XFRFr{CNQ8)Xb~jy=7uE?4gk`F&OBwm4 zCoMHTH>$?xM%AIWM*@A{$sTp={U_D<+^9-VTDxK-EK`kLJ+5RzDnM!ek$H}yvF_~J zI*(=_0U-a;0)z8Wb)S zQLZ90W&QVw7&*Bd#kDto4a&FO>rT+B>2t%_D-HHP*Nt0qx&3jG%#?*w*}g}u7*V?q zC7?WT9&9^T7ittfS!~IwsWS)S-1}*T;uj^>ZdO>nzDliBXXNxy;O7swHVm3ETF1EN z4>(O1#JYDsk>%W4c>Lb8d62J?Ix`%Uf2Yk(iFNB}y6}hU)_oQ5>d!CYZn)gNQs$4D zKRXVhm%qw}1`)u%qg{dS$JcVyN_M3G6VnGdaH2iso z*ZbP|p!QdtrOPGu48|kL$mfBbu>v}-m+cT8XD>e8k&fM(*Y<#MYaY*k@Ki@S_G~Xi l#{maD><5W>*iW*51^`FRlAF&_hJ*kB002ovPDHLkV1iBj&&U7( literal 0 HcmV?d00001 diff --git a/resources/[essential]/es_extended/html/img/accounts/black_money.png b/resources/[essential]/es_extended/html/img/accounts/black_money.png new file mode 100644 index 0000000000000000000000000000000000000000..a42f6aa5191115bd04d04a728fb3c3463e6f4345 GIT binary patch literal 1030 zcmV+h1o``kP)(_`g8%^e{{R4h=>PzAFaQARU;qF*m;eA5Z<1fd zMgRZT+Hn2g&!y2+1h(>773hKd&LYji7 zJxDS2q!OyV*_F1(HYnsEh!-iPJ(ZSP4aAjfgeH{rV4AN*TFttfb$4bmZx7v>?##{# z?V&y}hv%8+>;1pa$1D1}yJgw3cww6SpVXsi=&FhUWSBxsRZ)ZpHLjQ@PC%vrF-;5A zcci3ZS)uWZC+3;63 zP5NhNQG_7k$iD&Ti^Y6K$y>Lur5_yG;D0)PoSwjGx9WA?yK@Hs5kM{?1izg=O;;2A zE;12U>4j-}Ke7u86iTH~$S#kLGN9`%@&R4v!+raho}Ul3%PuT1H9YLaYQ8!YA?Of- zVztV(#YN7~&4oJYkHxr{N_qVKVv+mBqQ_rKrRWbJ>C*YRIj$`(Qmj_#5W-hqGN!6> zV{%d^3_~`GGW5GJG9sN!Mmm{{ygWMU$&U>V%5RSxkxnKfFN}=5(nrED_VAxIbo05=N-zC3)GHzE;!+1%vw@o_Ie!Z2_5K&81r!?IKr zh1|)L^k^EFQYm)L%mA>fvlD<*LqnXsdzb!LjLmA5H@mvL+HiFMpO3e$U&jh*>&SnZ zV$Kc?zZa1REj@pHO6~;d1>2x z`tTvs=`>qSb=2%5?DW0_oIrm*E|tjU^S*KVxKv_5*ZFQ`g|C;En1A||AJ*1bt5o_1QC~4jk~{59$PIcV{Q6qIgLP zKq^8|I&+4yWpT4m;NyGu+76Wq2dk9|S8_RzKNyeuf?vty+6KQmHpaPRl6W-Aj+7n(5dsSW zU}|`nua=fVm(h*oWj@%uw`CvvUM_QEd6{>0J#-nldmtFgTgU5_if`vg<{vZ*r`$_iK0G#)*@UBUHMF0Q*07*qoM6N<$f`k9( AtN;K2 literal 0 HcmV?d00001 diff --git a/resources/[essential]/es_extended/html/img/cursor.png b/resources/[essential]/es_extended/html/img/cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..39536f953d701b36a90dc56084bafd988371a2fb GIT binary patch literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{1|(OCFP#RYSkfJR9T^xl_H+M9WCij$3p^r= z85sBufiR<}hF1enP_o1|q9iy!t)x7$D3zfgF*C13FE6!3!9>qM&(L5k7uNxxqFzrI z#}Etut!FreS`>I(0^ikVp5f1PInc0ibrsXWO3z8Ee_BE>W<&%Ean9H1Y|@_Ma)5tI zP3vrppG@U}o4EJ`H!a-_TKCSz%v`zHX&3lrYRgJzbSuAt9 z@6PvoS_%Jm+&BGp_A+yZ?Fo&SwU@JtJ?kA`YTb#E`^&mC!8qZZWp1Mjt5em&H79@$ OWAJqKb6Mw<&;$S!<6)ox literal 0 HcmV?d00001 diff --git a/resources/[essential]/es_extended/html/img/keys/enter.png b/resources/[essential]/es_extended/html/img/keys/enter.png new file mode 100644 index 0000000000000000000000000000000000000000..3eb9a1f69f58c651517329c92d28cdb1c605f165 GIT binary patch literal 941 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h5*QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$Aj3=GUpo-U3d6>)E`8wN=`3bZEbov^iFaeu%P z(=cbwj44wlOz4rm5xb{;*Ri~}uR6cp(A&Mg;nJ7c^H#o^DiE{vT2%I1{SRyZiuLSP z%I`LO*R@CY*bePa+aw;ZJ8?S+Bq+DcEWq?az(jNYVCfZ787ofAZePh8!fO)pBkQX z_v_cMN3~tQ9xnRXb?ICkwaPbd-|8+sfB5~ocaKb5*$ZEQP2MMD?ps&IpveBkTdrZ6 zxw-l0$rY8AfmJN&5XWi1Tr~N;qpPCYQm=EdrvtPXJvz5h@~FDPw92D`R+fPvAFW@~ zU8c75`%1Gbh1a`Q>?qE0`*<(h^|W${-y)Ec<2}XS`n>x2)3WZB?5;)4TWYMP-*<76OIq zPp@4X%Z+C%*K#BUX=ORzsAov;Kl`m>i&y`Jz)nzj*Qmyplm-1%6v*YUbiCHwmEO<$ zF|Z@`-}HhOKR<9>X}?rT5Bm9ye^tw4euv}#-v4JmQzRDkY{|X*_d_{Xwfto_xNQ|y z-^Qlff58%JWZtYCU#*y5vIf?_WBTiPU(9hK5Tmx!-~Iodkpb3zr{Lwk`bljQz#(xy zvE05v9vtTHlU}QP{nuV*08Uf+$??{$l9IqgWxio$Zh{XeF$LeaxXn-#^iFnsKzTLkWYeXNfKEXTvUB0pJdzPZ}OMgdS+TyQ( lJso37+@RE7f9~qla<)GklNn{1`ISV`@iy0XBj({-ZRBb+Kpaxz~7srr_xVN`&cQqS`I9#;&|Ns0smZ-L@ zqu)%cbtmkrE=&Hfsn_t^{^k|)kLw3AbqG7mVR+;>`#|k>^_ZL6&QAQlndu0pf*(U6 zREkAFy}^PJuTYF$!{g|Ur7IbD{_6-gJlsE>3DGO)9eE;D=anIC*ESQi{xCV$~42}L!4TJCrkQD1~tJw zr&teYqgpL=o@s|#!;B|~71m*K { + + 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' + notif + ''); + + $('#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) + }); + } + +})() \ No newline at end of file diff --git a/resources/[essential]/es_extended/html/js/mustache.min.js b/resources/[essential]/es_extended/html/js/mustache.min.js new file mode 100644 index 00000000..520cfcb9 --- /dev/null +++ b/resources/[essential]/es_extended/html/js/mustache.min.js @@ -0,0 +1 @@ +(function defineMustache(global,factory){if(typeof exports==="object"&&exports&&typeof exports.nodeName!=="string"){factory(exports)}else if(typeof define==="function"&&define.amd){define(["exports"],factory)}else{global.Mustache={};factory(global.Mustache)}})(this,function mustacheFactory(mustache){var objectToString=Object.prototype.toString;var isArray=Array.isArray||function isArrayPolyfill(object){return objectToString.call(object)==="[object Array]"};function isFunction(object){return typeof object==="function"}function typeStr(obj){return isArray(obj)?"array":typeof obj}function escapeRegExp(string){return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function hasProperty(obj,propName){return obj!=null&&typeof obj==="object"&&propName in obj}var regExpTest=RegExp.prototype.test;function testRegExp(re,string){return regExpTest.call(re,string)}var nonSpaceRe=/\S/;function isWhitespace(string){return!testRegExp(nonSpaceRe,string)}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(string){return String(string).replace(/[&<>"'`=\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile==="string")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error("Invalid tags: "+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+"\\s*");closingTagRe=new RegExp("\\s*"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp("\\s*"+escapeRegExp("}"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===""};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return"";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={".":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf(".")>0){value=context.view;names=name.split(".");index=0;while(value!=null&&index")value=this.renderPartial(token,context,partials,originalTemplate);else if(symbol==="&")value=this.unescapedValue(token,context);else if(symbol==="name")value=this.escapedValue(token,context);else if(symbol==="text")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate){var self=this;var buffer="";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j + + + + + +
+
+ + + + + + + + \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/classes/player.lua b/resources/[essential]/es_extended/server/classes/player.lua new file mode 100644 index 00000000..954dcf63 --- /dev/null +++ b/resources/[essential]/es_extended/server/classes/player.lua @@ -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 \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua new file mode 100644 index 00000000..2d4ccc12 --- /dev/null +++ b/resources/[essential]/es_extended/server/commands.lua @@ -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'}) \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua new file mode 100644 index 00000000..915707f8 --- /dev/null +++ b/resources/[essential]/es_extended/server/common.lua @@ -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) \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua new file mode 100644 index 00000000..44b01413 --- /dev/null +++ b/resources/[essential]/es_extended/server/functions.lua @@ -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) diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua new file mode 100644 index 00000000..251d70c8 --- /dev/null +++ b/resources/[essential]/es_extended/server/main.lua @@ -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() diff --git a/resources/[esx]/[ui]/esx_menu_default b/resources/[esx]/[ui]/esx_menu_default new file mode 160000 index 00000000..9954bec8 --- /dev/null +++ b/resources/[esx]/[ui]/esx_menu_default @@ -0,0 +1 @@ +Subproject commit 9954bec81228b19479730969a76fb75afa2b3b0c diff --git a/resources/[esx]/[ui]/esx_menu_dialog b/resources/[esx]/[ui]/esx_menu_dialog new file mode 160000 index 00000000..73f0d5dd --- /dev/null +++ b/resources/[esx]/[ui]/esx_menu_dialog @@ -0,0 +1 @@ +Subproject commit 73f0d5dd0ee5318e03b9bb5003573ef2e88df66a diff --git a/resources/[esx]/[ui]/esx_menu_list b/resources/[esx]/[ui]/esx_menu_list new file mode 160000 index 00000000..5bd0f9e9 --- /dev/null +++ b/resources/[esx]/[ui]/esx_menu_list @@ -0,0 +1 @@ +Subproject commit 5bd0f9e9a5986d74ebc0465b712db6648d7a92bd diff --git a/resources/async b/resources/async new file mode 160000 index 00000000..089dbcc1 --- /dev/null +++ b/resources/async @@ -0,0 +1 @@ +Subproject commit 089dbcc1a5b3baa2eaca09b8f43d6c14d83cdaaf From 7e6245f53f28027c83eabe5f0f222b87d8e5ae74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 12:56:02 +0200 Subject: [PATCH 003/672] Remove dev comment --- resources/[essential]/es_extended/client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 8e52a0b2..38ea9a91 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -350,7 +350,7 @@ ESX.Game.GetClosestPlayer = function() local target = GetPlayerPed(players[i]) - -- if target ~= playerPed then + if target ~= playerPed then local targetCoords = GetEntityCoords(target) local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, playerCoords.x, playerCoords.y, playerCoords.z, true) @@ -360,7 +360,7 @@ ESX.Game.GetClosestPlayer = function() closestDistance = distance end - -- end + end end From 159f79850bba6c715e68474e11db7e8e03cde95c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 13:00:01 +0200 Subject: [PATCH 004/672] Replace folder copies with submodules --- .gitmodules | 12 ++++++++++++ resources/[esx]/[ui]/esx_menu_default | 1 - resources/[esx]/[ui]/esx_menu_dialog | 1 - resources/[esx]/[ui]/esx_menu_list | 1 - resources/[esx]/[ui]/fxserver-esx_menu_default | 1 + resources/[esx]/[ui]/fxserver-esx_menu_dialog | 1 + resources/[esx]/[ui]/fxserver-esx_menu_list | 1 + resources/async | 1 - resources/fxserver-async | 1 + 9 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 .gitmodules delete mode 160000 resources/[esx]/[ui]/esx_menu_default delete mode 160000 resources/[esx]/[ui]/esx_menu_dialog delete mode 160000 resources/[esx]/[ui]/esx_menu_list create mode 160000 resources/[esx]/[ui]/fxserver-esx_menu_default create mode 160000 resources/[esx]/[ui]/fxserver-esx_menu_dialog create mode 160000 resources/[esx]/[ui]/fxserver-esx_menu_list delete mode 160000 resources/async create mode 160000 resources/fxserver-async diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..452a39c6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,12 @@ +[submodule "resources/[esx]/[ui]/fxserver-esx_menu_default"] + path = resources/[esx]/[ui]/fxserver-esx_menu_default + url = https://github.com/FXServer-ESX/fxserver-esx_menu_default +[submodule "resources/[esx]/[ui]/fxserver-esx_menu_list"] + path = resources/[esx]/[ui]/fxserver-esx_menu_list + url = https://github.com/FXServer-ESX/fxserver-esx_menu_list +[submodule "resources/[esx]/[ui]/fxserver-esx_menu_dialog"] + path = resources/[esx]/[ui]/fxserver-esx_menu_dialog + url = https://github.com/FXServer-ESX/fxserver-esx_menu_dialog +[submodule "resources/fxserver-async"] + path = resources/fxserver-async + url = https://github.com/FXServer-ESX/fxserver-async diff --git a/resources/[esx]/[ui]/esx_menu_default b/resources/[esx]/[ui]/esx_menu_default deleted file mode 160000 index 9954bec8..00000000 --- a/resources/[esx]/[ui]/esx_menu_default +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9954bec81228b19479730969a76fb75afa2b3b0c diff --git a/resources/[esx]/[ui]/esx_menu_dialog b/resources/[esx]/[ui]/esx_menu_dialog deleted file mode 160000 index 73f0d5dd..00000000 --- a/resources/[esx]/[ui]/esx_menu_dialog +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 73f0d5dd0ee5318e03b9bb5003573ef2e88df66a diff --git a/resources/[esx]/[ui]/esx_menu_list b/resources/[esx]/[ui]/esx_menu_list deleted file mode 160000 index 5bd0f9e9..00000000 --- a/resources/[esx]/[ui]/esx_menu_list +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5bd0f9e9a5986d74ebc0465b712db6648d7a92bd diff --git a/resources/[esx]/[ui]/fxserver-esx_menu_default b/resources/[esx]/[ui]/fxserver-esx_menu_default new file mode 160000 index 00000000..b8b97530 --- /dev/null +++ b/resources/[esx]/[ui]/fxserver-esx_menu_default @@ -0,0 +1 @@ +Subproject commit b8b9753005ac7636502a123f8d81cfb43d199d47 diff --git a/resources/[esx]/[ui]/fxserver-esx_menu_dialog b/resources/[esx]/[ui]/fxserver-esx_menu_dialog new file mode 160000 index 00000000..f3300e27 --- /dev/null +++ b/resources/[esx]/[ui]/fxserver-esx_menu_dialog @@ -0,0 +1 @@ +Subproject commit f3300e27cb18d2a6b5d32bf9e36df0a398bd45ff diff --git a/resources/[esx]/[ui]/fxserver-esx_menu_list b/resources/[esx]/[ui]/fxserver-esx_menu_list new file mode 160000 index 00000000..c7303bfb --- /dev/null +++ b/resources/[esx]/[ui]/fxserver-esx_menu_list @@ -0,0 +1 @@ +Subproject commit c7303bfb6b533a032bb23aa2dca92db54b9ea2a6 diff --git a/resources/async b/resources/async deleted file mode 160000 index 089dbcc1..00000000 --- a/resources/async +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 089dbcc1a5b3baa2eaca09b8f43d6c14d83cdaaf diff --git a/resources/fxserver-async b/resources/fxserver-async new file mode 160000 index 00000000..a2c8d748 --- /dev/null +++ b/resources/fxserver-async @@ -0,0 +1 @@ +Subproject commit a2c8d748875b465d2b9dff4070226fb0ea0a7344 From 48bf0ee08f09fc902dcb1db341b09d533f5a332f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 13:14:53 +0200 Subject: [PATCH 005/672] Update mysql-async submodule --- resources/fxserver-async | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/fxserver-async b/resources/fxserver-async index a2c8d748..2708a317 160000 --- a/resources/fxserver-async +++ b/resources/fxserver-async @@ -1 +1 @@ -Subproject commit a2c8d748875b465d2b9dff4070226fb0ea0a7344 +Subproject commit 2708a31751824e91a73cd6867150723fb60ab332 From 163c936f61287c50699ce49b443c64546666c64e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 13:15:55 +0200 Subject: [PATCH 006/672] Update mysql-async submodule --- resources/fxserver-async | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/fxserver-async b/resources/fxserver-async index 2708a317..90ea196b 160000 --- a/resources/fxserver-async +++ b/resources/fxserver-async @@ -1 +1 @@ -Subproject commit 2708a31751824e91a73cd6867150723fb60ab332 +Subproject commit 90ea196bad6e9b5f82a8101758d186a22ee67a88 From 3f1ab268932b892de388bc9592b569923ee63e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 13:19:37 +0200 Subject: [PATCH 007/672] Rename submodules --- .gitmodules | 8 ++++---- .../[ui]/{fxserver-esx_menu_default => esx_menu_default} | 0 .../[ui]/{fxserver-esx_menu_dialog => esx_menu_dialog} | 0 .../[esx]/[ui]/{fxserver-esx_menu_list => esx_menu_list} | 0 resources/{fxserver-async => async} | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename resources/[esx]/[ui]/{fxserver-esx_menu_default => esx_menu_default} (100%) rename resources/[esx]/[ui]/{fxserver-esx_menu_dialog => esx_menu_dialog} (100%) rename resources/[esx]/[ui]/{fxserver-esx_menu_list => esx_menu_list} (100%) rename resources/{fxserver-async => async} (100%) diff --git a/.gitmodules b/.gitmodules index 452a39c6..b58eb350 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,12 +1,12 @@ [submodule "resources/[esx]/[ui]/fxserver-esx_menu_default"] - path = resources/[esx]/[ui]/fxserver-esx_menu_default + path = resources/[esx]/[ui]/esx_menu_default url = https://github.com/FXServer-ESX/fxserver-esx_menu_default [submodule "resources/[esx]/[ui]/fxserver-esx_menu_list"] - path = resources/[esx]/[ui]/fxserver-esx_menu_list + path = resources/[esx]/[ui]/esx_menu_list url = https://github.com/FXServer-ESX/fxserver-esx_menu_list [submodule "resources/[esx]/[ui]/fxserver-esx_menu_dialog"] - path = resources/[esx]/[ui]/fxserver-esx_menu_dialog + path = resources/[esx]/[ui]/esx_menu_dialog url = https://github.com/FXServer-ESX/fxserver-esx_menu_dialog [submodule "resources/fxserver-async"] - path = resources/fxserver-async + path = resources/async url = https://github.com/FXServer-ESX/fxserver-async diff --git a/resources/[esx]/[ui]/fxserver-esx_menu_default b/resources/[esx]/[ui]/esx_menu_default similarity index 100% rename from resources/[esx]/[ui]/fxserver-esx_menu_default rename to resources/[esx]/[ui]/esx_menu_default diff --git a/resources/[esx]/[ui]/fxserver-esx_menu_dialog b/resources/[esx]/[ui]/esx_menu_dialog similarity index 100% rename from resources/[esx]/[ui]/fxserver-esx_menu_dialog rename to resources/[esx]/[ui]/esx_menu_dialog diff --git a/resources/[esx]/[ui]/fxserver-esx_menu_list b/resources/[esx]/[ui]/esx_menu_list similarity index 100% rename from resources/[esx]/[ui]/fxserver-esx_menu_list rename to resources/[esx]/[ui]/esx_menu_list diff --git a/resources/fxserver-async b/resources/async similarity index 100% rename from resources/fxserver-async rename to resources/async From 669f6c76c13e662699d3c3f570b7d89bcc9fca57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 13:21:04 +0200 Subject: [PATCH 008/672] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index fb128760..727b2b9f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # fxserver-es_extended FXServer ES Extended + +[WIP] \ No newline at end of file From f285833ae37ec79eadc0c547c32010da08a21a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 15:25:53 +0200 Subject: [PATCH 009/672] Optimize SQL queries + minor changes --- .../es_extended/server/commands.lua | 3 +- .../[essential]/es_extended/server/common.lua | 26 ++++++- .../es_extended/server/functions.lua | 76 +++++++++++-------- .../[essential]/es_extended/server/main.lua | 3 +- 4 files changed, 73 insertions(+), 35 deletions(-) diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index 2d4ccc12..cf54ee92 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -45,4 +45,5 @@ 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'}) \ No newline at end of file +end, {help = 'Spawn un véhicule'}) + diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index 915707f8..06d8f8af 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -3,6 +3,7 @@ ESX.Players = {} ESX.UsableItemsCallbacks = {} ESX.Items = {} ESX.ServerCallbacks = {} +ESX.LastPlayerData = {} AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) @@ -25,4 +26,27 @@ AddEventHandler('onMySQLReady', function () end ) -end) \ No newline at end of file +end) + +AddEventHandler('esx:playerLoaded', function(source) + + local xPlayer = ESX.GetPlayerFromId(source) + local accounts = {} + local items = {} + local xPlayerAccounts = xPlayer.getAccounts() + local xPlayerItems = xPlayer.getInventory() + + for i=1, #xPlayerAccounts, 1 do + accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money + end + + for i=1, #xPlayerItems, 1 do + items[xPlayerItems[i].name] = xPlayerItems[i].count + end + + ESX.LastPlayerData[source] = { + accounts = accounts, + items = items + } + +end) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 44b01413..cb042b02 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -1,15 +1,15 @@ -local charset = {} +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 +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)] + return ESX.GetRandomString(length - 1) .. Charset[math.random(1, #Charset)] else return '' end @@ -32,42 +32,54 @@ ESX.SavePlayer = function(xPlayer, cb) -- User accounts for i=1, #xPlayer.accounts, 1 do - table.insert(asyncTasks, function(cb) + if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then - 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 - ) + table.insert(asyncTasks, function(cb) - end) + 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) + + ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] = xPlayer.accounts[i].money + + end end -- Inventory items for i=1, #xPlayer.inventory, 1 do - table.insert(asyncTasks, function(cb) + if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then - 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 - ) + table.insert(asyncTasks, function(cb) - end) + 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) + + ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] = xPlayer.inventory[i].count + + end end @@ -164,7 +176,7 @@ end RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) - RconPrint(msg) + RconPrint(msg .. "\n") end) RegisterServerEvent('esx:triggerServerCallback') diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 251d70c8..9e617b1d 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -265,7 +265,8 @@ AddEventHandler('playerDropped', function() TriggerEvent('esx:playerDropped', _source) ESX.SavePlayer(xPlayer, function() - ESX.Players[_source] = nil + ESX.Players[_source] = nil + ESX.LastPlayerData[_source] = nil end) end From d81aaf15bfdb2936422dd470c4278ec2c93bed49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 15:34:23 +0200 Subject: [PATCH 010/672] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 727b2b9f..25f50ab4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ -# fxserver-es_extended +# fxserver-es_extended [WIP] FXServer ES Extended -[WIP] \ No newline at end of file From b904282013fc5eb0d1e66498da07df008b5cbdb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 15:55:11 +0200 Subject: [PATCH 011/672] Add SQL dump --- es_extended.sql | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 es_extended.sql diff --git a/es_extended.sql b/es_extended.sql new file mode 100644 index 00000000..e1a4a9ea --- /dev/null +++ b/es_extended.sql @@ -0,0 +1,56 @@ +USE `gta5_gamemode_essential`; + +ALTER TABLE `users` +ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, +ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, +ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, +ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, +ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, +ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout`; + +CREATE TABLE `items` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `limit` int(11) NOT NULL DEFAULT '-1', + PRIMARY KEY (`id`) +); + +CREATE TABLE `job_grades` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `job_name` varchar(255) DEFAULT NULL, + `grade` int(11) NOT NULL, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `salary` int(11) NOT NULL, + `skin_male` longtext NOT NULL, + `skin_female` longtext NOT NULL, + PRIMARY KEY (`id`) +); + +INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','RSA',200,'{}','{}'); + +CREATE TABLE `jobs` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +); + +INSERT INTO `jobs` VALUES (1,'unemployed','Chômeur'); + +CREATE TABLE `user_accounts` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `money` double NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +); + +CREATE TABLE `user_inventory` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `item` varchar(255) NOT NULL, + `count` int(11) NOT NULL, + PRIMARY KEY (`id`) +); \ No newline at end of file From 826341bc202476d0c4af91ed5c637f240f031836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 15:57:40 +0200 Subject: [PATCH 012/672] Update SQL dump --- es_extended.sql | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/es_extended.sql b/es_extended.sql index e1a4a9ea..411e682b 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -9,14 +9,17 @@ ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout`; CREATE TABLE `items` ( + `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `label` varchar(255) NOT NULL, `limit` int(11) NOT NULL DEFAULT '-1', + PRIMARY KEY (`id`) ); CREATE TABLE `job_grades` ( + `id` int(11) NOT NULL AUTO_INCREMENT, `job_name` varchar(255) DEFAULT NULL, `grade` int(11) NOT NULL, @@ -25,32 +28,39 @@ CREATE TABLE `job_grades` ( `salary` int(11) NOT NULL, `skin_male` longtext NOT NULL, `skin_female` longtext NOT NULL, + PRIMARY KEY (`id`) ); INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','RSA',200,'{}','{}'); CREATE TABLE `jobs` ( + `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `label` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) ); INSERT INTO `jobs` VALUES (1,'unemployed','Chômeur'); CREATE TABLE `user_accounts` ( + `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `money` double NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) ); CREATE TABLE `user_inventory` ( + `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `item` varchar(255) NOT NULL, `count` int(11) NOT NULL, + PRIMARY KEY (`id`) ); \ No newline at end of file From dfb4613324786e88c9f02a43c8b7e7a706636e9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 31 Jul 2017 16:08:54 +0200 Subject: [PATCH 013/672] Update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 25f50ab4..267e6e2d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,14 @@ # fxserver-es_extended [WIP] FXServer ES Extended +[INSTALLATION] + +``` +git clone https://github.com/FXServer-ESX/fxserver-es_extended +cd fxserver-es_extended +git submodule init +git submodule update --recursive +``` + +1) Copy all folders inside resources to your server resources folder +2) Import es_extended.sql in your database From efc7555386e300e4d8150466cd503b863836c3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 10:56:38 +0200 Subject: [PATCH 014/672] Update README.md --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 267e6e2d..f88ada79 100644 --- a/README.md +++ b/README.md @@ -12,3 +12,12 @@ git submodule update --recursive 1) Copy all folders inside resources to your server resources folder 2) Import es_extended.sql in your database +3) Add this in your server.cfg : + +``` +start es_extended + +start esx_menu_default +start esx_menu_list +start esx_menu_dialog +``` \ No newline at end of file From bcdcdb91c28c48c0592f90ebaf30ed483d09ebac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:17:15 +0200 Subject: [PATCH 015/672] Update README.md --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index f88ada79..8b2041d7 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,15 @@ start es_extended start esx_menu_default start esx_menu_list start esx_menu_dialog +``` + +4) Create a resource or add this in an existing resource : + +``` +`server.lua + +TriggerEvent('es:setDefaultSettings', { + nativeMoneySystem = false, +}); + ``` \ No newline at end of file From 9016f70ef69c15c631edc080e6ee39801b68ed1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 1 Aug 2017 11:17:37 +0200 Subject: [PATCH 016/672] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8b2041d7..325054d4 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ start esx_menu_dialog 4) Create a resource or add this in an existing resource : ``` -`server.lua +server.lua TriggerEvent('es:setDefaultSettings', { nativeMoneySystem = false, From 2fcb0b36e043ebea782503660567cf22e0b34c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 13:10:38 +0200 Subject: [PATCH 017/672] Add vehicle functions --- .../es_extended/client/functions.lua | 83 +++++++++++++++---- 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 38ea9a91..63806af8 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -1,8 +1,8 @@ -local charset = {} +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 +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 @@ -21,7 +21,7 @@ ESX.GetRandomString = function(length) math.randomseed(GetGameTimer()) if length > 0 then - return ESX.GetRandomString(length - 1) .. charset[math.random(1, #charset)] + return ESX.GetRandomString(length - 1) .. Charset[math.random(1, #Charset)] else return '' end @@ -267,8 +267,7 @@ end ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) - local playerPed = GetPlayerPed(-1) - local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) + local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) Citizen.CreateThread(function() @@ -279,9 +278,10 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) end local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) - + local id = NetworkGetNetworkIdFromEntity(vehicle) + SetNetworkIdCanMigrate(id, true) - SetEntityAsMissionEntity(vehicle, true, true) + SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) @@ -292,8 +292,6 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) Citizen.Wait(0) end - local id = NetworkGetNetworkIdFromEntity(vehicle) - if cb ~= nil then cb(vehicle) end @@ -304,8 +302,7 @@ end ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) - local playerPed = GetPlayerPed(-1) - local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) + local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) Citizen.CreateThread(function() @@ -319,7 +316,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) local id = NetworkGetNetworkIdFromEntity(vehicle) SetNetworkIdCanMigrate(id, true) - SetEntityAsMissionEntity(vehicle, true, true) + SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) @@ -387,6 +384,64 @@ ESX.Game.GetPlayersInArea = function(coords, area) return playersInArea end +ESX.Game.GetVehicles = function() + + local vehicles = {} + local handle, vehicle = FindFirstVehicle() + local success = nil + + repeat + table.insert(vehicles, vehicle) + success, vehicle = FindNextVehicle(handle) + until not success + + EndFindVehicle(handle) + + return vehicles + +end + +ESX.Game.GetClosestVehicle = function(coords) + + local vehicles = ESX.Game.GetVehicles() + local closestDistance = -1 + local closestPlayer = -1 + + for i=1, #vehicles, 1 do + + local vehicleCoords = GetEntityCoords(vehicles[i]) + local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) + + if closestDistance == -1 or closestDistance > distance then + closestVehicle = vehicles[i] + closestDistance = distance + end + + end + + return closestVehicle, closestDistance + +end + +ESX.Game.GetVehiclesInArea = function(coords, area) + + local vehicles = ESX.Game.GetVehicles() + local vehiclesInArea = {} + + for i=1, #vehicles, 1 do + + local vehicleCoords = GetEntityCoords(vehicles[i]) + local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) + + if distance <= area then + table.insert(vehiclesInArea, vehicles[i]) + end + + end + + return vehiclesInArea +end + ESX.Game.GetVehicleProperties = function(vehicle) local colour1, colour2 = GetVehicleColours(vehicle) From 08fa16c7504d07c9053c57c38eb71cba11c1e3a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 13:34:00 +0200 Subject: [PATCH 018/672] Optionnal coords --- .../es_extended/client/functions.lua | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 63806af8..f1b3f265 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -335,22 +335,28 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) end -ESX.Game.GetClosestPlayer = function() +ESX.Game.GetClosestPlayer = function(coords) local players = ESX.Game.GetPlayers() local closestDistance = -1 local closestPlayer = -1 - local playerPed = GetPlayerPed(-1) - local playerCoords = GetEntityCoords(playerPed) - + local coords = coords + local usePlayerPed = false + + if coords == nil then + usePlayerPed = true + local playerPed = GetPlayerPed(-1) + coords = GetEntityCoords(playerPed) + end + for i=1, #players, 1 do local target = GetPlayerPed(players[i]) - if target ~= playerPed then + if not usePlayerPed or (usePlayerPed and target ~= playerPed) then local targetCoords = GetEntityCoords(target) - local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, playerCoords.x, playerCoords.y, playerCoords.z, true) + local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) if closestDistance == -1 or closestDistance > distance then closestPlayer = players[i] @@ -403,10 +409,16 @@ end ESX.Game.GetClosestVehicle = function(coords) - local vehicles = ESX.Game.GetVehicles() + local vehicles = ESX.Game.GetVehicles() local closestDistance = -1 local closestPlayer = -1 - + local coords = coords + + if coords == nil then + local playerPed = GetPlayerPed(-1) + coords = GetEntityCoords(playerPed) + end + for i=1, #vehicles, 1 do local vehicleCoords = GetEntityCoords(vehicles[i]) From afebc0e23eff5adab5ac86c845667dbadbcd793c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 13:42:08 +0200 Subject: [PATCH 019/672] Remove wrong code --- resources/[essential]/es_extended/client/functions.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index f1b3f265..945fa6a8 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -313,9 +313,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) end local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) - local id = NetworkGetNetworkIdFromEntity(vehicle) - SetNetworkIdCanMigrate(id, true) SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) From 700355cf55710b39de7733aa41c9b19dd0dee66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 3 Aug 2017 15:44:01 +0200 Subject: [PATCH 020/672] Add ESX.Game.Teleport --- .../es_extended/client/functions.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 945fa6a8..f70fe539 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -247,6 +247,23 @@ ESX.GetWeaponLabel = function(name) end +ESX.Game.Teleport = function(entity, coords, cb) + + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + + while not HasCollisionLoadedAroundEntity(entity) do + RequestCollisionAtCoord(coords.x, coords.x, coords.x) + Citizen.Wait(0) + end + + SetEntityCoords(entity, coords.x, coords.y, coords.z) + + if cb ~= nil then + cb() + end + +end + ESX.Game.GetPlayers = function() local maxPlayers = Config.MaxPlayers From d6659dc9afaac0e4e39bdee618e62e2102dd585e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 11:54:00 +0200 Subject: [PATCH 021/672] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 325054d4..20106bde 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # fxserver-es_extended [WIP] FXServer ES Extended +[REQUIREMENTS] + +- essentialmode-mysql : https://github.com/FXServer-ESX/fxserver-essentialmode-mysql + [INSTALLATION] ``` @@ -31,4 +35,4 @@ TriggerEvent('es:setDefaultSettings', { nativeMoneySystem = false, }); -``` \ No newline at end of file +``` From 7339db977c670af457d028ef03b6b310918e082a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 14:02:34 +0200 Subject: [PATCH 022/672] Fix playerPed issue --- resources/[essential]/es_extended/client/functions.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index f70fe539..d9c6be2a 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -357,11 +357,12 @@ ESX.Game.GetClosestPlayer = function(coords) local closestPlayer = -1 local coords = coords local usePlayerPed = false + local playerPed = nil if coords == nil then - usePlayerPed = true - local playerPed = GetPlayerPed(-1) - coords = GetEntityCoords(playerPed) + usePlayerPed = true + playerPed = GetPlayerPed(-1) + coords = GetEntityCoords(playerPed) end for i=1, #players, 1 do From e1498d234092f5d47281e0a3f6e22080144678eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 4 Aug 2017 19:26:40 +0200 Subject: [PATCH 023/672] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 20106bde..094f170f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # fxserver-es_extended [WIP] FXServer ES Extended +[DISCORD] + +https://discord.gg/8P7zjMF + [REQUIREMENTS] - essentialmode-mysql : https://github.com/FXServer-ESX/fxserver-essentialmode-mysql From f827f62dd498f79affa43d65b1a156055b4ee1ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 08:55:02 +0200 Subject: [PATCH 024/672] Edit discord link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 094f170f..244da74e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ FXServer ES Extended [DISCORD] -https://discord.gg/8P7zjMF +https://discord.me/fivem_esx [REQUIREMENTS] From 448fdaa9fae1544a9644129de8e76d69e9a84c56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 11:34:03 +0200 Subject: [PATCH 025/672] Add ESX.Game.Utils.DrawText3D --- .../es_extended/client/functions.lua | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index d9c6be2a..195c4d71 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -15,6 +15,7 @@ ESX.UI.Menu = {} ESX.UI.Menu.RegisteredTypes = {} ESX.UI.Menu.Opened = {} ESX.Game = {} +ESX.Game.Utils = {} ESX.GetRandomString = function(length) @@ -649,6 +650,42 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end +ESX.Game.Utils.DrawText3D = function(coords, text, size) + + local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) + local camCoords = GetGameplayCamCoords() + local dist = GetDistanceBetweenCoords(camCoords.x, camCoords.y, camCoords.z, coords.x, coords.y, coords.z, 1) + local size = size + + if size == nil then + size = 1 + end + + local scale = (size / dist) * 2 + local fov = (1 / GetGameplayCamFov()) * 100 + local scale = scale * fov + + if onScreen then + + SetTextScale(0.0 * scale, 0.55 * scale) + SetTextFont(0) + SetTextProportional(1) + -- SetTextScale(0.0, 0.55) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0, 0, 0, 0, 255) + SetTextEdge(2, 0, 0, 0, 150) + SetTextDropShadow() + SetTextOutline() + SetTextEntry('STRING') + SetTextCentre(1) + + AddTextComponentString(text) + + DrawText(x, y) + end + +end + ESX.ShowInventory = function() ESX.TriggerServerCallback('esx:getPlayerData', function(data) From 3f438c01b005e68cdf5096f149b49c9185c48438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 11:43:40 +0200 Subject: [PATCH 026/672] Add ESX.Game.DeleteVehicle --- resources/[essential]/es_extended/client/functions.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 195c4d71..bcdbd663 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -283,6 +283,11 @@ ESX.Game.GetPlayers = function() end +ESX.Game.DeleteVehicle = function(vehicle) + SetEntityAsMissionEntity(vehicle, false, true) + DeleteVehicle(vehicle) +end + ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) @@ -670,7 +675,6 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size) SetTextScale(0.0 * scale, 0.55 * scale) SetTextFont(0) SetTextProportional(1) - -- SetTextScale(0.0, 0.55) SetTextColour(255, 255, 255, 255) SetTextDropshadow(0, 0, 0, 0, 255) SetTextEdge(2, 0, 0, 0, 150) From 97e0735320d0722467403713d45fa9be3f1b6263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 11:46:38 +0200 Subject: [PATCH 027/672] Update ESX.Game.DeleteVehicle --- resources/[essential]/es_extended/client/functions.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index bcdbd663..6a31c79e 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -285,6 +285,7 @@ end ESX.Game.DeleteVehicle = function(vehicle) SetEntityAsMissionEntity(vehicle, false, true) + SetEntityAsNoLongerNeeded(vehicle) DeleteVehicle(vehicle) end From 55ba8521ab8436ce1528709f098e214d7160f1c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 15:26:00 +0200 Subject: [PATCH 028/672] Update ESX.Game.DeleteVehicle --- resources/[essential]/es_extended/client/functions.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 6a31c79e..c023905f 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -284,9 +284,8 @@ ESX.Game.GetPlayers = function() end ESX.Game.DeleteVehicle = function(vehicle) - SetEntityAsMissionEntity(vehicle, false, true) - SetEntityAsNoLongerNeeded(vehicle) - DeleteVehicle(vehicle) + SetEntityAsMissionEntity(CurrentActionData.vehicle, false, true) + DeleteVehicle(CurrentActionData.vehicle) end ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) From b650b76b2ab578bf08976f87e6bfc5e075783498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 15:26:49 +0200 Subject: [PATCH 029/672] Update ESX.Game.DeleteVehicle --- resources/[essential]/es_extended/client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index c023905f..bcdbd663 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -284,8 +284,8 @@ ESX.Game.GetPlayers = function() end ESX.Game.DeleteVehicle = function(vehicle) - SetEntityAsMissionEntity(CurrentActionData.vehicle, false, true) - DeleteVehicle(CurrentActionData.vehicle) + SetEntityAsMissionEntity(vehicle, false, true) + DeleteVehicle(vehicle) end ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) From 8bc3fad9d499d1fe55815cff25c8817f976204d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 5 Aug 2017 23:55:17 +0200 Subject: [PATCH 030/672] Add weapon types --- resources/[essential]/es_extended/config.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 22f1c7c9..5a166b37 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -84,6 +84,8 @@ Config.Weapons = { {name = 'WEAPON_PIPEBOMB', label = 'Bombe tuyau'}, {name = 'WEAPON_POOLCUE', label = 'Queue de billard'}, {name = 'WEAPON_WRENCH', label = 'Clé'}, + {name = 'WEAPON_FLASHLIGHT', label = 'Lampe torche'}, + {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, {name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'}, {name = 'GADGET_PARACHUTE', label = 'Parachute'}, } \ No newline at end of file From 921a2962b19eb15674a348cbce1bacf38441f648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 10:14:43 +0200 Subject: [PATCH 031/672] Fix missing weapon labels --- resources/[essential]/es_extended/config.lua | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 5a166b37..2c891417 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -42,12 +42,12 @@ Config.Weapons = { {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_BZGAS', label = 'Grenade à gaz BZ'}, + {name = 'WEAPON_MOLOTOV', label = 'Cocktail molotov'}, + {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, + {name = 'WEAPON_PETROLCAN', label = 'Jerrican d\'essence'}, + {name = 'WEAPON_DIGISCANNER', label = 'Digiscanner'}, + {name = 'WEAPON_BALL', label = 'Balle'}, {name = 'WEAPON_SNSPISTOL', label = 'Pistolet SNS'}, {name = 'WEAPON_BOTTLE', label = 'Bouteille'}, {name = 'WEAPON_GUSENBERG', label = 'Balayeuse Gusenberg'}, @@ -85,7 +85,6 @@ Config.Weapons = { {name = 'WEAPON_POOLCUE', label = 'Queue de billard'}, {name = 'WEAPON_WRENCH', label = 'Clé'}, {name = 'WEAPON_FLASHLIGHT', label = 'Lampe torche'}, - {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, {name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'}, {name = 'GADGET_PARACHUTE', label = 'Parachute'}, } \ No newline at end of file From 1f0fe4b6a9f94b0233110e0f3b7bf7cd053315de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 11:50:35 +0200 Subject: [PATCH 032/672] Fix loadDefaultModel --- resources/[essential]/es_extended/client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index a2e1adb1..5e6e8591 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -85,7 +85,7 @@ AddEventHandler('playerSpawned', function() end) -AddEventHandler('skinchanger:LoadDefaultModel', function() +AddEventHandler('skinchanger:loadDefaultModel', function() LoadoutLoaded = false end) From c6aababf26344cc77314176c97b73e3dc993e63f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 18:12:36 +0200 Subject: [PATCH 033/672] Update essentialmode download link --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 244da74e..286e7a95 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ https://discord.me/fivem_esx [REQUIREMENTS] -- essentialmode-mysql : https://github.com/FXServer-ESX/fxserver-essentialmode-mysql +- essentialmode => https://forum.fivem.net/t/release-essentialmode-base/3665 +- esplugin_mysql => https://forum.fivem.net/t/release-essentialmode-base/3665/1181 [INSTALLATION] From 53a5ed6017911d2f4ecbfd9ddb04e3117d058483 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 19:50:04 +0200 Subject: [PATCH 034/672] Add screenshot + description --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 286e7a95..320dd401 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,25 @@ FXServer ES Extended https://discord.me/fivem_esx +[SCREENSHOT] + +![screenshot](http://i.imgur.com/aPFdJl3.jpg) + +[DESCRIPTION] + +Add support for accounts (bank / black money) you can also add others accounts + +Add support for inventory (press F5 ingame) => Players can now remove items from inventory + +Add support for jobs + +Loadouts are saved in database and restored on spawn + +Positions are saved in database and restored on spawn + [REQUIREMENTS] -- essentialmode => https://forum.fivem.net/t/release-essentialmode-base/3665 +- essentialmode + es_admin => https://forum.fivem.net/t/release-essentialmode-base/3665 - esplugin_mysql => https://forum.fivem.net/t/release-essentialmode-base/3665/1181 [INSTALLATION] From 4d2b430781e01aa2d3fefeef58ac9f12d19a2fac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 6 Aug 2017 20:01:00 +0200 Subject: [PATCH 035/672] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 320dd401..fa8471cb 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ https://discord.me/fivem_esx Add support for accounts (bank / black money) you can also add others accounts -Add support for inventory (press F5 ingame) => Players can now remove items from inventory +Add support for inventory (press F2 ingame) => Players can now remove items from inventory Add support for jobs From e2e223d7de2716280f39cc1dddadf0b01cf70ac6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 7 Aug 2017 12:17:27 +0200 Subject: [PATCH 036/672] Update es_extended.sql --- es_extended.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 411e682b..834a229c 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,4 +1,4 @@ -USE `gta5_gamemode_essential`; +USE `essentialmode`; ALTER TABLE `users` ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, @@ -63,4 +63,4 @@ CREATE TABLE `user_inventory` ( `count` int(11) NOT NULL, PRIMARY KEY (`id`) -); \ No newline at end of file +); From a599d6981a46068c20076d8ff356be1beb7b27d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 8 Aug 2017 19:11:33 +0200 Subject: [PATCH 037/672] Add functions --- .../es_extended/client/functions.lua | 114 ++++++++++++++++-- .../es_extended/server/functions.lua | 17 +++ 2 files changed, 121 insertions(+), 10 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index bcdbd663..509211cb 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -265,21 +265,25 @@ ESX.Game.Teleport = function(entity, coords, cb) end -ESX.Game.GetPlayers = function() - - local maxPlayers = Config.MaxPlayers - local players = {} +ESX.Game.SpawnObject = function(model, coords, radius, cb) - for i=0, maxPlayers, 1 do + local model = (type(model) == 'number' and model or GetHashKey(model)) - local ped = GetPlayerPed(i) + Citizen.CreateThread(function() - if DoesEntityExist(ped) then - table.insert(players, i) + RequestModel(model) + + while not HasModelLoaded(model) do + Citizen.Wait(0) end - end - return players + local obj = CreateObject(model, coords.x, coords.y, coords.z, true, true, true) + + if cb ~= nil then + cb(obj) + end + + end) end @@ -356,6 +360,96 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) end +ESX.Game.GetObjects = function() + + local objects = {} + local handle, object = FindFirstObject() + local success = nil + + repeat + table.insert(objects, object) + success, object = FindNextObject(handle) + until not success + + EndFindObject(handle) + + return objects + +end + +ESX.Game.GetClosestObject = function(filter, coords) + + local objects = ESX.Game.GetObjects() + local closestDistance = -1 + local closestPlayer = -1 + local filter = filter + local coords = coords + + if type(filter) == 'string' then + if filter ~= '' then + filter = {filter} + end + end + + if coords == nil then + local playerPed = GetPlayerPed(-1) + coords = GetEntityCoords(playerPed) + end + + for i=1, #objects, 1 do + + local foundObject = false + + if filter == nil or (type(filter) == 'table' and #filter == 0) then + foundObject = true + else + + local objectModel = GetEntityModel(objects[i]) + + for j=1, #filter, 1 do + if objectModel == GetHashKey(filter[j]) then + foundObject = true + end + end + + end + + if foundObject then + + local objectCoords = GetEntityCoords(objects[i]) + local distance = GetDistanceBetweenCoords(objectCoords.x, objectCoords.y, objectCoords.z, coords.x, coords.y, coords.z, true) + + if closestDistance == -1 or closestDistance > distance then + closestObject = objects[i] + closestDistance = distance + end + + end + + end + + return closestObject, closestDistance + +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.GetClosestPlayer = function(coords) local players = ESX.Game.GetPlayers() diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index cb042b02..b1001dba 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -174,6 +174,23 @@ ESX.UseItem = function(source, item) ESX.UsableItemsCallbacks[item](source) 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 + RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) RconPrint(msg .. "\n") From e065a26e46e75008bd1907657a0436fd531a04dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 8 Aug 2017 19:43:48 +0200 Subject: [PATCH 038/672] Fix GetClosestObject and GetClosestVehicle bugs --- resources/[essential]/es_extended/client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 509211cb..64323e53 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -381,7 +381,7 @@ ESX.Game.GetClosestObject = function(filter, coords) local objects = ESX.Game.GetObjects() local closestDistance = -1 - local closestPlayer = -1 + local closestObject = -1 local filter = filter local coords = coords @@ -527,7 +527,7 @@ ESX.Game.GetClosestVehicle = function(coords) local vehicles = ESX.Game.GetVehicles() local closestDistance = -1 - local closestPlayer = -1 + local closestVehicle = -1 local coords = coords if coords == nil then From a2ef3b0aa0383fdd05b69bbe50146062974d664a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 8 Aug 2017 21:35:51 +0200 Subject: [PATCH 039/672] Add usable items --- resources/[essential]/es_extended/client/functions.lua | 6 +++++- resources/[essential]/es_extended/server/main.lua | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 64323e53..7f3d273b 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -858,7 +858,7 @@ ESX.ShowInventory = function() local elements = {} if data.current.usable then - table.insert(elements, {label = 'Utiliser', action = 'use', type = data.current.type, value = data.current.value}) + 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}) @@ -941,6 +941,10 @@ ESX.ShowInventory = function() end + elseif data.current.action == 'use' then + + TriggerServerEvent('esx:useItem', data.current.value) + elseif data.current.action == 'return' then ESX.UI.Menu.CloseAll() ESX.ShowInventory() diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 9e617b1d..5f86cd94 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -490,6 +490,11 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end) +RegisterServerEvent('esx:useItem') +AddEventHandler('esx:useItem', function(item) + ESX.UseItem(source, item) +end) + ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) From 9106a7db2b97d8d5bc73274dcb0d2ab9e58c0702 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 9 Aug 2017 14:08:56 +0200 Subject: [PATCH 040/672] Add LICENSE.txt --- LICENSE.txt | 674 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 674 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 00000000..30ace6a8 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file From 5b97605431b06c31396d162383127e8d49d8bfdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 18:15:32 +0200 Subject: [PATCH 041/672] Add exports, Config.Locale and some functions --- .../[essential]/es_extended/__resource.lua | 13 ++++++++ .../[essential]/es_extended/client/common.lua | 7 +++++ .../es_extended/client/functions.lua | 31 ++++++++++++++++--- resources/[essential]/es_extended/config.lua | 1 + .../[essential]/es_extended/server/common.lua | 4 +++ .../es_extended/server/functions.lua | 4 +++ .../[essential]/es_extended/server/main.lua | 7 +++++ 7 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 resources/[essential]/es_extended/client/common.lua diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 4157559d..005516e5 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -15,6 +15,7 @@ server_scripts { client_scripts { 'config.lua', + 'client/common.lua', 'client/functions.lua', 'client/main.lua' } @@ -41,4 +42,16 @@ files { 'html/img/accounts/bank.png', 'html/img/accounts/black_money.png' +} + +exports { + 'getSharedObject' +} + +server_exports { + 'getSharedObject' +} + +dependencies { + 'essentialmode' } \ No newline at end of file diff --git a/resources/[essential]/es_extended/client/common.lua b/resources/[essential]/es_extended/client/common.lua new file mode 100644 index 00000000..26c0ed40 --- /dev/null +++ b/resources/[essential]/es_extended/client/common.lua @@ -0,0 +1,7 @@ +AddEventHandler('esx:getSharedObject', function(cb) + cb(ESX) +end) + +function getSharedObject() + return ESX +end diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 7f3d273b..18f52c63 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -17,6 +17,10 @@ ESX.UI.Menu.Opened = {} ESX.Game = {} ESX.Game.Utils = {} +ESX.GetConfig = function() + return Config +end + ESX.GetRandomString = function(length) math.randomseed(GetGameTimer()) @@ -123,6 +127,8 @@ end ESX.UI.Menu.RegisterType = function(type, open, close) + print('ESX.UI.Menu.RegisterType => ' .. type) + ESX.UI.Menu.RegisteredTypes[type] = { open = open, close = close, @@ -749,6 +755,27 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end +ESX.Game.TeleportEntity = function(entity, coords, cb) + + Citizen.CreateThread(function() + + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + + while not HasCollisionLoadedAroundEntity(entity) do + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + Citizen.Wait(0) + end + + SetEntityCoords(entity, coords.x, coords.y, coords.z) + + if cb ~= nil then + cb() + end + + end) + +end + ESX.Game.Utils.DrawText3D = function(coords, text, size) local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) @@ -967,10 +994,6 @@ ESX.ShowInventory = function() 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) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 2c891417..f1d53a77 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -6,6 +6,7 @@ Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 +Config.Locale = 'fr_FR' Config.Weapons = { diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index 06d8f8af..b001fcaa 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -9,6 +9,10 @@ AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) end) +function getSharedObject() + return ESX +end + AddEventHandler('onMySQLReady', function () MySQL.Async.fetchAll( diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index b1001dba..f3a25eea 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -4,6 +4,10 @@ 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.GetConfig = function() + return Config +end + ESX.GetRandomString = function(length) math.randomseed(os.time()) diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 5f86cd94..2523e3e8 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -279,6 +279,13 @@ AddEventHandler('esx:updateLoadout', function(loadout) xPlayer.loadout = loadout end) +RegisterServerEvent('esx:updateLastPosition') +AddEventHandler('esx:updateLastPosition', function(position) + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.lastPosition = position +end) + + RegisterServerEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) From 47d51c0fdf30df1af3c53bc57490c894f6f0469f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 18:16:12 +0200 Subject: [PATCH 042/672] Remove debug code --- resources/[essential]/es_extended/client/functions.lua | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 18f52c63..d2eb5fe4 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -126,8 +126,6 @@ ESX.UI.HUD.UpdateElement = function(name, data) end ESX.UI.Menu.RegisterType = function(type, open, close) - - print('ESX.UI.Menu.RegisterType => ' .. type) ESX.UI.Menu.RegisteredTypes[type] = { open = open, From c7f2c27e118754bff91de06fd8202f77fecaa942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 10 Aug 2017 19:04:22 +0200 Subject: [PATCH 043/672] Add setInventoryItem + better weapon management --- .../es_extended/server/classes/player.lua | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/resources/[essential]/es_extended/server/classes/player.lua b/resources/[essential]/es_extended/server/classes/player.lua index 954dcf63..107960e7 100644 --- a/resources/[essential]/es_extended/server/classes/player.lua +++ b/resources/[essential]/es_extended/server/classes/player.lua @@ -300,6 +300,22 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end + self.setInventoryItem = function(name, count) + + local item = self.getInventoryItem(name) + local oldCount = item.count + item.count = count + + if oldCount > item.count then + TriggerEvent("esx:onRemoveInventoryItem", self.source, item, oldCount - item.count ) + TriggerClientEvent("esx:removeInventoryItem", self.source, item, oldCount - item.count ) + else + TriggerEvent("esx:onAddInventoryItem", self.source, item, item.count - oldCount) + TriggerClientEvent("esx:addInventoryItem", self.source, item, item.count - oldCount) + end + + end + self.setJob = function(name, grade) MySQL.Async.fetchAll( @@ -358,6 +374,22 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end + local foundWeapon = false + + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + foundWeapon = true + end + end + + if not foundWeapon then + table.insert(self.loadout, { + name = weaponName, + ammo = ammon, + label = weaponLabel + }) + end + TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) TriggerClientEvent("esx:addInventoryItem", self.source, {label = weaponLabel}, 1) end @@ -373,6 +405,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end + local foundWeapon = false + + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + table.remove(self.loadout, i) + break + end + end + TriggerClientEvent('esx:removeWeapon', self.source, weaponName) TriggerClientEvent("esx:removeInventoryItem", self.source, {label = weaponLabel}, 1) end From 3fbbdb38559e656522d590f9ef1d1d171a9b54df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 11 Aug 2017 16:45:57 +0200 Subject: [PATCH 044/672] Fix callback triggering to early --- resources/[essential]/es_extended/client/main.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 5e6e8591..66a26500 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -91,6 +91,10 @@ end) AddEventHandler('skinchanger:modelLoaded', function() + while not PlayerLoaded do + Citizen.Wait(0) + end + -- Restore loadout ESX.TriggerServerCallback('esx:getPlayerData', function(data) From fe1d0279309822f2d6e865f69350bc4076608b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 11 Aug 2017 17:20:36 +0200 Subject: [PATCH 045/672] Add refresh function for menus --- resources/[essential]/es_extended/client/functions.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index d2eb5fe4..bb508164 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -176,12 +176,14 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change) end end - ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data) - end end + menu.refresh = function() + ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data) + end + menu.setElement = function(i, key, val) menu.data.elements[i][key] = val end From bf637611d0efafc12d052b06b0e7741993ee8785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 11:24:30 +0200 Subject: [PATCH 046/672] Better server callback code + move events in common.lua --- .../es_extended/client/functions.lua | 4 ++-- .../[essential]/es_extended/server/common.lua | 16 ++++++++++++++++ .../es_extended/server/functions.lua | 17 ++--------------- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index bb508164..3b70390e 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -46,11 +46,11 @@ ESX.ShowNotification = function(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.TriggerServerCallback = function(name, cb, ...) 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) + TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, ...) if ESX.CurrentRequestId < 65535 then ESX.CurrentRequestId = ESX.CurrentRequestId + 1 diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index b001fcaa..ffadee09 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -54,3 +54,19 @@ AddEventHandler('esx:playerLoaded', function(source) } end) + +RegisterServerEvent('esx:clientLog') +AddEventHandler('esx:clientLog', function(msg) + RconPrint(msg .. "\n") +end) + +RegisterServerEvent('esx:triggerServerCallback') +AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) + + local _source = source + + ESX.TriggerServerCallback(name, requestID, _source, function(...) + TriggerClientEvent('esx:serverCallback', _source, requestId, ...) + end, ...) + +end) \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index f3a25eea..c8dbc033 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -24,8 +24,8 @@ 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) +ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) + ESX.ServerCallbacks[name](source, cb, ...) end ESX.SavePlayer = function(xPlayer, cb) @@ -194,16 +194,3 @@ ESX.GetWeaponLabel = function(name) end end - -RegisterServerEvent('esx:clientLog') -AddEventHandler('esx:clientLog', function(msg) - RconPrint(msg .. "\n") -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) From 9244d3726555cbcf2cb0a48beaed0f1701cd5678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 12:29:07 +0200 Subject: [PATCH 047/672] Base for translating es_extended --- .../[essential]/es_extended/__resource.lua | 8 ++ .../es_extended/client/functions.lua | 12 +-- resources/[essential]/es_extended/config.lua | 84 +------------------ .../es_extended/config.weapons.lua | 81 ++++++++++++++++++ resources/[essential]/es_extended/locale.lua | 9 ++ .../[essential]/es_extended/locales/en.lua | 8 ++ .../[essential]/es_extended/locales/fr.lua | 8 ++ 7 files changed, 121 insertions(+), 89 deletions(-) create mode 100644 resources/[essential]/es_extended/config.weapons.lua create mode 100644 resources/[essential]/es_extended/locale.lua create mode 100644 resources/[essential]/es_extended/locales/en.lua create mode 100644 resources/[essential]/es_extended/locales/fr.lua diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 005516e5..84a0f8dc 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -6,6 +6,10 @@ server_scripts { '@async/async.lua', '@mysql-async/lib/MySQL.lua', 'config.lua', + 'locale.lua', + 'locales/fr.lua', + 'locales/en.lua', + 'config.weapons.lua', 'server/common.lua', 'server/classes/player.lua', 'server/functions.lua', @@ -15,6 +19,10 @@ server_scripts { client_scripts { 'config.lua', + 'locale.lua', + 'locales/fr.lua', + 'locales/en.lua', + 'config.weapons.lua', 'client/common.lua', 'client/functions.lua', 'client/main.lua' diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 3b70390e..7839dd7e 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -874,7 +874,7 @@ ESX.ShowInventory = function() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'inventory', { - title = 'Inventaire', + title = _U('inventory'), align = 'bottom-right', elements = elements, }, @@ -885,17 +885,17 @@ ESX.ShowInventory = function() local elements = {} if data.current.usable then - table.insert(elements, {label = 'Utiliser', action = 'use', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('use'), 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'}) + table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('return'), action = 'return'}) ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'inventory_item', { - title = 'Inventaire', + title = _U('inventory'), align = 'bottom-right', elements = elements, }, diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index f1d53a77..b372f0eb 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -6,86 +6,4 @@ Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 -Config.Locale = 'fr_FR' - -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', label = 'Grenade à gaz BZ'}, - {name = 'WEAPON_MOLOTOV', label = 'Cocktail molotov'}, - {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, - {name = 'WEAPON_PETROLCAN', label = 'Jerrican d\'essence'}, - {name = 'WEAPON_DIGISCANNER', label = 'Digiscanner'}, - {name = 'WEAPON_BALL', label = '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 = 'WEAPON_FLASHLIGHT', label = 'Lampe torche'}, - {name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'}, - {name = 'GADGET_PARACHUTE', label = 'Parachute'}, -} \ No newline at end of file +Config.Locale = 'fr' diff --git a/resources/[essential]/es_extended/config.weapons.lua b/resources/[essential]/es_extended/config.weapons.lua new file mode 100644 index 00000000..4210cd94 --- /dev/null +++ b/resources/[essential]/es_extended/config.weapons.lua @@ -0,0 +1,81 @@ +Config.Weapons = { + + {name = 'WEAPON_KNIFE', label = _U('weapon_knife')}, + {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', label = 'Grenade à gaz BZ'}, + {name = 'WEAPON_MOLOTOV', label = 'Cocktail molotov'}, + {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, + {name = 'WEAPON_PETROLCAN', label = 'Jerrican d\'essence'}, + {name = 'WEAPON_DIGISCANNER', label = 'Digiscanner'}, + {name = 'WEAPON_BALL', label = '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 = 'WEAPON_FLASHLIGHT', label = 'Lampe torche'}, + {name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'}, + {name = 'GADGET_PARACHUTE', label = 'Parachute'}, +} \ No newline at end of file diff --git a/resources/[essential]/es_extended/locale.lua b/resources/[essential]/es_extended/locale.lua new file mode 100644 index 00000000..5fd59603 --- /dev/null +++ b/resources/[essential]/es_extended/locale.lua @@ -0,0 +1,9 @@ +Locales = {} + +function _(str, ...) -- Translate string + return string.format(Locales[Config.Locale][str], ...) +end + +function _U(str, ...) -- Translate string first char uppercase + return _(str, ...):gsub("^%l", string.upper) +end diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua new file mode 100644 index 00000000..1c4b0fb4 --- /dev/null +++ b/resources/[essential]/es_extended/locales/en.lua @@ -0,0 +1,8 @@ +Locales.en = { + ['inventory'] = 'inventory', + ['use'] = 'use', + ['give'] = 'give', + ['remove'] = 'remove', + ['return'] = 'return', + ['weapon_knife'] = 'knife', +} \ No newline at end of file diff --git a/resources/[essential]/es_extended/locales/fr.lua b/resources/[essential]/es_extended/locales/fr.lua new file mode 100644 index 00000000..77204f96 --- /dev/null +++ b/resources/[essential]/es_extended/locales/fr.lua @@ -0,0 +1,8 @@ +Locales['fr'] = { + ['inventory'] = 'inventaire', + ['use'] = 'utiliser', + ['give'] = 'donner', + ['remove'] = 'jeter', + ['return'] = 'retour', + ['weapon_knife'] = 'couteau', +} \ No newline at end of file From c5382f838c9eee8eb50d5e9bf784cd63a312c507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 12:31:03 +0200 Subject: [PATCH 048/672] Fix typo --- resources/[essential]/es_extended/locales/en.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua index 1c4b0fb4..42abd3f0 100644 --- a/resources/[essential]/es_extended/locales/en.lua +++ b/resources/[essential]/es_extended/locales/en.lua @@ -1,4 +1,4 @@ -Locales.en = { +Locales['en'] = { ['inventory'] = 'inventory', ['use'] = 'use', ['give'] = 'give', From bd3d3fd28dfc7bf40526cb84c07515bf1cf58c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 19:32:12 +0200 Subject: [PATCH 049/672] Fix locale issue --- resources/[essential]/es_extended/locale.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/locale.lua b/resources/[essential]/es_extended/locale.lua index 5fd59603..c8b11067 100644 --- a/resources/[essential]/es_extended/locale.lua +++ b/resources/[essential]/es_extended/locale.lua @@ -5,5 +5,5 @@ function _(str, ...) -- Translate string end function _U(str, ...) -- Translate string first char uppercase - return _(str, ...):gsub("^%l", string.upper) + return tostring(_(str, ...):gsub("^%l", string.upper)) end From a59c3a984be62a6cb8dd05b15e45e7a8f989863f Mon Sep 17 00:00:00 2001 From: nlmarcio Date: Sat, 12 Aug 2017 23:06:22 +0200 Subject: [PATCH 050/672] Add Weapon pickup Allows you to drop your weapon from the inventory. Possibility to spawn the weapon on the ground by activating Config.EnableWeaponPickup in config.lua --- resources/[essential]/es_extended/client/main.lua | 11 ++++++++++- resources/[essential]/es_extended/config.lua | 1 + resources/[essential]/es_extended/server/main.lua | 9 +++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 66a26500..416db725 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -373,4 +373,13 @@ if Config.DisableWantedLevel then end end) -end \ No newline at end of file +end + +-- Pickup Weapon +RegisterNetEvent('esx:pickupWeapon') +AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName) + local ped = GetPlayerPed(-1) + local playerPedPos = GetEntityCoords(ped, true) + CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, 999, 1, false, true) + +end) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index b372f0eb..d87401a8 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -7,3 +7,4 @@ Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 Config.Locale = 'fr' +Config.EnableWeaponPickup = false diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 2523e3e8..1e1ffd03 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -479,17 +479,26 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) elseif type == 'item_weapon' then + local xPlayer = ESX.GetPlayerFromId(source) + local weaponLabel = itemName + local weaponName = nil + local weaponPickup = nil for i=1, #Config.Weapons, 1 do if Config.Weapons[i].name == itemName then weaponLabel = Config.Weapons[i].label + weaponName = Config.Weapons[i].name + weaponPickup = 'PICKUP_'..weaponName break end end SetTimeout(Config.RemoveInventoryItemDelay, function() xPlayer.removeWeapon(itemName) + if Config.EnableWeaponPickup then + TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName) + end TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ x1 ' .. ' ~g~' .. weaponLabel) end) From e270494b1de674e1856760451260504b59c4f4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 12 Aug 2017 23:42:24 +0200 Subject: [PATCH 051/672] Add givemoney, giveaccountmoney, giveitem and giveweapon commands --- .../es_extended/server/commands.lua | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index cf54ee92..d81a2100 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -47,3 +47,71 @@ end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = 'Spawn un véhicule'}) +TriggerEvent('es:addGroupCommand', 'givemoney', 'admin', function(source, args, user) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[2]) + local amount = tonumber(args[3]) + + if amount ~= nil then + xPlayer.addMoney(amount) + else + TriggerClientEvent('esx:showNotification', _source, 'Montant invalide') + end + +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'givemoney [id] [montant]'}) + +TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[2]) + local account = args[3] + local amount = tonumber(args[4]) + + if amount ~= nil then + if xPlayer.getAccount(account) ~= nil then + xPlayer.addAccountMoney(account, amount) + else + TriggerClientEvent('esx:showNotification', _source, 'Compte invalide') + end + else + TriggerClientEvent('esx:showNotification', _source, 'Montant invalide') + end + +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'giveaccountmoney [id] [compte] [montant]'}) + +TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[2]) + local item = args[3] + local count = (args[4] == nil and 1 or tonumber(args[4])) + + if count ~= nil then + if xPlayer.getInventoryItem(item) ~= nil then + xPlayer.addInventoryItem(item, count) + else + TriggerClientEvent('esx:showNotification', _source, 'Item invalide') + end + else + TriggerClientEvent('esx:showNotification', _source, 'Quantité invalide') + end + +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'giveitem [id] [item] [[quantité]]'}) + +TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) + + local xPlayer = ESX.GetPlayerFromId(args[2]) + local weaponName = string.upper(args[3]) + + xPlayer.addWeapon(weaponName, 1000) + +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = 'giveweapon [id] [arme]'}) From 7b3963d67a0800f2351ef8c0a21e20b09945fac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 00:06:02 +0200 Subject: [PATCH 052/672] reorganize code + close menu when they should be closed --- .../es_extended/client/functions.lua | 22 +++++++++++-------- .../[essential]/es_extended/client/main.lua | 19 +++++++++------- resources/[essential]/es_extended/config.lua | 2 +- .../es_extended/server/commands.lua | 1 + .../[essential]/es_extended/server/main.lua | 8 +++++-- 5 files changed, 32 insertions(+), 20 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 7839dd7e..32a871b9 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -915,7 +915,7 @@ ESX.ShowInventory = function() { title = 'Quantité' }, - function(data2, menu) + function(data2, menu2) local quantity = tonumber(data2.value) local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() @@ -926,9 +926,11 @@ ESX.ShowInventory = function() TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) end + menu2.close() menu.close() + end, - function(data2, menu) + function(data2, menu2) menu.close() end ) @@ -946,23 +948,22 @@ ESX.ShowInventory = function() { title = 'Quantité' }, - function(data2, menu) + function(data2, menu2) local quantity = tonumber(data2.value) if quantity == nil then ESX.ShowNotification('Montant invalide') else - - menu.close() - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) - end + + menu2.close() + menu.close() end, - function(data2, menu) - menu.close() + function(data2, menu2) + menu2.close() end ) @@ -972,6 +973,9 @@ ESX.ShowInventory = function() TriggerServerEvent('esx:useItem', data.current.value) + menu2.close() + menu.close() + elseif data.current.action == 'return' then ESX.UI.Menu.CloseAll() ESX.ShowInventory() diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 416db725..d0266595 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -249,6 +249,17 @@ AddEventHandler('esx:spawnVehicle', function(model) end) +-- Pickup Weapon +RegisterNetEvent('esx:pickupWeapon') +AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName) + + local ped = GetPlayerPed(-1) + local playerPedPos = GetEntityCoords(ped, true) + + CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, 1000, 1, false, true) + +end) + -- Pause menu disable HUD display Citizen.CreateThread(function() while true do @@ -375,11 +386,3 @@ if Config.DisableWantedLevel then end --- Pickup Weapon -RegisterNetEvent('esx:pickupWeapon') -AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName) - local ped = GetPlayerPed(-1) - local playerPedPos = GetEntityCoords(ped, true) - CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, 999, 1, false, true) - -end) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index d87401a8..a0546b7b 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -6,5 +6,5 @@ Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 +Config.EnableWeaponPickup = false Config.Locale = 'fr' -Config.EnableWeaponPickup = false diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index d81a2100..6b47414d 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -115,3 +115,4 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = 'giveweapon [id] [arme]'}) + diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 1e1ffd03..8f7a47cb 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -481,8 +481,8 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) local xPlayer = ESX.GetPlayerFromId(source) - local weaponLabel = itemName - local weaponName = nil + local weaponLabel = itemName + local weaponName = nil local weaponPickup = nil for i=1, #Config.Weapons, 1 do @@ -495,11 +495,15 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end SetTimeout(Config.RemoveInventoryItemDelay, function() + xPlayer.removeWeapon(itemName) + if Config.EnableWeaponPickup then TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName) end + TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ x1 ' .. ' ~g~' .. weaponLabel) + end) end From 031030adbe779e5c09ad20d9a1b5ccfa800bb968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 00:20:57 +0200 Subject: [PATCH 053/672] add menu.close() --- resources/[essential]/es_extended/client/functions.lua | 3 +++ resources/[essential]/es_extended/server/main.lua | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 32a871b9..0d38862a 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -940,7 +940,10 @@ ESX.ShowInventory = function() elseif data.current.action == 'remove' then if type == 'item_weapon' then + TriggerServerEvent('esx:removeInventoryItem', type, item, 1) + menu.close() + else ESX.UI.Menu.Open( diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 8f7a47cb..c06d44b8 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -479,8 +479,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) elseif type == 'item_weapon' then - local xPlayer = ESX.GetPlayerFromId(source) - + local xPlayer = ESX.GetPlayerFromId(source) local weaponLabel = itemName local weaponName = nil local weaponPickup = nil From 8388a8d05ea9e72df1ee9c65aecf62db2169cec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 10:38:13 +0200 Subject: [PATCH 054/672] Fix give item close + TriggerServerCallback debug message --- resources/[essential]/es_extended/client/functions.lua | 2 +- resources/[essential]/es_extended/server/functions.lua | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 0d38862a..fe32b357 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -931,7 +931,7 @@ ESX.ShowInventory = function() end, function(data2, menu2) - menu.close() + menu2.close() end ) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index c8dbc033..c5541654 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -25,7 +25,13 @@ ESX.RegisterServerCallback = function(name, cb) end ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) - ESX.ServerCallbacks[name](source, cb, ...) + + if ESX.ServerCallbacks[name] ~= nil then + ESX.ServerCallbacks[name](source, cb, ...) + else + print('TriggerServerCallback => [' .. name .. '] does not exists') + end + end ESX.SavePlayer = function(xPlayer, cb) From 7cbcab51e19e2fa0df634c48179bc0e5271bb5d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 12:21:18 +0200 Subject: [PATCH 055/672] Add neon support for ESX.Game.GetVehicleProperties and ESX.Game.SetVehicleProperties --- .../[essential]/es_extended/client/functions.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index fe32b357..2a489e33 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -599,6 +599,13 @@ ESX.Game.GetVehicleProperties = function(vehicle) wheels = GetVehicleWheelType(vehicle), windowTint = GetVehicleWindowTint(vehicle), + neonEnabled = { + IsVehicleNeonLightEnabled(vehicle, 0), + IsVehicleNeonLightEnabled(vehicle, 1), + IsVehicleNeonLightEnabled(vehicle, 2), + IsVehicleNeonLightEnabled(vehicle, 3) + } + neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), modSpoilers = GetVehicleMod(vehicle, 0), @@ -665,6 +672,13 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleWindowTint(vehicle, props.windowTint) end + if props.neonEnabled ~= nil then + SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]), + SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]), + SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]), + SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) + end + if props.neonColor ~= nil then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end From d8f64a409892655b0248e5c3bfa9fd37b1553f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 12:46:36 +0200 Subject: [PATCH 056/672] Fix typo --- resources/[essential]/es_extended/client/functions.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 2a489e33..ccbd1138 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -673,9 +673,9 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end if props.neonEnabled ~= nil then - SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]), - SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]), - SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]), + SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) + SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) + SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) end From 10def0786dde6579ede6d9e4d7e44e452477d1a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 12:55:09 +0200 Subject: [PATCH 057/672] Update vehicle color apply functions --- resources/[essential]/es_extended/client/functions.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index ccbd1138..765ef2ed 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -656,8 +656,14 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleDirtLevel(vehicle, props.dirtLevel) end - if props.color1 ~= nil and props.color2 ~= nil then - SetVehicleColours(vehicle, props.color1, props.color2) + if props.color1 ~= nil then + local colour1, colour2 = GetVehicleColours(vehicle) + SetVehicleColours(vehicle, props.color1, color2) + end + + if props.color2 ~= nil then + local colour1, colour2 = GetVehicleColours(vehicle) + SetVehicleColours(vehicle, color1, props.color2) end if props.pearlescentColor ~= nil and props.wheelColor ~= nil then From 94f61f2ed4780340c28785ad7b122bda6fb3f20b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 13:10:17 +0200 Subject: [PATCH 058/672] Fix wrong var names --- resources/[essential]/es_extended/client/functions.lua | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 765ef2ed..33e448c9 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -578,7 +578,7 @@ end ESX.Game.GetVehicleProperties = function(vehicle) - local colour1, colour2 = GetVehicleColours(vehicle) + local color1, color2 = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) return { @@ -591,8 +591,6 @@ ESX.Game.GetVehicleProperties = function(vehicle) health = GetEntityHealth(vehicle), dirtLevel = GetVehicleDirtLevel(vehicle), - color1 = colour1, - color2 = colour2, pearlescentColor = pearlescentColor, wheelColor = wheelColor, @@ -657,12 +655,12 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end if props.color1 ~= nil then - local colour1, colour2 = GetVehicleColours(vehicle) + local color1, color2 = GetVehicleColours(vehicle) SetVehicleColours(vehicle, props.color1, color2) end if props.color2 ~= nil then - local colour1, colour2 = GetVehicleColours(vehicle) + local color1, color2 = GetVehicleColours(vehicle) SetVehicleColours(vehicle, color1, props.color2) end From d41ba790757599ae76703823b4a3d59a98d24889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 14:07:12 +0200 Subject: [PATCH 059/672] Fix bugs --- resources/[essential]/es_extended/client/functions.lua | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 33e448c9..c6c7a795 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -591,6 +591,9 @@ ESX.Game.GetVehicleProperties = function(vehicle) health = GetEntityHealth(vehicle), dirtLevel = GetVehicleDirtLevel(vehicle), + color1 = color1, + color2 = color2, + pearlescentColor = pearlescentColor, wheelColor = wheelColor, @@ -601,8 +604,8 @@ ESX.Game.GetVehicleProperties = function(vehicle) IsVehicleNeonLightEnabled(vehicle, 0), IsVehicleNeonLightEnabled(vehicle, 1), IsVehicleNeonLightEnabled(vehicle, 2), - IsVehicleNeonLightEnabled(vehicle, 3) - } + IsVehicleNeonLightEnabled(vehicle, 3), + }, neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), From 2379178fa5c586396c84fa0acbc4659cef543901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 13 Aug 2017 16:18:36 +0200 Subject: [PATCH 060/672] Update README.md --- README.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/README.md b/README.md index fa8471cb..b827b23e 100644 --- a/README.md +++ b/README.md @@ -47,13 +47,3 @@ start esx_menu_list start esx_menu_dialog ``` -4) Create a resource or add this in an existing resource : - -``` -server.lua - -TriggerEvent('es:setDefaultSettings', { - nativeMoneySystem = false, -}); - -``` From 9cd25a852e31928ed5ce66fe3c1b3e4fe3662e52 Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 14 Aug 2017 01:48:16 +0200 Subject: [PATCH 061/672] Add pearl + wheels support --- resources/[essential]/es_extended/client/functions.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index c6c7a795..f3c04818 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -667,8 +667,14 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleColours(vehicle, color1, props.color2) end - if props.pearlescentColor ~= nil and props.wheelColor ~= nil then - SetVehicleExtraColours(vehicle, props.pearlescentColor, props.wheelColor) + if props.pearlescentColor ~= nil then + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) + end + + if props.wheelColor ~= nil then + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) end if props.wheels ~= nil then From a3a7eaa584ac60dd1b9f55a5ea00bb0a5e243f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 09:53:14 +0200 Subject: [PATCH 062/672] UseItem fixes + add paycheck --- .../es_extended/client/functions.lua | 5 ++-- .../es_extended/server/functions.lua | 23 +++++++++++++++++++ .../[essential]/es_extended/server/main.lua | 14 +++++++++-- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index f3c04818..60d2aff5 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -1003,12 +1003,11 @@ ESX.ShowInventory = function() TriggerServerEvent('esx:useItem', data.current.value) - menu2.close() - menu.close() - elseif data.current.action == 'return' then + ESX.UI.Menu.CloseAll() ESX.ShowInventory() + end end, diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index c5541654..97b9f252 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -158,6 +158,29 @@ ESX.StartDBSync = function() end +ESX.StartPayCheck = function() + + function payCheck() + + local xPlayers = ESX.GetPlayers() + + for k,v in pairs(xPlayers) do + + if v.job.grade_salary > 0 then + v.addMoney(v.job.grade_salary) + TriggerClientEvent('esx:showNotification', v.source, 'Vous avez reçu votre salaire : ~g~$' .. v.job.grade_salary) + end + + end + + SetTimeout(Config.PaycheckInterval, payCheck) + + end + + SetTimeout(Config.PaycheckInterval, payCheck) + +end + ESX.GetPlayers = function() return ESX.Players end diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index c06d44b8..4338ed81 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -510,8 +510,17 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end) RegisterServerEvent('esx:useItem') -AddEventHandler('esx:useItem', function(item) - ESX.UseItem(source, item) +AddEventHandler('esx:useItem', function(itemName) + + local xPlayer = ESX.GetPlayerFromId(source) + local count = xPlayer.getInventoryItem(itemName).count + + if count > 0 then + ESX.UseItem(source, itemName) + else + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Action impossible') + end + end) ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) @@ -547,3 +556,4 @@ end) TriggerEvent("es:addGroup", "jobmaster", "user", function(group) end) ESX.StartDBSync() +ESX.StartPayCheck() \ No newline at end of file From fdcd78325f816f809ab926e233bae546ddafa360 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 12:52:46 -0400 Subject: [PATCH 063/672] Multi-language support Completed multi-language support, added params to commands. --- .../es_extended/client/functions.lua | 8 +- resources/[essential]/es_extended/config.lua | 5 +- .../es_extended/config.weapons.lua | 154 +++++++++--------- .../[essential]/es_extended/locales/en.lua | 115 ++++++++++++- .../[essential]/es_extended/locales/fr.lua | 115 ++++++++++++- .../es_extended/server/commands.lua | 31 ++-- .../es_extended/server/functions.lua | 2 +- .../[essential]/es_extended/server/main.lua | 52 +++--- 8 files changed, 354 insertions(+), 128 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 60d2aff5..8a33b9eb 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -940,7 +940,7 @@ ESX.ShowInventory = function() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', { - title = 'Quantité' + title = _U('amount') }, function(data2, menu2) @@ -948,7 +948,7 @@ ESX.ShowInventory = function() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification('Aucun joueur à proximité') + ESX.ShowNotification(_U('players_nearby')) else TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) end @@ -976,14 +976,14 @@ ESX.ShowInventory = function() ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { - title = 'Quantité' + title = _U('amount') }, function(data2, menu2) local quantity = tonumber(data2.value) if quantity == nil then - ESX.ShowNotification('Montant invalide') + ESX.ShowNotification(_U('amount_invalid')) else TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) end diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index a0546b7b..51392295 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -1,10 +1,11 @@ Config = {} Config.MaxPlayers = 32 Config.Accounts = {'bank', 'black_money'} -Config.AccountLabels = {bank = 'Banque', black_money = 'Argent Sale'} +Config.AccountLabels = {bank = 'Banque', black_money = 'Argent Sale'} -- French +--Config.AccountLabels = {bank = 'Bank', black_money = 'Dirty Money'} -- English Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 Config.EnableWeaponPickup = false -Config.Locale = 'fr' +Config.Locale = 'en' diff --git a/resources/[essential]/es_extended/config.weapons.lua b/resources/[essential]/es_extended/config.weapons.lua index 4210cd94..3ce8b4c5 100644 --- a/resources/[essential]/es_extended/config.weapons.lua +++ b/resources/[essential]/es_extended/config.weapons.lua @@ -1,81 +1,81 @@ Config.Weapons = { {name = 'WEAPON_KNIFE', label = _U('weapon_knife')}, - {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', label = 'Grenade à gaz BZ'}, - {name = 'WEAPON_MOLOTOV', label = 'Cocktail molotov'}, - {name = 'WEAPON_FIREEXTINGUISHER', label = 'Extincteur'}, - {name = 'WEAPON_PETROLCAN', label = 'Jerrican d\'essence'}, - {name = 'WEAPON_DIGISCANNER', label = 'Digiscanner'}, - {name = 'WEAPON_BALL', label = '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 = 'WEAPON_FLASHLIGHT', label = 'Lampe torche'}, - {name = 'GADGET_NIGHTVISION', label = 'Vision nocturne'}, - {name = 'GADGET_PARACHUTE', label = 'Parachute'}, + {name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick')}, + {name = 'WEAPON_HAMMER', label = _U('weapon_hammer')}, + {name = 'WEAPON_BAT', label = _U('weapon_bat')}, + {name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub')}, + {name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar')}, + {name = 'WEAPON_PISTOL', label = _U('weapon_pistol')}, + {name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol')}, + {name = 'WEAPON_APPISTOL', label = _U('weapon_appistol')}, + {name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50')}, + {name = 'WEAPON_MICROSMG', label = _U('weapon_microsmg')}, + {name = 'WEAPON_SMG', label = _U('weapon_smg')}, + {name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg')}, + {name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle')}, + {name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle')}, + {name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle')}, + {name = 'WEAPON_MG', label = _U('weapon_mg')}, + {name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg')}, + {name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun')}, + {name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun')}, + {name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun')}, + {name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun')}, + {name = 'WEAPON_STUNGUN', label = _U('weapon_stungun')}, + {name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle')}, + {name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper')}, + {name = 'WEAPON_REMOTESNIPER', label = _U('weapon_remotesniper')}, + {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher')}, + {name = 'WEAPON_RPG', label = _U('weapon_rpg')}, + {name = 'WEAPON_STINGER', label = _U('weapon_stinger')}, + {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun')}, + {name = 'WEAPON_GRENADE', label = _U('weapon_grenade')}, + {name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb')}, + {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade')}, + {name = 'WEAPON_BZGAS', label = _U('weapon_bzgas')}, + {name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov')}, + {name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher')}, + {name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan')}, + {name = 'WEAPON_DIGISCANNER', label = _U('weapon_digiscanner')}, + {name = 'WEAPON_BALL', label = _U('weapon_ball')}, + {name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol')}, + {name = 'WEAPON_BOTTLE', label = _U('weapon_bottle')}, + {name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg')}, + {name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine')}, + {name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol')}, + {name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle')}, + {name = 'WEAPON_DAGGER', label = _U('weapon_dagger')}, + {name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol')}, + {name = 'WEAPON_FIREWORK', label = _U('weapon_firework')}, + {name = 'WEAPON_MUSKET', label = _U('weapon_musket')}, + {name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun')}, + {name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle')}, + {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher')}, + {name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine')}, + {name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball')}, + {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun')}, + {name = 'WEAPON_GARBAGEBAG', label = _U('weapon_garbagebag')}, + {name = 'WEAPON_HANDCUFFS', label = _U('weapon_handcuffs')}, + {name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw')}, + {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol')}, + {name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle')}, + {name = 'WEAPON_HATCHET', label = _U('weapon_hatchet')}, + {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun')}, + {name = 'WEAPON_MACHETE', label = _U('weapon_machete')}, + {name = 'WEAPON_MACHINEPISTOL', label = _U('weapon_machinepistol')}, + {name = 'WEAPON_SWITCHBLADE', label = _U('weapon_switchblade')}, + {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver')}, + {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun')}, + {name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle')}, + {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun')}, + {name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe')}, + {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher')}, + {name = 'WEAPON_MINISMG', label = _U('weapon_minismg')}, + {name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb')}, + {name = 'WEAPON_POOLCUE', label = _U('weapon_poolcue')}, + {name = 'WEAPON_WRENCH', label = _U('weapon_wrench')}, + {name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight')}, + {name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision')}, + {name = 'GADGET_PARACHUTE', label = _U('gadget_parachute')}, } \ No newline at end of file diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua index 42abd3f0..b1f3aa26 100644 --- a/resources/[essential]/es_extended/locales/en.lua +++ b/resources/[essential]/es_extended/locales/en.lua @@ -4,5 +4,118 @@ Locales['en'] = { ['give'] = 'give', ['remove'] = 'remove', ['return'] = 'return', - ['weapon_knife'] = 'knife', + ['amount'] = 'amount', + ['amount_invalid'] = 'invalid amount', + ['players_nearby'] = 'no players nearby', + ['ex_inv_lim'] = 'action not possible, exceeding invetory limit for ~b~', + ['yougave'] = 'you gave', + ['youreceived'] = 'you received', + ['to'] = '~s~ to ~b~', + ['by'] = '~s~ by ~b~', + ['imp_invalid_quantity'] = 'action impossible, invalid quantity', + ['imp_invalid_amount'] = 'action impossible, invalid amount', + ['delete_five_min'] = '~r~delete~s~ in 5 minutes', + ['threw'] = 'you ~r~threw~s~', + ['rec_salary'] = 'you received your salary: ', + ['act_imp'] = 'action impossible', + -- Commands + ['setjob'] = 'assign a job to a user', + ['id_param'] = 'the id of the player', + ['setjob_param2'] = 'the job you wish to assign', + ['setjob_param3'] = 'the job level', + ['load_ipl'] = 'load ipl', + ['unload_ipl'] = 'unload ipl', + ['play_anim'] = 'play animation', + ['play_emote'] = 'play emote', + ['spawn_car'] = 'spawn a car', + ['spawn_car_param'] = 'name of car', + ['givemoney'] = 'give money', + ['money_amount'] = 'amount of money', + ['invalid_account'] = 'invalid account', + ['account'] = 'account', + ['giveaccountmoney'] = 'give account money', + ['invalid_item'] = 'invalid item', + ['item'] = 'item', + ['giveitem'] = 'give item', + ['weapon'] = 'weapon', + ['giveweapon'] = 'give weapon', + -- Weapons + ['weapon_knife'] = 'knife', + ['weapon_nightstick'] = 'nightstick', + ['weapon_hammer'] = 'hammer', + ['weapon_bat'] = 'bat', + ['weapon_golfclub'] = 'golf club', + ['weapon_crowbar'] = 'crow bar', + ['weapon_pistol'] = 'pistol', + ['weapon_combatpistol'] = 'combat pistol', + ['weapon_appistol'] = 'ap pistol', + ['weapon_pistol50'] = 'pistol .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'assault smg', + ['weapon_assaultrifle'] = 'assault rifle', + ['weapon_carbinerifle'] = 'carbine rifle', + ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'combat mg', + ['weapon_pumpshotgun'] = 'pump shotgun', + ['weapon_sawnoffshotgun'] = 'sawed off shotgun', + ['weapon_assaultshotgun'] = 'assault shotgun', + ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'sniper rifle', + ['weapon_heavysniper'] = 'heavy sniper', + ['weapon_remotesniper'] = 'remote sniper', + ['weapon_grenadelauncher'] = 'grenade launcher', + ['weapon_rpg'] = 'rocket launcher', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'grenade', + ['weapon_stickybomb'] = 'sticky bomb', + ['weapon_smokegrenade'] = 'smoke grenade', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'molotov cocktail', + ['weapon_fireextinguisher'] = 'fire extinguisher', + ['weapon_petrolcan'] = 'jerrycan', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'ball', + ['weapon_snspistol'] = 'sns pistol', + ['weapon_bottle'] = 'bottle', + ['weapon_gusenberg'] = 'gusenberg sweeper', + ['weapon_specialcarbine'] = 'special carbine', + ['weapon_heavypistol'] = 'heavy pistol', + ['weapon_bullpuprifle'] = 'bullpup rifle', + ['weapon_dagger'] = 'dagger', + ['weapon_vintagepistol'] = 'vintage pistol', + ['weapon_firework'] = 'firework', + ['weapon_musket'] = 'musket', + ['weapon_heavyshotgun'] = 'heavy shotgun', + ['weapon_marksmanrifle'] = 'marksman rifle', + ['weapon_hominglauncher'] = 'homing launcher', + ['weapon_proxmine'] = 'proximity mine', + ['weapon_snowball'] = 'snow ball', + ['weapon_flaregun'] = 'flaregun', + ['weapon_garbagebag'] = 'garbage bag', + ['weapon_handcuffs'] = 'handcuffs', + ['weapon_combatpdw'] = 'combat pdw', + ['weapon_marksmanpistol'] = 'marksman pistol', + ['weapon_knuckle'] = 'knuckledusters', + ['weapon_hatchet'] = 'hatchet', + ['weapon_railgun'] = 'railgun', + ['weapon_machete'] = 'machete', + ['weapon_machinepistol'] = 'machine pistol', + ['weapon_switchblade'] = 'switchblade', + ['weapon_revolver'] = 'heavy revolver', + ['weapon_dbshotgun'] = 'double barrel shotgun', + ['weapon_compactrifle'] = 'compact rifle', + ['weapon_autoshotgun'] = 'auto shotgun', + ['weapon_battleaxe'] = 'battle axe', + ['weapon_compactlauncher'] = 'compact launcher', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'pipe bomb', + ['weapon_poolcue'] = 'pool cue', + ['weapon_wrench'] = 'pipe wrench', + ['weapon_flashlight'] = 'flashlight', + ['gadget_nightvision'] = 'night vision', + ['gadget_parachute'] = 'parachute', } \ No newline at end of file diff --git a/resources/[essential]/es_extended/locales/fr.lua b/resources/[essential]/es_extended/locales/fr.lua index 77204f96..fa699bf5 100644 --- a/resources/[essential]/es_extended/locales/fr.lua +++ b/resources/[essential]/es_extended/locales/fr.lua @@ -4,5 +4,118 @@ Locales['fr'] = { ['give'] = 'donner', ['remove'] = 'jeter', ['return'] = 'retour', - ['weapon_knife'] = 'couteau', + ['amount'] = 'quantité', + ['amount_invalid'] = 'montant invalide', + ['players_nearby'] = 'aucun joueur à proximité', + ['ex_inv_lim'] = 'action impossible, depassement de la limite d\'inventaire pour ~b~', + ['yougave'] = 'vous avez donné', + ['youreceived'] = 'vous avez reçu', + ['to'] = '~s~ à ~b~', + ['by'] = '~s~ par ~b~', + ['imp_invalid_quantity'] = 'action impossible, ~r~quantité invalide', + ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', + ['delete_five_min'] = '~r~suppression~s~ dans 5 minutes', + ['threw'] = 'vous avez ~r~jeté~s~', + ['rec_salary'] = 'vous avez reçu votre salaire : ', + ['act_imp'] = 'action impossible', + -- Commands + ['setjob'] = 'assigner job', + ['id_param'] = 'identification du joueur', + ['setjob_param2'] = 'le travail que vous souhaitez assigner', + ['setjob_param3'] = 'le niveau d\'emploi', + ['load_ipl'] = 'charger ipl', + ['unload_ipl'] = 'décharger ipl', + ['play_anim'] = 'jouer animation', + ['play_emote'] = 'jouer emote', + ['spawn_car'] = 'spawn un véhicule', + ['spawn_car_param'] = 'nom de la voiture', + ['givemoney'] = 'donner de l\'argent', + ['money_amount'] = 'somme d\'argent', + ['invalid_account'] = 'compete invalide', + ['account'] = 'compte', + ['giveaccountmoney'] = 'donner de l\'argent au compte', + ['invalid_item'] = 'item invalide', + ['item'] = 'article', + ['giveitem'] = 'donner un article', + ['weapon'] = 'arme', + ['giveweapon'] = 'donner de l\'arme', + -- Weapons + ['weapon_knife'] = 'couteau', + ['weapon_nightstick'] = 'matraque', + ['weapon_hammer'] = 'marteau', + ['weapon_bat'] = 'bat', + ['weapon_golfclub'] = 'club de golfe', + ['weapon_crowbar'] = 'pied de biche', + ['weapon_pistol'] = 'pistolet', + ['weapon_combatpistol'] = 'pistolet de combat', + ['weapon_appistol'] = 'pistolet automatique', + ['weapon_pistol50'] = 'pistolet calibre 50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'smg d\'assaut', + ['weapon_assaultrifle'] = 'fusil d\'assaut', + ['weapon_carbinerifle'] = 'carabine d\'assaut', + ['weapon_advancedrifle'] = 'fusil avancé', + ['weapon_mg'] = 'mitrailleuse', + ['weapon_combatmg'] = 'mitrailleuse de combat', + ['weapon_pumpshotgun'] = 'fusil à pompe', + ['weapon_sawnoffshotgun'] = 'carabine à canon scié', + ['weapon_assaultshotgun'] = 'carabine d\'assaut', + ['weapon_bullpupshotgun'] = 'carabine bullpup', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'fusil de sniper', + ['weapon_heavysniper'] = 'fusil de sniper lourd', + ['weapon_remotesniper'] = 'fusil de sniper à distance', + ['weapon_grenadelauncher'] = 'lance-grenade', + ['weapon_rpg'] = 'lance-rocket', + ['weapon_stinger'] = 'lance-missile stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'grenade', + ['weapon_stickybomb'] = 'bombe collante', + ['weapon_smokegrenade'] = 'grenade fumigène', + ['weapon_bzgas'] = 'grenade à gaz bz', + ['weapon_molotov'] = 'cocktail molotov', + ['weapon_fireextinguisher'] = 'extincteur', + ['weapon_petrolcan'] = 'jerrican d\'essence', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'balle', + ['weapon_snspistol'] = 'pistolet sns', + ['weapon_bottle'] = 'bouteille', + ['weapon_gusenberg'] = 'balayeuse gusenberg', + ['weapon_specialcarbine'] = 'carabine spéciale', + ['weapon_heavypistol'] = 'pistolet lourd', + ['weapon_bullpuprifle'] = 'fusil bullpup', + ['weapon_dagger'] = 'poignard', + ['weapon_vintagepistol'] = 'pistolet vintage', + ['weapon_firework'] = 'feu d\'artifice', + ['weapon_musket'] = 'mousquet', + ['weapon_heavyshotgun'] = 'fusil à pompe lourd', + ['weapon_marksmanrifle'] = 'fusil marksman', + ['weapon_hominglauncher'] = 'lance tête-chercheuse', + ['weapon_proxmine'] = 'mine de proximité', + ['weapon_snowball'] = 'boule de neige', + ['weapon_flaregun'] = 'lance fusée de détresse', + ['weapon_garbagebag'] = 'sac poubelle', + ['weapon_handcuffs'] = 'menottes', + ['weapon_combatpdw'] = 'arme de défense personnelle', + ['weapon_marksmanpistol'] = 'pistolet marksman', + ['weapon_knuckle'] = 'poing américain', + ['weapon_hatchet'] = 'hachette', + ['weapon_railgun'] = 'canon éléctrique', + ['weapon_machete'] = 'machetta', + ['weapon_machinepistol'] = 'pistolet mitrailleur', + ['weapon_switchblade'] = 'couteau à cran d\'arrêt', + ['weapon_revolver'] = 'revolver', + ['weapon_dbshotgun'] = 'fusil à pompe double canon', + ['weapon_compactrifle'] = 'fusil compact', + ['weapon_autoshotgun'] = 'fusil à pompe automatique', + ['weapon_battleaxe'] = 'hache de combat', + ['weapon_compactlauncher'] = 'lanceur compact', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'bombe tuyau', + ['weapon_poolcue'] = 'queue de billard', + ['weapon_wrench'] = 'clé', + ['weapon_flashlight'] = 'lampe torche', + ['gadget_nightvision'] = 'vision nocturne', + ['gadget_parachute'] = 'parachute', } \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index 6b47414d..16def62e 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -15,37 +15,37 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, 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]'}) +end, {help = _U('setjob'), params = {{name = "id", help = _U('id_param')}, {name = "job", help = _U('setjob_param2')}, {name = "grade_id", help = _U('setjob_param3')}}}) 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'}) +end, {help = _U('load_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'}) +end, {help = _U('unload_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'}) +end, {help = _U('play_anim')}) 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'}) +end, {help = _U('play_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'}) +end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) TriggerEvent('es:addGroupCommand', 'givemoney', 'admin', function(source, args, user) @@ -56,12 +56,12 @@ TriggerEvent('es:addGroupCommand', 'givemoney', 'admin', function(source, args, if amount ~= nil then xPlayer.addMoney(amount) else - TriggerClientEvent('esx:showNotification', _source, 'Montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) end end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'givemoney [id] [montant]'}) +end, {help = _U('givemoney'), params = {{name = "id", help = _U('id_param')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) @@ -74,15 +74,15 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, if xPlayer.getAccount(account) ~= nil then xPlayer.addAccountMoney(account, amount) else - TriggerClientEvent('esx:showNotification', _source, 'Compte invalide') + TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) end else - TriggerClientEvent('esx:showNotification', _source, 'Montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) end end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'giveaccountmoney [id] [compte] [montant]'}) +end, {help = _U('giveaccountmoney'), params = {{name = "id", help = _U('id_param')}, {name = "account", help = _U('account')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) @@ -95,15 +95,15 @@ TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, u if xPlayer.getInventoryItem(item) ~= nil then xPlayer.addInventoryItem(item, count) else - TriggerClientEvent('esx:showNotification', _source, 'Item invalide') + TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) end else - TriggerClientEvent('esx:showNotification', _source, 'Quantité invalide') + TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) end end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'giveitem [id] [item] [[quantité]]'}) +end, {help = _U('giveitem'), params = {{name = "id", help = _U('id_param')}, {name = "item", help = _U('item')}, {name = "amount", help = _U('amount')}}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) @@ -114,5 +114,4 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = 'giveweapon [id] [arme]'}) - +end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 97b9f252..000402cf 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -168,7 +168,7 @@ ESX.StartPayCheck = function() if v.job.grade_salary > 0 then v.addMoney(v.job.grade_salary) - TriggerClientEvent('esx:showNotification', v.source, 'Vous avez reçu votre salaire : ~g~$' .. v.job.grade_salary) + TriggerClientEvent('esx:showNotification', v.source, _U('rec_salary') .. '~g~$' .. v.job.grade_salary) end end diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 4338ed81..6d56ac13 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -302,17 +302,17 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo 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) + TriggerClientEvent('esx:showNotification', target, _U('ex_inv_lim') .. 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) + TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. _U('by') .. sourceXPlayer.name) end else - TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~quantité invalide') + TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_quantity')) end elseif type == 'item_money' then @@ -322,11 +322,11 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo 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) + TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' ~g~$' .. itemCount .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' ~g~$' .. itemCount .. _U('by') .. sourceXPlayer.name) else - TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_amount')) end elseif type == 'item_account' then @@ -336,11 +336,11 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo 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) + TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. _U('by') .. sourceXPlayer.name) else - TriggerClientEvent('esx:showNotification', target, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_amount')) end elseif type == 'item_weapon' then @@ -357,8 +357,8 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo 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) + TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' x1 ~g~' .. weaponLabel .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' x1 ~g~' .. weaponLabel .. _U('by') .. sourceXPlayer.name) end end) @@ -371,7 +371,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if type == 'item_standard' then if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~quantité invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) else local xPlayer = ESX.GetPlayerFromId(source) @@ -384,10 +384,10 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end if itemCount > foundItem.count then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~quantité invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) else - TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes') + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) SetTimeout(Config.RemoveInventoryItemDelay, function() @@ -400,7 +400,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeInventoryItem(itemName, total) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ ' .. foundItem.label .. ' x' .. total) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) end end) @@ -412,16 +412,16 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) elseif type == 'item_money' then if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else local xPlayer = ESX.GetPlayerFromId(source) if itemCount > xPlayer.player.get('money') then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else - TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes') + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) SetTimeout(Config.RemoveInventoryItemDelay, function() @@ -434,7 +434,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeMoney(total) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ [Cash] $' .. total) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end end) @@ -446,16 +446,16 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) elseif type == 'item_account' then if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else local xPlayer = ESX.GetPlayerFromId(source) if itemCount > xPlayer.getAccount(itemName).money then - TriggerClientEvent('esx:showNotification', _source, 'Action impossible, ~r~montant invalide') + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else - TriggerClientEvent('esx:showNotification', _source, '~r~Suppression~s~ dans 5 minutes') + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) SetTimeout(Config.RemoveInventoryItemDelay, function() @@ -468,7 +468,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeAccountMoney(itemName, total) - TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ [Cash] $' .. total) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end end) @@ -501,7 +501,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName) end - TriggerClientEvent('esx:showNotification', _source, 'Vous avez ~r~jeté~s~ x1 ' .. ' ~g~' .. weaponLabel) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' x1 ~g~' .. weaponLabel) end) @@ -518,7 +518,7 @@ AddEventHandler('esx:useItem', function(itemName) if count > 0 then ESX.UseItem(source, itemName) else - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Action impossible') + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('act_imp')) end end) From 40bc44774777ee400a19c978fb6d5a1368077d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 15 Aug 2017 19:05:31 +0200 Subject: [PATCH 064/672] Set fr as default locale --- resources/[essential]/es_extended/config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 51392295..8b280075 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -8,4 +8,4 @@ Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 Config.EnableWeaponPickup = false -Config.Locale = 'en' +Config.Locale = 'fr' From ff2613c551d914b34fbe7c46b82872be9bcd0b2d Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 15 Aug 2017 15:42:51 -0400 Subject: [PATCH 065/672] Grammatical fix (en) --- resources/[essential]/es_extended/config.lua | 2 +- resources/[essential]/es_extended/locales/en.lua | 6 +++--- resources/[essential]/es_extended/locales/fr.lua | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 51392295..8b280075 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -8,4 +8,4 @@ Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 Config.EnableWeaponPickup = false -Config.Locale = 'en' +Config.Locale = 'fr' diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua index b1f3aa26..0a059de2 100644 --- a/resources/[essential]/es_extended/locales/en.lua +++ b/resources/[essential]/es_extended/locales/en.lua @@ -20,11 +20,11 @@ Locales['en'] = { ['act_imp'] = 'action impossible', -- Commands ['setjob'] = 'assign a job to a user', - ['id_param'] = 'the id of the player', + ['id_param'] = 'the ID of the player', ['setjob_param2'] = 'the job you wish to assign', ['setjob_param3'] = 'the job level', - ['load_ipl'] = 'load ipl', - ['unload_ipl'] = 'unload ipl', + ['load_ipl'] = 'load IPL', + ['unload_ipl'] = 'unload IPL', ['play_anim'] = 'play animation', ['play_emote'] = 'play emote', ['spawn_car'] = 'spawn a car', diff --git a/resources/[essential]/es_extended/locales/fr.lua b/resources/[essential]/es_extended/locales/fr.lua index fa699bf5..e5af7b97 100644 --- a/resources/[essential]/es_extended/locales/fr.lua +++ b/resources/[essential]/es_extended/locales/fr.lua @@ -23,8 +23,8 @@ Locales['fr'] = { ['id_param'] = 'identification du joueur', ['setjob_param2'] = 'le travail que vous souhaitez assigner', ['setjob_param3'] = 'le niveau d\'emploi', - ['load_ipl'] = 'charger ipl', - ['unload_ipl'] = 'décharger ipl', + ['load_ipl'] = 'charger IPL', + ['unload_ipl'] = 'décharger IPL', ['play_anim'] = 'jouer animation', ['play_emote'] = 'jouer emote', ['spawn_car'] = 'spawn un véhicule', From f997a44b46dd505894c38ef598b35cc81c71bc78 Mon Sep 17 00:00:00 2001 From: renaiku Date: Thu, 17 Aug 2017 08:16:53 +0200 Subject: [PATCH 066/672] Updating functions to be ready for lscutsom --- resources/[essential]/es_extended/client/functions.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 8a33b9eb..5e85b674 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -608,6 +608,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) }, neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), modSpoilers = GetVehicleMod(vehicle, 0), modFrontBumper = GetVehicleMod(vehicle, 1), @@ -629,6 +630,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) modArmor = GetVehicleMod(vehicle, 16), modTurbo = IsToggleModOn(vehicle, 18), + modSmokeEnabled = IsToggleModOn(vehicle, 20), modXenon = IsToggleModOn(vehicle, 22), modFrontWheels = GetVehicleMod(vehicle, 23), @@ -696,6 +698,14 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end + if props.modSmokeEnabled ~= nil then + ToggleVehicleMod(vehicle, 20, true) + end + + if props.tyreSmokeColor ~= nil then + SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) + end + if props.modSpoilers ~= nil then SetVehicleMod(vehicle, 0, props.modSpoilers, false) end From 5d491d357cbed0cdb55cb06b3f811959b4b57804 Mon Sep 17 00:00:00 2001 From: TakumiBR <31086346+TakumiBR@users.noreply.github.com> Date: Thu, 17 Aug 2017 09:08:30 -0700 Subject: [PATCH 067/672] Multi-language support Brazilian Portuguese translation. --- .../[essential]/es_extended/__resource.lua | 2 + .../[essential]/es_extended/locales/br.lua | 121 ++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 resources/[essential]/es_extended/locales/br.lua diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 84a0f8dc..396a1e69 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -7,6 +7,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', 'config.lua', 'locale.lua', + 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', 'config.weapons.lua', @@ -20,6 +21,7 @@ server_scripts { client_scripts { 'config.lua', 'locale.lua', + 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', 'config.weapons.lua', diff --git a/resources/[essential]/es_extended/locales/br.lua b/resources/[essential]/es_extended/locales/br.lua new file mode 100644 index 00000000..db4e39aa --- /dev/null +++ b/resources/[essential]/es_extended/locales/br.lua @@ -0,0 +1,121 @@ +Locales['br'] = { + ['inventory'] = 'inventário', + ['use'] = 'usar', + ['give'] = 'dar', + ['remove'] = 'remover', + ['return'] = 'voltar', + ['amount'] = 'quantidade', + ['amount_invalid'] = 'quantidade inválida', + ['players_nearby'] = 'nenhum jogador nas proximidades', + ['ex_inv_lim'] = 'Esta ação não é possível, supera o limite do inventário para ~b~', + ['yougave'] = 'você deu', + ['youreceived'] = 'você recebeu', + ['to'] = '~s~ para ~b~', + ['by'] = '~s~ por ~b~', + ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', + ['imp_invalid_amount'] = 'ação impossível, valor inválido', + ['delete_five_min'] = '~r~deleta~s~ em 5 minutos', + ['threw'] = 'você ~r~jogou~s~', + ['rec_salary'] = 'você recebeu seu salário: ', + ['act_imp'] = 'ação impossível', + -- Commands + ['setjob'] = 'atribuir um emprego a um usuário', + ['id_param'] = 'o id do jogador', + ['setjob_param2'] = 'o trabalho que você deseja atribuir', + ['setjob_param3'] = 'o nível de trabalho', + ['load_ipl'] = 'carregando ipl', + ['unload_ipl'] = 'descarregando ipl', + ['play_anim'] = 'reproduzir animação', + ['play_emote'] = 'reproduzir emote', + ['spawn_car'] = 'fazer aparecer um carro', + ['spawn_car_param'] = 'nome do carro', + ['givemoney'] = 'dar dinheiro', + ['money_amount'] = 'quantia do dinheiro', + ['invalid_account'] = 'conta inválida', + ['account'] = 'conta', + ['giveaccountmoney'] = 'dar dinheiro em conta', + ['invalid_item'] = 'item inválido', + ['item'] = 'item', + ['giveitem'] = 'dar item', + ['weapon'] = 'arma', + ['giveweapon'] = 'dar arma', + -- Weapons + ['weapon_knife'] = 'ffaca', + ['weapon_nightstick'] = 'cacetete', + ['weapon_hammer'] = 'martelo', + ['weapon_bat'] = 'bastão', + ['weapon_golfclub'] = 'golf club', + ['weapon_crowbar'] = 'pé de cabra', + ['weapon_pistol'] = 'pistola', + ['weapon_combatpistol'] = 'pistola de combate', + ['weapon_appistol'] = 'ap pistola', + ['weapon_pistol50'] = 'pistola .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'assault smg', + ['weapon_assaultrifle'] = 'assault rifle', + ['weapon_carbinerifle'] = 'carbine rifle', + ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'combat mg', + ['weapon_pumpshotgun'] = 'espingarda', + ['weapon_sawnoffshotgun'] = 'sawed off shotgun', + ['weapon_assaultshotgun'] = 'assault shotgun', + ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_stungun'] = 'arma de choque', + ['weapon_sniperrifle'] = 'sniper rifle', + ['weapon_heavysniper'] = 'heavy sniper', + ['weapon_remotesniper'] = 'remote sniper', + ['weapon_grenadelauncher'] = 'lançador de granada', + ['weapon_rpg'] = 'lançador de foguetes', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'granada', + ['weapon_stickybomb'] = 'bomba pegajosa', + ['weapon_smokegrenade'] = 'granada de fumaça', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'coquetel molotov', + ['weapon_fireextinguisher'] = 'extintor', + ['weapon_petrolcan'] = 'galão de combustivel', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'bola', + ['weapon_snspistol'] = 'sns pistol', + ['weapon_bottle'] = 'garrafa', + ['weapon_gusenberg'] = 'gusenberg sweeper', + ['weapon_specialcarbine'] = 'carabina especial', + ['weapon_heavypistol'] = 'heavy pistol', + ['weapon_bullpuprifle'] = 'bullpup rifle', + ['weapon_dagger'] = 'punhal', + ['weapon_vintagepistol'] = 'vintage pistol', + ['weapon_firework'] = 'fogos de artifício', + ['weapon_musket'] = 'mosquete', + ['weapon_heavyshotgun'] = 'heavy shotgun', + ['weapon_marksmanrifle'] = 'marksman rifle', + ['weapon_hominglauncher'] = 'homing launcher', + ['weapon_proxmine'] = 'mina de proximidade', + ['weapon_snowball'] = 'bola de neve', + ['weapon_flaregun'] = 'sinalizador', + ['weapon_garbagebag'] = 'saco de lixo', + ['weapon_handcuffs'] = 'algemas', + ['weapon_combatpdw'] = 'combat pdw', + ['weapon_marksmanpistol'] = 'marksman pistol', + ['weapon_knuckle'] = 'soco inglês', + ['weapon_hatchet'] = 'machado', + ['weapon_railgun'] = 'railgun', + ['weapon_machete'] = 'facão', + ['weapon_machinepistol'] = 'machine pistol', + ['weapon_switchblade'] = 'canivete', + ['weapon_revolver'] = 'heavy revolver', + ['weapon_dbshotgun'] = 'espingarda de cano duplo', + ['weapon_compactrifle'] = 'compact rifle', + ['weapon_autoshotgun'] = 'auto shotgun', + ['weapon_battleaxe'] = 'battle axe', + ['weapon_compactlauncher'] = 'compact launcher', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'bomba caseira', + ['weapon_poolcue'] = 'taco de sinuca', + ['weapon_wrench'] = 'chave de cano', + ['weapon_flashlight'] = 'laterna', + ['gadget_nightvision'] = 'visão noturna', + ['gadget_parachute'] = 'paraquedas', +} \ No newline at end of file From a5c420e05e852b86f6e80b969b77d569de6044be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 18 Aug 2017 10:17:47 +0200 Subject: [PATCH 068/672] Fix give weapon --- .../[essential]/es_extended/client/functions.lua | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 5e85b674..f9d3b60f 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -463,11 +463,11 @@ ESX.Game.GetClosestPlayer = function(coords) local closestPlayer = -1 local coords = coords local usePlayerPed = false - local playerPed = nil + local playerPed = GetPlayerPed(-1) + local playerId = PlayerId() if coords == nil then usePlayerPed = true - playerPed = GetPlayerPed(-1) coords = GetEntityCoords(playerPed) end @@ -475,7 +475,7 @@ ESX.Game.GetClosestPlayer = function(coords) local target = GetPlayerPed(players[i]) - if not usePlayerPed or (usePlayerPed and target ~= playerPed) then + if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then local targetCoords = GetEntityCoords(target) local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) @@ -944,7 +944,15 @@ ESX.ShowInventory = function() if data.current.action == 'give' then if type == 'item_weapon' then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('players_nearby')) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) + end + else ESX.UI.Menu.Open( From 4e4bc821c8eb221af02bcbaf56f55396ab083a3a Mon Sep 17 00:00:00 2001 From: renaiku Date: Sat, 19 Aug 2017 08:19:06 +0200 Subject: [PATCH 069/672] update GetVehicleProperties and SetVehicleProperties --- .../es_extended/client/functions.lua | 118 +++++++++++++++++- 1 file changed, 117 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index f9d3b60f..792495f0 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -634,7 +634,31 @@ ESX.Game.GetVehicleProperties = function(vehicle) modXenon = IsToggleModOn(vehicle, 22), modFrontWheels = GetVehicleMod(vehicle, 23), - modBackWheels = GetVehicleMod(vehicle, 24) + modBackWheels = GetVehicleMod(vehicle, 24), + + modPlateHolder = GetVehicleMod(vehicle, 25), + modVanityPlate = GetVehicleMod(vehicle, 26), + modTrimA = GetVehicleMod(vehicle, 27), + modOrnaments = GetVehicleMod(vehicle, 28), + modDashboard = GetVehicleMod(vehicle, 29), + modDial = GetVehicleMod(vehicle, 30), + modDoorSpeaker = GetVehicleMod(vehicle, 31), + modSeats = GetVehicleMod(vehicle, 32), + modSteeringWheel = GetVehicleMod(vehicle, 33), + modShifterLeavers = GetVehicleMod(vehicle, 34), + modAPlate = GetVehicleMod(vehicle, 35), + modSpeakers = GetVehicleMod(vehicle, 36), + modTrunk = GetVehicleMod(vehicle, 37), + modHydrolic = GetVehicleMod(vehicle, 38), + modEngineBlock = GetVehicleMod(vehicle, 39), + modAirFilter = GetVehicleMod(vehicle, 40), + modStruts = GetVehicleMod(vehicle, 41), + modArchCover = GetVehicleMod(vehicle, 42), + modAerials = GetVehicleMod(vehicle, 43), + modTrimB = GetVehicleMod(vehicle, 44), + modTank = GetVehicleMod(vehicle, 45), + modWindows = GetVehicleMod(vehicle, 46), + modLivery = GetVehicleMod(vehicle, 48) } end @@ -790,6 +814,98 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleMod(vehicle, 24, props.modBackWheels, false) end + if props.modPlateHolder ~= nil then + SetVehicleMod(vehicle, 25, props.modPlateHolder , false) + end + + if props.modVanityPlate ~= nil then + SetVehicleMod(vehicle, 26, props.modVanityPlate , false) + end + + if props.modTrimA ~= nil then + SetVehicleMod(vehicle, 27, props.modTrimA , false) + end + + if props.modOrnaments ~= nil then + SetVehicleMod(vehicle, 28, props.modOrnaments , false) + end + + if props.modDashboard ~= nil then + SetVehicleMod(vehicle, 29, props.modDashboard , false) + end + + if props.modDial ~= nil then + SetVehicleMod(vehicle, 30, props.modDial , false) + end + + if props.modDoorSpeaker ~= nil then + SetVehicleMod(vehicle, 31, props.modDoorSpeaker , false) + end + + if props.modSeats ~= nil then + SetVehicleMod(vehicle, 32, props.modSeats , false) + end + + if props.modSteeringWheel ~= nil then + SetVehicleMod(vehicle, 33, props.modSteeringWheel , false) + end + + if props.modShifterLeavers ~= nil then + SetVehicleMod(vehicle, 34, props.modShifterLeavers , false) + end + + if props.modAPlate ~= nil then + SetVehicleMod(vehicle, 35, props.modAPlate , false) + end + + if props.modSpeakers ~= nil then + SetVehicleMod(vehicle, 36, props.modSpeakers , false) + end + + if props.modTrunk ~= nil then + SetVehicleMod(vehicle, 37, props.modTrunk , false) + end + + if props.modHydrolic ~= nil then + SetVehicleMod(vehicle, 38, props.modHydrolic , false) + end + + if props.modEngineBlock ~= nil then + SetVehicleMod(vehicle, 39, props.modEngineBlock , false) + end + + if props.modAirFilter ~= nil then + SetVehicleMod(vehicle, 40, props.modAirFilter , false) + end + + if props.modStruts ~= nil then + SetVehicleMod(vehicle, 41, props.modStruts , false) + end + + if props.modArchCover ~= nil then + SetVehicleMod(vehicle, 42, props.modArchCover , false) + end + + if props.modAerials ~= nil then + SetVehicleMod(vehicle, 43, props.modAerials , false) + end + + if props.modTrimB ~= nil then + SetVehicleMod(vehicle, 44, props.modTrimB , false) + end + + if props.modTank ~= nil then + SetVehicleMod(vehicle, 45, props.modTank , false) + end + + if props.modWindows ~= nil then + SetVehicleMod(vehicle, 46, props.modWindows , false) + end + + if props.modLivery ~= nil then + SetVehicleMod(vehicle, 48, props.modLivery , false) + end + end ESX.Game.TeleportEntity = function(entity, coords, cb) From 8c74011b397337e3c24bb716f133039ac32ad90a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 11:28:19 +0200 Subject: [PATCH 070/672] Add fallback cases --- resources/[essential]/es_extended/locale.lua | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/locale.lua b/resources/[essential]/es_extended/locale.lua index c8b11067..03e2271f 100644 --- a/resources/[essential]/es_extended/locale.lua +++ b/resources/[essential]/es_extended/locale.lua @@ -1,7 +1,19 @@ Locales = {} function _(str, ...) -- Translate string - return string.format(Locales[Config.Locale][str], ...) + + if Locales[Config.Locale] ~= nil then + + if Locales[Config.Locale][str] ~= nil then + return string.format(Locales[Config.Locale][str], ...) + else + return 'Translation [' .. Config.Locale .. '][' .. str .. '] does not exists' + end + + else + return 'Locale [' .. Config.Locale .. '] does not exists' + end + end function _U(str, ...) -- Translate string first char uppercase From ec1e8c0852b7461472dc9c332464ad55c81682e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 13:14:04 +0200 Subject: [PATCH 071/672] Add rare and canRemove flags on items --- es_extended.sql | 17 +++--- .../es_extended/client/functions.lua | 55 +++++++++++-------- .../[essential]/es_extended/server/common.lua | 6 +- .../[essential]/es_extended/server/main.lua | 24 ++++---- 4 files changed, 61 insertions(+), 41 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 834a229c..15ce8398 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,12 +1,13 @@ USE `essentialmode`; ALTER TABLE `users` -ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, -ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, -ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, -ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, -ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, -ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout`; + ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, + ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, + ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` +; CREATE TABLE `items` ( @@ -14,7 +15,9 @@ CREATE TABLE `items` ( `name` varchar(255) NOT NULL, `label` varchar(255) NOT NULL, `limit` int(11) NOT NULL DEFAULT '-1', - + `rare` int(11) NOT NULL DEFAULT '0', + `can_remove` int(11) NOT NULL DEFAULT '1', + PRIMARY KEY (`id`) ); diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 792495f0..d9680031 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -972,20 +972,24 @@ ESX.ShowInventory = function() local elements = {} table.insert(elements, { - label = '[Cash] $' .. data.money, - count = data.money, - type = 'item_money', - value = 'money', - usable = false + label = '[Cash] $' .. data.money, + count = data.money, + type = 'item_money', + value = 'money', + usable = false, + rare = false, + canRemove = true }) 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 + label = '[' .. data.accounts[i].label .. '] $' .. data.accounts[i].money, + count = data.accounts[i].money, + type = 'item_account', + value = data.accounts[i].name, + usable = false, + rare = false, + canRemove = true }) end @@ -993,11 +997,13 @@ ESX.ShowInventory = function() 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 + 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, + rare = data.inventory[i].rare, + canRemove = data.inventory[i].canRemove, }) end @@ -1012,11 +1018,13 @@ ESX.ShowInventory = function() 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 + label = Config.Weapons[i].label .. ' x1 [' .. ammo .. ']', + count = 1, + type = 'item_weapon', + value = Config.Weapons[i].name, + usable = false, + rare = false, + canRemove = true }) end @@ -1041,8 +1049,11 @@ ESX.ShowInventory = function() table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) end - table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) - table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) + if data.current.canRemove then + table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) + end + table.insert(elements, {label = _U('return'), action = 'return'}) ESX.UI.Menu.Open( diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index ffadee09..5e6a1042 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -22,8 +22,10 @@ AddEventHandler('onMySQLReady', function () for i=1, #result, 1 do ESX.Items[result[i].name] = { - label = result[i].label, - limit = result[i].limit + label = result[i].label, + limit = result[i].limit, + rare = (result[i].rare == 1 and true or false), + canRemove = (result[i].can_remove == 1 and true or false), } end diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 6d56ac13..23bab0e4 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -71,11 +71,13 @@ AddEventHandler('es:playerLoaded', function(source, _player) 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 + 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, + rare = ESX.Items[inventory[i].item].rare, + canRemove = ESX.Items[inventory[i].item].canRemove, }) end @@ -93,11 +95,13 @@ AddEventHandler('es:playerLoaded', function(source, _player) 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 + name = k, + count = 0, + label = ESX.Items[k].label, + limit = ESX.Items[k].limit, + usable = ESX.UsableItemsCallbacks[k] ~= nil, + rare = ESX.Items[k].rare, + canRemove = ESX.Items[k].canRemove, }) MySQL.Async.execute( From cb3533925167546bfd75c09adbbf42429c502efc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 13:15:55 +0200 Subject: [PATCH 072/672] Update README.md --- README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.md b/README.md index b827b23e..38dfcb62 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,16 @@ # fxserver-es_extended [WIP] FXServer ES Extended +[UPDATE] + +Since commit : https://github.com/FXServer-ESX/fxserver-es_extended/commit/ec1e8c0852b7461472dc9c332464ad55c81682e7 you have to add this SQL if you have already installed es_extended : +```sql +ALTER TABLE `items` + ADD COLUMN `rare` int(11) NOT NULL DEFAULT '0', + ADD COLUMN `can_remove` int(11) NOT NULL DEFAULT '1' +; +``` + [DISCORD] https://discord.me/fivem_esx From b2a93ea5de5cf9b428bc3d6cdc896c9afeea95fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 18:00:13 +0200 Subject: [PATCH 073/672] Add ESX.SpawnLocalObject --- .../es_extended/client/functions.lua | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index d9680031..6e01a4fb 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -293,6 +293,28 @@ ESX.Game.SpawnObject = function(model, coords, radius, cb) end +ESX.Game.SpawnLocalObject = function(model, coords, radius, cb) + + local model = (type(model) == 'number' and model or GetHashKey(model)) + + Citizen.CreateThread(function() + + RequestModel(model) + + while not HasModelLoaded(model) do + Citizen.Wait(0) + end + + local obj = CreateObject(model, coords.x, coords.y, coords.z, false, true, true) + + if cb ~= nil then + cb(obj) + end + + end) + +end + ESX.Game.DeleteVehicle = function(vehicle) SetEntityAsMissionEntity(vehicle, false, true) DeleteVehicle(vehicle) From 79a3c83b6a9dbf9ed3252c77b89b13ac7dda8643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 19 Aug 2017 18:02:52 +0200 Subject: [PATCH 074/672] Fix SpawnOBject arguments --- resources/[essential]/es_extended/client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 6e01a4fb..61580780 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -271,7 +271,7 @@ ESX.Game.Teleport = function(entity, coords, cb) end -ESX.Game.SpawnObject = function(model, coords, radius, cb) +ESX.Game.SpawnObject = function(model, coords, cb) local model = (type(model) == 'number' and model or GetHashKey(model)) @@ -293,7 +293,7 @@ ESX.Game.SpawnObject = function(model, coords, radius, cb) end -ESX.Game.SpawnLocalObject = function(model, coords, radius, cb) +ESX.Game.SpawnLocalObject = function(model, coords, cb) local model = (type(model) == 'number' and model or GetHashKey(model)) From 5f7188b760ecc8f963427e952a80a5a4e012d592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 20 Aug 2017 19:43:59 +0200 Subject: [PATCH 075/672] Fix hacky methods --- resources/[essential]/es_extended/client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 61580780..1ae278af 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -1195,8 +1195,8 @@ ESX.ShowInventory = function() 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) +AddEventHandler('esx:serverCallback', function(requestId, ...) + ESX.ServerCallbacks[requestId](...) ESX.ServerCallbacks[requestId] = nil end) From 0ef34c549139a5ef9b9447f903dc9507d2a013fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 12:04:03 +0200 Subject: [PATCH 076/672] Add object pickups when dropping + add /spawnobject admin command --- .../es_extended/client/functions.lua | 5 + .../[essential]/es_extended/client/main.lua | 93 ++++++++++++++++++- .../[essential]/es_extended/locales/br.lua | 1 + .../[essential]/es_extended/locales/en.lua | 1 + .../[essential]/es_extended/locales/fr.lua | 1 + .../es_extended/server/commands.lua | 6 ++ .../[essential]/es_extended/server/common.lua | 2 + .../es_extended/server/functions.lua | 16 ++++ .../[essential]/es_extended/server/main.lua | 21 +++++ 9 files changed, 145 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 1ae278af..4e215f1d 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -320,6 +320,11 @@ ESX.Game.DeleteVehicle = function(vehicle) DeleteVehicle(vehicle) end +ESX.Game.DeleteObject = function(object) + SetEntityAsMissionEntity(object, false, true) + DeleteObject(object) +end + ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index d0266595..1d9ffa1e 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -16,6 +16,7 @@ local PlayerLoaded = false local LoadoutLoaded = false local IsPaused = false local LastLoadout = {} +local Pickups = {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) @@ -249,7 +250,65 @@ AddEventHandler('esx:spawnVehicle', function(model) end) --- Pickup Weapon +RegisterNetEvent('esx:spawnObject') +AddEventHandler('esx:spawnObject', function(model) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) + + ESX.Game.SpawnObject(model, { + x = x, + y = y, + z = z + }, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + end) + +end) + +RegisterNetEvent('esx:pickup') +AddEventHandler('esx:pickup', function(id, label) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + 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) @@ -386,3 +445,35 @@ if Config.DisableWantedLevel then end +-- Pickups +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + for k,v in pairs(Pickups) do + + local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true) + + 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 distance <= 1.0 and not v.inRange then + TriggerServerEvent('esx:onPickup', v.id) + v.inRange = true + end + + end + + end +end) \ No newline at end of file diff --git a/resources/[essential]/es_extended/locales/br.lua b/resources/[essential]/es_extended/locales/br.lua index db4e39aa..cf47cb80 100644 --- a/resources/[essential]/es_extended/locales/br.lua +++ b/resources/[essential]/es_extended/locales/br.lua @@ -29,6 +29,7 @@ Locales['br'] = { ['play_emote'] = 'reproduzir emote', ['spawn_car'] = 'fazer aparecer um carro', ['spawn_car_param'] = 'nome do carro', + ['spawn_object'] = 'gerar um objeto', ['givemoney'] = 'dar dinheiro', ['money_amount'] = 'quantia do dinheiro', ['invalid_account'] = 'conta inválida', diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua index 0a059de2..def2cc5e 100644 --- a/resources/[essential]/es_extended/locales/en.lua +++ b/resources/[essential]/es_extended/locales/en.lua @@ -29,6 +29,7 @@ Locales['en'] = { ['play_emote'] = 'play emote', ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', + ['spawn_object'] = 'spawn object', ['givemoney'] = 'give money', ['money_amount'] = 'amount of money', ['invalid_account'] = 'invalid account', diff --git a/resources/[essential]/es_extended/locales/fr.lua b/resources/[essential]/es_extended/locales/fr.lua index e5af7b97..02bf1c10 100644 --- a/resources/[essential]/es_extended/locales/fr.lua +++ b/resources/[essential]/es_extended/locales/fr.lua @@ -29,6 +29,7 @@ Locales['fr'] = { ['play_emote'] = 'jouer emote', ['spawn_car'] = 'spawn un véhicule', ['spawn_car_param'] = 'nom de la voiture', + ['spawn_object'] = 'spawn un objet', ['givemoney'] = 'donner de l\'argent', ['money_amount'] = 'somme d\'argent', ['invalid_account'] = 'compete invalide', diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index 16def62e..e4102452 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -47,6 +47,12 @@ end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) +TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) + TriggerClientEvent('esx:spawnObject', source, args[2]) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = _U('spawn_object'), params = {{name = "name"}}}) + TriggerEvent('es:addGroupCommand', 'givemoney', 'admin', function(source, args, user) local _source = source diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index 5e6a1042..6676db37 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -4,6 +4,8 @@ ESX.UsableItemsCallbacks = {} ESX.Items = {} ESX.ServerCallbacks = {} ESX.LastPlayerData = {} +ESX.Pickups = {} +ESX.PickupId = 0 AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 000402cf..45582314 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -223,3 +223,19 @@ ESX.GetWeaponLabel = function(name) end end + +ESX.CreatePickup = function(type, name, count, label) + + local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) + + ESX.Pickups[pickupId] = { + type = type, + name = name, + count = count + } + + TriggerClientEvent('esx:pickup', -1, pickupId, label) + + ESX.PickupId = pickupId + +end \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 23bab0e4..1a9134c3 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -404,6 +404,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeInventoryItem(itemName, total) + ESX.CreatePickup('item_standard', itemName, total, foundItem.label) TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) end @@ -438,6 +439,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeMoney(total) + ESX.CreatePickup('item_money', 'money', total, 'Cash') TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end @@ -472,6 +474,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeAccountMoney(itemName, total) + ESX.CreatePickup('item_account', itemName, total, 'Cash') TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end @@ -527,6 +530,24 @@ AddEventHandler('esx:useItem', function(itemName) end) +RegisterServerEvent('esx:onPickup') +AddEventHandler('esx:onPickup', function(id) + + local pickup = ESX.Pickups[id] + local xPlayer = ESX.GetPlayerFromId(source) + + if pickup.type == 'item_standard' then + xPlayer.addInventoryItem(pickup.name, pickup.count) + elseif pickup.type == 'item_money' then + xPlayer.addMoney(pickup.count) + elseif pickup.type == 'item_account' then + xPlayer.addAccountMoney(pickup.name, pickup.count) + end + + TriggerClientEvent('esx:removePickup', -1, id) + +end) + ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) From 93daeaaf456f3428b1b5fcc875c8a9c8c08d0100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 13:38:27 +0200 Subject: [PATCH 077/672] Fix pickup spawn behind any player --- resources/[essential]/es_extended/client/main.lua | 10 +++++----- resources/[essential]/es_extended/server/functions.lua | 4 ++-- resources/[essential]/es_extended/server/main.lua | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 1d9ffa1e..0fff86b3 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -270,12 +270,12 @@ AddEventHandler('esx:spawnObject', function(model) end) RegisterNetEvent('esx:pickup') -AddEventHandler('esx:pickup', function(id, label) +AddEventHandler('esx:pickup', function(id, label, coords) - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * -2.0) + 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, diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 45582314..ae1bc2e7 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -224,7 +224,7 @@ ESX.GetWeaponLabel = function(name) end -ESX.CreatePickup = function(type, name, count, label) +ESX.CreatePickup = function(type, name, count, label, player) local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) @@ -234,7 +234,7 @@ ESX.CreatePickup = function(type, name, count, label) count = count } - TriggerClientEvent('esx:pickup', -1, pickupId, label) + TriggerClientEvent('esx:pickup', -1, pickupId, label, player) ESX.PickupId = pickupId diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 1a9134c3..e634c744 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -404,7 +404,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeInventoryItem(itemName, total) - ESX.CreatePickup('item_standard', itemName, total, foundItem.label) + ESX.CreatePickup('item_standard', itemName, total, foundItem.label, _source) TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) end @@ -439,7 +439,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeMoney(total) - ESX.CreatePickup('item_money', 'money', total, 'Cash') + ESX.CreatePickup('item_money', 'money', total, 'Cash', _source) TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end @@ -474,7 +474,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeAccountMoney(itemName, total) - ESX.CreatePickup('item_account', itemName, total, 'Cash') + ESX.CreatePickup('item_account', itemName, total, 'Cash', _source) TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end From 5f95bd0efceadf5d4239141c0bb1d61a83414ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:00:38 +0200 Subject: [PATCH 078/672] Update GetPlayers --- .../es_extended/server/functions.lua | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index ae1bc2e7..7cd575e1 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -127,11 +127,12 @@ end ESX.SavePlayers = function(cb) local asyncTasks = {} - local players = ESX.GetPlayers() + local xPlayers = ESX.GetPlayers() - for k,v in pairs(players) do + for i=1, #xPlayers, 1 do table.insert(asyncTasks, function(cb) - ESX.SavePlayer(v, cb) + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + ESX.SavePlayer(v, xPlayer) end) end @@ -164,11 +165,13 @@ ESX.StartPayCheck = function() local xPlayers = ESX.GetPlayers() - for k,v in pairs(xPlayers) do + for i=1, #xPlayers, 1 do - if v.job.grade_salary > 0 then - v.addMoney(v.job.grade_salary) - TriggerClientEvent('esx:showNotification', v.source, _U('rec_salary') .. '~g~$' .. v.job.grade_salary) + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer.job.grade_salary > 0 then + xPlayer.addMoney(xPlayer.job.grade_salary) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) end end @@ -182,9 +185,17 @@ ESX.StartPayCheck = function() end ESX.GetPlayers = function() - return ESX.Players + + local sources = {} + + for k,v in pairs(ESX.Players) do + table.insert(source, k) + end + + return sources end + ESX.GetPlayerFromId = function(source) return ESX.Players[tonumber(source)] end From dac3492ce8d203953b4f60407d501eb739b44593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:25:01 +0200 Subject: [PATCH 079/672] Fix typo --- resources/[essential]/es_extended/server/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 7cd575e1..2bbdbbcd 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -189,7 +189,7 @@ ESX.GetPlayers = function() local sources = {} for k,v in pairs(ESX.Players) do - table.insert(source, k) + table.insert(sources, k) end return sources From 1122ec02491e0bd0357160522f57de591e8b4820 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 21 Aug 2017 21:40:23 +0200 Subject: [PATCH 080/672] Fix error --- resources/[essential]/es_extended/server/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 2bbdbbcd..4c6ee6b3 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -132,7 +132,7 @@ ESX.SavePlayers = function(cb) for i=1, #xPlayers, 1 do table.insert(asyncTasks, function(cb) local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - ESX.SavePlayer(v, xPlayer) + ESX.SavePlayer(xPlayer, cb) end) end From b215be0db3d7438d42281c35d3c59f660ef99608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 22 Aug 2017 03:42:35 +0200 Subject: [PATCH 081/672] add close callback + return menu when opening --- resources/[essential]/es_extended/client/functions.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 4e215f1d..0a8f2035 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -134,7 +134,7 @@ ESX.UI.Menu.RegisterType = function(type, open, close) end -ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change) +ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, close) local menu = {} @@ -156,6 +156,10 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change) end end + if close ~= nil then + close() + end + end menu.update = function(query, newData) @@ -192,6 +196,8 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change) ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, data) + return menu + end ESX.UI.Menu.Close = function(type, namespace, name) From 0389a5c643fcf9255f149a370be2acaf1129cc25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 15:29:57 +0200 Subject: [PATCH 082/672] Remove TeleportEntity duplicate of Teleport --- .../es_extended/client/functions.lua | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 0a8f2035..1dd6725c 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -941,27 +941,6 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end -ESX.Game.TeleportEntity = function(entity, coords, cb) - - Citizen.CreateThread(function() - - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - - while not HasCollisionLoadedAroundEntity(entity) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - Citizen.Wait(0) - end - - SetEntityCoords(entity, coords.x, coords.y, coords.z) - - if cb ~= nil then - cb() - end - - end) - -end - ESX.Game.Utils.DrawText3D = function(coords, text, size) local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) From e9cea9fe51ab8ee03e888fedcc8f7b75eb4bc04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 23 Aug 2017 17:12:00 +0200 Subject: [PATCH 083/672] Fix menu close bug --- .../es_extended/client/functions.lua | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 1dd6725c..24b68c95 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -134,6 +134,8 @@ ESX.UI.Menu.RegisterType = function(type, open, close) end +local _type = type + ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, close) local menu = {} @@ -151,9 +153,13 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, 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 + + if ESX.UI.Menu.Opened[i] ~= nil then + 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 if close ~= nil then @@ -203,9 +209,11 @@ 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 + if ESX.UI.Menu.Opened[i] ~= nil then + 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 From 12cbc52ab9e2dd732cd44c8a57cdf3f4377b74cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 24 Aug 2017 15:28:44 +0200 Subject: [PATCH 084/672] Now use entityiter.lua --- .../[essential]/es_extended/__resource.lua | 1 + .../es_extended/client/entityiter.lua | 79 +++++++++++++++++++ .../es_extended/client/functions.lua | 34 ++++---- 3 files changed, 98 insertions(+), 16 deletions(-) create mode 100644 resources/[essential]/es_extended/client/entityiter.lua diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 396a1e69..26eb01ef 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -26,6 +26,7 @@ client_scripts { 'locales/en.lua', 'config.weapons.lua', 'client/common.lua', + 'client/entityiter.lua', 'client/functions.lua', 'client/main.lua' } diff --git a/resources/[essential]/es_extended/client/entityiter.lua b/resources/[essential]/es_extended/client/entityiter.lua new file mode 100644 index 00000000..71e9ee23 --- /dev/null +++ b/resources/[essential]/es_extended/client/entityiter.lua @@ -0,0 +1,79 @@ +--[[The MIT License (MIT) + +Copyright (c) 2017 IllidanS4 + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +]] + +local entityEnumerator = { + __gc = function(enum) + if enum.destructor and enum.handle then + enum.destructor(enum.handle) + end + enum.destructor = nil + enum.handle = nil + end +} + +local function EnumerateEntities(initFunc, moveFunc, disposeFunc) + return coroutine.wrap(function() + local iter, id = initFunc() + if not id or id == 0 then + disposeFunc(iter) + return + end + + local enum = {handle = iter, destructor = disposeFunc} + setmetatable(enum, entityEnumerator) + + local next = true + repeat + coroutine.yield(id) + next, id = moveFunc(iter) + until not next + + enum.destructor, enum.handle = nil, nil + disposeFunc(iter) + end) +end + +function EnumerateObjects() + return EnumerateEntities(FindFirstObject, FindNextObject, EndFindObject) +end + +function EnumeratePeds() + return EnumerateEntities(FindFirstPed, FindNextPed, EndFindPed) +end + +function EnumerateVehicles() + return EnumerateEntities(FindFirstVehicle, FindNextVehicle, EndFindVehicle) +end + +function EnumeratePickups() + return EnumerateEntities(FindFirstPickup, FindNextPickup, EndFindPickup) +end + +--[[Usage: +for ped in EnumeratePeds() do + +end +]] \ No newline at end of file diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 24b68c95..0ef5872f 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -409,16 +409,11 @@ end ESX.Game.GetObjects = function() - local objects = {} - local handle, object = FindFirstObject() - local success = nil + local objects = {} - repeat + for object in EnumerateObjects() do table.insert(objects, object) - success, object = FindNextObject(handle) - until not success - - EndFindObject(handle) + end return objects @@ -555,16 +550,11 @@ end ESX.Game.GetVehicles = function() - local vehicles = {} - local handle, vehicle = FindFirstVehicle() - local success = nil + local vehicles = {} - repeat + for vehicle in EnumerateVehicles() do table.insert(vehicles, vehicle) - success, vehicle = FindNextVehicle(handle) - until not success - - EndFindVehicle(handle) + end return vehicles @@ -617,6 +607,18 @@ ESX.Game.GetVehiclesInArea = function(coords, area) return vehiclesInArea end +ESX.Game.GetPeds = function() + + local peds = {} + + for ped in EnumeratePeds() do + table.insert(peds, ped) + end + + return peds + +end + ESX.Game.GetVehicleProperties = function(vehicle) local color1, color2 = GetVehicleColours(vehicle) From c1f58d7b6416a34d01b7c5899e9ff4a6f4f7c869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 24 Aug 2017 20:15:44 +0200 Subject: [PATCH 085/672] Fix nil value bugs --- .../es_extended/client/functions.lua | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 0ef5872f..4d2f4541 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -222,8 +222,10 @@ 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 + if ESX.UI.Menu.Opened[i] ~= nil then + ESX.UI.Menu.Opened[i].close() + ESX.UI.Menu.Opened[i] = nil + end end end @@ -231,8 +233,10 @@ 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] + if ESX.UI.Menu.Opened[i] ~= nil then + 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 @@ -1215,9 +1219,13 @@ Citizen.CreateThread(function() for i=1, #ESX.TimeoutCallbacks, 1 do - if currTime >= ESX.TimeoutCallbacks[i].time then - ESX.TimeoutCallbacks[i].cb() - ESX.TimeoutCallbacks[i] = nil + if ESX.TimeoutCallbacks[i] ~= nil then + + if currTime >= ESX.TimeoutCallbacks[i].time then + ESX.TimeoutCallbacks[i].cb() + ESX.TimeoutCallbacks[i] = nil + end + end end From 0f32bbcf9c040d583ded50d695a5f9826433a5a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 25 Aug 2017 10:44:57 +0200 Subject: [PATCH 086/672] Add ESX.ClearTimeout --- resources/[essential]/es_extended/client/functions.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 4d2f4541..f2394e18 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -38,6 +38,11 @@ ESX.SetTimeout = function(msec, cb) time = GetGameTimer() + msec, cb = cb }) + return #ESX.TimeoutCallbacks +end + +ESX.ClearTimeout = function(i) + ESX.TimeoutCallbacks[i] = nil end ESX.ShowNotification = function(msg) From 2772576df8e8f339cf7cc7c77493e5b4614f10f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 09:03:48 +0200 Subject: [PATCH 087/672] Fix pickup --- resources/[essential]/es_extended/client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 0fff86b3..caa47ea7 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -270,7 +270,7 @@ AddEventHandler('esx:spawnObject', function(model) end) RegisterNetEvent('esx:pickup') -AddEventHandler('esx:pickup', function(id, label, coords) +AddEventHandler('esx:pickup', function(id, label, player) local ped = GetPlayerPed(GetPlayerFromServerId(player)) local coords = GetEntityCoords(ped) From e84541553acdcb1bd64fa12ab0d7e56463ece546 Mon Sep 17 00:00:00 2001 From: ultratm Date: Sat, 26 Aug 2017 10:47:13 +0200 Subject: [PATCH 088/672] Add German Language --- de_es_extended.sql | 69 ++++++++++ .../[essential]/es_extended/__resource.lua | 2 + .../[essential]/es_extended/locales/de.lua | 121 ++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 de_es_extended.sql create mode 100644 resources/[essential]/es_extended/locales/de.lua diff --git a/de_es_extended.sql b/de_es_extended.sql new file mode 100644 index 00000000..9e4add3a --- /dev/null +++ b/de_es_extended.sql @@ -0,0 +1,69 @@ +USE `essentialmode`; + +ALTER TABLE `users` + ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, + ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, + ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` +; + +CREATE TABLE `items` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `limit` int(11) NOT NULL DEFAULT '-1', + `rare` int(11) NOT NULL DEFAULT '0', + `can_remove` int(11) NOT NULL DEFAULT '1', + + PRIMARY KEY (`id`) +); + +CREATE TABLE `job_grades` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `job_name` varchar(255) DEFAULT NULL, + `grade` int(11) NOT NULL, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `salary` int(11) NOT NULL, + `skin_male` longtext NOT NULL, + `skin_female` longtext NOT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','Arbeitslos',200,'{}','{}'); + +CREATE TABLE `jobs` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) DEFAULT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `jobs` VALUES (1,'unemployed','Suchend'); + +CREATE TABLE `user_accounts` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `money` double NOT NULL DEFAULT '0', + + PRIMARY KEY (`id`) +); + +CREATE TABLE `user_inventory` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `item` varchar(255) NOT NULL, + `count` int(11) NOT NULL, + + PRIMARY KEY (`id`) +); diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 26eb01ef..225d2734 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -7,6 +7,7 @@ server_scripts { '@mysql-async/lib/MySQL.lua', 'config.lua', 'locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', @@ -21,6 +22,7 @@ server_scripts { client_scripts { 'config.lua', 'locale.lua', + 'locales/de.lua', 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', diff --git a/resources/[essential]/es_extended/locales/de.lua b/resources/[essential]/es_extended/locales/de.lua new file mode 100644 index 00000000..21ec922b --- /dev/null +++ b/resources/[essential]/es_extended/locales/de.lua @@ -0,0 +1,121 @@ +Locales['de'] = { + ['inventory'] = 'Inventar', + ['use'] = 'benutzen', + ['give'] = 'geben', + ['remove'] = 'entfernen', + ['return'] = 'zurück', + ['amount'] = 'Betrag', + ['amount_invalid'] = 'ungültiger Betrag', + ['players_nearby'] = 'keine Spieler in der Nähe', + ['ex_inv_lim'] = 'Aktion nicht möglich, inventarlimit überschritten für ~b~', + ['yougave'] = 'du gibst', + ['youreceived'] = 'to empfängst', + ['to'] = '~s~ zu ~b~', + ['by'] = '~s~ von ~b~', + ['imp_invalid_quantity'] = 'Aktion nicht möglich, ungültige Anzahl', + ['imp_invalid_amount'] = 'Aktion nicht möglich, ungültiger Betrag', + ['delete_five_min'] = '~r~löschen~s~ in 5 Minuten', + ['threw'] = 'du ~r~wirfst weg~s~', + ['rec_salary'] = 'du hast dein Gehalt erhalten: ', + ['act_imp'] = 'Aktion nicht möglich', + -- Commands + ['setjob'] = 'assign a job to a user', + ['id_param'] = 'the ID of the player', + ['setjob_param2'] = 'the job you wish to assign', + ['setjob_param3'] = 'the job level', + ['load_ipl'] = 'load IPL', + ['unload_ipl'] = 'unload IPL', + ['play_anim'] = 'play animation', + ['play_emote'] = 'play emote', + ['spawn_car'] = 'spawn a car', + ['spawn_car_param'] = 'name of car', + ['givemoney'] = 'give money', + ['money_amount'] = 'amount of money', + ['invalid_account'] = 'invalid account', + ['account'] = 'account', + ['giveaccountmoney'] = 'give account money', + ['invalid_item'] = 'invalid item', + ['item'] = 'item', + ['giveitem'] = 'give item', + ['weapon'] = 'weapon', + ['giveweapon'] = 'give weapon', + -- Weapons + ['weapon_knife'] = 'Messer', + ['weapon_nightstick'] = 'Schlagstock', + ['weapon_hammer'] = 'Hammer', + ['weapon_bat'] = 'Schläger', + ['weapon_golfclub'] = 'Golfschläger', + ['weapon_crowbar'] = 'Brecheisen', + ['weapon_pistol'] = 'Pistole', + ['weapon_combatpistol'] = 'Kampfpistole', + ['weapon_appistol'] = 'AP Pistole', + ['weapon_pistol50'] = 'Pistole .50', + ['weapon_microsmg'] = 'Mikro SMG', + ['weapon_smg'] = 'SMG', + ['weapon_assaultsmg'] = 'Kampf SMG', + ['weapon_assaultrifle'] = 'Kampfgewehr', + ['weapon_carbinerifle'] = 'Karabinergewehr', + ['weapon_advancedrifle'] = 'Advancedgewehr', + ['weapon_mg'] = 'MG', + ['weapon_combatmg'] = 'Kampf MG', + ['weapon_pumpshotgun'] = 'Pumpgun', + ['weapon_sawnoffshotgun'] = 'Abgesägte Schrotflinte', + ['weapon_assaultshotgun'] = 'Kampf Schrotflinte', + ['weapon_bullpupshotgun'] = 'Bullpup Schrotflinte', + ['weapon_stungun'] = 'Tazer', + ['weapon_sniperrifle'] = 'Scharfschützengewehr', + ['weapon_heavysniper'] = 'Schweres Sniper', + ['weapon_remotesniper'] = 'Remote sniper', + ['weapon_grenadelauncher'] = 'Granatwerfer', + ['weapon_rpg'] = 'RPG', + ['weapon_stinger'] = 'Stinger', + ['weapon_minigun'] = 'Minigun', + ['weapon_grenade'] = 'Granate', + ['weapon_stickybomb'] = 'Haftbombe', + ['weapon_smokegrenade'] = 'Rauchgranate', + ['weapon_bzgas'] = 'BZ Gas', + ['weapon_molotov'] = 'Molotov Cocktail', + ['weapon_fireextinguisher'] = 'Feuerlöscher', + ['weapon_petrolcan'] = 'Benzinkanister', + ['weapon_digiscanner'] = 'Digiscanner', + ['weapon_ball'] = 'Ball', + ['weapon_snspistol'] = 'SNS Pistole', + ['weapon_bottle'] = 'Flasche', + ['weapon_gusenberg'] = 'Gusenberg', + ['weapon_specialcarbine'] = 'Spezialkarabiner', + ['weapon_heavypistol'] = 'Schwere Pistole', + ['weapon_bullpuprifle'] = 'Bullpupgewehr', + ['weapon_dagger'] = 'Dolch', + ['weapon_vintagepistol'] = 'Vintage Pistole', + ['weapon_firework'] = 'Feuerwerk', + ['weapon_musket'] = 'Muskete', + ['weapon_heavyshotgun'] = 'Schwere Schrotflinte', + ['weapon_marksmanrifle'] = 'Marksmangewehr', + ['weapon_hominglauncher'] = 'Homing Launcher', + ['weapon_proxmine'] = 'Annäherungsmine', + ['weapon_snowball'] = 'Schneeball', + ['weapon_flaregun'] = 'Leuchtpistole', + ['weapon_garbagebag'] = 'Müllsack', + ['weapon_handcuffs'] = 'Handschellen', + ['weapon_combatpdw'] = 'Kampf PDW', + ['weapon_marksmanpistol'] = 'Marksman Pistole', + ['weapon_knuckle'] = 'Schlagring', + ['weapon_hatchet'] = 'Axt', + ['weapon_railgun'] = 'Railgun', + ['weapon_machete'] = 'Machete', + ['weapon_machinepistol'] = 'Maschinenpistole', + ['weapon_switchblade'] = 'Klappmesser', + ['weapon_revolver'] = 'Schwerer Revolver', + ['weapon_dbshotgun'] = 'Doppelläufige Schrotflinte', + ['weapon_compactrifle'] = 'Kampfgewehr', + ['weapon_autoshotgun'] = 'Auto Shotgun', + ['weapon_battleaxe'] = 'Kampfaxt', + ['weapon_compactlauncher'] = 'Kompakt Launcher', + ['weapon_minismg'] = 'Mini SMG', + ['weapon_pipebomb'] = 'Rohrbombe', + ['weapon_poolcue'] = 'Kö', + ['weapon_wrench'] = 'Rohrzange', + ['weapon_flashlight'] = 'Taschenlampe', + ['gadget_nightvision'] = 'Nachtsichtgerät', + ['gadget_parachute'] = 'Fallschirm', +} \ No newline at end of file From 5491654979a8977030c7aa7b8bbc000e8b24bd10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 17:33:04 +0200 Subject: [PATCH 089/672] Add /spawnped command --- .../[essential]/es_extended/client/main.lua | 27 +++++++++++++++++++ .../es_extended/server/commands.lua | 6 +++++ 2 files changed, 33 insertions(+) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index caa47ea7..f594f8ac 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -319,6 +319,33 @@ AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName) end) +RegisterNetEvent('esx:spawnPed') +AddEventHandler('esx:spawnPed', function(model) + + model = (tonumber(model) ~= nil and tonumber(model) or GetHashKey(model)) + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) + + Citizen.CreateThread(function() + + print(model) + + RequestModel(model) + + while not HasModelLoaded(model) do + Citizen.Wait(0) + end + + print('LOADED') + + CreatePed(5, model, x, y, z, 0.0, true, false) + + end) + +end) + -- Pause menu disable HUD display Citizen.CreateThread(function() while true do diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index e4102452..d21f081c 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -47,6 +47,12 @@ end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) +TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) + TriggerClientEvent('esx:spawnPed', source, args[2]) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end) + TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnObject', source, args[2]) end, function(source, args, user) From 859c118ccf2b0c4e310ef2f02b14a147ab5407e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 26 Aug 2017 18:55:05 +0200 Subject: [PATCH 090/672] Add dv --- .../[essential]/es_extended/client/main.lua | 21 +++++++++++++++++++ .../es_extended/server/commands.lua | 7 +++++++ 2 files changed, 28 insertions(+) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index f594f8ac..efd451d2 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -346,6 +346,27 @@ AddEventHandler('esx:spawnPed', function(model) end) +RegisterNetEvent('esx:deleteVehicle') +AddEventHandler('esx:deleteVehicle', function() + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle = GetVehiclePedIsIn(playerPed, false) + ESX.Game.DeleteVehicle(vehicle) + + elseif IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + ESX.Game.DeleteVehicle(vehicle) + + end + +end) + + -- Pause menu disable HUD display Citizen.CreateThread(function() while true do diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index d21f081c..5d0800e7 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -47,6 +47,13 @@ end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) +TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) + TriggerClientEvent('esx:deleteVehicle', source) +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end) + + TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnPed', source, args[2]) end, function(source, args, user) From b7a7f77c324778de2bdd35f4e07b1827e03156da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 17:22:07 +0200 Subject: [PATCH 091/672] Bandwith optimization + Add ESX.SetTimeout / ESX.ClearTimeout serverside --- .../es_extended/client/functions.lua | 325 +++++++++--------- .../[essential]/es_extended/client/main.lua | 74 ++-- resources/[essential]/es_extended/config.lua | 2 +- .../[essential]/es_extended/server/common.lua | 27 +- .../es_extended/server/functions.lua | 15 +- 5 files changed, 251 insertions(+), 192 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index f2394e18..87e53b3b 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -5,6 +5,7 @@ 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.PlayerData = {} ESX.CurrentRequestId = 0 ESX.ServerCallbacks = {} ESX.TimeoutCallbacks = {} @@ -996,210 +997,206 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size) end ESX.ShowInventory = function() - - ESX.TriggerServerCallback('esx:getPlayerData', function(data) - local playerPed = GetPlayerPed(-1) - local elements = {} + local playerPed = GetPlayerPed(-1) + local elements = {} + table.insert(elements, { + label = '[Cash] $' .. ESX.PlayerData.money, + count = ESX.PlayerData.money, + type = 'item_money', + value = 'money', + usable = false, + rare = false, + canRemove = true + }) + + for i=1, #ESX.PlayerData.accounts, 1 do table.insert(elements, { - label = '[Cash] $' .. data.money, - count = data.money, - type = 'item_money', - value = 'money', + label = '[' .. ESX.PlayerData.accounts[i].label .. '] $' .. ESX.PlayerData.accounts[i].money, + count = ESX.PlayerData.accounts[i].money, + type = 'item_account', + value = ESX.PlayerData.accounts[i].name, usable = false, rare = false, canRemove = true }) + end - for i=1, #data.accounts, 1 do + for i=1, #ESX.PlayerData.inventory, 1 do + + if ESX.PlayerData.inventory[i].count > 0 then 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, + label = ESX.PlayerData.inventory[i].label .. ' x' .. ESX.PlayerData.inventory[i].count, + count = ESX.PlayerData.inventory[i].count, + type = 'item_standard', + value = ESX.PlayerData.inventory[i].name, + usable = ESX.PlayerData.inventory[i].usable, + rare = ESX.PlayerData.inventory[i].rare, + canRemove = ESX.PlayerData.inventory[i].canRemove, + }) + 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, rare = false, canRemove = true }) + end + end - for i=1, #data.inventory, 1 do + ESX.UI.Menu.CloseAll() - 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, - rare = data.inventory[i].rare, - canRemove = data.inventory[i].canRemove, - }) + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'inventory', + { + title = _U('inventory'), + align = 'bottom-right', + elements = elements, + }, + function(data, menu) + + menu.close() + + local elements = {} + + if data.current.usable then + table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) 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, - rare = false, - canRemove = true - }) - + if data.current.canRemove then + table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) end - end - ESX.UI.Menu.CloseAll() + table.insert(elements, {label = _U('return'), action = 'return'}) - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'inventory', - { - title = _U('inventory'), - align = 'bottom-right', - elements = elements, - }, - function(data, menu) + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'inventory_item', + { + title = _U('inventory'), + align = 'bottom-right', + elements = elements, + }, + function(data, menu) - menu.close() + local item = data.current.value + local type = data.current.type - local elements = {} + if data.current.action == 'give' then - if data.current.usable then - table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) - end + if type == 'item_weapon' then - if data.current.canRemove then - table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) - table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) - end + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - table.insert(elements, {label = _U('return'), action = 'return'}) + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('players_nearby')) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) + end - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'inventory_item', - { - title = _U('inventory'), - align = 'bottom-right', - elements = elements, - }, - function(data, menu) + else - local item = data.current.value - local type = data.current.type + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', + { + title = _U('amount') + }, + function(data2, menu2) - if data.current.action == 'give' then + local quantity = tonumber(data2.value) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if type == 'item_weapon' then + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('players_nearby')) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + end - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + menu2.close() + menu.close() - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('players_nearby')) - else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) + end, + function(data2, menu2) + menu2.close() end + ) - else - - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', - { - title = _U('amount') - }, - function(data2, menu2) - - local quantity = tonumber(data2.value) - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('players_nearby')) - else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) - end - - menu2.close() - menu.close() - - end, - function(data2, menu2) - menu2.close() - end - ) - - end - - elseif data.current.action == 'remove' then - - if type == 'item_weapon' then - - TriggerServerEvent('esx:removeInventoryItem', type, item, 1) - menu.close() - - else - - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', - { - title = _U('amount') - }, - function(data2, menu2) - - local quantity = tonumber(data2.value) - - if quantity == nil then - ESX.ShowNotification(_U('amount_invalid')) - else - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) - end - - menu2.close() - menu.close() - - end, - function(data2, menu2) - menu2.close() - end - ) - - end - - elseif data.current.action == 'use' then - - TriggerServerEvent('esx:useItem', data.current.value) - - elseif data.current.action == 'return' then - - ESX.UI.Menu.CloseAll() - ESX.ShowInventory() - end + + elseif data.current.action == 'remove' then + + if type == 'item_weapon' then + + TriggerServerEvent('esx:removeInventoryItem', type, item, 1) + menu.close() + + else + + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', + { + title = _U('amount') + }, + function(data2, menu2) + + local quantity = tonumber(data2.value) + + if quantity == nil then + ESX.ShowNotification(_U('amount_invalid')) + else + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + end + + menu2.close() + menu.close() + + end, + function(data2, menu2) + menu2.close() + end + ) + + end + + elseif data.current.action == 'use' then + + TriggerServerEvent('esx:useItem', data.current.value) + + elseif data.current.action == 'return' then - end, - function(data, menu) 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, + function(data, menu) + menu.close() + end + ) end diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index efd451d2..45387806 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -21,7 +21,8 @@ local Pickups = {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - PlayerLoaded = true + PlayerLoaded = true + ESX.PlayerData = xPlayer for i=1, #xPlayer.accounts, 1 do @@ -63,24 +64,20 @@ AddEventHandler('playerSpawned', function() Citizen.Wait(0) end - ESX.TriggerServerCallback('esx:getPlayerData', function(data) - - local playerPed = GetPlayerPed(-1) + local playerPed = GetPlayerPed(-1) - -- Restore position - if data.lastPosition ~= nil then - SetEntityCoords(playerPed, data.lastPosition.x, data.lastPosition.y, data.lastPosition.z) - end + -- Restore position + if ESX.PlayerData.lastPosition ~= nil then + SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.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 + -- Restore loadout + for i=1, #ESX.PlayerData.loadout, 1 do + local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) + GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) + end - LoadoutLoaded = true - - end) + LoadoutLoaded = true end) @@ -97,31 +94,46 @@ AddEventHandler('skinchanger:modelLoaded', function() end -- Restore loadout - ESX.TriggerServerCallback('esx:getPlayerData', function(data) - local playerPed = GetPlayerPed(-1) + 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 + for i=1, #ESX.PlayerData.loadout, 1 do + local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) + GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) + end - LoadoutLoaded = true - - end) + LoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') AddEventHandler('esx:setAccountMoney', function(account) + + for i=1, #ESX.PlayerData.accounts, 1 do + if ESX.PlayerData.accounts[i].name == account.name then + ESX.PlayerData.accounts[i] = account + end + end + ESX.UI.HUD.UpdateElement('account_' .. account.name, { money = account.money }) end) +RegisterNetEvent('es:activateMoney') +AddEventHandler('es:activateMoney', function(money) + ESX.PlayerData.money = money +end) + RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count) + for i=1, #ESX.PlayerData.inventory, 1 do + if ESX.PlayerData.inventory[i].name == item.name then + ESX.PlayerData.inventory[i] = item + end + end + ESX.UI.ShowInventoryItemNotification(true, item, count) if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then @@ -133,6 +145,12 @@ end) RegisterNetEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(item, count) + for i=1, #ESX.PlayerData.inventory, 1 do + if ESX.PlayerData.inventory[i].name == item.name then + ESX.PlayerData.inventory[i] = item + end + end + ESX.UI.ShowInventoryItemNotification(false, item, count) if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then @@ -141,6 +159,11 @@ AddEventHandler('esx:removeInventoryItem', function(item, count) 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 = GetPlayerPed(-1) @@ -431,6 +454,7 @@ Citizen.CreateThread(function() end if loadoutChanged and LoadoutLoaded then + ESX.PlayerData.loadout = loadout TriggerServerEvent('esx:updateLoadout', loadout) end diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 8b280075..02da4807 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -7,5 +7,5 @@ Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 -Config.EnableWeaponPickup = false +Config.EnableWeaponPickup = true Config.Locale = 'fr' diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index 6676db37..f8b1c72d 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -3,6 +3,7 @@ ESX.Players = {} ESX.UsableItemsCallbacks = {} ESX.Items = {} ESX.ServerCallbacks = {} +ESX.TimeoutCallbacks = {} ESX.LastPlayerData = {} ESX.Pickups = {} ESX.PickupId = 0 @@ -73,4 +74,28 @@ AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) TriggerClientEvent('esx:serverCallback', _source, requestId, ...) end, ...) -end) \ No newline at end of file +end) + +-- SetTimeout +CreateThread(function() + while true do + + Wait(0) + + local currTime = os.clock() * 1000 + + for i=1, #ESX.TimeoutCallbacks, 1 do + + if ESX.TimeoutCallbacks[i] ~= nil then + + if currTime >= ESX.TimeoutCallbacks[i].time then + ESX.TimeoutCallbacks[i].cb() + ESX.TimeoutCallbacks[i] = nil + end + + end + + end + + end +end) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 4c6ee6b3..1ac85f8e 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -20,6 +20,18 @@ ESX.GetRandomString = function(length) end +ESX.SetTimeout = function(msec, cb) + table.insert(ESX.TimeoutCallbacks, { + time = os.clock() * 1000 + msec, + cb = cb + }) + return #ESX.TimeoutCallbacks +end + +ESX.ClearTimeout = function(i) + ESX.TimeoutCallbacks[i] = nil +end + ESX.RegisterServerCallback = function(name, cb) ESX.ServerCallbacks[name] = cb end @@ -249,4 +261,5 @@ ESX.CreatePickup = function(type, name, count, label, player) ESX.PickupId = pickupId -end \ No newline at end of file +end + From 10a903c9e0e97d89866ee952502a221d95c1576d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 18:04:22 +0200 Subject: [PATCH 092/672] Add ESX.GetClosestPed --- .../es_extended/client/functions.lua | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 87e53b3b..6857bae5 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -617,18 +617,54 @@ ESX.Game.GetVehiclesInArea = function(coords, area) return vehiclesInArea end -ESX.Game.GetPeds = function() - - local peds = {} +ESX.Game.GetPeds = function(ignoreList) + + local ignoreList = ignoreList or {} + local peds = {} for ped in EnumeratePeds() do - table.insert(peds, ped) + + local found = false + + for j=1, #ignoreList, 1 do + if ignoreList[j] == ped then + found = true + end + end + + if not found then + table.insert(peds, ped) + end + end return peds end +ESX.Game.GetClosestPed = function(coords, ignoreList) + + local ignoreList = ignoreList or {} + local peds = ESX.Game.GetPeds(ignoreList) + local closestDistance = -1 + local closestPed = -1 + + for i=1, #peds, 1 do + + local pedCoords = GetEntityCoords(peds[i]) + local distance = GetDistanceBetweenCoords(pedCoords.x, pedCoords.y, pedCoords.z, coords.x, coords.y, coords.z, true) + + if closestDistance == -1 or closestDistance > distance then + closestPed = peds[i] + closestDistance = distance + end + + end + + return closestPed, closestDistance + +end + ESX.Game.GetVehicleProperties = function(vehicle) local color1, color2 = GetVehicleColours(vehicle) From 9c849044d588e0c7f430de856b4ec81c06cf4d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 18:07:18 +0200 Subject: [PATCH 093/672] Add ESX.PlayerLoaded --- resources/[essential]/es_extended/client/functions.lua | 1 + resources/[essential]/es_extended/client/main.lua | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 6857bae5..6cc0363c 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -6,6 +6,7 @@ for i = 97, 122 do table.insert(Charset, string.char(i)) end ESX = {} ESX.PlayerData = {} +ESX.PlayerLoaded = false ESX.CurrentRequestId = 0 ESX.ServerCallbacks = {} ESX.TimeoutCallbacks = {} diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 45387806..309e8cda 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -12,7 +12,6 @@ local Keys = { local GUI = {} GUI.Time = 0 -local PlayerLoaded = false local LoadoutLoaded = false local IsPaused = false local LastLoadout = {} @@ -21,8 +20,8 @@ local Pickups = {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - PlayerLoaded = true - ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer for i=1, #xPlayer.accounts, 1 do @@ -60,7 +59,7 @@ AddEventHandler('playerSpawned', function() Citizen.CreateThread(function() - while not PlayerLoaded do + while not ESX.PlayerLoaded do Citizen.Wait(0) end @@ -89,7 +88,7 @@ end) AddEventHandler('skinchanger:modelLoaded', function() - while not PlayerLoaded do + while not ESX.PlayerLoaded do Citizen.Wait(0) end From 4f63c141b9adef6fe6a487a84a0a40bed3650b04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 19:40:49 +0200 Subject: [PATCH 094/672] Fix position with new system --- .../[essential]/es_extended/client/main.lua | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 309e8cda..66ed6b61 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -546,5 +546,25 @@ Citizen.CreateThread(function() end + end +end) + +-- Last position +Citizen.CreateThread(function() + while true do + + Citizen.Wait(1000) + + if ESX ~= nil and ESX.PlayerLoaded then + + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + + if not IsEntityDead(playerPed) then + ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} + end + + end + end end) \ No newline at end of file From 2bc7caef0e159a59de2d8feb8c29ec7635b680ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 23:29:01 +0200 Subject: [PATCH 095/672] Add ESX.IsPlayerLoaded --- resources/[essential]/es_extended/client/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 6cc0363c..e8a8028e 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -47,6 +47,10 @@ ESX.ClearTimeout = function(i) ESX.TimeoutCallbacks[i] = nil end +ESX.IsPlayerLoaded = function() + return ESX.PlayerLoaded +end + ESX.ShowNotification = function(msg) SetNotificationTextEntry('STRING') AddTextComponentString(msg) From b285ae9c8935a45c95a06c17413a4c40a8bff7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Wed, 30 Aug 2017 23:45:19 +0200 Subject: [PATCH 096/672] Add ESX.GetPlayerData() --- resources/[essential]/es_extended/client/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index e8a8028e..81142ee2 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -51,6 +51,10 @@ ESX.IsPlayerLoaded = function() return ESX.PlayerLoaded end +ESX.GetPlayerData = function() + return ESX.PlayerData +end + ESX.ShowNotification = function(msg) SetNotificationTextEntry('STRING') AddTextComponentString(msg) From 4c88c72b50c36177939ce6685b7839a434f502b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 31 Aug 2017 00:59:34 +0200 Subject: [PATCH 097/672] Add ESX.SetPlayerData --- resources/[essential]/es_extended/client/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 81142ee2..7c6eb4b8 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -55,6 +55,10 @@ ESX.GetPlayerData = function() return ESX.PlayerData end +ESX.SetPlayerData = function(key, val) + ESX.PlayerData[key] = val +end + ESX.ShowNotification = function(msg) SetNotificationTextEntry('STRING') AddTextComponentString(msg) From a10f4df910f2e81554e5e78b9b360df777811ca1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 31 Aug 2017 09:50:19 +0200 Subject: [PATCH 098/672] Fix player spawn --- .../[essential]/es_extended/client/main.lua | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 66ed6b61..82664623 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -14,6 +14,7 @@ local GUI = {} GUI.Time = 0 local LoadoutLoaded = false local IsPaused = false +local PlayerSpawned = false local LastLoadout = {} local Pickups = {} @@ -77,6 +78,7 @@ AddEventHandler('playerSpawned', function() end LoadoutLoaded = true + PlayerSpawned = true end) @@ -352,16 +354,12 @@ AddEventHandler('esx:spawnPed', function(model) Citizen.CreateThread(function() - print(model) - RequestModel(model) while not HasModelLoaded(model) do Citizen.Wait(0) end - print('LOADED') - CreatePed(5, model, x, y, z, 0.0, true, false) end) @@ -551,11 +549,12 @@ end) -- Last position Citizen.CreateThread(function() + while true do Citizen.Wait(1000) - if ESX ~= nil and ESX.PlayerLoaded then + if ESX ~= nil and ESX.PlayerLoaded and PlayerSpawned then local playerPed = GetPlayerPed(-1) local coords = GetEntityCoords(playerPed) @@ -567,4 +566,20 @@ Citizen.CreateThread(function() end end + +end) + +Citizen.CreateThread(function() + + while true do + + Citizen.Wait(0) + + local playerPed = GetPlayerPed(-1) + + if IsEntityDead(playerPed) and PlayerSpawned then + PlayerSpawned = false + end + end + end) \ No newline at end of file From 9ac17cf76d3c5845dbe606e3dfb9016ff2d13dd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 00:21:58 +0200 Subject: [PATCH 099/672] Add esx:setJob server event + ESX.Trace + increase save timeout --- resources/[essential]/es_extended/config.lua | 2 ++ .../es_extended/server/classes/player.lua | 3 +++ .../[essential]/es_extended/server/functions.lua | 14 ++++++++++---- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index 02da4807..b6714cc6 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -9,3 +9,5 @@ Config.DisableWantedLevel = true Config.RemoveInventoryItemDelay = 5 * 60000 Config.EnableWeaponPickup = true Config.Locale = 'fr' +Config.EnableDebug = false + diff --git a/resources/[essential]/es_extended/server/classes/player.lua b/resources/[essential]/es_extended/server/classes/player.lua index 107960e7..6a29f4f1 100644 --- a/resources/[essential]/es_extended/server/classes/player.lua +++ b/resources/[essential]/es_extended/server/classes/player.lua @@ -318,6 +318,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.setJob = function(name, grade) + local lastJob = json.decode(json.encode(self.job)) + MySQL.Async.fetchAll( 'SELECT * FROM `jobs` WHERE `name` = @name', { @@ -353,6 +355,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.job['skin_female'] = json.decode(result[1].skin_female) end + TriggerEvent("esx:setJob", self.source, self.job, lastJob) TriggerClientEvent("esx:setJob", self.source, self.job) end diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index 1ac85f8e..fad63172 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -4,6 +4,12 @@ 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.Trace = function(str) + if Config.EnableDebug then + print('ESX> ' .. str) + end +end + ESX.GetConfig = function() return Config end @@ -148,7 +154,7 @@ ESX.SavePlayers = function(cb) end) end - Async.parallelLimit(asyncTasks, 15, function(results) + Async.parallelLimit(asyncTasks, 8, function(results) RconPrint('[SAVED] All players' .. "\n") @@ -164,15 +170,15 @@ ESX.StartDBSync = function() function saveData() ESX.SavePlayers() - SetTimeout(60000, saveData) + SetTimeout(10 * 60 * 1000, saveData) end - SetTimeout(60000, saveData) + SetTimeout(10 * 60 * 1000, saveData) end ESX.StartPayCheck = function() - + function payCheck() local xPlayers = ESX.GetPlayers() From f6229f51c46f58cf76a853960be6179efc42949e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 2 Sep 2017 13:17:37 +0200 Subject: [PATCH 100/672] Fix inventory limit + move paycheck in separate file --- .../[essential]/es_extended/__resource.lua | 1 + .../es_extended/server/functions.lua | 25 ------------------- .../[essential]/es_extended/server/main.lua | 2 +- .../es_extended/server/paycheck.lua | 24 ++++++++++++++++++ 4 files changed, 26 insertions(+), 26 deletions(-) create mode 100644 resources/[essential]/es_extended/server/paycheck.lua diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 225d2734..9557254a 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -15,6 +15,7 @@ server_scripts { 'server/common.lua', 'server/classes/player.lua', 'server/functions.lua', + 'server/paycheck.lua', 'server/main.lua', 'server/commands.lua' } diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index fad63172..ffbbe1dd 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -177,31 +177,6 @@ ESX.StartDBSync = function() end -ESX.StartPayCheck = function() - - function payCheck() - - local xPlayers = ESX.GetPlayers() - - for i=1, #xPlayers, 1 do - - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - - if xPlayer.job.grade_salary > 0 then - xPlayer.addMoney(xPlayer.job.grade_salary) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) - end - - end - - SetTimeout(Config.PaycheckInterval, payCheck) - - end - - SetTimeout(Config.PaycheckInterval, payCheck) - -end - ESX.GetPlayers = function() local sources = {} diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index e634c744..7985851a 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -305,7 +305,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if itemCount > 0 and sourceItem.count >= itemCount then - if targetItem.limit ~= -1 and (targetItem.count + sourceItem.count) > targetItem.limit then + if targetItem.limit ~= -1 and (targetItem.count + itemCount) > targetItem.limit then TriggerClientEvent('esx:showNotification', target, _U('ex_inv_lim') .. targetXPlayer.name) else sourceXPlayer.removeInventoryItem(itemName, itemCount) diff --git a/resources/[essential]/es_extended/server/paycheck.lua b/resources/[essential]/es_extended/server/paycheck.lua new file mode 100644 index 00000000..f68818a4 --- /dev/null +++ b/resources/[essential]/es_extended/server/paycheck.lua @@ -0,0 +1,24 @@ +ESX.StartPayCheck = function() + + function payCheck() + + local xPlayers = ESX.GetPlayers() + + for i=1, #xPlayers, 1 do + + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer.job.grade_salary > 0 then + xPlayer.addMoney(xPlayer.job.grade_salary) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) + end + + end + + SetTimeout(Config.PaycheckInterval, payCheck) + + end + + SetTimeout(Config.PaycheckInterval, payCheck) + +end \ No newline at end of file From 699c5a820c2e4eba73ca463f3406a071404408b2 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Sat, 2 Sep 2017 10:13:12 -0700 Subject: [PATCH 101/672] added chat help dv, spawn ped Updated en.lua locale for dv, spawn ped --- resources/[essential]/es_extended/locales/en.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua index def2cc5e..6f1c10b4 100644 --- a/resources/[essential]/es_extended/locales/en.lua +++ b/resources/[essential]/es_extended/locales/en.lua @@ -29,7 +29,11 @@ Locales['en'] = { ['play_emote'] = 'play emote', ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', + ['delete_vehicle'] = 'deletes Vehicle', + ['delete_veh_param'] = 'press enter', ['spawn_object'] = 'spawn object', + ['spawn_ped'] = 'spawn ped', + ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'give money', ['money_amount'] = 'amount of money', ['invalid_account'] = 'invalid account', @@ -119,4 +123,4 @@ Locales['en'] = { ['weapon_flashlight'] = 'flashlight', ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', -} \ No newline at end of file +} From abb2d8c828c50e1053d43508857f20f832af7c63 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Sat, 2 Sep 2017 10:15:07 -0700 Subject: [PATCH 102/672] Add chat help dv and spawn ped --- resources/[essential]/es_extended/server/commands.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index 5d0800e7..461af225 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -51,14 +51,14 @@ TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) TriggerClientEvent('esx:deleteVehicle', source) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end) +end, {help = _U('delete_vehicle'), params = {{name = "car", help = _U('delete_veh_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnPed', source, args[2]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end) +end, {help = _U('spawn_ped'), params = {{name = "name", help = _U('spawn_ped_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnObject', source, args[2]) @@ -133,4 +133,4 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) \ No newline at end of file +end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) From e05ff4beb0058658dd781beeda5ff1ee2f3d7026 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Sat, 2 Sep 2017 10:19:31 -0700 Subject: [PATCH 103/672] Update fr.lua --- resources/[essential]/es_extended/locales/fr.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/resources/[essential]/es_extended/locales/fr.lua b/resources/[essential]/es_extended/locales/fr.lua index 02bf1c10..1fb41d49 100644 --- a/resources/[essential]/es_extended/locales/fr.lua +++ b/resources/[essential]/es_extended/locales/fr.lua @@ -29,7 +29,11 @@ Locales['fr'] = { ['play_emote'] = 'jouer emote', ['spawn_car'] = 'spawn un véhicule', ['spawn_car_param'] = 'nom de la voiture', - ['spawn_object'] = 'spawn un objet', + ['delete_vehicle'] = 'supprimer le véhicule', + ['delete_veh_param'] = 'appuyez sur Entrée', + ['spawn_object'] = 'engendre un objet', + ['spawn_ped'] = 'spawn ped', + ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'donner de l\'argent', ['money_amount'] = 'somme d\'argent', ['invalid_account'] = 'compete invalide', @@ -119,4 +123,4 @@ Locales['fr'] = { ['weapon_flashlight'] = 'lampe torche', ['gadget_nightvision'] = 'vision nocturne', ['gadget_parachute'] = 'parachute', -} \ No newline at end of file +} From 9ebca6de88616f58d1d2ac753fccc65f018d1e7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 9 Sep 2017 17:07:57 +0200 Subject: [PATCH 104/672] Clean up repo --- de_es_extended.sql => localization/de_es_extended.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename de_es_extended.sql => localization/de_es_extended.sql (100%) diff --git a/de_es_extended.sql b/localization/de_es_extended.sql similarity index 100% rename from de_es_extended.sql rename to localization/de_es_extended.sql From 960108caf03747ee83ba6c046417bd072fa0ac11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 10 Sep 2017 11:51:05 +0200 Subject: [PATCH 105/672] Add identifier in playerdata --- resources/[essential]/es_extended/server/commands.lua | 2 +- resources/[essential]/es_extended/server/main.lua | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index 461af225..814c6d4a 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -133,4 +133,4 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) +end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) \ No newline at end of file diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index 7985851a..e30ae8ef 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -241,12 +241,13 @@ AddEventHandler('es:playerLoaded', function(source, _player) TriggerEvent('esx:playerLoaded', _source) TriggerClientEvent('esx:playerLoaded', _source, { + identifier = xPlayer.identifier, accounts = xPlayer.getAccounts(), inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), lastPosition = xPlayer.getLastPosition(), - money = xPlayer.player.get('money') + money = xPlayer.get('money') }) xPlayer.player.displayMoney(xPlayer.get('money')) @@ -553,12 +554,13 @@ ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) local xPlayer = ESX.GetPlayerFromId(source) cb({ + identifier = xPlayer.identifier, accounts = xPlayer.getAccounts(), inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), lastPosition = xPlayer.getLastPosition(), - money = xPlayer.player.get('money') + money = xPlayer.get('money') }) end) @@ -568,12 +570,13 @@ ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target local xPlayer = ESX.GetPlayerFromId(target) cb({ + identifier = xPlayer.identifier, accounts = xPlayer.getAccounts(), inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), lastPosition = xPlayer.getLastPosition(), - money = xPlayer.player.get('money') + money = xPlayer.get('money') }) end) From 287b9821d819defcab0b9445b39115ccc252aae2 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Tue, 12 Sep 2017 16:29:15 -0400 Subject: [PATCH 106/672] EN SQL --- localization/en_es_extended.sql | 69 +++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 localization/en_es_extended.sql diff --git a/localization/en_es_extended.sql b/localization/en_es_extended.sql new file mode 100644 index 00000000..f2584874 --- /dev/null +++ b/localization/en_es_extended.sql @@ -0,0 +1,69 @@ +USE `essentialmode`; + +ALTER TABLE `users` + ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, + ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, + ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` +; + +CREATE TABLE `items` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `limit` int(11) NOT NULL DEFAULT '-1', + `rare` int(11) NOT NULL DEFAULT '0', + `can_remove` int(11) NOT NULL DEFAULT '1', + + PRIMARY KEY (`id`) +); + +CREATE TABLE `job_grades` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `job_name` varchar(255) DEFAULT NULL, + `grade` int(11) NOT NULL, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `salary` int(11) NOT NULL, + `skin_male` longtext NOT NULL, + `skin_female` longtext NOT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','Welfare',200,'{}','{}'); + +CREATE TABLE `jobs` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) DEFAULT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `jobs` VALUES (1,'unemployed','Unemployed'); + +CREATE TABLE `user_accounts` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `money` double NOT NULL DEFAULT '0', + + PRIMARY KEY (`id`) +); + +CREATE TABLE `user_inventory` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `item` varchar(255) NOT NULL, + `count` int(11) NOT NULL, + + PRIMARY KEY (`id`) +); From bf80c92a4a6c401eb29d811c0d457ae1d06f8c1b Mon Sep 17 00:00:00 2001 From: Romain Lanz Date: Wed, 13 Sep 2017 22:04:39 +0200 Subject: [PATCH 107/672] feat(loadout): extract loadout loading to his own handler --- resources/[essential]/es_extended/client/main.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 82664623..8263a996 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -89,13 +89,14 @@ AddEventHandler('skinchanger:loadDefaultModel', function() end) AddEventHandler('skinchanger:modelLoaded', function() - while not ESX.PlayerLoaded do Citizen.Wait(0) end - -- Restore loadout + TriggerEvent('esx:restoreLoadout') +end) +AddEventHandler('esx:restoreLoadout', function () local playerPed = GetPlayerPed(-1) for i=1, #ESX.PlayerData.loadout, 1 do @@ -104,7 +105,6 @@ AddEventHandler('skinchanger:modelLoaded', function() end LoadoutLoaded = true - end) RegisterNetEvent('esx:setAccountMoney') @@ -582,4 +582,4 @@ Citizen.CreateThread(function() end end -end) \ No newline at end of file +end) From 7475640ae193a98246137fd04e00a048d72462a3 Mon Sep 17 00:00:00 2001 From: Romain Lanz Date: Thu, 14 Sep 2017 16:23:35 +0200 Subject: [PATCH 108/672] chore(coding-style): correct indentation --- .editorconfig | 9 + es_extended.sql | 32 +- localization/de_es_extended.sql | 32 +- localization/en_es_extended.sql | 32 +- .../[essential]/es_extended/__resource.lua | 87 +- .../[essential]/es_extended/client/common.lua | 4 +- .../es_extended/client/entityiter.lua | 8 +- .../es_extended/client/functions.lua | 1688 ++++++++--------- .../[essential]/es_extended/client/main.lua | 614 +++--- resources/[essential]/es_extended/config.lua | 6 +- .../es_extended/config.weapons.lua | 159 +- resources/[essential]/es_extended/locale.lua | 20 +- .../[essential]/es_extended/locales/br.lua | 242 +-- .../[essential]/es_extended/locales/de.lua | 240 +-- .../[essential]/es_extended/locales/en.lua | 248 +-- .../[essential]/es_extended/locales/fr.lua | 248 +-- .../es_extended/server/classes/player.lua | 720 +++---- .../es_extended/server/commands.lua | 150 +- .../[essential]/es_extended/server/common.lua | 100 +- .../es_extended/server/functions.lua | 268 +-- .../[essential]/es_extended/server/main.lua | 834 ++++---- .../es_extended/server/paycheck.lua | 26 +- 22 files changed, 2887 insertions(+), 2880 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..41c2aaf2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +indent_size = 2 +indent_style = space +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true \ No newline at end of file diff --git a/es_extended.sql b/es_extended.sql index 15ce8398..4c60754b 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,16 +1,16 @@ USE `essentialmode`; -ALTER TABLE `users` - ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, - ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, - ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, - ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, - ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` +ALTER TABLE `users` + ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, + ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, + ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` ; CREATE TABLE `items` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `label` varchar(255) NOT NULL, @@ -22,7 +22,7 @@ CREATE TABLE `items` ( ); CREATE TABLE `job_grades` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `job_name` varchar(255) DEFAULT NULL, `grade` int(11) NOT NULL, @@ -31,39 +31,39 @@ CREATE TABLE `job_grades` ( `salary` int(11) NOT NULL, `skin_male` longtext NOT NULL, `skin_female` longtext NOT NULL, - + PRIMARY KEY (`id`) ); INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','RSA',200,'{}','{}'); CREATE TABLE `jobs` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `label` varchar(255) DEFAULT NULL, - + PRIMARY KEY (`id`) ); INSERT INTO `jobs` VALUES (1,'unemployed','Chômeur'); CREATE TABLE `user_accounts` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `money` double NOT NULL DEFAULT '0', - + PRIMARY KEY (`id`) ); CREATE TABLE `user_inventory` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `item` varchar(255) NOT NULL, `count` int(11) NOT NULL, - + PRIMARY KEY (`id`) ); diff --git a/localization/de_es_extended.sql b/localization/de_es_extended.sql index 9e4add3a..2350a6cd 100644 --- a/localization/de_es_extended.sql +++ b/localization/de_es_extended.sql @@ -1,16 +1,16 @@ USE `essentialmode`; -ALTER TABLE `users` - ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, - ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, - ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, - ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, - ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` +ALTER TABLE `users` + ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, + ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, + ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` ; CREATE TABLE `items` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `label` varchar(255) NOT NULL, @@ -22,7 +22,7 @@ CREATE TABLE `items` ( ); CREATE TABLE `job_grades` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `job_name` varchar(255) DEFAULT NULL, `grade` int(11) NOT NULL, @@ -31,39 +31,39 @@ CREATE TABLE `job_grades` ( `salary` int(11) NOT NULL, `skin_male` longtext NOT NULL, `skin_female` longtext NOT NULL, - + PRIMARY KEY (`id`) ); INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','Arbeitslos',200,'{}','{}'); CREATE TABLE `jobs` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `label` varchar(255) DEFAULT NULL, - + PRIMARY KEY (`id`) ); INSERT INTO `jobs` VALUES (1,'unemployed','Suchend'); CREATE TABLE `user_accounts` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `money` double NOT NULL DEFAULT '0', - + PRIMARY KEY (`id`) ); CREATE TABLE `user_inventory` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `item` varchar(255) NOT NULL, `count` int(11) NOT NULL, - + PRIMARY KEY (`id`) ); diff --git a/localization/en_es_extended.sql b/localization/en_es_extended.sql index f2584874..dcef2c84 100644 --- a/localization/en_es_extended.sql +++ b/localization/en_es_extended.sql @@ -1,16 +1,16 @@ USE `essentialmode`; -ALTER TABLE `users` - ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, - ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, - ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, - ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, - ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` +ALTER TABLE `users` + ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, + ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, + ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` ; CREATE TABLE `items` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `label` varchar(255) NOT NULL, @@ -22,7 +22,7 @@ CREATE TABLE `items` ( ); CREATE TABLE `job_grades` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `job_name` varchar(255) DEFAULT NULL, `grade` int(11) NOT NULL, @@ -31,39 +31,39 @@ CREATE TABLE `job_grades` ( `salary` int(11) NOT NULL, `skin_male` longtext NOT NULL, `skin_female` longtext NOT NULL, - + PRIMARY KEY (`id`) ); INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','Welfare',200,'{}','{}'); CREATE TABLE `jobs` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `label` varchar(255) DEFAULT NULL, - + PRIMARY KEY (`id`) ); INSERT INTO `jobs` VALUES (1,'unemployed','Unemployed'); CREATE TABLE `user_accounts` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, `money` double NOT NULL DEFAULT '0', - + PRIMARY KEY (`id`) ); CREATE TABLE `user_inventory` ( - + `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `item` varchar(255) NOT NULL, `count` int(11) NOT NULL, - + PRIMARY KEY (`id`) ); diff --git a/resources/[essential]/es_extended/__resource.lua b/resources/[essential]/es_extended/__resource.lua index 9557254a..26694ac3 100644 --- a/resources/[essential]/es_extended/__resource.lua +++ b/resources/[essential]/es_extended/__resource.lua @@ -3,69 +3,68 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' server_scripts { - '@async/async.lua', - '@mysql-async/lib/MySQL.lua', - 'config.lua', - 'locale.lua', - 'locales/de.lua', - 'locales/br.lua', - 'locales/fr.lua', - 'locales/en.lua', - 'config.weapons.lua', - 'server/common.lua', - 'server/classes/player.lua', - 'server/functions.lua', - 'server/paycheck.lua', - 'server/main.lua', - 'server/commands.lua' + '@async/async.lua', + '@mysql-async/lib/MySQL.lua', + 'config.lua', + 'locale.lua', + 'locales/de.lua', + 'locales/br.lua', + 'locales/fr.lua', + 'locales/en.lua', + 'config.weapons.lua', + 'server/common.lua', + 'server/classes/player.lua', + 'server/functions.lua', + 'server/paycheck.lua', + 'server/main.lua', + 'server/commands.lua' } client_scripts { - 'config.lua', - 'locale.lua', - 'locales/de.lua', - 'locales/br.lua', - 'locales/fr.lua', - 'locales/en.lua', - 'config.weapons.lua', - 'client/common.lua', - 'client/entityiter.lua', - 'client/functions.lua', - 'client/main.lua' + 'config.lua', + 'locale.lua', + 'locales/de.lua', + 'locales/br.lua', + 'locales/fr.lua', + 'locales/en.lua', + 'config.weapons.lua', + 'client/common.lua', + 'client/entityiter.lua', + 'client/functions.lua', + 'client/main.lua' } ui_page { - 'html/ui.html' + 'html/ui.html' } files { + 'html/ui.html', - 'html/ui.html', - - 'html/css/app.css', + 'html/css/app.css', - 'html/js/mustache.min.js', - 'html/js/app.js', - - 'html/fonts/pdown.ttf', - 'html/fonts/bankgothic.ttf', + 'html/js/mustache.min.js', + 'html/js/app.js', - 'html/img/cursor.png', - 'html/img/keys/enter.png', - 'html/img/keys/return.png', + 'html/fonts/pdown.ttf', + 'html/fonts/bankgothic.ttf', - 'html/img/accounts/bank.png', - 'html/img/accounts/black_money.png' + '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' } exports { - 'getSharedObject' + 'getSharedObject' } server_exports { - 'getSharedObject' + 'getSharedObject' } dependencies { - 'essentialmode' -} \ No newline at end of file + 'essentialmode' +} diff --git a/resources/[essential]/es_extended/client/common.lua b/resources/[essential]/es_extended/client/common.lua index 26c0ed40..14b6a4e6 100644 --- a/resources/[essential]/es_extended/client/common.lua +++ b/resources/[essential]/es_extended/client/common.lua @@ -1,7 +1,7 @@ AddEventHandler('esx:getSharedObject', function(cb) - cb(ESX) + cb(ESX) end) function getSharedObject() - return ESX + return ESX end diff --git a/resources/[essential]/es_extended/client/entityiter.lua b/resources/[essential]/es_extended/client/entityiter.lua index 71e9ee23..7c7ec4d5 100644 --- a/resources/[essential]/es_extended/client/entityiter.lua +++ b/resources/[essential]/es_extended/client/entityiter.lua @@ -41,16 +41,16 @@ local function EnumerateEntities(initFunc, moveFunc, disposeFunc) disposeFunc(iter) return end - + local enum = {handle = iter, destructor = disposeFunc} setmetatable(enum, entityEnumerator) - + local next = true repeat coroutine.yield(id) next, id = moveFunc(iter) until not next - + enum.destructor, enum.handle = nil, nil disposeFunc(iter) end) @@ -76,4 +76,4 @@ end for ped in EnumeratePeds() do end -]] \ No newline at end of file +]] diff --git a/resources/[essential]/es_extended/client/functions.lua b/resources/[essential]/es_extended/client/functions.lua index 7c6eb4b8..6729f0da 100644 --- a/resources/[essential]/es_extended/client/functions.lua +++ b/resources/[essential]/es_extended/client/functions.lua @@ -20,7 +20,7 @@ ESX.Game = {} ESX.Game.Utils = {} ESX.GetConfig = function() - return Config + return Config end ESX.GetRandomString = function(length) @@ -32,368 +32,368 @@ ESX.GetRandomString = function(length) else return '' end - + end ESX.SetTimeout = function(msec, cb) - table.insert(ESX.TimeoutCallbacks, { - time = GetGameTimer() + msec, - cb = cb - }) - return #ESX.TimeoutCallbacks + table.insert(ESX.TimeoutCallbacks, { + time = GetGameTimer() + msec, + cb = cb + }) + return #ESX.TimeoutCallbacks end ESX.ClearTimeout = function(i) - ESX.TimeoutCallbacks[i] = nil + ESX.TimeoutCallbacks[i] = nil end ESX.IsPlayerLoaded = function() - return ESX.PlayerLoaded + return ESX.PlayerLoaded end ESX.GetPlayerData = function() - return ESX.PlayerData + return ESX.PlayerData end ESX.SetPlayerData = function(key, val) - ESX.PlayerData[key] = val + ESX.PlayerData[key] = val end ESX.ShowNotification = function(msg) - SetNotificationTextEntry('STRING') - AddTextComponentString(msg) - DrawNotification(0,1) + SetNotificationTextEntry('STRING') + AddTextComponentString(msg) + DrawNotification(0,1) end ESX.TriggerServerCallback = function(name, cb, ...) - - ESX.ServerCallbacks[ESX.CurrentRequestId] = cb - - TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, ...) - - if ESX.CurrentRequestId < 65535 then - ESX.CurrentRequestId = ESX.CurrentRequestId + 1 - else - ESX.CurrentRequestId = 0 - end + + ESX.ServerCallbacks[ESX.CurrentRequestId] = cb + + TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, ...) + + 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 - }) + SendNUIMessage({ + action = 'setHUDDisplay', + opacity = opacity + }) end ESX.UI.HUD.RegisterElement = function(name, index, priority, html, data) - local found = false + 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 + 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 + if found then + return + end - table.insert(ESX.UI.HUD.RegisteredElements, name) + table.insert(ESX.UI.HUD.RegisteredElements, name) - SendNUIMessage({ - action = 'insertHUDElement', - name = name, - index = index, - priority = priority, - html = html, - data = data, - }) + SendNUIMessage({ + action = 'insertHUDElement', + name = name, + index = index, + priority = priority, + html = html, + data = data, + }) - ESX.UI.HUD.UpdateElement(name, 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 + 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 - }) + SendNUIMessage({ + action = 'deleteHUDElement', + name = name + }) end ESX.UI.HUD.UpdateElement = function(name, data) - SendNUIMessage({ - action = 'updateHUDElement', - name = name, - data = 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, - } + ESX.UI.Menu.RegisteredTypes[type] = { + open = open, + close = close, + } end local _type = type ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, close) - - 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 + local menu = {} - if ESX.UI.Menu.Opened[i] ~= nil then - 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 + menu.type = type + menu.namespace = namespace + menu.name = name + menu.data = data + menu.submit = submit + menu.cancel = cancel + menu.change = change - end + menu.close = function() - if close ~= nil then - close() - end + ESX.UI.Menu.RegisteredTypes[type].close(namespace, name) - end + for i=1, #ESX.UI.Menu.Opened, 1 do - menu.update = function(query, newData) + if ESX.UI.Menu.Opened[i] ~= nil then + 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 - for i=1, #menu.data.elements, 1 do - - local match = true + end - for k,v in pairs(query) do - if menu.data.elements[i][k] ~= v then - match = false - end - end + if close ~= nil then + close() + end - if match then - for k,v in pairs(newData) do - menu.data.elements[i][k] = v - end - end + end - end + menu.update = function(query, newData) - end + for i=1, #menu.data.elements, 1 do - menu.refresh = function() - ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data) - end + local match = true - menu.setElement = function(i, key, val) - menu.data.elements[i][key] = val - end + for k,v in pairs(query) do + if menu.data.elements[i][k] ~= v then + match = false + end + end - table.insert(ESX.UI.Menu.Opened, menu) + 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, data) + end - return menu + end + + menu.refresh = function() + ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data) + 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) + + return menu end ESX.UI.Menu.Close = function(type, namespace, name) - - for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then - 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 + + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i] ~= nil then + 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 end ESX.UI.Menu.CloseAll = function() - - for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then - ESX.UI.Menu.Opened[i].close() - ESX.UI.Menu.Opened[i] = nil - end - end + + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i] ~= nil then + ESX.UI.Menu.Opened[i].close() + ESX.UI.Menu.Opened[i] = nil + end + 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] ~= nil then - 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 + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i] ~= nil then + 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 end ESX.UI.Menu.IsOpen = function(type, namespace, name) - return ESX.UI.Menu.GetOpened(type, namespace, name) ~= nil + 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 - }) + SendNUIMessage({ + action = 'inventoryNotification', + add = add, + item = item, + count = count + }) end ESX.GetWeaponList = function() - return Config.Weapons + 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 + + 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.Teleport = function(entity, coords, cb) - - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - - while not HasCollisionLoadedAroundEntity(entity) do - RequestCollisionAtCoord(coords.x, coords.x, coords.x) - Citizen.Wait(0) - end - SetEntityCoords(entity, coords.x, coords.y, coords.z) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) - if cb ~= nil then - cb() - end + while not HasCollisionLoadedAroundEntity(entity) do + RequestCollisionAtCoord(coords.x, coords.x, coords.x) + Citizen.Wait(0) + end + + SetEntityCoords(entity, coords.x, coords.y, coords.z) + + if cb ~= nil then + cb() + end end ESX.Game.SpawnObject = function(model, coords, cb) - local model = (type(model) == 'number' and model or GetHashKey(model)) + local model = (type(model) == 'number' and model or GetHashKey(model)) - Citizen.CreateThread(function() + Citizen.CreateThread(function() - RequestModel(model) + RequestModel(model) - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - local obj = CreateObject(model, coords.x, coords.y, coords.z, true, true, true) + local obj = CreateObject(model, coords.x, coords.y, coords.z, true, true, true) - if cb ~= nil then - cb(obj) - end + if cb ~= nil then + cb(obj) + end - end) + end) end ESX.Game.SpawnLocalObject = function(model, coords, cb) - local model = (type(model) == 'number' and model or GetHashKey(model)) + local model = (type(model) == 'number' and model or GetHashKey(model)) - Citizen.CreateThread(function() + Citizen.CreateThread(function() - RequestModel(model) + RequestModel(model) - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - local obj = CreateObject(model, coords.x, coords.y, coords.z, false, true, true) + local obj = CreateObject(model, coords.x, coords.y, coords.z, false, true, true) - if cb ~= nil then - cb(obj) - end + if cb ~= nil then + cb(obj) + end - end) + end) end ESX.Game.DeleteVehicle = function(vehicle) - SetEntityAsMissionEntity(vehicle, false, true) - DeleteVehicle(vehicle) + SetEntityAsMissionEntity(vehicle, false, true) + DeleteVehicle(vehicle) end ESX.Game.DeleteObject = function(object) - SetEntityAsMissionEntity(object, false, true) - DeleteObject(object) + SetEntityAsMissionEntity(object, false, true) + DeleteObject(object) end ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) - Citizen.CreateThread(function() + Citizen.CreateThread(function() - RequestModel(model) + RequestModel(model) - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) - local id = NetworkGetNetworkIdFromEntity(vehicle) + local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) + local id = NetworkGetNetworkIdFromEntity(vehicle) - SetNetworkIdCanMigrate(id, true) - SetEntityAsMissionEntity(vehicle, true, false) - SetVehicleHasBeenOwnedByPlayer(vehicle, true) - SetModelAsNoLongerNeeded(model) + SetNetworkIdCanMigrate(id, true) + SetEntityAsMissionEntity(vehicle, true, false) + 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 + RequestCollisionAtCoord(coords.x, coords.y, coords.z) - if cb ~= nil then - cb(vehicle) - end + while not HasCollisionLoadedAroundEntity(vehicle) do + RequestCollisionAtCoord(coords.x, coords.x, coords.x) + Citizen.Wait(0) + end - end) + if cb ~= nil then + cb(vehicle) + end + + end) end @@ -401,632 +401,632 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) - Citizen.CreateThread(function() + Citizen.CreateThread(function() - RequestModel(model) + RequestModel(model) - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) + local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) - SetEntityAsMissionEntity(vehicle, true, false) - SetVehicleHasBeenOwnedByPlayer(vehicle, true) - SetModelAsNoLongerNeeded(model) + SetEntityAsMissionEntity(vehicle, true, false) + 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 + RequestCollisionAtCoord(coords.x, coords.y, coords.z) - if cb ~= nil then - cb(vehicle) - end + while not HasCollisionLoadedAroundEntity(vehicle) do + RequestCollisionAtCoord(coords.x, coords.x, coords.x) + Citizen.Wait(0) + end - end) + if cb ~= nil then + cb(vehicle) + end + + end) end ESX.Game.GetObjects = function() - local objects = {} + local objects = {} - for object in EnumerateObjects() do - table.insert(objects, object) - end + for object in EnumerateObjects() do + table.insert(objects, object) + end - return objects + return objects end ESX.Game.GetClosestObject = function(filter, coords) - - local objects = ESX.Game.GetObjects() - local closestDistance = -1 - local closestObject = -1 - local filter = filter - local coords = coords - if type(filter) == 'string' then - if filter ~= '' then - filter = {filter} - end - end + local objects = ESX.Game.GetObjects() + local closestDistance = -1 + local closestObject = -1 + local filter = filter + local coords = coords - if coords == nil then - local playerPed = GetPlayerPed(-1) - coords = GetEntityCoords(playerPed) - end + if type(filter) == 'string' then + if filter ~= '' then + filter = {filter} + end + end - for i=1, #objects, 1 do - - local foundObject = false + if coords == nil then + local playerPed = GetPlayerPed(-1) + coords = GetEntityCoords(playerPed) + end - if filter == nil or (type(filter) == 'table' and #filter == 0) then - foundObject = true - else + for i=1, #objects, 1 do - local objectModel = GetEntityModel(objects[i]) + local foundObject = false - for j=1, #filter, 1 do - if objectModel == GetHashKey(filter[j]) then - foundObject = true - end - end + if filter == nil or (type(filter) == 'table' and #filter == 0) then + foundObject = true + else - end + local objectModel = GetEntityModel(objects[i]) - if foundObject then + for j=1, #filter, 1 do + if objectModel == GetHashKey(filter[j]) then + foundObject = true + end + end - local objectCoords = GetEntityCoords(objects[i]) - local distance = GetDistanceBetweenCoords(objectCoords.x, objectCoords.y, objectCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestObject = objects[i] - closestDistance = distance - end + end - end + if foundObject then - end - - return closestObject, closestDistance + local objectCoords = GetEntityCoords(objects[i]) + local distance = GetDistanceBetweenCoords(objectCoords.x, objectCoords.y, objectCoords.z, coords.x, coords.y, coords.z, true) + + if closestDistance == -1 or closestDistance > distance then + closestObject = objects[i] + closestDistance = distance + end + + end + + end + + return closestObject, closestDistance end ESX.Game.GetPlayers = function() - - local maxPlayers = Config.MaxPlayers - local players = {} - for i=0, maxPlayers, 1 do + local maxPlayers = Config.MaxPlayers + local players = {} - local ped = GetPlayerPed(i) + for i=0, maxPlayers, 1 do - if DoesEntityExist(ped) then - table.insert(players, i) - end - end + local ped = GetPlayerPed(i) - return players + if DoesEntityExist(ped) then + table.insert(players, i) + end + end + + return players end ESX.Game.GetClosestPlayer = function(coords) - - local players = ESX.Game.GetPlayers() - local closestDistance = -1 - local closestPlayer = -1 - local coords = coords - local usePlayerPed = false - local playerPed = GetPlayerPed(-1) - local playerId = PlayerId() - if coords == nil then - usePlayerPed = true - coords = GetEntityCoords(playerPed) - end + local players = ESX.Game.GetPlayers() + local closestDistance = -1 + local closestPlayer = -1 + local coords = coords + local usePlayerPed = false + local playerPed = GetPlayerPed(-1) + local playerId = PlayerId() - for i=1, #players, 1 do - - local target = GetPlayerPed(players[i]) - - if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then - - local targetCoords = GetEntityCoords(target) - local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestPlayer = players[i] - closestDistance = distance - end + if coords == nil then + usePlayerPed = true + coords = GetEntityCoords(playerPed) + end - end + for i=1, #players, 1 do - end - - return closestPlayer, closestDistance + local target = GetPlayerPed(players[i]) + + if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then + + local targetCoords = GetEntityCoords(target) + local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.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 + local players = ESX.Game.GetPlayers() + local playersInArea = {} - end - - return 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.GetVehicles = function() - local vehicles = {} + local vehicles = {} - for vehicle in EnumerateVehicles() do - table.insert(vehicles, vehicle) - end + for vehicle in EnumerateVehicles() do + table.insert(vehicles, vehicle) + end - return vehicles + return vehicles end ESX.Game.GetClosestVehicle = function(coords) - - local vehicles = ESX.Game.GetVehicles() - local closestDistance = -1 - local closestVehicle = -1 - local coords = coords - if coords == nil then - local playerPed = GetPlayerPed(-1) - coords = GetEntityCoords(playerPed) - end + local vehicles = ESX.Game.GetVehicles() + local closestDistance = -1 + local closestVehicle = -1 + local coords = coords - for i=1, #vehicles, 1 do - - local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestVehicle = vehicles[i] - closestDistance = distance - end + if coords == nil then + local playerPed = GetPlayerPed(-1) + coords = GetEntityCoords(playerPed) + end - end - - return closestVehicle, closestDistance + for i=1, #vehicles, 1 do + + local vehicleCoords = GetEntityCoords(vehicles[i]) + local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) + + if closestDistance == -1 or closestDistance > distance then + closestVehicle = vehicles[i] + closestDistance = distance + end + + end + + return closestVehicle, closestDistance end ESX.Game.GetVehiclesInArea = function(coords, area) - - local vehicles = ESX.Game.GetVehicles() - local vehiclesInArea = {} - - for i=1, #vehicles, 1 do - - local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) - if distance <= area then - table.insert(vehiclesInArea, vehicles[i]) - end + local vehicles = ESX.Game.GetVehicles() + local vehiclesInArea = {} - end - - return vehiclesInArea + for i=1, #vehicles, 1 do + + local vehicleCoords = GetEntityCoords(vehicles[i]) + local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) + + if distance <= area then + table.insert(vehiclesInArea, vehicles[i]) + end + + end + + return vehiclesInArea end ESX.Game.GetPeds = function(ignoreList) - - local ignoreList = ignoreList or {} - local peds = {} - for ped in EnumeratePeds() do - - local found = false + local ignoreList = ignoreList or {} + local peds = {} - for j=1, #ignoreList, 1 do - if ignoreList[j] == ped then - found = true - end - end + for ped in EnumeratePeds() do - if not found then - table.insert(peds, ped) - end + local found = false - end + for j=1, #ignoreList, 1 do + if ignoreList[j] == ped then + found = true + end + end - return peds + if not found then + table.insert(peds, ped) + end + + end + + return peds end ESX.Game.GetClosestPed = function(coords, ignoreList) - local ignoreList = ignoreList or {} - local peds = ESX.Game.GetPeds(ignoreList) - local closestDistance = -1 - local closestPed = -1 + local ignoreList = ignoreList or {} + local peds = ESX.Game.GetPeds(ignoreList) + local closestDistance = -1 + local closestPed = -1 - for i=1, #peds, 1 do - - local pedCoords = GetEntityCoords(peds[i]) - local distance = GetDistanceBetweenCoords(pedCoords.x, pedCoords.y, pedCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestPed = peds[i] - closestDistance = distance - end + for i=1, #peds, 1 do - end - - return closestPed, closestDistance + local pedCoords = GetEntityCoords(peds[i]) + local distance = GetDistanceBetweenCoords(pedCoords.x, pedCoords.y, pedCoords.z, coords.x, coords.y, coords.z, true) + + if closestDistance == -1 or closestDistance > distance then + closestPed = peds[i] + closestDistance = distance + end + + end + + return closestPed, closestDistance end ESX.Game.GetVehicleProperties = function(vehicle) - local color1, color2 = GetVehicleColours(vehicle) - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - - return { - - model = GetEntityModel(vehicle), - - plate = GetVehicleNumberPlateText(vehicle), - plateIndex = GetVehicleNumberPlateTextIndex(vehicle), + local color1, color2 = GetVehicleColours(vehicle) + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - health = GetEntityHealth(vehicle), - dirtLevel = GetVehicleDirtLevel(vehicle), + return { - color1 = color1, - color2 = color2, + model = GetEntityModel(vehicle), - pearlescentColor = pearlescentColor, - wheelColor = wheelColor, - - wheels = GetVehicleWheelType(vehicle), - windowTint = GetVehicleWindowTint(vehicle), - - neonEnabled = { - IsVehicleNeonLightEnabled(vehicle, 0), - IsVehicleNeonLightEnabled(vehicle, 1), - IsVehicleNeonLightEnabled(vehicle, 2), - IsVehicleNeonLightEnabled(vehicle, 3), - }, + plate = GetVehicleNumberPlateText(vehicle), + plateIndex = GetVehicleNumberPlateTextIndex(vehicle), - neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), - tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(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), + health = GetEntityHealth(vehicle), + dirtLevel = GetVehicleDirtLevel(vehicle), - modEngine = GetVehicleMod(vehicle, 11), - modBrakes = GetVehicleMod(vehicle, 12), - modTransmission = GetVehicleMod(vehicle, 13), - modHorns = GetVehicleMod(vehicle, 14), - modSuspension = GetVehicleMod(vehicle, 15), - modArmor = GetVehicleMod(vehicle, 16), + color1 = color1, + color2 = color2, - modTurbo = IsToggleModOn(vehicle, 18), - modSmokeEnabled = IsToggleModOn(vehicle, 20), - modXenon = IsToggleModOn(vehicle, 22), + pearlescentColor = pearlescentColor, + wheelColor = wheelColor, - modFrontWheels = GetVehicleMod(vehicle, 23), - modBackWheels = GetVehicleMod(vehicle, 24), + wheels = GetVehicleWheelType(vehicle), + windowTint = GetVehicleWindowTint(vehicle), - modPlateHolder = GetVehicleMod(vehicle, 25), - modVanityPlate = GetVehicleMod(vehicle, 26), - modTrimA = GetVehicleMod(vehicle, 27), - modOrnaments = GetVehicleMod(vehicle, 28), - modDashboard = GetVehicleMod(vehicle, 29), - modDial = GetVehicleMod(vehicle, 30), - modDoorSpeaker = GetVehicleMod(vehicle, 31), - modSeats = GetVehicleMod(vehicle, 32), - modSteeringWheel = GetVehicleMod(vehicle, 33), - modShifterLeavers = GetVehicleMod(vehicle, 34), - modAPlate = GetVehicleMod(vehicle, 35), - modSpeakers = GetVehicleMod(vehicle, 36), - modTrunk = GetVehicleMod(vehicle, 37), - modHydrolic = GetVehicleMod(vehicle, 38), - modEngineBlock = GetVehicleMod(vehicle, 39), - modAirFilter = GetVehicleMod(vehicle, 40), - modStruts = GetVehicleMod(vehicle, 41), - modArchCover = GetVehicleMod(vehicle, 42), - modAerials = GetVehicleMod(vehicle, 43), - modTrimB = GetVehicleMod(vehicle, 44), - modTank = GetVehicleMod(vehicle, 45), - modWindows = GetVehicleMod(vehicle, 46), - modLivery = GetVehicleMod(vehicle, 48) - } + neonEnabled = { + IsVehicleNeonLightEnabled(vehicle, 0), + IsVehicleNeonLightEnabled(vehicle, 1), + IsVehicleNeonLightEnabled(vehicle, 2), + IsVehicleNeonLightEnabled(vehicle, 3), + }, + + neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(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), + modSmokeEnabled = IsToggleModOn(vehicle, 20), + modXenon = IsToggleModOn(vehicle, 22), + + modFrontWheels = GetVehicleMod(vehicle, 23), + modBackWheels = GetVehicleMod(vehicle, 24), + + modPlateHolder = GetVehicleMod(vehicle, 25), + modVanityPlate = GetVehicleMod(vehicle, 26), + modTrimA = GetVehicleMod(vehicle, 27), + modOrnaments = GetVehicleMod(vehicle, 28), + modDashboard = GetVehicleMod(vehicle, 29), + modDial = GetVehicleMod(vehicle, 30), + modDoorSpeaker = GetVehicleMod(vehicle, 31), + modSeats = GetVehicleMod(vehicle, 32), + modSteeringWheel = GetVehicleMod(vehicle, 33), + modShifterLeavers = GetVehicleMod(vehicle, 34), + modAPlate = GetVehicleMod(vehicle, 35), + modSpeakers = GetVehicleMod(vehicle, 36), + modTrunk = GetVehicleMod(vehicle, 37), + modHydrolic = GetVehicleMod(vehicle, 38), + modEngineBlock = GetVehicleMod(vehicle, 39), + modAirFilter = GetVehicleMod(vehicle, 40), + modStruts = GetVehicleMod(vehicle, 41), + modArchCover = GetVehicleMod(vehicle, 42), + modAerials = GetVehicleMod(vehicle, 43), + modTrimB = GetVehicleMod(vehicle, 44), + modTank = GetVehicleMod(vehicle, 45), + modWindows = GetVehicleMod(vehicle, 46), + modLivery = GetVehicleMod(vehicle, 48) + } end ESX.Game.SetVehicleProperties = function(vehicle, props) - SetVehicleModKit(vehicle, 0) + SetVehicleModKit(vehicle, 0) - if props.plate ~= nil then - SetVehicleNumberPlateText(vehicle, props.plate) - end + if props.plate ~= nil then + SetVehicleNumberPlateText(vehicle, props.plate) + end - if props.plateIndex ~= nil then - SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) - end + if props.plateIndex ~= nil then + SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) + end - if props.health ~= nil then - SetEntityHealth(vehicle, props.health) - end + if props.health ~= nil then + SetEntityHealth(vehicle, props.health) + end - if props.dirtLevel ~= nil then - SetVehicleDirtLevel(vehicle, props.dirtLevel) - end + if props.dirtLevel ~= nil then + SetVehicleDirtLevel(vehicle, props.dirtLevel) + end - if props.color1 ~= nil then - local color1, color2 = GetVehicleColours(vehicle) - SetVehicleColours(vehicle, props.color1, color2) - end + if props.color1 ~= nil then + local color1, color2 = GetVehicleColours(vehicle) + SetVehicleColours(vehicle, props.color1, color2) + end - if props.color2 ~= nil then - local color1, color2 = GetVehicleColours(vehicle) - SetVehicleColours(vehicle, color1, props.color2) - end + if props.color2 ~= nil then + local color1, color2 = GetVehicleColours(vehicle) + SetVehicleColours(vehicle, color1, props.color2) + end - if props.pearlescentColor ~= nil then - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) - end + if props.pearlescentColor ~= nil then + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) + end - if props.wheelColor ~= nil then - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) - end + if props.wheelColor ~= nil then + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) + end - if props.wheels ~= nil then - SetVehicleWheelType(vehicle, props.wheels) - end + if props.wheels ~= nil then + SetVehicleWheelType(vehicle, props.wheels) + end - if props.windowTint ~= nil then - SetVehicleWindowTint(vehicle, props.windowTint) - end + if props.windowTint ~= nil then + SetVehicleWindowTint(vehicle, props.windowTint) + end - if props.neonEnabled ~= nil then - SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) - SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) - SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) - SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) - end + if props.neonEnabled ~= nil then + SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) + SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) + SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) + SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) + end - if props.neonColor ~= nil then - SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) - end + if props.neonColor ~= nil then + SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) + end - if props.modSmokeEnabled ~= nil then - ToggleVehicleMod(vehicle, 20, true) - end + if props.modSmokeEnabled ~= nil then + ToggleVehicleMod(vehicle, 20, true) + end - if props.tyreSmokeColor ~= nil then - SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) - end - - if props.modSpoilers ~= nil then - SetVehicleMod(vehicle, 0, props.modSpoilers, false) - end + if props.tyreSmokeColor ~= nil then + SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) + end - if props.modFrontBumper ~= nil then - SetVehicleMod(vehicle, 1, props.modFrontBumper, false) - end + if props.modSpoilers ~= nil then + SetVehicleMod(vehicle, 0, props.modSpoilers, false) + end - if props.modRearBumper ~= nil then - SetVehicleMod(vehicle, 2, props.modRearBumper, false) - end + if props.modFrontBumper ~= nil then + SetVehicleMod(vehicle, 1, props.modFrontBumper, false) + end - if props.modSideSkirt ~= nil then - SetVehicleMod(vehicle, 3, props.modSideSkirt, false) - end + if props.modRearBumper ~= nil then + SetVehicleMod(vehicle, 2, props.modRearBumper, false) + end - if props.modExhaust ~= nil then - SetVehicleMod(vehicle, 4, props.modExhaust, false) - end + if props.modSideSkirt ~= nil then + SetVehicleMod(vehicle, 3, props.modSideSkirt, false) + end - if props.modFrame ~= nil then - SetVehicleMod(vehicle, 5, props.modFrame, false) - end + if props.modExhaust ~= nil then + SetVehicleMod(vehicle, 4, props.modExhaust, false) + end - if props.modGrille ~= nil then - SetVehicleMod(vehicle, 6, props.modGrille, false) - end + if props.modFrame ~= nil then + SetVehicleMod(vehicle, 5, props.modFrame, false) + end - if props.modHood ~= nil then - SetVehicleMod(vehicle, 7, props.modHood, false) - end + if props.modGrille ~= nil then + SetVehicleMod(vehicle, 6, props.modGrille, false) + end - if props.modFender ~= nil then - SetVehicleMod(vehicle, 8, props.modFender, false) - end + if props.modHood ~= nil then + SetVehicleMod(vehicle, 7, props.modHood, false) + end - if props.modRightFender ~= nil then - SetVehicleMod(vehicle, 9, props.modRightFender, false) - end + if props.modFender ~= nil then + SetVehicleMod(vehicle, 8, props.modFender, false) + end - if props.modRoof ~= nil then - SetVehicleMod(vehicle, 10, props.modRoof, false) - end + if props.modRightFender ~= nil then + SetVehicleMod(vehicle, 9, props.modRightFender, false) + end - if props.modEngine ~= nil then - SetVehicleMod(vehicle, 11, props.modEngine, false) - end + if props.modRoof ~= nil then + SetVehicleMod(vehicle, 10, props.modRoof, false) + end - if props.modBrakes ~= nil then - SetVehicleMod(vehicle, 12, props.modBrakes, false) - end + if props.modEngine ~= nil then + SetVehicleMod(vehicle, 11, props.modEngine, false) + end - if props.modTransmission ~= nil then - SetVehicleMod(vehicle, 13, props.modTransmission, false) - end + if props.modBrakes ~= nil then + SetVehicleMod(vehicle, 12, props.modBrakes, false) + end - if props.modHorns ~= nil then - SetVehicleMod(vehicle, 14, props.modHorns, false) - end + if props.modTransmission ~= nil then + SetVehicleMod(vehicle, 13, props.modTransmission, false) + end - if props.modSuspension ~= nil then - SetVehicleMod(vehicle, 15, props.modSuspension, false) - end + if props.modHorns ~= nil then + SetVehicleMod(vehicle, 14, props.modHorns, false) + end - if props.modArmor ~= nil then - SetVehicleMod(vehicle, 16, props.modArmor, false) - end + if props.modSuspension ~= nil then + SetVehicleMod(vehicle, 15, props.modSuspension, false) + end - if props.modTurbo ~= nil then - ToggleVehicleMod(vehicle, 18, props.modTurbo) - end + if props.modArmor ~= nil then + SetVehicleMod(vehicle, 16, props.modArmor, false) + end - if props.modXenon ~= nil then - ToggleVehicleMod(vehicle, 22, props.modXenon) - end + if props.modTurbo ~= nil then + ToggleVehicleMod(vehicle, 18, props.modTurbo) + end - if props.modFrontWheels ~= nil then - SetVehicleMod(vehicle, 23, props.modFrontWheels, false) - end + if props.modXenon ~= nil then + ToggleVehicleMod(vehicle, 22, props.modXenon) + end - if props.modBackWheels ~= nil then - SetVehicleMod(vehicle, 24, props.modBackWheels, false) - end + if props.modFrontWheels ~= nil then + SetVehicleMod(vehicle, 23, props.modFrontWheels, false) + end - if props.modPlateHolder ~= nil then - SetVehicleMod(vehicle, 25, props.modPlateHolder , false) - end + if props.modBackWheels ~= nil then + SetVehicleMod(vehicle, 24, props.modBackWheels, false) + end - if props.modVanityPlate ~= nil then - SetVehicleMod(vehicle, 26, props.modVanityPlate , false) - end + if props.modPlateHolder ~= nil then + SetVehicleMod(vehicle, 25, props.modPlateHolder , false) + end - if props.modTrimA ~= nil then - SetVehicleMod(vehicle, 27, props.modTrimA , false) - end + if props.modVanityPlate ~= nil then + SetVehicleMod(vehicle, 26, props.modVanityPlate , false) + end - if props.modOrnaments ~= nil then - SetVehicleMod(vehicle, 28, props.modOrnaments , false) - end + if props.modTrimA ~= nil then + SetVehicleMod(vehicle, 27, props.modTrimA , false) + end - if props.modDashboard ~= nil then - SetVehicleMod(vehicle, 29, props.modDashboard , false) - end + if props.modOrnaments ~= nil then + SetVehicleMod(vehicle, 28, props.modOrnaments , false) + end - if props.modDial ~= nil then - SetVehicleMod(vehicle, 30, props.modDial , false) - end + if props.modDashboard ~= nil then + SetVehicleMod(vehicle, 29, props.modDashboard , false) + end - if props.modDoorSpeaker ~= nil then - SetVehicleMod(vehicle, 31, props.modDoorSpeaker , false) - end + if props.modDial ~= nil then + SetVehicleMod(vehicle, 30, props.modDial , false) + end - if props.modSeats ~= nil then - SetVehicleMod(vehicle, 32, props.modSeats , false) - end + if props.modDoorSpeaker ~= nil then + SetVehicleMod(vehicle, 31, props.modDoorSpeaker , false) + end - if props.modSteeringWheel ~= nil then - SetVehicleMod(vehicle, 33, props.modSteeringWheel , false) - end + if props.modSeats ~= nil then + SetVehicleMod(vehicle, 32, props.modSeats , false) + end - if props.modShifterLeavers ~= nil then - SetVehicleMod(vehicle, 34, props.modShifterLeavers , false) - end + if props.modSteeringWheel ~= nil then + SetVehicleMod(vehicle, 33, props.modSteeringWheel , false) + end - if props.modAPlate ~= nil then - SetVehicleMod(vehicle, 35, props.modAPlate , false) - end + if props.modShifterLeavers ~= nil then + SetVehicleMod(vehicle, 34, props.modShifterLeavers , false) + end - if props.modSpeakers ~= nil then - SetVehicleMod(vehicle, 36, props.modSpeakers , false) - end + if props.modAPlate ~= nil then + SetVehicleMod(vehicle, 35, props.modAPlate , false) + end - if props.modTrunk ~= nil then - SetVehicleMod(vehicle, 37, props.modTrunk , false) - end + if props.modSpeakers ~= nil then + SetVehicleMod(vehicle, 36, props.modSpeakers , false) + end - if props.modHydrolic ~= nil then - SetVehicleMod(vehicle, 38, props.modHydrolic , false) - end + if props.modTrunk ~= nil then + SetVehicleMod(vehicle, 37, props.modTrunk , false) + end - if props.modEngineBlock ~= nil then - SetVehicleMod(vehicle, 39, props.modEngineBlock , false) - end + if props.modHydrolic ~= nil then + SetVehicleMod(vehicle, 38, props.modHydrolic , false) + end - if props.modAirFilter ~= nil then - SetVehicleMod(vehicle, 40, props.modAirFilter , false) - end + if props.modEngineBlock ~= nil then + SetVehicleMod(vehicle, 39, props.modEngineBlock , false) + end - if props.modStruts ~= nil then - SetVehicleMod(vehicle, 41, props.modStruts , false) - end + if props.modAirFilter ~= nil then + SetVehicleMod(vehicle, 40, props.modAirFilter , false) + end - if props.modArchCover ~= nil then - SetVehicleMod(vehicle, 42, props.modArchCover , false) - end + if props.modStruts ~= nil then + SetVehicleMod(vehicle, 41, props.modStruts , false) + end - if props.modAerials ~= nil then - SetVehicleMod(vehicle, 43, props.modAerials , false) - end + if props.modArchCover ~= nil then + SetVehicleMod(vehicle, 42, props.modArchCover , false) + end - if props.modTrimB ~= nil then - SetVehicleMod(vehicle, 44, props.modTrimB , false) - end + if props.modAerials ~= nil then + SetVehicleMod(vehicle, 43, props.modAerials , false) + end - if props.modTank ~= nil then - SetVehicleMod(vehicle, 45, props.modTank , false) - end + if props.modTrimB ~= nil then + SetVehicleMod(vehicle, 44, props.modTrimB , false) + end - if props.modWindows ~= nil then - SetVehicleMod(vehicle, 46, props.modWindows , false) - end - - if props.modLivery ~= nil then - SetVehicleMod(vehicle, 48, props.modLivery , false) - end + if props.modTank ~= nil then + SetVehicleMod(vehicle, 45, props.modTank , false) + end + + if props.modWindows ~= nil then + SetVehicleMod(vehicle, 46, props.modWindows , false) + end + + if props.modLivery ~= nil then + SetVehicleMod(vehicle, 48, props.modLivery , false) + end end ESX.Game.Utils.DrawText3D = function(coords, text, size) - + local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) local camCoords = GetGameplayCamCoords() local dist = GetDistanceBetweenCoords(camCoords.x, camCoords.y, camCoords.z, coords.x, coords.y, coords.z, 1) local size = size if size == nil then - size = 1 + size = 1 end local scale = (size / dist) * 2 local fov = (1 / GetGameplayCamFov()) * 100 local scale = scale * fov - + if onScreen then - + SetTextScale(0.0 * scale, 0.55 * scale) SetTextFont(0) SetTextProportional(1) @@ -1037,9 +1037,9 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size) SetTextOutline() SetTextEntry('STRING') SetTextCentre(1) - + AddTextComponentString(text) - + DrawText(x, y) end @@ -1047,239 +1047,239 @@ end ESX.ShowInventory = function() - local playerPed = GetPlayerPed(-1) - local elements = {} + local playerPed = GetPlayerPed(-1) + local elements = {} - table.insert(elements, { - label = '[Cash] $' .. ESX.PlayerData.money, - count = ESX.PlayerData.money, - type = 'item_money', - value = 'money', - usable = false, - rare = false, - canRemove = true - }) + table.insert(elements, { + label = '[Cash] $' .. ESX.PlayerData.money, + count = ESX.PlayerData.money, + type = 'item_money', + value = 'money', + usable = false, + rare = false, + canRemove = true + }) - for i=1, #ESX.PlayerData.accounts, 1 do - table.insert(elements, { - label = '[' .. ESX.PlayerData.accounts[i].label .. '] $' .. ESX.PlayerData.accounts[i].money, - count = ESX.PlayerData.accounts[i].money, - type = 'item_account', - value = ESX.PlayerData.accounts[i].name, - usable = false, - rare = false, - canRemove = true - }) - end + for i=1, #ESX.PlayerData.accounts, 1 do + table.insert(elements, { + label = '[' .. ESX.PlayerData.accounts[i].label .. '] $' .. ESX.PlayerData.accounts[i].money, + count = ESX.PlayerData.accounts[i].money, + type = 'item_account', + value = ESX.PlayerData.accounts[i].name, + usable = false, + rare = false, + canRemove = true + }) + end - for i=1, #ESX.PlayerData.inventory, 1 do + for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].count > 0 then - table.insert(elements, { - label = ESX.PlayerData.inventory[i].label .. ' x' .. ESX.PlayerData.inventory[i].count, - count = ESX.PlayerData.inventory[i].count, - type = 'item_standard', - value = ESX.PlayerData.inventory[i].name, - usable = ESX.PlayerData.inventory[i].usable, - rare = ESX.PlayerData.inventory[i].rare, - canRemove = ESX.PlayerData.inventory[i].canRemove, - }) - end + if ESX.PlayerData.inventory[i].count > 0 then + table.insert(elements, { + label = ESX.PlayerData.inventory[i].label .. ' x' .. ESX.PlayerData.inventory[i].count, + count = ESX.PlayerData.inventory[i].count, + type = 'item_standard', + value = ESX.PlayerData.inventory[i].name, + usable = ESX.PlayerData.inventory[i].usable, + rare = ESX.PlayerData.inventory[i].rare, + canRemove = ESX.PlayerData.inventory[i].canRemove, + }) + end - end + end - for i=1, #Config.Weapons, 1 do - - local weaponHash = GetHashKey(Config.Weapons[i].name) + for i=1, #Config.Weapons, 1 do - if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + local weaponHash = GetHashKey(Config.Weapons[i].name) - 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, - rare = false, - canRemove = true - }) + if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then - end - end + local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) - ESX.UI.Menu.CloseAll() + table.insert(elements, { + label = Config.Weapons[i].label .. ' x1 [' .. ammo .. ']', + count = 1, + type = 'item_weapon', + value = Config.Weapons[i].name, + usable = false, + rare = false, + canRemove = true + }) - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'inventory', - { - title = _U('inventory'), - align = 'bottom-right', - elements = elements, - }, - function(data, menu) + end + end - menu.close() + ESX.UI.Menu.CloseAll() - local elements = {} + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'inventory', + { + title = _U('inventory'), + align = 'bottom-right', + elements = elements, + }, + function(data, menu) - if data.current.usable then - table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) - end + menu.close() - if data.current.canRemove then - table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) - table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) - end + local elements = {} - table.insert(elements, {label = _U('return'), action = 'return'}) + if data.current.usable then + table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) + end - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'inventory_item', - { - title = _U('inventory'), - align = 'bottom-right', - elements = elements, - }, - function(data, menu) + if data.current.canRemove then + table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) + end - local item = data.current.value - local type = data.current.type + table.insert(elements, {label = _U('return'), action = 'return'}) - if data.current.action == 'give' then + ESX.UI.Menu.Open( + 'default', GetCurrentResourceName(), 'inventory_item', + { + title = _U('inventory'), + align = 'bottom-right', + elements = elements, + }, + function(data, menu) - if type == 'item_weapon' then + local item = data.current.value + local type = data.current.type - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if data.current.action == 'give' then - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('players_nearby')) - else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) - end + if type == 'item_weapon' then - else + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', - { - title = _U('amount') - }, - function(data2, menu2) + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('players_nearby')) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) + end - local quantity = tonumber(data2.value) - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + else - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('players_nearby')) - else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) - end + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', + { + title = _U('amount') + }, + function(data2, menu2) - menu2.close() - menu.close() + local quantity = tonumber(data2.value) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - end, - function(data2, menu2) - menu2.close() - end - ) + if closestPlayer == -1 or closestDistance > 3.0 then + ESX.ShowNotification(_U('players_nearby')) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + end - end + menu2.close() + menu.close() - elseif data.current.action == 'remove' then + end, + function(data2, menu2) + menu2.close() + end + ) - if type == 'item_weapon' then - - TriggerServerEvent('esx:removeInventoryItem', type, item, 1) - menu.close() - - else + end - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', - { - title = _U('amount') - }, - function(data2, menu2) + elseif data.current.action == 'remove' then - local quantity = tonumber(data2.value) + if type == 'item_weapon' then - if quantity == nil then - ESX.ShowNotification(_U('amount_invalid')) - else - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) - end + TriggerServerEvent('esx:removeInventoryItem', type, item, 1) + menu.close() - menu2.close() - menu.close() - - end, - function(data2, menu2) - menu2.close() - end - ) + else - end + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', + { + title = _U('amount') + }, + function(data2, menu2) - elseif data.current.action == 'use' then + local quantity = tonumber(data2.value) - TriggerServerEvent('esx:useItem', data.current.value) + if quantity == nil then + ESX.ShowNotification(_U('amount_invalid')) + else + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + 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 - ) + menu2.close() + menu.close() - end, - function(data, menu) - menu.close() - end - ) + end, + function(data2, menu2) + menu2.close() + end + ) + + end + + elseif data.current.action == 'use' then + + TriggerServerEvent('esx:useItem', data.current.value) + + 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 RegisterNetEvent('esx:serverCallback') AddEventHandler('esx:serverCallback', function(requestId, ...) - ESX.ServerCallbacks[requestId](...) - ESX.ServerCallbacks[requestId] = nil + ESX.ServerCallbacks[requestId](...) + ESX.ServerCallbacks[requestId] = nil end) RegisterNetEvent('esx:showNotification') AddEventHandler('esx:showNotification', function(msg) - ESX.ShowNotification(msg) + ESX.ShowNotification(msg) end) -- SetTimeout Citizen.CreateThread(function() - while true do + while true do - Citizen.Wait(0) + Citizen.Wait(0) - local currTime = GetGameTimer() + local currTime = GetGameTimer() - for i=1, #ESX.TimeoutCallbacks, 1 do + for i=1, #ESX.TimeoutCallbacks, 1 do - if ESX.TimeoutCallbacks[i] ~= nil then + if ESX.TimeoutCallbacks[i] ~= nil then - if currTime >= ESX.TimeoutCallbacks[i].time then - ESX.TimeoutCallbacks[i].cb() - ESX.TimeoutCallbacks[i] = nil - end + if currTime >= ESX.TimeoutCallbacks[i].time then + ESX.TimeoutCallbacks[i].cb() + ESX.TimeoutCallbacks[i] = nil + end - end + end - end + end - end -end) \ No newline at end of file + end +end) diff --git a/resources/[essential]/es_extended/client/main.lua b/resources/[essential]/es_extended/client/main.lua index 8263a996..4b1e50ba 100644 --- a/resources/[essential]/es_extended/client/main.lua +++ b/resources/[essential]/es_extended/client/main.lua @@ -1,13 +1,13 @@ 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 + ["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 = {} @@ -21,368 +21,368 @@ local Pickups = {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - ESX.PlayerLoaded = true - ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer - for i=1, #xPlayer.accounts, 1 do + for i=1, #xPlayer.accounts, 1 do - local accountTpl = '
 {{money}}
' + local accountTpl = '
 {{money}}
' - ESX.UI.HUD.RegisterElement('account_' .. xPlayer.accounts[i].name, i-1, 0, accountTpl, { - money = 0 - }) + 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 - }) + ESX.UI.HUD.UpdateElement('account_' .. xPlayer.accounts[i].name, { + money = xPlayer.accounts[i].money + }) - end + end - local jobTpl = '
{{job_label}} - {{grade_label}}
' + local jobTpl = '
{{job_label}} - {{grade_label}}
' - if xPlayer.job.grade_label == '' then - jobTpl = '
{{job_label}}
' - end + 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.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 - }) + ESX.UI.HUD.UpdateElement('job', { + job_label = xPlayer.job.label, + grade_label = xPlayer.job.grade_label + }) end) AddEventHandler('playerSpawned', function() - Citizen.CreateThread(function() + Citizen.CreateThread(function() - while not ESX.PlayerLoaded do - Citizen.Wait(0) - end + while not ESX.PlayerLoaded do + Citizen.Wait(0) + end - local playerPed = GetPlayerPed(-1) + local playerPed = GetPlayerPed(-1) - -- Restore position - if ESX.PlayerData.lastPosition ~= nil then - SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.lastPosition.z) - end + -- Restore position + if ESX.PlayerData.lastPosition ~= nil then + SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.lastPosition.z) + end - -- Restore loadout - for i=1, #ESX.PlayerData.loadout, 1 do - local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) - GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) - end + -- Restore loadout + for i=1, #ESX.PlayerData.loadout, 1 do + local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) + GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) + end - LoadoutLoaded = true - PlayerSpawned = true + LoadoutLoaded = true + PlayerSpawned = true - end) + end) end) AddEventHandler('skinchanger:loadDefaultModel', function() - LoadoutLoaded = false + LoadoutLoaded = false end) AddEventHandler('skinchanger:modelLoaded', function() - while not ESX.PlayerLoaded do - Citizen.Wait(0) - end - - TriggerEvent('esx:restoreLoadout') + while not ESX.PlayerLoaded do + Citizen.Wait(0) + end + + TriggerEvent('esx:restoreLoadout') end) AddEventHandler('esx:restoreLoadout', function () - local playerPed = GetPlayerPed(-1) + local playerPed = GetPlayerPed(-1) - for i=1, #ESX.PlayerData.loadout, 1 do - local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) - GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) - end + for i=1, #ESX.PlayerData.loadout, 1 do + local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) + GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) + end - LoadoutLoaded = true + LoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') AddEventHandler('esx:setAccountMoney', function(account) - for i=1, #ESX.PlayerData.accounts, 1 do - if ESX.PlayerData.accounts[i].name == account.name then - ESX.PlayerData.accounts[i] = account - end - end + for i=1, #ESX.PlayerData.accounts, 1 do + if ESX.PlayerData.accounts[i].name == account.name then + ESX.PlayerData.accounts[i] = account + end + end - ESX.UI.HUD.UpdateElement('account_' .. account.name, { - money = account.money - }) + ESX.UI.HUD.UpdateElement('account_' .. account.name, { + money = account.money + }) end) RegisterNetEvent('es:activateMoney') AddEventHandler('es:activateMoney', function(money) - ESX.PlayerData.money = money + ESX.PlayerData.money = money end) RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count) - - for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item - end - end - ESX.UI.ShowInventoryItemNotification(true, item, count) + for i=1, #ESX.PlayerData.inventory, 1 do + if ESX.PlayerData.inventory[i].name == item.name then + ESX.PlayerData.inventory[i] = item + end + end - if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then - ESX.ShowInventory() - 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 i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item - end - end + for i=1, #ESX.PlayerData.inventory, 1 do + if ESX.PlayerData.inventory[i].name == item.name then + ESX.PlayerData.inventory[i] = item + end + end - ESX.UI.ShowInventoryItemNotification(false, item, count) + ESX.UI.ShowInventoryItemNotification(false, item, count) + + if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + ESX.ShowInventory() + end - 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 + ESX.PlayerData.job = job end) RegisterNetEvent('esx:addWeapon') AddEventHandler('esx:addWeapon', function(weaponName, ammo) - local playerPed = GetPlayerPed(-1) - local weaponHash = GetHashKey(weaponName) - - GiveWeaponToPed(playerPed, weaponHash, ammo, false, false) + 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) + 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 + 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 + RequestCollisionAtCoord(pos.x, pos.y, pos.z) - SetEntityCoords(GetPlayerPed(-1), 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 - }) + 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) + Citizen.CreateThread(function() + LoadMpDlcMaps() + EnableMpDlcMaps(true) + RequestIpl(name) + end) end) RegisterNetEvent('esx:unloadIPL') AddEventHandler('esx:unloadIPL', function(name) - Citizen.CreateThread(function() - RemoveIpl(name) - end) + Citizen.CreateThread(function() + RemoveIpl(name) + end) end) RegisterNetEvent('esx:playAnim') AddEventHandler('esx:playAnim', function(dict, anim) - Citizen.CreateThread(function() + Citizen.CreateThread(function() - local pid = PlayerPedId() - - RequestAnimDict(dict) - - while not HasAnimDictLoaded(dict) do - Wait(0) - end + local pid = PlayerPedId() - TaskPlayAnim(pid, dict, anim, 1.0, -1.0, 20000, 0, 1, true, true, true) - - end) + 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) + Citizen.CreateThread(function() - TaskStartScenarioInPlace(playerPed, emote, 0, false); - Wait(20000) - ClearPedTasks(playerPed) + local playerPed = GetPlayerPed(-1) - end) + 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) + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) - ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) + ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) end) RegisterNetEvent('esx:spawnObject') AddEventHandler('esx:spawnObject', function(model) - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) - ESX.Game.SpawnObject(model, { - x = x, - y = y, - z = z - }, function(obj) - SetEntityHeading(obj, GetEntityHeading(playerPed)) - PlaceObjectOnGroundProperly(obj) - end) + ESX.Game.SpawnObject(model, { + x = x, + y = y, + z = z + }, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + 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) + 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) + ESX.Game.SpawnLocalObject('prop_money_bag_01', { + x = x, + y = y, + z = z - 2.0, + }, function(obj) - PlaceObjectOnGroundProperly(obj) - - Pickups[id] = { - id = id, - obj = obj, - label = label, - inRange = false, - coords = { - x = x, - y = y, - z = z - }, - } + SetEntityAsMissionEntity(obj, true, false) - end) + 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 + ESX.Game.DeleteObject(Pickups[id].obj) + Pickups[id] = nil end) RegisterNetEvent('esx:pickupWeapon') AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName) - - local ped = GetPlayerPed(-1) - local playerPedPos = GetEntityCoords(ped, true) - - CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, 1000, 1, false, true) + + local ped = GetPlayerPed(-1) + local playerPedPos = GetEntityCoords(ped, true) + + CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, 1000, 1, false, true) end) RegisterNetEvent('esx:spawnPed') AddEventHandler('esx:spawnPed', function(model) - model = (tonumber(model) ~= nil and tonumber(model) or GetHashKey(model)) - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) + model = (tonumber(model) ~= nil and tonumber(model) or GetHashKey(model)) + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) - Citizen.CreateThread(function() + Citizen.CreateThread(function() - RequestModel(model) + RequestModel(model) - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - CreatePed(5, model, x, y, z, 0.0, true, false) + CreatePed(5, model, x, y, z, 0.0, true, false) - end) + end) end) RegisterNetEvent('esx:deleteVehicle') AddEventHandler('esx:deleteVehicle', function() - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) - if IsPedInAnyVehicle(playerPed, false) then - - local vehicle = GetVehiclePedIsIn(playerPed, false) - ESX.Game.DeleteVehicle(vehicle) - - elseif IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - - local vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) - ESX.Game.DeleteVehicle(vehicle) - - end + if IsPedInAnyVehicle(playerPed, false) then + + local vehicle = GetVehiclePedIsIn(playerPed, false) + ESX.Game.DeleteVehicle(vehicle) + + elseif IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then + + local vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) + ESX.Game.DeleteVehicle(vehicle) + + end end) @@ -394,11 +394,11 @@ Citizen.CreateThread(function() if IsPauseMenuActive() and not IsPaused then IsPaused = true TriggerEvent('es:setMoneyDisplay', 0.0) - ESX.UI.HUD.SetDisplay(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) + ESX.UI.HUD.SetDisplay(1.0) end end end) @@ -406,67 +406,67 @@ end) -- Save loadout Citizen.CreateThread(function() - while true do + while true do - Wait(0) + Wait(0) - local playerPed = GetPlayerPed(-1) - local loadout = {} - local loadoutChanged = false - - if IsPedDeadOrDying(playerPed) then - LoadoutLoaded = false - end + local playerPed = GetPlayerPed(-1) + local loadout = {} + local loadoutChanged = false - for i=1, #Config.Weapons, 1 do + if IsPedDeadOrDying(playerPed) then + LoadoutLoaded = false + end - local weaponHash = GetHashKey(Config.Weapons[i].name) + for i=1, #Config.Weapons, 1 do - if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + local weaponHash = GetHashKey(Config.Weapons[i].name) - local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then - if LastLoadout[Config.Weapons[i].name] == nil or LastLoadout[Config.Weapons[i].name] ~= ammo then - loadoutChanged = true - end + local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) - LastLoadout[Config.Weapons[i].name] = ammo + if LastLoadout[Config.Weapons[i].name] == nil or LastLoadout[Config.Weapons[i].name] ~= ammo then + loadoutChanged = true + end - table.insert(loadout, { - name = Config.Weapons[i].name, - ammo = ammo, - label = Config.Weapons[i].label - }) + LastLoadout[Config.Weapons[i].name] = ammo - else + table.insert(loadout, { + name = Config.Weapons[i].name, + ammo = ammo, + label = Config.Weapons[i].label + }) - if LastLoadout[Config.Weapons[i].name] ~= nil then - loadoutChanged = true - end + else - LastLoadout[Config.Weapons[i].name] = nil + if LastLoadout[Config.Weapons[i].name] ~= nil then + loadoutChanged = true + end - end + LastLoadout[Config.Weapons[i].name] = nil - end + end - if loadoutChanged and LoadoutLoaded then - ESX.PlayerData.loadout = loadout - TriggerServerEvent('esx:updateLoadout', loadout) - end + end - end + if loadoutChanged and LoadoutLoaded then + ESX.PlayerData.loadout = loadout + TriggerServerEvent('esx:updateLoadout', loadout) + end + + end end) -- Menu interactions Citizen.CreateThread(function() - while true do + while true do - Wait(0) + 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() + 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 @@ -475,31 +475,31 @@ end) -- Dot above head if Config.ShowDotAbovePlayer then - Citizen.CreateThread(function() - while true do + Citizen.CreateThread(function() + while true do - Citizen.Wait(0) + Citizen.Wait(0) - local players = ESX.Game.GetPlayers() + 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 + 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 + end) end -- Disable wanted level if Config.DisableWantedLevel then - Citizen.CreateThread(function() + Citizen.CreateThread(function() while true do - + Citizen.Wait(0) local playerId = PlayerId() @@ -510,76 +510,76 @@ if Config.DisableWantedLevel then end end - end) + end) end -- Pickups Citizen.CreateThread(function() - while true do + while true do - Citizen.Wait(0) + Citizen.Wait(0) - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) - for k,v in pairs(Pickups) do + for k,v in pairs(Pickups) do - local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true) + local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true) - 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) + if distance <= 5.0 then - end + ESX.Game.Utils.DrawText3D({ + x = v.coords.x, + y = v.coords.y, + z = v.coords.z + 0.25 + }, v.label) - if distance <= 1.0 and not v.inRange then - TriggerServerEvent('esx:onPickup', v.id) - v.inRange = true - end + end - end + if distance <= 1.0 and not v.inRange then + TriggerServerEvent('esx:onPickup', v.id) + v.inRange = true + end - end + end + + end end) -- Last position Citizen.CreateThread(function() - - while true do - Citizen.Wait(1000) + while true do - if ESX ~= nil and ESX.PlayerLoaded and PlayerSpawned then + Citizen.Wait(1000) - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) + if ESX ~= nil and ESX.PlayerLoaded and PlayerSpawned then - if not IsEntityDead(playerPed) then - ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} - end + local playerPed = GetPlayerPed(-1) + local coords = GetEntityCoords(playerPed) - end + if not IsEntityDead(playerPed) then + ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} + end - end + end + + end end) Citizen.CreateThread(function() - while true do + while true do - Citizen.Wait(0) + Citizen.Wait(0) - local playerPed = GetPlayerPed(-1) + local playerPed = GetPlayerPed(-1) - if IsEntityDead(playerPed) and PlayerSpawned then - PlayerSpawned = false - end - end + if IsEntityDead(playerPed) and PlayerSpawned then + PlayerSpawned = false + end + end end) diff --git a/resources/[essential]/es_extended/config.lua b/resources/[essential]/es_extended/config.lua index b6714cc6..215a67fb 100644 --- a/resources/[essential]/es_extended/config.lua +++ b/resources/[essential]/es_extended/config.lua @@ -1,8 +1,8 @@ Config = {} Config.MaxPlayers = 32 -Config.Accounts = {'bank', 'black_money'} -Config.AccountLabels = {bank = 'Banque', black_money = 'Argent Sale'} -- French ---Config.AccountLabels = {bank = 'Bank', black_money = 'Dirty Money'} -- English +Config.Accounts = { 'bank', 'black_money' } +Config.AccountLabels = { bank = 'Banque', black_money = 'Argent Sale' } -- French +-- Config.AccountLabels = { bank = 'Bank', black_money = 'Dirty Money' } -- English Config.PaycheckInterval = 7 * 60000 Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true diff --git a/resources/[essential]/es_extended/config.weapons.lua b/resources/[essential]/es_extended/config.weapons.lua index 3ce8b4c5..ec1327ce 100644 --- a/resources/[essential]/es_extended/config.weapons.lua +++ b/resources/[essential]/es_extended/config.weapons.lua @@ -1,81 +1,80 @@ Config.Weapons = { - - {name = 'WEAPON_KNIFE', label = _U('weapon_knife')}, - {name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick')}, - {name = 'WEAPON_HAMMER', label = _U('weapon_hammer')}, - {name = 'WEAPON_BAT', label = _U('weapon_bat')}, - {name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub')}, - {name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar')}, - {name = 'WEAPON_PISTOL', label = _U('weapon_pistol')}, - {name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol')}, - {name = 'WEAPON_APPISTOL', label = _U('weapon_appistol')}, - {name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50')}, - {name = 'WEAPON_MICROSMG', label = _U('weapon_microsmg')}, - {name = 'WEAPON_SMG', label = _U('weapon_smg')}, - {name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg')}, - {name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle')}, - {name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle')}, - {name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle')}, - {name = 'WEAPON_MG', label = _U('weapon_mg')}, - {name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg')}, - {name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun')}, - {name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun')}, - {name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun')}, - {name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun')}, - {name = 'WEAPON_STUNGUN', label = _U('weapon_stungun')}, - {name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle')}, - {name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper')}, - {name = 'WEAPON_REMOTESNIPER', label = _U('weapon_remotesniper')}, - {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher')}, - {name = 'WEAPON_RPG', label = _U('weapon_rpg')}, - {name = 'WEAPON_STINGER', label = _U('weapon_stinger')}, - {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun')}, - {name = 'WEAPON_GRENADE', label = _U('weapon_grenade')}, - {name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb')}, - {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade')}, - {name = 'WEAPON_BZGAS', label = _U('weapon_bzgas')}, - {name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov')}, - {name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher')}, - {name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan')}, - {name = 'WEAPON_DIGISCANNER', label = _U('weapon_digiscanner')}, - {name = 'WEAPON_BALL', label = _U('weapon_ball')}, - {name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol')}, - {name = 'WEAPON_BOTTLE', label = _U('weapon_bottle')}, - {name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg')}, - {name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine')}, - {name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol')}, - {name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle')}, - {name = 'WEAPON_DAGGER', label = _U('weapon_dagger')}, - {name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol')}, - {name = 'WEAPON_FIREWORK', label = _U('weapon_firework')}, - {name = 'WEAPON_MUSKET', label = _U('weapon_musket')}, - {name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun')}, - {name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle')}, - {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher')}, - {name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine')}, - {name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball')}, - {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun')}, - {name = 'WEAPON_GARBAGEBAG', label = _U('weapon_garbagebag')}, - {name = 'WEAPON_HANDCUFFS', label = _U('weapon_handcuffs')}, - {name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw')}, - {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol')}, - {name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle')}, - {name = 'WEAPON_HATCHET', label = _U('weapon_hatchet')}, - {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun')}, - {name = 'WEAPON_MACHETE', label = _U('weapon_machete')}, - {name = 'WEAPON_MACHINEPISTOL', label = _U('weapon_machinepistol')}, - {name = 'WEAPON_SWITCHBLADE', label = _U('weapon_switchblade')}, - {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver')}, - {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun')}, - {name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle')}, - {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun')}, - {name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe')}, - {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher')}, - {name = 'WEAPON_MINISMG', label = _U('weapon_minismg')}, - {name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb')}, - {name = 'WEAPON_POOLCUE', label = _U('weapon_poolcue')}, - {name = 'WEAPON_WRENCH', label = _U('weapon_wrench')}, - {name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight')}, - {name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision')}, - {name = 'GADGET_PARACHUTE', label = _U('gadget_parachute')}, -} \ No newline at end of file + { name = 'WEAPON_KNIFE', label = _U('weapon_knife') }, + { name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick') }, + { name = 'WEAPON_HAMMER', label = _U('weapon_hammer') }, + { name = 'WEAPON_BAT', label = _U('weapon_bat') }, + { name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub') }, + { name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar') }, + { name = 'WEAPON_PISTOL', label = _U('weapon_pistol') }, + { name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol') }, + { name = 'WEAPON_APPISTOL', label = _U('weapon_appistol') }, + { name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50') }, + { name = 'WEAPON_MICROSMG', label = _U('weapon_microsmg') }, + { name = 'WEAPON_SMG', label = _U('weapon_smg') }, + { name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg') }, + { name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle') }, + { name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle') }, + { name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle') }, + { name = 'WEAPON_MG', label = _U('weapon_mg') }, + { name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg') }, + { name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun') }, + { name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun') }, + { name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun') }, + { name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun') }, + { name = 'WEAPON_STUNGUN', label = _U('weapon_stungun') }, + { name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle') }, + { name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper') }, + { name = 'WEAPON_REMOTESNIPER', label = _U('weapon_remotesniper') }, + { name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher') }, + { name = 'WEAPON_RPG', label = _U('weapon_rpg') }, + { name = 'WEAPON_STINGER', label = _U('weapon_stinger') }, + { name = 'WEAPON_MINIGUN', label = _U('weapon_minigun') }, + { name = 'WEAPON_GRENADE', label = _U('weapon_grenade') }, + { name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb') }, + { name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade') }, + { name = 'WEAPON_BZGAS', label = _U('weapon_bzgas') }, + { name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov') }, + { name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher') }, + { name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan') }, + { name = 'WEAPON_DIGISCANNER', label = _U('weapon_digiscanner') }, + { name = 'WEAPON_BALL', label = _U('weapon_ball') }, + { name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol') }, + { name = 'WEAPON_BOTTLE', label = _U('weapon_bottle') }, + { name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg') }, + { name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine') }, + { name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol') }, + { name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle') }, + { name = 'WEAPON_DAGGER', label = _U('weapon_dagger') }, + { name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol') }, + { name = 'WEAPON_FIREWORK', label = _U('weapon_firework') }, + { name = 'WEAPON_MUSKET', label = _U('weapon_musket') }, + { name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun') }, + { name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle') }, + { name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher') }, + { name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine') }, + { name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball') }, + { name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun') }, + { name = 'WEAPON_GARBAGEBAG', label = _U('weapon_garbagebag') }, + { name = 'WEAPON_HANDCUFFS', label = _U('weapon_handcuffs') }, + { name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw') }, + { name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol') }, + { name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle') }, + { name = 'WEAPON_HATCHET', label = _U('weapon_hatchet') }, + { name = 'WEAPON_RAILGUN', label = _U('weapon_railgun') }, + { name = 'WEAPON_MACHETE', label = _U('weapon_machete') }, + { name = 'WEAPON_MACHINEPISTOL', label = _U('weapon_machinepistol') }, + { name = 'WEAPON_SWITCHBLADE', label = _U('weapon_switchblade') }, + { name = 'WEAPON_REVOLVER', label = _U('weapon_revolver') }, + { name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun') }, + { name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle') }, + { name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun') }, + { name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe') }, + { name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher') }, + { name = 'WEAPON_MINISMG', label = _U('weapon_minismg') }, + { name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb') }, + { name = 'WEAPON_POOLCUE', label = _U('weapon_poolcue') }, + { name = 'WEAPON_WRENCH', label = _U('weapon_wrench') }, + { name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight') }, + { name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision') }, + { name = 'GADGET_PARACHUTE', label = _U('gadget_parachute') }, +} diff --git a/resources/[essential]/es_extended/locale.lua b/resources/[essential]/es_extended/locale.lua index 03e2271f..208cf827 100644 --- a/resources/[essential]/es_extended/locale.lua +++ b/resources/[essential]/es_extended/locale.lua @@ -1,18 +1,18 @@ Locales = {} -function _(str, ...) -- Translate string +function _(str, ...) -- Translate string - if Locales[Config.Locale] ~= nil then + if Locales[Config.Locale] ~= nil then - if Locales[Config.Locale][str] ~= nil then - return string.format(Locales[Config.Locale][str], ...) - else - return 'Translation [' .. Config.Locale .. '][' .. str .. '] does not exists' - end + if Locales[Config.Locale][str] ~= nil then + return string.format(Locales[Config.Locale][str], ...) + else + return 'Translation [' .. Config.Locale .. '][' .. str .. '] does not exists' + end - else - return 'Locale [' .. Config.Locale .. '] does not exists' - end + else + return 'Locale [' .. Config.Locale .. '] does not exists' + end end diff --git a/resources/[essential]/es_extended/locales/br.lua b/resources/[essential]/es_extended/locales/br.lua index cf47cb80..89379694 100644 --- a/resources/[essential]/es_extended/locales/br.lua +++ b/resources/[essential]/es_extended/locales/br.lua @@ -1,122 +1,122 @@ Locales['br'] = { - ['inventory'] = 'inventário', - ['use'] = 'usar', - ['give'] = 'dar', - ['remove'] = 'remover', - ['return'] = 'voltar', - ['amount'] = 'quantidade', - ['amount_invalid'] = 'quantidade inválida', - ['players_nearby'] = 'nenhum jogador nas proximidades', - ['ex_inv_lim'] = 'Esta ação não é possível, supera o limite do inventário para ~b~', - ['yougave'] = 'você deu', - ['youreceived'] = 'você recebeu', - ['to'] = '~s~ para ~b~', - ['by'] = '~s~ por ~b~', - ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', - ['imp_invalid_amount'] = 'ação impossível, valor inválido', - ['delete_five_min'] = '~r~deleta~s~ em 5 minutos', - ['threw'] = 'você ~r~jogou~s~', - ['rec_salary'] = 'você recebeu seu salário: ', - ['act_imp'] = 'ação impossível', - -- Commands - ['setjob'] = 'atribuir um emprego a um usuário', - ['id_param'] = 'o id do jogador', - ['setjob_param2'] = 'o trabalho que você deseja atribuir', - ['setjob_param3'] = 'o nível de trabalho', - ['load_ipl'] = 'carregando ipl', - ['unload_ipl'] = 'descarregando ipl', - ['play_anim'] = 'reproduzir animação', - ['play_emote'] = 'reproduzir emote', - ['spawn_car'] = 'fazer aparecer um carro', - ['spawn_car_param'] = 'nome do carro', - ['spawn_object'] = 'gerar um objeto', - ['givemoney'] = 'dar dinheiro', - ['money_amount'] = 'quantia do dinheiro', - ['invalid_account'] = 'conta inválida', - ['account'] = 'conta', - ['giveaccountmoney'] = 'dar dinheiro em conta', - ['invalid_item'] = 'item inválido', - ['item'] = 'item', - ['giveitem'] = 'dar item', - ['weapon'] = 'arma', - ['giveweapon'] = 'dar arma', - -- Weapons - ['weapon_knife'] = 'ffaca', - ['weapon_nightstick'] = 'cacetete', - ['weapon_hammer'] = 'martelo', - ['weapon_bat'] = 'bastão', - ['weapon_golfclub'] = 'golf club', - ['weapon_crowbar'] = 'pé de cabra', - ['weapon_pistol'] = 'pistola', - ['weapon_combatpistol'] = 'pistola de combate', - ['weapon_appistol'] = 'ap pistola', - ['weapon_pistol50'] = 'pistola .50', - ['weapon_microsmg'] = 'micro smg', - ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'assault smg', - ['weapon_assaultrifle'] = 'assault rifle', - ['weapon_carbinerifle'] = 'carbine rifle', - ['weapon_advancedrifle'] = 'advanced rifle', - ['weapon_mg'] = 'mg', - ['weapon_combatmg'] = 'combat mg', - ['weapon_pumpshotgun'] = 'espingarda', - ['weapon_sawnoffshotgun'] = 'sawed off shotgun', - ['weapon_assaultshotgun'] = 'assault shotgun', - ['weapon_bullpupshotgun'] = 'bullpup shotgun', - ['weapon_stungun'] = 'arma de choque', - ['weapon_sniperrifle'] = 'sniper rifle', - ['weapon_heavysniper'] = 'heavy sniper', - ['weapon_remotesniper'] = 'remote sniper', - ['weapon_grenadelauncher'] = 'lançador de granada', - ['weapon_rpg'] = 'lançador de foguetes', - ['weapon_stinger'] = 'stinger', - ['weapon_minigun'] = 'minigun', - ['weapon_grenade'] = 'granada', - ['weapon_stickybomb'] = 'bomba pegajosa', - ['weapon_smokegrenade'] = 'granada de fumaça', - ['weapon_bzgas'] = 'bz gas', - ['weapon_molotov'] = 'coquetel molotov', - ['weapon_fireextinguisher'] = 'extintor', - ['weapon_petrolcan'] = 'galão de combustivel', - ['weapon_digiscanner'] = 'digiscanner', - ['weapon_ball'] = 'bola', - ['weapon_snspistol'] = 'sns pistol', - ['weapon_bottle'] = 'garrafa', - ['weapon_gusenberg'] = 'gusenberg sweeper', - ['weapon_specialcarbine'] = 'carabina especial', - ['weapon_heavypistol'] = 'heavy pistol', - ['weapon_bullpuprifle'] = 'bullpup rifle', - ['weapon_dagger'] = 'punhal', - ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_firework'] = 'fogos de artifício', - ['weapon_musket'] = 'mosquete', - ['weapon_heavyshotgun'] = 'heavy shotgun', - ['weapon_marksmanrifle'] = 'marksman rifle', - ['weapon_hominglauncher'] = 'homing launcher', - ['weapon_proxmine'] = 'mina de proximidade', - ['weapon_snowball'] = 'bola de neve', - ['weapon_flaregun'] = 'sinalizador', - ['weapon_garbagebag'] = 'saco de lixo', - ['weapon_handcuffs'] = 'algemas', - ['weapon_combatpdw'] = 'combat pdw', - ['weapon_marksmanpistol'] = 'marksman pistol', - ['weapon_knuckle'] = 'soco inglês', - ['weapon_hatchet'] = 'machado', - ['weapon_railgun'] = 'railgun', - ['weapon_machete'] = 'facão', - ['weapon_machinepistol'] = 'machine pistol', - ['weapon_switchblade'] = 'canivete', - ['weapon_revolver'] = 'heavy revolver', - ['weapon_dbshotgun'] = 'espingarda de cano duplo', - ['weapon_compactrifle'] = 'compact rifle', - ['weapon_autoshotgun'] = 'auto shotgun', - ['weapon_battleaxe'] = 'battle axe', - ['weapon_compactlauncher'] = 'compact launcher', - ['weapon_minismg'] = 'mini smg', - ['weapon_pipebomb'] = 'bomba caseira', - ['weapon_poolcue'] = 'taco de sinuca', - ['weapon_wrench'] = 'chave de cano', - ['weapon_flashlight'] = 'laterna', - ['gadget_nightvision'] = 'visão noturna', - ['gadget_parachute'] = 'paraquedas', -} \ No newline at end of file + ['inventory'] = 'inventário', + ['use'] = 'usar', + ['give'] = 'dar', + ['remove'] = 'remover', + ['return'] = 'voltar', + ['amount'] = 'quantidade', + ['amount_invalid'] = 'quantidade inválida', + ['players_nearby'] = 'nenhum jogador nas proximidades', + ['ex_inv_lim'] = 'Esta ação não é possível, supera o limite do inventário para ~b~', + ['yougave'] = 'você deu', + ['youreceived'] = 'você recebeu', + ['to'] = '~s~ para ~b~', + ['by'] = '~s~ por ~b~', + ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', + ['imp_invalid_amount'] = 'ação impossível, valor inválido', + ['delete_five_min'] = '~r~deleta~s~ em 5 minutos', + ['threw'] = 'você ~r~jogou~s~', + ['rec_salary'] = 'você recebeu seu salário: ', + ['act_imp'] = 'ação impossível', + -- Commands + ['setjob'] = 'atribuir um emprego a um usuário', + ['id_param'] = 'o id do jogador', + ['setjob_param2'] = 'o trabalho que você deseja atribuir', + ['setjob_param3'] = 'o nível de trabalho', + ['load_ipl'] = 'carregando ipl', + ['unload_ipl'] = 'descarregando ipl', + ['play_anim'] = 'reproduzir animação', + ['play_emote'] = 'reproduzir emote', + ['spawn_car'] = 'fazer aparecer um carro', + ['spawn_car_param'] = 'nome do carro', + ['spawn_object'] = 'gerar um objeto', + ['givemoney'] = 'dar dinheiro', + ['money_amount'] = 'quantia do dinheiro', + ['invalid_account'] = 'conta inválida', + ['account'] = 'conta', + ['giveaccountmoney'] = 'dar dinheiro em conta', + ['invalid_item'] = 'item inválido', + ['item'] = 'item', + ['giveitem'] = 'dar item', + ['weapon'] = 'arma', + ['giveweapon'] = 'dar arma', + -- Weapons + ['weapon_knife'] = 'ffaca', + ['weapon_nightstick'] = 'cacetete', + ['weapon_hammer'] = 'martelo', + ['weapon_bat'] = 'bastão', + ['weapon_golfclub'] = 'golf club', + ['weapon_crowbar'] = 'pé de cabra', + ['weapon_pistol'] = 'pistola', + ['weapon_combatpistol'] = 'pistola de combate', + ['weapon_appistol'] = 'ap pistola', + ['weapon_pistol50'] = 'pistola .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'assault smg', + ['weapon_assaultrifle'] = 'assault rifle', + ['weapon_carbinerifle'] = 'carbine rifle', + ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'combat mg', + ['weapon_pumpshotgun'] = 'espingarda', + ['weapon_sawnoffshotgun'] = 'sawed off shotgun', + ['weapon_assaultshotgun'] = 'assault shotgun', + ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_stungun'] = 'arma de choque', + ['weapon_sniperrifle'] = 'sniper rifle', + ['weapon_heavysniper'] = 'heavy sniper', + ['weapon_remotesniper'] = 'remote sniper', + ['weapon_grenadelauncher'] = 'lançador de granada', + ['weapon_rpg'] = 'lançador de foguetes', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'granada', + ['weapon_stickybomb'] = 'bomba pegajosa', + ['weapon_smokegrenade'] = 'granada de fumaça', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'coquetel molotov', + ['weapon_fireextinguisher'] = 'extintor', + ['weapon_petrolcan'] = 'galão de combustivel', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'bola', + ['weapon_snspistol'] = 'sns pistol', + ['weapon_bottle'] = 'garrafa', + ['weapon_gusenberg'] = 'gusenberg sweeper', + ['weapon_specialcarbine'] = 'carabina especial', + ['weapon_heavypistol'] = 'heavy pistol', + ['weapon_bullpuprifle'] = 'bullpup rifle', + ['weapon_dagger'] = 'punhal', + ['weapon_vintagepistol'] = 'vintage pistol', + ['weapon_firework'] = 'fogos de artifício', + ['weapon_musket'] = 'mosquete', + ['weapon_heavyshotgun'] = 'heavy shotgun', + ['weapon_marksmanrifle'] = 'marksman rifle', + ['weapon_hominglauncher'] = 'homing launcher', + ['weapon_proxmine'] = 'mina de proximidade', + ['weapon_snowball'] = 'bola de neve', + ['weapon_flaregun'] = 'sinalizador', + ['weapon_garbagebag'] = 'saco de lixo', + ['weapon_handcuffs'] = 'algemas', + ['weapon_combatpdw'] = 'combat pdw', + ['weapon_marksmanpistol'] = 'marksman pistol', + ['weapon_knuckle'] = 'soco inglês', + ['weapon_hatchet'] = 'machado', + ['weapon_railgun'] = 'railgun', + ['weapon_machete'] = 'facão', + ['weapon_machinepistol'] = 'machine pistol', + ['weapon_switchblade'] = 'canivete', + ['weapon_revolver'] = 'heavy revolver', + ['weapon_dbshotgun'] = 'espingarda de cano duplo', + ['weapon_compactrifle'] = 'compact rifle', + ['weapon_autoshotgun'] = 'auto shotgun', + ['weapon_battleaxe'] = 'battle axe', + ['weapon_compactlauncher'] = 'compact launcher', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'bomba caseira', + ['weapon_poolcue'] = 'taco de sinuca', + ['weapon_wrench'] = 'chave de cano', + ['weapon_flashlight'] = 'laterna', + ['gadget_nightvision'] = 'visão noturna', + ['gadget_parachute'] = 'paraquedas', +} diff --git a/resources/[essential]/es_extended/locales/de.lua b/resources/[essential]/es_extended/locales/de.lua index 21ec922b..2c6d8d22 100644 --- a/resources/[essential]/es_extended/locales/de.lua +++ b/resources/[essential]/es_extended/locales/de.lua @@ -1,121 +1,121 @@ Locales['de'] = { - ['inventory'] = 'Inventar', - ['use'] = 'benutzen', - ['give'] = 'geben', - ['remove'] = 'entfernen', - ['return'] = 'zurück', - ['amount'] = 'Betrag', - ['amount_invalid'] = 'ungültiger Betrag', - ['players_nearby'] = 'keine Spieler in der Nähe', - ['ex_inv_lim'] = 'Aktion nicht möglich, inventarlimit überschritten für ~b~', - ['yougave'] = 'du gibst', - ['youreceived'] = 'to empfängst', - ['to'] = '~s~ zu ~b~', - ['by'] = '~s~ von ~b~', - ['imp_invalid_quantity'] = 'Aktion nicht möglich, ungültige Anzahl', - ['imp_invalid_amount'] = 'Aktion nicht möglich, ungültiger Betrag', - ['delete_five_min'] = '~r~löschen~s~ in 5 Minuten', - ['threw'] = 'du ~r~wirfst weg~s~', - ['rec_salary'] = 'du hast dein Gehalt erhalten: ', - ['act_imp'] = 'Aktion nicht möglich', - -- Commands - ['setjob'] = 'assign a job to a user', - ['id_param'] = 'the ID of the player', - ['setjob_param2'] = 'the job you wish to assign', - ['setjob_param3'] = 'the job level', - ['load_ipl'] = 'load IPL', - ['unload_ipl'] = 'unload IPL', - ['play_anim'] = 'play animation', - ['play_emote'] = 'play emote', - ['spawn_car'] = 'spawn a car', - ['spawn_car_param'] = 'name of car', - ['givemoney'] = 'give money', - ['money_amount'] = 'amount of money', - ['invalid_account'] = 'invalid account', - ['account'] = 'account', - ['giveaccountmoney'] = 'give account money', - ['invalid_item'] = 'invalid item', - ['item'] = 'item', - ['giveitem'] = 'give item', - ['weapon'] = 'weapon', - ['giveweapon'] = 'give weapon', - -- Weapons - ['weapon_knife'] = 'Messer', - ['weapon_nightstick'] = 'Schlagstock', - ['weapon_hammer'] = 'Hammer', - ['weapon_bat'] = 'Schläger', - ['weapon_golfclub'] = 'Golfschläger', - ['weapon_crowbar'] = 'Brecheisen', - ['weapon_pistol'] = 'Pistole', - ['weapon_combatpistol'] = 'Kampfpistole', - ['weapon_appistol'] = 'AP Pistole', - ['weapon_pistol50'] = 'Pistole .50', - ['weapon_microsmg'] = 'Mikro SMG', - ['weapon_smg'] = 'SMG', - ['weapon_assaultsmg'] = 'Kampf SMG', - ['weapon_assaultrifle'] = 'Kampfgewehr', - ['weapon_carbinerifle'] = 'Karabinergewehr', - ['weapon_advancedrifle'] = 'Advancedgewehr', - ['weapon_mg'] = 'MG', - ['weapon_combatmg'] = 'Kampf MG', - ['weapon_pumpshotgun'] = 'Pumpgun', - ['weapon_sawnoffshotgun'] = 'Abgesägte Schrotflinte', - ['weapon_assaultshotgun'] = 'Kampf Schrotflinte', - ['weapon_bullpupshotgun'] = 'Bullpup Schrotflinte', - ['weapon_stungun'] = 'Tazer', - ['weapon_sniperrifle'] = 'Scharfschützengewehr', - ['weapon_heavysniper'] = 'Schweres Sniper', - ['weapon_remotesniper'] = 'Remote sniper', - ['weapon_grenadelauncher'] = 'Granatwerfer', - ['weapon_rpg'] = 'RPG', - ['weapon_stinger'] = 'Stinger', - ['weapon_minigun'] = 'Minigun', - ['weapon_grenade'] = 'Granate', - ['weapon_stickybomb'] = 'Haftbombe', - ['weapon_smokegrenade'] = 'Rauchgranate', - ['weapon_bzgas'] = 'BZ Gas', - ['weapon_molotov'] = 'Molotov Cocktail', - ['weapon_fireextinguisher'] = 'Feuerlöscher', - ['weapon_petrolcan'] = 'Benzinkanister', - ['weapon_digiscanner'] = 'Digiscanner', - ['weapon_ball'] = 'Ball', - ['weapon_snspistol'] = 'SNS Pistole', - ['weapon_bottle'] = 'Flasche', - ['weapon_gusenberg'] = 'Gusenberg', - ['weapon_specialcarbine'] = 'Spezialkarabiner', - ['weapon_heavypistol'] = 'Schwere Pistole', - ['weapon_bullpuprifle'] = 'Bullpupgewehr', - ['weapon_dagger'] = 'Dolch', - ['weapon_vintagepistol'] = 'Vintage Pistole', - ['weapon_firework'] = 'Feuerwerk', - ['weapon_musket'] = 'Muskete', - ['weapon_heavyshotgun'] = 'Schwere Schrotflinte', - ['weapon_marksmanrifle'] = 'Marksmangewehr', - ['weapon_hominglauncher'] = 'Homing Launcher', - ['weapon_proxmine'] = 'Annäherungsmine', - ['weapon_snowball'] = 'Schneeball', - ['weapon_flaregun'] = 'Leuchtpistole', - ['weapon_garbagebag'] = 'Müllsack', - ['weapon_handcuffs'] = 'Handschellen', - ['weapon_combatpdw'] = 'Kampf PDW', - ['weapon_marksmanpistol'] = 'Marksman Pistole', - ['weapon_knuckle'] = 'Schlagring', - ['weapon_hatchet'] = 'Axt', - ['weapon_railgun'] = 'Railgun', - ['weapon_machete'] = 'Machete', - ['weapon_machinepistol'] = 'Maschinenpistole', - ['weapon_switchblade'] = 'Klappmesser', - ['weapon_revolver'] = 'Schwerer Revolver', - ['weapon_dbshotgun'] = 'Doppelläufige Schrotflinte', - ['weapon_compactrifle'] = 'Kampfgewehr', - ['weapon_autoshotgun'] = 'Auto Shotgun', - ['weapon_battleaxe'] = 'Kampfaxt', - ['weapon_compactlauncher'] = 'Kompakt Launcher', - ['weapon_minismg'] = 'Mini SMG', - ['weapon_pipebomb'] = 'Rohrbombe', - ['weapon_poolcue'] = 'Kö', - ['weapon_wrench'] = 'Rohrzange', - ['weapon_flashlight'] = 'Taschenlampe', - ['gadget_nightvision'] = 'Nachtsichtgerät', - ['gadget_parachute'] = 'Fallschirm', -} \ No newline at end of file + ['inventory'] = 'Inventar', + ['use'] = 'benutzen', + ['give'] = 'geben', + ['remove'] = 'entfernen', + ['return'] = 'zurück', + ['amount'] = 'Betrag', + ['amount_invalid'] = 'ungültiger Betrag', + ['players_nearby'] = 'keine Spieler in der Nähe', + ['ex_inv_lim'] = 'Aktion nicht möglich, inventarlimit überschritten für ~b~', + ['yougave'] = 'du gibst', + ['youreceived'] = 'to empfängst', + ['to'] = '~s~ zu ~b~', + ['by'] = '~s~ von ~b~', + ['imp_invalid_quantity'] = 'Aktion nicht möglich, ungültige Anzahl', + ['imp_invalid_amount'] = 'Aktion nicht möglich, ungültiger Betrag', + ['delete_five_min'] = '~r~löschen~s~ in 5 Minuten', + ['threw'] = 'du ~r~wirfst weg~s~', + ['rec_salary'] = 'du hast dein Gehalt erhalten: ', + ['act_imp'] = 'Aktion nicht möglich', + -- Commands + ['setjob'] = 'assign a job to a user', + ['id_param'] = 'the ID of the player', + ['setjob_param2'] = 'the job you wish to assign', + ['setjob_param3'] = 'the job level', + ['load_ipl'] = 'load IPL', + ['unload_ipl'] = 'unload IPL', + ['play_anim'] = 'play animation', + ['play_emote'] = 'play emote', + ['spawn_car'] = 'spawn a car', + ['spawn_car_param'] = 'name of car', + ['givemoney'] = 'give money', + ['money_amount'] = 'amount of money', + ['invalid_account'] = 'invalid account', + ['account'] = 'account', + ['giveaccountmoney'] = 'give account money', + ['invalid_item'] = 'invalid item', + ['item'] = 'item', + ['giveitem'] = 'give item', + ['weapon'] = 'weapon', + ['giveweapon'] = 'give weapon', + -- Weapons + ['weapon_knife'] = 'Messer', + ['weapon_nightstick'] = 'Schlagstock', + ['weapon_hammer'] = 'Hammer', + ['weapon_bat'] = 'Schläger', + ['weapon_golfclub'] = 'Golfschläger', + ['weapon_crowbar'] = 'Brecheisen', + ['weapon_pistol'] = 'Pistole', + ['weapon_combatpistol'] = 'Kampfpistole', + ['weapon_appistol'] = 'AP Pistole', + ['weapon_pistol50'] = 'Pistole .50', + ['weapon_microsmg'] = 'Mikro SMG', + ['weapon_smg'] = 'SMG', + ['weapon_assaultsmg'] = 'Kampf SMG', + ['weapon_assaultrifle'] = 'Kampfgewehr', + ['weapon_carbinerifle'] = 'Karabinergewehr', + ['weapon_advancedrifle'] = 'Advancedgewehr', + ['weapon_mg'] = 'MG', + ['weapon_combatmg'] = 'Kampf MG', + ['weapon_pumpshotgun'] = 'Pumpgun', + ['weapon_sawnoffshotgun'] = 'Abgesägte Schrotflinte', + ['weapon_assaultshotgun'] = 'Kampf Schrotflinte', + ['weapon_bullpupshotgun'] = 'Bullpup Schrotflinte', + ['weapon_stungun'] = 'Tazer', + ['weapon_sniperrifle'] = 'Scharfschützengewehr', + ['weapon_heavysniper'] = 'Schweres Sniper', + ['weapon_remotesniper'] = 'Remote sniper', + ['weapon_grenadelauncher'] = 'Granatwerfer', + ['weapon_rpg'] = 'RPG', + ['weapon_stinger'] = 'Stinger', + ['weapon_minigun'] = 'Minigun', + ['weapon_grenade'] = 'Granate', + ['weapon_stickybomb'] = 'Haftbombe', + ['weapon_smokegrenade'] = 'Rauchgranate', + ['weapon_bzgas'] = 'BZ Gas', + ['weapon_molotov'] = 'Molotov Cocktail', + ['weapon_fireextinguisher'] = 'Feuerlöscher', + ['weapon_petrolcan'] = 'Benzinkanister', + ['weapon_digiscanner'] = 'Digiscanner', + ['weapon_ball'] = 'Ball', + ['weapon_snspistol'] = 'SNS Pistole', + ['weapon_bottle'] = 'Flasche', + ['weapon_gusenberg'] = 'Gusenberg', + ['weapon_specialcarbine'] = 'Spezialkarabiner', + ['weapon_heavypistol'] = 'Schwere Pistole', + ['weapon_bullpuprifle'] = 'Bullpupgewehr', + ['weapon_dagger'] = 'Dolch', + ['weapon_vintagepistol'] = 'Vintage Pistole', + ['weapon_firework'] = 'Feuerwerk', + ['weapon_musket'] = 'Muskete', + ['weapon_heavyshotgun'] = 'Schwere Schrotflinte', + ['weapon_marksmanrifle'] = 'Marksmangewehr', + ['weapon_hominglauncher'] = 'Homing Launcher', + ['weapon_proxmine'] = 'Annäherungsmine', + ['weapon_snowball'] = 'Schneeball', + ['weapon_flaregun'] = 'Leuchtpistole', + ['weapon_garbagebag'] = 'Müllsack', + ['weapon_handcuffs'] = 'Handschellen', + ['weapon_combatpdw'] = 'Kampf PDW', + ['weapon_marksmanpistol'] = 'Marksman Pistole', + ['weapon_knuckle'] = 'Schlagring', + ['weapon_hatchet'] = 'Axt', + ['weapon_railgun'] = 'Railgun', + ['weapon_machete'] = 'Machete', + ['weapon_machinepistol'] = 'Maschinenpistole', + ['weapon_switchblade'] = 'Klappmesser', + ['weapon_revolver'] = 'Schwerer Revolver', + ['weapon_dbshotgun'] = 'Doppelläufige Schrotflinte', + ['weapon_compactrifle'] = 'Kampfgewehr', + ['weapon_autoshotgun'] = 'Auto Shotgun', + ['weapon_battleaxe'] = 'Kampfaxt', + ['weapon_compactlauncher'] = 'Kompakt Launcher', + ['weapon_minismg'] = 'Mini SMG', + ['weapon_pipebomb'] = 'Rohrbombe', + ['weapon_poolcue'] = 'Kö', + ['weapon_wrench'] = 'Rohrzange', + ['weapon_flashlight'] = 'Taschenlampe', + ['gadget_nightvision'] = 'Nachtsichtgerät', + ['gadget_parachute'] = 'Fallschirm', +} diff --git a/resources/[essential]/es_extended/locales/en.lua b/resources/[essential]/es_extended/locales/en.lua index 6f1c10b4..2ded07f6 100644 --- a/resources/[essential]/es_extended/locales/en.lua +++ b/resources/[essential]/es_extended/locales/en.lua @@ -1,126 +1,126 @@ Locales['en'] = { - ['inventory'] = 'inventory', - ['use'] = 'use', - ['give'] = 'give', - ['remove'] = 'remove', - ['return'] = 'return', - ['amount'] = 'amount', - ['amount_invalid'] = 'invalid amount', - ['players_nearby'] = 'no players nearby', - ['ex_inv_lim'] = 'action not possible, exceeding invetory limit for ~b~', - ['yougave'] = 'you gave', - ['youreceived'] = 'you received', - ['to'] = '~s~ to ~b~', - ['by'] = '~s~ by ~b~', - ['imp_invalid_quantity'] = 'action impossible, invalid quantity', - ['imp_invalid_amount'] = 'action impossible, invalid amount', - ['delete_five_min'] = '~r~delete~s~ in 5 minutes', - ['threw'] = 'you ~r~threw~s~', - ['rec_salary'] = 'you received your salary: ', - ['act_imp'] = 'action impossible', - -- Commands - ['setjob'] = 'assign a job to a user', - ['id_param'] = 'the ID of the player', - ['setjob_param2'] = 'the job you wish to assign', - ['setjob_param3'] = 'the job level', - ['load_ipl'] = 'load IPL', - ['unload_ipl'] = 'unload IPL', - ['play_anim'] = 'play animation', - ['play_emote'] = 'play emote', - ['spawn_car'] = 'spawn a car', - ['spawn_car_param'] = 'name of car', - ['delete_vehicle'] = 'deletes Vehicle', - ['delete_veh_param'] = 'press enter', - ['spawn_object'] = 'spawn object', - ['spawn_ped'] = 'spawn ped', - ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', - ['givemoney'] = 'give money', - ['money_amount'] = 'amount of money', - ['invalid_account'] = 'invalid account', - ['account'] = 'account', - ['giveaccountmoney'] = 'give account money', - ['invalid_item'] = 'invalid item', - ['item'] = 'item', - ['giveitem'] = 'give item', - ['weapon'] = 'weapon', - ['giveweapon'] = 'give weapon', - -- Weapons - ['weapon_knife'] = 'knife', - ['weapon_nightstick'] = 'nightstick', - ['weapon_hammer'] = 'hammer', - ['weapon_bat'] = 'bat', - ['weapon_golfclub'] = 'golf club', - ['weapon_crowbar'] = 'crow bar', - ['weapon_pistol'] = 'pistol', - ['weapon_combatpistol'] = 'combat pistol', - ['weapon_appistol'] = 'ap pistol', - ['weapon_pistol50'] = 'pistol .50', - ['weapon_microsmg'] = 'micro smg', - ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'assault smg', - ['weapon_assaultrifle'] = 'assault rifle', - ['weapon_carbinerifle'] = 'carbine rifle', - ['weapon_advancedrifle'] = 'advanced rifle', - ['weapon_mg'] = 'mg', - ['weapon_combatmg'] = 'combat mg', - ['weapon_pumpshotgun'] = 'pump shotgun', - ['weapon_sawnoffshotgun'] = 'sawed off shotgun', - ['weapon_assaultshotgun'] = 'assault shotgun', - ['weapon_bullpupshotgun'] = 'bullpup shotgun', - ['weapon_stungun'] = 'tazer', - ['weapon_sniperrifle'] = 'sniper rifle', - ['weapon_heavysniper'] = 'heavy sniper', - ['weapon_remotesniper'] = 'remote sniper', - ['weapon_grenadelauncher'] = 'grenade launcher', - ['weapon_rpg'] = 'rocket launcher', - ['weapon_stinger'] = 'stinger', - ['weapon_minigun'] = 'minigun', - ['weapon_grenade'] = 'grenade', - ['weapon_stickybomb'] = 'sticky bomb', - ['weapon_smokegrenade'] = 'smoke grenade', - ['weapon_bzgas'] = 'bz gas', - ['weapon_molotov'] = 'molotov cocktail', - ['weapon_fireextinguisher'] = 'fire extinguisher', - ['weapon_petrolcan'] = 'jerrycan', - ['weapon_digiscanner'] = 'digiscanner', - ['weapon_ball'] = 'ball', - ['weapon_snspistol'] = 'sns pistol', - ['weapon_bottle'] = 'bottle', - ['weapon_gusenberg'] = 'gusenberg sweeper', - ['weapon_specialcarbine'] = 'special carbine', - ['weapon_heavypistol'] = 'heavy pistol', - ['weapon_bullpuprifle'] = 'bullpup rifle', - ['weapon_dagger'] = 'dagger', - ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_firework'] = 'firework', - ['weapon_musket'] = 'musket', - ['weapon_heavyshotgun'] = 'heavy shotgun', - ['weapon_marksmanrifle'] = 'marksman rifle', - ['weapon_hominglauncher'] = 'homing launcher', - ['weapon_proxmine'] = 'proximity mine', - ['weapon_snowball'] = 'snow ball', - ['weapon_flaregun'] = 'flaregun', - ['weapon_garbagebag'] = 'garbage bag', - ['weapon_handcuffs'] = 'handcuffs', - ['weapon_combatpdw'] = 'combat pdw', - ['weapon_marksmanpistol'] = 'marksman pistol', - ['weapon_knuckle'] = 'knuckledusters', - ['weapon_hatchet'] = 'hatchet', - ['weapon_railgun'] = 'railgun', - ['weapon_machete'] = 'machete', - ['weapon_machinepistol'] = 'machine pistol', - ['weapon_switchblade'] = 'switchblade', - ['weapon_revolver'] = 'heavy revolver', - ['weapon_dbshotgun'] = 'double barrel shotgun', - ['weapon_compactrifle'] = 'compact rifle', - ['weapon_autoshotgun'] = 'auto shotgun', - ['weapon_battleaxe'] = 'battle axe', - ['weapon_compactlauncher'] = 'compact launcher', - ['weapon_minismg'] = 'mini smg', - ['weapon_pipebomb'] = 'pipe bomb', - ['weapon_poolcue'] = 'pool cue', - ['weapon_wrench'] = 'pipe wrench', - ['weapon_flashlight'] = 'flashlight', - ['gadget_nightvision'] = 'night vision', - ['gadget_parachute'] = 'parachute', + ['inventory'] = 'inventory', + ['use'] = 'use', + ['give'] = 'give', + ['remove'] = 'remove', + ['return'] = 'return', + ['amount'] = 'amount', + ['amount_invalid'] = 'invalid amount', + ['players_nearby'] = 'no players nearby', + ['ex_inv_lim'] = 'action not possible, exceeding invetory limit for ~b~', + ['yougave'] = 'you gave', + ['youreceived'] = 'you received', + ['to'] = '~s~ to ~b~', + ['by'] = '~s~ by ~b~', + ['imp_invalid_quantity'] = 'action impossible, invalid quantity', + ['imp_invalid_amount'] = 'action impossible, invalid amount', + ['delete_five_min'] = '~r~delete~s~ in 5 minutes', + ['threw'] = 'you ~r~threw~s~', + ['rec_salary'] = 'you received your salary: ', + ['act_imp'] = 'action impossible', + -- Commands + ['setjob'] = 'assign a job to a user', + ['id_param'] = 'the ID of the player', + ['setjob_param2'] = 'the job you wish to assign', + ['setjob_param3'] = 'the job level', + ['load_ipl'] = 'load IPL', + ['unload_ipl'] = 'unload IPL', + ['play_anim'] = 'play animation', + ['play_emote'] = 'play emote', + ['spawn_car'] = 'spawn a car', + ['spawn_car_param'] = 'name of car', + ['delete_vehicle'] = 'deletes Vehicle', + ['delete_veh_param'] = 'press enter', + ['spawn_object'] = 'spawn object', + ['spawn_ped'] = 'spawn ped', + ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', + ['givemoney'] = 'give money', + ['money_amount'] = 'amount of money', + ['invalid_account'] = 'invalid account', + ['account'] = 'account', + ['giveaccountmoney'] = 'give account money', + ['invalid_item'] = 'invalid item', + ['item'] = 'item', + ['giveitem'] = 'give item', + ['weapon'] = 'weapon', + ['giveweapon'] = 'give weapon', + -- Weapons + ['weapon_knife'] = 'knife', + ['weapon_nightstick'] = 'nightstick', + ['weapon_hammer'] = 'hammer', + ['weapon_bat'] = 'bat', + ['weapon_golfclub'] = 'golf club', + ['weapon_crowbar'] = 'crow bar', + ['weapon_pistol'] = 'pistol', + ['weapon_combatpistol'] = 'combat pistol', + ['weapon_appistol'] = 'ap pistol', + ['weapon_pistol50'] = 'pistol .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'assault smg', + ['weapon_assaultrifle'] = 'assault rifle', + ['weapon_carbinerifle'] = 'carbine rifle', + ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'combat mg', + ['weapon_pumpshotgun'] = 'pump shotgun', + ['weapon_sawnoffshotgun'] = 'sawed off shotgun', + ['weapon_assaultshotgun'] = 'assault shotgun', + ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'sniper rifle', + ['weapon_heavysniper'] = 'heavy sniper', + ['weapon_remotesniper'] = 'remote sniper', + ['weapon_grenadelauncher'] = 'grenade launcher', + ['weapon_rpg'] = 'rocket launcher', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'grenade', + ['weapon_stickybomb'] = 'sticky bomb', + ['weapon_smokegrenade'] = 'smoke grenade', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'molotov cocktail', + ['weapon_fireextinguisher'] = 'fire extinguisher', + ['weapon_petrolcan'] = 'jerrycan', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'ball', + ['weapon_snspistol'] = 'sns pistol', + ['weapon_bottle'] = 'bottle', + ['weapon_gusenberg'] = 'gusenberg sweeper', + ['weapon_specialcarbine'] = 'special carbine', + ['weapon_heavypistol'] = 'heavy pistol', + ['weapon_bullpuprifle'] = 'bullpup rifle', + ['weapon_dagger'] = 'dagger', + ['weapon_vintagepistol'] = 'vintage pistol', + ['weapon_firework'] = 'firework', + ['weapon_musket'] = 'musket', + ['weapon_heavyshotgun'] = 'heavy shotgun', + ['weapon_marksmanrifle'] = 'marksman rifle', + ['weapon_hominglauncher'] = 'homing launcher', + ['weapon_proxmine'] = 'proximity mine', + ['weapon_snowball'] = 'snow ball', + ['weapon_flaregun'] = 'flaregun', + ['weapon_garbagebag'] = 'garbage bag', + ['weapon_handcuffs'] = 'handcuffs', + ['weapon_combatpdw'] = 'combat pdw', + ['weapon_marksmanpistol'] = 'marksman pistol', + ['weapon_knuckle'] = 'knuckledusters', + ['weapon_hatchet'] = 'hatchet', + ['weapon_railgun'] = 'railgun', + ['weapon_machete'] = 'machete', + ['weapon_machinepistol'] = 'machine pistol', + ['weapon_switchblade'] = 'switchblade', + ['weapon_revolver'] = 'heavy revolver', + ['weapon_dbshotgun'] = 'double barrel shotgun', + ['weapon_compactrifle'] = 'compact rifle', + ['weapon_autoshotgun'] = 'auto shotgun', + ['weapon_battleaxe'] = 'battle axe', + ['weapon_compactlauncher'] = 'compact launcher', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'pipe bomb', + ['weapon_poolcue'] = 'pool cue', + ['weapon_wrench'] = 'pipe wrench', + ['weapon_flashlight'] = 'flashlight', + ['gadget_nightvision'] = 'night vision', + ['gadget_parachute'] = 'parachute', } diff --git a/resources/[essential]/es_extended/locales/fr.lua b/resources/[essential]/es_extended/locales/fr.lua index 1fb41d49..ca81613a 100644 --- a/resources/[essential]/es_extended/locales/fr.lua +++ b/resources/[essential]/es_extended/locales/fr.lua @@ -1,126 +1,126 @@ Locales['fr'] = { - ['inventory'] = 'inventaire', - ['use'] = 'utiliser', - ['give'] = 'donner', - ['remove'] = 'jeter', - ['return'] = 'retour', - ['amount'] = 'quantité', - ['amount_invalid'] = 'montant invalide', - ['players_nearby'] = 'aucun joueur à proximité', - ['ex_inv_lim'] = 'action impossible, depassement de la limite d\'inventaire pour ~b~', - ['yougave'] = 'vous avez donné', - ['youreceived'] = 'vous avez reçu', - ['to'] = '~s~ à ~b~', - ['by'] = '~s~ par ~b~', - ['imp_invalid_quantity'] = 'action impossible, ~r~quantité invalide', - ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', - ['delete_five_min'] = '~r~suppression~s~ dans 5 minutes', - ['threw'] = 'vous avez ~r~jeté~s~', - ['rec_salary'] = 'vous avez reçu votre salaire : ', - ['act_imp'] = 'action impossible', - -- Commands - ['setjob'] = 'assigner job', - ['id_param'] = 'identification du joueur', - ['setjob_param2'] = 'le travail que vous souhaitez assigner', - ['setjob_param3'] = 'le niveau d\'emploi', - ['load_ipl'] = 'charger IPL', - ['unload_ipl'] = 'décharger IPL', - ['play_anim'] = 'jouer animation', - ['play_emote'] = 'jouer emote', - ['spawn_car'] = 'spawn un véhicule', - ['spawn_car_param'] = 'nom de la voiture', - ['delete_vehicle'] = 'supprimer le véhicule', - ['delete_veh_param'] = 'appuyez sur Entrée', - ['spawn_object'] = 'engendre un objet', - ['spawn_ped'] = 'spawn ped', - ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', - ['givemoney'] = 'donner de l\'argent', - ['money_amount'] = 'somme d\'argent', - ['invalid_account'] = 'compete invalide', - ['account'] = 'compte', - ['giveaccountmoney'] = 'donner de l\'argent au compte', - ['invalid_item'] = 'item invalide', - ['item'] = 'article', - ['giveitem'] = 'donner un article', - ['weapon'] = 'arme', - ['giveweapon'] = 'donner de l\'arme', - -- Weapons - ['weapon_knife'] = 'couteau', - ['weapon_nightstick'] = 'matraque', - ['weapon_hammer'] = 'marteau', - ['weapon_bat'] = 'bat', - ['weapon_golfclub'] = 'club de golfe', - ['weapon_crowbar'] = 'pied de biche', - ['weapon_pistol'] = 'pistolet', - ['weapon_combatpistol'] = 'pistolet de combat', - ['weapon_appistol'] = 'pistolet automatique', - ['weapon_pistol50'] = 'pistolet calibre 50', - ['weapon_microsmg'] = 'micro smg', - ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'smg d\'assaut', - ['weapon_assaultrifle'] = 'fusil d\'assaut', - ['weapon_carbinerifle'] = 'carabine d\'assaut', - ['weapon_advancedrifle'] = 'fusil avancé', - ['weapon_mg'] = 'mitrailleuse', - ['weapon_combatmg'] = 'mitrailleuse de combat', - ['weapon_pumpshotgun'] = 'fusil à pompe', - ['weapon_sawnoffshotgun'] = 'carabine à canon scié', - ['weapon_assaultshotgun'] = 'carabine d\'assaut', - ['weapon_bullpupshotgun'] = 'carabine bullpup', - ['weapon_stungun'] = 'tazer', - ['weapon_sniperrifle'] = 'fusil de sniper', - ['weapon_heavysniper'] = 'fusil de sniper lourd', - ['weapon_remotesniper'] = 'fusil de sniper à distance', - ['weapon_grenadelauncher'] = 'lance-grenade', - ['weapon_rpg'] = 'lance-rocket', - ['weapon_stinger'] = 'lance-missile stinger', - ['weapon_minigun'] = 'minigun', - ['weapon_grenade'] = 'grenade', - ['weapon_stickybomb'] = 'bombe collante', - ['weapon_smokegrenade'] = 'grenade fumigène', - ['weapon_bzgas'] = 'grenade à gaz bz', - ['weapon_molotov'] = 'cocktail molotov', - ['weapon_fireextinguisher'] = 'extincteur', - ['weapon_petrolcan'] = 'jerrican d\'essence', - ['weapon_digiscanner'] = 'digiscanner', - ['weapon_ball'] = 'balle', - ['weapon_snspistol'] = 'pistolet sns', - ['weapon_bottle'] = 'bouteille', - ['weapon_gusenberg'] = 'balayeuse gusenberg', - ['weapon_specialcarbine'] = 'carabine spéciale', - ['weapon_heavypistol'] = 'pistolet lourd', - ['weapon_bullpuprifle'] = 'fusil bullpup', - ['weapon_dagger'] = 'poignard', - ['weapon_vintagepistol'] = 'pistolet vintage', - ['weapon_firework'] = 'feu d\'artifice', - ['weapon_musket'] = 'mousquet', - ['weapon_heavyshotgun'] = 'fusil à pompe lourd', - ['weapon_marksmanrifle'] = 'fusil marksman', - ['weapon_hominglauncher'] = 'lance tête-chercheuse', - ['weapon_proxmine'] = 'mine de proximité', - ['weapon_snowball'] = 'boule de neige', - ['weapon_flaregun'] = 'lance fusée de détresse', - ['weapon_garbagebag'] = 'sac poubelle', - ['weapon_handcuffs'] = 'menottes', - ['weapon_combatpdw'] = 'arme de défense personnelle', - ['weapon_marksmanpistol'] = 'pistolet marksman', - ['weapon_knuckle'] = 'poing américain', - ['weapon_hatchet'] = 'hachette', - ['weapon_railgun'] = 'canon éléctrique', - ['weapon_machete'] = 'machetta', - ['weapon_machinepistol'] = 'pistolet mitrailleur', - ['weapon_switchblade'] = 'couteau à cran d\'arrêt', - ['weapon_revolver'] = 'revolver', - ['weapon_dbshotgun'] = 'fusil à pompe double canon', - ['weapon_compactrifle'] = 'fusil compact', - ['weapon_autoshotgun'] = 'fusil à pompe automatique', - ['weapon_battleaxe'] = 'hache de combat', - ['weapon_compactlauncher'] = 'lanceur compact', - ['weapon_minismg'] = 'mini smg', - ['weapon_pipebomb'] = 'bombe tuyau', - ['weapon_poolcue'] = 'queue de billard', - ['weapon_wrench'] = 'clé', - ['weapon_flashlight'] = 'lampe torche', - ['gadget_nightvision'] = 'vision nocturne', - ['gadget_parachute'] = 'parachute', + ['inventory'] = 'inventaire', + ['use'] = 'utiliser', + ['give'] = 'donner', + ['remove'] = 'jeter', + ['return'] = 'retour', + ['amount'] = 'quantité', + ['amount_invalid'] = 'montant invalide', + ['players_nearby'] = 'aucun joueur à proximité', + ['ex_inv_lim'] = 'action impossible, depassement de la limite d\'inventaire pour ~b~', + ['yougave'] = 'vous avez donné', + ['youreceived'] = 'vous avez reçu', + ['to'] = '~s~ à ~b~', + ['by'] = '~s~ par ~b~', + ['imp_invalid_quantity'] = 'action impossible, ~r~quantité invalide', + ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', + ['delete_five_min'] = '~r~suppression~s~ dans 5 minutes', + ['threw'] = 'vous avez ~r~jeté~s~', + ['rec_salary'] = 'vous avez reçu votre salaire : ', + ['act_imp'] = 'action impossible', + -- Commands + ['setjob'] = 'assigner job', + ['id_param'] = 'identification du joueur', + ['setjob_param2'] = 'le travail que vous souhaitez assigner', + ['setjob_param3'] = 'le niveau d\'emploi', + ['load_ipl'] = 'charger IPL', + ['unload_ipl'] = 'décharger IPL', + ['play_anim'] = 'jouer animation', + ['play_emote'] = 'jouer emote', + ['spawn_car'] = 'spawn un véhicule', + ['spawn_car_param'] = 'nom de la voiture', + ['delete_vehicle'] = 'supprimer le véhicule', + ['delete_veh_param'] = 'appuyez sur Entrée', + ['spawn_object'] = 'engendre un objet', + ['spawn_ped'] = 'spawn ped', + ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', + ['givemoney'] = 'donner de l\'argent', + ['money_amount'] = 'somme d\'argent', + ['invalid_account'] = 'compete invalide', + ['account'] = 'compte', + ['giveaccountmoney'] = 'donner de l\'argent au compte', + ['invalid_item'] = 'item invalide', + ['item'] = 'article', + ['giveitem'] = 'donner un article', + ['weapon'] = 'arme', + ['giveweapon'] = 'donner de l\'arme', + -- Weapons + ['weapon_knife'] = 'couteau', + ['weapon_nightstick'] = 'matraque', + ['weapon_hammer'] = 'marteau', + ['weapon_bat'] = 'bat', + ['weapon_golfclub'] = 'club de golfe', + ['weapon_crowbar'] = 'pied de biche', + ['weapon_pistol'] = 'pistolet', + ['weapon_combatpistol'] = 'pistolet de combat', + ['weapon_appistol'] = 'pistolet automatique', + ['weapon_pistol50'] = 'pistolet calibre 50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'smg d\'assaut', + ['weapon_assaultrifle'] = 'fusil d\'assaut', + ['weapon_carbinerifle'] = 'carabine d\'assaut', + ['weapon_advancedrifle'] = 'fusil avancé', + ['weapon_mg'] = 'mitrailleuse', + ['weapon_combatmg'] = 'mitrailleuse de combat', + ['weapon_pumpshotgun'] = 'fusil à pompe', + ['weapon_sawnoffshotgun'] = 'carabine à canon scié', + ['weapon_assaultshotgun'] = 'carabine d\'assaut', + ['weapon_bullpupshotgun'] = 'carabine bullpup', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'fusil de sniper', + ['weapon_heavysniper'] = 'fusil de sniper lourd', + ['weapon_remotesniper'] = 'fusil de sniper à distance', + ['weapon_grenadelauncher'] = 'lance-grenade', + ['weapon_rpg'] = 'lance-rocket', + ['weapon_stinger'] = 'lance-missile stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'grenade', + ['weapon_stickybomb'] = 'bombe collante', + ['weapon_smokegrenade'] = 'grenade fumigène', + ['weapon_bzgas'] = 'grenade à gaz bz', + ['weapon_molotov'] = 'cocktail molotov', + ['weapon_fireextinguisher'] = 'extincteur', + ['weapon_petrolcan'] = 'jerrican d\'essence', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'balle', + ['weapon_snspistol'] = 'pistolet sns', + ['weapon_bottle'] = 'bouteille', + ['weapon_gusenberg'] = 'balayeuse gusenberg', + ['weapon_specialcarbine'] = 'carabine spéciale', + ['weapon_heavypistol'] = 'pistolet lourd', + ['weapon_bullpuprifle'] = 'fusil bullpup', + ['weapon_dagger'] = 'poignard', + ['weapon_vintagepistol'] = 'pistolet vintage', + ['weapon_firework'] = 'feu d\'artifice', + ['weapon_musket'] = 'mousquet', + ['weapon_heavyshotgun'] = 'fusil à pompe lourd', + ['weapon_marksmanrifle'] = 'fusil marksman', + ['weapon_hominglauncher'] = 'lance tête-chercheuse', + ['weapon_proxmine'] = 'mine de proximité', + ['weapon_snowball'] = 'boule de neige', + ['weapon_flaregun'] = 'lance fusée de détresse', + ['weapon_garbagebag'] = 'sac poubelle', + ['weapon_handcuffs'] = 'menottes', + ['weapon_combatpdw'] = 'arme de défense personnelle', + ['weapon_marksmanpistol'] = 'pistolet marksman', + ['weapon_knuckle'] = 'poing américain', + ['weapon_hatchet'] = 'hachette', + ['weapon_railgun'] = 'canon éléctrique', + ['weapon_machete'] = 'machetta', + ['weapon_machinepistol'] = 'pistolet mitrailleur', + ['weapon_switchblade'] = 'couteau à cran d\'arrêt', + ['weapon_revolver'] = 'revolver', + ['weapon_dbshotgun'] = 'fusil à pompe double canon', + ['weapon_compactrifle'] = 'fusil compact', + ['weapon_autoshotgun'] = 'fusil à pompe automatique', + ['weapon_battleaxe'] = 'hache de combat', + ['weapon_compactlauncher'] = 'lanceur compact', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'bombe tuyau', + ['weapon_poolcue'] = 'queue de billard', + ['weapon_wrench'] = 'clé', + ['weapon_flashlight'] = 'lampe torche', + ['gadget_nightvision'] = 'vision nocturne', + ['gadget_parachute'] = 'parachute', } diff --git a/resources/[essential]/es_extended/server/classes/player.lua b/resources/[essential]/es_extended/server/classes/player.lua index 6a29f4f1..b7d365b4 100644 --- a/resources/[essential]/es_extended/server/classes/player.lua +++ b/resources/[essential]/es_extended/server/classes/player.lua @@ -1,426 +1,426 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, lastPosition) - local self = {} + local self = {} - self.player = player - self.accounts = accounts - self.inventory = inventory - self.job = job - self.loadout = loadout - self.name = name - self.lastPosition = lastPosition + 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.source = self.player.get('source') + self.identifier = self.player.get('identifier') - 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.setMoney = function(m) + self.player.setMoney(m) + end - self.getAccounts = function() + self.getMoney = function() + return self.player.get('money') + end - local accounts = {} + self.setBankBalance = function(m) + self.player.setBankBalance(m) + end - 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 + self.getBank = function() + return self.player.get('bank') + end - 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 + self.getCoords = function() + return self.player.get('coords') + end - return accounts + self.setCoords = function(x, y, z) + self.player.coords = {x = x, y = y, z = z} + end - end - - self.getAccount = function(a) + self.kick = function(r) + self.player.kick(r) + end - if a == 'bank' then - - return { - name = 'bank', - money = self.get('bank'), - label = Config.AccountLabels['bank'] - } + self.addMoney = function(m) + self.player.addMoney(m) + end - end + self.removeMoney = function(m) + self.player.removeMoney(m) + end - for i=1, #self.accounts, 1 do - if self.accounts[i].name == a then - return self.accounts[i] - end - end - end + self.addBank = function(m) + self.player.addBank(m) + end - self.getInventory = function() - return self.inventory - end + self.removeBank = function(m) + self.player.removeBank(m) + end - self.getJob = function() - return self.job - end + self.displayMoney = function(m) + self.player.displayMoney(m) + end - self.getLoadout = function() - return self.loadout - end + self.displayBank = function(m) + self.player.displayBank(m) + end - self.getName = function() - return self.name - end + self.setSessionVar = function(key, value) + self.player.setSessionVar(key, value) + end - self.getLastPosition = function() - return self.lastPosition - end + self.getSessionVar = function(k) + return self.player.getSessionVar(k) + end - self.getMissingAccounts = function(cb) - - MySQL.Async.fetchAll( - 'SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', - { - ['@identifier'] = self.getIdentifier() - }, - function(result) + self.getPermissions = function() + return self.player.getPermissions() + end - local missingAccounts = {}; + self.setPermissions = function(p) + self.player.setPermissions(p) + end - for i=1, #Config.Accounts, 1 do + self.getIdentifier = function() + return self.player.getIdentifier() + end - if Config.Accounts[i] ~= 'bank' then + self.getGroup = function() + return self.player.getGroup() + end - local found = false + self.set = function(k, v) + self.player.set(k, v) + end - for j=1, #result, 1 do - if Config.Accounts[i] == result[j].name then - found = true - end - end + self.get = function(k) + return self.player.get(k) + end - if not found then - table.insert(missingAccounts, Config.Accounts[i]) - end + self.getPlayer = function() + return self.player + end - end + self.getAccounts = function() - end + local accounts = {} - cb(missingAccounts) + for i=1, #Config.Accounts, 1 do - end - ) + if Config.Accounts[i] == 'bank' then - end + table.insert(accounts, { + name = 'bank', + money = self.get('bank'), + label = Config.AccountLabels['bank'] + }) - self.createAccounts = function(missingAccounts, cb) + else - 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 + 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 + end - self.setAccountMoney = function(a, m) - - local account = self.getAccount(a) - local prevMoney = account.money - local newMoney = m + return accounts - account.money = newMoney + end - if a == 'bank' then - self.set('bank', newMoney) - end + self.getAccount = function(a) - TriggerClientEvent('esx:setAccountMoney', self.source, account) - end + if a == 'bank' then - self.addAccountMoney = function(a, m) + return { + name = 'bank', + money = self.get('bank'), + label = Config.AccountLabels['bank'] + } - local account = self.getAccount(a) - local newMoney = account.money + m + end - account.money = newMoney + for i=1, #self.accounts, 1 do + if self.accounts[i].name == a then + return self.accounts[i] + end + end + end - if a == 'bank' then - self.set('bank', newMoney) - end + self.getInventory = function() + return self.inventory + end - TriggerClientEvent('esx:setAccountMoney', self.source, account) - end + self.getJob = function() + return self.job + end - self.removeAccountMoney = function(a, m) - local account = self.getAccount(a) - local newMoney = account.money - m + self.getLoadout = function() + return self.loadout + end - account.money = newMoney + self.getName = function() + return self.name + end - if a == 'bank' then - self.set('bank', newMoney) - end + self.getLastPosition = function() + return self.lastPosition + end - TriggerClientEvent('esx:setAccountMoney', self.source, account) - end + self.getMissingAccounts = function(cb) - self.getInventoryItem = function(name) - - for i=1, #self.inventory, 1 do - if self.inventory[i].name == name then - return self.inventory[i] - end - end + MySQL.Async.fetchAll( + 'SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', + { + ['@identifier'] = self.getIdentifier() + }, + function(result) - end + local missingAccounts = {}; - self.addInventoryItem = function(name, count) + for i=1, #Config.Accounts, 1 do - local item = self.getInventoryItem(name) - local newCount = item.count + count - item.count = newCount + if Config.Accounts[i] ~= 'bank' then - TriggerEvent("esx:onAddInventoryItem", self.source, item, count) - TriggerClientEvent("esx:addInventoryItem", self.source, item, count) + local found = false - end + for j=1, #result, 1 do + if Config.Accounts[i] == result[j].name then + found = true + end + end - self.removeInventoryItem = function(name, count) - - local item = self.getInventoryItem(name) - local newCount = item.count - count - item.count = newCount + if not found then + table.insert(missingAccounts, Config.Accounts[i]) + end - TriggerEvent("esx:onRemoveInventoryItem", self.source, item, count) - TriggerClientEvent("esx:removeInventoryItem", self.source, item, count) + end - end + end - self.setInventoryItem = function(name, count) - - local item = self.getInventoryItem(name) - local oldCount = item.count - item.count = count - - if oldCount > item.count then - TriggerEvent("esx:onRemoveInventoryItem", self.source, item, oldCount - item.count ) - TriggerClientEvent("esx:removeInventoryItem", self.source, item, oldCount - item.count ) - else - TriggerEvent("esx:onAddInventoryItem", self.source, item, item.count - oldCount) - TriggerClientEvent("esx:addInventoryItem", self.source, item, item.count - oldCount) - end - - end - - self.setJob = function(name, grade) - - local lastJob = json.decode(json.encode(self.job)) + cb(missingAccounts) - MySQL.Async.fetchAll( - 'SELECT * FROM `jobs` WHERE `name` = @name', - { - ['@name'] = name - }, - function(result) + end + ) - self.job['id'] = result[1].id - self.job['name'] = result[1].name - self.job['label'] = result[1].label + end - MySQL.Async.fetchAll( - 'SELECT * FROM `job_grades` WHERE `job_name` = @job_name AND `grade` = @grade', - { - ['@job_name'] = name, - ['@grade'] = grade - }, - function(result) + self.createAccounts = function(missingAccounts, cb) - 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 + 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 - self.job['skin_male'] = nil - self.job['skin_female'] = nil + end - if result[1].skin_male ~= nil then - self.job['skin_male'] = json.decode(result[1].skin_male) - end + self.setAccountMoney = function(a, m) - if result[1].skin_female ~= nil then - self.job['skin_female'] = json.decode(result[1].skin_female) - end + local account = self.getAccount(a) + local prevMoney = account.money + local newMoney = m - TriggerEvent("esx:setJob", self.source, self.job, lastJob) - TriggerClientEvent("esx:setJob", self.source, self.job) + account.money = newMoney - 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 - - local foundWeapon = false - - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - foundWeapon = true - end - end - - if not foundWeapon then - table.insert(self.loadout, { - name = weaponName, - ammo = ammon, - label = weaponLabel - }) - 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 - - local foundWeapon = false - - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - table.remove(self.loadout, i) - break - end - end - - TriggerClientEvent('esx:removeWeapon', self.source, weaponName) - TriggerClientEvent("esx:removeInventoryItem", self.source, {label = weaponLabel}, 1) - end - - return self - -end \ No newline at end of file + 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.setInventoryItem = function(name, count) + + local item = self.getInventoryItem(name) + local oldCount = item.count + item.count = count + + if oldCount > item.count then + TriggerEvent("esx:onRemoveInventoryItem", self.source, item, oldCount - item.count ) + TriggerClientEvent("esx:removeInventoryItem", self.source, item, oldCount - item.count ) + else + TriggerEvent("esx:onAddInventoryItem", self.source, item, item.count - oldCount) + TriggerClientEvent("esx:addInventoryItem", self.source, item, item.count - oldCount) + end + + end + + self.setJob = function(name, grade) + + local lastJob = json.decode(json.encode(self.job)) + + 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 + + TriggerEvent("esx:setJob", self.source, self.job, lastJob) + 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 + + local foundWeapon = false + + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + foundWeapon = true + end + end + + if not foundWeapon then + table.insert(self.loadout, { + name = weaponName, + ammo = ammon, + label = weaponLabel + }) + 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 + + local foundWeapon = false + + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + table.remove(self.loadout, i) + break + end + end + + TriggerClientEvent('esx:removeWeapon', self.source, weaponName) + TriggerClientEvent("esx:removeInventoryItem", self.source, {label = weaponLabel}, 1) + end + + return self + +end diff --git a/resources/[essential]/es_extended/server/commands.lua b/resources/[essential]/es_extended/server/commands.lua index 814c6d4a..755dea95 100644 --- a/resources/[essential]/es_extended/server/commands.lua +++ b/resources/[essential]/es_extended/server/commands.lua @@ -1,136 +1,136 @@ 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]) - }) + 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.") + 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])) + 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.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('setjob'), params = {{name = "id", help = _U('id_param')}, {name = "job", help = _U('setjob_param2')}, {name = "grade_id", help = _U('setjob_param3')}}}) TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:loadIPL', -1, args[2]) + TriggerClientEvent('esx:loadIPL', -1, args[2]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('load_ipl')}) TriggerEvent('es:addGroupCommand', 'unloadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:unloadIPL', -1, args[2]) + TriggerClientEvent('esx:unloadIPL', -1, args[2]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('unload_ipl')}) TriggerEvent('es:addGroupCommand', 'playanim', 'admin', function(source, args, user) - TriggerClientEvent('esx:playAnim', -1, args[2], args[3]) + TriggerClientEvent('esx:playAnim', -1, args[2], args[3]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('play_anim')}) TriggerEvent('es:addGroupCommand', 'playemote', 'admin', function(source, args, user) - TriggerClientEvent('esx:playEmote', -1, args[2]) + TriggerClientEvent('esx:playEmote', -1, args[2]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('play_emote')}) TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnVehicle', source, args[2]) + TriggerClientEvent('esx:spawnVehicle', source, args[2]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) - TriggerClientEvent('esx:deleteVehicle', source) + TriggerClientEvent('esx:deleteVehicle', source) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('delete_vehicle'), params = {{name = "car", help = _U('delete_veh_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnPed', source, args[2]) + TriggerClientEvent('esx:spawnPed', source, args[2]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_ped'), params = {{name = "name", help = _U('spawn_ped_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnObject', source, args[2]) + TriggerClientEvent('esx:spawnObject', source, args[2]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_object'), params = {{name = "name"}}}) TriggerEvent('es:addGroupCommand', 'givemoney', 'admin', function(source, args, user) - - local _source = source - local xPlayer = ESX.GetPlayerFromId(args[2]) - local amount = tonumber(args[3]) - - if amount ~= nil then - xPlayer.addMoney(amount) - else - TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) - end + + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[2]) + local amount = tonumber(args[3]) + + if amount ~= nil then + xPlayer.addMoney(amount) + else + TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) + end end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('givemoney'), params = {{name = "id", help = _U('id_param')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) - - local _source = source - local xPlayer = ESX.GetPlayerFromId(args[2]) - local account = args[3] - local amount = tonumber(args[4]) - - if amount ~= nil then - if xPlayer.getAccount(account) ~= nil then - xPlayer.addAccountMoney(account, amount) - else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) - end - else - TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) - end + + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[2]) + local account = args[3] + local amount = tonumber(args[4]) + + if amount ~= nil then + if xPlayer.getAccount(account) ~= nil then + xPlayer.addAccountMoney(account, amount) + else + TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) + end + else + TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) + end end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('giveaccountmoney'), params = {{name = "id", help = _U('id_param')}, {name = "account", help = _U('account')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) - - local _source = source - local xPlayer = ESX.GetPlayerFromId(args[2]) - local item = args[3] - local count = (args[4] == nil and 1 or tonumber(args[4])) - - if count ~= nil then - if xPlayer.getInventoryItem(item) ~= nil then - xPlayer.addInventoryItem(item, count) - else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) - end - else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) - end + + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[2]) + local item = args[3] + local count = (args[4] == nil and 1 or tonumber(args[4])) + + if count ~= nil then + if xPlayer.getInventoryItem(item) ~= nil then + xPlayer.addInventoryItem(item, count) + else + TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) + end + else + TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) + end end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('giveitem'), params = {{name = "id", help = _U('id_param')}, {name = "item", help = _U('item')}, {name = "amount", help = _U('amount')}}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) - - local xPlayer = ESX.GetPlayerFromId(args[2]) - local weaponName = string.upper(args[3]) - - xPlayer.addWeapon(weaponName, 1000) + + local xPlayer = ESX.GetPlayerFromId(args[2]) + local weaponName = string.upper(args[3]) + + xPlayer.addWeapon(weaponName, 1000) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) \ No newline at end of file + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) diff --git a/resources/[essential]/es_extended/server/common.lua b/resources/[essential]/es_extended/server/common.lua index f8b1c72d..4bde6732 100644 --- a/resources/[essential]/es_extended/server/common.lua +++ b/resources/[essential]/es_extended/server/common.lua @@ -9,93 +9,93 @@ ESX.Pickups = {} ESX.PickupId = 0 AddEventHandler('esx:getSharedObject', function(cb) - cb(ESX) + cb(ESX) end) function getSharedObject() - return ESX + return ESX end AddEventHandler('onMySQLReady', function () - MySQL.Async.fetchAll( - 'SELECT * FROM items', - {}, - function(result) + 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, - rare = (result[i].rare == 1 and true or false), - canRemove = (result[i].can_remove == 1 and true or false), - } - end + for i=1, #result, 1 do + ESX.Items[result[i].name] = { + label = result[i].label, + limit = result[i].limit, + rare = (result[i].rare == 1 and true or false), + canRemove = (result[i].can_remove == 1 and true or false), + } + end - end - ) + end + ) end) AddEventHandler('esx:playerLoaded', function(source) - local xPlayer = ESX.GetPlayerFromId(source) - local accounts = {} - local items = {} - local xPlayerAccounts = xPlayer.getAccounts() - local xPlayerItems = xPlayer.getInventory() + local xPlayer = ESX.GetPlayerFromId(source) + local accounts = {} + local items = {} + local xPlayerAccounts = xPlayer.getAccounts() + local xPlayerItems = xPlayer.getInventory() - for i=1, #xPlayerAccounts, 1 do - accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money - end + for i=1, #xPlayerAccounts, 1 do + accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money + end - for i=1, #xPlayerItems, 1 do - items[xPlayerItems[i].name] = xPlayerItems[i].count - end + for i=1, #xPlayerItems, 1 do + items[xPlayerItems[i].name] = xPlayerItems[i].count + end - ESX.LastPlayerData[source] = { - accounts = accounts, - items = items - } + ESX.LastPlayerData[source] = { + accounts = accounts, + items = items + } end) RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) - RconPrint(msg .. "\n") + RconPrint(msg .. "\n") end) RegisterServerEvent('esx:triggerServerCallback') AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) - - local _source = source - - ESX.TriggerServerCallback(name, requestID, _source, function(...) - TriggerClientEvent('esx:serverCallback', _source, requestId, ...) - end, ...) + + local _source = source + + ESX.TriggerServerCallback(name, requestID, _source, function(...) + TriggerClientEvent('esx:serverCallback', _source, requestId, ...) + end, ...) end) -- SetTimeout CreateThread(function() - while true do + while true do - Wait(0) + Wait(0) - local currTime = os.clock() * 1000 + local currTime = os.clock() * 1000 - for i=1, #ESX.TimeoutCallbacks, 1 do + for i=1, #ESX.TimeoutCallbacks, 1 do - if ESX.TimeoutCallbacks[i] ~= nil then + if ESX.TimeoutCallbacks[i] ~= nil then - if currTime >= ESX.TimeoutCallbacks[i].time then - ESX.TimeoutCallbacks[i].cb() - ESX.TimeoutCallbacks[i] = nil - end + if currTime >= ESX.TimeoutCallbacks[i].time then + ESX.TimeoutCallbacks[i].cb() + ESX.TimeoutCallbacks[i] = nil + end - end + end - end + end - end + end end) diff --git a/resources/[essential]/es_extended/server/functions.lua b/resources/[essential]/es_extended/server/functions.lua index ffbbe1dd..f5dfb5ed 100644 --- a/resources/[essential]/es_extended/server/functions.lua +++ b/resources/[essential]/es_extended/server/functions.lua @@ -5,13 +5,13 @@ 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.Trace = function(str) - if Config.EnableDebug then - print('ESX> ' .. str) - end + if Config.EnableDebug then + print('ESX> ' .. str) + end end ESX.GetConfig = function() - return Config + return Config end ESX.GetRandomString = function(length) @@ -23,224 +23,224 @@ ESX.GetRandomString = function(length) else return '' end - + end ESX.SetTimeout = function(msec, cb) - table.insert(ESX.TimeoutCallbacks, { - time = os.clock() * 1000 + msec, - cb = cb - }) - return #ESX.TimeoutCallbacks + table.insert(ESX.TimeoutCallbacks, { + time = os.clock() * 1000 + msec, + cb = cb + }) + return #ESX.TimeoutCallbacks end ESX.ClearTimeout = function(i) - ESX.TimeoutCallbacks[i] = nil + ESX.TimeoutCallbacks[i] = nil end ESX.RegisterServerCallback = function(name, cb) - ESX.ServerCallbacks[name] = cb + ESX.ServerCallbacks[name] = cb end ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) - - if ESX.ServerCallbacks[name] ~= nil then - ESX.ServerCallbacks[name](source, cb, ...) - else - print('TriggerServerCallback => [' .. name .. '] does not exists') - end + + if ESX.ServerCallbacks[name] ~= nil then + ESX.ServerCallbacks[name](source, cb, ...) + else + print('TriggerServerCallback => [' .. name .. '] does not exists') + end end ESX.SavePlayer = function(xPlayer, cb) - local asyncTasks = {} - xPlayer.lastPosition = xPlayer.get('coords') + local asyncTasks = {} + xPlayer.lastPosition = xPlayer.get('coords') - -- User accounts - for i=1, #xPlayer.accounts, 1 do + -- User accounts + for i=1, #xPlayer.accounts, 1 do - if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then + if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then - table.insert(asyncTasks, function(cb) + 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 - ) + 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) - ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] = xPlayer.accounts[i].money + ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] = xPlayer.accounts[i].money - end + end - end + end - -- Inventory items - for i=1, #xPlayer.inventory, 1 do + -- Inventory items + for i=1, #xPlayer.inventory, 1 do - if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then + if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then - table.insert(asyncTasks, function(cb) + 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 - ) + 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) - ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] = xPlayer.inventory[i].count + ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] = xPlayer.inventory[i].count - end + end - end + end - -- Job, loadout and position - table.insert(asyncTasks, function(cb) + -- 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 - ) + 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) + end) - Async.parallel(asyncTasks, function(results) - - RconPrint('[SAVED] ' .. xPlayer.name .. "\n") + Async.parallel(asyncTasks, function(results) - if cb ~= nil then - cb() - end + RconPrint('[SAVED] ' .. xPlayer.name .. "\n") - end) + if cb ~= nil then + cb() + end + + end) end ESX.SavePlayers = function(cb) - local asyncTasks = {} - local xPlayers = ESX.GetPlayers() + local asyncTasks = {} + local xPlayers = ESX.GetPlayers() - for i=1, #xPlayers, 1 do - table.insert(asyncTasks, function(cb) - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - ESX.SavePlayer(xPlayer, cb) - end) - end + for i=1, #xPlayers, 1 do + table.insert(asyncTasks, function(cb) + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + ESX.SavePlayer(xPlayer, cb) + end) + end - Async.parallelLimit(asyncTasks, 8, function(results) - - RconPrint('[SAVED] All players' .. "\n") + Async.parallelLimit(asyncTasks, 8, function(results) - if cb ~= nil then - cb() - end + RconPrint('[SAVED] All players' .. "\n") - end) + if cb ~= nil then + cb() + end + + end) end ESX.StartDBSync = function() - - function saveData() - ESX.SavePlayers() - SetTimeout(10 * 60 * 1000, saveData) - end - SetTimeout(10 * 60 * 1000, saveData) + function saveData() + ESX.SavePlayers() + SetTimeout(10 * 60 * 1000, saveData) + end + + SetTimeout(10 * 60 * 1000, saveData) end ESX.GetPlayers = function() - local sources = {} + local sources = {} - for k,v in pairs(ESX.Players) do - table.insert(sources, k) - end + for k,v in pairs(ESX.Players) do + table.insert(sources, k) + end - return sources + return sources end ESX.GetPlayerFromId = function(source) - return ESX.Players[tonumber(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 + + 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 + ESX.UsableItemsCallbacks[item] = cb end ESX.UseItem = function(source, item) - ESX.UsableItemsCallbacks[item](source) + ESX.UsableItemsCallbacks[item](source) end ESX.GetWeaponList = function() - return Config.Weapons + 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 + + 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.CreatePickup = function(type, name, count, label, player) - local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) + local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) - ESX.Pickups[pickupId] = { - type = type, - name = name, - count = count - } + ESX.Pickups[pickupId] = { + type = type, + name = name, + count = count + } - TriggerClientEvent('esx:pickup', -1, pickupId, label, player) + TriggerClientEvent('esx:pickup', -1, pickupId, label, player) - ESX.PickupId = pickupId + ESX.PickupId = pickupId end diff --git a/resources/[essential]/es_extended/server/main.lua b/resources/[essential]/es_extended/server/main.lua index e30ae8ef..7db15f56 100644 --- a/resources/[essential]/es_extended/server/main.lua +++ b/resources/[essential]/es_extended/server/main.lua @@ -1,587 +1,587 @@ AddEventHandler('es:playerLoaded', function(source, _player) - local _source = source - local tasks = {} + local _source = source + local tasks = {} - local userData = { - accounts = {}, - inventory = {}, - job = {}, - loadout = {}, - playerName = GetPlayerName(_source), - lastPosition = nil - } + local userData = { + accounts = {}, + inventory = {}, + job = {}, + loadout = {}, + playerName = GetPlayerName(_source), + lastPosition = nil + } - TriggerEvent('es:getPlayerFromId', _source, function(player) + TriggerEvent('es:getPlayerFromId', _source, function(player) - -- Update user name in DB - table.insert(tasks, function(cb) + -- 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 - ) + MySQL.Async.execute( + 'UPDATE `users` SET `name` = @name WHERE `identifier` = @identifier', + { + ['@identifier'] = player.getIdentifier(), + ['@name'] = userData.playerName + }, + function(rowsChanged) + cb() + end + ) - end) + end) - -- Get accounts - table.insert(tasks, function(cb) + -- Get accounts + table.insert(tasks, function(cb) - MySQL.Async.fetchAll( - 'SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', - { - ['@identifier'] = player.getIdentifier() - }, - function(accounts) + 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 + 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 + end - cb() - end - ) + cb() + end + ) - end) + end) - -- Get Inventory - table.insert(tasks, function(cb) + -- 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, - rare = ESX.Items[inventory[i].item].rare, - canRemove = ESX.Items[inventory[i].item].canRemove, - }) - end + MySQL.Async.fetchAll( + 'SELECT * FROM `user_inventory` WHERE `identifier` = @identifier', + { + ['@identifier'] = player.getIdentifier() + }, + function(inventory) - for k,v in pairs(ESX.Items) do + 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, + rare = ESX.Items[inventory[i].item].rare, + canRemove = ESX.Items[inventory[i].item].canRemove, + }) + end - local found = false + for k,v in pairs(ESX.Items) do - for j=1, #userData.inventory, 1 do - if userData.inventory[j].name == k then - found = true - break - end - end + local found = false - 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, - rare = ESX.Items[k].rare, - canRemove = ESX.Items[k].canRemove, - }) + for j=1, #userData.inventory, 1 do + if userData.inventory[j].name == k then + found = true + break + end + end - MySQL.Async.execute( - 'INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', - { - ['@identifier'] = player.getIdentifier(), - ['@item'] = k, - ['@count'] = 0 - } - ) + if not found then - end + table.insert(userData.inventory, { + name = k, + count = 0, + label = ESX.Items[k].label, + limit = ESX.Items[k].limit, + usable = ESX.UsableItemsCallbacks[k] ~= nil, + rare = ESX.Items[k].rare, + canRemove = ESX.Items[k].canRemove, + }) - end + MySQL.Async.execute( + 'INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', + { + ['@identifier'] = player.getIdentifier(), + ['@item'] = k, + ['@count'] = 0 + } + ) - table.sort(userData.inventory, function(a,b) - return a.label < b.label - end) + end - cb() - end - ) + end - end) + table.sort(userData.inventory, function(a,b) + return a.label < b.label + end) - -- Get job and loadout - table.insert(tasks, function(cb) + cb() + end + ) - local tasks2 = {} + end) - -- Get job name, grade and last position - table.insert(tasks2, function(cb2) + -- Get job and loadout + table.insert(tasks, function(cb) - 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 + local tasks2 = {} - if result[1].loadout ~= nil then - userData.loadout = json.decode(result[1].loadout) - end + -- Get job name, grade and last position + table.insert(tasks2, function(cb2) - if result[1].position ~= nil then - userData.lastPosition = json.decode(result[1].position) - end + MySQL.Async.fetchAll( + 'SELECT * FROM `users` WHERE `identifier` = @identifier', + { + ['@identifier'] = player.getIdentifier() + }, + function(result) - cb2() + userData.job['name'] = result[1].job + userData.job['grade'] = result[1].job_grade - end - ) + if result[1].loadout ~= nil then + userData.loadout = json.decode(result[1].loadout) + end - end) + if result[1].position ~= nil then + userData.lastPosition = json.decode(result[1].position) + end - -- Get job label - table.insert(tasks2, function(cb2) + cb2() - MySQL.Async.fetchAll( - 'SELECT * FROM `jobs` WHERE `name` = @name', - { - ['@name'] = userData.job.name - }, - function(result) - - userData.job['label'] = result[1].label + end + ) - cb2() + end) - end - ) + -- Get job label + table.insert(tasks2, function(cb2) - end) + MySQL.Async.fetchAll( + 'SELECT * FROM `jobs` WHERE `name` = @name', + { + ['@name'] = userData.job.name + }, + function(result) - -- Get job grade data - table.insert(tasks2, function(cb2) + userData.job['label'] = result[1].label - 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 + cb2() - userData.job['skin_male'] = {} - userData.job['skin_female'] = {} + end + ) - if result[1].skin_male ~= nil then - userData.job['skin_male'] = json.decode(result[1].skin_male) - end + end) - if result[1].skin_female ~= nil then - userData.job['skin_female'] = json.decode(result[1].skin_female) - end + -- Get job grade data + table.insert(tasks2, function(cb2) - 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) - end - ) + userData.job['grade_name'] = result[1].name + userData.job['grade_label'] = result[1].label + userData.job['grade_salary'] = result[1].salary - end) + userData.job['skin_male'] = {} + userData.job['skin_female'] = {} - Async.series(tasks2, cb) + if result[1].skin_male ~= nil then + userData.job['skin_male'] = json.decode(result[1].skin_male) + end - end) + if result[1].skin_female ~= nil then + userData.job['skin_female'] = json.decode(result[1].skin_female) + end - -- Run Tasks - Async.parallel(tasks, function(results) + cb2() - local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.lastPosition) + end + ) - xPlayer.getMissingAccounts(function(missingAccounts) + end) - if #missingAccounts > 0 then + Async.series(tasks2, cb) - for i=1, #missingAccounts, 1 do - table.insert(xPlayer.accounts, { - name = missingAccounts[i], - money = 0, - label = Config.AccountLabels[missingAccounts[i]] - }) - end + end) - xPlayer.createAccounts(missingAccounts) - end + -- Run Tasks + Async.parallel(tasks, function(results) - ESX.Players[_source] = xPlayer + local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.lastPosition) - TriggerEvent('esx:playerLoaded', _source) - - TriggerClientEvent('esx:playerLoaded', _source, { - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') - }) - - xPlayer.player.displayMoney(xPlayer.get('money')) + xPlayer.getMissingAccounts(function(missingAccounts) - end) + if #missingAccounts > 0 then - end) + for i=1, #missingAccounts, 1 do + table.insert(xPlayer.accounts, { + name = missingAccounts[i], + money = 0, + label = Config.AccountLabels[missingAccounts[i]] + }) + end - end) + xPlayer.createAccounts(missingAccounts) + end + + ESX.Players[_source] = xPlayer + + TriggerEvent('esx:playerLoaded', _source) + + TriggerClientEvent('esx:playerLoaded', _source, { + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.get('money') + }) + + xPlayer.player.displayMoney(xPlayer.get('money')) + + end) + + end) + + end) end) AddEventHandler('playerDropped', function() - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) - if xPlayer ~= nil then - - TriggerEvent('esx:playerDropped', _source) - - ESX.SavePlayer(xPlayer, function() - ESX.Players[_source] = nil - ESX.LastPlayerData[_source] = nil - end) + if xPlayer ~= nil then - end + TriggerEvent('esx:playerDropped', _source) + + ESX.SavePlayer(xPlayer, function() + ESX.Players[_source] = nil + ESX.LastPlayerData[_source] = nil + end) + + end end) RegisterServerEvent('esx:updateLoadout') AddEventHandler('esx:updateLoadout', function(loadout) - local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.loadout = loadout + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.loadout = loadout end) RegisterServerEvent('esx:updateLastPosition') AddEventHandler('esx:updateLastPosition', function(position) - local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.lastPosition = position + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.lastPosition = position end) RegisterServerEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) - local _source = source + local _source = source - local sourceXPlayer = ESX.GetPlayerFromId(_source) - local targetXPlayer = ESX.GetPlayerFromId(target) - - if type == 'item_standard' then + local sourceXPlayer = ESX.GetPlayerFromId(_source) + local targetXPlayer = ESX.GetPlayerFromId(target) - local sourceItem = sourceXPlayer.getInventoryItem(itemName) - local targetItem = targetXPlayer.getInventoryItem(itemName) + if type == 'item_standard' then - if itemCount > 0 and sourceItem.count >= itemCount then + local sourceItem = sourceXPlayer.getInventoryItem(itemName) + local targetItem = targetXPlayer.getInventoryItem(itemName) - if targetItem.limit ~= -1 and (targetItem.count + itemCount) > targetItem.limit then - TriggerClientEvent('esx:showNotification', target, _U('ex_inv_lim') .. targetXPlayer.name) - else - sourceXPlayer.removeInventoryItem(itemName, itemCount) - targetXPlayer.addInventoryItem (itemName, itemCount) + if itemCount > 0 and sourceItem.count >= itemCount then - TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. _U('to') .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. _U('by') .. sourceXPlayer.name) - end + if targetItem.limit ~= -1 and (targetItem.count + itemCount) > targetItem.limit then + TriggerClientEvent('esx:showNotification', target, _U('ex_inv_lim') .. targetXPlayer.name) + else + sourceXPlayer.removeInventoryItem(itemName, itemCount) + targetXPlayer.addInventoryItem (itemName, itemCount) - else - TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_quantity')) - end + TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. _U('by') .. sourceXPlayer.name) + end - elseif type == 'item_money' then + else + TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_quantity')) + end - if itemCount > 0 and sourceXPlayer.player.get('money') >= itemCount then + elseif type == 'item_money' then - sourceXPlayer.removeMoney(itemCount) - targetXPlayer.addMoney(itemCount) + if itemCount > 0 and sourceXPlayer.player.get('money') >= itemCount then - TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' ~g~$' .. itemCount .. _U('to') .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' ~g~$' .. itemCount .. _U('by') .. sourceXPlayer.name) + sourceXPlayer.removeMoney(itemCount) + targetXPlayer.addMoney(itemCount) - else - TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_amount')) - end + TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' ~g~$' .. itemCount .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' ~g~$' .. itemCount .. _U('by') .. sourceXPlayer.name) - elseif type == 'item_account' then + else + TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_amount')) + end - if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then + elseif type == 'item_account' then - sourceXPlayer.removeAccountMoney(itemName, itemCount) - targetXPlayer.addAccountMoney(itemName, itemCount) + if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then - TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. _U('to') .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. _U('by') .. sourceXPlayer.name) + sourceXPlayer.removeAccountMoney(itemName, itemCount) + targetXPlayer.addAccountMoney(itemName, itemCount) - else - TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_amount')) - end + TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. _U('by') .. sourceXPlayer.name) - elseif type == 'item_weapon' then - - sourceXPlayer.removeWeapon(itemName) - targetXPlayer.addWeapon(itemName, itemCount) + else + TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_amount')) + end - local weaponLabel = itemName + elseif type == 'item_weapon' then - for i=1, #Config.Weapons, 1 do - if Config.Weapons[i].name == itemName then - weaponLabel = Config.Weapons[i].label - break - end - end + sourceXPlayer.removeWeapon(itemName) + targetXPlayer.addWeapon(itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' x1 ~g~' .. weaponLabel .. _U('to') .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' x1 ~g~' .. weaponLabel .. _U('by') .. sourceXPlayer.name) - end + 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, _U('yougave') .. ' x1 ~g~' .. weaponLabel .. _U('to') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' x1 ~g~' .. weaponLabel .. _U('by') .. sourceXPlayer.name) + end end) RegisterServerEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) - - local _source = source - if type == 'item_standard' then + local _source = source - if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) - else + if type == 'item_standard' then - local xPlayer = ESX.GetPlayerFromId(source) - local foundItem = nil + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + else - for i=1, #xPlayer.inventory, 1 do - if xPlayer.inventory[i].name == itemName then - foundItem = xPlayer.inventory[i] - end - end + local xPlayer = ESX.GetPlayerFromId(source) + local foundItem = nil - if itemCount > foundItem.count then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) - else - - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - - SetTimeout(Config.RemoveInventoryItemDelay, function() - - local remainingCount = xPlayer.getInventoryItem(itemName).count - local total = itemCount + for i=1, #xPlayer.inventory, 1 do + if xPlayer.inventory[i].name == itemName then + foundItem = xPlayer.inventory[i] + end + end - if remainingCount < itemCount then - total = remainingCount - end - - if total > 0 then - xPlayer.removeInventoryItem(itemName, total) - ESX.CreatePickup('item_standard', itemName, total, foundItem.label, _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) - end + if itemCount > foundItem.count then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + else - end) + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - end + SetTimeout(Config.RemoveInventoryItemDelay, function() - end + local remainingCount = xPlayer.getInventoryItem(itemName).count + local total = itemCount - elseif type == 'item_money' then + if remainingCount < itemCount then + total = remainingCount + end - if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else + if total > 0 then + xPlayer.removeInventoryItem(itemName, total) + ESX.CreatePickup('item_standard', itemName, total, foundItem.label, _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) + end - local xPlayer = ESX.GetPlayerFromId(source) + end) - if itemCount > xPlayer.player.get('money') then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else - - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - - SetTimeout(Config.RemoveInventoryItemDelay, function() - - local remainingCount = xPlayer.player.get('money') - local total = itemCount + end - if remainingCount < itemCount then - total = remainingCount - end - - if total > 0 then - xPlayer.removeMoney(total) - ESX.CreatePickup('item_money', 'money', total, 'Cash', _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) - end + end - end) + elseif type == 'item_money' then - end + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else - end + local xPlayer = ESX.GetPlayerFromId(source) - elseif type == 'item_account' then + if itemCount > xPlayer.player.get('money') then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else - if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - local xPlayer = ESX.GetPlayerFromId(source) + SetTimeout(Config.RemoveInventoryItemDelay, function() - if itemCount > xPlayer.getAccount(itemName).money then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else - - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - - SetTimeout(Config.RemoveInventoryItemDelay, function() - - local remainingCount = xPlayer.getAccount(itemName).money - local total = itemCount + local remainingCount = xPlayer.player.get('money') + local total = itemCount - if remainingCount < itemCount then - total = remainingCount - end - - if total > 0 then - xPlayer.removeAccountMoney(itemName, total) - ESX.CreatePickup('item_account', itemName, total, 'Cash', _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) - end + if remainingCount < itemCount then + total = remainingCount + end - end) + if total > 0 then + xPlayer.removeMoney(total) + ESX.CreatePickup('item_money', 'money', total, 'Cash', _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) + end - end + end) - end + end - elseif type == 'item_weapon' then + end - local xPlayer = ESX.GetPlayerFromId(source) - local weaponLabel = itemName - local weaponName = nil - local weaponPickup = nil + elseif type == 'item_account' then - for i=1, #Config.Weapons, 1 do - if Config.Weapons[i].name == itemName then - weaponLabel = Config.Weapons[i].label - weaponName = Config.Weapons[i].name - weaponPickup = 'PICKUP_'..weaponName - break - end - end + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else - SetTimeout(Config.RemoveInventoryItemDelay, function() - - xPlayer.removeWeapon(itemName) - - if Config.EnableWeaponPickup then - TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName) - end - - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' x1 ~g~' .. weaponLabel) - - end) + local xPlayer = ESX.GetPlayerFromId(source) - end + if itemCount > xPlayer.getAccount(itemName).money then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else + + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) + + 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) + ESX.CreatePickup('item_account', itemName, total, 'Cash', _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) + end + + end) + + end + + end + + elseif type == 'item_weapon' then + + local xPlayer = ESX.GetPlayerFromId(source) + local weaponLabel = itemName + local weaponName = nil + local weaponPickup = nil + + for i=1, #Config.Weapons, 1 do + if Config.Weapons[i].name == itemName then + weaponLabel = Config.Weapons[i].label + weaponName = Config.Weapons[i].name + weaponPickup = 'PICKUP_'..weaponName + break + end + end + + SetTimeout(Config.RemoveInventoryItemDelay, function() + + xPlayer.removeWeapon(itemName) + + if Config.EnableWeaponPickup then + TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName) + end + + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' x1 ~g~' .. weaponLabel) + + end) + + end end) RegisterServerEvent('esx:useItem') AddEventHandler('esx:useItem', function(itemName) - local xPlayer = ESX.GetPlayerFromId(source) - local count = xPlayer.getInventoryItem(itemName).count + local xPlayer = ESX.GetPlayerFromId(source) + local count = xPlayer.getInventoryItem(itemName).count - if count > 0 then - ESX.UseItem(source, itemName) - else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('act_imp')) - end + if count > 0 then + ESX.UseItem(source, itemName) + else + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('act_imp')) + end end) RegisterServerEvent('esx:onPickup') AddEventHandler('esx:onPickup', function(id) - local pickup = ESX.Pickups[id] - local xPlayer = ESX.GetPlayerFromId(source) + local pickup = ESX.Pickups[id] + local xPlayer = ESX.GetPlayerFromId(source) - if pickup.type == 'item_standard' then - xPlayer.addInventoryItem(pickup.name, pickup.count) - elseif pickup.type == 'item_money' then - xPlayer.addMoney(pickup.count) - elseif pickup.type == 'item_account' then - xPlayer.addAccountMoney(pickup.name, pickup.count) - end + if pickup.type == 'item_standard' then + xPlayer.addInventoryItem(pickup.name, pickup.count) + elseif pickup.type == 'item_money' then + xPlayer.addMoney(pickup.count) + elseif pickup.type == 'item_account' then + xPlayer.addAccountMoney(pickup.name, pickup.count) + end - TriggerClientEvent('esx:removePickup', -1, id) + TriggerClientEvent('esx:removePickup', -1, id) end) ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) - local xPlayer = ESX.GetPlayerFromId(source) + local xPlayer = ESX.GetPlayerFromId(source) - cb({ - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') - }) + cb({ + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.get('money') + }) end) ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target) - local xPlayer = ESX.GetPlayerFromId(target) + local xPlayer = ESX.GetPlayerFromId(target) - cb({ - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') - }) + cb({ + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.get('money') + }) end) TriggerEvent("es:addGroup", "jobmaster", "user", function(group) end) ESX.StartDBSync() -ESX.StartPayCheck() \ No newline at end of file +ESX.StartPayCheck() diff --git a/resources/[essential]/es_extended/server/paycheck.lua b/resources/[essential]/es_extended/server/paycheck.lua index f68818a4..69f3de3e 100644 --- a/resources/[essential]/es_extended/server/paycheck.lua +++ b/resources/[essential]/es_extended/server/paycheck.lua @@ -1,24 +1,24 @@ ESX.StartPayCheck = function() - function payCheck() + function payCheck() - local xPlayers = ESX.GetPlayers() + local xPlayers = ESX.GetPlayers() - for i=1, #xPlayers, 1 do + for i=1, #xPlayers, 1 do - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - if xPlayer.job.grade_salary > 0 then - xPlayer.addMoney(xPlayer.job.grade_salary) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) - end + if xPlayer.job.grade_salary > 0 then + xPlayer.addMoney(xPlayer.job.grade_salary) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) + end - end + end - SetTimeout(Config.PaycheckInterval, payCheck) + SetTimeout(Config.PaycheckInterval, payCheck) - end + end - SetTimeout(Config.PaycheckInterval, payCheck) + SetTimeout(Config.PaycheckInterval, payCheck) -end \ No newline at end of file +end From 98bb04f6635af41ad799a1708f499ed91776b64b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 14 Sep 2017 23:16:16 +0200 Subject: [PATCH 109/672] Update LICENSE.txt --- LICENSE.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LICENSE.txt b/LICENSE.txt index 30ace6a8..b2b6280b 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - {one line to give the program's name and a brief idea of what it does.} - Copyright (C) {year} {name of author} + fxserver-es_extended + Copyright (C) 2015 Jérémie N'gadi This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: - {project} Copyright (C) {year} {fullname} + fxserver-es_extended Copyright (C) 2015 Jérémie N'gadi This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. From 9ee7a5f61e56db87d7bd288306ff7d48cb4c59e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 15 Sep 2017 09:41:34 +0200 Subject: [PATCH 110/672] build(submodules): Update submodules Update sumbodules : async, esx_menu_default, esx_menu_list and esx_menu_dialog --- resources/[esx]/[ui]/esx_menu_default | 2 +- resources/[esx]/[ui]/esx_menu_dialog | 2 +- resources/[esx]/[ui]/esx_menu_list | 2 +- resources/async | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/[esx]/[ui]/esx_menu_default b/resources/[esx]/[ui]/esx_menu_default index b8b97530..4b1eae7a 160000 --- a/resources/[esx]/[ui]/esx_menu_default +++ b/resources/[esx]/[ui]/esx_menu_default @@ -1 +1 @@ -Subproject commit b8b9753005ac7636502a123f8d81cfb43d199d47 +Subproject commit 4b1eae7a25cbb5ff496c3471dc0560487284a46e diff --git a/resources/[esx]/[ui]/esx_menu_dialog b/resources/[esx]/[ui]/esx_menu_dialog index f3300e27..21c1051a 160000 --- a/resources/[esx]/[ui]/esx_menu_dialog +++ b/resources/[esx]/[ui]/esx_menu_dialog @@ -1 +1 @@ -Subproject commit f3300e27cb18d2a6b5d32bf9e36df0a398bd45ff +Subproject commit 21c1051a39184aa970528d8a435167860a092147 diff --git a/resources/[esx]/[ui]/esx_menu_list b/resources/[esx]/[ui]/esx_menu_list index c7303bfb..b96205cd 160000 --- a/resources/[esx]/[ui]/esx_menu_list +++ b/resources/[esx]/[ui]/esx_menu_list @@ -1 +1 @@ -Subproject commit c7303bfb6b533a032bb23aa2dca92db54b9ea2a6 +Subproject commit b96205cdf6f8350a8600a983660eb007eb4375ce diff --git a/resources/async b/resources/async index 90ea196b..1ced6286 160000 --- a/resources/async +++ b/resources/async @@ -1 +1 @@ -Subproject commit 90ea196bad6e9b5f82a8101758d186a22ee67a88 +Subproject commit 1ced6286328b04dc0d5466da1c559116b0a1f421 From 97adf4f97cc5f84911985a5878e2c95a03cc2601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 15 Sep 2017 14:26:56 +0200 Subject: [PATCH 111/672] build(submodules): Remove submodules + move everything at root --- .gitmodules | 12 ------------ .../es_extended/__resource.lua => __resource.lua | 0 .../es_extended/client => client}/common.lua | 0 .../es_extended/client => client}/entityiter.lua | 0 .../es_extended/client => client}/functions.lua | 0 .../es_extended/client => client}/main.lua | 0 .../es_extended/config.lua => config.lua | 0 .../config.weapons.lua => config.weapons.lua | 0 .../es_extended/html => html}/css/app.css | 0 .../es_extended/html => html}/fonts/bankgothic.ttf | Bin .../es_extended/html => html}/fonts/pdown.ttf | Bin .../es_extended/html => html}/img/accounts/bank.png | Bin .../html => html}/img/accounts/black_money.png | Bin .../es_extended/html => html}/img/cursor.png | Bin .../es_extended/html => html}/img/keys/enter.png | Bin .../es_extended/html => html}/img/keys/return.png | Bin .../[essential]/es_extended/html => html}/js/app.js | 0 .../es_extended/html => html}/js/mustache.min.js | 0 .../[essential]/es_extended/html => html}/ui.html | 0 .../es_extended/locale.lua => locale.lua | 0 .../es_extended/locales => locales}/br.lua | 0 .../es_extended/locales => locales}/de.lua | 0 .../es_extended/locales => locales}/en.lua | 0 .../es_extended/locales => locales}/fr.lua | 0 resources/[esx]/[ui]/esx_menu_default | 1 - resources/[esx]/[ui]/esx_menu_dialog | 1 - resources/[esx]/[ui]/esx_menu_list | 1 - resources/async | 1 - .../server => server}/classes/player.lua | 0 .../es_extended/server => server}/commands.lua | 0 .../es_extended/server => server}/common.lua | 0 .../es_extended/server => server}/functions.lua | 0 .../es_extended/server => server}/main.lua | 0 .../es_extended/server => server}/paycheck.lua | 0 34 files changed, 16 deletions(-) delete mode 100644 .gitmodules rename resources/[essential]/es_extended/__resource.lua => __resource.lua (100%) rename {resources/[essential]/es_extended/client => client}/common.lua (100%) rename {resources/[essential]/es_extended/client => client}/entityiter.lua (100%) rename {resources/[essential]/es_extended/client => client}/functions.lua (100%) rename {resources/[essential]/es_extended/client => client}/main.lua (100%) rename resources/[essential]/es_extended/config.lua => config.lua (100%) rename resources/[essential]/es_extended/config.weapons.lua => config.weapons.lua (100%) rename {resources/[essential]/es_extended/html => html}/css/app.css (100%) rename {resources/[essential]/es_extended/html => html}/fonts/bankgothic.ttf (100%) rename {resources/[essential]/es_extended/html => html}/fonts/pdown.ttf (100%) rename {resources/[essential]/es_extended/html => html}/img/accounts/bank.png (100%) rename {resources/[essential]/es_extended/html => html}/img/accounts/black_money.png (100%) rename {resources/[essential]/es_extended/html => html}/img/cursor.png (100%) rename {resources/[essential]/es_extended/html => html}/img/keys/enter.png (100%) rename {resources/[essential]/es_extended/html => html}/img/keys/return.png (100%) rename {resources/[essential]/es_extended/html => html}/js/app.js (100%) rename {resources/[essential]/es_extended/html => html}/js/mustache.min.js (100%) rename {resources/[essential]/es_extended/html => html}/ui.html (100%) rename resources/[essential]/es_extended/locale.lua => locale.lua (100%) rename {resources/[essential]/es_extended/locales => locales}/br.lua (100%) rename {resources/[essential]/es_extended/locales => locales}/de.lua (100%) rename {resources/[essential]/es_extended/locales => locales}/en.lua (100%) rename {resources/[essential]/es_extended/locales => locales}/fr.lua (100%) delete mode 160000 resources/[esx]/[ui]/esx_menu_default delete mode 160000 resources/[esx]/[ui]/esx_menu_dialog delete mode 160000 resources/[esx]/[ui]/esx_menu_list delete mode 160000 resources/async rename {resources/[essential]/es_extended/server => server}/classes/player.lua (100%) rename {resources/[essential]/es_extended/server => server}/commands.lua (100%) rename {resources/[essential]/es_extended/server => server}/common.lua (100%) rename {resources/[essential]/es_extended/server => server}/functions.lua (100%) rename {resources/[essential]/es_extended/server => server}/main.lua (100%) rename {resources/[essential]/es_extended/server => server}/paycheck.lua (100%) diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index b58eb350..00000000 --- a/.gitmodules +++ /dev/null @@ -1,12 +0,0 @@ -[submodule "resources/[esx]/[ui]/fxserver-esx_menu_default"] - path = resources/[esx]/[ui]/esx_menu_default - url = https://github.com/FXServer-ESX/fxserver-esx_menu_default -[submodule "resources/[esx]/[ui]/fxserver-esx_menu_list"] - path = resources/[esx]/[ui]/esx_menu_list - url = https://github.com/FXServer-ESX/fxserver-esx_menu_list -[submodule "resources/[esx]/[ui]/fxserver-esx_menu_dialog"] - path = resources/[esx]/[ui]/esx_menu_dialog - url = https://github.com/FXServer-ESX/fxserver-esx_menu_dialog -[submodule "resources/fxserver-async"] - path = resources/async - url = https://github.com/FXServer-ESX/fxserver-async diff --git a/resources/[essential]/es_extended/__resource.lua b/__resource.lua similarity index 100% rename from resources/[essential]/es_extended/__resource.lua rename to __resource.lua diff --git a/resources/[essential]/es_extended/client/common.lua b/client/common.lua similarity index 100% rename from resources/[essential]/es_extended/client/common.lua rename to client/common.lua diff --git a/resources/[essential]/es_extended/client/entityiter.lua b/client/entityiter.lua similarity index 100% rename from resources/[essential]/es_extended/client/entityiter.lua rename to client/entityiter.lua diff --git a/resources/[essential]/es_extended/client/functions.lua b/client/functions.lua similarity index 100% rename from resources/[essential]/es_extended/client/functions.lua rename to client/functions.lua diff --git a/resources/[essential]/es_extended/client/main.lua b/client/main.lua similarity index 100% rename from resources/[essential]/es_extended/client/main.lua rename to client/main.lua diff --git a/resources/[essential]/es_extended/config.lua b/config.lua similarity index 100% rename from resources/[essential]/es_extended/config.lua rename to config.lua diff --git a/resources/[essential]/es_extended/config.weapons.lua b/config.weapons.lua similarity index 100% rename from resources/[essential]/es_extended/config.weapons.lua rename to config.weapons.lua diff --git a/resources/[essential]/es_extended/html/css/app.css b/html/css/app.css similarity index 100% rename from resources/[essential]/es_extended/html/css/app.css rename to html/css/app.css diff --git a/resources/[essential]/es_extended/html/fonts/bankgothic.ttf b/html/fonts/bankgothic.ttf similarity index 100% rename from resources/[essential]/es_extended/html/fonts/bankgothic.ttf rename to html/fonts/bankgothic.ttf diff --git a/resources/[essential]/es_extended/html/fonts/pdown.ttf b/html/fonts/pdown.ttf similarity index 100% rename from resources/[essential]/es_extended/html/fonts/pdown.ttf rename to html/fonts/pdown.ttf diff --git a/resources/[essential]/es_extended/html/img/accounts/bank.png b/html/img/accounts/bank.png similarity index 100% rename from resources/[essential]/es_extended/html/img/accounts/bank.png rename to html/img/accounts/bank.png diff --git a/resources/[essential]/es_extended/html/img/accounts/black_money.png b/html/img/accounts/black_money.png similarity index 100% rename from resources/[essential]/es_extended/html/img/accounts/black_money.png rename to html/img/accounts/black_money.png diff --git a/resources/[essential]/es_extended/html/img/cursor.png b/html/img/cursor.png similarity index 100% rename from resources/[essential]/es_extended/html/img/cursor.png rename to html/img/cursor.png diff --git a/resources/[essential]/es_extended/html/img/keys/enter.png b/html/img/keys/enter.png similarity index 100% rename from resources/[essential]/es_extended/html/img/keys/enter.png rename to html/img/keys/enter.png diff --git a/resources/[essential]/es_extended/html/img/keys/return.png b/html/img/keys/return.png similarity index 100% rename from resources/[essential]/es_extended/html/img/keys/return.png rename to html/img/keys/return.png diff --git a/resources/[essential]/es_extended/html/js/app.js b/html/js/app.js similarity index 100% rename from resources/[essential]/es_extended/html/js/app.js rename to html/js/app.js diff --git a/resources/[essential]/es_extended/html/js/mustache.min.js b/html/js/mustache.min.js similarity index 100% rename from resources/[essential]/es_extended/html/js/mustache.min.js rename to html/js/mustache.min.js diff --git a/resources/[essential]/es_extended/html/ui.html b/html/ui.html similarity index 100% rename from resources/[essential]/es_extended/html/ui.html rename to html/ui.html diff --git a/resources/[essential]/es_extended/locale.lua b/locale.lua similarity index 100% rename from resources/[essential]/es_extended/locale.lua rename to locale.lua diff --git a/resources/[essential]/es_extended/locales/br.lua b/locales/br.lua similarity index 100% rename from resources/[essential]/es_extended/locales/br.lua rename to locales/br.lua diff --git a/resources/[essential]/es_extended/locales/de.lua b/locales/de.lua similarity index 100% rename from resources/[essential]/es_extended/locales/de.lua rename to locales/de.lua diff --git a/resources/[essential]/es_extended/locales/en.lua b/locales/en.lua similarity index 100% rename from resources/[essential]/es_extended/locales/en.lua rename to locales/en.lua diff --git a/resources/[essential]/es_extended/locales/fr.lua b/locales/fr.lua similarity index 100% rename from resources/[essential]/es_extended/locales/fr.lua rename to locales/fr.lua diff --git a/resources/[esx]/[ui]/esx_menu_default b/resources/[esx]/[ui]/esx_menu_default deleted file mode 160000 index 4b1eae7a..00000000 --- a/resources/[esx]/[ui]/esx_menu_default +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4b1eae7a25cbb5ff496c3471dc0560487284a46e diff --git a/resources/[esx]/[ui]/esx_menu_dialog b/resources/[esx]/[ui]/esx_menu_dialog deleted file mode 160000 index 21c1051a..00000000 --- a/resources/[esx]/[ui]/esx_menu_dialog +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 21c1051a39184aa970528d8a435167860a092147 diff --git a/resources/[esx]/[ui]/esx_menu_list b/resources/[esx]/[ui]/esx_menu_list deleted file mode 160000 index b96205cd..00000000 --- a/resources/[esx]/[ui]/esx_menu_list +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b96205cdf6f8350a8600a983660eb007eb4375ce diff --git a/resources/async b/resources/async deleted file mode 160000 index 1ced6286..00000000 --- a/resources/async +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1ced6286328b04dc0d5466da1c559116b0a1f421 diff --git a/resources/[essential]/es_extended/server/classes/player.lua b/server/classes/player.lua similarity index 100% rename from resources/[essential]/es_extended/server/classes/player.lua rename to server/classes/player.lua diff --git a/resources/[essential]/es_extended/server/commands.lua b/server/commands.lua similarity index 100% rename from resources/[essential]/es_extended/server/commands.lua rename to server/commands.lua diff --git a/resources/[essential]/es_extended/server/common.lua b/server/common.lua similarity index 100% rename from resources/[essential]/es_extended/server/common.lua rename to server/common.lua diff --git a/resources/[essential]/es_extended/server/functions.lua b/server/functions.lua similarity index 100% rename from resources/[essential]/es_extended/server/functions.lua rename to server/functions.lua diff --git a/resources/[essential]/es_extended/server/main.lua b/server/main.lua similarity index 100% rename from resources/[essential]/es_extended/server/main.lua rename to server/main.lua diff --git a/resources/[essential]/es_extended/server/paycheck.lua b/server/paycheck.lua similarity index 100% rename from resources/[essential]/es_extended/server/paycheck.lua rename to server/paycheck.lua From 210ed08402a224c6be0e488b30898a7f5772b766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 15 Sep 2017 14:32:10 +0200 Subject: [PATCH 112/672] docs(readme): Update README.txt with new instructions --- README.md | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 38dfcb62..e5505cb8 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,6 @@ -# fxserver-es_extended [WIP] +# es_extended FXServer ES Extended -[UPDATE] - -Since commit : https://github.com/FXServer-ESX/fxserver-es_extended/commit/ec1e8c0852b7461472dc9c332464ad55c81682e7 you have to add this SQL if you have already installed es_extended : -```sql -ALTER TABLE `items` - ADD COLUMN `rare` int(11) NOT NULL DEFAULT '0', - ADD COLUMN `can_remove` int(11) NOT NULL DEFAULT '1' -; -``` - [DISCORD] https://discord.me/fivem_esx @@ -39,15 +29,16 @@ Positions are saved in database and restored on spawn [INSTALLATION] ``` -git clone https://github.com/FXServer-ESX/fxserver-es_extended -cd fxserver-es_extended -git submodule init -git submodule update --recursive +cd in your ressources directory +git clone https://github.com/ESX-Org/es_extended [esssential]/es_extended +git clone https://github.com/ESX-Org/esx_menu-core [esx]/[ui]/esx_menu-core +git clone https://github.com/ESX-Org/esx_menu-list [esx]/[ui]/esx_menu-list +git clone https://github.com/ESX-Org/esx_menu-dialog [esx]/[ui]/esx_menu-dialog + ``` -1) Copy all folders inside resources to your server resources folder -2) Import es_extended.sql in your database -3) Add this in your server.cfg : +1) Import es_extended.sql in your database +2) Add this in your server.cfg : ``` start es_extended From 0bc401367504e88c2129fb601712ec9ab6fc73ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 15 Sep 2017 14:33:14 +0200 Subject: [PATCH 113/672] docs(readme): Fix readme --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e5505cb8..9da586f0 100644 --- a/README.md +++ b/README.md @@ -43,8 +43,8 @@ git clone https://github.com/ESX-Org/esx_menu-dialog [esx]/[ui]/esx_menu-dialog ``` start es_extended -start esx_menu_default -start esx_menu_list -start esx_menu_dialog +start esx_menu-core +start esx_menu-list +start esx_menu-dialog ``` From b11bd5f9936109e45617bb77927e7bca2c9a7ebf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 15 Sep 2017 14:35:27 +0200 Subject: [PATCH 114/672] docs(readme): Fix README.txt --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9da586f0..9fa63f57 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Positions are saved in database and restored on spawn ``` cd in your ressources directory -git clone https://github.com/ESX-Org/es_extended [esssential]/es_extended +git clone https://github.com/ESX-Org/es_extended [essential]/es_extended git clone https://github.com/ESX-Org/esx_menu-core [esx]/[ui]/esx_menu-core git clone https://github.com/ESX-Org/esx_menu-list [esx]/[ui]/esx_menu-list git clone https://github.com/ESX-Org/esx_menu-dialog [esx]/[ui]/esx_menu-dialog From 7c0c704d852840840cf06b3fd69a8692350db55b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 15 Sep 2017 14:56:23 +0200 Subject: [PATCH 115/672] docs(readme): Fix README.txt --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9fa63f57..dc04bd54 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Positions are saved in database and restored on spawn ``` cd in your ressources directory git clone https://github.com/ESX-Org/es_extended [essential]/es_extended -git clone https://github.com/ESX-Org/esx_menu-core [esx]/[ui]/esx_menu-core +git clone https://github.com/ESX-Org/esx_menu-core [esx]/[ui]/esx_menu-default git clone https://github.com/ESX-Org/esx_menu-list [esx]/[ui]/esx_menu-list git clone https://github.com/ESX-Org/esx_menu-dialog [esx]/[ui]/esx_menu-dialog @@ -43,7 +43,7 @@ git clone https://github.com/ESX-Org/esx_menu-dialog [esx]/[ui]/esx_menu-dialog ``` start es_extended -start esx_menu-core +start esx_menu-default start esx_menu-list start esx_menu-dialog ``` From fab9c176fe4c12b121c0b52a76f98bcd453568c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 15 Sep 2017 14:56:48 +0200 Subject: [PATCH 116/672] docs(readme): Fix README.txt --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc04bd54..edf221b8 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Positions are saved in database and restored on spawn ``` cd in your ressources directory git clone https://github.com/ESX-Org/es_extended [essential]/es_extended -git clone https://github.com/ESX-Org/esx_menu-core [esx]/[ui]/esx_menu-default +git clone https://github.com/ESX-Org/esx_menu-default [esx]/[ui]/esx_menu-default git clone https://github.com/ESX-Org/esx_menu-list [esx]/[ui]/esx_menu-list git clone https://github.com/ESX-Org/esx_menu-dialog [esx]/[ui]/esx_menu-dialog From a99c34cab20094db799bbe25dfaf4625bd155468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 15 Sep 2017 15:14:08 +0200 Subject: [PATCH 117/672] chore(resource): Add version --- __resource.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/__resource.lua b/__resource.lua index 26694ac3..3705566b 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,6 +2,8 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' +version '1.0.0' + server_scripts { '@async/async.lua', '@mysql-async/lib/MySQL.lua', From a7ca2f3557a6dee2e311eca52cdc646f4dc84e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 15 Sep 2017 17:37:57 +0200 Subject: [PATCH 118/672] docs(readme): Update README --- README.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index edf221b8..91ebddc8 100644 --- a/README.md +++ b/README.md @@ -28,15 +28,27 @@ Positions are saved in database and restored on spawn [INSTALLATION] +1) Using fvm ``` -cd in your ressources directory -git clone https://github.com/ESX-Org/es_extended [essential]/es_extended -git clone https://github.com/ESX-Org/esx_menu-default [esx]/[ui]/esx_menu-default -git clone https://github.com/ESX-Org/esx_menu-list [esx]/[ui]/esx_menu-list -git clone https://github.com/ESX-Org/esx_menu-dialog [esx]/[ui]/esx_menu-dialog +fvm install --save --folder=essential ESX-Org/es_extended +fvm install --save --folder=esx ESX-Org/esx_menu-default +fvm install --save --folder=esx ESX-Org/esx_menu-dialog +fvm install --save --folder=esx ESX-Org/esx_menu-list ``` +2) Manually +``` +- Download https://github.com/ESX-Org/es_extended/releases/latest +- Put in in [essential] directory +- Download https://github.com/ESX-Org/esx_menu-default/release/latest +- Put in in [esx] directory +- Download https://github.com/ESX-Org/esx_menu-dialog/release/latest +- Put in in [esx] directory +- Download https://github.com/ESX-Org/esx_menu-list/release/latest +- Put in in [esx] directory +``` + 1) Import es_extended.sql in your database 2) Add this in your server.cfg : From f9167091438097cde5bc2b088dc71c35867cbaca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 15 Sep 2017 17:38:44 +0200 Subject: [PATCH 119/672] docs(readme): Update README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 91ebddc8..85fd015f 100644 --- a/README.md +++ b/README.md @@ -40,13 +40,13 @@ fvm install --save --folder=esx ESX-Org/esx_menu-list 2) Manually ``` - Download https://github.com/ESX-Org/es_extended/releases/latest -- Put in in [essential] directory +- Put it in [essential] directory - Download https://github.com/ESX-Org/esx_menu-default/release/latest -- Put in in [esx] directory +- Put it in [esx] directory - Download https://github.com/ESX-Org/esx_menu-dialog/release/latest -- Put in in [esx] directory +- Put it in [esx] directory - Download https://github.com/ESX-Org/esx_menu-list/release/latest -- Put in in [esx] directory +- Put it in [esx] directory ``` 1) Import es_extended.sql in your database From fd377727e1f13c37b728545aa0a152f1d1720daa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 15 Sep 2017 17:39:32 +0200 Subject: [PATCH 120/672] docs(readme): Update README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 85fd015f..c0956f8c 100644 --- a/README.md +++ b/README.md @@ -41,11 +41,11 @@ fvm install --save --folder=esx ESX-Org/esx_menu-list ``` - Download https://github.com/ESX-Org/es_extended/releases/latest - Put it in [essential] directory -- Download https://github.com/ESX-Org/esx_menu-default/release/latest +- Download https://github.com/ESX-Org/esx_menu-default/releases/latest - Put it in [esx] directory -- Download https://github.com/ESX-Org/esx_menu-dialog/release/latest +- Download https://github.com/ESX-Org/esx_menu-dialog/releases/latest - Put it in [esx] directory -- Download https://github.com/ESX-Org/esx_menu-list/release/latest +- Download https://github.com/ESX-Org/esx_menu-list/releases/latest - Put it in [esx] directory ``` From 6b0a7c377917c229664f2c20988622f4c1fa5622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 16 Sep 2017 09:53:07 +0200 Subject: [PATCH 121/672] docs(readme): Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index c0956f8c..03ea36fa 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,9 @@ Positions are saved in database and restored on spawn 1) Using fvm ``` fvm install --save --folder=essential ESX-Org/es_extended -fvm install --save --folder=esx ESX-Org/esx_menu-default -fvm install --save --folder=esx ESX-Org/esx_menu-dialog -fvm install --save --folder=esx ESX-Org/esx_menu-list +fvm install --save --folder=esx ESX-Org/esx_menu_default +fvm install --save --folder=esx ESX-Org/esx_menu_dialog +fvm install --save --folder=esx ESX-Org/esx_menu_list ``` @@ -41,11 +41,11 @@ fvm install --save --folder=esx ESX-Org/esx_menu-list ``` - Download https://github.com/ESX-Org/es_extended/releases/latest - Put it in [essential] directory -- Download https://github.com/ESX-Org/esx_menu-default/releases/latest +- Download https://github.com/ESX-Org/esx_menu_default/releases/latest - Put it in [esx] directory -- Download https://github.com/ESX-Org/esx_menu-dialog/releases/latest +- Download https://github.com/ESX-Org/esx_menu_dialog/releases/latest - Put it in [esx] directory -- Download https://github.com/ESX-Org/esx_menu-list/releases/latest +- Download https://github.com/ESX-Org/esx_menu_list/releases/latest - Put it in [esx] directory ``` @@ -55,8 +55,8 @@ fvm install --save --folder=esx ESX-Org/esx_menu-list ``` start es_extended -start esx_menu-default -start esx_menu-list -start esx_menu-dialog +start esx_menu_default +start esx_menu_list +start esx_menu_dialog ``` From 73d3306e5218dfb867a46981a16dbbc871fc5b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 16 Sep 2017 09:54:12 +0200 Subject: [PATCH 122/672] docs(readme): Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 03ea36fa..40d6f6d4 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ fvm install --save --folder=esx ESX-Org/esx_menu_list ``` 2) Manually -``` + - Download https://github.com/ESX-Org/es_extended/releases/latest - Put it in [essential] directory - Download https://github.com/ESX-Org/esx_menu_default/releases/latest @@ -47,7 +47,7 @@ fvm install --save --folder=esx ESX-Org/esx_menu_list - Put it in [esx] directory - Download https://github.com/ESX-Org/esx_menu_list/releases/latest - Put it in [esx] directory -``` + 1) Import es_extended.sql in your database 2) Add this in your server.cfg : From 0b72491c8a48e8dffb54c26601a2225775f4a2c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 16 Sep 2017 10:30:09 +0200 Subject: [PATCH 123/672] docs(readme): Update README --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 40d6f6d4..ccc5d24c 100644 --- a/README.md +++ b/README.md @@ -25,10 +25,12 @@ Positions are saved in database and restored on spawn - essentialmode + es_admin => https://forum.fivem.net/t/release-essentialmode-base/3665 - esplugin_mysql => https://forum.fivem.net/t/release-essentialmode-base/3665/1181 +- mysql-async => https://github.com/brouznouf/fivem-mysql-async/releases/latest +- async => https://github.com/ESX-Org/async/releases/latest [INSTALLATION] -1) Using fvm +1) Using [fvm](https://github.com/qlaffont/fvm-installer) ``` fvm install --save --folder=essential ESX-Org/es_extended fvm install --save --folder=esx ESX-Org/esx_menu_default From f0e106e903d09321961f26c421d223e41f1485d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 16 Sep 2017 10:31:37 +0200 Subject: [PATCH 124/672] docs(readme): Update README --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ccc5d24c..dd726195 100644 --- a/README.md +++ b/README.md @@ -26,16 +26,16 @@ Positions are saved in database and restored on spawn - essentialmode + es_admin => https://forum.fivem.net/t/release-essentialmode-base/3665 - esplugin_mysql => https://forum.fivem.net/t/release-essentialmode-base/3665/1181 - mysql-async => https://github.com/brouznouf/fivem-mysql-async/releases/latest -- async => https://github.com/ESX-Org/async/releases/latest +- async => https://github.com/esx-org/async/releases/latest [INSTALLATION] 1) Using [fvm](https://github.com/qlaffont/fvm-installer) ``` -fvm install --save --folder=essential ESX-Org/es_extended -fvm install --save --folder=esx ESX-Org/esx_menu_default -fvm install --save --folder=esx ESX-Org/esx_menu_dialog -fvm install --save --folder=esx ESX-Org/esx_menu_list +fvm install --save --folder=essential esx-org/es_extended +fvm install --save --folder=esx esx-org/esx_menu_default +fvm install --save --folder=esx esx-org/esx_menu_dialog +fvm install --save --folder=esx esx-org/esx_menu_list ``` From 9c0839e1e51a8548b75fc5b6473ac0e05e0edc85 Mon Sep 17 00:00:00 2001 From: Romain Lanz Date: Sat, 16 Sep 2017 22:12:59 +0200 Subject: [PATCH 125/672] chore(paycheck): change message if interim --- locales/fr.lua | 1 + server/paycheck.lua | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/locales/fr.lua b/locales/fr.lua index ca81613a..1379b73a 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -17,6 +17,7 @@ Locales['fr'] = { ['delete_five_min'] = '~r~suppression~s~ dans 5 minutes', ['threw'] = 'vous avez ~r~jeté~s~', ['rec_salary'] = 'vous avez reçu votre salaire : ', + ['rec_help'] = 'vous avez reçu une aide de l\état : ', ['act_imp'] = 'action impossible', -- Commands ['setjob'] = 'assigner job', diff --git a/server/paycheck.lua b/server/paycheck.lua index 69f3de3e..f44fb680 100644 --- a/server/paycheck.lua +++ b/server/paycheck.lua @@ -10,7 +10,12 @@ ESX.StartPayCheck = function() if xPlayer.job.grade_salary > 0 then xPlayer.addMoney(xPlayer.job.grade_salary) - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) + + if xPlayer.job.grade_name == 'interim' then + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_help') .. '~g~$' .. xPlayer.job.grade_salary) + else + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) + end end end From 4c0f1ebe65f0c45ca72e0ce58a6c2d62a25fa3a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 16 Sep 2017 22:31:30 +0200 Subject: [PATCH 126/672] chore(resource): Increment version --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 3705566b..66a8567f 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.0' +version '1.0.1' server_scripts { '@async/async.lua', From 9b42c33ae547b6ea77ee899098cc1fe93056cbf9 Mon Sep 17 00:00:00 2001 From: Romain Lanz Date: Sun, 17 Sep 2017 02:06:59 +0200 Subject: [PATCH 127/672] fix(locales): fix escaping of character Closes https://github.com/ESX-Org/es_extended/issues/15 --- locales/fr.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.lua b/locales/fr.lua index 1379b73a..3506de3a 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -17,7 +17,7 @@ Locales['fr'] = { ['delete_five_min'] = '~r~suppression~s~ dans 5 minutes', ['threw'] = 'vous avez ~r~jeté~s~', ['rec_salary'] = 'vous avez reçu votre salaire : ', - ['rec_help'] = 'vous avez reçu une aide de l\état : ', + ['rec_help'] = 'vous avez reçu une aide de l\'état : ', ['act_imp'] = 'action impossible', -- Commands ['setjob'] = 'assigner job', From 2c9e5c6615a9b0858a8876f7c714c4a1d9835044 Mon Sep 17 00:00:00 2001 From: Romain Lanz Date: Sun, 17 Sep 2017 02:07:31 +0200 Subject: [PATCH 128/672] chore: bump version --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 66a8567f..2bca416e 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.1' +version '1.0.2' server_scripts { '@async/async.lua', From af3fd5bdf9504498227460fdc628855a100c5ce4 Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Wed, 20 Sep 2017 22:15:03 -0400 Subject: [PATCH 129/672] fix(locales): add missing en translation --- __resource.lua | 2 +- locales/en.lua | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 2bca416e..23ca5e56 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.2' +version '1.0.3' server_scripts { '@async/async.lua', diff --git a/locales/en.lua b/locales/en.lua index 2ded07f6..da2118f7 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -17,6 +17,7 @@ Locales['en'] = { ['delete_five_min'] = '~r~delete~s~ in 5 minutes', ['threw'] = 'you ~r~threw~s~', ['rec_salary'] = 'you received your salary: ', + ['rec_help'] = 'you recieved your welfare check: ', ['act_imp'] = 'action impossible', -- Commands ['setjob'] = 'assign a job to a user', From 5d14f3d8607c5b9a45a814513d84580ad25adc22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 23 Sep 2017 11:25:36 +0200 Subject: [PATCH 130/672] fix(client): Better loadout management --- client/main.lua | 97 +++++++++++++++++++++++-------------------------- 1 file changed, 45 insertions(+), 52 deletions(-) diff --git a/client/main.lua b/client/main.lua index 4b1e50ba..5a9db470 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,13 +10,12 @@ local Keys = { ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 } -local GUI = {} -GUI.Time = 0 -local LoadoutLoaded = false -local IsPaused = false -local PlayerSpawned = false -local LastLoadout = {} -local Pickups = {} +local GUI = {} +GUI.Time = 0 +local IsPaused = false +local PlayerSpawned = false +local PlayerShootingTimeouts = {} +local Pickups = {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) @@ -77,17 +76,12 @@ AddEventHandler('playerSpawned', function() GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) end - LoadoutLoaded = true PlayerSpawned = true end) end) -AddEventHandler('skinchanger:loadDefaultModel', function() - LoadoutLoaded = false -end) - AddEventHandler('skinchanger:modelLoaded', function() while not ESX.PlayerLoaded do Citizen.Wait(0) @@ -97,6 +91,7 @@ AddEventHandler('skinchanger:modelLoaded', function() end) AddEventHandler('esx:restoreLoadout', function () + local playerPed = GetPlayerPed(-1) for i=1, #ESX.PlayerData.loadout, 1 do @@ -104,7 +99,6 @@ AddEventHandler('esx:restoreLoadout', function () GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) end - LoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') @@ -406,53 +400,52 @@ end) -- Save loadout Citizen.CreateThread(function() + while ESX == nil and not ESX.PlayerLoaded do + Citizen.Wait(0) + end + while true do - Wait(0) + Citizen.Wait(0) - local playerPed = GetPlayerPed(-1) - local loadout = {} - local loadoutChanged = false + local playerPed = GetPlayerPed(-1) - 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 + if IsPedShooting(playerPed) then + for i=1, #PlayerShootingTimeouts, 1 do + ESX.ClearTimeout(PlayerShootingTimeouts[i]) end - end + PlayerShootingTimeouts = {} + + local timeout = ESX.SetTimeout(1000, function() + + local loadout = {} + + 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 + + table.insert(loadout, { + name = Config.Weapons[i].name, + ammo = GetAmmoInPedWeapon(playerPed, weaponHash), + label = Config.Weapons[i].label + }) + + end + + end + + ESX.PlayerData.loadout = loadout + + TriggerServerEvent('esx:updateLoadout', loadout) + + end) + + table.insert(PlayerShootingTimeouts, timeout) - if loadoutChanged and LoadoutLoaded then - ESX.PlayerData.loadout = loadout - TriggerServerEvent('esx:updateLoadout', loadout) end end From 38978958c49fe34fbd6ba67572e5766906e4783f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 23 Sep 2017 11:37:50 +0200 Subject: [PATCH 131/672] fix(client): Fix restoring of loadout --- client/main.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5a9db470..d2e669ba 100644 --- a/client/main.lua +++ b/client/main.lua @@ -71,10 +71,7 @@ AddEventHandler('playerSpawned', function() end -- Restore loadout - for i=1, #ESX.PlayerData.loadout, 1 do - local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) - GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) - end + TriggerEvent('esx:restoreLoadout') PlayerSpawned = true @@ -94,6 +91,8 @@ AddEventHandler('esx:restoreLoadout', function () local playerPed = GetPlayerPed(-1) + RemoveAllPedWeapons(playerPed, true) + for i=1, #ESX.PlayerData.loadout, 1 do local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) From 574864a0b1e30446bd29cb15bace6d5b50e8e18e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 23 Sep 2017 11:41:18 +0200 Subject: [PATCH 132/672] chore(version): Increment version --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 23ca5e56..a3b54f2a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.3' +version '1.0.4' server_scripts { '@async/async.lua', From 5aea6373bf561eb76695ac4becb1cbe94887a3a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 23 Sep 2017 21:34:16 +0200 Subject: [PATCH 133/672] docs(readme): Update README --- README.md | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index dd726195..9b0ccdfe 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ # es_extended FXServer ES Extended -[DISCORD] +## DISCORD https://discord.me/fivem_esx -[SCREENSHOT] +## SCREENSHOT ![screenshot](http://i.imgur.com/aPFdJl3.jpg) -[DESCRIPTION] +## DESCRIPTION Add support for accounts (bank / black money) you can also add others accounts @@ -21,16 +21,17 @@ Loadouts are saved in database and restored on spawn Positions are saved in database and restored on spawn -[REQUIREMENTS] +## Requirements -- essentialmode + es_admin => https://forum.fivem.net/t/release-essentialmode-base/3665 -- esplugin_mysql => https://forum.fivem.net/t/release-essentialmode-base/3665/1181 -- mysql-async => https://github.com/brouznouf/fivem-mysql-async/releases/latest -- async => https://github.com/esx-org/async/releases/latest +- **essentialmode** + **es_admin** => https://forum.fivem.net/t/release-essentialmode-base/3665 +- **esplugin_mysql** => https://forum.fivem.net/t/release-essentialmode-base/3665/1181 +- **mysql-async** => https://github.com/brouznouf/fivem-mysql-async/releases/latest +- **async** => https://github.com/esx-org/async/releases/latest -[INSTALLATION] +## Download + +**1) Using [fvm](https://github.com/qlaffont/fvm-installer)** -1) Using [fvm](https://github.com/qlaffont/fvm-installer) ``` fvm install --save --folder=essential esx-org/es_extended fvm install --save --folder=esx esx-org/esx_menu_default @@ -39,17 +40,28 @@ fvm install --save --folder=esx esx-org/esx_menu_list ``` -2) Manually +**2) Manually** - Download https://github.com/ESX-Org/es_extended/releases/latest -- Put it in [essential] directory +- Put it in resource/[essential] directory - Download https://github.com/ESX-Org/esx_menu_default/releases/latest -- Put it in [esx] directory +- Put it in resource/[esx] directory - Download https://github.com/ESX-Org/esx_menu_dialog/releases/latest -- Put it in [esx] directory +- Put it in resource/[esx] directory - Download https://github.com/ESX-Org/esx_menu_list/releases/latest -- Put it in [esx] directory +- Put it in resource/[esx] directory +**3) Using git** + +``` +cd resources +git clone https://github.com/ESX-Org/es_extended +git clone https://github.com/ESX-Org/esx_menu_default +git clone https://github.com/ESX-Org/esx_menu_dialog +git clone https://github.com/ESX-Org/esx_menu_list +``` + +## Installation 1) Import es_extended.sql in your database 2) Add this in your server.cfg : @@ -61,4 +73,3 @@ start esx_menu_default start esx_menu_list start esx_menu_dialog ``` - From 8ac3232b7aefa97d4be724b384f4f7abd7db381c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 23 Sep 2017 21:37:01 +0200 Subject: [PATCH 134/672] docs(readme): Update README --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9b0ccdfe..d88723ec 100644 --- a/README.md +++ b/README.md @@ -55,10 +55,10 @@ fvm install --save --folder=esx esx-org/esx_menu_list ``` cd resources -git clone https://github.com/ESX-Org/es_extended -git clone https://github.com/ESX-Org/esx_menu_default -git clone https://github.com/ESX-Org/esx_menu_dialog -git clone https://github.com/ESX-Org/esx_menu_list +git clone https://github.com/ESX-Org/es_extended [essential]/es_extended +git clone https://github.com/ESX-Org/esx_menu_default [esx]/[ui]/esx_menu_default +git clone https://github.com/ESX-Org/esx_menu_dialog [esx]/[ui]/esx_menu_dialog +git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list ``` ## Installation From 799ee1f91450ac76a5a395e63d1f4a4b3bf85115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 3 Oct 2017 18:20:52 +0200 Subject: [PATCH 135/672] Revert "fix(client): Better loadout management" This reverts commit 5d14f3d8607c5b9a45a814513d84580ad25adc22. --- client/main.lua | 83 +++++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/client/main.lua b/client/main.lua index d2e669ba..66e9a8b4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,12 +10,13 @@ local Keys = { ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 } -local GUI = {} -GUI.Time = 0 -local IsPaused = false -local PlayerSpawned = false -local PlayerShootingTimeouts = {} -local Pickups = {} +local GUI = {} +GUI.Time = 0 +local LoadoutLoaded = false +local IsPaused = false +local PlayerSpawned = false +local LastLoadout = {} +local Pickups = {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) @@ -73,12 +74,17 @@ AddEventHandler('playerSpawned', function() -- Restore loadout TriggerEvent('esx:restoreLoadout') + LoadoutLoaded = true PlayerSpawned = true end) end) +AddEventHandler('skinchanger:loadDefaultModel', function() + LoadoutLoaded = false +end) + AddEventHandler('skinchanger:modelLoaded', function() while not ESX.PlayerLoaded do Citizen.Wait(0) @@ -88,7 +94,6 @@ AddEventHandler('skinchanger:modelLoaded', function() end) AddEventHandler('esx:restoreLoadout', function () - local playerPed = GetPlayerPed(-1) RemoveAllPedWeapons(playerPed, true) @@ -98,6 +103,7 @@ AddEventHandler('esx:restoreLoadout', function () GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) end + LoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') @@ -399,52 +405,53 @@ end) -- Save loadout Citizen.CreateThread(function() - while ESX == nil and not ESX.PlayerLoaded do - Citizen.Wait(0) - end - while true do - Citizen.Wait(0) + Wait(0) - local playerPed = GetPlayerPed(-1) + local playerPed = GetPlayerPed(-1) + local loadout = {} + local loadoutChanged = false - if IsPedShooting(playerPed) then + if IsPedDeadOrDying(playerPed) then + LoadoutLoaded = false + end - for i=1, #PlayerShootingTimeouts, 1 do - ESX.ClearTimeout(PlayerShootingTimeouts[i]) - end + for i=1, #Config.Weapons, 1 do - PlayerShootingTimeouts = {} + local weaponHash = GetHashKey(Config.Weapons[i].name) - local timeout = ESX.SetTimeout(1000, function() + if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then - local loadout = {} - - 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 - - table.insert(loadout, { - name = Config.Weapons[i].name, - ammo = GetAmmoInPedWeapon(playerPed, weaponHash), - label = Config.Weapons[i].label - }) - - end + local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + if LastLoadout[Config.Weapons[i].name] == nil or LastLoadout[Config.Weapons[i].name] ~= ammo then + loadoutChanged = true end - ESX.PlayerData.loadout = loadout + LastLoadout[Config.Weapons[i].name] = ammo - TriggerServerEvent('esx:updateLoadout', loadout) + table.insert(loadout, { + name = Config.Weapons[i].name, + ammo = ammo, + label = Config.Weapons[i].label + }) - end) + else - table.insert(PlayerShootingTimeouts, timeout) + if LastLoadout[Config.Weapons[i].name] ~= nil then + loadoutChanged = true + end + LastLoadout[Config.Weapons[i].name] = nil + + end + + end + + if loadoutChanged and LoadoutLoaded then + ESX.PlayerData.loadout = loadout + TriggerServerEvent('esx:updateLoadout', loadout) end end From 7545b266905e4acb7a07fe719e6327d874eee6a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Tue, 3 Oct 2017 18:23:17 +0200 Subject: [PATCH 136/672] chore(version): Increment version --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index a3b54f2a..11b473ad 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.4' +version '1.0.5' server_scripts { '@async/async.lua', From 43946dcec432e37ba5152de5b810207c1490ea3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 7 Oct 2017 10:30:24 +0200 Subject: [PATCH 137/672] fix(item insertion): Fix mysql timeout when inserting too many items --- server/main.lua | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/server/main.lua b/server/main.lua index 7db15f56..c3e6ffb7 100644 --- a/server/main.lua +++ b/server/main.lua @@ -69,6 +69,8 @@ AddEventHandler('es:playerLoaded', function(source, _player) }, function(inventory) + local tasks2 = {} + for i=1, #inventory, 1 do table.insert(userData.inventory, { name = inventory[i].item, @@ -104,19 +106,34 @@ AddEventHandler('es:playerLoaded', function(source, _player) canRemove = ESX.Items[k].canRemove, }) - MySQL.Async.execute( - 'INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', - { - ['@identifier'] = player.getIdentifier(), - ['@item'] = k, - ['@count'] = 0 - } - ) + local scope = function(item, identifier) + + table.insert(tasks2, function(cb2) + + MySQL.Async.execute( + 'INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', + { + ['@identifier'] = identifier, + ['@item'] = item, + ['@count'] = 0 + }, + function(rowsChanged) + cb2() + end + ) + + end) + + end + + scope(k, player.getIdentifier()) end end + Async.parallelLimit(tasks2, 5, function(results) end) + table.sort(userData.inventory, function(a,b) return a.label < b.label end) From c9fb054a45830ca99c1a306f317050e0b592b211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 7 Oct 2017 10:31:44 +0200 Subject: [PATCH 138/672] chore(version): Increment version --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 11b473ad..0dcd11de 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.5' +version '1.0.6' server_scripts { '@async/async.lua', From d0c822f0a6d3097d0863ee1b1eebf6537e21f903 Mon Sep 17 00:00:00 2001 From: Romain Lanz Date: Sat, 7 Oct 2017 11:24:48 +0200 Subject: [PATCH 139/672] feat(paycheck): add company paycheck --- server/paycheck_company.lua | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 server/paycheck_company.lua diff --git a/server/paycheck_company.lua b/server/paycheck_company.lua new file mode 100644 index 00000000..3041f791 --- /dev/null +++ b/server/paycheck_company.lua @@ -0,0 +1,29 @@ +ESX.StartPayCheck = function () + function payCheck () + local xPlayers = ESX.GetPlayers() + + for i=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + + if xPlayer.job.grade_salary > 0 then + xPlayer.addMoney(xPlayer.job.grade_salary) + + if xPlayer.job.grade_name == 'interim' then + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_help') .. '~g~$' .. xPlayer.job.grade_salary) + else + TriggerEvent('esx_society:getSociety', xPlayer.job.name, function (society) + TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function (account) + account.removeMoney(xPlayer.job.grade_salary) + end) + end) + + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) + end + end + end + + SetTimeout(Config.PaycheckInterval, payCheck) + end + + SetTimeout(Config.PaycheckInterval, payCheck) +end From 6a174821f1d7cb52c168ccfc2923efa088c9e7fa Mon Sep 17 00:00:00 2001 From: renaiku Date: Mon, 30 Oct 2017 19:59:07 +0100 Subject: [PATCH 140/672] Essential 5.0 compatibility update --- server/commands.lua | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/server/commands.lua b/server/commands.lua index 755dea95..1341f0b2 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -1,9 +1,9 @@ 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]) + x = tonumber(args[1]), + y = tonumber(args[2]), + z = tonumber(args[3]) }) end, function(source, args, user) @@ -11,38 +11,38 @@ end, function(source, args, user) end) TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[2]) - xPlayer.setJob(args[3], tonumber(args[4])) + local xPlayer = ESX.GetPlayerFromId(args[1]) + xPlayer.setJob(args[2], tonumber(args[3])) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('setjob'), params = {{name = "id", help = _U('id_param')}, {name = "job", help = _U('setjob_param2')}, {name = "grade_id", help = _U('setjob_param3')}}}) TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:loadIPL', -1, args[2]) + TriggerClientEvent('esx:loadIPL', -1, args[1]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('load_ipl')}) TriggerEvent('es:addGroupCommand', 'unloadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:unloadIPL', -1, args[2]) + TriggerClientEvent('esx:unloadIPL', -1, args[1]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('unload_ipl')}) TriggerEvent('es:addGroupCommand', 'playanim', 'admin', function(source, args, user) - TriggerClientEvent('esx:playAnim', -1, args[2], args[3]) + TriggerClientEvent('esx:playAnim', -1, args[1], args[3]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('play_anim')}) TriggerEvent('es:addGroupCommand', 'playemote', 'admin', function(source, args, user) - TriggerClientEvent('esx:playEmote', -1, args[2]) + TriggerClientEvent('esx:playEmote', -1, args[1]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('play_emote')}) TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnVehicle', source, args[2]) + TriggerClientEvent('esx:spawnVehicle', source, args[1]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) @@ -55,13 +55,13 @@ end, {help = _U('delete_vehicle'), params = {{name = "car", help = _U('delete_ve TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnPed', source, args[2]) + TriggerClientEvent('esx:spawnPed', source, args[1]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_ped'), params = {{name = "name", help = _U('spawn_ped_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnObject', source, args[2]) + TriggerClientEvent('esx:spawnObject', source, args[1]) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_object'), params = {{name = "name"}}}) @@ -69,8 +69,8 @@ end, {help = _U('spawn_object'), params = {{name = "name"}}}) TriggerEvent('es:addGroupCommand', 'givemoney', 'admin', function(source, args, user) local _source = source - local xPlayer = ESX.GetPlayerFromId(args[2]) - local amount = tonumber(args[3]) + local xPlayer = ESX.GetPlayerFromId(args[1]) + local amount = tonumber(args[2]) if amount ~= nil then xPlayer.addMoney(amount) @@ -85,9 +85,9 @@ end, {help = _U('givemoney'), params = {{name = "id", help = _U('id_param')}, {n TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) local _source = source - local xPlayer = ESX.GetPlayerFromId(args[2]) - local account = args[3] - local amount = tonumber(args[4]) + local xPlayer = ESX.GetPlayerFromId(args[1]) + local account = args[2] + local amount = tonumber(args[3]) if amount ~= nil then if xPlayer.getAccount(account) ~= nil then @@ -106,9 +106,9 @@ end, {help = _U('giveaccountmoney'), params = {{name = "id", help = _U('id_param TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) local _source = source - local xPlayer = ESX.GetPlayerFromId(args[2]) - local item = args[3] - local count = (args[4] == nil and 1 or tonumber(args[4])) + local xPlayer = ESX.GetPlayerFromId(args[1]) + local item = args[2] + local count = (args[3] == nil and 1 or tonumber(args[3])) if count ~= nil then if xPlayer.getInventoryItem(item) ~= nil then @@ -126,8 +126,8 @@ end, {help = _U('giveitem'), params = {{name = "id", help = _U('id_param')}, {na TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[2]) - local weaponName = string.upper(args[3]) + local xPlayer = ESX.GetPlayerFromId(args[1]) + local weaponName = string.upper(args[2]) xPlayer.addWeapon(weaponName, 1000) From 4b1f056103a7b1a3b803404d04dd1fdb4e1fb1ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 4 Nov 2017 10:34:04 +0100 Subject: [PATCH 141/672] fix(timeout): Fix server timeout problems (clock too slow) under rare conditions --- server/common.lua | 26 ++------------------------ server/functions.lua | 24 +++++++++++++++++------- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/server/common.lua b/server/common.lua index 4bde6732..034d0921 100644 --- a/server/common.lua +++ b/server/common.lua @@ -3,7 +3,8 @@ ESX.Players = {} ESX.UsableItemsCallbacks = {} ESX.Items = {} ESX.ServerCallbacks = {} -ESX.TimeoutCallbacks = {} +ESX.TimeoutCount = -1 +ESX.CancelledTimeouts = {} ESX.LastPlayerData = {} ESX.Pickups = {} ESX.PickupId = 0 @@ -76,26 +77,3 @@ AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) end) --- SetTimeout -CreateThread(function() - while true do - - Wait(0) - - local currTime = os.clock() * 1000 - - for i=1, #ESX.TimeoutCallbacks, 1 do - - if ESX.TimeoutCallbacks[i] ~= nil then - - if currTime >= ESX.TimeoutCallbacks[i].time then - ESX.TimeoutCallbacks[i].cb() - ESX.TimeoutCallbacks[i] = nil - end - - end - - end - - end -end) diff --git a/server/functions.lua b/server/functions.lua index f5dfb5ed..3b90a58b 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -27,15 +27,25 @@ ESX.GetRandomString = function(length) end ESX.SetTimeout = function(msec, cb) - table.insert(ESX.TimeoutCallbacks, { - time = os.clock() * 1000 + msec, - cb = cb - }) - return #ESX.TimeoutCallbacks + + local id = ESX.TimeoutCount + 1 + + SetTimeout(msec, function() + + if ESX.CancelledTimeouts[id] then + ESX.CancelledTimeouts[id] = nil + else + cb() + end + + end) + + return id + end -ESX.ClearTimeout = function(i) - ESX.TimeoutCallbacks[i] = nil +ESX.ClearTimeout = function(id) + ESX.CancelledTimeouts[id] = true end ESX.RegisterServerCallback = function(name, cb) From 9e32bc9570c6a0d5bef87bf921f44042642b95ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 4 Nov 2017 10:35:00 +0100 Subject: [PATCH 142/672] chore(version): Increment version --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 0dcd11de..48b403d9 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.6' +version '1.0.7' server_scripts { '@async/async.lua', From cb84be5e4cf9d0b4525a08b0b0504fe32d5bdb85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sat, 4 Nov 2017 10:36:06 +0100 Subject: [PATCH 143/672] chore(version): Increment version --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 48b403d9..5b7ba20d 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.7' +version '1.0.8' server_scripts { '@async/async.lua', From b47236951eedfdef2bd65ef078a409aa81135da5 Mon Sep 17 00:00:00 2001 From: renaiku Date: Thu, 30 Nov 2017 03:05:41 +0100 Subject: [PATCH 144/672] ESX.GetPedMugshot --- client/functions.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index 6729f0da..a2478a63 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -291,6 +291,14 @@ ESX.GetWeaponLabel = function(name) end +ESX.Game.GetPedMugshot = function(ped) + mugshot = RegisterPedheadshot(ped) + while not IsPedheadshotReady(mugshot) do + Wait(0) + end + return mugshot, GetPedheadshotTxdString(mugshot) +end + ESX.Game.Teleport = function(entity, coords, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) From ca3d4ab017462d046102b5cf375b3d70c5b0fb7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 1 Dec 2017 16:19:48 +0100 Subject: [PATCH 145/672] fix(timeout): Fix sever timeout not triggering --- server/functions.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/functions.lua b/server/functions.lua index 3b90a58b..6a0fd5ed 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -40,6 +40,8 @@ ESX.SetTimeout = function(msec, cb) end) + ESX.TimeoutCount = id + return id end From 8bc574ba192b42d4a166affe65c2299cbdbc683a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Fri, 1 Dec 2017 16:20:47 +0100 Subject: [PATCH 146/672] chore(version): Increment version --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 5b7ba20d..72b70298 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.8' +version '1.0.9' server_scripts { '@async/async.lua', From b91e4e7337a2eaa47b1c3b8d2fb206074f8ae99a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Sun, 3 Dec 2017 15:42:13 +0100 Subject: [PATCH 147/672] feat(menus): add ESX.UI.Menu.GetOpenedMenus --- __resource.lua | 2 +- client/functions.lua | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 72b70298..f8b222f5 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.9' +version '1.0.10' server_scripts { '@async/async.lua', diff --git a/client/functions.lua b/client/functions.lua index a2478a63..9d8cca2c 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -261,6 +261,10 @@ ESX.UI.Menu.GetOpened = function(type, namespace, name) end +ESX.UI.Menu.GetOpenedMenus = function() + return ESX.UI.Menu.Opened +end + ESX.UI.Menu.IsOpen = function(type, namespace, name) return ESX.UI.Menu.GetOpened(type, namespace, name) ~= nil end From 90018baac608d1cd5162eb7f77ae9960ca0941db Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Sun, 3 Dec 2017 21:37:09 +0100 Subject: [PATCH 148/672] Update paycheck_company.lua No more cunt who are giving them 1 million with society paycheck. No money in society account, no pay. That's all --- server/paycheck_company.lua | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/server/paycheck_company.lua b/server/paycheck_company.lua index 3041f791..76773f27 100644 --- a/server/paycheck_company.lua +++ b/server/paycheck_company.lua @@ -1,29 +1,30 @@ ESX.StartPayCheck = function () + function payCheck () local xPlayers = ESX.GetPlayers() - for i=1, #xPlayers, 1 do local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - - if xPlayer.job.grade_salary > 0 then - xPlayer.addMoney(xPlayer.job.grade_salary) - - if xPlayer.job.grade_name == 'interim' then - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_help') .. '~g~$' .. xPlayer.job.grade_salary) - else - TriggerEvent('esx_society:getSociety', xPlayer.job.name, function (society) - TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function (account) - account.removeMoney(xPlayer.job.grade_salary) - end) - end) - - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) + if xPlayer.job.grade_name == 'interim' or xPlayer.job.grade_name == 'rsa' or xPlayer.job.grade_name == 'employee' then -- Si il n'est pas dans une société, je prends chez l'état + if xPlayer.job.grade_salary > 0 then + xPlayer.addAccountMoney('bank',xPlayer.job.grade_salary) + TriggerClientEvent('esx:showNotification', xPlayer.source, ('L\'état vous a payé ') .. '~g~$' .. xPlayer.job.grade_salary) end - end + else -- Sinon je prends l'argent dans la société + TriggerEvent('esx_society:getSociety', xPlayer.job.name, function (society) + TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function (account) + if account.money >= xPlayer.job.grade_salary then + xPlayer.addAccountMoney('bank',xPlayer.job.grade_salary) + account.removeMoney(xPlayer.job.grade_salary) + TriggerClientEvent('esx:showNotification', xPlayer.source, ('Votre entreprise vous a payé ') .. '~g~$' .. xPlayer.job.grade_salary) + else + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Votre entreprise n\'a plus d\'argent pour vous payer !') + end + end) + end) + end end SetTimeout(Config.PaycheckInterval, payCheck) end - SetTimeout(Config.PaycheckInterval, payCheck) end From 8d0b2d73e5ffeea5e39c2f4bc6d4a914f4a4fe44 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Mon, 4 Dec 2017 20:11:41 -0800 Subject: [PATCH 149/672] Update fr.lua lang company pay check --- locales/fr.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locales/fr.lua b/locales/fr.lua index 3506de3a..1e259b97 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -18,6 +18,9 @@ Locales['fr'] = { ['threw'] = 'vous avez ~r~jeté~s~', ['rec_salary'] = 'vous avez reçu votre salaire : ', ['rec_help'] = 'vous avez reçu une aide de l\'état : ', + ['company_paid'] = 'Votre entreprise vous a payé ', + ['company_nomoney'] = 'Votre entreprise n\'a plus d\'argent pour vous payer !', + ['state_paid'] = 'L\'état vous a payé ', ['act_imp'] = 'action impossible', -- Commands ['setjob'] = 'assigner job', From 09dee59bb53af2f2bd64b5fbfbf5b67df0ea8b16 Mon Sep 17 00:00:00 2001 From: Don <30905704+ddh3@users.noreply.github.com> Date: Mon, 4 Dec 2017 20:15:50 -0800 Subject: [PATCH 150/672] add(locales): added company paycheck translation --- locales/en.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/locales/en.lua b/locales/en.lua index da2118f7..358f0b84 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -18,6 +18,9 @@ Locales['en'] = { ['threw'] = 'you ~r~threw~s~', ['rec_salary'] = 'you received your salary: ', ['rec_help'] = 'you recieved your welfare check: ', + ['company_paid'] = 'Company paycheck received', + ['company_nomoney'] = 'Your company is broke!', + ['state_paid'] = 'You received a state check', ['act_imp'] = 'action impossible', -- Commands ['setjob'] = 'assign a job to a user', From 36f14f62ed5fbf094ae65ddd92a78e7b5691b304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 11 Dec 2017 10:26:51 +0100 Subject: [PATCH 151/672] feat(pickups): Improve pickups Don't add more items than the inventory limit => Re-throw excessive amount on floor + Pickup count display --- __resource.lua | 2 +- server/main.lua | 31 ++++++++++++++++++++++++------- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/__resource.lua b/__resource.lua index f8b222f5..1d65a3a3 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.10' +version '1.0.11' server_scripts { '@async/async.lua', diff --git a/server/main.lua b/server/main.lua index c3e6ffb7..8bafdddf 100644 --- a/server/main.lua +++ b/server/main.lua @@ -422,7 +422,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeInventoryItem(itemName, total) - ESX.CreatePickup('item_standard', itemName, total, foundItem.label, _source) + ESX.CreatePickup('item_standard', itemName, total, foundItem.label .. ' [' .. itemCount .. ']', _source) TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) end @@ -457,7 +457,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeMoney(total) - ESX.CreatePickup('item_money', 'money', total, 'Cash', _source) + ESX.CreatePickup('item_money', 'money', total, 'Cash' .. ' [' .. itemCount .. ']', _source) TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end @@ -492,7 +492,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if total > 0 then xPlayer.removeAccountMoney(itemName, total) - ESX.CreatePickup('item_account', itemName, total, 'Cash', _source) + ESX.CreatePickup('item_account', itemName, total, Config.AccountLabels[itemName] .. ' [' .. itemCount .. ']', _source) TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) end @@ -551,19 +551,36 @@ end) RegisterServerEvent('esx:onPickup') AddEventHandler('esx:onPickup', function(id) + local _source = source local pickup = ESX.Pickups[id] - local xPlayer = ESX.GetPlayerFromId(source) + local xPlayer = ESX.GetPlayerFromId(_source) if pickup.type == 'item_standard' then - xPlayer.addInventoryItem(pickup.name, pickup.count) + + local item = xPlayer.getInventoryItem(pickup.name) + local canTake = (item.limit - item.count > 0) and (item.limit - item.count) or 0 + local total = pickup.count < canTake and pickup.count or canTake + local remaining = pickup.count - total + + TriggerClientEvent('esx:removePickup', -1, id) + + if total > 0 then + xPlayer.addInventoryItem(pickup.name, total) + end + + if remaining > 0 then + TriggerClientEvent('esx:showNotification', _source, 'Vous n\'avez plus de place pour ~b~' .. item.label .. '~s~') + ESX.CreatePickup('item_standard', pickup.name, remaining, item.label .. ' [' .. remaining .. ']', _source) + end + elseif pickup.type == 'item_money' then + TriggerClientEvent('esx:removePickup', -1, id) xPlayer.addMoney(pickup.count) elseif pickup.type == 'item_account' then + TriggerClientEvent('esx:removePickup', -1, id) xPlayer.addAccountMoney(pickup.name, pickup.count) end - TriggerClientEvent('esx:removePickup', -1, id) - end) ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) From 34cae4afc8086f5cdecaf0164662e589959718d9 Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Mon, 1 Jan 2018 09:42:11 +0100 Subject: [PATCH 152/672] fixed glitch Players were able to duplicate pickups when driving fast on it --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 66e9a8b4..347d4a07 100644 --- a/client/main.lua +++ b/client/main.lua @@ -536,7 +536,7 @@ Citizen.CreateThread(function() end - if distance <= 1.0 and not v.inRange then + if distance <= 1.0 and not v.inRange and not IsPedSittingInAnyVehicle(playerPed) then TriggerServerEvent('esx:onPickup', v.id) v.inRange = true end From 4a6ee74ab7c7d8134fbd53fb6f7f454de4f5a6be Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Mon, 15 Jan 2018 16:34:14 +0100 Subject: [PATCH 153/672] Fixed glitchs New fixs for glitchs Not being able to duplicate weapons by staying on pressing enter Not being able to duplicate money/items and weapons by giving it in vehicles --- client/functions.lua | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 9d8cca2c..a63845da 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1159,17 +1159,24 @@ ESX.ShowInventory = function() local item = data.current.value local type = data.current.type - if data.current.action == 'give' then + if data.current.action == 'give' then if type == 'item_weapon' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + local closestPed = GetPlayerPed(closestPlayer) - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('players_nearby')) - else + if closestPlayer ~= -1 or closestDistance > 3.0 then + -- PERSONNE + if not IsPedSittingInAnyVehicle(closestPed) then TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) + else + ESX.ShowNotification(_U("in_vehicle")) + end + else + ESX.ShowNotification(_U('players_nearby')) end + menu.close() else @@ -1182,11 +1189,15 @@ ESX.ShowInventory = function() local quantity = tonumber(data2.value) local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - - if closestPlayer == -1 or closestDistance > 3.0 then - ESX.ShowNotification(_U('players_nearby')) + local closestPed = GetPlayerPed(closestPlayer) + if not IsPedSittingInAnyVehicle(closestPed) then + if closestPlayer ~= -1 or closestDistance < 3.0 then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + else + ESX.ShowNotification(_U('players_nearby')) + end else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + ESX.ShowNotification(_U("in_vehicle")) end menu2.close() From a5af6409320830b5ad30dfe89cd0c47fcab54531 Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Mon, 15 Jan 2018 17:17:59 +0100 Subject: [PATCH 154/672] Update fr.lua --- locales/fr.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/fr.lua b/locales/fr.lua index 1e259b97..58b9e240 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -22,6 +22,7 @@ Locales['fr'] = { ['company_nomoney'] = 'Votre entreprise n\'a plus d\'argent pour vous payer !', ['state_paid'] = 'L\'état vous a payé ', ['act_imp'] = 'action impossible', + ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule' -- Commands ['setjob'] = 'assigner job', ['id_param'] = 'identification du joueur', From 16a0b7681c07be7f67b08253dd5edeb7cb2254e3 Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Mon, 15 Jan 2018 17:19:01 +0100 Subject: [PATCH 155/672] Update en.lua --- locales/en.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/en.lua b/locales/en.lua index 358f0b84..8bdb9e44 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -22,6 +22,7 @@ Locales['en'] = { ['company_nomoney'] = 'Your company is broke!', ['state_paid'] = 'You received a state check', ['act_imp'] = 'action impossible', + ['in_vehicle'] = 'You can\'t give anything to someone in vehicle -- Commands ['setjob'] = 'assign a job to a user', ['id_param'] = 'the ID of the player', From 4943843d550d85d2ea95df13e788ac05d63e242e Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Mon, 15 Jan 2018 20:30:28 +0100 Subject: [PATCH 156/672] Forgot end of syntax --- locales/en.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.lua b/locales/en.lua index 8bdb9e44..2c03137b 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -22,7 +22,7 @@ Locales['en'] = { ['company_nomoney'] = 'Your company is broke!', ['state_paid'] = 'You received a state check', ['act_imp'] = 'action impossible', - ['in_vehicle'] = 'You can\'t give anything to someone in vehicle + ['in_vehicle'] = 'You can\'t give anything to someone in vehicle', -- Commands ['setjob'] = 'assign a job to a user', ['id_param'] = 'the ID of the player', From 35d5d27c32f3d1ad3e19b0599f8b2086b4d3e8ae Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Mon, 15 Jan 2018 20:31:23 +0100 Subject: [PATCH 157/672] forgot syntax --- locales/fr.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/fr.lua b/locales/fr.lua index 58b9e240..60540df3 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -22,7 +22,7 @@ Locales['fr'] = { ['company_nomoney'] = 'Votre entreprise n\'a plus d\'argent pour vous payer !', ['state_paid'] = 'L\'état vous a payé ', ['act_imp'] = 'action impossible', - ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule' + ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', -- Commands ['setjob'] = 'assigner job', ['id_param'] = 'identification du joueur', From 06fe0c7969941b94d7d613040938af15b22d1fb5 Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Sun, 21 Jan 2018 15:54:25 +0100 Subject: [PATCH 158/672] Only Keyboard --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 347d4a07..3594b85f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -463,7 +463,7 @@ Citizen.CreateThread(function() Wait(0) - if IsControlPressed(0, Keys["F2"]) and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') and (GetGameTimer() - GUI.Time) > 150 then + if IsControlPressed(0, Keys["F2"]) and GetLastInputMethod(2) and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') and (GetGameTimer() - GUI.Time) > 150 then ESX.ShowInventory() GUI.Time = GetGameTimer() end From 9102a8e24a8af225ea9274eec032ab3ef5b78a3b Mon Sep 17 00:00:00 2001 From: FumaPraQue <35692178+FumaPraQue@users.noreply.github.com> Date: Thu, 15 Feb 2018 16:04:38 -0200 Subject: [PATCH 159/672] Minor fix to vehicle request collision Minor fix in vehicle request collision code. --- client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index a63845da..d6b9e676 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -397,7 +397,7 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.x, coords.x) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) Citizen.Wait(0) end @@ -430,7 +430,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.x, coords.x) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) Citizen.Wait(0) end From eb42f346b288e9b544b269873a5fcd5d7a1c92b8 Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Mon, 19 Feb 2018 03:30:02 +0100 Subject: [PATCH 160/672] Add files via upload --- client/functions.lua | 127 +++++++++++++++++++++++++++++++++----- client/main.lua | 8 +-- config.lua | 10 +-- locales/de.lua | 5 ++ locales/en.lua | 7 ++- locales/fr.lua | 5 ++ server/classes/player.lua | 3 +- server/main.lua | 10 +-- 8 files changed, 143 insertions(+), 32 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index d6b9e676..b6c2ae1a 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -430,7 +430,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) + RequestCollisionAtCoord(coords.x, coords.x, coords.x) Citizen.Wait(0) end @@ -1057,6 +1057,7 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size) end + ESX.ShowInventory = function() local playerPed = GetPlayerPed(-1) @@ -1145,6 +1146,10 @@ ESX.ShowInventory = function() table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) end + if data.current.type == "item_weapon" then + table.insert(elements, {label = --[[_U('giveammo')]]"Give ammo", action = 'giveammo', type = data.current.type, value = data.current.value}) + end + table.insert(elements, {label = _U('return'), action = 'return'}) ESX.UI.Menu.Open( @@ -1158,29 +1163,54 @@ ESX.ShowInventory = function() local item = data.current.value local type = data.current.type + local playerPed = GetPlayerPed(-1) if data.current.action == 'give' then if type == 'item_weapon' then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() local closestPed = GetPlayerPed(closestPlayer) + local pedammo = GetAmmoInPedWeapon(GetPlayerPed(-1),GetHashKey(item)) + if not IsPedSittingInAnyVehicle(closestPed) then + if closestPlayer ~= -1 and closestDistance < 3.0 then + if pedammo > 0 then + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', + { + title = _U('amountammo') + }, + function(data2, menu2) + local quantity = tonumber(data2.value) + if quantity <= pedammo and quantity >= 0 and quantity ~= nil then + local ammobefore = GetAmmoInPedWeapon(playerPed, item) + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + local finalammo = math.floor(ammobefore - quantity) + SetPedAmmo(playerPed, item, finalammo) + menu2.close() + menu.close() + else + ESX.ShowNotification(_U("noammo")) + end - if closestPlayer ~= -1 or closestDistance > 3.0 then - -- PERSONNE - if not IsPedSittingInAnyVehicle(closestPed) then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 1) - else - ESX.ShowNotification(_U("in_vehicle")) - end + end, + function(data2, menu2) + menu2.close() + end + ) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 0) + menu.close() + end + else + ESX.ShowNotification(_U('players_nearby')) + end else - ESX.ShowNotification(_U('players_nearby')) + ESX.ShowNotification(_U("in_vehicle")) end - menu.close() else - ESX.UI.Menu.Open( + ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', { title = _U('amount') @@ -1191,7 +1221,7 @@ ESX.ShowInventory = function() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() local closestPed = GetPlayerPed(closestPlayer) if not IsPedSittingInAnyVehicle(closestPed) then - if closestPlayer ~= -1 or closestDistance < 3.0 then + if closestPlayer ~= -1 and closestDistance < 3.0 then TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) else ESX.ShowNotification(_U('players_nearby')) @@ -1214,9 +1244,33 @@ ESX.ShowInventory = function() elseif data.current.action == 'remove' then if type == 'item_weapon' then + local pedammo = GetAmmoInPedWeapon(GetPlayerPed(-1),GetHashKey(item)) + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', + { + title = _U('amount') + }, + function(data2, menu2) - TriggerServerEvent('esx:removeInventoryItem', type, item, 1) - menu.close() + local quantity = tonumber(data2.value) + + if quantity <= pedammo and quantity >= 0 and quantity ~= nil then + local ammobefore = GetAmmoInPedWeapon(playerPed, item) + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + local finalammo = math.floor(ammobefore - quantity) + SetPedAmmo(playerPed, item, finalammo) + else + ESX.ShowNotification(_U("noammo")) + end + + menu2.close() + menu.close() + + end, + function(data2, menu2) + menu2.close() + end + ) else @@ -1255,6 +1309,49 @@ ESX.ShowInventory = function() ESX.UI.Menu.CloseAll() ESX.ShowInventory() + elseif data.current.action == 'giveammo' then + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + local closestPed = GetPlayerPed(closestPlayer) + local pedammo = GetAmmoInPedWeapon(playerPed,GetHashKey(item)) + if not IsPedSittingInAnyVehicle(closestPed) then + if closestPlayer ~= -1 and closestDistance < 3.0 then + if pedammo > 0 then + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', + { + title = _U('amountammo') + }, + function(data2, menu2) + local quantity = tonumber(data2.value) + if quantity <= pedammo and quantity >= 0 and quantity ~= nil then + local ammobefore2 = GetAmmoInPedWeapon(closestPed, item) + local finalammo = math.floor(pedammo - quantity) + local finalammo2 = math.floor(ammobefore2 + quantity) + SetPedAmmo(playerPed, item, finalammo) + Citizen.invokeNative(0x78F0424C34306220,closestPed, item, finalammo2) + --SetPedAmmo(closestPed, item, finalammo2) + ESX.ShowNotification(_U('yougave') .. "x~r~ " .. quantity .. _U('ammogiven') ) + menu2.close() + menu.close() + else + ESX.ShowNotification(_U("noammo")) + end + + end, + function(data2, menu2) + menu2.close() + end + ) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 0) + menu.close() + end + else + ESX.ShowNotification(_U('players_nearby')) + end + else + ESX.ShowNotification(_U("in_vehicle")) + end end end, diff --git a/client/main.lua b/client/main.lua index 3594b85f..cec70363 100644 --- a/client/main.lua +++ b/client/main.lua @@ -333,13 +333,13 @@ AddEventHandler('esx:removePickup', function(id) end) RegisterNetEvent('esx:pickupWeapon') -AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName) +AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName,ammo) local ped = GetPlayerPed(-1) local playerPedPos = GetEntityCoords(ped, true) - - CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, 1000, 1, false, true) - + print(ammo) + CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, ammo, 1, false, true) + end) RegisterNetEvent('esx:spawnPed') diff --git a/config.lua b/config.lua index 215a67fb..c5775be6 100644 --- a/config.lua +++ b/config.lua @@ -1,13 +1,13 @@ Config = {} -Config.MaxPlayers = 32 +Config.MaxPlayers = 4 Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = 'Banque', black_money = 'Argent Sale' } -- French -- Config.AccountLabels = { bank = 'Bank', black_money = 'Dirty Money' } -- English -Config.PaycheckInterval = 7 * 60000 -Config.ShowDotAbovePlayer = false +Config.PaycheckInterval = 2 * 60000 +Config.ShowDotAbovePlayer = true Config.DisableWantedLevel = true -Config.RemoveInventoryItemDelay = 5 * 60000 +Config.RemoveInventoryItemDelay = 1000 Config.EnableWeaponPickup = true Config.Locale = 'fr' -Config.EnableDebug = false +Config.EnableDebug = true diff --git a/locales/de.lua b/locales/de.lua index 2c6d8d22..23c6ea75 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,4 +1,9 @@ Locales['de'] = { + ['amountammo'] = 'anzahl der Munition', + ['noammo'] = 'Du hast keine Munition !', + ['withammo'] = '~s~ mit x', + ['ammogiven'] = '~s~ Kugeln', + ['giveammo'] = 'Munition geben', ['inventory'] = 'Inventar', ['use'] = 'benutzen', ['give'] = 'geben', diff --git a/locales/en.lua b/locales/en.lua index 2c03137b..12bc40f7 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -5,6 +5,11 @@ Locales['en'] = { ['remove'] = 'remove', ['return'] = 'return', ['amount'] = 'amount', + ['amountammo'] = 'amount of ammo', + ['noammo'] = 'You dont have all these ammo !', + ['withammo'] = '~s~ with x', + ['ammogiven'] = '~s~ bullets', + ['giveammo'] = 'Give ammo', ['amount_invalid'] = 'invalid amount', ['players_nearby'] = 'no players nearby', ['ex_inv_lim'] = 'action not possible, exceeding invetory limit for ~b~', @@ -128,4 +133,4 @@ Locales['en'] = { ['weapon_flashlight'] = 'flashlight', ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', -} +} \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua index 60540df3..dcae71ec 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -5,6 +5,11 @@ Locales['fr'] = { ['remove'] = 'jeter', ['return'] = 'retour', ['amount'] = 'quantité', + ['amountammo'] = 'nombre de munitions', + ['noammo'] = 'Tu n\'as pas toutes ces munitions !', + ['withammo'] = '~s~ avec x ', + ['ammogiven'] = '~s~ balles', + ['giveammo'] = 'Donner munitions', ['amount_invalid'] = 'montant invalide', ['players_nearby'] = 'aucun joueur à proximité', ['ex_inv_lim'] = 'action impossible, depassement de la limite d\'inventaire pour ~b~', diff --git a/server/classes/player.lua b/server/classes/player.lua index b7d365b4..bf88ac93 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -388,11 +388,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if not foundWeapon then table.insert(self.loadout, { name = weaponName, - ammo = ammon, + ammo = ammo, label = weaponLabel }) end - TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) TriggerClientEvent("esx:addInventoryItem", self.source, {label = weaponLabel}, 1) end diff --git a/server/main.lua b/server/main.lua index 8bafdddf..2e2e10cb 100644 --- a/server/main.lua +++ b/server/main.lua @@ -309,7 +309,7 @@ end) RegisterServerEvent('esx:giveInventoryItem') -AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) +AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount,ammotogive) local _source = source @@ -366,10 +366,10 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo end elseif type == 'item_weapon' then - + sourceXPlayer.removeWeapon(itemName) targetXPlayer.addWeapon(itemName, itemCount) - + local weaponLabel = itemName for i=1, #Config.Weapons, 1 do @@ -523,10 +523,10 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) xPlayer.removeWeapon(itemName) if Config.EnableWeaponPickup then - TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName) + TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName,itemCount) end - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' x1 ~g~' .. weaponLabel) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' x1 ~g~' .. weaponLabel .. _U('withammo').. '~r~' .. itemCount .. _U('ammogiven')) end) From f3dc5d9d60df1713cd27e22f03594978d10acc34 Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Mon, 19 Feb 2018 03:31:41 +0100 Subject: [PATCH 161/672] Update config.lua --- config.lua | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/config.lua b/config.lua index c5775be6..ce90edee 100644 --- a/config.lua +++ b/config.lua @@ -1,13 +1,12 @@ Config = {} -Config.MaxPlayers = 4 +Config.MaxPlayers = 32 Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = 'Banque', black_money = 'Argent Sale' } -- French -- Config.AccountLabels = { bank = 'Bank', black_money = 'Dirty Money' } -- English -Config.PaycheckInterval = 2 * 60000 -Config.ShowDotAbovePlayer = true +Config.PaycheckInterval = 7 * 60000 +Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true -Config.RemoveInventoryItemDelay = 1000 +Config.RemoveInventoryItemDelay = 5 * 60000 Config.EnableWeaponPickup = true Config.Locale = 'fr' -Config.EnableDebug = true - +Config.EnableDebug = false From 4929632dcbafd4ac91399e8b579504497e396060 Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Mon, 19 Feb 2018 03:40:02 +0100 Subject: [PATCH 162/672] Update __resource.lua --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 1d65a3a3..9dd1a91b 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.11' +version '1.0.12' server_scripts { '@async/async.lua', From 7da07f5e5be96b889d9b904657bd7137623c381d Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Wed, 21 Feb 2018 12:12:19 +0100 Subject: [PATCH 163/672] Update functions.lua --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index b6c2ae1a..239ef100 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -430,7 +430,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.x, coords.x) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) Citizen.Wait(0) end From e14089167457b5553315f82e96f94ad954f3ca72 Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Wed, 21 Feb 2018 12:18:03 +0100 Subject: [PATCH 164/672] Update functions.lua --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index 239ef100..3d413cbc 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1147,7 +1147,7 @@ ESX.ShowInventory = function() end if data.current.type == "item_weapon" then - table.insert(elements, {label = --[[_U('giveammo')]]"Give ammo", action = 'giveammo', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('giveammo'), action = 'giveammo', type = data.current.type, value = data.current.value}) end table.insert(elements, {label = _U('return'), action = 'return'}) From 7eaa8f2c7a74a2ecc80489460804a84c0d675736 Mon Sep 17 00:00:00 2001 From: Vanheden <33155577+Vanheden@users.noreply.github.com> Date: Wed, 7 Mar 2018 15:09:11 +0100 Subject: [PATCH 165/672] Create sv.lua --- locales/sv.lua | 130 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 locales/sv.lua diff --git a/locales/sv.lua b/locales/sv.lua new file mode 100644 index 00000000..bda695af --- /dev/null +++ b/locales/sv.lua @@ -0,0 +1,130 @@ +Locales['sv'] = { + ['inventory'] = 'Mitt förråd', + ['use'] = 'använd', + ['give'] = 'ge', + ['remove'] = 'ta bort', + ['return'] = 'gå tillbaka', + ['amount'] = 'belopp', + ['amount_invalid'] = 'giltigt belopp', + ['players_nearby'] = 'inga spelare nära', + ['ex_inv_lim'] = 'åtgärd inte möjligt, översteg förrådets gräns ~b~', + ['yougave'] = 'du gav', + ['youreceived'] = 'du fick', + ['to'] = '~s~ till ~b~', + ['by'] = '~s~ av ~b~', + ['imp_invalid_quantity'] = 'åtgärd omöjlig, ogiltig mängd', + ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', + ['delete_five_min'] = '~r~ta bort~s~ inom 5 minuter', + ['threw'] = 'du ~r~kastade~s~', + ['rec_salary'] = 'du fick din lön: ', + ['rec_help'] = 'du fick din välfärdskontroll: ', + ['company_paid'] = 'Företags lön mottaget', + ['company_nomoney'] = 'Ditt företag är för fattigt!!', + ['state_paid'] = 'Du fick en statlig check', + ['act_imp'] = 'åtgärd omöjlig', + -- Commands + ['setjob'] = 'tilldela ett jobb till en användare', + ['id_param'] = 'spelarens ID', + ['setjob_param2'] = 'det jobb du vill tilldela', + ['setjob_param3'] = 'job level', + ['load_ipl'] = 'load IPL', + ['unload_ipl'] = 'unload IPL', + ['play_anim'] = 'spela animering', + ['play_emote'] = 'spela emote', + ['spawn_car'] = 'spawna en bil', + ['spawn_car_param'] = 'namn på bil', + ['delete_vehicle'] = 'ta bort Fordon', + ['delete_veh_param'] = 'tryck enter', + ['spawn_object'] = 'spawna föremål', + ['spawn_ped'] = 'spawna NPC', + ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', + ['givemoney'] = 'ge pengar', + ['money_amount'] = 'summa pengar', + ['invalid_account'] = 'ogiltigt konto', + ['account'] = 'konto', + ['giveaccountmoney'] = 'ge spelarkonto pengar', + ['invalid_item'] = 'ogiltigt föremål', + ['item'] = 'föremål', + ['giveitem'] = 'ge föremål', + ['weapon'] = 'vapen', + ['giveweapon'] = 'ge vapen', + -- Weapons + ['weapon_knife'] = 'knife', + ['weapon_nightstick'] = 'nightstick', + ['weapon_hammer'] = 'hammer', + ['weapon_bat'] = 'bat', + ['weapon_golfclub'] = 'golf club', + ['weapon_crowbar'] = 'crow bar', + ['weapon_pistol'] = 'pistol', + ['weapon_combatpistol'] = 'combat pistol', + ['weapon_appistol'] = 'ap pistol', + ['weapon_pistol50'] = 'pistol .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'assault smg', + ['weapon_assaultrifle'] = 'assault rifle', + ['weapon_carbinerifle'] = 'carbine rifle', + ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'combat mg', + ['weapon_pumpshotgun'] = 'pump shotgun', + ['weapon_sawnoffshotgun'] = 'sawed off shotgun', + ['weapon_assaultshotgun'] = 'assault shotgun', + ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'sniper rifle', + ['weapon_heavysniper'] = 'heavy sniper', + ['weapon_remotesniper'] = 'remote sniper', + ['weapon_grenadelauncher'] = 'grenade launcher', + ['weapon_rpg'] = 'rocket launcher', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'grenade', + ['weapon_stickybomb'] = 'sticky bomb', + ['weapon_smokegrenade'] = 'smoke grenade', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'molotov cocktail', + ['weapon_fireextinguisher'] = 'fire extinguisher', + ['weapon_petrolcan'] = 'jerrycan', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'ball', + ['weapon_snspistol'] = 'sns pistol', + ['weapon_bottle'] = 'bottle', + ['weapon_gusenberg'] = 'gusenberg sweeper', + ['weapon_specialcarbine'] = 'special carbine', + ['weapon_heavypistol'] = 'heavy pistol', + ['weapon_bullpuprifle'] = 'bullpup rifle', + ['weapon_dagger'] = 'dagger', + ['weapon_vintagepistol'] = 'vintage pistol', + ['weapon_firework'] = 'firework', + ['weapon_musket'] = 'musket', + ['weapon_heavyshotgun'] = 'heavy shotgun', + ['weapon_marksmanrifle'] = 'marksman rifle', + ['weapon_hominglauncher'] = 'homing launcher', + ['weapon_proxmine'] = 'proximity mine', + ['weapon_snowball'] = 'snow ball', + ['weapon_flaregun'] = 'flaregun', + ['weapon_garbagebag'] = 'garbage bag', + ['weapon_handcuffs'] = 'handcuffs', + ['weapon_combatpdw'] = 'combat pdw', + ['weapon_marksmanpistol'] = 'marksman pistol', + ['weapon_knuckle'] = 'knuckledusters', + ['weapon_hatchet'] = 'hatchet', + ['weapon_railgun'] = 'railgun', + ['weapon_machete'] = 'machete', + ['weapon_machinepistol'] = 'machine pistol', + ['weapon_switchblade'] = 'switchblade', + ['weapon_revolver'] = 'heavy revolver', + ['weapon_dbshotgun'] = 'double barrel shotgun', + ['weapon_compactrifle'] = 'compact rifle', + ['weapon_autoshotgun'] = 'auto shotgun', + ['weapon_battleaxe'] = 'battle axe', + ['weapon_compactlauncher'] = 'compact launcher', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'pipe bomb', + ['weapon_poolcue'] = 'pool cue', + ['weapon_wrench'] = 'pipe wrench', + ['weapon_flashlight'] = 'flashlight', + ['gadget_nightvision'] = 'night vision', + ['gadget_parachute'] = 'parachute', +} From 8cefef021828efbba9595b6b166193d5a1e084c1 Mon Sep 17 00:00:00 2001 From: Vanheden <33155577+Vanheden@users.noreply.github.com> Date: Wed, 7 Mar 2018 15:09:43 +0100 Subject: [PATCH 166/672] Update __resource.lua --- __resource.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/__resource.lua b/__resource.lua index 9dd1a91b..e93e2936 100644 --- a/__resource.lua +++ b/__resource.lua @@ -13,6 +13,7 @@ server_scripts { 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', + 'locales/sv.lua', 'config.weapons.lua', 'server/common.lua', 'server/classes/player.lua', @@ -29,6 +30,7 @@ client_scripts { 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', + 'locales/sv.lua', 'config.weapons.lua', 'client/common.lua', 'client/entityiter.lua', From a1410d6963f2892e8f5440fe5ef4af2ebd650957 Mon Sep 17 00:00:00 2001 From: Vanheden <33155577+Vanheden@users.noreply.github.com> Date: Wed, 7 Mar 2018 15:10:42 +0100 Subject: [PATCH 167/672] Create sv_es_extended --- localization/sv_es_extended | 69 +++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 localization/sv_es_extended diff --git a/localization/sv_es_extended b/localization/sv_es_extended new file mode 100644 index 00000000..0add2588 --- /dev/null +++ b/localization/sv_es_extended @@ -0,0 +1,69 @@ +USE `essentialmode`; + +ALTER TABLE `users` + ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, + ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, + ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` +; + +CREATE TABLE `items` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `limit` int(11) NOT NULL DEFAULT '-1', + `rare` int(11) NOT NULL DEFAULT '0', + `can_remove` int(11) NOT NULL DEFAULT '1', + + PRIMARY KEY (`id`) +); + +CREATE TABLE `job_grades` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `job_name` varchar(255) DEFAULT NULL, + `grade` int(11) NOT NULL, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `salary` int(11) NOT NULL, + `skin_male` longtext NOT NULL, + `skin_female` longtext NOT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','A-Kassa',200,'{}','{}'); + +CREATE TABLE `jobs` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) DEFAULT NULL, + + PRIMARY KEY (`id`) +); + +INSERT INTO `jobs` VALUES (1,'unemployed','Arbetslös'); + +CREATE TABLE `user_accounts` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `money` double NOT NULL DEFAULT '0', + + PRIMARY KEY (`id`) +); + +CREATE TABLE `user_inventory` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `item` varchar(255) NOT NULL, + `count` int(11) NOT NULL, + + PRIMARY KEY (`id`) +); From 152040a8c66f487f96941b4bc43a76cbf4b00ff7 Mon Sep 17 00:00:00 2001 From: Vanheden <33155577+Vanheden@users.noreply.github.com> Date: Wed, 7 Mar 2018 15:11:03 +0100 Subject: [PATCH 168/672] Rename sv_es_extended to sv_es_extended.sql --- localization/{sv_es_extended => sv_es_extended.sql} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename localization/{sv_es_extended => sv_es_extended.sql} (100%) diff --git a/localization/sv_es_extended b/localization/sv_es_extended.sql similarity index 100% rename from localization/sv_es_extended rename to localization/sv_es_extended.sql From 2ce4629d735dc687850dc90b2d9f7d4f7d549eee Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 8 Mar 2018 00:13:57 -0500 Subject: [PATCH 169/672] Fixed vehicle network id issues by removing mission entity re gistration adding proper manifest version and setting up vehicle migration from config --- __resource.lua | 2 +- client/functions.lua | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/__resource.lua b/__resource.lua index 9dd1a91b..d4d72cc4 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,4 +1,4 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9' description 'ES Extended' diff --git a/client/functions.lua b/client/functions.lua index 3d413cbc..2be4b88a 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -390,7 +390,7 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) local id = NetworkGetNetworkIdFromEntity(vehicle) SetNetworkIdCanMigrate(id, true) - SetEntityAsMissionEntity(vehicle, true, false) + --SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) @@ -423,7 +423,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) - SetEntityAsMissionEntity(vehicle, true, false) + --SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) @@ -1182,7 +1182,7 @@ ESX.ShowInventory = function() function(data2, menu2) local quantity = tonumber(data2.value) if quantity <= pedammo and quantity >= 0 and quantity ~= nil then - local ammobefore = GetAmmoInPedWeapon(playerPed, item) + local ammobefore = GetAmmoInPedWeapon(playerPed, item) TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) local finalammo = math.floor(ammobefore - quantity) SetPedAmmo(playerPed, item, finalammo) @@ -1255,7 +1255,7 @@ ESX.ShowInventory = function() local quantity = tonumber(data2.value) if quantity <= pedammo and quantity >= 0 and quantity ~= nil then - local ammobefore = GetAmmoInPedWeapon(playerPed, item) + local ammobefore = GetAmmoInPedWeapon(playerPed, item) TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) local finalammo = math.floor(ammobefore - quantity) SetPedAmmo(playerPed, item, finalammo) @@ -1324,7 +1324,7 @@ ESX.ShowInventory = function() function(data2, menu2) local quantity = tonumber(data2.value) if quantity <= pedammo and quantity >= 0 and quantity ~= nil then - local ammobefore2 = GetAmmoInPedWeapon(closestPed, item) + local ammobefore2 = GetAmmoInPedWeapon(closestPed, item) local finalammo = math.floor(pedammo - quantity) local finalammo2 = math.floor(ammobefore2 + quantity) SetPedAmmo(playerPed, item, finalammo) From f3e15cabdbdf0e148a77b43a85db03708585cc53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Thu, 15 Mar 2018 12:10:03 +0100 Subject: [PATCH 170/672] Add nui message chunking --- __resource.lua | 2 ++ client/wrapper.lua | 16 ++++++++++++++++ html/js/wrapper.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 client/wrapper.lua create mode 100644 html/js/wrapper.js diff --git a/__resource.lua b/__resource.lua index 9dd1a91b..2040c72a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -33,6 +33,7 @@ client_scripts { 'client/common.lua', 'client/entityiter.lua', 'client/functions.lua', + 'client/wrapper.lua', 'client/main.lua' } @@ -46,6 +47,7 @@ files { 'html/css/app.css', 'html/js/mustache.min.js', + 'html/js/wrapper.js', 'html/js/app.js', 'html/fonts/pdown.ttf', diff --git a/client/wrapper.lua b/client/wrapper.lua new file mode 100644 index 00000000..9ac13dcf --- /dev/null +++ b/client/wrapper.lua @@ -0,0 +1,16 @@ +local Chunks = {} + +RegisterNUICallback('__chunk', function(data, cb) + + Chunks[data.id] = Chunks[data.id] or '' + Chunks[data.id] = Chunks[data.id] .. data.chunk + + if data['end'] then + local msg = json.decode(Chunks[data.id]) + TriggerEvent(GetCurrentResourceName() .. ':message:' .. data.__type, msg) + Chunks[data.id] = nil + end + + cb('') + +end) diff --git a/html/js/wrapper.js b/html/js/wrapper.js new file mode 100644 index 00000000..054e8d06 --- /dev/null +++ b/html/js/wrapper.js @@ -0,0 +1,42 @@ +(() => { + + let ESXWrapper = {}; + ESXWrapper.MessageSize = 1024; + ESXWrapper.messageId = 0; + + window.SendMessage = function(namespace, type, msg) { + + ESXWrapper.messageId = (ESXWrapper.messageId < 65535) ? ESXWrapper.messageId + 1 : 0; + const str = JSON.stringify(msg); + + for(let i=0; i Date: Thu, 15 Mar 2018 12:39:23 +0100 Subject: [PATCH 171/672] bump version --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index 2040c72a..0fd1fb25 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.12' +version '1.0.13' server_scripts { '@async/async.lua', From 09b1164e15a395a9fd9ace12e61860394b583eb6 Mon Sep 17 00:00:00 2001 From: Tracid Date: Sat, 17 Mar 2018 07:38:26 +0100 Subject: [PATCH 172/672] Add Doomsday Weapons. --- config.weapons.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/config.weapons.lua b/config.weapons.lua index ec1327ce..c16f019c 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -77,4 +77,13 @@ Config.Weapons = { { name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight') }, { name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision') }, { name = 'GADGET_PARACHUTE', label = _U('gadget_parachute') }, + { name = 'WEAPON_FLARE', label = _U('weapon_flare') }, + { name = 'WEAPON_SNSPISTOL_MK2', label = _U('weapon_snspistol_mk2') }, + { name = 'WEAPON_REVOLVER_MK2', label = _U('weapon_revolver_mk2') }, + { name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction') }, + { name = 'WEAPON_SPECIALCARBINE_MK2', label = _U('weapon_specialcarabine_mk2') }, + { name = 'WEAPON_BULLPUPRIFLE_MK2', label = _U('weapon_bullpruprifle_mk2') }, + { name = 'WEAPON_PUMPSHOTGUN_MK2', label = _U('weapon_pumpshotgun_mk2') }, + { name = 'WEAPON_MARKSMANRIFLE_MK2 ', label = _U('weapon_marksmanrifle_mk2') }, + } From 60bde9e43901d0bc3014404108b0a3dc0c3a8bd5 Mon Sep 17 00:00:00 2001 From: Tracid Date: Sat, 17 Mar 2018 07:42:31 +0100 Subject: [PATCH 173/672] Add Doomsday Weapons --- locales/fr.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/locales/fr.lua b/locales/fr.lua index dcae71ec..c685620a 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -133,4 +133,12 @@ Locales['fr'] = { ['weapon_flashlight'] = 'lampe torche', ['gadget_nightvision'] = 'vision nocturne', ['gadget_parachute'] = 'parachute', + ['weapon_flare'] = 'Fusée Détresse', + ['weapon_snspistol_mk2'] = 'Snspistol MK2', + ['weapon_revolver_mk2'] = 'Revolver MK2', + ['weapon_doubleaction'] = 'Revolver DoubleAction', + ['weapon_specialcarabine_mk2'] = 'SP Carabine MK2', + ['weapon_bullpruprifle_mk2'] = 'Rifle MK2', + ['weapon_pumpshotgun_mk2'] = 'Pompe MK2', + ['weapon_marksmanrifle_mk2'] = 'Rifle MK2', } From 0b23dde6c831ad4256cc6ea68eb7f8ccd2ab6447 Mon Sep 17 00:00:00 2001 From: Tracid Date: Sat, 17 Mar 2018 13:44:32 +0100 Subject: [PATCH 174/672] Update config.weapons.lua --- config.weapons.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.weapons.lua b/config.weapons.lua index c16f019c..cd1567df 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -84,6 +84,6 @@ Config.Weapons = { { name = 'WEAPON_SPECIALCARBINE_MK2', label = _U('weapon_specialcarabine_mk2') }, { name = 'WEAPON_BULLPUPRIFLE_MK2', label = _U('weapon_bullpruprifle_mk2') }, { name = 'WEAPON_PUMPSHOTGUN_MK2', label = _U('weapon_pumpshotgun_mk2') }, - { name = 'WEAPON_MARKSMANRIFLE_MK2 ', label = _U('weapon_marksmanrifle_mk2') }, + { name = 'WEAPON_MARKSMANRIFLE_MK2', label = _U('weapon_marksmanrifle_mk2') }, } From 06ad627b989a53d50f808e8c8d41417fcb05141b Mon Sep 17 00:00:00 2001 From: Tracid Date: Sat, 17 Mar 2018 15:42:24 +0100 Subject: [PATCH 175/672] Update fr.lua --- locales/fr.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index c685620a..e7dfd06c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -138,7 +138,7 @@ Locales['fr'] = { ['weapon_revolver_mk2'] = 'Revolver MK2', ['weapon_doubleaction'] = 'Revolver DoubleAction', ['weapon_specialcarabine_mk2'] = 'SP Carabine MK2', - ['weapon_bullpruprifle_mk2'] = 'Rifle MK2', + ['weapon_bullpruprifle_mk2'] = 'Bullprup Rifle MK2', ['weapon_pumpshotgun_mk2'] = 'Pompe MK2', - ['weapon_marksmanrifle_mk2'] = 'Rifle MK2', + ['weapon_marksmanrifle_mk2'] = 'MarksMan Rifle MK2', } From 2434eaee00d690b4a9b00460a2493cc876879c12 Mon Sep 17 00:00:00 2001 From: Tracid Date: Sat, 17 Mar 2018 16:10:13 +0100 Subject: [PATCH 176/672] Update config.weapons.lua --- config.weapons.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/config.weapons.lua b/config.weapons.lua index cd1567df..04546755 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -85,5 +85,10 @@ Config.Weapons = { { name = 'WEAPON_BULLPUPRIFLE_MK2', label = _U('weapon_bullpruprifle_mk2') }, { name = 'WEAPON_PUMPSHOTGUN_MK2', label = _U('weapon_pumpshotgun_mk2') }, { name = 'WEAPON_MARKSMANRIFLE_MK2', label = _U('weapon_marksmanrifle_mk2') }, - + { name = 'WEAPON_ASSAULTRIFLE_MK2', label = _U('weapon_assaultrifle_mk2') }, + { name = 'WEAPON_CARBINERIFLE_MK2', label = _U('weapon_carbinerifle_mk2') }, + { name = 'WEAPON_COMBATMG_MK2', label = _U('weapon_combatmg_mk2') }, + { name = 'WEAPON_HEAVYSNIPER_MK2', label = _U('weapon_heavysniper_mk2') }, + { name = 'WEAPON_PISTOL_MK2', label = _U('weapon_pistol_mk2') }, + { name = 'WEAPON_SMG_MK2', label = _U('weapon_smg_mk2') }, } From 7a6c789bec77574bde965f4ff98a6e27a7b7b218 Mon Sep 17 00:00:00 2001 From: Tracid Date: Sat, 17 Mar 2018 16:11:00 +0100 Subject: [PATCH 177/672] Update fr.lua --- locales/fr.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/locales/fr.lua b/locales/fr.lua index e7dfd06c..142c9274 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -140,5 +140,11 @@ Locales['fr'] = { ['weapon_specialcarabine_mk2'] = 'SP Carabine MK2', ['weapon_bullpruprifle_mk2'] = 'Bullprup Rifle MK2', ['weapon_pumpshotgun_mk2'] = 'Pompe MK2', - ['weapon_marksmanrifle_mk2'] = 'MarksMan Rifle MK2', + ['weapon_marksmanrifle_mk2'] = 'MarksMan Rifle MK2', + ['weapon_assaultrifle_mk2'] = 'Assault MK2', + ['weapon_carbinerifle_mk2'] = 'Rifle Carabine MK2', + ['weapon_combatmg_mk2'] = 'Mitrailleuse MK2', + ['weapon_heavysniper_mk2'] = 'Heavy Sniper MK2', + ['weapon_pistol_mk2'] = 'Pistol MK2', + ['weapon_smg_mk2'] = 'SMG MK2', } From 88c4c22fae3fbf6e4a6b0890dd8db2f8e527cb35 Mon Sep 17 00:00:00 2001 From: Tracid Date: Sat, 17 Mar 2018 16:27:55 +0100 Subject: [PATCH 178/672] Best Name Weapons --- locales/fr.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 142c9274..1f447f78 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -134,17 +134,17 @@ Locales['fr'] = { ['gadget_nightvision'] = 'vision nocturne', ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'Fusée Détresse', - ['weapon_snspistol_mk2'] = 'Snspistol MK2', - ['weapon_revolver_mk2'] = 'Revolver MK2', - ['weapon_doubleaction'] = 'Revolver DoubleAction', - ['weapon_specialcarabine_mk2'] = 'SP Carabine MK2', - ['weapon_bullpruprifle_mk2'] = 'Bullprup Rifle MK2', - ['weapon_pumpshotgun_mk2'] = 'Pompe MK2', - ['weapon_marksmanrifle_mk2'] = 'MarksMan Rifle MK2', - ['weapon_assaultrifle_mk2'] = 'Assault MK2', - ['weapon_carbinerifle_mk2'] = 'Rifle Carabine MK2', - ['weapon_combatmg_mk2'] = 'Mitrailleuse MK2', - ['weapon_heavysniper_mk2'] = 'Heavy Sniper MK2', - ['weapon_pistol_mk2'] = 'Pistol MK2', - ['weapon_smg_mk2'] = 'SMG MK2', + ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', + ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', + ['weapon_doubleaction'] = 'Double-Action Revolver', + ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', + ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', + ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', + ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', + ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', + ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', + ['weapon_combatmg_mk2'] = 'Combat MG Mk II', + ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', + ['weapon_pistol_mk2'] = 'Pistol Mk II', + ['weapon_smg_mk2'] = 'SMG Mk II', } From aacc2d108363e9381a212d78a6d5dcb0fb305d4c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 17 Mar 2018 18:11:16 +0100 Subject: [PATCH 179/672] Fixed ammo bug Fixed the famous ammo bug where if you remove a weapon from your inventory, it doesn't remove the ammo for it. --- client/main.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index cec70363..245c8976 100644 --- a/client/main.lua +++ b/client/main.lua @@ -170,6 +170,7 @@ AddEventHandler('esx:addWeapon', function(weaponName, ammo) local weaponHash = GetHashKey(weaponName) GiveWeaponToPed(playerPed, weaponHash, ammo, false, false) + SetPedAmmo(playerPed, weaponHash, ammo) -- remove leftover ammo end) RegisterNetEvent('esx:removeWeapon') @@ -178,6 +179,7 @@ AddEventHandler('esx:removeWeapon', function(weaponName) local weaponHash = GetHashKey(weaponName) RemoveWeaponFromPed(playerPed, weaponHash) + SetPedAmmo(playerPed, weaponHash, 0) -- remove leftover ammo end) -- Commands @@ -337,7 +339,6 @@ AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName,ammo) local ped = GetPlayerPed(-1) local playerPedPos = GetEntityCoords(ped, true) - print(ammo) CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, ammo, 1, false, true) end) From 5fbf544e0fa38dcd64dc93980195cbe3885d0e5c Mon Sep 17 00:00:00 2001 From: MrLumi Date: Wed, 28 Mar 2018 11:09:52 +0100 Subject: [PATCH 180/672] Update br.lua --- locales/br.lua | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/locales/br.lua b/locales/br.lua index 89379694..867307ec 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -119,4 +119,18 @@ Locales['br'] = { ['weapon_flashlight'] = 'laterna', ['gadget_nightvision'] = 'visão noturna', ['gadget_parachute'] = 'paraquedas', + ['weapon_flare'] = 'Flare', + ['weapon_snspistol_mk2'] = 'Pistola SNS Mk II', + ['weapon_revolver_mk2'] = 'Revolver Pesada Mk II', + ['weapon_doubleaction'] = 'Revolver Dupla-acao', + ['weapon_specialcarabine_mk2'] = 'Carabina Especial Mk II', + ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', + ['weapon_pumpshotgun_mk2'] = 'Espingarda Mk II', + ['weapon_marksmanrifle_mk2'] = 'Rifle Marksman Mk II', + ['weapon_assaultrifle_mk2'] = 'Rifle de assalto Mk II ', + ['weapon_carbinerifle_mk2'] = 'Carabina Mk II ', + ['weapon_combatmg_mk2'] = 'MG de Combate Mk II', + ['weapon_heavysniper_mk2'] = 'Sniper pesada Mk II', + ['weapon_pistol_mk2'] = 'Pistola Mk II', + ['weapon_smg_mk2'] = 'SMG Mk II', } From 7f8f7f880474e855f5eb85af4003698249f06db7 Mon Sep 17 00:00:00 2001 From: renildomarcio Date: Sun, 1 Apr 2018 12:15:25 -0300 Subject: [PATCH 181/672] Create br_es_extened.sql --- localization/br_es_extened.sql | 69 ++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 localization/br_es_extened.sql diff --git a/localization/br_es_extened.sql b/localization/br_es_extened.sql new file mode 100644 index 00000000..cf210476 --- /dev/null +++ b/localization/br_es_extened.sql @@ -0,0 +1,69 @@ + USE `essentialmode`; + + ALTER TABLE `users` + ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, + ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, + ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` + ; + + CREATE TABLE `items` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `limit` int(11) NOT NULL DEFAULT '-1', + `rare` int(11) NOT NULL DEFAULT '0', + `can_remove` int(11) NOT NULL DEFAULT '1', + + PRIMARY KEY (`id`) + ); + + CREATE TABLE `job_grades` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `job_name` varchar(255) DEFAULT NULL, + `grade` int(11) NOT NULL, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `salary` int(11) NOT NULL, + `skin_male` longtext NOT NULL, + `skin_female` longtext NOT NULL, + + PRIMARY KEY (`id`) + ); + + INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','Desempregado',200,'{}','{}'); + + CREATE TABLE `jobs` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `label` varchar(255) DEFAULT NULL, + + PRIMARY KEY (`id`) + ); + + INSERT INTO `jobs` VALUES (1,'unemployed','Desempregado'); + + CREATE TABLE `user_accounts` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `money` double NOT NULL DEFAULT '0', + + PRIMARY KEY (`id`) + ); + + CREATE TABLE `user_inventory` ( + + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `item` varchar(255) NOT NULL, + `count` int(11) NOT NULL, + + PRIMARY KEY (`id`) + ); From 6153d956863cc3717108ac9c2efb7669158f9889 Mon Sep 17 00:00:00 2001 From: renildomarcio Date: Sun, 1 Apr 2018 12:18:10 -0300 Subject: [PATCH 182/672] Update br.lua --- locales/br.lua | 259 ++++++++++++++++++++++++++----------------------- 1 file changed, 137 insertions(+), 122 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 89379694..09e9f65e 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,122 +1,137 @@ -Locales['br'] = { - ['inventory'] = 'inventário', - ['use'] = 'usar', - ['give'] = 'dar', - ['remove'] = 'remover', - ['return'] = 'voltar', - ['amount'] = 'quantidade', - ['amount_invalid'] = 'quantidade inválida', - ['players_nearby'] = 'nenhum jogador nas proximidades', - ['ex_inv_lim'] = 'Esta ação não é possível, supera o limite do inventário para ~b~', - ['yougave'] = 'você deu', - ['youreceived'] = 'você recebeu', - ['to'] = '~s~ para ~b~', - ['by'] = '~s~ por ~b~', - ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', - ['imp_invalid_amount'] = 'ação impossível, valor inválido', - ['delete_five_min'] = '~r~deleta~s~ em 5 minutos', - ['threw'] = 'você ~r~jogou~s~', - ['rec_salary'] = 'você recebeu seu salário: ', - ['act_imp'] = 'ação impossível', - -- Commands - ['setjob'] = 'atribuir um emprego a um usuário', - ['id_param'] = 'o id do jogador', - ['setjob_param2'] = 'o trabalho que você deseja atribuir', - ['setjob_param3'] = 'o nível de trabalho', - ['load_ipl'] = 'carregando ipl', - ['unload_ipl'] = 'descarregando ipl', - ['play_anim'] = 'reproduzir animação', - ['play_emote'] = 'reproduzir emote', - ['spawn_car'] = 'fazer aparecer um carro', - ['spawn_car_param'] = 'nome do carro', - ['spawn_object'] = 'gerar um objeto', - ['givemoney'] = 'dar dinheiro', - ['money_amount'] = 'quantia do dinheiro', - ['invalid_account'] = 'conta inválida', - ['account'] = 'conta', - ['giveaccountmoney'] = 'dar dinheiro em conta', - ['invalid_item'] = 'item inválido', - ['item'] = 'item', - ['giveitem'] = 'dar item', - ['weapon'] = 'arma', - ['giveweapon'] = 'dar arma', - -- Weapons - ['weapon_knife'] = 'ffaca', - ['weapon_nightstick'] = 'cacetete', - ['weapon_hammer'] = 'martelo', - ['weapon_bat'] = 'bastão', - ['weapon_golfclub'] = 'golf club', - ['weapon_crowbar'] = 'pé de cabra', - ['weapon_pistol'] = 'pistola', - ['weapon_combatpistol'] = 'pistola de combate', - ['weapon_appistol'] = 'ap pistola', - ['weapon_pistol50'] = 'pistola .50', - ['weapon_microsmg'] = 'micro smg', - ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'assault smg', - ['weapon_assaultrifle'] = 'assault rifle', - ['weapon_carbinerifle'] = 'carbine rifle', - ['weapon_advancedrifle'] = 'advanced rifle', - ['weapon_mg'] = 'mg', - ['weapon_combatmg'] = 'combat mg', - ['weapon_pumpshotgun'] = 'espingarda', - ['weapon_sawnoffshotgun'] = 'sawed off shotgun', - ['weapon_assaultshotgun'] = 'assault shotgun', - ['weapon_bullpupshotgun'] = 'bullpup shotgun', - ['weapon_stungun'] = 'arma de choque', - ['weapon_sniperrifle'] = 'sniper rifle', - ['weapon_heavysniper'] = 'heavy sniper', - ['weapon_remotesniper'] = 'remote sniper', - ['weapon_grenadelauncher'] = 'lançador de granada', - ['weapon_rpg'] = 'lançador de foguetes', - ['weapon_stinger'] = 'stinger', - ['weapon_minigun'] = 'minigun', - ['weapon_grenade'] = 'granada', - ['weapon_stickybomb'] = 'bomba pegajosa', - ['weapon_smokegrenade'] = 'granada de fumaça', - ['weapon_bzgas'] = 'bz gas', - ['weapon_molotov'] = 'coquetel molotov', - ['weapon_fireextinguisher'] = 'extintor', - ['weapon_petrolcan'] = 'galão de combustivel', - ['weapon_digiscanner'] = 'digiscanner', - ['weapon_ball'] = 'bola', - ['weapon_snspistol'] = 'sns pistol', - ['weapon_bottle'] = 'garrafa', - ['weapon_gusenberg'] = 'gusenberg sweeper', - ['weapon_specialcarbine'] = 'carabina especial', - ['weapon_heavypistol'] = 'heavy pistol', - ['weapon_bullpuprifle'] = 'bullpup rifle', - ['weapon_dagger'] = 'punhal', - ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_firework'] = 'fogos de artifício', - ['weapon_musket'] = 'mosquete', - ['weapon_heavyshotgun'] = 'heavy shotgun', - ['weapon_marksmanrifle'] = 'marksman rifle', - ['weapon_hominglauncher'] = 'homing launcher', - ['weapon_proxmine'] = 'mina de proximidade', - ['weapon_snowball'] = 'bola de neve', - ['weapon_flaregun'] = 'sinalizador', - ['weapon_garbagebag'] = 'saco de lixo', - ['weapon_handcuffs'] = 'algemas', - ['weapon_combatpdw'] = 'combat pdw', - ['weapon_marksmanpistol'] = 'marksman pistol', - ['weapon_knuckle'] = 'soco inglês', - ['weapon_hatchet'] = 'machado', - ['weapon_railgun'] = 'railgun', - ['weapon_machete'] = 'facão', - ['weapon_machinepistol'] = 'machine pistol', - ['weapon_switchblade'] = 'canivete', - ['weapon_revolver'] = 'heavy revolver', - ['weapon_dbshotgun'] = 'espingarda de cano duplo', - ['weapon_compactrifle'] = 'compact rifle', - ['weapon_autoshotgun'] = 'auto shotgun', - ['weapon_battleaxe'] = 'battle axe', - ['weapon_compactlauncher'] = 'compact launcher', - ['weapon_minismg'] = 'mini smg', - ['weapon_pipebomb'] = 'bomba caseira', - ['weapon_poolcue'] = 'taco de sinuca', - ['weapon_wrench'] = 'chave de cano', - ['weapon_flashlight'] = 'laterna', - ['gadget_nightvision'] = 'visão noturna', - ['gadget_parachute'] = 'paraquedas', -} + Locales['br'] = { + ['inventory'] = 'inventário', + ['use'] = 'use', + ['give'] = 'dar', + ['remove'] = 'remover', + ['return'] = 'retorna', + ['amount'] = 'quantidade', + ['amountammo'] = 'quantidade de munição', + ['noammo'] = 'Você não tem todas essas munições!', + ['withammo'] = '~s~ com x', + ['ammogiven'] = '~s~ balas', + ['giveammo'] = 'Dar munição', + ['amount_invalid'] = 'quantidade inválida', + ['players_nearby'] = 'nenhum jogador por perto', + ['ex_inv_lim'] = 'ação não é possível, excedendo o limite de estoque para ~b~', + ['yougave'] = 'você deu', + ['youreceived'] = 'você recebeu', + ['to'] = '~s~ para ~b~', + ['by'] = '~s~ de ~b~', + ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', + ['imp_invalid_amount'] = 'ação impossível, valor inválido', + ['delete_five_min'] = '~r~excluir~s~ em 5 minutos', + ['threw'] = 'você ~r~jogou~s~', + ['rec_salary'] = 'você recebeu seu salário: ', + ['rec_help'] = 'você recebeu seu cheque de bem-estar: ', + ['company_paid'] = 'Cheque de pagamento da empresa recebido', + ['company_nomoney'] = 'Sua empresa está falida!', + ['state_paid'] = 'Você recebeu um cheque de estado', + ['act_imp'] = 'ação impossível', + ['in_vehicle'] = 'Você não pode dar nada para alguém no veículo', + -- Commands + ['setjob'] = 'atribuir um trabalho a um usuário', + ['id_param'] = 'o ID do jogador', + ['setjob_param2'] = 'o trabalho que você deseja atribuir', + ['setjob_param3'] = 'o nível de emprego', + ['load_ipl'] = 'carregar IPL', + ['unload_ipl'] = 'descarregar o IPL', + ['play_anim'] = 'tocar animação', + ['play_emote'] = 'jogar emote', + ['spawn_car'] = 'spawn um carro', + ['spawn_car_param'] = 'nome do carro', + ['delete_vehicle'] = 'excluir Veículo', + ['delete_veh_param'] = 'pressione Enter', + ['spawn_object'] = 'spawn objeto', + ['spawn_ped'] = 'spawn ped', + ['spawn_ped_param'] = 'exemplo a_m_m_hillbilly_01', + ['givemoney'] = 'dar dinheiro', + ['money_amount'] = 'quantia de dinheiro', + ['invalid_account'] = 'conta inválida', + ['account'] = 'conta', + ['giveaccountmoney'] = 'dar dinheiro da conta', + ['invalid_item'] = 'item inválido', + ['item'] = 'item', + ['giveitem'] = 'dar item', + ['weapon'] = 'arma', + ['giveweapon'] = 'dar arma', + -- Weapons + ['weapon_knife'] = 'faca', + ['weapon_nightstick'] = 'cacetete', + ['weapon_hammer'] = 'martelo', + ['weapon_bat'] = 'bastão', + ['weapon_golfclub'] = 'golf club', + ['weapon_crowbar'] = 'pé de cabra', + ['weapon_pistol'] = 'pistola', + ['weapon_combatpistol'] = 'pistola de combate', + ['weapon_appistol'] = 'ap pistola', + ['weapon_pistol50'] = 'pistola .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'assault smg', + ['weapon_assaultrifle'] = 'assault rifle', + ['weapon_carbinerifle'] = 'carbine rifle', + ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'combat mg', + ['weapon_pumpshotgun'] = 'espingarda', + ['weapon_sawnoffshotgun'] = 'sawed off shotgun', + ['weapon_assaultshotgun'] = 'assault shotgun', + ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_stungun'] = 'arma de choque', + ['weapon_sniperrifle'] = 'sniper rifle', + ['weapon_heavysniper'] = 'heavy sniper', + ['weapon_remotesniper'] = 'remote sniper', + ['weapon_grenadelauncher'] = 'lançador de granada', + ['weapon_rpg'] = 'lançador de foguetes', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'granada', + ['weapon_stickybomb'] = 'bomba pegajosa', + ['weapon_smokegrenade'] = 'granada de fumaça', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'coquetel molotov', + ['weapon_fireextinguisher'] = 'extintor', + ['weapon_petrolcan'] = 'galão de combustivel', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'bola', + ['weapon_snspistol'] = 'sns pistol', + ['weapon_bottle'] = 'garrafa', + ['weapon_gusenberg'] = 'gusenberg sweeper', + ['weapon_specialcarbine'] = 'carabina especial', + ['weapon_heavypistol'] = 'heavy pistol', + ['weapon_bullpuprifle'] = 'bullpup rifle', + ['weapon_dagger'] = 'punhal', + ['weapon_vintagepistol'] = 'vintage pistol', + ['weapon_firework'] = 'fogos de artifício', + ['weapon_musket'] = 'mosquete', + ['weapon_heavyshotgun'] = 'heavy shotgun', + ['weapon_marksmanrifle'] = 'marksman rifle', + ['weapon_hominglauncher'] = 'homing launcher', + ['weapon_proxmine'] = 'mina de proximidade', + ['weapon_snowball'] = 'bola de neve', + ['weapon_flaregun'] = 'sinalizador', + ['weapon_garbagebag'] = 'saco de lixo', + ['weapon_handcuffs'] = 'algemas', + ['weapon_combatpdw'] = 'combat pdw', + ['weapon_marksmanpistol'] = 'marksman pistol', + ['weapon_knuckle'] = 'soco inglês', + ['weapon_hatchet'] = 'machado', + ['weapon_railgun'] = 'railgun', + ['weapon_machete'] = 'facão', + ['weapon_machinepistol'] = 'machine pistol', + ['weapon_switchblade'] = 'canivete', + ['weapon_revolver'] = 'heavy revolver', + ['weapon_dbshotgun'] = 'espingarda de cano duplo', + ['weapon_compactrifle'] = 'compact rifle', + ['weapon_autoshotgun'] = 'auto shotgun', + ['weapon_battleaxe'] = 'battle axe', + ['weapon_compactlauncher'] = 'compact launcher', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'bomba caseira', + ['weapon_poolcue'] = 'taco de sinuca', + ['weapon_wrench'] = 'chave de cano', + ['weapon_flashlight'] = 'laterna', + ['gadget_nightvision'] = 'visão noturna', + ['gadget_parachute'] = 'paraquedas', + } + From 2e67349645c8471b6a6a68dc6c09a368c85a830f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 14 Apr 2018 14:25:37 +0200 Subject: [PATCH 183/672] Fixed hardcoded strings, added new trigger esx:onPlayerDeath --- client/main.lua | 30 ++++++++++++++--------- locales/en.lua | 7 +++--- locales/fr.lua | 1 + locales/sv.lua | 1 + server/main.lua | 2 +- server/paycheck_company.lua | 48 ++++++++++++++++++------------------- 6 files changed, 50 insertions(+), 39 deletions(-) diff --git a/client/main.lua b/client/main.lua index 245c8976..b0d78e43 100644 --- a/client/main.lua +++ b/client/main.lua @@ -61,7 +61,7 @@ AddEventHandler('playerSpawned', function() Citizen.CreateThread(function() while not ESX.PlayerLoaded do - Citizen.Wait(0) + Citizen.Wait(1) end local playerPed = GetPlayerPed(-1) @@ -81,13 +81,21 @@ AddEventHandler('playerSpawned', function() end) +AddEventHandler('baseevents:onPlayerDied', function(killerType, coords) + TriggerEvent('esx:onPlayerDeath') +end) + +AddEventHandler('baseevents:onPlayerKilled', function(killerId, data) + TriggerEvent('esx:onPlayerDeath') +end) + AddEventHandler('skinchanger:loadDefaultModel', function() - LoadoutLoaded = false + LoadoutLoaded = false end) AddEventHandler('skinchanger:modelLoaded', function() while not ESX.PlayerLoaded do - Citizen.Wait(0) + Citizen.Wait(1) end TriggerEvent('esx:restoreLoadout') @@ -194,7 +202,7 @@ AddEventHandler('esx:teleport', function(pos) while not HasCollisionLoadedAroundEntity(GetPlayerPed(-1)) do RequestCollisionAtCoord(pos.x, pos.y, pos.z) - Citizen.Wait(0) + Citizen.Wait(1) end SetEntityCoords(GetPlayerPed(-1), pos.x, pos.y, pos.z) @@ -239,7 +247,7 @@ AddEventHandler('esx:playAnim', function(dict, anim) RequestAnimDict(dict) while not HasAnimDictLoaded(dict) do - Wait(0) + Citizen.Wait(1) end TaskPlayAnim(pid, dict, anim, 1.0, -1.0, 20000, 0, 1, true, true, true) @@ -256,7 +264,7 @@ AddEventHandler('esx:playEmote', function(emote) local playerPed = GetPlayerPed(-1) TaskStartScenarioInPlace(playerPed, emote, 0, false); - Wait(20000) + Citizen.Wait(20000) ClearPedTasks(playerPed) end) @@ -357,7 +365,7 @@ AddEventHandler('esx:spawnPed', function(model) RequestModel(model) while not HasModelLoaded(model) do - Citizen.Wait(0) + Citizen.Wait(1) end CreatePed(5, model, x, y, z, 0.0, true, false) @@ -408,7 +416,7 @@ Citizen.CreateThread(function() while true do - Wait(0) + Citizen.Wait(1) local playerPed = GetPlayerPed(-1) local loadout = {} @@ -462,7 +470,7 @@ end) Citizen.CreateThread(function() while true do - Wait(0) + Citizen.Wait(10) if IsControlPressed(0, Keys["F2"]) and GetLastInputMethod(2) and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') and (GetGameTimer() - GUI.Time) > 150 then ESX.ShowInventory() @@ -500,7 +508,7 @@ if Config.DisableWantedLevel then Citizen.CreateThread(function() while true do - Citizen.Wait(0) + Citizen.Wait(10) local playerId = PlayerId() @@ -573,7 +581,7 @@ Citizen.CreateThread(function() while true do - Citizen.Wait(0) + Citizen.Wait(10) local playerPed = GetPlayerPed(-1) diff --git a/locales/en.lua b/locales/en.lua index 12bc40f7..d6cfa6d7 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -6,13 +6,13 @@ Locales['en'] = { ['return'] = 'return', ['amount'] = 'amount', ['amountammo'] = 'amount of ammo', - ['noammo'] = 'You dont have all these ammo !', + ['noammo'] = 'you do not have enough ammo!', ['withammo'] = '~s~ with x', ['ammogiven'] = '~s~ bullets', ['giveammo'] = 'Give ammo', ['amount_invalid'] = 'invalid amount', ['players_nearby'] = 'no players nearby', - ['ex_inv_lim'] = 'action not possible, exceeding invetory limit for ~b~', + ['ex_inv_lim'] = 'action not possible, exceeding inventory limit for ~b~', ['yougave'] = 'you gave', ['youreceived'] = 'you received', ['to'] = '~s~ to ~b~', @@ -27,7 +27,8 @@ Locales['en'] = { ['company_nomoney'] = 'Your company is broke!', ['state_paid'] = 'You received a state check', ['act_imp'] = 'action impossible', - ['in_vehicle'] = 'You can\'t give anything to someone in vehicle', + ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', + ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', -- Commands ['setjob'] = 'assign a job to a user', ['id_param'] = 'the ID of the player', diff --git a/locales/fr.lua b/locales/fr.lua index 1f447f78..c8d40f32 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -28,6 +28,7 @@ Locales['fr'] = { ['state_paid'] = 'L\'état vous a payé ', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', + ['cannot_pickup_room'] = 'vous n\'avez plus de place pour ~y~%s~s~!', -- Commands ['setjob'] = 'assigner job', ['id_param'] = 'identification du joueur', diff --git a/locales/sv.lua b/locales/sv.lua index bda695af..95912ed7 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -22,6 +22,7 @@ Locales['sv'] = { ['company_nomoney'] = 'Ditt företag är för fattigt!!', ['state_paid'] = 'Du fick en statlig check', ['act_imp'] = 'åtgärd omöjlig', + ['cannot_pickup_room'] = 'du har inte plats för att plocka upp ~y~%s~s~!', -- Commands ['setjob'] = 'tilldela ett jobb till en användare', ['id_param'] = 'spelarens ID', diff --git a/server/main.lua b/server/main.lua index 2e2e10cb..94bfc585 100644 --- a/server/main.lua +++ b/server/main.lua @@ -569,7 +569,7 @@ AddEventHandler('esx:onPickup', function(id) end if remaining > 0 then - TriggerClientEvent('esx:showNotification', _source, 'Vous n\'avez plus de place pour ~b~' .. item.label .. '~s~') + TriggerClientEvent('esx:showNotification', _source, _U('cannot_pickup_room', item.label)) ESX.CreatePickup('item_standard', pickup.name, remaining, item.label .. ' [' .. remaining .. ']', _source) end diff --git a/server/paycheck_company.lua b/server/paycheck_company.lua index 76773f27..892c0281 100644 --- a/server/paycheck_company.lua +++ b/server/paycheck_company.lua @@ -1,30 +1,30 @@ ESX.StartPayCheck = function () - function payCheck () - local xPlayers = ESX.GetPlayers() - for i=1, #xPlayers, 1 do - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - if xPlayer.job.grade_name == 'interim' or xPlayer.job.grade_name == 'rsa' or xPlayer.job.grade_name == 'employee' then -- Si il n'est pas dans une société, je prends chez l'état - if xPlayer.job.grade_salary > 0 then - xPlayer.addAccountMoney('bank',xPlayer.job.grade_salary) - TriggerClientEvent('esx:showNotification', xPlayer.source, ('L\'état vous a payé ') .. '~g~$' .. xPlayer.job.grade_salary) - end - else -- Sinon je prends l'argent dans la société - TriggerEvent('esx_society:getSociety', xPlayer.job.name, function (society) - TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function (account) - if account.money >= xPlayer.job.grade_salary then - xPlayer.addAccountMoney('bank',xPlayer.job.grade_salary) - account.removeMoney(xPlayer.job.grade_salary) - TriggerClientEvent('esx:showNotification', xPlayer.source, ('Votre entreprise vous a payé ') .. '~g~$' .. xPlayer.job.grade_salary) - else - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Votre entreprise n\'a plus d\'argent pour vous payer !') - end - end) - end) - end - end +function payCheck () + local xPlayers = ESX.GetPlayers() + for i=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + if xPlayer.job.grade_name == 'interim' or xPlayer.job.grade_name == 'rsa' or xPlayer.job.grade_name == 'employee' then -- only if the player is employeed in a company + if xPlayer.job.grade_salary > 0 then + xPlayer.addAccountMoney('bank', xPlayer.job.grade_salary) + TriggerClientEvent('esx:showNotification', xPlayer.source, ('L\'état vous a payé ') .. '~g~$' .. xPlayer.job.grade_salary) + end + else -- Else take money from society + TriggerEvent('esx_society:getSociety', xPlayer.job.name, function (society) + TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function (account) + if account.money >= xPlayer.job.grade_salary then + xPlayer.addAccountMoney('bank',xPlayer.job.grade_salary) + account.removeMoney(xPlayer.job.grade_salary) + TriggerClientEvent('esx:showNotification', xPlayer.source, ('Votre entreprise vous a payé ') .. '~g~$' .. xPlayer.job.grade_salary) + else + TriggerClientEvent('esx:showNotification', xPlayer.source, 'Votre entreprise n\'a plus d\'argent pour vous payer !') + end + end) + end) + end + end - SetTimeout(Config.PaycheckInterval, payCheck) + SetTimeout(Config.PaycheckInterval, payCheck) end SetTimeout(Config.PaycheckInterval, payCheck) end From 36d82c922fb2487967277070b1917a86425446ed Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 15 Apr 2018 01:33:33 +0200 Subject: [PATCH 184/672] See the description for changes (cleanup) - reworked /setmoney [id] [money type] [amount] - implemented /disc (/disconnect) - the give submenu does no longer appear if there's no one nearby - if you have 0 cash, bank or black money it wont appear in your f2 inventory - when selecting a item, let the item label be the title of the menu (inventory menu) - minor improvements --- client/functions.lua | 44 ++++++----- client/main.lua | 37 +++++---- locales/en.lua | 10 ++- locales/sv.lua | 6 +- .../{br_es_extened.sql => br_es_extended.sql} | 0 server/commands.lua | 75 +++++++++++++------ 6 files changed, 108 insertions(+), 64 deletions(-) rename localization/{br_es_extened.sql => br_es_extended.sql} (100%) diff --git a/client/functions.lua b/client/functions.lua index 2be4b88a..d6babc04 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1063,28 +1063,32 @@ ESX.ShowInventory = function() local playerPed = GetPlayerPed(-1) local elements = {} - table.insert(elements, { - label = '[Cash] $' .. ESX.PlayerData.money, - count = ESX.PlayerData.money, - type = 'item_money', - value = 'money', - usable = false, - rare = false, - canRemove = true - }) - - for i=1, #ESX.PlayerData.accounts, 1 do + if ESX.PlayerData.money > 0 then table.insert(elements, { - label = '[' .. ESX.PlayerData.accounts[i].label .. '] $' .. ESX.PlayerData.accounts[i].money, - count = ESX.PlayerData.accounts[i].money, - type = 'item_account', - value = ESX.PlayerData.accounts[i].name, + label = '[Cash] $' .. ESX.PlayerData.money, + count = ESX.PlayerData.money, + type = 'item_money', + value = 'money', usable = false, rare = false, canRemove = true }) end + for i=1, #ESX.PlayerData.accounts, 1 do + if ESX.PlayerData.accounts[i].money > 0 then + table.insert(elements, { + label = '[' .. ESX.PlayerData.accounts[i].label .. '] $' .. ESX.PlayerData.accounts[i].money, + count = ESX.PlayerData.accounts[i].money, + type = 'item_account', + value = ESX.PlayerData.accounts[i].name, + usable = false, + rare = false, + canRemove = true + }) + end + end + for i=1, #ESX.PlayerData.inventory, 1 do if ESX.PlayerData.inventory[i].count > 0 then @@ -1132,9 +1136,9 @@ ESX.ShowInventory = function() elements = elements, }, function(data, menu) - menu.close() + local player, distance = ESX.Game.GetClosestPlayer() local elements = {} if data.current.usable then @@ -1142,7 +1146,9 @@ ESX.ShowInventory = function() end if data.current.canRemove then - table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + if player ~= -1 and distance <= 3.0 then + table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + end table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) end @@ -1155,7 +1161,7 @@ ESX.ShowInventory = function() ESX.UI.Menu.Open( 'default', GetCurrentResourceName(), 'inventory_item', { - title = _U('inventory'), + title = data.current.label, align = 'bottom-right', elements = elements, }, @@ -1301,14 +1307,12 @@ ESX.ShowInventory = function() end elseif data.current.action == 'use' then - TriggerServerEvent('esx:useItem', data.current.value) elseif data.current.action == 'return' then ESX.UI.Menu.CloseAll() ESX.ShowInventory() - elseif data.current.action == 'giveammo' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() local closestPed = GetPlayerPed(closestPlayer) diff --git a/client/main.lua b/client/main.lua index b0d78e43..53e5bab7 100644 --- a/client/main.lua +++ b/client/main.lua @@ -17,6 +17,7 @@ local IsPaused = false local PlayerSpawned = false local LastLoadout = {} local Pickups = {} +local isDead = false RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) @@ -57,28 +58,22 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) end) AddEventHandler('playerSpawned', function() + while not ESX.PlayerLoaded do + Citizen.Wait(1) + end - Citizen.CreateThread(function() + local playerPed = GetPlayerPed(-1) - while not ESX.PlayerLoaded do - Citizen.Wait(1) - end + -- Restore position + if ESX.PlayerData.lastPosition ~= nil then + SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.lastPosition.z) + end - local playerPed = GetPlayerPed(-1) - - -- Restore position - if ESX.PlayerData.lastPosition ~= nil then - SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.lastPosition.z) - end - - -- Restore loadout - TriggerEvent('esx:restoreLoadout') - - LoadoutLoaded = true - PlayerSpawned = true - - end) + TriggerEvent('esx:restoreLoadout') -- restore loadout + LoadoutLoaded = true + PlayerSpawned = true + isDead = false end) AddEventHandler('baseevents:onPlayerDied', function(killerType, coords) @@ -89,6 +84,10 @@ AddEventHandler('baseevents:onPlayerKilled', function(killerId, data) TriggerEvent('esx:onPlayerDeath') end) +AddEventHandler('esx:onPlayerDeath', function() + isDead = true +end) + AddEventHandler('skinchanger:loadDefaultModel', function() LoadoutLoaded = false end) @@ -472,7 +471,7 @@ Citizen.CreateThread(function() Citizen.Wait(10) - if IsControlPressed(0, Keys["F2"]) and GetLastInputMethod(2) and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') and (GetGameTimer() - GUI.Time) > 150 then + if IsControlPressed(0, Keys["F2"]) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') and (GetGameTimer() - GUI.Time) > 150 then ESX.ShowInventory() GUI.Time = GetGameTimer() end diff --git a/locales/en.lua b/locales/en.lua index d6cfa6d7..b84aed7a 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -19,12 +19,12 @@ Locales['en'] = { ['by'] = '~s~ by ~b~', ['imp_invalid_quantity'] = 'action impossible, invalid quantity', ['imp_invalid_amount'] = 'action impossible, invalid amount', - ['delete_five_min'] = '~r~delete~s~ in 5 minutes', + ['delete_five_min'] = 'the item will be ~r~deleted~s~ in 5 minutes', ['threw'] = 'you ~r~threw~s~', ['rec_salary'] = 'you received your salary: ', ['rec_help'] = 'you recieved your welfare check: ', - ['company_paid'] = 'Company paycheck received', - ['company_nomoney'] = 'Your company is broke!', + ['company_paid'] = 'company paycheck received', + ['company_nomoney'] = 'your company is broke!', ['state_paid'] = 'You received a state check', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', @@ -46,6 +46,9 @@ Locales['en'] = { ['spawn_ped'] = 'spawn ped', ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'give money', + ['setmoney'] = 'set money for a player', + ['money_type'] = 'valid money types: cash, bank, black', + ['money_set'] = 'someone ~y~highly ranked~s~ just set ~g~$%s~s~ (%s) for you!', ['money_amount'] = 'amount of money', ['invalid_account'] = 'invalid account', ['account'] = 'account', @@ -55,6 +58,7 @@ Locales['en'] = { ['giveitem'] = 'give item', ['weapon'] = 'weapon', ['giveweapon'] = 'give weapon', + ['disconnect'] = 'disconnect from the server', -- Weapons ['weapon_knife'] = 'knife', ['weapon_nightstick'] = 'nightstick', diff --git a/locales/sv.lua b/locales/sv.lua index 95912ed7..8a97c51e 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -2,7 +2,7 @@ Locales['sv'] = { ['inventory'] = 'Mitt förråd', ['use'] = 'använd', ['give'] = 'ge', - ['remove'] = 'ta bort', + ['remove'] = 'kasta', ['return'] = 'gå tillbaka', ['amount'] = 'belopp', ['amount_invalid'] = 'giltigt belopp', @@ -40,6 +40,9 @@ Locales['sv'] = { ['spawn_ped'] = 'spawna NPC', ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'ge pengar', + ['setmoney'] = 'bestäm mängd pengar till en valfri person', + ['money_type'] = 'giltiga typer: cash, bank, black', + ['money_set'] = 'någon ~y~högt uppsatt~s~ satte ~g~$%s~s~ (%s) för dig!', ['money_amount'] = 'summa pengar', ['invalid_account'] = 'ogiltigt konto', ['account'] = 'konto', @@ -49,6 +52,7 @@ Locales['sv'] = { ['giveitem'] = 'ge föremål', ['weapon'] = 'vapen', ['giveweapon'] = 'ge vapen', + ['disconnect'] = 'koppla från servern', -- Weapons ['weapon_knife'] = 'knife', ['weapon_nightstick'] = 'nightstick', diff --git a/localization/br_es_extened.sql b/localization/br_es_extended.sql similarity index 100% rename from localization/br_es_extened.sql rename to localization/br_es_extended.sql diff --git a/server/commands.lua b/server/commands.lua index 1341f0b2..e0e371f9 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -1,14 +1,20 @@ TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) - - TriggerClientEvent("esx:teleport", source, { - x = tonumber(args[1]), - y = tonumber(args[2]), - z = tonumber(args[3]) - }) - + local x = tonumber(args[1]) + local y = tonumber(args[2]) + local z = tonumber(args[3]) + + if x and y and z then + TriggerClientEvent("esx:teleport", source, { + x = x, + y = y, + z = z + }) + else + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Invalid coordinates!") + end end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end) +end, {help = "Teleport to coordinates", params = {{name = "x", help = "X coords"}, {name = "y", help = "Y coords"}, {name = "z", help = "Z coords"}}}) TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) local xPlayer = ESX.GetPlayerFromId(args[1]) @@ -66,21 +72,36 @@ end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('spawn_object'), params = {{name = "name"}}}) -TriggerEvent('es:addGroupCommand', 'givemoney', 'admin', function(source, args, user) - - local _source = source - local xPlayer = ESX.GetPlayerFromId(args[1]) - local amount = tonumber(args[2]) - - if amount ~= nil then - xPlayer.addMoney(amount) - else - TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) - end +TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) + local _source = source + + local target = tonumber(args[1]) + local money_type = args[2] + local money_amount = tonumber(args[3]) + + local xTarget = ESX.GetPlayerFromId(target) + if target and money_type and money_amount and xTarget ~= nil then + if money_type == 'cash' then + xTarget.setMoney(money_amount) + elseif money_type == 'bank' then + xTarget.setAccountMoney('bank', money_amount) + elseif money_type == 'black' then + xTarget.setAccountMoney('black_money', money_amount) + else + TriggerClientEvent('chatMessage', _source, "SYSTEM", {255, 0, 0}, "^2" .. money_type .. " ^0 is not a valid money type!") + return + end + else + TriggerClientEvent('chatMessage', _source, "SYSTEM", {255, 0, 0}, "Invalid arguments.") + return + end + + print('es_extended: ' .. GetPlayerName(source) .. ' just set $' .. money_amount .. ' (' .. money_type .. ') to ' .. xTarget.name) + TriggerClientEvent('esx:showNotification', xTarget.source, _U('money_set', money_amount, money_type)) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = _U('givemoney'), params = {{name = "id", help = _U('id_param')}, {name = "amount", help = _U('money_amount')}}}) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = _U('setmoney'), params = {{name = "id", help = _U('id_param')}, {name = "money type", help = _U('money_type')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) @@ -134,3 +155,15 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) + +TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) + DropPlayer(source, 'You have been disconnected') +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = _U('disconnect')}) + +TriggerEvent('es:addGroupCommand', 'disconnect', 'admin', function(source, args, user) + DropPlayer(source, 'You have been disconnected') +end, function(source, args, user) + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") +end, {help = _U('disconnect')}) \ No newline at end of file From 03da86848ebd00e4bc5352a1e64b0e303e05d5c2 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 15 Apr 2018 13:39:46 +0200 Subject: [PATCH 185/672] Updated README with accual information --- README.md | 62 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index d88723ec..1aa2ee55 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,33 @@ # es_extended -FXServer ES Extended +es_extended is an extention that is developed on top of [EssentialMode](https://essentialmode.com/) (aka ES), thus commonly named ESX - the EssentialMode Extended framework for FiveM. -## DISCORD +### Links & Read more +- [Official Discord community](https://discord.me/fivem_esx) +- [ESX Documentation](https://esx-org.github.io/) (things are missing!) +- [ES Documentation](https://docs.essentialmode.com/) -https://discord.me/fivem_esx - -## SCREENSHOT +### Screenshot preview (todo) ![screenshot](http://i.imgur.com/aPFdJl3.jpg) -## DESCRIPTION +### Features +- Accounts (bank / black money) you can also add others accounts +- Advanced inventory system (press `F2` ingame) +- Job system +- Loadouts and position synced in database +- The best framework out there for RP servers +- i18n (locate) system +- Loads of plugins available -Add support for accounts (bank / black money) you can also add others accounts +### Requirements +This order also applies in the startup order. +- Base events +- [mysql-async](https://github.com/brouznouf/fivem-mysql-async/releases/latest) +- [EssentialMode](https://essentialmode.com/) (es_admin2 included, a basic admin tool) +- [esplugin_mysql](https://forum.fivem.net/t/release-essentialmode-base/3665/1181) +- [async](https://github.com/ESX-Org/async/releases/latest) -Add support for inventory (press F2 ingame) => Players can now remove items from inventory - -Add support for jobs - -Loadouts are saved in database and restored on spawn - -Positions are saved in database and restored on spawn - -## Requirements - -- **essentialmode** + **es_admin** => https://forum.fivem.net/t/release-essentialmode-base/3665 -- **esplugin_mysql** => https://forum.fivem.net/t/release-essentialmode-base/3665/1181 -- **mysql-async** => https://github.com/brouznouf/fivem-mysql-async/releases/latest -- **async** => https://github.com/esx-org/async/releases/latest - -## Download +### Download & Installation **1) Using [fvm](https://github.com/qlaffont/fvm-installer)** @@ -43,13 +42,13 @@ fvm install --save --folder=esx esx-org/esx_menu_list **2) Manually** - Download https://github.com/ESX-Org/es_extended/releases/latest -- Put it in resource/[essential] directory +- Put it in the resource/[essential] directory - Download https://github.com/ESX-Org/esx_menu_default/releases/latest -- Put it in resource/[esx] directory +- Put it in the resource/[esx]/[ui] directory - Download https://github.com/ESX-Org/esx_menu_dialog/releases/latest -- Put it in resource/[esx] directory +- Put it in the resource/[esx]/[ui] directory - Download https://github.com/ESX-Org/esx_menu_list/releases/latest -- Put it in resource/[esx] directory +- Put it in the resource/[esx]/[ui] directory **3) Using git** @@ -64,9 +63,16 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list ## Installation 1) Import es_extended.sql in your database -2) Add this in your server.cfg : +2) Configure your `server.cfg` to look like this ``` +start baseevents + +start mysql-async +start essentialmode +start esplugin_mysql +start es_admin2 + start es_extended start esx_menu_default From c7e5d5d6ab7cac57f20991b44f79569647d2138c Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 15 Apr 2018 13:44:18 +0200 Subject: [PATCH 186/672] Added legal information --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 1aa2ee55..3b7b5dbc 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ es_extended is an extention that is developed on top of [EssentialMode](https:// - [Official Discord community](https://discord.me/fivem_esx) - [ESX Documentation](https://esx-org.github.io/) (things are missing!) - [ES Documentation](https://docs.essentialmode.com/) +- [FiveM Native Reference](https://runtime.fivem.net/doc/reference.html) ### Screenshot preview (todo) @@ -79,3 +80,14 @@ start esx_menu_default start esx_menu_list start esx_menu_dialog ``` +# Legal +### License +es_extended - EssentialMode Extended framework for FiveM + +Copyright (C) 2015-2018 Jérémie N'gadi + +This program Is free software: you can redistribute it And/Or modify it under the terms Of the GNU General Public License As published by the Free Software Foundation, either version 3 Of the License, Or (at your option) any later version. + +This program Is distributed In the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty Of MERCHANTABILITY Or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License For more details. + +You should have received a copy Of the GNU General Public License along with this program. If Not, see http://www.gnu.org/licenses/. From 8b648c5d7f644a11f68503effb6f64356ac8fd93 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 15 Apr 2018 20:41:31 +0200 Subject: [PATCH 187/672] (i18n) added missing strings --- locales/sv.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/locales/sv.lua b/locales/sv.lua index 8a97c51e..5e00ac11 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -4,8 +4,13 @@ Locales['sv'] = { ['give'] = 'ge', ['remove'] = 'kasta', ['return'] = 'gå tillbaka', - ['amount'] = 'belopp', - ['amount_invalid'] = 'giltigt belopp', + ['amount'] = 'antal', + ['amountammo'] = 'mängd ammunition', + ['noammo'] = 'du har inte tillräckligt med ammunition!', + ['withammo'] = '~s~ med x', + ['ammogiven'] = '~s~ skott', + ['giveammo'] = 'Ge ammunition', + ['amount_invalid'] = 'ogiltig mängd', ['players_nearby'] = 'inga spelare nära', ['ex_inv_lim'] = 'åtgärd inte möjligt, översteg förrådets gräns ~b~', ['yougave'] = 'du gav', From 5f93c0a1290b60083d7624afe120fc555c12f9a4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 15 Apr 2018 22:52:03 +0200 Subject: [PATCH 188/672] Improved i18 formatting, see desc - /giveweapon now takes ammo as an argument - improved Swedish translation - hide actions in the inventory menu if they cannot be done. - general code improvements, cleanup --- client/functions.lua | 90 ++++++++++++++++++++++---------------------- locales/en.lua | 9 +++-- locales/sv.lua | 10 +++-- server/commands.lua | 4 +- server/main.lua | 15 ++++---- 5 files changed, 67 insertions(+), 61 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index d6babc04..49ecb156 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1118,6 +1118,7 @@ ESX.ShowInventory = function() count = 1, type = 'item_weapon', value = Config.Weapons[i].name, + ammo = ammo, usable = false, rare = false, canRemove = true @@ -1152,7 +1153,7 @@ ESX.ShowInventory = function() table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) end - if data.current.type == "item_weapon" then + if data.current.type == "item_weapon" and data.current.ammo > 0 and player ~= -1 and distance <= 3.0 then table.insert(elements, {label = _U('giveammo'), action = 'giveammo', type = data.current.type, value = data.current.value}) end @@ -1176,10 +1177,10 @@ ESX.ShowInventory = function() if type == 'item_weapon' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() local closestPed = GetPlayerPed(closestPlayer) - local pedammo = GetAmmoInPedWeapon(GetPlayerPed(-1),GetHashKey(item)) + local pedAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1),GetHashKey(item)) if not IsPedSittingInAnyVehicle(closestPed) then if closestPlayer ~= -1 and closestDistance < 3.0 then - if pedammo > 0 then + if pedAmmo > 0 then ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', { @@ -1187,19 +1188,17 @@ ESX.ShowInventory = function() }, function(data2, menu2) local quantity = tonumber(data2.value) - if quantity <= pedammo and quantity >= 0 and quantity ~= nil then - local ammobefore = GetAmmoInPedWeapon(playerPed, item) + if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) - local finalammo = math.floor(ammobefore - quantity) + local finalammo = math.floor(pedAmmo - quantity) SetPedAmmo(playerPed, item, finalammo) menu2.close() menu.close() else - ESX.ShowNotification(_U("noammo")) + ESX.ShowNotification(_U('noammo')) end - end, - function(data2, menu2) + end, function(data2, menu2) menu2.close() end ) @@ -1250,33 +1249,34 @@ ESX.ShowInventory = function() elseif data.current.action == 'remove' then if type == 'item_weapon' then - local pedammo = GetAmmoInPedWeapon(GetPlayerPed(-1),GetHashKey(item)) - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', - { - title = _U('amount') - }, - function(data2, menu2) + local pedAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1),GetHashKey(item)) + + -- does the player have any ammo for the weapon? + if pedAmmo > 0 then + ESX.UI.Menu.Open( + 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', + { + title = _U('amount') + }, function(data2, menu2) + local quantity = tonumber(data2.value) - local quantity = tonumber(data2.value) - - if quantity <= pedammo and quantity >= 0 and quantity ~= nil then - local ammobefore = GetAmmoInPedWeapon(playerPed, item) - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) - local finalammo = math.floor(ammobefore - quantity) - SetPedAmmo(playerPed, item, finalammo) - else - ESX.ShowNotification(_U("noammo")) - end - - menu2.close() - menu.close() - - end, - function(data2, menu2) - menu2.close() - end - ) + if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then + local finalammo = math.floor(pedAmmo - quantity) + + SetPedAmmo(playerPed, item, finalammo) + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + else + ESX.ShowNotification(_U('noammo')) + end + menu2.close() + menu.close() + end, function(data2, menu2) + menu2.close() + end) + else + TriggerServerEvent('esx:removeInventoryItem', type, item, 0) + menu.close() + end else @@ -1316,10 +1316,10 @@ ESX.ShowInventory = function() elseif data.current.action == 'giveammo' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() local closestPed = GetPlayerPed(closestPlayer) - local pedammo = GetAmmoInPedWeapon(playerPed,GetHashKey(item)) + local pedAmmo = GetAmmoInPedWeapon(playerPed,GetHashKey(item)) if not IsPedSittingInAnyVehicle(closestPed) then if closestPlayer ~= -1 and closestDistance < 3.0 then - if pedammo > 0 then + if pedAmmo > 0 then ESX.UI.Menu.Open( 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', { @@ -1327,18 +1327,16 @@ ESX.ShowInventory = function() }, function(data2, menu2) local quantity = tonumber(data2.value) - if quantity <= pedammo and quantity >= 0 and quantity ~= nil then - local ammobefore2 = GetAmmoInPedWeapon(closestPed, item) - local finalammo = math.floor(pedammo - quantity) - local finalammo2 = math.floor(ammobefore2 + quantity) - SetPedAmmo(playerPed, item, finalammo) - Citizen.invokeNative(0x78F0424C34306220,closestPed, item, finalammo2) - --SetPedAmmo(closestPed, item, finalammo2) - ESX.ShowNotification(_U('yougave') .. "x~r~ " .. quantity .. _U('ammogiven') ) + if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then + local finalAmmoSource = math.floor(pedAmmo - quantity) + SetPedAmmo(playerPed, item, finalAmmoSource) + AddAmmoToPed(closestPed, item, quantity) + ESX.ShowNotification(_U('gave_ammo', quantity)) + -- todo notify target that he recived ammo menu2.close() menu.close() else - ESX.ShowNotification(_U("noammo")) + ESX.ShowNotification(_U('noammo')) end end, diff --git a/locales/en.lua b/locales/en.lua index b84aed7a..c02bba66 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -7,8 +7,11 @@ Locales['en'] = { ['amount'] = 'amount', ['amountammo'] = 'amount of ammo', ['noammo'] = 'you do not have enough ammo!', - ['withammo'] = '~s~ with x', - ['ammogiven'] = '~s~ bullets', + ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['recived_weapon'] = 'you recived ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', + ['recived_ammo'] = 'you recived ~o~%sx~s~ bullets from ~b~%s~s~.', ['giveammo'] = 'Give ammo', ['amount_invalid'] = 'invalid amount', ['players_nearby'] = 'no players nearby', @@ -19,7 +22,7 @@ Locales['en'] = { ['by'] = '~s~ by ~b~', ['imp_invalid_quantity'] = 'action impossible, invalid quantity', ['imp_invalid_amount'] = 'action impossible, invalid amount', - ['delete_five_min'] = 'the item will be ~r~deleted~s~ in 5 minutes', + ['delete_five_min'] = 'the item will be ~r~thrown~s~ in 5 minutes', ['threw'] = 'you ~r~threw~s~', ['rec_salary'] = 'you received your salary: ', ['rec_help'] = 'you recieved your welfare check: ', diff --git a/locales/sv.lua b/locales/sv.lua index 5e00ac11..00044a41 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -7,8 +7,11 @@ Locales['sv'] = { ['amount'] = 'antal', ['amountammo'] = 'mängd ammunition', ['noammo'] = 'du har inte tillräckligt med ammunition!', - ['withammo'] = '~s~ med x', - ['ammogiven'] = '~s~ skott', + ['threw_weapon'] = 'du ~r~slängde~s~ ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott!', + ['gave_weapon'] = 'du gav ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~.', + ['recived_weapon'] = 'du tog emot ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~.', + ['gave_ammo'] = 'du gav ~o~%sx~s~ skott till ~y~%s~s~.', + ['recived_ammo'] = 'du tog emot ~o~%sx~s~ skott från ~b~%s~s~.', ['giveammo'] = 'Ge ammunition', ['amount_invalid'] = 'ogiltig mängd', ['players_nearby'] = 'inga spelare nära', @@ -19,7 +22,7 @@ Locales['sv'] = { ['by'] = '~s~ av ~b~', ['imp_invalid_quantity'] = 'åtgärd omöjlig, ogiltig mängd', ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', - ['delete_five_min'] = '~r~ta bort~s~ inom 5 minuter', + ['delete_five_min'] = 'objektet kommer att ~r~tas bort~s~ om 5 minuter!', ['threw'] = 'du ~r~kastade~s~', ['rec_salary'] = 'du fick din lön: ', ['rec_help'] = 'du fick din välfärdskontroll: ', @@ -27,6 +30,7 @@ Locales['sv'] = { ['company_nomoney'] = 'Ditt företag är för fattigt!!', ['state_paid'] = 'Du fick en statlig check', ['act_imp'] = 'åtgärd omöjlig', + ['in_vehicle'] = 'du kan inte ge saker till en som sitter i ett fordon!', ['cannot_pickup_room'] = 'du har inte plats för att plocka upp ~y~%s~s~!', -- Commands ['setjob'] = 'tilldela ett jobb till en användare', diff --git a/server/commands.lua b/server/commands.lua index e0e371f9..d53a7948 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -150,11 +150,11 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, local xPlayer = ESX.GetPlayerFromId(args[1]) local weaponName = string.upper(args[2]) - xPlayer.addWeapon(weaponName, 1000) + xPlayer.addWeapon(weaponName, tonumber(args[3])) end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}}}) +end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}, {name = "ammo", help = _U('amountammo')}}}) TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) DropPlayer(source, 'You have been disconnected') diff --git a/server/main.lua b/server/main.lua index 94bfc585..147690f5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -309,7 +309,7 @@ end) RegisterServerEvent('esx:giveInventoryItem') -AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount,ammotogive) +AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) local _source = source @@ -379,8 +379,8 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo end end - TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' x1 ~g~' .. weaponLabel .. _U('to') .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' x1 ~g~' .. weaponLabel .. _U('by') .. sourceXPlayer.name) + TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, itemCount, targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('recived_weapon', weaponLabel, itemCount, sourceXPlayer.name)) end end) @@ -517,16 +517,17 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) break end end - + + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) + SetTimeout(Config.RemoveInventoryItemDelay, function() xPlayer.removeWeapon(itemName) - if Config.EnableWeaponPickup then - TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName,itemCount) + TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName, itemCount) end - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' x1 ~g~' .. weaponLabel .. _U('withammo').. '~r~' .. itemCount .. _U('ammogiven')) + TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon', weaponLabel, itemCount)) end) From 160dc9c849790f30f231701585011dfa4e934180 Mon Sep 17 00:00:00 2001 From: Samuel Date: Tue, 17 Apr 2018 00:38:48 +0200 Subject: [PATCH 189/672] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b7b5dbc..d0b33aee 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # es_extended -es_extended is an extention that is developed on top of [EssentialMode](https://essentialmode.com/) (aka ES), thus commonly named ESX - the EssentialMode Extended framework for FiveM. +es_extended is an extention that is developed on top of [EssentialMode](https://essentialmode.com/) (aka ES), thus commonly named ESX - the **Es**sentialMode **E**xtended framework for FiveM. ### Links & Read more - [Official Discord community](https://discord.me/fivem_esx) From 0edf413a99fb311dda16002ebb9500db0b92cecf Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 28 Apr 2018 11:34:25 +0200 Subject: [PATCH 190/672] Exploit fixed: money negative values --- server/classes/player.lua | 49 ++++++++++++++++++++++++++++++++++----- server/commands.lua | 17 ++++++++------ 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index bf88ac93..86170fc2 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -14,7 +14,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.identifier = self.player.get('identifier') self.setMoney = function(m) - self.player.setMoney(m) + if m >= 0 then + self.player.setMoney(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 cash balance)') + end end self.getMoney = function() @@ -22,7 +26,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.setBankBalance = function(m) - self.player.setBankBalance(m) + if m >= 0 then + self.player.setBankBalance(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 bank balance)') + end end self.getBank = function() @@ -42,19 +50,35 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.addMoney = function(m) - self.player.addMoney(m) + if m >= 0 then + self.player.addMoney(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 cash balance)') + end end self.removeMoney = function(m) - self.player.removeMoney(m) + if m >= 0 then + self.player.removeMoney(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 cash balance)') + end end self.addBank = function(m) - self.player.addBank(m) + if m >= 0 then + self.player.addBank(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 bank balance)') + end end self.removeBank = function(m) - self.player.removeBank(m) + if m >= 0 then + self.player.removeBank(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 bank balance)') + end end self.displayMoney = function(m) @@ -227,6 +251,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.setAccountMoney = function(a, m) + if m < 0 then + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 account balance)') + return + end local account = self.getAccount(a) local prevMoney = account.money @@ -242,6 +270,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.addAccountMoney = function(a, m) + if m < 0 then + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 account balance)') + return + end local account = self.getAccount(a) local newMoney = account.money + m @@ -256,6 +288,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.removeAccountMoney = function(a, m) + if m < 0 then + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 account balance)') + return + end + local account = self.getAccount(a) local newMoney = account.money - m diff --git a/server/commands.lua b/server/commands.lua index d53a7948..78a53373 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -79,15 +79,15 @@ TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, u local money_type = args[2] local money_amount = tonumber(args[3]) - local xTarget = ESX.GetPlayerFromId(target) + local xPlayer = ESX.GetPlayerFromId(target) - if target and money_type and money_amount and xTarget ~= nil then + if target and money_type and money_amount and xPlayer ~= nil then if money_type == 'cash' then - xTarget.setMoney(money_amount) + xPlayer.setMoney(money_amount) elseif money_type == 'bank' then - xTarget.setAccountMoney('bank', money_amount) + xPlayer.setAccountMoney('bank', money_amount) elseif money_type == 'black' then - xTarget.setAccountMoney('black_money', money_amount) + xPlayer.setAccountMoney('black_money', money_amount) else TriggerClientEvent('chatMessage', _source, "SYSTEM", {255, 0, 0}, "^2" .. money_type .. " ^0 is not a valid money type!") return @@ -97,8 +97,11 @@ TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, u return end - print('es_extended: ' .. GetPlayerName(source) .. ' just set $' .. money_amount .. ' (' .. money_type .. ') to ' .. xTarget.name) - TriggerClientEvent('esx:showNotification', xTarget.source, _U('money_set', money_amount, money_type)) + print('es_extended: ' .. GetPlayerName(source) .. ' just set $' .. money_amount .. ' (' .. money_type .. ') to ' .. xPlayer.name) + + if xPlayer.source ~= _source then + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) + end end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('setmoney'), params = {{name = "id", help = _U('id_param')}, {name = "money type", help = _U('money_type')}, {name = "amount", help = _U('money_amount')}}}) From 3760c3350fb5fc249690157b54f61789efd13b17 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 1 May 2018 12:09:06 +0200 Subject: [PATCH 191/672] Improved translations, fixes #69 and #67 --- client/functions.lua | 2 +- locales/br.lua | 302 ++++++++++++++++++++++--------------------- locales/de.lua | 23 +++- locales/en.lua | 16 ++- locales/fr.lua | 23 ++-- locales/sv.lua | 14 ++ server/main.lua | 27 +--- 7 files changed, 221 insertions(+), 186 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 49ecb156..6d9d62a5 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1177,7 +1177,7 @@ ESX.ShowInventory = function() if type == 'item_weapon' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() local closestPed = GetPlayerPed(closestPlayer) - local pedAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1),GetHashKey(item)) + local pedAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1), GetHashKey(item)) if not IsPedSittingInAnyVehicle(closestPed) then if closestPlayer ~= -1 and closestDistance < 3.0 then if pedAmmo > 0 then diff --git a/locales/br.lua b/locales/br.lua index 491f232c..78846777 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,150 +1,154 @@ - Locales['br'] = { - ['inventory'] = 'inventário', - ['use'] = 'use', - ['give'] = 'dar', - ['remove'] = 'remover', - ['return'] = 'retorna', - ['amount'] = 'quantidade', - ['amountammo'] = 'quantidade de munição', - ['noammo'] = 'Você não tem todas essas munições!', - ['withammo'] = '~s~ com x', - ['ammogiven'] = '~s~ balas', - ['giveammo'] = 'Dar munição', - ['amount_invalid'] = 'quantidade inválida', - ['players_nearby'] = 'nenhum jogador por perto', - ['ex_inv_lim'] = 'ação não é possível, excedendo o limite de estoque para ~b~', - ['yougave'] = 'você deu', - ['youreceived'] = 'você recebeu', - ['to'] = '~s~ para ~b~', - ['by'] = '~s~ de ~b~', - ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', - ['imp_invalid_amount'] = 'ação impossível, valor inválido', - ['delete_five_min'] = '~r~excluir~s~ em 5 minutos', - ['threw'] = 'você ~r~jogou~s~', - ['rec_salary'] = 'você recebeu seu salário: ', - ['rec_help'] = 'você recebeu seu cheque de bem-estar: ', - ['company_paid'] = 'Cheque de pagamento da empresa recebido', - ['company_nomoney'] = 'Sua empresa está falida!', - ['state_paid'] = 'Você recebeu um cheque de estado', - ['act_imp'] = 'ação impossível', - ['in_vehicle'] = 'Você não pode dar nada para alguém no veículo', - -- Commands - ['setjob'] = 'atribuir um trabalho a um usuário', - ['id_param'] = 'o ID do jogador', - ['setjob_param2'] = 'o trabalho que você deseja atribuir', - ['setjob_param3'] = 'o nível de emprego', - ['load_ipl'] = 'carregar IPL', - ['unload_ipl'] = 'descarregar o IPL', - ['play_anim'] = 'tocar animação', - ['play_emote'] = 'jogar emote', - ['spawn_car'] = 'spawn um carro', - ['spawn_car_param'] = 'nome do carro', - ['delete_vehicle'] = 'excluir Veículo', - ['delete_veh_param'] = 'pressione Enter', - ['spawn_object'] = 'spawn objeto', - ['spawn_ped'] = 'spawn ped', - ['spawn_ped_param'] = 'exemplo a_m_m_hillbilly_01', - ['givemoney'] = 'dar dinheiro', - ['money_amount'] = 'quantia de dinheiro', - ['invalid_account'] = 'conta inválida', - ['account'] = 'conta', - ['giveaccountmoney'] = 'dar dinheiro da conta', - ['invalid_item'] = 'item inválido', - ['item'] = 'item', - ['giveitem'] = 'dar item', - ['weapon'] = 'arma', - ['giveweapon'] = 'dar arma', - -- Weapons - ['weapon_knife'] = 'faca', - ['weapon_nightstick'] = 'cacetete', - ['weapon_hammer'] = 'martelo', - ['weapon_bat'] = 'bastão', - ['weapon_golfclub'] = 'golf club', - ['weapon_crowbar'] = 'pé de cabra', - ['weapon_pistol'] = 'pistola', - ['weapon_combatpistol'] = 'pistola de combate', - ['weapon_appistol'] = 'ap pistola', - ['weapon_pistol50'] = 'pistola .50', - ['weapon_microsmg'] = 'micro smg', - ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'assault smg', - ['weapon_assaultrifle'] = 'assault rifle', - ['weapon_carbinerifle'] = 'carbine rifle', - ['weapon_advancedrifle'] = 'advanced rifle', - ['weapon_mg'] = 'mg', - ['weapon_combatmg'] = 'combat mg', - ['weapon_pumpshotgun'] = 'espingarda', - ['weapon_sawnoffshotgun'] = 'sawed off shotgun', - ['weapon_assaultshotgun'] = 'assault shotgun', - ['weapon_bullpupshotgun'] = 'bullpup shotgun', - ['weapon_stungun'] = 'arma de choque', - ['weapon_sniperrifle'] = 'sniper rifle', - ['weapon_heavysniper'] = 'heavy sniper', - ['weapon_remotesniper'] = 'remote sniper', - ['weapon_grenadelauncher'] = 'lançador de granada', - ['weapon_rpg'] = 'lançador de foguetes', - ['weapon_stinger'] = 'stinger', - ['weapon_minigun'] = 'minigun', - ['weapon_grenade'] = 'granada', - ['weapon_stickybomb'] = 'bomba pegajosa', - ['weapon_smokegrenade'] = 'granada de fumaça', - ['weapon_bzgas'] = 'bz gas', - ['weapon_molotov'] = 'coquetel molotov', - ['weapon_fireextinguisher'] = 'extintor', - ['weapon_petrolcan'] = 'galão de combustivel', - ['weapon_digiscanner'] = 'digiscanner', - ['weapon_ball'] = 'bola', - ['weapon_snspistol'] = 'sns pistol', - ['weapon_bottle'] = 'garrafa', - ['weapon_gusenberg'] = 'gusenberg sweeper', - ['weapon_specialcarbine'] = 'carabina especial', - ['weapon_heavypistol'] = 'heavy pistol', - ['weapon_bullpuprifle'] = 'bullpup rifle', - ['weapon_dagger'] = 'punhal', - ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_firework'] = 'fogos de artifício', - ['weapon_musket'] = 'mosquete', - ['weapon_heavyshotgun'] = 'heavy shotgun', - ['weapon_marksmanrifle'] = 'marksman rifle', - ['weapon_hominglauncher'] = 'homing launcher', - ['weapon_proxmine'] = 'mina de proximidade', - ['weapon_snowball'] = 'bola de neve', - ['weapon_flaregun'] = 'sinalizador', - ['weapon_garbagebag'] = 'saco de lixo', - ['weapon_handcuffs'] = 'algemas', - ['weapon_combatpdw'] = 'combat pdw', - ['weapon_marksmanpistol'] = 'marksman pistol', - ['weapon_knuckle'] = 'soco inglês', - ['weapon_hatchet'] = 'machado', - ['weapon_railgun'] = 'railgun', - ['weapon_machete'] = 'facão', - ['weapon_machinepistol'] = 'machine pistol', - ['weapon_switchblade'] = 'canivete', - ['weapon_revolver'] = 'heavy revolver', - ['weapon_dbshotgun'] = 'espingarda de cano duplo', - ['weapon_compactrifle'] = 'compact rifle', - ['weapon_autoshotgun'] = 'auto shotgun', - ['weapon_battleaxe'] = 'battle axe', - ['weapon_compactlauncher'] = 'compact launcher', - ['weapon_minismg'] = 'mini smg', - ['weapon_pipebomb'] = 'bomba caseira', - ['weapon_poolcue'] = 'taco de sinuca', - ['weapon_wrench'] = 'chave de cano', - ['weapon_flashlight'] = 'laterna', - ['gadget_nightvision'] = 'visão noturna', - ['gadget_parachute'] = 'paraquedas', - ['weapon_flare'] = 'Flare', - ['weapon_snspistol_mk2'] = 'Pistola SNS Mk II', - ['weapon_revolver_mk2'] = 'Revolver Pesada Mk II', - ['weapon_doubleaction'] = 'Revolver Dupla-acao', - ['weapon_specialcarabine_mk2'] = 'Carabina Especial Mk II', - ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', - ['weapon_pumpshotgun_mk2'] = 'Espingarda Mk II', - ['weapon_marksmanrifle_mk2'] = 'Rifle Marksman Mk II', - ['weapon_assaultrifle_mk2'] = 'Rifle de assalto Mk II ', - ['weapon_carbinerifle_mk2'] = 'Carabina Mk II ', - ['weapon_combatmg_mk2'] = 'MG de Combate Mk II', - ['weapon_heavysniper_mk2'] = 'Sniper pesada Mk II', - ['weapon_pistol_mk2'] = 'Pistola Mk II', - ['weapon_smg_mk2'] = 'SMG Mk II', +Locales['br'] = { + ['inventory'] = 'inventário', + ['use'] = 'use', + ['give'] = 'dar', + ['remove'] = 'remover', + ['return'] = 'retorna', + ['amount'] = 'quantidade', + ['amountammo'] = 'quantidade de munição', + ['noammo'] = 'Você não tem todas essas munições!', + ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['recived_weapon'] = 'you recived ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', + ['recived_ammo'] = 'you recived ~o~%sx~s~ bullets from ~b~%s~s~.', + ['giveammo'] = 'Dar munição', + ['amount_invalid'] = 'quantidade inválida', + ['players_nearby'] = 'nenhum jogador por perto', + ['ex_inv_lim'] = 'ação não é possível, excedendo o limite de estoque para ~b~', + ['yougave'] = 'você deu', + ['youreceived'] = 'você recebeu', + ['to'] = '~s~ para ~b~', + ['by'] = '~s~ de ~b~', + ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', + ['imp_invalid_amount'] = 'ação impossível, valor inválido', + ['delete_five_min'] = '~r~excluir~s~ em 5 minutos', + ['threw'] = 'você ~r~jogou~s~', + ['rec_salary'] = 'você recebeu seu salário: ', + ['rec_help'] = 'você recebeu seu cheque de bem-estar: ', + ['company_paid'] = 'Cheque de pagamento da empresa recebido', + ['company_nomoney'] = 'Sua empresa está falida!', + ['state_paid'] = 'Você recebeu um cheque de estado', + ['act_imp'] = 'ação impossível', + ['in_vehicle'] = 'Você não pode dar nada para alguém no veículo', + ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', + -- Commands + ['setjob'] = 'atribuir um trabalho a um usuário', + ['id_param'] = 'o ID do jogador', + ['setjob_param2'] = 'o trabalho que você deseja atribuir', + ['setjob_param3'] = 'o nível de emprego', + ['load_ipl'] = 'carregar IPL', + ['unload_ipl'] = 'descarregar o IPL', + ['play_anim'] = 'tocar animação', + ['play_emote'] = 'jogar emote', + ['spawn_car'] = 'spawn um carro', + ['spawn_car_param'] = 'nome do carro', + ['delete_vehicle'] = 'excluir Veículo', + ['delete_veh_param'] = 'pressione Enter', + ['spawn_object'] = 'spawn objeto', + ['spawn_ped'] = 'spawn ped', + ['spawn_ped_param'] = 'exemplo a_m_m_hillbilly_01', + ['givemoney'] = 'dar dinheiro', + ['money_amount'] = 'quantia de dinheiro', + ['invalid_account'] = 'conta inválida', + ['account'] = 'conta', + ['giveaccountmoney'] = 'dar dinheiro da conta', + ['invalid_item'] = 'item inválido', + ['item'] = 'item', + ['giveitem'] = 'dar item', + ['weapon'] = 'arma', + ['giveweapon'] = 'dar arma', + -- Weapons + ['weapon_knife'] = 'faca', + ['weapon_nightstick'] = 'cacetete', + ['weapon_hammer'] = 'martelo', + ['weapon_bat'] = 'bastão', + ['weapon_golfclub'] = 'golf club', + ['weapon_crowbar'] = 'pé de cabra', + ['weapon_pistol'] = 'pistola', + ['weapon_combatpistol'] = 'pistola de combate', + ['weapon_appistol'] = 'ap pistola', + ['weapon_pistol50'] = 'pistola .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'assault smg', + ['weapon_assaultrifle'] = 'assault rifle', + ['weapon_carbinerifle'] = 'carbine rifle', + ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'combat mg', + ['weapon_pumpshotgun'] = 'espingarda', + ['weapon_sawnoffshotgun'] = 'sawed off shotgun', + ['weapon_assaultshotgun'] = 'assault shotgun', + ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_stungun'] = 'arma de choque', + ['weapon_sniperrifle'] = 'sniper rifle', + ['weapon_heavysniper'] = 'heavy sniper', + ['weapon_remotesniper'] = 'remote sniper', + ['weapon_grenadelauncher'] = 'lançador de granada', + ['weapon_rpg'] = 'lançador de foguetes', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'granada', + ['weapon_stickybomb'] = 'bomba pegajosa', + ['weapon_smokegrenade'] = 'granada de fumaça', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'coquetel molotov', + ['weapon_fireextinguisher'] = 'extintor', + ['weapon_petrolcan'] = 'galão de combustivel', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'bola', + ['weapon_snspistol'] = 'sns pistol', + ['weapon_bottle'] = 'garrafa', + ['weapon_gusenberg'] = 'gusenberg sweeper', + ['weapon_specialcarbine'] = 'carabina especial', + ['weapon_heavypistol'] = 'heavy pistol', + ['weapon_bullpuprifle'] = 'bullpup rifle', + ['weapon_dagger'] = 'punhal', + ['weapon_vintagepistol'] = 'vintage pistol', + ['weapon_firework'] = 'fogos de artifício', + ['weapon_musket'] = 'mosquete', + ['weapon_heavyshotgun'] = 'heavy shotgun', + ['weapon_marksmanrifle'] = 'marksman rifle', + ['weapon_hominglauncher'] = 'homing launcher', + ['weapon_proxmine'] = 'mina de proximidade', + ['weapon_snowball'] = 'bola de neve', + ['weapon_flaregun'] = 'sinalizador', + ['weapon_garbagebag'] = 'saco de lixo', + ['weapon_handcuffs'] = 'algemas', + ['weapon_combatpdw'] = 'combat pdw', + ['weapon_marksmanpistol'] = 'marksman pistol', + ['weapon_knuckle'] = 'soco inglês', + ['weapon_hatchet'] = 'machado', + ['weapon_railgun'] = 'railgun', + ['weapon_machete'] = 'facão', + ['weapon_machinepistol'] = 'machine pistol', + ['weapon_switchblade'] = 'canivete', + ['weapon_revolver'] = 'heavy revolver', + ['weapon_dbshotgun'] = 'espingarda de cano duplo', + ['weapon_compactrifle'] = 'compact rifle', + ['weapon_autoshotgun'] = 'auto shotgun', + ['weapon_battleaxe'] = 'battle axe', + ['weapon_compactlauncher'] = 'compact launcher', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'bomba caseira', + ['weapon_poolcue'] = 'taco de sinuca', + ['weapon_wrench'] = 'chave de cano', + ['weapon_flashlight'] = 'laterna', + ['gadget_nightvision'] = 'visão noturna', + ['gadget_parachute'] = 'paraquedas', + ['weapon_flare'] = 'Flare', + ['weapon_snspistol_mk2'] = 'Pistola SNS Mk II', + ['weapon_revolver_mk2'] = 'Revolver Pesada Mk II', + ['weapon_doubleaction'] = 'Revolver Dupla-acao', + ['weapon_specialcarabine_mk2'] = 'Carabina Especial Mk II', + ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', + ['weapon_pumpshotgun_mk2'] = 'Espingarda Mk II', + ['weapon_marksmanrifle_mk2'] = 'Rifle Marksman Mk II', + ['weapon_assaultrifle_mk2'] = 'Rifle de assalto Mk II ', + ['weapon_carbinerifle_mk2'] = 'Carabina Mk II ', + ['weapon_combatmg_mk2'] = 'MG de Combate Mk II', + ['weapon_heavysniper_mk2'] = 'Sniper pesada Mk II', + ['weapon_pistol_mk2'] = 'Pistola Mk II', + ['weapon_smg_mk2'] = 'SMG Mk II', } diff --git a/locales/de.lua b/locales/de.lua index 23c6ea75..6f4323b7 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,8 +1,11 @@ Locales['de'] = { ['amountammo'] = 'anzahl der Munition', - ['noammo'] = 'Du hast keine Munition !', - ['withammo'] = '~s~ mit x', - ['ammogiven'] = '~s~ Kugeln', + ['noammo'] = 'du hast keine Munition!', + ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['recived_weapon'] = 'you recived ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', + ['recived_ammo'] = 'you recived ~o~%sx~s~ bullets from ~b~%s~s~.', ['giveammo'] = 'Munition geben', ['inventory'] = 'Inventar', ['use'] = 'benutzen', @@ -123,4 +126,18 @@ Locales['de'] = { ['weapon_flashlight'] = 'Taschenlampe', ['gadget_nightvision'] = 'Nachtsichtgerät', ['gadget_parachute'] = 'Fallschirm', + ['weapon_flare'] = 'Fusée Détresse', + ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', + ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', + ['weapon_doubleaction'] = 'Double-Action Revolver', + ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', + ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', + ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', + ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', + ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', + ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', + ['weapon_combatmg_mk2'] = 'Combat MG Mk II', + ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', + ['weapon_pistol_mk2'] = 'Pistol Mk II', + ['weapon_smg_mk2'] = 'SMG Mk II', } diff --git a/locales/en.lua b/locales/en.lua index c02bba66..96c84eb5 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -12,7 +12,7 @@ Locales['en'] = { ['recived_weapon'] = 'you recived ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', ['recived_ammo'] = 'you recived ~o~%sx~s~ bullets from ~b~%s~s~.', - ['giveammo'] = 'Give ammo', + ['giveammo'] = 'give ammo', ['amount_invalid'] = 'invalid amount', ['players_nearby'] = 'no players nearby', ['ex_inv_lim'] = 'action not possible, exceeding inventory limit for ~b~', @@ -141,4 +141,18 @@ Locales['en'] = { ['weapon_flashlight'] = 'flashlight', ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', + ['weapon_flare'] = 'Fusée Détresse', + ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', + ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', + ['weapon_doubleaction'] = 'Double-Action Revolver', + ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', + ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', + ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', + ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', + ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', + ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', + ['weapon_combatmg_mk2'] = 'Combat MG Mk II', + ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', + ['weapon_pistol_mk2'] = 'Pistol Mk II', + ['weapon_smg_mk2'] = 'SMG Mk II', } \ No newline at end of file diff --git a/locales/fr.lua b/locales/fr.lua index c8d40f32..5e2027f1 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -7,9 +7,12 @@ Locales['fr'] = { ['amount'] = 'quantité', ['amountammo'] = 'nombre de munitions', ['noammo'] = 'Tu n\'as pas toutes ces munitions !', - ['withammo'] = '~s~ avec x ', - ['ammogiven'] = '~s~ balles', - ['giveammo'] = 'Donner munitions', + ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['recived_weapon'] = 'you recived ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', + ['recived_ammo'] = 'you recived ~o~%sx~s~ bullets from ~b~%s~s~.', + ['giveammo'] = 'give ammo', ['amount_invalid'] = 'montant invalide', ['players_nearby'] = 'aucun joueur à proximité', ['ex_inv_lim'] = 'action impossible, depassement de la limite d\'inventaire pour ~b~', @@ -141,11 +144,11 @@ Locales['fr'] = { ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', - ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', - ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', - ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', - ['weapon_combatmg_mk2'] = 'Combat MG Mk II', - ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', - ['weapon_pistol_mk2'] = 'Pistol Mk II', - ['weapon_smg_mk2'] = 'SMG Mk II', + ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', + ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', + ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', + ['weapon_combatmg_mk2'] = 'Combat MG Mk II', + ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', + ['weapon_pistol_mk2'] = 'Pistol Mk II', + ['weapon_smg_mk2'] = 'SMG Mk II', } diff --git a/locales/sv.lua b/locales/sv.lua index 00044a41..5c6db2ff 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -141,4 +141,18 @@ Locales['sv'] = { ['weapon_flashlight'] = 'flashlight', ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', + ['weapon_flare'] = 'Fusée Détresse', + ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', + ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', + ['weapon_doubleaction'] = 'Double-Action Revolver', + ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', + ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', + ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', + ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', + ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', + ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', + ['weapon_combatmg_mk2'] = 'Combat MG Mk II', + ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', + ['weapon_pistol_mk2'] = 'Pistol Mk II', + ['weapon_smg_mk2'] = 'SMG Mk II', } diff --git a/server/main.lua b/server/main.lua index 147690f5..6c4bc028 100644 --- a/server/main.lua +++ b/server/main.lua @@ -370,17 +370,9 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo 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 - + local weaponLabel = ESX.GetWeaponLabel(itemName) TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, itemCount, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('recived_weapon', weaponLabel, itemCount, sourceXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('recived_weapon', weaponLabel, itemCount, sourceXPlayer.name)) end end) @@ -505,18 +497,9 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) elseif type == 'item_weapon' then local xPlayer = ESX.GetPlayerFromId(source) - local weaponLabel = itemName - local weaponName = nil - local weaponPickup = nil - - for i=1, #Config.Weapons, 1 do - if Config.Weapons[i].name == itemName then - weaponLabel = Config.Weapons[i].label - weaponName = Config.Weapons[i].name - weaponPickup = 'PICKUP_'..weaponName - break - end - end + local weaponName = itemName + local weaponLabel = ESX.GetWeaponLabel(weaponName) + local weaponPickup = 'PICKUP_' .. weaponName TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) From 8c129873f02643740656c7c8094580f6e8444b14 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 1 May 2018 21:56:41 +0200 Subject: [PATCH 192/672] Fixed #67 one last time --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index 6d9d62a5..0aa4aa40 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1331,7 +1331,7 @@ ESX.ShowInventory = function() local finalAmmoSource = math.floor(pedAmmo - quantity) SetPedAmmo(playerPed, item, finalAmmoSource) AddAmmoToPed(closestPed, item, quantity) - ESX.ShowNotification(_U('gave_ammo', quantity)) + ESX.ShowNotification(_U('gave_ammo', quantity, GetPlayerName(closestPlayer))) -- todo notify target that he recived ammo menu2.close() menu.close() From 987a40bf0d92f5a196fa30654d020b74fe4744cd Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 5 May 2018 23:56:12 +0200 Subject: [PATCH 193/672] ESX.Game.GetVehicleInDirection, no more car spawn with radio --- client/functions.lua | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 0aa4aa40..510e3454 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -390,7 +390,6 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) local id = NetworkGetNetworkIdFromEntity(vehicle) SetNetworkIdCanMigrate(id, true) - --SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) @@ -401,6 +400,8 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) Citizen.Wait(0) end + SetVehRadioStation(vehicle, 'OFF') + if cb ~= nil then cb(vehicle) end @@ -423,7 +424,6 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) - --SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) @@ -434,6 +434,8 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) Citizen.Wait(0) end + SetVehRadioStation(vehicle, 'OFF') + if cb ~= nil then cb(vehicle) end @@ -642,6 +644,16 @@ ESX.Game.GetVehiclesInArea = function(coords, area) return vehiclesInArea end +ESX.Game.GetVehicleInDirection = function() + local playerPed = GetPlayerPed(-1) + local playerCoords = GetEntityCoords(playerPed, 1) + local inDirection = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 5.0, 0.0) + local rayHandle = CastRayPointToPoint(playerCoords.x, playerCoords.y, playerCoords.z, inDirection.x, inDirection.y, inDirection.z, 10, playerPed, 0) + local a, b, c, d, vehicle = GetRaycastResult(rayHandle) + + return vehicle +end + ESX.Game.GetPeds = function(ignoreList) local ignoreList = ignoreList or {} From 66e7eceddf4b182be424fc1613f690d2f671de80 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 11 May 2018 13:57:35 +0200 Subject: [PATCH 194/672] Improved paycheck system, added advanced notifications, see desc - Improved paycheck system - we now take society money if there is any, or else the employees wont get a salary at all - now using ESX.ShowAdvancedNotifications --- client/functions.lua | 12 +++++ es_extended.sql | 77 +++++++++++++++------------------ locales/br.lua | 13 +++--- locales/de.lua | 20 ++++++--- locales/en.lua | 12 ++--- locales/fr.lua | 12 ++--- locales/sv.lua | 12 ++--- localization/br_es_extended.sql | 69 ----------------------------- localization/de_es_extended.sql | 69 ----------------------------- localization/en_es_extended.sql | 69 ----------------------------- localization/sv_es_extended.sql | 69 ----------------------------- server/commands.lua | 12 ++++- server/paycheck.lua | 56 ++++++++++++++++-------- server/paycheck_company.lua | 30 ------------- 14 files changed, 137 insertions(+), 395 deletions(-) delete mode 100644 localization/br_es_extended.sql delete mode 100644 localization/de_es_extended.sql delete mode 100644 localization/en_es_extended.sql delete mode 100644 localization/sv_es_extended.sql delete mode 100644 server/paycheck_company.lua diff --git a/client/functions.lua b/client/functions.lua index 510e3454..d26ce3e9 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -65,6 +65,13 @@ ESX.ShowNotification = function(msg) DrawNotification(0,1) end +ESX.ShowAdvancedNotification = function(title, subject, msg, icon, iconType) + SetNotificationTextEntry('STRING') + AddTextComponentString(msg) + SetNotificationMessage(icon, icon, false, iconType, title, subject) + DrawNotification(false, false) +end + ESX.TriggerServerCallback = function(name, cb, ...) ESX.ServerCallbacks[ESX.CurrentRequestId] = cb @@ -1394,6 +1401,11 @@ AddEventHandler('esx:showNotification', function(msg) ESX.ShowNotification(msg) end) +RegisterNetEvent('esx:showAdvancedNotification') +AddEventHandler('esx:showAdvancedNotification', function(title, subject, msg, icon, iconType) + ESX.ShowAdvancedNotification(title, subject, msg, icon, iconType) +end) + -- SetTimeout Citizen.CreateThread(function() while true do diff --git a/es_extended.sql b/es_extended.sql index 4c60754b..e1d142fe 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,69 +1,64 @@ USE `essentialmode`; ALTER TABLE `users` - ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, - ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, - ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, - ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, - ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` + ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, + ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, + ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` ; CREATE TABLE `items` ( + `name` varchar(50) NOT NULL, + `label` varchar(255) NOT NULL, + `limit` int(11) NOT NULL DEFAULT '-1', + `rare` int(11) NOT NULL DEFAULT '0', + `can_remove` int(11) NOT NULL DEFAULT '1', - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `limit` int(11) NOT NULL DEFAULT '-1', - `rare` int(11) NOT NULL DEFAULT '0', - `can_remove` int(11) NOT NULL DEFAULT '1', - - PRIMARY KEY (`id`) + PRIMARY KEY (`name`) ); CREATE TABLE `job_grades` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `job_name` varchar(255) DEFAULT NULL, + `grade` int(11) NOT NULL, + `name` varchar(255) NOT NULL, + `label` varchar(255) NOT NULL, + `salary` int(11) NOT NULL, + `skin_male` longtext NOT NULL DEFAULT '{}', + `skin_female` longtext NOT NULL DEFAULT '{}', - `id` int(11) NOT NULL AUTO_INCREMENT, - `job_name` varchar(255) DEFAULT NULL, - `grade` int(11) NOT NULL, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `salary` int(11) NOT NULL, - `skin_male` longtext NOT NULL, - `skin_female` longtext NOT NULL, - - PRIMARY KEY (`id`) + PRIMARY KEY (`id`) ); -INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','RSA',200,'{}','{}'); +INSERT INTO `job_grades` VALUES (1,'unemployed',0,'unemployed','Unemployed',200,'{}','{}'); CREATE TABLE `jobs` ( + `name` varchar(50) NOT NULL, + `label` varchar(255) DEFAULT NULL, - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) DEFAULT NULL, - - PRIMARY KEY (`id`) + PRIMARY KEY (`name`) ); -INSERT INTO `jobs` VALUES (1,'unemployed','Chômeur'); +INSERT INTO `jobs` VALUES ('unemployed','Unemployed'); CREATE TABLE `user_accounts` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `name` varchar(255) NOT NULL, - `money` double NOT NULL DEFAULT '0', + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `name` varchar(255) NOT NULL, + `money` double NOT NULL DEFAULT '0', - PRIMARY KEY (`id`) + PRIMARY KEY (`id`) ); CREATE TABLE `user_inventory` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `item` varchar(255) NOT NULL, - `count` int(11) NOT NULL, + `id` int(11) NOT NULL AUTO_INCREMENT, + `identifier` varchar(255) NOT NULL, + `item` varchar(255) NOT NULL, + `count` int(11) NOT NULL, - PRIMARY KEY (`id`) + PRIMARY KEY (`id`) ); diff --git a/locales/br.lua b/locales/br.lua index 78846777..b6235ab2 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -24,11 +24,14 @@ Locales['br'] = { ['imp_invalid_amount'] = 'ação impossível, valor inválido', ['delete_five_min'] = '~r~excluir~s~ em 5 minutos', ['threw'] = 'você ~r~jogou~s~', - ['rec_salary'] = 'você recebeu seu salário: ', - ['rec_help'] = 'você recebeu seu cheque de bem-estar: ', - ['company_paid'] = 'Cheque de pagamento da empresa recebido', - ['company_nomoney'] = 'Sua empresa está falida!', - ['state_paid'] = 'Você recebeu um cheque de estado', + -- Salary related + ['recived_salary'] = 'você recebeu seu salário: ', + ['recived_help'] = 'você recebeu seu cheque de bem-estar: ', + ['company_nomoney'] = 'Sua empresa está falida!', -- incorrect translation + ['recived_money'] = 'recived money', + ['bank'] = 'bank', + + ['act_imp'] = 'ação impossível', ['in_vehicle'] = 'Você não pode dar nada para alguém no veículo', ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', diff --git a/locales/de.lua b/locales/de.lua index 6f4323b7..3e77d440 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,4 +1,10 @@ Locales['de'] = { + ['inventory'] = 'Inventar', + ['use'] = 'benutzen', + ['give'] = 'geben', + ['remove'] = 'entfernen', + ['return'] = 'zurück', + ['amount'] = 'Betrag', ['amountammo'] = 'anzahl der Munition', ['noammo'] = 'du hast keine Munition!', ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', @@ -7,12 +13,6 @@ Locales['de'] = { ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', ['recived_ammo'] = 'you recived ~o~%sx~s~ bullets from ~b~%s~s~.', ['giveammo'] = 'Munition geben', - ['inventory'] = 'Inventar', - ['use'] = 'benutzen', - ['give'] = 'geben', - ['remove'] = 'entfernen', - ['return'] = 'zurück', - ['amount'] = 'Betrag', ['amount_invalid'] = 'ungültiger Betrag', ['players_nearby'] = 'keine Spieler in der Nähe', ['ex_inv_lim'] = 'Aktion nicht möglich, inventarlimit überschritten für ~b~', @@ -24,7 +24,13 @@ Locales['de'] = { ['imp_invalid_amount'] = 'Aktion nicht möglich, ungültiger Betrag', ['delete_five_min'] = '~r~löschen~s~ in 5 Minuten', ['threw'] = 'du ~r~wirfst weg~s~', - ['rec_salary'] = 'du hast dein Gehalt erhalten: ', + -- Salary related + ['recived_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', + ['recived_help'] = 'you recieved your welfare check: ~g~$%s~s~', + ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary.', + ['recived_money'] = 'recived money', + ['bank'] = 'bank', + ['act_imp'] = 'Aktion nicht möglich', -- Commands ['setjob'] = 'assign a job to a user', diff --git a/locales/en.lua b/locales/en.lua index 96c84eb5..eec86111 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -24,11 +24,13 @@ Locales['en'] = { ['imp_invalid_amount'] = 'action impossible, invalid amount', ['delete_five_min'] = 'the item will be ~r~thrown~s~ in 5 minutes', ['threw'] = 'you ~r~threw~s~', - ['rec_salary'] = 'you received your salary: ', - ['rec_help'] = 'you recieved your welfare check: ', - ['company_paid'] = 'company paycheck received', - ['company_nomoney'] = 'your company is broke!', - ['state_paid'] = 'You received a state check', + -- Salary related + ['recived_salary'] = 'you received your salary: ~g~$%s~s~', + ['recived_help'] = 'you recieved your welfare check: ~g~$%s~s~', + ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary.', + ['recived_money'] = 'recived money', + ['bank'] = 'bank', + ['act_imp'] = 'action impossible', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', diff --git a/locales/fr.lua b/locales/fr.lua index 5e2027f1..b980b46d 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -24,11 +24,13 @@ Locales['fr'] = { ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', ['delete_five_min'] = '~r~suppression~s~ dans 5 minutes', ['threw'] = 'vous avez ~r~jeté~s~', - ['rec_salary'] = 'vous avez reçu votre salaire : ', - ['rec_help'] = 'vous avez reçu une aide de l\'état : ', - ['company_paid'] = 'Votre entreprise vous a payé ', - ['company_nomoney'] = 'Votre entreprise n\'a plus d\'argent pour vous payer !', - ['state_paid'] = 'L\'état vous a payé ', + -- Salary related + ['recived_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', + ['recived_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', + ['company_nomoney'] = 'votre entreprise n\'a plus d\'argent pour vous payer!', -- fix translation + ['recived_money'] = 'recived money', + ['bank'] = 'bank', + ['act_imp'] = 'action impossible', ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', ['cannot_pickup_room'] = 'vous n\'avez plus de place pour ~y~%s~s~!', diff --git a/locales/sv.lua b/locales/sv.lua index 5c6db2ff..512624cb 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -24,11 +24,13 @@ Locales['sv'] = { ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', ['delete_five_min'] = 'objektet kommer att ~r~tas bort~s~ om 5 minuter!', ['threw'] = 'du ~r~kastade~s~', - ['rec_salary'] = 'du fick din lön: ', - ['rec_help'] = 'du fick din välfärdskontroll: ', - ['company_paid'] = 'Företags lön mottaget', - ['company_nomoney'] = 'Ditt företag är för fattigt!!', - ['state_paid'] = 'Du fick en statlig check', + -- Salary related + ['recived_salary'] = 'du har mottagit din lön på ~g~$%s~s~', + ['recived_help'] = 'du har mottagit bidrag på ~g~$%s~s~', + ['company_nomoney'] = 'företaget du är anställt hos har inte råd att betala ut din lön.', + ['recived_money'] = 'mottagit pengar', + ['bank'] = 'bank', + ['act_imp'] = 'åtgärd omöjlig', ['in_vehicle'] = 'du kan inte ge saker till en som sitter i ett fordon!', ['cannot_pickup_room'] = 'du har inte plats för att plocka upp ~y~%s~s~!', diff --git a/localization/br_es_extended.sql b/localization/br_es_extended.sql deleted file mode 100644 index cf210476..00000000 --- a/localization/br_es_extended.sql +++ /dev/null @@ -1,69 +0,0 @@ - USE `essentialmode`; - - ALTER TABLE `users` - ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, - ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, - ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, - ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, - ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` - ; - - CREATE TABLE `items` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `limit` int(11) NOT NULL DEFAULT '-1', - `rare` int(11) NOT NULL DEFAULT '0', - `can_remove` int(11) NOT NULL DEFAULT '1', - - PRIMARY KEY (`id`) - ); - - CREATE TABLE `job_grades` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `job_name` varchar(255) DEFAULT NULL, - `grade` int(11) NOT NULL, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `salary` int(11) NOT NULL, - `skin_male` longtext NOT NULL, - `skin_female` longtext NOT NULL, - - PRIMARY KEY (`id`) - ); - - INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','Desempregado',200,'{}','{}'); - - CREATE TABLE `jobs` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) DEFAULT NULL, - - PRIMARY KEY (`id`) - ); - - INSERT INTO `jobs` VALUES (1,'unemployed','Desempregado'); - - CREATE TABLE `user_accounts` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `name` varchar(255) NOT NULL, - `money` double NOT NULL DEFAULT '0', - - PRIMARY KEY (`id`) - ); - - CREATE TABLE `user_inventory` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `item` varchar(255) NOT NULL, - `count` int(11) NOT NULL, - - PRIMARY KEY (`id`) - ); diff --git a/localization/de_es_extended.sql b/localization/de_es_extended.sql deleted file mode 100644 index 2350a6cd..00000000 --- a/localization/de_es_extended.sql +++ /dev/null @@ -1,69 +0,0 @@ -USE `essentialmode`; - -ALTER TABLE `users` - ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, - ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, - ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, - ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, - ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` -; - -CREATE TABLE `items` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `limit` int(11) NOT NULL DEFAULT '-1', - `rare` int(11) NOT NULL DEFAULT '0', - `can_remove` int(11) NOT NULL DEFAULT '1', - - PRIMARY KEY (`id`) -); - -CREATE TABLE `job_grades` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `job_name` varchar(255) DEFAULT NULL, - `grade` int(11) NOT NULL, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `salary` int(11) NOT NULL, - `skin_male` longtext NOT NULL, - `skin_female` longtext NOT NULL, - - PRIMARY KEY (`id`) -); - -INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','Arbeitslos',200,'{}','{}'); - -CREATE TABLE `jobs` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) DEFAULT NULL, - - PRIMARY KEY (`id`) -); - -INSERT INTO `jobs` VALUES (1,'unemployed','Suchend'); - -CREATE TABLE `user_accounts` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `name` varchar(255) NOT NULL, - `money` double NOT NULL DEFAULT '0', - - PRIMARY KEY (`id`) -); - -CREATE TABLE `user_inventory` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `item` varchar(255) NOT NULL, - `count` int(11) NOT NULL, - - PRIMARY KEY (`id`) -); diff --git a/localization/en_es_extended.sql b/localization/en_es_extended.sql deleted file mode 100644 index dcef2c84..00000000 --- a/localization/en_es_extended.sql +++ /dev/null @@ -1,69 +0,0 @@ -USE `essentialmode`; - -ALTER TABLE `users` - ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, - ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, - ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, - ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, - ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` -; - -CREATE TABLE `items` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `limit` int(11) NOT NULL DEFAULT '-1', - `rare` int(11) NOT NULL DEFAULT '0', - `can_remove` int(11) NOT NULL DEFAULT '1', - - PRIMARY KEY (`id`) -); - -CREATE TABLE `job_grades` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `job_name` varchar(255) DEFAULT NULL, - `grade` int(11) NOT NULL, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `salary` int(11) NOT NULL, - `skin_male` longtext NOT NULL, - `skin_female` longtext NOT NULL, - - PRIMARY KEY (`id`) -); - -INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','Welfare',200,'{}','{}'); - -CREATE TABLE `jobs` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) DEFAULT NULL, - - PRIMARY KEY (`id`) -); - -INSERT INTO `jobs` VALUES (1,'unemployed','Unemployed'); - -CREATE TABLE `user_accounts` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `name` varchar(255) NOT NULL, - `money` double NOT NULL DEFAULT '0', - - PRIMARY KEY (`id`) -); - -CREATE TABLE `user_inventory` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `item` varchar(255) NOT NULL, - `count` int(11) NOT NULL, - - PRIMARY KEY (`id`) -); diff --git a/localization/sv_es_extended.sql b/localization/sv_es_extended.sql deleted file mode 100644 index 0add2588..00000000 --- a/localization/sv_es_extended.sql +++ /dev/null @@ -1,69 +0,0 @@ -USE `essentialmode`; - -ALTER TABLE `users` - ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, - ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, - ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, - ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, - ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` -; - -CREATE TABLE `items` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `limit` int(11) NOT NULL DEFAULT '-1', - `rare` int(11) NOT NULL DEFAULT '0', - `can_remove` int(11) NOT NULL DEFAULT '1', - - PRIMARY KEY (`id`) -); - -CREATE TABLE `job_grades` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `job_name` varchar(255) DEFAULT NULL, - `grade` int(11) NOT NULL, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, - `salary` int(11) NOT NULL, - `skin_male` longtext NOT NULL, - `skin_female` longtext NOT NULL, - - PRIMARY KEY (`id`) -); - -INSERT INTO `job_grades` VALUES (1,'unemployed',0,'rsa','A-Kassa',200,'{}','{}'); - -CREATE TABLE `jobs` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `name` varchar(255) NOT NULL, - `label` varchar(255) DEFAULT NULL, - - PRIMARY KEY (`id`) -); - -INSERT INTO `jobs` VALUES (1,'unemployed','Arbetslös'); - -CREATE TABLE `user_accounts` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `name` varchar(255) NOT NULL, - `money` double NOT NULL DEFAULT '0', - - PRIMARY KEY (`id`) -); - -CREATE TABLE `user_inventory` ( - - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `item` varchar(255) NOT NULL, - `count` int(11) NOT NULL, - - PRIMARY KEY (`id`) -); diff --git a/server/commands.lua b/server/commands.lua index 78a53373..4f12fb48 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -17,8 +17,16 @@ end, function(source, args, user) end, {help = "Teleport to coordinates", params = {{name = "x", help = "X coords"}, {name = "y", help = "Y coords"}, {name = "z", help = "Z coords"}}}) TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[1]) - xPlayer.setJob(args[2], tonumber(args[3])) + if tonumber(args[1]) and args[2] and tonumber(args[3]) then + local xPlayer = ESX.GetPlayerFromId(args[1]) + if xPlayer ~= nil then + xPlayer.setJob(args[2], args[3]) + else + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Player not online.") + end + else + TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Invalid usage.") + end end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") end, {help = _U('setjob'), params = {{name = "id", help = _U('id_param')}, {name = "job", help = _U('setjob_param2')}, {name = "grade_id", help = _U('setjob_param3')}}}) diff --git a/server/paycheck.lua b/server/paycheck.lua index f44fb680..f7551baf 100644 --- a/server/paycheck.lua +++ b/server/paycheck.lua @@ -1,29 +1,47 @@ ESX.StartPayCheck = function() - function payCheck() + function payCheck() + local xPlayers = ESX.GetPlayers() - local xPlayers = ESX.GetPlayers() + for i=1, #xPlayers, 1 do + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + local job = xPlayer.job.grade_name + local salary = xPlayer.job.grade_salary - for i=1, #xPlayers, 1 do + if salary > 0 then + if job == 'unemployed' then -- unemployed + xPlayer.addAccountMoney('bank', salary) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_help', salary), 'CHAR_BANK_MAZE', 9) + elseif job == 'employee' then -- generic job, not a society + xPlayer.addAccountMoney('bank', salary) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_salary', salary), 'CHAR_BANK_MAZE', 9) + else -- possibly a society + TriggerEvent('esx_society:getSociety', xPlayer.job.name, function (society) + if society ~= nil then -- verified society + TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function (account) + if account.money >= salary then -- does the society money to pay its employees? + xPlayer.addAccountMoney('bank', salary) + account.removeMoney(salary) + + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_salary', salary), 'CHAR_BANK_MAZE', 9) + else + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), '', _U('company_nomoney'), 'CHAR_BANK_MAZE', 1) + end + end) + else -- not a society, use 'employee' as grade name! + xPlayer.addAccountMoney('bank', salary) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_salary', salary), 'CHAR_BANK_MAZE', 9) + end + end) + end + end - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + end - if xPlayer.job.grade_salary > 0 then - xPlayer.addMoney(xPlayer.job.grade_salary) + SetTimeout(Config.PaycheckInterval, payCheck) - if xPlayer.job.grade_name == 'interim' then - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_help') .. '~g~$' .. xPlayer.job.grade_salary) - else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('rec_salary') .. '~g~$' .. xPlayer.job.grade_salary) - end - end + end - end - - SetTimeout(Config.PaycheckInterval, payCheck) - - end - - SetTimeout(Config.PaycheckInterval, payCheck) + SetTimeout(Config.PaycheckInterval, payCheck) end diff --git a/server/paycheck_company.lua b/server/paycheck_company.lua deleted file mode 100644 index 892c0281..00000000 --- a/server/paycheck_company.lua +++ /dev/null @@ -1,30 +0,0 @@ -ESX.StartPayCheck = function () - -function payCheck () - local xPlayers = ESX.GetPlayers() - for i=1, #xPlayers, 1 do - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - if xPlayer.job.grade_name == 'interim' or xPlayer.job.grade_name == 'rsa' or xPlayer.job.grade_name == 'employee' then -- only if the player is employeed in a company - if xPlayer.job.grade_salary > 0 then - xPlayer.addAccountMoney('bank', xPlayer.job.grade_salary) - TriggerClientEvent('esx:showNotification', xPlayer.source, ('L\'état vous a payé ') .. '~g~$' .. xPlayer.job.grade_salary) - end - else -- Else take money from society - TriggerEvent('esx_society:getSociety', xPlayer.job.name, function (society) - TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function (account) - if account.money >= xPlayer.job.grade_salary then - xPlayer.addAccountMoney('bank',xPlayer.job.grade_salary) - account.removeMoney(xPlayer.job.grade_salary) - TriggerClientEvent('esx:showNotification', xPlayer.source, ('Votre entreprise vous a payé ') .. '~g~$' .. xPlayer.job.grade_salary) - else - TriggerClientEvent('esx:showNotification', xPlayer.source, 'Votre entreprise n\'a plus d\'argent pour vous payer !') - end - end) - end) - end - end - - SetTimeout(Config.PaycheckInterval, payCheck) - end - SetTimeout(Config.PaycheckInterval, payCheck) -end From 0cd409add9efb672ca2c23bbab76757072c71214 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 May 2018 22:30:09 +0200 Subject: [PATCH 195/672] Fixed invalid SQL --- es_extended.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index e1d142fe..badf8f87 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -26,8 +26,8 @@ CREATE TABLE `job_grades` ( `name` varchar(255) NOT NULL, `label` varchar(255) NOT NULL, `salary` int(11) NOT NULL, - `skin_male` longtext NOT NULL DEFAULT '{}', - `skin_female` longtext NOT NULL DEFAULT '{}', + `skin_male` longtext NOT NULL, + `skin_female` longtext NOT NULL, PRIMARY KEY (`id`) ); From 8b8a4f45ec840e2d8039999031dcfdd979314eb9 Mon Sep 17 00:00:00 2001 From: Corey McCown Date: Tue, 15 May 2018 13:46:09 -0400 Subject: [PATCH 196/672] Update main.lua Fix #38, item pickup issue. --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 6c4bc028..73e1fefd 100644 --- a/server/main.lua +++ b/server/main.lua @@ -542,7 +542,7 @@ AddEventHandler('esx:onPickup', function(id) if pickup.type == 'item_standard' then local item = xPlayer.getInventoryItem(pickup.name) - local canTake = (item.limit - item.count > 0) and (item.limit - item.count) or 0 + local canTake = ((item.limit == -1) and (pickup.count)) or ((item.limit - item.count > 0) and (item.limit - item.count)) or 0 local total = pickup.count < canTake and pickup.count or canTake local remaining = pickup.count - total From 6511182681a7874c600811f2648cf4d787579718 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 16 May 2018 21:14:08 +0200 Subject: [PATCH 197/672] Config cleanup, final commit v1.0.14 --- __resource.lua | 95 ++++++++++++++++++++++++---------------------- config.lua | 13 ++++--- config.weapons.lua | 20 +++++----- locales/br.lua | 2 +- locales/de.lua | 1 + locales/en.lua | 1 + locales/fr.lua | 3 +- locales/sv.lua | 3 +- 8 files changed, 73 insertions(+), 65 deletions(-) diff --git a/__resource.lua b/__resource.lua index a331f70e..0f5d29ff 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,75 +2,78 @@ resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9' description 'ES Extended' -version '1.0.13' +version '1.0.14' server_scripts { - '@async/async.lua', - '@mysql-async/lib/MySQL.lua', - 'config.lua', - 'locale.lua', - 'locales/de.lua', - 'locales/br.lua', - 'locales/fr.lua', - 'locales/en.lua', - 'locales/sv.lua', - 'config.weapons.lua', - 'server/common.lua', - 'server/classes/player.lua', - 'server/functions.lua', - 'server/paycheck.lua', - 'server/main.lua', - 'server/commands.lua' + '@async/async.lua', + '@mysql-async/lib/MySQL.lua', + 'locale.lua', + 'locales/de.lua', + 'locales/br.lua', + 'locales/fr.lua', + 'locales/en.lua', + 'locales/sv.lua', + 'config.lua', + 'config.weapons.lua', + 'server/common.lua', + 'server/classes/player.lua', + 'server/functions.lua', + 'server/paycheck.lua', + 'server/main.lua', + 'server/commands.lua' } client_scripts { - 'config.lua', - 'locale.lua', - 'locales/de.lua', - 'locales/br.lua', - 'locales/fr.lua', - 'locales/en.lua', - 'locales/sv.lua', - 'config.weapons.lua', - 'client/common.lua', - 'client/entityiter.lua', - 'client/functions.lua', - 'client/wrapper.lua', - 'client/main.lua' + 'locale.lua', + 'locales/de.lua', + 'locales/br.lua', + 'locales/fr.lua', + 'locales/en.lua', + 'locales/sv.lua', + 'config.lua', + 'config.weapons.lua', + 'client/common.lua', + 'client/entityiter.lua', + 'client/functions.lua', + 'client/wrapper.lua', + 'client/main.lua' } ui_page { - 'html/ui.html' + 'html/ui.html' } files { - 'html/ui.html', + 'html/ui.html', - 'html/css/app.css', + 'html/css/app.css', - 'html/js/mustache.min.js', - 'html/js/wrapper.js', - 'html/js/app.js', + 'html/js/mustache.min.js', + 'html/js/wrapper.js', + 'html/js/app.js', - 'html/fonts/pdown.ttf', - 'html/fonts/bankgothic.ttf', + 'html/fonts/pdown.ttf', + 'html/fonts/bankgothic.ttf', - 'html/img/cursor.png', - 'html/img/keys/enter.png', - 'html/img/keys/return.png', + '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' + 'html/img/accounts/bank.png', + 'html/img/accounts/black_money.png' } exports { - 'getSharedObject' + 'getSharedObject' } server_exports { - 'getSharedObject' + 'getSharedObject' } dependencies { - 'essentialmode' + 'essentialmode', + 'mysql-async', + 'async', + 'baseevents' } diff --git a/config.lua b/config.lua index ce90edee..1a1f6a36 100644 --- a/config.lua +++ b/config.lua @@ -1,12 +1,13 @@ Config = {} -Config.MaxPlayers = 32 +Config.Locale = 'fr' + Config.Accounts = { 'bank', 'black_money' } -Config.AccountLabels = { bank = 'Banque', black_money = 'Argent Sale' } -- French --- Config.AccountLabels = { bank = 'Bank', black_money = 'Dirty Money' } -- English -Config.PaycheckInterval = 7 * 60000 +Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } + Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true -Config.RemoveInventoryItemDelay = 5 * 60000 Config.EnableWeaponPickup = true -Config.Locale = 'fr' +Config.RemoveInventoryItemDelay = 5 * 60000 +Config.PaycheckInterval = 7 * 60000 +Config.MaxPlayers = 32 Config.EnableDebug = false diff --git a/config.weapons.lua b/config.weapons.lua index 04546755..bff086bd 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -78,17 +78,17 @@ Config.Weapons = { { name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision') }, { name = 'GADGET_PARACHUTE', label = _U('gadget_parachute') }, { name = 'WEAPON_FLARE', label = _U('weapon_flare') }, - { name = 'WEAPON_SNSPISTOL_MK2', label = _U('weapon_snspistol_mk2') }, - { name = 'WEAPON_REVOLVER_MK2', label = _U('weapon_revolver_mk2') }, - { name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction') }, - { name = 'WEAPON_SPECIALCARBINE_MK2', label = _U('weapon_specialcarabine_mk2') }, - { name = 'WEAPON_BULLPUPRIFLE_MK2', label = _U('weapon_bullpruprifle_mk2') }, + { name = 'WEAPON_SNSPISTOL_MK2', label = _U('weapon_snspistol_mk2') }, + { name = 'WEAPON_REVOLVER_MK2', label = _U('weapon_revolver_mk2') }, + { name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction') }, + { name = 'WEAPON_SPECIALCARBINE_MK2', label = _U('weapon_specialcarabine_mk2') }, + { name = 'WEAPON_BULLPUPRIFLE_MK2', label = _U('weapon_bullpruprifle_mk2') }, { name = 'WEAPON_PUMPSHOTGUN_MK2', label = _U('weapon_pumpshotgun_mk2') }, - { name = 'WEAPON_MARKSMANRIFLE_MK2', label = _U('weapon_marksmanrifle_mk2') }, + { name = 'WEAPON_MARKSMANRIFLE_MK2', label = _U('weapon_marksmanrifle_mk2') }, { name = 'WEAPON_ASSAULTRIFLE_MK2', label = _U('weapon_assaultrifle_mk2') }, - { name = 'WEAPON_CARBINERIFLE_MK2', label = _U('weapon_carbinerifle_mk2') }, - { name = 'WEAPON_COMBATMG_MK2', label = _U('weapon_combatmg_mk2') }, - { name = 'WEAPON_HEAVYSNIPER_MK2', label = _U('weapon_heavysniper_mk2') }, - { name = 'WEAPON_PISTOL_MK2', label = _U('weapon_pistol_mk2') }, + { name = 'WEAPON_CARBINERIFLE_MK2', label = _U('weapon_carbinerifle_mk2') }, + { name = 'WEAPON_COMBATMG_MK2', label = _U('weapon_combatmg_mk2') }, + { name = 'WEAPON_HEAVYSNIPER_MK2', label = _U('weapon_heavysniper_mk2') }, + { name = 'WEAPON_PISTOL_MK2', label = _U('weapon_pistol_mk2') }, { name = 'WEAPON_SMG_MK2', label = _U('weapon_smg_mk2') }, } diff --git a/locales/br.lua b/locales/br.lua index b6235ab2..5caa5f5e 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -30,7 +30,7 @@ Locales['br'] = { ['company_nomoney'] = 'Sua empresa está falida!', -- incorrect translation ['recived_money'] = 'recived money', ['bank'] = 'bank', - + ['black_money'] = 'dirty Money', ['act_imp'] = 'ação impossível', ['in_vehicle'] = 'Você não pode dar nada para alguém no veículo', diff --git a/locales/de.lua b/locales/de.lua index 3e77d440..ce75ce24 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -30,6 +30,7 @@ Locales['de'] = { ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary.', ['recived_money'] = 'recived money', ['bank'] = 'bank', + ['black_money'] = 'dirty Money', ['act_imp'] = 'Aktion nicht möglich', -- Commands diff --git a/locales/en.lua b/locales/en.lua index eec86111..fccc46d1 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -30,6 +30,7 @@ Locales['en'] = { ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary.', ['recived_money'] = 'recived money', ['bank'] = 'bank', + ['black_money'] = 'dirty Money', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', diff --git a/locales/fr.lua b/locales/fr.lua index b980b46d..0c80ee2e 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -29,7 +29,8 @@ Locales['fr'] = { ['recived_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', ['company_nomoney'] = 'votre entreprise n\'a plus d\'argent pour vous payer!', -- fix translation ['recived_money'] = 'recived money', - ['bank'] = 'bank', + ['bank'] = 'banque', + ['black_money'] = 'argent Sale', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', diff --git a/locales/sv.lua b/locales/sv.lua index 512624cb..dc183369 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -22,7 +22,7 @@ Locales['sv'] = { ['by'] = '~s~ av ~b~', ['imp_invalid_quantity'] = 'åtgärd omöjlig, ogiltig mängd', ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', - ['delete_five_min'] = 'objektet kommer att ~r~tas bort~s~ om 5 minuter!', + ['delete_five_min'] = 'objektet kommer att ~r~kastas~s~ om 5 minuter!', ['threw'] = 'du ~r~kastade~s~', -- Salary related ['recived_salary'] = 'du har mottagit din lön på ~g~$%s~s~', @@ -30,6 +30,7 @@ Locales['sv'] = { ['company_nomoney'] = 'företaget du är anställt hos har inte råd att betala ut din lön.', ['recived_money'] = 'mottagit pengar', ['bank'] = 'bank', + ['black_money'] = 'svarta pengar', ['act_imp'] = 'åtgärd omöjlig', ['in_vehicle'] = 'du kan inte ge saker till en som sitter i ett fordon!', From 321e4b2af804049c9739d47fe3970b0d4cf9e562 Mon Sep 17 00:00:00 2001 From: renildomarcio Date: Sun, 20 May 2018 08:51:51 -0300 Subject: [PATCH 198/672] fix on update v1.0.14 100% corrected translation --- locales/br.lua | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 5caa5f5e..b9b5dfaa 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -7,11 +7,11 @@ Locales['br'] = { ['amount'] = 'quantidade', ['amountammo'] = 'quantidade de munição', ['noammo'] = 'Você não tem todas essas munições!', - ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', - ['recived_weapon'] = 'you recived ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', - ['recived_ammo'] = 'you recived ~o~%sx~s~ bullets from ~b~%s~s~.', + ['threw_weapon'] = 'você ~r~jogou~s~ ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas!', -- fix on update v1.0.14 + ['gave_weapon'] = 'você deu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas para ~y~%s~s~.', -- fix on update v1.0.14 + ['recived_weapon'] = 'você recebeu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~.', -- fix on update v1.0.14 + ['gave_ammo'] = 'você deu ~o~%sx~s~ balas para ~y~%s~s~.', -- fix on update v1.0.14 + ['recived_ammo'] = 'você recebeu ~o~%sx~s~ balas de ~b~%s~s~.', -- fix on update v1.0.14 ['giveammo'] = 'Dar munição', ['amount_invalid'] = 'quantidade inválida', ['players_nearby'] = 'nenhum jogador por perto', @@ -24,18 +24,17 @@ Locales['br'] = { ['imp_invalid_amount'] = 'ação impossível, valor inválido', ['delete_five_min'] = '~r~excluir~s~ em 5 minutos', ['threw'] = 'você ~r~jogou~s~', - -- Salary related + -- Relacionado com salário ['recived_salary'] = 'você recebeu seu salário: ', ['recived_help'] = 'você recebeu seu cheque de bem-estar: ', - ['company_nomoney'] = 'Sua empresa está falida!', -- incorrect translation - ['recived_money'] = 'recived money', - ['bank'] = 'bank', - ['black_money'] = 'dirty Money', - + ['company_nomoney'] = 'a empresa em que você está empregado esta muito pobre para pagar seu salário.', -- fix on update v1.0.14 + ['recived_money'] = 'recebeu dinheiro', -- fix on update v1.0.14 + ['bank'] = 'banco', -- fix on update v1.0.14 + ['black_money'] = 'dinheiro sujo', -- fix on update v1.0.14 ['act_imp'] = 'ação impossível', ['in_vehicle'] = 'Você não pode dar nada para alguém no veículo', - ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', - -- Commands + ['cannot_pickup_room'] = 'você não tem espaço suficiente no seu inventário para pegar ~y~%s~s~!', -- fix on update v1.0.14 + -- Comandos ['setjob'] = 'atribuir um trabalho a um usuário', ['id_param'] = 'o ID do jogador', ['setjob_param2'] = 'o trabalho que você deseja atribuir', @@ -61,7 +60,7 @@ Locales['br'] = { ['giveitem'] = 'dar item', ['weapon'] = 'arma', ['giveweapon'] = 'dar arma', - -- Weapons + -- Armas ['weapon_knife'] = 'faca', ['weapon_nightstick'] = 'cacetete', ['weapon_hammer'] = 'martelo', From 181bf9218de5297259f823f2d4201e79d154fc27 Mon Sep 17 00:00:00 2001 From: renildomarcio Date: Sun, 20 May 2018 21:36:23 -0300 Subject: [PATCH 199/672] Update 20/05 --- locales/br.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index b9b5dfaa..0f790571 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -7,11 +7,11 @@ Locales['br'] = { ['amount'] = 'quantidade', ['amountammo'] = 'quantidade de munição', ['noammo'] = 'Você não tem todas essas munições!', - ['threw_weapon'] = 'você ~r~jogou~s~ ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas!', -- fix on update v1.0.14 - ['gave_weapon'] = 'você deu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas para ~y~%s~s~.', -- fix on update v1.0.14 - ['recived_weapon'] = 'você recebeu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~.', -- fix on update v1.0.14 - ['gave_ammo'] = 'você deu ~o~%sx~s~ balas para ~y~%s~s~.', -- fix on update v1.0.14 - ['recived_ammo'] = 'você recebeu ~o~%sx~s~ balas de ~b~%s~s~.', -- fix on update v1.0.14 + ['threw_weapon'] = 'você ~r~jogou~s~ ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas!', + ['gave_weapon'] = 'você deu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas para ~y~%s~s~.', + ['recived_weapon'] = 'você recebeu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~.', + ['gave_ammo'] = 'você deu ~o~%sx~s~ balas para ~y~%s~s~.', + ['recived_ammo'] = 'você recebeu ~o~%sx~s~ balas de ~b~%s~s~.', ['giveammo'] = 'Dar munição', ['amount_invalid'] = 'quantidade inválida', ['players_nearby'] = 'nenhum jogador por perto', @@ -27,13 +27,13 @@ Locales['br'] = { -- Relacionado com salário ['recived_salary'] = 'você recebeu seu salário: ', ['recived_help'] = 'você recebeu seu cheque de bem-estar: ', - ['company_nomoney'] = 'a empresa em que você está empregado esta muito pobre para pagar seu salário.', -- fix on update v1.0.14 - ['recived_money'] = 'recebeu dinheiro', -- fix on update v1.0.14 - ['bank'] = 'banco', -- fix on update v1.0.14 - ['black_money'] = 'dinheiro sujo', -- fix on update v1.0.14 + ['company_nomoney'] = 'a empresa em que você está empregado esta muito pobre para pagar seu salário.', + ['recived_money'] = 'recebeu dinheiro', + ['bank'] = 'banco', + ['black_money'] = 'dinheiro sujo', ['act_imp'] = 'ação impossível', ['in_vehicle'] = 'Você não pode dar nada para alguém no veículo', - ['cannot_pickup_room'] = 'você não tem espaço suficiente no seu inventário para pegar ~y~%s~s~!', -- fix on update v1.0.14 + ['cannot_pickup_room'] = 'você não tem espaço suficiente no seu inventário para pegar ~y~%s~s~!', -- Comandos ['setjob'] = 'atribuir um trabalho a um usuário', ['id_param'] = 'o ID do jogador', From 56597825da05c9fcf853e6e93f964741a0386c19 Mon Sep 17 00:00:00 2001 From: MrLumi Date: Thu, 24 May 2018 19:37:29 +0100 Subject: [PATCH 200/672] Update br.lua --- locales/br.lua | 82 +++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 0f790571..e60577f9 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,61 +1,61 @@ Locales['br'] = { - ['inventory'] = 'inventário', - ['use'] = 'use', + ['inventory'] = 'inventario', + ['use'] = 'usar', ['give'] = 'dar', ['remove'] = 'remover', - ['return'] = 'retorna', + ['return'] = 'voltar', ['amount'] = 'quantidade', - ['amountammo'] = 'quantidade de munição', - ['noammo'] = 'Você não tem todas essas munições!', - ['threw_weapon'] = 'você ~r~jogou~s~ ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas!', - ['gave_weapon'] = 'você deu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas para ~y~%s~s~.', - ['recived_weapon'] = 'você recebeu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~.', - ['gave_ammo'] = 'você deu ~o~%sx~s~ balas para ~y~%s~s~.', - ['recived_ammo'] = 'você recebeu ~o~%sx~s~ balas de ~b~%s~s~.', - ['giveammo'] = 'Dar munição', - ['amount_invalid'] = 'quantidade inválida', + ['amountammo'] = 'quantidade de muniçao', + ['noammo'] = 'voce nao tem todas essas muniçoes!', + ['threw_weapon'] = 'voce ~r~atirou~s~ ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas!', + ['gave_weapon'] = 'voce deu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas para ~y~%s~s~.', + ['recived_weapon'] = 'voce recebeu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~.', + ['gave_ammo'] = 'voce deu ~o~%sx~s~ balas para ~y~%s~s~.', + ['recived_ammo'] = 'voce recebeu ~o~%sx~s~ balas de ~b~%s~s~.', + ['giveammo'] = 'Dar muniçao', + ['amount_invalid'] = 'quantidade invalida', ['players_nearby'] = 'nenhum jogador por perto', - ['ex_inv_lim'] = 'ação não é possível, excedendo o limite de estoque para ~b~', - ['yougave'] = 'você deu', - ['youreceived'] = 'você recebeu', + ['ex_inv_lim'] = 'acao nao e possivel, excedendo o limite de estoque para ~b~', + ['yougave'] = 'voce deu', + ['youreceived'] = 'voce recebeu', ['to'] = '~s~ para ~b~', ['by'] = '~s~ de ~b~', - ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', - ['imp_invalid_amount'] = 'ação impossível, valor inválido', + ['imp_invalid_quantity'] = 'acao impossivel, quantidade invalida', + ['imp_invalid_amount'] = 'acao impossivel, valor invalido', ['delete_five_min'] = '~r~excluir~s~ em 5 minutos', - ['threw'] = 'você ~r~jogou~s~', - -- Relacionado com salário - ['recived_salary'] = 'você recebeu seu salário: ', - ['recived_help'] = 'você recebeu seu cheque de bem-estar: ', - ['company_nomoney'] = 'a empresa em que você está empregado esta muito pobre para pagar seu salário.', + ['threw'] = 'voce ~r~jogou~s~', + -- Relacionado com salario + ['recived_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', + ['recived_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', + ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salario.', ['recived_money'] = 'recebeu dinheiro', ['bank'] = 'banco', ['black_money'] = 'dinheiro sujo', - ['act_imp'] = 'ação impossível', - ['in_vehicle'] = 'Você não pode dar nada para alguém no veículo', - ['cannot_pickup_room'] = 'você não tem espaço suficiente no seu inventário para pegar ~y~%s~s~!', + ['act_imp'] = 'acao impossivel', + ['in_vehicle'] = 'voce nao pode dar nada para alguem no veiculo', + ['cannot_pickup_room'] = 'voce nao tem espaço suficiente no seu inventario para pegar ~y~%s~s~!', -- Comandos - ['setjob'] = 'atribuir um trabalho a um usuário', + ['setjob'] = 'atribuir um trabalho a um usuario', ['id_param'] = 'o ID do jogador', - ['setjob_param2'] = 'o trabalho que você deseja atribuir', - ['setjob_param3'] = 'o nível de emprego', + ['setjob_param2'] = 'o trabalho que voce deseja atribuir', + ['setjob_param3'] = 'o nivel de emprego', ['load_ipl'] = 'carregar IPL', ['unload_ipl'] = 'descarregar o IPL', - ['play_anim'] = 'tocar animação', - ['play_emote'] = 'jogar emote', + ['play_anim'] = 'Iniciar animacao', + ['play_emote'] = 'Iniciar emote', ['spawn_car'] = 'spawn um carro', ['spawn_car_param'] = 'nome do carro', - ['delete_vehicle'] = 'excluir Veículo', + ['delete_vehicle'] = 'excluir Veiculo', ['delete_veh_param'] = 'pressione Enter', ['spawn_object'] = 'spawn objeto', ['spawn_ped'] = 'spawn ped', ['spawn_ped_param'] = 'exemplo a_m_m_hillbilly_01', ['givemoney'] = 'dar dinheiro', ['money_amount'] = 'quantia de dinheiro', - ['invalid_account'] = 'conta inválida', + ['invalid_account'] = 'conta invalida', ['account'] = 'conta', ['giveaccountmoney'] = 'dar dinheiro da conta', - ['invalid_item'] = 'item inválido', + ['invalid_item'] = 'item invalido', ['item'] = 'item', ['giveitem'] = 'dar item', ['weapon'] = 'arma', @@ -64,9 +64,9 @@ Locales['br'] = { ['weapon_knife'] = 'faca', ['weapon_nightstick'] = 'cacetete', ['weapon_hammer'] = 'martelo', - ['weapon_bat'] = 'bastão', + ['weapon_bat'] = 'bastao', ['weapon_golfclub'] = 'golf club', - ['weapon_crowbar'] = 'pé de cabra', + ['weapon_crowbar'] = 'pe de cabra', ['weapon_pistol'] = 'pistola', ['weapon_combatpistol'] = 'pistola de combate', ['weapon_appistol'] = 'ap pistola', @@ -95,9 +95,9 @@ Locales['br'] = { ['weapon_stickybomb'] = 'bomba pegajosa', ['weapon_smokegrenade'] = 'granada de fumaça', ['weapon_bzgas'] = 'bz gas', - ['weapon_molotov'] = 'coquetel molotov', + ['weapon_molotov'] = 'molotov', ['weapon_fireextinguisher'] = 'extintor', - ['weapon_petrolcan'] = 'galão de combustivel', + ['weapon_petrolcan'] = 'galao de combustivel', ['weapon_digiscanner'] = 'digiscanner', ['weapon_ball'] = 'bola', ['weapon_snspistol'] = 'sns pistol', @@ -108,7 +108,7 @@ Locales['br'] = { ['weapon_bullpuprifle'] = 'bullpup rifle', ['weapon_dagger'] = 'punhal', ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_firework'] = 'fogos de artifício', + ['weapon_firework'] = 'fogos de artificio', ['weapon_musket'] = 'mosquete', ['weapon_heavyshotgun'] = 'heavy shotgun', ['weapon_marksmanrifle'] = 'marksman rifle', @@ -120,10 +120,10 @@ Locales['br'] = { ['weapon_handcuffs'] = 'algemas', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', - ['weapon_knuckle'] = 'soco inglês', + ['weapon_knuckle'] = 'soco ingles', ['weapon_hatchet'] = 'machado', ['weapon_railgun'] = 'railgun', - ['weapon_machete'] = 'facão', + ['weapon_machete'] = 'facao', ['weapon_machinepistol'] = 'machine pistol', ['weapon_switchblade'] = 'canivete', ['weapon_revolver'] = 'heavy revolver', @@ -137,7 +137,7 @@ Locales['br'] = { ['weapon_poolcue'] = 'taco de sinuca', ['weapon_wrench'] = 'chave de cano', ['weapon_flashlight'] = 'laterna', - ['gadget_nightvision'] = 'visão noturna', + ['gadget_nightvision'] = 'visao noturna', ['gadget_parachute'] = 'paraquedas', ['weapon_flare'] = 'Flare', ['weapon_snspistol_mk2'] = 'Pistola SNS Mk II', From f5a9a96f38409df4f3435ccd3f9306c2506f71e4 Mon Sep 17 00:00:00 2001 From: Ben Sherman Date: Sat, 26 May 2018 22:51:08 +0200 Subject: [PATCH 201/672] Resolved invalid number format Setting jobs on players causes grade check to return an error rather than the check itself. `if PlayerData.job.grade >= 3 then` returns `Attempt to compare number with string` --- server/commands.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/commands.lua b/server/commands.lua index 4f12fb48..641a9077 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -20,7 +20,7 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, if tonumber(args[1]) and args[2] and tonumber(args[3]) then local xPlayer = ESX.GetPlayerFromId(args[1]) if xPlayer ~= nil then - xPlayer.setJob(args[2], args[3]) + xPlayer.setJob(args[2], tonumber(args[3])) else TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Player not online.") end @@ -177,4 +177,4 @@ TriggerEvent('es:addGroupCommand', 'disconnect', 'admin', function(source, args, DropPlayer(source, 'You have been disconnected') end, function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") -end, {help = _U('disconnect')}) \ No newline at end of file +end, {help = _U('disconnect')}) From dcb4fbdaa02d9e92d9bcff067493ef781c4c65bc Mon Sep 17 00:00:00 2001 From: AdrineX Date: Tue, 12 Jun 2018 16:51:10 +0300 Subject: [PATCH 202/672] add locale for cash --- client/functions.lua | 2 +- locales/br.lua | 1 + locales/de.lua | 1 + locales/en.lua | 1 + locales/fr.lua | 1 + locales/sv.lua | 1 + 6 files changed, 6 insertions(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index d26ce3e9..6fc8d6df 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1084,7 +1084,7 @@ ESX.ShowInventory = function() if ESX.PlayerData.money > 0 then table.insert(elements, { - label = '[Cash] $' .. ESX.PlayerData.money, + label = _U('cash') .. ESX.PlayerData.money, count = ESX.PlayerData.money, type = 'item_money', value = 'money', diff --git a/locales/br.lua b/locales/br.lua index e60577f9..16442c00 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,4 +1,5 @@ Locales['br'] = { + ['cash'] = 'efectivo $ ', ['inventory'] = 'inventario', ['use'] = 'usar', ['give'] = 'dar', diff --git a/locales/de.lua b/locales/de.lua index ce75ce24..02a0e6b3 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,4 +1,5 @@ Locales['de'] = { + ['cash'] = 'kontanter $ ', ['inventory'] = 'Inventar', ['use'] = 'benutzen', ['give'] = 'geben', diff --git a/locales/en.lua b/locales/en.lua index fccc46d1..0d272a17 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,4 +1,5 @@ Locales['en'] = { + ['cash'] = 'cash $ ', ['inventory'] = 'inventory', ['use'] = 'use', ['give'] = 'give', diff --git a/locales/fr.lua b/locales/fr.lua index 0c80ee2e..ce3b109a 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,4 +1,5 @@ Locales['fr'] = { + ['cash'] = 'espèces $ ', ['inventory'] = 'inventaire', ['use'] = 'utiliser', ['give'] = 'donner', diff --git a/locales/sv.lua b/locales/sv.lua index dc183369..f4b2c666 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,4 +1,5 @@ Locales['sv'] = { + ['cash'] = 'kontanter $ ', ['inventory'] = 'Mitt förråd', ['use'] = 'använd', ['give'] = 'ge', From 32a198daf85f61dded57bcd055f4e5a21b3859c5 Mon Sep 17 00:00:00 2001 From: AdrineX Date: Tue, 12 Jun 2018 17:58:23 +0300 Subject: [PATCH 203/672] Add Finnish lang.. --- __resource.lua | 2 + locales/fi.lua | 162 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 locales/fi.lua diff --git a/__resource.lua b/__resource.lua index 0f5d29ff..2bb79d2f 100644 --- a/__resource.lua +++ b/__resource.lua @@ -12,6 +12,7 @@ server_scripts { 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', + 'locales/fi.lua', 'locales/sv.lua', 'config.lua', 'config.weapons.lua', @@ -29,6 +30,7 @@ client_scripts { 'locales/br.lua', 'locales/fr.lua', 'locales/en.lua', + 'locales/fi.lua', 'locales/sv.lua', 'config.lua', 'config.weapons.lua', diff --git a/locales/fi.lua b/locales/fi.lua new file mode 100644 index 00000000..13efb83c --- /dev/null +++ b/locales/fi.lua @@ -0,0 +1,162 @@ +Locales['fi'] = { + ['cash'] = 'käteinen $ ', + ['inventory'] = 'reppu', + ['use'] = 'käytä', + ['give'] = 'anna', + ['remove'] = 'poista', + ['return'] = 'takaisin', + ['amount'] = 'määrä', + ['amountammo'] = 'ammusten määrä', + ['noammo'] = 'sinulla ei ole ammuksia!', + ['threw_weapon'] = 'sinä ~r~heitit~s~ ~y~1x~s~ ~b~%s~s~ jossa oli ~o~%sx~s~ ammuksia!', + ['gave_weapon'] = 'sinä annoit ~y~1x~s~ ~b~%s~s~ jossa oli ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~.', + ['recived_weapon'] = 'sinä sait ~y~1x~s~ ~b~%s~s~ jossa oli ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~.', + ['gave_ammo'] = 'sinä annoit ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~.', + ['recived_ammo'] = 'sinä sait ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~.', + ['giveammo'] = 'anna ammuksia', + ['amount_invalid'] = 'virheellinen määrä', + ['players_nearby'] = 'ei pelaajia lähettyvillä', + ['ex_inv_lim'] = 'toiminto mahdoton, reppu alkaa olla täysi ~b~', + ['yougave'] = 'sinä annoit', + ['youreceived'] = 'sinä sait', + ['to'] = '~s~ henkilölle ~b~', + ['by'] = '~s~ henkilöltä ~b~', + ['imp_invalid_quantity'] = 'toiminto mahdoton, virheellinen määrä', + ['imp_invalid_amount'] = 'toiminto mahdoton, virhellinen summa', + ['delete_five_min'] = 'esine ~r~poistetaan~s~ 5 minuutin päästä repusta', + ['threw'] = 'sinä ~r~tiputit~s~', + -- Salary related + ['recived_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', + ['recived_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', + ['company_nomoney'] = 'yritys jolle teet töitä on köyhä eikä voi maksaa palkkaasi.', + ['recived_money'] = 'sai rahaa', + ['bank'] = 'Pankki', + ['black_money'] = 'likainen Raha', + + ['act_imp'] = 'toiminto mahdoton', + ['in_vehicle'] = 'et voi antaa ajoneuvossa olevalle mitään.', + ['cannot_pickup_room'] = 'sinulla ei ole tilaa repussa nostaaksesi ~y~%s~s~!', + -- Commands + ['setjob'] = 'määritä työ käyttäjälle', + ['id_param'] = 'käyttäjän ID', + ['setjob_param2'] = 'työ jonka haluat määrittää', + ['setjob_param3'] = 'työn taso', + ['load_ipl'] = 'lataa IPL', + ['unload_ipl'] = 'poista IPL', + ['play_anim'] = 'toista animaatio', + ['play_emote'] = 'toista ele', + ['spawn_car'] = 'spawnaa ajoneuvo', + ['spawn_car_param'] = 'ajoneuvon nimi', + ['delete_vehicle'] = 'poistaa ajoneuvon', + ['delete_veh_param'] = 'paina Enter', + ['spawn_object'] = 'spawnaa objekti', + ['spawn_ped'] = 'spawnaa pedi', + ['spawn_ped_param'] = 'esimerkki a_m_m_hillbilly_01', + ['givemoney'] = 'anna rahaa', + ['setmoney'] = 'aseta pelaajan rahat', + ['money_type'] = 'hyväksytyt rahatyypit: cash, bank, black', + ['money_set'] = 'joku ~y~korkeesti rankattu~s~ asetti ~g~$%s~s~ (%s) sinulle!', + ['money_amount'] = 'rahan määrä', + ['invalid_account'] = 'virheellinen tunnus', + ['account'] = 'tunnus', + ['giveaccountmoney'] = 'anna tilille rahaa', + ['invalid_item'] = 'virheellinen itemi', + ['item'] = 'esine', + ['giveitem'] = 'anna itemi', + ['weapon'] = 'ase', + ['giveweapon'] = 'anna ase', + ['disconnect'] = 'poistu serveriltä', + -- Weapons + ['weapon_knife'] = 'veitsi', + ['weapon_nightstick'] = 'pamppu', + ['weapon_hammer'] = 'vasara', + ['weapon_bat'] = 'pesäpallomaila', + ['weapon_golfclub'] = 'golf maila', + ['weapon_crowbar'] = 'sorkkarauta', + ['weapon_pistol'] = 'pistooli', + ['weapon_combatpistol'] = 'taistelu pistooli', + ['weapon_appistol'] = 'automaatti pistooli', + ['weapon_pistol50'] = '50 kaliiperinen pistooli', + ['weapon_microsmg'] = 'mikro konepistooli', + ['weapon_smg'] = 'konepistooli', + ['weapon_assaultsmg'] = 'rynnäkkö konepistooli', + ['weapon_assaultrifle'] = 'rynnäkkökivääri', + ['weapon_carbinerifle'] = 'karbiini kivääri', + ['weapon_advancedrifle'] = 'edistynyt kivääri', + ['weapon_mg'] = 'konekivääri', + ['weapon_combatmg'] = 'rynnäkkö konekivääri', + ['weapon_pumpshotgun'] = 'pumppu haulikko', + ['weapon_sawnoffshotgun'] = 'katkaistuhaulikko', + ['weapon_assaultshotgun'] = 'hyökkäyshaulikko', + ['weapon_bullpupshotgun'] = 'bullpup haulikko', + ['weapon_stungun'] = 'tainutusase', + ['weapon_sniperrifle'] = 'tarkkuuskivääri', + ['weapon_heavysniper'] = 'raskas tarkkuuskivääri', + ['weapon_remotesniper'] = 'etäohjattava tarkkuuskivääri', + ['weapon_grenadelauncher'] = 'kranaatinheitin', + ['weapon_rpg'] = 'raketinheitin', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'kranaatti', + ['weapon_stickybomb'] = 'tahma pommi', + ['weapon_smokegrenade'] = 'savu kranaatti', + ['weapon_bzgas'] = 'bz-kaasu', + ['weapon_molotov'] = 'polttopullo', + ['weapon_fireextinguisher'] = 'palosammutin', + ['weapon_petrolcan'] = 'jerrykannu', + ['weapon_digiscanner'] = 'digiskanneri', + ['weapon_ball'] = 'pallo', + ['weapon_snspistol'] = 'pienpistooli', + ['weapon_bottle'] = 'pullo', + ['weapon_gusenberg'] = 'tommy gun', + ['weapon_specialcarbine'] = 'G86C', + ['weapon_heavypistol'] = 'raskas pistooli', + ['weapon_bullpuprifle'] = 'bullpup kivääri', + ['weapon_dagger'] = 'tikari', + ['weapon_vintagepistol'] = 'vanha pistooli', + ['weapon_firework'] = 'ilotulitus', + ['weapon_musket'] = 'musketti', + ['weapon_heavyshotgun'] = 'raskas haulikko', + ['weapon_marksmanrifle'] = 'marksman kivääri', + ['weapon_hominglauncher'] = 'ohjautuva raketinheitin', + ['weapon_proxmine'] = 'lähellä räjähtävä miina', + ['weapon_snowball'] = 'lumipallo', + ['weapon_flaregun'] = 'valopyssy', + ['weapon_garbagebag'] = 'roskapussi', + ['weapon_handcuffs'] = 'käsiraudat', + ['weapon_combatpdw'] = 'rynnäkkö pdw', + ['weapon_marksmanpistol'] = 'marksman pistooli', + ['weapon_knuckle'] = 'nyrkkirauta', + ['weapon_hatchet'] = 'kirves', + ['weapon_railgun'] = 'raidetykki', + ['weapon_machete'] = 'viidakkoveitsi', + ['weapon_machinepistol'] = 'konepistooli', + ['weapon_switchblade'] = 'stiletti', + ['weapon_revolver'] = 'raskas revolveri', + ['weapon_dbshotgun'] = 'kakspiippunen haulikko', + ['weapon_compactrifle'] = 'pikku AK', + ['weapon_autoshotgun'] = 'automaattinen haulikko', + ['weapon_battleaxe'] = 'Taistelukirves', + ['weapon_compactlauncher'] = 'pien kranaatinheitin', + ['weapon_minismg'] = 'mini konepistooli', + ['weapon_pipebomb'] = 'putkipommi', + ['weapon_poolcue'] = 'biljardimaila', + ['weapon_wrench'] = 'putkipihdit', + ['weapon_flashlight'] = 'taskulamppu', + ['gadget_nightvision'] = 'yökiikarit', + ['gadget_parachute'] = 'laskuvarjo', + ['weapon_flare'] = 'hätäraketti', + ['weapon_snspistol_mk2'] = 'konepistooli Mk II', + ['weapon_revolver_mk2'] = 'raskas revolveri Mk II', + ['weapon_doubleaction'] = 'kaksitoiminen Revolveri', + ['weapon_specialcarabine_mk2'] = 'G86C Mk II', + ['weapon_bullpruprifle_mk2'] = 'Bullpup Kivääri Mk II', + ['weapon_pumpshotgun_mk2'] = 'Pumppuhaulikko Mk II', + ['weapon_marksmanrifle_mk2'] = 'Marksman Kivääri Mk II', + ['weapon_assaultrifle_mk2'] = 'Rynnäkkökivääri Mk II ', + ['weapon_carbinerifle_mk2'] = 'Karbiini Kivääri Mk II ', + ['weapon_combatmg_mk2'] = 'Rynnäkkökonekivääri Mk II', + ['weapon_heavysniper_mk2'] = 'Raskas Tarkkuuskivääri Mk II', + ['weapon_pistol_mk2'] = 'Pistooli Mk II', + ['weapon_smg_mk2'] = 'Konepistooli Mk II', +} \ No newline at end of file From 6eb077461e53a99944be30f6925c483cccad551b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 16 Jun 2018 10:17:05 +0200 Subject: [PATCH 204/672] Minor cleanup --- __resource.lua | 1 - html/css/app.css | 6 ------ html/img/cursor.png | Bin 272 -> 0 bytes html/ui.html | 2 -- locale.lua | 4 ++-- 5 files changed, 2 insertions(+), 11 deletions(-) delete mode 100644 html/img/cursor.png diff --git a/__resource.lua b/__resource.lua index 0f5d29ff..38e4e40d 100644 --- a/__resource.lua +++ b/__resource.lua @@ -55,7 +55,6 @@ files { 'html/fonts/pdown.ttf', 'html/fonts/bankgothic.ttf', - 'html/img/cursor.png', 'html/img/keys/enter.png', 'html/img/keys/return.png', diff --git a/html/css/app.css b/html/css/app.css index 2f72814b..6fff380f 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -12,12 +12,6 @@ html { overflow: hidden; } -#cursor { - position: absolute; - z-index: 999999; - display: none; -} - #hud { position : absolute; font-family: 'Pricedown'; diff --git a/html/img/cursor.png b/html/img/cursor.png deleted file mode 100644 index 39536f953d701b36a90dc56084bafd988371a2fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 272 zcmeAS@N?(olHy`uVBq!ia0vp^q9Dw{1|(OCFP#RYSkfJR9T^xl_H+M9WCij$3p^r= z85sBufiR<}hF1enP_o1|q9iy!t)x7$D3zfgF*C13FE6!3!9>qM&(L5k7uNxxqFzrI z#}Etut!FreS`>I(0^ikVp5f1PInc0ibrsXWO3z8Ee_BE>W<&%Ean9H1Y|@_Ma)5tI zP3vrppG@U}o4EJ`H!a-_TKCSz%v`zHX&3lrYRgJzbSuAt9 z@6PvoS_%Jm+&BGp_A+yZ?Fo&SwU@JtJ?kA`YTb#E`^&mC!8qZZWp1Mjt5em&H79@$ OWAJqKb6Mw<&;$S!<6)ox diff --git a/html/ui.html b/html/ui.html index cb51f0b3..653f41d8 100644 --- a/html/ui.html +++ b/html/ui.html @@ -7,10 +7,8 @@
- - \ No newline at end of file diff --git a/locale.lua b/locale.lua index 208cf827..a116cec4 100644 --- a/locale.lua +++ b/locale.lua @@ -7,11 +7,11 @@ function _(str, ...) -- Translate string if Locales[Config.Locale][str] ~= nil then return string.format(Locales[Config.Locale][str], ...) else - return 'Translation [' .. Config.Locale .. '][' .. str .. '] does not exists' + return 'Translation [' .. Config.Locale .. '][' .. str .. '] does not exist' end else - return 'Locale [' .. Config.Locale .. '] does not exists' + return 'Locale [' .. Config.Locale .. '] does not exist' end end From 93d226300350840347117d4055eb8592de79a918 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 16 Jun 2018 10:24:02 +0200 Subject: [PATCH 205/672] Proper string formatting --- client/functions.lua | 2 +- locales/br.lua | 2 +- locales/de.lua | 2 +- locales/en.lua | 2 +- locales/fi.lua | 2 +- locales/fr.lua | 2 +- locales/sv.lua | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 6fc8d6df..4dbd7750 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1084,7 +1084,7 @@ ESX.ShowInventory = function() if ESX.PlayerData.money > 0 then table.insert(elements, { - label = _U('cash') .. ESX.PlayerData.money, + label = _U('cash', ESX.PlayerData.money), count = ESX.PlayerData.money, type = 'item_money', value = 'money', diff --git a/locales/br.lua b/locales/br.lua index 16442c00..1c4ea005 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,5 +1,5 @@ Locales['br'] = { - ['cash'] = 'efectivo $ ', + ['cash'] = 'efectivo $%s', ['inventory'] = 'inventario', ['use'] = 'usar', ['give'] = 'dar', diff --git a/locales/de.lua b/locales/de.lua index 02a0e6b3..566e780f 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,5 +1,5 @@ Locales['de'] = { - ['cash'] = 'kontanter $ ', + ['cash'] = 'kontanter $%s', ['inventory'] = 'Inventar', ['use'] = 'benutzen', ['give'] = 'geben', diff --git a/locales/en.lua b/locales/en.lua index 0d272a17..36a62551 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,5 +1,5 @@ Locales['en'] = { - ['cash'] = 'cash $ ', + ['cash'] = 'cash $%s', ['inventory'] = 'inventory', ['use'] = 'use', ['give'] = 'give', diff --git a/locales/fi.lua b/locales/fi.lua index 13efb83c..2c5d6cf3 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,5 +1,5 @@ Locales['fi'] = { - ['cash'] = 'käteinen $ ', + ['cash'] = 'käteinen $%s', ['inventory'] = 'reppu', ['use'] = 'käytä', ['give'] = 'anna', diff --git a/locales/fr.lua b/locales/fr.lua index ce3b109a..165eafe3 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,5 +1,5 @@ Locales['fr'] = { - ['cash'] = 'espèces $ ', + ['cash'] = 'espèces $%s', ['inventory'] = 'inventaire', ['use'] = 'utiliser', ['give'] = 'donner', diff --git a/locales/sv.lua b/locales/sv.lua index f4b2c666..dc33495e 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,5 +1,5 @@ Locales['sv'] = { - ['cash'] = 'kontanter $ ', + ['cash'] = 'kontanter $%s', ['inventory'] = 'Mitt förråd', ['use'] = 'använd', ['give'] = 'ge', From 74d27e4d807df57c32ce9145ec659d2c48422258 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 16 Jun 2018 10:31:01 +0200 Subject: [PATCH 206/672] Manual revert: buggy networked vehicle It broke prop spawning so it's gone. --- __resource.lua | 2 +- client/functions.lua | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/__resource.lua b/__resource.lua index efea945d..7bfb5a51 100644 --- a/__resource.lua +++ b/__resource.lua @@ -1,4 +1,4 @@ -resource_manifest_version '05cfa83c-a124-4cfa-a768-c24a5811d8f9' +resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' diff --git a/client/functions.lua b/client/functions.lua index 4dbd7750..1e373b01 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -397,7 +397,8 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) local id = NetworkGetNetworkIdFromEntity(vehicle) SetNetworkIdCanMigrate(id, true) - SetVehicleHasBeenOwnedByPlayer(vehicle, true) + SetEntityAsMissionEntity(vehicle, true, false) + SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) RequestCollisionAtCoord(coords.x, coords.y, coords.z) @@ -431,7 +432,8 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) - SetVehicleHasBeenOwnedByPlayer(vehicle, true) + SetEntityAsMissionEntity(vehicle, true, false) + SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetModelAsNoLongerNeeded(model) RequestCollisionAtCoord(coords.x, coords.y, coords.z) From a738a82970e9758d664f8e6613b54b2d16077656 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 16 Jun 2018 10:38:07 +0200 Subject: [PATCH 207/672] Implemented Config.EnableSocietyPayouts --- config.lua | 1 + server/paycheck.lua | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/config.lua b/config.lua index 1a1f6a36..6113efcb 100644 --- a/config.lua +++ b/config.lua @@ -4,6 +4,7 @@ Config.Locale = 'fr' Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } +Config.EnableSocietyPayouts = false -- pay from the society account that the plyayers are employeed at instead of plain giving money. Requirement: esx_society Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.EnableWeaponPickup = true diff --git a/server/paycheck.lua b/server/paycheck.lua index f7551baf..f9af867a 100644 --- a/server/paycheck.lua +++ b/server/paycheck.lua @@ -12,10 +12,7 @@ ESX.StartPayCheck = function() if job == 'unemployed' then -- unemployed xPlayer.addAccountMoney('bank', salary) TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_help', salary), 'CHAR_BANK_MAZE', 9) - elseif job == 'employee' then -- generic job, not a society - xPlayer.addAccountMoney('bank', salary) - TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_salary', salary), 'CHAR_BANK_MAZE', 9) - else -- possibly a society + elseif Config.EnableSocietyPayouts then -- possibly a society TriggerEvent('esx_society:getSociety', xPlayer.job.name, function (society) if society ~= nil then -- verified society TriggerEvent('esx_addonaccount:getSharedAccount', society.account, function (account) @@ -28,11 +25,14 @@ ESX.StartPayCheck = function() TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), '', _U('company_nomoney'), 'CHAR_BANK_MAZE', 1) end end) - else -- not a society, use 'employee' as grade name! + else -- not a society xPlayer.addAccountMoney('bank', salary) TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_salary', salary), 'CHAR_BANK_MAZE', 9) end end) + else -- generic job + xPlayer.addAccountMoney('bank', salary) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_salary', salary), 'CHAR_BANK_MAZE', 9) end end From 5bf8dc2b80d99410c18322bfe7571116e8c18332 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 19 Jun 2018 21:52:38 +0200 Subject: [PATCH 208/672] Major locale formatting improvements --- locales/br.lua | 33 ++++++++++++++++++--------------- locales/de.lua | 41 ++++++++++++++++++++++------------------- locales/en.lua | 27 +++++++++++++++------------ locales/fi.lua | 39 +++++++++++++++++++++------------------ locales/fr.lua | 33 ++++++++++++++++++--------------- locales/sv.lua | 29 ++++++++++++++++------------- server/main.lua | 32 ++++++++++++++++---------------- server/paycheck.lua | 8 ++++---- 8 files changed, 130 insertions(+), 112 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 1c4ea005..5b5231c3 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,4 +1,5 @@ Locales['br'] = { + -- Inventory ['cash'] = 'efectivo $%s', ['inventory'] = 'inventario', ['use'] = 'usar', @@ -6,36 +7,38 @@ Locales['br'] = { ['remove'] = 'remover', ['return'] = 'voltar', ['amount'] = 'quantidade', + ['giveammo'] = 'Dar muniçao', ['amountammo'] = 'quantidade de muniçao', ['noammo'] = 'voce nao tem todas essas muniçoes!', - ['threw_weapon'] = 'voce ~r~atirou~s~ ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas!', + ['gave_item'] = 'voce deu ~y~%sx~s~ ~b~%s~s~ para ~y~%s~s~', + ['received_item'] = 'voce recebeu ~y~%sx~s~ ~b~%s~s~ de ~b~%s~s~', ['gave_weapon'] = 'voce deu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas para ~y~%s~s~.', - ['recived_weapon'] = 'voce recebeu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~.', + ['received_weapon'] = 'voce recebeu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~.', ['gave_ammo'] = 'voce deu ~o~%sx~s~ balas para ~y~%s~s~.', - ['recived_ammo'] = 'voce recebeu ~o~%sx~s~ balas de ~b~%s~s~.', - ['giveammo'] = 'Dar muniçao', + ['received_ammo'] = 'voce recebeu ~o~%sx~s~ balas de ~b~%s~s~.', + ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', + ['received_money'] = 'voce recebeu ~g~$%s~s~ de ~b~%s~s~', + ['gave_account_money'] = 'voce deu ~g~$%s~s~ (%s) para ~y~%s~s~', + ['received_account_money'] = 'voce recebeu ~g~$%s~s~ (%s) de ~b~%s~s~', ['amount_invalid'] = 'quantidade invalida', ['players_nearby'] = 'nenhum jogador por perto', - ['ex_inv_lim'] = 'acao nao e possivel, excedendo o limite de estoque para ~b~', - ['yougave'] = 'voce deu', - ['youreceived'] = 'voce recebeu', - ['to'] = '~s~ para ~b~', - ['by'] = '~s~ de ~b~', + ['ex_inv_lim'] = 'acao nao e possivel, excedendo o limite de estoque para ~y~%s~s~', ['imp_invalid_quantity'] = 'acao impossivel, quantidade invalida', ['imp_invalid_amount'] = 'acao impossivel, valor invalido', ['delete_five_min'] = '~r~excluir~s~ em 5 minutos', ['threw'] = 'voce ~r~jogou~s~', - -- Relacionado com salario - ['recived_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', - ['recived_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', + ['threw_weapon'] = 'voce ~r~atirou~s~ ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas!', + -- Salary related + ['received_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', + ['received_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salario.', - ['recived_money'] = 'recebeu dinheiro', + ['received_money'] = 'recebeu dinheiro', ['bank'] = 'banco', ['black_money'] = 'dinheiro sujo', ['act_imp'] = 'acao impossivel', ['in_vehicle'] = 'voce nao pode dar nada para alguem no veiculo', ['cannot_pickup_room'] = 'voce nao tem espaço suficiente no seu inventario para pegar ~y~%s~s~!', - -- Comandos + -- Commands ['setjob'] = 'atribuir um trabalho a um usuario', ['id_param'] = 'o ID do jogador', ['setjob_param2'] = 'o trabalho que voce deseja atribuir', @@ -61,7 +64,7 @@ Locales['br'] = { ['giveitem'] = 'dar item', ['weapon'] = 'arma', ['giveweapon'] = 'dar arma', - -- Armas + -- Weapons ['weapon_knife'] = 'faca', ['weapon_nightstick'] = 'cacetete', ['weapon_hammer'] = 'martelo', diff --git a/locales/de.lua b/locales/de.lua index 566e780f..97353c84 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,35 +1,38 @@ Locales['de'] = { + -- Inventory ['cash'] = 'kontanter $%s', - ['inventory'] = 'Inventar', + ['inventory'] = 'inventar', ['use'] = 'benutzen', ['give'] = 'geben', ['remove'] = 'entfernen', ['return'] = 'zurück', ['amount'] = 'Betrag', - ['amountammo'] = 'anzahl der Munition', - ['noammo'] = 'du hast keine Munition!', - ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', + ['giveammo'] = 'munition geben', + ['amountammo'] = 'anzahl der munition', + ['noammo'] = 'du hast keine munition!', + ['gave_item'] = 'du gibst ~y~%sx~s~ ~b~%s~s~ zu ~y~%s~s~', + ['received_item'] = 'to empfängst ~y~%sx~s~ ~b~%s~s~ von ~b~%s~s~', ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', - ['recived_weapon'] = 'you recived ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', - ['recived_ammo'] = 'you recived ~o~%sx~s~ bullets from ~b~%s~s~.', - ['giveammo'] = 'Munition geben', + ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_money'] = 'du gibst ~g~$%s~s~ zu ~y~%s~s~', + ['received_money'] = 'to empfängst ~g~$%s~s~ von ~b~%s~s~', + ['gave_account_money'] = 'du gibst ~g~$%s~s~ (%s) zu ~y~%s~s~', + ['received_account_money'] = 'to empfängst ~g~$%s~s~ (%s) von ~b~%s~s~', ['amount_invalid'] = 'ungültiger Betrag', - ['players_nearby'] = 'keine Spieler in der Nähe', - ['ex_inv_lim'] = 'Aktion nicht möglich, inventarlimit überschritten für ~b~', - ['yougave'] = 'du gibst', - ['youreceived'] = 'to empfängst', - ['to'] = '~s~ zu ~b~', - ['by'] = '~s~ von ~b~', - ['imp_invalid_quantity'] = 'Aktion nicht möglich, ungültige Anzahl', - ['imp_invalid_amount'] = 'Aktion nicht möglich, ungültiger Betrag', - ['delete_five_min'] = '~r~löschen~s~ in 5 Minuten', + ['players_nearby'] = 'keine Spieler in der nähe', + ['ex_inv_lim'] = 'aktion nicht möglich, inventarlimit überschritten für ~y~%s~s~', + ['imp_invalid_quantity'] = 'aktion nicht möglich, ungültige anzahl', + ['imp_invalid_amount'] = 'aktion nicht möglich, ungültiger betrag', + ['delete_five_min'] = '~r~Löschen~s~ in 5 minuten~s~', ['threw'] = 'du ~r~wirfst weg~s~', + ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', -- Salary related - ['recived_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', - ['recived_help'] = 'you recieved your welfare check: ~g~$%s~s~', + ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', + ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary.', - ['recived_money'] = 'recived money', + ['received_money'] = 'received money', ['bank'] = 'bank', ['black_money'] = 'dirty Money', diff --git a/locales/en.lua b/locales/en.lua index 36a62551..4dee4a57 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,4 +1,5 @@ Locales['en'] = { + -- Inventory ['cash'] = 'cash $%s', ['inventory'] = 'inventory', ['use'] = 'use', @@ -6,30 +7,32 @@ Locales['en'] = { ['remove'] = 'remove', ['return'] = 'return', ['amount'] = 'amount', + ['giveammo'] = 'give ammo', ['amountammo'] = 'amount of ammo', ['noammo'] = 'you do not have enough ammo!', - ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', + ['gave_item'] = 'you gave ~y~%sx~s~ ~b~%s~s~ to ~y~%s~s~', + ['received_item'] = 'you received ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~', ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', - ['recived_weapon'] = 'you recived ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', - ['recived_ammo'] = 'you recived ~o~%sx~s~ bullets from ~b~%s~s~.', - ['giveammo'] = 'give ammo', + ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_money'] = 'you gave ~g~$%s~s~ to ~y~%s~s~', + ['received_money'] = 'you received ~g~$%s~s~ from ~b~%s~s~', + ['gave_account_money'] = 'you gave ~g~$%s~s~ (%s) to ~y~%s~s~', + ['received_account_money'] = 'you received ~g~$%s~s~ (%s) from ~b~%s~s~', ['amount_invalid'] = 'invalid amount', ['players_nearby'] = 'no players nearby', - ['ex_inv_lim'] = 'action not possible, exceeding inventory limit for ~b~', - ['yougave'] = 'you gave', - ['youreceived'] = 'you received', - ['to'] = '~s~ to ~b~', - ['by'] = '~s~ by ~b~', + ['ex_inv_lim'] = 'action not possible, exceeding inventory limit for ~y~%s~s~', ['imp_invalid_quantity'] = 'action impossible, invalid quantity', ['imp_invalid_amount'] = 'action impossible, invalid amount', ['delete_five_min'] = 'the item will be ~r~thrown~s~ in 5 minutes', ['threw'] = 'you ~r~threw~s~', + ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', -- Salary related - ['recived_salary'] = 'you received your salary: ~g~$%s~s~', - ['recived_help'] = 'you recieved your welfare check: ~g~$%s~s~', + ['received_salary'] = 'you received your salary: ~g~$%s~s~', + ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary.', - ['recived_money'] = 'recived money', + ['received_money'] = 'received money', ['bank'] = 'bank', ['black_money'] = 'dirty Money', diff --git a/locales/fi.lua b/locales/fi.lua index 2c5d6cf3..9c2cece9 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,35 +1,38 @@ Locales['fi'] = { - ['cash'] = 'käteinen $%s', - ['inventory'] = 'reppu', - ['use'] = 'käytä', - ['give'] = 'anna', - ['remove'] = 'poista', - ['return'] = 'takaisin', + -- Inventory + ['cash'] = 'käteinen $%s', + ['inventory'] = 'reppu', + ['use'] = 'käytä', + ['give'] = 'anna', + ['remove'] = 'poista', + ['return'] = 'takaisin', ['amount'] = 'määrä', + ['giveammo'] = 'anna ammuksia', ['amountammo'] = 'ammusten määrä', ['noammo'] = 'sinulla ei ole ammuksia!', - ['threw_weapon'] = 'sinä ~r~heitit~s~ ~y~1x~s~ ~b~%s~s~ jossa oli ~o~%sx~s~ ammuksia!', + ['gave_item'] = 'sinä annoit ~y~%sx~s~ ~b~%s~s~ henkilölle ~y~%s~s~', + ['received_item'] = 'sinä sait ~y~%sx~s~ ~b~%s~s~ henkilöltä ~b~%s~s~', ['gave_weapon'] = 'sinä annoit ~y~1x~s~ ~b~%s~s~ jossa oli ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~.', - ['recived_weapon'] = 'sinä sait ~y~1x~s~ ~b~%s~s~ jossa oli ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~.', + ['received_weapon'] = 'sinä sait ~y~1x~s~ ~b~%s~s~ jossa oli ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~.', ['gave_ammo'] = 'sinä annoit ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~.', - ['recived_ammo'] = 'sinä sait ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~.', - ['giveammo'] = 'anna ammuksia', + ['received_ammo'] = 'sinä sait ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~.', + ['gave_money'] = 'sinä annoit ~g~$%s~s~ henkilölle ~y~%s~s~', + ['received_money'] = 'sinä sait ~g~$%s~s~ henkilöltä ~b~%s~s~', + ['gave_account_money'] = 'sinä annoit ~g~$%s~s~ (%s) henkilölle ~y~%s~s~', + ['received_account_money'] = 'sinä sait ~g~$%s~s~ (%s) henkilöltä ~b~%s~s~', ['amount_invalid'] = 'virheellinen määrä', ['players_nearby'] = 'ei pelaajia lähettyvillä', - ['ex_inv_lim'] = 'toiminto mahdoton, reppu alkaa olla täysi ~b~', - ['yougave'] = 'sinä annoit', - ['youreceived'] = 'sinä sait', - ['to'] = '~s~ henkilölle ~b~', - ['by'] = '~s~ henkilöltä ~b~', + ['ex_inv_lim'] = 'toiminto mahdoton, reppu alkaa olla täysi ~y~%s~s~', ['imp_invalid_quantity'] = 'toiminto mahdoton, virheellinen määrä', ['imp_invalid_amount'] = 'toiminto mahdoton, virhellinen summa', ['delete_five_min'] = 'esine ~r~poistetaan~s~ 5 minuutin päästä repusta', ['threw'] = 'sinä ~r~tiputit~s~', + ['threw_weapon'] = 'sinä ~r~heitit~s~ ~y~1x~s~ ~b~%s~s~ jossa oli ~o~%sx~s~ ammuksia!', -- Salary related - ['recived_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', - ['recived_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', + ['received_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', + ['received_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', ['company_nomoney'] = 'yritys jolle teet töitä on köyhä eikä voi maksaa palkkaasi.', - ['recived_money'] = 'sai rahaa', + ['received_money'] = 'sai rahaa', ['bank'] = 'Pankki', ['black_money'] = 'likainen Raha', diff --git a/locales/fr.lua b/locales/fr.lua index 165eafe3..9e72101c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,4 +1,5 @@ Locales['fr'] = { + -- Inventory ['cash'] = 'espèces $%s', ['inventory'] = 'inventaire', ['use'] = 'utiliser', @@ -6,30 +7,32 @@ Locales['fr'] = { ['remove'] = 'jeter', ['return'] = 'retour', ['amount'] = 'quantité', - ['amountammo'] = 'nombre de munitions', - ['noammo'] = 'Tu n\'as pas toutes ces munitions !', - ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', - ['recived_weapon'] = 'you recived ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', - ['recived_ammo'] = 'you recived ~o~%sx~s~ bullets from ~b~%s~s~.', ['giveammo'] = 'give ammo', + ['amountammo'] = 'nombre de munitions', + ['noammo'] = 'tu n\'as pas toutes ces munitions!', + ['gave_item'] = 'vous avez donné ~y~%sx~s~ ~b~%s~s~ à ~y~%s~s~', + ['received_item'] = 'vous avez reçu ~y~%sx~s~ ~b~%s~s~ par ~b~%s~s~', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', + ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', + ['received_money'] = 'vous avez reçu ~g~$%s~s~ par ~b~%s~s~', + ['gave_account_money'] = 'vous avez donné ~g~$%s~s~ (%s) à ~y~%s~s~', + ['received_account_money'] = 'vous avez reçu ~g~$%s~s~ (%s) par ~b~%s~s~', ['amount_invalid'] = 'montant invalide', ['players_nearby'] = 'aucun joueur à proximité', - ['ex_inv_lim'] = 'action impossible, depassement de la limite d\'inventaire pour ~b~', - ['yougave'] = 'vous avez donné', - ['youreceived'] = 'vous avez reçu', - ['to'] = '~s~ à ~b~', - ['by'] = '~s~ par ~b~', + ['ex_inv_lim'] = 'action impossible, depassement de la limite d\'inventaire pour ~y~%s~s~', ['imp_invalid_quantity'] = 'action impossible, ~r~quantité invalide', ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', ['delete_five_min'] = '~r~suppression~s~ dans 5 minutes', ['threw'] = 'vous avez ~r~jeté~s~', + ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', -- Salary related - ['recived_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', - ['recived_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', + ['received_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', + ['received_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', ['company_nomoney'] = 'votre entreprise n\'a plus d\'argent pour vous payer!', -- fix translation - ['recived_money'] = 'recived money', + ['received_money'] = 'received money', ['bank'] = 'banque', ['black_money'] = 'argent Sale', diff --git a/locales/sv.lua b/locales/sv.lua index dc33495e..b1745f85 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,35 +1,38 @@ Locales['sv'] = { + -- Inventory ['cash'] = 'kontanter $%s', - ['inventory'] = 'Mitt förråd', + ['inventory'] = 'mitt förråd', ['use'] = 'använd', ['give'] = 'ge', ['remove'] = 'kasta', ['return'] = 'gå tillbaka', ['amount'] = 'antal', + ['giveammo'] = 'ge ammunition', ['amountammo'] = 'mängd ammunition', ['noammo'] = 'du har inte tillräckligt med ammunition!', - ['threw_weapon'] = 'du ~r~slängde~s~ ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott!', + ['gave_item'] = 'du gav ~y~%sx~s~ ~b~%s~s~ till ~y~%s~s~', + ['received_item'] = 'du tog emot ~y~%sx~s~ ~b~%s~s~ från ~b~%s~s~', ['gave_weapon'] = 'du gav ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~.', - ['recived_weapon'] = 'du tog emot ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~.', + ['received_weapon'] = 'du tog emot ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~.', ['gave_ammo'] = 'du gav ~o~%sx~s~ skott till ~y~%s~s~.', - ['recived_ammo'] = 'du tog emot ~o~%sx~s~ skott från ~b~%s~s~.', - ['giveammo'] = 'Ge ammunition', + ['received_ammo'] = 'du tog emot ~o~%sx~s~ skott från ~b~%s~s~.', + ['gave_money'] = 'du gav ~g~$%s~s~ till ~y~%s~s~', + ['received_money'] = 'du tog emot ~g~$%s~s~ från ~b~%s~s~', + ['gave_account_money'] = 'du gav ~g~$%s~s~ (%s) till ~y~%s~s~', + ['received_account_money'] = 'du tog emot ~g~$%s~s~ (%s) från ~b~%s~s~', ['amount_invalid'] = 'ogiltig mängd', ['players_nearby'] = 'inga spelare nära', - ['ex_inv_lim'] = 'åtgärd inte möjligt, översteg förrådets gräns ~b~', - ['yougave'] = 'du gav', - ['youreceived'] = 'du fick', - ['to'] = '~s~ till ~b~', - ['by'] = '~s~ av ~b~', + ['ex_inv_lim'] = 'åtgärd inte möjligt, översteg förråd gräns för ~y~%s~s~', ['imp_invalid_quantity'] = 'åtgärd omöjlig, ogiltig mängd', ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', ['delete_five_min'] = 'objektet kommer att ~r~kastas~s~ om 5 minuter!', ['threw'] = 'du ~r~kastade~s~', + ['threw_weapon'] = 'du ~r~slängde~s~ ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott!', -- Salary related - ['recived_salary'] = 'du har mottagit din lön på ~g~$%s~s~', - ['recived_help'] = 'du har mottagit bidrag på ~g~$%s~s~', + ['received_salary'] = 'du har mottagit din lön på ~g~$%s~s~', + ['received_help'] = 'du har mottagit bidrag på ~g~$%s~s~', ['company_nomoney'] = 'företaget du är anställt hos har inte råd att betala ut din lön.', - ['recived_money'] = 'mottagit pengar', + ['received_money'] = 'mottagit pengar', ['bank'] = 'bank', ['black_money'] = 'svarta pengar', diff --git a/server/main.lua b/server/main.lua index 73e1fefd..81c88fb6 100644 --- a/server/main.lua +++ b/server/main.lua @@ -277,14 +277,14 @@ AddEventHandler('es:playerLoaded', function(source, _player) end) -AddEventHandler('playerDropped', function() +AddEventHandler('playerDropped', function(reason) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) if xPlayer ~= nil then - TriggerEvent('esx:playerDropped', _source) + TriggerEvent('esx:playerDropped', _source, reason) ESX.SavePlayer(xPlayer, function() ESX.Players[_source] = nil @@ -324,17 +324,17 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if itemCount > 0 and sourceItem.count >= itemCount then if targetItem.limit ~= -1 and (targetItem.count + itemCount) > targetItem.limit then - TriggerClientEvent('esx:showNotification', target, _U('ex_inv_lim') .. targetXPlayer.name) + TriggerClientEvent('esx:showNotification', _source, _U('ex_inv_lim', targetXPlayer.name)) else sourceXPlayer.removeInventoryItem(itemName, itemCount) targetXPlayer.addInventoryItem (itemName, itemCount) - - TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. _U('to') .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' ~g~x' .. itemCount .. ' ' .. ESX.Items[itemName].label .. _U('by') .. sourceXPlayer.name) + + TriggerClientEvent('esx:showNotification', _source, _U('gave_item', itemCount, ESX.Items[itemName].label, targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_item', itemCount, ESX.Items[itemName].label, sourceXPlayer.name)) end else - TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_quantity')) + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) end elseif type == 'item_money' then @@ -342,13 +342,13 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if itemCount > 0 and sourceXPlayer.player.get('money') >= itemCount then sourceXPlayer.removeMoney(itemCount) - targetXPlayer.addMoney(itemCount) + targetXPlayer.addMoney (itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' ~g~$' .. itemCount .. _U('to') .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' ~g~$' .. itemCount .. _U('by') .. sourceXPlayer.name) + TriggerClientEvent('esx:showNotification', _source, _U('gave_money', itemCount, targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_money', itemCount, sourceXPlayer.name)) else - TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_amount')) + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) end elseif type == 'item_account' then @@ -356,13 +356,13 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then sourceXPlayer.removeAccountMoney(itemName, itemCount) - targetXPlayer.addAccountMoney(itemName, itemCount) + targetXPlayer.addAccountMoney (itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('yougave') .. ' [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. _U('to') .. targetXPlayer.name) - TriggerClientEvent('esx:showNotification', target, _U('youreceived') .. ' [' .. Config.AccountLabels[itemName] .. '] ~g~$' .. itemCount .. _U('by') .. sourceXPlayer.name) + TriggerClientEvent('esx:showNotification', _source, _U('gave_account_money', itemCount, Config.AccountLabels[itemName], targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_account_money', itemCount, Config.AccountLabels[itemName], sourceXPlayer.name)) else - TriggerClientEvent('esx:showNotification', target, _U('imp_invalid_amount')) + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) end elseif type == 'item_weapon' then @@ -372,7 +372,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo local weaponLabel = ESX.GetWeaponLabel(itemName) TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, itemCount, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('recived_weapon', weaponLabel, itemCount, sourceXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_weapon', weaponLabel, itemCount, sourceXPlayer.name)) end end) diff --git a/server/paycheck.lua b/server/paycheck.lua index f9af867a..df3cff43 100644 --- a/server/paycheck.lua +++ b/server/paycheck.lua @@ -11,7 +11,7 @@ ESX.StartPayCheck = function() if salary > 0 then if job == 'unemployed' then -- unemployed xPlayer.addAccountMoney('bank', salary) - TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_help', salary), 'CHAR_BANK_MAZE', 9) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_money'), _U('received_help', salary), 'CHAR_BANK_MAZE', 9) elseif Config.EnableSocietyPayouts then -- possibly a society TriggerEvent('esx_society:getSociety', xPlayer.job.name, function (society) if society ~= nil then -- verified society @@ -20,19 +20,19 @@ ESX.StartPayCheck = function() xPlayer.addAccountMoney('bank', salary) account.removeMoney(salary) - TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_salary', salary), 'CHAR_BANK_MAZE', 9) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_money'), _U('received_salary', salary), 'CHAR_BANK_MAZE', 9) else TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), '', _U('company_nomoney'), 'CHAR_BANK_MAZE', 1) end end) else -- not a society xPlayer.addAccountMoney('bank', salary) - TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_salary', salary), 'CHAR_BANK_MAZE', 9) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_money'), _U('received_salary', salary), 'CHAR_BANK_MAZE', 9) end end) else -- generic job xPlayer.addAccountMoney('bank', salary) - TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('recived_money'), _U('recived_salary', salary), 'CHAR_BANK_MAZE', 9) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_money'), _U('received_salary', salary), 'CHAR_BANK_MAZE', 9) end end From 3de26d020b989ed05dfece6239254764dc29c21c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 22 Jun 2018 22:25:34 +0200 Subject: [PATCH 209/672] Improved ammo handling --- client/functions.lua | 77 ++++++++++++++++++++------------------- client/main.lua | 25 ++++++++----- locales/en.lua | 2 +- locales/sv.lua | 10 ++--- server/classes/player.lua | 8 ++-- 5 files changed, 65 insertions(+), 57 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 1e373b01..04c2ce82 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -303,10 +303,11 @@ ESX.GetWeaponLabel = function(name) end ESX.Game.GetPedMugshot = function(ped) - mugshot = RegisterPedheadshot(ped) + local mugshot = RegisterPedheadshot(ped) while not IsPedheadshotReady(mugshot) do - Wait(0) + Citizen.Wait(0) end + return mugshot, GetPedheadshotTxdString(mugshot) end @@ -745,55 +746,55 @@ ESX.Game.GetVehicleProperties = function(vehicle) neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(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), + 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), + 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), - modSmokeEnabled = IsToggleModOn(vehicle, 20), - modXenon = IsToggleModOn(vehicle, 22), + modTurbo = IsToggleModOn(vehicle, 18), + modSmokeEnabled = IsToggleModOn(vehicle, 20), + modXenon = IsToggleModOn(vehicle, 22), - modFrontWheels = GetVehicleMod(vehicle, 23), - modBackWheels = GetVehicleMod(vehicle, 24), + modFrontWheels = GetVehicleMod(vehicle, 23), + modBackWheels = GetVehicleMod(vehicle, 24), modPlateHolder = GetVehicleMod(vehicle, 25), modVanityPlate = GetVehicleMod(vehicle, 26), - modTrimA = GetVehicleMod(vehicle, 27), + modTrimA = GetVehicleMod(vehicle, 27), modOrnaments = GetVehicleMod(vehicle, 28), modDashboard = GetVehicleMod(vehicle, 29), - modDial = GetVehicleMod(vehicle, 30), - modDoorSpeaker = GetVehicleMod(vehicle, 31), - modSeats = GetVehicleMod(vehicle, 32), - modSteeringWheel = GetVehicleMod(vehicle, 33), - modShifterLeavers = GetVehicleMod(vehicle, 34), - modAPlate = GetVehicleMod(vehicle, 35), + modDial = GetVehicleMod(vehicle, 30), + modDoorSpeaker = GetVehicleMod(vehicle, 31), + modSeats = GetVehicleMod(vehicle, 32), + modSteeringWheel = GetVehicleMod(vehicle, 33), + modShifterLeavers = GetVehicleMod(vehicle, 34), + modAPlate = GetVehicleMod(vehicle, 35), modSpeakers = GetVehicleMod(vehicle, 36), - modTrunk = GetVehicleMod(vehicle, 37), + modTrunk = GetVehicleMod(vehicle, 37), modHydrolic = GetVehicleMod(vehicle, 38), - modEngineBlock = GetVehicleMod(vehicle, 39), + modEngineBlock = GetVehicleMod(vehicle, 39), modAirFilter = GetVehicleMod(vehicle, 40), - modStruts = GetVehicleMod(vehicle, 41), + modStruts = GetVehicleMod(vehicle, 41), modArchCover = GetVehicleMod(vehicle, 42), modAerials = GetVehicleMod(vehicle, 43), - modTrimB = GetVehicleMod(vehicle, 44), - modTank = GetVehicleMod(vehicle, 45), + modTrimB = GetVehicleMod(vehicle, 44), + modTank = GetVehicleMod(vehicle, 45), modWindows = GetVehicleMod(vehicle, 46), - modLivery = GetVehicleMod(vehicle, 48) + modLivery = GetVehicleMod(vehicle, 48) } end @@ -1353,7 +1354,7 @@ ESX.ShowInventory = function() SetPedAmmo(playerPed, item, finalAmmoSource) AddAmmoToPed(closestPed, item, quantity) ESX.ShowNotification(_U('gave_ammo', quantity, GetPlayerName(closestPlayer))) - -- todo notify target that he recived ammo + -- todo notify target that he received ammo menu2.close() menu.close() else diff --git a/client/main.lua b/client/main.lua index 53e5bab7..56036754 100644 --- a/client/main.lua +++ b/client/main.lua @@ -173,20 +173,27 @@ end) RegisterNetEvent('esx:addWeapon') AddEventHandler('esx:addWeapon', function(weaponName, ammo) - local playerPed = GetPlayerPed(-1) - local weaponHash = GetHashKey(weaponName) + local playerPed = GetPlayerPed(-1) + local weaponHash = GetHashKey(weaponName) - GiveWeaponToPed(playerPed, weaponHash, ammo, false, false) - SetPedAmmo(playerPed, weaponHash, ammo) -- remove leftover ammo + GiveWeaponToPed(playerPed, weaponHash, ammo, false, false) + --AddAmmoToPed(playerPed, weaponHash, ammo) possibly not needed end) RegisterNetEvent('esx:removeWeapon') -AddEventHandler('esx:removeWeapon', function(weaponName) - local playerPed = GetPlayerPed(-1) - local weaponHash = GetHashKey(weaponName) +AddEventHandler('esx:removeWeapon', function(weaponName, ammo) + local playerPed = GetPlayerPed(-1) + local weaponHash = GetHashKey(weaponName) - RemoveWeaponFromPed(playerPed, weaponHash) - SetPedAmmo(playerPed, weaponHash, 0) -- remove leftover ammo + 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) -- Commands diff --git a/locales/en.lua b/locales/en.lua index 4dee4a57..7005a206 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -148,7 +148,7 @@ Locales['en'] = { ['weapon_flashlight'] = 'flashlight', ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', - ['weapon_flare'] = 'Fusée Détresse', + ['weapon_flare'] = 'flare gun', ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', ['weapon_doubleaction'] = 'Double-Action Revolver', diff --git a/locales/sv.lua b/locales/sv.lua index b1745f85..53f00495 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -48,13 +48,13 @@ Locales['sv'] = { ['unload_ipl'] = 'unload IPL', ['play_anim'] = 'spela animering', ['play_emote'] = 'spela emote', - ['spawn_car'] = 'spawna en bil', - ['spawn_car_param'] = 'namn på bil', - ['delete_vehicle'] = 'ta bort Fordon', + ['spawn_car'] = 'spawna ett fordon', + ['spawn_car_param'] = 'namn på fordon', + ['delete_vehicle'] = 'ta bort fordon', ['delete_veh_param'] = 'tryck enter', ['spawn_object'] = 'spawna föremål', ['spawn_ped'] = 'spawna NPC', - ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', + ['spawn_ped_param'] = 'exempel a_m_m_hillbilly_01', ['givemoney'] = 'ge pengar', ['setmoney'] = 'bestäm mängd pengar till en valfri person', ['money_type'] = 'giltiga typer: cash, bank, black', @@ -148,7 +148,7 @@ Locales['sv'] = { ['weapon_flashlight'] = 'flashlight', ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', - ['weapon_flare'] = 'Fusée Détresse', + ['weapon_flare'] = 'flare gun', ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', ['weapon_doubleaction'] = 'Double-Action Revolver', diff --git a/server/classes/player.lua b/server/classes/player.lua index 86170fc2..c2b8ce41 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -430,10 +430,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l }) end TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) - TriggerClientEvent("esx:addInventoryItem", self.source, {label = weaponLabel}, 1) + TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) end - self.removeWeapon = function(weaponName) + self.removeWeapon = function(weaponName, ammo) local weaponLabel = weaponName @@ -453,8 +453,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end - TriggerClientEvent('esx:removeWeapon', self.source, weaponName) - TriggerClientEvent("esx:removeInventoryItem", self.source, {label = weaponLabel}, 1) + TriggerClientEvent('esx:removeWeapon', self.source, weaponName, ammo) + TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) end return self From 6d99719a507e761523b3e0501faaa16753e18544 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 23 Jun 2018 11:47:24 +0200 Subject: [PATCH 210/672] Updated readme --- README.md | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index d0b33aee..819de528 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # es_extended -es_extended is an extention that is developed on top of [EssentialMode](https://essentialmode.com/) (aka ES), thus commonly named ESX - the **Es**sentialMode **E**xtended framework for FiveM. +es_extended is a roleplay framework for FiveM. It is developed on top of [EssentialMode](https://essentialmode.com/) (aka ES), thus commonly named ESX - the **Es**sentialMode **E**xtended framework for FiveM. ### Links & Read more - [Official Discord community](https://discord.me/fivem_esx) -- [ESX Documentation](https://esx-org.github.io/) (things are missing!) +- [ESX Documentation](https://esx-org.github.io/) (incomplete) - [ES Documentation](https://docs.essentialmode.com/) - [FiveM Native Reference](https://runtime.fivem.net/doc/reference.html) @@ -30,28 +30,15 @@ This order also applies in the startup order. ### Download & Installation -**1) Using [fvm](https://github.com/qlaffont/fvm-installer)** - +### Using [fvm](https://github.com/qlaffont/fvm-installer) ``` fvm install --save --folder=essential esx-org/es_extended fvm install --save --folder=esx esx-org/esx_menu_default fvm install --save --folder=esx esx-org/esx_menu_dialog fvm install --save --folder=esx esx-org/esx_menu_list - ``` -**2) Manually** - -- Download https://github.com/ESX-Org/es_extended/releases/latest -- Put it in the resource/[essential] directory -- Download https://github.com/ESX-Org/esx_menu_default/releases/latest -- Put it in the resource/[esx]/[ui] directory -- Download https://github.com/ESX-Org/esx_menu_dialog/releases/latest -- Put it in the resource/[esx]/[ui] directory -- Download https://github.com/ESX-Org/esx_menu_list/releases/latest -- Put it in the resource/[esx]/[ui] directory - -**3) Using git** +### Using Git ``` cd resources @@ -61,10 +48,20 @@ git clone https://github.com/ESX-Org/esx_menu_dialog [esx]/[ui]/esx_menu_dialog git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list ``` -## Installation +### Manually +- Download https://github.com/ESX-Org/es_extended/releases/latest +- Put it in the `resource/[essential]` directory +- Download https://github.com/ESX-Org/esx_menu_default/releases/latest +- Put it in the `resource/[esx]/[ui]` directory +- Download https://github.com/ESX-Org/esx_menu_dialog/releases/latest +- Put it in the `resource/[esx]/[ui]` directory +- Download https://github.com/ESX-Org/esx_menu_list/releases/latest +- Put it in the `resource/[esx]/[ui]` directory -1) Import es_extended.sql in your database -2) Configure your `server.cfg` to look like this + +## Installation +- Import `es_extended.sql` in your database +- Configure your `server.cfg` to look like this ``` start baseevents From 7ed39a4666e14e08b59fc189b3f84fa2fbab72ed Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 25 Jun 2018 21:45:23 +0200 Subject: [PATCH 211/672] Fixed duplicate locale strings, closes #95 --- locales/br.lua | 2 +- locales/de.lua | 2 +- locales/en.lua | 2 +- locales/fi.lua | 2 +- locales/fr.lua | 4 ++-- locales/sv.lua | 2 +- server/paycheck.lua | 8 ++++---- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 5b5231c3..70c77d3c 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -32,7 +32,7 @@ Locales['br'] = { ['received_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', ['received_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salario.', - ['received_money'] = 'recebeu dinheiro', + ['received_paycheck'] = 'recebeu dinheiro', ['bank'] = 'banco', ['black_money'] = 'dinheiro sujo', ['act_imp'] = 'acao impossivel', diff --git a/locales/de.lua b/locales/de.lua index 97353c84..e2b24b0e 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -32,7 +32,7 @@ Locales['de'] = { ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary.', - ['received_money'] = 'received money', + ['received_paycheck'] = 'received paycheck', ['bank'] = 'bank', ['black_money'] = 'dirty Money', diff --git a/locales/en.lua b/locales/en.lua index 7005a206..13224898 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -32,7 +32,7 @@ Locales['en'] = { ['received_salary'] = 'you received your salary: ~g~$%s~s~', ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary.', - ['received_money'] = 'received money', + ['received_paycheck'] = 'received paycheck', ['bank'] = 'bank', ['black_money'] = 'dirty Money', diff --git a/locales/fi.lua b/locales/fi.lua index 9c2cece9..b41b6802 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -32,7 +32,7 @@ Locales['fi'] = { ['received_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', ['received_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', ['company_nomoney'] = 'yritys jolle teet töitä on köyhä eikä voi maksaa palkkaasi.', - ['received_money'] = 'sai rahaa', + ['received_paycheck'] = 'sai rahaa', ['bank'] = 'Pankki', ['black_money'] = 'likainen Raha', diff --git a/locales/fr.lua b/locales/fr.lua index 9e72101c..dc54abec 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -31,8 +31,8 @@ Locales['fr'] = { -- Salary related ['received_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', ['received_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', - ['company_nomoney'] = 'votre entreprise n\'a plus d\'argent pour vous payer!', -- fix translation - ['received_money'] = 'received money', + ['company_nomoney'] = 'votre entreprise n\'a plus d\'argent pour vous payer!', + ['received_paycheck'] = 'received paycheck', ['bank'] = 'banque', ['black_money'] = 'argent Sale', diff --git a/locales/sv.lua b/locales/sv.lua index 53f00495..6e46cdd3 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -32,7 +32,7 @@ Locales['sv'] = { ['received_salary'] = 'du har mottagit din lön på ~g~$%s~s~', ['received_help'] = 'du har mottagit bidrag på ~g~$%s~s~', ['company_nomoney'] = 'företaget du är anställt hos har inte råd att betala ut din lön.', - ['received_money'] = 'mottagit pengar', + ['received_paycheck'] = 'mottagit lön', ['bank'] = 'bank', ['black_money'] = 'svarta pengar', diff --git a/server/paycheck.lua b/server/paycheck.lua index df3cff43..04719d3b 100644 --- a/server/paycheck.lua +++ b/server/paycheck.lua @@ -11,7 +11,7 @@ ESX.StartPayCheck = function() if salary > 0 then if job == 'unemployed' then -- unemployed xPlayer.addAccountMoney('bank', salary) - TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_money'), _U('received_help', salary), 'CHAR_BANK_MAZE', 9) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_paycheck'), _U('received_help', salary), 'CHAR_BANK_MAZE', 9) elseif Config.EnableSocietyPayouts then -- possibly a society TriggerEvent('esx_society:getSociety', xPlayer.job.name, function (society) if society ~= nil then -- verified society @@ -20,19 +20,19 @@ ESX.StartPayCheck = function() xPlayer.addAccountMoney('bank', salary) account.removeMoney(salary) - TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_money'), _U('received_salary', salary), 'CHAR_BANK_MAZE', 9) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_paycheck'), _U('received_salary', salary), 'CHAR_BANK_MAZE', 9) else TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), '', _U('company_nomoney'), 'CHAR_BANK_MAZE', 1) end end) else -- not a society xPlayer.addAccountMoney('bank', salary) - TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_money'), _U('received_salary', salary), 'CHAR_BANK_MAZE', 9) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_paycheck'), _U('received_salary', salary), 'CHAR_BANK_MAZE', 9) end end) else -- generic job xPlayer.addAccountMoney('bank', salary) - TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_money'), _U('received_salary', salary), 'CHAR_BANK_MAZE', 9) + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_paycheck'), _U('received_salary', salary), 'CHAR_BANK_MAZE', 9) end end From 8dad7591871d5cf41d9c4af0df0498ca76a48ba1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 1 Jul 2018 14:48:37 +0200 Subject: [PATCH 212/672] Added /clear /cls for clearing chat, 4 tab indent for inventory --- client/functions.lua | 514 ++++++++++++++++++++----------------------- locales/br.lua | 3 + locales/de.lua | 3 + locales/en.lua | 2 + locales/fi.lua | 2 + locales/fr.lua | 3 + locales/sv.lua | 2 + server/commands.lua | 56 +++-- 8 files changed, 297 insertions(+), 288 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 04c2ce82..a161825a 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -719,32 +719,32 @@ ESX.Game.GetVehicleProperties = function(vehicle) return { - model = GetEntityModel(vehicle), + model = GetEntityModel(vehicle), - plate = GetVehicleNumberPlateText(vehicle), - plateIndex = GetVehicleNumberPlateTextIndex(vehicle), + plate = GetVehicleNumberPlateText(vehicle), + plateIndex = GetVehicleNumberPlateTextIndex(vehicle), - health = GetEntityHealth(vehicle), - dirtLevel = GetVehicleDirtLevel(vehicle), + health = GetEntityHealth(vehicle), + dirtLevel = GetVehicleDirtLevel(vehicle), - color1 = color1, - color2 = color2, + color1 = color1, + color2 = color2, - pearlescentColor = pearlescentColor, - wheelColor = wheelColor, + pearlescentColor = pearlescentColor, + wheelColor = wheelColor, - wheels = GetVehicleWheelType(vehicle), - windowTint = GetVehicleWindowTint(vehicle), + wheels = GetVehicleWheelType(vehicle), + windowTint = GetVehicleWindowTint(vehicle), - neonEnabled = { + neonEnabled = { IsVehicleNeonLightEnabled(vehicle, 0), IsVehicleNeonLightEnabled(vehicle, 1), IsVehicleNeonLightEnabled(vehicle, 2), IsVehicleNeonLightEnabled(vehicle, 3), }, - neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), - tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), + neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), modSpoilers = GetVehicleMod(vehicle, 0), modFrontBumper = GetVehicleMod(vehicle, 1), @@ -1082,315 +1082,285 @@ end ESX.ShowInventory = function() - local playerPed = GetPlayerPed(-1) - local elements = {} + local playerPed = GetPlayerPed(-1) + local elements = {} - if ESX.PlayerData.money > 0 then - table.insert(elements, { - label = _U('cash', ESX.PlayerData.money), - count = ESX.PlayerData.money, - type = 'item_money', - value = 'money', - usable = false, - rare = false, - canRemove = true - }) - end + if ESX.PlayerData.money > 0 then + table.insert(elements, { + label = _U('cash', ESX.PlayerData.money), + count = ESX.PlayerData.money, + type = 'item_money', + value = 'money', + usable = false, + rare = false, + canRemove = true + }) + end - for i=1, #ESX.PlayerData.accounts, 1 do - if ESX.PlayerData.accounts[i].money > 0 then - table.insert(elements, { - label = '[' .. ESX.PlayerData.accounts[i].label .. '] $' .. ESX.PlayerData.accounts[i].money, - count = ESX.PlayerData.accounts[i].money, - type = 'item_account', - value = ESX.PlayerData.accounts[i].name, - usable = false, - rare = false, - canRemove = true - }) - end - end + for i=1, #ESX.PlayerData.accounts, 1 do + if ESX.PlayerData.accounts[i].money > 0 then + table.insert(elements, { + label = '[' .. ESX.PlayerData.accounts[i].label .. '] $' .. ESX.PlayerData.accounts[i].money, + count = ESX.PlayerData.accounts[i].money, + type = 'item_account', + value = ESX.PlayerData.accounts[i].name, + usable = false, + rare = false, + canRemove = true + }) + end + end - for i=1, #ESX.PlayerData.inventory, 1 do + for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].count > 0 then - table.insert(elements, { - label = ESX.PlayerData.inventory[i].label .. ' x' .. ESX.PlayerData.inventory[i].count, - count = ESX.PlayerData.inventory[i].count, - type = 'item_standard', - value = ESX.PlayerData.inventory[i].name, - usable = ESX.PlayerData.inventory[i].usable, - rare = ESX.PlayerData.inventory[i].rare, - canRemove = ESX.PlayerData.inventory[i].canRemove, - }) - end + if ESX.PlayerData.inventory[i].count > 0 then + table.insert(elements, { + label = ESX.PlayerData.inventory[i].label .. ' x' .. ESX.PlayerData.inventory[i].count, + count = ESX.PlayerData.inventory[i].count, + type = 'item_standard', + value = ESX.PlayerData.inventory[i].name, + usable = ESX.PlayerData.inventory[i].usable, + rare = ESX.PlayerData.inventory[i].rare, + canRemove = ESX.PlayerData.inventory[i].canRemove, + }) + end - end + end - for i=1, #Config.Weapons, 1 do + for i=1, #Config.Weapons, 1 do - local weaponHash = GetHashKey(Config.Weapons[i].name) + local weaponHash = GetHashKey(Config.Weapons[i].name) - if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + 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, + ammo = ammo, + usable = false, + rare = false, + canRemove = true + }) + end + end - local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + ESX.UI.Menu.CloseAll() - table.insert(elements, { - label = Config.Weapons[i].label .. ' x1 [' .. ammo .. ']', - count = 1, - type = 'item_weapon', - value = Config.Weapons[i].name, - ammo = ammo, - usable = false, - rare = false, - canRemove = true - }) + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory', + { + title = _U('inventory'), + align = 'bottom-right', + elements = elements, + }, function(data, menu) + menu.close() - end - end + local player, distance = ESX.Game.GetClosestPlayer() + local elements = {} - ESX.UI.Menu.CloseAll() + if data.current.usable then + table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) + end - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'inventory', - { - title = _U('inventory'), - align = 'bottom-right', - elements = elements, - }, - function(data, menu) - menu.close() + if data.current.canRemove then + if player ~= -1 and distance <= 3.0 then + table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + end + table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) + end - local player, distance = ESX.Game.GetClosestPlayer() - local elements = {} + if data.current.type == 'item_weapon' and data.current.ammo > 0 and player ~= -1 and distance <= 3.0 then + table.insert(elements, {label = _U('giveammo'), action = 'giveammo', type = data.current.type, value = data.current.value}) + end - if data.current.usable then - table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) - end + table.insert(elements, {label = _U('return'), action = 'return'}) - if data.current.canRemove then - if player ~= -1 and distance <= 3.0 then - table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) - end - table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) - end + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory_item', + { + title = data.current.label, + align = 'bottom-right', + elements = elements, + }, function(data, menu) - if data.current.type == "item_weapon" and data.current.ammo > 0 and player ~= -1 and distance <= 3.0 then - table.insert(elements, {label = _U('giveammo'), action = 'giveammo', type = data.current.type, value = data.current.value}) - end + local item = data.current.value + local type = data.current.type + local playerPed = GetPlayerPed(-1) - table.insert(elements, {label = _U('return'), action = 'return'}) + if data.current.action == 'give' then - ESX.UI.Menu.Open( - 'default', GetCurrentResourceName(), 'inventory_item', - { - title = data.current.label, - align = 'bottom-right', - elements = elements, - }, - function(data, menu) + if type == 'item_weapon' then + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + local closestPed = GetPlayerPed(closestPlayer) + local pedAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1), GetHashKey(item)) - local item = data.current.value - local type = data.current.type - local playerPed = GetPlayerPed(-1) + if not IsPedSittingInAnyVehicle(closestPed) then + if closestPlayer ~= -1 and closestDistance < 3.0 then + if pedAmmo > 0 then + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', + { + title = _U('amountammo') + }, function(data2, menu2) + local quantity = tonumber(data2.value) + if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + local finalammo = math.floor(pedAmmo - quantity) + SetPedAmmo(playerPed, item, finalammo) + menu2.close() + menu.close() + else + ESX.ShowNotification(_U('noammo')) + end + end, function(data2, menu2) + menu2.close() + end) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 0) + menu.close() + end + else + ESX.ShowNotification(_U('players_nearby')) + end + else + ESX.ShowNotification(_U('in_vehicle')) + end - if data.current.action == 'give' then + else -- type: item_standard - if type == 'item_weapon' then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - local closestPed = GetPlayerPed(closestPlayer) - local pedAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1), GetHashKey(item)) - if not IsPedSittingInAnyVehicle(closestPed) then - if closestPlayer ~= -1 and closestDistance < 3.0 then - if pedAmmo > 0 then - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', - { - title = _U('amountammo') - }, - function(data2, menu2) - local quantity = tonumber(data2.value) - if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) - local finalammo = math.floor(pedAmmo - quantity) - SetPedAmmo(playerPed, item, finalammo) - menu2.close() - menu.close() - else - ESX.ShowNotification(_U('noammo')) - end + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', + { + title = _U('amount') + }, function(data2, menu2) + local quantity = tonumber(data2.value) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + local closestPed = GetPlayerPed(closestPlayer) - end, function(data2, menu2) - menu2.close() - end - ) - else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 0) - menu.close() - end - else - ESX.ShowNotification(_U('players_nearby')) - end - else - ESX.ShowNotification(_U("in_vehicle")) - end + if not IsPedSittingInAnyVehicle(closestPed) then + if closestPlayer ~= -1 and closestDistance < 3.0 then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + else + ESX.ShowNotification(_U('players_nearby')) + end + else + ESX.ShowNotification(_U('in_vehicle')) + end - else + menu2.close() + menu.close() - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', - { - title = _U('amount') - }, - function(data2, menu2) + end, function(data2, menu2) + menu2.close() + end) + end - local quantity = tonumber(data2.value) - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - local closestPed = GetPlayerPed(closestPlayer) - if not IsPedSittingInAnyVehicle(closestPed) then - if closestPlayer ~= -1 and closestDistance < 3.0 then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) - else - ESX.ShowNotification(_U('players_nearby')) - end - else - ESX.ShowNotification(_U("in_vehicle")) - end + elseif data.current.action == 'remove' then - menu2.close() - menu.close() + if type == 'item_weapon' then + local pedAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1),GetHashKey(item)) + + -- does the player have any ammo for the weapon? + if pedAmmo > 0 then + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', + { + title = _U('amount') + }, function(data2, menu2) + local quantity = tonumber(data2.value) - end, - function(data2, menu2) - menu2.close() - end - ) + if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then + local finalammo = math.floor(pedAmmo - quantity) + + SetPedAmmo(playerPed, item, finalammo) + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + else + ESX.ShowNotification(_U('noammo')) + end + menu2.close() + menu.close() + end, function(data2, menu2) + menu2.close() + end) + else + TriggerServerEvent('esx:removeInventoryItem', type, item, 0) + menu.close() + end - end + else -- type: item_standard - elseif data.current.action == 'remove' then - - if type == 'item_weapon' then - local pedAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1),GetHashKey(item)) - - -- does the player have any ammo for the weapon? - if pedAmmo > 0 then - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { title = _U('amount') }, function(data2, menu2) local quantity = tonumber(data2.value) - if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then - local finalammo = math.floor(pedAmmo - quantity) - - SetPedAmmo(playerPed, item, finalammo) - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + if quantity == nil then + ESX.ShowNotification(_U('amount_invalid')) else - ESX.ShowNotification(_U('noammo')) + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) end + menu2.close() menu.close() end, function(data2, menu2) menu2.close() end) - else - TriggerServerEvent('esx:removeInventoryItem', type, item, 0) - menu.close() end - else + elseif data.current.action == 'use' then + TriggerServerEvent('esx:useItem', data.current.value) - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_remove', - { - title = _U('amount') - }, - function(data2, menu2) + elseif data.current.action == 'return' then - local quantity = tonumber(data2.value) + ESX.UI.Menu.CloseAll() + ESX.ShowInventory() + elseif data.current.action == 'giveammo' then + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + local closestPed = GetPlayerPed(closestPlayer) + local pedAmmo = GetAmmoInPedWeapon(playerPed,GetHashKey(item)) + if not IsPedSittingInAnyVehicle(closestPed) then + if closestPlayer ~= -1 and closestDistance < 3.0 then + if pedAmmo > 0 then + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', + { + title = _U('amountammo') + }, function(data2, menu2) + local quantity = tonumber(data2.value) + if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then - if quantity == nil then - ESX.ShowNotification(_U('amount_invalid')) - else - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) - end + local finalAmmoSource = math.floor(pedAmmo - quantity) + SetPedAmmo(playerPed, item, finalAmmoSource) + AddAmmoToPed(closestPed, item, quantity) - menu2.close() - menu.close() + ESX.ShowNotification(_U('gave_ammo', quantity, GetPlayerName(closestPlayer))) + -- todo notify target that he received ammo + menu2.close() + menu.close() + else + ESX.ShowNotification(_U('noammo')) + end - end, - function(data2, menu2) - menu2.close() - end - ) + end, function(data2, menu2) + menu2.close() + end) + else + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 0) + menu.close() + end + else + ESX.ShowNotification(_U('players_nearby')) + end + else + ESX.ShowNotification(_U('in_vehicle')) + end + end - end - - elseif data.current.action == 'use' then - TriggerServerEvent('esx:useItem', data.current.value) - - elseif data.current.action == 'return' then - - ESX.UI.Menu.CloseAll() - ESX.ShowInventory() - elseif data.current.action == 'giveammo' then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - local closestPed = GetPlayerPed(closestPlayer) - local pedAmmo = GetAmmoInPedWeapon(playerPed,GetHashKey(item)) - if not IsPedSittingInAnyVehicle(closestPed) then - if closestPlayer ~= -1 and closestDistance < 3.0 then - if pedAmmo > 0 then - ESX.UI.Menu.Open( - 'dialog', GetCurrentResourceName(), 'inventory_item_count_give', - { - title = _U('amountammo') - }, - function(data2, menu2) - local quantity = tonumber(data2.value) - if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then - local finalAmmoSource = math.floor(pedAmmo - quantity) - SetPedAmmo(playerPed, item, finalAmmoSource) - AddAmmoToPed(closestPed, item, quantity) - ESX.ShowNotification(_U('gave_ammo', quantity, GetPlayerName(closestPlayer))) - -- todo notify target that he received ammo - menu2.close() - menu.close() - else - ESX.ShowNotification(_U('noammo')) - end - - end, - function(data2, menu2) - menu2.close() - end - ) - else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 0) - menu.close() - end - else - ESX.ShowNotification(_U('players_nearby')) - end - else - ESX.ShowNotification(_U("in_vehicle")) - end - end - - end, - function(data, menu) - ESX.UI.Menu.CloseAll() - ESX.ShowInventory() - end - ) - - end, - function(data, menu) - menu.close() - end - ) + end, function(data, menu) + ESX.UI.Menu.CloseAll() + ESX.ShowInventory() + end) + end, function(data, menu) + menu.close() + end) end RegisterNetEvent('esx:serverCallback') diff --git a/locales/br.lua b/locales/br.lua index 70c77d3c..837444ad 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -64,6 +64,9 @@ Locales['br'] = { ['giveitem'] = 'dar item', ['weapon'] = 'arma', ['giveweapon'] = 'dar arma', + ['disconnect'] = 'disconnect from the server', + ['chat_clear'] = 'clear the chat', + ['chat_clear_all'] = 'clear the chat for everyone', -- Weapons ['weapon_knife'] = 'faca', ['weapon_nightstick'] = 'cacetete', diff --git a/locales/de.lua b/locales/de.lua index e2b24b0e..5f935f5f 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -58,6 +58,9 @@ Locales['de'] = { ['giveitem'] = 'give item', ['weapon'] = 'weapon', ['giveweapon'] = 'give weapon', + ['disconnect'] = 'disconnect from the server', + ['chat_clear'] = 'clear the chat', + ['chat_clear_all'] = 'clear the chat for everyone', -- Weapons ['weapon_knife'] = 'Messer', ['weapon_nightstick'] = 'Schlagstock', diff --git a/locales/en.lua b/locales/en.lua index 13224898..3577dd8b 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -69,6 +69,8 @@ Locales['en'] = { ['weapon'] = 'weapon', ['giveweapon'] = 'give weapon', ['disconnect'] = 'disconnect from the server', + ['chat_clear'] = 'clear the chat', + ['chat_clear_all'] = 'clear the chat for everyone', -- Weapons ['weapon_knife'] = 'knife', ['weapon_nightstick'] = 'nightstick', diff --git a/locales/fi.lua b/locales/fi.lua index b41b6802..bce5ee69 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -69,6 +69,8 @@ Locales['fi'] = { ['weapon'] = 'ase', ['giveweapon'] = 'anna ase', ['disconnect'] = 'poistu serveriltä', + ['chat_clear'] = 'clear the chat', + ['chat_clear_all'] = 'clear the chat for everyone', -- Weapons ['weapon_knife'] = 'veitsi', ['weapon_nightstick'] = 'pamppu', diff --git a/locales/fr.lua b/locales/fr.lua index dc54abec..d670928c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -65,6 +65,9 @@ Locales['fr'] = { ['giveitem'] = 'donner un article', ['weapon'] = 'arme', ['giveweapon'] = 'donner de l\'arme', + ['disconnect'] = 'disconnect from the server', + ['chat_clear'] = 'clear the chat', + ['chat_clear_all'] = 'clear the chat for everyone', -- Weapons ['weapon_knife'] = 'couteau', ['weapon_nightstick'] = 'matraque', diff --git a/locales/sv.lua b/locales/sv.lua index 6e46cdd3..6792b25c 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -69,6 +69,8 @@ Locales['sv'] = { ['weapon'] = 'vapen', ['giveweapon'] = 'ge vapen', ['disconnect'] = 'koppla från servern', + ['chat_clear'] = 'töm chatten', + ['chat_clear_all'] = 'töm chatten för alla', -- Weapons ['weapon_knife'] = 'knife', ['weapon_nightstick'] = 'nightstick', diff --git a/server/commands.lua b/server/commands.lua index 641a9077..f762b69d 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -13,7 +13,7 @@ TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Invalid coordinates!") end end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = "Teleport to coordinates", params = {{name = "x", help = "X coords"}, {name = "y", help = "Y coords"}, {name = "z", help = "Z coords"}}}) TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) @@ -28,56 +28,56 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Invalid usage.") end end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('setjob'), params = {{name = "id", help = _U('id_param')}, {name = "job", help = _U('setjob_param2')}, {name = "grade_id", help = _U('setjob_param3')}}}) TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user) TriggerClientEvent('esx:loadIPL', -1, args[1]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('load_ipl')}) TriggerEvent('es:addGroupCommand', 'unloadipl', 'admin', function(source, args, user) TriggerClientEvent('esx:unloadIPL', -1, args[1]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('unload_ipl')}) TriggerEvent('es:addGroupCommand', 'playanim', 'admin', function(source, args, user) TriggerClientEvent('esx:playAnim', -1, args[1], args[3]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('play_anim')}) TriggerEvent('es:addGroupCommand', 'playemote', 'admin', function(source, args, user) TriggerClientEvent('esx:playEmote', -1, args[1]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('play_emote')}) TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnVehicle', source, args[1]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) TriggerClientEvent('esx:deleteVehicle', source) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('delete_vehicle'), params = {{name = "car", help = _U('delete_veh_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnPed', source, args[1]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('spawn_ped'), params = {{name = "name", help = _U('spawn_ped_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnObject', source, args[1]) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('spawn_object'), params = {{name = "name"}}}) TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) @@ -111,7 +111,7 @@ TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, u TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) end end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('setmoney'), params = {{name = "id", help = _U('id_param')}, {name = "money type", help = _U('money_type')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) @@ -132,7 +132,7 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, end end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveaccountmoney'), params = {{name = "id", help = _U('id_param')}, {name = "account", help = _U('account')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) @@ -153,7 +153,7 @@ TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, u end end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveitem'), params = {{name = "id", help = _U('id_param')}, {name = "item", help = _U('item')}, {name = "amount", help = _U('amount')}}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) @@ -164,17 +164,41 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, xPlayer.addWeapon(weaponName, tonumber(args[3])) end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}, {name = "ammo", help = _U('amountammo')}}}) TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) DropPlayer(source, 'You have been disconnected') end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('disconnect')}) TriggerEvent('es:addGroupCommand', 'disconnect', 'admin', function(source, args, user) DropPlayer(source, 'You have been disconnected') end, function(source, args, user) - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Insufficient Permissions.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('disconnect')}) + +TriggerEvent('es:addGroupCommand', 'clear', 'user', function(source, args, user) + TriggerClientEvent('chat:clear', source) +end, function(source, args, user) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) +end, {help = _U('chat_clear')}) + +TriggerEvent('es:addGroupCommand', 'cls', 'user', function(source, args, user) + TriggerClientEvent('chat:clear', source) +end, function(source, args, user) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) +end, {help = _U('chat_clear')}) + +TriggerEvent('es:addGroupCommand', 'clsall', 'admin', function(source, args, user) + TriggerClientEvent('chat:clear') +end, function(source, args, user) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) +end, {help = _U('chat_clear_all')}) + +TriggerEvent('es:addGroupCommand', 'clearall', 'admin', function(source, args, user) + TriggerClientEvent('chat:clear') +end, function(source, args, user) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) +end, {help = _U('chat_clear_all')}) \ No newline at end of file From 2af146f83ef14e7cefb3ea8a9ffcd1d8a9be8341 Mon Sep 17 00:00:00 2001 From: Waltsh <36197644+Waltsh@users.noreply.github.com> Date: Sun, 1 Jul 2018 20:31:20 +0300 Subject: [PATCH 213/672] fixed Clear Chat --- locales/fi.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/fi.lua b/locales/fi.lua index bce5ee69..61965f6c 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -69,8 +69,8 @@ Locales['fi'] = { ['weapon'] = 'ase', ['giveweapon'] = 'anna ase', ['disconnect'] = 'poistu serveriltä', - ['chat_clear'] = 'clear the chat', - ['chat_clear_all'] = 'clear the chat for everyone', + ['chat_clear'] = 'tyhjennä chatti', + ['chat_clear_all'] = 'tyhjennä chatti kaikilta', -- Weapons ['weapon_knife'] = 'veitsi', ['weapon_nightstick'] = 'pamppu', @@ -164,4 +164,4 @@ Locales['fi'] = { ['weapon_heavysniper_mk2'] = 'Raskas Tarkkuuskivääri Mk II', ['weapon_pistol_mk2'] = 'Pistooli Mk II', ['weapon_smg_mk2'] = 'Konepistooli Mk II', -} \ No newline at end of file +} From e1c2b478ddc92638eadd088ce1f3ba22ce8b2e74 Mon Sep 17 00:00:00 2001 From: AdrineX Date: Sun, 1 Jul 2018 23:38:02 +0300 Subject: [PATCH 214/672] minor translation fix on paycheck --- locales/fi.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/fi.lua b/locales/fi.lua index 61965f6c..4bdd54fd 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -32,8 +32,8 @@ Locales['fi'] = { ['received_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', ['received_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', ['company_nomoney'] = 'yritys jolle teet töitä on köyhä eikä voi maksaa palkkaasi.', - ['received_paycheck'] = 'sai rahaa', - ['bank'] = 'Pankki', + ['received_paycheck'] = 'sait palkan', + ['bank'] = 'pankki', ['black_money'] = 'likainen Raha', ['act_imp'] = 'toiminto mahdoton', From a9a0dedeed8bf837465cf42ef5674d63d648ad5f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 5 Jul 2018 18:04:40 +0200 Subject: [PATCH 215/672] Minor changes --- .editorconfig | 4 ++-- README.md | 1 - client/main.lua | 19 ++++++++----------- html/css/app.css | 2 +- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/.editorconfig b/.editorconfig index 41c2aaf2..6866fb40 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,8 +1,8 @@ root = true [*] -indent_size = 2 -indent_style = space +indent_size = 4 +indent_style = tab end_of_line = lf charset = utf-8 trim_trailing_whitespace = true diff --git a/README.md b/README.md index 819de528..e41d792e 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,6 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list - Download https://github.com/ESX-Org/esx_menu_list/releases/latest - Put it in the `resource/[esx]/[ui]` directory - ## Installation - Import `es_extended.sql` in your database - Configure your `server.cfg` to look like this diff --git a/client/main.lua b/client/main.lua index 56036754..fd73a267 100644 --- a/client/main.lua +++ b/client/main.lua @@ -10,8 +10,6 @@ local Keys = { ["NENTER"] = 201, ["N4"] = 108, ["N5"] = 60, ["N6"] = 107, ["N+"] = 96, ["N-"] = 97, ["N7"] = 117, ["N8"] = 61, ["N9"] = 118 } -local GUI = {} -GUI.Time = 0 local LoadoutLoaded = false local IsPaused = false local PlayerSpawned = false @@ -76,11 +74,12 @@ AddEventHandler('playerSpawned', function() isDead = false end) -AddEventHandler('baseevents:onPlayerDied', function(killerType, coords) +AddEventHandler('baseevents:onPlayerDied', function(killerType, deathCoords) TriggerEvent('esx:onPlayerDeath') end) -AddEventHandler('baseevents:onPlayerKilled', function(killerId, data) +-- handle death client side (could have been server side...) +AddEventHandler('baseevents:onPlayerKilled', function(killerPed, data) TriggerEvent('esx:onPlayerDeath') end) @@ -100,7 +99,7 @@ AddEventHandler('skinchanger:modelLoaded', function() TriggerEvent('esx:restoreLoadout') end) -AddEventHandler('esx:restoreLoadout', function () +AddEventHandler('esx:restoreLoadout', function() local playerPed = GetPlayerPed(-1) RemoveAllPedWeapons(playerPed, true) @@ -199,7 +198,6 @@ 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 @@ -478,9 +476,8 @@ Citizen.CreateThread(function() Citizen.Wait(10) - if IsControlPressed(0, Keys["F2"]) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') and (GetGameTimer() - GUI.Time) > 150 then + if IsControlJustReleased(0, Keys["F2"]) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() - GUI.Time = GetGameTimer() end end @@ -492,14 +489,14 @@ if Config.ShowDotAbovePlayer then Citizen.CreateThread(function() while true do - Citizen.Wait(0) + Citizen.Wait(1) 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) + local headId = CreateMpGamerTag(ped, ('·'), false, false, '', false) end end @@ -587,7 +584,7 @@ Citizen.CreateThread(function() while true do - Citizen.Wait(10) + Citizen.Wait(1000) local playerPed = GetPlayerPed(-1) diff --git a/html/css/app.css b/html/css/app.css index 6fff380f..cfe7e0ab 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -47,7 +47,7 @@ html { .menu { font-family: 'Open Sans', sans-serif; min-width : 400px; - min-height: : 250px; + min-height : 250px; color : #fff; position : absolute; left : 40; From 985f2a81fba8768a6dad1877e60b9865ea3fd0b9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 7 Jul 2018 13:31:40 +0200 Subject: [PATCH 216/672] Refactoring, added shared functions - Added ESX.ShowHelpNotification - Added misc shared functions --- __resource.lua | 13 ++++++++-- client/functions.lua | 39 +++++++++++++--------------- server/common.lua | 2 +- server/functions.lua | 11 +++++--- shared/functions.lua | 61 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 99 insertions(+), 27 deletions(-) create mode 100644 shared/functions.lua diff --git a/__resource.lua b/__resource.lua index 7bfb5a51..a68ee339 100644 --- a/__resource.lua +++ b/__resource.lua @@ -7,6 +7,7 @@ version '1.0.14' server_scripts { '@async/async.lua', '@mysql-async/lib/MySQL.lua', + 'locale.lua', 'locales/de.lua', 'locales/br.lua', @@ -14,14 +15,18 @@ server_scripts { 'locales/en.lua', 'locales/fi.lua', 'locales/sv.lua', + 'config.lua', 'config.weapons.lua', + 'server/common.lua', 'server/classes/player.lua', 'server/functions.lua', 'server/paycheck.lua', 'server/main.lua', - 'server/commands.lua' + 'server/commands.lua', + + 'shared/functions.lua' } client_scripts { @@ -32,13 +37,17 @@ client_scripts { 'locales/en.lua', 'locales/fi.lua', 'locales/sv.lua', + 'config.lua', 'config.weapons.lua', + 'client/common.lua', 'client/entityiter.lua', 'client/functions.lua', 'client/wrapper.lua', - 'client/main.lua' + 'client/main.lua', + + 'shared/functions.lua' } ui_page { diff --git a/client/functions.lua b/client/functions.lua index a161825a..fa800d0c 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1,21 +1,17 @@ -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.PlayerData = {} ESX.PlayerLoaded = false 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.Game.Utils = {} @@ -23,18 +19,6 @@ ESX.GetConfig = function() return Config end -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, @@ -60,9 +44,9 @@ ESX.SetPlayerData = function(key, val) end ESX.ShowNotification = function(msg) - SetNotificationTextEntry('STRING') - AddTextComponentString(msg) - DrawNotification(0,1) + SetNotificationTextEntry('STRING') + AddTextComponentString(msg) + DrawNotification(false, true) end ESX.ShowAdvancedNotification = function(title, subject, msg, icon, iconType) @@ -72,6 +56,14 @@ ESX.ShowAdvancedNotification = function(title, subject, msg, icon, iconType) DrawNotification(false, false) end +ESX.ShowHelpNotification = function(msg) + if not IsHelpMessageOnScreen() then + SetTextComponentFormat('STRING') + AddTextComponentString(msg) + DisplayHelpTextFromStringLabel(0, 0, 1, -1) + end +end + ESX.TriggerServerCallback = function(name, cb, ...) ESX.ServerCallbacks[ESX.CurrentRequestId] = cb @@ -1379,6 +1371,11 @@ AddEventHandler('esx:showAdvancedNotification', function(title, subject, msg, ic ESX.ShowAdvancedNotification(title, subject, msg, icon, iconType) end) +RegisterNetEvent('esx:showHelpNotification') +AddEventHandler('esx:showHelpNotification', function(msg) + ESX.ShowHelpNotification(msg) +end) + -- SetTimeout Citizen.CreateThread(function() while true do diff --git a/server/common.lua b/server/common.lua index 034d0921..2a2eef94 100644 --- a/server/common.lua +++ b/server/common.lua @@ -17,7 +17,7 @@ function getSharedObject() return ESX end -AddEventHandler('onMySQLReady', function () +AddEventHandler('onMySQLReady', function() MySQL.Async.fetchAll( 'SELECT * FROM items', diff --git a/server/functions.lua b/server/functions.lua index 6a0fd5ed..da0673c2 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -59,7 +59,7 @@ ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) if ESX.ServerCallbacks[name] ~= nil then ESX.ServerCallbacks[name](source, cb, ...) else - print('TriggerServerCallback => [' .. name .. '] does not exists') + print('TriggerServerCallback => [' .. name .. '] does not exist') end end @@ -223,6 +223,12 @@ ESX.UseItem = function(source, item) ESX.UsableItemsCallbacks[item](source) end +ESX.GetItemLabel = function(item) + if ESX.Items[item] ~= nil then + return ESX.Items[item].label + end +end + ESX.GetWeaponList = function() return Config.Weapons end @@ -254,5 +260,4 @@ ESX.CreatePickup = function(type, name, count, label, player) ESX.PickupId = pickupId -end - +end \ No newline at end of file diff --git a/shared/functions.lua b/shared/functions.lua new file mode 100644 index 00000000..5bb240fd --- /dev/null +++ b/shared/functions.lua @@ -0,0 +1,61 @@ +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(GetGameTimer()) + + if length > 0 then + return ESX.GetRandomString(length - 1) .. Charset[math.random(1, #Charset)] + else + return '' + end +end + +ESX.TableContainsValue = function(table, value) + for k, v in pairs(table) do + if v == value then + return true + end + end + + return false +end + +ESX.TableToString = function(table, nb) + if nb == nil then + nb = 0 + end + + if type(table) == 'table' then + local s = '' + for i = 1, nb + 1, 1 do + s = s .. " " + end + + s = '{\n' + for k,v in pairs(table) do + if type(k) ~= 'number' then k = '"'..k..'"' end + for i = 1, nb, 1 do + s = s .. " " + end + s = s .. '['..k..'] = ' .. ESX.TableToString(v, nb + 1) .. ',\n' + end + + for i = 1, nb, 1 do + s = s .. " " + end + + return s .. '}' + else + return tostring(table) + end +end + + +ESX.Round = function(value) + return value >= 0 and math.floor(value + 0.5) or math.ceil(value - 0.5) +end + From a0fc21dc7fce546707adc8bf3e206f83697e4c77 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 8 Jul 2018 12:34:17 +0200 Subject: [PATCH 217/672] Renamed function ESX.TableToString to ESX.DumpTable --- shared/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/functions.lua b/shared/functions.lua index 5bb240fd..222c163f 100644 --- a/shared/functions.lua +++ b/shared/functions.lua @@ -24,7 +24,7 @@ ESX.TableContainsValue = function(table, value) return false end -ESX.TableToString = function(table, nb) +ESX.DumpTable = function(table, nb) if nb == nil then nb = 0 end @@ -41,7 +41,7 @@ ESX.TableToString = function(table, nb) for i = 1, nb, 1 do s = s .. " " end - s = s .. '['..k..'] = ' .. ESX.TableToString(v, nb + 1) .. ',\n' + s = s .. '['..k..'] = ' .. ESX.DumpTable(v, nb + 1) .. ',\n' end for i = 1, nb, 1 do From 330fb4527b0ddb40f0498ea65dcde6c2db20416d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 8 Jul 2018 15:33:13 +0200 Subject: [PATCH 218/672] Fixed exploit dupe throw in vehicles, closes #101 --- client/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index fa800d0c..60480661 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1247,6 +1247,10 @@ ESX.ShowInventory = function() elseif data.current.action == 'remove' then + if IsPedSittingInAnyVehicle(playerPed) then + menu.close() + end + if type == 'item_weapon' then local pedAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1),GetHashKey(item)) From 963432a73770acd962b0569ba5e7401f250c3503 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 10 Jul 2018 13:15:05 +0200 Subject: [PATCH 219/672] esx:onPlayerDeath trigger improved --- client/main.lua | 50 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index fd73a267..6ef73fbd 100644 --- a/client/main.lua +++ b/client/main.lua @@ -75,12 +75,56 @@ AddEventHandler('playerSpawned', function() end) AddEventHandler('baseevents:onPlayerDied', function(killerType, deathCoords) - TriggerEvent('esx:onPlayerDeath') + local playerPed = GetPlayerPed(-1) + + local data = { + killed = false, + killerType = killerType, + deathCoords = deathCoords, + deathCause = GetPedCauseOfDeath(playerPed) + } + + TriggerEvent('esx:onPlayerDeath', data) + TriggerServerEvent('esx:onPlayerDeath', data) end) --- handle death client side (could have been server side...) AddEventHandler('baseevents:onPlayerKilled', function(killerPed, data) - TriggerEvent('esx:onPlayerDeath') + local playerPed = GetPlayerPed(-1) + + -- corrected table childs + local victimCoords = data.killerpos + local weaponHash = data.weaponhash + + data.killerpos = nil + data.weaponhash = nil + + table.insert(data, { + victimCoords = victimCoords, + weaponHash = weaponHash + deathCause = GetPedCauseOfDeath(playerPed) + }) + + if killerPed ~= -1 then -- if the killer isn't AI + local killerCoords = GetEntityCoords(killerPed) + local distance = GetDistanceBetweenCoords(table.unpack(killerCoords), table.unpack(data.victimCoords), false) + + table.insert(data, { + killed = true, + killerPed = killerPed, + killerCoords = killerCoords, + distance = ESX.Round(distance) + }) + + else -- player died by AI, we cannot provide as much info because of baseevents setting 'killerPed' to '-1' + + table.insert(data, { + killed = false + }) + + end + + TriggerEvent('esx:onPlayerDeath', data) + TriggerServerEvent('esx:onPlayerDeath', data) end) AddEventHandler('esx:onPlayerDeath', function() From b51889afe3ec4bf413d45b3bae02029385f1b249 Mon Sep 17 00:00:00 2001 From: LuaDeldu Date: Tue, 10 Jul 2018 16:13:09 +0200 Subject: [PATCH 220/672] Missing comma --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 6ef73fbd..59930d9e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -100,7 +100,7 @@ AddEventHandler('baseevents:onPlayerKilled', function(killerPed, data) table.insert(data, { victimCoords = victimCoords, - weaponHash = weaponHash + weaponHash = weaponHash, deathCause = GetPedCauseOfDeath(playerPed) }) From 4a5913b3d4f2f1e60db478b164a1ae912bb5ebf4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 14 Jul 2018 19:33:20 +0200 Subject: [PATCH 221/672] Fixed dupe pickups #102 --- client/main.lua | 51 +++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/client/main.lua b/client/main.lua index 59930d9e..b0edfeea 100644 --- a/client/main.lua +++ b/client/main.lua @@ -242,6 +242,7 @@ end) -- Commands RegisterNetEvent('esx:teleport') AddEventHandler('esx:teleport', function(pos) +-- heading?! pos.x = pos.x + 0.0 pos.y = pos.y + 0.0 pos.z = pos.z + 0.0 @@ -416,7 +417,7 @@ AddEventHandler('esx:spawnPed', function(model) Citizen.Wait(1) end - CreatePed(5, model, x, y, z, 0.0, true, false) + CreatePed(5, model, x, y, z, 0.0, true, false) end) @@ -520,7 +521,7 @@ Citizen.CreateThread(function() Citizen.Wait(10) - if IsControlJustReleased(0, Keys["F2"]) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + if IsControlJustReleased(0, Keys['F2']) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() end @@ -571,35 +572,39 @@ end -- Pickups Citizen.CreateThread(function() - while true do + while true do - Citizen.Wait(0) + Citizen.Wait(0) - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) + local playerPed = GetPlayerPed(-1) + 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 + for k,v in pairs(Pickups) do - local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true) + local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - if distance <= 5.0 then + 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 - ESX.Game.Utils.DrawText3D({ - x = v.coords.x, - y = v.coords.y, - z = v.coords.z + 0.25 - }, v.label) + if (closestDistance == -1 or closestDistance > 3) and distance <= 1.0 and not v.inRange and not IsPedSittingInAnyVehicle(playerPed) then + TriggerServerEvent('esx:onPickup', v.id) + v.inRange = true + end - end + end - if distance <= 1.0 and not v.inRange and not IsPedSittingInAnyVehicle(playerPed) then - TriggerServerEvent('esx:onPickup', v.id) - v.inRange = true - end - - end - - end + end end) -- Last position From 38f3b14f94aff97ddd710e94f5d4a5726956d1d1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 14 Jul 2018 22:55:57 +0200 Subject: [PATCH 222/672] Implemented selecting who to give items, major improvements with inventory system, closes #107 --- client/functions.lua | 259 +++++++++++++++++++++++++++++-------------- locales/br.lua | 1 + locales/de.lua | 1 + locales/en.lua | 3 +- locales/fi.lua | 1 + locales/fr.lua | 1 + locales/sv.lua | 1 + 7 files changed, 181 insertions(+), 86 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 60480661..f77dd4f8 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1071,7 +1071,6 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size) end - ESX.ShowInventory = function() local playerPed = GetPlayerPed(-1) @@ -1157,8 +1156,9 @@ ESX.ShowInventory = function() if data.current.canRemove then if player ~= -1 and distance <= 3.0 then - table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) end + table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) end @@ -1173,82 +1173,156 @@ ESX.ShowInventory = function() title = data.current.label, align = 'bottom-right', elements = elements, - }, function(data, menu) + }, function(data1, menu1) - local item = data.current.value - local type = data.current.type + local item = data1.current.value + local type = data1.current.type local playerPed = GetPlayerPed(-1) - if data.current.action == 'give' then + if data1.current.action == 'give' then - if type == 'item_weapon' then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - local closestPed = GetPlayerPed(closestPlayer) - local pedAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1), GetHashKey(item)) + local players = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) + local foundPlayers = false + local elements = {} + + for i=1, #players, 1 do + if players[i] ~= PlayerId() then + foundPlayers = true + table.insert(elements, {label = GetPlayerName(players[i]), value = players[i]}) + end + end + + if not foundPlayers then + ESX.ShowNotification(_U('players_nearby')) + return + end + + foundPlayers = false + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'give_item_to', + { + title = _U('give_to'), + align = 'bottom-right', + elements = elements + }, function(data2, menu2) + + players = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) + + for i=1, #players, 1 do + if players[i] ~= PlayerId() then + + if players[i] == data2.current.value then + foundPlayers = true + break + end + end + end + + if not foundPlayers then + ESX.ShowNotification(_U('players_nearby')) + menu2.close() + return + end + + if type == 'item_weapon' then + + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + local closestPed = GetPlayerPed(closestPlayer) + local sourceAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1), GetHashKey(item)) + + if IsPedSittingInAnyVehicle(closestPed) then + ESX.ShowNotification(_U('in_vehicle')) + return + end - if not IsPedSittingInAnyVehicle(closestPed) then if closestPlayer ~= -1 and closestDistance < 3.0 then - if pedAmmo > 0 then + + if sourceAmmo > 0 then + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { title = _U('amountammo') - }, function(data2, menu2) - local quantity = tonumber(data2.value) - if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) - local finalammo = math.floor(pedAmmo - quantity) - SetPedAmmo(playerPed, item, finalammo) - menu2.close() - menu.close() + }, function(data3, menu3) + local quantity = tonumber(data3.value) + + if quantity ~= nil then + if quantity <= sourceAmmo and quantity >= 0 then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + + sourceAmmo = sourceAmmo - quantity + SetPedAmmo(playerPed, item, sourceAmmo) + + menu3.close() + menu2.close() + menu1.close() + else + ESX.ShowNotification(_U('noammo')) + end else - ESX.ShowNotification(_U('noammo')) + ESX.ShowNotification(_U('amount_invalid')) end - end, function(data2, menu2) - menu2.close() + + end, function(data3, menu3) + menu3.close() end) + else TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 0) - menu.close() + menu2.close() + menu1.close() end else ESX.ShowNotification(_U('players_nearby')) end - else - ESX.ShowNotification(_U('in_vehicle')) - end - else -- type: item_standard + else -- type: item_standard - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', - { - title = _U('amount') - }, function(data2, menu2) - local quantity = tonumber(data2.value) - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - local closestPed = GetPlayerPed(closestPlayer) + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', + { + title = _U('amount') + }, function(data3, menu3) + local quantity = tonumber(data3.value) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + local closestPed = GetPlayerPed(closestPlayer) + + if IsPedSittingInAnyVehicle(closestPed) then + ESX.ShowNotification(_U('in_vehicle')) + return + end - if not IsPedSittingInAnyVehicle(closestPed) then if closestPlayer ~= -1 and closestDistance < 3.0 then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + if quantity ~= nil then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) + + menu3.close() + menu2.close() + menu1.close() + else + ESX.ShowNotification(_U('amount_invalid')) + end + else ESX.ShowNotification(_U('players_nearby')) + + menu3.close() + menu2.close() + menu1.close() end - else - ESX.ShowNotification(_U('in_vehicle')) - end - menu2.close() - menu.close() + end, function(data3, menu3) + menu3.close() + end) + end + end, function(data2, menu2) + menu2.close() + end) -- give end - end, function(data2, menu2) - menu2.close() - end) - end - elseif data.current.action == 'remove' then + + elseif data1.current.action == 'remove' then if IsPedSittingInAnyVehicle(playerPed) then - menu.close() + return end if type == 'item_weapon' then @@ -1262,22 +1336,29 @@ ESX.ShowInventory = function() }, function(data2, menu2) local quantity = tonumber(data2.value) - if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then - local finalammo = math.floor(pedAmmo - quantity) - - SetPedAmmo(playerPed, item, finalammo) - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + if quantity ~= nil then + if quantity <= pedAmmo and quantity >= 0 then + local finalammo = math.floor(pedAmmo - quantity) + + SetPedAmmo(playerPed, item, finalammo) + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + + menu2.close() + menu1.close() + else + ESX.ShowNotification(_U('noammo')) + end else - ESX.ShowNotification(_U('noammo')) + ESX.ShowNotification(_U('amount_invalid')) end - menu2.close() - menu.close() + + end, function(data2, menu2) menu2.close() end) else TriggerServerEvent('esx:removeInventoryItem', type, item, 0) - menu.close() + menu1.close() end else -- type: item_standard @@ -1292,35 +1373,43 @@ ESX.ShowInventory = function() ESX.ShowNotification(_U('amount_invalid')) else TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + menu2.close() + menu1.close() end - menu2.close() - menu.close() end, function(data2, menu2) menu2.close() end) end - elseif data.current.action == 'use' then - TriggerServerEvent('esx:useItem', data.current.value) - - elseif data.current.action == 'return' then + elseif data1.current.action == 'use' then + TriggerServerEvent('esx:useItem', item) + elseif data1.current.action == 'return' then ESX.UI.Menu.CloseAll() ESX.ShowInventory() - elseif data.current.action == 'giveammo' then + elseif data1.current.action == 'giveammo' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() local closestPed = GetPlayerPed(closestPlayer) - local pedAmmo = GetAmmoInPedWeapon(playerPed,GetHashKey(item)) - if not IsPedSittingInAnyVehicle(closestPed) then - if closestPlayer ~= -1 and closestDistance < 3.0 then - if pedAmmo > 0 then - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', - { - title = _U('amountammo') - }, function(data2, menu2) - local quantity = tonumber(data2.value) - if quantity <= pedAmmo and quantity >= 0 and quantity ~= nil then + local pedAmmo = GetAmmoInPedWeapon(playerPed, GetHashKey(item)) + + if IsPedSittingInAnyVehicle(closestPed) then + ESX.ShowNotification(_U('in_vehicle')) + return + end + + if closestPlayer ~= -1 and closestDistance < 3.0 then + if pedAmmo > 0 then + + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', + { + title = _U('amountammo') + }, function(data2, menu2) + + local quantity = tonumber(data2.value) + + if quantity ~= nil then + if quantity <= pedAmmo and quantity >= 0 then local finalAmmoSource = math.floor(pedAmmo - quantity) SetPedAmmo(playerPed, item, finalAmmoSource) @@ -1329,27 +1418,27 @@ ESX.ShowInventory = function() ESX.ShowNotification(_U('gave_ammo', quantity, GetPlayerName(closestPlayer))) -- todo notify target that he received ammo menu2.close() - menu.close() + menu1.close() else ESX.ShowNotification(_U('noammo')) end + else + ESX.ShowNotification(_U('amount_invalid')) + end - end, function(data2, menu2) - menu2.close() - end) - else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 0) - menu.close() - end + end, function(data2, menu2) + menu2.close() + end) else - ESX.ShowNotification(_U('players_nearby')) + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 0) + menu1.close() end else - ESX.ShowNotification(_U('in_vehicle')) + ESX.ShowNotification(_U('players_nearby')) end end - end, function(data, menu) + end, function(data1, menu1) ESX.UI.Menu.CloseAll() ESX.ShowInventory() end) diff --git a/locales/br.lua b/locales/br.lua index 837444ad..f8b1c12c 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -6,6 +6,7 @@ Locales['br'] = { ['give'] = 'dar', ['remove'] = 'remover', ['return'] = 'voltar', + ['give_to'] = 'give to', ['amount'] = 'quantidade', ['giveammo'] = 'Dar muniçao', ['amountammo'] = 'quantidade de muniçao', diff --git a/locales/de.lua b/locales/de.lua index 5f935f5f..8f4654c8 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -6,6 +6,7 @@ Locales['de'] = { ['give'] = 'geben', ['remove'] = 'entfernen', ['return'] = 'zurück', + ['give_to'] = 'give to', ['amount'] = 'Betrag', ['giveammo'] = 'munition geben', ['amountammo'] = 'anzahl der munition', diff --git a/locales/en.lua b/locales/en.lua index 3577dd8b..ec0ab2f5 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -4,8 +4,9 @@ Locales['en'] = { ['inventory'] = 'inventory', ['use'] = 'use', ['give'] = 'give', - ['remove'] = 'remove', + ['remove'] = 'throw', ['return'] = 'return', + ['give_to'] = 'give to', ['amount'] = 'amount', ['giveammo'] = 'give ammo', ['amountammo'] = 'amount of ammo', diff --git a/locales/fi.lua b/locales/fi.lua index 4bdd54fd..f9334de4 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -6,6 +6,7 @@ Locales['fi'] = { ['give'] = 'anna', ['remove'] = 'poista', ['return'] = 'takaisin', + ['give_to'] = 'give to', ['amount'] = 'määrä', ['giveammo'] = 'anna ammuksia', ['amountammo'] = 'ammusten määrä', diff --git a/locales/fr.lua b/locales/fr.lua index d670928c..b729c493 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -6,6 +6,7 @@ Locales['fr'] = { ['give'] = 'donner', ['remove'] = 'jeter', ['return'] = 'retour', + ['give_to'] = 'give to', ['amount'] = 'quantité', ['giveammo'] = 'give ammo', ['amountammo'] = 'nombre de munitions', diff --git a/locales/sv.lua b/locales/sv.lua index 6792b25c..a9872464 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -6,6 +6,7 @@ Locales['sv'] = { ['give'] = 'ge', ['remove'] = 'kasta', ['return'] = 'gå tillbaka', + ['give_to'] = 'ge till', ['amount'] = 'antal', ['giveammo'] = 'ge ammunition', ['amountammo'] = 'mängd ammunition', From e7016c723cf51f689efd85d1e91682e775603d81 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 15 Jul 2018 13:15:14 +0200 Subject: [PATCH 223/672] Play sound when picking up throwed item --- client/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/client/main.lua b/client/main.lua index b0edfeea..51f79c65 100644 --- a/client/main.lua +++ b/client/main.lua @@ -599,6 +599,7 @@ Citizen.CreateThread(function() if (closestDistance == -1 or closestDistance > 3) and distance <= 1.0 and not v.inRange and not IsPedSittingInAnyVehicle(playerPed) then TriggerServerEvent('esx:onPickup', v.id) + PlaySoundFrontend(-1, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", 1) v.inRange = true end From 2dfff894e57d35eb9850a6470c68e70a317f84f6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 15 Jul 2018 13:37:03 +0200 Subject: [PATCH 224/672] Commented out distance calculating until it gets fixed --- client/main.lua | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/client/main.lua b/client/main.lua index 51f79c65..626c8746 100644 --- a/client/main.lua +++ b/client/main.lua @@ -104,9 +104,18 @@ AddEventHandler('baseevents:onPlayerKilled', function(killerPed, data) deathCause = GetPedCauseOfDeath(playerPed) }) - if killerPed ~= -1 then -- if the killer isn't AI + if killerPed == -1 then -- player died by AI, we cannot provide as much info because of baseevents setting 'killerPed' to '-1' + + table.insert(data, { + killed = false + }) + + else -- if the killer isn't AI + + killerPed = GetPlayerPed(GetPlayerFromServerId(killerPed)) local killerCoords = GetEntityCoords(killerPed) - local distance = GetDistanceBetweenCoords(table.unpack(killerCoords), table.unpack(data.victimCoords), false) + --local distance = GetDistanceBetweenCoords(table.unpack(killerCoords), table.unpack(data.victimCoords), false) + local distance = 2 table.insert(data, { killed = true, @@ -115,12 +124,6 @@ AddEventHandler('baseevents:onPlayerKilled', function(killerPed, data) distance = ESX.Round(distance) }) - else -- player died by AI, we cannot provide as much info because of baseevents setting 'killerPed' to '-1' - - table.insert(data, { - killed = false - }) - end TriggerEvent('esx:onPlayerDeath', data) From 50c5deff5feee4a360d2f9d62b6585eb0c729301 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 15 Jul 2018 13:38:46 +0200 Subject: [PATCH 225/672] Implemented experimental Scaleform API --- __resource.lua | 2 + client/functions.lua | 3 ++ client/modules/scaleform.lua | 93 ++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 client/modules/scaleform.lua diff --git a/__resource.lua b/__resource.lua index a68ee339..f3cbb740 100644 --- a/__resource.lua +++ b/__resource.lua @@ -47,6 +47,8 @@ client_scripts { 'client/wrapper.lua', 'client/main.lua', + 'client/modules/scaleform.lua', + 'shared/functions.lua' } diff --git a/client/functions.lua b/client/functions.lua index f77dd4f8..fd1fa693 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -15,6 +15,9 @@ ESX.UI.Menu.Opened = {} ESX.Game = {} ESX.Game.Utils = {} +ESX.Scaleform = {} +ESX.Scaleform.Utils = {} + ESX.GetConfig = function() return Config end diff --git a/client/modules/scaleform.lua b/client/modules/scaleform.lua new file mode 100644 index 00000000..eca6ba16 --- /dev/null +++ b/client/modules/scaleform.lua @@ -0,0 +1,93 @@ +ESX.Scaleform.ShowFreemodeMessage = function(title, msg, sec) + local scaleform = ESX.Scaleform.Utils.RequestScaleformMovie('MP_BIG_MESSAGE_FREEMODE') + + PushScaleformMovieFunction(scaleform, 'SHOW_SHARD_WASTED_MP_MESSAGE') + PushScaleformMovieFunctionParameterString(title) + PushScaleformMovieFunctionParameterString(msg) + PopScaleformMovieFunctionVoid() + + while sec > 0 do + Citizen.Wait(1) + sec = sec - 0.01 + + DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255) + end + + SetScaleformMovieAsNoLongerNeeded(scaleform) +end + +ESX.Scaleform.ShowBreakingNews = function(title, msg, bottom, sec) + local scaleform = ESX.Scaleform.Utils.RequestScaleformMovie('BREAKING_NEWS') + + PushScaleformMovieFunction(scaleform, 'SET_TEXT') + PushScaleformMovieFunctionParameterString(msg) + PushScaleformMovieFunctionParameterString(bottom) + PopScaleformMovieFunctionVoid() + + PushScaleformMovieFunction(scaleform, 'SET_SCROLL_TEXT') + PushScaleformMovieFunctionParameterInt(0) -- top ticker + PushScaleformMovieFunctionParameterInt(0) -- Since this is the first string, start at 0 + PushScaleformMovieFunctionParameterString(title) + PopScaleformMovieFunctionVoid() + + PushScaleformMovieFunction(scaleform, 'DISPLAY_SCROLL_TEXT') + PushScaleformMovieFunctionParameterInt(0) -- Top ticker + PushScaleformMovieFunctionParameterInt(0) -- Index of string + PopScaleformMovieFunctionVoid() + + while sec > 0 do + Citizen.Wait(1) + sec = sec - 0.01 + + DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255) + end + + SetScaleformMovieAsNoLongerNeeded(scaleform) +end + +ESX.Scaleform.ShowPopupWarning = function(title, msg, bottom, sec) + local scaleform = ESX.Scaleform.Utils.RequestScaleformMovie('POPUP_WARNING') + + PushScaleformMovieFunction(scaleform, 'SHOW_POPUP_WARNING') + PushScaleformMovieFunctionParameterFloat(500.0) -- black background + PushScaleformMovieFunctionParameterString(title) + PushScaleformMovieFunctionParameterString(msg) + PushScaleformMovieFunctionParameterString(bottom) + PushScaleformMovieFunctionParameterBool(true) + PopScaleformMovieFunctionVoid() + + while sec > 0 do + Citizen.Wait(1) + sec = sec - 0.01 + + DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255) + end + + SetScaleformMovieAsNoLongerNeeded(scaleform) +end + +ESX.Scaleform.ShowTrafficMovie = function(sec) + local scaleform = ESX.Scaleform.Utils.RequestScaleformMovie('TRAFFIC_CAM') + + PushScaleformMovieFunction(scaleform, 'PLAY_CAM_MOVIE') + PopScaleformMovieFunctionVoid() + + while sec > 0 do + Citizen.Wait(1) + sec = sec - 0.01 + + DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255) + end + + SetScaleformMovieAsNoLongerNeeded(scaleform) +end + +ESX.Scaleform.Utils.RequestScaleformMovie = function(movie) + local scaleform = RequestScaleformMovie(movie) + + while not HasScaleformMovieLoaded(scaleform) do + Citizen.Wait(0) + end + + return scaleform +end \ No newline at end of file From 6551c4ef03df5528488b18918f8bc474ca072b8a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 18 Jul 2018 12:29:40 +0200 Subject: [PATCH 226/672] Removed unneeded chat suggestions for command aliases --- server/commands.lua | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/server/commands.lua b/server/commands.lua index f762b69d..bb2a343f 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -4,7 +4,7 @@ TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) local z = tonumber(args[3]) if x and y and z then - TriggerClientEvent("esx:teleport", source, { + TriggerClientEvent('esx:teleport', source, { x = x, y = y, z = z @@ -67,7 +67,6 @@ end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('delete_vehicle'), params = {{name = "car", help = _U('delete_veh_param')}}}) - TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnPed', source, args[1]) end, function(source, args, user) @@ -171,7 +170,7 @@ TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) DropPlayer(source, 'You have been disconnected') end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('disconnect')}) +end) TriggerEvent('es:addGroupCommand', 'disconnect', 'admin', function(source, args, user) DropPlayer(source, 'You have been disconnected') @@ -189,16 +188,16 @@ TriggerEvent('es:addGroupCommand', 'cls', 'user', function(source, args, user) TriggerClientEvent('chat:clear', source) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('chat_clear')}) +end) TriggerEvent('es:addGroupCommand', 'clsall', 'admin', function(source, args, user) - TriggerClientEvent('chat:clear') + TriggerClientEvent('chat:clear', -1) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('chat_clear_all')}) +end) TriggerEvent('es:addGroupCommand', 'clearall', 'admin', function(source, args, user) - TriggerClientEvent('chat:clear') + TriggerClientEvent('chat:clear', -1) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('chat_clear_all')}) \ No newline at end of file From f90ca1f03a92b5339a16a27b88d9784b93f217f8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 18 Jul 2018 19:48:23 +0200 Subject: [PATCH 227/672] Fixed esx:onPlayerDeath trigger final time --- client/main.lua | 41 ++++++++++++++--------------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/client/main.lua b/client/main.lua index 626c8746..21140c27 100644 --- a/client/main.lua +++ b/client/main.lua @@ -75,7 +75,7 @@ AddEventHandler('playerSpawned', function() end) AddEventHandler('baseevents:onPlayerDied', function(killerType, deathCoords) - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local data = { killed = false, @@ -88,46 +88,33 @@ AddEventHandler('baseevents:onPlayerDied', function(killerType, deathCoords) TriggerServerEvent('esx:onPlayerDeath', data) end) -AddEventHandler('baseevents:onPlayerKilled', function(killerPed, data) - local playerPed = GetPlayerPed(-1) +AddEventHandler('baseevents:onPlayerKilled', function(killerId, data) + local playerPed = PlayerPedId() - -- corrected table childs + -- snake text; killerpos actually is the victim local victimCoords = data.killerpos local weaponHash = data.weaponhash data.killerpos = nil data.weaponhash = nil + local killerPed = GetPlayerPed(GetPlayerFromServerId(killerId)) + local killerCoords = GetEntityCoords(killerPed) + local distance = GetDistanceBetweenCoords(victimCoords[1], victimCoords[2], victimCoords[3], killerCoords, false) + table.insert(data, { victimCoords = victimCoords, weaponHash = weaponHash, - deathCause = GetPedCauseOfDeath(playerPed) + deathCause = GetPedCauseOfDeath(playerPed), + killed = true, + killerId = killerId, + killerCoords = { table.unpack(killerCoords) }, + distance = ESX.Round(distance) }) - if killerPed == -1 then -- player died by AI, we cannot provide as much info because of baseevents setting 'killerPed' to '-1' - - table.insert(data, { - killed = false - }) - - else -- if the killer isn't AI - - killerPed = GetPlayerPed(GetPlayerFromServerId(killerPed)) - local killerCoords = GetEntityCoords(killerPed) - --local distance = GetDistanceBetweenCoords(table.unpack(killerCoords), table.unpack(data.victimCoords), false) - local distance = 2 - - table.insert(data, { - killed = true, - killerPed = killerPed, - killerCoords = killerCoords, - distance = ESX.Round(distance) - }) - - end - TriggerEvent('esx:onPlayerDeath', data) TriggerServerEvent('esx:onPlayerDeath', data) + end) AddEventHandler('esx:onPlayerDeath', function() From 7d47e7b772fe778e6abd4a846bc3ac577ae2f95c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 19 Jul 2018 19:29:38 +0200 Subject: [PATCH 228/672] Implemented ESX.Streaming helper --- __resource.lua | 1 + client/functions.lua | 2 ++ client/modules/streaming.lua | 41 ++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 client/modules/streaming.lua diff --git a/__resource.lua b/__resource.lua index f3cbb740..0c4d096a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -48,6 +48,7 @@ client_scripts { 'client/main.lua', 'client/modules/scaleform.lua', + 'client/modules/streaming.lua', 'shared/functions.lua' } diff --git a/client/functions.lua b/client/functions.lua index fd1fa693..967b1078 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -18,6 +18,8 @@ ESX.Game.Utils = {} ESX.Scaleform = {} ESX.Scaleform.Utils = {} +ESX.Streaming = {} + ESX.GetConfig = function() return Config end diff --git a/client/modules/streaming.lua b/client/modules/streaming.lua new file mode 100644 index 00000000..6d7d3815 --- /dev/null +++ b/client/modules/streaming.lua @@ -0,0 +1,41 @@ +function ESX.Streaming.RequestModel(model) + local modelHash = GetHashKey(model) + + if not HasModelLoaded(modelHash) then + RequestModel(modelHash) + + while not HasModelLoaded(modelHash) do + Citizen.Wait(1) + end + end +end + +function ESX.Streaming.RequestStreamedTextureDict(textureDict) + if not HasStreamedTextureDictLoaded(textureDict) then + RequestStreamedTextureDict(textureDict) + + while not HasStreamedTextureDictLoaded(textureDict) do + Citizen.Wait(1) + end + end +end + +function ESX.Streaming.RequestAnimSet(animSet) + if not HasAnimSetLoaded(animSet) then + RequestAnimSet(animSet) + + while not HasAnimSetLoaded(animSet) do + Citizen.Wait(1) + end + end +end + +function ESX.Streaming.RequestAnimDict(animDict) + if not HasAnimDictLoaded(animDict) then + RequestAnimDict(animDict) + + while not HasAnimDictLoaded(animDict) do + Citizen.Wait(1) + end + end +end \ No newline at end of file From 8df8d5462e52b360f697232f1195ae2347f74489 Mon Sep 17 00:00:00 2001 From: MajorMarcin Date: Thu, 19 Jul 2018 19:48:34 +0200 Subject: [PATCH 229/672] add pl --- __resource.lua | 2 + locales/pl.lua | 165 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 locales/pl.lua diff --git a/__resource.lua b/__resource.lua index 0c4d096a..2556b821 100644 --- a/__resource.lua +++ b/__resource.lua @@ -15,6 +15,7 @@ server_scripts { 'locales/en.lua', 'locales/fi.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'config.weapons.lua', @@ -37,6 +38,7 @@ client_scripts { 'locales/en.lua', 'locales/fi.lua', 'locales/sv.lua', + 'locales/pl.lua', 'config.lua', 'config.weapons.lua', diff --git a/locales/pl.lua b/locales/pl.lua new file mode 100644 index 00000000..f9e369f9 --- /dev/null +++ b/locales/pl.lua @@ -0,0 +1,165 @@ +Locales['pl'] = { + -- Inventory + ['cash'] = 'gotówka $%s', + ['inventory'] = 'ekwipunek', + ['use'] = 'użyj', + ['give'] = 'daj', + ['remove'] = 'usuń', + ['return'] = 'return', + ['amount'] = 'amount', + ['giveammo'] = 'give ammo', + ['amountammo'] = 'ilość amunicji', + ['noammo'] = 'nie masz wystarczającej ilości amunicji!', + ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', + ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', + ['gave_weapon'] = 'dajesz ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~.', + ['received_weapon'] = 'otrzymujesz ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~.', + ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~.', + ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~.', + ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', + ['received_money'] = 'otrzymujesz ~g~%s$~s~ od ~b~%s~s~', + ['gave_account_money'] = 'dajesz ~g~%s$~s~ (%s) dla ~y~%s~s~', + ['received_account_money'] = 'otrzymujesz ~g~%s$~s~ (%s) od ~b~%s~s~', + ['amount_invalid'] = 'nieprawidłowa ilość', + ['players_nearby'] = 'brak graczy w pobliżu', + ['ex_inv_lim'] = 'akcja nie jest możliwa, nie możesz mieć więcej ~y~%s~s~', + ['imp_invalid_quantity'] = 'akcja jest niemożliwa, nieprawidłowa ilość', + ['imp_invalid_amount'] = 'akcja jest niemożliwa, nieprawidłowa kwota', + ['delete_five_min'] = 'przedmiot zostanie ~r~usunięty~s~ za 5 minut', + ['threw'] = '~r~upuściłeś~s~', + ['threw_weapon'] = '~r~Upuściłeś~s~ ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ pociskami!', + -- Salary related + ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', + ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', + ['company_nomoney'] = 'firma, w której pracujesz, jest zbyt biedna, by wypłacić twoją pensję.', + ['received_paycheck'] = 'otrzymana wypłata', + ['bank'] = 'bank', + ['black_money'] = 'brudne pieniądze', + + ['act_imp'] = 'działanie niemożliwe', + ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', + ['cannot_pickup_room'] = 'nie masz wystarczająco dużo miejsca w ekwipunku, aby podnieść ~y~%s~s~!', + -- Commands + ['setjob'] = 'przydziel prace użytkownikowi', + ['id_param'] = 'iD użyszkodnika', + ['setjob_param2'] = 'praca, którą chcesz przydzielić', + ['setjob_param3'] = 'poziom pracy', + ['load_ipl'] = 'załaduj IPL', + ['unload_ipl'] = 'usuń IPL', + ['play_anim'] = 'uruchom animację', + ['play_emote'] = 'uruchom emocje', + ['spawn_car'] = 'sprowadź pojazd', + ['spawn_car_param'] = 'nazwa samochodu', + ['delete_vehicle'] = 'usuń pojazd', + ['delete_veh_param'] = 'naciśnij enter', + ['spawn_object'] = 'pojaw obiekt', + ['spawn_ped'] = 'pojaw peda', + ['spawn_ped_param'] = 'np. a_m_m_hillbilly_01', + ['givemoney'] = 'daj pieniądze', + ['setmoney'] = 'ustaw pieniądze dla gracza', + ['money_type'] = 'aktualne typy pieniędzy: cash, bank, black', + ['money_set'] = 'ktoś ~y~wysoko postawiony~s~ podarował Ci pieniądze i masz teraz ~g~%s$~s~ (%s)!', + ['money_amount'] = 'kwota pieniędzy', + ['invalid_account'] = 'błędne konto', + ['account'] = 'konto', + ['giveaccountmoney'] = 'daj pieniądze na konto', + ['invalid_item'] = 'nieprawidłowy przedmiot', + ['item'] = 'przedmiot', + ['giveitem'] = 'daj przedmiot', + ['weapon'] = 'broń', + ['giveweapon'] = 'daj broń', + ['disconnect'] = 'odłącz się od serwera', + -- Weapons + ['weapon_knife'] = 'nóż', + ['weapon_nightstick'] = 'pałka', + ['weapon_hammer'] = 'młotek', + ['weapon_bat'] = 'kij', + ['weapon_golfclub'] = 'kij golfowy', + ['weapon_crowbar'] = 'łom', + ['weapon_pistol'] = 'pistolet', + ['weapon_combatpistol'] = 'pistolet bojowy', + ['weapon_appistol'] = 'ap pistol', + ['weapon_pistol50'] = 'pistol .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'assault smg', + ['weapon_assaultrifle'] = 'assault rifle', + ['weapon_carbinerifle'] = 'carbine rifle', + ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'combat mg', + ['weapon_pumpshotgun'] = 'pump shotgun', + ['weapon_sawnoffshotgun'] = 'sawed off shotgun', + ['weapon_assaultshotgun'] = 'assault shotgun', + ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'karabin snajperski', + ['weapon_heavysniper'] = 'ciężki karabin snajperski', + ['weapon_remotesniper'] = 'remote sniper', + ['weapon_grenadelauncher'] = 'granatnik', + ['weapon_rpg'] = 'wyrzutnia rakiet', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'granat', + ['weapon_stickybomb'] = 'ładunek przylepny', + ['weapon_smokegrenade'] = 'granat dymny', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'koktajl Mołotowa', + ['weapon_fireextinguisher'] = 'gaśnica', + ['weapon_petrolcan'] = 'kanister', + ['weapon_digiscanner'] = 'skaner częstotliwości', + ['weapon_ball'] = 'piłka', + ['weapon_snspistol'] = 'sns pistolet', + ['weapon_bottle'] = 'butelka', + ['weapon_gusenberg'] = 'gusenberg sweeper', + ['weapon_specialcarbine'] = 'special carbine', + ['weapon_heavypistol'] = 'heavy pistol', + ['weapon_bullpuprifle'] = 'karabin wyborowy', + ['weapon_dagger'] = 'sztylet', + ['weapon_vintagepistol'] = 'vintage pistol', + ['weapon_firework'] = 'fajerwerki', + ['weapon_musket'] = 'muszkiet', + ['weapon_heavyshotgun'] = 'ciężki shotgun', + ['weapon_marksmanrifle'] = 'marksman rifle', + ['weapon_hominglauncher'] = 'program uruchamiający', + ['weapon_proxmine'] = 'mina zbliżeniowa', + ['weapon_snowball'] = 'śnieżka', + ['weapon_flaregun'] = 'flara', + ['weapon_garbagebag'] = 'worek na śmieci', + ['weapon_handcuffs'] = 'kajdanki', + ['weapon_combatpdw'] = 'combat pdw', + ['weapon_marksmanpistol'] = 'marksman pistol', + ['weapon_knuckle'] = 'kastety', + ['weapon_hatchet'] = 'toporek', + ['weapon_railgun'] = 'karabin', + ['weapon_machete'] = 'meczeta', + ['weapon_machinepistol'] = 'pistolet maszynowy', + ['weapon_switchblade'] = 'scyzoryk', + ['weapon_revolver'] = 'ciężki rewolwer', + ['weapon_dbshotgun'] = 'dwururka', + ['weapon_compactrifle'] = 'compact rifle', + ['weapon_autoshotgun'] = 'auto shotgun', + ['weapon_battleaxe'] = 'topór bitewny', + ['weapon_compactlauncher'] = 'compact launcher', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'bomba rurowa', + ['weapon_poolcue'] = 'kij bilardowy', + ['weapon_wrench'] = 'klucz do rur', + ['weapon_flashlight'] = 'latarka', + ['gadget_nightvision'] = 'noktowizor', + ['gadget_parachute'] = 'spadochron', + ['weapon_flare'] = 'pistolet sygnałowy', + ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', + ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', + ['weapon_doubleaction'] = 'Double-Action Revolver', + ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', + ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', + ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', + ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', + ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', + ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', + ['weapon_combatmg_mk2'] = 'Combat MG Mk II', + ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', + ['weapon_pistol_mk2'] = 'Pistol Mk II', + ['weapon_smg_mk2'] = 'SMG Mk II', +} \ No newline at end of file From 7e947b3a4fee2b81c3072a16299d02174a58c1e3 Mon Sep 17 00:00:00 2001 From: Netouss Date: Fri, 20 Jul 2018 16:15:34 +0200 Subject: [PATCH 230/672] Fix French locales Fix multiple little errors and add new translation. --- locales/fr.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index b729c493..41c34d5e 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -6,17 +6,17 @@ Locales['fr'] = { ['give'] = 'donner', ['remove'] = 'jeter', ['return'] = 'retour', - ['give_to'] = 'give to', + ['give_to'] = 'donner à', ['amount'] = 'quantité', - ['giveammo'] = 'give ammo', + ['giveammo'] = 'donner munitions', ['amountammo'] = 'nombre de munitions', ['noammo'] = 'tu n\'as pas toutes ces munitions!', ['gave_item'] = 'vous avez donné ~y~%sx~s~ ~b~%s~s~ à ~y~%s~s~', ['received_item'] = 'vous avez reçu ~y~%sx~s~ ~b~%s~s~ par ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', - ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_weapon'] = 'vous donnez ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ minitions à ~y~%s~s~.', + ['received_weapon'] = 'vous recevez ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ munitions de ~b~%s~s~.', + ['gave_ammo'] = 'vous donnez ~o~%sx~s~ munitions à ~y~%s~s~.', + ['received_ammo'] = 'vous recevez ~o~%sx~s~ munitions de ~b~%s~s~.', ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', ['received_money'] = 'vous avez reçu ~g~$%s~s~ par ~b~%s~s~', ['gave_account_money'] = 'vous avez donné ~g~$%s~s~ (%s) à ~y~%s~s~', @@ -28,12 +28,12 @@ Locales['fr'] = { ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', ['delete_five_min'] = '~r~suppression~s~ dans 5 minutes', ['threw'] = 'vous avez ~r~jeté~s~', - ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', + ['threw_weapon'] = 'vous ~r~jetez~s~ ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ munitions!', -- Salary related ['received_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', ['received_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', ['company_nomoney'] = 'votre entreprise n\'a plus d\'argent pour vous payer!', - ['received_paycheck'] = 'received paycheck', + ['received_paycheck'] = 'paiement reçu', ['bank'] = 'banque', ['black_money'] = 'argent Sale', @@ -73,8 +73,8 @@ Locales['fr'] = { ['weapon_knife'] = 'couteau', ['weapon_nightstick'] = 'matraque', ['weapon_hammer'] = 'marteau', - ['weapon_bat'] = 'bat', - ['weapon_golfclub'] = 'club de golfe', + ['weapon_bat'] = 'batte', + ['weapon_golfclub'] = 'club de golf', ['weapon_crowbar'] = 'pied de biche', ['weapon_pistol'] = 'pistolet', ['weapon_combatpistol'] = 'pistolet de combat', @@ -132,7 +132,7 @@ Locales['fr'] = { ['weapon_knuckle'] = 'poing américain', ['weapon_hatchet'] = 'hachette', ['weapon_railgun'] = 'canon éléctrique', - ['weapon_machete'] = 'machetta', + ['weapon_machete'] = 'machette', ['weapon_machinepistol'] = 'pistolet mitrailleur', ['weapon_switchblade'] = 'couteau à cran d\'arrêt', ['weapon_revolver'] = 'revolver', From 9c2c83d025045989455af06b21971461d682d799 Mon Sep 17 00:00:00 2001 From: Samuel Date: Sat, 21 Jul 2018 18:34:29 +0200 Subject: [PATCH 231/672] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e41d792e..bb376513 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,8 @@ es_extended is a roleplay framework for FiveM. It is developed on top of [Essent - Job system - Loadouts and position synced in database - The best framework out there for RP servers -- i18n (locate) system -- Loads of plugins available +- i18n (locale) system +- Plenty of plugins available ### Requirements This order also applies in the startup order. From 0f528770e6421404177c10442a6f14f16dbfa321 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 28 Jul 2018 15:38:37 +0200 Subject: [PATCH 232/672] Implemented callbacks for ESX.Streaming (desc) closes #113 - ESX.Streaming.RequestClipSet - ESX.Streaming.RequestWeaponAsset - ESX.Streaming.RequestPtfxAsset - ESX.Streaming.RequestNamedPtfxAsset --- client/modules/streaming.lua | 82 +++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/client/modules/streaming.lua b/client/modules/streaming.lua index 6d7d3815..0c278f82 100644 --- a/client/modules/streaming.lua +++ b/client/modules/streaming.lua @@ -1,5 +1,5 @@ -function ESX.Streaming.RequestModel(model) - local modelHash = GetHashKey(model) +function ESX.Streaming.RequestModel(modelHash, cb) + modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash)) if not HasModelLoaded(modelHash) then RequestModel(modelHash) @@ -8,9 +8,13 @@ function ESX.Streaming.RequestModel(model) Citizen.Wait(1) end end + + if cb ~= nil then + cb() + end end -function ESX.Streaming.RequestStreamedTextureDict(textureDict) +function ESX.Streaming.RequestStreamedTextureDict(textureDict, cb) if not HasStreamedTextureDictLoaded(textureDict) then RequestStreamedTextureDict(textureDict) @@ -18,9 +22,41 @@ function ESX.Streaming.RequestStreamedTextureDict(textureDict) Citizen.Wait(1) end end + + if cb ~= nil then + cb() + end end -function ESX.Streaming.RequestAnimSet(animSet) +function ESX.Streaming.RequestPtfxAsset(assetName, cb) + if not HasPtfxAssetLoaded(assetName) then + RequestPtfxAsset(assetName) + + while not HasPtfxAssetLoaded(assetName) do + Citizen.Wait(1) + end + end + + if cb ~= nil then + cb() + end +end + +function ESX.Streaming.RequestNamedPtfxAsset(assetName, cb) + if not HasNamedPtfxAssetLoaded(assetName) then + RequestNamedPtfxAsset(assetName) + + while not HasNamedPtfxAssetLoaded(assetName) do + Citizen.Wait(1) + end + end + + if cb ~= nil then + cb() + end +end + +function ESX.Streaming.RequestAnimSet(animSet, cb) if not HasAnimSetLoaded(animSet) then RequestAnimSet(animSet) @@ -28,9 +64,13 @@ function ESX.Streaming.RequestAnimSet(animSet) Citizen.Wait(1) end end + + if cb ~= nil then + cb() + end end -function ESX.Streaming.RequestAnimDict(animDict) +function ESX.Streaming.RequestAnimDict(animDict, cb) if not HasAnimDictLoaded(animDict) then RequestAnimDict(animDict) @@ -38,4 +78,36 @@ function ESX.Streaming.RequestAnimDict(animDict) Citizen.Wait(1) end end + + if cb ~= nil then + cb() + end +end + +function ESX.Streaming.RequestWeaponAsset(weaponHash, cb) + if not HasWeaponAssetLoaded(weaponHash) then + RequestWeaponAsset(weaponHash) + + while not HasWeaponAssetLoaded(weaponHash) do + Citizen.Wait(1) + end + end + + if cb ~= nil then + cb() + end +end + +function ESX.Streaming.RequestClipSet(clipSet, cb) + if not HasClipSetLoaded(clipSet) then + RequestClipSet(clipSet) + + while not HasClipSetLoaded(clipSet) do + Citizen.Wait(1) + end + end + + if cb ~= nil then + cb() + end end \ No newline at end of file From 5e6714a3239776002f4b5cb383fc520e2bf2bd9c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 5 Aug 2018 13:08:02 +0200 Subject: [PATCH 233/672] Implemented ESX.Game.IsSpawnPointClear(coords, radius) --- client/functions.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index 967b1078..f4b2e459 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -661,6 +661,12 @@ ESX.Game.GetVehicleInDirection = function() return vehicle end +ESX.Game.IsSpawnPointClear = function(coords, radius) + local vehicles = ESX.Game.GetVehiclesInArea(coords, radius) + + return #vehicles == 0 +end + ESX.Game.GetPeds = function(ignoreList) local ignoreList = ignoreList or {} From 941a556ea7dcd640e35599902000e3c66403966d Mon Sep 17 00:00:00 2001 From: nearbyplayer Date: Fri, 10 Aug 2018 00:48:51 -0400 Subject: [PATCH 234/672] Repo Update --- .editorconfig | 2 +- LICENSE.txt => LICENSE | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename LICENSE.txt => LICENSE (100%) diff --git a/.editorconfig b/.editorconfig index 6866fb40..9b425256 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,7 +3,7 @@ root = true [*] indent_size = 4 indent_style = tab -end_of_line = lf +end_of_line = crlf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE similarity index 100% rename from LICENSE.txt rename to LICENSE From 5ac8c6fbfa576660b184a1bb4ffc04e3542cb663 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 11 Aug 2018 23:53:57 +0200 Subject: [PATCH 235/672] Corrected swedish currency --- locales/sv.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/locales/sv.lua b/locales/sv.lua index a9872464..f9b3c19a 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,6 +1,6 @@ Locales['sv'] = { -- Inventory - ['cash'] = 'kontanter $%s', + ['cash'] = 'kontanter %s SEK', ['inventory'] = 'mitt förråd', ['use'] = 'använd', ['give'] = 'ge', @@ -17,10 +17,10 @@ Locales['sv'] = { ['received_weapon'] = 'du tog emot ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~.', ['gave_ammo'] = 'du gav ~o~%sx~s~ skott till ~y~%s~s~.', ['received_ammo'] = 'du tog emot ~o~%sx~s~ skott från ~b~%s~s~.', - ['gave_money'] = 'du gav ~g~$%s~s~ till ~y~%s~s~', - ['received_money'] = 'du tog emot ~g~$%s~s~ från ~b~%s~s~', - ['gave_account_money'] = 'du gav ~g~$%s~s~ (%s) till ~y~%s~s~', - ['received_account_money'] = 'du tog emot ~g~$%s~s~ (%s) från ~b~%s~s~', + ['gave_money'] = 'du gav ~g~%s SEK~s~ till ~y~%s~s~', + ['received_money'] = 'du tog emot ~g~%s SEK~s~ från ~b~%s~s~', + ['gave_account_money'] = 'du gav ~g~%s SEK~s~ (%s) till ~y~%s~s~', + ['received_account_money'] = 'du tog emot ~g~%s SEK~s~ (%s) från ~b~%s~s~', ['amount_invalid'] = 'ogiltig mängd', ['players_nearby'] = 'inga spelare nära', ['ex_inv_lim'] = 'åtgärd inte möjligt, översteg förråd gräns för ~y~%s~s~', @@ -30,8 +30,8 @@ Locales['sv'] = { ['threw'] = 'du ~r~kastade~s~', ['threw_weapon'] = 'du ~r~slängde~s~ ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott!', -- Salary related - ['received_salary'] = 'du har mottagit din lön på ~g~$%s~s~', - ['received_help'] = 'du har mottagit bidrag på ~g~$%s~s~', + ['received_salary'] = 'du har mottagit din lön på ~g~%s SEK~s~', + ['received_help'] = 'du har mottagit bidrag på ~g~%s SEK~s~', ['company_nomoney'] = 'företaget du är anställt hos har inte råd att betala ut din lön.', ['received_paycheck'] = 'mottagit lön', ['bank'] = 'bank', @@ -59,7 +59,7 @@ Locales['sv'] = { ['givemoney'] = 'ge pengar', ['setmoney'] = 'bestäm mängd pengar till en valfri person', ['money_type'] = 'giltiga typer: cash, bank, black', - ['money_set'] = 'någon ~y~högt uppsatt~s~ satte ~g~$%s~s~ (%s) för dig!', + ['money_set'] = 'någon ~y~högt uppsatt~s~ satte ~g~%s SEK~s~ (%s) för dig!', ['money_amount'] = 'summa pengar', ['invalid_account'] = 'ogiltigt konto', ['account'] = 'konto', From 8045af8122e8525cd5bffa41bbf72cf18368d6ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Rychl=C3=BD?= Date: Tue, 14 Aug 2018 23:32:36 +0200 Subject: [PATCH 236/672] Add of Czech translate --- __resource.lua | 2 + locales/cs.lua | 168 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 locales/cs.lua diff --git a/__resource.lua b/__resource.lua index 2556b821..ffa72e02 100644 --- a/__resource.lua +++ b/__resource.lua @@ -16,6 +16,7 @@ server_scripts { 'locales/fi.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/cs.lua', 'config.lua', 'config.weapons.lua', @@ -39,6 +40,7 @@ client_scripts { 'locales/fi.lua', 'locales/sv.lua', 'locales/pl.lua', + 'locales/cs.lua', 'config.lua', 'config.weapons.lua', diff --git a/locales/cs.lua b/locales/cs.lua new file mode 100644 index 00000000..111dc8ee --- /dev/null +++ b/locales/cs.lua @@ -0,0 +1,168 @@ +Locales['cs'] = { + -- Inventory + ['cash'] = 'hotovost $%s', + ['inventory'] = 'inventář', + ['use'] = 'použít', + ['give'] = 'dát', + ['remove'] = 'zahodit', + ['return'] = 'zpět', + ['give_to'] = 'dát', + ['amount'] = 'množství', + ['giveammo'] = 'dát munici', + ['amountammo'] = 'množství munice', + ['noammo'] = 'nemáte dostatek munice!', + ['gave_item'] = 'dali jste ~y~%sx~s~ ~b~%s~s~ ~y~%s~s~', + ['received_item'] = 'obdrželi jste ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', + ['gave_weapon'] = 'dali jste ~y~1x~s~ ~b~%s~s~ s ~o~%sx~s~ náboji ~y~%s~s~.', + ['received_weapon'] = 'obdrželi jste ~y~1x~s~ ~b~%s~s~ s ~o~%sx~s~ náboji od ~b~%s~s~.', + ['gave_ammo'] = 'dali jste ~o~%sx~s~ nábojů ~y~%s~s~.', + ['received_ammo'] = 'obdrželi jste ~o~%sx~s~ nábojů od ~b~%s~s~.', + ['gave_money'] = 'dali jste ~g~$%s~s~ ~y~%s~s~', + ['received_money'] = 'obdrželi jste ~g~$%s~s~ od ~b~%s~s~', + ['gave_account_money'] = 'dali jste ~g~$%s~s~ (%s) ~y~%s~s~', + ['received_account_money'] = 'obdrželi jste ~g~$%s~s~ (%s) od ~b~%s~s~', + ['amount_invalid'] = 'neplatné množství', + ['players_nearby'] = 'žádní hráči poblíž', + ['ex_inv_lim'] = 'akce není možná, překročen limit inventáře pro ~y~%s~s~', + ['imp_invalid_quantity'] = 'akce není možná, neplatný počet', + ['imp_invalid_amount'] = 'akce není možná, neplatné množství', + ['delete_five_min'] = 'věc bude ~r~zahozena~s~ za 5 minut', + ['threw'] = '~r~zahodili~s~ jste', + ['threw_weapon'] = '~r~zahodili~s~ jste ~y~1x~s~ ~b~%s~s~ s ~o~%sx~s~ náboji!', + -- Salary related + ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', + ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', + ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat.', + ['received_paycheck'] = 'obdržena výplata', + ['bank'] = 'bankovní účet', + ['black_money'] = 'špinavé peníze', + + ['act_imp'] = 'akce není možná', + ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', + ['cannot_pickup_room'] = 've vašem inventáři není dostatek místa pro ~y~%s~s~!', + -- Commands + ['setjob'] = 'přiřadit práci hráči', + ['id_param'] = 'iD hráče', + ['setjob_param2'] = 'název přiřazované práce', + ['setjob_param3'] = 'úroveň práce', + ['load_ipl'] = 'načíst IPL', + ['unload_ipl'] = 'odnačíst IPL', + ['play_anim'] = 'přehrát animaci', + ['play_emote'] = 'přehrát emoci', + ['spawn_car'] = 'spawn auto', + ['spawn_car_param'] = 'název auta', + ['delete_vehicle'] = 'odstranit vozidlo', + ['delete_veh_param'] = 'zmáčkněte enter', + ['spawn_object'] = 'spawn objekt', + ['spawn_ped'] = 'spawn peda', + ['spawn_ped_param'] = 'příklad a_m_m_hillbilly_01', + ['givemoney'] = 'dát peníze', + ['setmoney'] = 'nastavit peníze hráči', + ['money_type'] = 'platné typy peněz: cash, bank, black', + ['money_set'] = 'někdo s ~y~vysokou úrovní~s~ vám právě nastavil ~g~$%s~s~ (%s)!', + ['money_amount'] = 'množství peněz', + ['invalid_account'] = 'neplatný účet', + ['account'] = 'účet', + ['giveaccountmoney'] = 'dát peníze na účet', + ['invalid_item'] = 'neplatná věc', + ['item'] = 'věc', + ['giveitem'] = 'dát věc', + ['weapon'] = 'zbraň', + ['giveweapon'] = 'dát zbraň', + ['disconnect'] = 'odpojit od serveru', + ['chat_clear'] = 'vyčistit chat', + ['chat_clear_all'] = 'vyčistit chat pro všechny', + -- Weapons + ['weapon_knife'] = 'knife', + ['weapon_nightstick'] = 'nightstick', + ['weapon_hammer'] = 'hammer', + ['weapon_bat'] = 'bat', + ['weapon_golfclub'] = 'golf club', + ['weapon_crowbar'] = 'crow bar', + ['weapon_pistol'] = 'pistol', + ['weapon_combatpistol'] = 'combat pistol', + ['weapon_appistol'] = 'ap pistol', + ['weapon_pistol50'] = 'pistol .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'assault smg', + ['weapon_assaultrifle'] = 'assault rifle', + ['weapon_carbinerifle'] = 'carbine rifle', + ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'combat mg', + ['weapon_pumpshotgun'] = 'pump shotgun', + ['weapon_sawnoffshotgun'] = 'sawed off shotgun', + ['weapon_assaultshotgun'] = 'assault shotgun', + ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'sniper rifle', + ['weapon_heavysniper'] = 'heavy sniper', + ['weapon_remotesniper'] = 'remote sniper', + ['weapon_grenadelauncher'] = 'grenade launcher', + ['weapon_rpg'] = 'rocket launcher', + ['weapon_stinger'] = 'stinger', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'grenade', + ['weapon_stickybomb'] = 'sticky bomb', + ['weapon_smokegrenade'] = 'smoke grenade', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'molotov cocktail', + ['weapon_fireextinguisher'] = 'fire extinguisher', + ['weapon_petrolcan'] = 'jerrycan', + ['weapon_digiscanner'] = 'digiscanner', + ['weapon_ball'] = 'ball', + ['weapon_snspistol'] = 'sns pistol', + ['weapon_bottle'] = 'bottle', + ['weapon_gusenberg'] = 'gusenberg sweeper', + ['weapon_specialcarbine'] = 'special carbine', + ['weapon_heavypistol'] = 'heavy pistol', + ['weapon_bullpuprifle'] = 'bullpup rifle', + ['weapon_dagger'] = 'dagger', + ['weapon_vintagepistol'] = 'vintage pistol', + ['weapon_firework'] = 'firework', + ['weapon_musket'] = 'musket', + ['weapon_heavyshotgun'] = 'heavy shotgun', + ['weapon_marksmanrifle'] = 'marksman rifle', + ['weapon_hominglauncher'] = 'homing launcher', + ['weapon_proxmine'] = 'proximity mine', + ['weapon_snowball'] = 'snow ball', + ['weapon_flaregun'] = 'flaregun', + ['weapon_garbagebag'] = 'garbage bag', + ['weapon_handcuffs'] = 'handcuffs', + ['weapon_combatpdw'] = 'combat pdw', + ['weapon_marksmanpistol'] = 'marksman pistol', + ['weapon_knuckle'] = 'knuckledusters', + ['weapon_hatchet'] = 'hatchet', + ['weapon_railgun'] = 'railgun', + ['weapon_machete'] = 'machete', + ['weapon_machinepistol'] = 'machine pistol', + ['weapon_switchblade'] = 'switchblade', + ['weapon_revolver'] = 'heavy revolver', + ['weapon_dbshotgun'] = 'double barrel shotgun', + ['weapon_compactrifle'] = 'compact rifle', + ['weapon_autoshotgun'] = 'auto shotgun', + ['weapon_battleaxe'] = 'battle axe', + ['weapon_compactlauncher'] = 'compact launcher', + ['weapon_minismg'] = 'mini smg', + ['weapon_pipebomb'] = 'pipe bomb', + ['weapon_poolcue'] = 'pool cue', + ['weapon_wrench'] = 'pipe wrench', + ['weapon_flashlight'] = 'flashlight', + ['gadget_nightvision'] = 'night vision', + ['gadget_parachute'] = 'parachute', + ['weapon_flare'] = 'flare gun', + ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', + ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', + ['weapon_doubleaction'] = 'Double-Action Revolver', + ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', + ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', + ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', + ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', + ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', + ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', + ['weapon_combatmg_mk2'] = 'Combat MG Mk II', + ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', + ['weapon_pistol_mk2'] = 'Pistol Mk II', + ['weapon_smg_mk2'] = 'SMG Mk II', +} From 36a0c0d0d9ba8b3828205e7460fc22a2881cc2f9 Mon Sep 17 00:00:00 2001 From: Corey McCown Date: Tue, 14 Aug 2018 19:35:39 -0400 Subject: [PATCH 237/672] Fix #114 (#123) Fixes #114 --- client/functions.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index f4b2e459..befcf9e8 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -397,6 +397,7 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) SetNetworkIdCanMigrate(id, true) SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) + SetVehicleNeedsToBeHotwired(vehicle, false) SetModelAsNoLongerNeeded(model) RequestCollisionAtCoord(coords.x, coords.y, coords.z) @@ -432,6 +433,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) + SetVehicleNeedsToBeHotwired(vehicle, false) SetModelAsNoLongerNeeded(model) RequestCollisionAtCoord(coords.x, coords.y, coords.z) From d161162190d3eb22807c377aa50ef147c3af0d29 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 21 Aug 2018 21:23:50 +0200 Subject: [PATCH 238/672] Car delete now uses player direction, Added /cardelete (same as /dv), removed /dv arg --- client/main.lua | 54 ++++++++++++++++++++------------------------- server/commands.lua | 8 ++++++- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/client/main.lua b/client/main.lua index 21140c27..770037d5 100644 --- a/client/main.lua +++ b/client/main.lua @@ -60,7 +60,7 @@ AddEventHandler('playerSpawned', function() Citizen.Wait(1) end - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() -- Restore position if ESX.PlayerData.lastPosition ~= nil then @@ -134,7 +134,7 @@ AddEventHandler('skinchanger:modelLoaded', function() end) AddEventHandler('esx:restoreLoadout', function() - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() RemoveAllPedWeapons(playerPed, true) @@ -206,7 +206,7 @@ end) RegisterNetEvent('esx:addWeapon') AddEventHandler('esx:addWeapon', function(weaponName, ammo) - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) GiveWeaponToPed(playerPed, weaponHash, ammo, false, false) @@ -215,7 +215,7 @@ end) RegisterNetEvent('esx:removeWeapon') AddEventHandler('esx:removeWeapon', function(weaponName, ammo) - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) RemoveWeaponFromPed(playerPed, weaponHash) @@ -239,12 +239,12 @@ AddEventHandler('esx:teleport', function(pos) RequestCollisionAtCoord(pos.x, pos.y, pos.z) - while not HasCollisionLoadedAroundEntity(GetPlayerPed(-1)) do + while not HasCollisionLoadedAroundEntity(PlayerPedId()) do RequestCollisionAtCoord(pos.x, pos.y, pos.z) Citizen.Wait(1) end - SetEntityCoords(GetPlayerPed(-1), pos.x, pos.y, pos.z) + SetEntityCoords(PlayerPedId(), pos.x, pos.y, pos.z) end) @@ -300,7 +300,7 @@ AddEventHandler('esx:playEmote', function(emote) Citizen.CreateThread(function() - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() TaskStartScenarioInPlace(playerPed, emote, 0, false); Citizen.Wait(20000) @@ -313,7 +313,7 @@ end) RegisterNetEvent('esx:spawnVehicle') AddEventHandler('esx:spawnVehicle', function(model) - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) @@ -325,7 +325,7 @@ end) RegisterNetEvent('esx:spawnObject') AddEventHandler('esx:spawnObject', function(model) - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) local forward = GetEntityForwardVector(playerPed) local x, y, z = table.unpack(coords + forward * 1.0) @@ -384,7 +384,7 @@ end) RegisterNetEvent('esx:pickupWeapon') AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName,ammo) - local ped = GetPlayerPed(-1) + local ped = PlayerPedId() local playerPedPos = GetEntityCoords(ped, true) CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, ammo, 1, false, true) @@ -394,7 +394,7 @@ RegisterNetEvent('esx:spawnPed') AddEventHandler('esx:spawnPed', function(model) model = (tonumber(model) ~= nil and tonumber(model) or GetHashKey(model)) - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) local forward = GetEntityForwardVector(playerPed) local x, y, z = table.unpack(coords + forward * 1.0) @@ -403,7 +403,7 @@ AddEventHandler('esx:spawnPed', function(model) RequestModel(model) - while not HasModelLoaded(model) do + while not HasModelLoaded(model) do Citizen.Wait(1) end @@ -415,22 +415,16 @@ end) RegisterNetEvent('esx:deleteVehicle') AddEventHandler('esx:deleteVehicle', function() + local playerPed = PlayerPedId() + local vehicle = ESX.Game.GetVehicleInDirection() - local playerPed = GetPlayerPed(-1) - local coords = GetEntityCoords(playerPed) - - if IsPedInAnyVehicle(playerPed, false) then - - local vehicle = GetVehiclePedIsIn(playerPed, false) - ESX.Game.DeleteVehicle(vehicle) - - elseif IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 5.0) then - - local vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 5.0, 0, 71) - ESX.Game.DeleteVehicle(vehicle) - - end + if IsPedInAnyVehicle(playerPed, false) then + vehicle = GetVehiclePedIsIn(playerPed, false) + end + if DoesEntityExist(vehicle) then + ESX.Game.DeleteVehicle(vehicle) + end end) @@ -457,7 +451,7 @@ Citizen.CreateThread(function() Citizen.Wait(1) - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local loadout = {} local loadoutChanged = false @@ -566,7 +560,7 @@ Citizen.CreateThread(function() Citizen.Wait(0) - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) -- if there's no nearby pickups we can wait a bit to save performance @@ -607,7 +601,7 @@ Citizen.CreateThread(function() if ESX ~= nil and ESX.PlayerLoaded and PlayerSpawned then - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) if not IsEntityDead(playerPed) then @@ -626,7 +620,7 @@ Citizen.CreateThread(function() Citizen.Wait(1000) - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() if IsEntityDead(playerPed) and PlayerSpawned then PlayerSpawned = false diff --git a/server/commands.lua b/server/commands.lua index bb2a343f..9ec51722 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -61,11 +61,17 @@ end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) +TriggerEvent('es:addGroupCommand', 'cardelete', 'admin', function(source, args, user) + TriggerClientEvent('esx:deleteVehicle', source) +end, function(source, args, user) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) +end, {help = _U('delete_vehicle')}) + TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) TriggerClientEvent('esx:deleteVehicle', source) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('delete_vehicle'), params = {{name = "car", help = _U('delete_veh_param')}}}) +end, {help = _U('delete_vehicle')}) TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnPed', source, args[1]) From 0cac67ef863d63b135e1a56afe3e86425c2b8513 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 21 Aug 2018 21:56:35 +0200 Subject: [PATCH 239/672] Renamed new command --- server/commands.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/commands.lua b/server/commands.lua index 9ec51722..bfd0ca9e 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -61,7 +61,7 @@ end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) -TriggerEvent('es:addGroupCommand', 'cardelete', 'admin', function(source, args, user) +TriggerEvent('es:addGroupCommand', 'cardel', 'admin', function(source, args, user) TriggerClientEvent('esx:deleteVehicle', source) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) From 7e31fc90f4e589323a5a8d5d7035023186094774 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 28 Aug 2018 12:02:05 +0200 Subject: [PATCH 240/672] Possible fix for onPlayerKilled event where killer id isn't an active player --- client/functions.lua | 24 ++++++++++++------------ client/main.lua | 42 +++++++++++++++++++++++++----------------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index befcf9e8..ae21a250 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -480,7 +480,7 @@ ESX.Game.GetClosestObject = function(filter, coords) end if coords == nil then - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() coords = GetEntityCoords(playerPed) end @@ -545,7 +545,7 @@ ESX.Game.GetClosestPlayer = function(coords) local closestPlayer = -1 local coords = coords local usePlayerPed = false - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local playerId = PlayerId() if coords == nil then @@ -614,7 +614,7 @@ ESX.Game.GetClosestVehicle = function(coords) local coords = coords if coords == nil then - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() coords = GetEntityCoords(playerPed) end @@ -654,7 +654,7 @@ ESX.Game.GetVehiclesInArea = function(coords, area) end ESX.Game.GetVehicleInDirection = function() - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local playerCoords = GetEntityCoords(playerPed, 1) local inDirection = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 5.0, 0.0) local rayHandle = CastRayPointToPoint(playerCoords.x, playerCoords.y, playerCoords.z, inDirection.x, inDirection.y, inDirection.z, 10, playerPed, 0) @@ -1086,7 +1086,7 @@ end ESX.ShowInventory = function() - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() local elements = {} if ESX.PlayerData.money > 0 then @@ -1104,10 +1104,10 @@ ESX.ShowInventory = function() for i=1, #ESX.PlayerData.accounts, 1 do if ESX.PlayerData.accounts[i].money > 0 then table.insert(elements, { - label = '[' .. ESX.PlayerData.accounts[i].label .. '] $' .. ESX.PlayerData.accounts[i].money, + label = ESX.PlayerData.accounts[i].label .. ' $' .. ESX.PlayerData.accounts[i].money, count = ESX.PlayerData.accounts[i].money, type = 'item_account', - value = ESX.PlayerData.accounts[i].name, + value = ESX.PlayerData.accounts[i].name, usable = false, rare = false, canRemove = true @@ -1135,7 +1135,7 @@ ESX.ShowInventory = function() local weaponHash = GetHashKey(Config.Weapons[i].name) - if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + 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 .. ']', @@ -1169,7 +1169,7 @@ ESX.ShowInventory = function() if data.current.canRemove then if player ~= -1 and distance <= 3.0 then - table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('give'), action = 'give', type = data.current.type, value = data.current.value}) end table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) @@ -1190,7 +1190,7 @@ ESX.ShowInventory = function() local item = data1.current.value local type = data1.current.type - local playerPed = GetPlayerPed(-1) + local playerPed = PlayerPedId() if data1.current.action == 'give' then @@ -1241,7 +1241,7 @@ ESX.ShowInventory = function() local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() local closestPed = GetPlayerPed(closestPlayer) - local sourceAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1), GetHashKey(item)) + local sourceAmmo = GetAmmoInPedWeapon(PlayerPedId(), GetHashKey(item)) if IsPedSittingInAnyVehicle(closestPed) then ESX.ShowNotification(_U('in_vehicle')) @@ -1339,7 +1339,7 @@ ESX.ShowInventory = function() end if type == 'item_weapon' then - local pedAmmo = GetAmmoInPedWeapon(GetPlayerPed(-1),GetHashKey(item)) + local pedAmmo = GetAmmoInPedWeapon(PlayerPedId(),GetHashKey(item)) -- does the player have any ammo for the weapon? if pedAmmo > 0 then diff --git a/client/main.lua b/client/main.lua index 770037d5..7894280c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -90,27 +90,35 @@ end) AddEventHandler('baseevents:onPlayerKilled', function(killerId, data) local playerPed = PlayerPedId() + local killer = GetPlayerFromServerId(killerId) - -- snake text; killerpos actually is the victim - local victimCoords = data.killerpos - local weaponHash = data.weaponhash + if NetworkIsPlayerActive(killer) then + local victimCoords = data.killerpos + local weaponHash = data.weaponhash - data.killerpos = nil - data.weaponhash = nil + data.killerpos = nil + data.weaponhash = nil - local killerPed = GetPlayerPed(GetPlayerFromServerId(killerId)) - local killerCoords = GetEntityCoords(killerPed) - local distance = GetDistanceBetweenCoords(victimCoords[1], victimCoords[2], victimCoords[3], killerCoords, false) + local killerPed = GetPlayerPed(killer) + local killerCoords = GetEntityCoords(killerPed) + local distance = GetDistanceBetweenCoords(victimCoords[1], victimCoords[2], victimCoords[3], killerCoords, false) - table.insert(data, { - victimCoords = victimCoords, - weaponHash = weaponHash, - deathCause = GetPedCauseOfDeath(playerPed), - killed = true, - killerId = killerId, - killerCoords = { table.unpack(killerCoords) }, - distance = ESX.Round(distance) - }) + table.insert(data, { + victimCoords = victimCoords, + weaponHash = weaponHash, + deathCause = GetPedCauseOfDeath(playerPed), + killed = true, + killerId = killerId, + killerCoords = { table.unpack(killerCoords) }, + distance = ESX.Round(distance) + }) + + else + table.insert(data, { + killed = false, + deathCause = GetPedCauseOfDeath(playerPed) + }) + end TriggerEvent('esx:onPlayerDeath', data) TriggerServerEvent('esx:onPlayerDeath', data) From c07cdde7c8b348e092091d68157a5e42cb22817b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 1 Sep 2018 17:43:35 +0200 Subject: [PATCH 241/672] Tab indent update --- client/common.lua | 4 +- client/entityiter.lua | 61 +- client/functions.lua | 1430 +++++++++++++++++-------------------- client/main.lua | 542 +++++++------- client/wrapper.lua | 18 +- html/css/app.css | 126 ++-- html/js/app.js | 1 - html/js/wrapper.js | 50 +- server/classes/player.lua | 869 +++++++++++----------- server/commands.lua | 111 ++- server/common.lua | 77 +- server/functions.lua | 304 ++++---- server/main.lua | 870 +++++++++++----------- shared/functions.lua | 4 + 14 files changed, 2059 insertions(+), 2408 deletions(-) diff --git a/client/common.lua b/client/common.lua index 14b6a4e6..26c0ed40 100644 --- a/client/common.lua +++ b/client/common.lua @@ -1,7 +1,7 @@ AddEventHandler('esx:getSharedObject', function(cb) - cb(ESX) + cb(ESX) end) function getSharedObject() - return ESX + return ESX end diff --git a/client/entityiter.lua b/client/entityiter.lua index 7c7ec4d5..20dd2018 100644 --- a/client/entityiter.lua +++ b/client/entityiter.lua @@ -25,55 +25,50 @@ OTHER DEALINGS IN THE SOFTWARE. ]] local entityEnumerator = { - __gc = function(enum) - if enum.destructor and enum.handle then - enum.destructor(enum.handle) - end - enum.destructor = nil - enum.handle = nil - end + __gc = function(enum) + if enum.destructor and enum.handle then + enum.destructor(enum.handle) + end + + enum.destructor = nil + enum.handle = nil + end } local function EnumerateEntities(initFunc, moveFunc, disposeFunc) - return coroutine.wrap(function() - local iter, id = initFunc() - if not id or id == 0 then - disposeFunc(iter) - return - end + return coroutine.wrap(function() + local iter, id = initFunc() + if not id or id == 0 then + disposeFunc(iter) + return + end - local enum = {handle = iter, destructor = disposeFunc} - setmetatable(enum, entityEnumerator) + local enum = {handle = iter, destructor = disposeFunc} + setmetatable(enum, entityEnumerator) - local next = true - repeat - coroutine.yield(id) - next, id = moveFunc(iter) - until not next + local next = true + repeat + coroutine.yield(id) + next, id = moveFunc(iter) + until not next - enum.destructor, enum.handle = nil, nil - disposeFunc(iter) - end) + enum.destructor, enum.handle = nil, nil + disposeFunc(iter) + end) end function EnumerateObjects() - return EnumerateEntities(FindFirstObject, FindNextObject, EndFindObject) + return EnumerateEntities(FindFirstObject, FindNextObject, EndFindObject) end function EnumeratePeds() - return EnumerateEntities(FindFirstPed, FindNextPed, EndFindPed) + return EnumerateEntities(FindFirstPed, FindNextPed, EndFindPed) end function EnumerateVehicles() - return EnumerateEntities(FindFirstVehicle, FindNextVehicle, EndFindVehicle) + return EnumerateEntities(FindFirstVehicle, FindNextVehicle, EndFindVehicle) end function EnumeratePickups() - return EnumerateEntities(FindFirstPickup, FindNextPickup, EndFindPickup) + return EnumerateEntities(FindFirstPickup, FindNextPickup, EndFindPickup) end - ---[[Usage: -for ped in EnumeratePeds() do - -end -]] diff --git a/client/functions.lua b/client/functions.lua index ae21a250..1867e8ba 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -20,32 +20,28 @@ ESX.Scaleform.Utils = {} ESX.Streaming = {} -ESX.GetConfig = function() - return Config -end - ESX.SetTimeout = function(msec, cb) - table.insert(ESX.TimeoutCallbacks, { - time = GetGameTimer() + msec, - cb = cb - }) - return #ESX.TimeoutCallbacks + table.insert(ESX.TimeoutCallbacks, { + time = GetGameTimer() + msec, + cb = cb + }) + return #ESX.TimeoutCallbacks end ESX.ClearTimeout = function(i) - ESX.TimeoutCallbacks[i] = nil + ESX.TimeoutCallbacks[i] = nil end ESX.IsPlayerLoaded = function() - return ESX.PlayerLoaded + return ESX.PlayerLoaded end ESX.GetPlayerData = function() - return ESX.PlayerData + return ESX.PlayerData end ESX.SetPlayerData = function(key, val) - ESX.PlayerData[key] = val + ESX.PlayerData[key] = val end ESX.ShowNotification = function(msg) @@ -70,587 +66,515 @@ ESX.ShowHelpNotification = function(msg) end ESX.TriggerServerCallback = function(name, cb, ...) + ESX.ServerCallbacks[ESX.CurrentRequestId] = cb - ESX.ServerCallbacks[ESX.CurrentRequestId] = cb - - TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, ...) - - if ESX.CurrentRequestId < 65535 then - ESX.CurrentRequestId = ESX.CurrentRequestId + 1 - else - ESX.CurrentRequestId = 0 - end + TriggerServerEvent('esx:triggerServerCallback', name, ESX.CurrentRequestId, ...) + 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 - }) - + SendNUIMessage({ + action = 'setHUDDisplay', + opacity = opacity + }) end ESX.UI.HUD.RegisterElement = function(name, index, priority, html, data) + local found = false - 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 - 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 - if found then - return - end + table.insert(ESX.UI.HUD.RegisteredElements, name) - 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) + 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 - 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 - }) - + SendNUIMessage({ + action = 'deleteHUDElement', + name = name + }) end ESX.UI.HUD.UpdateElement = function(name, data) - - SendNUIMessage({ - action = 'updateHUDElement', - name = name, - data = 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, - } - + ESX.UI.Menu.RegisteredTypes[type] = { + open = open, + close = close, + } end -local _type = type - ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, close) + local menu = {} - local menu = {} + menu.type = type + menu.namespace = namespace + menu.name = name + menu.data = data + menu.submit = submit + menu.cancel = cancel + menu.change = change - menu.type = type - menu.namespace = namespace - menu.name = name - menu.data = data - menu.submit = submit - menu.cancel = cancel - menu.change = change + menu.close = function() - menu.close = function() + ESX.UI.Menu.RegisteredTypes[type].close(namespace, name) - ESX.UI.Menu.RegisteredTypes[type].close(namespace, name) + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i] ~= nil then + 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 - for i=1, #ESX.UI.Menu.Opened, 1 do + if close ~= nil then + close() + end - if ESX.UI.Menu.Opened[i] ~= nil then - 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 - end + menu.update = function(query, newData) - if close ~= nil then - close() - end + for i=1, #menu.data.elements, 1 do + local match = true - end + for k,v in pairs(query) do + if menu.data.elements[i][k] ~= v then + match = false + end + end - menu.update = function(query, newData) + if match then + for k,v in pairs(newData) do + menu.data.elements[i][k] = v + end + end + end - for i=1, #menu.data.elements, 1 do + end - local match = true + menu.refresh = function() + ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data) + end - for k,v in pairs(query) do - if menu.data.elements[i][k] ~= v then - match = false - end - end + menu.setElement = function(i, key, val) + menu.data.elements[i][key] = val + end - if match then - for k,v in pairs(newData) do - menu.data.elements[i][k] = v - end - end - - end - - end - - menu.refresh = function() - ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, menu.data) - 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) - - return menu + table.insert(ESX.UI.Menu.Opened, menu) + ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, data) + return menu end ESX.UI.Menu.Close = function(type, namespace, name) - - for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then - 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 - + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i] ~= nil then + 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 end ESX.UI.Menu.CloseAll = function() - - for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then - ESX.UI.Menu.Opened[i].close() - ESX.UI.Menu.Opened[i] = nil - end - end - + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i] ~= nil then + ESX.UI.Menu.Opened[i].close() + ESX.UI.Menu.Opened[i] = nil + end + 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] ~= nil then - 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 - + for i=1, #ESX.UI.Menu.Opened, 1 do + if ESX.UI.Menu.Opened[i] ~= nil then + 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 end ESX.UI.Menu.GetOpenedMenus = function() - return ESX.UI.Menu.Opened + return ESX.UI.Menu.Opened end ESX.UI.Menu.IsOpen = function(type, namespace, name) - return ESX.UI.Menu.GetOpened(type, namespace, name) ~= nil + 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 - }) + SendNUIMessage({ + action = 'inventoryNotification', + add = add, + item = item, + count = count + }) end ESX.GetWeaponList = function() - return Config.Weapons + return Config.Weapons end ESX.GetWeaponLabel = function(name) + name = string.upper(name) + local weapons = ESX.GetWeaponList() - 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 - + for i=1, #weapons, 1 do + if weapons[i].name == name then + return weapons[i].label + end + end end ESX.Game.GetPedMugshot = function(ped) - local mugshot = RegisterPedheadshot(ped) - while not IsPedheadshotReady(mugshot) do - Citizen.Wait(0) - end + local mugshot = RegisterPedheadshot(ped) + while not IsPedheadshotReady(mugshot) do + Citizen.Wait(0) + end - return mugshot, GetPedheadshotTxdString(mugshot) + return mugshot, GetPedheadshotTxdString(mugshot) end ESX.Game.Teleport = function(entity, coords, cb) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) - RequestCollisionAtCoord(coords.x, coords.y, coords.z) + while not HasCollisionLoadedAroundEntity(entity) do + RequestCollisionAtCoord(coords.x, coords.x, coords.x) + Citizen.Wait(0) + end - while not HasCollisionLoadedAroundEntity(entity) do - RequestCollisionAtCoord(coords.x, coords.x, coords.x) - Citizen.Wait(0) - end - - SetEntityCoords(entity, coords.x, coords.y, coords.z) - - if cb ~= nil then - cb() - end + SetEntityCoords(entity, coords.x, coords.y, coords.z) + if cb ~= nil then + cb() + end end ESX.Game.SpawnObject = function(model, coords, cb) + local model = (type(model) == 'number' and model or GetHashKey(model)) - local model = (type(model) == 'number' and model or GetHashKey(model)) + Citizen.CreateThread(function() + RequestModel(model) - Citizen.CreateThread(function() + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end - - local obj = CreateObject(model, coords.x, coords.y, coords.z, true, true, true) - - if cb ~= nil then - cb(obj) - end - - end) + local obj = CreateObject(model, coords.x, coords.y, coords.z, true, true, true) + if cb ~= nil then + cb(obj) + end + end) end ESX.Game.SpawnLocalObject = function(model, coords, cb) + local model = (type(model) == 'number' and model or GetHashKey(model)) - local model = (type(model) == 'number' and model or GetHashKey(model)) + Citizen.CreateThread(function() + RequestModel(model) - Citizen.CreateThread(function() + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end - - local obj = CreateObject(model, coords.x, coords.y, coords.z, false, true, true) - - if cb ~= nil then - cb(obj) - end - - end) + local obj = CreateObject(model, coords.x, coords.y, coords.z, false, true, true) + if cb ~= nil then + cb(obj) + end + end) end ESX.Game.DeleteVehicle = function(vehicle) - SetEntityAsMissionEntity(vehicle, false, true) - DeleteVehicle(vehicle) + SetEntityAsMissionEntity(vehicle, false, true) + DeleteVehicle(vehicle) end ESX.Game.DeleteObject = function(object) - SetEntityAsMissionEntity(object, false, true) - DeleteObject(object) + SetEntityAsMissionEntity(object, false, true) + DeleteObject(object) end ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) + local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) - local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) + Citizen.CreateThread(function() + RequestModel(model) - Citizen.CreateThread(function() + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - RequestModel(model) + local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) + local id = NetworkGetNetworkIdFromEntity(vehicle) - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + SetNetworkIdCanMigrate(id, true) + SetEntityAsMissionEntity(vehicle, true, false) + SetVehicleHasBeenOwnedByPlayer(vehicle, true) + SetVehicleNeedsToBeHotwired(vehicle, false) + SetModelAsNoLongerNeeded(model) - local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) - local id = NetworkGetNetworkIdFromEntity(vehicle) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) - SetNetworkIdCanMigrate(id, true) - SetEntityAsMissionEntity(vehicle, true, false) - SetVehicleHasBeenOwnedByPlayer(vehicle, true) - SetVehicleNeedsToBeHotwired(vehicle, false) - SetModelAsNoLongerNeeded(model) + while not HasCollisionLoadedAroundEntity(vehicle) do + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + Citizen.Wait(0) + end - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - - while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - Citizen.Wait(0) - end - - SetVehRadioStation(vehicle, 'OFF') - - if cb ~= nil then - cb(vehicle) - end - - end) + SetVehRadioStation(vehicle, 'OFF') + if cb ~= nil then + cb(vehicle) + end + end) end ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) + local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) - local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) + Citizen.CreateThread(function() + RequestModel(model) - Citizen.CreateThread(function() + while not HasModelLoaded(model) do + Citizen.Wait(0) + end - RequestModel(model) + local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + SetEntityAsMissionEntity(vehicle, true, false) + SetVehicleHasBeenOwnedByPlayer(vehicle, true) + SetVehicleNeedsToBeHotwired(vehicle, false) + SetModelAsNoLongerNeeded(model) - local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) - SetEntityAsMissionEntity(vehicle, true, false) - SetVehicleHasBeenOwnedByPlayer(vehicle, true) - SetVehicleNeedsToBeHotwired(vehicle, false) - SetModelAsNoLongerNeeded(model) + while not HasCollisionLoadedAroundEntity(vehicle) do + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + Citizen.Wait(0) + end - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - - while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - Citizen.Wait(0) - end - - SetVehRadioStation(vehicle, 'OFF') - - if cb ~= nil then - cb(vehicle) - end - - end) + SetVehRadioStation(vehicle, 'OFF') + if cb ~= nil then + cb(vehicle) + end + end) end ESX.Game.GetObjects = function() + local objects = {} - local objects = {} - - for object in EnumerateObjects() do - table.insert(objects, object) - end - - return objects + for object in EnumerateObjects() do + table.insert(objects, object) + end + return objects end ESX.Game.GetClosestObject = function(filter, coords) + local objects = ESX.Game.GetObjects() + local closestDistance = -1 + local closestObject = -1 + local filter = filter + local coords = coords - local objects = ESX.Game.GetObjects() - local closestDistance = -1 - local closestObject = -1 - local filter = filter - local coords = coords + if type(filter) == 'string' then + if filter ~= '' then + filter = {filter} + end + end - if type(filter) == 'string' then - if filter ~= '' then - filter = {filter} - end - end + if coords == nil then + local playerPed = PlayerPedId() + coords = GetEntityCoords(playerPed) + end - if coords == nil then - local playerPed = PlayerPedId() - coords = GetEntityCoords(playerPed) - end + for i=1, #objects, 1 do - for i=1, #objects, 1 do + local foundObject = false - local foundObject = false + if filter == nil or (type(filter) == 'table' and #filter == 0) then + foundObject = true + else - if filter == nil or (type(filter) == 'table' and #filter == 0) then - foundObject = true - else + local objectModel = GetEntityModel(objects[i]) - local objectModel = GetEntityModel(objects[i]) + for j=1, #filter, 1 do + if objectModel == GetHashKey(filter[j]) then + foundObject = true + end + end - for j=1, #filter, 1 do - if objectModel == GetHashKey(filter[j]) then - foundObject = true - end - end + end - end + if foundObject then + local objectCoords = GetEntityCoords(objects[i]) + local distance = GetDistanceBetweenCoords(objectCoords.x, objectCoords.y, objectCoords.z, coords.x, coords.y, coords.z, true) - if foundObject then + if closestDistance == -1 or closestDistance > distance then + closestObject = objects[i] + closestDistance = distance + end + end - local objectCoords = GetEntityCoords(objects[i]) - local distance = GetDistanceBetweenCoords(objectCoords.x, objectCoords.y, objectCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestObject = objects[i] - closestDistance = distance - end - - end - - end - - return closestObject, closestDistance + end + return closestObject, closestDistance end ESX.Game.GetPlayers = function() + local maxPlayers = Config.MaxPlayers + local players = {} - local maxPlayers = Config.MaxPlayers - local players = {} + for i=0, maxPlayers, 1 do - for i=0, maxPlayers, 1 do + local ped = GetPlayerPed(i) - local ped = GetPlayerPed(i) - - if DoesEntityExist(ped) then - table.insert(players, i) - end - end - - return players + if DoesEntityExist(ped) then + table.insert(players, i) + end + end + return players end ESX.Game.GetClosestPlayer = function(coords) + local players = ESX.Game.GetPlayers() + local closestDistance = -1 + local closestPlayer = -1 + local coords = coords + local usePlayerPed = false + local playerPed = PlayerPedId() + local playerId = PlayerId() - local players = ESX.Game.GetPlayers() - local closestDistance = -1 - local closestPlayer = -1 - local coords = coords - local usePlayerPed = false - local playerPed = PlayerPedId() - local playerId = PlayerId() + if coords == nil then + usePlayerPed = true + coords = GetEntityCoords(playerPed) + end - if coords == nil then - usePlayerPed = true - coords = GetEntityCoords(playerPed) - end + for i=1, #players, 1 do + local target = GetPlayerPed(players[i]) - for i=1, #players, 1 do + if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then + local targetCoords = GetEntityCoords(target) + local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) - local target = GetPlayerPed(players[i]) + if closestDistance == -1 or closestDistance > distance then + closestPlayer = players[i] + closestDistance = distance + end + end + end - if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then - - local targetCoords = GetEntityCoords(target) - local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestPlayer = players[i] - closestDistance = distance - end - - end - - end - - return closestPlayer, closestDistance + return closestPlayer, closestDistance end ESX.Game.GetPlayersInArea = function(coords, area) + local players = ESX.Game.GetPlayers() + local playersInArea = {} - 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) - for i=1, #players, 1 do + if distance <= area then + table.insert(playersInArea, players[i]) + end + end - 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 + return playersInArea end ESX.Game.GetVehicles = function() + local vehicles = {} - local vehicles = {} - - for vehicle in EnumerateVehicles() do - table.insert(vehicles, vehicle) - end - - return vehicles + for vehicle in EnumerateVehicles() do + table.insert(vehicles, vehicle) + end + return vehicles end ESX.Game.GetClosestVehicle = function(coords) + local vehicles = ESX.Game.GetVehicles() + local closestDistance = -1 + local closestVehicle = -1 + local coords = coords - local vehicles = ESX.Game.GetVehicles() - local closestDistance = -1 - local closestVehicle = -1 - local coords = coords + if coords == nil then + local playerPed = PlayerPedId() + coords = GetEntityCoords(playerPed) + end - if coords == nil then - local playerPed = PlayerPedId() - coords = GetEntityCoords(playerPed) - end + for i=1, #vehicles, 1 do + local vehicleCoords = GetEntityCoords(vehicles[i]) + local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) - for i=1, #vehicles, 1 do - - local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestVehicle = vehicles[i] - closestDistance = distance - end - - end - - return closestVehicle, closestDistance + if closestDistance == -1 or closestDistance > distance then + closestVehicle = vehicles[i] + closestDistance = distance + end + end + return closestVehicle, closestDistance end ESX.Game.GetVehiclesInArea = function(coords, area) + local vehicles = ESX.Game.GetVehicles() + local vehiclesInArea = {} - local vehicles = ESX.Game.GetVehicles() - local vehiclesInArea = {} + for i=1, #vehicles, 1 do + local vehicleCoords = GetEntityCoords(vehicles[i]) + local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) - for i=1, #vehicles, 1 do + if distance <= area then + table.insert(vehiclesInArea, vehicles[i]) + end + end - local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) - - if distance <= area then - table.insert(vehiclesInArea, vehicles[i]) - end - - end - - return vehiclesInArea + return vehiclesInArea end ESX.Game.GetVehicleInDirection = function() @@ -670,434 +594,417 @@ ESX.Game.IsSpawnPointClear = function(coords, radius) end ESX.Game.GetPeds = function(ignoreList) + local ignoreList = ignoreList or {} + local peds = {} - local ignoreList = ignoreList or {} - local peds = {} + for ped in EnumeratePeds() do + local found = false - for ped in EnumeratePeds() do + for j=1, #ignoreList, 1 do + if ignoreList[j] == ped then + found = true + end + end - local found = false - - for j=1, #ignoreList, 1 do - if ignoreList[j] == ped then - found = true - end - end - - if not found then - table.insert(peds, ped) - end - - end - - return peds + if not found then + table.insert(peds, ped) + end + end + return peds end ESX.Game.GetClosestPed = function(coords, ignoreList) + local ignoreList = ignoreList or {} + local peds = ESX.Game.GetPeds(ignoreList) + local closestDistance = -1 + local closestPed = -1 - local ignoreList = ignoreList or {} - local peds = ESX.Game.GetPeds(ignoreList) - local closestDistance = -1 - local closestPed = -1 + for i=1, #peds, 1 do + local pedCoords = GetEntityCoords(peds[i]) + local distance = GetDistanceBetweenCoords(pedCoords.x, pedCoords.y, pedCoords.z, coords.x, coords.y, coords.z, true) - for i=1, #peds, 1 do - - local pedCoords = GetEntityCoords(peds[i]) - local distance = GetDistanceBetweenCoords(pedCoords.x, pedCoords.y, pedCoords.z, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestPed = peds[i] - closestDistance = distance - end - - end - - return closestPed, closestDistance + if closestDistance == -1 or closestDistance > distance then + closestPed = peds[i] + closestDistance = distance + end + end + return closestPed, closestDistance end ESX.Game.GetVehicleProperties = function(vehicle) + local color1, color2 = GetVehicleColours(vehicle) + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - local color1, color2 = GetVehicleColours(vehicle) - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + return { - return { + model = GetEntityModel(vehicle), - model = GetEntityModel(vehicle), + plate = GetVehicleNumberPlateText(vehicle), + plateIndex = GetVehicleNumberPlateTextIndex(vehicle), - plate = GetVehicleNumberPlateText(vehicle), - plateIndex = GetVehicleNumberPlateTextIndex(vehicle), + health = GetEntityHealth(vehicle), + dirtLevel = GetVehicleDirtLevel(vehicle), - health = GetEntityHealth(vehicle), - dirtLevel = GetVehicleDirtLevel(vehicle), + color1 = color1, + color2 = color2, - color1 = color1, - color2 = color2, + pearlescentColor = pearlescentColor, + wheelColor = wheelColor, - pearlescentColor = pearlescentColor, - wheelColor = wheelColor, + wheels = GetVehicleWheelType(vehicle), + windowTint = GetVehicleWindowTint(vehicle), - wheels = GetVehicleWheelType(vehicle), - windowTint = GetVehicleWindowTint(vehicle), + neonEnabled = { + IsVehicleNeonLightEnabled(vehicle, 0), + IsVehicleNeonLightEnabled(vehicle, 1), + IsVehicleNeonLightEnabled(vehicle, 2), + IsVehicleNeonLightEnabled(vehicle, 3) + }, - neonEnabled = { - IsVehicleNeonLightEnabled(vehicle, 0), - IsVehicleNeonLightEnabled(vehicle, 1), - IsVehicleNeonLightEnabled(vehicle, 2), - IsVehicleNeonLightEnabled(vehicle, 3), - }, + neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), - neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), - tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(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), - 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), - 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), + modSmokeEnabled = IsToggleModOn(vehicle, 20), + modXenon = IsToggleModOn(vehicle, 22), - modTurbo = IsToggleModOn(vehicle, 18), - modSmokeEnabled = IsToggleModOn(vehicle, 20), - modXenon = IsToggleModOn(vehicle, 22), - - modFrontWheels = GetVehicleMod(vehicle, 23), - modBackWheels = GetVehicleMod(vehicle, 24), - - modPlateHolder = GetVehicleMod(vehicle, 25), - modVanityPlate = GetVehicleMod(vehicle, 26), - modTrimA = GetVehicleMod(vehicle, 27), - modOrnaments = GetVehicleMod(vehicle, 28), - modDashboard = GetVehicleMod(vehicle, 29), - modDial = GetVehicleMod(vehicle, 30), - modDoorSpeaker = GetVehicleMod(vehicle, 31), - modSeats = GetVehicleMod(vehicle, 32), - modSteeringWheel = GetVehicleMod(vehicle, 33), - modShifterLeavers = GetVehicleMod(vehicle, 34), - modAPlate = GetVehicleMod(vehicle, 35), - modSpeakers = GetVehicleMod(vehicle, 36), - modTrunk = GetVehicleMod(vehicle, 37), - modHydrolic = GetVehicleMod(vehicle, 38), - modEngineBlock = GetVehicleMod(vehicle, 39), - modAirFilter = GetVehicleMod(vehicle, 40), - modStruts = GetVehicleMod(vehicle, 41), - modArchCover = GetVehicleMod(vehicle, 42), - modAerials = GetVehicleMod(vehicle, 43), - modTrimB = GetVehicleMod(vehicle, 44), - modTank = GetVehicleMod(vehicle, 45), - modWindows = GetVehicleMod(vehicle, 46), - modLivery = GetVehicleMod(vehicle, 48) - } + modFrontWheels = GetVehicleMod(vehicle, 23), + modBackWheels = GetVehicleMod(vehicle, 24), + modPlateHolder = GetVehicleMod(vehicle, 25), + modVanityPlate = GetVehicleMod(vehicle, 26), + modTrimA = GetVehicleMod(vehicle, 27), + modOrnaments = GetVehicleMod(vehicle, 28), + modDashboard = GetVehicleMod(vehicle, 29), + modDial = GetVehicleMod(vehicle, 30), + modDoorSpeaker = GetVehicleMod(vehicle, 31), + modSeats = GetVehicleMod(vehicle, 32), + modSteeringWheel = GetVehicleMod(vehicle, 33), + modShifterLeavers = GetVehicleMod(vehicle, 34), + modAPlate = GetVehicleMod(vehicle, 35), + modSpeakers = GetVehicleMod(vehicle, 36), + modTrunk = GetVehicleMod(vehicle, 37), + modHydrolic = GetVehicleMod(vehicle, 38), + modEngineBlock = GetVehicleMod(vehicle, 39), + modAirFilter = GetVehicleMod(vehicle, 40), + modStruts = GetVehicleMod(vehicle, 41), + modArchCover = GetVehicleMod(vehicle, 42), + modAerials = GetVehicleMod(vehicle, 43), + modTrimB = GetVehicleMod(vehicle, 44), + modTank = GetVehicleMod(vehicle, 45), + modWindows = GetVehicleMod(vehicle, 46), + modLivery = GetVehicleMod(vehicle, 48) + } end ESX.Game.SetVehicleProperties = function(vehicle, props) + SetVehicleModKit(vehicle, 0) - SetVehicleModKit(vehicle, 0) + if props.plate ~= nil then + SetVehicleNumberPlateText(vehicle, props.plate) + end - if props.plate ~= nil then - SetVehicleNumberPlateText(vehicle, props.plate) - end + if props.plateIndex ~= nil then + SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) + end - if props.plateIndex ~= nil then - SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) - end + if props.health ~= nil then + SetEntityHealth(vehicle, props.health) + end - if props.health ~= nil then - SetEntityHealth(vehicle, props.health) - end + if props.dirtLevel ~= nil then + SetVehicleDirtLevel(vehicle, props.dirtLevel) + end - if props.dirtLevel ~= nil then - SetVehicleDirtLevel(vehicle, props.dirtLevel) - end + if props.color1 ~= nil then + local color1, color2 = GetVehicleColours(vehicle) + SetVehicleColours(vehicle, props.color1, color2) + end - if props.color1 ~= nil then - local color1, color2 = GetVehicleColours(vehicle) - SetVehicleColours(vehicle, props.color1, color2) - end + if props.color2 ~= nil then + local color1, color2 = GetVehicleColours(vehicle) + SetVehicleColours(vehicle, color1, props.color2) + end - if props.color2 ~= nil then - local color1, color2 = GetVehicleColours(vehicle) - SetVehicleColours(vehicle, color1, props.color2) - end + if props.pearlescentColor ~= nil then + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) + end - if props.pearlescentColor ~= nil then - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) - end + if props.wheelColor ~= nil then + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) + end - if props.wheelColor ~= nil then - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) - end + if props.wheels ~= nil then + SetVehicleWheelType(vehicle, props.wheels) + end - if props.wheels ~= nil then - SetVehicleWheelType(vehicle, props.wheels) - end + if props.windowTint ~= nil then + SetVehicleWindowTint(vehicle, props.windowTint) + end - if props.windowTint ~= nil then - SetVehicleWindowTint(vehicle, props.windowTint) - end + if props.neonEnabled ~= nil then + SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) + SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) + SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) + SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) + end - if props.neonEnabled ~= nil then - SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) - SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) - SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) - SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) - end + if props.neonColor ~= nil then + SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) + end - if props.neonColor ~= nil then - SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) - end + if props.modSmokeEnabled ~= nil then + ToggleVehicleMod(vehicle, 20, true) + end - if props.modSmokeEnabled ~= nil then - ToggleVehicleMod(vehicle, 20, true) - end + if props.tyreSmokeColor ~= nil then + SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) + end - if props.tyreSmokeColor ~= nil then - SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) - end + if props.modSpoilers ~= nil then + SetVehicleMod(vehicle, 0, props.modSpoilers, false) + 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.modFrontBumper ~= nil then - SetVehicleMod(vehicle, 1, props.modFrontBumper, false) - end + if props.modRearBumper ~= nil then + SetVehicleMod(vehicle, 2, props.modRearBumper, 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.modSideSkirt ~= nil then - SetVehicleMod(vehicle, 3, props.modSideSkirt, false) - end + if props.modExhaust ~= nil then + SetVehicleMod(vehicle, 4, props.modExhaust, 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.modFrame ~= nil then - SetVehicleMod(vehicle, 5, props.modFrame, false) - end + if props.modGrille ~= nil then + SetVehicleMod(vehicle, 6, props.modGrille, 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.modHood ~= nil then - SetVehicleMod(vehicle, 7, props.modHood, false) - end + if props.modFender ~= nil then + SetVehicleMod(vehicle, 8, props.modFender, 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.modRightFender ~= nil then - SetVehicleMod(vehicle, 9, props.modRightFender, false) - end + if props.modRoof ~= nil then + SetVehicleMod(vehicle, 10, props.modRoof, 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.modEngine ~= nil then - SetVehicleMod(vehicle, 11, props.modEngine, false) - end + if props.modBrakes ~= nil then + SetVehicleMod(vehicle, 12, props.modBrakes, 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.modTransmission ~= nil then - SetVehicleMod(vehicle, 13, props.modTransmission, false) - end + if props.modHorns ~= nil then + SetVehicleMod(vehicle, 14, props.modHorns, 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.modSuspension ~= nil then - SetVehicleMod(vehicle, 15, props.modSuspension, false) - end + if props.modArmor ~= nil then + SetVehicleMod(vehicle, 16, props.modArmor, 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.modTurbo ~= nil then - ToggleVehicleMod(vehicle, 18, props.modTurbo) - end + if props.modXenon ~= nil then + ToggleVehicleMod(vehicle, 22, props.modXenon) + 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.modFrontWheels ~= nil then - SetVehicleMod(vehicle, 23, props.modFrontWheels, false) - end + if props.modBackWheels ~= nil then + SetVehicleMod(vehicle, 24, props.modBackWheels, false) + end - if props.modBackWheels ~= nil then - SetVehicleMod(vehicle, 24, props.modBackWheels, false) - end + if props.modPlateHolder ~= nil then + SetVehicleMod(vehicle, 25, props.modPlateHolder, false) + end - if props.modPlateHolder ~= nil then - SetVehicleMod(vehicle, 25, props.modPlateHolder , false) - end + if props.modVanityPlate ~= nil then + SetVehicleMod(vehicle, 26, props.modVanityPlate, false) + end - if props.modVanityPlate ~= nil then - SetVehicleMod(vehicle, 26, props.modVanityPlate , false) - end + if props.modTrimA ~= nil then + SetVehicleMod(vehicle, 27, props.modTrimA, false) + end - if props.modTrimA ~= nil then - SetVehicleMod(vehicle, 27, props.modTrimA , false) - end + if props.modOrnaments ~= nil then + SetVehicleMod(vehicle, 28, props.modOrnaments, false) + end - if props.modOrnaments ~= nil then - SetVehicleMod(vehicle, 28, props.modOrnaments , false) - end + if props.modDashboard ~= nil then + SetVehicleMod(vehicle, 29, props.modDashboard, false) + end - if props.modDashboard ~= nil then - SetVehicleMod(vehicle, 29, props.modDashboard , false) - end + if props.modDial ~= nil then + SetVehicleMod(vehicle, 30, props.modDial, false) + end - if props.modDial ~= nil then - SetVehicleMod(vehicle, 30, props.modDial , false) - end + if props.modDoorSpeaker ~= nil then + SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) + end - if props.modDoorSpeaker ~= nil then - SetVehicleMod(vehicle, 31, props.modDoorSpeaker , false) - end + if props.modSeats ~= nil then + SetVehicleMod(vehicle, 32, props.modSeats, false) + end - if props.modSeats ~= nil then - SetVehicleMod(vehicle, 32, props.modSeats , false) - end + if props.modSteeringWheel ~= nil then + SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) + end - if props.modSteeringWheel ~= nil then - SetVehicleMod(vehicle, 33, props.modSteeringWheel , false) - end + if props.modShifterLeavers ~= nil then + SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) + end - if props.modShifterLeavers ~= nil then - SetVehicleMod(vehicle, 34, props.modShifterLeavers , false) - end + if props.modAPlate ~= nil then + SetVehicleMod(vehicle, 35, props.modAPlate, false) + end - if props.modAPlate ~= nil then - SetVehicleMod(vehicle, 35, props.modAPlate , false) - end + if props.modSpeakers ~= nil then + SetVehicleMod(vehicle, 36, props.modSpeakers, false) + end - if props.modSpeakers ~= nil then - SetVehicleMod(vehicle, 36, props.modSpeakers , false) - end + if props.modTrunk ~= nil then + SetVehicleMod(vehicle, 37, props.modTrunk, false) + end - if props.modTrunk ~= nil then - SetVehicleMod(vehicle, 37, props.modTrunk , false) - end + if props.modHydrolic ~= nil then + SetVehicleMod(vehicle, 38, props.modHydrolic, false) + end - if props.modHydrolic ~= nil then - SetVehicleMod(vehicle, 38, props.modHydrolic , false) - end + if props.modEngineBlock ~= nil then + SetVehicleMod(vehicle, 39, props.modEngineBlock, false) + end - if props.modEngineBlock ~= nil then - SetVehicleMod(vehicle, 39, props.modEngineBlock , false) - end + if props.modAirFilter ~= nil then + SetVehicleMod(vehicle, 40, props.modAirFilter, false) + end - if props.modAirFilter ~= nil then - SetVehicleMod(vehicle, 40, props.modAirFilter , false) - end + if props.modStruts ~= nil then + SetVehicleMod(vehicle, 41, props.modStruts, false) + end - if props.modStruts ~= nil then - SetVehicleMod(vehicle, 41, props.modStruts , false) - end + if props.modArchCover ~= nil then + SetVehicleMod(vehicle, 42, props.modArchCover, false) + end - if props.modArchCover ~= nil then - SetVehicleMod(vehicle, 42, props.modArchCover , false) - end + if props.modAerials ~= nil then + SetVehicleMod(vehicle, 43, props.modAerials, false) + end - if props.modAerials ~= nil then - SetVehicleMod(vehicle, 43, props.modAerials , false) - end + if props.modTrimB ~= nil then + SetVehicleMod(vehicle, 44, props.modTrimB, false) + end - if props.modTrimB ~= nil then - SetVehicleMod(vehicle, 44, props.modTrimB , false) - end + if props.modTank ~= nil then + SetVehicleMod(vehicle, 45, props.modTank, false) + end - if props.modTank ~= nil then - SetVehicleMod(vehicle, 45, props.modTank , false) - end - - if props.modWindows ~= nil then - SetVehicleMod(vehicle, 46, props.modWindows , false) - end - - if props.modLivery ~= nil then - SetVehicleMod(vehicle, 48, props.modLivery , false) - end + if props.modWindows ~= nil then + SetVehicleMod(vehicle, 46, props.modWindows, false) + end + if props.modLivery ~= nil then + SetVehicleMod(vehicle, 48, props.modLivery, false) + end end ESX.Game.Utils.DrawText3D = function(coords, text, size) + local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) + local camCoords = GetGameplayCamCoords() + local dist = GetDistanceBetweenCoords(camCoords.x, camCoords.y, camCoords.z, coords.x, coords.y, coords.z, 1) + local size = size - local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) - local camCoords = GetGameplayCamCoords() - local dist = GetDistanceBetweenCoords(camCoords.x, camCoords.y, camCoords.z, coords.x, coords.y, coords.z, 1) - local size = size + if size == nil then + size = 1 + end - if size == nil then - size = 1 - end + local scale = (size / dist) * 2 + local fov = (1 / GetGameplayCamFov()) * 100 + local scale = scale * fov - local scale = (size / dist) * 2 - local fov = (1 / GetGameplayCamFov()) * 100 - local scale = scale * fov - - if onScreen then - - SetTextScale(0.0 * scale, 0.55 * scale) - SetTextFont(0) - SetTextProportional(1) - SetTextColour(255, 255, 255, 255) - SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(2, 0, 0, 0, 150) - SetTextDropShadow() - SetTextOutline() - SetTextEntry('STRING') - SetTextCentre(1) - - AddTextComponentString(text) - - DrawText(x, y) - end + if onScreen then + SetTextScale(0.0 * scale, 0.55 * scale) + SetTextFont(0) + SetTextProportional(1) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0, 0, 0, 0, 255) + SetTextEdge(2, 0, 0, 0, 150) + SetTextDropShadow() + SetTextOutline() + SetTextEntry('STRING') + SetTextCentre(1) + AddTextComponentString(text) + DrawText(x, y) + end end ESX.ShowInventory = function() - local playerPed = PlayerPedId() local elements = {} if ESX.PlayerData.money > 0 then table.insert(elements, { - label = _U('cash', ESX.PlayerData.money), - count = ESX.PlayerData.money, - type = 'item_money', - value = 'money', - usable = false, - rare = false, - canRemove = true + label = _U('cash', ESX.PlayerData.money), + count = ESX.PlayerData.money, + type = 'item_money', + value = 'money', + usable = false, + rare = false, + canRemove = true }) end @@ -1339,8 +1246,8 @@ ESX.ShowInventory = function() end if type == 'item_weapon' then - local pedAmmo = GetAmmoInPedWeapon(PlayerPedId(),GetHashKey(item)) - + local pedAmmo = GetAmmoInPedWeapon(PlayerPedId(), GetHashKey(item)) + -- does the player have any ammo for the weapon? if pedAmmo > 0 then ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', @@ -1410,7 +1317,7 @@ ESX.ShowInventory = function() ESX.ShowNotification(_U('in_vehicle')) return end - + if closestPlayer ~= -1 and closestDistance < 3.0 then if pedAmmo > 0 then @@ -1463,13 +1370,13 @@ end RegisterNetEvent('esx:serverCallback') AddEventHandler('esx:serverCallback', function(requestId, ...) - ESX.ServerCallbacks[requestId](...) - ESX.ServerCallbacks[requestId] = nil + ESX.ServerCallbacks[requestId](...) + ESX.ServerCallbacks[requestId] = nil end) RegisterNetEvent('esx:showNotification') AddEventHandler('esx:showNotification', function(msg) - ESX.ShowNotification(msg) + ESX.ShowNotification(msg) end) RegisterNetEvent('esx:showAdvancedNotification') @@ -1484,24 +1391,21 @@ end) -- SetTimeout Citizen.CreateThread(function() - while true do + while true do - Citizen.Wait(0) + Citizen.Wait(0) + local currTime = GetGameTimer() - local currTime = GetGameTimer() + for i=1, #ESX.TimeoutCallbacks, 1 do - for i=1, #ESX.TimeoutCallbacks, 1 do + if ESX.TimeoutCallbacks[i] ~= nil then + if currTime >= ESX.TimeoutCallbacks[i].time then + ESX.TimeoutCallbacks[i].cb() + ESX.TimeoutCallbacks[i] = nil + end + end - if ESX.TimeoutCallbacks[i] ~= nil then + end - if currTime >= ESX.TimeoutCallbacks[i].time then - ESX.TimeoutCallbacks[i].cb() - ESX.TimeoutCallbacks[i] = nil - end - - end - - end - - end + end end) diff --git a/client/main.lua b/client/main.lua index 7894280c..014e93d5 100644 --- a/client/main.lua +++ b/client/main.lua @@ -19,40 +19,36 @@ local isDead = false RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) + ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer - ESX.PlayerLoaded = true - ESX.PlayerData = xPlayer + for i=1, #xPlayer.accounts, 1 do + local accountTpl = '
 {{money}}
' - for i=1, #xPlayer.accounts, 1 do + ESX.UI.HUD.RegisterElement('account_' .. xPlayer.accounts[i].name, i-1, 0, accountTpl, { + money = 0 + }) - local accountTpl = '
 {{money}}
' + ESX.UI.HUD.UpdateElement('account_' .. xPlayer.accounts[i].name, { + money = xPlayer.accounts[i].money + }) + end - ESX.UI.HUD.RegisterElement('account_' .. xPlayer.accounts[i].name, i-1, 0, accountTpl, { - money = 0 - }) + local jobTpl = '
{{job_label}} - {{grade_label}}
' - ESX.UI.HUD.UpdateElement('account_' .. xPlayer.accounts[i].name, { - money = xPlayer.accounts[i].money - }) + if xPlayer.job.grade_label == '' then + jobTpl = '
{{job_label}}
' + end - 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 - }) + 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() @@ -122,7 +118,6 @@ AddEventHandler('baseevents:onPlayerKilled', function(killerId, data) TriggerEvent('esx:onPlayerDeath', data) TriggerServerEvent('esx:onPlayerDeath', data) - end) AddEventHandler('esx:onPlayerDeath', function() @@ -134,82 +129,77 @@ AddEventHandler('skinchanger:loadDefaultModel', function() end) AddEventHandler('skinchanger:modelLoaded', function() - while not ESX.PlayerLoaded do - Citizen.Wait(1) - end + while not ESX.PlayerLoaded do + Citizen.Wait(1) + end - TriggerEvent('esx:restoreLoadout') + TriggerEvent('esx:restoreLoadout') end) AddEventHandler('esx:restoreLoadout', function() - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() - RemoveAllPedWeapons(playerPed, true) + RemoveAllPedWeapons(playerPed, true) - for i=1, #ESX.PlayerData.loadout, 1 do - local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) - GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) - end + for i=1, #ESX.PlayerData.loadout, 1 do + local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) + GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) + end - LoadoutLoaded = true + LoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') AddEventHandler('esx:setAccountMoney', function(account) + for i=1, #ESX.PlayerData.accounts, 1 do + if ESX.PlayerData.accounts[i].name == account.name then + ESX.PlayerData.accounts[i] = account + end + end - for i=1, #ESX.PlayerData.accounts, 1 do - if ESX.PlayerData.accounts[i].name == account.name then - ESX.PlayerData.accounts[i] = account - end - end - - ESX.UI.HUD.UpdateElement('account_' .. account.name, { - money = account.money - }) + ESX.UI.HUD.UpdateElement('account_' .. account.name, { + money = account.money + }) end) RegisterNetEvent('es:activateMoney') AddEventHandler('es:activateMoney', function(money) - ESX.PlayerData.money = money + ESX.PlayerData.money = money end) RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count) + for i=1, #ESX.PlayerData.inventory, 1 do + if ESX.PlayerData.inventory[i].name == item.name then + ESX.PlayerData.inventory[i] = item + end + end - for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item - end - end - - ESX.UI.ShowInventoryItemNotification(true, item, count) - - if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then - ESX.ShowInventory() - 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 i=1, #ESX.PlayerData.inventory, 1 do + if ESX.PlayerData.inventory[i].name == item.name then + ESX.PlayerData.inventory[i] = item + end + end - for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item - end - end - - ESX.UI.ShowInventoryItemNotification(false, item, count) - - if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then - ESX.ShowInventory() - 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 + ESX.PlayerData.job = job end) RegisterNetEvent('esx:addWeapon') @@ -240,185 +230,157 @@ end) -- Commands RegisterNetEvent('esx:teleport') AddEventHandler('esx:teleport', function(pos) --- heading?! - pos.x = pos.x + 0.0 - pos.y = pos.y + 0.0 - pos.z = pos.z + 0.0 + 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) + 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) + 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) - ESX.UI.HUD.UpdateElement('job', { - job_label = job.label, - grade_label = job.grade_label - }) + 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) - + Citizen.CreateThread(function() + LoadMpDlcMaps() + EnableMpDlcMaps(true) + RequestIpl(name) + end) end) RegisterNetEvent('esx:unloadIPL') AddEventHandler('esx:unloadIPL', function(name) - - Citizen.CreateThread(function() - RemoveIpl(name) - end) - + Citizen.CreateThread(function() + RemoveIpl(name) + end) end) RegisterNetEvent('esx:playAnim') AddEventHandler('esx:playAnim', function(dict, anim) + Citizen.CreateThread(function() + local playerPed = PlayerPedId() + RequestAnimDict(dict) - Citizen.CreateThread(function() - - local pid = PlayerPedId() - - RequestAnimDict(dict) - - while not HasAnimDictLoaded(dict) do - Citizen.Wait(1) - end - - TaskPlayAnim(pid, dict, anim, 1.0, -1.0, 20000, 0, 1, true, true, true) - - end) + while not HasAnimDictLoaded(dict) do + Citizen.Wait(1) + end + TaskPlayAnim(playerPed, 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() - Citizen.CreateThread(function() + local playerPed = PlayerPedId() - local playerPed = PlayerPedId() - - TaskStartScenarioInPlace(playerPed, emote, 0, false); - Citizen.Wait(20000) - ClearPedTasks(playerPed) - - end) + TaskStartScenarioInPlace(playerPed, emote, 0, false); + Citizen.Wait(20000) + ClearPedTasks(playerPed) + end) end) RegisterNetEvent('esx:spawnVehicle') AddEventHandler('esx:spawnVehicle', function(model) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - - ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) - + ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + end) end) RegisterNetEvent('esx:spawnObject') AddEventHandler('esx:spawnObject', function(model) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) - - ESX.Game.SpawnObject(model, { - x = x, - y = y, - z = z - }, function(obj) - SetEntityHeading(obj, GetEntityHeading(playerPed)) - PlaceObjectOnGroundProperly(obj) - end) - + ESX.Game.SpawnObject(model, { + x = x, + y = y, + z = z + }, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + 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) - 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) + 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 + ESX.Game.DeleteObject(Pickups[id].obj) + Pickups[id] = nil end) RegisterNetEvent('esx:pickupWeapon') AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName,ammo) - - local ped = PlayerPedId() - local playerPedPos = GetEntityCoords(ped, true) - CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, ammo, 1, false, true) - + local ped = PlayerPedId() + local playerPedPos = GetEntityCoords(ped, true) + CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, ammo, 1, false, true) end) RegisterNetEvent('esx:spawnPed') AddEventHandler('esx:spawnPed', function(model) + model = (tonumber(model) ~= nil and tonumber(model) or GetHashKey(model)) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + local forward = GetEntityForwardVector(playerPed) + local x, y, z = table.unpack(coords + forward * 1.0) - model = (tonumber(model) ~= nil and tonumber(model) or GetHashKey(model)) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) + Citizen.CreateThread(function() + RequestModel(model) - Citizen.CreateThread(function() - - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(1) - end - - CreatePed(5, model, x, y, z, 0.0, true, false) - - end) + while not HasModelLoaded(model) do + Citizen.Wait(1) + end + CreatePed(5, model, x, y, z, 0.0, true, false) + end) end) RegisterNetEvent('esx:deleteVehicle') @@ -438,127 +400,121 @@ 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 + 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 - while true do + Citizen.Wait(1) - Citizen.Wait(1) + local playerPed = PlayerPedId() + local loadout = {} + local loadoutChanged = false - local playerPed = PlayerPedId() - local loadout = {} - local loadoutChanged = false + if IsPedDeadOrDying(playerPed) then + LoadoutLoaded = false + end - if IsPedDeadOrDying(playerPed) then - LoadoutLoaded = false - end + for i=1, #Config.Weapons, 1 do - for i=1, #Config.Weapons, 1 do + local weaponHash = GetHashKey(Config.Weapons[i].name) - 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 HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + if LastLoadout[Config.Weapons[i].name] == nil or LastLoadout[Config.Weapons[i].name] ~= ammo then + loadoutChanged = true + end - local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + LastLoadout[Config.Weapons[i].name] = ammo - if LastLoadout[Config.Weapons[i].name] == nil or LastLoadout[Config.Weapons[i].name] ~= ammo then - loadoutChanged = true - end + 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] = ammo + LastLoadout[Config.Weapons[i].name] = nil + end - table.insert(loadout, { - name = Config.Weapons[i].name, - ammo = ammo, - label = Config.Weapons[i].label - }) + end - else + if loadoutChanged and LoadoutLoaded then + ESX.PlayerData.loadout = loadout + TriggerServerEvent('esx:updateLoadout', loadout) + end - if LastLoadout[Config.Weapons[i].name] ~= nil then - loadoutChanged = true - end - - LastLoadout[Config.Weapons[i].name] = nil - - end - - end - - if loadoutChanged and LoadoutLoaded then - ESX.PlayerData.loadout = loadout - TriggerServerEvent('esx:updateLoadout', loadout) - end - - end + end end) -- Menu interactions Citizen.CreateThread(function() - while true do + while true do - Citizen.Wait(10) + Citizen.Wait(10) - if IsControlJustReleased(0, Keys['F2']) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then - ESX.ShowInventory() - end + if IsControlJustReleased(0, Keys['F2']) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + ESX.ShowInventory() + end - end + end end) -- Dot above head if Config.ShowDotAbovePlayer then - Citizen.CreateThread(function() - while true do + Citizen.CreateThread(function() + while true do - Citizen.Wait(1) + Citizen.Wait(1) - local players = ESX.Game.GetPlayers() + local players = ESX.Game.GetPlayers() + for i = 1, #players, 1 do + if players[i] ~= PlayerId() then + local ped = GetPlayerPed(players[i]) + local headId = CreateMpGamerTag(ped, ('·'), false, false, '', false) + end + end - for i = 1, #players, 1 do - if players[i] ~= PlayerId() then - local ped = GetPlayerPed(players[i]) - local headId = CreateMpGamerTag(ped, ('·'), false, false, '', false) - end - end - - end - end) + end + end) end -- Disable wanted level if Config.DisableWantedLevel then - Citizen.CreateThread(function() - while true do + Citizen.CreateThread(function() + while true do - Citizen.Wait(10) + Citizen.Wait(10) - local playerId = PlayerId() + local playerId = PlayerId() + if GetPlayerWantedLevel(playerId) ~= 0 then + SetPlayerWantedLevel(playerId, 0, false) + SetPlayerWantedLevelNow(playerId, false) + end - if GetPlayerWantedLevel(playerId) ~= 0 then - SetPlayerWantedLevel(playerId, 0, false) - SetPlayerWantedLevelNow(playerId, false) - end - - end - end) + end + end) end @@ -602,37 +558,29 @@ end) -- Last position Citizen.CreateThread(function() + while true do - while true do + Citizen.Wait(1000) + if ESX ~= nil and ESX.PlayerLoaded and PlayerSpawned then + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) - Citizen.Wait(1000) - - if ESX ~= nil and ESX.PlayerLoaded and PlayerSpawned then - - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - - if not IsEntityDead(playerPed) then - ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} - end - - end - - end + if not IsEntityDead(playerPed) then + ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} + end + end + end end) Citizen.CreateThread(function() + while true do - while true do - - Citizen.Wait(1000) - - local playerPed = PlayerPedId() - - if IsEntityDead(playerPed) and PlayerSpawned then - PlayerSpawned = false - end - end + Citizen.Wait(1000) + local playerPed = PlayerPedId() + if IsEntityDead(playerPed) and PlayerSpawned then + PlayerSpawned = false + end + end end) diff --git a/client/wrapper.lua b/client/wrapper.lua index 9ac13dcf..441312d8 100644 --- a/client/wrapper.lua +++ b/client/wrapper.lua @@ -1,16 +1,14 @@ local Chunks = {} RegisterNUICallback('__chunk', function(data, cb) + Chunks[data.id] = Chunks[data.id] or '' + Chunks[data.id] = Chunks[data.id] .. data.chunk - Chunks[data.id] = Chunks[data.id] or '' - Chunks[data.id] = Chunks[data.id] .. data.chunk - - if data['end'] then - local msg = json.decode(Chunks[data.id]) - TriggerEvent(GetCurrentResourceName() .. ':message:' .. data.__type, msg) - Chunks[data.id] = nil - end - - cb('') + if data['end'] then + local msg = json.decode(Chunks[data.id]) + TriggerEvent(GetCurrentResourceName() .. ':message:' .. data.__type, msg) + Chunks[data.id] = nil + end + cb('') end) diff --git a/html/css/app.css b/html/css/app.css index cfe7e0ab..e4327c9c 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -1,95 +1,87 @@ @font-face { - font-family: 'Pricedown'; - src: url('../fonts/pdown.ttf') /* TTF file for CSS3 browsers */ + 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 */ + font-family: 'bankgothic'; + src: url('../fonts/bankgothic.ttf')/* TTF file for CSS3 browsers */ } html { - overflow: hidden; + overflow: hidden; } #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; + 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; + 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; + 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); + 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; + 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; + 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; -} +} \ No newline at end of file diff --git a/html/js/app.js b/html/js/app.js index 6da6d52b..901e081e 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -30,7 +30,6 @@ ESX.HUDElements[i].data = data; ESX.refreshHUD(); - } ESX.deleteHUDElement = function(name){ diff --git a/html/js/wrapper.js b/html/js/wrapper.js index 054e8d06..0d208709 100644 --- a/html/js/wrapper.js +++ b/html/js/wrapper.js @@ -1,42 +1,42 @@ (() => { - let ESXWrapper = {}; - ESXWrapper.MessageSize = 1024; - ESXWrapper.messageId = 0; + let ESXWrapper = {}; + ESXWrapper.MessageSize = 1024; + ESXWrapper.messageId = 0; - window.SendMessage = function(namespace, type, msg) { + window.SendMessage = function (namespace, type, msg) { - ESXWrapper.messageId = (ESXWrapper.messageId < 65535) ? ESXWrapper.messageId + 1 : 0; - const str = JSON.stringify(msg); + ESXWrapper.messageId = (ESXWrapper.messageId < 65535) ? ESXWrapper.messageId + 1 : 0; + const str = JSON.stringify(msg); - for(let i=0; i= 0 then + self.player.setMoney(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 cash balance)') + end + end + + self.getMoney = function() + return self.player.get('money') + end + + self.setBankBalance = function(m) + if m >= 0 then + self.player.setBankBalance(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 bank balance)') + end + 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) + if m >= 0 then + self.player.addMoney(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 cash balance)') + end + end + + self.removeMoney = function(m) + if m >= 0 then + self.player.removeMoney(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 cash balance)') + end + end + + self.addBank = function(m) + if m >= 0 then + self.player.addBank(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 bank balance)') + end + end + + self.removeBank = function(m) + if m >= 0 then + self.player.removeBank(m) + else + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 bank balance)') + end + 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 - 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) - if m >= 0 then - self.player.setMoney(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 cash balance)') - end - end - - self.getMoney = function() - return self.player.get('money') - end - - self.setBankBalance = function(m) - if m >= 0 then - self.player.setBankBalance(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 bank balance)') - end - 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) - if m >= 0 then - self.player.addMoney(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 cash balance)') - end - end - - self.removeMoney = function(m) - if m >= 0 then - self.player.removeMoney(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 cash balance)') - end - end - - self.addBank = function(m) - if m >= 0 then - self.player.addBank(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 bank balance)') - end - end - - self.removeBank = function(m) - if m >= 0 then - self.player.removeBank(m) - else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 bank balance)') - end - 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.getName = function() + return self.name + end - self.getPlayer = function() - return self.player - end + self.getLastPosition = function() + return self.lastPosition + end - self.getAccounts = function() + self.getMissingAccounts = function(cb) + MySQL.Async.fetchAll('SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', { + ['@identifier'] = self.getIdentifier() + }, function(result) - 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) - if m < 0 then - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 account balance)') - return - end - - 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) - if m < 0 then - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 account balance)') - return - end - - 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) - if m < 0 then - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 account balance)') - return - end - - 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.setInventoryItem = function(name, count) - - local item = self.getInventoryItem(name) - local oldCount = item.count - item.count = count - - if oldCount > item.count then - TriggerEvent("esx:onRemoveInventoryItem", self.source, item, oldCount - item.count ) - TriggerClientEvent("esx:removeInventoryItem", self.source, item, oldCount - item.count ) - else - TriggerEvent("esx:onAddInventoryItem", self.source, item, item.count - oldCount) - TriggerClientEvent("esx:addInventoryItem", self.source, item, item.count - oldCount) - end - - end - - self.setJob = function(name, grade) - - local lastJob = json.decode(json.encode(self.job)) - - 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 - - TriggerEvent("esx:setJob", self.source, self.job, lastJob) - 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 - - local foundWeapon = false - - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - foundWeapon = true - end - end - - if not foundWeapon then - table.insert(self.loadout, { - name = weaponName, - ammo = ammo, - label = weaponLabel - }) - end - TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) - TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) - end - - self.removeWeapon = 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 - - local foundWeapon = false - - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - table.remove(self.loadout, i) - break - end - end - - TriggerClientEvent('esx:removeWeapon', self.source, weaponName, ammo) - TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) - end - - return self + 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) + if m < 0 then + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 account balance)') + return + end + + 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) + if m < 0 then + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 account balance)') + return + end + + 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) + if m < 0 then + print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 account balance)') + return + end + + 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.setInventoryItem = function(name, count) + local item = self.getInventoryItem(name) + local oldCount = item.count + item.count = count + + if oldCount > item.count then + TriggerEvent("esx:onRemoveInventoryItem", self.source, item, oldCount - item.count) + TriggerClientEvent("esx:removeInventoryItem", self.source, item, oldCount - item.count) + else + TriggerEvent("esx:onAddInventoryItem", self.source, item, item.count - oldCount) + TriggerClientEvent("esx:addInventoryItem", self.source, item, item.count - oldCount) + end + end + + self.setJob = function(name, grade) + local lastJob = json.decode(json.encode(self.job)) + + 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 + + TriggerEvent("esx:setJob", self.source, self.job, lastJob) + 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 + + local foundWeapon = false + + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + foundWeapon = true + end + end + + if not foundWeapon then + table.insert(self.loadout, { + name = weaponName, + ammo = ammo, + label = weaponLabel + }) + end + + TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) + TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) + end + + self.removeWeapon = 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 + + local foundWeapon = false + + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + table.remove(self.loadout, i) + break + end + end + + TriggerClientEvent('esx:removeWeapon', self.source, weaponName, ammo) + TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) + end + + return self end diff --git a/server/commands.lua b/server/commands.lua index bfd0ca9e..3de2797e 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -13,7 +13,7 @@ TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Invalid coordinates!") end end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = "Teleport to coordinates", params = {{name = "x", help = "X coords"}, {name = "y", help = "Y coords"}, {name = "z", help = "Z coords"}}}) TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) @@ -28,37 +28,37 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Invalid usage.") end end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('setjob'), params = {{name = "id", help = _U('id_param')}, {name = "job", help = _U('setjob_param2')}, {name = "grade_id", help = _U('setjob_param3')}}}) TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:loadIPL', -1, args[1]) + TriggerClientEvent('esx:loadIPL', -1, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('load_ipl')}) TriggerEvent('es:addGroupCommand', 'unloadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:unloadIPL', -1, args[1]) + TriggerClientEvent('esx:unloadIPL', -1, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('unload_ipl')}) TriggerEvent('es:addGroupCommand', 'playanim', 'admin', function(source, args, user) - TriggerClientEvent('esx:playAnim', -1, args[1], args[3]) + TriggerClientEvent('esx:playAnim', -1, args[1], args[3]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('play_anim')}) TriggerEvent('es:addGroupCommand', 'playemote', 'admin', function(source, args, user) - TriggerClientEvent('esx:playEmote', -1, args[1]) + TriggerClientEvent('esx:playEmote', -1, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('play_emote')}) TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnVehicle', source, args[1]) + TriggerClientEvent('esx:spawnVehicle', source, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) TriggerEvent('es:addGroupCommand', 'cardel', 'admin', function(source, args, user) @@ -68,26 +68,25 @@ end, function(source, args, user) end, {help = _U('delete_vehicle')}) TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) - TriggerClientEvent('esx:deleteVehicle', source) + TriggerClientEvent('esx:deleteVehicle', source) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('delete_vehicle')}) TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnPed', source, args[1]) + TriggerClientEvent('esx:spawnPed', source, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('spawn_ped'), params = {{name = "name", help = _U('spawn_ped_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnObject', source, args[1]) + TriggerClientEvent('esx:spawnObject', source, args[1]) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('spawn_object'), params = {{name = "name"}}}) TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) local _source = source - local target = tonumber(args[1]) local money_type = args[2] local money_amount = tonumber(args[3]) @@ -113,63 +112,57 @@ TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, u print('es_extended: ' .. GetPlayerName(source) .. ' just set $' .. money_amount .. ' (' .. money_type .. ') to ' .. xPlayer.name) if xPlayer.source ~= _source then - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('setmoney'), params = {{name = "id", help = _U('id_param')}, {name = "money type", help = _U('money_type')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[1]) + local account = args[2] + local amount = tonumber(args[3]) - local _source = source - local xPlayer = ESX.GetPlayerFromId(args[1]) - local account = args[2] - local amount = tonumber(args[3]) - - if amount ~= nil then - if xPlayer.getAccount(account) ~= nil then - xPlayer.addAccountMoney(account, amount) - else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) - end - else - TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) - end - + if amount ~= nil then + if xPlayer.getAccount(account) ~= nil then + xPlayer.addAccountMoney(account, amount) + else + TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) + end + else + TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) + end end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveaccountmoney'), params = {{name = "id", help = _U('id_param')}, {name = "account", help = _U('account')}, {name = "amount", help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) + local _source = source + local xPlayer = ESX.GetPlayerFromId(args[1]) + local item = args[2] + local count = (args[3] == nil and 1 or tonumber(args[3])) - local _source = source - local xPlayer = ESX.GetPlayerFromId(args[1]) - local item = args[2] - local count = (args[3] == nil and 1 or tonumber(args[3])) - - if count ~= nil then - if xPlayer.getInventoryItem(item) ~= nil then - xPlayer.addInventoryItem(item, count) - else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) - end - else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) - end - + if count ~= nil then + if xPlayer.getInventoryItem(item) ~= nil then + xPlayer.addInventoryItem(item, count) + else + TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) + end + else + TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) + end end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveitem'), params = {{name = "id", help = _U('id_param')}, {name = "item", help = _U('item')}, {name = "amount", help = _U('amount')}}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) + local xPlayer = ESX.GetPlayerFromId(args[1]) + local weaponName = string.upper(args[2]) - local xPlayer = ESX.GetPlayerFromId(args[1]) - local weaponName = string.upper(args[2]) - - xPlayer.addWeapon(weaponName, tonumber(args[3])) - + xPlayer.addWeapon(weaponName, tonumber(args[3])) end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}, {name = "ammo", help = _U('amountammo')}}}) TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) @@ -206,4 +199,4 @@ TriggerEvent('es:addGroupCommand', 'clearall', 'admin', function(source, args, u TriggerClientEvent('chat:clear', -1) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('chat_clear_all')}) \ No newline at end of file +end, {help = _U('chat_clear_all')}) diff --git a/server/common.lua b/server/common.lua index 2a2eef94..4ed0d53a 100644 --- a/server/common.lua +++ b/server/common.lua @@ -10,70 +10,57 @@ ESX.Pickups = {} ESX.PickupId = 0 AddEventHandler('esx:getSharedObject', function(cb) - cb(ESX) + cb(ESX) end) function getSharedObject() - return ESX + return 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, - rare = (result[i].rare == 1 and true or false), - canRemove = (result[i].can_remove == 1 and true or false), - } - end - - end - ) - + 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, + rare = (result[i].rare == 1 and true or false), + canRemove = (result[i].can_remove == 1 and true or false), + } + end + end) end) AddEventHandler('esx:playerLoaded', function(source) + local xPlayer = ESX.GetPlayerFromId(source) + local accounts = {} + local items = {} + local xPlayerAccounts = xPlayer.getAccounts() + local xPlayerItems = xPlayer.getInventory() - local xPlayer = ESX.GetPlayerFromId(source) - local accounts = {} - local items = {} - local xPlayerAccounts = xPlayer.getAccounts() - local xPlayerItems = xPlayer.getInventory() + for i=1, #xPlayerAccounts, 1 do + accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money + end - for i=1, #xPlayerAccounts, 1 do - accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money - end - - for i=1, #xPlayerItems, 1 do - items[xPlayerItems[i].name] = xPlayerItems[i].count - end - - ESX.LastPlayerData[source] = { - accounts = accounts, - items = items - } + for i=1, #xPlayerItems, 1 do + items[xPlayerItems[i].name] = xPlayerItems[i].count + end + ESX.LastPlayerData[source] = { + accounts = accounts, + items = items + } end) RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) - RconPrint(msg .. "\n") + RconPrint(msg .. "\n") end) RegisterServerEvent('esx:triggerServerCallback') AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) + local _source = source - local _source = source - - ESX.TriggerServerCallback(name, requestID, _source, function(...) - TriggerClientEvent('esx:serverCallback', _source, requestId, ...) - end, ...) - + ESX.TriggerServerCallback(name, requestID, _source, function(...) + TriggerClientEvent('esx:serverCallback', _source, requestId, ...) + end, ...) end) - diff --git a/server/functions.lua b/server/functions.lua index da0673c2..60d3cd17 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -1,226 +1,171 @@ -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.Trace = function(str) - if Config.EnableDebug then - print('ESX> ' .. str) - end -end - -ESX.GetConfig = function() - return Config -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 - + if Config.EnableDebug then + print('ESX> ' .. str) + end end ESX.SetTimeout = function(msec, cb) + local id = ESX.TimeoutCount + 1 - local id = ESX.TimeoutCount + 1 + SetTimeout(msec, function() + if ESX.CancelledTimeouts[id] then + ESX.CancelledTimeouts[id] = nil + else + cb() + end + end) - SetTimeout(msec, function() - - if ESX.CancelledTimeouts[id] then - ESX.CancelledTimeouts[id] = nil - else - cb() - end - - end) - - ESX.TimeoutCount = id - - return id + ESX.TimeoutCount = id + return id end ESX.ClearTimeout = function(id) - ESX.CancelledTimeouts[id] = true + ESX.CancelledTimeouts[id] = true end ESX.RegisterServerCallback = function(name, cb) - ESX.ServerCallbacks[name] = cb + ESX.ServerCallbacks[name] = cb end ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) - - if ESX.ServerCallbacks[name] ~= nil then - ESX.ServerCallbacks[name](source, cb, ...) - else - print('TriggerServerCallback => [' .. name .. '] does not exist') - end - + if ESX.ServerCallbacks[name] ~= nil then + ESX.ServerCallbacks[name](source, cb, ...) + else + print('es_extended: TriggerServerCallback => [' .. name .. '] does not exist') + end end ESX.SavePlayer = function(xPlayer, cb) + local asyncTasks = {} + xPlayer.lastPosition = xPlayer.get('coords') - local asyncTasks = {} - xPlayer.lastPosition = xPlayer.get('coords') + -- User accounts + for i=1, #xPlayer.accounts, 1 do - -- User accounts - for i=1, #xPlayer.accounts, 1 do + if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then - if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then + 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) - table.insert(asyncTasks, function(cb) + ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] = xPlayer.accounts[i].money - 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) + end - ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] = xPlayer.accounts[i].money + -- Inventory items + for i=1, #xPlayer.inventory, 1 do - end + if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then - end + 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) - -- Inventory items - for i=1, #xPlayer.inventory, 1 do + ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] = xPlayer.inventory[i].count - if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then + end - table.insert(asyncTasks, function(cb) + end - 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 - ) + -- 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) - end) + Async.parallel(asyncTasks, function(results) + RconPrint('[SAVED] ' .. xPlayer.name .. "\n") - ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] = xPlayer.inventory[i].count - - 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) + if cb ~= nil then + cb() + end + end) end ESX.SavePlayers = function(cb) + local asyncTasks = {} + local xPlayers = ESX.GetPlayers() - local asyncTasks = {} - local xPlayers = ESX.GetPlayers() + for i=1, #xPlayers, 1 do + table.insert(asyncTasks, function(cb) + local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) + ESX.SavePlayer(xPlayer, cb) + end) + end - for i=1, #xPlayers, 1 do - table.insert(asyncTasks, function(cb) - local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - ESX.SavePlayer(xPlayer, cb) - end) - end - - Async.parallelLimit(asyncTasks, 8, function(results) - - RconPrint('[SAVED] All players' .. "\n") - - if cb ~= nil then - cb() - end - - end) + Async.parallelLimit(asyncTasks, 8, function(results) + RconPrint('[SAVED] All players' .. "\n") + if cb ~= nil then + cb() + end + end) end ESX.StartDBSync = function() + function saveData() + ESX.SavePlayers() + SetTimeout(10 * 60 * 1000, saveData) + end - function saveData() - ESX.SavePlayers() - SetTimeout(10 * 60 * 1000, saveData) - end - - SetTimeout(10 * 60 * 1000, saveData) - + SetTimeout(10 * 60 * 1000, saveData) end ESX.GetPlayers = function() + local sources = {} - local sources = {} + for k,v in pairs(ESX.Players) do + table.insert(sources, k) + end - for k,v in pairs(ESX.Players) do - table.insert(sources, k) - end - - return sources + return sources end ESX.GetPlayerFromId = function(source) - return ESX.Players[tonumber(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 - + 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 + ESX.UsableItemsCallbacks[item] = cb end ESX.UseItem = function(source, item) - ESX.UsableItemsCallbacks[item](source) + ESX.UsableItemsCallbacks[item](source) end ESX.GetItemLabel = function(item) @@ -230,34 +175,29 @@ ESX.GetItemLabel = function(item) end ESX.GetWeaponList = function() - return Config.Weapons + return Config.Weapons end ESX.GetWeaponLabel = function(name) + name = string.upper(name) + local weapons = ESX.GetWeaponList() - 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 - + for i=1, #weapons, 1 do + if weapons[i].name == name then + return weapons[i].label + end + end end ESX.CreatePickup = function(type, name, count, label, player) + local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) - local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) + ESX.Pickups[pickupId] = { + type = type, + name = name, + count = count + } - ESX.Pickups[pickupId] = { - type = type, - name = name, - count = count - } - - TriggerClientEvent('esx:pickup', -1, pickupId, label, player) - - ESX.PickupId = pickupId - -end \ No newline at end of file + TriggerClientEvent('esx:pickup', -1, pickupId, label, player) + ESX.PickupId = pickupId +end diff --git a/server/main.lua b/server/main.lua index 81c88fb6..abe364e1 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,298 +1,252 @@ 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) + + local tasks2 = {} + + 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, + rare = ESX.Items[inventory[i].item].rare, + canRemove = ESX.Items[inventory[i].item].canRemove + }) + 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, + rare = ESX.Items[k].rare, + canRemove = ESX.Items[k].canRemove + }) + + local scope = function(item, identifier) + + table.insert(tasks2, function(cb2) + MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', + { + ['@identifier'] = identifier, + ['@item'] = item, + ['@count'] = 0 + }, function(rowsChanged) + cb2() + end) + end) + + end + + scope(k, player.getIdentifier()) + + end + + end + + Async.parallelLimit(tasks2, 5, function(results) 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) - 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) - - local tasks2 = {} - - 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, - rare = ESX.Items[inventory[i].item].rare, - canRemove = ESX.Items[inventory[i].item].canRemove, - }) - 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 + 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 not found then + if result[1].loadout ~= nil then + userData.loadout = json.decode(result[1].loadout) + end - table.insert(userData.inventory, { - name = k, - count = 0, - label = ESX.Items[k].label, - limit = ESX.Items[k].limit, - usable = ESX.UsableItemsCallbacks[k] ~= nil, - rare = ESX.Items[k].rare, - canRemove = ESX.Items[k].canRemove, - }) - - local scope = function(item, identifier) + if result[1].position ~= nil then + userData.lastPosition = json.decode(result[1].position) + end - table.insert(tasks2, function(cb2) + cb2() + end) - MySQL.Async.execute( - 'INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', - { - ['@identifier'] = identifier, - ['@item'] = item, - ['@count'] = 0 - }, - function(rowsChanged) - cb2() - end - ) + 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) - end + -- Get job grade data + table.insert(tasks2, function(cb2) - scope(k, player.getIdentifier()) + 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) - end + userData.job['grade_name'] = result[1].name + userData.job['grade_label'] = result[1].label + userData.job['grade_salary'] = result[1].salary - end + userData.job['skin_male'] = {} + userData.job['skin_female'] = {} - Async.parallelLimit(tasks2, 5, function(results) end) + if result[1].skin_male ~= nil then + userData.job['skin_male'] = json.decode(result[1].skin_male) + end - table.sort(userData.inventory, function(a,b) - return a.label < b.label - end) + if result[1].skin_female ~= nil then + userData.job['skin_female'] = json.decode(result[1].skin_female) + end - cb() - end - ) + cb2() + end) - end) + end) - -- Get job and loadout - table.insert(tasks, function(cb) + Async.series(tasks2, cb) - local tasks2 = {} + end) - -- Get job name, grade and last position - table.insert(tasks2, function(cb2) + -- Run Tasks + Async.parallel(tasks, function(results) - MySQL.Async.fetchAll( - 'SELECT * FROM `users` WHERE `identifier` = @identifier', - { - ['@identifier'] = player.getIdentifier() - }, - function(result) + local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.lastPosition) - userData.job['name'] = result[1].job - userData.job['grade'] = result[1].job_grade + xPlayer.getMissingAccounts(function(missingAccounts) - if result[1].loadout ~= nil then - userData.loadout = json.decode(result[1].loadout) - end + if #missingAccounts > 0 then - if result[1].position ~= nil then - userData.lastPosition = json.decode(result[1].position) - end + for i=1, #missingAccounts, 1 do + table.insert(xPlayer.accounts, { + name = missingAccounts[i], + money = 0, + label = Config.AccountLabels[missingAccounts[i]] + }) + end - cb2() + xPlayer.createAccounts(missingAccounts) + end - end - ) + ESX.Players[_source] = xPlayer - end) + TriggerEvent('esx:playerLoaded', _source) - -- Get job label - table.insert(tasks2, function(cb2) + TriggerClientEvent('esx:playerLoaded', _source, { + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.get('money') + }) - MySQL.Async.fetchAll( - 'SELECT * FROM `jobs` WHERE `name` = @name', - { - ['@name'] = userData.job.name - }, - function(result) + xPlayer.player.displayMoney(xPlayer.get('money')) - userData.job['label'] = result[1].label + end) - cb2() + end) - 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, { - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') - }) - - xPlayer.player.displayMoney(xPlayer.get('money')) - - end) - - end) - - end) + end) end) AddEventHandler('playerDropped', function(reason) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) - - if xPlayer ~= nil then - - TriggerEvent('esx:playerDropped', _source, reason) - - ESX.SavePlayer(xPlayer, function() - ESX.Players[_source] = nil - ESX.LastPlayerData[_source] = nil - end) - - end + if xPlayer ~= nil then + TriggerEvent('esx:playerDropped', _source, reason) + ESX.SavePlayer(xPlayer, function() + ESX.Players[_source] = nil + ESX.LastPlayerData[_source] = nil + end) + end end) RegisterServerEvent('esx:updateLoadout') @@ -310,293 +264,271 @@ end) RegisterServerEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) + local _source = source - local _source = source + local sourceXPlayer = ESX.GetPlayerFromId(_source) + local targetXPlayer = ESX.GetPlayerFromId(target) - local sourceXPlayer = ESX.GetPlayerFromId(_source) - local targetXPlayer = ESX.GetPlayerFromId(target) + if type == 'item_standard' then - if type == 'item_standard' then + local sourceItem = sourceXPlayer.getInventoryItem(itemName) + local targetItem = targetXPlayer.getInventoryItem(itemName) - local sourceItem = sourceXPlayer.getInventoryItem(itemName) - local targetItem = targetXPlayer.getInventoryItem(itemName) + if itemCount > 0 and sourceItem.count >= itemCount then - if itemCount > 0 and sourceItem.count >= itemCount then + if targetItem.limit ~= -1 and (targetItem.count + itemCount) > targetItem.limit then + TriggerClientEvent('esx:showNotification', _source, _U('ex_inv_lim', targetXPlayer.name)) + else + sourceXPlayer.removeInventoryItem(itemName, itemCount) + targetXPlayer.addInventoryItem (itemName, itemCount) + + TriggerClientEvent('esx:showNotification', _source, _U('gave_item', itemCount, ESX.Items[itemName].label, targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_item', itemCount, ESX.Items[itemName].label, sourceXPlayer.name)) + end - if targetItem.limit ~= -1 and (targetItem.count + itemCount) > targetItem.limit then - TriggerClientEvent('esx:showNotification', _source, _U('ex_inv_lim', targetXPlayer.name)) - else - sourceXPlayer.removeInventoryItem(itemName, itemCount) - targetXPlayer.addInventoryItem (itemName, itemCount) - - TriggerClientEvent('esx:showNotification', _source, _U('gave_item', itemCount, ESX.Items[itemName].label, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_item', itemCount, ESX.Items[itemName].label, sourceXPlayer.name)) - end + else + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + end - else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) - end + elseif type == 'item_money' then - elseif type == 'item_money' then + if itemCount > 0 and sourceXPlayer.player.get('money') >= itemCount then - if itemCount > 0 and sourceXPlayer.player.get('money') >= itemCount then + sourceXPlayer.removeMoney(itemCount) + targetXPlayer.addMoney (itemCount) - sourceXPlayer.removeMoney(itemCount) - targetXPlayer.addMoney (itemCount) + TriggerClientEvent('esx:showNotification', _source, _U('gave_money', itemCount, targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_money', itemCount, sourceXPlayer.name)) - TriggerClientEvent('esx:showNotification', _source, _U('gave_money', itemCount, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_money', itemCount, sourceXPlayer.name)) + else + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + end - else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - end + elseif type == 'item_account' then - elseif type == 'item_account' then + if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then - if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then + sourceXPlayer.removeAccountMoney(itemName, itemCount) + targetXPlayer.addAccountMoney (itemName, itemCount) - sourceXPlayer.removeAccountMoney(itemName, itemCount) - targetXPlayer.addAccountMoney (itemName, itemCount) + TriggerClientEvent('esx:showNotification', _source, _U('gave_account_money', itemCount, Config.AccountLabels[itemName], targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_account_money', itemCount, Config.AccountLabels[itemName], sourceXPlayer.name)) - TriggerClientEvent('esx:showNotification', _source, _U('gave_account_money', itemCount, Config.AccountLabels[itemName], targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_account_money', itemCount, Config.AccountLabels[itemName], sourceXPlayer.name)) + else + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + end - else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - end - - elseif type == 'item_weapon' then - - sourceXPlayer.removeWeapon(itemName) - targetXPlayer.addWeapon(itemName, itemCount) - - local weaponLabel = ESX.GetWeaponLabel(itemName) - TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, itemCount, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_weapon', weaponLabel, itemCount, sourceXPlayer.name)) - end + elseif type == 'item_weapon' then + + sourceXPlayer.removeWeapon(itemName) + targetXPlayer.addWeapon(itemName, itemCount) + + local weaponLabel = ESX.GetWeaponLabel(itemName) + TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, itemCount, targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_weapon', weaponLabel, itemCount, sourceXPlayer.name)) + end end) RegisterServerEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) + local _source = source - local _source = source + if type == 'item_standard' then - if type == 'item_standard' then + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + else - if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) - else + local xPlayer = ESX.GetPlayerFromId(source) + local foundItem = nil - 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 - 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, _U('imp_invalid_quantity')) + else - if itemCount > foundItem.count then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) - else + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) + SetTimeout(Config.RemoveInventoryItemDelay, function() + local remainingCount = xPlayer.getInventoryItem(itemName).count + local total = itemCount - SetTimeout(Config.RemoveInventoryItemDelay, function() + if remainingCount < itemCount then + total = remainingCount + end - local remainingCount = xPlayer.getInventoryItem(itemName).count - local total = itemCount + if total > 0 then + xPlayer.removeInventoryItem(itemName, total) + ESX.CreatePickup('item_standard', itemName, total, foundItem.label .. ' [' .. itemCount .. ']', _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) + end + end) + end - if remainingCount < itemCount then - total = remainingCount - end + end - if total > 0 then - xPlayer.removeInventoryItem(itemName, total) - ESX.CreatePickup('item_standard', itemName, total, foundItem.label .. ' [' .. itemCount .. ']', _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) - end + elseif type == 'item_money' then - end) + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else - end + local xPlayer = ESX.GetPlayerFromId(source) - end + if itemCount > xPlayer.player.get('money') then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else - elseif type == 'item_money' then + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else + SetTimeout(Config.RemoveInventoryItemDelay, function() + local remainingCount = xPlayer.player.get('money') + local total = itemCount - local xPlayer = ESX.GetPlayerFromId(source) + if remainingCount < itemCount then + total = remainingCount + end - if itemCount > xPlayer.player.get('money') then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else + if total > 0 then + xPlayer.removeMoney(total) + ESX.CreatePickup('item_money', 'money', total, 'Cash' .. ' [' .. itemCount .. ']', _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) + end + end) + end - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) + end - SetTimeout(Config.RemoveInventoryItemDelay, function() + elseif type == 'item_account' then - local remainingCount = xPlayer.player.get('money') - local total = itemCount + if itemCount == nil or itemCount <= 0 then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else - if remainingCount < itemCount then - total = remainingCount - end + local xPlayer = ESX.GetPlayerFromId(source) - if total > 0 then - xPlayer.removeMoney(total) - ESX.CreatePickup('item_money', 'money', total, 'Cash' .. ' [' .. itemCount .. ']', _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) - end + if itemCount > xPlayer.getAccount(itemName).money then + TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + else - end) + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - end + SetTimeout(Config.RemoveInventoryItemDelay, function() + local remainingCount = xPlayer.getAccount(itemName).money + local total = itemCount - end + if remainingCount < itemCount then + total = remainingCount + end - elseif type == 'item_account' then + if total > 0 then + xPlayer.removeAccountMoney(itemName, total) + ESX.CreatePickup('item_account', itemName, total, Config.AccountLabels[itemName] .. ' [' .. itemCount .. ']', _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) + end + end) + end - if itemCount == nil or itemCount <= 0 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else + end - local xPlayer = ESX.GetPlayerFromId(source) + elseif type == 'item_weapon' then - if itemCount > xPlayer.getAccount(itemName).money then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) - else + local xPlayer = ESX.GetPlayerFromId(source) + local weaponName = itemName + local weaponLabel = ESX.GetWeaponLabel(weaponName) + local weaponPickup = 'PICKUP_' .. weaponName + + TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) + + SetTimeout(Config.RemoveInventoryItemDelay, function() + xPlayer.removeWeapon(itemName) + if Config.EnableWeaponPickup then + TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName, itemCount) + end - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - - 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) - ESX.CreatePickup('item_account', itemName, total, Config.AccountLabels[itemName] .. ' [' .. itemCount .. ']', _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) - end - - end) - - end - - end - - elseif type == 'item_weapon' then - - local xPlayer = ESX.GetPlayerFromId(source) - local weaponName = itemName - local weaponLabel = ESX.GetWeaponLabel(weaponName) - local weaponPickup = 'PICKUP_' .. weaponName - - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - - SetTimeout(Config.RemoveInventoryItemDelay, function() - - xPlayer.removeWeapon(itemName) - if Config.EnableWeaponPickup then - TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName, itemCount) - end - - TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon', weaponLabel, itemCount)) - - end) - - end + TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon', weaponLabel, itemCount)) + end) + end end) RegisterServerEvent('esx:useItem') AddEventHandler('esx:useItem', function(itemName) + local xPlayer = ESX.GetPlayerFromId(source) + local count = xPlayer.getInventoryItem(itemName).count - local xPlayer = ESX.GetPlayerFromId(source) - local count = xPlayer.getInventoryItem(itemName).count - - if count > 0 then - ESX.UseItem(source, itemName) - else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('act_imp')) - end - + if count > 0 then + ESX.UseItem(source, itemName) + else + TriggerClientEvent('esx:showNotification', xPlayer.source, _U('act_imp')) + end end) RegisterServerEvent('esx:onPickup') AddEventHandler('esx:onPickup', function(id) + local _source = source + local pickup = ESX.Pickups[id] + local xPlayer = ESX.GetPlayerFromId(_source) - local _source = source - local pickup = ESX.Pickups[id] - local xPlayer = ESX.GetPlayerFromId(_source) + if pickup.type == 'item_standard' then - if pickup.type == 'item_standard' then + local item = xPlayer.getInventoryItem(pickup.name) + local canTake = ((item.limit == -1) and (pickup.count)) or ((item.limit - item.count > 0) and (item.limit - item.count)) or 0 + local total = pickup.count < canTake and pickup.count or canTake + local remaining = pickup.count - total - local item = xPlayer.getInventoryItem(pickup.name) - local canTake = ((item.limit == -1) and (pickup.count)) or ((item.limit - item.count > 0) and (item.limit - item.count)) or 0 - local total = pickup.count < canTake and pickup.count or canTake - local remaining = pickup.count - total + TriggerClientEvent('esx:removePickup', -1, id) - TriggerClientEvent('esx:removePickup', -1, id) + if total > 0 then + xPlayer.addInventoryItem(pickup.name, total) + end - if total > 0 then - xPlayer.addInventoryItem(pickup.name, total) - end - - if remaining > 0 then - TriggerClientEvent('esx:showNotification', _source, _U('cannot_pickup_room', item.label)) - ESX.CreatePickup('item_standard', pickup.name, remaining, item.label .. ' [' .. remaining .. ']', _source) - end - - elseif pickup.type == 'item_money' then - TriggerClientEvent('esx:removePickup', -1, id) - xPlayer.addMoney(pickup.count) - elseif pickup.type == 'item_account' then - TriggerClientEvent('esx:removePickup', -1, id) - xPlayer.addAccountMoney(pickup.name, pickup.count) - end + if remaining > 0 then + TriggerClientEvent('esx:showNotification', _source, _U('cannot_pickup_room', item.label)) + ESX.CreatePickup('item_standard', pickup.name, remaining, item.label .. ' [' .. remaining .. ']', _source) + end + elseif pickup.type == 'item_money' then + TriggerClientEvent('esx:removePickup', -1, id) + xPlayer.addMoney(pickup.count) + elseif pickup.type == 'item_account' then + TriggerClientEvent('esx:removePickup', -1, id) + xPlayer.addAccountMoney(pickup.name, pickup.count) + end end) ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) - local xPlayer = ESX.GetPlayerFromId(source) - - cb({ - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') - }) - + cb({ + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.get('money') + }) end) ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target) + local xPlayer = ESX.GetPlayerFromId(target) - local xPlayer = ESX.GetPlayerFromId(target) - - cb({ - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') - }) - + cb({ + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + lastPosition = xPlayer.getLastPosition(), + money = xPlayer.get('money') + }) end) TriggerEvent("es:addGroup", "jobmaster", "user", function(group) end) diff --git a/shared/functions.lua b/shared/functions.lua index 222c163f..d55ec2b0 100644 --- a/shared/functions.lua +++ b/shared/functions.lua @@ -14,6 +14,10 @@ ESX.GetRandomString = function(length) end end +ESX.GetConfig = function() + return Config +end + ESX.TableContainsValue = function(table, value) for k, v in pairs(table) do if v == value then From 810949fe0913ed9a235082949ec7fd21a981ed5d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 20 Sep 2018 22:45:00 +0200 Subject: [PATCH 242/672] Performance improvements --- client/main.lua | 8 ++- server/classes/player.lua | 100 ++++++++++++++++++++------------------ server/main.lua | 9 ++-- 3 files changed, 60 insertions(+), 57 deletions(-) diff --git a/client/main.lua b/client/main.lua index 014e93d5..da20c066 100644 --- a/client/main.lua +++ b/client/main.lua @@ -60,7 +60,7 @@ AddEventHandler('playerSpawned', function() -- Restore position if ESX.PlayerData.lastPosition ~= nil then - SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.lastPosition.z) + SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.lastPosition.z) end TriggerEvent('esx:restoreLoadout') -- restore loadout @@ -401,7 +401,7 @@ end) -- Pause menu disable HUD display Citizen.CreateThread(function() while true do - Citizen.Wait(1) + Citizen.Wait(500) if IsPauseMenuActive() and not IsPaused then IsPaused = true @@ -419,7 +419,7 @@ end) Citizen.CreateThread(function() while true do - Citizen.Wait(1) + Citizen.Wait(500) local playerPed = PlayerPedId() local loadout = {} @@ -504,7 +504,6 @@ if Config.DisableWantedLevel then Citizen.CreateThread(function() while true do - Citizen.Wait(10) local playerId = PlayerId() @@ -512,7 +511,6 @@ if Config.DisableWantedLevel then SetPlayerWantedLevel(playerId, 0, false) SetPlayerWantedLevelNow(playerId, false) end - end end) diff --git a/server/classes/player.lua b/server/classes/player.lua index a54e2d60..3bd4ef3c 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -12,11 +12,13 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.source = self.player.get('source') self.identifier = self.player.get('identifier') - self.setMoney = function(m) - if m >= 0 then - self.player.setMoney(m) + self.setMoney = function(money) + money = ESX.Round(money) + + if money >= 0 then + self.player.setMoney(money) else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 cash balance)') + print(('es_extended: %s attempted exploiting! (reason: player tried setting -1 cash balance)'):format(self.identifier)) end end @@ -24,11 +26,13 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return self.player.get('money') end - self.setBankBalance = function(m) - if m >= 0 then - self.player.setBankBalance(m) + self.setBankBalance = function(money) + money = ESX.Round(money) + + if money >= 0 then + self.player.setBankBalance(money) else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 bank balance)') + print(('es_extended: %s attempted exploiting! (reason: player tried setting -1 bank balance)'):format(self.identifier)) end end @@ -48,44 +52,52 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.player.kick(r) end - self.addMoney = function(m) - if m >= 0 then - self.player.addMoney(m) + self.addMoney = function(money) + money = ESX.Round(money) + + if money >= 0 then + self.player.addMoney(money) else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 cash balance)') + print(('es_extended: %s attempted exploiting! (reason: player tried adding -1 cash balance)'):format(self.identifier)) end end - self.removeMoney = function(m) - if m >= 0 then - self.player.removeMoney(m) + self.removeMoney = function(money) + money = ESX.Round(money) + + if money >= 0 then + self.player.removeMoney(money) else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 cash balance)') + print(('es_extended: %s attempted exploiting! (reason: player tried removing -1 cash balance)'):format(self.identifier)) end end - self.addBank = function(m) - if m >= 0 then - self.player.addBank(m) + self.addBank = function(money) + money = ESX.Round(money) + + if money >= 0 then + self.player.addBank(money) else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 bank balance)') + print(('es_extended: %s attempted exploiting! (reason: player tried adding -1 bank balance)'):format(self.identifier)) end end - self.removeBank = function(m) - if m >= 0 then - self.player.removeBank(m) + self.removeBank = function(money) + money = ESX.Round(money) + + if money >= 0 then + self.player.removeBank(money) else - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 bank balance)') + print(('es_extended: %s attempted exploiting! (reason: player tried removing -1 bank balance)'):format(self.identifier)) end end - self.displayMoney = function(m) - self.player.displayMoney(m) + self.displayMoney = function(money) + self.player.displayMoney(money) end - self.displayBank = function(m) - self.player.displayBank(m) + self.displayBank = function(money) + self.player.displayBank(money) end self.setSessionVar = function(key, value) @@ -190,13 +202,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l 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 @@ -208,13 +217,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if not found then table.insert(missingAccounts, Config.Accounts[i]) end - end - end cb(missingAccounts) - end) end @@ -232,37 +238,37 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end - self.setAccountMoney = function(a, m) - if m < 0 then - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried setting -1 account balance)') + self.setAccountMoney = function(acc, money) + if money < 0 then + print(('es_extended: %s attempted exploiting! (reason: player tried setting -1 account balance)'):format(self.identifier)) return end - local account = self.getAccount(a) + local account = self.getAccount(acc) local prevMoney = account.money - local newMoney = m + local newMoney = ESX.Round(money) account.money = newMoney - if a == 'bank' then + if acc == 'bank' then self.set('bank', newMoney) end TriggerClientEvent('esx:setAccountMoney', self.source, account) end - self.addAccountMoney = function(a, m) - if m < 0 then - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried adding -1 account balance)') + self.addAccountMoney = function(acc, money) + if money < 0 then + print(('es_extended: %s attempted exploiting! (reason: player tried adding -1 account balance)'):format(self.identifier)) return end - local account = self.getAccount(a) - local newMoney = account.money + m + local account = self.getAccount(acc) + local newMoney = account.money + ESX.Round(money) account.money = newMoney - if a == 'bank' then + if acc == 'bank' then self.set('bank', newMoney) end @@ -271,7 +277,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.removeAccountMoney = function(a, m) if m < 0 then - print('es_extended: ' .. self.name .. ' (' .. self.identifier .. ') attempted exploiting! (reason: player tried removing -1 account balance)') + print(('es_extended: %s attempted exploiting! (reason: player tried removing -1 account balance)'):format(self.identifier)) return end diff --git a/server/main.lua b/server/main.lua index abe364e1..a3ab6237 100644 --- a/server/main.lua +++ b/server/main.lua @@ -251,17 +251,16 @@ end) RegisterServerEvent('esx:updateLoadout') AddEventHandler('esx:updateLoadout', function(loadout) - local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.loadout = loadout + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.loadout = loadout end) RegisterServerEvent('esx:updateLastPosition') AddEventHandler('esx:updateLastPosition', function(position) - local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.lastPosition = position + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.lastPosition = position end) - RegisterServerEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) local _source = source From c7693d471de5ee3249ac8a9997e456fdb497d1ff Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 23 Sep 2018 22:00:19 +0200 Subject: [PATCH 243/672] mysql-async v3.0.1 support --- server/common.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/common.lua b/server/common.lua index 4ed0d53a..82b8496f 100644 --- a/server/common.lua +++ b/server/common.lua @@ -17,7 +17,7 @@ function getSharedObject() return ESX end -AddEventHandler('onMySQLReady', function() +MySQL.ready(function() MySQL.Async.fetchAll('SELECT * FROM items', {}, function(result) for i=1, #result, 1 do ESX.Items[result[i].name] = { From f172cfee9bce722355cc13b5ddcca9e33bcf7035 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 28 Sep 2018 09:17:00 +0200 Subject: [PATCH 244/672] Removed specifiying amount of ammo when giving weapon --- client/functions.lua | 80 ++++---------------------------------------- 1 file changed, 7 insertions(+), 73 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 1867e8ba..a472962c 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -283,7 +283,7 @@ ESX.Game.Teleport = function(entity, coords, cb) Citizen.Wait(0) end - SetEntityCoords(entity, coords.x, coords.y, coords.z) + SetEntityCoords(entity, coords.x, coords.y, coords.z) if cb ~= nil then cb() @@ -1156,41 +1156,9 @@ ESX.ShowInventory = function() end if closestPlayer ~= -1 and closestDistance < 3.0 then - - if sourceAmmo > 0 then - - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', - { - title = _U('amountammo') - }, function(data3, menu3) - local quantity = tonumber(data3.value) - - if quantity ~= nil then - if quantity <= sourceAmmo and quantity >= 0 then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) - - sourceAmmo = sourceAmmo - quantity - SetPedAmmo(playerPed, item, sourceAmmo) - - menu3.close() - menu2.close() - menu1.close() - else - ESX.ShowNotification(_U('noammo')) - end - else - ESX.ShowNotification(_U('amount_invalid')) - end - - end, function(data3, menu3) - menu3.close() - end) - - else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 0) - menu2.close() - menu1.close() - end + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, sourceAmmo) + menu2.close() + menu1.close() else ESX.ShowNotification(_U('players_nearby')) end @@ -1237,8 +1205,6 @@ ESX.ShowInventory = function() menu2.close() end) -- give end - - elseif data1.current.action == 'remove' then if IsPedSittingInAnyVehicle(playerPed) then @@ -1246,40 +1212,9 @@ ESX.ShowInventory = function() end if type == 'item_weapon' then - local pedAmmo = GetAmmoInPedWeapon(PlayerPedId(), GetHashKey(item)) - -- does the player have any ammo for the weapon? - if pedAmmo > 0 then - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', - { - title = _U('amount') - }, function(data2, menu2) - local quantity = tonumber(data2.value) - - if quantity ~= nil then - if quantity <= pedAmmo and quantity >= 0 then - local finalammo = math.floor(pedAmmo - quantity) - - SetPedAmmo(playerPed, item, finalammo) - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) - - menu2.close() - menu1.close() - else - ESX.ShowNotification(_U('noammo')) - end - else - ESX.ShowNotification(_U('amount_invalid')) - end - - - end, function(data2, menu2) - menu2.close() - end) - else - TriggerServerEvent('esx:removeInventoryItem', type, item, 0) - menu1.close() - end + TriggerServerEvent('esx:removeInventoryItem', type, item, nil) + menu1.close() else -- type: item_standard @@ -1350,8 +1285,7 @@ ESX.ShowInventory = function() menu2.close() end) else - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, 0) - menu1.close() + ESX.ShowNotification(_U('noammo')) end else ESX.ShowNotification(_U('players_nearby')) From 6461ee2822aaa530f1503c713fd00b1a5922efe8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 28 Sep 2018 10:34:05 +0200 Subject: [PATCH 245/672] Implemented Config.EnableHud --- client/functions.lua | 3 -- client/main.lua | 104 ++++++++++++++++++++++++------------------- 2 files changed, 58 insertions(+), 49 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index a472962c..c453a2c2 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1023,7 +1023,6 @@ ESX.ShowInventory = function() end for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].count > 0 then table.insert(elements, { label = ESX.PlayerData.inventory[i].label .. ' x' .. ESX.PlayerData.inventory[i].count, @@ -1035,11 +1034,9 @@ ESX.ShowInventory = function() canRemove = ESX.PlayerData.inventory[i].canRemove, }) 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 diff --git a/client/main.lua b/client/main.lua index da20c066..6e155de1 100644 --- a/client/main.lua +++ b/client/main.lua @@ -19,36 +19,42 @@ local isDead = false RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - ESX.PlayerLoaded = true - ESX.PlayerData = xPlayer + ESX.PlayerLoaded = true + ESX.PlayerData = xPlayer - for i=1, #xPlayer.accounts, 1 do - local accountTpl = '
 {{money}}
' + if Config.EnableHud then - ESX.UI.HUD.RegisterElement('account_' .. xPlayer.accounts[i].name, i-1, 0, accountTpl, { - money = 0 + for i=1, #xPlayer.accounts, 1 do + local accountTpl = '
 {{money}}
' + + 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 = '
{{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('account_' .. xPlayer.accounts[i].name, { - money = xPlayer.accounts[i].money + ESX.UI.HUD.UpdateElement('job', { + job_label = xPlayer.job.label, + grade_label = xPlayer.job.grade_label }) + + else + TriggerEvent('es:setMoneyDisplay', 0.0) 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 - }) end) AddEventHandler('playerSpawned', function() @@ -153,13 +159,15 @@ RegisterNetEvent('esx:setAccountMoney') AddEventHandler('esx:setAccountMoney', function(account) for i=1, #ESX.PlayerData.accounts, 1 do if ESX.PlayerData.accounts[i].name == account.name then - ESX.PlayerData.accounts[i] = account + ESX.PlayerData.accounts[i] = account end end - ESX.UI.HUD.UpdateElement('account_' .. account.name, { - money = account.money - }) + if Config.EnableHud then + ESX.UI.HUD.UpdateElement('account_' .. account.name, { + money = account.money + }) + end end) RegisterNetEvent('es:activateMoney') @@ -216,7 +224,7 @@ AddEventHandler('esx:removeWeapon', function(weaponName, ammo) local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) - RemoveWeaponFromPed(playerPed, weaponHash) + RemoveWeaponFromPed(playerPed, weaponHash) if ammo then local pedAmmo = GetAmmoInPedWeapon(playerPed, weaponHash) @@ -246,10 +254,12 @@ end) RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) - ESX.UI.HUD.UpdateElement('job', { - job_label = job.label, - grade_label = job.grade_label - }) + if Config.EnableHud then + ESX.UI.HUD.UpdateElement('job', { + job_label = job.label, + grade_label = job.grade_label + }) + end end) RegisterNetEvent('esx:loadIPL') @@ -399,21 +409,23 @@ end) -- Pause menu disable HUD display -Citizen.CreateThread(function() - while true do - Citizen.Wait(500) +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) + 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) + end) +end -- Save loadout Citizen.CreateThread(function() From 8c596d4c1c1353860006827fbb86834a81ce8cff Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 28 Sep 2018 10:35:41 +0200 Subject: [PATCH 246/672] Implemented Config.EnableHud --- config.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/config.lua b/config.lua index 6113efcb..56f912a6 100644 --- a/config.lua +++ b/config.lua @@ -8,6 +8,7 @@ Config.EnableSocietyPayouts = false -- pay from the society account that the Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.EnableWeaponPickup = true +Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) Config.RemoveInventoryItemDelay = 5 * 60000 Config.PaycheckInterval = 7 * 60000 Config.MaxPlayers = 32 From 4ef2deaa29630751965b96b8fc78a04455b0d2ad Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 30 Sep 2018 17:51:37 +0200 Subject: [PATCH 247/672] JS i18n (locale) libary --- __resource.lua | 1 + locale.js | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ locale.lua | 20 ++++++++-------- 3 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 locale.js diff --git a/__resource.lua b/__resource.lua index ffa72e02..256c1966 100644 --- a/__resource.lua +++ b/__resource.lua @@ -62,6 +62,7 @@ ui_page { } files { + 'locale.js', 'html/ui.html', 'html/css/app.css', diff --git a/locale.js b/locale.js new file mode 100644 index 00000000..4b5390f8 --- /dev/null +++ b/locale.js @@ -0,0 +1,65 @@ +var locale = []; + +/** + * Similar to the concept of gettext, this function returns the + * localized string for the parsed string. The function supports + * wrapping. + * + * @param {string} args The string we want localized + * @return {string} Returns the localized string + * + */ +function _U() { + var args = arguments; + var string = args[0]; + + // Was a string specified? + if (!string) { + console.log('locale.js: no string was parsed'); + return 'locale.js: no string was parsed'; + } + + // Has the locale file been set? + if (locale.length == 0) { + console.log('locale.js: no locale has been set'); + return 'locale.js: no locale has been set'; + } + + // Does the translation exist? + if (!locale[string]) { + console.log('locale.js: translation [{0}] does not exist'.format(string)); + return 'locale.js: translation [{0}] does not exist'.format(string); + } + + // Do we need to format the string? + if (args.length == 1) { + return capitalize(locale[string]); + } else { + return formatString(args); + } +} + +function formatString(args) { + var string = capitalize(locale[args[0]]); + + for (var i = 1; i < args.length; i++) { + string = string.replace(/%s/, args[i]); + } + + return string; +} + +function capitalize(string) { + return string[0].toUpperCase() + string.slice(1); +} + +// https://stackoverflow.com/a/35359503 +String.prototype.format = function () { + var args = arguments; + return this.replace(/{(\d+)}/g, function (match, number) { + return typeof args[number] != 'undefined' + ? args[number] + : match + ; + }); +}; diff --git a/locale.lua b/locale.lua index a116cec4..68de6651 100644 --- a/locale.lua +++ b/locale.lua @@ -2,20 +2,20 @@ Locales = {} function _(str, ...) -- Translate string - if Locales[Config.Locale] ~= nil then + if Locales[Config.Locale] ~= nil then - if Locales[Config.Locale][str] ~= nil then - return string.format(Locales[Config.Locale][str], ...) - else - return 'Translation [' .. Config.Locale .. '][' .. str .. '] does not exist' - end + if Locales[Config.Locale][str] ~= nil then + return string.format(Locales[Config.Locale][str], ...) + else + return 'Translation [' .. Config.Locale .. '][' .. str .. '] does not exist' + end - else - return 'Locale [' .. Config.Locale .. '] does not exist' - end + else + return 'Locale [' .. Config.Locale .. '] does not exist' + end end function _U(str, ...) -- Translate string first char uppercase - return tostring(_(str, ...):gsub("^%l", string.upper)) + return tostring(_(str, ...):gsub("^%l", string.upper)) end From 99bf793b964cce2a944c63e2f44a56390851708f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 13 Oct 2018 20:44:42 +0200 Subject: [PATCH 248/672] Updated readme with github links to ES --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bb376513..95f75664 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ es_extended is a roleplay framework for FiveM. It is developed on top of [EssentialMode](https://essentialmode.com/) (aka ES), thus commonly named ESX - the **Es**sentialMode **E**xtended framework for FiveM. ### Links & Read more -- [Official Discord community](https://discord.me/fivem_esx) - [ESX Documentation](https://esx-org.github.io/) (incomplete) - [ES Documentation](https://docs.essentialmode.com/) +- [FiveM Forum Thread](https://forum.fivem.net/t/release-esx-base/39881) - [FiveM Native Reference](https://runtime.fivem.net/doc/reference.html) ### Screenshot preview (todo) @@ -12,7 +12,7 @@ es_extended is a roleplay framework for FiveM. It is developed on top of [Essent ![screenshot](http://i.imgur.com/aPFdJl3.jpg) ### Features -- Accounts (bank / black money) you can also add others accounts +- Accounts (bank / black money). You can add further accounts - Advanced inventory system (press `F2` ingame) - Job system - Loadouts and position synced in database @@ -23,10 +23,10 @@ es_extended is a roleplay framework for FiveM. It is developed on top of [Essent ### Requirements This order also applies in the startup order. - Base events -- [mysql-async](https://github.com/brouznouf/fivem-mysql-async/releases/latest) -- [EssentialMode](https://essentialmode.com/) (es_admin2 included, a basic admin tool) -- [esplugin_mysql](https://forum.fivem.net/t/release-essentialmode-base/3665/1181) -- [async](https://github.com/ESX-Org/async/releases/latest) +- [mysql-async](https://github.com/brouznouf/fivem-mysql-async) +- [essentialmode](https://github.com/kanersps/essentialmode) +- [esplugin_mysql](https://github.com/kanersps/esplugin_mysql) +- [async](https://github.com/ESX-Org/async) ### Download & Installation From 4c5d1532b21e9c4c6e7f6eff674c182f6efbca4f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 22 Oct 2018 22:37:20 +0200 Subject: [PATCH 249/672] Added ESX.Math.* --- README.md | 1 - __resource.lua | 1 + config.weapons.lua | 184 ++++++++++++++++++++-------------------- locales/br.lua | 2 + locales/cs.lua | 2 + locales/de.lua | 2 + locales/en.lua | 4 +- locales/fi.lua | 2 + locales/fr.lua | 2 + locales/pl.lua | 2 + locales/sv.lua | 70 +++++++-------- shared/functions.lua | 5 +- shared/modules/math.lua | 12 +++ 13 files changed, 158 insertions(+), 131 deletions(-) create mode 100644 shared/modules/math.lua diff --git a/README.md b/README.md index 95f75664..aed31db4 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,6 @@ start baseevents start mysql-async start essentialmode start esplugin_mysql -start es_admin2 start es_extended diff --git a/__resource.lua b/__resource.lua index 256c1966..7e2f587c 100644 --- a/__resource.lua +++ b/__resource.lua @@ -28,6 +28,7 @@ server_scripts { 'server/main.lua', 'server/commands.lua', + 'shared/modules/math.lua', 'shared/functions.lua' } diff --git a/config.weapons.lua b/config.weapons.lua index bff086bd..74627321 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -1,94 +1,94 @@ Config.Weapons = { - { name = 'WEAPON_KNIFE', label = _U('weapon_knife') }, - { name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick') }, - { name = 'WEAPON_HAMMER', label = _U('weapon_hammer') }, - { name = 'WEAPON_BAT', label = _U('weapon_bat') }, - { name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub') }, - { name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar') }, - { name = 'WEAPON_PISTOL', label = _U('weapon_pistol') }, - { name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol') }, - { name = 'WEAPON_APPISTOL', label = _U('weapon_appistol') }, - { name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50') }, - { name = 'WEAPON_MICROSMG', label = _U('weapon_microsmg') }, - { name = 'WEAPON_SMG', label = _U('weapon_smg') }, - { name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg') }, - { name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle') }, - { name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle') }, - { name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle') }, - { name = 'WEAPON_MG', label = _U('weapon_mg') }, - { name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg') }, - { name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun') }, - { name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun') }, - { name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun') }, - { name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun') }, - { name = 'WEAPON_STUNGUN', label = _U('weapon_stungun') }, - { name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle') }, - { name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper') }, - { name = 'WEAPON_REMOTESNIPER', label = _U('weapon_remotesniper') }, - { name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher') }, - { name = 'WEAPON_RPG', label = _U('weapon_rpg') }, - { name = 'WEAPON_STINGER', label = _U('weapon_stinger') }, - { name = 'WEAPON_MINIGUN', label = _U('weapon_minigun') }, - { name = 'WEAPON_GRENADE', label = _U('weapon_grenade') }, - { name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb') }, - { name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade') }, - { name = 'WEAPON_BZGAS', label = _U('weapon_bzgas') }, - { name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov') }, - { name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher') }, - { name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan') }, - { name = 'WEAPON_DIGISCANNER', label = _U('weapon_digiscanner') }, - { name = 'WEAPON_BALL', label = _U('weapon_ball') }, - { name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol') }, - { name = 'WEAPON_BOTTLE', label = _U('weapon_bottle') }, - { name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg') }, - { name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine') }, - { name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol') }, - { name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle') }, - { name = 'WEAPON_DAGGER', label = _U('weapon_dagger') }, - { name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol') }, - { name = 'WEAPON_FIREWORK', label = _U('weapon_firework') }, - { name = 'WEAPON_MUSKET', label = _U('weapon_musket') }, - { name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun') }, - { name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle') }, - { name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher') }, - { name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine') }, - { name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball') }, - { name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun') }, - { name = 'WEAPON_GARBAGEBAG', label = _U('weapon_garbagebag') }, - { name = 'WEAPON_HANDCUFFS', label = _U('weapon_handcuffs') }, - { name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw') }, - { name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol') }, - { name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle') }, - { name = 'WEAPON_HATCHET', label = _U('weapon_hatchet') }, - { name = 'WEAPON_RAILGUN', label = _U('weapon_railgun') }, - { name = 'WEAPON_MACHETE', label = _U('weapon_machete') }, - { name = 'WEAPON_MACHINEPISTOL', label = _U('weapon_machinepistol') }, - { name = 'WEAPON_SWITCHBLADE', label = _U('weapon_switchblade') }, - { name = 'WEAPON_REVOLVER', label = _U('weapon_revolver') }, - { name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun') }, - { name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle') }, - { name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun') }, - { name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe') }, - { name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher') }, - { name = 'WEAPON_MINISMG', label = _U('weapon_minismg') }, - { name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb') }, - { name = 'WEAPON_POOLCUE', label = _U('weapon_poolcue') }, - { name = 'WEAPON_WRENCH', label = _U('weapon_wrench') }, - { name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight') }, - { name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision') }, - { name = 'GADGET_PARACHUTE', label = _U('gadget_parachute') }, - { name = 'WEAPON_FLARE', label = _U('weapon_flare') }, - { name = 'WEAPON_SNSPISTOL_MK2', label = _U('weapon_snspistol_mk2') }, - { name = 'WEAPON_REVOLVER_MK2', label = _U('weapon_revolver_mk2') }, - { name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction') }, - { name = 'WEAPON_SPECIALCARBINE_MK2', label = _U('weapon_specialcarabine_mk2') }, - { name = 'WEAPON_BULLPUPRIFLE_MK2', label = _U('weapon_bullpruprifle_mk2') }, - { name = 'WEAPON_PUMPSHOTGUN_MK2', label = _U('weapon_pumpshotgun_mk2') }, - { name = 'WEAPON_MARKSMANRIFLE_MK2', label = _U('weapon_marksmanrifle_mk2') }, - { name = 'WEAPON_ASSAULTRIFLE_MK2', label = _U('weapon_assaultrifle_mk2') }, - { name = 'WEAPON_CARBINERIFLE_MK2', label = _U('weapon_carbinerifle_mk2') }, - { name = 'WEAPON_COMBATMG_MK2', label = _U('weapon_combatmg_mk2') }, - { name = 'WEAPON_HEAVYSNIPER_MK2', label = _U('weapon_heavysniper_mk2') }, - { name = 'WEAPON_PISTOL_MK2', label = _U('weapon_pistol_mk2') }, - { name = 'WEAPON_SMG_MK2', label = _U('weapon_smg_mk2') }, + { name = 'WEAPON_KNIFE', label = _U('weapon_knife') }, + { name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick') }, + { name = 'WEAPON_HAMMER', label = _U('weapon_hammer') }, + { name = 'WEAPON_BAT', label = _U('weapon_bat') }, + { name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub') }, + { name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar') }, + { name = 'WEAPON_PISTOL', label = _U('weapon_pistol') }, + { name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol') }, + { name = 'WEAPON_APPISTOL', label = _U('weapon_appistol') }, + { name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50') }, + { name = 'WEAPON_MICROSMG', label = _U('weapon_microsmg') }, + { name = 'WEAPON_SMG', label = _U('weapon_smg') }, + { name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg') }, + { name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle') }, + { name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle') }, + { name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle') }, + { name = 'WEAPON_MG', label = _U('weapon_mg') }, + { name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg') }, + { name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun') }, + { name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun') }, + { name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun') }, + { name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun') }, + { name = 'WEAPON_STUNGUN', label = _U('weapon_stungun') }, + { name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle') }, + { name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper') }, + { name = 'WEAPON_REMOTESNIPER', label = _U('weapon_remotesniper') }, + { name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher') }, + { name = 'WEAPON_RPG', label = _U('weapon_rpg') }, + { name = 'WEAPON_STINGER', label = _U('weapon_stinger') }, + { name = 'WEAPON_MINIGUN', label = _U('weapon_minigun') }, + { name = 'WEAPON_GRENADE', label = _U('weapon_grenade') }, + { name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb') }, + { name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade') }, + { name = 'WEAPON_BZGAS', label = _U('weapon_bzgas') }, + { name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov') }, + { name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher') }, + { name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan') }, + { name = 'WEAPON_DIGISCANNER', label = _U('weapon_digiscanner') }, + { name = 'WEAPON_BALL', label = _U('weapon_ball') }, + { name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol') }, + { name = 'WEAPON_BOTTLE', label = _U('weapon_bottle') }, + { name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg') }, + { name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine') }, + { name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol') }, + { name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle') }, + { name = 'WEAPON_DAGGER', label = _U('weapon_dagger') }, + { name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol') }, + { name = 'WEAPON_FIREWORK', label = _U('weapon_firework') }, + { name = 'WEAPON_MUSKET', label = _U('weapon_musket') }, + { name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun') }, + { name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle') }, + { name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher') }, + { name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine') }, + { name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball') }, + { name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun') }, + { name = 'WEAPON_GARBAGEBAG', label = _U('weapon_garbagebag') }, + { name = 'WEAPON_HANDCUFFS', label = _U('weapon_handcuffs') }, + { name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw') }, + { name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol') }, + { name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle') }, + { name = 'WEAPON_HATCHET', label = _U('weapon_hatchet') }, + { name = 'WEAPON_RAILGUN', label = _U('weapon_railgun') }, + { name = 'WEAPON_MACHETE', label = _U('weapon_machete') }, + { name = 'WEAPON_MACHINEPISTOL', label = _U('weapon_machinepistol') }, + { name = 'WEAPON_SWITCHBLADE', label = _U('weapon_switchblade') }, + { name = 'WEAPON_REVOLVER', label = _U('weapon_revolver') }, + { name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun') }, + { name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle') }, + { name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun') }, + { name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe') }, + { name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher') }, + { name = 'WEAPON_MINISMG', label = _U('weapon_minismg') }, + { name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb') }, + { name = 'WEAPON_POOLCUE', label = _U('weapon_poolcue') }, + { name = 'WEAPON_WRENCH', label = _U('weapon_wrench') }, + { name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight') }, + { name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision') }, + { name = 'GADGET_PARACHUTE', label = _U('gadget_parachute') }, + { name = 'WEAPON_FLARE', label = _U('weapon_flare') }, + { name = 'WEAPON_SNSPISTOL_MK2', label = _U('weapon_snspistol_mk2') }, + { name = 'WEAPON_REVOLVER_MK2', label = _U('weapon_revolver_mk2') }, + { name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction') }, + { name = 'WEAPON_SPECIALCARBINE_MK2', label = _U('weapon_specialcarabine_mk2') }, + { name = 'WEAPON_BULLPUPRIFLE_MK2', label = _U('weapon_bullpruprifle_mk2') }, + { name = 'WEAPON_PUMPSHOTGUN_MK2', label = _U('weapon_pumpshotgun_mk2') }, + { name = 'WEAPON_MARKSMANRIFLE_MK2', label = _U('weapon_marksmanrifle_mk2') }, + { name = 'WEAPON_ASSAULTRIFLE_MK2', label = _U('weapon_assaultrifle_mk2') }, + { name = 'WEAPON_CARBINERIFLE_MK2', label = _U('weapon_carbinerifle_mk2') }, + { name = 'WEAPON_COMBATMG_MK2', label = _U('weapon_combatmg_mk2') }, + { name = 'WEAPON_HEAVYSNIPER_MK2', label = _U('weapon_heavysniper_mk2') }, + { name = 'WEAPON_PISTOL_MK2', label = _U('weapon_pistol_mk2') }, + { name = 'WEAPON_SMG_MK2', label = _U('weapon_smg_mk2') } } diff --git a/locales/br.lua b/locales/br.lua index f8b1c12c..07dde39b 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -68,6 +68,8 @@ Locales['br'] = { ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', + -- Locale settings + ['locale_digit_grouping_symbol'] = ' ', -- Weapons ['weapon_knife'] = 'faca', ['weapon_nightstick'] = 'cacetete', diff --git a/locales/cs.lua b/locales/cs.lua index 111dc8ee..4193b2af 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -72,6 +72,8 @@ Locales['cs'] = { ['disconnect'] = 'odpojit od serveru', ['chat_clear'] = 'vyčistit chat', ['chat_clear_all'] = 'vyčistit chat pro všechny', + -- Locale settings + ['locale_digit_grouping_symbol'] = ' ', -- Weapons ['weapon_knife'] = 'knife', ['weapon_nightstick'] = 'nightstick', diff --git a/locales/de.lua b/locales/de.lua index 8f4654c8..2ea6b598 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -62,6 +62,8 @@ Locales['de'] = { ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', + -- Locale settings + ['locale_digit_grouping_symbol'] = ' ', -- Weapons ['weapon_knife'] = 'Messer', ['weapon_nightstick'] = 'Schlagstock', diff --git a/locales/en.lua b/locales/en.lua index ec0ab2f5..82317285 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -72,6 +72,8 @@ Locales['en'] = { ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', + -- Locale settings + ['locale_digit_grouping_symbol'] = ',', -- Weapons ['weapon_knife'] = 'knife', ['weapon_nightstick'] = 'nightstick', @@ -95,7 +97,7 @@ Locales['en'] = { ['weapon_sawnoffshotgun'] = 'sawed off shotgun', ['weapon_assaultshotgun'] = 'assault shotgun', ['weapon_bullpupshotgun'] = 'bullpup shotgun', - ['weapon_stungun'] = 'tazer', + ['weapon_stungun'] = 'taser', ['weapon_sniperrifle'] = 'sniper rifle', ['weapon_heavysniper'] = 'heavy sniper', ['weapon_remotesniper'] = 'remote sniper', diff --git a/locales/fi.lua b/locales/fi.lua index f9334de4..4c248515 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -72,6 +72,8 @@ Locales['fi'] = { ['disconnect'] = 'poistu serveriltä', ['chat_clear'] = 'tyhjennä chatti', ['chat_clear_all'] = 'tyhjennä chatti kaikilta', + -- Locale settings + ['locale_digit_grouping_symbol'] = ' ', -- Weapons ['weapon_knife'] = 'veitsi', ['weapon_nightstick'] = 'pamppu', diff --git a/locales/fr.lua b/locales/fr.lua index 41c34d5e..818e1892 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -69,6 +69,8 @@ Locales['fr'] = { ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', + -- Locale settings + ['locale_digit_grouping_symbol'] = ' ', -- Weapons ['weapon_knife'] = 'couteau', ['weapon_nightstick'] = 'matraque', diff --git a/locales/pl.lua b/locales/pl.lua index f9e369f9..ef580470 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -69,6 +69,8 @@ Locales['pl'] = { ['weapon'] = 'broń', ['giveweapon'] = 'daj broń', ['disconnect'] = 'odłącz się od serwera', + -- Locale settings + ['locale_digit_grouping_symbol'] = ' ', -- Weapons ['weapon_knife'] = 'nóż', ['weapon_nightstick'] = 'pałka', diff --git a/locales/sv.lua b/locales/sv.lua index f9b3c19a..f71c0096 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -55,7 +55,7 @@ Locales['sv'] = { ['delete_veh_param'] = 'tryck enter', ['spawn_object'] = 'spawna föremål', ['spawn_ped'] = 'spawna NPC', - ['spawn_ped_param'] = 'exempel a_m_m_hillbilly_01', + ['spawn_ped_param'] = 'exempelvis a_m_m_hillbilly_01', ['givemoney'] = 'ge pengar', ['setmoney'] = 'bestäm mängd pengar till en valfri person', ['money_type'] = 'giltiga typer: cash, bank, black', @@ -72,13 +72,15 @@ Locales['sv'] = { ['disconnect'] = 'koppla från servern', ['chat_clear'] = 'töm chatten', ['chat_clear_all'] = 'töm chatten för alla', + -- Locale settings + ['locale_digit_grouping_symbol'] = ' ', -- Weapons - ['weapon_knife'] = 'knife', - ['weapon_nightstick'] = 'nightstick', - ['weapon_hammer'] = 'hammer', - ['weapon_bat'] = 'bat', + ['weapon_knife'] = 'kniv', + ['weapon_nightstick'] = 'batong', + ['weapon_hammer'] = 'hammare', + ['weapon_bat'] = 'slagträ', ['weapon_golfclub'] = 'golf club', - ['weapon_crowbar'] = 'crow bar', + ['weapon_crowbar'] = 'kofot', ['weapon_pistol'] = 'pistol', ['weapon_combatpistol'] = 'combat pistol', ['weapon_appistol'] = 'ap pistol', @@ -95,45 +97,45 @@ Locales['sv'] = { ['weapon_sawnoffshotgun'] = 'sawed off shotgun', ['weapon_assaultshotgun'] = 'assault shotgun', ['weapon_bullpupshotgun'] = 'bullpup shotgun', - ['weapon_stungun'] = 'tazer', - ['weapon_sniperrifle'] = 'sniper rifle', - ['weapon_heavysniper'] = 'heavy sniper', + ['weapon_stungun'] = 'elchockpistol', + ['weapon_sniperrifle'] = 'prickskyttegevär', + ['weapon_heavysniper'] = 'tung prickskytt', ['weapon_remotesniper'] = 'remote sniper', - ['weapon_grenadelauncher'] = 'grenade launcher', - ['weapon_rpg'] = 'rocket launcher', + ['weapon_grenadelauncher'] = 'granatkastare', + ['weapon_rpg'] = 'raketgevär', ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', - ['weapon_grenade'] = 'grenade', - ['weapon_stickybomb'] = 'sticky bomb', - ['weapon_smokegrenade'] = 'smoke grenade', + ['weapon_grenade'] = 'granat', + ['weapon_stickybomb'] = 'klibbig bomb', + ['weapon_smokegrenade'] = 'rökgranat', ['weapon_bzgas'] = 'bz gas', ['weapon_molotov'] = 'molotov cocktail', - ['weapon_fireextinguisher'] = 'fire extinguisher', - ['weapon_petrolcan'] = 'jerrycan', + ['weapon_fireextinguisher'] = 'brandsläckare', + ['weapon_petrolcan'] = 'bensindunk', ['weapon_digiscanner'] = 'digiscanner', - ['weapon_ball'] = 'ball', + ['weapon_ball'] = 'boll', ['weapon_snspistol'] = 'sns pistol', - ['weapon_bottle'] = 'bottle', + ['weapon_bottle'] = 'flaska', ['weapon_gusenberg'] = 'gusenberg sweeper', ['weapon_specialcarbine'] = 'special carbine', ['weapon_heavypistol'] = 'heavy pistol', ['weapon_bullpuprifle'] = 'bullpup rifle', - ['weapon_dagger'] = 'dagger', + ['weapon_dagger'] = 'dolk', ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_firework'] = 'firework', - ['weapon_musket'] = 'musket', + ['weapon_firework'] = 'fyrverkeri', + ['weapon_musket'] = 'musköt', ['weapon_heavyshotgun'] = 'heavy shotgun', ['weapon_marksmanrifle'] = 'marksman rifle', ['weapon_hominglauncher'] = 'homing launcher', ['weapon_proxmine'] = 'proximity mine', - ['weapon_snowball'] = 'snow ball', - ['weapon_flaregun'] = 'flaregun', - ['weapon_garbagebag'] = 'garbage bag', - ['weapon_handcuffs'] = 'handcuffs', + ['weapon_snowball'] = 'snöboll', + ['weapon_flaregun'] = 'signalpistol', + ['weapon_garbagebag'] = 'soppåse', + ['weapon_handcuffs'] = 'handklovar', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', - ['weapon_knuckle'] = 'knuckledusters', - ['weapon_hatchet'] = 'hatchet', + ['weapon_knuckle'] = 'knogjärn', + ['weapon_hatchet'] = 'yxa', ['weapon_railgun'] = 'railgun', ['weapon_machete'] = 'machete', ['weapon_machinepistol'] = 'machine pistol', @@ -142,16 +144,16 @@ Locales['sv'] = { ['weapon_dbshotgun'] = 'double barrel shotgun', ['weapon_compactrifle'] = 'compact rifle', ['weapon_autoshotgun'] = 'auto shotgun', - ['weapon_battleaxe'] = 'battle axe', + ['weapon_battleaxe'] = 'stridsyxa', ['weapon_compactlauncher'] = 'compact launcher', ['weapon_minismg'] = 'mini smg', ['weapon_pipebomb'] = 'pipe bomb', - ['weapon_poolcue'] = 'pool cue', - ['weapon_wrench'] = 'pipe wrench', - ['weapon_flashlight'] = 'flashlight', - ['gadget_nightvision'] = 'night vision', - ['gadget_parachute'] = 'parachute', - ['weapon_flare'] = 'flare gun', + ['weapon_poolcue'] = 'biljardkö', + ['weapon_wrench'] = 'rörtång', + ['weapon_flashlight'] = 'ficklampa', + ['gadget_nightvision'] = 'mörkerseende', + ['gadget_parachute'] = 'fallskärm', + ['weapon_flare'] = 'signalpistol', ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', ['weapon_doubleaction'] = 'Double-Action Revolver', diff --git a/shared/functions.lua b/shared/functions.lua index d55ec2b0..84f3ec3b 100644 --- a/shared/functions.lua +++ b/shared/functions.lua @@ -59,7 +59,6 @@ ESX.DumpTable = function(table, nb) end -ESX.Round = function(value) - return value >= 0 and math.floor(value + 0.5) or math.ceil(value - 0.5) +ESX.Round = function(value, numDecimalPlaces) + return ESX.Math.Round(value, numDecimalPlaces) end - diff --git a/shared/modules/math.lua b/shared/modules/math.lua new file mode 100644 index 00000000..23273627 --- /dev/null +++ b/shared/modules/math.lua @@ -0,0 +1,12 @@ +ESX.Math = {} + +ESX.Math.Round = function(value, numDecimalPlaces) + return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", value)) +end + +-- credit http://richard.warburton.it +ESX.Math.GroupDigits = function(value) + local left,num,right = string.match(value,'^([^%d]*%d)(%d*)(.-)$') + + return left..(num:reverse():gsub('(%d%d%d)','%1' .. _U('locale_digit_grouping_symbol')):reverse())..right +end From 23ef814d82730a599124e5f9e3db7ca6605c4ecb Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 6 Nov 2018 20:10:55 +0100 Subject: [PATCH 250/672] Push forgotten resource metadata, closes #156 --- __resource.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/__resource.lua b/__resource.lua index 7e2f587c..3826fd4d 100644 --- a/__resource.lua +++ b/__resource.lua @@ -55,6 +55,7 @@ client_scripts { 'client/modules/scaleform.lua', 'client/modules/streaming.lua', + 'shared/modules/math.lua', 'shared/functions.lua' } From aedd4132cdd83794f2842fd88ecdb5d340b07229 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 9 Nov 2018 23:38:00 +0100 Subject: [PATCH 251/672] Only select what we need --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index a3ab6237..9bcf75f9 100644 --- a/server/main.lua +++ b/server/main.lua @@ -129,7 +129,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get job name, grade and last position table.insert(tasks2, function(cb2) - MySQL.Async.fetchAll('SELECT * FROM `users` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT loadout, position FROM `users` WHERE `identifier` = @identifier', { ['@identifier'] = player.getIdentifier() }, function(result) userData.job['name'] = result[1].job From db50388543b51dfd7dc166196fec8fad5b09ef5c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 10:37:27 +0100 Subject: [PATCH 252/672] Minor changes, missing semicolons in JS --- __resource.lua | 3 -- client/functions.lua | 2 +- client/main.lua | 8 ++-- config.lua | 4 +- es_extended.sql | 2 - html/css/app.css | 4 +- html/img/keys/enter.png | Bin 941 -> 0 bytes html/img/keys/return.png | Bin 376 -> 0 bytes html/js/app.js | 99 +++++++++++++++++++-------------------- 9 files changed, 57 insertions(+), 65 deletions(-) delete mode 100644 html/img/keys/enter.png delete mode 100644 html/img/keys/return.png diff --git a/__resource.lua b/__resource.lua index 3826fd4d..c947865a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -76,9 +76,6 @@ files { 'html/fonts/pdown.ttf', 'html/fonts/bankgothic.ttf', - 'html/img/keys/enter.png', - 'html/img/keys/return.png', - 'html/img/accounts/bank.png', 'html/img/accounts/black_money.png' } diff --git a/client/functions.lua b/client/functions.lua index c453a2c2..5131653e 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -261,7 +261,7 @@ ESX.GetWeaponLabel = function(name) for i=1, #weapons, 1 do if weapons[i].name == name then - return weapons[i].label + return weapons[i].label end end end diff --git a/client/main.lua b/client/main.lua index 6e155de1..6bd986b0 100644 --- a/client/main.lua +++ b/client/main.lua @@ -160,6 +160,7 @@ AddEventHandler('esx:setAccountMoney', function(account) for i=1, #ESX.PlayerData.accounts, 1 do if ESX.PlayerData.accounts[i].name == account.name then ESX.PlayerData.accounts[i] = account + break end end @@ -179,7 +180,7 @@ RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count) for i=1, #ESX.PlayerData.inventory, 1 do if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item + ESX.PlayerData.inventory[i] = item end end @@ -194,7 +195,7 @@ RegisterNetEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(item, count) for i=1, #ESX.PlayerData.inventory, 1 do if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item + ESX.PlayerData.inventory[i] = item end end @@ -407,7 +408,6 @@ AddEventHandler('esx:deleteVehicle', function() end end) - -- Pause menu disable HUD display if Config.EnableHud then Citizen.CreateThread(function() @@ -544,7 +544,7 @@ Citizen.CreateThread(function() for k,v in pairs(Pickups) do - local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true) + local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true) local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() if distance <= 5.0 then diff --git a/config.lua b/config.lua index 56f912a6..c7a6590b 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,5 @@ Config = {} -Config.Locale = 'fr' +Config.Locale = 'sv' Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } @@ -9,7 +9,9 @@ Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.EnableWeaponPickup = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) + Config.RemoveInventoryItemDelay = 5 * 60000 Config.PaycheckInterval = 7 * 60000 Config.MaxPlayers = 32 + Config.EnableDebug = false diff --git a/es_extended.sql b/es_extended.sql index badf8f87..31fa0467 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -44,7 +44,6 @@ CREATE TABLE `jobs` ( INSERT INTO `jobs` VALUES ('unemployed','Unemployed'); CREATE TABLE `user_accounts` ( - `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `name` varchar(255) NOT NULL, @@ -54,7 +53,6 @@ CREATE TABLE `user_accounts` ( ); CREATE TABLE `user_inventory` ( - `id` int(11) NOT NULL AUTO_INCREMENT, `identifier` varchar(255) NOT NULL, `item` varchar(255) NOT NULL, diff --git a/html/css/app.css b/html/css/app.css index e4327c9c..bac47fad 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -1,11 +1,11 @@ @font-face { font-family: 'Pricedown'; - src: url('../fonts/pdown.ttf')/* TTF file for CSS3 browsers */ + src: url('../fonts/pdown.ttf') } @font-face { font-family: 'bankgothic'; - src: url('../fonts/bankgothic.ttf')/* TTF file for CSS3 browsers */ + src: url('../fonts/bankgothic.ttf') } html { diff --git a/html/img/keys/enter.png b/html/img/keys/enter.png deleted file mode 100644 index 3eb9a1f69f58c651517329c92d28cdb1c605f165..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 941 zcmeAS@N?(olHy`uVBq!ia0vp^4M6O`!2~2@x4h5*QjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`ISV`@iy0XB4ude`@%$Aj3=GUpo-U3d6>)E`8wN=`3bZEbov^iFaeu%P z(=cbwj44wlOz4rm5xb{;*Ri~}uR6cp(A&Mg;nJ7c^H#o^DiE{vT2%I1{SRyZiuLSP z%I`LO*R@CY*bePa+aw;ZJ8?S+Bq+DcEWq?az(jNYVCfZ787ofAZePh8!fO)pBkQX z_v_cMN3~tQ9xnRXb?ICkwaPbd-|8+sfB5~ocaKb5*$ZEQP2MMD?ps&IpveBkTdrZ6 zxw-l0$rY8AfmJN&5XWi1Tr~N;qpPCYQm=EdrvtPXJvz5h@~FDPw92D`R+fPvAFW@~ zU8c75`%1Gbh1a`Q>?qE0`*<(h^|W${-y)Ec<2}XS`n>x2)3WZB?5;)4TWYMP-*<76OIq zPp@4X%Z+C%*K#BUX=ORzsAov;Kl`m>i&y`Jz)nzj*Qmyplm-1%6v*YUbiCHwmEO<$ zF|Z@`-}HhOKR<9>X}?rT5Bm9ye^tw4euv}#-v4JmQzRDkY{|X*_d_{Xwfto_xNQ|y z-^Qlff58%JWZtYCU#*y5vIf?_WBTiPU(9hK5Tmx!-~Iodkpb3zr{Lwk`bljQz#(xy zvE05v9vtTHlU}QP{nuV*08Uf+$??{$l9IqgWxio$Zh{XeF$LeaxXn-#^iFnsKzTLkWYeXNfKEXTvUB0pJdzPZ}OMgdS+TyQ( lJso37+@RE7f9~qla<)GklNn{1`ISV`@iy0XBj({-ZRBb+Kpaxz~7srr_xVN`&cQqS`I9#;&|Ns0smZ-L@ zqu)%cbtmkrE=&Hfsn_t^{^k|)kLw3AbqG7mVR+;>`#|k>^_ZL6&QAQlndu0pf*(U6 zREkAFy}^PJuTYF$!{g|Ur7IbD{_6-gJlsE>3DGO)9eE;D=anIC*ESQi{xCV$~42}L!4TJCrkQD1~tJw zr&teYqgpL=o@s|#!;B|~71m*K { - ESX = {}; + ESX = {}; ESX.HUDElements = []; - ESX.setHUDDisplay = function(opacity){ + ESX.setHUDDisplay = function (opacity) { $('#hud').css('opacity', opacity); - } - - ESX.insertHUDElement = function(name, index, priority, html, data){ + }; + ESX.insertHUDElement = function (name, index, priority, html, data) { ESX.HUDElements.push({ - name : name, - index : index, - priority : priority, - html : html, - data : data - }) + name: name, + index: index, + priority: priority, + html: html, + data: data + }); - ESX.HUDElements.sort((a,b) => { + ESX.HUDElements.sort((a, b) => { return a.index - b.index || b.priority - a.priority; - }) + }); + }; - } + ESX.updateHUDElement = function (name, data) { - ESX.updateHUDElement = function(name, data){ - - for(let i=0; i { - - switch(data.action){ - - case 'setHUDDisplay' : { + switch (data.action) { + case 'setHUDDisplay': { ESX.setHUDDisplay(data.opacity); break; } - case 'insertHUDElement' : { + case 'insertHUDElement': { ESX.insertHUDElement(data.name, data.index, data.priority, data.html, data.data); break; } - case 'updateHUDElement' : { + case 'updateHUDElement': { ESX.updateHUDElement(data.name, data.data); break; } - case 'deleteHUDElement' : { + case 'deleteHUDElement': { ESX.deleteHUDElement(data.name); break; } - case 'inventoryNotification' : { - ESX.inventoryNotification(data.add, data.item, data.count) + case 'inventoryNotification': { + ESX.inventoryNotification(data.add, data.item, data.count); } - } + }; - } - - window.onload = function(e){ + window.onload = function (e) { window.addEventListener('message', (event) => { - onData(event.data) + onData(event.data); }); - } + }; -})() \ No newline at end of file +})(); \ No newline at end of file From bac7be4f6b04ee61627bec09a619e15c3db38dea Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 10:38:00 +0100 Subject: [PATCH 253/672] Added setName() to xPlayer class --- server/classes/player.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/classes/player.lua b/server/classes/player.lua index 3bd4ef3c..03f29901 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -194,6 +194,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return self.name end + self.setName = function(newName) + self.name = newName + end + self.getLastPosition = function() return self.lastPosition end From 9093c9912b4ffce4a46d7e2ae9523fbd05d2dbf0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 11:11:07 +0100 Subject: [PATCH 254/672] Fixed #157 --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 9bcf75f9..d3717a86 100644 --- a/server/main.lua +++ b/server/main.lua @@ -129,7 +129,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get job name, grade and last position table.insert(tasks2, function(cb2) - MySQL.Async.fetchAll('SELECT loadout, position FROM `users` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM `users` WHERE `identifier` = @identifier', { ['@identifier'] = player.getIdentifier() }, function(result) userData.job['name'] = result[1].job From 08df1362491a808b113b9d89d66c727007821e33 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Nov 2018 21:44:23 +0100 Subject: [PATCH 255/672] Default language to France --- config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.lua b/config.lua index c7a6590b..a42083d6 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,5 @@ Config = {} -Config.Locale = 'sv' +Config.Locale = 'fr' Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } From a4152db8c36588e5f594675f5572310d5aa046fc Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 11 Nov 2018 11:52:16 +0100 Subject: [PATCH 256/672] xPlayer.hasWeapon() function --- server/classes/player.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 03f29901..114cc66d 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -384,15 +384,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end - local foundWeapon = false - - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - foundWeapon = true - end - end - - if not foundWeapon then + if not self.hasWeapon(weaponName) then table.insert(self.loadout, { name = weaponName, ammo = ammo, @@ -414,8 +406,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end - local foundWeapon = false - for i=1, #self.loadout, 1 do if self.loadout[i].name == weaponName then table.remove(self.loadout, i) @@ -427,5 +417,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) end + self.hasWeapon = function(weaponName) + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + return true + end + end + + return false + end + return self end From d804fb316f656325d51c29e811c79565669e2682 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 17 Nov 2018 12:37:17 +0100 Subject: [PATCH 257/672] Money color and formatting in inventory --- client/functions.lua | 10 +++++++--- client/main.lua | 4 ++-- locales/br.lua | 3 ++- locales/cs.lua | 3 ++- locales/de.lua | 3 ++- locales/en.lua | 3 ++- locales/fi.lua | 3 ++- locales/fr.lua | 3 ++- locales/pl.lua | 3 ++- locales/sv.lua | 3 ++- 10 files changed, 25 insertions(+), 13 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 5131653e..51337139 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -997,8 +997,10 @@ ESX.ShowInventory = function() local elements = {} if ESX.PlayerData.money > 0 then + local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(ESX.PlayerData.money)) + table.insert(elements, { - label = _U('cash', ESX.PlayerData.money), + label = ('%s: %s'):format(_U('cash'), formattedMoney), count = ESX.PlayerData.money, type = 'item_money', value = 'money', @@ -1010,8 +1012,10 @@ ESX.ShowInventory = function() for i=1, #ESX.PlayerData.accounts, 1 do if ESX.PlayerData.accounts[i].money > 0 then + local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(ESX.PlayerData.accounts[i].money)) + table.insert(elements, { - label = ESX.PlayerData.accounts[i].label .. ' $' .. ESX.PlayerData.accounts[i].money, + label = ('%s: %s'):format(ESX.PlayerData.accounts[i].label, formattedMoney), count = ESX.PlayerData.accounts[i].money, type = 'item_account', value = ESX.PlayerData.accounts[i].name, @@ -1042,7 +1046,7 @@ ESX.ShowInventory = function() 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 .. ']', + label = Config.Weapons[i].label .. ' [' .. ammo .. ']', count = 1, type = 'item_weapon', value = Config.Weapons[i].name, diff --git a/client/main.lua b/client/main.lua index 6bd986b0..10907c94 100644 --- a/client/main.lua +++ b/client/main.lua @@ -32,7 +32,7 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) }) ESX.UI.HUD.UpdateElement('account_' .. xPlayer.accounts[i].name, { - money = xPlayer.accounts[i].money + money = ESX.Math.GroupDigits(xPlayer.accounts[i].money) }) end @@ -166,7 +166,7 @@ AddEventHandler('esx:setAccountMoney', function(account) if Config.EnableHud then ESX.UI.HUD.UpdateElement('account_' .. account.name, { - money = account.money + money = ESX.Math.GroupDigits(account.money) }) end end) diff --git a/locales/br.lua b/locales/br.lua index 07dde39b..1b54127c 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,6 +1,6 @@ Locales['br'] = { -- Inventory - ['cash'] = 'efectivo $%s', + ['cash'] = 'efectivo', ['inventory'] = 'inventario', ['use'] = 'usar', ['give'] = 'dar', @@ -70,6 +70,7 @@ Locales['br'] = { ['chat_clear_all'] = 'clear the chat for everyone', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', + ['locale_currency'] = '$%s', -- Weapons ['weapon_knife'] = 'faca', ['weapon_nightstick'] = 'cacetete', diff --git a/locales/cs.lua b/locales/cs.lua index 4193b2af..2a3c6bf5 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -1,6 +1,6 @@ Locales['cs'] = { -- Inventory - ['cash'] = 'hotovost $%s', + ['cash'] = 'hotovost', ['inventory'] = 'inventář', ['use'] = 'použít', ['give'] = 'dát', @@ -74,6 +74,7 @@ Locales['cs'] = { ['chat_clear_all'] = 'vyčistit chat pro všechny', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', + ['locale_currency'] = '$%s', -- Weapons ['weapon_knife'] = 'knife', ['weapon_nightstick'] = 'nightstick', diff --git a/locales/de.lua b/locales/de.lua index 2ea6b598..200032df 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,6 +1,6 @@ Locales['de'] = { -- Inventory - ['cash'] = 'kontanter $%s', + ['cash'] = 'kontanter', ['inventory'] = 'inventar', ['use'] = 'benutzen', ['give'] = 'geben', @@ -64,6 +64,7 @@ Locales['de'] = { ['chat_clear_all'] = 'clear the chat for everyone', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', + ['locale_currency'] = '$%s', -- Weapons ['weapon_knife'] = 'Messer', ['weapon_nightstick'] = 'Schlagstock', diff --git a/locales/en.lua b/locales/en.lua index 82317285..3b4859b6 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,6 +1,6 @@ Locales['en'] = { -- Inventory - ['cash'] = 'cash $%s', + ['cash'] = 'cash', ['inventory'] = 'inventory', ['use'] = 'use', ['give'] = 'give', @@ -74,6 +74,7 @@ Locales['en'] = { ['chat_clear_all'] = 'clear the chat for everyone', -- Locale settings ['locale_digit_grouping_symbol'] = ',', + ['locale_currency'] = '$%s', -- Weapons ['weapon_knife'] = 'knife', ['weapon_nightstick'] = 'nightstick', diff --git a/locales/fi.lua b/locales/fi.lua index 4c248515..a22e7130 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,6 +1,6 @@ Locales['fi'] = { -- Inventory - ['cash'] = 'käteinen $%s', + ['cash'] = 'käteinen', ['inventory'] = 'reppu', ['use'] = 'käytä', ['give'] = 'anna', @@ -74,6 +74,7 @@ Locales['fi'] = { ['chat_clear_all'] = 'tyhjennä chatti kaikilta', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', + ['locale_currency'] = '$%s', -- Weapons ['weapon_knife'] = 'veitsi', ['weapon_nightstick'] = 'pamppu', diff --git a/locales/fr.lua b/locales/fr.lua index 818e1892..044a0530 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,6 +1,6 @@ Locales['fr'] = { -- Inventory - ['cash'] = 'espèces $%s', + ['cash'] = 'espèces', ['inventory'] = 'inventaire', ['use'] = 'utiliser', ['give'] = 'donner', @@ -71,6 +71,7 @@ Locales['fr'] = { ['chat_clear_all'] = 'clear the chat for everyone', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', + ['locale_currency'] = '$%s', -- Weapons ['weapon_knife'] = 'couteau', ['weapon_nightstick'] = 'matraque', diff --git a/locales/pl.lua b/locales/pl.lua index ef580470..2b249813 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,6 +1,6 @@ Locales['pl'] = { -- Inventory - ['cash'] = 'gotówka $%s', + ['cash'] = 'gotówka', ['inventory'] = 'ekwipunek', ['use'] = 'użyj', ['give'] = 'daj', @@ -71,6 +71,7 @@ Locales['pl'] = { ['disconnect'] = 'odłącz się od serwera', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', + ['locale_currency'] = '$%s', -- Weapons ['weapon_knife'] = 'nóż', ['weapon_nightstick'] = 'pałka', diff --git a/locales/sv.lua b/locales/sv.lua index f71c0096..0c759e7b 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,6 +1,6 @@ Locales['sv'] = { -- Inventory - ['cash'] = 'kontanter %s SEK', + ['cash'] = 'kontanter', ['inventory'] = 'mitt förråd', ['use'] = 'använd', ['give'] = 'ge', @@ -74,6 +74,7 @@ Locales['sv'] = { ['chat_clear_all'] = 'töm chatten för alla', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', + ['locale_currency'] = '%s SEK', -- Weapons ['weapon_knife'] = 'kniv', ['weapon_nightstick'] = 'batong', From 096a84aa1b22ab71170a1b80a48a0781385e7eb6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 17 Nov 2018 12:39:43 +0100 Subject: [PATCH 258/672] Ditch baseevents, closes #125, see #118 --- README.md | 2 -- __resource.lua | 4 +-- client/main.lua | 50 ------------------------------- client/modules/death.lua | 65 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 54 deletions(-) create mode 100644 client/modules/death.lua diff --git a/README.md b/README.md index aed31db4..2223427b 100644 --- a/README.md +++ b/README.md @@ -63,8 +63,6 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list - Configure your `server.cfg` to look like this ``` -start baseevents - start mysql-async start essentialmode start esplugin_mysql diff --git a/__resource.lua b/__resource.lua index c947865a..a6a15dc6 100644 --- a/__resource.lua +++ b/__resource.lua @@ -52,6 +52,7 @@ client_scripts { 'client/wrapper.lua', 'client/main.lua', + 'client/modules/death.lua', 'client/modules/scaleform.lua', 'client/modules/streaming.lua', @@ -91,6 +92,5 @@ server_exports { dependencies { 'essentialmode', 'mysql-async', - 'async', - 'baseevents' + 'async' } diff --git a/client/main.lua b/client/main.lua index 10907c94..df46d989 100644 --- a/client/main.lua +++ b/client/main.lua @@ -76,56 +76,6 @@ AddEventHandler('playerSpawned', function() isDead = false end) -AddEventHandler('baseevents:onPlayerDied', function(killerType, deathCoords) - local playerPed = PlayerPedId() - - local data = { - killed = false, - killerType = killerType, - deathCoords = deathCoords, - deathCause = GetPedCauseOfDeath(playerPed) - } - - TriggerEvent('esx:onPlayerDeath', data) - TriggerServerEvent('esx:onPlayerDeath', data) -end) - -AddEventHandler('baseevents:onPlayerKilled', function(killerId, data) - local playerPed = PlayerPedId() - local killer = GetPlayerFromServerId(killerId) - - if NetworkIsPlayerActive(killer) then - local victimCoords = data.killerpos - local weaponHash = data.weaponhash - - data.killerpos = nil - data.weaponhash = nil - - local killerPed = GetPlayerPed(killer) - local killerCoords = GetEntityCoords(killerPed) - local distance = GetDistanceBetweenCoords(victimCoords[1], victimCoords[2], victimCoords[3], killerCoords, false) - - table.insert(data, { - victimCoords = victimCoords, - weaponHash = weaponHash, - deathCause = GetPedCauseOfDeath(playerPed), - killed = true, - killerId = killerId, - killerCoords = { table.unpack(killerCoords) }, - distance = ESX.Round(distance) - }) - - else - table.insert(data, { - killed = false, - deathCause = GetPedCauseOfDeath(playerPed) - }) - end - - TriggerEvent('esx:onPlayerDeath', data) - TriggerServerEvent('esx:onPlayerDeath', data) -end) - AddEventHandler('esx:onPlayerDeath', function() isDead = true end) diff --git a/client/modules/death.lua b/client/modules/death.lua new file mode 100644 index 00000000..4c9aca54 --- /dev/null +++ b/client/modules/death.lua @@ -0,0 +1,65 @@ +Citizen.CreateThread(function() + local isDead = false + + while true do + Citizen.Wait(0) + + local player = PlayerId() + + if NetworkIsPlayerActive(player) then + local playerPed = PlayerPedId() + + if IsPedFatallyInjured(playerPed) and not isDead then + isDead = true + + local killer, killerWeapon = NetworkGetEntityKillerOfPlayer(player) + local killerServerId = NetworkGetPlayerIndexFromPed(killer) + + if killer ~= playerPed and killerServerId ~= nil and NetworkIsPlayerActive(killerServerId) then + PlayerKilledByPlayer(killerServerId, GetPlayerServerId(killerServerId), killerWeapon) + else + PlayerKilled() + end + + elseif not IsPedFatallyInjured(playerPed) then + isDead = false + end + end + end +end) + +function PlayerKilledByPlayer(killerServerId, killerClientId, killerWeapon) + local victimCoords = GetEntityCoords(PlayerPedId()) + local killerCoords = GetEntityCoords(killerPed) + local distance = GetDistanceBetweenCoords(victimCoords, killerCoords, true) + + local data = { + victimCoords = victimCoords, + killerCoords = killerCoords, + + killedByPlayer = true, + deathCause = killerWeapon, + distance = ESX.Math.Round(distance, 1), + + killerServerId = killerServerId, + killerClientId = killerClientId + } + + TriggerEvent('esx:onPlayerDeath', data) + TriggerServerEvent('esx:onPlayerDeath', data) +end + +function PlayerKilled() + local playerPed = PlayerPedId() + local victimCoords = GetEntityCoords(PlayerPedId()) + + local data = { + victimCoords = victimCoords, + + killedByPlayer = false, + deathCause = GetPedCauseOfDeath(playerPed) + } + + TriggerEvent('esx:onPlayerDeath', data) + TriggerServerEvent('esx:onPlayerDeath', data) +end \ No newline at end of file From 4ede7f86e3d052ea625c9ad9a352b423bb96111b Mon Sep 17 00:00:00 2001 From: Samuel Date: Sun, 18 Nov 2018 12:18:14 +0100 Subject: [PATCH 259/672] Added new discord --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2223427b..541d9b5a 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ es_extended is a roleplay framework for FiveM. It is developed on top of [Essent ### Links & Read more - [ESX Documentation](https://esx-org.github.io/) (incomplete) - [ES Documentation](https://docs.essentialmode.com/) +- [ESX Discord Community](https://discord.gg/MsWzPqE) - [FiveM Forum Thread](https://forum.fivem.net/t/release-esx-base/39881) - [FiveM Native Reference](https://runtime.fivem.net/doc/reference.html) From 7d1aea8ab72591de30b081e8909527d43e3ee718 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 18 Nov 2018 22:12:48 +0100 Subject: [PATCH 260/672] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2223427b..436ecf4a 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ es_extended is a roleplay framework for FiveM. It is developed on top of [Essent ### Requirements This order also applies in the startup order. -- Base events + - [mysql-async](https://github.com/brouznouf/fivem-mysql-async) - [essentialmode](https://github.com/kanersps/essentialmode) - [esplugin_mysql](https://github.com/kanersps/esplugin_mysql) From 3fc17880f8a9649b35264516ce9742d82605256c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 20 Nov 2018 21:03:44 +0100 Subject: [PATCH 261/672] Added ESX.Math.Trim function --- client/main.lua | 2 +- server/classes/player.lua | 1 + shared/modules/math.lua | 4 ++++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index df46d989..9bb7ebea 100644 --- a/client/main.lua +++ b/client/main.lua @@ -521,6 +521,7 @@ Citizen.CreateThread(function() while true do Citizen.Wait(1000) + if ESX ~= nil and ESX.PlayerLoaded and PlayerSpawned then local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) @@ -535,7 +536,6 @@ end) Citizen.CreateThread(function() while true do - Citizen.Wait(1000) local playerPed = PlayerPedId() diff --git a/server/classes/player.lua b/server/classes/player.lua index 114cc66d..819b2947 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -215,6 +215,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l for j=1, #result, 1 do if Config.Accounts[i] == result[j].name then found = true + break end end diff --git a/shared/modules/math.lua b/shared/modules/math.lua index 23273627..e707693c 100644 --- a/shared/modules/math.lua +++ b/shared/modules/math.lua @@ -10,3 +10,7 @@ ESX.Math.GroupDigits = function(value) return left..(num:reverse():gsub('(%d%d%d)','%1' .. _U('locale_digit_grouping_symbol')):reverse())..right end + +ESX.Math.Trim = function(value) + return (string.gsub(value, "^%s*(.-)%s*$", "%1")) +end \ No newline at end of file From d1d87bbe9110423453f57528fdfa0d268f05847b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 25 Nov 2018 13:36:19 +0100 Subject: [PATCH 262/672] Fixed death bugs --- client/modules/death.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/modules/death.lua b/client/modules/death.lua index 4c9aca54..b32838c3 100644 --- a/client/modules/death.lua +++ b/client/modules/death.lua @@ -16,7 +16,7 @@ Citizen.CreateThread(function() local killerServerId = NetworkGetPlayerIndexFromPed(killer) if killer ~= playerPed and killerServerId ~= nil and NetworkIsPlayerActive(killerServerId) then - PlayerKilledByPlayer(killerServerId, GetPlayerServerId(killerServerId), killerWeapon) + PlayerKilledByPlayer(GetPlayerServerId(killerServerId), killerServerId, killerWeapon) else PlayerKilled() end @@ -30,7 +30,7 @@ end) function PlayerKilledByPlayer(killerServerId, killerClientId, killerWeapon) local victimCoords = GetEntityCoords(PlayerPedId()) - local killerCoords = GetEntityCoords(killerPed) + local killerCoords = GetEntityCoords(GetPlayerPed(killerClientId)) local distance = GetDistanceBetweenCoords(victimCoords, killerCoords, true) local data = { From c975fea6d30f0bd3b7ac2bb1f9e7ce181406c27d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 25 Nov 2018 17:32:36 +0100 Subject: [PATCH 263/672] Don't give weapon if target already has one, seperate string for weapon without ammo --- client/functions.lua | 15 +++++++------- client/main.lua | 2 ++ locales/br.lua | 8 ++++++-- locales/cs.lua | 8 ++++++-- locales/de.lua | 8 ++++++-- locales/en.lua | 8 ++++++-- locales/fi.lua | 8 ++++++-- locales/fr.lua | 8 ++++++-- locales/pl.lua | 9 +++++++-- locales/sv.lua | 8 ++++++-- server/main.lua | 48 ++++++++++++++++++++++++++++---------------- 11 files changed, 90 insertions(+), 40 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 51337139..ab0b0e5d 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1109,7 +1109,11 @@ ESX.ShowInventory = function() for i=1, #players, 1 do if players[i] ~= PlayerId() then foundPlayers = true - table.insert(elements, {label = GetPlayerName(players[i]), value = players[i]}) + + table.insert(elements, { + label = GetPlayerName(players[i]), + value = players[i] + }) end end @@ -1166,8 +1170,7 @@ ESX.ShowInventory = function() else -- type: item_standard - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', - { + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { title = _U('amount') }, function(data3, menu3) local quantity = tonumber(data3.value) @@ -1219,8 +1222,7 @@ ESX.ShowInventory = function() else -- type: item_standard - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', - { + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { title = _U('amount') }, function(data2, menu2) local quantity = tonumber(data2.value) @@ -1257,8 +1259,7 @@ ESX.ShowInventory = function() if closestPlayer ~= -1 and closestDistance < 3.0 then if pedAmmo > 0 then - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', - { + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { title = _U('amountammo') }, function(data2, menu2) diff --git a/client/main.lua b/client/main.lua index 9bb7ebea..b4c305d9 100644 --- a/client/main.lua +++ b/client/main.lua @@ -131,6 +131,7 @@ AddEventHandler('esx:addInventoryItem', function(item, count) for i=1, #ESX.PlayerData.inventory, 1 do if ESX.PlayerData.inventory[i].name == item.name then ESX.PlayerData.inventory[i] = item + break end end @@ -146,6 +147,7 @@ AddEventHandler('esx:removeInventoryItem', function(item, count) for i=1, #ESX.PlayerData.inventory, 1 do if ESX.PlayerData.inventory[i].name == item.name then ESX.PlayerData.inventory[i] = item + break end end diff --git a/locales/br.lua b/locales/br.lua index 1b54127c..b4958196 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -13,8 +13,12 @@ Locales['br'] = { ['noammo'] = 'voce nao tem todas essas muniçoes!', ['gave_item'] = 'voce deu ~y~%sx~s~ ~b~%s~s~ para ~y~%s~s~', ['received_item'] = 'voce recebeu ~y~%sx~s~ ~b~%s~s~ de ~b~%s~s~', - ['gave_weapon'] = 'voce deu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas para ~y~%s~s~.', - ['received_weapon'] = 'voce recebeu ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~.', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', + ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', + ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', ['gave_ammo'] = 'voce deu ~o~%sx~s~ balas para ~y~%s~s~.', ['received_ammo'] = 'voce recebeu ~o~%sx~s~ balas de ~b~%s~s~.', ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', diff --git a/locales/cs.lua b/locales/cs.lua index 2a3c6bf5..98b34f8d 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -13,8 +13,12 @@ Locales['cs'] = { ['noammo'] = 'nemáte dostatek munice!', ['gave_item'] = 'dali jste ~y~%sx~s~ ~b~%s~s~ ~y~%s~s~', ['received_item'] = 'obdrželi jste ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'dali jste ~y~1x~s~ ~b~%s~s~ s ~o~%sx~s~ náboji ~y~%s~s~.', - ['received_weapon'] = 'obdrželi jste ~y~1x~s~ ~b~%s~s~ s ~o~%sx~s~ náboji od ~b~%s~s~.', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', + ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', + ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', ['gave_ammo'] = 'dali jste ~o~%sx~s~ nábojů ~y~%s~s~.', ['received_ammo'] = 'obdrželi jste ~o~%sx~s~ nábojů od ~b~%s~s~.', ['gave_money'] = 'dali jste ~g~$%s~s~ ~y~%s~s~', diff --git a/locales/de.lua b/locales/de.lua index 200032df..1ec804c1 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -13,8 +13,12 @@ Locales['de'] = { ['noammo'] = 'du hast keine munition!', ['gave_item'] = 'du gibst ~y~%sx~s~ ~b~%s~s~ zu ~y~%s~s~', ['received_item'] = 'to empfängst ~y~%sx~s~ ~b~%s~s~ von ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', + ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', + ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~.', ['gave_money'] = 'du gibst ~g~$%s~s~ zu ~y~%s~s~', diff --git a/locales/en.lua b/locales/en.lua index 3b4859b6..7819c5cb 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -13,8 +13,12 @@ Locales['en'] = { ['noammo'] = 'you do not have enough ammo!', ['gave_item'] = 'you gave ~y~%sx~s~ ~b~%s~s~ to ~y~%s~s~', ['received_item'] = 'you received ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', + ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', + ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~.', ['gave_money'] = 'you gave ~g~$%s~s~ to ~y~%s~s~', diff --git a/locales/fi.lua b/locales/fi.lua index a22e7130..39b7c8e9 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -13,8 +13,12 @@ Locales['fi'] = { ['noammo'] = 'sinulla ei ole ammuksia!', ['gave_item'] = 'sinä annoit ~y~%sx~s~ ~b~%s~s~ henkilölle ~y~%s~s~', ['received_item'] = 'sinä sait ~y~%sx~s~ ~b~%s~s~ henkilöltä ~b~%s~s~', - ['gave_weapon'] = 'sinä annoit ~y~1x~s~ ~b~%s~s~ jossa oli ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~.', - ['received_weapon'] = 'sinä sait ~y~1x~s~ ~b~%s~s~ jossa oli ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~.', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', + ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', + ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', ['gave_ammo'] = 'sinä annoit ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~.', ['received_ammo'] = 'sinä sait ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~.', ['gave_money'] = 'sinä annoit ~g~$%s~s~ henkilölle ~y~%s~s~', diff --git a/locales/fr.lua b/locales/fr.lua index 044a0530..fc676c62 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -13,8 +13,12 @@ Locales['fr'] = { ['noammo'] = 'tu n\'as pas toutes ces munitions!', ['gave_item'] = 'vous avez donné ~y~%sx~s~ ~b~%s~s~ à ~y~%s~s~', ['received_item'] = 'vous avez reçu ~y~%sx~s~ ~b~%s~s~ par ~b~%s~s~', - ['gave_weapon'] = 'vous donnez ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ minitions à ~y~%s~s~.', - ['received_weapon'] = 'vous recevez ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ munitions de ~b~%s~s~.', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', + ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', + ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', ['gave_ammo'] = 'vous donnez ~o~%sx~s~ munitions à ~y~%s~s~.', ['received_ammo'] = 'vous recevez ~o~%sx~s~ munitions de ~b~%s~s~.', ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', diff --git a/locales/pl.lua b/locales/pl.lua index 2b249813..3dc704cb 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -6,14 +6,19 @@ Locales['pl'] = { ['give'] = 'daj', ['remove'] = 'usuń', ['return'] = 'return', + ['give_to'] = 'give to', ['amount'] = 'amount', ['giveammo'] = 'give ammo', ['amountammo'] = 'ilość amunicji', ['noammo'] = 'nie masz wystarczającej ilości amunicji!', ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'dajesz ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~.', - ['received_weapon'] = 'otrzymujesz ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~.', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', + ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', + ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~.', ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~.', ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', diff --git a/locales/sv.lua b/locales/sv.lua index 0c759e7b..2d3453be 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -13,8 +13,12 @@ Locales['sv'] = { ['noammo'] = 'du har inte tillräckligt med ammunition!', ['gave_item'] = 'du gav ~y~%sx~s~ ~b~%s~s~ till ~y~%s~s~', ['received_item'] = 'du tog emot ~y~%sx~s~ ~b~%s~s~ från ~b~%s~s~', - ['gave_weapon'] = 'du gav ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~.', - ['received_weapon'] = 'du tog emot ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~.', + ['gave_weapon'] = 'du gav ~y~1x~s~ ~b~%s~s~ till ~y~%s~s~.', + ['gave_weapon_ammo'] = 'du gav ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~.', + ['gave_weapon_hasalready'] = '~y~%s~s~ har redan en ~y~%s~s~', + ['received_weapon'] = 'du tog emot ~y~1x~s~ ~b~%s~s~ från ~b~%s~s~.', + ['received_weapon_ammo'] = 'du tog emot ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~.', + ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det har du redan.', ['gave_ammo'] = 'du gav ~o~%sx~s~ skott till ~y~%s~s~.', ['received_ammo'] = 'du tog emot ~o~%sx~s~ skott från ~b~%s~s~.', ['gave_money'] = 'du gav ~g~%s SEK~s~ till ~y~%s~s~', diff --git a/server/main.lua b/server/main.lua index d3717a86..f008d0d7 100644 --- a/server/main.lua +++ b/server/main.lua @@ -15,11 +15,10 @@ AddEventHandler('es:playerLoaded', function(source, _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) + MySQL.Async.execute('UPDATE `users` SET `name` = @name WHERE `identifier` = @identifier', { + ['@identifier'] = player.getIdentifier(), + ['@name'] = userData.playerName + }, function(rowsChanged) cb() end) end) @@ -291,13 +290,13 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo elseif type == 'item_money' then - if itemCount > 0 and sourceXPlayer.player.get('money') >= itemCount then + if itemCount > 0 and sourceXPlayer.getMoney() >= itemCount then sourceXPlayer.removeMoney(itemCount) targetXPlayer.addMoney (itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('gave_money', itemCount, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_money', itemCount, sourceXPlayer.name)) + TriggerClientEvent('esx:showNotification', _source, _U('gave_money', ESX.Math.GroupDigits(itemCount), targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_money', ESX.Math.GroupDigits(itemCount), sourceXPlayer.name)) else TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) @@ -310,21 +309,35 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo sourceXPlayer.removeAccountMoney(itemName, itemCount) targetXPlayer.addAccountMoney (itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('gave_account_money', itemCount, Config.AccountLabels[itemName], targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_account_money', itemCount, Config.AccountLabels[itemName], sourceXPlayer.name)) + TriggerClientEvent('esx:showNotification', _source, _U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], sourceXPlayer.name)) else TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) end elseif type == 'item_weapon' then - - sourceXPlayer.removeWeapon(itemName) - targetXPlayer.addWeapon(itemName, itemCount) - - local weaponLabel = ESX.GetWeaponLabel(itemName) - TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, itemCount, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_weapon', weaponLabel, itemCount, sourceXPlayer.name)) + + if not targetXPlayer.hasWeapon(itemName) then + + sourceXPlayer.removeWeapon(itemName) + targetXPlayer.addWeapon(itemName, itemCount) + + local weaponLabel = ESX.GetWeaponLabel(itemName) + + if itemCount > 0 then + TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon_ammo', weaponLabel, itemCount, targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_weapon_ammo', weaponLabel, itemCount, sourceXPlayer.name)) + else + TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, targetXPlayer.name)) + TriggerClientEvent('esx:showNotification', target, _U('received_weapon', weaponLabel, sourceXPlayer.name)) + end + + else + TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) + TriggerClientEvent('esx:showNotification', _source, _U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) + end + end end) @@ -345,6 +358,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) for i=1, #xPlayer.inventory, 1 do if xPlayer.inventory[i].name == itemName then foundItem = xPlayer.inventory[i] + break end end From f68e11be2df81ad78b0dcacc8b995cd88757deb0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 29 Nov 2018 15:32:36 +0100 Subject: [PATCH 264/672] Trim vehicle plates --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index ab0b0e5d..9e92c7a7 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -641,7 +641,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) model = GetEntityModel(vehicle), - plate = GetVehicleNumberPlateText(vehicle), + plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)), plateIndex = GetVehicleNumberPlateTextIndex(vehicle), health = GetEntityHealth(vehicle), From 088a10d01711eba0bcc30547d64ba59a8fb33d4c Mon Sep 17 00:00:00 2001 From: Samuel Date: Fri, 30 Nov 2018 13:39:24 +0100 Subject: [PATCH 265/672] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aa72fb86..4aa706cc 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # es_extended -es_extended is a roleplay framework for FiveM. It is developed on top of [EssentialMode](https://essentialmode.com/) (aka ES), thus commonly named ESX - the **Es**sentialMode **E**xtended framework for FiveM. +es_extended is a roleplay framework for FiveM. It is developed on top of [EssentialMode](https://essentialmode.com/) (aka ES), thus commonly named ESX - the **Es**sentialMode E**x**tended framework for FiveM. ### Links & Read more - [ESX Documentation](https://esx-org.github.io/) (incomplete) From 6d849fabbc74e0036ea3c67e7b8502e875521c3d Mon Sep 17 00:00:00 2001 From: Manuel <38227219+Tindergarten@users.noreply.github.com> Date: Tue, 11 Dec 2018 14:30:26 +0100 Subject: [PATCH 266/672] update de.lua minor changes for the german language --- locales/de.lua | 54 +++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/locales/de.lua b/locales/de.lua index 1ec804c1..d1c4f072 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,45 +1,45 @@ Locales['de'] = { -- Inventory - ['cash'] = 'kontanter', + ['cash'] = 'bargeld', ['inventory'] = 'inventar', ['use'] = 'benutzen', ['give'] = 'geben', ['remove'] = 'entfernen', ['return'] = 'zurück', - ['give_to'] = 'give to', + ['give_to'] = 'geben an', ['amount'] = 'Betrag', ['giveammo'] = 'munition geben', ['amountammo'] = 'anzahl der munition', ['noammo'] = 'du hast keine munition!', - ['gave_item'] = 'du gibst ~y~%sx~s~ ~b~%s~s~ zu ~y~%s~s~', - ['received_item'] = 'to empfängst ~y~%sx~s~ ~b~%s~s~ von ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', - ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', - ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', - ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~.', - ['gave_money'] = 'du gibst ~g~$%s~s~ zu ~y~%s~s~', - ['received_money'] = 'to empfängst ~g~$%s~s~ von ~b~%s~s~', - ['gave_account_money'] = 'du gibst ~g~$%s~s~ (%s) zu ~y~%s~s~', - ['received_account_money'] = 'to empfängst ~g~$%s~s~ (%s) von ~b~%s~s~', + ['gave_item'] = 'du gibst ~y~%sx~s~ ~b~%s~s~ an ~y~%s~s~', + ['received_item'] = 'du empfängst ~y~%sx~s~ ~b~%s~s~ von ~b~%s~s~', + ['gave_weapon'] = 'du gibst ~y~1x~s~ ~b~%s~s~ an ~y~%s~s~', + ['gave_weapon_ammo'] = 'du gibst ~y~1x~s~ ~b~%s~s~ mit ~o~%sx~s~ Schuss an ~y~%s~s~', + ['gave_weapon_hasalready'] = '~y~%s~s~ hat bereits eine(n) ~y~%s~s~', + ['received_weapon'] = 'du erhälst ~y~1x~s~ ~b~%s~s~ von ~b~%s~s~', + ['received_weapon_ammo'] = 'du erhälst ~y~1x~s~ ~b~%s~s~ mit ~o~%sx~s~ Schuss von ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ hat versucht dir eine(n) ~y~%s~s~ zu geben, aber du hast bereits eine(n)', + ['gave_ammo'] = 'du gibst ~o~%sx~s~ Schuss an ~y~%s~s~', + ['received_ammo'] = 'du erhälst ~o~%sx~s~ Schuss von ~b~%s~s~', + ['gave_money'] = 'du gibst ~g~$%s~s~ an ~y~%s~s~', + ['received_money'] = 'du erhälst ~g~$%s~s~ von ~b~%s~s~', + ['gave_account_money'] = 'du gibst ~g~$%s~s~ (%s) an ~y~%s~s~', + ['received_account_money'] = 'du empfängst ~g~$%s~s~ (%s) von ~b~%s~s~', ['amount_invalid'] = 'ungültiger Betrag', - ['players_nearby'] = 'keine Spieler in der nähe', - ['ex_inv_lim'] = 'aktion nicht möglich, inventarlimit überschritten für ~y~%s~s~', - ['imp_invalid_quantity'] = 'aktion nicht möglich, ungültige anzahl', - ['imp_invalid_amount'] = 'aktion nicht möglich, ungültiger betrag', - ['delete_five_min'] = '~r~Löschen~s~ in 5 minuten~s~', + ['players_nearby'] = 'keine Spieler in der Nähe', + ['ex_inv_lim'] = 'aktion nicht möglich, Inventarlimit überschritten für ~y~%s~s~', + ['imp_invalid_quantity'] = 'aktion nicht möglich, ungültige Anzahl', + ['imp_invalid_amount'] = 'aktion nicht möglich, ungültiger Betrag', + ['delete_five_min'] = 'item wird in ~y~fünf Minuten~s~ ~r~gelöscht~s~', ['threw'] = 'du ~r~wirfst weg~s~', - ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', + ['threw_weapon'] = 'du hast ~y~1x~s~ ~b~%s~s~ mit ~o~%sx~s~ Schuss ~r~fallengelassen~s~!', -- Salary related ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', - ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', - ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary.', - ['received_paycheck'] = 'received paycheck', + ['received_help'] = 'du hast deine Sozialhilfe erhalten.: ~g~$%s~s~', + ['company_nomoney'] = 'die Firma in der du angestellt bist, ist zu arm um dein Gehalt zu zahlen.', + ['received_paycheck'] = 'erhaltener Gehaltsscheck', ['bank'] = 'bank', - ['black_money'] = 'dirty Money', + ['black_money'] = 'schwarzgeld', ['act_imp'] = 'Aktion nicht möglich', -- Commands @@ -148,7 +148,7 @@ Locales['de'] = { ['weapon_flashlight'] = 'Taschenlampe', ['gadget_nightvision'] = 'Nachtsichtgerät', ['gadget_parachute'] = 'Fallschirm', - ['weapon_flare'] = 'Fusée Détresse', + ['weapon_flare'] = 'Leuchtpistole', ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', ['weapon_doubleaction'] = 'Double-Action Revolver', From f935db8e8be82d803933e4217676b1c1f495222f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 16 Dec 2018 00:03:04 +0100 Subject: [PATCH 267/672] Use new scaleform native names --- client/modules/scaleform.lua | 57 ++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/client/modules/scaleform.lua b/client/modules/scaleform.lua index eca6ba16..20a9c6e8 100644 --- a/client/modules/scaleform.lua +++ b/client/modules/scaleform.lua @@ -1,10 +1,10 @@ ESX.Scaleform.ShowFreemodeMessage = function(title, msg, sec) local scaleform = ESX.Scaleform.Utils.RequestScaleformMovie('MP_BIG_MESSAGE_FREEMODE') - PushScaleformMovieFunction(scaleform, 'SHOW_SHARD_WASTED_MP_MESSAGE') - PushScaleformMovieFunctionParameterString(title) - PushScaleformMovieFunctionParameterString(msg) - PopScaleformMovieFunctionVoid() + BeginScaleformMovieMethod(scaleform, 'SHOW_SHARD_WASTED_MP_MESSAGE') + PushScaleformMovieMethodParameterString(title) + PushScaleformMovieMethodParameterString(msg) + EndScaleformMovieMethod() while sec > 0 do Citizen.Wait(1) @@ -19,21 +19,23 @@ end ESX.Scaleform.ShowBreakingNews = function(title, msg, bottom, sec) local scaleform = ESX.Scaleform.Utils.RequestScaleformMovie('BREAKING_NEWS') - PushScaleformMovieFunction(scaleform, 'SET_TEXT') - PushScaleformMovieFunctionParameterString(msg) - PushScaleformMovieFunctionParameterString(bottom) - PopScaleformMovieFunctionVoid() + BeginScaleformMovieMethod(scaleform, 'SET_TEXT') + PushScaleformMovieMethodParameterString(msg) + PushScaleformMovieMethodParameterString(bottom) + EndScaleformMovieMethod() - PushScaleformMovieFunction(scaleform, 'SET_SCROLL_TEXT') - PushScaleformMovieFunctionParameterInt(0) -- top ticker - PushScaleformMovieFunctionParameterInt(0) -- Since this is the first string, start at 0 - PushScaleformMovieFunctionParameterString(title) - PopScaleformMovieFunctionVoid() + BeginScaleformMovieMethod(scaleform, 'SET_SCROLL_TEXT') + PushScaleformMovieMethodParameterInt(0) -- top ticker + PushScaleformMovieMethodParameterInt(0) -- Since this is the first string, start at 0 + PushScaleformMovieMethodParameterString(title) - PushScaleformMovieFunction(scaleform, 'DISPLAY_SCROLL_TEXT') - PushScaleformMovieFunctionParameterInt(0) -- Top ticker - PushScaleformMovieFunctionParameterInt(0) -- Index of string - PopScaleformMovieFunctionVoid() + EndScaleformMovieMethod() + + BeginScaleformMovieMethod(scaleform, 'DISPLAY_SCROLL_TEXT') + PushScaleformMovieMethodParameterInt(0) -- Top ticker + PushScaleformMovieMethodParameterInt(0) -- Index of string + + EndScaleformMovieMethod() while sec > 0 do Citizen.Wait(1) @@ -48,13 +50,15 @@ end ESX.Scaleform.ShowPopupWarning = function(title, msg, bottom, sec) local scaleform = ESX.Scaleform.Utils.RequestScaleformMovie('POPUP_WARNING') - PushScaleformMovieFunction(scaleform, 'SHOW_POPUP_WARNING') - PushScaleformMovieFunctionParameterFloat(500.0) -- black background - PushScaleformMovieFunctionParameterString(title) - PushScaleformMovieFunctionParameterString(msg) - PushScaleformMovieFunctionParameterString(bottom) - PushScaleformMovieFunctionParameterBool(true) - PopScaleformMovieFunctionVoid() + BeginScaleformMovieMethod(scaleform, 'SHOW_POPUP_WARNING') + + PushScaleformMovieMethodParameterFloat(500.0) -- black background + PushScaleformMovieMethodParameterString(title) + PushScaleformMovieMethodParameterString(msg) + PushScaleformMovieMethodParameterString(bottom) + PushScaleformMovieMethodParameterBool(true) + + EndScaleformMovieMethod() while sec > 0 do Citizen.Wait(1) @@ -69,8 +73,9 @@ end ESX.Scaleform.ShowTrafficMovie = function(sec) local scaleform = ESX.Scaleform.Utils.RequestScaleformMovie('TRAFFIC_CAM') - PushScaleformMovieFunction(scaleform, 'PLAY_CAM_MOVIE') - PopScaleformMovieFunctionVoid() + BeginScaleformMovieMethod(scaleform, 'PLAY_CAM_MOVIE') + + EndScaleformMovieMethod() while sec > 0 do Citizen.Wait(1) From a3d3692479772bd528537d8c86ce4bd795606437 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Dec 2018 21:47:23 +0100 Subject: [PATCH 268/672] Proper CreateObject() arguments --- client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 9e92c7a7..dcc4e33a 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -300,7 +300,7 @@ ESX.Game.SpawnObject = function(model, coords, cb) Citizen.Wait(0) end - local obj = CreateObject(model, coords.x, coords.y, coords.z, true, true, true) + local obj = CreateObject(model, coords.x, coords.y, coords.z, true, false, true) if cb ~= nil then cb(obj) @@ -318,7 +318,7 @@ ESX.Game.SpawnLocalObject = function(model, coords, cb) Citizen.Wait(0) end - local obj = CreateObject(model, coords.x, coords.y, coords.z, false, true, true) + local obj = CreateObject(model, coords.x, coords.y, coords.z, false, false, true) if cb ~= nil then cb(obj) From 9224f9119f018bf703c17f585341ae711096cd22 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 23 Dec 2018 11:38:39 +0100 Subject: [PATCH 269/672] Minor changes, updated native names --- client/functions.lua | 37 ++++++++++++++++++------------------- config.lua | 2 +- server/main.lua | 4 ++-- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index dcc4e33a..2a3b6ac1 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -46,22 +46,22 @@ end ESX.ShowNotification = function(msg) SetNotificationTextEntry('STRING') - AddTextComponentString(msg) + AddTextComponentSubstringWebsite(msg) DrawNotification(false, true) end ESX.ShowAdvancedNotification = function(title, subject, msg, icon, iconType) SetNotificationTextEntry('STRING') - AddTextComponentString(msg) + AddTextComponentSubstringWebsite(msg) SetNotificationMessage(icon, icon, false, iconType, title, subject) DrawNotification(false, false) end ESX.ShowHelpNotification = function(msg) if not IsHelpMessageOnScreen() then - SetTextComponentFormat('STRING') - AddTextComponentString(msg) - DisplayHelpTextFromStringLabel(0, 0, 1, -1) + BeginTextCommandDisplayHelp('STRING') + AddTextComponentSubstringWebsite(msg) + EndTextCommandDisplayHelp(0, false, true, -1) end end @@ -106,7 +106,7 @@ ESX.UI.HUD.RegisterElement = function(name, index, priority, html, data) index = index, priority = priority, html = html, - data = data, + data = data }) ESX.UI.HUD.UpdateElement(name, data) @@ -450,7 +450,7 @@ ESX.Game.GetClosestObject = function(filter, coords) if foundObject then local objectCoords = GetEntityCoords(objects[i]) - local distance = GetDistanceBetweenCoords(objectCoords.x, objectCoords.y, objectCoords.z, coords.x, coords.y, coords.z, true) + local distance = GetDistanceBetweenCoords(objectCoords, coords.x, coords.y, coords.z, true) if closestDistance == -1 or closestDistance > distance then closestObject = objects[i] @@ -498,7 +498,7 @@ ESX.Game.GetClosestPlayer = function(coords) if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then local targetCoords = GetEntityCoords(target) - local distance = GetDistanceBetweenCoords(targetCoords.x, targetCoords.y, targetCoords.z, coords.x, coords.y, coords.z, true) + local distance = GetDistanceBetweenCoords(targetCoords, coords.x, coords.y, coords.z, true) if closestDistance == -1 or closestDistance > distance then closestPlayer = players[i] @@ -517,7 +517,7 @@ ESX.Game.GetPlayersInArea = function(coords, area) 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) + local distance = GetDistanceBetweenCoords(targetCoords, coords.x, coords.y, coords.z, true) if distance <= area then table.insert(playersInArea, players[i]) @@ -550,7 +550,7 @@ ESX.Game.GetClosestVehicle = function(coords) for i=1, #vehicles, 1 do local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) + local distance = GetDistanceBetweenCoords(vehicleCoords, coords.x, coords.y, coords.z, true) if closestDistance == -1 or closestDistance > distance then closestVehicle = vehicles[i] @@ -567,7 +567,7 @@ ESX.Game.GetVehiclesInArea = function(coords, area) for i=1, #vehicles, 1 do local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords.x, vehicleCoords.y, vehicleCoords.z, coords.x, coords.y, coords.z, true) + local distance = GetDistanceBetweenCoords(vehicleCoords, coords.x, coords.y, coords.z, true) if distance <= area then table.insert(vehiclesInArea, vehicles[i]) @@ -579,11 +579,10 @@ end ESX.Game.GetVehicleInDirection = function() local playerPed = PlayerPedId() - local playerCoords = GetEntityCoords(playerPed, 1) + local playerCoords = GetEntityCoords(playerPed) local inDirection = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 5.0, 0.0) - local rayHandle = CastRayPointToPoint(playerCoords.x, playerCoords.y, playerCoords.z, inDirection.x, inDirection.y, inDirection.z, 10, playerPed, 0) - local a, b, c, d, vehicle = GetRaycastResult(rayHandle) - + local rayHandle = StartShapeTestRay(playerCoords, inDirection, 10, playerPed, 0) + local a, b, c, d, vehicle = GetShapeTestResult(rayHandle) return vehicle end @@ -622,7 +621,7 @@ ESX.Game.GetClosestPed = function(coords, ignoreList) for i=1, #peds, 1 do local pedCoords = GetEntityCoords(peds[i]) - local distance = GetDistanceBetweenCoords(pedCoords.x, pedCoords.y, pedCoords.z, coords.x, coords.y, coords.z, true) + local distance = GetDistanceBetweenCoords(pedCoords, coords.x, coords.y, coords.z, true) if closestDistance == -1 or closestDistance > distance then closestPed = peds[i] @@ -962,9 +961,9 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end ESX.Game.Utils.DrawText3D = function(coords, text, size) - local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) + local onScreen, x, y = GetScreenCoordFromWorldCoord(coords.x, coords.y, coords.z) local camCoords = GetGameplayCamCoords() - local dist = GetDistanceBetweenCoords(camCoords.x, camCoords.y, camCoords.z, coords.x, coords.y, coords.z, 1) + local dist = GetDistanceBetweenCoords(camCoords, coords.x, coords.y, coords.z, true) local size = size if size == nil then @@ -1035,7 +1034,7 @@ ESX.ShowInventory = function() value = ESX.PlayerData.inventory[i].name, usable = ESX.PlayerData.inventory[i].usable, rare = ESX.PlayerData.inventory[i].rare, - canRemove = ESX.PlayerData.inventory[i].canRemove, + canRemove = ESX.PlayerData.inventory[i].canRemove }) end end diff --git a/config.lua b/config.lua index a42083d6..149784b4 100644 --- a/config.lua +++ b/config.lua @@ -4,7 +4,7 @@ Config.Locale = 'fr' Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } -Config.EnableSocietyPayouts = false -- pay from the society account that the plyayers are employeed at instead of plain giving money. Requirement: esx_society +Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.EnableWeaponPickup = true diff --git a/server/main.lua b/server/main.lua index f008d0d7..bdc81691 100644 --- a/server/main.lua +++ b/server/main.lua @@ -269,8 +269,8 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if type == 'item_standard' then - local sourceItem = sourceXPlayer.getInventoryItem(itemName) - local targetItem = targetXPlayer.getInventoryItem(itemName) + local sourceItem = sourceXPlayer.getInventoryItem(itemName) + local targetItem = targetXPlayer.getInventoryItem(itemName) if itemCount > 0 and sourceItem.count >= itemCount then From 37ada40b219c84dee6a02fe6e1d572ab20af48c7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 23 Dec 2018 12:21:28 +0100 Subject: [PATCH 270/672] Fixed ammo duplicate on restoreLoadout, fixes #171 --- client/main.lua | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index b4c305d9..bc0f6ad3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -94,12 +94,19 @@ end) AddEventHandler('esx:restoreLoadout', function() local playerPed = PlayerPedId() + local ammoTypes = {} RemoveAllPedWeapons(playerPed, true) for i=1, #ESX.PlayerData.loadout, 1 do local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) - GiveWeaponToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo, false, false) + GiveWeaponToPed(playerPed, weaponHash, 0, false, false) + local ammoType = GetPedAmmoTypeFromWeapon(playerPed, weaponHash) + + if not ammoTypes[ammoType] then + AddAmmoToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo) + ammoTypes[ammoType] = true + end end LoadoutLoaded = true From 2fd7d326be2d5070a1218bf29e87de28418bd034 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 23 Dec 2018 14:32:38 +0100 Subject: [PATCH 271/672] 'Throwing' update, see desc, resolves #19 - proper i18n strings for dropping accounts, money, standard and weapons - check if the player has the weapon - workaround for duplicating weapon ammo when dropping weapon with 0 ammo - removed throw delay - code cleanup --- client/functions.lua | 2 +- client/main.lua | 16 +++--- config.lua | 2 - locales/br.lua | 8 ++- locales/cs.lua | 8 ++- locales/de.lua | 8 ++- locales/en.lua | 8 ++- locales/fi.lua | 8 ++- locales/fr.lua | 8 ++- locales/pl.lua | 8 ++- locales/sv.lua | 8 ++- server/main.lua | 134 +++++++++++++++++-------------------------- 12 files changed, 104 insertions(+), 114 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 2a3b6ac1..90ff3125 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1216,7 +1216,7 @@ ESX.ShowInventory = function() if type == 'item_weapon' then - TriggerServerEvent('esx:removeInventoryItem', type, item, nil) + TriggerServerEvent('esx:removeInventoryItem', type, item) menu1.close() else -- type: item_standard diff --git a/client/main.lua b/client/main.lua index bc0f6ad3..5fab7cc2 100644 --- a/client/main.lua +++ b/client/main.lua @@ -328,10 +328,12 @@ AddEventHandler('esx:removePickup', function(id) end) RegisterNetEvent('esx:pickupWeapon') -AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName,ammo) - local ped = PlayerPedId() - local playerPedPos = GetEntityCoords(ped, true) - CreateAmbientPickup(GetHashKey(weaponPickup), playerPedPos.x + 2.0, playerPedPos.y, playerPedPos.z + 0.5, 0, ammo, 1, false, true) +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:spawnPed') @@ -358,7 +360,7 @@ AddEventHandler('esx:deleteVehicle', function() local playerPed = PlayerPedId() local vehicle = ESX.Game.GetVehicleInDirection() - if IsPedInAnyVehicle(playerPed, false) then + if IsPedInAnyVehicle(playerPed, true) then vehicle = GetVehiclePedIsIn(playerPed, false) end @@ -503,7 +505,7 @@ Citizen.CreateThread(function() for k,v in pairs(Pickups) do - local distance = GetDistanceBetweenCoords(coords.x, coords.y, coords.z, v.coords.x, v.coords.y, v.coords.z, true) + 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 @@ -516,7 +518,7 @@ Citizen.CreateThread(function() if (closestDistance == -1 or closestDistance > 3) and distance <= 1.0 and not v.inRange and not IsPedSittingInAnyVehicle(playerPed) then TriggerServerEvent('esx:onPickup', v.id) - PlaySoundFrontend(-1, "PICK_UP", "HUD_FRONTEND_DEFAULT_SOUNDSET", 1) + PlaySoundFrontend(-1, 'PICK_UP', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) v.inRange = true end diff --git a/config.lua b/config.lua index 149784b4..2efac3de 100644 --- a/config.lua +++ b/config.lua @@ -7,10 +7,8 @@ Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_m Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true -Config.EnableWeaponPickup = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) -Config.RemoveInventoryItemDelay = 5 * 60000 Config.PaycheckInterval = 7 * 60000 Config.MaxPlayers = 32 diff --git a/locales/br.lua b/locales/br.lua index b4958196..c5328418 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -30,9 +30,11 @@ Locales['br'] = { ['ex_inv_lim'] = 'acao nao e possivel, excedendo o limite de estoque para ~y~%s~s~', ['imp_invalid_quantity'] = 'acao impossivel, quantidade invalida', ['imp_invalid_amount'] = 'acao impossivel, valor invalido', - ['delete_five_min'] = '~r~excluir~s~ em 5 minutos', - ['threw'] = 'voce ~r~jogou~s~', - ['threw_weapon'] = 'voce ~r~atirou~s~ ~y~1x~s~ ~b~%s~s~ com ~o~%sx~s~ balas!', + ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', ['received_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', diff --git a/locales/cs.lua b/locales/cs.lua index 98b34f8d..69a04afb 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -30,9 +30,11 @@ Locales['cs'] = { ['ex_inv_lim'] = 'akce není možná, překročen limit inventáře pro ~y~%s~s~', ['imp_invalid_quantity'] = 'akce není možná, neplatný počet', ['imp_invalid_amount'] = 'akce není možná, neplatné množství', - ['delete_five_min'] = 'věc bude ~r~zahozena~s~ za 5 minut', - ['threw'] = '~r~zahodili~s~ jste', - ['threw_weapon'] = '~r~zahodili~s~ jste ~y~1x~s~ ~b~%s~s~ s ~o~%sx~s~ náboji!', + ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', diff --git a/locales/de.lua b/locales/de.lua index d1c4f072..3af360a2 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -30,9 +30,11 @@ Locales['de'] = { ['ex_inv_lim'] = 'aktion nicht möglich, Inventarlimit überschritten für ~y~%s~s~', ['imp_invalid_quantity'] = 'aktion nicht möglich, ungültige Anzahl', ['imp_invalid_amount'] = 'aktion nicht möglich, ungültiger Betrag', - ['delete_five_min'] = 'item wird in ~y~fünf Minuten~s~ ~r~gelöscht~s~', - ['threw'] = 'du ~r~wirfst weg~s~', - ['threw_weapon'] = 'du hast ~y~1x~s~ ~b~%s~s~ mit ~o~%sx~s~ Schuss ~r~fallengelassen~s~!', + ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', ['received_help'] = 'du hast deine Sozialhilfe erhalten.: ~g~$%s~s~', diff --git a/locales/en.lua b/locales/en.lua index 7819c5cb..6fa0dd63 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -30,9 +30,11 @@ Locales['en'] = { ['ex_inv_lim'] = 'action not possible, exceeding inventory limit for ~y~%s~s~', ['imp_invalid_quantity'] = 'action impossible, invalid quantity', ['imp_invalid_amount'] = 'action impossible, invalid amount', - ['delete_five_min'] = 'the item will be ~r~thrown~s~ in 5 minutes', - ['threw'] = 'you ~r~threw~s~', - ['threw_weapon'] = 'you ~r~threw~s~ ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets!', + ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'you received your salary: ~g~$%s~s~', ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', diff --git a/locales/fi.lua b/locales/fi.lua index 39b7c8e9..f53df544 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -30,9 +30,11 @@ Locales['fi'] = { ['ex_inv_lim'] = 'toiminto mahdoton, reppu alkaa olla täysi ~y~%s~s~', ['imp_invalid_quantity'] = 'toiminto mahdoton, virheellinen määrä', ['imp_invalid_amount'] = 'toiminto mahdoton, virhellinen summa', - ['delete_five_min'] = 'esine ~r~poistetaan~s~ 5 minuutin päästä repusta', - ['threw'] = 'sinä ~r~tiputit~s~', - ['threw_weapon'] = 'sinä ~r~heitit~s~ ~y~1x~s~ ~b~%s~s~ jossa oli ~o~%sx~s~ ammuksia!', + ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', ['received_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', diff --git a/locales/fr.lua b/locales/fr.lua index fc676c62..f46482a4 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -30,9 +30,11 @@ Locales['fr'] = { ['ex_inv_lim'] = 'action impossible, depassement de la limite d\'inventaire pour ~y~%s~s~', ['imp_invalid_quantity'] = 'action impossible, ~r~quantité invalide', ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', - ['delete_five_min'] = '~r~suppression~s~ dans 5 minutes', - ['threw'] = 'vous avez ~r~jeté~s~', - ['threw_weapon'] = 'vous ~r~jetez~s~ ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ munitions!', + ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', ['received_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', diff --git a/locales/pl.lua b/locales/pl.lua index 3dc704cb..8c754742 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -30,9 +30,11 @@ Locales['pl'] = { ['ex_inv_lim'] = 'akcja nie jest możliwa, nie możesz mieć więcej ~y~%s~s~', ['imp_invalid_quantity'] = 'akcja jest niemożliwa, nieprawidłowa ilość', ['imp_invalid_amount'] = 'akcja jest niemożliwa, nieprawidłowa kwota', - ['delete_five_min'] = 'przedmiot zostanie ~r~usunięty~s~ za 5 minut', - ['threw'] = '~r~upuściłeś~s~', - ['threw_weapon'] = '~r~Upuściłeś~s~ ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ pociskami!', + ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', diff --git a/locales/sv.lua b/locales/sv.lua index 2d3453be..ad2236ca 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -30,9 +30,11 @@ Locales['sv'] = { ['ex_inv_lim'] = 'åtgärd inte möjligt, översteg förråd gräns för ~y~%s~s~', ['imp_invalid_quantity'] = 'åtgärd omöjlig, ogiltig mängd', ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', - ['delete_five_min'] = 'objektet kommer att ~r~kastas~s~ om 5 minuter!', - ['threw'] = 'du ~r~kastade~s~', - ['threw_weapon'] = 'du ~r~slängde~s~ ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott!', + ['threw_standard'] = 'du kastade ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'du kastade ~r~$%s~s~ ~b~kontanter~s~', + ['threw_account'] = 'du kastade ~r~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'du kastade ~y~1x~s~ ~b~%s~s~', + ['threw_weapon_ammo'] = 'du kastade ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott', -- Salary related ['received_salary'] = 'du har mottagit din lön på ~g~%s SEK~s~', ['received_help'] = 'du har mottagit bidrag på ~g~%s SEK~s~', diff --git a/server/main.lua b/server/main.lua index bdc81691..cb7dfa8f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -348,125 +348,97 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if type == 'item_standard' then - if itemCount == nil or itemCount <= 0 then + if itemCount == nil or itemCount < 1 then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) else - local xPlayer = ESX.GetPlayerFromId(source) - local foundItem = nil + local xPlayer = ESX.GetPlayerFromId(source) + local xItem = xPlayer.getInventoryItem(itemName) - for i=1, #xPlayer.inventory, 1 do - if xPlayer.inventory[i].name == itemName then - foundItem = xPlayer.inventory[i] - break - end - end - - if itemCount > foundItem.count then + if (itemCount > xItem.count or xItem.count < 1) then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) else + xPlayer.removeInventoryItem(itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - - 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) - ESX.CreatePickup('item_standard', itemName, total, foundItem.label .. ' [' .. itemCount .. ']', _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' ' .. foundItem.label .. ' x' .. total) - end - end) + local pickupLabel = ('~y~%s~s~ [~b~%s~s~]'):format(xItem.label, itemCount) + ESX.CreatePickup('item_standard', itemName, itemCount, pickupLabel, _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw_standard', itemCount, xItem.label)) end end elseif type == 'item_money' then - if itemCount == nil or itemCount <= 0 then + if itemCount == nil or itemCount < 1 then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else local xPlayer = ESX.GetPlayerFromId(source) + local playerCash = xPlayer.getMoney() - if itemCount > xPlayer.player.get('money') then + if (itemCount > playerCash or playerCash < 1) then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else + xPlayer.removeMoney(itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - - 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) - ESX.CreatePickup('item_money', 'money', total, 'Cash' .. ' [' .. itemCount .. ']', _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) - end - end) + local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(_U('cash'), _U('locale_currency', ESX.Math.GroupDigits(itemCount))) + ESX.CreatePickup('item_money', 'money', itemCount, pickupLabel, _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw_money', ESX.Math.GroupDigits(itemCount))) end end elseif type == 'item_account' then - if itemCount == nil or itemCount <= 0 then + if itemCount == nil or itemCount < 1 then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else local xPlayer = ESX.GetPlayerFromId(source) + local account = xPlayer.getAccount(itemName) - if itemCount > xPlayer.getAccount(itemName).money then + if (itemCount > account.money or account.money < 1) then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else + xPlayer.removeAccountMoney(itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - - 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) - ESX.CreatePickup('item_account', itemName, total, Config.AccountLabels[itemName] .. ' [' .. itemCount .. ']', _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw') .. ' [Cash] $' .. total) - end - end) + local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(account.label, _U('locale_currency', ESX.Math.GroupDigits(itemCount))) + ESX.CreatePickup('item_account', itemName, itemCount, pickupLabel, _source) + TriggerClientEvent('esx:showNotification', _source, _U('threw_account', ESX.Math.GroupDigits(itemCount), string.lower(account.label))) end end elseif type == 'item_weapon' then - local xPlayer = ESX.GetPlayerFromId(source) - local weaponName = itemName - local weaponLabel = ESX.GetWeaponLabel(weaponName) - local weaponPickup = 'PICKUP_' .. weaponName - - TriggerClientEvent('esx:showNotification', _source, _U('delete_five_min')) - - SetTimeout(Config.RemoveInventoryItemDelay, function() - xPlayer.removeWeapon(itemName) - if Config.EnableWeaponPickup then - TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, weaponName, itemCount) - end + local xPlayer = ESX.GetPlayerFromId(source) + local loadout = xPlayer.getLoadout() + + for i=1, #loadout, 1 do + if loadout[i].name == itemName then + itemCount = loadout[i].ammo + break + end + end + + -- workaround for CreateAmbientPickup() giving 30 rounds of ammo when you drop the weapon with 0 ammo + if itemCount == 0 then + itemCount = 1 + end + + if xPlayer.hasWeapon(itemName) then + local weaponLabel, weaponPickup = ESX.GetWeaponLabel(itemName), 'PICKUP_' .. string.upper(itemName) + + xPlayer.removeWeapon(itemName) + TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, itemName, itemCount) + + if itemCount > 0 then + TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon_ammo', weaponLabel, itemCount)) + else + TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon', weaponLabel)) + end + end - TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon', weaponLabel, itemCount)) - end) end end) @@ -504,7 +476,9 @@ AddEventHandler('esx:onPickup', function(id) if remaining > 0 then TriggerClientEvent('esx:showNotification', _source, _U('cannot_pickup_room', item.label)) - ESX.CreatePickup('item_standard', pickup.name, remaining, item.label .. ' [' .. remaining .. ']', _source) + + local pickupLabel = ('~y~%s~s~ [~b~%s~s~]'):format(item.label, remaining) + ESX.CreatePickup('item_standard', pickup.name, remaining, pickupLabel, _source) end elseif pickup.type == 'item_money' then @@ -526,7 +500,7 @@ ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') + money = xPlayer.getMoney() }) end) @@ -540,7 +514,7 @@ ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') + money = xPlayer.getMoney() }) end) From b63c147fc070b67f2a4a7cc9fdf61e2321eb39f7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 23 Dec 2018 15:05:00 +0100 Subject: [PATCH 272/672] Proper raycast arguments, trim last position --- client/functions.lua | 9 +++++++-- client/main.lua | 2 +- es_extended.sql | 22 +++++++++++----------- server/classes/player.lua | 20 ++++++++++++-------- server/functions.lua | 4 ++-- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 90ff3125..61333dd2 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -582,8 +582,13 @@ ESX.Game.GetVehicleInDirection = function() local playerCoords = GetEntityCoords(playerPed) local inDirection = GetOffsetFromEntityInWorldCoords(playerPed, 0.0, 5.0, 0.0) local rayHandle = StartShapeTestRay(playerCoords, inDirection, 10, playerPed, 0) - local a, b, c, d, vehicle = GetShapeTestResult(rayHandle) - return vehicle + local numRayHandle, hit, endCoords, surfaceNormal, entityHit = GetShapeTestResult(rayHandle) + + if hit == 1 and GetEntityType(entityHit) == 2 then + return entityHit + end + + return nil end ESX.Game.IsSpawnPointClear = function(coords, radius) diff --git a/client/main.lua b/client/main.lua index 5fab7cc2..92d63cd9 100644 --- a/client/main.lua +++ b/client/main.lua @@ -538,7 +538,7 @@ Citizen.CreateThread(function() local coords = GetEntityCoords(playerPed) if not IsEntityDead(playerPed) then - ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} + ESX.PlayerData.lastPosition = {x = ESX.Math.Round(coords.x, 2), y = ESX.Math.Round(coords.y, 2), z = ESX.Math.Round(coords.z, 2)} end end diff --git a/es_extended.sql b/es_extended.sql index 31fa0467..0b51e267 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -3,15 +3,15 @@ USE `essentialmode`; ALTER TABLE `users` ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, - ADD COLUMN `job` varchar(255) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job` varchar(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(255) NULL AFTER `loadout` + ADD COLUMN `position` VARCHAR(50) NULL AFTER `loadout` ; CREATE TABLE `items` ( `name` varchar(50) NOT NULL, - `label` varchar(255) NOT NULL, + `label` varchar(50) NOT NULL, `limit` int(11) NOT NULL DEFAULT '-1', `rare` int(11) NOT NULL DEFAULT '0', `can_remove` int(11) NOT NULL DEFAULT '1', @@ -21,10 +21,10 @@ CREATE TABLE `items` ( CREATE TABLE `job_grades` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `job_name` varchar(255) DEFAULT NULL, + `job_name` varchar(50) DEFAULT NULL, `grade` int(11) NOT NULL, - `name` varchar(255) NOT NULL, - `label` varchar(255) NOT NULL, + `name` varchar(50) NOT NULL, + `label` varchar(50) NOT NULL, `salary` int(11) NOT NULL, `skin_male` longtext NOT NULL, `skin_female` longtext NOT NULL, @@ -36,7 +36,7 @@ INSERT INTO `job_grades` VALUES (1,'unemployed',0,'unemployed','Unemployed',200, CREATE TABLE `jobs` ( `name` varchar(50) NOT NULL, - `label` varchar(255) DEFAULT NULL, + `label` varchar(50) DEFAULT NULL, PRIMARY KEY (`name`) ); @@ -45,8 +45,8 @@ INSERT INTO `jobs` VALUES ('unemployed','Unemployed'); CREATE TABLE `user_accounts` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `name` varchar(255) NOT NULL, + `identifier` varchar(22) NOT NULL, + `name` varchar(50) NOT NULL, `money` double NOT NULL DEFAULT '0', PRIMARY KEY (`id`) @@ -54,8 +54,8 @@ CREATE TABLE `user_accounts` ( CREATE TABLE `user_inventory` ( `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(255) NOT NULL, - `item` varchar(255) NOT NULL, + `identifier` varchar(22) NOT NULL, + `item` varchar(50) NOT NULL, `count` int(11) NOT NULL, PRIMARY KEY (`id`) diff --git a/server/classes/player.lua b/server/classes/player.lua index 819b2947..ec0cf554 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -13,7 +13,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.identifier = self.player.get('identifier') self.setMoney = function(money) - money = ESX.Round(money) + money = ESX.Math.Round(money) if money >= 0 then self.player.setMoney(money) @@ -27,7 +27,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.setBankBalance = function(money) - money = ESX.Round(money) + money = ESX.Math.Round(money) if money >= 0 then self.player.setBankBalance(money) @@ -53,7 +53,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.addMoney = function(money) - money = ESX.Round(money) + money = ESX.Math.Round(money) if money >= 0 then self.player.addMoney(money) @@ -63,7 +63,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.removeMoney = function(money) - money = ESX.Round(money) + money = ESX.Math.Round(money) if money >= 0 then self.player.removeMoney(money) @@ -73,7 +73,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.addBank = function(money) - money = ESX.Round(money) + money = ESX.Math.Round(money) if money >= 0 then self.player.addBank(money) @@ -83,7 +83,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.removeBank = function(money) - money = ESX.Round(money) + money = ESX.Math.Round(money) if money >= 0 then self.player.removeBank(money) @@ -199,6 +199,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.getLastPosition = function() + self.lastPosition.x = ESX.Math.Round(self.lastPosition.x, 2) + self.lastPosition.y = ESX.Math.Round(self.lastPosition.y, 2) + self.lastPosition.z = ESX.Math.Round(self.lastPosition.z, 2) + return self.lastPosition end @@ -251,7 +255,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l local account = self.getAccount(acc) local prevMoney = account.money - local newMoney = ESX.Round(money) + local newMoney = ESX.Math.Round(money) account.money = newMoney @@ -269,7 +273,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end local account = self.getAccount(acc) - local newMoney = account.money + ESX.Round(money) + local newMoney = account.money + ESX.Math.Round(money) account.money = newMoney diff --git a/server/functions.lua b/server/functions.lua index 60d3cd17..3d682d5c 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -90,8 +90,8 @@ ESX.SavePlayer = function(xPlayer, cb) { ['@job'] = xPlayer.job.name, ['@job_grade'] = xPlayer.job.grade, - ['@loadout'] = json.encode(xPlayer.loadout), - ['@position'] = json.encode(xPlayer.lastPosition), + ['@loadout'] = json.encode(xPlayer.getLoadout()), + ['@position'] = json.encode(xPlayer.getLastPosition()), ['@identifier'] = xPlayer.identifier }, function(rowsChanged) cb() From 201b5f9ff2cc8893817f9933edc61553d28a4af7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 23 Dec 2018 17:46:55 +0100 Subject: [PATCH 273/672] Use old native as new one broke drawing 3d text --- client/functions.lua | 2 +- server/main.lua | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 61333dd2..a4f82218 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -966,7 +966,7 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end ESX.Game.Utils.DrawText3D = function(coords, text, size) - local onScreen, x, y = GetScreenCoordFromWorldCoord(coords.x, coords.y, coords.z) + local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) local camCoords = GetGameplayCamCoords() local dist = GetDistanceBetweenCoords(camCoords, coords.x, coords.y, coords.z, true) local size = size diff --git a/server/main.lua b/server/main.lua index cb7dfa8f..fedefeda 100644 --- a/server/main.lua +++ b/server/main.lua @@ -421,20 +421,17 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end end - -- workaround for CreateAmbientPickup() giving 30 rounds of ammo when you drop the weapon with 0 ammo - if itemCount == 0 then - itemCount = 1 - end - if xPlayer.hasWeapon(itemName) then local weaponLabel, weaponPickup = ESX.GetWeaponLabel(itemName), 'PICKUP_' .. string.upper(itemName) xPlayer.removeWeapon(itemName) - TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, itemName, itemCount) - + if itemCount > 0 then + TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, itemName, itemCount) TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon_ammo', weaponLabel, itemCount)) else + -- workaround for CreateAmbientPickup() giving 30 rounds of ammo when you drop the weapon with 0 ammo + TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, itemName, 1) TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon', weaponLabel)) end end From 31f3bddf4cb9ef0130c51dc55f6aee5e9d581b53 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 29 Dec 2018 00:05:23 +0100 Subject: [PATCH 274/672] Added weapon components --- config.weapons.lua | 741 +++++++++++++++++++++++++++++++++++++++------ locales/br.lua | 1 - locales/cs.lua | 1 - locales/de.lua | 1 - locales/en.lua | 1 - locales/fi.lua | 1 - locales/fr.lua | 1 - locales/pl.lua | 1 - locales/sv.lua | 1 - 9 files changed, 649 insertions(+), 100 deletions(-) diff --git a/config.weapons.lua b/config.weapons.lua index 74627321..320a9da5 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -1,94 +1,651 @@ Config.Weapons = { - { name = 'WEAPON_KNIFE', label = _U('weapon_knife') }, - { name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick') }, - { name = 'WEAPON_HAMMER', label = _U('weapon_hammer') }, - { name = 'WEAPON_BAT', label = _U('weapon_bat') }, - { name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub') }, - { name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar') }, - { name = 'WEAPON_PISTOL', label = _U('weapon_pistol') }, - { name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol') }, - { name = 'WEAPON_APPISTOL', label = _U('weapon_appistol') }, - { name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50') }, - { name = 'WEAPON_MICROSMG', label = _U('weapon_microsmg') }, - { name = 'WEAPON_SMG', label = _U('weapon_smg') }, - { name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg') }, - { name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle') }, - { name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle') }, - { name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle') }, - { name = 'WEAPON_MG', label = _U('weapon_mg') }, - { name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg') }, - { name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun') }, - { name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun') }, - { name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun') }, - { name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun') }, - { name = 'WEAPON_STUNGUN', label = _U('weapon_stungun') }, - { name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle') }, - { name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper') }, - { name = 'WEAPON_REMOTESNIPER', label = _U('weapon_remotesniper') }, - { name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher') }, - { name = 'WEAPON_RPG', label = _U('weapon_rpg') }, - { name = 'WEAPON_STINGER', label = _U('weapon_stinger') }, - { name = 'WEAPON_MINIGUN', label = _U('weapon_minigun') }, - { name = 'WEAPON_GRENADE', label = _U('weapon_grenade') }, - { name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb') }, - { name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade') }, - { name = 'WEAPON_BZGAS', label = _U('weapon_bzgas') }, - { name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov') }, - { name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher') }, - { name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan') }, - { name = 'WEAPON_DIGISCANNER', label = _U('weapon_digiscanner') }, - { name = 'WEAPON_BALL', label = _U('weapon_ball') }, - { name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol') }, - { name = 'WEAPON_BOTTLE', label = _U('weapon_bottle') }, - { name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg') }, - { name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine') }, - { name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol') }, - { name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle') }, - { name = 'WEAPON_DAGGER', label = _U('weapon_dagger') }, - { name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol') }, - { name = 'WEAPON_FIREWORK', label = _U('weapon_firework') }, - { name = 'WEAPON_MUSKET', label = _U('weapon_musket') }, - { name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun') }, - { name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle') }, - { name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher') }, - { name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine') }, - { name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball') }, - { name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun') }, - { name = 'WEAPON_GARBAGEBAG', label = _U('weapon_garbagebag') }, - { name = 'WEAPON_HANDCUFFS', label = _U('weapon_handcuffs') }, - { name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw') }, - { name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol') }, - { name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle') }, - { name = 'WEAPON_HATCHET', label = _U('weapon_hatchet') }, - { name = 'WEAPON_RAILGUN', label = _U('weapon_railgun') }, - { name = 'WEAPON_MACHETE', label = _U('weapon_machete') }, - { name = 'WEAPON_MACHINEPISTOL', label = _U('weapon_machinepistol') }, - { name = 'WEAPON_SWITCHBLADE', label = _U('weapon_switchblade') }, - { name = 'WEAPON_REVOLVER', label = _U('weapon_revolver') }, - { name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun') }, - { name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle') }, - { name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun') }, - { name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe') }, - { name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher') }, - { name = 'WEAPON_MINISMG', label = _U('weapon_minismg') }, - { name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb') }, - { name = 'WEAPON_POOLCUE', label = _U('weapon_poolcue') }, - { name = 'WEAPON_WRENCH', label = _U('weapon_wrench') }, - { name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight') }, - { name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision') }, - { name = 'GADGET_PARACHUTE', label = _U('gadget_parachute') }, - { name = 'WEAPON_FLARE', label = _U('weapon_flare') }, - { name = 'WEAPON_SNSPISTOL_MK2', label = _U('weapon_snspistol_mk2') }, - { name = 'WEAPON_REVOLVER_MK2', label = _U('weapon_revolver_mk2') }, - { name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction') }, - { name = 'WEAPON_SPECIALCARBINE_MK2', label = _U('weapon_specialcarabine_mk2') }, - { name = 'WEAPON_BULLPUPRIFLE_MK2', label = _U('weapon_bullpruprifle_mk2') }, - { name = 'WEAPON_PUMPSHOTGUN_MK2', label = _U('weapon_pumpshotgun_mk2') }, - { name = 'WEAPON_MARKSMANRIFLE_MK2', label = _U('weapon_marksmanrifle_mk2') }, - { name = 'WEAPON_ASSAULTRIFLE_MK2', label = _U('weapon_assaultrifle_mk2') }, - { name = 'WEAPON_CARBINERIFLE_MK2', label = _U('weapon_carbinerifle_mk2') }, - { name = 'WEAPON_COMBATMG_MK2', label = _U('weapon_combatmg_mk2') }, - { name = 'WEAPON_HEAVYSNIPER_MK2', label = _U('weapon_heavysniper_mk2') }, - { name = 'WEAPON_PISTOL_MK2', label = _U('weapon_pistol_mk2') }, - { name = 'WEAPON_SMG_MK2', label = _U('weapon_smg_mk2') } + + { + name = 'WEAPON_KNIFE', + label = _U('weapon_knife'), + components = {} + }, + + { + name = 'WEAPON_NIGHTSTICK', + label = _U('weapon_nightstick'), + components = {} + }, + + { + name = 'WEAPON_HAMMER', + label = _U('weapon_hammer'), + components = {} + }, + + { + name = 'WEAPON_BAT', + label = _U('weapon_bat'), + components = {} + }, + + { + name = 'WEAPON_GOLFCLUB', + label = _U('weapon_golfclub'), + components = {} + }, + + { + name = 'WEAPON_CROWBAR', + label = _U('weapon_crowbar'), + components = {} + }, + + { + name = 'WEAPON_PISTOL', + label = _U('weapon_pistol'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_02') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP_02') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PISTOL_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_COMBATPISTOL', + label = _U('weapon_combatpistol'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_02') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_COMBATPISTOL_VARMOD_LOWRIDER') } + } + }, + + { + name = 'WEAPON_APPISTOL', + label = _U('weapon_appistol'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_02') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_APPISTOL_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_PISTOL50', + label = _U('weapon_pistol50'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_02') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PISTOL50_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_REVOLVER', + label = _U('weapon_revolver'), + components = {} + }, + + { + name = 'WEAPON_SNSPISTOL', + label = _U('weapon_snspistol'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_02') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SNSPISTOL_VARMOD_LOWRIDER') } + } + }, + + { + name = 'WEAPON_HEAVYPISTOL', + label = _U('weapon_heavypistol'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_02') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_VINTAGEPISTOL', + label = _U('weapon_vintagepistol'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_02') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') } + } + }, + + { + name = 'WEAPON_MICROSMG', + label = _U('weapon_microsmg'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_02') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MICROSMG_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_SMG', + label = _U('weapon_smg'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SMG_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SMG_CLIP_02') }, + { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_SMG_CLIP_03') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO_02') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SMG_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_ASSAULTSMG', + label = _U('weapon_assaultsmg'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_02') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ASSAULTSMG_VARMOD_LOWRIDER') } + } + }, + + { + name = 'WEAPON_MINISMG', + label = _U('weapon_minismg'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_02') } + } + }, + + { + name = 'WEAPON_MACHINEPISTOL', + label = _U('weapon_machinepistol'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_02') }, + { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_03') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') } + } + }, + + { + name = 'WEAPON_COMBATPDW', + label = _U('weapon_combatpdw'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_02') }, + { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_03') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL') } + } + }, + + { + name = 'WEAPON_PUMPSHOTGUN', + label = _U('weapon_pumpshotgun'), + components = { + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_SR_SUPP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PUMPSHOTGUN_VARMOD_LOWRIDER') } + } + }, + + { + name = 'WEAPON_SAWNOFFSHOTGUN', + label = _U('weapon_sawnoffshotgun'), + components = { + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SAWNOFFSHOTGUN_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_ASSAULTSHOTGUN', + label = _U('weapon_assaultshotgun'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_02') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, + { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') } + } + }, + + { + name = 'WEAPON_BULLPUPSHOTGUN', + label = _U('weapon_bullpupshotgun'), + components = { + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, + { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') } + } + }, + + { + name = 'WEAPON_HEAVYSHOTGUN', + label = _U('weapon_heavyshotgun'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_02') }, + { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_03') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, + { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') } + } + }, + + { + name = 'WEAPON_ASSAULTRIFLE', + label = _U('weapon_assaultrifle'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_02') }, + { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_03') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, + { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_CARBINERIFLE', + label = _U('weapon_carbinerifle'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_02') }, + { name = 'clip_box', label = _U('component_clip_box'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_03') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, + { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_CARBINERIFLE_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_ADVANCEDRIFLE', + label = _U('weapon_advancedrifle'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_02') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_SPECIALCARBINE', + label = _U('weapon_specialcarbine'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_02') }, + { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_03') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, + { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_VARMOD_LOWRIDER') } + } + }, + + { + name = 'WEAPON_BULLPUPRIFLE', + label = _U('weapon_bullpuprifle'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_02') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, + { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_VARMOD_LOW') } + } + }, + + { + name = 'WEAPON_COMPACTRIFLE', + label = _U('weapon_compactrifle'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_02') }, + { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_03') } + } + }, + + { + name = 'WEAPON_MG', + label = _U('weapon_mg'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MG_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MG_CLIP_02') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL_02') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MG_VARMOD_LOWRIDER') } + } + }, + + { + name = 'WEAPON_COMBATMG', + label = _U('weapon_combatmg'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_02') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM') }, + { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_COMBATMG_VARMOD_LOWRIDER') } + } + }, + + { + name = 'WEAPON_GUSENBERG', + label = _U('weapon_gusenberg'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_02') }, + } + }, + + { + name = 'WEAPON_SNIPERRIFLE', + label = _U('weapon_sniperrifle'), + components = { + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE') }, + { name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SNIPERRIFLE_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_HEAVYSNIPER', + label = _U('weapon_heavysniper'), + components = { + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE') }, + { name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX') } + } + }, + + { + name = 'WEAPON_MARKSMANRIFLE', + label = _U('weapon_marksmanrifle'), + components = { + { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_01') }, + { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_02') }, + { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, + { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE_FIXED_ZOOM') }, + { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, + { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, + { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_VARMOD_LUXE') } + } + }, + + { + name = 'WEAPON_GRENADELAUNCHER', + label = _U('weapon_grenadelauncher'), + components = {} + }, + + { + name = 'WEAPON_RPG', + label = _U('weapon_rpg'), + components = {} + }, + + { + name = 'WEAPON_STINGER', + label = _U('weapon_stinger'), + components = {} + }, + + { + name = 'WEAPON_MINIGUN', + label = _U('weapon_minigun'), + components = {} + }, + + { + name = 'WEAPON_GRENADE', + label = _U('weapon_grenade'), + components = {} + }, + + { + name = 'WEAPON_STICKYBOMB', + label = _U('weapon_stickybomb'), + components = {} + }, + + { + name = 'WEAPON_SMOKEGRENADE', + label = _U('weapon_smokegrenade'), + components = {} + }, + + { + name = 'WEAPON_BZGAS', + label = _U('weapon_bzgas'), + components = {} + }, + + { + name = 'WEAPON_MOLOTOV', + label = _U('weapon_molotov'), + components = {} + }, + + { + name = 'WEAPON_FIREEXTINGUISHER', + label = _U('weapon_fireextinguisher'), + components = {} + }, + + { + name = 'WEAPON_PETROLCAN', + label = _U('weapon_petrolcan'), + components = {} + }, + + { + name = 'WEAPON_DIGISCANNER', + label = _U('weapon_digiscanner'), + components = {} + }, + + { + name = 'WEAPON_BALL', + label = _U('weapon_ball'), + components = {} + }, + + { + name = 'WEAPON_BOTTLE', + label = _U('weapon_bottle'), + components = {} + }, + + { + name = 'WEAPON_DAGGER', + label = _U('weapon_dagger'), + components = {} + }, + + { + name = 'WEAPON_FIREWORK', + label = _U('weapon_firework'), + components = {} + }, + + { + name = 'WEAPON_MUSKET', + label = _U('weapon_musket'), + components = {} + }, + + { + name = 'WEAPON_STUNGUN', + label = _U('weapon_stungun'), + components = {} + }, + + { + name = 'WEAPON_HOMINGLAUNCHER', + label = _U('weapon_hominglauncher'), + components = {} + }, + + { + name = 'WEAPON_PROXMINE', + label = _U('weapon_proxmine'), + components = {} + }, + + { + name = 'WEAPON_SNOWBALL', + label = _U('weapon_snowball'), + components = {} + }, + + { + name = 'WEAPON_FLAREGUN', + label = _U('weapon_flaregun'), + components = {} + }, + + { + name = 'WEAPON_GARBAGEBAG', + label = _U('weapon_garbagebag'), + components = {} + }, + + { + name = 'WEAPON_HANDCUFFS', + label = _U('weapon_handcuffs'), + components = {} + }, + + { + name = 'WEAPON_MARKSMANPISTOL', + label = _U('weapon_marksmanpistol'), + components = {} + }, + + { + name = 'WEAPON_KNUCKLE', + label = _U('weapon_knuckle'), + components = {} + }, + + { + name = 'WEAPON_HATCHET', + label = _U('weapon_hatchet'), + components = {} + }, + + { + name = 'WEAPON_RAILGUN', + label = _U('weapon_railgun'), + components = {} + }, + + { + name = 'WEAPON_MACHETE', + label = _U('weapon_machete'), + components = {} + }, + + { + name = 'WEAPON_SWITCHBLADE', + label = _U('weapon_switchblade'), + components = {} + }, + + { + name = 'WEAPON_DBSHOTGUN', + label = _U('weapon_dbshotgun'), + components = {} + }, + + { + name = 'WEAPON_AUTOSHOTGUN', + label = _U('weapon_autoshotgun'), + components = {} + }, + + { + name = 'WEAPON_BATTLEAXE', + label = _U('weapon_battleaxe'), + components = {} + }, + + { + name = 'WEAPON_COMPACTLAUNCHER', + label = _U('weapon_compactlauncher'), + components = {} + }, + + { + name = 'WEAPON_PIPEBOMB', + label = _U('weapon_pipebomb'), + components = {} + }, + + { + name = 'WEAPON_POOLCUE', + label = _U('weapon_poolcue'), + components = {} + }, + + { + name = 'WEAPON_WRENCH', + label = _U('weapon_wrench'), + components = {} + }, + + { + name = 'WEAPON_FLASHLIGHT', + label = _U('weapon_flashlight'), + components = {} + }, + + { + name = 'GADGET_NIGHTVISION', + label = _U('gadget_nightvision'), + components = {} + }, + + { + name = 'GADGET_PARACHUTE', + label = _U('gadget_parachute'), + components = {} + }, + + { + name = 'WEAPON_FLARE', + label = _U('weapon_flare'), + components = {} + }, + + { + name = 'WEAPON_DOUBLEACTION', + label = _U('weapon_doubleaction'), + components = {} + } + } diff --git a/locales/br.lua b/locales/br.lua index c5328418..077ab420 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -103,7 +103,6 @@ Locales['br'] = { ['weapon_stungun'] = 'arma de choque', ['weapon_sniperrifle'] = 'sniper rifle', ['weapon_heavysniper'] = 'heavy sniper', - ['weapon_remotesniper'] = 'remote sniper', ['weapon_grenadelauncher'] = 'lançador de granada', ['weapon_rpg'] = 'lançador de foguetes', ['weapon_stinger'] = 'stinger', diff --git a/locales/cs.lua b/locales/cs.lua index 69a04afb..1d5001de 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -107,7 +107,6 @@ Locales['cs'] = { ['weapon_stungun'] = 'tazer', ['weapon_sniperrifle'] = 'sniper rifle', ['weapon_heavysniper'] = 'heavy sniper', - ['weapon_remotesniper'] = 'remote sniper', ['weapon_grenadelauncher'] = 'grenade launcher', ['weapon_rpg'] = 'rocket launcher', ['weapon_stinger'] = 'stinger', diff --git a/locales/de.lua b/locales/de.lua index 3af360a2..746b36bc 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -97,7 +97,6 @@ Locales['de'] = { ['weapon_stungun'] = 'Tazer', ['weapon_sniperrifle'] = 'Scharfschützengewehr', ['weapon_heavysniper'] = 'Schweres Sniper', - ['weapon_remotesniper'] = 'Remote sniper', ['weapon_grenadelauncher'] = 'Granatwerfer', ['weapon_rpg'] = 'RPG', ['weapon_stinger'] = 'Stinger', diff --git a/locales/en.lua b/locales/en.lua index 6fa0dd63..d0c14870 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -107,7 +107,6 @@ Locales['en'] = { ['weapon_stungun'] = 'taser', ['weapon_sniperrifle'] = 'sniper rifle', ['weapon_heavysniper'] = 'heavy sniper', - ['weapon_remotesniper'] = 'remote sniper', ['weapon_grenadelauncher'] = 'grenade launcher', ['weapon_rpg'] = 'rocket launcher', ['weapon_stinger'] = 'stinger', diff --git a/locales/fi.lua b/locales/fi.lua index f53df544..920662c8 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -107,7 +107,6 @@ Locales['fi'] = { ['weapon_stungun'] = 'tainutusase', ['weapon_sniperrifle'] = 'tarkkuuskivääri', ['weapon_heavysniper'] = 'raskas tarkkuuskivääri', - ['weapon_remotesniper'] = 'etäohjattava tarkkuuskivääri', ['weapon_grenadelauncher'] = 'kranaatinheitin', ['weapon_rpg'] = 'raketinheitin', ['weapon_stinger'] = 'stinger', diff --git a/locales/fr.lua b/locales/fr.lua index f46482a4..f7cd5a38 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -104,7 +104,6 @@ Locales['fr'] = { ['weapon_stungun'] = 'tazer', ['weapon_sniperrifle'] = 'fusil de sniper', ['weapon_heavysniper'] = 'fusil de sniper lourd', - ['weapon_remotesniper'] = 'fusil de sniper à distance', ['weapon_grenadelauncher'] = 'lance-grenade', ['weapon_rpg'] = 'lance-rocket', ['weapon_stinger'] = 'lance-missile stinger', diff --git a/locales/pl.lua b/locales/pl.lua index 8c754742..380730d2 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -105,7 +105,6 @@ Locales['pl'] = { ['weapon_stungun'] = 'tazer', ['weapon_sniperrifle'] = 'karabin snajperski', ['weapon_heavysniper'] = 'ciężki karabin snajperski', - ['weapon_remotesniper'] = 'remote sniper', ['weapon_grenadelauncher'] = 'granatnik', ['weapon_rpg'] = 'wyrzutnia rakiet', ['weapon_stinger'] = 'stinger', diff --git a/locales/sv.lua b/locales/sv.lua index ad2236ca..01511450 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -107,7 +107,6 @@ Locales['sv'] = { ['weapon_stungun'] = 'elchockpistol', ['weapon_sniperrifle'] = 'prickskyttegevär', ['weapon_heavysniper'] = 'tung prickskytt', - ['weapon_remotesniper'] = 'remote sniper', ['weapon_grenadelauncher'] = 'granatkastare', ['weapon_rpg'] = 'raketgevär', ['weapon_stinger'] = 'stinger', From 48a1605bc23f96a7b706183f7e2e66136df45fc5 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 29 Dec 2018 00:19:29 +0100 Subject: [PATCH 275/672] Added missing translations, removed MK2, closes #185 --- locales/br.lua | 19 +++++-------------- locales/cs.lua | 15 +-------------- locales/de.lua | 23 ++++++++++------------- locales/fi.lua | 15 +-------------- locales/fr.lua | 18 ++++-------------- locales/pl.lua | 21 +++++---------------- locales/sv.lua | 17 ++--------------- 7 files changed, 28 insertions(+), 100 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 077ab420..ae7a53a9 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -42,6 +42,7 @@ Locales['br'] = { ['received_paycheck'] = 'recebeu dinheiro', ['bank'] = 'banco', ['black_money'] = 'dinheiro sujo', + ['act_imp'] = 'acao impossivel', ['in_vehicle'] = 'voce nao pode dar nada para alguem no veiculo', ['cannot_pickup_room'] = 'voce nao tem espaço suficiente no seu inventario para pegar ~y~%s~s~!', @@ -57,11 +58,13 @@ Locales['br'] = { ['spawn_car'] = 'spawn um carro', ['spawn_car_param'] = 'nome do carro', ['delete_vehicle'] = 'excluir Veiculo', - ['delete_veh_param'] = 'pressione Enter', ['spawn_object'] = 'spawn objeto', ['spawn_ped'] = 'spawn ped', ['spawn_ped_param'] = 'exemplo a_m_m_hillbilly_01', ['givemoney'] = 'dar dinheiro', + ['setmoney'] = 'set money for a player', + ['money_type'] = 'valid money types: cash, bank, black', + ['money_set'] = 'someone ~y~highly ranked~s~ just set ~g~$%s~s~ (%s) for you!', ['money_amount'] = 'quantia de dinheiro', ['invalid_account'] = 'conta invalida', ['account'] = 'conta', @@ -156,17 +159,5 @@ Locales['br'] = { ['gadget_nightvision'] = 'visao noturna', ['gadget_parachute'] = 'paraquedas', ['weapon_flare'] = 'Flare', - ['weapon_snspistol_mk2'] = 'Pistola SNS Mk II', - ['weapon_revolver_mk2'] = 'Revolver Pesada Mk II', - ['weapon_doubleaction'] = 'Revolver Dupla-acao', - ['weapon_specialcarabine_mk2'] = 'Carabina Especial Mk II', - ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', - ['weapon_pumpshotgun_mk2'] = 'Espingarda Mk II', - ['weapon_marksmanrifle_mk2'] = 'Rifle Marksman Mk II', - ['weapon_assaultrifle_mk2'] = 'Rifle de assalto Mk II ', - ['weapon_carbinerifle_mk2'] = 'Carabina Mk II ', - ['weapon_combatmg_mk2'] = 'MG de Combate Mk II', - ['weapon_heavysniper_mk2'] = 'Sniper pesada Mk II', - ['weapon_pistol_mk2'] = 'Pistola Mk II', - ['weapon_smg_mk2'] = 'SMG Mk II', + ['weapon_doubleaction'] = 'double-Action Revolver', } diff --git a/locales/cs.lua b/locales/cs.lua index 1d5001de..a0085562 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -58,7 +58,6 @@ Locales['cs'] = { ['spawn_car'] = 'spawn auto', ['spawn_car_param'] = 'název auta', ['delete_vehicle'] = 'odstranit vozidlo', - ['delete_veh_param'] = 'zmáčkněte enter', ['spawn_object'] = 'spawn objekt', ['spawn_ped'] = 'spawn peda', ['spawn_ped_param'] = 'příklad a_m_m_hillbilly_01', @@ -160,17 +159,5 @@ Locales['cs'] = { ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'flare gun', - ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', - ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', - ['weapon_doubleaction'] = 'Double-Action Revolver', - ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', - ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', - ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', - ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', - ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', - ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', - ['weapon_combatmg_mk2'] = 'Combat MG Mk II', - ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', - ['weapon_pistol_mk2'] = 'Pistol Mk II', - ['weapon_smg_mk2'] = 'SMG Mk II', + ['weapon_doubleaction'] = 'double-Action Revolver', } diff --git a/locales/de.lua b/locales/de.lua index 746b36bc..64bdfdec 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -44,6 +44,8 @@ Locales['de'] = { ['black_money'] = 'schwarzgeld', ['act_imp'] = 'Aktion nicht möglich', + ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', + ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', -- Commands ['setjob'] = 'assign a job to a user', ['id_param'] = 'the ID of the player', @@ -55,7 +57,14 @@ Locales['de'] = { ['play_emote'] = 'play emote', ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', + ['delete_vehicle'] = 'deletes Vehicle', + ['spawn_object'] = 'spawn object', + ['spawn_ped'] = 'spawn ped', + ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'give money', + ['setmoney'] = 'set money for a player', + ['money_type'] = 'valid money types: cash, bank, black', + ['money_set'] = 'someone ~y~highly ranked~s~ just set ~g~$%s~s~ (%s) for you!', ['money_amount'] = 'amount of money', ['invalid_account'] = 'invalid account', ['account'] = 'account', @@ -150,17 +159,5 @@ Locales['de'] = { ['gadget_nightvision'] = 'Nachtsichtgerät', ['gadget_parachute'] = 'Fallschirm', ['weapon_flare'] = 'Leuchtpistole', - ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', - ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', - ['weapon_doubleaction'] = 'Double-Action Revolver', - ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', - ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', - ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', - ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', - ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', - ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', - ['weapon_combatmg_mk2'] = 'Combat MG Mk II', - ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', - ['weapon_pistol_mk2'] = 'Pistol Mk II', - ['weapon_smg_mk2'] = 'SMG Mk II', + ['weapon_doubleaction'] = 'double-Action Revolver', } diff --git a/locales/fi.lua b/locales/fi.lua index 920662c8..ab033182 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -58,7 +58,6 @@ Locales['fi'] = { ['spawn_car'] = 'spawnaa ajoneuvo', ['spawn_car_param'] = 'ajoneuvon nimi', ['delete_vehicle'] = 'poistaa ajoneuvon', - ['delete_veh_param'] = 'paina Enter', ['spawn_object'] = 'spawnaa objekti', ['spawn_ped'] = 'spawnaa pedi', ['spawn_ped_param'] = 'esimerkki a_m_m_hillbilly_01', @@ -160,17 +159,5 @@ Locales['fi'] = { ['gadget_nightvision'] = 'yökiikarit', ['gadget_parachute'] = 'laskuvarjo', ['weapon_flare'] = 'hätäraketti', - ['weapon_snspistol_mk2'] = 'konepistooli Mk II', - ['weapon_revolver_mk2'] = 'raskas revolveri Mk II', - ['weapon_doubleaction'] = 'kaksitoiminen Revolveri', - ['weapon_specialcarabine_mk2'] = 'G86C Mk II', - ['weapon_bullpruprifle_mk2'] = 'Bullpup Kivääri Mk II', - ['weapon_pumpshotgun_mk2'] = 'Pumppuhaulikko Mk II', - ['weapon_marksmanrifle_mk2'] = 'Marksman Kivääri Mk II', - ['weapon_assaultrifle_mk2'] = 'Rynnäkkökivääri Mk II ', - ['weapon_carbinerifle_mk2'] = 'Karbiini Kivääri Mk II ', - ['weapon_combatmg_mk2'] = 'Rynnäkkökonekivääri Mk II', - ['weapon_heavysniper_mk2'] = 'Raskas Tarkkuuskivääri Mk II', - ['weapon_pistol_mk2'] = 'Pistooli Mk II', - ['weapon_smg_mk2'] = 'Konepistooli Mk II', + ['weapon_doubleaction'] = 'double-Action Revolver', } diff --git a/locales/fr.lua b/locales/fr.lua index f7cd5a38..c4c598d5 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -58,11 +58,13 @@ Locales['fr'] = { ['spawn_car'] = 'spawn un véhicule', ['spawn_car_param'] = 'nom de la voiture', ['delete_vehicle'] = 'supprimer le véhicule', - ['delete_veh_param'] = 'appuyez sur Entrée', ['spawn_object'] = 'engendre un objet', ['spawn_ped'] = 'spawn ped', ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'donner de l\'argent', + ['setmoney'] = 'set money for a player', + ['money_type'] = 'valid money types: cash, bank, black', + ['money_set'] = 'someone ~y~highly ranked~s~ just set ~g~$%s~s~ (%s) for you!', ['money_amount'] = 'somme d\'argent', ['invalid_account'] = 'compete invalide', ['account'] = 'compte', @@ -157,17 +159,5 @@ Locales['fr'] = { ['gadget_nightvision'] = 'vision nocturne', ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'Fusée Détresse', - ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', - ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', - ['weapon_doubleaction'] = 'Double-Action Revolver', - ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', - ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', - ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', - ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', - ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', - ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', - ['weapon_combatmg_mk2'] = 'Combat MG Mk II', - ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', - ['weapon_pistol_mk2'] = 'Pistol Mk II', - ['weapon_smg_mk2'] = 'SMG Mk II', + ['weapon_doubleaction'] = 'double-Action Revolver', } diff --git a/locales/pl.lua b/locales/pl.lua index 380730d2..55f8c640 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -42,7 +42,7 @@ Locales['pl'] = { ['received_paycheck'] = 'otrzymana wypłata', ['bank'] = 'bank', ['black_money'] = 'brudne pieniądze', - + ['act_imp'] = 'działanie niemożliwe', ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', ['cannot_pickup_room'] = 'nie masz wystarczająco dużo miejsca w ekwipunku, aby podnieść ~y~%s~s~!', @@ -58,7 +58,6 @@ Locales['pl'] = { ['spawn_car'] = 'sprowadź pojazd', ['spawn_car_param'] = 'nazwa samochodu', ['delete_vehicle'] = 'usuń pojazd', - ['delete_veh_param'] = 'naciśnij enter', ['spawn_object'] = 'pojaw obiekt', ['spawn_ped'] = 'pojaw peda', ['spawn_ped_param'] = 'np. a_m_m_hillbilly_01', @@ -76,6 +75,8 @@ Locales['pl'] = { ['weapon'] = 'broń', ['giveweapon'] = 'daj broń', ['disconnect'] = 'odłącz się od serwera', + ['chat_clear'] = 'clear the chat', + ['chat_clear_all'] = 'clear the chat for everyone', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', @@ -158,17 +159,5 @@ Locales['pl'] = { ['gadget_nightvision'] = 'noktowizor', ['gadget_parachute'] = 'spadochron', ['weapon_flare'] = 'pistolet sygnałowy', - ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', - ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', - ['weapon_doubleaction'] = 'Double-Action Revolver', - ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', - ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', - ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', - ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', - ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', - ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', - ['weapon_combatmg_mk2'] = 'Combat MG Mk II', - ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', - ['weapon_pistol_mk2'] = 'Pistol Mk II', - ['weapon_smg_mk2'] = 'SMG Mk II', -} \ No newline at end of file + ['weapon_doubleaction'] = 'double-Action Revolver', +} diff --git a/locales/sv.lua b/locales/sv.lua index 01511450..6e76e4be 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -58,7 +58,6 @@ Locales['sv'] = { ['spawn_car'] = 'spawna ett fordon', ['spawn_car_param'] = 'namn på fordon', ['delete_vehicle'] = 'ta bort fordon', - ['delete_veh_param'] = 'tryck enter', ['spawn_object'] = 'spawna föremål', ['spawn_ped'] = 'spawna NPC', ['spawn_ped_param'] = 'exempelvis a_m_m_hillbilly_01', @@ -160,17 +159,5 @@ Locales['sv'] = { ['gadget_nightvision'] = 'mörkerseende', ['gadget_parachute'] = 'fallskärm', ['weapon_flare'] = 'signalpistol', - ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', - ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', - ['weapon_doubleaction'] = 'Double-Action Revolver', - ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', - ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', - ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', - ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', - ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', - ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', - ['weapon_combatmg_mk2'] = 'Combat MG Mk II', - ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', - ['weapon_pistol_mk2'] = 'Pistol Mk II', - ['weapon_smg_mk2'] = 'SMG Mk II', -} + ['weapon_doubleaction'] = 'double-Action Revolver', +} \ No newline at end of file From 2e7ffa33835b96b8be1bddfc9ccebb66870aabcd Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 29 Dec 2018 00:19:39 +0100 Subject: [PATCH 276/672] Update en.lua --- locales/en.lua | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/locales/en.lua b/locales/en.lua index d0c14870..196409d4 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -42,7 +42,7 @@ Locales['en'] = { ['received_paycheck'] = 'received paycheck', ['bank'] = 'bank', ['black_money'] = 'dirty Money', - + ['act_imp'] = 'action impossible', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', @@ -58,7 +58,6 @@ Locales['en'] = { ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', ['delete_vehicle'] = 'deletes Vehicle', - ['delete_veh_param'] = 'press enter', ['spawn_object'] = 'spawn object', ['spawn_ped'] = 'spawn ped', ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', @@ -160,17 +159,5 @@ Locales['en'] = { ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'flare gun', - ['weapon_snspistol_mk2'] = 'SNS Pistol Mk II', - ['weapon_revolver_mk2'] = 'Heavy Revolver Mk II', - ['weapon_doubleaction'] = 'Double-Action Revolver', - ['weapon_specialcarabine_mk2'] = 'Special Carbine Mk II', - ['weapon_bullpruprifle_mk2'] = 'Bullpup Rifle Mk II', - ['weapon_pumpshotgun_mk2'] = 'Pump Shotgun Mk II', - ['weapon_marksmanrifle_mk2'] = 'Marksman Rifle Mk II', - ['weapon_assaultrifle_mk2'] = 'Assault Rifle Mk II ', - ['weapon_carbinerifle_mk2'] = 'Carbine Rifle Mk II ', - ['weapon_combatmg_mk2'] = 'Combat MG Mk II', - ['weapon_heavysniper_mk2'] = 'Heavy Sniper Mk II', - ['weapon_pistol_mk2'] = 'Pistol Mk II', - ['weapon_smg_mk2'] = 'SMG Mk II', -} \ No newline at end of file + ['weapon_doubleaction'] = 'double-Action Revolver', +} From e5124676be18f4e148a2a1434dafb4b0e68713ac Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 29 Dec 2018 00:31:07 +0100 Subject: [PATCH 277/672] Added i18n strings for components --- locales/br.lua | 12 ++++++++++++ locales/cs.lua | 12 ++++++++++++ locales/de.lua | 12 ++++++++++++ locales/en.lua | 12 ++++++++++++ locales/fi.lua | 12 ++++++++++++ locales/fr.lua | 12 ++++++++++++ locales/pl.lua | 12 ++++++++++++ locales/sv.lua | 14 +++++++++++++- 8 files changed, 97 insertions(+), 1 deletion(-) diff --git a/locales/br.lua b/locales/br.lua index ae7a53a9..e19797f8 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -160,4 +160,16 @@ Locales['br'] = { ['gadget_parachute'] = 'paraquedas', ['weapon_flare'] = 'Flare', ['weapon_doubleaction'] = 'double-Action Revolver', + + -- Weapon Components + ['component_clip_default'] = 'default Grip', + ['component_clip_extended'] = 'extended Grip', + ['component_clip_drum'] = 'drum Magazine', + ['component_clip_box'] = 'box Magazine', + ['component_flashlight'] = 'flashlight', + ['component_scope'] = 'scope', + ['component_scope_advanced'] = 'advanced Scope', + ['component_suppressor'] = 'suppressor', + ['component_grip'] = 'grip', + ['component_luxary_finish'] = 'luxary Weapon Finish', } diff --git a/locales/cs.lua b/locales/cs.lua index a0085562..eacd5cae 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -160,4 +160,16 @@ Locales['cs'] = { ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'flare gun', ['weapon_doubleaction'] = 'double-Action Revolver', + + -- Weapon Components + ['component_clip_default'] = 'default Grip', + ['component_clip_extended'] = 'extended Grip', + ['component_clip_drum'] = 'drum Magazine', + ['component_clip_box'] = 'box Magazine', + ['component_flashlight'] = 'flashlight', + ['component_scope'] = 'scope', + ['component_scope_advanced'] = 'advanced Scope', + ['component_suppressor'] = 'suppressor', + ['component_grip'] = 'grip', + ['component_luxary_finish'] = 'luxary Weapon Finish', } diff --git a/locales/de.lua b/locales/de.lua index 64bdfdec..5bc6fd29 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -160,4 +160,16 @@ Locales['de'] = { ['gadget_parachute'] = 'Fallschirm', ['weapon_flare'] = 'Leuchtpistole', ['weapon_doubleaction'] = 'double-Action Revolver', + + -- Weapon Components + ['component_clip_default'] = 'default Grip', + ['component_clip_extended'] = 'extended Grip', + ['component_clip_drum'] = 'drum Magazine', + ['component_clip_box'] = 'box Magazine', + ['component_flashlight'] = 'flashlight', + ['component_scope'] = 'scope', + ['component_scope_advanced'] = 'advanced Scope', + ['component_suppressor'] = 'suppressor', + ['component_grip'] = 'grip', + ['component_luxary_finish'] = 'luxary Weapon Finish', } diff --git a/locales/en.lua b/locales/en.lua index 196409d4..996b1976 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -160,4 +160,16 @@ Locales['en'] = { ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'flare gun', ['weapon_doubleaction'] = 'double-Action Revolver', + + -- Weapon Components + ['component_clip_default'] = 'default Grip', + ['component_clip_extended'] = 'extended Grip', + ['component_clip_drum'] = 'drum Magazine', + ['component_clip_box'] = 'box Magazine', + ['component_flashlight'] = 'flashlight', + ['component_scope'] = 'scope', + ['component_scope_advanced'] = 'advanced Scope', + ['component_suppressor'] = 'suppressor', + ['component_grip'] = 'grip', + ['component_luxary_finish'] = 'luxary Weapon Finish', } diff --git a/locales/fi.lua b/locales/fi.lua index ab033182..255d6dd9 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -160,4 +160,16 @@ Locales['fi'] = { ['gadget_parachute'] = 'laskuvarjo', ['weapon_flare'] = 'hätäraketti', ['weapon_doubleaction'] = 'double-Action Revolver', + + -- Weapon Components + ['component_clip_default'] = 'default Grip', + ['component_clip_extended'] = 'extended Grip', + ['component_clip_drum'] = 'drum Magazine', + ['component_clip_box'] = 'box Magazine', + ['component_flashlight'] = 'flashlight', + ['component_scope'] = 'scope', + ['component_scope_advanced'] = 'advanced Scope', + ['component_suppressor'] = 'suppressor', + ['component_grip'] = 'grip', + ['component_luxary_finish'] = 'luxary Weapon Finish', } diff --git a/locales/fr.lua b/locales/fr.lua index c4c598d5..2af83b00 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -160,4 +160,16 @@ Locales['fr'] = { ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'Fusée Détresse', ['weapon_doubleaction'] = 'double-Action Revolver', + + -- Weapon Components + ['component_clip_default'] = 'default Grip', + ['component_clip_extended'] = 'extended Grip', + ['component_clip_drum'] = 'drum Magazine', + ['component_clip_box'] = 'box Magazine', + ['component_flashlight'] = 'flashlight', + ['component_scope'] = 'scope', + ['component_scope_advanced'] = 'advanced Scope', + ['component_suppressor'] = 'suppressor', + ['component_grip'] = 'grip', + ['component_luxary_finish'] = 'luxary Weapon Finish', } diff --git a/locales/pl.lua b/locales/pl.lua index 55f8c640..8d925fd2 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -160,4 +160,16 @@ Locales['pl'] = { ['gadget_parachute'] = 'spadochron', ['weapon_flare'] = 'pistolet sygnałowy', ['weapon_doubleaction'] = 'double-Action Revolver', + + -- Weapon Components + ['component_clip_default'] = 'default Grip', + ['component_clip_extended'] = 'extended Grip', + ['component_clip_drum'] = 'drum Magazine', + ['component_clip_box'] = 'box Magazine', + ['component_flashlight'] = 'flashlight', + ['component_scope'] = 'scope', + ['component_scope_advanced'] = 'advanced Scope', + ['component_suppressor'] = 'suppressor', + ['component_grip'] = 'grip', + ['component_luxary_finish'] = 'luxary Weapon Finish', } diff --git a/locales/sv.lua b/locales/sv.lua index 6e76e4be..faa1f04c 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -160,4 +160,16 @@ Locales['sv'] = { ['gadget_parachute'] = 'fallskärm', ['weapon_flare'] = 'signalpistol', ['weapon_doubleaction'] = 'double-Action Revolver', -} \ No newline at end of file + + -- Weapon Components + ['component_clip_default'] = 'standard magg', + ['component_clip_extended'] = 'förlängd magg', + ['component_clip_drum'] = 'trummagasin', + ['component_clip_box'] = 'lådmagasin', + ['component_flashlight'] = 'ficklampa', + ['component_scope'] = 'sikte', + ['component_scope_advanced'] = 'advancerat sikte', + ['component_suppressor'] = 'ljuddämpare', + ['component_grip'] = 'handtag', + ['component_luxary_finish'] = 'lyxvapen behandling', +} From caec0579541fa760d7b7af3329da4f7081327cb0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 29 Dec 2018 02:10:37 +0100 Subject: [PATCH 278/672] Initial support for weapon components --- client/functions.lua | 15 ---------- client/main.lua | 62 +++++++++++++++++++++++++++++++-------- server/classes/player.lua | 57 +++++++++++++++++++++++------------ server/functions.lua | 15 ---------- shared/functions.lua | 31 +++++++++++++++++++- 5 files changed, 118 insertions(+), 62 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index a4f82218..0a12aa14 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -251,21 +251,6 @@ ESX.UI.ShowInventoryItemNotification = function(add, item, 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.GetPedMugshot = function(ped) local mugshot = RegisterPedheadshot(ped) while not IsPedheadshotReady(mugshot) do diff --git a/client/main.lua b/client/main.lua index 92d63cd9..47d8bc09 100644 --- a/client/main.lua +++ b/client/main.lua @@ -99,10 +99,19 @@ AddEventHandler('esx:restoreLoadout', function() RemoveAllPedWeapons(playerPed, true) for i=1, #ESX.PlayerData.loadout, 1 do - local weaponHash = GetHashKey(ESX.PlayerData.loadout[i].name) + local weaponName = ESX.PlayerData.loadout[i].name + local weaponHash = GetHashKey(weaponName) + GiveWeaponToPed(playerPed, weaponHash, 0, false, false) local ammoType = GetPedAmmoTypeFromWeapon(playerPed, weaponHash) + for j=1, #ESX.PlayerData.loadout[i].components, 1 do + local weaponComponent = ESX.PlayerData.loadout[i].components[j] + local componentHash = ESX.GetWeaponComponentHash(weaponName, weaponComponent) + + GiveWeaponComponentToPed(playerPed, weaponHash, componentHash) + end + if not ammoTypes[ammoType] then AddAmmoToPed(playerPed, weaponHash, ESX.PlayerData.loadout[i].ammo) ammoTypes[ammoType] = true @@ -179,6 +188,15 @@ AddEventHandler('esx:addWeapon', function(weaponName, ammo) --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.GetWeaponComponentHash(weaponName, weaponComponent) + + GiveWeaponComponentToPed(playerPed, weaponHash, componentHash) +end) + RegisterNetEvent('esx:removeWeapon') AddEventHandler('esx:removeWeapon', function(weaponName, ammo) local playerPed = PlayerPedId() @@ -187,7 +205,7 @@ AddEventHandler('esx:removeWeapon', function(weaponName, ammo) RemoveWeaponFromPed(playerPed, weaponHash) if ammo then - local pedAmmo = GetAmmoInPedWeapon(playerPed, weaponHash) + local pedAmmo = GetAmmoInPedWeapon(playerPed, weaponHash) local finalAmmo = math.floor(pedAmmo - ammo) SetPedAmmo(playerPed, weaponHash, finalAmmo) else @@ -195,6 +213,16 @@ AddEventHandler('esx:removeWeapon', function(weaponName, ammo) end end) + +RegisterNetEvent('esx:removeWeaponComponent') +AddEventHandler('esx:removeWeaponComponent', function(weaponName, weaponComponent) + local playerPed = PlayerPedId() + local weaponHash = GetHashKey(weaponName) + local componentHash = ESX.GetWeaponComponentHash(weaponName, weaponComponent) + + RemoveWeaponComponentFromPed(playerPed, weaponHash, componentHash) +end) + -- Commands RegisterNetEvent('esx:teleport') AddEventHandler('esx:teleport', function(pos) @@ -392,7 +420,7 @@ end Citizen.CreateThread(function() while true do - Citizen.Wait(500) + Citizen.Wait(5000) local playerPed = PlayerPedId() local loadout = {} @@ -404,28 +432,38 @@ Citizen.CreateThread(function() for i=1, #Config.Weapons, 1 do - local weaponHash = GetHashKey(Config.Weapons[i].name) + local weaponName = Config.Weapons[i].name + local weaponHash = GetHashKey(weaponName) + local weaponComponents = {} - if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + if HasPedGotWeapon(playerPed, weaponHash, false) and weaponName ~= 'WEAPON_UNARMED' then local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + local components = Config.Weapons[i].components - if LastLoadout[Config.Weapons[i].name] == nil or LastLoadout[Config.Weapons[i].name] ~= ammo then + for j=1, #components, 1 do + if HasPedGotWeaponComponent(playerPed, weaponHash, components[j].hash) then + table.insert(weaponComponents, components[j].name) + end + end + + if LastLoadout[weaponName] == nil or LastLoadout[weaponName] ~= ammo then loadoutChanged = true end - LastLoadout[Config.Weapons[i].name] = ammo + LastLoadout[weaponName] = ammo table.insert(loadout, { - name = Config.Weapons[i].name, - ammo = ammo, - label = Config.Weapons[i].label + name = weaponName, + ammo = ammo, + label = Config.Weapons[i].label, + components = weaponComponents }) else - if LastLoadout[Config.Weapons[i].name] ~= nil then + if LastLoadout[weaponName] ~= nil then loadoutChanged = true end - LastLoadout[Config.Weapons[i].name] = nil + LastLoadout[weaponName] = nil end end diff --git a/server/classes/player.lua b/server/classes/player.lua index ec0cf554..76d35e24 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -380,20 +380,14 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l 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 + local weaponLabel = ESX.GetWeaponLabel(weaponName) if not self.hasWeapon(weaponName) then table.insert(self.loadout, { - name = weaponName, - ammo = ammo, - label = weaponLabel + name = weaponName, + ammo = ammo, + label = weaponLabel, + components = {} }) end @@ -401,18 +395,20 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) end - self.removeWeapon = function(weaponName, ammo) - local weaponLabel = weaponName + self.addWeaponComponent = function(weaponName, weaponComponent) + local loadoutNum, weapon = self.getWeapon(weaponName) + table.insert(self.loadout[loadoutNum].components, weaponComponent) - for i=1, #Config.Weapons, 1 do - if Config.Weapons[i].name == weaponName then - weaponLabel = Config.Weapons[i].label - break - end - end + TriggerClientEvent('esx:addWeaponComponent', self.source, weaponName, weaponComponent) + end + + self.removeWeapon = function(weaponName, ammo) + local weaponLabel for i=1, #self.loadout, 1 do if self.loadout[i].name == weaponName then + weaponLabel = self.loadout[i].label + table.remove(self.loadout, i) break end @@ -422,6 +418,19 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) end + self.removeWeaponComponent = function(weaponName, weaponComponent) + local loadoutNum, weapon = self.getWeapon(weaponName) + + for i=1, #self.loadout[loadoutNum].components, 1 do + if self.loadout[loadoutNum].components.name == weaponComponent then + table.remove(self.loadout[loadoutNum].components, i) + break + end + end + + TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, weaponComponent) + end + self.hasWeapon = function(weaponName) for i=1, #self.loadout, 1 do if self.loadout[i].name == weaponName then @@ -432,5 +441,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return false end + self.getWeapon = function(weaponName) + for i=1, #self.loadout, 1 do + if self.loadout[i].name == weaponName then + return i, self.loadout[i] + end + end + + return nil + end + return self end diff --git a/server/functions.lua b/server/functions.lua index 3d682d5c..36da07c0 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -174,21 +174,6 @@ ESX.GetItemLabel = function(item) end 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.CreatePickup = function(type, name, count, label, player) local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) diff --git a/shared/functions.lua b/shared/functions.lua index 84f3ec3b..268d1d67 100644 --- a/shared/functions.lua +++ b/shared/functions.lua @@ -18,6 +18,36 @@ ESX.GetConfig = function() return Config end +ESX.GetWeaponList = function() + return Config.Weapons +end + +ESX.GetWeaponLabel = function(weaponName) + weaponName = string.upper(weaponName) + local weapons = ESX.GetWeaponList() + + for i=1, #weapons, 1 do + if weapons[i].name == weaponName then + return weapons[i].label + end + end +end + +ESX.GetWeaponComponentHash = function(weaponName, weaponComponent) + weaponName = string.upper(weaponName) + local weapons = ESX.GetWeaponList() + + for i=1, #weapons, 1 do + if weapons[i].name == weaponName then + for j=1, #weapons[i].components, 1 do + if weapons[i].components[j].name == weaponComponent then + return weapons[i].components[j].hash + end + end + end + end +end + ESX.TableContainsValue = function(table, value) for k, v in pairs(table) do if v == value then @@ -58,7 +88,6 @@ ESX.DumpTable = function(table, nb) end end - ESX.Round = function(value, numDecimalPlaces) return ESX.Math.Round(value, numDecimalPlaces) end From e0f9358b22a059d3140aeb4b525b9c5787771fae Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 29 Dec 2018 13:47:01 +0100 Subject: [PATCH 279/672] Only add weapon component once, check if player has weapon --- client/main.lua | 6 +++--- server/classes/player.lua | 31 +++++++++++++++++++++++++++++-- shared/functions.lua | 4 ++-- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/client/main.lua b/client/main.lua index 47d8bc09..77ccec35 100644 --- a/client/main.lua +++ b/client/main.lua @@ -107,7 +107,7 @@ AddEventHandler('esx:restoreLoadout', function() for j=1, #ESX.PlayerData.loadout[i].components, 1 do local weaponComponent = ESX.PlayerData.loadout[i].components[j] - local componentHash = ESX.GetWeaponComponentHash(weaponName, weaponComponent) + local componentHash = ESX.GetWeaponComponent(weaponName, weaponComponent).hash GiveWeaponComponentToPed(playerPed, weaponHash, componentHash) end @@ -192,7 +192,7 @@ RegisterNetEvent('esx:addWeaponComponent') AddEventHandler('esx:addWeaponComponent', function(weaponName, weaponComponent) local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) - local componentHash = ESX.GetWeaponComponentHash(weaponName, weaponComponent) + local componentHash = ESX.GetWeaponComponent(weaponName, weaponComponent).hash GiveWeaponComponentToPed(playerPed, weaponHash, componentHash) end) @@ -218,7 +218,7 @@ RegisterNetEvent('esx:removeWeaponComponent') AddEventHandler('esx:removeWeaponComponent', function(weaponName, weaponComponent) local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) - local componentHash = ESX.GetWeaponComponentHash(weaponName, weaponComponent) + local componentHash = ESX.GetWeaponComponent(weaponName, weaponComponent).hash RemoveWeaponComponentFromPed(playerPed, weaponHash, componentHash) end) diff --git a/server/classes/player.lua b/server/classes/player.lua index 76d35e24..32e4ac74 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -397,6 +397,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.addWeaponComponent = function(weaponName, weaponComponent) local loadoutNum, weapon = self.getWeapon(weaponName) + + if self.hasWeaponComponent(weaponName, weaponComponent) then + return + end + table.insert(self.loadout[loadoutNum].components, weaponComponent) TriggerClientEvent('esx:addWeaponComponent', self.source, weaponName, weaponComponent) @@ -414,12 +419,18 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end - TriggerClientEvent('esx:removeWeapon', self.source, weaponName, ammo) - TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) + if weaponLabel then + TriggerClientEvent('esx:removeWeapon', self.source, weaponName, ammo) + TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) + end end self.removeWeaponComponent = function(weaponName, weaponComponent) local loadoutNum, weapon = self.getWeapon(weaponName) + + if not weapon then + return + end for i=1, #self.loadout[loadoutNum].components, 1 do if self.loadout[loadoutNum].components.name == weaponComponent then @@ -431,6 +442,22 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, weaponComponent) end + self.hasWeaponComponent = function(weaponName, weaponComponent) + local loadoutNum, weapon = self.getWeapon(weaponName) + + if not weapon then + return false + end + + for i=1, #weapon.components, 1 do + if weapon.components[i] == weaponComponent then + return true + end + end + + return false + end + self.hasWeapon = function(weaponName) for i=1, #self.loadout, 1 do if self.loadout[i].name == weaponName then diff --git a/shared/functions.lua b/shared/functions.lua index 268d1d67..ba6ab61b 100644 --- a/shared/functions.lua +++ b/shared/functions.lua @@ -33,7 +33,7 @@ ESX.GetWeaponLabel = function(weaponName) end end -ESX.GetWeaponComponentHash = function(weaponName, weaponComponent) +ESX.GetWeaponComponent = function(weaponName, weaponComponent) weaponName = string.upper(weaponName) local weapons = ESX.GetWeaponList() @@ -41,7 +41,7 @@ ESX.GetWeaponComponentHash = function(weaponName, weaponComponent) if weapons[i].name == weaponName then for j=1, #weapons[i].components, 1 do if weapons[i].components[j].name == weaponComponent then - return weapons[i].components[j].hash + return weapons[i].components[j] end end end From e6f07a6f805d99b9da315b805ef88377bdcaefdd Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 29 Dec 2018 13:48:41 +0100 Subject: [PATCH 280/672] Respect sv_maxclients --- config.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/config.lua b/config.lua index 2efac3de..27e32bb9 100644 --- a/config.lua +++ b/config.lua @@ -1,15 +1,15 @@ -Config = {} -Config.Locale = 'fr' +Config = {} +Config.Locale = 'fr' -Config.Accounts = { 'bank', 'black_money' } -Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } +Config.Accounts = { 'bank', 'black_money' } +Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } -Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society -Config.ShowDotAbovePlayer = false -Config.DisableWantedLevel = true -Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) +Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society +Config.ShowDotAbovePlayer = false +Config.DisableWantedLevel = true +Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) -Config.PaycheckInterval = 7 * 60000 -Config.MaxPlayers = 32 +Config.PaycheckInterval = 7 * 60000 +Config.MaxPlayers = GetConvarInt('sv_maxclients', 32) -Config.EnableDebug = false +Config.EnableDebug = false From 4279cc03f7424fd48142cc865f372cb1afb3c21b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 29 Dec 2018 14:07:04 +0100 Subject: [PATCH 281/672] added /clearinventory /clearloadout --- locales/br.lua | 5 +++++ locales/cs.lua | 5 +++++ locales/de.lua | 5 +++++ locales/en.lua | 17 +++++++++------ locales/fi.lua | 5 +++++ locales/fr.lua | 5 +++++ locales/pl.lua | 5 +++++ locales/sv.lua | 5 +++++ server/commands.lua | 51 ++++++++++++++++++++++++++++++++++++++++++--- 9 files changed, 94 insertions(+), 9 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index e19797f8..9ef7555e 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -46,6 +46,7 @@ Locales['br'] = { ['act_imp'] = 'acao impossivel', ['in_vehicle'] = 'voce nao pode dar nada para alguem no veiculo', ['cannot_pickup_room'] = 'voce nao tem espaço suficiente no seu inventario para pegar ~y~%s~s~!', + -- Commands ['setjob'] = 'atribuir um trabalho a um usuario', ['id_param'] = 'o ID do jogador', @@ -77,9 +78,13 @@ Locales['br'] = { ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', + ['command_clearinventory'] = 'clear all items from inventory', + ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', + -- Weapons ['weapon_knife'] = 'faca', ['weapon_nightstick'] = 'cacetete', diff --git a/locales/cs.lua b/locales/cs.lua index eacd5cae..0b3b3e07 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -46,6 +46,7 @@ Locales['cs'] = { ['act_imp'] = 'akce není možná', ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', ['cannot_pickup_room'] = 've vašem inventáři není dostatek místa pro ~y~%s~s~!', + -- Commands ['setjob'] = 'přiřadit práci hráči', ['id_param'] = 'iD hráče', @@ -77,9 +78,13 @@ Locales['cs'] = { ['disconnect'] = 'odpojit od serveru', ['chat_clear'] = 'vyčistit chat', ['chat_clear_all'] = 'vyčistit chat pro všechny', + ['command_clearinventory'] = 'clear all items from inventory', + ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', + -- Weapons ['weapon_knife'] = 'knife', ['weapon_nightstick'] = 'nightstick', diff --git a/locales/de.lua b/locales/de.lua index 5bc6fd29..1aa9b2ed 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -46,6 +46,7 @@ Locales['de'] = { ['act_imp'] = 'Aktion nicht möglich', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', + -- Commands ['setjob'] = 'assign a job to a user', ['id_param'] = 'the ID of the player', @@ -77,9 +78,13 @@ Locales['de'] = { ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', + ['command_clearinventory'] = 'clear all items from inventory', + ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', + -- Weapons ['weapon_knife'] = 'Messer', ['weapon_nightstick'] = 'Schlagstock', diff --git a/locales/en.lua b/locales/en.lua index 996b1976..1ccf6f37 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -46,6 +46,7 @@ Locales['en'] = { ['act_imp'] = 'action impossible', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', + -- Commands ['setjob'] = 'assign a job to a user', ['id_param'] = 'the ID of the player', @@ -77,9 +78,13 @@ Locales['en'] = { ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', + ['command_clearinventory'] = 'clear all items from inventory', + ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ',', ['locale_currency'] = '$%s', + -- Weapons ['weapon_knife'] = 'knife', ['weapon_nightstick'] = 'nightstick', @@ -89,16 +94,16 @@ Locales['en'] = { ['weapon_crowbar'] = 'crow bar', ['weapon_pistol'] = 'pistol', ['weapon_combatpistol'] = 'combat pistol', - ['weapon_appistol'] = 'ap pistol', + ['weapon_appistol'] = 'AP pistol', ['weapon_pistol50'] = 'pistol .50', - ['weapon_microsmg'] = 'micro smg', - ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'assault smg', + ['weapon_microsmg'] = 'micro SMG', + ['weapon_smg'] = 'SMG', + ['weapon_assaultsmg'] = 'assault SMG', ['weapon_assaultrifle'] = 'assault rifle', ['weapon_carbinerifle'] = 'carbine rifle', ['weapon_advancedrifle'] = 'advanced rifle', - ['weapon_mg'] = 'mg', - ['weapon_combatmg'] = 'combat mg', + ['weapon_mg'] = 'MG', + ['weapon_combatmg'] = 'combat MG', ['weapon_pumpshotgun'] = 'pump shotgun', ['weapon_sawnoffshotgun'] = 'sawed off shotgun', ['weapon_assaultshotgun'] = 'assault shotgun', diff --git a/locales/fi.lua b/locales/fi.lua index 255d6dd9..08adfa48 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -46,6 +46,7 @@ Locales['fi'] = { ['act_imp'] = 'toiminto mahdoton', ['in_vehicle'] = 'et voi antaa ajoneuvossa olevalle mitään.', ['cannot_pickup_room'] = 'sinulla ei ole tilaa repussa nostaaksesi ~y~%s~s~!', + -- Commands ['setjob'] = 'määritä työ käyttäjälle', ['id_param'] = 'käyttäjän ID', @@ -77,9 +78,13 @@ Locales['fi'] = { ['disconnect'] = 'poistu serveriltä', ['chat_clear'] = 'tyhjennä chatti', ['chat_clear_all'] = 'tyhjennä chatti kaikilta', + ['command_clearinventory'] = 'clear all items from inventory', + ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', + -- Weapons ['weapon_knife'] = 'veitsi', ['weapon_nightstick'] = 'pamppu', diff --git a/locales/fr.lua b/locales/fr.lua index 2af83b00..b49d9cb5 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -46,6 +46,7 @@ Locales['fr'] = { ['act_imp'] = 'action impossible', ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', ['cannot_pickup_room'] = 'vous n\'avez plus de place pour ~y~%s~s~!', + -- Commands ['setjob'] = 'assigner job', ['id_param'] = 'identification du joueur', @@ -77,9 +78,13 @@ Locales['fr'] = { ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', + ['command_clearinventory'] = 'clear all items from inventory', + ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', + -- Weapons ['weapon_knife'] = 'couteau', ['weapon_nightstick'] = 'matraque', diff --git a/locales/pl.lua b/locales/pl.lua index 8d925fd2..c898ca26 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -46,6 +46,7 @@ Locales['pl'] = { ['act_imp'] = 'działanie niemożliwe', ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', ['cannot_pickup_room'] = 'nie masz wystarczająco dużo miejsca w ekwipunku, aby podnieść ~y~%s~s~!', + -- Commands ['setjob'] = 'przydziel prace użytkownikowi', ['id_param'] = 'iD użyszkodnika', @@ -77,9 +78,13 @@ Locales['pl'] = { ['disconnect'] = 'odłącz się od serwera', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', + ['command_clearinventory'] = 'clear all items from inventory', + ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', + -- Weapons ['weapon_knife'] = 'nóż', ['weapon_nightstick'] = 'pałka', diff --git a/locales/sv.lua b/locales/sv.lua index faa1f04c..647dd50b 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -46,6 +46,7 @@ Locales['sv'] = { ['act_imp'] = 'åtgärd omöjlig', ['in_vehicle'] = 'du kan inte ge saker till en som sitter i ett fordon!', ['cannot_pickup_room'] = 'du har inte plats för att plocka upp ~y~%s~s~!', + -- Commands ['setjob'] = 'tilldela ett jobb till en användare', ['id_param'] = 'spelarens ID', @@ -77,9 +78,13 @@ Locales['sv'] = { ['disconnect'] = 'koppla från servern', ['chat_clear'] = 'töm chatten', ['chat_clear_all'] = 'töm chatten för alla', + ['command_clearinventory'] = 'clear all items from inventory', + ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '%s SEK', + -- Weapons ['weapon_knife'] = 'kniv', ['weapon_nightstick'] = 'batong', diff --git a/server/commands.lua b/server/commands.lua index 3de2797e..0b585460 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -19,13 +19,14 @@ end, {help = "Teleport to coordinates", params = {{name = "x", help = "X coords" TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) if tonumber(args[1]) and args[2] and tonumber(args[3]) then local xPlayer = ESX.GetPlayerFromId(args[1]) - if xPlayer ~= nil then + + if xPlayer then xPlayer.setJob(args[2], tonumber(args[3])) else - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Player not online.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end else - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Invalid usage.") + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid usage.' } }) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) @@ -200,3 +201,47 @@ TriggerEvent('es:addGroupCommand', 'clearall', 'admin', function(source, args, u end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('chat_clear_all')}) + +TriggerEvent('es:addGroupCommand', 'clearinventory', 'admin', function(source, args, user) + local xPlayer + + if args[1] then + xPlayer = ESX.GetPlayerFromId(args[1]) + else + xPlayer = ESX.GetPlayerFromId(source) + end + + if not xPlayer then + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) + return + end + + for i=1, #xPlayer.inventory, 1 do + if xPlayer.inventory[i].count > 0 then + xPlayer.setInventoryItem(xPlayer.inventory[i].name, 0) + end + end +end, function(source, args, user) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) +end, {help = _U('command_clearinventory'), params = {{name = "playerId", help = _U('command_playerid_param')}}}) + +TriggerEvent('es:addGroupCommand', 'clearloadout', 'admin', function(source, args, user) + local xPlayer + + if args[1] then + xPlayer = ESX.GetPlayerFromId(args[1]) + else + xPlayer = ESX.GetPlayerFromId(source) + end + + if not xPlayer then + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) + return + end + + for i=1, #xPlayer.loadout, 1 do + xPlayer.removeWeapon(xPlayer.loadout[i].name) + end +end, function(source, args, user) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) +end, {help = _U('command_clearloadout'), params = {{name = "playerId", help = _U('command_playerid_param')}}}) From 0a374bd83184dfc89c68235327c644ad966784b5 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 29 Dec 2018 14:22:16 +0100 Subject: [PATCH 282/672] Use saved nearbyPlayer variable, see #181 --- client/functions.lua | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 0a12aa14..54969ba3 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1101,7 +1101,7 @@ ESX.ShowInventory = function() table.insert(elements, { label = GetPlayerName(players[i]), - value = players[i] + player = players[i] }) end end @@ -1120,13 +1120,14 @@ ESX.ShowInventory = function() elements = elements }, function(data2, menu2) - players = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) + local players, nearbyPlayer = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) for i=1, #players, 1 do if players[i] ~= PlayerId() then - if players[i] == data2.current.value then + if players[i] == data2.current.player then foundPlayers = true + nearbyPlayer = players[i] break end end @@ -1140,8 +1141,7 @@ ESX.ShowInventory = function() if type == 'item_weapon' then - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - local closestPed = GetPlayerPed(closestPlayer) + local closestPed = GetPlayerPed(nearbyPlayer) local sourceAmmo = GetAmmoInPedWeapon(PlayerPedId(), GetHashKey(item)) if IsPedSittingInAnyVehicle(closestPed) then @@ -1149,45 +1149,31 @@ ESX.ShowInventory = function() return end - if closestPlayer ~= -1 and closestDistance < 3.0 then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, sourceAmmo) - menu2.close() - menu1.close() - else - ESX.ShowNotification(_U('players_nearby')) - end + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, sourceAmmo) + menu2.close() + menu1.close() - else -- type: item_standard + else ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { title = _U('amount') }, function(data3, menu3) local quantity = tonumber(data3.value) - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - local closestPed = GetPlayerPed(closestPlayer) + local closestPed = GetPlayerPed(nearbyPlayer) if IsPedSittingInAnyVehicle(closestPed) then ESX.ShowNotification(_U('in_vehicle')) return end - if closestPlayer ~= -1 and closestDistance < 3.0 then - if quantity ~= nil then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), type, item, quantity) - - menu3.close() - menu2.close() - menu1.close() - else - ESX.ShowNotification(_U('amount_invalid')) - end - - else - ESX.ShowNotification(_U('players_nearby')) + if quantity ~= nil then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, quantity) menu3.close() menu2.close() menu1.close() + else + ESX.ShowNotification(_U('amount_invalid')) end end, function(data3, menu3) From 6c32c9ede0e03a88a6c81780ed4556a0844fd139 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 29 Dec 2018 14:47:29 +0100 Subject: [PATCH 283/672] Fixed bank money being droppable --- client/functions.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index 54969ba3..81a449d3 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1002,6 +1002,7 @@ ESX.ShowInventory = function() for i=1, #ESX.PlayerData.accounts, 1 do if ESX.PlayerData.accounts[i].money > 0 then local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(ESX.PlayerData.accounts[i].money)) + local canDrop = ESX.PlayerData.accounts[i].name ~= 'bank' table.insert(elements, { label = ('%s: %s'):format(ESX.PlayerData.accounts[i].label, formattedMoney), @@ -1010,7 +1011,7 @@ ESX.ShowInventory = function() value = ESX.PlayerData.accounts[i].name, usable = false, rare = false, - canRemove = true + canRemove = canDrop }) end end From c95ac3b87faaea43eeaab52fee80b172fe59a8a7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 30 Dec 2018 20:57:42 +0100 Subject: [PATCH 284/672] Run menu check and anti-wanted every frame --- __resource.lua | 2 +- client/main.lua | 4 ++-- client/modules/blip.lua | 25 +++++++++++++++++++++++++ client/modules/scaleform.lua | 4 ++-- config.lua | 2 +- 5 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 client/modules/blip.lua diff --git a/__resource.lua b/__resource.lua index a6a15dc6..be77bcc9 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.14' +version '1.1.0' server_scripts { '@async/async.lua', diff --git a/client/main.lua b/client/main.lua index 77ccec35..a899bced 100644 --- a/client/main.lua +++ b/client/main.lua @@ -480,7 +480,7 @@ end) Citizen.CreateThread(function() while true do - Citizen.Wait(10) + Citizen.Wait(0) if IsControlJustReleased(0, Keys['F2']) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() @@ -515,7 +515,7 @@ if Config.DisableWantedLevel then Citizen.CreateThread(function() while true do - Citizen.Wait(10) + Citizen.Wait(0) local playerId = PlayerId() if GetPlayerWantedLevel(playerId) ~= 0 then diff --git a/client/modules/blip.lua b/client/modules/blip.lua new file mode 100644 index 00000000..22297a5e --- /dev/null +++ b/client/modules/blip.lua @@ -0,0 +1,25 @@ +ESX.Blip.CreateBlip = function(coords, text, sprite, color, scale, display) + local blip = AddBlipForCoord( table.unpack(coords) ) + + SetBlipSprite(blip, sprite) + + if display then + SetBlipDisplay(blip, display) + end + + if scale then + SetBlipScale(blip, scale) + end + + if color then + SetBlipColour(blip, color) + end + + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(text) + EndTextCommandSetBlipName(blip) + + return blip +end \ No newline at end of file diff --git a/client/modules/scaleform.lua b/client/modules/scaleform.lua index 20a9c6e8..33d32860 100644 --- a/client/modules/scaleform.lua +++ b/client/modules/scaleform.lua @@ -47,7 +47,7 @@ ESX.Scaleform.ShowBreakingNews = function(title, msg, bottom, sec) SetScaleformMovieAsNoLongerNeeded(scaleform) end -ESX.Scaleform.ShowPopupWarning = function(title, msg, bottom, sec) +ESX.Scaleform.ShowPopupWarning = function(title, msg, footer, sec) local scaleform = ESX.Scaleform.Utils.RequestScaleformMovie('POPUP_WARNING') BeginScaleformMovieMethod(scaleform, 'SHOW_POPUP_WARNING') @@ -55,7 +55,7 @@ ESX.Scaleform.ShowPopupWarning = function(title, msg, bottom, sec) PushScaleformMovieMethodParameterFloat(500.0) -- black background PushScaleformMovieMethodParameterString(title) PushScaleformMovieMethodParameterString(msg) - PushScaleformMovieMethodParameterString(bottom) + PushScaleformMovieMethodParameterString(footer) PushScaleformMovieMethodParameterBool(true) EndScaleformMovieMethod() diff --git a/config.lua b/config.lua index 27e32bb9..46e53930 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,5 @@ Config = {} -Config.Locale = 'fr' +Config.Locale = 'sv' Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } From ccc36f388bd0a7b7ef63a87083a4750a75f296ca Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 30 Dec 2018 21:41:59 +0100 Subject: [PATCH 285/672] Revert "Run menu check and anti-wanted every frame" This reverts commit c95ac3b87faaea43eeaab52fee80b172fe59a8a7. --- __resource.lua | 2 +- client/main.lua | 4 ++-- client/modules/blip.lua | 25 ------------------------- client/modules/scaleform.lua | 4 ++-- config.lua | 2 +- 5 files changed, 6 insertions(+), 31 deletions(-) delete mode 100644 client/modules/blip.lua diff --git a/__resource.lua b/__resource.lua index be77bcc9..a6a15dc6 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.1.0' +version '1.0.14' server_scripts { '@async/async.lua', diff --git a/client/main.lua b/client/main.lua index a899bced..77ccec35 100644 --- a/client/main.lua +++ b/client/main.lua @@ -480,7 +480,7 @@ end) Citizen.CreateThread(function() while true do - Citizen.Wait(0) + Citizen.Wait(10) if IsControlJustReleased(0, Keys['F2']) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() @@ -515,7 +515,7 @@ if Config.DisableWantedLevel then Citizen.CreateThread(function() while true do - Citizen.Wait(0) + Citizen.Wait(10) local playerId = PlayerId() if GetPlayerWantedLevel(playerId) ~= 0 then diff --git a/client/modules/blip.lua b/client/modules/blip.lua deleted file mode 100644 index 22297a5e..00000000 --- a/client/modules/blip.lua +++ /dev/null @@ -1,25 +0,0 @@ -ESX.Blip.CreateBlip = function(coords, text, sprite, color, scale, display) - local blip = AddBlipForCoord( table.unpack(coords) ) - - SetBlipSprite(blip, sprite) - - if display then - SetBlipDisplay(blip, display) - end - - if scale then - SetBlipScale(blip, scale) - end - - if color then - SetBlipColour(blip, color) - end - - SetBlipAsShortRange(blip, true) - - BeginTextCommandSetBlipName('STRING') - AddTextComponentSubstringPlayerName(text) - EndTextCommandSetBlipName(blip) - - return blip -end \ No newline at end of file diff --git a/client/modules/scaleform.lua b/client/modules/scaleform.lua index 33d32860..20a9c6e8 100644 --- a/client/modules/scaleform.lua +++ b/client/modules/scaleform.lua @@ -47,7 +47,7 @@ ESX.Scaleform.ShowBreakingNews = function(title, msg, bottom, sec) SetScaleformMovieAsNoLongerNeeded(scaleform) end -ESX.Scaleform.ShowPopupWarning = function(title, msg, footer, sec) +ESX.Scaleform.ShowPopupWarning = function(title, msg, bottom, sec) local scaleform = ESX.Scaleform.Utils.RequestScaleformMovie('POPUP_WARNING') BeginScaleformMovieMethod(scaleform, 'SHOW_POPUP_WARNING') @@ -55,7 +55,7 @@ ESX.Scaleform.ShowPopupWarning = function(title, msg, footer, sec) PushScaleformMovieMethodParameterFloat(500.0) -- black background PushScaleformMovieMethodParameterString(title) PushScaleformMovieMethodParameterString(msg) - PushScaleformMovieMethodParameterString(footer) + PushScaleformMovieMethodParameterString(bottom) PushScaleformMovieMethodParameterBool(true) EndScaleformMovieMethod() diff --git a/config.lua b/config.lua index 46e53930..27e32bb9 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,5 @@ Config = {} -Config.Locale = 'sv' +Config.Locale = 'fr' Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } From dc44b7c66779f625657ba5dd9313a39bffaaee18 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 30 Dec 2018 21:43:15 +0100 Subject: [PATCH 286/672] Run menu check and anti-wanted every frame --- client/main.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index 77ccec35..a899bced 100644 --- a/client/main.lua +++ b/client/main.lua @@ -480,7 +480,7 @@ end) Citizen.CreateThread(function() while true do - Citizen.Wait(10) + Citizen.Wait(0) if IsControlJustReleased(0, Keys['F2']) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() @@ -515,7 +515,7 @@ if Config.DisableWantedLevel then Citizen.CreateThread(function() while true do - Citizen.Wait(10) + Citizen.Wait(0) local playerId = PlayerId() if GetPlayerWantedLevel(playerId) ~= 0 then From 22a4d67971e3e0ed79d446cf37929cc8e28ff79b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 31 Dec 2018 14:11:05 +0100 Subject: [PATCH 287/672] Fix new player error on first spawn --- client/main.lua | 6 ++---- es_extended.sql | 4 ++-- server/classes/player.lua | 8 +++++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/client/main.lua b/client/main.lua index a899bced..74dd7f76 100644 --- a/client/main.lua +++ b/client/main.lua @@ -568,18 +568,16 @@ end) -- Last position Citizen.CreateThread(function() while true do - Citizen.Wait(1000) - if ESX ~= nil and ESX.PlayerLoaded and PlayerSpawned then + if ESX.PlayerLoaded and PlayerSpawned then local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) if not IsEntityDead(playerPed) then - ESX.PlayerData.lastPosition = {x = ESX.Math.Round(coords.x, 2), y = ESX.Math.Round(coords.y, 2), z = ESX.Math.Round(coords.z, 2)} + ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} end end - end end) diff --git a/es_extended.sql b/es_extended.sql index 0b51e267..6ea1ce6f 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,12 +1,12 @@ USE `essentialmode`; ALTER TABLE `users` - ADD COLUMN `name` VARCHAR(255) NULL DEFAULT '' AFTER `money`, + ADD COLUMN `name` VARCHAR(50) NULL DEFAULT '' AFTER `money`, ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, ADD COLUMN `job` varchar(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(50) NULL AFTER `loadout` + ADD COLUMN `position` VARCHAR(36) NULL AFTER `loadout` ; CREATE TABLE `items` ( diff --git a/server/classes/player.lua b/server/classes/player.lua index 32e4ac74..1ced96d6 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -199,9 +199,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.getLastPosition = function() - self.lastPosition.x = ESX.Math.Round(self.lastPosition.x, 2) - self.lastPosition.y = ESX.Math.Round(self.lastPosition.y, 2) - self.lastPosition.z = ESX.Math.Round(self.lastPosition.z, 2) + if self.lastPosition then + self.lastPosition.x = ESX.Math.Round(self.lastPosition.x, 1) + self.lastPosition.y = ESX.Math.Round(self.lastPosition.y, 1) + self.lastPosition.z = ESX.Math.Round(self.lastPosition.z, 1) + end return self.lastPosition end From 7152867a4174990d05bc323b6f3044955a4f3ee9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 31 Dec 2018 14:13:24 +0100 Subject: [PATCH 288/672] Final commit v1.1.0 --- __resource.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__resource.lua b/__resource.lua index a6a15dc6..be77bcc9 100644 --- a/__resource.lua +++ b/__resource.lua @@ -2,7 +2,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' description 'ES Extended' -version '1.0.14' +version '1.1.0' server_scripts { '@async/async.lua', From b1d58d2abd6bf5db013f0a4059522309014b2503 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 1 Jan 2019 11:03:02 +0100 Subject: [PATCH 289/672] Removed some never used streaming helpers --- client/modules/streaming.lua | 28 ---------------------------- server/classes/player.lua | 2 +- 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/client/modules/streaming.lua b/client/modules/streaming.lua index 0c278f82..143d0c0c 100644 --- a/client/modules/streaming.lua +++ b/client/modules/streaming.lua @@ -28,20 +28,6 @@ function ESX.Streaming.RequestStreamedTextureDict(textureDict, cb) end end -function ESX.Streaming.RequestPtfxAsset(assetName, cb) - if not HasPtfxAssetLoaded(assetName) then - RequestPtfxAsset(assetName) - - while not HasPtfxAssetLoaded(assetName) do - Citizen.Wait(1) - end - end - - if cb ~= nil then - cb() - end -end - function ESX.Streaming.RequestNamedPtfxAsset(assetName, cb) if not HasNamedPtfxAssetLoaded(assetName) then RequestNamedPtfxAsset(assetName) @@ -97,17 +83,3 @@ function ESX.Streaming.RequestWeaponAsset(weaponHash, cb) cb() end end - -function ESX.Streaming.RequestClipSet(clipSet, cb) - if not HasClipSetLoaded(clipSet) then - RequestClipSet(clipSet) - - while not HasClipSetLoaded(clipSet) do - Citizen.Wait(1) - end - end - - if cb ~= nil then - cb() - end -end \ No newline at end of file diff --git a/server/classes/player.lua b/server/classes/player.lua index 1ced96d6..15f2b57a 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -429,7 +429,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.removeWeaponComponent = function(weaponName, weaponComponent) local loadoutNum, weapon = self.getWeapon(weaponName) - + if not weapon then return end From ac4e9c9a827c20112557eecb50178241ad5594b3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 1 Jan 2019 11:05:06 +0100 Subject: [PATCH 290/672] Renamed shared folder to common --- README.md | 2 +- __resource.lua | 11 ++++++----- {shared => common}/functions.lua | 0 {shared => common}/modules/math.lua | 0 4 files changed, 7 insertions(+), 6 deletions(-) rename {shared => common}/functions.lua (100%) rename {shared => common}/modules/math.lua (100%) diff --git a/README.md b/README.md index 4aa706cc..3c1d49ea 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ es_extended is a roleplay framework for FiveM. It is developed on top of [EssentialMode](https://essentialmode.com/) (aka ES), thus commonly named ESX - the **Es**sentialMode E**x**tended framework for FiveM. ### Links & Read more -- [ESX Documentation](https://esx-org.github.io/) (incomplete) +- [ESX Documentation](https://esx-org.github.io/) - [ES Documentation](https://docs.essentialmode.com/) - [ESX Discord Community](https://discord.gg/MsWzPqE) - [FiveM Forum Thread](https://forum.fivem.net/t/release-esx-base/39881) diff --git a/__resource.lua b/__resource.lua index be77bcc9..cfa44c60 100644 --- a/__resource.lua +++ b/__resource.lua @@ -28,8 +28,8 @@ server_scripts { 'server/main.lua', 'server/commands.lua', - 'shared/modules/math.lua', - 'shared/functions.lua' + 'common/modules/math.lua', + 'common/functions.lua' } client_scripts { @@ -56,8 +56,8 @@ client_scripts { 'client/modules/scaleform.lua', 'client/modules/streaming.lua', - 'shared/modules/math.lua', - 'shared/functions.lua' + 'common/modules/math.lua', + 'common/functions.lua' } ui_page { @@ -90,7 +90,8 @@ server_exports { } dependencies { - 'essentialmode', 'mysql-async', + 'essentialmode', + 'esplugin_mysql', 'async' } diff --git a/shared/functions.lua b/common/functions.lua similarity index 100% rename from shared/functions.lua rename to common/functions.lua diff --git a/shared/modules/math.lua b/common/modules/math.lua similarity index 100% rename from shared/modules/math.lua rename to common/modules/math.lua From 452243e8c2ca997f22537f095347052b455a47e2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 1 Jan 2019 16:18:59 +0100 Subject: [PATCH 291/672] Added GetWeapon function --- common/functions.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/common/functions.lua b/common/functions.lua index ba6ab61b..755ae468 100644 --- a/common/functions.lua +++ b/common/functions.lua @@ -18,6 +18,17 @@ ESX.GetConfig = function() return Config end +ESX.GetWeapon = function(weaponName) + weaponName = string.upper(weaponName) + local weapons = ESX.GetWeaponList() + + for i=1, #weapons, 1 do + if weapons[i].name == weaponName then + return i, weapons[i] + end + end +end + ESX.GetWeaponList = function() return Config.Weapons end From 5e35663c95135c5980abe9f2daa8de2d95eeac36 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 1 Jan 2019 18:34:13 +0100 Subject: [PATCH 292/672] Fixed mod liveries, thanks to Chubbs --- client/functions.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index 81a449d3..1e25e11b 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -703,7 +703,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) modTrimB = GetVehicleMod(vehicle, 44), modTank = GetVehicleMod(vehicle, 45), modWindows = GetVehicleMod(vehicle, 46), - modLivery = GetVehicleMod(vehicle, 48) + modLivery = GetVehicleLivery(vehicle) } end @@ -947,6 +947,7 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) if props.modLivery ~= nil then SetVehicleMod(vehicle, 48, props.modLivery, false) + SetVehicleLivery(vehicle, props.modLivery) end end From 16e5177d085bd2c67240ff1c79e39f176d9f55f3 Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Wed, 2 Jan 2019 11:33:20 +0100 Subject: [PATCH 293/672] Update fr.lua little update, some fixes and a better translation --- locales/fr.lua | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index b49d9cb5..ed73dc12 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -13,12 +13,12 @@ Locales['fr'] = { ['noammo'] = 'tu n\'as pas toutes ces munitions!', ['gave_item'] = 'vous avez donné ~y~%sx~s~ ~b~%s~s~ à ~y~%s~s~', ['received_item'] = 'vous avez reçu ~y~%sx~s~ ~b~%s~s~ par ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', - ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', + ['gave_weapon'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ à ~y~%s~s~.', + ['gave_weapon_ammo'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles à ~y~%s~s~.', + ['gave_weapon_hasalready'] = '~y~%s~s~ a déjà ~y~%s~s~', + ['received_weapon'] = 'vous recevez ~y~1x~s~ ~b~%s~s~ de ~b~%s~s~.', + ['received_weapon_ammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles de ~b~%s~s~.', + ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire.', ['gave_ammo'] = 'vous donnez ~o~%sx~s~ munitions à ~y~%s~s~.', ['received_ammo'] = 'vous recevez ~o~%sx~s~ munitions de ~b~%s~s~.', ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', @@ -30,18 +30,18 @@ Locales['fr'] = { ['ex_inv_lim'] = 'action impossible, depassement de la limite d\'inventaire pour ~y~%s~s~', ['imp_invalid_quantity'] = 'action impossible, ~r~quantité invalide', ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', - ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_standard'] = 'vous avez jeté ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'vous avez jeté ~r~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'vous avez jeté ~r~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~', + ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles', -- Salary related ['received_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', ['received_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', ['company_nomoney'] = 'votre entreprise n\'a plus d\'argent pour vous payer!', ['received_paycheck'] = 'paiement reçu', ['bank'] = 'banque', - ['black_money'] = 'argent Sale', + ['black_money'] = 'argent sale', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', @@ -63,22 +63,22 @@ Locales['fr'] = { ['spawn_ped'] = 'spawn ped', ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'donner de l\'argent', - ['setmoney'] = 'set money for a player', - ['money_type'] = 'valid money types: cash, bank, black', - ['money_set'] = 'someone ~y~highly ranked~s~ just set ~g~$%s~s~ (%s) for you!', + ['setmoney'] = 'définir l\'argent pour un joueur', + ['money_type'] = 'types de monnaies valides: cash, bank, black', + ['money_set'] = 'quelqu\'un de ~y~haut placé~s~ vous a attribué ~g~$%s~s~ (%s) !', ['money_amount'] = 'somme d\'argent', - ['invalid_account'] = 'compete invalide', + ['invalid_account'] = 'compte invalide', ['account'] = 'compte', ['giveaccountmoney'] = 'donner de l\'argent au compte', ['invalid_item'] = 'item invalide', ['item'] = 'article', ['giveitem'] = 'donner un article', ['weapon'] = 'arme', - ['giveweapon'] = 'donner de l\'arme', - ['disconnect'] = 'disconnect from the server', - ['chat_clear'] = 'clear the chat', - ['chat_clear_all'] = 'clear the chat for everyone', - ['command_clearinventory'] = 'clear all items from inventory', + ['giveweapon'] = 'donner l\'arme', + ['disconnect'] = 'déconnecter du serveur', + ['chat_clear'] = 'vider le chat', + ['chat_clear_all'] = 'vider le chat pour tous le monde', + ['command_clearinventory'] = 'effacer tout les items de l\'inventaire', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings From 28d1ebe9d90422b50f5f6775a8da726d24d5c080 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 2 Jan 2019 12:51:18 +0100 Subject: [PATCH 294/672] Fixed problems with /clearloadout --- server/classes/player.lua | 5 +++++ server/commands.lua | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 15f2b57a..546a26b3 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -416,6 +416,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if self.loadout[i].name == weaponName then weaponLabel = self.loadout[i].label + for j=1, #self.loadout[i].components, 1 do + TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, self.loadout[i].components[j]) + table.remove(self.loadout[i].components, j) + end + table.remove(self.loadout, i) break end diff --git a/server/commands.lua b/server/commands.lua index 0b585460..6d0a7d78 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -239,7 +239,7 @@ TriggerEvent('es:addGroupCommand', 'clearloadout', 'admin', function(source, arg return end - for i=1, #xPlayer.loadout, 1 do + for i=#xPlayer.loadout, 1, -1 do xPlayer.removeWeapon(xPlayer.loadout[i].name) end end, function(source, args, user) From 79c626aa9a91a8dd1d7567c4eacec193d9f537dc Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 3 Jan 2019 13:32:29 +0100 Subject: [PATCH 295/672] Fixed removing weapon --- server/classes/player.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 546a26b3..a1f3091b 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -418,7 +418,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l for j=1, #self.loadout[i].components, 1 do TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, self.loadout[i].components[j]) - table.remove(self.loadout[i].components, j) end table.remove(self.loadout, i) From 8cd724e9392f8ff1bc8d724f98065bd3efdb1e69 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 3 Jan 2019 14:01:34 +0100 Subject: [PATCH 296/672] Parse xPlayer in esx:playerLoaded --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index fedefeda..f213925a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -212,7 +212,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) ESX.Players[_source] = xPlayer - TriggerEvent('esx:playerLoaded', _source) + TriggerEvent('esx:playerLoaded', _source, xPlayer) TriggerClientEvent('esx:playerLoaded', _source, { identifier = xPlayer.identifier, From 1a2c52bc831a171da3e733fa759c87c35bac362f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 3 Jan 2019 14:19:18 +0100 Subject: [PATCH 297/672] Check if last position exists --- server/classes/player.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index a1f3091b..e42267a8 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -199,7 +199,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.getLastPosition = function() - if self.lastPosition then + if self.lastPosition and self.lastPosition.x and self.lastPosition.y and self.lastPosition.z then self.lastPosition.x = ESX.Math.Round(self.lastPosition.x, 1) self.lastPosition.y = ESX.Math.Round(self.lastPosition.y, 1) self.lastPosition.z = ESX.Math.Round(self.lastPosition.z, 1) From 2ac03e534e438a6ebe217c777511d28750a503e5 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 6 Jan 2019 18:47:49 +0100 Subject: [PATCH 298/672] Implemented menu.removeElement(query) --- client/functions.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index 1e25e11b..fab66592 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -198,6 +198,16 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, menu.data.elements[i][key] = val end + menu.removeElement = function(query) + for i=1, #menu.data.elements, 1 do + for k,v in pairs(query) do + if menu.data.elements[i][k] == v then + menu.data.elements[i] = nil + end + end + end + end + table.insert(ESX.UI.Menu.Opened, menu) ESX.UI.Menu.RegisteredTypes[type].open(namespace, name, data) From 018d7050ac526b5532d299d96882e641fa04cbc1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 6 Jan 2019 18:55:46 +0100 Subject: [PATCH 299/672] Fixed trim error --- common/modules/math.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/common/modules/math.lua b/common/modules/math.lua index e707693c..6b4a4a5d 100644 --- a/common/modules/math.lua +++ b/common/modules/math.lua @@ -12,5 +12,9 @@ ESX.Math.GroupDigits = function(value) end ESX.Math.Trim = function(value) - return (string.gsub(value, "^%s*(.-)%s*$", "%1")) + if value then + return (string.gsub(value, "^%s*(.-)%s*$", "%1")) + else + return nil + end end \ No newline at end of file From 9382128f2e501d4d8498691f29efc9493f6498b2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 8 Jan 2019 13:51:00 +0100 Subject: [PATCH 300/672] Proper RequestCollisionAtCoord arguments --- client/functions.lua | 3 ++- config.lua | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index fab66592..274a1735 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -263,6 +263,7 @@ end ESX.Game.GetPedMugshot = function(ped) local mugshot = RegisterPedheadshot(ped) + while not IsPedheadshotReady(mugshot) do Citizen.Wait(0) end @@ -274,7 +275,7 @@ ESX.Game.Teleport = function(entity, coords, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(entity) do - RequestCollisionAtCoord(coords.x, coords.x, coords.x) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) Citizen.Wait(0) end diff --git a/config.lua b/config.lua index 27e32bb9..b519ada4 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,5 @@ Config = {} -Config.Locale = 'fr' +Config.Locale = 'en' Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } @@ -7,7 +7,7 @@ Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true -Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) +Config.EnableHud = false -- enable the default hud? Display current job and accounts (black, bank & cash) Config.PaycheckInterval = 7 * 60000 Config.MaxPlayers = GetConvarInt('sv_maxclients', 32) From dade4f70ab63d4dc45d703165339cd66e17a460a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 12 Jan 2019 19:50:18 +0100 Subject: [PATCH 301/672] Fixed removing elements --- client/functions.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 274a1735..97f12ff7 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -201,9 +201,13 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, menu.removeElement = function(query) for i=1, #menu.data.elements, 1 do for k,v in pairs(query) do - if menu.data.elements[i][k] == v then - menu.data.elements[i] = nil + if menu.data.elements[i] then + if menu.data.elements[i][k] == v then + table.remove(menu.data.elements, i) + break + end end + end end end @@ -427,13 +431,11 @@ ESX.Game.GetClosestObject = function(filter, coords) end for i=1, #objects, 1 do - local foundObject = false if filter == nil or (type(filter) == 'table' and #filter == 0) then foundObject = true else - local objectModel = GetEntityModel(objects[i]) for j=1, #filter, 1 do @@ -441,7 +443,6 @@ ESX.Game.GetClosestObject = function(filter, coords) foundObject = true end end - end if foundObject then @@ -453,7 +454,6 @@ ESX.Game.GetClosestObject = function(filter, coords) closestDistance = distance end end - end return closestObject, closestDistance From fb816bb9b7fe8776a7086101a520369edebb529f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Jan 2019 00:33:00 +0100 Subject: [PATCH 302/672] Implemented menu.setTitle() --- client/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index 97f12ff7..814b2c63 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -198,6 +198,10 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, menu.data.elements[i][key] = val end + menu.setTitle = function(val) + menu.data.title = val + end + menu.removeElement = function(query) for i=1, #menu.data.elements, 1 do for k,v in pairs(query) do From b916bd74b7af6d575953ecdb6df25ef7d1374c17 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Jan 2019 22:44:32 +0100 Subject: [PATCH 303/672] Fixed #172 --- client/modules/death.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/modules/death.lua b/client/modules/death.lua index b32838c3..a7015bdd 100644 --- a/client/modules/death.lua +++ b/client/modules/death.lua @@ -34,8 +34,8 @@ function PlayerKilledByPlayer(killerServerId, killerClientId, killerWeapon) local distance = GetDistanceBetweenCoords(victimCoords, killerCoords, true) local data = { - victimCoords = victimCoords, - killerCoords = killerCoords, + victimCoords = {table.unpack(victimCoords)}, + killerCoords = {table.unpack(killerCoords)}, killedByPlayer = true, deathCause = killerWeapon, @@ -54,7 +54,7 @@ function PlayerKilled() local victimCoords = GetEntityCoords(PlayerPedId()) local data = { - victimCoords = victimCoords, + victimCoords = {table.unpack(victimCoords)}, killedByPlayer = false, deathCause = GetPedCauseOfDeath(playerPed) From 63c8191be366d822113c9dd598ebb59101e5f80a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Jan 2019 22:45:03 +0100 Subject: [PATCH 304/672] Proper default config --- client/functions.lua | 4 ++++ config.lua | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 814b2c63..5035e0d6 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -667,6 +667,10 @@ ESX.Game.GetVehicleProperties = function(vehicle) IsVehicleNeonLightEnabled(vehicle, 3) }, + extras = { + + }, + neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), diff --git a/config.lua b/config.lua index b519ada4..27e32bb9 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,5 @@ Config = {} -Config.Locale = 'en' +Config.Locale = 'fr' Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } @@ -7,7 +7,7 @@ Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true -Config.EnableHud = false -- enable the default hud? Display current job and accounts (black, bank & cash) +Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) Config.PaycheckInterval = 7 * 60000 Config.MaxPlayers = GetConvarInt('sv_maxclients', 32) From 7e66edc351999e777bd0db29dc2097051daca38f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 15 Jan 2019 23:35:51 +0100 Subject: [PATCH 305/672] Use correct text component --- client/functions.lua | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 5035e0d6..69152076 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -46,23 +46,23 @@ end ESX.ShowNotification = function(msg) SetNotificationTextEntry('STRING') - AddTextComponentSubstringWebsite(msg) + AddTextComponentSubstringPlayerName(msg) DrawNotification(false, true) end ESX.ShowAdvancedNotification = function(title, subject, msg, icon, iconType) SetNotificationTextEntry('STRING') - AddTextComponentSubstringWebsite(msg) + AddTextComponentSubstringPlayerName(msg) SetNotificationMessage(icon, icon, false, iconType, title, subject) DrawNotification(false, false) end ESX.ShowHelpNotification = function(msg) - if not IsHelpMessageOnScreen() then + --if not IsHelpMessageBeingDisplayed() then BeginTextCommandDisplayHelp('STRING') - AddTextComponentSubstringWebsite(msg) + AddTextComponentSubstringPlayerName(msg) EndTextCommandDisplayHelp(0, false, true, -1) - end + --end end ESX.TriggerServerCallback = function(name, cb, ...) @@ -130,14 +130,14 @@ ESX.UI.HUD.UpdateElement = function(name, data) SendNUIMessage({ action = 'updateHUDElement', name = name, - data = data, + data = data }) end ESX.UI.Menu.RegisterType = function(type, open, close) ESX.UI.Menu.RegisteredTypes[type] = { open = open, - close = close, + close = close } end From 63da91273d41856cd9dda12963f902404a3d7c9d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 22 Feb 2019 18:51:27 +0100 Subject: [PATCH 306/672] death: x,y,z variables instead of unpacked table --- client/modules/death.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/modules/death.lua b/client/modules/death.lua index a7015bdd..650f1e6a 100644 --- a/client/modules/death.lua +++ b/client/modules/death.lua @@ -34,8 +34,8 @@ function PlayerKilledByPlayer(killerServerId, killerClientId, killerWeapon) local distance = GetDistanceBetweenCoords(victimCoords, killerCoords, true) local data = { - victimCoords = {table.unpack(victimCoords)}, - killerCoords = {table.unpack(killerCoords)}, + victimCoords = { x = ESX.Math.Round(victimCoords.x, 1), y = ESX.Math.Round(victimCoords.y, 1), z = ESX.Math.Round(victimCoords.z, 1) }, + killerCoords = { x = ESX.Math.Round(killerCoords.x, 1), y = ESX.Math.Round(killerCoords.y, 1), z = ESX.Math.Round(killerCoords.z, 1) }, killedByPlayer = true, deathCause = killerWeapon, @@ -54,7 +54,7 @@ function PlayerKilled() local victimCoords = GetEntityCoords(PlayerPedId()) local data = { - victimCoords = {table.unpack(victimCoords)}, + victimCoords = { x = ESX.Math.Round(victimCoords.x, 1), y = ESX.Math.Round(victimCoords.y, 1), z = ESX.Math.Round(victimCoords.z, 1) }, killedByPlayer = false, deathCause = GetPedCauseOfDeath(playerPed) From 06aa7bf513d7e9c2c32aca9e83a7710a10e86bd1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 22 Feb 2019 18:51:38 +0100 Subject: [PATCH 307/672] Minor changes --- server/main.lua | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/server/main.lua b/server/main.lua index f213925a..f8ed067e 100644 --- a/server/main.lua +++ b/server/main.lua @@ -56,12 +56,12 @@ AddEventHandler('es:playerLoaded', function(source, _player) 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, - rare = ESX.Items[inventory[i].item].rare, + 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, + rare = ESX.Items[inventory[i].item].rare, canRemove = ESX.Items[inventory[i].item].canRemove }) end @@ -79,23 +79,22 @@ AddEventHandler('es:playerLoaded', function(source, _player) 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, - rare = ESX.Items[k].rare, + name = k, + count = 0, + label = ESX.Items[k].label, + limit = ESX.Items[k].limit, + usable = ESX.UsableItemsCallbacks[k] ~= nil, + rare = ESX.Items[k].rare, canRemove = ESX.Items[k].canRemove }) local scope = function(item, identifier) table.insert(tasks2, function(cb2) - MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', - { + MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', { ['@identifier'] = identifier, - ['@item'] = item, - ['@count'] = 0 + ['@item'] = item, + ['@count'] = 0 }, function(rowsChanged) cb2() end) @@ -160,10 +159,9 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get job grade data table.insert(tasks2, function(cb2) - MySQL.Async.fetchAll('SELECT * FROM `job_grades` WHERE `job_name` = @job_name AND `grade` = @grade', - { + MySQL.Async.fetchAll('SELECT * FROM `job_grades` WHERE `job_name` = @job_name AND `grade` = @grade', { ['@job_name'] = userData.job.name, - ['@grade'] = userData.job.grade + ['@grade'] = userData.job.grade }, function(result) userData.job['grade_name'] = result[1].name @@ -250,13 +248,13 @@ end) RegisterServerEvent('esx:updateLoadout') AddEventHandler('esx:updateLoadout', function(loadout) - local xPlayer = ESX.GetPlayerFromId(source) + local xPlayer = ESX.GetPlayerFromId(source) xPlayer.loadout = loadout end) RegisterServerEvent('esx:updateLastPosition') AddEventHandler('esx:updateLastPosition', function(position) - local xPlayer = ESX.GetPlayerFromId(source) + local xPlayer = ESX.GetPlayerFromId(source) xPlayer.lastPosition = position end) From 799a35fdf409456db4fd655c8bda7bcd18abc95e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 24 Feb 2019 19:28:47 +0100 Subject: [PATCH 308/672] Implemented ESX.Game.IsVehicleEmpty() --- client/functions.lua | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index 69152076..3a71b997 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -406,6 +406,17 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) end) end +ESX.Game.IsVehicleEmpty = function(vehicle) + local passengers = GetVehicleNumberOfPassengers(vehicle) + local driverSeatFree = IsVehicleSeatFree(vehicle, -1) + + if driverSeatFree then + passengers = passengers + 1 + end + + return passengers == 0 +end + ESX.Game.GetObjects = function() local objects = {} From 611bf76aaa6786bb14c2f9c7cdf87ec25bc8c40d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 27 Feb 2019 09:24:37 +0100 Subject: [PATCH 309/672] Fixed IsVehicleEmpty() --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index 3a71b997..5f77d9de 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -410,7 +410,7 @@ ESX.Game.IsVehicleEmpty = function(vehicle) local passengers = GetVehicleNumberOfPassengers(vehicle) local driverSeatFree = IsVehicleSeatFree(vehicle, -1) - if driverSeatFree then + if not driverSeatFree then passengers = passengers + 1 end From 5ab6123b442d2f999cccd578b4f6ecf4581c16da Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 28 Feb 2019 12:57:09 +0100 Subject: [PATCH 310/672] Implemented ESX.DoesJobExist() --- server/classes/player.lua | 49 ++++++++++++++++++--------------------- server/commands.lua | 7 +++++- server/common.lua | 25 ++++++++++++++++++++ server/functions.lua | 10 ++++++++ 4 files changed, 64 insertions(+), 27 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index e42267a8..3c949697 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -345,40 +345,37 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.setJob = function(name, grade) + self.setJob = function(job, grade) local lastJob = json.decode(json.encode(self.job)) - MySQL.Async.fetchAll('SELECT * FROM `jobs` WHERE `name` = @name', { - ['@name'] = name - }, function(result) + if ESX.DoesJobExist(job, grade) then + local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] - self.job['id'] = result[1].id - self.job['name'] = result[1].name - self.job['label'] = result[1].label + self.job['id'] = jobObject.id + self.job['name'] = jobObject.name + self.job['label'] = jobObject.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['grade'] = grade + self.job['grade_name'] = gradeObject.name + self.job['grade_label'] = gradeObject.label + self.job['grade_salary'] = gradeObject.salary - self.job['skin_male'] = nil - self.job['skin_female'] = nil + 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 gradeObject.skin_male ~= nil then + self.job['skin_male'] = json.decode(gradeObject.skin_male) + end - if result[1].skin_female ~= nil then - self.job['skin_female'] = json.decode(result[1].skin_female) - end + if gradeObject.skin_female ~= nil then + self.job['skin_female'] = json.decode(gradeObject.skin_female) + end - TriggerEvent("esx:setJob", self.source, self.job, lastJob) - TriggerClientEvent("esx:setJob", self.source, self.job) - end) - end) + TriggerEvent('esx:setJob', self.source, self.job, lastJob) + TriggerClientEvent('esx:setJob', self.source, self.job) + else + print(('es_extended: ignoring setJob for %s due to job not found!'):format(self.source)) + end end self.addWeapon = function(weaponName, ammo) diff --git a/server/commands.lua b/server/commands.lua index 6d0a7d78..36617956 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -21,7 +21,12 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, local xPlayer = ESX.GetPlayerFromId(args[1]) if xPlayer then - xPlayer.setJob(args[2], tonumber(args[3])) + if ESX.DoesJobExist(args[2], args[3]) then + xPlayer.setJob(args[2], args[3]) + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'That job does not exist.' } }) + end + else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end diff --git a/server/common.lua b/server/common.lua index 82b8496f..9009735f 100644 --- a/server/common.lua +++ b/server/common.lua @@ -8,6 +8,7 @@ ESX.CancelledTimeouts = {} ESX.LastPlayerData = {} ESX.Pickups = {} ESX.PickupId = 0 +ESX.Jobs = {} AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) @@ -28,6 +29,30 @@ MySQL.ready(function() } end end) + + local result = MySQL.Sync.fetchAll('SELECT * FROM jobs', {}) + + for i=1, #result do + ESX.Jobs[result[i].name] = result[i] + ESX.Jobs[result[i].name].grades = {} + end + + local result2 = MySQL.Sync.fetchAll('SELECT * FROM job_grades', {}) + + for i=1, #result2 do + if ESX.Jobs[result2[i].job_name] then + ESX.Jobs[result2[i].job_name].grades[tostring(result2[i].grade)] = result2[i] + else + print(('es_extended: invalid job "%s" from table job_grades ignored!'):format(result2[i].job_name)) + end + end + + for k,v in pairs(ESX.Jobs) do + if next(v.grades) == nil then + ESX.Jobs[v.name] = nil + print(('es_extended: ignoring job "%s" due to missing job grades!'):format(v.name)) + end + end end) AddEventHandler('esx:playerLoaded', function(source) diff --git a/server/functions.lua b/server/functions.lua index 36da07c0..a722f533 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -186,3 +186,13 @@ ESX.CreatePickup = function(type, name, count, label, player) TriggerClientEvent('esx:pickup', -1, pickupId, label, player) ESX.PickupId = pickupId end + +ESX.DoesJobExist = function(job, grade) + if job and grade then + if ESX.Jobs[job] and ESX.Jobs[job].grades[grade] then + return true + end + end + + return false +end \ No newline at end of file From 9a39f83aee27f9484ce1e494cbe571cefc4a9df0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 28 Feb 2019 12:57:54 +0100 Subject: [PATCH 311/672] Minor changes --- client/main.lua | 1 - server/classes/player.lua | 24 +++++++++++------------- server/functions.lua | 9 +++------ 3 files changed, 14 insertions(+), 20 deletions(-) diff --git a/client/main.lua b/client/main.lua index 74dd7f76..6b8bf6f6 100644 --- a/client/main.lua +++ b/client/main.lua @@ -254,7 +254,6 @@ RegisterNetEvent('esx:loadIPL') AddEventHandler('esx:loadIPL', function(name) Citizen.CreateThread(function() LoadMpDlcMaps() - EnableMpDlcMaps(true) RequestIpl(name) end) end) diff --git a/server/classes/player.lua b/server/classes/player.lua index 3c949697..1224407c 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -48,8 +48,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.player.coords = {x = x, y = y, z = z} end - self.kick = function(r) - self.player.kick(r) + self.kick = function(reason) + self.player.kick(reason) end self.addMoney = function(money) @@ -237,8 +237,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.createAccounts = function(missingAccounts, cb) for i=1, #missingAccounts, 1 do - MySQL.Async.execute('INSERT INTO `user_accounts` (identifier, name) VALUES (@identifier, @name)', - { + MySQL.Async.execute('INSERT INTO `user_accounts` (identifier, name) VALUES (@identifier, @name)', { ['@identifier'] = self.getIdentifier(), ['@name'] = missingAccounts[i] }, function(rowsChanged) @@ -317,8 +316,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l local newCount = item.count + count item.count = newCount - TriggerEvent("esx:onAddInventoryItem", self.source, item, count) - TriggerClientEvent("esx:addInventoryItem", self.source, item, count) + TriggerEvent('esx:onAddInventoryItem', self.source, item, count) + TriggerClientEvent('esx:addInventoryItem', self.source, item, count) end self.removeInventoryItem = function(name, count) @@ -326,8 +325,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l local newCount = item.count - count item.count = newCount - TriggerEvent("esx:onRemoveInventoryItem", self.source, item, count) - TriggerClientEvent("esx:removeInventoryItem", self.source, item, count) + TriggerEvent('esx:onRemoveInventoryItem', self.source, item, count) + TriggerClientEvent('esx:removeInventoryItem', self.source, item, count) end self.setInventoryItem = function(name, count) @@ -336,15 +335,14 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l item.count = count if oldCount > item.count then - TriggerEvent("esx:onRemoveInventoryItem", self.source, item, oldCount - item.count) - TriggerClientEvent("esx:removeInventoryItem", self.source, item, oldCount - item.count) + TriggerEvent('esx:onRemoveInventoryItem', self.source, item, oldCount - item.count) + TriggerClientEvent('esx:removeInventoryItem', self.source, item, oldCount - item.count) else - TriggerEvent("esx:onAddInventoryItem", self.source, item, item.count - oldCount) - TriggerClientEvent("esx:addInventoryItem", self.source, item, item.count - oldCount) + TriggerEvent('esx:onAddInventoryItem', self.source, item, item.count - oldCount) + TriggerClientEvent('esx:addInventoryItem', self.source, item, item.count - oldCount) end end - self.setJob = function(name, grade) self.setJob = function(job, grade) local lastJob = json.decode(json.encode(self.job)) diff --git a/server/functions.lua b/server/functions.lua index a722f533..84c5c6ed 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -46,8 +46,7 @@ ESX.SavePlayer = function(xPlayer, cb) if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE user_accounts SET `money` = @money WHERE identifier = @identifier AND name = @name', - { + 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 @@ -68,8 +67,7 @@ ESX.SavePlayer = function(xPlayer, cb) if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE user_inventory SET `count` = @count WHERE identifier = @identifier AND item = @item', - { + 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 @@ -86,8 +84,7 @@ ESX.SavePlayer = function(xPlayer, cb) -- 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', - { + 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.getLoadout()), From e976de722b081eff4c6603756d12e425da7e020f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 28 Feb 2019 12:59:44 +0100 Subject: [PATCH 312/672] Implemented xPlayer.setLastPosition and fixed saving coords --- server/classes/player.lua | 4 ++++ server/functions.lua | 2 +- server/main.lua | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 1224407c..90af90f6 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -208,6 +208,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return self.lastPosition end + self.setLastPosition = function(position) + self.lastPosition = position + end + self.getMissingAccounts = function(cb) MySQL.Async.fetchAll('SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', { ['@identifier'] = self.getIdentifier() diff --git a/server/functions.lua b/server/functions.lua index 84c5c6ed..2b9467c9 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -38,7 +38,7 @@ end ESX.SavePlayer = function(xPlayer, cb) local asyncTasks = {} - xPlayer.lastPosition = xPlayer.get('coords') + xPlayer.setLastPosition(xPlayer.getCoords()) -- User accounts for i=1, #xPlayer.accounts, 1 do diff --git a/server/main.lua b/server/main.lua index f8ed067e..200431dc 100644 --- a/server/main.lua +++ b/server/main.lua @@ -255,7 +255,7 @@ end) RegisterServerEvent('esx:updateLastPosition') AddEventHandler('esx:updateLastPosition', function(position) local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.lastPosition = position + xPlayer.setLastPosition(position) end) RegisterServerEvent('esx:giveInventoryItem') From b8d0669b6416f79fc26cb7f3ea49b8e6302a4ee3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 4 Mar 2019 21:21:18 +0100 Subject: [PATCH 313/672] Fixed job issues and dont query sql on xPlayer creation --- server/classes/player.lua | 23 +++++----- server/functions.lua | 2 + server/main.lua | 90 +++++++++++++++++++++------------------ 3 files changed, 62 insertions(+), 53 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 90af90f6..73f5bbb9 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -348,29 +348,30 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.setJob = function(job, grade) + grade = tostring(grade) local lastJob = json.decode(json.encode(self.job)) if ESX.DoesJobExist(job, grade) then local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] - self.job['id'] = jobObject.id - self.job['name'] = jobObject.name - self.job['label'] = jobObject.label + self.job.id = jobObject.id + self.job.name = jobObject.name + self.job.label = jobObject.label - self.job['grade'] = grade - self.job['grade_name'] = gradeObject.name - self.job['grade_label'] = gradeObject.label - self.job['grade_salary'] = gradeObject.salary + self.job.grade = grade + self.job.grade_name = gradeObject.name + self.job.grade_label = gradeObject.label + self.job.grade_salary = gradeObject.salary - self.job['skin_male'] = nil - self.job['skin_female'] = nil + self.job.skin_male = {} + self.job.skin_female = {} if gradeObject.skin_male ~= nil then - self.job['skin_male'] = json.decode(gradeObject.skin_male) + self.job.skin_male = json.decode(gradeObject.skin_male) end if gradeObject.skin_female ~= nil then - self.job['skin_female'] = json.decode(gradeObject.skin_female) + self.job.skin_female = json.decode(gradeObject.skin_female) end TriggerEvent('esx:setJob', self.source, self.job, lastJob) diff --git a/server/functions.lua b/server/functions.lua index 2b9467c9..c61e17b2 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -185,6 +185,8 @@ ESX.CreatePickup = function(type, name, count, label, player) end ESX.DoesJobExist = function(job, grade) + grade = tostring(grade) + if job and grade then if ESX.Jobs[job] and ESX.Jobs[job].grades[grade] then return true diff --git a/server/main.lua b/server/main.lua index 200431dc..26033bac 100644 --- a/server/main.lua +++ b/server/main.lua @@ -130,8 +130,52 @@ AddEventHandler('es:playerLoaded', function(source, _player) MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM `users` WHERE `identifier` = @identifier', { ['@identifier'] = player.getIdentifier() }, function(result) - userData.job['name'] = result[1].job - userData.job['grade'] = result[1].job_grade + local job, grade = result[1].job, tostring(result[1].job_grade) + + if ESX.DoesJobExist(job, grade) then + local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + + userData.job = {} + + userData.job.id = jobObject.id + userData.job.name = jobObject.name + userData.job.label = jobObject.label + + userData.job.grade = grade + userData.job.grade_name = gradeObject.name + userData.job.grade_label = gradeObject.label + userData.job.grade_salary = gradeObject.salary + + userData.job.skin_male = {} + userData.job.skin_female = {} + + if gradeObject.skin_male ~= nil then + userData.job.skin_male = json.decode(gradeObject.skin_male) + end + + if gradeObject.skin_female ~= nil then + userData.job.skin_female = json.decode(gradeObject.skin_female) + end + else + print(('es_extended: %s had an unknown job [job: %s, grade: %s], setting as unemployed!'):format(player.getIdentifier(), job, grade)) + + local job, grade = 'unemployed', '0' + local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + + userData.job = {} + + userData.job.id = jobObject.id + userData.job.name = jobObject.name + userData.job.label = jobObject.label + + userData.job.grade = grade + userData.job.grade_name = gradeObject.name + userData.job.grade_label = gradeObject.label + userData.job.grade_salary = gradeObject.salary + + userData.job.skin_male = {} + userData.job.skin_female = {} + end if result[1].loadout ~= nil then userData.loadout = json.decode(result[1].loadout) @@ -146,44 +190,6 @@ AddEventHandler('es:playerLoaded', function(source, _player) 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) @@ -219,10 +225,10 @@ AddEventHandler('es:playerLoaded', function(source, _player) job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), lastPosition = xPlayer.getLastPosition(), - money = xPlayer.get('money') + money = xPlayer.getMoney() }) - xPlayer.player.displayMoney(xPlayer.get('money')) + xPlayer.displayMoney(xPlayer.getMoney()) end) From a088fae0e4f25958b6724ec10046896274277e25 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 4 Mar 2019 21:32:23 +0100 Subject: [PATCH 314/672] Compatibility with old loadouts prior to components update, fixes #194 --- server/main.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/server/main.lua b/server/main.lua index 26033bac..48853eaf 100644 --- a/server/main.lua +++ b/server/main.lua @@ -179,6 +179,13 @@ AddEventHandler('es:playerLoaded', function(source, _player) if result[1].loadout ~= nil then userData.loadout = json.decode(result[1].loadout) + + -- Compatibility with old loadouts prior to components update + for k,v in ipairs(userData.loadout) do + if v.components == nil then + v.components = {} + end + end end if result[1].position ~= nil then From cd9383a56fd6e8e1e15745dd13a7ac2d01cb34a3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 6 Mar 2019 22:50:43 +0100 Subject: [PATCH 315/672] Grade supposed to be number type --- client/main.lua | 2 +- server/classes/player.lua | 2 +- server/main.lua | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/client/main.lua b/client/main.lua index 6b8bf6f6..fbb010c0 100644 --- a/client/main.lua +++ b/client/main.lua @@ -481,7 +481,7 @@ Citizen.CreateThread(function() Citizen.Wait(0) - if IsControlJustReleased(0, Keys['F2']) and GetLastInputMethod(2) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + if IsControlJustReleased(0, Keys['F2']) and IsInputDisabled(0) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() end diff --git a/server/classes/player.lua b/server/classes/player.lua index 73f5bbb9..256b365c 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -358,7 +358,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.job.name = jobObject.name self.job.label = jobObject.label - self.job.grade = grade + self.job.grade = tonumber(grade) self.job.grade_name = gradeObject.name self.job.grade_label = gradeObject.label self.job.grade_salary = gradeObject.salary diff --git a/server/main.lua b/server/main.lua index 48853eaf..4ac0b405 100644 --- a/server/main.lua +++ b/server/main.lua @@ -141,7 +141,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) userData.job.name = jobObject.name userData.job.label = jobObject.label - userData.job.grade = grade + userData.job.grade = tonumber(grade) userData.job.grade_name = gradeObject.name userData.job.grade_label = gradeObject.label userData.job.grade_salary = gradeObject.salary @@ -168,7 +168,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) userData.job.name = jobObject.name userData.job.label = jobObject.label - userData.job.grade = grade + userData.job.grade = tonumber(grade) userData.job.grade_name = gradeObject.name userData.job.grade_label = gradeObject.label userData.job.grade_salary = gradeObject.salary From 28ce131fb7e4cc9cb5b7e7375ba07cf41944fc8c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 9 Mar 2019 18:37:01 +0100 Subject: [PATCH 316/672] Implemented vehicle extras property support, closes #186 --- client/functions.lua | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 5f77d9de..5ad1d095 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -649,8 +649,16 @@ ESX.Game.GetClosestPed = function(coords, ignoreList) end ESX.Game.GetVehicleProperties = function(vehicle) - local color1, color2 = GetVehicleColours(vehicle) + local color1, color2 = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + local extras = {} + + for id=0, 12 do + if DoesExtraExist(vehicle, id) then + local state = IsVehicleExtraTurnedOn(vehicle, id) == 1 + extras[tostring(id)] = state + end + end return { @@ -678,9 +686,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) IsVehicleNeonLightEnabled(vehicle, 3) }, - extras = { - - }, + extras = extras, neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), @@ -791,6 +797,16 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) end + if props.extras ~= nil then + for id,enabled in pairs(props.extras) do + if enabled then + SetVehicleExtra(vehicle, tonumber(id), 0) + else + SetVehicleExtra(vehicle, tonumber(id), 1) + end + end + end + if props.neonColor ~= nil then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end From 51b2df94aff1ac31e31256d7a2a81a4e75a51cd2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 30 Mar 2019 08:49:03 +0100 Subject: [PATCH 317/672] Fixed IsVehicleEmpty() again --- client/functions.lua | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 5ad1d095..57269725 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -410,11 +410,7 @@ ESX.Game.IsVehicleEmpty = function(vehicle) local passengers = GetVehicleNumberOfPassengers(vehicle) local driverSeatFree = IsVehicleSeatFree(vehicle, -1) - if not driverSeatFree then - passengers = passengers + 1 - end - - return passengers == 0 + return passengers == 0 and driverSeatFree end ESX.Game.GetObjects = function() From 17cbed02633992d08049ab45ff9c1651bed8fb50 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 13 Apr 2019 23:00:26 +0200 Subject: [PATCH 318/672] Added table module, thanks to Gizz MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Jérémie N'gadi --- __resource.lua | 2 + common/modules/table.lua | 132 +++++++++++++++++++++++++++++++++++++++ server/main.lua | 5 +- 3 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 common/modules/table.lua diff --git a/__resource.lua b/__resource.lua index cfa44c60..953bf74a 100644 --- a/__resource.lua +++ b/__resource.lua @@ -29,6 +29,7 @@ server_scripts { 'server/commands.lua', 'common/modules/math.lua', + 'common/modules/table.lua', 'common/functions.lua' } @@ -57,6 +58,7 @@ client_scripts { 'client/modules/streaming.lua', 'common/modules/math.lua', + 'common/modules/table.lua', 'common/functions.lua' } diff --git a/common/modules/table.lua b/common/modules/table.lua new file mode 100644 index 00000000..fa65baa4 --- /dev/null +++ b/common/modules/table.lua @@ -0,0 +1,132 @@ +-- nil proof alternative to #table +function ESX.Table.SizeOf(table) + local keys = {} + + for k,v in pairs(table) do + table.insert(keys, tonumber(k)) + end + + table.sort(keys, function(a,b) return a < b end) + + if #keys > 0 then + return keys[#keys] + else + return 0 + end +end + +function ESX.Table.IndexOf(table, value) + for i=1, #table, 1 do + if table[i] == value then + return i + end + end + + return -1 +end + +function ESX.Table.LastIndexOf(table, value) + for i=#table, 1, -1 do + if table[i] == value then + return i + end + end + + return -1 +end + +function ESX.Table.Find(table, cb) + for i=1, #table, 1 do + if cb(table[i]) then + return table[i] + end + end + + return nil +end + +function ESX.Table.FindIndex(table, cb) + for i=1, #table, 1 do + if cb(table[i]) then + return i + end + end + + return -1 +end + +function ESX.Table.Filter(table, cb) + local newTable = {} + + for i=1, #table, 1 do + if cb(table[i]) then + table.insert(newTable, table[i]) + end + end + + return newTable +end + +function ESX.Table.Map(table, cb) + local newTable = {} + + for i=1, #table, 1 do + newTable[i] = cb(table[i], i) + end + + return newTable +end + +function ESX.Table.Reverse(table) + local newTable = {} + + for i=#table, 1, -1 do + table.insert(newTable, table[i]) + end + + return newTable +end + +function ESX.Table.Clone(table) + if type(table) ~= 'table' then return table end + + local meta = getmetatable(table) + local target = {} + + for k,v in pairs(table) do + if type(v) == 'table' then + target[k] = ESX.Table.Clone(v) + else + target[k] = v + end + end + + setmetatable(target, meta) + + return target +end + +function ESX.Table.Concat(table1, table2) + local table3 = ESX.Table.Clone(table1) + + for i=1, #table2, 1 do + table.insert(table3, table2[i]) + end + + return t3 +end + +function ESX.Table.Join(table, sep) + local sep = sep or ',' + local str = '' + + for i=1, #table, 1 do + if i > 1 then + str = str .. sep + end + + str = str .. table[i] + end + + return str +end \ No newline at end of file diff --git a/server/main.lua b/server/main.lua index 4ac0b405..84c3ab20 100644 --- a/server/main.lua +++ b/server/main.lua @@ -17,7 +17,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) table.insert(tasks, function(cb) MySQL.Async.execute('UPDATE `users` SET `name` = @name WHERE `identifier` = @identifier', { ['@identifier'] = player.getIdentifier(), - ['@name'] = userData.playerName + ['@name'] = userData.playerName }, function(rowsChanged) cb() end) @@ -28,7 +28,6 @@ AddEventHandler('es:playerLoaded', function(source, _player) 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 @@ -38,6 +37,8 @@ AddEventHandler('es:playerLoaded', function(source, _player) label = Config.AccountLabels[accounts[j].name] }) end + + break end end From fb8379899c49adf4715c9f57d7a79420efb5f564 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 13 Apr 2019 23:03:24 +0200 Subject: [PATCH 319/672] Missing decleration --- common/modules/table.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/modules/table.lua b/common/modules/table.lua index fa65baa4..62751e56 100644 --- a/common/modules/table.lua +++ b/common/modules/table.lua @@ -1,3 +1,5 @@ +ESX.Table = {} + -- nil proof alternative to #table function ESX.Table.SizeOf(table) local keys = {} From a0cc840ec97aa8b7bac8946c1a3541fb2610a0a0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 13 Apr 2019 23:15:13 +0200 Subject: [PATCH 320/672] Renamed arguments --- common/modules/table.lua | 76 +++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/common/modules/table.lua b/common/modules/table.lua index 62751e56..51126b98 100644 --- a/common/modules/table.lua +++ b/common/modules/table.lua @@ -1,14 +1,16 @@ ESX.Table = {} -- nil proof alternative to #table -function ESX.Table.SizeOf(table) +function ESX.Table.SizeOf(t) local keys = {} - for k,v in pairs(table) do + for k,v in pairs(t) do table.insert(keys, tonumber(k)) end - table.sort(keys, function(a,b) return a < b end) + table.sort(keys, function(a, b) + return a < b + end) if #keys > 0 then return keys[#keys] @@ -17,9 +19,9 @@ function ESX.Table.SizeOf(table) end end -function ESX.Table.IndexOf(table, value) - for i=1, #table, 1 do - if table[i] == value then +function ESX.Table.IndexOf(t, value) + for i=1, #t, 1 do + if t[i] == value then return i end end @@ -27,9 +29,9 @@ function ESX.Table.IndexOf(table, value) return -1 end -function ESX.Table.LastIndexOf(table, value) - for i=#table, 1, -1 do - if table[i] == value then +function ESX.Table.LastIndexOf(t, value) + for i=#t, 1, -1 do + if t[i] == value then return i end end @@ -37,19 +39,19 @@ function ESX.Table.LastIndexOf(table, value) return -1 end -function ESX.Table.Find(table, cb) - for i=1, #table, 1 do - if cb(table[i]) then - return table[i] +function ESX.Table.Find(t, cb) + for i=1, #t, 1 do + if cb(t[i]) then + return t[i] end end return nil end -function ESX.Table.FindIndex(table, cb) - for i=1, #table, 1 do - if cb(table[i]) then +function ESX.Table.FindIndex(t, cb) + for i=1, #t, 1 do + if cb(t[i]) then return i end end @@ -57,45 +59,45 @@ function ESX.Table.FindIndex(table, cb) return -1 end -function ESX.Table.Filter(table, cb) +function ESX.Table.Filter(t, cb) local newTable = {} - for i=1, #table, 1 do - if cb(table[i]) then - table.insert(newTable, table[i]) + for i=1, #t, 1 do + if cb(t[i]) then + table.insert(newTable, t[i]) end end return newTable end -function ESX.Table.Map(table, cb) +function ESX.Table.Map(t, cb) local newTable = {} - for i=1, #table, 1 do - newTable[i] = cb(table[i], i) + for i=1, #t, 1 do + newTable[i] = cb(t[i], i) end return newTable end -function ESX.Table.Reverse(table) +function ESX.Table.Reverse(t) local newTable = {} - for i=#table, 1, -1 do - table.insert(newTable, table[i]) + for i=#t, 1, -1 do + table.insert(newTable, t[i]) end return newTable end -function ESX.Table.Clone(table) - if type(table) ~= 'table' then return table end +function ESX.Table.Clone(t) + if type(t) ~= 'table' then return t end - local meta = getmetatable(table) + local meta = getmetatable(t) local target = {} - for k,v in pairs(table) do + for k,v in pairs(t) do if type(v) == 'table' then target[k] = ESX.Table.Clone(v) else @@ -108,26 +110,26 @@ function ESX.Table.Clone(table) return target end -function ESX.Table.Concat(table1, table2) - local table3 = ESX.Table.Clone(table1) +function ESX.Table.Concat(t1, t2) + local t3 = ESX.Table.Clone(t1) - for i=1, #table2, 1 do - table.insert(table3, table2[i]) + for i=1, #t2, 1 do + table.insert(t3, t2[i]) end return t3 end -function ESX.Table.Join(table, sep) +function ESX.Table.Join(t, sep) local sep = sep or ',' local str = '' - for i=1, #table, 1 do + for i=1, #t, 1 do if i > 1 then str = str .. sep end - str = str .. table[i] + str = str .. t[i] end return str From 16a78f4613f8274f8a69ad925e0e5b116b24be88 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 15 Apr 2019 11:14:37 +0200 Subject: [PATCH 321/672] Rewrote .SizeOf() function --- common/modules/table.lua | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/common/modules/table.lua b/common/modules/table.lua index 51126b98..fb862439 100644 --- a/common/modules/table.lua +++ b/common/modules/table.lua @@ -2,21 +2,13 @@ ESX.Table = {} -- nil proof alternative to #table function ESX.Table.SizeOf(t) - local keys = {} + local count = 0 - for k,v in pairs(t) do - table.insert(keys, tonumber(k)) + for _,_ in pairs(t) do + count = count + 1 end - table.sort(keys, function(a, b) - return a < b - end) - - if #keys > 0 then - return keys[#keys] - else - return 0 - end + return count end function ESX.Table.IndexOf(t, value) From 3d27e2b0a67873422d77365089faf53cfa7ea888 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 17 Apr 2019 11:38:12 +0200 Subject: [PATCH 322/672] Indent cleanup --- client/functions.lua | 10 +++------- server/functions.lua | 13 ++----------- server/main.lua | 28 ++-------------------------- 3 files changed, 7 insertions(+), 44 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 57269725..ac6a6109 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1138,7 +1138,7 @@ ESX.ShowInventory = function() local players = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) local foundPlayers = false local elements = {} - + for i=1, #players, 1 do if players[i] ~= PlayerId() then foundPlayers = true @@ -1168,7 +1168,7 @@ ESX.ShowInventory = function() for i=1, #players, 1 do if players[i] ~= PlayerId() then - + if players[i] == data2.current.player then foundPlayers = true nearbyPlayer = players[i] @@ -1347,20 +1347,16 @@ end) -- SetTimeout Citizen.CreateThread(function() while true do - Citizen.Wait(0) local currTime = GetGameTimer() for i=1, #ESX.TimeoutCallbacks, 1 do - - if ESX.TimeoutCallbacks[i] ~= nil then + if ESX.TimeoutCallbacks[i] then if currTime >= ESX.TimeoutCallbacks[i].time then ESX.TimeoutCallbacks[i].cb() ESX.TimeoutCallbacks[i] = nil end end - end - end end) diff --git a/server/functions.lua b/server/functions.lua index c61e17b2..621692d8 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -37,14 +37,12 @@ ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) end ESX.SavePlayer = function(xPlayer, cb) - local asyncTasks = {} + local asyncTasks = {} xPlayer.setLastPosition(xPlayer.getCoords()) -- User accounts for i=1, #xPlayer.accounts, 1 do - if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then - 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, @@ -56,16 +54,12 @@ ESX.SavePlayer = function(xPlayer, cb) end) ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] = xPlayer.accounts[i].money - end - end -- Inventory items for i=1, #xPlayer.inventory, 1 do - if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then - 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, @@ -77,9 +71,7 @@ ESX.SavePlayer = function(xPlayer, cb) end) ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] = xPlayer.inventory[i].count - end - end -- Job, loadout and position @@ -96,13 +88,12 @@ ESX.SavePlayer = function(xPlayer, cb) end) Async.parallel(asyncTasks, function(results) - RconPrint('[SAVED] ' .. xPlayer.name .. "\n") + RconPrint('[SAVED] ' .. xPlayer.name .. "^7\n") if cb ~= nil then cb() end end) - end ESX.SavePlayers = function(cb) diff --git a/server/main.lua b/server/main.lua index 84c3ab20..370d135f 100644 --- a/server/main.lua +++ b/server/main.lua @@ -12,7 +12,6 @@ AddEventHandler('es:playerLoaded', function(source, _player) } 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', { @@ -78,7 +77,6 @@ AddEventHandler('es:playerLoaded', function(source, _player) end if not found then - table.insert(userData.inventory, { name = k, count = 0, @@ -90,7 +88,6 @@ AddEventHandler('es:playerLoaded', function(source, _player) }) local scope = function(item, identifier) - table.insert(tasks2, function(cb2) MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', { ['@identifier'] = identifier, @@ -100,11 +97,9 @@ AddEventHandler('es:playerLoaded', function(source, _player) cb2() end) end) - end scope(k, player.getIdentifier()) - end end @@ -204,11 +199,9 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- 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 @@ -237,24 +230,21 @@ AddEventHandler('es:playerLoaded', function(source, _player) }) xPlayer.displayMoney(xPlayer.getMoney()) - end) - end) end) - end) AddEventHandler('playerDropped', function(reason) local _source = source local xPlayer = ESX.GetPlayerFromId(_source) - if xPlayer ~= nil then + if xPlayer then TriggerEvent('esx:playerDropped', _source, reason) ESX.SavePlayer(xPlayer, function() - ESX.Players[_source] = nil + ESX.Players[_source] = nil ESX.LastPlayerData[_source] = nil end) end @@ -303,13 +293,11 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo elseif type == 'item_money' then if itemCount > 0 and sourceXPlayer.getMoney() >= itemCount then - sourceXPlayer.removeMoney(itemCount) targetXPlayer.addMoney (itemCount) TriggerClientEvent('esx:showNotification', _source, _U('gave_money', ESX.Math.GroupDigits(itemCount), targetXPlayer.name)) TriggerClientEvent('esx:showNotification', target, _U('received_money', ESX.Math.GroupDigits(itemCount), sourceXPlayer.name)) - else TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) end @@ -317,13 +305,11 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo 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, _U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], targetXPlayer.name)) TriggerClientEvent('esx:showNotification', target, _U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], sourceXPlayer.name)) - else TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) end @@ -331,7 +317,6 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo elseif type == 'item_weapon' then if not targetXPlayer.hasWeapon(itemName) then - sourceXPlayer.removeWeapon(itemName) targetXPlayer.addWeapon(itemName, itemCount) @@ -344,14 +329,12 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, targetXPlayer.name)) TriggerClientEvent('esx:showNotification', target, _U('received_weapon', weaponLabel, sourceXPlayer.name)) end - else TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) TriggerClientEvent('esx:showNotification', _source, _U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) end end - end) RegisterServerEvent('esx:removeInventoryItem') @@ -363,7 +346,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if itemCount == nil or itemCount < 1 then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) else - local xPlayer = ESX.GetPlayerFromId(source) local xItem = xPlayer.getInventoryItem(itemName) @@ -376,7 +358,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) ESX.CreatePickup('item_standard', itemName, itemCount, pickupLabel, _source) TriggerClientEvent('esx:showNotification', _source, _U('threw_standard', itemCount, xItem.label)) end - end elseif type == 'item_money' then @@ -384,7 +365,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if itemCount == nil or itemCount < 1 then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else - local xPlayer = ESX.GetPlayerFromId(source) local playerCash = xPlayer.getMoney() @@ -397,7 +377,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) ESX.CreatePickup('item_money', 'money', itemCount, pickupLabel, _source) TriggerClientEvent('esx:showNotification', _source, _U('threw_money', ESX.Math.GroupDigits(itemCount))) end - end elseif type == 'item_account' then @@ -405,7 +384,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if itemCount == nil or itemCount < 1 then TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) else - local xPlayer = ESX.GetPlayerFromId(source) local account = xPlayer.getAccount(itemName) @@ -418,7 +396,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) ESX.CreatePickup('item_account', itemName, itemCount, pickupLabel, _source) TriggerClientEvent('esx:showNotification', _source, _U('threw_account', ESX.Math.GroupDigits(itemCount), string.lower(account.label))) end - end elseif type == 'item_weapon' then @@ -449,7 +426,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end end - end) RegisterServerEvent('esx:useItem') From debaf54c443e2c1d76c24564e4734750609c986d Mon Sep 17 00:00:00 2001 From: KandaSoranyan <32266067+KandaSoranyan@users.noreply.github.com> Date: Sat, 20 Apr 2019 07:45:28 +0200 Subject: [PATCH 323/672] translating missing lfr ocale --- locales/fr.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index ed73dc12..f7c1fedd 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -79,8 +79,8 @@ Locales['fr'] = { ['chat_clear'] = 'vider le chat', ['chat_clear_all'] = 'vider le chat pour tous le monde', ['command_clearinventory'] = 'effacer tout les items de l\'inventaire', - ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + ['command_clearloadout'] = 'retirer toutes les armes de l\'équipement', + ['command_playerid_param'] = 'spécifiez un playerid ou laissez vide pour vous-même', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', @@ -163,18 +163,18 @@ Locales['fr'] = { ['weapon_flashlight'] = 'lampe torche', ['gadget_nightvision'] = 'vision nocturne', ['gadget_parachute'] = 'parachute', - ['weapon_flare'] = 'Fusée Détresse', + ['weapon_flare'] = 'fusée Détresse', ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', - ['component_clip_drum'] = 'drum Magazine', - ['component_clip_box'] = 'box Magazine', - ['component_flashlight'] = 'flashlight', - ['component_scope'] = 'scope', - ['component_scope_advanced'] = 'advanced Scope', - ['component_suppressor'] = 'suppressor', - ['component_grip'] = 'grip', - ['component_luxary_finish'] = 'luxary Weapon Finish', + ['component_clip_default'] = 'chargeur par défaut', + ['component_clip_extended'] = 'chargeur grande capacité', + ['component_clip_drum'] = 'chargeur tambour', + ['component_clip_box'] = 'chargeur très grande capacité', + ['component_flashlight'] = 'torche', + ['component_scope'] = 'viseur', + ['component_scope_advanced'] = 'lunette', + ['component_suppressor'] = 'réducteur de son', + ['component_grip'] = 'poignée', + ['component_luxary_finish'] = 'finission de luxe', } From 166d8c17a6f5cd78f0bf1264c795abd06457274a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 22 Apr 2019 11:36:49 +0200 Subject: [PATCH 324/672] Ignore items not registered in "items" table --- server/main.lua | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/server/main.lua b/server/main.lua index 370d135f..3f0a4d73 100644 --- a/server/main.lua +++ b/server/main.lua @@ -51,25 +51,30 @@ AddEventHandler('es:playerLoaded', function(source, _player) MySQL.Async.fetchAll('SELECT * FROM `user_inventory` WHERE `identifier` = @identifier', { ['@identifier'] = player.getIdentifier() }, function(inventory) - local tasks2 = {} - 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, - rare = ESX.Items[inventory[i].item].rare, - canRemove = ESX.Items[inventory[i].item].canRemove - }) + for i=1, #inventory do + local item = ESX.Items[inventory[i].item] + + if item then + table.insert(userData.inventory, { + name = inventory[i].item, + count = inventory[i].count, + label = item.label, + limit = item.limit, + usable = ESX.UsableItemsCallbacks[inventory[i].item] ~= nil, + rare = item.rare, + canRemove = item.canRemove + }) + else + print(('es_extended: invalid item "%s" ignored!'):format(inventory[i].item)) + end end for k,v in pairs(ESX.Items) do local found = false - for j=1, #userData.inventory, 1 do + for j=1, #userData.inventory do if userData.inventory[j].name == k then found = true break From d6323124c233f0cc10cea5396516afb28f15048b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 22 Apr 2019 11:37:06 +0200 Subject: [PATCH 325/672] OneSync note --- config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.lua b/config.lua index 27e32bb9..95cd34be 100644 --- a/config.lua +++ b/config.lua @@ -10,6 +10,6 @@ Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) Config.PaycheckInterval = 7 * 60000 -Config.MaxPlayers = GetConvarInt('sv_maxclients', 32) +Config.MaxPlayers = GetConvarInt('sv_maxclients', 32) -- set this value to 255 if you're running OneSync Config.EnableDebug = false From cde81c4e8e9efc2e0c891e53a1988b80d15df8c8 Mon Sep 17 00:00:00 2001 From: jquiaios Date: Fri, 26 Apr 2019 19:03:01 -0400 Subject: [PATCH 326/672] Fix mislocated break in player accounts loop --- server/main.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index 3f0a4d73..415b703a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -35,9 +35,8 @@ AddEventHandler('es:playerLoaded', function(source, _player) money = accounts[j].money, label = Config.AccountLabels[accounts[j].name] }) + break end - - break end end From 47c81f36eb4205339576b48a2ab8def6f28c2522 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 1 May 2019 21:56:49 +0200 Subject: [PATCH 327/672] Implemented ESX.Table.Sort() for pairs --- common/modules/table.lua | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/common/modules/table.lua b/common/modules/table.lua index fb862439..ea7dad28 100644 --- a/common/modules/table.lua +++ b/common/modules/table.lua @@ -125,4 +125,35 @@ function ESX.Table.Join(t, sep) end return str +end + +-- Credit: https://stackoverflow.com/a/15706820 +-- Description: sort function for pairs +function ESX.Table.Sort(t, order) + -- collect the keys + local keys = {} + + for k,_ in pairs(t) do + keys[#keys + 1] = k + end + + -- if order function given, sort by it by passing the table and keys a, b, + -- otherwise just sort the keys + if order then + table.sort(keys, function(a,b) + return order(t, a, b) + end) + else + table.sort(keys) + end + + -- return the iterator function + local i = 0 + + return function() + i = i + 1 + if keys[i] then + return keys[i], t[keys[i]] + end + end end \ No newline at end of file From fb9f4263a2d07d07029e18c07ad65a9e392b6438 Mon Sep 17 00:00:00 2001 From: izio38 Date: Sun, 5 May 2019 23:00:08 +0200 Subject: [PATCH 328/672] wrong notif target --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 3f0a4d73..b43e66d6 100644 --- a/server/main.lua +++ b/server/main.lua @@ -336,7 +336,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo end else TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) - TriggerClientEvent('esx:showNotification', _source, _U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) + TriggerClientEvent('esx:showNotification', target, _U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) end end From 36bc96cdfe9e2214706d48d3fe462184169368a7 Mon Sep 17 00:00:00 2001 From: DanishRP Date: Sat, 11 May 2019 01:18:59 +0200 Subject: [PATCH 329/672] Changed Variables Changed Variables for self.removeAccountMoney, did not match same scheme as other functions in same function --- server/classes/player.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 256b365c..5642c527 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -289,18 +289,18 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l TriggerClientEvent('esx:setAccountMoney', self.source, account) end - self.removeAccountMoney = function(a, m) - if m < 0 then + self.removeAccountMoney = function(acc, money) + if money < 0 then print(('es_extended: %s attempted exploiting! (reason: player tried removing -1 account balance)'):format(self.identifier)) return end - local account = self.getAccount(a) - local newMoney = account.money - m + local account = self.getAccount(acc) + local newMoney = account.money - ESX.Math.Round(money) account.money = newMoney - if a == 'bank' then + if acc == 'bank' then self.set('bank', newMoney) end From 15489ec3c798199df945d6290d86a653299c249c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 May 2019 23:05:38 +0200 Subject: [PATCH 330/672] Proper hud natives --- client/functions.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index ac6a6109..a8e3c3d1 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1010,7 +1010,6 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size) if onScreen then SetTextScale(0.0 * scale, 0.55 * scale) SetTextFont(0) - SetTextProportional(1) SetTextColour(255, 255, 255, 255) SetTextDropshadow(0, 0, 0, 0, 255) SetTextEdge(2, 0, 0, 0, 150) From 954572c93406be752779153434911f8e13573df8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 8 Jun 2019 22:24:20 +0200 Subject: [PATCH 331/672] Minor changes, removed keys table --- client/functions.lua | 26 ++---------- client/main.lua | 97 +++++++++++++++----------------------------- 2 files changed, 36 insertions(+), 87 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index a8e3c3d1..f7fc4107 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -298,11 +298,7 @@ ESX.Game.SpawnObject = function(model, coords, cb) local model = (type(model) == 'number' and model or GetHashKey(model)) Citizen.CreateThread(function() - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + ESX.Streaming.RequestModel(model) local obj = CreateObject(model, coords.x, coords.y, coords.z, true, false, true) @@ -316,11 +312,7 @@ ESX.Game.SpawnLocalObject = function(model, coords, cb) local model = (type(model) == 'number' and model or GetHashKey(model)) Citizen.CreateThread(function() - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + ESX.Streaming.RequestModel(model) local obj = CreateObject(model, coords.x, coords.y, coords.z, false, false, true) @@ -344,11 +336,7 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) Citizen.CreateThread(function() - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + ESX.Streaming.RequestModel(model) local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) local id = NetworkGetNetworkIdFromEntity(vehicle) @@ -378,11 +366,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) local model = (type(modelName) == 'number' and modelName or GetHashKey(modelName)) Citizen.CreateThread(function() - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(0) - end + ESX.Streaming.RequestModel(model) local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) @@ -390,7 +374,6 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleNeedsToBeHotwired(vehicle, false) SetModelAsNoLongerNeeded(model) - RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(vehicle) do @@ -1012,7 +995,6 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size) SetTextFont(0) SetTextColour(255, 255, 255, 255) SetTextDropshadow(0, 0, 0, 0, 255) - SetTextEdge(2, 0, 0, 0, 150) SetTextDropShadow() SetTextOutline() SetTextEntry('STRING') diff --git a/client/main.lua b/client/main.lua index fbb010c0..d7bb1f43 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,29 +1,13 @@ -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 LoadoutLoaded = false -local IsPaused = false -local PlayerSpawned = false -local LastLoadout = {} -local Pickups = {} -local isDead = false +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 + ESX.PlayerData = xPlayer if Config.EnableHud then - for i=1, #xPlayer.accounts, 1 do local accountTpl = '
 {{money}}
' @@ -51,7 +35,6 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) job_label = xPlayer.job.label, grade_label = xPlayer.job.grade_label }) - else TriggerEvent('es:setMoneyDisplay', 0.0) end @@ -65,14 +48,14 @@ AddEventHandler('playerSpawned', function() local playerPed = PlayerPedId() -- Restore position - if ESX.PlayerData.lastPosition ~= nil then + 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 - LoadoutLoaded = true - PlayerSpawned = true + isLoadoutLoaded = true + isPlayerSpawned = true isDead = false end) @@ -81,7 +64,7 @@ AddEventHandler('esx:onPlayerDeath', function() end) AddEventHandler('skinchanger:loadDefaultModel', function() - LoadoutLoaded = false + isLoadoutLoaded = false end) AddEventHandler('skinchanger:modelLoaded', function() @@ -118,7 +101,7 @@ AddEventHandler('esx:restoreLoadout', function() end end - LoadoutLoaded = true + isLoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') @@ -334,7 +317,7 @@ AddEventHandler('esx:pickup', function(id, label, player) SetEntityAsMissionEntity(obj, true, false) PlaceObjectOnGroundProperly(obj) - Pickups[id] = { + pickups[id] = { id = id, obj = obj, label = label, @@ -350,8 +333,8 @@ end) RegisterNetEvent('esx:removePickup') AddEventHandler('esx:removePickup', function(id) - ESX.Game.DeleteObject(Pickups[id].obj) - Pickups[id] = nil + ESX.Game.DeleteObject(pickups[id].obj) + pickups[id] = nil end) RegisterNetEvent('esx:pickupWeapon') @@ -402,12 +385,12 @@ if Config.EnableHud then while true do Citizen.Wait(300) - if IsPauseMenuActive() and not IsPaused then - IsPaused = true + 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 + elseif not IsPauseMenuActive() and isPaused then + isPaused = false TriggerEvent('es:setMoneyDisplay', 1.0) ESX.UI.HUD.SetDisplay(1.0) end @@ -418,7 +401,6 @@ end -- Save loadout Citizen.CreateThread(function() while true do - Citizen.Wait(5000) local playerPed = PlayerPedId() @@ -426,11 +408,10 @@ Citizen.CreateThread(function() local loadoutChanged = false if IsPedDeadOrDying(playerPed) then - LoadoutLoaded = false + isLoadoutLoaded = false end - for i=1, #Config.Weapons, 1 do - + for i=1, #Config.Weapons do local weaponName = Config.Weapons[i].name local weaponHash = GetHashKey(weaponName) local weaponComponents = {} @@ -439,17 +420,17 @@ Citizen.CreateThread(function() local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) local components = Config.Weapons[i].components - for j=1, #components, 1 do + for j=1, #components do if HasPedGotWeaponComponent(playerPed, weaponHash, components[j].hash) then table.insert(weaponComponents, components[j].name) end end - if LastLoadout[weaponName] == nil or LastLoadout[weaponName] ~= ammo then + if not lastLoadout[weaponName] or lastLoadout[weaponName] ~= ammo then loadoutChanged = true end - LastLoadout[weaponName] = ammo + lastLoadout[weaponName] = ammo table.insert(loadout, { name = weaponName, @@ -458,42 +439,36 @@ Citizen.CreateThread(function() components = weaponComponents }) else - if LastLoadout[weaponName] ~= nil then + if lastLoadout[weaponName] then loadoutChanged = true end - LastLoadout[weaponName] = nil + lastLoadout[weaponName] = nil end - end - if loadoutChanged and LoadoutLoaded then + 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, Keys['F2']) and IsInputDisabled(0) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + 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) -- Dot above head if Config.ShowDotAbovePlayer then - Citizen.CreateThread(function() while true do - Citizen.Wait(1) local players = ESX.Game.GetPlayers() @@ -503,15 +478,12 @@ if Config.ShowDotAbovePlayer then local headId = CreateMpGamerTag(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) @@ -523,25 +495,22 @@ if Config.DisableWantedLevel then end end end) - end --- Pickups +-- pickups Citizen.CreateThread(function() while true do - Citizen.Wait(0) local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) + local coords = GetEntityCoords(playerPed) -- if there's no nearby pickups we can wait a bit to save performance - if next(Pickups) == nil then + if next(pickups) == nil then Citizen.Wait(500) end - for k,v in pairs(Pickups) do - + 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() @@ -553,14 +522,12 @@ Citizen.CreateThread(function() }, v.label) end - if (closestDistance == -1 or closestDistance > 3) and distance <= 1.0 and not v.inRange and not IsPedSittingInAnyVehicle(playerPed) then + 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) @@ -569,7 +536,7 @@ Citizen.CreateThread(function() while true do Citizen.Wait(1000) - if ESX.PlayerLoaded and PlayerSpawned then + if ESX.PlayerLoaded and isPlayerSpawned then local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) @@ -585,8 +552,8 @@ Citizen.CreateThread(function() Citizen.Wait(1000) local playerPed = PlayerPedId() - if IsEntityDead(playerPed) and PlayerSpawned then - PlayerSpawned = false + if IsEntityDead(playerPed) and isPlayerSpawned then + isPlayerSpawned = false end end end) From 9fa0c12e02efcbec33c018e8c55801dd2c59df08 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 20 Jul 2019 13:09:42 +0200 Subject: [PATCH 332/672] =?UTF-8?q?Replaced=20MaxPlayers=20with=20GetActiv?= =?UTF-8?q?ePlayers=20for=20all=20babies=20=F0=9F=91=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/functions.lua | 10 ++++------ config.lua | 1 - 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index f7fc4107..083a4160 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -454,15 +454,13 @@ ESX.Game.GetClosestObject = function(filter, coords) end ESX.Game.GetPlayers = function() - local maxPlayers = Config.MaxPlayers - local players = {} + local players = {} - for i=0, maxPlayers, 1 do - - local ped = GetPlayerPed(i) + for _,player in ipairs(GetActivePlayers()) do + local ped = GetPlayerPed(player) if DoesEntityExist(ped) then - table.insert(players, i) + table.insert(players, player) end end diff --git a/config.lua b/config.lua index 95cd34be..223afade 100644 --- a/config.lua +++ b/config.lua @@ -10,6 +10,5 @@ Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) Config.PaycheckInterval = 7 * 60000 -Config.MaxPlayers = GetConvarInt('sv_maxclients', 32) -- set this value to 255 if you're running OneSync Config.EnableDebug = false From 63bdd6daef734c9478ca569926c3f33dd657b748 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 20 Jul 2019 14:34:13 +0200 Subject: [PATCH 333/672] Removed Show Dot Above Player --- client/main.lua | 17 ----------------- config.lua | 1 - 2 files changed, 18 deletions(-) diff --git a/client/main.lua b/client/main.lua index d7bb1f43..f04422d7 100644 --- a/client/main.lua +++ b/client/main.lua @@ -465,23 +465,6 @@ Citizen.CreateThread(function() end end) --- Dot above head -if Config.ShowDotAbovePlayer then - Citizen.CreateThread(function() - while true do - Citizen.Wait(1) - - local players = ESX.Game.GetPlayers() - for i = 1, #players, 1 do - if players[i] ~= PlayerId() then - local ped = GetPlayerPed(players[i]) - local headId = CreateMpGamerTag(ped, ('·'), false, false, '', false) - end - end - end - end) -end - -- Disable wanted level if Config.DisableWantedLevel then Citizen.CreateThread(function() diff --git a/config.lua b/config.lua index 223afade..453d052a 100644 --- a/config.lua +++ b/config.lua @@ -5,7 +5,6 @@ Config.Accounts = { 'bank', 'black_money' } Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society -Config.ShowDotAbovePlayer = false Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) From e850da085e694a17235501873d11635be2fa43c0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 30 Jul 2019 20:40:39 +0200 Subject: [PATCH 334/672] See description for changes Fixed the "health" problems on vehicles. It seems like you shouldn't use the `GetEntityHealth()` on vehicles at all since it is linked to the `GetVehicleBodyHealth()` native. But if you use the `SetEntityHealth()` native on an vehicle it breaks the link. Instead there's both body health and engine health that ESX has missed out on. Since the new used `GetVehicle***` natives return decimal values we round them to 1 decmial. Also dirt levels are now rounded to one decimal since they make 0 visable difference. --- client/functions.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 083a4160..3b54aee4 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -638,15 +638,15 @@ ESX.Game.GetVehicleProperties = function(vehicle) end return { - model = GetEntityModel(vehicle), plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)), plateIndex = GetVehicleNumberPlateTextIndex(vehicle), - health = GetEntityHealth(vehicle), - dirtLevel = GetVehicleDirtLevel(vehicle), + bodyHealth = ESX.Math.Round(GetVehicleBodyHealth(vehicle), 1), + engineHealth = ESX.Math.Round(GetVehicleEngineHealth(vehicle), 1), + dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), color1 = color1, color2 = color2, @@ -731,8 +731,12 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) end - if props.health ~= nil then - SetEntityHealth(vehicle, props.health) + if props.bodyHealth ~= nil then + SetVehicleBodyHealth(vehicle, props.bodyHealth) + end + + if props.engineHealth ~= nil then + SetVehicleEngineHealth(vehicle, props.engineHealth) end if props.dirtLevel ~= nil then From 44c05b8fae757870e3d4a37f0919da462d3d74ad Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 2 Aug 2019 11:33:10 +0200 Subject: [PATCH 335/672] Added fuel to veh properties and ensure decimal value --- client/functions.lua | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 3b54aee4..486d5551 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -646,6 +646,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) bodyHealth = ESX.Math.Round(GetVehicleBodyHealth(vehicle), 1), engineHealth = ESX.Math.Round(GetVehicleEngineHealth(vehicle), 1), + fuelLevel = ESX.Math.Round(GetVehicleFuelLevel(vehicle), 1), dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), color1 = color1, color2 = color2, @@ -732,15 +733,19 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end if props.bodyHealth ~= nil then - SetVehicleBodyHealth(vehicle, props.bodyHealth) + SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) end if props.engineHealth ~= nil then - SetVehicleEngineHealth(vehicle, props.engineHealth) + SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) + end + + if props.fuelLevel ~= nil then + SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end if props.dirtLevel ~= nil then - SetVehicleDirtLevel(vehicle, props.dirtLevel) + SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end if props.color1 ~= nil then From 06d3ee286f52169693b063164d1bed400e50680d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Aug 2019 14:55:04 +0200 Subject: [PATCH 336/672] Replaced for i= loops with ipairs --- client/main.lua | 65 +++++++++++++---------------- server/classes/player.lua | 86 +++++++++++++++++++-------------------- 2 files changed, 69 insertions(+), 82 deletions(-) diff --git a/client/main.lua b/client/main.lua index f04422d7..722d4041 100644 --- a/client/main.lua +++ b/client/main.lua @@ -8,15 +8,15 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) ESX.PlayerData = xPlayer if Config.EnableHud then - for i=1, #xPlayer.accounts, 1 do - local accountTpl = '
 {{money}}
' + for k,v in ipairs(xPlayer.accounts) do + local accountTpl = '
 {{money}}
' - ESX.UI.HUD.RegisterElement('account_' .. xPlayer.accounts[i].name, i-1, 0, accountTpl, { + ESX.UI.HUD.RegisterElement('account_' .. v.name, k - 1, 0, accountTpl, { money = 0 }) - ESX.UI.HUD.UpdateElement('account_' .. xPlayer.accounts[i].name, { - money = ESX.Math.GroupDigits(xPlayer.accounts[i].money) + ESX.UI.HUD.UpdateElement('account_' .. v.name, { + money = ESX.Math.GroupDigits(v.money) }) end @@ -81,22 +81,21 @@ AddEventHandler('esx:restoreLoadout', function() RemoveAllPedWeapons(playerPed, true) - for i=1, #ESX.PlayerData.loadout, 1 do - local weaponName = ESX.PlayerData.loadout[i].name + 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 j=1, #ESX.PlayerData.loadout[i].components, 1 do - local weaponComponent = ESX.PlayerData.loadout[i].components[j] - local componentHash = ESX.GetWeaponComponent(weaponName, weaponComponent).hash + 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, ESX.PlayerData.loadout[i].ammo) + AddAmmoToPed(playerPed, weaponHash, v.ammo) ammoTypes[ammoType] = true end end @@ -106,9 +105,9 @@ end) RegisterNetEvent('esx:setAccountMoney') AddEventHandler('esx:setAccountMoney', function(account) - for i=1, #ESX.PlayerData.accounts, 1 do - if ESX.PlayerData.accounts[i].name == account.name then - ESX.PlayerData.accounts[i] = account + for k,v in ipairs(ESX.PlayerData.accounts) do + if v.name == account.name then + ESX.PlayerData.accounts[k] = account break end end @@ -127,9 +126,9 @@ end) RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count) - for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item + for k,v in ipairs(ESX.PlayerData.inventory) do + if v.name == item.name then + ESX.PlayerData.inventory[k] = item break end end @@ -143,9 +142,9 @@ end) RegisterNetEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(item, count) - for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].name == item.name then - ESX.PlayerData.inventory[i] = item + for k,v in ipairs(ESX.PlayerData.inventory) do + if v.name == item.name then + ESX.PlayerData.inventory[k] = item break end end @@ -411,18 +410,17 @@ Citizen.CreateThread(function() isLoadoutLoaded = false end - for i=1, #Config.Weapons do - local weaponName = Config.Weapons[i].name + 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) - local components = Config.Weapons[i].components - for j=1, #components do - if HasPedGotWeaponComponent(playerPed, weaponHash, components[j].hash) then - table.insert(weaponComponents, components[j].name) + for k2,v2 in ipairs(v.components) do + if HasPedGotWeaponComponent(playerPed, weaponHash, v2.hash) then + table.insert(weaponComponents, v2.name) end end @@ -435,7 +433,7 @@ Citizen.CreateThread(function() table.insert(loadout, { name = weaponName, ammo = ammo, - label = Config.Weapons[i].label, + label = v.label, components = weaponComponents }) else @@ -480,7 +478,7 @@ if Config.DisableWantedLevel then end) end --- pickups +-- Pickups Citizen.CreateThread(function() while true do Citizen.Wait(0) @@ -518,23 +516,16 @@ end) Citizen.CreateThread(function() while true do Citizen.Wait(1000) + local playerPed = PlayerPedId() if ESX.PlayerLoaded and isPlayerSpawned then - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) + local coords = GetEntityCoords(playerPed) if not IsEntityDead(playerPed) then ESX.PlayerData.lastPosition = {x = coords.x, y = coords.y, z = coords.z} end end - end -end) -Citizen.CreateThread(function() - while true do - Citizen.Wait(1000) - - local playerPed = PlayerPedId() if IsEntityDead(playerPed) and isPlayerSpawned then isPlayerSpawned = false end diff --git a/server/classes/player.lua b/server/classes/player.lua index 5642c527..15bd7057 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -139,23 +139,19 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.getAccounts = function() local accounts = {} - for i=1, #Config.Accounts, 1 do - if Config.Accounts[i] == 'bank' then - + for k,v in ipairs(Config.Accounts) do + if v == 'bank' then table.insert(accounts, { name = 'bank', money = self.get('bank'), - label = Config.AccountLabels['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]) + for k2,v2 in ipairs(self.accounts) do + if v2 == v then + table.insert(accounts, v2) end end - end end @@ -167,13 +163,13 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return { name = 'bank', money = self.get('bank'), - label = Config.AccountLabels['bank'] + label = Config.AccountLabels.bank } end - for i=1, #self.accounts, 1 do - if self.accounts[i].name == a then - return self.accounts[i] + for k,v in ipairs(self.accounts) do + if v.name == a then + return v end end end @@ -213,24 +209,24 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.getMissingAccounts = function(cb) - MySQL.Async.fetchAll('SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT name 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 + for k,v in ipairs(Config.Accounts) do + if v ~= 'bank' then local found = false - for j=1, #result, 1 do - if Config.Accounts[i] == result[j].name then + for k2,v2 in ipairs(result) do + if v == v2.name then found = true break end end if not found then - table.insert(missingAccounts, Config.Accounts[i]) + table.insert(missingAccounts, v) end end end @@ -240,12 +236,12 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.createAccounts = function(missingAccounts, cb) - for i=1, #missingAccounts, 1 do - MySQL.Async.execute('INSERT INTO `user_accounts` (identifier, name) VALUES (@identifier, @name)', { + for k,v in ipairs(missingAccounts) do + MySQL.Async.execute('INSERT INTO user_accounts (identifier, name) VALUES (@identifier, @name)', { ['@identifier'] = self.getIdentifier(), - ['@name'] = missingAccounts[i] + ['@name'] = v }, function(rowsChanged) - if cb ~= nil then + if cb then cb() end end) @@ -308,9 +304,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.getInventoryItem = function(name) - for i=1, #self.inventory, 1 do - if self.inventory[i].name == name then - return self.inventory[i] + for k,v in ipairs(self.inventory) do + if v.name == name then + return v end end end @@ -366,11 +362,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.job.skin_male = {} self.job.skin_female = {} - if gradeObject.skin_male ~= nil then + if gradeObject.skin_male then self.job.skin_male = json.decode(gradeObject.skin_male) end - if gradeObject.skin_female ~= nil then + if gradeObject.skin_female then self.job.skin_female = json.decode(gradeObject.skin_female) end @@ -412,15 +408,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.removeWeapon = function(weaponName, ammo) local weaponLabel - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - weaponLabel = self.loadout[i].label + for k,v in ipairs(self.loadout) do + if v.name == weaponName then + weaponLabel = v.label - for j=1, #self.loadout[i].components, 1 do - TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, self.loadout[i].components[j]) + for k2,v2 in ipairs(v.components) do + TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, v2) end - table.remove(self.loadout, i) + table.remove(self.loadout, k) break end end @@ -438,9 +434,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return end - for i=1, #self.loadout[loadoutNum].components, 1 do - if self.loadout[loadoutNum].components.name == weaponComponent then - table.remove(self.loadout[loadoutNum].components, i) + for k,v in ipairs(self.loadout[loadoutNum].components) do + if v.name == weaponComponent then + table.remove(self.loadout[loadoutNum].components, k) break end end @@ -455,8 +451,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return false end - for i=1, #weapon.components, 1 do - if weapon.components[i] == weaponComponent then + for k,v in ipairs(weapon.components) do + if v == weaponComponent then return true end end @@ -465,8 +461,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.hasWeapon = function(weaponName) - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then + for k,v in ipairs(self.loadout) do + if v.name == weaponName then return true end end @@ -475,9 +471,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.getWeapon = function(weaponName) - for i=1, #self.loadout, 1 do - if self.loadout[i].name == weaponName then - return i, self.loadout[i] + for k,v in ipairs(self.loadout) do + if v.name == weaponName then + return k, v end end From 2e39e3d01a79d246738be266f8cad390767bad1c Mon Sep 17 00:00:00 2001 From: Viktor <35453587+LifeGoal@users.noreply.github.com> Date: Sun, 4 Aug 2019 16:47:33 +0200 Subject: [PATCH 337/672] Fixed loadout flaw when confiscated while dead --- client/main.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/client/main.lua b/client/main.lua index 722d4041..f7e0f47f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -406,10 +406,6 @@ Citizen.CreateThread(function() local loadout = {} local loadoutChanged = false - if IsPedDeadOrDying(playerPed) then - isLoadoutLoaded = false - end - for k,v in ipairs(Config.Weapons) do local weaponName = v.name local weaponHash = GetHashKey(weaponName) From adfb9f65229cb8f3859eecdf5838c9ebfa56a58f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Aug 2019 17:54:18 +0200 Subject: [PATCH 338/672] Fixed xplayer typo --- server/classes/player.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 15bd7057..bad6436c 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -148,7 +148,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l }) else for k2,v2 in ipairs(self.accounts) do - if v2 == v then + if v2.name == v then table.insert(accounts, v2) end end From 48cf1d56be977d6b78f0e75b893d73b4eb72dee3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 4 Aug 2019 17:54:46 +0200 Subject: [PATCH 339/672] removed old ESX.TableContainsValue --- common/functions.lua | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/common/functions.lua b/common/functions.lua index 755ae468..ed9deb82 100644 --- a/common/functions.lua +++ b/common/functions.lua @@ -59,16 +59,6 @@ ESX.GetWeaponComponent = function(weaponName, weaponComponent) end end -ESX.TableContainsValue = function(table, value) - for k, v in pairs(table) do - if v == value then - return true - end - end - - return false -end - ESX.DumpTable = function(table, nb) if nb == nil then nb = 0 From 5159e892fe1ecc5758600dbbaa342299206720db Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 10 Aug 2019 12:43:09 +0200 Subject: [PATCH 340/672] Removed unneeded backticks --- server/functions.lua | 6 +++--- server/main.lua | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/server/functions.lua b/server/functions.lua index 621692d8..351c0511 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -44,7 +44,7 @@ ESX.SavePlayer = function(xPlayer, cb) for i=1, #xPlayer.accounts, 1 do if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE user_accounts SET `money` = @money WHERE identifier = @identifier AND name = @name', { + 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 @@ -61,7 +61,7 @@ ESX.SavePlayer = function(xPlayer, cb) for i=1, #xPlayer.inventory, 1 do if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE user_inventory SET `count` = @count WHERE identifier = @identifier AND item = @item', { + 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 @@ -76,7 +76,7 @@ ESX.SavePlayer = function(xPlayer, cb) -- 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', { + 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.getLoadout()), diff --git a/server/main.lua b/server/main.lua index 3e42442a..57e4b615 100644 --- a/server/main.lua +++ b/server/main.lua @@ -14,7 +14,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) 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', { + MySQL.Async.execute('UPDATE users SET name = @name WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier(), ['@name'] = userData.playerName }, function(rowsChanged) @@ -24,7 +24,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get accounts table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT * FROM `user_accounts` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT * FROM user_accounts WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(accounts) for i=1, #Config.Accounts, 1 do @@ -47,7 +47,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get inventory table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT * FROM `user_inventory` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT * FROM user_inventory WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(inventory) local tasks2 = {} @@ -127,7 +127,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get job name, grade and last position table.insert(tasks2, function(cb2) - MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM `users` WHERE `identifier` = @identifier', { + MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(result) local job, grade = result[1].job, tostring(result[1].job_grade) From 8586fdcce24eb98ba06cab046424382483236fe0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 18 Sep 2019 13:47:41 +0200 Subject: [PATCH 341/672] Fix thrown items not synced with mid-joined players --- client/main.lua | 18 ++++++++++++++++++ server/functions.lua | 9 ++++++--- server/main.lua | 1 + 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 722d4041..b71d5cf1 100644 --- a/client/main.lua +++ b/client/main.lua @@ -40,6 +40,24 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) end end) +RegisterNetEvent('esx:createMissingPickups') +AddEventHandler('esx:createMissingPickups', function(pickups) + for pickupId,v in pairs(pickups) 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) diff --git a/server/functions.lua b/server/functions.lua index 351c0511..3ab80291 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -162,16 +162,19 @@ ESX.GetItemLabel = function(item) end end -ESX.CreatePickup = function(type, name, count, label, player) +ESX.CreatePickup = function(type, name, count, label, playerId) local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) + local xPlayer = ESX.GetPlayerFromId(playerId) ESX.Pickups[pickupId] = { type = type, name = name, - count = count + count = count, + label = label, + coords = xPlayer.getCoords() } - TriggerClientEvent('esx:pickup', -1, pickupId, label, player) + TriggerClientEvent('esx:pickup', -1, pickupId, label, playerId) ESX.PickupId = pickupId end diff --git a/server/main.lua b/server/main.lua index 57e4b615..86d7f2f4 100644 --- a/server/main.lua +++ b/server/main.lua @@ -234,6 +234,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) }) xPlayer.displayMoney(xPlayer.getMoney()) + TriggerClientEvent('esx:createMissingPickups', _source, ESX.Pickups) end) end) From 06952418bf3b5ae86fb7f7de3de2ada498b5f927 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 29 Sep 2019 11:30:21 +0200 Subject: [PATCH 342/672] DrawText3D: use SetDrawOrigin() instead of World3dToScreen2d() that was one frame behind --- client/functions.lua | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 486d5551..726c7311 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -984,32 +984,30 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end ESX.Game.Utils.DrawText3D = function(coords, text, size) - local onScreen, x, y = World3dToScreen2d(coords.x, coords.y, coords.z) - local camCoords = GetGameplayCamCoords() - local dist = GetDistanceBetweenCoords(camCoords, coords.x, coords.y, coords.z, true) - local size = size + coords = vector3(coords.x, coords.y, coords.z) - if size == nil then - size = 1 - end + local camCoords = GetGameplayCamCoords() + local distance = #(coords - camCoords) - local scale = (size / dist) * 2 - local fov = (1 / GetGameplayCamFov()) * 100 - local scale = scale * fov + if not size then size = 1 end + + local scale = (size / distance) * 2 + local fov = (1 / GetGameplayCamFov()) * 100 + scale = scale * fov - if onScreen then - SetTextScale(0.0 * scale, 0.55 * scale) - SetTextFont(0) - SetTextColour(255, 255, 255, 255) - SetTextDropshadow(0, 0, 0, 0, 255) - SetTextDropShadow() - SetTextOutline() - SetTextEntry('STRING') - SetTextCentre(1) + SetTextScale(0.0 * scale, 0.55 * scale) + SetTextFont(0) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0, 0, 0, 0, 255) + SetTextDropShadow() + SetTextOutline() + SetTextCentre(true) - AddTextComponentString(text) - DrawText(x, y) - end + SetDrawOrigin(coords, 0) + BeginTextCommandDisplayText('STRING') + AddTextComponentSubstringPlayerName(text) + EndTextCommandDisplayText(0.0, 0.0) + ClearDrawOrigin() end ESX.ShowInventory = function() From 8a7cf56497285285b76ed54157ea24766edf5bed Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 29 Sep 2019 11:30:42 +0200 Subject: [PATCH 343/672] xPlayer.getCoords() round to one decimal from ES --- server/classes/player.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index bad6436c..0c5158f8 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -41,7 +41,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.getCoords = function() - return self.player.get('coords') + local coords = self.player.get('coords') + return {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1)} end self.setCoords = function(x, y, z) From 4000e1eb34e5779c3020db2e91843da85b45efc7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 6 Oct 2019 20:29:21 +0200 Subject: [PATCH 344/672] Added DrawText3D() optional font argument --- client/functions.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 726c7311..a167c934 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -983,20 +983,21 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end end -ESX.Game.Utils.DrawText3D = function(coords, text, size) +ESX.Game.Utils.DrawText3D = function(coords, text, size, font) coords = vector3(coords.x, coords.y, coords.z) local camCoords = GetGameplayCamCoords() local distance = #(coords - camCoords) if not size then size = 1 end + if not font then font = 0 end local scale = (size / distance) * 2 local fov = (1 / GetGameplayCamFov()) * 100 scale = scale * fov SetTextScale(0.0 * scale, 0.55 * scale) - SetTextFont(0) + SetTextFont(font) SetTextColour(255, 255, 255, 255) SetTextDropshadow(0, 0, 0, 0, 255) SetTextDropShadow() From 546ac33b1a82bed78ada9e922a6324745c15a0c8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 6 Oct 2019 20:29:56 +0200 Subject: [PATCH 345/672] Added xPlayer .showNotification() and .showHelpNotification() --- server/classes/player.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server/classes/player.lua b/server/classes/player.lua index 0c5158f8..f4e75e1a 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -481,5 +481,13 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return nil end + self.showNotification = function(msg) + TriggerClientEvent('esx:showNotification', self.source, msg) + end + + self.showHelpNotification = function(msg) + TriggerClientEvent('esx:showHelpNotification', self.source, msg) + end + return self end From 322fb19034add1dfbcaf03c2e092ce73de7035bf Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 9 Oct 2019 21:55:44 +0200 Subject: [PATCH 346/672] Fixed #350 --- client/main.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index b4819a15..2950bcda 100644 --- a/client/main.lua +++ b/client/main.lua @@ -41,13 +41,13 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) end) RegisterNetEvent('esx:createMissingPickups') -AddEventHandler('esx:createMissingPickups', function(pickups) - for pickupId,v in pairs(pickups) do +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] = { + pickups[pickupId] = { id = pickupId, obj = obj, label = v.label, From f438ea21dbb4744c65b88cb6e9a7be977f02424a Mon Sep 17 00:00:00 2001 From: userMacieG Date: Fri, 11 Oct 2019 14:35:49 +0200 Subject: [PATCH 347/672] Update pl.lua --- locales/pl.lua | 61 +++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/locales/pl.lua b/locales/pl.lua index c898ca26..ee840465 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -5,20 +5,20 @@ Locales['pl'] = { ['use'] = 'użyj', ['give'] = 'daj', ['remove'] = 'usuń', - ['return'] = 'return', - ['give_to'] = 'give to', - ['amount'] = 'amount', - ['giveammo'] = 'give ammo', + ['return'] = 'wróć', + ['give_to'] = 'daj dla', + ['amount'] = 'ilość', + ['giveammo'] = 'daj amunicje', ['amountammo'] = 'ilość amunicji', - ['noammo'] = 'nie masz wystarczającej ilości amunicji!', + ['noammo'] = 'nie posiadasz wystarczającej ilości amunicji!', ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', - ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', + ['gave_weapon'] = 'dajesz ~y~1x~s~ ~b~%s~s~ dla ~y~%s~s~.', + ['gave_weapon_ammo'] = 'dałeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~.', + ['gave_weapon_hasalready'] = '~y~%s~s~ już posiada ~y~%s~s~', + ['received_weapon'] = 'otrzymałeś/aś ~y~1x~s~ ~b~%s~s~ od ~b~%s~s~.', + ['received_weapon_ammo'] = 'otrzymałeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~.', + ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno.', ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~.', ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~.', ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', @@ -30,11 +30,12 @@ Locales['pl'] = { ['ex_inv_lim'] = 'akcja nie jest możliwa, nie możesz mieć więcej ~y~%s~s~', ['imp_invalid_quantity'] = 'akcja jest niemożliwa, nieprawidłowa ilość', ['imp_invalid_amount'] = 'akcja jest niemożliwa, nieprawidłowa kwota', - ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_standard'] = 'wyrzuciłeś/aś ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~gotówki~s~', + ['threw_account'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'wyrzuciłeś/aś ~y~1x~s~ ~b~%s~s~', + ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami', + -- Salary related ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', @@ -42,14 +43,13 @@ Locales['pl'] = { ['received_paycheck'] = 'otrzymana wypłata', ['bank'] = 'bank', ['black_money'] = 'brudne pieniądze', - ['act_imp'] = 'działanie niemożliwe', ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', ['cannot_pickup_room'] = 'nie masz wystarczająco dużo miejsca w ekwipunku, aby podnieść ~y~%s~s~!', -- Commands ['setjob'] = 'przydziel prace użytkownikowi', - ['id_param'] = 'iD użyszkodnika', + ['id_param'] = 'ID użytkownika', ['setjob_param2'] = 'praca, którą chcesz przydzielić', ['setjob_param3'] = 'poziom pracy', ['load_ipl'] = 'załaduj IPL', @@ -76,11 +76,12 @@ Locales['pl'] = { ['weapon'] = 'broń', ['giveweapon'] = 'daj broń', ['disconnect'] = 'odłącz się od serwera', - ['chat_clear'] = 'clear the chat', - ['chat_clear_all'] = 'clear the chat for everyone', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + ['chat_clear'] = 'wyczyść czat', + ['chat_clear_all'] = 'wyczyść czat dla wszystkich', + ['command_clearinventory'] = 'usuń wszystkie przedmioty z ekwipunku', + ['command_clearloadout'] = 'usuń wszystkie bronie z wyposażenia', + ['command_playerid_param'] = 'id gracza lub zostaw puste dla siebie', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', @@ -167,14 +168,14 @@ Locales['pl'] = { ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', + ['component_clip_default'] = 'domyślny tłumik', + ['component_clip_extended'] = 'rozszerzony tłumik', ['component_clip_drum'] = 'drum Magazine', ['component_clip_box'] = 'box Magazine', - ['component_flashlight'] = 'flashlight', - ['component_scope'] = 'scope', - ['component_scope_advanced'] = 'advanced Scope', - ['component_suppressor'] = 'suppressor', - ['component_grip'] = 'grip', + ['component_flashlight'] = 'latarka', + ['component_scope'] = 'luneta', + ['component_scope_advanced'] = 'zaawansowana luneta', + ['component_suppressor'] = 'tłumik', + ['component_grip'] = 'uchwyt', ['component_luxary_finish'] = 'luxary Weapon Finish', } From 61fe6e7323aafdbbee7a4319e2642703c50bc3e9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Oct 2019 16:38:56 +0200 Subject: [PATCH 348/672] Removed ES links, see #356 --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 3c1d49ea..06cbe1ba 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ # es_extended -es_extended is a roleplay framework for FiveM. It is developed on top of [EssentialMode](https://essentialmode.com/) (aka ES), thus commonly named ESX - the **Es**sentialMode E**x**tended framework for FiveM. +es_extended is a roleplay framework for FiveM. It is developed on top of EssentialMode (aka ES), thus commonly named ESX - the **Es**sentialMode E**x**tended framework for FiveM. ### Links & Read more - [ESX Documentation](https://esx-org.github.io/) -- [ES Documentation](https://docs.essentialmode.com/) - [ESX Discord Community](https://discord.gg/MsWzPqE) - [FiveM Forum Thread](https://forum.fivem.net/t/release-esx-base/39881) - [FiveM Native Reference](https://runtime.fivem.net/doc/reference.html) @@ -13,7 +12,7 @@ es_extended is a roleplay framework for FiveM. It is developed on top of [Essent ![screenshot](http://i.imgur.com/aPFdJl3.jpg) ### Features -- Accounts (bank / black money). You can add further accounts +- Accounts (comes with bank / black money), you can add more accounts - Advanced inventory system (press `F2` ingame) - Job system - Loadouts and position synced in database @@ -78,7 +77,7 @@ start esx_menu_dialog ### License es_extended - EssentialMode Extended framework for FiveM -Copyright (C) 2015-2018 Jérémie N'gadi +Copyright (C) 2015-2019 Jérémie N'gadi This program Is free software: you can redistribute it And/Or modify it under the terms Of the GNU General Public License As published by the Free Software Foundation, either version 3 Of the License, Or (at your option) any later version. From 32e6c7edc216051d71750359cddb3d937a17c84c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Oct 2019 16:39:29 +0200 Subject: [PATCH 349/672] Added optional xPlayer.getCoords() argument to return vector3 type --- server/classes/player.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index f4e75e1a..6fc49b8a 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -40,9 +40,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return self.player.get('bank') end - self.getCoords = function() + self.getCoords = function(vectorType) local coords = self.player.get('coords') - return {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1)} + coords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1)} + + if vectorType then + return vector3(coords.x, coords.y, coords.z) + else + return coords + end end self.setCoords = function(x, y, z) From 0e5dda5779c9a9191bb0e8a9f02aef17ded4ac4a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Oct 2019 19:18:22 +0200 Subject: [PATCH 350/672] Added pvp to esx, fixes #302 --- client/main.lua | 9 ++++++--- config.lua | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 2950bcda..e829044f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -72,9 +72,12 @@ AddEventHandler('playerSpawned', function() TriggerEvent('esx:restoreLoadout') -- restore loadout - isLoadoutLoaded = true - isPlayerSpawned = true - isDead = false + isLoadoutLoaded, isPlayerSpawned, isDead = true, true, false + + if Config.EnablePvP then + SetCanAttackFriendly(playerPed, true, false) + NetworkSetFriendlyFireOption(true) + end end) AddEventHandler('esx:onPlayerDeath', function() diff --git a/config.lua b/config.lua index 453d052a..ee531780 100644 --- a/config.lua +++ b/config.lua @@ -7,6 +7,7 @@ Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) +Config.EnablePvP = true -- enable pvp? Config.PaycheckInterval = 7 * 60000 From 130df3f18f0e248623060a87399ed710022d715a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Oct 2019 20:20:12 +0200 Subject: [PATCH 351/672] Fixed notification 99 char limit by using TextEntry, fixes #286 You can also split up strings each 99 chars and still use AddTextComponentSubstringPlayerName --- client/functions.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index a167c934..75b9d68b 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -45,22 +45,22 @@ ESX.SetPlayerData = function(key, val) end ESX.ShowNotification = function(msg) - SetNotificationTextEntry('STRING') - AddTextComponentSubstringPlayerName(msg) + AddTextEntry('esxNotification', msg) + SetNotificationTextEntry('esxNotification') DrawNotification(false, true) end ESX.ShowAdvancedNotification = function(title, subject, msg, icon, iconType) - SetNotificationTextEntry('STRING') - AddTextComponentSubstringPlayerName(msg) + AddTextEntry('esxAdvancedNotification', msg) + SetNotificationTextEntry('esxAdvancedNotification') SetNotificationMessage(icon, icon, false, iconType, title, subject) DrawNotification(false, false) end ESX.ShowHelpNotification = function(msg) --if not IsHelpMessageBeingDisplayed() then - BeginTextCommandDisplayHelp('STRING') - AddTextComponentSubstringPlayerName(msg) + AddTextEntry('esxHelpNotification', msg) + BeginTextCommandDisplayHelp('esxHelpNotification') EndTextCommandDisplayHelp(0, false, true, -1) --end end From 145f8ebe755670dba185ce86ddcf2b0bca266926 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 13 Oct 2019 20:56:09 +0200 Subject: [PATCH 352/672] Breaking changes: implemented global weight inventory system, read description before updating! - Fixed #256 - Implements #173 __NO OFFICIAL ESX SCRIPT WILL WORK WITH THIS AT THE MOMENT__ This commit will break your entire ESX if you dont use the new SQL format, follow the new one if you want it all to work properly. Scripts using `item.limit` will break too, instead use `xPlayer.canCarryItem(item, count)` --- client/functions.lua | 491 ++++++++++++++--------------- client/main.lua | 20 +- config.lua | 1 + config.weapons.lua | 632 ++++++++++++-------------------------- es_extended.sql | 48 +-- locales/br.lua | 27 +- locales/cs.lua | 27 +- locales/de.lua | 23 +- locales/en.lua | 27 +- locales/fi.lua | 25 +- locales/fr.lua | 21 +- locales/pl.lua | 27 +- locales/sv.lua | 29 +- server/classes/player.lua | 82 +++-- server/common.lua | 32 +- server/main.lua | 178 +++++------ 16 files changed, 723 insertions(+), 967 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 75b9d68b..95b89359 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -157,14 +157,14 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, ESX.UI.Menu.RegisteredTypes[type].close(namespace, name) for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i] then 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 - if close ~= nil then + if close then close() end @@ -224,7 +224,7 @@ end ESX.UI.Menu.Close = function(type, namespace, name) for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i] then 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 @@ -235,7 +235,7 @@ end ESX.UI.Menu.CloseAll = function() for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i] then ESX.UI.Menu.Opened[i].close() ESX.UI.Menu.Opened[i] = nil end @@ -244,7 +244,7 @@ end ESX.UI.Menu.GetOpened = function(type, namespace, name) for i=1, #ESX.UI.Menu.Opened, 1 do - if ESX.UI.Menu.Opened[i] ~= nil then + if ESX.UI.Menu.Opened[i] then 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 @@ -289,7 +289,7 @@ ESX.Game.Teleport = function(entity, coords, cb) SetEntityCoords(entity, coords.x, coords.y, coords.z) - if cb ~= nil then + if cb then cb() end end @@ -302,7 +302,7 @@ ESX.Game.SpawnObject = function(model, coords, cb) local obj = CreateObject(model, coords.x, coords.y, coords.z, true, false, true) - if cb ~= nil then + if cb then cb(obj) end end) @@ -316,7 +316,7 @@ ESX.Game.SpawnLocalObject = function(model, coords, cb) local obj = CreateObject(model, coords.x, coords.y, coords.z, false, false, true) - if cb ~= nil then + if cb then cb(obj) end end) @@ -356,7 +356,7 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) SetVehRadioStation(vehicle, 'OFF') - if cb ~= nil then + if cb then cb(vehicle) end end) @@ -383,7 +383,7 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) SetVehRadioStation(vehicle, 'OFF') - if cb ~= nil then + if cb then cb(vehicle) end end) @@ -407,11 +407,9 @@ ESX.Game.GetObjects = function() end ESX.Game.GetClosestObject = function(filter, coords) - local objects = ESX.Game.GetObjects() - local closestDistance = -1 - local closestObject = -1 - local filter = filter - local coords = coords + local objects = ESX.Game.GetObjects() + local closestDistance, closestObject = -1, -1 + local filter, coords = filter, coords if type(filter) == 'string' then if filter ~= '' then @@ -419,9 +417,11 @@ ESX.Game.GetClosestObject = function(filter, coords) end end - if coords == nil then + if coords then + coords = vector3(coords.x, coords.y, coords.z) + else local playerPed = PlayerPedId() - coords = GetEntityCoords(playerPed) + coords = GetEntityCoords(playerPed) end for i=1, #objects, 1 do @@ -435,16 +435,17 @@ ESX.Game.GetClosestObject = function(filter, coords) for j=1, #filter, 1 do if objectModel == GetHashKey(filter[j]) then foundObject = true + break end end end if foundObject then local objectCoords = GetEntityCoords(objects[i]) - local distance = GetDistanceBetweenCoords(objectCoords, coords.x, coords.y, coords.z, true) + local distance = #(objectCoords - coords) if closestDistance == -1 or closestDistance > distance then - closestObject = objects[i] + closestObject = objects[i] closestDistance = distance end end @@ -468,17 +469,15 @@ ESX.Game.GetPlayers = function() end ESX.Game.GetClosestPlayer = function(coords) - local players = ESX.Game.GetPlayers() - local closestDistance = -1 - local closestPlayer = -1 - local coords = coords - local usePlayerPed = false - local playerPed = PlayerPedId() - local playerId = PlayerId() + local players, closestDistance, closestPlayer = ESX.Game.GetPlayers(), -1, -1 + local coords, usePlayerPed = coords, false + local playerPed, playerId = PlayerPedId(), PlayerId() - if coords == nil then + if coords then + coords = vector3(coords.x, coords.y, coords.z) + else usePlayerPed = true - coords = GetEntityCoords(playerPed) + coords = GetEntityCoords(playerPed) end for i=1, #players, 1 do @@ -486,10 +485,10 @@ ESX.Game.GetClosestPlayer = function(coords) if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then local targetCoords = GetEntityCoords(target) - local distance = GetDistanceBetweenCoords(targetCoords, coords.x, coords.y, coords.z, true) + local distance = #(coords - targetCoords) if closestDistance == -1 or closestDistance > distance then - closestPlayer = players[i] + closestPlayer = players[i] closestDistance = distance end end @@ -724,66 +723,66 @@ end ESX.Game.SetVehicleProperties = function(vehicle, props) SetVehicleModKit(vehicle, 0) - if props.plate ~= nil then + if props.plate then SetVehicleNumberPlateText(vehicle, props.plate) end - if props.plateIndex ~= nil then + if props.plateIndex then SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) end - if props.bodyHealth ~= nil then + if props.bodyHealth then SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) end - if props.engineHealth ~= nil then + if props.engineHealth then SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) end - if props.fuelLevel ~= nil then + if props.fuelLevel then SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end - if props.dirtLevel ~= nil then + if props.dirtLevel then SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end - if props.color1 ~= nil then + if props.color1 then local color1, color2 = GetVehicleColours(vehicle) SetVehicleColours(vehicle, props.color1, color2) end - if props.color2 ~= nil then + if props.color2 then local color1, color2 = GetVehicleColours(vehicle) SetVehicleColours(vehicle, color1, props.color2) end - if props.pearlescentColor ~= nil then + if props.pearlescentColor then local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) end - if props.wheelColor ~= nil then + if props.wheelColor then local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) end - if props.wheels ~= nil then + if props.wheels then SetVehicleWheelType(vehicle, props.wheels) end - if props.windowTint ~= nil then + if props.windowTint then SetVehicleWindowTint(vehicle, props.windowTint) end - if props.neonEnabled ~= nil then + if props.neonEnabled then SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) end - if props.extras ~= nil then + if props.extras then for id,enabled in pairs(props.extras) do if enabled then SetVehicleExtra(vehicle, tonumber(id), 0) @@ -793,191 +792,191 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end end - if props.neonColor ~= nil then + if props.neonColor then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end - if props.modSmokeEnabled ~= nil then + if props.modSmokeEnabled then ToggleVehicleMod(vehicle, 20, true) end - if props.tyreSmokeColor ~= nil then + if props.tyreSmokeColor then SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) end - if props.modSpoilers ~= nil then + if props.modSpoilers then SetVehicleMod(vehicle, 0, props.modSpoilers, false) end - if props.modFrontBumper ~= nil then + if props.modFrontBumper then SetVehicleMod(vehicle, 1, props.modFrontBumper, false) end - if props.modRearBumper ~= nil then + if props.modRearBumper then SetVehicleMod(vehicle, 2, props.modRearBumper, false) end - if props.modSideSkirt ~= nil then + if props.modSideSkirt then SetVehicleMod(vehicle, 3, props.modSideSkirt, false) end - if props.modExhaust ~= nil then + if props.modExhaust then SetVehicleMod(vehicle, 4, props.modExhaust, false) end - if props.modFrame ~= nil then + if props.modFrame then SetVehicleMod(vehicle, 5, props.modFrame, false) end - if props.modGrille ~= nil then + if props.modGrille then SetVehicleMod(vehicle, 6, props.modGrille, false) end - if props.modHood ~= nil then + if props.modHood then SetVehicleMod(vehicle, 7, props.modHood, false) end - if props.modFender ~= nil then + if props.modFender then SetVehicleMod(vehicle, 8, props.modFender, false) end - if props.modRightFender ~= nil then + if props.modRightFender then SetVehicleMod(vehicle, 9, props.modRightFender, false) end - if props.modRoof ~= nil then + if props.modRoof then SetVehicleMod(vehicle, 10, props.modRoof, false) end - if props.modEngine ~= nil then + if props.modEngine then SetVehicleMod(vehicle, 11, props.modEngine, false) end - if props.modBrakes ~= nil then + if props.modBrakes then SetVehicleMod(vehicle, 12, props.modBrakes, false) end - if props.modTransmission ~= nil then + if props.modTransmission then SetVehicleMod(vehicle, 13, props.modTransmission, false) end - if props.modHorns ~= nil then + if props.modHorns then SetVehicleMod(vehicle, 14, props.modHorns, false) end - if props.modSuspension ~= nil then + if props.modSuspension then SetVehicleMod(vehicle, 15, props.modSuspension, false) end - if props.modArmor ~= nil then + if props.modArmor then SetVehicleMod(vehicle, 16, props.modArmor, false) end - if props.modTurbo ~= nil then + if props.modTurbo then ToggleVehicleMod(vehicle, 18, props.modTurbo) end - if props.modXenon ~= nil then + if props.modXenon then ToggleVehicleMod(vehicle, 22, props.modXenon) end - if props.modFrontWheels ~= nil then + if props.modFrontWheels then SetVehicleMod(vehicle, 23, props.modFrontWheels, false) end - if props.modBackWheels ~= nil then + if props.modBackWheels then SetVehicleMod(vehicle, 24, props.modBackWheels, false) end - if props.modPlateHolder ~= nil then + if props.modPlateHolder then SetVehicleMod(vehicle, 25, props.modPlateHolder, false) end - if props.modVanityPlate ~= nil then + if props.modVanityPlate then SetVehicleMod(vehicle, 26, props.modVanityPlate, false) end - if props.modTrimA ~= nil then + if props.modTrimA then SetVehicleMod(vehicle, 27, props.modTrimA, false) end - if props.modOrnaments ~= nil then + if props.modOrnaments then SetVehicleMod(vehicle, 28, props.modOrnaments, false) end - if props.modDashboard ~= nil then + if props.modDashboard then SetVehicleMod(vehicle, 29, props.modDashboard, false) end - if props.modDial ~= nil then + if props.modDial then SetVehicleMod(vehicle, 30, props.modDial, false) end - if props.modDoorSpeaker ~= nil then + if props.modDoorSpeaker then SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) end - if props.modSeats ~= nil then + if props.modSeats then SetVehicleMod(vehicle, 32, props.modSeats, false) end - if props.modSteeringWheel ~= nil then + if props.modSteeringWheel then SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) end - if props.modShifterLeavers ~= nil then + if props.modShifterLeavers then SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) end - if props.modAPlate ~= nil then + if props.modAPlate then SetVehicleMod(vehicle, 35, props.modAPlate, false) end - if props.modSpeakers ~= nil then + if props.modSpeakers then SetVehicleMod(vehicle, 36, props.modSpeakers, false) end - if props.modTrunk ~= nil then + if props.modTrunk then SetVehicleMod(vehicle, 37, props.modTrunk, false) end - if props.modHydrolic ~= nil then + if props.modHydrolic then SetVehicleMod(vehicle, 38, props.modHydrolic, false) end - if props.modEngineBlock ~= nil then + if props.modEngineBlock then SetVehicleMod(vehicle, 39, props.modEngineBlock, false) end - if props.modAirFilter ~= nil then + if props.modAirFilter then SetVehicleMod(vehicle, 40, props.modAirFilter, false) end - if props.modStruts ~= nil then + if props.modStruts then SetVehicleMod(vehicle, 41, props.modStruts, false) end - if props.modArchCover ~= nil then + if props.modArchCover then SetVehicleMod(vehicle, 42, props.modArchCover, false) end - if props.modAerials ~= nil then + if props.modAerials then SetVehicleMod(vehicle, 43, props.modAerials, false) end - if props.modTrimB ~= nil then + if props.modTrimB then SetVehicleMod(vehicle, 44, props.modTrimB, false) end - if props.modTank ~= nil then + if props.modTank then SetVehicleMod(vehicle, 45, props.modTank, false) end - if props.modWindows ~= nil then + if props.modWindows then SetVehicleMod(vehicle, 46, props.modWindows, false) end - if props.modLivery ~= nil then + if props.modLivery then SetVehicleMod(vehicle, 48, props.modLivery, false) SetVehicleLivery(vehicle, props.modLivery) end @@ -1013,7 +1012,7 @@ end ESX.ShowInventory = function() local playerPed = PlayerPedId() - local elements = {} + local elements, currentWeight = {}, 0 if ESX.PlayerData.money > 0 then local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(ESX.PlayerData.money)) @@ -1029,16 +1028,16 @@ ESX.ShowInventory = function() }) end - for i=1, #ESX.PlayerData.accounts, 1 do - if ESX.PlayerData.accounts[i].money > 0 then - local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(ESX.PlayerData.accounts[i].money)) - local canDrop = ESX.PlayerData.accounts[i].name ~= 'bank' + for k,v in pairs(ESX.PlayerData.accounts) do + if v.money > 0 then + local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(v.money)) + local canDrop = v.name ~= 'bank' table.insert(elements, { - label = ('%s: %s'):format(ESX.PlayerData.accounts[i].label, formattedMoney), - count = ESX.PlayerData.accounts[i].money, + label = ('%s: %s'):format(v.label, formattedMoney), + count = v.money, type = 'item_account', - value = ESX.PlayerData.accounts[i].name, + value = v.name, usable = false, rare = false, canRemove = canDrop @@ -1046,30 +1045,32 @@ ESX.ShowInventory = function() end end - for i=1, #ESX.PlayerData.inventory, 1 do - if ESX.PlayerData.inventory[i].count > 0 then + for k,v in ipairs(ESX.PlayerData.inventory) do + if v.count > 0 then + currentWeight = currentWeight + (v.weight * v.count) table.insert(elements, { - label = ESX.PlayerData.inventory[i].label .. ' x' .. ESX.PlayerData.inventory[i].count, - count = ESX.PlayerData.inventory[i].count, + label = ('%s x%s'):format(v.label, v.count), + count = v.count, type = 'item_standard', - value = ESX.PlayerData.inventory[i].name, - usable = ESX.PlayerData.inventory[i].usable, - rare = ESX.PlayerData.inventory[i].rare, - canRemove = ESX.PlayerData.inventory[i].canRemove + value = v.name, + usable = v.usable, + rare = v.rare, + canRemove = v.canRemove }) end end - for i=1, #Config.Weapons, 1 do - local weaponHash = GetHashKey(Config.Weapons[i].name) + for k,v in ipairs(Config.Weapons) do + local weaponHash = GetHashKey(v.name) - if HasPedGotWeapon(playerPed, weaponHash, false) and Config.Weapons[i].name ~= 'WEAPON_UNARMED' then + if HasPedGotWeapon(playerPed, weaponHash, false) then local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + table.insert(elements, { - label = Config.Weapons[i].label .. ' [' .. ammo .. ']', + label = ('%s [%s]'):format(v.label, ammo), count = 1, type = 'item_weapon', - value = Config.Weapons[i].name, + value = v.name, ammo = ammo, usable = false, rare = false, @@ -1080,14 +1081,12 @@ ESX.ShowInventory = function() ESX.UI.Menu.CloseAll() - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory', - { - title = _U('inventory'), + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory', { + title = _U('inventory', currentWeight, ESX.PlayerData.maxWeight), align = 'bottom-right', - elements = elements, + elements = elements }, function(data, menu) menu.close() - local player, distance = ESX.Game.GetClosestPlayer() local elements = {} @@ -1104,207 +1103,169 @@ ESX.ShowInventory = function() end if data.current.type == 'item_weapon' and data.current.ammo > 0 and player ~= -1 and distance <= 3.0 then - table.insert(elements, {label = _U('giveammo'), action = 'giveammo', type = data.current.type, value = data.current.value}) + table.insert(elements, {label = _U('giveammo'), action = 'give_ammo', type = data.current.type, value = data.current.value}) end table.insert(elements, {label = _U('return'), action = 'return'}) - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory_item', - { + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'inventory_item', { title = data.current.label, align = 'bottom-right', elements = elements, }, function(data1, menu1) - local item = data1.current.value local type = data1.current.type - local playerPed = PlayerPedId() if data1.current.action == 'give' then + local playersInArea = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) + local foundPlayers, elements = false, {} - local players = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) - local foundPlayers = false - local elements = {} - - for i=1, #players, 1 do - if players[i] ~= PlayerId() then + for k,v in ipairs(playersInArea) do + if v ~= PlayerId() then foundPlayers = true table.insert(elements, { - label = GetPlayerName(players[i]), - player = players[i] + label = GetPlayerName(v), + player = v }) end end - if not foundPlayers then + if foundPlayers then + foundPlayers = false + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'give_item_to', { + title = _U('give_to'), + align = 'bottom-right', + elements = elements + }, function(data2, menu2) + local playersInArea, nearbyPlayer = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) + + for k,v in ipairs(playersInArea) do + if v ~= PlayerId() then + + if v == data2.current.player then + foundPlayers = true + nearbyPlayer = v + break + end + end + end + + if foundPlayers then + if type == 'item_weapon' then + local closestPed = GetPlayerPed(nearbyPlayer) + local sourceAmmo = GetAmmoInPedWeapon(playerPed, GetHashKey(item)) + + if IsPedOnFoot(closestPed) then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, sourceAmmo) + menu2.close() + menu1.close() + else + ESX.ShowNotification(_U('in_vehicle')) + end + else + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { + title = _U('amount') + }, function(data3, menu3) + local quantity = tonumber(data3.value) + local closestPed = GetPlayerPed(nearbyPlayer) + + if IsPedOnFoot(closestPed) then + if quantity then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, quantity) + menu3.close() + menu2.close() + menu1.close() + else + ESX.ShowNotification(_U('amount_invalid')) + end + else + ESX.ShowNotification(_U('in_vehicle')) + end + end, function(data3, menu3) + menu3.close() + end) + end + else + ESX.ShowNotification(_U('players_nearby')) + menu2.close() + end + end, function(data2, menu2) + menu2.close() + end) -- give end + else ESX.ShowNotification(_U('players_nearby')) - return end - - foundPlayers = false - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'give_item_to', - { - title = _U('give_to'), - align = 'bottom-right', - elements = elements - }, function(data2, menu2) - - local players, nearbyPlayer = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) - - for i=1, #players, 1 do - if players[i] ~= PlayerId() then - - if players[i] == data2.current.player then - foundPlayers = true - nearbyPlayer = players[i] - break - end - end - end - - if not foundPlayers then - ESX.ShowNotification(_U('players_nearby')) - menu2.close() - return - end - + elseif data1.current.action == 'remove' then + if IsPedOnFoot(playerPed) then if type == 'item_weapon' then - - local closestPed = GetPlayerPed(nearbyPlayer) - local sourceAmmo = GetAmmoInPedWeapon(PlayerPedId(), GetHashKey(item)) - - if IsPedSittingInAnyVehicle(closestPed) then - ESX.ShowNotification(_U('in_vehicle')) - return - end - - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, sourceAmmo) - menu2.close() + TriggerServerEvent('esx:removeInventoryItem', type, item) menu1.close() - - else - - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { + else -- type: item_standard + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { title = _U('amount') - }, function(data3, menu3) - local quantity = tonumber(data3.value) - local closestPed = GetPlayerPed(nearbyPlayer) - - if IsPedSittingInAnyVehicle(closestPed) then - ESX.ShowNotification(_U('in_vehicle')) - return - end - - if quantity ~= nil then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, quantity) - - menu3.close() + }, function(data2, menu2) + local quantity = tonumber(data2.value) + + if quantity then + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) menu2.close() menu1.close() else ESX.ShowNotification(_U('amount_invalid')) end - - end, function(data3, menu3) - menu3.close() + end, function(data2, menu2) + menu2.close() end) end - end, function(data2, menu2) - menu2.close() - end) -- give end - - elseif data1.current.action == 'remove' then - - if IsPedSittingInAnyVehicle(playerPed) then - return end - - if type == 'item_weapon' then - - TriggerServerEvent('esx:removeInventoryItem', type, item) - menu1.close() - - else -- type: item_standard - - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { - title = _U('amount') - }, function(data2, menu2) - local quantity = tonumber(data2.value) - - if quantity == nil then - ESX.ShowNotification(_U('amount_invalid')) - else - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) - menu2.close() - menu1.close() - end - - end, function(data2, menu2) - menu2.close() - end) - end - elseif data1.current.action == 'use' then TriggerServerEvent('esx:useItem', item) - elseif data1.current.action == 'return' then ESX.UI.Menu.CloseAll() ESX.ShowInventory() - elseif data1.current.action == 'giveammo' then + elseif data1.current.action == 'give_ammo' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() local closestPed = GetPlayerPed(closestPlayer) local pedAmmo = GetAmmoInPedWeapon(playerPed, GetHashKey(item)) - if IsPedSittingInAnyVehicle(closestPed) then - ESX.ShowNotification(_U('in_vehicle')) - return - end - - if closestPlayer ~= -1 and closestDistance < 3.0 then - if pedAmmo > 0 then - - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { - title = _U('amountammo') - }, function(data2, menu2) - - local quantity = tonumber(data2.value) - - if quantity ~= nil then - if quantity <= pedAmmo and quantity >= 0 then - - local finalAmmoSource = math.floor(pedAmmo - quantity) - SetPedAmmo(playerPed, item, finalAmmoSource) - AddAmmoToPed(closestPed, item, quantity) - - ESX.ShowNotification(_U('gave_ammo', quantity, GetPlayerName(closestPlayer))) - -- todo notify target that he received ammo - menu2.close() - menu1.close() + if IsPedOnFoot(closestPed) then + if closestPlayer ~= -1 and closestDistance < 3.0 then + if pedAmmo > 0 then + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { + title = _U('amountammo') + }, function(data2, menu2) + local quantity = tonumber(data2.value) + + if quantity then + if pedAmmo >= quantity and quantity > 0 then + TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), 'item_ammo', item, quantity) + menu2.close() + menu1.close() + else + ESX.ShowNotification(_U('noammo')) + end else - ESX.ShowNotification(_U('noammo')) + ESX.ShowNotification(_U('amount_invalid')) end - else - ESX.ShowNotification(_U('amount_invalid')) - end - - end, function(data2, menu2) - menu2.close() - end) + end, function(data2, menu2) + menu2.close() + end) + else + ESX.ShowNotification(_U('noammo')) + end else - ESX.ShowNotification(_U('noammo')) + ESX.ShowNotification(_U('players_nearby')) end else - ESX.ShowNotification(_U('players_nearby')) + ESX.ShowNotification(_U('in_vehicle')) end end - end, function(data1, menu1) ESX.UI.Menu.CloseAll() ESX.ShowInventory() end) - end, function(data, menu) menu.close() end) diff --git a/client/main.lua b/client/main.lua index e829044f..9c8019c3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -40,6 +40,11 @@ AddEventHandler('esx:playerLoaded', function(xPlayer) 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 @@ -200,6 +205,14 @@ AddEventHandler('esx:addWeaponComponent', function(weaponName, weaponComponent) 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() @@ -256,7 +269,6 @@ end) RegisterNetEvent('esx:loadIPL') AddEventHandler('esx:loadIPL', function(name) Citizen.CreateThread(function() - LoadMpDlcMaps() RequestIpl(name) end) end) @@ -342,11 +354,7 @@ AddEventHandler('esx:pickup', function(id, label, player) obj = obj, label = label, inRange = false, - coords = { - x = x, - y = y, - z = z - } + coords = {x = x, y = y, z = z} } end) end) diff --git a/config.lua b/config.lua index ee531780..a332cf44 100644 --- a/config.lua +++ b/config.lua @@ -8,6 +8,7 @@ Config.EnableSocietyPayouts = false -- pay from the society account that the pla Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) Config.EnablePvP = true -- enable pvp? +Config.MaxWeight = 24 -- the max inventory weight without backpack Config.PaycheckInterval = 7 * 60000 diff --git a/config.weapons.lua b/config.weapons.lua index 320a9da5..8dd7676c 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -1,50 +1,20 @@ Config.Weapons = { - - { - name = 'WEAPON_KNIFE', - label = _U('weapon_knife'), - components = {} - }, - - { - name = 'WEAPON_NIGHTSTICK', - label = _U('weapon_nightstick'), - components = {} - }, - - { - name = 'WEAPON_HAMMER', - label = _U('weapon_hammer'), - components = {} - }, - - { - name = 'WEAPON_BAT', - label = _U('weapon_bat'), - components = {} - }, - - { - name = 'WEAPON_GOLFCLUB', - label = _U('weapon_golfclub'), - components = {} - }, - - { - name = 'WEAPON_CROWBAR', - label = _U('weapon_crowbar'), - components = {} - }, + {name = 'WEAPON_KNIFE', label = _U('weapon_knife'), components = {}}, + {name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick'), components = {}}, + {name = 'WEAPON_HAMMER', label = _U('weapon_hammer'), components = {}}, + {name = 'WEAPON_BAT', label = _U('weapon_bat'), components = {}}, + {name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub'), components = {}}, + {name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar'), components = {}}, { name = 'WEAPON_PISTOL', label = _U('weapon_pistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PISTOL_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PISTOL_VARMOD_LUXE')} } }, @@ -52,11 +22,11 @@ Config.Weapons = { name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_COMBATPISTOL_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_COMBATPISTOL_VARMOD_LOWRIDER')} } }, @@ -64,11 +34,11 @@ Config.Weapons = { name = 'WEAPON_APPISTOL', label = _U('weapon_appistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_APPISTOL_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_APPISTOL_VARMOD_LUXE')} } }, @@ -76,27 +46,23 @@ Config.Weapons = { name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PISTOL50_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PISTOL50_VARMOD_LUXE')} } }, - { - name = 'WEAPON_REVOLVER', - label = _U('weapon_revolver'), - components = {} - }, + {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver'), components = {}}, { name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SNSPISTOL_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SNSPISTOL_VARMOD_LOWRIDER')} } }, @@ -104,11 +70,11 @@ Config.Weapons = { name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_VARMOD_LUXE')} } }, @@ -116,9 +82,9 @@ Config.Weapons = { name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_02') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_02')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')} } }, @@ -126,12 +92,12 @@ Config.Weapons = { name = 'WEAPON_MICROSMG', label = _U('weapon_microsmg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MICROSMG_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MICROSMG_VARMOD_LUXE')} } }, @@ -139,13 +105,13 @@ Config.Weapons = { name = 'WEAPON_SMG', label = _U('weapon_smg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SMG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SMG_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_SMG_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO_02') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SMG_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SMG_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_SMG_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO_02')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SMG_VARMOD_LUXE')} } }, @@ -153,12 +119,12 @@ Config.Weapons = { name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ASSAULTSMG_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ASSAULTSMG_VARMOD_LOWRIDER')} } }, @@ -166,8 +132,8 @@ Config.Weapons = { name = 'WEAPON_MINISMG', label = _U('weapon_minismg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_02') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_02')} } }, @@ -175,10 +141,10 @@ Config.Weapons = { name = 'WEAPON_MACHINEPISTOL', label = _U('weapon_machinepistol'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_03') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_03')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')} } }, @@ -186,12 +152,12 @@ Config.Weapons = { name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL')} } }, @@ -199,9 +165,9 @@ Config.Weapons = { name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun'), components = { - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_SR_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PUMPSHOTGUN_VARMOD_LOWRIDER') } + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_SR_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_PUMPSHOTGUN_VARMOD_LOWRIDER')} } }, @@ -209,7 +175,7 @@ Config.Weapons = { name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun'), components = { - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SAWNOFFSHOTGUN_VARMOD_LUXE') } + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SAWNOFFSHOTGUN_VARMOD_LUXE')} } }, @@ -217,11 +183,11 @@ Config.Weapons = { name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')} } }, @@ -229,9 +195,9 @@ Config.Weapons = { name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun'), components = { - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') } + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')} } }, @@ -239,12 +205,12 @@ Config.Weapons = { name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')} } }, @@ -252,14 +218,14 @@ Config.Weapons = { name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_VARMOD_LUXE')} } }, @@ -267,14 +233,14 @@ Config.Weapons = { name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_02') }, - { name = 'clip_box', label = _U('component_clip_box'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_CARBINERIFLE_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_02')}, + {name = 'clip_box', label = _U('component_clip_box'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_CARBINERIFLE_VARMOD_LUXE')} } }, @@ -282,12 +248,12 @@ Config.Weapons = { name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_VARMOD_LUXE')} } }, @@ -295,14 +261,14 @@ Config.Weapons = { name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_03') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_03')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_VARMOD_LOWRIDER')} } }, @@ -310,13 +276,13 @@ Config.Weapons = { name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_VARMOD_LOW') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_VARMOD_LOW')} } }, @@ -324,9 +290,9 @@ Config.Weapons = { name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_02') }, - { name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_03') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_03')} } }, @@ -334,10 +300,10 @@ Config.Weapons = { name = 'WEAPON_MG', label = _U('weapon_mg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MG_CLIP_02') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MG_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MG_CLIP_02')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MG_VARMOD_LOWRIDER')} } }, @@ -345,11 +311,11 @@ Config.Weapons = { name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_02') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_COMBATMG_VARMOD_LOWRIDER') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_02')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MEDIUM')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_COMBATMG_VARMOD_LOWRIDER')} } }, @@ -357,8 +323,8 @@ Config.Weapons = { name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_02') }, + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_02')}, } }, @@ -366,10 +332,10 @@ Config.Weapons = { name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle'), components = { - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE') }, - { name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SNIPERRIFLE_VARMOD_LUXE') } + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, + {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SNIPERRIFLE_VARMOD_LUXE')} } }, @@ -377,8 +343,8 @@ Config.Weapons = { name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper'), components = { - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE') }, - { name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX') } + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, + {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')} } }, @@ -386,266 +352,56 @@ Config.Weapons = { name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle'), components = { - { name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_01') }, - { name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_02') }, - { name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH') }, - { name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE_FIXED_ZOOM') }, - { name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP') }, - { name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP') }, - { name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_VARMOD_LUXE') } + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE_FIXED_ZOOM')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP')}, + {name = 'grip', label = _U('component_grip'), hash = GetHashKey('COMPONENT_AT_AR_AFGRIP')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_VARMOD_LUXE')} } }, - { - name = 'WEAPON_GRENADELAUNCHER', - label = _U('weapon_grenadelauncher'), - components = {} - }, - - { - name = 'WEAPON_RPG', - label = _U('weapon_rpg'), - components = {} - }, - - { - name = 'WEAPON_STINGER', - label = _U('weapon_stinger'), - components = {} - }, - - { - name = 'WEAPON_MINIGUN', - label = _U('weapon_minigun'), - components = {} - }, - - { - name = 'WEAPON_GRENADE', - label = _U('weapon_grenade'), - components = {} - }, - - { - name = 'WEAPON_STICKYBOMB', - label = _U('weapon_stickybomb'), - components = {} - }, - - { - name = 'WEAPON_SMOKEGRENADE', - label = _U('weapon_smokegrenade'), - components = {} - }, - - { - name = 'WEAPON_BZGAS', - label = _U('weapon_bzgas'), - components = {} - }, - - { - name = 'WEAPON_MOLOTOV', - label = _U('weapon_molotov'), - components = {} - }, - - { - name = 'WEAPON_FIREEXTINGUISHER', - label = _U('weapon_fireextinguisher'), - components = {} - }, - - { - name = 'WEAPON_PETROLCAN', - label = _U('weapon_petrolcan'), - components = {} - }, - - { - name = 'WEAPON_DIGISCANNER', - label = _U('weapon_digiscanner'), - components = {} - }, - - { - name = 'WEAPON_BALL', - label = _U('weapon_ball'), - components = {} - }, - - { - name = 'WEAPON_BOTTLE', - label = _U('weapon_bottle'), - components = {} - }, - - { - name = 'WEAPON_DAGGER', - label = _U('weapon_dagger'), - components = {} - }, - - { - name = 'WEAPON_FIREWORK', - label = _U('weapon_firework'), - components = {} - }, - - { - name = 'WEAPON_MUSKET', - label = _U('weapon_musket'), - components = {} - }, - - { - name = 'WEAPON_STUNGUN', - label = _U('weapon_stungun'), - components = {} - }, - - { - name = 'WEAPON_HOMINGLAUNCHER', - label = _U('weapon_hominglauncher'), - components = {} - }, - - { - name = 'WEAPON_PROXMINE', - label = _U('weapon_proxmine'), - components = {} - }, - - { - name = 'WEAPON_SNOWBALL', - label = _U('weapon_snowball'), - components = {} - }, - - { - name = 'WEAPON_FLAREGUN', - label = _U('weapon_flaregun'), - components = {} - }, - - { - name = 'WEAPON_GARBAGEBAG', - label = _U('weapon_garbagebag'), - components = {} - }, - - { - name = 'WEAPON_HANDCUFFS', - label = _U('weapon_handcuffs'), - components = {} - }, - - { - name = 'WEAPON_MARKSMANPISTOL', - label = _U('weapon_marksmanpistol'), - components = {} - }, - - { - name = 'WEAPON_KNUCKLE', - label = _U('weapon_knuckle'), - components = {} - }, - - { - name = 'WEAPON_HATCHET', - label = _U('weapon_hatchet'), - components = {} - }, - - { - name = 'WEAPON_RAILGUN', - label = _U('weapon_railgun'), - components = {} - }, - - { - name = 'WEAPON_MACHETE', - label = _U('weapon_machete'), - components = {} - }, - - { - name = 'WEAPON_SWITCHBLADE', - label = _U('weapon_switchblade'), - components = {} - }, - - { - name = 'WEAPON_DBSHOTGUN', - label = _U('weapon_dbshotgun'), - components = {} - }, - - { - name = 'WEAPON_AUTOSHOTGUN', - label = _U('weapon_autoshotgun'), - components = {} - }, - - { - name = 'WEAPON_BATTLEAXE', - label = _U('weapon_battleaxe'), - components = {} - }, - - { - name = 'WEAPON_COMPACTLAUNCHER', - label = _U('weapon_compactlauncher'), - components = {} - }, - - { - name = 'WEAPON_PIPEBOMB', - label = _U('weapon_pipebomb'), - components = {} - }, - - { - name = 'WEAPON_POOLCUE', - label = _U('weapon_poolcue'), - components = {} - }, - - { - name = 'WEAPON_WRENCH', - label = _U('weapon_wrench'), - components = {} - }, - - { - name = 'WEAPON_FLASHLIGHT', - label = _U('weapon_flashlight'), - components = {} - }, - - { - name = 'GADGET_NIGHTVISION', - label = _U('gadget_nightvision'), - components = {} - }, - - { - name = 'GADGET_PARACHUTE', - label = _U('gadget_parachute'), - components = {} - }, - - { - name = 'WEAPON_FLARE', - label = _U('weapon_flare'), - components = {} - }, - - { - name = 'WEAPON_DOUBLEACTION', - label = _U('weapon_doubleaction'), - components = {} - } - -} + {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher'), components = {}}, + {name = 'WEAPON_RPG', label = _U('weapon_rpg'), components = {}}, + {name = 'WEAPON_STINGER', label = _U('weapon_stinger'), components = {}}, + {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun'), components = {}}, + {name = 'WEAPON_GRENADE', label = _U('weapon_grenade'), components = {}}, + {name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb'), components = {}}, + {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade'), components = {}}, + {name = 'WEAPON_BZGAS', label = _U('weapon_bzgas'), components = {}}, + {name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov'), components = {}}, + {name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher'), components = {}}, + {name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan'), components = {}}, + {name = 'WEAPON_DIGISCANNER', label = _U('weapon_digiscanner'), components = {}}, + {name = 'WEAPON_BALL', label = _U('weapon_ball'), components = {}}, + {name = 'WEAPON_BOTTLE', label = _U('weapon_bottle'), components = {}}, + {name = 'WEAPON_DAGGER', label = _U('weapon_dagger'), components = {}}, + {name = 'WEAPON_FIREWORK', label = _U('weapon_firework'), components = {}}, + {name = 'WEAPON_MUSKET', label = _U('weapon_musket'), components = {}}, + {name = 'WEAPON_STUNGUN', label = _U('weapon_stungun'), components = {}}, + {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher'), components = {}}, + {name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine'), components = {}}, + {name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball'), components = {}}, + {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun'), components = {}}, + {name = 'WEAPON_GARBAGEBAG', label = _U('weapon_garbagebag'), components = {}}, + {name = 'WEAPON_HANDCUFFS', label = _U('weapon_handcuffs'), components = {}}, + {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol'), components = {}}, + {name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle'), components = {}}, + {name = 'WEAPON_HATCHET', label = _U('weapon_hatchet'), components = {}}, + {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun'), components = {}}, + {name = 'WEAPON_MACHETE', label = _U('weapon_machete'), components = {}}, + {name = 'WEAPON_SWITCHBLADE', label = _U('weapon_switchblade'), components = {}}, + {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun'), components = {}}, + {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun'), components = {}}, + {name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe'), components = {}}, + {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher'), components = {}}, + {name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb'), components = {}}, + {name = 'WEAPON_POOLCUE', label = _U('weapon_poolcue'), components = {}}, + {name = 'WEAPON_WRENCH', label = _U('weapon_wrench'), components = {}}, + {name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight'), components = {}}, + {name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision'), components = {}}, + {name = 'GADGET_PARACHUTE', label = _U('gadget_parachute'), components = {}}, + {name = 'WEAPON_FLARE', label = _U('weapon_flare'), components = {}}, + {name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction'), components = {}} +} \ No newline at end of file diff --git a/es_extended.sql b/es_extended.sql index 6ea1ce6f..38fc2f9d 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -3,31 +3,31 @@ USE `essentialmode`; ALTER TABLE `users` ADD COLUMN `name` VARCHAR(50) NULL DEFAULT '' AFTER `money`, ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, - ADD COLUMN `job` varchar(50) NULL DEFAULT 'unemployed' AFTER `skin`, + ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, ADD COLUMN `position` VARCHAR(36) NULL AFTER `loadout` ; CREATE TABLE `items` ( - `name` varchar(50) NOT NULL, - `label` varchar(50) NOT NULL, - `limit` int(11) NOT NULL DEFAULT '-1', - `rare` int(11) NOT NULL DEFAULT '0', - `can_remove` int(11) NOT NULL DEFAULT '1', + `name` VARCHAR(50) NOT NULL, + `label` VARCHAR(50) NOT NULL, + `weight` TINYINT(1) NOT NULL DEFAULT 1, + `rare` TINYINT(1) NOT NULL DEFAULT 0, + `can_remove` TINYINT(1) NOT NULL DEFAULT 1, PRIMARY KEY (`name`) ); CREATE TABLE `job_grades` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `job_name` varchar(50) DEFAULT NULL, - `grade` int(11) NOT NULL, - `name` varchar(50) NOT NULL, - `label` varchar(50) NOT NULL, - `salary` int(11) NOT NULL, - `skin_male` longtext NOT NULL, - `skin_female` longtext NOT NULL, + `id` INT(11) NOT NULL AUTO_INCREMENT, + `job_name` VARCHAR(50) DEFAULT NULL, + `grade` INT(11) NOT NULL, + `name` VARCHAR(50) NOT NULL, + `label` VARCHAR(50) NOT NULL, + `salary` INT(11) NOT NULL, + `skin_male` LONGTEXT NOT NULL, + `skin_female` LONGTEXT NOT NULL, PRIMARY KEY (`id`) ); @@ -35,8 +35,8 @@ CREATE TABLE `job_grades` ( INSERT INTO `job_grades` VALUES (1,'unemployed',0,'unemployed','Unemployed',200,'{}','{}'); CREATE TABLE `jobs` ( - `name` varchar(50) NOT NULL, - `label` varchar(50) DEFAULT NULL, + `name` VARCHAR(50) NOT NULL, + `label` VARCHAR(50) DEFAULT NULL, PRIMARY KEY (`name`) ); @@ -44,19 +44,19 @@ CREATE TABLE `jobs` ( INSERT INTO `jobs` VALUES ('unemployed','Unemployed'); CREATE TABLE `user_accounts` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(22) NOT NULL, - `name` varchar(50) NOT NULL, - `money` double NOT NULL DEFAULT '0', + `id` INT(11) NOT NULL AUTO_INCREMENT, + `identifier` VARCHAR(22) NOT NULL, + `name` VARCHAR(50) NOT NULL, + `money` INT(11) NOT NULL DEFAULT '0', PRIMARY KEY (`id`) ); CREATE TABLE `user_inventory` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `identifier` varchar(22) NOT NULL, - `item` varchar(50) NOT NULL, - `count` int(11) NOT NULL, + `id` INT(11) NOT NULL AUTO_INCREMENT, + `identifier` VARCHAR(22) NOT NULL, + `item` VARCHAR(50) NOT NULL, + `count` INT(11) NOT NULL, PRIMARY KEY (`id`) ); diff --git a/locales/br.lua b/locales/br.lua index 9ef7555e..7a044fb7 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,7 +1,7 @@ Locales['br'] = { -- Inventory ['cash'] = 'efectivo', - ['inventory'] = 'inventario', + ['inventory'] = 'inventario %s / %s', ['use'] = 'usar', ['give'] = 'dar', ['remove'] = 'remover', @@ -13,14 +13,18 @@ Locales['br'] = { ['noammo'] = 'voce nao tem todas essas muniçoes!', ['gave_item'] = 'voce deu ~y~%sx~s~ ~b~%s~s~ para ~y~%s~s~', ['received_item'] = 'voce recebeu ~y~%sx~s~ ~b~%s~s~ de ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', - ['gave_ammo'] = 'voce deu ~o~%sx~s~ balas para ~y~%s~s~.', - ['received_ammo'] = 'voce recebeu ~o~%sx~s~ balas de ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'voce deu ~o~%sx~s~ balas para ~y~%s~s~', + ['received_ammo'] = 'voce recebeu ~o~%sx~s~ balas de ~b~%s~s~', ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', ['received_money'] = 'voce recebeu ~g~$%s~s~ de ~b~%s~s~', ['gave_account_money'] = 'voce deu ~g~$%s~s~ (%s) para ~y~%s~s~', @@ -33,19 +37,18 @@ Locales['br'] = { ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon'] = 'you threw ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', ['received_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', - ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salario.', + ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salario', ['received_paycheck'] = 'recebeu dinheiro', ['bank'] = 'banco', ['black_money'] = 'dinheiro sujo', ['act_imp'] = 'acao impossivel', ['in_vehicle'] = 'voce nao pode dar nada para alguem no veiculo', - ['cannot_pickup_room'] = 'voce nao tem espaço suficiente no seu inventario para pegar ~y~%s~s~!', -- Commands ['setjob'] = 'atribuir um trabalho a um usuario', diff --git a/locales/cs.lua b/locales/cs.lua index 0b3b3e07..a620792c 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -1,7 +1,7 @@ Locales['cs'] = { -- Inventory ['cash'] = 'hotovost', - ['inventory'] = 'inventář', + ['inventory'] = 'inventář %s / %s', ['use'] = 'použít', ['give'] = 'dát', ['remove'] = 'zahodit', @@ -13,14 +13,18 @@ Locales['cs'] = { ['noammo'] = 'nemáte dostatek munice!', ['gave_item'] = 'dali jste ~y~%sx~s~ ~b~%s~s~ ~y~%s~s~', ['received_item'] = 'obdrželi jste ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', - ['gave_ammo'] = 'dali jste ~o~%sx~s~ nábojů ~y~%s~s~.', - ['received_ammo'] = 'obdrželi jste ~o~%sx~s~ nábojů od ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'dali jste ~o~%sx~s~ nábojů ~y~%s~s~', + ['received_ammo'] = 'obdrželi jste ~o~%sx~s~ nábojů od ~b~%s~s~', ['gave_money'] = 'dali jste ~g~$%s~s~ ~y~%s~s~', ['received_money'] = 'obdrželi jste ~g~$%s~s~ od ~b~%s~s~', ['gave_account_money'] = 'dali jste ~g~$%s~s~ (%s) ~y~%s~s~', @@ -33,19 +37,18 @@ Locales['cs'] = { ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon'] = 'you threw ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', - ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat.', + ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', ['received_paycheck'] = 'obdržena výplata', ['bank'] = 'bankovní účet', ['black_money'] = 'špinavé peníze', ['act_imp'] = 'akce není možná', ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', - ['cannot_pickup_room'] = 've vašem inventáři není dostatek místa pro ~y~%s~s~!', -- Commands ['setjob'] = 'přiřadit práci hráči', diff --git a/locales/de.lua b/locales/de.lua index 1aa9b2ed..10d67f5e 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,7 +1,7 @@ Locales['de'] = { -- Inventory ['cash'] = 'bargeld', - ['inventory'] = 'inventar', + ['inventory'] = 'inventar %s / %s', ['use'] = 'benutzen', ['give'] = 'geben', ['remove'] = 'entfernen', @@ -13,12 +13,16 @@ Locales['de'] = { ['noammo'] = 'du hast keine munition!', ['gave_item'] = 'du gibst ~y~%sx~s~ ~b~%s~s~ an ~y~%s~s~', ['received_item'] = 'du empfängst ~y~%sx~s~ ~b~%s~s~ von ~b~%s~s~', - ['gave_weapon'] = 'du gibst ~y~1x~s~ ~b~%s~s~ an ~y~%s~s~', - ['gave_weapon_ammo'] = 'du gibst ~y~1x~s~ ~b~%s~s~ mit ~o~%sx~s~ Schuss an ~y~%s~s~', + ['gave_weapon'] = 'du gibst ~b~%s~s~ an ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'du gibst ~b~%s~s~ mit ~o~%sx~s~ Schuss an ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ hat bereits eine(n) ~y~%s~s~', - ['received_weapon'] = 'du erhälst ~y~1x~s~ ~b~%s~s~ von ~b~%s~s~', - ['received_weapon_ammo'] = 'du erhälst ~y~1x~s~ ~b~%s~s~ mit ~o~%sx~s~ Schuss von ~b~%s~s~', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'du erhälst ~b~%s~s~ von ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx~s~ Schuss von ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ hat versucht dir eine(n) ~y~%s~s~ zu geben, aber du hast bereits eine(n)', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', ['gave_ammo'] = 'du gibst ~o~%sx~s~ Schuss an ~y~%s~s~', ['received_ammo'] = 'du erhälst ~o~%sx~s~ Schuss von ~b~%s~s~', ['gave_money'] = 'du gibst ~g~$%s~s~ an ~y~%s~s~', @@ -33,19 +37,18 @@ Locales['de'] = { ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon'] = 'you threw ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', - ['received_help'] = 'du hast deine Sozialhilfe erhalten.: ~g~$%s~s~', - ['company_nomoney'] = 'die Firma in der du angestellt bist, ist zu arm um dein Gehalt zu zahlen.', + ['received_help'] = 'du hast deine Sozialhilfe erhalten: ~g~$%s~s~', + ['company_nomoney'] = 'die Firma in der du angestellt bist, ist zu arm um dein Gehalt zu zahlen', ['received_paycheck'] = 'erhaltener Gehaltsscheck', ['bank'] = 'bank', ['black_money'] = 'schwarzgeld', ['act_imp'] = 'Aktion nicht möglich', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', - ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', -- Commands ['setjob'] = 'assign a job to a user', diff --git a/locales/en.lua b/locales/en.lua index 1ccf6f37..91c9eca2 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,7 +1,7 @@ Locales['en'] = { -- Inventory ['cash'] = 'cash', - ['inventory'] = 'inventory', + ['inventory'] = 'inventory %s / %s', ['use'] = 'use', ['give'] = 'give', ['remove'] = 'throw', @@ -13,14 +13,18 @@ Locales['en'] = { ['noammo'] = 'you do not have enough ammo!', ['gave_item'] = 'you gave ~y~%sx~s~ ~b~%s~s~ to ~y~%s~s~', ['received_item'] = 'you received ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', - ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~.', - ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~', + ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~', ['gave_money'] = 'you gave ~g~$%s~s~ to ~y~%s~s~', ['received_money'] = 'you received ~g~$%s~s~ from ~b~%s~s~', ['gave_account_money'] = 'you gave ~g~$%s~s~ (%s) to ~y~%s~s~', @@ -33,19 +37,18 @@ Locales['en'] = { ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon'] = 'you threw ~b~%s~s~', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', -- Salary related ['received_salary'] = 'you received your salary: ~g~$%s~s~', ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', - ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary.', + ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary', ['received_paycheck'] = 'received paycheck', ['bank'] = 'bank', ['black_money'] = 'dirty Money', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', - ['cannot_pickup_room'] = 'you do not have enough space in your inventory to pick up ~y~%s~s~!', -- Commands ['setjob'] = 'assign a job to a user', diff --git a/locales/fi.lua b/locales/fi.lua index 08adfa48..eb3ac49f 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,7 +1,7 @@ Locales['fi'] = { -- Inventory ['cash'] = 'käteinen', - ['inventory'] = 'reppu', + ['inventory'] = 'reppu %s / %s', ['use'] = 'käytä', ['give'] = 'anna', ['remove'] = 'poista', @@ -13,14 +13,18 @@ Locales['fi'] = { ['noammo'] = 'sinulla ei ole ammuksia!', ['gave_item'] = 'sinä annoit ~y~%sx~s~ ~b~%s~s~ henkilölle ~y~%s~s~', ['received_item'] = 'sinä sait ~y~%sx~s~ ~b~%s~s~ henkilöltä ~b~%s~s~', - ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~.', - ['gave_weapon_ammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~.', + ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~.', - ['received_weapon_ammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one.', - ['gave_ammo'] = 'sinä annoit ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~.', - ['received_ammo'] = 'sinä sait ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'sinä annoit ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~', + ['received_ammo'] = 'sinä sait ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~', ['gave_money'] = 'sinä annoit ~g~$%s~s~ henkilölle ~y~%s~s~', ['received_money'] = 'sinä sait ~g~$%s~s~ henkilöltä ~b~%s~s~', ['gave_account_money'] = 'sinä annoit ~g~$%s~s~ (%s) henkilölle ~y~%s~s~', @@ -38,14 +42,13 @@ Locales['fi'] = { -- Salary related ['received_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', ['received_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', - ['company_nomoney'] = 'yritys jolle teet töitä on köyhä eikä voi maksaa palkkaasi.', + ['company_nomoney'] = 'yritys jolle teet töitä on köyhä eikä voi maksaa palkkaasi', ['received_paycheck'] = 'sait palkan', ['bank'] = 'pankki', ['black_money'] = 'likainen Raha', ['act_imp'] = 'toiminto mahdoton', - ['in_vehicle'] = 'et voi antaa ajoneuvossa olevalle mitään.', - ['cannot_pickup_room'] = 'sinulla ei ole tilaa repussa nostaaksesi ~y~%s~s~!', + ['in_vehicle'] = 'et voi antaa ajoneuvossa olevalle mitään', -- Commands ['setjob'] = 'määritä työ käyttäjälle', diff --git a/locales/fr.lua b/locales/fr.lua index f7c1fedd..11bfd194 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,7 +1,7 @@ Locales['fr'] = { -- Inventory ['cash'] = 'espèces', - ['inventory'] = 'inventaire', + ['inventory'] = 'inventaire %s / %s', ['use'] = 'utiliser', ['give'] = 'donner', ['remove'] = 'jeter', @@ -13,14 +13,18 @@ Locales['fr'] = { ['noammo'] = 'tu n\'as pas toutes ces munitions!', ['gave_item'] = 'vous avez donné ~y~%sx~s~ ~b~%s~s~ à ~y~%s~s~', ['received_item'] = 'vous avez reçu ~y~%sx~s~ ~b~%s~s~ par ~b~%s~s~', - ['gave_weapon'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ à ~y~%s~s~.', - ['gave_weapon_ammo'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles à ~y~%s~s~.', + ['gave_weapon'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ à ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles à ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ a déjà ~y~%s~s~', - ['received_weapon'] = 'vous recevez ~y~1x~s~ ~b~%s~s~ de ~b~%s~s~.', - ['received_weapon_ammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles de ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire.', - ['gave_ammo'] = 'vous donnez ~o~%sx~s~ munitions à ~y~%s~s~.', - ['received_ammo'] = 'vous recevez ~o~%sx~s~ munitions de ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'vous recevez ~y~1x~s~ ~b~%s~s~ de ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles de ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'vous donnez ~o~%sx~s~ munitions à ~y~%s~s~', + ['received_ammo'] = 'vous recevez ~o~%sx~s~ munitions de ~b~%s~s~', ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', ['received_money'] = 'vous avez reçu ~g~$%s~s~ par ~b~%s~s~', ['gave_account_money'] = 'vous avez donné ~g~$%s~s~ (%s) à ~y~%s~s~', @@ -45,7 +49,6 @@ Locales['fr'] = { ['act_imp'] = 'action impossible', ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', - ['cannot_pickup_room'] = 'vous n\'avez plus de place pour ~y~%s~s~!', -- Commands ['setjob'] = 'assigner job', diff --git a/locales/pl.lua b/locales/pl.lua index ee840465..f4e927c4 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,7 +1,7 @@ Locales['pl'] = { -- Inventory ['cash'] = 'gotówka', - ['inventory'] = 'ekwipunek', + ['inventory'] = 'ekwipunek %s / %s', ['use'] = 'użyj', ['give'] = 'daj', ['remove'] = 'usuń', @@ -13,14 +13,18 @@ Locales['pl'] = { ['noammo'] = 'nie posiadasz wystarczającej ilości amunicji!', ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'dajesz ~y~1x~s~ ~b~%s~s~ dla ~y~%s~s~.', - ['gave_weapon_ammo'] = 'dałeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~.', + ['gave_weapon'] = 'dajesz ~b~%s~s~ dla ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'dałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ już posiada ~y~%s~s~', - ['received_weapon'] = 'otrzymałeś/aś ~y~1x~s~ ~b~%s~s~ od ~b~%s~s~.', - ['received_weapon_ammo'] = 'otrzymałeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno.', - ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~.', - ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'otrzymałeś/aś ~b~%s~s~ od ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~', + ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~', ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', ['received_money'] = 'otrzymujesz ~g~%s$~s~ od ~b~%s~s~', ['gave_account_money'] = 'dajesz ~g~%s$~s~ (%s) dla ~y~%s~s~', @@ -33,19 +37,18 @@ Locales['pl'] = { ['threw_standard'] = 'wyrzuciłeś/aś ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~gotówki~s~', ['threw_account'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'wyrzuciłeś/aś ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~y~1x~s~ ~b~%s~s~ z ~o~%sx~s~ nabojami', + ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', + ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami', -- Salary related ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', - ['company_nomoney'] = 'firma, w której pracujesz, jest zbyt biedna, by wypłacić twoją pensję.', + ['company_nomoney'] = 'firma, w której pracujesz, jest zbyt biedna, by wypłacić twoją pensję', ['received_paycheck'] = 'otrzymana wypłata', ['bank'] = 'bank', ['black_money'] = 'brudne pieniądze', ['act_imp'] = 'działanie niemożliwe', ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', - ['cannot_pickup_room'] = 'nie masz wystarczająco dużo miejsca w ekwipunku, aby podnieść ~y~%s~s~!', -- Commands ['setjob'] = 'przydziel prace użytkownikowi', diff --git a/locales/sv.lua b/locales/sv.lua index 647dd50b..38d9d115 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,7 +1,7 @@ Locales['sv'] = { -- Inventory ['cash'] = 'kontanter', - ['inventory'] = 'mitt förråd', + ['inventory'] = 'mitt förråd %s / %s', ['use'] = 'använd', ['give'] = 'ge', ['remove'] = 'kasta', @@ -13,14 +13,18 @@ Locales['sv'] = { ['noammo'] = 'du har inte tillräckligt med ammunition!', ['gave_item'] = 'du gav ~y~%sx~s~ ~b~%s~s~ till ~y~%s~s~', ['received_item'] = 'du tog emot ~y~%sx~s~ ~b~%s~s~ från ~b~%s~s~', - ['gave_weapon'] = 'du gav ~y~1x~s~ ~b~%s~s~ till ~y~%s~s~.', - ['gave_weapon_ammo'] = 'du gav ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~.', + ['gave_weapon'] = 'du gav ~b~%s~s~ till ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'du gav ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ har redan en ~y~%s~s~', - ['received_weapon'] = 'du tog emot ~y~1x~s~ ~b~%s~s~ från ~b~%s~s~.', - ['received_weapon_ammo'] = 'du tog emot ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~.', - ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det har du redan.', - ['gave_ammo'] = 'du gav ~o~%sx~s~ skott till ~y~%s~s~.', - ['received_ammo'] = 'du tog emot ~o~%sx~s~ skott från ~b~%s~s~.', + ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['received_weapon'] = 'du tog emot ~b~%s~s~ från ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'du tog emot ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det har du redan', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_ammo'] = 'du gav ~o~%sx~s~ skott till ~y~%s~s~', + ['received_ammo'] = 'du tog emot ~o~%sx~s~ skott från ~b~%s~s~', ['gave_money'] = 'du gav ~g~%s SEK~s~ till ~y~%s~s~', ['received_money'] = 'du tog emot ~g~%s SEK~s~ från ~b~%s~s~', ['gave_account_money'] = 'du gav ~g~%s SEK~s~ (%s) till ~y~%s~s~', @@ -33,22 +37,21 @@ Locales['sv'] = { ['threw_standard'] = 'du kastade ~y~%sx~s~ ~b~%s~s~', ['threw_money'] = 'du kastade ~r~$%s~s~ ~b~kontanter~s~', ['threw_account'] = 'du kastade ~r~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'du kastade ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'du kastade ~y~1x~s~ ~b~%s~s~ med ~o~%sx~s~ skott', + ['threw_weapon'] = 'du kastade ~b~%s~s~', + ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx~s~ skott', -- Salary related ['received_salary'] = 'du har mottagit din lön på ~g~%s SEK~s~', ['received_help'] = 'du har mottagit bidrag på ~g~%s SEK~s~', - ['company_nomoney'] = 'företaget du är anställt hos har inte råd att betala ut din lön.', + ['company_nomoney'] = 'företaget du är anställt hos har inte råd att betala ut din lön', ['received_paycheck'] = 'mottagit lön', ['bank'] = 'bank', ['black_money'] = 'svarta pengar', ['act_imp'] = 'åtgärd omöjlig', ['in_vehicle'] = 'du kan inte ge saker till en som sitter i ett fordon!', - ['cannot_pickup_room'] = 'du har inte plats för att plocka upp ~y~%s~s~!', -- Commands - ['setjob'] = 'tilldela ett jobb till en användare', + ['setjob'] = 'tilldela ett jobb till en spelare', ['id_param'] = 'spelarens ID', ['setjob_param2'] = 'det jobb du vill tilldela', ['setjob_param3'] = 'job level', diff --git a/server/classes/player.lua b/server/classes/player.lua index 6fc49b8a..8e67fe7f 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -8,6 +8,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.loadout = loadout self.name = name self.lastPosition = lastPosition + self.maxWeight = Config.MaxWeight self.source = self.player.get('source') self.identifier = self.player.get('identifier') @@ -350,6 +351,28 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end + self.getWeight = function() + local inventoryWeight = 0 + + for k,v in ipairs(self.inventory) do + inventoryWeight = inventoryWeight + (v.count * v.weight) + end + + return inventoryWeight + end + + self.canCarryItem = function(name, count) + local currentWeight, itemWeight = self.getWeight(), ESX.Items[name].weight + local newWeight = currentWeight + (itemWeight * count) + + return newWeight <= self.maxWeight + end + + self.setMaxWeight = function(newWeight) + self.maxWeight = newWeight + TriggerClientEvent('esx:setMaxWeight', self.source, self.maxWeight) + end + self.setJob = function(job, grade) grade = tostring(grade) local lastJob = json.decode(json.encode(self.job)) @@ -403,13 +426,21 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.addWeaponComponent = function(weaponName, weaponComponent) local loadoutNum, weapon = self.getWeapon(weaponName) - if self.hasWeaponComponent(weaponName, weaponComponent) then - return + if weapon then + if not self.hasWeaponComponent(weaponName, weaponComponent) then + table.insert(self.loadout[loadoutNum].components, weaponComponent) + TriggerClientEvent('esx:addWeaponComponent', self.source, weaponName, weaponComponent) + end end + end - table.insert(self.loadout[loadoutNum].components, weaponComponent) + self.addWeaponAmmo = function(weaponName, ammoCount) + local loadoutNum, weapon = self.getWeapon(weaponName) - TriggerClientEvent('esx:addWeaponComponent', self.source, weaponName, weaponComponent) + if weapon then + weapon.ammo = weapon.ammo + ammoCount + TriggerClientEvent('esx:setWeaponAmmo', self.source, weaponName, weapon.ammo) + end end self.removeWeapon = function(weaponName, ammo) @@ -437,34 +468,41 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.removeWeaponComponent = function(weaponName, weaponComponent) local loadoutNum, weapon = self.getWeapon(weaponName) - if not weapon then - return - end - - for k,v in ipairs(self.loadout[loadoutNum].components) do - if v.name == weaponComponent then - table.remove(self.loadout[loadoutNum].components, k) - break + if weapon then + for k,v in ipairs(self.loadout[loadoutNum].components) do + if v.name == weaponComponent then + table.remove(self.loadout[loadoutNum].components, k) + break + end end + + TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, weaponComponent) end + end - TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, weaponComponent) + self.removeWeaponAmmo = function(weaponName, ammoCount) + local loadoutNum, weapon = self.getWeapon(weaponName) + + if weapon then + weapon.ammo = weapon.ammo - ammoCount + TriggerClientEvent('esx:setWeaponAmmo', self.source, weaponName, weapon.ammo) + end end self.hasWeaponComponent = function(weaponName, weaponComponent) local loadoutNum, weapon = self.getWeapon(weaponName) - if not weapon then + if weapon then + for k,v in ipairs(weapon.components) do + if v == weaponComponent then + return true + end + end + + return false + else return false end - - for k,v in ipairs(weapon.components) do - if v == weaponComponent then - return true - end - end - - return false end self.hasWeapon = function(weaponName) diff --git a/server/common.lua b/server/common.lua index 9009735f..ed937f54 100644 --- a/server/common.lua +++ b/server/common.lua @@ -1,14 +1,14 @@ -ESX = {} -ESX.Players = {} +ESX = {} +ESX.Players = {} ESX.UsableItemsCallbacks = {} -ESX.Items = {} -ESX.ServerCallbacks = {} -ESX.TimeoutCount = -1 -ESX.CancelledTimeouts = {} -ESX.LastPlayerData = {} -ESX.Pickups = {} -ESX.PickupId = 0 -ESX.Jobs = {} +ESX.Items = {} +ESX.ServerCallbacks = {} +ESX.TimeoutCount = -1 +ESX.CancelledTimeouts = {} +ESX.LastPlayerData = {} +ESX.Pickups = {} +ESX.PickupId = 0 +ESX.Jobs = {} AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) @@ -20,12 +20,12 @@ end MySQL.ready(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, - rare = (result[i].rare == 1 and true or false), - canRemove = (result[i].can_remove == 1 and true or false), + for k,v in ipairs(result) do + ESX.Items[v.name] = { + label = v.label, + weight = v.weight, + rare = v.rare, + canRemove = v.can_remove } end end) diff --git a/server/main.lua b/server/main.lua index 86d7f2f4..48821a4d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -47,26 +47,26 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get inventory table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT * FROM user_inventory WHERE identifier = @identifier', { + MySQL.Async.fetchAll('SELECT item, count FROM user_inventory WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(inventory) local tasks2 = {} - for i=1, #inventory do - local item = ESX.Items[inventory[i].item] + for k,v in ipairs(inventory) do + local item = ESX.Items[v.item] if item then table.insert(userData.inventory, { - name = inventory[i].item, - count = inventory[i].count, + name = v.item, + count = v.count, label = item.label, - limit = item.limit, - usable = ESX.UsableItemsCallbacks[inventory[i].item] ~= nil, + weight = item.weight, + usable = ESX.UsableItemsCallbacks[v.item] ~= nil, rare = item.rare, canRemove = item.canRemove }) else - print(('es_extended: invalid item "%s" ignored!'):format(inventory[i].item)) + print(('es_extended: invalid item "%s" ignored!'):format(v.item)) end end @@ -85,7 +85,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) name = k, count = 0, label = ESX.Items[k].label, - limit = ESX.Items[k].limit, + weight = ESX.Items[k].weight, usable = ESX.UsableItemsCallbacks[k] ~= nil, rare = ESX.Items[k].rare, canRemove = ESX.Items[k].canRemove @@ -230,7 +230,8 @@ AddEventHandler('es:playerLoaded', function(source, _player) job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), lastPosition = xPlayer.getLastPosition(), - money = xPlayer.getMoney() + money = xPlayer.getMoney(), + maxWeight = xPlayer.maxWeight }) xPlayer.displayMoney(xPlayer.getMoney()) @@ -269,179 +270,161 @@ end) RegisterServerEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) - local _source = source - - local sourceXPlayer = ESX.GetPlayerFromId(_source) + local playerId = source + local sourceXPlayer = ESX.GetPlayerFromId(playerId) 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 + itemCount) > targetItem.limit then - TriggerClientEvent('esx:showNotification', _source, _U('ex_inv_lim', targetXPlayer.name)) - else + if targetXPlayer.canCarryItem(itemName, itemCount) then sourceXPlayer.removeInventoryItem(itemName, itemCount) targetXPlayer.addInventoryItem (itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('gave_item', itemCount, ESX.Items[itemName].label, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_item', itemCount, ESX.Items[itemName].label, sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_item', itemCount, sourceItem.label, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_item', itemCount, sourceItem.label, sourceXPlayer.name)) + else + sourceXPlayer.showNotification(_U('ex_inv_lim', targetXPlayer.name)) end - else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + sourceXPlayer.showNotification(_U('imp_invalid_quantity')) end - elseif type == 'item_money' then - if itemCount > 0 and sourceXPlayer.getMoney() >= itemCount then sourceXPlayer.removeMoney(itemCount) targetXPlayer.addMoney (itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('gave_money', ESX.Math.GroupDigits(itemCount), targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_money', ESX.Math.GroupDigits(itemCount), sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_money', ESX.Math.GroupDigits(itemCount), targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_money', ESX.Math.GroupDigits(itemCount), sourceXPlayer.name)) else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + sourceXPlayer.showNotification(_U('imp_invalid_amount')) 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, _U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], sourceXPlayer.name)) else - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + sourceXPlayer.showNotification(_U('imp_invalid_amount')) end - elseif type == 'item_weapon' then - if not targetXPlayer.hasWeapon(itemName) then sourceXPlayer.removeWeapon(itemName) targetXPlayer.addWeapon(itemName, itemCount) - local weaponLabel = ESX.GetWeaponLabel(itemName) if itemCount > 0 then - TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon_ammo', weaponLabel, itemCount, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_weapon_ammo', weaponLabel, itemCount, sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, sourceXPlayer.name)) else - TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon', weaponLabel, targetXPlayer.name)) - TriggerClientEvent('esx:showNotification', target, _U('received_weapon', weaponLabel, sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_weapon', weaponLabel, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon', weaponLabel, sourceXPlayer.name)) end else - TriggerClientEvent('esx:showNotification', _source, _U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) - TriggerClientEvent('esx:showNotification', target, _U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) + sourceXPlayer.showNotification(_U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) + targetXPlayer.showNotification(_U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) end + elseif type == 'item_ammo' then + if sourceXPlayer.hasWeapon(itemName) then + if targetXPlayer.hasWeapon(itemName) then + local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) + if weapon.ammo >= itemCount then + sourceXPlayer.removeWeaponAmmo(itemName, itemCount) + targetXPlayer.addWeaponAmmo(itemName, itemCount) + + sourceXPlayer.showNotification(_U('gave_weapon_ammo', itemCount, weapon.label, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_ammo', itemCount, weapon.label, sourceXPlayer.name)) + end + else + sourceXPlayer.showNotification(_U('gave_weapon_noweapon', targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_noweapon', sourceXPlayer.name, weapon.label)) + end + end end end) RegisterServerEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) - local _source = source + local playerId = source + local xPlayer = ESX.GetPlayerFromId(source) if type == 'item_standard' then - if itemCount == nil or itemCount < 1 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + xPlayer.showNotification(_U('imp_invalid_quantity')) else - local xPlayer = ESX.GetPlayerFromId(source) local xItem = xPlayer.getInventoryItem(itemName) if (itemCount > xItem.count or xItem.count < 1) then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_quantity')) + xPlayer.showNotification(_U('imp_invalid_quantity')) else xPlayer.removeInventoryItem(itemName, itemCount) - local pickupLabel = ('~y~%s~s~ [~b~%s~s~]'):format(xItem.label, itemCount) - ESX.CreatePickup('item_standard', itemName, itemCount, pickupLabel, _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw_standard', itemCount, xItem.label)) + ESX.CreatePickup('item_standard', itemName, itemCount, pickupLabel, playerId) + xPlayer.showNotification(_U('threw_standard', itemCount, xItem.label)) end end - elseif type == 'item_money' then - if itemCount == nil or itemCount < 1 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + xPlayer.showNotification(_U('imp_invalid_amount')) else - local xPlayer = ESX.GetPlayerFromId(source) local playerCash = xPlayer.getMoney() if (itemCount > playerCash or playerCash < 1) then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + xPlayer.showNotification(_U('imp_invalid_amount')) else xPlayer.removeMoney(itemCount) - local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(_U('cash'), _U('locale_currency', ESX.Math.GroupDigits(itemCount))) - ESX.CreatePickup('item_money', 'money', itemCount, pickupLabel, _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw_money', ESX.Math.GroupDigits(itemCount))) + ESX.CreatePickup('item_money', 'money', itemCount, pickupLabel, playerId) + xPlayer.showNotification(_U('threw_money', ESX.Math.GroupDigits(itemCount))) end end - elseif type == 'item_account' then - if itemCount == nil or itemCount < 1 then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + xPlayer.showNotification(_U('imp_invalid_amount')) else - local xPlayer = ESX.GetPlayerFromId(source) local account = xPlayer.getAccount(itemName) if (itemCount > account.money or account.money < 1) then - TriggerClientEvent('esx:showNotification', _source, _U('imp_invalid_amount')) + xPlayer.showNotification(_U('imp_invalid_amount')) else xPlayer.removeAccountMoney(itemName, itemCount) - local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(account.label, _U('locale_currency', ESX.Math.GroupDigits(itemCount))) - ESX.CreatePickup('item_account', itemName, itemCount, pickupLabel, _source) - TriggerClientEvent('esx:showNotification', _source, _U('threw_account', ESX.Math.GroupDigits(itemCount), string.lower(account.label))) + ESX.CreatePickup('item_account', itemName, itemCount, pickupLabel, playerId) + xPlayer.showNotification(_U('threw_account', ESX.Math.GroupDigits(itemCount), string.lower(account.label))) end end - elseif type == 'item_weapon' then - - local xPlayer = ESX.GetPlayerFromId(source) - local loadout = xPlayer.getLoadout() - - for i=1, #loadout, 1 do - if loadout[i].name == itemName then - itemCount = loadout[i].ammo - break - end - end - if xPlayer.hasWeapon(itemName) then - local weaponLabel, weaponPickup = ESX.GetWeaponLabel(itemName), 'PICKUP_' .. string.upper(itemName) - + local weaponNum, weapon = xPlayer.getWeapon(itemName) + local weaponPickup = 'PICKUP_' .. string.upper(itemName) xPlayer.removeWeapon(itemName) - if itemCount > 0 then - TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, itemName, itemCount) - TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon_ammo', weaponLabel, itemCount)) + if weapon.ammo > 0 then + TriggerClientEvent('esx:pickupWeapon', playerId, weaponPickup, itemName, weapon.ammo) + xPlayer.showNotification(_U('threw_weapon_ammo', weapon.label, weapon.ammo)) else -- workaround for CreateAmbientPickup() giving 30 rounds of ammo when you drop the weapon with 0 ammo - TriggerClientEvent('esx:pickupWeapon', _source, weaponPickup, itemName, 1) - TriggerClientEvent('esx:showNotification', _source, _U('threw_weapon', weaponLabel)) + TriggerClientEvent('esx:pickupWeapon', playerId, weaponPickup, itemName, 1) + xPlayer.showNotification(_U('threw_weapon', weapon.label)) end end - end end) RegisterServerEvent('esx:useItem') AddEventHandler('esx:useItem', function(itemName) local xPlayer = ESX.GetPlayerFromId(source) - local count = xPlayer.getInventoryItem(itemName).count + local count = xPlayer.getInventoryItem(itemName).count if count > 0 then ESX.UseItem(source, itemName) else - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('act_imp')) + xPlayer.showNotification(_U('act_imp')) end end) @@ -452,25 +435,10 @@ AddEventHandler('esx:onPickup', function(id) local xPlayer = ESX.GetPlayerFromId(_source) if pickup.type == 'item_standard' then - - local item = xPlayer.getInventoryItem(pickup.name) - local canTake = ((item.limit == -1) and (pickup.count)) or ((item.limit - item.count > 0) and (item.limit - item.count)) or 0 - local total = pickup.count < canTake and pickup.count or canTake - local remaining = pickup.count - total - - TriggerClientEvent('esx:removePickup', -1, id) - - if total > 0 then - xPlayer.addInventoryItem(pickup.name, total) + if xPlayer.canCarryItem(pickup.name, pickup.count) then + xPlayer.addInventoryItem(pickup.name, pickup.count) + TriggerClientEvent('esx:removePickup', -1, id) end - - if remaining > 0 then - TriggerClientEvent('esx:showNotification', _source, _U('cannot_pickup_room', item.label)) - - local pickupLabel = ('~y~%s~s~ [~b~%s~s~]'):format(item.label, remaining) - ESX.CreatePickup('item_standard', pickup.name, remaining, pickupLabel, _source) - end - elseif pickup.type == 'item_money' then TriggerClientEvent('esx:removePickup', -1, id) xPlayer.addMoney(pickup.count) From d9a545727f3834580d540a733ede2de19fb04549 Mon Sep 17 00:00:00 2001 From: BenjiM <34999231+BenjiM@users.noreply.github.com> Date: Mon, 14 Oct 2019 01:34:47 +0200 Subject: [PATCH 353/672] Update fr.lua --- locales/fr.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 11bfd194..45362203 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -14,15 +14,15 @@ Locales['fr'] = { ['gave_item'] = 'vous avez donné ~y~%sx~s~ ~b~%s~s~ à ~y~%s~s~', ['received_item'] = 'vous avez reçu ~y~%sx~s~ ~b~%s~s~ par ~b~%s~s~', ['gave_weapon'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ à ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'vous avez donné ~o~%sx~s~ balles pour ~b~%s~s~ à ~y~%s~s~', ['gave_weapon_withammo'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles à ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ a déjà ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['gave_weapon_noweapon'] = '~y~%s~s~ n\'a pas cette arme', ['received_weapon'] = 'vous recevez ~y~1x~s~ ~b~%s~s~ de ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'vous avez reçu ~o~%sx~s~ balles pour votre ~b~%s~s~ de ~b~%s~s~', ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['received_weapon_noweapon'] = '~b~%s~s~ tente de vous donner des munitions pour ~y~%s~s~, mais vous n\'en avez pas', ['gave_ammo'] = 'vous donnez ~o~%sx~s~ munitions à ~y~%s~s~', ['received_ammo'] = 'vous recevez ~o~%sx~s~ munitions de ~b~%s~s~', ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', From 9ac7d39884faee4775d2f6afdc0b12e0656f7f34 Mon Sep 17 00:00:00 2001 From: userMacieG Date: Mon, 14 Oct 2019 14:07:27 +0200 Subject: [PATCH 354/672] Update pl.lua --- locales/pl.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/pl.lua b/locales/pl.lua index f4e927c4..57ee9a5b 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -14,15 +14,15 @@ Locales['pl'] = { ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', ['gave_weapon'] = 'dajesz ~b~%s~s~ dla ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'dałeś/aś ~o~%sx~s~ naboi do ~b~%s~s~ dla ~y~%s~s~', ['gave_weapon_withammo'] = 'dałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ już posiada ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['gave_weapon_noweapon'] = '~y~%s~s~ nie posiada tej broni', ['received_weapon'] = 'otrzymałeś/aś ~b~%s~s~ od ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'otrzymałeś/aś ~o~%sx~s~ naboi do twojego ~b~%s~s~ od ~b~%s~s~', ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['received_weapon_noweapon'] = '~b~%s~s~ próbował/a przekazać ci amunicje do ~y~%s~s~, lecz nie posiadasz tej broni', ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~', ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~', ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', From f33c317d6f5618764eb60f7e22e15755d3075687 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 19 Oct 2019 19:38:54 +0200 Subject: [PATCH 355/672] Fixed sql file inproper weight type --- es_extended.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es_extended.sql b/es_extended.sql index 38fc2f9d..52534684 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -12,7 +12,7 @@ ALTER TABLE `users` CREATE TABLE `items` ( `name` VARCHAR(50) NOT NULL, `label` VARCHAR(50) NOT NULL, - `weight` TINYINT(1) NOT NULL DEFAULT 1, + `weight` INT(11) NOT NULL DEFAULT 1, `rare` TINYINT(1) NOT NULL DEFAULT 0, `can_remove` TINYINT(1) NOT NULL DEFAULT 1, From 87fb7b657194291e0bfd7bc6d655220276d90574 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 19 Oct 2019 19:48:34 +0200 Subject: [PATCH 356/672] Removed old locales, updated Swedish locale --- locales/br.lua | 2 -- locales/cs.lua | 2 -- locales/de.lua | 2 -- locales/en.lua | 2 -- locales/fi.lua | 2 -- locales/fr.lua | 2 -- locales/pl.lua | 2 -- locales/sv.lua | 12 +++++------- 8 files changed, 5 insertions(+), 21 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 7a044fb7..6dc07cba 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -23,8 +23,6 @@ Locales['br'] = { ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'voce deu ~o~%sx~s~ balas para ~y~%s~s~', - ['received_ammo'] = 'voce recebeu ~o~%sx~s~ balas de ~b~%s~s~', ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', ['received_money'] = 'voce recebeu ~g~$%s~s~ de ~b~%s~s~', ['gave_account_money'] = 'voce deu ~g~$%s~s~ (%s) para ~y~%s~s~', diff --git a/locales/cs.lua b/locales/cs.lua index a620792c..92e3c5f4 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -23,8 +23,6 @@ Locales['cs'] = { ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'dali jste ~o~%sx~s~ nábojů ~y~%s~s~', - ['received_ammo'] = 'obdrželi jste ~o~%sx~s~ nábojů od ~b~%s~s~', ['gave_money'] = 'dali jste ~g~$%s~s~ ~y~%s~s~', ['received_money'] = 'obdrželi jste ~g~$%s~s~ od ~b~%s~s~', ['gave_account_money'] = 'dali jste ~g~$%s~s~ (%s) ~y~%s~s~', diff --git a/locales/de.lua b/locales/de.lua index 10d67f5e..91cf4c82 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -23,8 +23,6 @@ Locales['de'] = { ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx~s~ Schuss von ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ hat versucht dir eine(n) ~y~%s~s~ zu geben, aber du hast bereits eine(n)', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'du gibst ~o~%sx~s~ Schuss an ~y~%s~s~', - ['received_ammo'] = 'du erhälst ~o~%sx~s~ Schuss von ~b~%s~s~', ['gave_money'] = 'du gibst ~g~$%s~s~ an ~y~%s~s~', ['received_money'] = 'du erhälst ~g~$%s~s~ von ~b~%s~s~', ['gave_account_money'] = 'du gibst ~g~$%s~s~ (%s) an ~y~%s~s~', diff --git a/locales/en.lua b/locales/en.lua index 91c9eca2..ecb89bff 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -23,8 +23,6 @@ Locales['en'] = { ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'you gave ~o~%sx~s~ bullets to ~y~%s~s~', - ['received_ammo'] = 'you received ~o~%sx~s~ bullets from ~b~%s~s~', ['gave_money'] = 'you gave ~g~$%s~s~ to ~y~%s~s~', ['received_money'] = 'you received ~g~$%s~s~ from ~b~%s~s~', ['gave_account_money'] = 'you gave ~g~$%s~s~ (%s) to ~y~%s~s~', diff --git a/locales/fi.lua b/locales/fi.lua index eb3ac49f..5cbca385 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -23,8 +23,6 @@ Locales['fi'] = { ['received_weapon_withammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'sinä annoit ~o~%sx~s~ ammuksia henkilölle ~y~%s~s~', - ['received_ammo'] = 'sinä sait ~o~%sx~s~ ammuksia henkilöltä ~b~%s~s~', ['gave_money'] = 'sinä annoit ~g~$%s~s~ henkilölle ~y~%s~s~', ['received_money'] = 'sinä sait ~g~$%s~s~ henkilöltä ~b~%s~s~', ['gave_account_money'] = 'sinä annoit ~g~$%s~s~ (%s) henkilölle ~y~%s~s~', diff --git a/locales/fr.lua b/locales/fr.lua index 45362203..b3f77b7c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -23,8 +23,6 @@ Locales['fr'] = { ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire', ['received_weapon_noweapon'] = '~b~%s~s~ tente de vous donner des munitions pour ~y~%s~s~, mais vous n\'en avez pas', - ['gave_ammo'] = 'vous donnez ~o~%sx~s~ munitions à ~y~%s~s~', - ['received_ammo'] = 'vous recevez ~o~%sx~s~ munitions de ~b~%s~s~', ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', ['received_money'] = 'vous avez reçu ~g~$%s~s~ par ~b~%s~s~', ['gave_account_money'] = 'vous avez donné ~g~$%s~s~ (%s) à ~y~%s~s~', diff --git a/locales/pl.lua b/locales/pl.lua index 57ee9a5b..09e61c5a 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -23,8 +23,6 @@ Locales['pl'] = { ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', ['received_weapon_noweapon'] = '~b~%s~s~ próbował/a przekazać ci amunicje do ~y~%s~s~, lecz nie posiadasz tej broni', - ['gave_ammo'] = 'dajesz ~o~%sx~s~ naboje dla ~y~%s~s~', - ['received_ammo'] = 'otrzymujesz ~o~%sx~s~ naboje od ~b~%s~s~', ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', ['received_money'] = 'otrzymujesz ~g~%s$~s~ od ~b~%s~s~', ['gave_account_money'] = 'dajesz ~g~%s$~s~ (%s) dla ~y~%s~s~', diff --git a/locales/sv.lua b/locales/sv.lua index 38d9d115..d15ce060 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -14,23 +14,21 @@ Locales['sv'] = { ['gave_item'] = 'du gav ~y~%sx~s~ ~b~%s~s~ till ~y~%s~s~', ['received_item'] = 'du tog emot ~y~%sx~s~ ~b~%s~s~ från ~b~%s~s~', ['gave_weapon'] = 'du gav ~b~%s~s~ till ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'du gav ~o~%sx~s~ skott för ~b~%s~s~ till ~y~%s~s~', ['gave_weapon_withammo'] = 'du gav ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ har redan en ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['gave_weapon_noweapon'] = '~y~%s~s~ har inte det vapnet', ['received_weapon'] = 'du tog emot ~b~%s~s~ från ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'du tog emot ~o~%sx~s~ skott för ~b~%s~s~ från ~b~%s~s~', ['received_weapon_withammo'] = 'du tog emot ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det har du redan', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_ammo'] = 'du gav ~o~%sx~s~ skott till ~y~%s~s~', - ['received_ammo'] = 'du tog emot ~o~%sx~s~ skott från ~b~%s~s~', + ['received_weapon_noweapon'] = '~b~%s~s~ försökte ge dig ammunition för ett ~y~%s~s~, men du har inget sådant vapen', ['gave_money'] = 'du gav ~g~%s SEK~s~ till ~y~%s~s~', ['received_money'] = 'du tog emot ~g~%s SEK~s~ från ~b~%s~s~', ['gave_account_money'] = 'du gav ~g~%s SEK~s~ (%s) till ~y~%s~s~', ['received_account_money'] = 'du tog emot ~g~%s SEK~s~ (%s) från ~b~%s~s~', ['amount_invalid'] = 'ogiltig mängd', - ['players_nearby'] = 'inga spelare nära', + ['players_nearby'] = 'det finns inga spelare nära', ['ex_inv_lim'] = 'åtgärd inte möjligt, översteg förråd gräns för ~y~%s~s~', ['imp_invalid_quantity'] = 'åtgärd omöjlig, ogiltig mängd', ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', From 40f9d2aa1f4789db5dbd248462f901e4abff615c Mon Sep 17 00:00:00 2001 From: Petr Sopf Date: Wed, 23 Oct 2019 21:47:35 +0200 Subject: [PATCH 357/672] Fix pickups not syncing server sided --- server/main.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/main.lua b/server/main.lua index 48821a4d..5b61ae49 100644 --- a/server/main.lua +++ b/server/main.lua @@ -437,12 +437,15 @@ AddEventHandler('esx:onPickup', function(id) if pickup.type == 'item_standard' then if xPlayer.canCarryItem(pickup.name, pickup.count) then xPlayer.addInventoryItem(pickup.name, pickup.count) + ESX.Pickups[id] = nil TriggerClientEvent('esx:removePickup', -1, id) end elseif pickup.type == 'item_money' then + ESX.Pickups[id] = nil TriggerClientEvent('esx:removePickup', -1, id) xPlayer.addMoney(pickup.count) elseif pickup.type == 'item_account' then + ESX.Pickups[id] = nil TriggerClientEvent('esx:removePickup', -1, id) xPlayer.addAccountMoney(pickup.name, pickup.count) end From f32f44f5021e46f1013b783c1d2a2cfe675385c3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 14 Nov 2019 21:25:16 +0100 Subject: [PATCH 358/672] Fixed trailing spaces, and commands.lua use apostrof --- server/commands.lua | 36 ++++++++++++++++++------------------ server/main.lua | 9 ++++----- server/paycheck.lua | 2 +- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/server/commands.lua b/server/commands.lua index 36617956..20044962 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -2,7 +2,7 @@ TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) local x = tonumber(args[1]) local y = tonumber(args[2]) local z = tonumber(args[3]) - + if x and y and z then TriggerClientEvent('esx:teleport', source, { x = x, @@ -10,11 +10,11 @@ TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) z = z }) else - TriggerClientEvent('chatMessage', source, "SYSTEM", {255, 0, 0}, "Invalid coordinates!") + TriggerClientEvent('chatMessage', source, 'SYSTEM', {255, 0, 0}, 'Invalid coordinates!') end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = "Teleport to coordinates", params = {{name = "x", help = "X coords"}, {name = "y", help = "Y coords"}, {name = "z", help = "Z coords"}}}) +end, {help = 'Teleport to coordinates', params = {{name = 'x', help = 'X coords'}, {name = 'y', help = 'Y coords'}, {name = 'z', help = 'Z coords'}}}) TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) if tonumber(args[1]) and args[2] and tonumber(args[3]) then @@ -35,7 +35,7 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('setjob'), params = {{name = "id", help = _U('id_param')}, {name = "job", help = _U('setjob_param2')}, {name = "grade_id", help = _U('setjob_param3')}}}) +end, {help = _U('setjob'), params = {{name = 'id', help = _U('id_param')}, {name = 'job', help = _U('setjob_param2')}, {name = 'grade_id', help = _U('setjob_param3')}}}) TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user) TriggerClientEvent('esx:loadIPL', -1, args[1]) @@ -65,7 +65,7 @@ TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnVehicle', source, args[1]) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_car'), params = {{name = "car", help = _U('spawn_car_param')}}}) +end, {help = _U('spawn_car'), params = {{name = 'car', help = _U('spawn_car_param')}}}) TriggerEvent('es:addGroupCommand', 'cardel', 'admin', function(source, args, user) TriggerClientEvent('esx:deleteVehicle', source) @@ -83,20 +83,20 @@ TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, u TriggerClientEvent('esx:spawnPed', source, args[1]) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_ped'), params = {{name = "name", help = _U('spawn_ped_param')}}}) +end, {help = _U('spawn_ped'), params = {{name = 'name', help = _U('spawn_ped_param')}}}) TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnObject', source, args[1]) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_object'), params = {{name = "name"}}}) +end, {help = _U('spawn_object'), params = {{name = 'name'}}}) TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) local _source = source local target = tonumber(args[1]) local money_type = args[2] local money_amount = tonumber(args[3]) - + local xPlayer = ESX.GetPlayerFromId(target) if target and money_type and money_amount and xPlayer ~= nil then @@ -107,22 +107,22 @@ TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, u elseif money_type == 'black' then xPlayer.setAccountMoney('black_money', money_amount) else - TriggerClientEvent('chatMessage', _source, "SYSTEM", {255, 0, 0}, "^2" .. money_type .. " ^0 is not a valid money type!") + TriggerClientEvent('chatMessage', _source, 'SYSTEM', {255, 0, 0}, '^2' .. money_type .. ' ^0 is not a valid money type!') return end else - TriggerClientEvent('chatMessage', _source, "SYSTEM", {255, 0, 0}, "Invalid arguments.") + TriggerClientEvent('chatMessage', _source, 'SYSTEM', {255, 0, 0}, 'Invalid arguments.') return end - + print('es_extended: ' .. GetPlayerName(source) .. ' just set $' .. money_amount .. ' (' .. money_type .. ') to ' .. xPlayer.name) - + if xPlayer.source ~= _source then TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('setmoney'), params = {{name = "id", help = _U('id_param')}, {name = "money type", help = _U('money_type')}, {name = "amount", help = _U('money_amount')}}}) +end, {help = _U('setmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'money type', help = _U('money_type')}, {name = 'amount', help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) local _source = source @@ -141,7 +141,7 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveaccountmoney'), params = {{name = "id", help = _U('id_param')}, {name = "account", help = _U('account')}, {name = "amount", help = _U('money_amount')}}}) +end, {help = _U('giveaccountmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'account', help = _U('account')}, {name = 'amount', help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) local _source = source @@ -160,7 +160,7 @@ TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, u end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveitem'), params = {{name = "id", help = _U('id_param')}, {name = "item", help = _U('item')}, {name = "amount", help = _U('amount')}}}) +end, {help = _U('giveitem'), params = {{name = 'id', help = _U('id_param')}, {name = 'item', help = _U('item')}, {name = 'amount', help = _U('amount')}}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) local xPlayer = ESX.GetPlayerFromId(args[1]) @@ -169,7 +169,7 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, xPlayer.addWeapon(weaponName, tonumber(args[3])) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveweapon'), params = {{name = "id", help = _U('id_param')}, {name = "weapon", help = _U('weapon')}, {name = "ammo", help = _U('amountammo')}}}) +end, {help = _U('giveweapon'), params = {{name = 'id', help = _U('id_param')}, {name = 'weapon', help = _U('weapon')}, {name = 'ammo', help = _U('amountammo')}}}) TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) DropPlayer(source, 'You have been disconnected') @@ -228,7 +228,7 @@ TriggerEvent('es:addGroupCommand', 'clearinventory', 'admin', function(source, a end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('command_clearinventory'), params = {{name = "playerId", help = _U('command_playerid_param')}}}) +end, {help = _U('command_clearinventory'), params = {{name = 'playerId', help = _U('command_playerid_param')}}}) TriggerEvent('es:addGroupCommand', 'clearloadout', 'admin', function(source, args, user) local xPlayer @@ -249,4 +249,4 @@ TriggerEvent('es:addGroupCommand', 'clearloadout', 'admin', function(source, arg end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('command_clearloadout'), params = {{name = "playerId", help = _U('command_playerid_param')}}}) +end, {help = _U('command_clearloadout'), params = {{name = 'playerId', help = _U('command_playerid_param')}}}) diff --git a/server/main.lua b/server/main.lua index 5b61ae49..bf0eeaeb 100644 --- a/server/main.lua +++ b/server/main.lua @@ -152,7 +152,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) if gradeObject.skin_male ~= nil then userData.job.skin_male = json.decode(gradeObject.skin_male) end - + if gradeObject.skin_female ~= nil then userData.job.skin_female = json.decode(gradeObject.skin_female) end @@ -167,12 +167,12 @@ AddEventHandler('es:playerLoaded', function(source, _player) userData.job.id = jobObject.id userData.job.name = jobObject.name userData.job.label = jobObject.label - + userData.job.grade = tonumber(grade) userData.job.grade_name = gradeObject.name userData.job.grade_label = gradeObject.label userData.job.grade_salary = gradeObject.salary - + userData.job.skin_male = {} userData.job.skin_female = {} end @@ -207,7 +207,6 @@ AddEventHandler('es:playerLoaded', function(source, _player) xPlayer.getMissingAccounts(function(missingAccounts) if #missingAccounts > 0 then - for i=1, #missingAccounts, 1 do table.insert(xPlayer.accounts, { name = missingAccounts[i], @@ -282,7 +281,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if targetXPlayer.canCarryItem(itemName, itemCount) then sourceXPlayer.removeInventoryItem(itemName, itemCount) targetXPlayer.addInventoryItem (itemName, itemCount) - + sourceXPlayer.showNotification(_U('gave_item', itemCount, sourceItem.label, targetXPlayer.name)) targetXPlayer.showNotification(_U('received_item', itemCount, sourceItem.label, sourceXPlayer.name)) else diff --git a/server/paycheck.lua b/server/paycheck.lua index 04719d3b..8df7bf95 100644 --- a/server/paycheck.lua +++ b/server/paycheck.lua @@ -19,7 +19,7 @@ ESX.StartPayCheck = function() if account.money >= salary then -- does the society money to pay its employees? xPlayer.addAccountMoney('bank', salary) account.removeMoney(salary) - + TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), _U('received_paycheck'), _U('received_salary', salary), 'CHAR_BANK_MAZE', 9) else TriggerClientEvent('esx:showAdvancedNotification', xPlayer.source, _U('bank'), '', _U('company_nomoney'), 'CHAR_BANK_MAZE', 1) From aa1ad0a1e8feba8236e3436c308f1b8500ac95a0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 14 Nov 2019 22:26:13 +0100 Subject: [PATCH 359/672] Minor code improvements --- server/functions.lua | 21 +++++++++--------- server/main.lua | 51 +++++++++++++++++--------------------------- 2 files changed, 30 insertions(+), 42 deletions(-) diff --git a/server/functions.lua b/server/functions.lua index 3ab80291..07fa9501 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -41,36 +41,36 @@ ESX.SavePlayer = function(xPlayer, cb) xPlayer.setLastPosition(xPlayer.getCoords()) -- User accounts - for i=1, #xPlayer.accounts, 1 do - if ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] ~= xPlayer.accounts[i].money then + for k,v in ipairs(xPlayer.accounts) do + if ESX.LastPlayerData[xPlayer.source].accounts[v.name] ~= v.money then 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, + ['@money'] = v.money, ['@identifier'] = xPlayer.identifier, - ['@name'] = xPlayer.accounts[i].name + ['@name'] = v.name }, function(rowsChanged) cb() end) end) - ESX.LastPlayerData[xPlayer.source].accounts[xPlayer.accounts[i].name] = xPlayer.accounts[i].money + ESX.LastPlayerData[xPlayer.source].accounts[v.name] = v.money end end -- Inventory items - for i=1, #xPlayer.inventory, 1 do - if ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] ~= xPlayer.inventory[i].count then + for k,v in ipairs(xPlayer.inventory) do + if ESX.LastPlayerData[xPlayer.source].items[v.name] ~= v.count then 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, + ['@count'] = v.count, ['@identifier'] = xPlayer.identifier, - ['@item'] = xPlayer.inventory[i].name + ['@item'] = v.name }, function(rowsChanged) cb() end) end) - ESX.LastPlayerData[xPlayer.source].items[xPlayer.inventory[i].name] = xPlayer.inventory[i].count + ESX.LastPlayerData[xPlayer.source].items[v.name] = v.count end end @@ -135,7 +135,6 @@ ESX.GetPlayers = function() return sources end - ESX.GetPlayerFromId = function(source) return ESX.Players[tonumber(source)] end diff --git a/server/main.lua b/server/main.lua index bf0eeaeb..946b4d1c 100644 --- a/server/main.lua +++ b/server/main.lua @@ -24,19 +24,16 @@ AddEventHandler('es:playerLoaded', function(source, _player) -- Get accounts table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT * FROM user_accounts WHERE identifier = @identifier', { + MySQL.Async.fetchAll('SELECT name, money 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] - }) - break - end + for k,v in ipairs(accounts) do + if Config.Accounts[v.name] then + table.insert(userData.accounts, { + name = v.name, + money = v.money, + label = Config.AccountLabels[v.name] + }) end end @@ -50,12 +47,14 @@ AddEventHandler('es:playerLoaded', function(source, _player) MySQL.Async.fetchAll('SELECT item, count FROM user_inventory WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(inventory) - local tasks2 = {} + local tasks2, foundItems = {}, {} for k,v in ipairs(inventory) do local item = ESX.Items[v.item] if item then + foundItems[v.item] = true + table.insert(userData.inventory, { name = v.item, count = v.count, @@ -70,25 +69,16 @@ AddEventHandler('es:playerLoaded', function(source, _player) end end - for k,v in pairs(ESX.Items) do - local found = false - - for j=1, #userData.inventory do - if userData.inventory[j].name == k then - found = true - break - end - end - - if not found then + for itemName,item in pairs(ESX.Items) do + if not foundItems[itemName] then table.insert(userData.inventory, { - name = k, + name = itemName, count = 0, - label = ESX.Items[k].label, - weight = ESX.Items[k].weight, - usable = ESX.UsableItemsCallbacks[k] ~= nil, - rare = ESX.Items[k].rare, - canRemove = ESX.Items[k].canRemove + label = item.label, + weight = item.weight, + usable = ESX.UsableItemsCallbacks[itemName] ~= nil, + rare = item.rare, + canRemove = item.canRemove }) local scope = function(item, identifier) @@ -103,9 +93,8 @@ AddEventHandler('es:playerLoaded', function(source, _player) end) end - scope(k, player.getIdentifier()) + scope(itemName, player.getIdentifier()) end - end Async.parallelLimit(tasks2, 5, function(results) end) From c7a30efdd1b1d245d9ac8c42512f1c4512c4b3fa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 16 Nov 2019 17:41:41 +0100 Subject: [PATCH 360/672] Added ESX.Table.Set() function and fixed accounts not loading http://www.lua.org/pil/11.5.html --- common/modules/table.lua | 6 ++++++ server/main.lua | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/common/modules/table.lua b/common/modules/table.lua index ea7dad28..3741e01e 100644 --- a/common/modules/table.lua +++ b/common/modules/table.lua @@ -11,6 +11,12 @@ function ESX.Table.SizeOf(t) return count end +function ESX.Table.Set(t) + local set = {} + for k,v in ipairs(t) do set[v] = true end + return set +end + function ESX.Table.IndexOf(t, value) for i=1, #t, 1 do if t[i] == value then diff --git a/server/main.lua b/server/main.lua index 946b4d1c..689e8b35 100644 --- a/server/main.lua +++ b/server/main.lua @@ -27,8 +27,9 @@ AddEventHandler('es:playerLoaded', function(source, _player) MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(accounts) + local validAccounts = ESX.Table.Set(Config.Accounts) for k,v in ipairs(accounts) do - if Config.Accounts[v.name] then + if validAccounts[v.name] then table.insert(userData.accounts, { name = v.name, money = v.money, From 3aa7ada4827defde105114ffa0278a8b8935cd71 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 16 Nov 2019 18:26:36 +0100 Subject: [PATCH 361/672] Follow markdown standard --- README.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 06cbe1ba..1b15eacc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # es_extended + es_extended is a roleplay framework for FiveM. It is developed on top of EssentialMode (aka ES), thus commonly named ESX - the **Es**sentialMode E**x**tended framework for FiveM. -### Links & Read more +## Links & Read more + - [ESX Documentation](https://esx-org.github.io/) - [ESX Discord Community](https://discord.gg/MsWzPqE) - [FiveM Forum Thread](https://forum.fivem.net/t/release-esx-base/39881) @@ -11,7 +13,8 @@ es_extended is a roleplay framework for FiveM. It is developed on top of Essenti ![screenshot](http://i.imgur.com/aPFdJl3.jpg) -### Features +## Features + - Accounts (comes with bank / black money), you can add more accounts - Advanced inventory system (press `F2` ingame) - Job system @@ -20,7 +23,8 @@ es_extended is a roleplay framework for FiveM. It is developed on top of Essenti - i18n (locale) system - Plenty of plugins available -### Requirements +## Requirements + This order also applies in the startup order. - [mysql-async](https://github.com/brouznouf/fivem-mysql-async) @@ -28,9 +32,10 @@ This order also applies in the startup order. - [esplugin_mysql](https://github.com/kanersps/esplugin_mysql) - [async](https://github.com/ESX-Org/async) -### Download & Installation +## Download & Installation ### Using [fvm](https://github.com/qlaffont/fvm-installer) + ``` fvm install --save --folder=essential esx-org/es_extended fvm install --save --folder=esx esx-org/esx_menu_default @@ -49,6 +54,7 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list ``` ### Manually + - Download https://github.com/ESX-Org/es_extended/releases/latest - Put it in the `resource/[essential]` directory - Download https://github.com/ESX-Org/esx_menu_default/releases/latest @@ -58,7 +64,8 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list - Download https://github.com/ESX-Org/esx_menu_list/releases/latest - Put it in the `resource/[esx]/[ui]` directory -## Installation +### Installation + - Import `es_extended.sql` in your database - Configure your `server.cfg` to look like this @@ -73,8 +80,11 @@ start esx_menu_default start esx_menu_list start esx_menu_dialog ``` -# Legal + +## Legal + ### License + es_extended - EssentialMode Extended framework for FiveM Copyright (C) 2015-2019 Jérémie N'gadi From 0439cab26b34f1bbb514108f7c68df380f126a02 Mon Sep 17 00:00:00 2001 From: lemonpea <59174721+lemonpea@users.noreply.github.com> Date: Mon, 23 Dec 2019 17:03:28 +0100 Subject: [PATCH 362/672] Add function to replace all elements. This would be nice to have, it would be easier to manage a menu if it's already opened. Here is an example where I would use it. https://gyazo.com/a5b648502bc15c0c629ce3b86d1759cd --- client/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index 95b89359..d3b68d36 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -197,6 +197,10 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, menu.setElement = function(i, key, val) menu.data.elements[i][key] = val end + + menu.setElements = function(newElements) + menu.data.elements = newElements + end menu.setTitle = function(val) menu.data.title = val From 28bcb5ca71db1f1597aa0f0cfd536e982b8791a2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 13:00:54 +0100 Subject: [PATCH 363/672] Removed commands: /loadipl /unloadipl /playanim /playemote /spawnped /spawnobject --- client/main.lua | 77 --------------------------------------------- locales/br.lua | 7 ----- locales/cs.lua | 7 ----- locales/de.lua | 7 ----- locales/en.lua | 7 ----- locales/fi.lua | 7 ----- locales/fr.lua | 7 ----- locales/pl.lua | 7 ----- locales/sv.lua | 7 ----- server/commands.lua | 73 ++++++++++-------------------------------- 10 files changed, 17 insertions(+), 189 deletions(-) diff --git a/client/main.lua b/client/main.lua index 9c8019c3..5c8be801 100644 --- a/client/main.lua +++ b/client/main.lua @@ -266,47 +266,6 @@ AddEventHandler('esx:setJob', function(job) end end) -RegisterNetEvent('esx:loadIPL') -AddEventHandler('esx:loadIPL', function(name) - Citizen.CreateThread(function() - 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 playerPed = PlayerPedId() - RequestAnimDict(dict) - - while not HasAnimDictLoaded(dict) do - Citizen.Wait(1) - end - - TaskPlayAnim(playerPed, 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 = PlayerPedId() - - TaskStartScenarioInPlace(playerPed, emote, 0, false); - Citizen.Wait(20000) - ClearPedTasks(playerPed) - - end) -end) - RegisterNetEvent('esx:spawnVehicle') AddEventHandler('esx:spawnVehicle', function(model) local playerPed = PlayerPedId() @@ -317,23 +276,6 @@ AddEventHandler('esx:spawnVehicle', function(model) end) end) -RegisterNetEvent('esx:spawnObject') -AddEventHandler('esx:spawnObject', function(model) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) - - ESX.Game.SpawnObject(model, { - x = x, - y = y, - z = z - }, function(obj) - SetEntityHeading(obj, GetEntityHeading(playerPed)) - PlaceObjectOnGroundProperly(obj) - end) -end) - RegisterNetEvent('esx:pickup') AddEventHandler('esx:pickup', function(id, label, player) local ped = GetPlayerPed(GetPlayerFromServerId(player)) @@ -374,25 +316,6 @@ AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName, ammo) CreateAmbientPickup(weaponHash, pickupCoords, 0, ammo, 1, false, true) end) -RegisterNetEvent('esx:spawnPed') -AddEventHandler('esx:spawnPed', function(model) - model = (tonumber(model) ~= nil and tonumber(model) or GetHashKey(model)) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - local forward = GetEntityForwardVector(playerPed) - local x, y, z = table.unpack(coords + forward * 1.0) - - Citizen.CreateThread(function() - RequestModel(model) - - while not HasModelLoaded(model) do - Citizen.Wait(1) - end - - CreatePed(5, model, x, y, z, 0.0, true, false) - end) -end) - RegisterNetEvent('esx:deleteVehicle') AddEventHandler('esx:deleteVehicle', function() local playerPed = PlayerPedId() diff --git a/locales/br.lua b/locales/br.lua index 6dc07cba..e2c5b503 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -53,16 +53,9 @@ Locales['br'] = { ['id_param'] = 'o ID do jogador', ['setjob_param2'] = 'o trabalho que voce deseja atribuir', ['setjob_param3'] = 'o nivel de emprego', - ['load_ipl'] = 'carregar IPL', - ['unload_ipl'] = 'descarregar o IPL', - ['play_anim'] = 'Iniciar animacao', - ['play_emote'] = 'Iniciar emote', ['spawn_car'] = 'spawn um carro', ['spawn_car_param'] = 'nome do carro', ['delete_vehicle'] = 'excluir Veiculo', - ['spawn_object'] = 'spawn objeto', - ['spawn_ped'] = 'spawn ped', - ['spawn_ped_param'] = 'exemplo a_m_m_hillbilly_01', ['givemoney'] = 'dar dinheiro', ['setmoney'] = 'set money for a player', ['money_type'] = 'valid money types: cash, bank, black', diff --git a/locales/cs.lua b/locales/cs.lua index 92e3c5f4..c1dc7c82 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -53,16 +53,9 @@ Locales['cs'] = { ['id_param'] = 'iD hráče', ['setjob_param2'] = 'název přiřazované práce', ['setjob_param3'] = 'úroveň práce', - ['load_ipl'] = 'načíst IPL', - ['unload_ipl'] = 'odnačíst IPL', - ['play_anim'] = 'přehrát animaci', - ['play_emote'] = 'přehrát emoci', ['spawn_car'] = 'spawn auto', ['spawn_car_param'] = 'název auta', ['delete_vehicle'] = 'odstranit vozidlo', - ['spawn_object'] = 'spawn objekt', - ['spawn_ped'] = 'spawn peda', - ['spawn_ped_param'] = 'příklad a_m_m_hillbilly_01', ['givemoney'] = 'dát peníze', ['setmoney'] = 'nastavit peníze hráči', ['money_type'] = 'platné typy peněz: cash, bank, black', diff --git a/locales/de.lua b/locales/de.lua index 91cf4c82..3ba684dd 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -53,16 +53,9 @@ Locales['de'] = { ['id_param'] = 'the ID of the player', ['setjob_param2'] = 'the job you wish to assign', ['setjob_param3'] = 'the job level', - ['load_ipl'] = 'load IPL', - ['unload_ipl'] = 'unload IPL', - ['play_anim'] = 'play animation', - ['play_emote'] = 'play emote', ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', ['delete_vehicle'] = 'deletes Vehicle', - ['spawn_object'] = 'spawn object', - ['spawn_ped'] = 'spawn ped', - ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'give money', ['setmoney'] = 'set money for a player', ['money_type'] = 'valid money types: cash, bank, black', diff --git a/locales/en.lua b/locales/en.lua index ecb89bff..d10db002 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -53,16 +53,9 @@ Locales['en'] = { ['id_param'] = 'the ID of the player', ['setjob_param2'] = 'the job you wish to assign', ['setjob_param3'] = 'the job level', - ['load_ipl'] = 'load IPL', - ['unload_ipl'] = 'unload IPL', - ['play_anim'] = 'play animation', - ['play_emote'] = 'play emote', ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', ['delete_vehicle'] = 'deletes Vehicle', - ['spawn_object'] = 'spawn object', - ['spawn_ped'] = 'spawn ped', - ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'give money', ['setmoney'] = 'set money for a player', ['money_type'] = 'valid money types: cash, bank, black', diff --git a/locales/fi.lua b/locales/fi.lua index 5cbca385..0898fde3 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -53,16 +53,9 @@ Locales['fi'] = { ['id_param'] = 'käyttäjän ID', ['setjob_param2'] = 'työ jonka haluat määrittää', ['setjob_param3'] = 'työn taso', - ['load_ipl'] = 'lataa IPL', - ['unload_ipl'] = 'poista IPL', - ['play_anim'] = 'toista animaatio', - ['play_emote'] = 'toista ele', ['spawn_car'] = 'spawnaa ajoneuvo', ['spawn_car_param'] = 'ajoneuvon nimi', ['delete_vehicle'] = 'poistaa ajoneuvon', - ['spawn_object'] = 'spawnaa objekti', - ['spawn_ped'] = 'spawnaa pedi', - ['spawn_ped_param'] = 'esimerkki a_m_m_hillbilly_01', ['givemoney'] = 'anna rahaa', ['setmoney'] = 'aseta pelaajan rahat', ['money_type'] = 'hyväksytyt rahatyypit: cash, bank, black', diff --git a/locales/fr.lua b/locales/fr.lua index b3f77b7c..09266cfd 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -53,16 +53,9 @@ Locales['fr'] = { ['id_param'] = 'identification du joueur', ['setjob_param2'] = 'le travail que vous souhaitez assigner', ['setjob_param3'] = 'le niveau d\'emploi', - ['load_ipl'] = 'charger IPL', - ['unload_ipl'] = 'décharger IPL', - ['play_anim'] = 'jouer animation', - ['play_emote'] = 'jouer emote', ['spawn_car'] = 'spawn un véhicule', ['spawn_car_param'] = 'nom de la voiture', ['delete_vehicle'] = 'supprimer le véhicule', - ['spawn_object'] = 'engendre un objet', - ['spawn_ped'] = 'spawn ped', - ['spawn_ped_param'] = 'example a_m_m_hillbilly_01', ['givemoney'] = 'donner de l\'argent', ['setmoney'] = 'définir l\'argent pour un joueur', ['money_type'] = 'types de monnaies valides: cash, bank, black', diff --git a/locales/pl.lua b/locales/pl.lua index 09e61c5a..a67dc75a 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -53,16 +53,9 @@ Locales['pl'] = { ['id_param'] = 'ID użytkownika', ['setjob_param2'] = 'praca, którą chcesz przydzielić', ['setjob_param3'] = 'poziom pracy', - ['load_ipl'] = 'załaduj IPL', - ['unload_ipl'] = 'usuń IPL', - ['play_anim'] = 'uruchom animację', - ['play_emote'] = 'uruchom emocje', ['spawn_car'] = 'sprowadź pojazd', ['spawn_car_param'] = 'nazwa samochodu', ['delete_vehicle'] = 'usuń pojazd', - ['spawn_object'] = 'pojaw obiekt', - ['spawn_ped'] = 'pojaw peda', - ['spawn_ped_param'] = 'np. a_m_m_hillbilly_01', ['givemoney'] = 'daj pieniądze', ['setmoney'] = 'ustaw pieniądze dla gracza', ['money_type'] = 'aktualne typy pieniędzy: cash, bank, black', diff --git a/locales/sv.lua b/locales/sv.lua index d15ce060..d0ab8171 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -53,16 +53,9 @@ Locales['sv'] = { ['id_param'] = 'spelarens ID', ['setjob_param2'] = 'det jobb du vill tilldela', ['setjob_param3'] = 'job level', - ['load_ipl'] = 'load IPL', - ['unload_ipl'] = 'unload IPL', - ['play_anim'] = 'spela animering', - ['play_emote'] = 'spela emote', ['spawn_car'] = 'spawna ett fordon', ['spawn_car_param'] = 'namn på fordon', ['delete_vehicle'] = 'ta bort fordon', - ['spawn_object'] = 'spawna föremål', - ['spawn_ped'] = 'spawna NPC', - ['spawn_ped_param'] = 'exempelvis a_m_m_hillbilly_01', ['givemoney'] = 'ge pengar', ['setmoney'] = 'bestäm mängd pengar till en valfri person', ['money_type'] = 'giltiga typer: cash, bank, black', diff --git a/server/commands.lua b/server/commands.lua index 20044962..097fef9a 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -26,7 +26,6 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'That job does not exist.' } }) end - else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end @@ -37,30 +36,6 @@ end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('setjob'), params = {{name = 'id', help = _U('id_param')}, {name = 'job', help = _U('setjob_param2')}, {name = 'grade_id', help = _U('setjob_param3')}}}) -TriggerEvent('es:addGroupCommand', 'loadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:loadIPL', -1, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('load_ipl')}) - -TriggerEvent('es:addGroupCommand', 'unloadipl', 'admin', function(source, args, user) - TriggerClientEvent('esx:unloadIPL', -1, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('unload_ipl')}) - -TriggerEvent('es:addGroupCommand', 'playanim', 'admin', function(source, args, user) - TriggerClientEvent('esx:playAnim', -1, args[1], args[3]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('play_anim')}) - -TriggerEvent('es:addGroupCommand', 'playemote', 'admin', function(source, args, user) - TriggerClientEvent('esx:playEmote', -1, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('play_emote')}) - TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnVehicle', source, args[1]) end, function(source, args, user) @@ -79,18 +54,6 @@ end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('delete_vehicle')}) -TriggerEvent('es:addGroupCommand', 'spawnped', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnPed', source, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_ped'), params = {{name = 'name', help = _U('spawn_ped_param')}}}) - -TriggerEvent('es:addGroupCommand', 'spawnobject', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnObject', source, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_object'), params = {{name = 'name'}}}) - TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) local _source = source local target = tonumber(args[1]) @@ -99,7 +62,7 @@ TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, u local xPlayer = ESX.GetPlayerFromId(target) - if target and money_type and money_amount and xPlayer ~= nil then + if target and money_type and money_amount and xPlayer then if money_type == 'cash' then xPlayer.setMoney(money_amount) elseif money_type == 'bank' then @@ -130,8 +93,8 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, local account = args[2] local amount = tonumber(args[3]) - if amount ~= nil then - if xPlayer.getAccount(account) ~= nil then + if amount then + if xPlayer.getAccount(account) then xPlayer.addAccountMoney(account, amount) else TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) @@ -149,8 +112,8 @@ TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, u local item = args[2] local count = (args[3] == nil and 1 or tonumber(args[3])) - if count ~= nil then - if xPlayer.getInventoryItem(item) ~= nil then + if count then + if xPlayer.getInventoryItem(item) then xPlayer.addInventoryItem(item, count) else TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) @@ -216,15 +179,14 @@ TriggerEvent('es:addGroupCommand', 'clearinventory', 'admin', function(source, a xPlayer = ESX.GetPlayerFromId(source) end - if not xPlayer then - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - return - end - - for i=1, #xPlayer.inventory, 1 do - if xPlayer.inventory[i].count > 0 then - xPlayer.setInventoryItem(xPlayer.inventory[i].name, 0) + if xPlayer then + for i=1, #xPlayer.inventory, 1 do + if xPlayer.inventory[i].count > 0 then + xPlayer.setInventoryItem(xPlayer.inventory[i].name, 0) + end end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) @@ -239,13 +201,12 @@ TriggerEvent('es:addGroupCommand', 'clearloadout', 'admin', function(source, arg xPlayer = ESX.GetPlayerFromId(source) end - if not xPlayer then + if xPlayer then + for i=#xPlayer.loadout, 1, -1 do + xPlayer.removeWeapon(xPlayer.loadout[i].name) + end + else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - return - end - - for i=#xPlayer.loadout, 1, -1 do - xPlayer.removeWeapon(xPlayer.loadout[i].name) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) From f0130e8f384950165b76a3e5135a5912dcd39b3b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 13:39:31 +0100 Subject: [PATCH 364/672] player.lua: test nil values --- server/classes/player.lua | 105 +++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 42 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 8e67fe7f..350a20e3 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -263,16 +263,19 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end local account = self.getAccount(acc) - local prevMoney = account.money - local newMoney = ESX.Math.Round(money) - account.money = newMoney - - if acc == 'bank' then - self.set('bank', newMoney) + if account then + local prevMoney = account.money + local newMoney = ESX.Math.Round(money) + + account.money = newMoney + + if acc == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end self.addAccountMoney = function(acc, money) @@ -282,15 +285,17 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end local account = self.getAccount(acc) - local newMoney = account.money + ESX.Math.Round(money) - account.money = newMoney - - if acc == 'bank' then - self.set('bank', newMoney) + if account then + local newMoney = account.money + ESX.Math.Round(money) + account.money = newMoney + + if acc == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end self.removeAccountMoney = function(acc, money) @@ -300,15 +305,17 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end local account = self.getAccount(acc) - local newMoney = account.money - ESX.Math.Round(money) - account.money = newMoney - - if acc == 'bank' then - self.set('bank', newMoney) + if account then + local newMoney = account.money - ESX.Math.Round(money) + account.money = newMoney + + if acc == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end self.getInventoryItem = function(name) @@ -317,37 +324,51 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return v end end + + return end self.addInventoryItem = function(name, count) - local item = self.getInventoryItem(name) - local newCount = item.count + count - item.count = newCount + local item = self.getInventoryItem(name) - TriggerEvent('esx:onAddInventoryItem', self.source, item, count) - TriggerClientEvent('esx:addInventoryItem', self.source, item, count) + if item then + local newCount = item.count + count + item.count = newCount + + TriggerEvent('esx:onAddInventoryItem', self.source, item, count) + TriggerClientEvent('esx:addInventoryItem', self.source, item, count) + end end self.removeInventoryItem = function(name, count) - local item = self.getInventoryItem(name) - local newCount = item.count - count - item.count = newCount + local item = self.getInventoryItem(name) - TriggerEvent('esx:onRemoveInventoryItem', self.source, item, count) - TriggerClientEvent('esx:removeInventoryItem', self.source, item, count) + if item then + local newCount = item.count - count + + if newCount >= 0 then + item.count = newCount + + TriggerEvent('esx:onRemoveInventoryItem', self.source, item, count) + TriggerClientEvent('esx:removeInventoryItem', self.source, item, count) + end + end end self.setInventoryItem = function(name, count) - local item = self.getInventoryItem(name) - local oldCount = item.count - item.count = count + local item = self.getInventoryItem(name) - if oldCount > item.count then - TriggerEvent('esx:onRemoveInventoryItem', self.source, item, oldCount - item.count) - TriggerClientEvent('esx:removeInventoryItem', self.source, item, oldCount - item.count) - else - TriggerEvent('esx:onAddInventoryItem', self.source, item, item.count - oldCount) - TriggerClientEvent('esx:addInventoryItem', self.source, item, item.count - oldCount) + if item and count >= 0 then + local oldCount = item.count + item.count = count + + if oldCount > item.count then + TriggerEvent('esx:onRemoveInventoryItem', self.source, item, oldCount - item.count) + TriggerClientEvent('esx:removeInventoryItem', self.source, item, oldCount - item.count) + else + TriggerEvent('esx:onAddInventoryItem', self.source, item, item.count - oldCount) + TriggerClientEvent('esx:addInventoryItem', self.source, item, item.count - oldCount) + end end end @@ -522,7 +543,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end - return nil + return end self.showNotification = function(msg) From f9afa6f01790aec37d7a21521ac141263d30dcf7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 13:45:53 +0100 Subject: [PATCH 365/672] player.lua: implement canSwapItem() and triggerEvent() --- server/classes/player.lua | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/server/classes/player.lua b/server/classes/player.lua index 350a20e3..617c04af 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -13,6 +13,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.source = self.player.get('source') self.identifier = self.player.get('identifier') + self.triggerEvent = function(eventName, ...) + TriggerClientEvent(eventName, self.source, ...) + end + self.setMoney = function(money) money = ESX.Math.Round(money) @@ -389,6 +393,20 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return newWeight <= self.maxWeight end + self.canSwapItem = function(firstItem, firstItemCount, testItem, testItemCount) + local firstItemObject = self.getInventoryItem(firstItem) + local testItemObject = self.getInventoryItem(testItem) + + if firstItemObject.count >= firstItemCount then + local weightWithoutFirstItem = ESX.Math.Round(self.getWeight() - (firstItemObject.weight * firstItemCount)) + local weightWithTestItem = ESX.Math.Round(weightWithoutFirstItem + (testItemObject.weight * testItemCount)) + + return weightWithTestItem <= self.maxWeight + end + + return false + end + self.setMaxWeight = function(newWeight) self.maxWeight = newWeight TriggerClientEvent('esx:setMaxWeight', self.source, self.maxWeight) From aad435842bb86e525fc094b8144846321b3c4b15 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 13:47:18 +0100 Subject: [PATCH 366/672] Update player.lua --- server/classes/player.lua | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 617c04af..002d2850 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -271,13 +271,13 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if account then local prevMoney = account.money local newMoney = ESX.Math.Round(money) - + account.money = newMoney - + if acc == 'bank' then self.set('bank', newMoney) end - + TriggerClientEvent('esx:setAccountMoney', self.source, account) end end @@ -293,11 +293,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if account then local newMoney = account.money + ESX.Math.Round(money) account.money = newMoney - + if acc == 'bank' then self.set('bank', newMoney) end - + TriggerClientEvent('esx:setAccountMoney', self.source, account) end end @@ -313,11 +313,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if account then local newMoney = account.money - ESX.Math.Round(money) account.money = newMoney - + if acc == 'bank' then self.set('bank', newMoney) end - + TriggerClientEvent('esx:setAccountMoney', self.source, account) end end @@ -338,7 +338,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if item then local newCount = item.count + count item.count = newCount - + TriggerEvent('esx:onAddInventoryItem', self.source, item, count) TriggerClientEvent('esx:addInventoryItem', self.source, item, count) end @@ -352,7 +352,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if newCount >= 0 then item.count = newCount - + TriggerEvent('esx:onRemoveInventoryItem', self.source, item, count) TriggerClientEvent('esx:removeInventoryItem', self.source, item, count) end @@ -365,7 +365,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if item and count >= 0 then local oldCount = item.count item.count = count - + if oldCount > item.count then TriggerEvent('esx:onRemoveInventoryItem', self.source, item, oldCount - item.count) TriggerClientEvent('esx:removeInventoryItem', self.source, item, oldCount - item.count) @@ -514,7 +514,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l break end end - + TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, weaponComponent) end end @@ -537,7 +537,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return true end end - + return false else return false From 2d80e556311c6026ef4a6910b404b13fd7414e08 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 13:49:40 +0100 Subject: [PATCH 367/672] rename _source variable to playerId --- server/classes/player.lua | 6 +++--- server/commands.lua | 20 ++++++++++---------- server/common.lua | 6 +++--- server/main.lua | 28 ++++++++++++++-------------- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 002d2850..d74b6429 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -456,10 +456,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l label = weaponLabel, components = {} }) - end - TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) - TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) + TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) + TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) + end end self.addWeaponComponent = function(weaponName, weaponComponent) diff --git a/server/commands.lua b/server/commands.lua index 097fef9a..b240f84d 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -55,7 +55,7 @@ end, function(source, args, user) end, {help = _U('delete_vehicle')}) TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) - local _source = source + local playerId = source local target = tonumber(args[1]) local money_type = args[2] local money_amount = tonumber(args[3]) @@ -70,17 +70,17 @@ TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, u elseif money_type == 'black' then xPlayer.setAccountMoney('black_money', money_amount) else - TriggerClientEvent('chatMessage', _source, 'SYSTEM', {255, 0, 0}, '^2' .. money_type .. ' ^0 is not a valid money type!') + TriggerClientEvent('chatMessage', playerId, 'SYSTEM', {255, 0, 0}, '^2' .. money_type .. ' ^0 is not a valid money type!') return end else - TriggerClientEvent('chatMessage', _source, 'SYSTEM', {255, 0, 0}, 'Invalid arguments.') + TriggerClientEvent('chatMessage', playerId, 'SYSTEM', {255, 0, 0}, 'Invalid arguments.') return end print('es_extended: ' .. GetPlayerName(source) .. ' just set $' .. money_amount .. ' (' .. money_type .. ') to ' .. xPlayer.name) - if xPlayer.source ~= _source then + if xPlayer.source ~= playerId then TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) end end, function(source, args, user) @@ -88,7 +88,7 @@ end, function(source, args, user) end, {help = _U('setmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'money type', help = _U('money_type')}, {name = 'amount', help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) - local _source = source + local playerId = source local xPlayer = ESX.GetPlayerFromId(args[1]) local account = args[2] local amount = tonumber(args[3]) @@ -97,17 +97,17 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, if xPlayer.getAccount(account) then xPlayer.addAccountMoney(account, amount) else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_account')) + TriggerClientEvent('esx:showNotification', playerId, _U('invalid_account')) end else - TriggerClientEvent('esx:showNotification', _source, _U('amount_invalid')) + TriggerClientEvent('esx:showNotification', playerId, _U('amount_invalid')) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveaccountmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'account', help = _U('account')}, {name = 'amount', help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) - local _source = source + local playerId = source local xPlayer = ESX.GetPlayerFromId(args[1]) local item = args[2] local count = (args[3] == nil and 1 or tonumber(args[3])) @@ -116,10 +116,10 @@ TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, u if xPlayer.getInventoryItem(item) then xPlayer.addInventoryItem(item, count) else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_item')) + TriggerClientEvent('esx:showNotification', playerId, _U('invalid_item')) end else - TriggerClientEvent('esx:showNotification', _source, _U('invalid_amount')) + TriggerClientEvent('esx:showNotification', playerId, _U('invalid_amount')) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) diff --git a/server/common.lua b/server/common.lua index ed937f54..a72e024e 100644 --- a/server/common.lua +++ b/server/common.lua @@ -83,9 +83,9 @@ end) RegisterServerEvent('esx:triggerServerCallback') AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) - local _source = source + local playerId = source - ESX.TriggerServerCallback(name, requestID, _source, function(...) - TriggerClientEvent('esx:serverCallback', _source, requestId, ...) + ESX.TriggerServerCallback(name, requestID, playerId, function(...) + TriggerClientEvent('esx:serverCallback', playerId, requestId, ...) end, ...) end) diff --git a/server/main.lua b/server/main.lua index 689e8b35..4a224094 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,5 +1,5 @@ AddEventHandler('es:playerLoaded', function(source, _player) - local _source = source + local playerId = source local tasks = {} local userData = { @@ -7,11 +7,11 @@ AddEventHandler('es:playerLoaded', function(source, _player) inventory = {}, job = {}, loadout = {}, - playerName = GetPlayerName(_source), + playerName = GetPlayerName(playerId), lastPosition = nil } - TriggerEvent('es:getPlayerFromId', _source, function(player) + TriggerEvent('es:getPlayerFromId', playerId, function(player) -- Update user name in DB table.insert(tasks, function(cb) MySQL.Async.execute('UPDATE users SET name = @name WHERE identifier = @identifier', { @@ -208,11 +208,11 @@ AddEventHandler('es:playerLoaded', function(source, _player) xPlayer.createAccounts(missingAccounts) end - ESX.Players[_source] = xPlayer + ESX.Players[playerId] = xPlayer - TriggerEvent('esx:playerLoaded', _source, xPlayer) + TriggerEvent('esx:playerLoaded', playerId, xPlayer) - TriggerClientEvent('esx:playerLoaded', _source, { + TriggerClientEvent('esx:playerLoaded', playerId, { identifier = xPlayer.identifier, accounts = xPlayer.getAccounts(), inventory = xPlayer.getInventory(), @@ -224,7 +224,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) }) xPlayer.displayMoney(xPlayer.getMoney()) - TriggerClientEvent('esx:createMissingPickups', _source, ESX.Pickups) + TriggerClientEvent('esx:createMissingPickups', playerId, ESX.Pickups) end) end) @@ -232,15 +232,15 @@ AddEventHandler('es:playerLoaded', function(source, _player) end) AddEventHandler('playerDropped', function(reason) - local _source = source - local xPlayer = ESX.GetPlayerFromId(_source) + local playerId = source + local xPlayer = ESX.GetPlayerFromId(playerId) if xPlayer then - TriggerEvent('esx:playerDropped', _source, reason) + TriggerEvent('esx:playerDropped', playerId, reason) ESX.SavePlayer(xPlayer, function() - ESX.Players[_source] = nil - ESX.LastPlayerData[_source] = nil + ESX.Players[playerId] = nil + ESX.LastPlayerData[playerId] = nil end) end end) @@ -419,9 +419,9 @@ end) RegisterServerEvent('esx:onPickup') AddEventHandler('esx:onPickup', function(id) - local _source = source + local playerId = source local pickup = ESX.Pickups[id] - local xPlayer = ESX.GetPlayerFromId(_source) + local xPlayer = ESX.GetPlayerFromId(playerId) if pickup.type == 'item_standard' then if xPlayer.canCarryItem(pickup.name, pickup.count) then From 756a13f3bb682aab36f32bc9782d6cfefdf664f2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 14:09:07 +0100 Subject: [PATCH 368/672] Add vehicle test for /car command, and use IsModelInCdimage() native --- client/main.lua | 18 ++++++++++++------ client/modules/streaming.lua | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5c8be801..8e7d3a4a 100644 --- a/client/main.lua +++ b/client/main.lua @@ -267,13 +267,19 @@ AddEventHandler('esx:setJob', function(job) end) RegisterNetEvent('esx:spawnVehicle') -AddEventHandler('esx:spawnVehicle', function(model) - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) +AddEventHandler('esx:spawnVehicle', function(vehicle) + local model = (type(vehicle) == 'number' and vehicle or GetHashKey(vehicle)) - ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) - TaskWarpPedIntoVehicle(playerPed, vehicle, -1) - end) + 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') diff --git a/client/modules/streaming.lua b/client/modules/streaming.lua index 143d0c0c..69fffe72 100644 --- a/client/modules/streaming.lua +++ b/client/modules/streaming.lua @@ -1,7 +1,7 @@ function ESX.Streaming.RequestModel(modelHash, cb) modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash)) - if not HasModelLoaded(modelHash) then + if not HasModelLoaded(modelHash) and IsModelInCdimage(modelHash) then RequestModel(modelHash) while not HasModelLoaded(modelHash) do From 418767514876674161fd7088bad2c1ba58fe8ea4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 27 Dec 2019 14:49:29 +0100 Subject: [PATCH 369/672] /dv command changes (see desc) - Added optional /dv argument for deleting vehicles in proximity - Use RequestControlOfEntity native to properly delete entities --- client/main.lua | 40 +++++++++++++++++++++++++++++++++------- server/commands.lua | 12 ++++++++---- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/client/main.lua b/client/main.lua index 8e7d3a4a..cc23ba5f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -323,16 +323,42 @@ AddEventHandler('esx:pickupWeapon', function(weaponPickup, weaponName, ammo) end) RegisterNetEvent('esx:deleteVehicle') -AddEventHandler('esx:deleteVehicle', function() +AddEventHandler('esx:deleteVehicle', function(radius) local playerPed = PlayerPedId() - local vehicle = ESX.Game.GetVehicleInDirection() - if IsPedInAnyVehicle(playerPed, true) then - vehicle = GetVehiclePedIsIn(playerPed, false) - end + if radius and tonumber(radius) then + radius = tonumber(radius) + 0.01 + local vehicles = ESX.Game.GetVehiclesInArea(GetEntityCoords(playerPed), radius) - if DoesEntityExist(vehicle) then - ESX.Game.DeleteVehicle(vehicle) + 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) diff --git a/server/commands.lua b/server/commands.lua index b240f84d..32e8447f 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -43,16 +43,20 @@ end, function(source, args, user) end, {help = _U('spawn_car'), params = {{name = 'car', help = _U('spawn_car_param')}}}) TriggerEvent('es:addGroupCommand', 'cardel', 'admin', function(source, args, user) - TriggerClientEvent('esx:deleteVehicle', source) + TriggerClientEvent('esx:deleteVehicle', source, args[1]) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('delete_vehicle')}) +end, {help = _U('delete_vehicle'), params = { + {name = 'radius', help = 'Optional, delete every vehicle within the specified radius'} +}}) TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) - TriggerClientEvent('esx:deleteVehicle', source) + TriggerClientEvent('esx:deleteVehicle', source, args[1]) end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('delete_vehicle')}) +end, {help = _U('delete_vehicle'), params = { + {name = 'radius', help = 'Optional, delete every vehicle within the specified radius'} +}}) TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) local playerId = source From 8eb1acd0825015940a4e4591c74944f2df42311e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 2 Jan 2020 14:31:46 +0100 Subject: [PATCH 370/672] Fixed round function not properly working in some locales, closes #258 --- common/modules/math.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/modules/math.lua b/common/modules/math.lua index 6b4a4a5d..99a87631 100644 --- a/common/modules/math.lua +++ b/common/modules/math.lua @@ -1,7 +1,8 @@ ESX.Math = {} ESX.Math.Round = function(value, numDecimalPlaces) - return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", value)) + local mult = 10^(numDecimalPlaces or 0) + return math.floor(value * mult + 0.5) / mult end -- credit http://richard.warburton.it From 2539e6fa9d454f559c52e9a719b319ccf7f32ac2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 12:49:07 +0100 Subject: [PATCH 371/672] Added missing exception handlers to commands, removed /setmoney command closes #206 --- locales/br.lua | 5 --- locales/cs.lua | 5 --- locales/de.lua | 5 --- locales/en.lua | 5 --- locales/fi.lua | 5 --- locales/fr.lua | 5 --- locales/pl.lua | 5 --- locales/sv.lua | 5 --- server/commands.lua | 92 ++++++++++++++++++++------------------------- 9 files changed, 40 insertions(+), 92 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index e2c5b503..9f6c9c96 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -56,11 +56,6 @@ Locales['br'] = { ['spawn_car'] = 'spawn um carro', ['spawn_car_param'] = 'nome do carro', ['delete_vehicle'] = 'excluir Veiculo', - ['givemoney'] = 'dar dinheiro', - ['setmoney'] = 'set money for a player', - ['money_type'] = 'valid money types: cash, bank, black', - ['money_set'] = 'someone ~y~highly ranked~s~ just set ~g~$%s~s~ (%s) for you!', - ['money_amount'] = 'quantia de dinheiro', ['invalid_account'] = 'conta invalida', ['account'] = 'conta', ['giveaccountmoney'] = 'dar dinheiro da conta', diff --git a/locales/cs.lua b/locales/cs.lua index c1dc7c82..f0bd3966 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -56,11 +56,6 @@ Locales['cs'] = { ['spawn_car'] = 'spawn auto', ['spawn_car_param'] = 'název auta', ['delete_vehicle'] = 'odstranit vozidlo', - ['givemoney'] = 'dát peníze', - ['setmoney'] = 'nastavit peníze hráči', - ['money_type'] = 'platné typy peněz: cash, bank, black', - ['money_set'] = 'někdo s ~y~vysokou úrovní~s~ vám právě nastavil ~g~$%s~s~ (%s)!', - ['money_amount'] = 'množství peněz', ['invalid_account'] = 'neplatný účet', ['account'] = 'účet', ['giveaccountmoney'] = 'dát peníze na účet', diff --git a/locales/de.lua b/locales/de.lua index 3ba684dd..e0be6b73 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -56,11 +56,6 @@ Locales['de'] = { ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', ['delete_vehicle'] = 'deletes Vehicle', - ['givemoney'] = 'give money', - ['setmoney'] = 'set money for a player', - ['money_type'] = 'valid money types: cash, bank, black', - ['money_set'] = 'someone ~y~highly ranked~s~ just set ~g~$%s~s~ (%s) for you!', - ['money_amount'] = 'amount of money', ['invalid_account'] = 'invalid account', ['account'] = 'account', ['giveaccountmoney'] = 'give account money', diff --git a/locales/en.lua b/locales/en.lua index d10db002..0001af22 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -56,11 +56,6 @@ Locales['en'] = { ['spawn_car'] = 'spawn a car', ['spawn_car_param'] = 'name of car', ['delete_vehicle'] = 'deletes Vehicle', - ['givemoney'] = 'give money', - ['setmoney'] = 'set money for a player', - ['money_type'] = 'valid money types: cash, bank, black', - ['money_set'] = 'someone ~y~highly ranked~s~ just set ~g~$%s~s~ (%s) for you!', - ['money_amount'] = 'amount of money', ['invalid_account'] = 'invalid account', ['account'] = 'account', ['giveaccountmoney'] = 'give account money', diff --git a/locales/fi.lua b/locales/fi.lua index 0898fde3..2105d3e2 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -56,11 +56,6 @@ Locales['fi'] = { ['spawn_car'] = 'spawnaa ajoneuvo', ['spawn_car_param'] = 'ajoneuvon nimi', ['delete_vehicle'] = 'poistaa ajoneuvon', - ['givemoney'] = 'anna rahaa', - ['setmoney'] = 'aseta pelaajan rahat', - ['money_type'] = 'hyväksytyt rahatyypit: cash, bank, black', - ['money_set'] = 'joku ~y~korkeesti rankattu~s~ asetti ~g~$%s~s~ (%s) sinulle!', - ['money_amount'] = 'rahan määrä', ['invalid_account'] = 'virheellinen tunnus', ['account'] = 'tunnus', ['giveaccountmoney'] = 'anna tilille rahaa', diff --git a/locales/fr.lua b/locales/fr.lua index 09266cfd..5dd22293 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -56,11 +56,6 @@ Locales['fr'] = { ['spawn_car'] = 'spawn un véhicule', ['spawn_car_param'] = 'nom de la voiture', ['delete_vehicle'] = 'supprimer le véhicule', - ['givemoney'] = 'donner de l\'argent', - ['setmoney'] = 'définir l\'argent pour un joueur', - ['money_type'] = 'types de monnaies valides: cash, bank, black', - ['money_set'] = 'quelqu\'un de ~y~haut placé~s~ vous a attribué ~g~$%s~s~ (%s) !', - ['money_amount'] = 'somme d\'argent', ['invalid_account'] = 'compte invalide', ['account'] = 'compte', ['giveaccountmoney'] = 'donner de l\'argent au compte', diff --git a/locales/pl.lua b/locales/pl.lua index a67dc75a..a8f22d78 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -56,11 +56,6 @@ Locales['pl'] = { ['spawn_car'] = 'sprowadź pojazd', ['spawn_car_param'] = 'nazwa samochodu', ['delete_vehicle'] = 'usuń pojazd', - ['givemoney'] = 'daj pieniądze', - ['setmoney'] = 'ustaw pieniądze dla gracza', - ['money_type'] = 'aktualne typy pieniędzy: cash, bank, black', - ['money_set'] = 'ktoś ~y~wysoko postawiony~s~ podarował Ci pieniądze i masz teraz ~g~%s$~s~ (%s)!', - ['money_amount'] = 'kwota pieniędzy', ['invalid_account'] = 'błędne konto', ['account'] = 'konto', ['giveaccountmoney'] = 'daj pieniądze na konto', diff --git a/locales/sv.lua b/locales/sv.lua index d0ab8171..6db1b5b7 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -56,11 +56,6 @@ Locales['sv'] = { ['spawn_car'] = 'spawna ett fordon', ['spawn_car_param'] = 'namn på fordon', ['delete_vehicle'] = 'ta bort fordon', - ['givemoney'] = 'ge pengar', - ['setmoney'] = 'bestäm mängd pengar till en valfri person', - ['money_type'] = 'giltiga typer: cash, bank, black', - ['money_set'] = 'någon ~y~högt uppsatt~s~ satte ~g~%s SEK~s~ (%s) för dig!', - ['money_amount'] = 'summa pengar', ['invalid_account'] = 'ogiltigt konto', ['account'] = 'konto', ['giveaccountmoney'] = 'ge spelarkonto pengar', diff --git a/server/commands.lua b/server/commands.lua index 32e8447f..81e485cb 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -58,82 +58,70 @@ end, {help = _U('delete_vehicle'), params = { {name = 'radius', help = 'Optional, delete every vehicle within the specified radius'} }}) -TriggerEvent('es:addGroupCommand', 'setmoney', 'admin', function(source, args, user) - local playerId = source - local target = tonumber(args[1]) - local money_type = args[2] - local money_amount = tonumber(args[3]) - - local xPlayer = ESX.GetPlayerFromId(target) - - if target and money_type and money_amount and xPlayer then - if money_type == 'cash' then - xPlayer.setMoney(money_amount) - elseif money_type == 'bank' then - xPlayer.setAccountMoney('bank', money_amount) - elseif money_type == 'black' then - xPlayer.setAccountMoney('black_money', money_amount) - else - TriggerClientEvent('chatMessage', playerId, 'SYSTEM', {255, 0, 0}, '^2' .. money_type .. ' ^0 is not a valid money type!') - return - end - else - TriggerClientEvent('chatMessage', playerId, 'SYSTEM', {255, 0, 0}, 'Invalid arguments.') - return - end - - print('es_extended: ' .. GetPlayerName(source) .. ' just set $' .. money_amount .. ' (' .. money_type .. ') to ' .. xPlayer.name) - - if xPlayer.source ~= playerId then - TriggerClientEvent('esx:showNotification', xPlayer.source, _U('money_set', money_amount, money_type)) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('setmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'money type', help = _U('money_type')}, {name = 'amount', help = _U('money_amount')}}}) - TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) - local playerId = source local xPlayer = ESX.GetPlayerFromId(args[1]) - local account = args[2] - local amount = tonumber(args[3]) - if amount then - if xPlayer.getAccount(account) then - xPlayer.addAccountMoney(account, amount) + if xPlayer then + local account = args[2] + local amount = tonumber(args[3]) + + if amount then + if xPlayer.getAccount(account) then + xPlayer.addAccountMoney(account, amount) + else + TriggerClientEvent('esx:showNotification', source, _U('invalid_account')) + end else - TriggerClientEvent('esx:showNotification', playerId, _U('invalid_account')) + TriggerClientEvent('esx:showNotification', source, _U('amount_invalid')) end else - TriggerClientEvent('esx:showNotification', playerId, _U('amount_invalid')) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveaccountmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'account', help = _U('account')}, {name = 'amount', help = _U('money_amount')}}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) - local playerId = source local xPlayer = ESX.GetPlayerFromId(args[1]) - local item = args[2] - local count = (args[3] == nil and 1 or tonumber(args[3])) - if count then - if xPlayer.getInventoryItem(item) then - xPlayer.addInventoryItem(item, count) + if xPlayer then + local item = args[2] + local count = tonumber(args[3]) + + if count then + if xPlayer.getInventoryItem(item) then + xPlayer.addInventoryItem(item, count) + else + TriggerClientEvent('esx:showNotification', source, _U('invalid_item')) + end else - TriggerClientEvent('esx:showNotification', playerId, _U('invalid_item')) + TriggerClientEvent('esx:showNotification', source, _U('invalid_amount')) end else - TriggerClientEvent('esx:showNotification', playerId, _U('invalid_amount')) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveitem'), params = {{name = 'id', help = _U('id_param')}, {name = 'item', help = _U('item')}, {name = 'amount', help = _U('amount')}}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[1]) - local weaponName = string.upper(args[2]) + local xPlayer = ESX.GetPlayerFromId(args[1]) - xPlayer.addWeapon(weaponName, tonumber(args[3])) + if xPlayer then + local weaponName = args[2] or 'unknown' + + if ESX.GetWeapon(weaponName) then + if xPlayer.hasWeapon(weaponName) then + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon.' } }) + else + xPlayer.addWeapon(weaponName, tonumber(args[3])) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon.' } }) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) + end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('giveweapon'), params = {{name = 'id', help = _U('id_param')}, {name = 'weapon', help = _U('weapon')}, {name = 'ammo', help = _U('amountammo')}}}) From ffa05600a4bdfb286485d753e2ee814bbdd75961 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 13:05:16 +0100 Subject: [PATCH 372/672] Updated readme --- README.md | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 1b15eacc..fd1543f1 100644 --- a/README.md +++ b/README.md @@ -1,27 +1,22 @@ # es_extended -es_extended is a roleplay framework for FiveM. It is developed on top of EssentialMode (aka ES), thus commonly named ESX - the **Es**sentialMode E**x**tended framework for FiveM. +es_extended is a roleplay framework for FiveM. It is developed on top of EssentialMode (aka ES), where the project ESX is originating from - the **Es**sentialMode E**x**tended framework for FiveM. ## Links & Read more - [ESX Documentation](https://esx-org.github.io/) -- [ESX Discord Community](https://discord.gg/MsWzPqE) -- [FiveM Forum Thread](https://forum.fivem.net/t/release-esx-base/39881) +- [ESX Development Discord](https://discord.gg/MsWzPqE) - [FiveM Native Reference](https://runtime.fivem.net/doc/reference.html) -### Screenshot preview (todo) - -![screenshot](http://i.imgur.com/aPFdJl3.jpg) - ## Features -- Accounts (comes with bank / black money), you can add more accounts -- Advanced inventory system (press `F2` ingame) -- Job system -- Loadouts and position synced in database -- The best framework out there for RP servers -- i18n (locale) system -- Plenty of plugins available +- Weight based inventory system +- Weapons support, including support for attachments +- Supports different money accounts (defaulted with bank & black money) +- Many official resources available in our GitHub +- Job system, with grades and clothes support +- Supports multiple languages, most strings are localized +- Easy to use API ## Requirements @@ -87,7 +82,7 @@ start esx_menu_dialog es_extended - EssentialMode Extended framework for FiveM -Copyright (C) 2015-2019 Jérémie N'gadi +Copyright (C) 2015-2020 Jérémie N'gadi This program Is free software: you can redistribute it And/Or modify it under the terms Of the GNU General Public License As published by the Free Software Foundation, either version 3 Of the License, Or (at your option) any later version. From 2140f8628c345efb437a494e7bd88f792aad0c3c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 13:55:23 +0100 Subject: [PATCH 373/672] Added log level to print uses, and change formatting --- server/classes/player.lua | 93 +++++++++++++++------------------------ server/common.lua | 10 +++-- server/functions.lua | 9 ++-- server/main.lua | 4 +- 4 files changed, 49 insertions(+), 67 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index d74b6429..fe1cf5e0 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -22,8 +22,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if money >= 0 then self.player.setMoney(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried setting -1 cash balance)'):format(self.identifier)) end end @@ -36,8 +34,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if money >= 0 then self.player.setBankBalance(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried setting -1 bank balance)'):format(self.identifier)) end end @@ -69,38 +65,30 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if money >= 0 then self.player.addMoney(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried adding -1 cash balance)'):format(self.identifier)) end end self.removeMoney = function(money) money = ESX.Math.Round(money) - if money >= 0 then + if money > 0 then self.player.removeMoney(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried removing -1 cash balance)'):format(self.identifier)) end end self.addBank = function(money) money = ESX.Math.Round(money) - if money >= 0 then + if money > 0 then self.player.addBank(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried adding -1 bank balance)'):format(self.identifier)) end end self.removeBank = function(money) money = ESX.Math.Round(money) - if money >= 0 then + if money > 0 then self.player.removeBank(money) - else - print(('es_extended: %s attempted exploiting! (reason: player tried removing -1 bank balance)'):format(self.identifier)) end end @@ -261,64 +249,55 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.setAccountMoney = function(acc, money) - if money < 0 then - print(('es_extended: %s attempted exploiting! (reason: player tried setting -1 account balance)'):format(self.identifier)) - return - end + if money >= 0 then + local account = self.getAccount(acc) - local account = self.getAccount(acc) + if account then + local prevMoney = account.money + local newMoney = ESX.Math.Round(money) - if account then - local prevMoney = account.money - local newMoney = ESX.Math.Round(money) + account.money = newMoney - account.money = newMoney + if acc == 'bank' then + self.set('bank', newMoney) + end - if acc == 'bank' then - self.set('bank', newMoney) + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end end self.addAccountMoney = function(acc, money) - if money < 0 then - print(('es_extended: %s attempted exploiting! (reason: player tried adding -1 account balance)'):format(self.identifier)) - return - end + if money > 0 then + local account = self.getAccount(acc) - local account = self.getAccount(acc) - - if account then - local newMoney = account.money + ESX.Math.Round(money) - account.money = newMoney - - if acc == 'bank' then - self.set('bank', newMoney) + if account then + local newMoney = account.money + ESX.Math.Round(money) + account.money = newMoney + + if acc == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end end self.removeAccountMoney = function(acc, money) - if money < 0 then - print(('es_extended: %s attempted exploiting! (reason: player tried removing -1 account balance)'):format(self.identifier)) - return - end + if money > 0 then + local account = self.getAccount(acc) - local account = self.getAccount(acc) - - if account then - local newMoney = account.money - ESX.Math.Round(money) - account.money = newMoney - - if acc == 'bank' then - self.set('bank', newMoney) + if account then + local newMoney = account.money - ESX.Math.Round(money) + account.money = newMoney + + if acc == 'bank' then + self.set('bank', newMoney) + end + + TriggerClientEvent('esx:setAccountMoney', self.source, account) end - - TriggerClientEvent('esx:setAccountMoney', self.source, account) end end @@ -442,7 +421,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l TriggerEvent('esx:setJob', self.source, self.job, lastJob) TriggerClientEvent('esx:setJob', self.source, self.job) else - print(('es_extended: ignoring setJob for %s due to job not found!'):format(self.source)) + print(('[es_extended] [^3WARNING^7] Ignoring invalid .setJob() usage for "%s"'):format(self.identifier)) end end diff --git a/server/common.lua b/server/common.lua index a72e024e..b3c76c71 100644 --- a/server/common.lua +++ b/server/common.lua @@ -43,16 +43,18 @@ MySQL.ready(function() if ESX.Jobs[result2[i].job_name] then ESX.Jobs[result2[i].job_name].grades[tostring(result2[i].grade)] = result2[i] else - print(('es_extended: invalid job "%s" from table job_grades ignored!'):format(result2[i].job_name)) + print(('[es_extended] [^3WARNING^7] Invalid job "%s" from table job_grades ignored'):format(result2[i].job_name)) end end for k,v in pairs(ESX.Jobs) do if next(v.grades) == nil then ESX.Jobs[v.name] = nil - print(('es_extended: ignoring job "%s" due to missing job grades!'):format(v.name)) + print(('[es_extended] [^3WARNING^7] Ignoring job "%s" due to missing job grades'):format(v.name)) end end + + print('[es_extended] [^2INFO^7] ESX developed by ESX-Org has been initialized') end) AddEventHandler('esx:playerLoaded', function(source) @@ -78,7 +80,9 @@ end) RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) - RconPrint(msg .. "\n") + if Config.EnableDebug then + print(('[es_extended] [^2TRACE^7] %s'):format(msg)) + end end) RegisterServerEvent('esx:triggerServerCallback') diff --git a/server/functions.lua b/server/functions.lua index 07fa9501..7c883aa5 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -1,6 +1,6 @@ ESX.Trace = function(str) if Config.EnableDebug then - print('ESX> ' .. str) + print(('[es_extended] [^2TRACE^7] %s'):format(str)) end end @@ -32,7 +32,7 @@ ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) if ESX.ServerCallbacks[name] ~= nil then ESX.ServerCallbacks[name](source, cb, ...) else - print('es_extended: TriggerServerCallback => [' .. name .. '] does not exist') + print(('[es_extended] [^3WARNING^7] Server callback "%s" does not exist. Make sure that the server sided file really is loading, an error in that file might cause it to not load.'):format(name)) end end @@ -88,7 +88,7 @@ ESX.SavePlayer = function(xPlayer, cb) end) Async.parallel(asyncTasks, function(results) - RconPrint('[SAVED] ' .. xPlayer.name .. "^7\n") + print(('[es_extended] [^2INFO^7] Saved %s'):format(xPlayer.getName())) if cb ~= nil then cb() @@ -108,8 +108,7 @@ ESX.SavePlayers = function(cb) end Async.parallelLimit(asyncTasks, 8, function(results) - RconPrint('[SAVED] All players' .. "\n") - + print(('[es_extended] [^2INFO^7] Saved %s player(s)'):format(#xPlayers)) if cb ~= nil then cb() end diff --git a/server/main.lua b/server/main.lua index 4a224094..c1bf5861 100644 --- a/server/main.lua +++ b/server/main.lua @@ -66,7 +66,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) canRemove = item.canRemove }) else - print(('es_extended: invalid item "%s" ignored!'):format(v.item)) + print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(v.item, player.getIdentifier())) end end @@ -147,7 +147,7 @@ AddEventHandler('es:playerLoaded', function(source, _player) userData.job.skin_female = json.decode(gradeObject.skin_female) end else - print(('es_extended: %s had an unknown job [job: %s, grade: %s], setting as unemployed!'):format(player.getIdentifier(), job, grade)) + print(('[es_extended] [^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(player.getIdentifier(), job, grade)) local job, grade = 'unemployed', '0' local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] From bf9c14ed57b2e1094a1cbfbd2b105997dfc43a45 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 17:56:44 +0100 Subject: [PATCH 374/672] Added /giveweaponcomponent command, easier to understand parms table --- server/commands.lua | 68 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 6 deletions(-) diff --git a/server/commands.lua b/server/commands.lua index 81e485cb..3c525759 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -14,7 +14,11 @@ TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = 'Teleport to coordinates', params = {{name = 'x', help = 'X coords'}, {name = 'y', help = 'Y coords'}, {name = 'z', help = 'Z coords'}}}) +end, {help = 'Teleport to coordinates', params = { + {name = 'x', help = 'X coords'}, + {name = 'y', help = 'Y coords'}, + {name = 'z', help = 'Z coords'} +}}) TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) if tonumber(args[1]) and args[2] and tonumber(args[3]) then @@ -34,7 +38,11 @@ TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('setjob'), params = {{name = 'id', help = _U('id_param')}, {name = 'job', help = _U('setjob_param2')}, {name = 'grade_id', help = _U('setjob_param3')}}}) +end, {help = _U('setjob'), params = { + {name = 'playerId', help = _U('id_param')}, + {name = 'job', help = _U('setjob_param2')}, + {name = 'grade_id', help = _U('setjob_param3')} +}}) TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) TriggerClientEvent('esx:spawnVehicle', source, args[1]) @@ -64,7 +72,7 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, if xPlayer then local account = args[2] local amount = tonumber(args[3]) - + if amount then if xPlayer.getAccount(account) then xPlayer.addAccountMoney(account, amount) @@ -79,7 +87,11 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveaccountmoney'), params = {{name = 'id', help = _U('id_param')}, {name = 'account', help = _U('account')}, {name = 'amount', help = _U('money_amount')}}}) +end, {help = _U('giveaccountmoney'), params = { + {name = 'playerId', help = _U('id_param')}, + {name = 'account', help = _U('account')}, + {name = 'amount', help = _U('money_amount')} +}}) TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) local xPlayer = ESX.GetPlayerFromId(args[1]) @@ -102,7 +114,11 @@ TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, u end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveitem'), params = {{name = 'id', help = _U('id_param')}, {name = 'item', help = _U('item')}, {name = 'amount', help = _U('amount')}}}) +end, {help = _U('giveitem'), params = { + {name = 'playerId', help = _U('id_param')}, + {name = 'item', help = _U('item')}, + {name = 'amount', help = _U('amount')} +}}) TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) local xPlayer = ESX.GetPlayerFromId(args[1]) @@ -124,7 +140,47 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, end end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveweapon'), params = {{name = 'id', help = _U('id_param')}, {name = 'weapon', help = _U('weapon')}, {name = 'ammo', help = _U('amountammo')}}}) +end, {help = _U('giveweapon'), params = { + {name = 'playerId', help = _U('id_param')}, + {name = 'weapon', help = _U('weapon')}, + {name = 'ammo', help = _U('amountammo')} +}}) + +TriggerEvent('es:addGroupCommand', 'giveweaponcomponent', 'admin', function(source, args, user) + local xPlayer = ESX.GetPlayerFromId(args[1]) + + if xPlayer then + local weapon = args[2] or 'unknown' + + if ESX.GetWeapon(weapon) then + if xPlayer.hasWeapon(weapon) then + local component = ESX.GetWeaponComponent(weapon, args[3] or 'unknown') + + if component then + if xPlayer.hasWeaponComponent(weapon, args[3]) then + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon component.' } }) + else + xPlayer.addWeaponComponent(weapon, args[3]) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon component.' } }) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player does not have that weapon.' } }) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon.' } }) + end + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) + end +end, function(source, args, user) + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) +end, {help = 'Give weapon component', params = { + {name = 'playerId', help = _U('id_param')}, + {name = 'weapon', help = _U('weapon')}, + {name = 'component', help = 'weapon component'} +}}) TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) DropPlayer(source, 'You have been disconnected') From 9b33a3e6ca09db51199b2440982e9103eab6f35a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 19:10:25 +0100 Subject: [PATCH 375/672] Fix math round function again Co-Authored-By: hugocabral --- common/modules/math.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/common/modules/math.lua b/common/modules/math.lua index 99a87631..947ccd78 100644 --- a/common/modules/math.lua +++ b/common/modules/math.lua @@ -1,8 +1,12 @@ ESX.Math = {} ESX.Math.Round = function(value, numDecimalPlaces) - local mult = 10^(numDecimalPlaces or 0) - return math.floor(value * mult + 0.5) / mult + if numDecimalPlaces then + local power = 10^numDecimalPlaces + return math.floor((value * power) + 0.5) / (power) + else + return math.floor(value + 0.5) + end end -- credit http://richard.warburton.it From 2f751524578980e0966c9f6b68be4d094de484f7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 3 Jan 2020 19:20:26 +0100 Subject: [PATCH 376/672] Changed how pickups work, see desc. Fixed #338, fixed #420 - Pickups now require you to press E once nearby to pick up - Fixed pickup objects sometimes not showing up #420 - Added animation to picking up and throwing items - Added message when inventory cannot accept picking up item --- client/functions.lua | 13 ++++++--- client/main.lua | 63 ++++++++++++++++++++++++++------------------ locales/br.lua | 6 +++-- locales/cs.lua | 6 +++-- locales/de.lua | 6 +++-- locales/en.lua | 6 +++-- locales/fi.lua | 6 +++-- locales/fr.lua | 6 +++-- locales/pl.lua | 7 ++--- locales/sv.lua | 6 +++-- server/main.lua | 32 ++++++++++++---------- 11 files changed, 98 insertions(+), 59 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 95b89359..5a56dd4d 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1199,19 +1199,26 @@ ESX.ShowInventory = function() end elseif data1.current.action == 'remove' then if IsPedOnFoot(playerPed) then + local dict, anim = 'weapons@first_person@aim_rng@generic@projectile@sticky_bomb@', 'plant_floor' + ESX.Streaming.RequestAnimDict(dict) + if type == 'item_weapon' then - TriggerServerEvent('esx:removeInventoryItem', type, item) menu1.close() - else -- type: item_standard + TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) + Citizen.Wait(1000) + TriggerServerEvent('esx:removeInventoryItem', type, item) + else ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { title = _U('amount') }, function(data2, menu2) local quantity = tonumber(data2.value) if quantity then - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) menu2.close() menu1.close() + TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) + Citizen.Wait(1000) + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) else ESX.ShowNotification(_U('amount_invalid')) end diff --git a/client/main.lua b/client/main.lua index cc23ba5f..7275114c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -51,13 +51,14 @@ AddEventHandler('esx:createMissingPickups', function(missingPickups) ESX.Game.SpawnLocalObject('prop_money_bag_01', v.coords, function(obj) SetEntityAsMissionEntity(obj, true, false) PlaceObjectOnGroundProperly(obj) + FreezeEntityPosition(obj, true) pickups[pickupId] = { id = pickupId, obj = obj, label = v.label, inRange = false, - coords = v.coords + coords = vector3(v.coords.x, v.coords.y, v.coords.z) } end) end @@ -273,7 +274,7 @@ AddEventHandler('esx:spawnVehicle', function(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) @@ -287,22 +288,19 @@ 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) + coords = (coords + forward * 2.0) - ESX.Game.SpawnLocalObject('prop_money_bag_01', { - x = x, - y = y, - z = z - 2.0, - }, function(obj) + ESX.Game.SpawnLocalObject('prop_money_bag_01', coords, function(obj) SetEntityAsMissionEntity(obj, true, false) PlaceObjectOnGroundProperly(obj) + FreezeEntityPosition(obj, true) pickups[id] = { id = id, obj = obj, label = label, inRange = false, - coords = {x = x, y = y, z = z} + coords = coords } end) end) @@ -462,32 +460,47 @@ end 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 + local playerCoords, letSleep = GetEntityCoords(playerPed), true + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() 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() + local distance = #(playerCoords - v.coords) + + if distance < 5 then + local label = v.label + letSleep = false + + if distance < 1 then + if IsControlJustReleased(0, 38) then + if IsPedOnFoot(playerPed) and (closestDistance == -1 or closestDistance > 3) and not v.inRange then + v.inRange = true + + local dict, anim = 'weapons@first_person@aim_rng@generic@projectile@sticky_bomb@', 'plant_floor' + ESX.Streaming.RequestAnimDict(dict) + TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) + Citizen.Wait(1000) + + TriggerServerEvent('esx:onPickup', v.id) + PlaySoundFrontend(-1, 'PICK_UP', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) + end + end + + label = ('%s~n~%s'):format(label, _U('threw_pickup_prompt')) + end - 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) + }, label, 1.2, 1) + elseif v.inRange then + v.inRange = false end + 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 + if letSleep then + Citizen.Wait(500) end end end) diff --git a/locales/br.lua b/locales/br.lua index 9f6c9c96..b84c6424 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -33,10 +33,12 @@ Locales['br'] = { ['imp_invalid_quantity'] = 'acao impossivel, quantidade invalida', ['imp_invalid_amount'] = 'acao impossivel, valor invalido', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', ['received_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', diff --git a/locales/cs.lua b/locales/cs.lua index f0bd3966..6a61bc90 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -33,10 +33,12 @@ Locales['cs'] = { ['imp_invalid_quantity'] = 'akce není možná, neplatný počet', ['imp_invalid_amount'] = 'akce není možná, neplatné množství', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', diff --git a/locales/de.lua b/locales/de.lua index e0be6b73..98d5f843 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -33,10 +33,12 @@ Locales['de'] = { ['imp_invalid_quantity'] = 'aktion nicht möglich, ungültige Anzahl', ['imp_invalid_amount'] = 'aktion nicht möglich, ungültiger Betrag', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', ['received_help'] = 'du hast deine Sozialhilfe erhalten: ~g~$%s~s~', diff --git a/locales/en.lua b/locales/en.lua index 0001af22..c5300254 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -33,10 +33,12 @@ Locales['en'] = { ['imp_invalid_quantity'] = 'action impossible, invalid quantity', ['imp_invalid_amount'] = 'action impossible, invalid amount', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'you received your salary: ~g~$%s~s~', ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', diff --git a/locales/fi.lua b/locales/fi.lua index 2105d3e2..626d853d 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -33,10 +33,12 @@ Locales['fi'] = { ['imp_invalid_quantity'] = 'toiminto mahdoton, virheellinen määrä', ['imp_invalid_amount'] = 'toiminto mahdoton, virhellinen summa', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', ['received_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', diff --git a/locales/fr.lua b/locales/fr.lua index 5dd22293..07de2fc6 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -33,10 +33,12 @@ Locales['fr'] = { ['imp_invalid_quantity'] = 'action impossible, ~r~quantité invalide', ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', ['threw_standard'] = 'vous avez jeté ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'vous avez jeté ~r~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'vous avez jeté ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'vous avez jeté ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'vous avez jeté ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', ['received_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', diff --git a/locales/pl.lua b/locales/pl.lua index a8f22d78..c46546e5 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -33,11 +33,12 @@ Locales['pl'] = { ['imp_invalid_quantity'] = 'akcja jest niemożliwa, nieprawidłowa ilość', ['imp_invalid_amount'] = 'akcja jest niemożliwa, nieprawidłowa kwota', ['threw_standard'] = 'wyrzuciłeś/aś ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~gotówki~s~', - ['threw_account'] = 'wyrzuciłeś/aś ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~gotówki~s~', + ['threw_account'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami', - + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', diff --git a/locales/sv.lua b/locales/sv.lua index 6db1b5b7..39b15a72 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -33,10 +33,12 @@ Locales['sv'] = { ['imp_invalid_quantity'] = 'åtgärd omöjlig, ogiltig mängd', ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', ['threw_standard'] = 'du kastade ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'du kastade ~r~$%s~s~ ~b~kontanter~s~', - ['threw_account'] = 'du kastade ~r~$%s~s~ ~b~%s~s~', + ['threw_money'] = 'du kastade ~g~%s SEK~s~ ~b~kontanter~s~', + ['threw_account'] = 'du kastade ~g~%s SEK~s~ ~b~%s~s~', ['threw_weapon'] = 'du kastade ~b~%s~s~', ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx~s~ skott', + ['threw_cannot_pickup'] = 'du kan inte plocka upp det på grund av att det kommer ej få plats i ditt förråd!', + ['threw_pickup_prompt'] = 'tryck ~y~E~s~ för att plocka upp', -- Salary related ['received_salary'] = 'du har mottagit din lön på ~g~%s SEK~s~', ['received_help'] = 'du har mottagit bidrag på ~g~%s SEK~s~', diff --git a/server/main.lua b/server/main.lua index c1bf5861..ad1c254a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -419,24 +419,28 @@ end) RegisterServerEvent('esx:onPickup') AddEventHandler('esx:onPickup', function(id) - local playerId = source - local pickup = ESX.Pickups[id] - local xPlayer = ESX.GetPlayerFromId(playerId) + local pickup, xPlayer, success = ESX.Pickups[id], ESX.GetPlayerFromId(source) - if pickup.type == 'item_standard' then - if xPlayer.canCarryItem(pickup.name, pickup.count) then - xPlayer.addInventoryItem(pickup.name, pickup.count) + if pickup then + if pickup.type == 'item_standard' then + if xPlayer.canCarryItem(pickup.name, pickup.count) then + xPlayer.addInventoryItem(pickup.name, pickup.count) + success = true + else + xPlayer.showNotification(_U('threw_cannot_pickup')) + end + elseif pickup.type == 'item_money' then + success = true + xPlayer.addMoney(pickup.count) + elseif pickup.type == 'item_account' then + success = true + xPlayer.addAccountMoney(pickup.name, pickup.count) + end + + if success then ESX.Pickups[id] = nil TriggerClientEvent('esx:removePickup', -1, id) end - elseif pickup.type == 'item_money' then - ESX.Pickups[id] = nil - TriggerClientEvent('esx:removePickup', -1, id) - xPlayer.addMoney(pickup.count) - elseif pickup.type == 'item_account' then - ESX.Pickups[id] = nil - TriggerClientEvent('esx:removePickup', -1, id) - xPlayer.addAccountMoney(pickup.name, pickup.count) end end) From fdabf80657ce24623d5e18cf27c6cfcca0a33921 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 01:33:12 +0100 Subject: [PATCH 377/672] Implemented ESX weapon drops with components support, closes #421 --- client/main.lua | 112 ++++++++++++++++++++++++++----------------- locales/br.lua | 1 + locales/cs.lua | 1 + locales/de.lua | 1 + locales/en.lua | 1 + locales/fi.lua | 1 + locales/fr.lua | 1 + locales/pl.lua | 1 + locales/sv.lua | 1 + server/functions.lua | 10 ++-- server/main.lua | 18 +++++-- 11 files changed, 97 insertions(+), 51 deletions(-) diff --git a/client/main.lua b/client/main.lua index 7275114c..261702cb 100644 --- a/client/main.lua +++ b/client/main.lua @@ -45,25 +45,6 @@ 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) - FreezeEntityPosition(obj, true) - - pickups[pickupId] = { - id = pickupId, - obj = obj, - label = v.label, - inRange = false, - coords = vector3(v.coords.x, v.coords.y, v.coords.z) - } - end) - end -end) - AddEventHandler('playerSpawned', function() while not ESX.PlayerLoaded do Citizen.Wait(1) @@ -283,26 +264,78 @@ AddEventHandler('esx:spawnVehicle', function(vehicle) 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) - coords = (coords + forward * 2.0) +RegisterNetEvent('esx:createPickup') +AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, name, components) + local playerPed = GetPlayerPed(GetPlayerFromServerId(playerId)) + local entityCoords, forward, pickupObject = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) + local objectCoords = (entityCoords + forward * 1.0) - ESX.Game.SpawnLocalObject('prop_money_bag_01', coords, function(obj) - SetEntityAsMissionEntity(obj, true, false) - PlaceObjectOnGroundProperly(obj) - FreezeEntityPosition(obj, true) + if type == 'item_weapon' then + ESX.Streaming.RequestWeaponAsset(GetHashKey(name)) + pickupObject = CreateWeaponObject(GetHashKey(name), 50, objectCoords, true, 1.0, 0) - pickups[id] = { - id = id, - obj = obj, - label = label, + for k,v in ipairs(components) do + local component = ESX.GetWeaponComponent(name, v) + GiveWeaponComponentToWeaponObject(pickupObject, component.hash) + end + else + ESX.Game.SpawnLocalObject('prop_money_bag_01', objectCoords, function(obj) + pickupObject = obj + end) + + while not pickupObject do + Citizen.Wait(10) + end + end + + SetEntityAsMissionEntity(pickupObject, true, false) + PlaceObjectOnGroundProperly(pickupObject) + FreezeEntityPosition(pickupObject, true) + + pickups[pickupId] = { + id = pickupId, + obj = pickupObject, + label = label, + inRange = false, + coords = objectCoords + } +end) + +RegisterNetEvent('esx:createMissingPickups') +AddEventHandler('esx:createMissingPickups', function(missingPickups) + for pickupId,pickup in pairs(missingPickups) do + local pickupObject = nil + + if pickup.type == 'item_weapon' then + ESX.Streaming.RequestWeaponAsset(GetHashKey(pickup.name)) + pickupObject = CreateWeaponObject(GetHashKey(pickup.name), 50, pickup.coords.x, pickup.coords.y, pickup.coords.z, true, 1.0, 0) + + for k,componentName in ipairs(pickup.components) do + local component = ESX.GetWeaponComponent(pickup.name, componentName) + GiveWeaponComponentToWeaponObject(pickupObject, component.hash) + end + else + ESX.Game.SpawnLocalObject('prop_money_bag_01', pickup.coords, function(obj) + pickupObject = obj + end) + + while not pickupObject do + Citizen.Wait(10) + end + end + + SetEntityAsMissionEntity(pickupObject, true, false) + PlaceObjectOnGroundProperly(pickupObject) + FreezeEntityPosition(pickupObject, true) + + pickups[pickupId] = { + id = pickupId, + obj = pickupObject, + label = pickup.label, inRange = false, - coords = coords + coords = vector3(pickup.coords.x, pickup.coords.y, pickup.coords.z) } - end) + end end) RegisterNetEvent('esx:removePickup') @@ -311,15 +344,6 @@ AddEventHandler('esx:removePickup', function(id) 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() diff --git a/locales/br.lua b/locales/br.lua index b84c6424..98d58441 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -37,6 +37,7 @@ Locales['br'] = { ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/cs.lua b/locales/cs.lua index 6a61bc90..38521079 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -37,6 +37,7 @@ Locales['cs'] = { ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/de.lua b/locales/de.lua index 98d5f843..5df299f5 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -37,6 +37,7 @@ Locales['de'] = { ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/en.lua b/locales/en.lua index c5300254..d3c2b4b4 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -37,6 +37,7 @@ Locales['en'] = { ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/fi.lua b/locales/fi.lua index 626d853d..b20da9c0 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -37,6 +37,7 @@ Locales['fi'] = { ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/fr.lua b/locales/fr.lua index 07de2fc6..2e134fe4 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -37,6 +37,7 @@ Locales['fr'] = { ['threw_account'] = 'vous avez jeté ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/pl.lua b/locales/pl.lua index c46546e5..40e7b373 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -37,6 +37,7 @@ Locales['pl'] = { ['threw_account'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami', + ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Salary related diff --git a/locales/sv.lua b/locales/sv.lua index 39b15a72..98605566 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -37,6 +37,7 @@ Locales['sv'] = { ['threw_account'] = 'du kastade ~g~%s SEK~s~ ~b~%s~s~', ['threw_weapon'] = 'du kastade ~b~%s~s~', ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx~s~ skott', + ['threw_weapon_already'] = 'du har redan ett sådant vapen på dig', ['threw_cannot_pickup'] = 'du kan inte plocka upp det på grund av att det kommer ej få plats i ditt förråd!', ['threw_pickup_prompt'] = 'tryck ~y~E~s~ för att plocka upp', -- Salary related diff --git a/server/functions.lua b/server/functions.lua index 7c883aa5..545e6002 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -160,7 +160,7 @@ ESX.GetItemLabel = function(item) end end -ESX.CreatePickup = function(type, name, count, label, playerId) +ESX.CreatePickup = function(type, name, count, label, playerId, components) local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) local xPlayer = ESX.GetPlayerFromId(playerId) @@ -169,10 +169,14 @@ ESX.CreatePickup = function(type, name, count, label, playerId) name = name, count = count, label = label, - coords = xPlayer.getCoords() + coords = xPlayer.getCoords(), } - TriggerClientEvent('esx:pickup', -1, pickupId, label, playerId) + if type == 'item_weapon' then + ESX.Pickups[pickupId].components = components + end + + TriggerClientEvent('esx:createPickup', -1, pickupId, label, playerId, type, name, components) ESX.PickupId = pickupId end diff --git a/server/main.lua b/server/main.lua index ad1c254a..853bff44 100644 --- a/server/main.lua +++ b/server/main.lua @@ -390,15 +390,14 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) elseif type == 'item_weapon' then if xPlayer.hasWeapon(itemName) then local weaponNum, weapon = xPlayer.getWeapon(itemName) - local weaponPickup = 'PICKUP_' .. string.upper(itemName) xPlayer.removeWeapon(itemName) + local pickupLabel = ('~y~%s~s~ [~g~%s~s~ ammo]'):format(weapon.label, weapon.ammo) + ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components) + if weapon.ammo > 0 then - TriggerClientEvent('esx:pickupWeapon', playerId, weaponPickup, itemName, weapon.ammo) xPlayer.showNotification(_U('threw_weapon_ammo', weapon.label, weapon.ammo)) else - -- workaround for CreateAmbientPickup() giving 30 rounds of ammo when you drop the weapon with 0 ammo - TriggerClientEvent('esx:pickupWeapon', playerId, weaponPickup, itemName, 1) xPlayer.showNotification(_U('threw_weapon', weapon.label)) end end @@ -435,6 +434,17 @@ AddEventHandler('esx:onPickup', function(id) elseif pickup.type == 'item_account' then success = true xPlayer.addAccountMoney(pickup.name, pickup.count) + elseif pickup.type == 'item_weapon' then + if xPlayer.hasWeapon(pickup.name) then + xPlayer.showNotification(_U('threw_weapon_already')) + else + success = true + xPlayer.addWeapon(pickup.name, pickup.count) + + for k,v in ipairs(pickup.components) do + xPlayer.addWeaponComponent(pickup.name, v) + end + end end if success then From b30e72bdcc54e1ed76ee39c63c7a7d52b391036d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 10:55:10 +0100 Subject: [PATCH 378/672] Fixed /givecommandcomponent command, closes #422 --- server/commands.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/commands.lua b/server/commands.lua index 3c525759..fc672392 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -153,6 +153,8 @@ TriggerEvent('es:addGroupCommand', 'giveweaponcomponent', 'admin', function(sour local weapon = args[2] or 'unknown' if ESX.GetWeapon(weapon) then + weapon = string.upper(weapon) + if xPlayer.hasWeapon(weapon) then local component = ESX.GetWeaponComponent(weapon, args[3] or 'unknown') From e83801cf42aebbdf1c00bcc8ef4ce7fc0e8333c6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 4 Jan 2020 23:54:39 +0100 Subject: [PATCH 379/672] Death module: fixed killer sometimes not getting found, changed native. Fixes #417 --- client/modules/death.lua | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/client/modules/death.lua b/client/modules/death.lua index 650f1e6a..a2aeb76b 100644 --- a/client/modules/death.lua +++ b/client/modules/death.lua @@ -3,7 +3,6 @@ Citizen.CreateThread(function() while true do Citizen.Wait(0) - local player = PlayerId() if NetworkIsPlayerActive(player) then @@ -12,13 +11,13 @@ Citizen.CreateThread(function() if IsPedFatallyInjured(playerPed) and not isDead then isDead = true - local killer, killerWeapon = NetworkGetEntityKillerOfPlayer(player) - local killerServerId = NetworkGetPlayerIndexFromPed(killer) - - if killer ~= playerPed and killerServerId ~= nil and NetworkIsPlayerActive(killerServerId) then - PlayerKilledByPlayer(GetPlayerServerId(killerServerId), killerServerId, killerWeapon) + local killerEntity, deathCause = GetPedSourceOfDeath(playerPed), GetPedCauseOfDeath(playerPed) + local killerClientId = NetworkGetPlayerIndexFromPed(killerEntity) + + if killerEntity ~= playerPed and killerClientId and NetworkIsPlayerActive(killerClientId) then + PlayerKilledByPlayer(GetPlayerServerId(killerClientId), killerClientId, deathCause) else - PlayerKilled() + PlayerKilled(deathCause) end elseif not IsPedFatallyInjured(playerPed) then @@ -28,18 +27,18 @@ Citizen.CreateThread(function() end end) -function PlayerKilledByPlayer(killerServerId, killerClientId, killerWeapon) +function PlayerKilledByPlayer(killerServerId, killerClientId, deathCause) local victimCoords = GetEntityCoords(PlayerPedId()) local killerCoords = GetEntityCoords(GetPlayerPed(killerClientId)) - local distance = GetDistanceBetweenCoords(victimCoords, killerCoords, true) + local distance = #(victimCoords - killerCoords) local data = { - victimCoords = { x = ESX.Math.Round(victimCoords.x, 1), y = ESX.Math.Round(victimCoords.y, 1), z = ESX.Math.Round(victimCoords.z, 1) }, - killerCoords = { x = ESX.Math.Round(killerCoords.x, 1), y = ESX.Math.Round(killerCoords.y, 1), z = ESX.Math.Round(killerCoords.z, 1) }, + victimCoords = {x = ESX.Math.Round(victimCoords.x, 1), y = ESX.Math.Round(victimCoords.y, 1), z = ESX.Math.Round(victimCoords.z, 1)}, + killerCoords = {x = ESX.Math.Round(killerCoords.x, 1), y = ESX.Math.Round(killerCoords.y, 1), z = ESX.Math.Round(killerCoords.z, 1)}, killedByPlayer = true, - deathCause = killerWeapon, - distance = ESX.Math.Round(distance, 1), + deathCause = deathCause, + distance = ESX.Math.Round(distance, 1), killerServerId = killerServerId, killerClientId = killerClientId @@ -49,15 +48,15 @@ function PlayerKilledByPlayer(killerServerId, killerClientId, killerWeapon) TriggerServerEvent('esx:onPlayerDeath', data) end -function PlayerKilled() +function PlayerKilled(deathCause) local playerPed = PlayerPedId() - local victimCoords = GetEntityCoords(PlayerPedId()) + local victimCoords = GetEntityCoords(playerPed) local data = { - victimCoords = { x = ESX.Math.Round(victimCoords.x, 1), y = ESX.Math.Round(victimCoords.y, 1), z = ESX.Math.Round(victimCoords.z, 1) }, + victimCoords = {x = ESX.Math.Round(victimCoords.x, 1), y = ESX.Math.Round(victimCoords.y, 1), z = ESX.Math.Round(victimCoords.z, 1)}, killedByPlayer = false, - deathCause = GetPedCauseOfDeath(playerPed) + deathCause = deathCause } TriggerEvent('esx:onPlayerDeath', data) From feaf8424205bfd9b14de786e15e9fb411f738fc7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 5 Jan 2020 15:49:00 +0100 Subject: [PATCH 380/672] Show player name and not steam name, fixes #354 --- client/functions.lua | 127 +++++++++++++++++++------------------------ server/main.lua | 44 +++++++++++---- 2 files changed, 89 insertions(+), 82 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 5a56dd4d..c42f6621 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -990,7 +990,7 @@ ESX.Game.Utils.DrawText3D = function(coords, text, size, font) if not size then size = 1 end if not font then font = 0 end - + local scale = (size / distance) * 2 local fov = (1 / GetGameplayCamFov()) * 100 scale = scale * fov @@ -1113,87 +1113,72 @@ ESX.ShowInventory = function() align = 'bottom-right', elements = elements, }, function(data1, menu1) - local item = data1.current.value - local type = data1.current.type + local item, type = data1.current.value, data1.current.type if data1.current.action == 'give' then - local playersInArea = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) - local foundPlayers, elements = false, {} + local playersNearby = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) - for k,v in ipairs(playersInArea) do - if v ~= PlayerId() then - foundPlayers = true + if #playersNearby > 0 then + local players, elements = {}, {} - table.insert(elements, { - label = GetPlayerName(v), - player = v - }) + for k,player in ipairs(playersNearby) do + players[GetPlayerServerId(player)] = true end - end - if foundPlayers then - foundPlayers = false - - ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'give_item_to', { - title = _U('give_to'), - align = 'bottom-right', - elements = elements - }, function(data2, menu2) - local playersInArea, nearbyPlayer = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) - - for k,v in ipairs(playersInArea) do - if v ~= PlayerId() then - - if v == data2.current.player then - foundPlayers = true - nearbyPlayer = v - break - end - end + ESX.TriggerServerCallback('esx:getPlayerNames', function(returnedPlayers) + for playerId,playerName in pairs(returnedPlayers) do + table.insert(elements, { + label = playerName, + playerId = playerId + }) end - - if foundPlayers then - if type == 'item_weapon' then - local closestPed = GetPlayerPed(nearbyPlayer) - local sourceAmmo = GetAmmoInPedWeapon(playerPed, GetHashKey(item)) - - if IsPedOnFoot(closestPed) then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, sourceAmmo) - menu2.close() - menu1.close() + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'give_item_to', { + title = _U('give_to'), + align = 'bottom-right', + elements = elements + }, function(data2, menu2) + local selectedPlayer, selectedPlayerId = GetPlayerFromServerId(data2.current.playerId), data2.current.playerId + playersNearby = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) + playersNearby = ESX.Table.Set(playersNearby) + + if playersNearby[selectedPlayer] then + local selectedPlayerPed = GetPlayerPed(selectedPlayer) + + if IsPedOnFoot(selectedPlayerPed) then + if type == 'item_weapon' then + TriggerServerEvent('esx:giveInventoryItem', selectedPlayerId, type, item, nil) + menu2.close() + menu1.close() + else + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { + title = _U('amount') + }, function(data3, menu3) + local quantity = tonumber(data3.value) + + if quantity then + TriggerServerEvent('esx:giveInventoryItem', selectedPlayerId, type, item, quantity) + menu3.close() + menu2.close() + menu1.close() + else + ESX.ShowNotification(_U('amount_invalid')) + end + end, function(data3, menu3) + menu3.close() + end) + end else ESX.ShowNotification(_U('in_vehicle')) end else - ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { - title = _U('amount') - }, function(data3, menu3) - local quantity = tonumber(data3.value) - local closestPed = GetPlayerPed(nearbyPlayer) - - if IsPedOnFoot(closestPed) then - if quantity then - TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(nearbyPlayer), type, item, quantity) - menu3.close() - menu2.close() - menu1.close() - else - ESX.ShowNotification(_U('amount_invalid')) - end - else - ESX.ShowNotification(_U('in_vehicle')) - end - end, function(data3, menu3) - menu3.close() - end) + ESX.ShowNotification(_U('players_nearby')) + menu2.close() end - else - ESX.ShowNotification(_U('players_nearby')) + end, function(data2, menu2) menu2.close() - end - end, function(data2, menu2) - menu2.close() - end) -- give end + end) + end, players) else ESX.ShowNotification(_U('players_nearby')) end @@ -1212,7 +1197,7 @@ ESX.ShowInventory = function() title = _U('amount') }, function(data2, menu2) local quantity = tonumber(data2.value) - + if quantity then menu2.close() menu1.close() @@ -1244,7 +1229,7 @@ ESX.ShowInventory = function() title = _U('amountammo') }, function(data2, menu2) local quantity = tonumber(data2.value) - + if quantity then if pedAmmo >= quantity and quantity > 0 then TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), 'item_ammo', item, quantity) diff --git a/server/main.lua b/server/main.lua index 853bff44..fc384765 100644 --- a/server/main.lua +++ b/server/main.lua @@ -301,21 +301,27 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo sourceXPlayer.showNotification(_U('imp_invalid_amount')) end elseif type == 'item_weapon' then - if not targetXPlayer.hasWeapon(itemName) then - sourceXPlayer.removeWeapon(itemName) - targetXPlayer.addWeapon(itemName, itemCount) + if sourceXPlayer.hasWeapon(itemName) then local weaponLabel = ESX.GetWeaponLabel(itemName) - if itemCount > 0 then - sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, sourceXPlayer.name)) + if not targetXPlayer.hasWeapon(itemName) then + local _,weapon = xPlayer.getWeapon(itemName) + itemCount = weapon.ammo + + sourceXPlayer.removeWeapon(itemName) + targetXPlayer.addWeapon(itemName, itemCount) + + if itemCount > 0 then + sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, sourceXPlayer.name)) + else + sourceXPlayer.showNotification(_U('gave_weapon', weaponLabel, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon', weaponLabel, sourceXPlayer.name)) + end else - sourceXPlayer.showNotification(_U('gave_weapon', weaponLabel, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon', weaponLabel, sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) + targetXPlayer.showNotification(_U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) end - else - sourceXPlayer.showNotification(_U('gave_weapon_hasalready', targetXPlayer.name, weaponLabel)) - targetXPlayer.showNotification(_U('received_weapon_hasalready', sourceXPlayer.name, weaponLabel)) end elseif type == 'item_ammo' then if sourceXPlayer.hasWeapon(itemName) then @@ -482,6 +488,22 @@ ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target }) end) +ESX.RegisterServerCallback('esx:getPlayerNames', function(source, cb, players) + players[source] = nil + + for playerId,v in pairs(players) do + local xPlayer = ESX.GetPlayerFromId(playerId) + + if xPlayer then + players[playerId] = xPlayer.getName() + else + players[playerId] = nil + end + end + + cb(players) +end) + TriggerEvent("es:addGroup", "jobmaster", "user", function(group) end) ESX.StartDBSync() From aa9ffd386638d4ba0a8e9fce5385baa0c07f3295 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 19:17:05 +0100 Subject: [PATCH 381/672] Replace __resource.lua with fxmanifest.lua --- __resource.lua => fxmanifest.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) rename __resource.lua => fxmanifest.lua (95%) diff --git a/__resource.lua b/fxmanifest.lua similarity index 95% rename from __resource.lua rename to fxmanifest.lua index 953bf74a..a4be3e72 100644 --- a/__resource.lua +++ b/fxmanifest.lua @@ -1,4 +1,6 @@ -resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937' +fx_version 'adamant' + +game 'gta5' description 'ES Extended' From 91eb2f85051f32ae35757aabb60431340b848a7d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 19:18:41 +0100 Subject: [PATCH 382/672] Removed jobmaster group --- server/commands.lua | 2 +- server/main.lua | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/server/commands.lua b/server/commands.lua index fc672392..cbee7f24 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -20,7 +20,7 @@ end, {help = 'Teleport to coordinates', params = { {name = 'z', help = 'Z coords'} }}) -TriggerEvent('es:addGroupCommand', 'setjob', 'jobmaster', function(source, args, user) +TriggerEvent('es:addGroupCommand', 'setjob', 'admin', function(source, args, user) if tonumber(args[1]) and args[2] and tonumber(args[3]) then local xPlayer = ESX.GetPlayerFromId(args[1]) diff --git a/server/main.lua b/server/main.lua index fc384765..f849c758 100644 --- a/server/main.lua +++ b/server/main.lua @@ -504,7 +504,5 @@ ESX.RegisterServerCallback('esx:getPlayerNames', function(source, cb, players) cb(players) end) -TriggerEvent("es:addGroup", "jobmaster", "user", function(group) end) - ESX.StartDBSync() ESX.StartPayCheck() From 9be103db3173db7499618d98a6b1dee91ffdd45c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 21:04:04 +0100 Subject: [PATCH 383/672] ESX.Game.Teleport() support heading, minor cleanup --- client/functions.lua | 352 ++++++++++++------------------------------- 1 file changed, 93 insertions(+), 259 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index c42f6621..c5e2021d 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -280,14 +280,20 @@ ESX.Game.GetPedMugshot = function(ped) end ESX.Game.Teleport = function(entity, coords, cb) - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - - while not HasCollisionLoadedAroundEntity(entity) do + if DoesEntityExist(entity) then RequestCollisionAtCoord(coords.x, coords.y, coords.z) - Citizen.Wait(0) - end - SetEntityCoords(entity, coords.x, coords.y, coords.z) + while not HasCollisionLoadedAroundEntity(entity) do + RequestCollisionAtCoord(coords.x, coords.y, coords.z) + Citizen.Wait(0) + end + + SetEntityCoords(entity, coords.x, coords.y, coords.z, false, false, false, false) + + if coords.heading then + SetEntityHeading(entity, coords.heading) + end + end if cb then cb() @@ -625,7 +631,7 @@ ESX.Game.GetClosestPed = function(coords, ignoreList) end ESX.Game.GetVehicleProperties = function(vehicle) - local color1, color2 = GetVehicleColours(vehicle) + local colorPrimary, colorSecondary = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) local extras = {} @@ -647,8 +653,8 @@ ESX.Game.GetVehicleProperties = function(vehicle) fuelLevel = ESX.Math.Round(GetVehicleFuelLevel(vehicle), 1), dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), - color1 = color1, - color2 = color2, + color1 = colorPrimary, + color2 = colorSecondary, pearlescentColor = pearlescentColor, wheelColor = wheelColor, @@ -721,264 +727,92 @@ ESX.Game.GetVehicleProperties = function(vehicle) end ESX.Game.SetVehicleProperties = function(vehicle, props) - SetVehicleModKit(vehicle, 0) - - if props.plate then - SetVehicleNumberPlateText(vehicle, props.plate) - end - - if props.plateIndex then - SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) - end - - if props.bodyHealth then - SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) - end - - if props.engineHealth then - SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) - end - - if props.fuelLevel then - SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) - end - - if props.dirtLevel then - SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) - end - - if props.color1 then - local color1, color2 = GetVehicleColours(vehicle) - SetVehicleColours(vehicle, props.color1, color2) - end - - if props.color2 then - local color1, color2 = GetVehicleColours(vehicle) - SetVehicleColours(vehicle, color1, props.color2) - end - - if props.pearlescentColor then + if DoesEntityExist(vehicle) then + local colorPrimary, colorSecondary = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) - end + SetVehicleModKit(vehicle, 0) - if props.wheelColor then - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) - end + if props.plate then SetVehicleNumberPlateText(vehicle, props.plate) end + if props.plateIndex then SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) end + if props.bodyHealth then SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) end + if props.engineHealth then SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) end + if props.fuelLevel then SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end + if props.dirtLevel then SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end + if props.color1 then SetVehicleColours(vehicle, props.color1, colorSecondary) end + if props.color2 then SetVehicleColours(vehicle, colorPrimary, props.color2) end + if props.pearlescentColor then SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) end + if props.wheelColor then SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) end + if props.wheels then SetVehicleWheelType(vehicle, props.wheels) end + if props.windowTint then SetVehicleWindowTint(vehicle, props.windowTint) end - if props.wheels then - SetVehicleWheelType(vehicle, props.wheels) - end + if props.neonEnabled then + SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) + SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) + SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) + SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) + end - if props.windowTint then - SetVehicleWindowTint(vehicle, props.windowTint) - end - - if props.neonEnabled then - SetVehicleNeonLightEnabled(vehicle, 0, props.neonEnabled[1]) - SetVehicleNeonLightEnabled(vehicle, 1, props.neonEnabled[2]) - SetVehicleNeonLightEnabled(vehicle, 2, props.neonEnabled[3]) - SetVehicleNeonLightEnabled(vehicle, 3, props.neonEnabled[4]) - end - - if props.extras then - for id,enabled in pairs(props.extras) do - if enabled then - SetVehicleExtra(vehicle, tonumber(id), 0) - else - SetVehicleExtra(vehicle, tonumber(id), 1) + if props.extras then + for id,enabled in pairs(props.extras) do + if enabled then + SetVehicleExtra(vehicle, tonumber(id), 0) + else + SetVehicleExtra(vehicle, tonumber(id), 1) + end end end - end - if props.neonColor then - SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) - end + if props.neonColor then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end + if props.modSmokeEnabled then ToggleVehicleMod(vehicle, 20, true) end + if props.tyreSmokeColor then SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) end + if props.modSpoilers then SetVehicleMod(vehicle, 0, props.modSpoilers, false) end + if props.modFrontBumper then SetVehicleMod(vehicle, 1, props.modFrontBumper, false) end + if props.modRearBumper then SetVehicleMod(vehicle, 2, props.modRearBumper, false) end + if props.modSideSkirt then SetVehicleMod(vehicle, 3, props.modSideSkirt, false) end + if props.modExhaust then SetVehicleMod(vehicle, 4, props.modExhaust, false) end + if props.modFrame then SetVehicleMod(vehicle, 5, props.modFrame, false) end + if props.modGrille then SetVehicleMod(vehicle, 6, props.modGrille, false) end + if props.modHood then SetVehicleMod(vehicle, 7, props.modHood, false) end + if props.modFender then SetVehicleMod(vehicle, 8, props.modFender, false) end + if props.modRightFender then SetVehicleMod(vehicle, 9, props.modRightFender, false) end + if props.modRoof then SetVehicleMod(vehicle, 10, props.modRoof, false) end + if props.modEngine then SetVehicleMod(vehicle, 11, props.modEngine, false) end + if props.modBrakes then SetVehicleMod(vehicle, 12, props.modBrakes, false) end + if props.modTransmission then SetVehicleMod(vehicle, 13, props.modTransmission, false) end + if props.modHorns then SetVehicleMod(vehicle, 14, props.modHorns, false) end + if props.modSuspension then SetVehicleMod(vehicle, 15, props.modSuspension, false) end + if props.modArmor then SetVehicleMod(vehicle, 16, props.modArmor, false) end + if props.modTurbo then ToggleVehicleMod(vehicle, 18, props.modTurbo) end + if props.modXenon then ToggleVehicleMod(vehicle, 22, props.modXenon) end + if props.modFrontWheels then SetVehicleMod(vehicle, 23, props.modFrontWheels, false) end + if props.modBackWheels then SetVehicleMod(vehicle, 24, props.modBackWheels, false) end + if props.modPlateHolder then SetVehicleMod(vehicle, 25, props.modPlateHolder, false) end + if props.modVanityPlate then SetVehicleMod(vehicle, 26, props.modVanityPlate, false) end + if props.modTrimA then SetVehicleMod(vehicle, 27, props.modTrimA, false) end + if props.modOrnaments then SetVehicleMod(vehicle, 28, props.modOrnaments, false) end + if props.modDashboard then SetVehicleMod(vehicle, 29, props.modDashboard, false) end + if props.modDial then SetVehicleMod(vehicle, 30, props.modDial, false) end + if props.modDoorSpeaker then SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) end + if props.modSeats then SetVehicleMod(vehicle, 32, props.modSeats, false) end + if props.modSteeringWheel then SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) end + if props.modShifterLeavers then SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) end + if props.modAPlate then SetVehicleMod(vehicle, 35, props.modAPlate, false) end + if props.modSpeakers then SetVehicleMod(vehicle, 36, props.modSpeakers, false) end + if props.modTrunk then SetVehicleMod(vehicle, 37, props.modTrunk, false) end + if props.modHydrolic then SetVehicleMod(vehicle, 38, props.modHydrolic, false) end + if props.modEngineBlock then SetVehicleMod(vehicle, 39, props.modEngineBlock, false) end + if props.modAirFilter then SetVehicleMod(vehicle, 40, props.modAirFilter, false) end + if props.modStruts then SetVehicleMod(vehicle, 41, props.modStruts, false) end + if props.modArchCover then SetVehicleMod(vehicle, 42, props.modArchCover, false) end + if props.modAerials then SetVehicleMod(vehicle, 43, props.modAerials, false) end + if props.modTrimB then SetVehicleMod(vehicle, 44, props.modTrimB, false) end + if props.modTank then SetVehicleMod(vehicle, 45, props.modTank, false) end + if props.modWindows then SetVehicleMod(vehicle, 46, props.modWindows, false) end - if props.modSmokeEnabled then - ToggleVehicleMod(vehicle, 20, true) - end - - if props.tyreSmokeColor then - SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) - end - - if props.modSpoilers then - SetVehicleMod(vehicle, 0, props.modSpoilers, false) - end - - if props.modFrontBumper then - SetVehicleMod(vehicle, 1, props.modFrontBumper, false) - end - - if props.modRearBumper then - SetVehicleMod(vehicle, 2, props.modRearBumper, false) - end - - if props.modSideSkirt then - SetVehicleMod(vehicle, 3, props.modSideSkirt, false) - end - - if props.modExhaust then - SetVehicleMod(vehicle, 4, props.modExhaust, false) - end - - if props.modFrame then - SetVehicleMod(vehicle, 5, props.modFrame, false) - end - - if props.modGrille then - SetVehicleMod(vehicle, 6, props.modGrille, false) - end - - if props.modHood then - SetVehicleMod(vehicle, 7, props.modHood, false) - end - - if props.modFender then - SetVehicleMod(vehicle, 8, props.modFender, false) - end - - if props.modRightFender then - SetVehicleMod(vehicle, 9, props.modRightFender, false) - end - - if props.modRoof then - SetVehicleMod(vehicle, 10, props.modRoof, false) - end - - if props.modEngine then - SetVehicleMod(vehicle, 11, props.modEngine, false) - end - - if props.modBrakes then - SetVehicleMod(vehicle, 12, props.modBrakes, false) - end - - if props.modTransmission then - SetVehicleMod(vehicle, 13, props.modTransmission, false) - end - - if props.modHorns then - SetVehicleMod(vehicle, 14, props.modHorns, false) - end - - if props.modSuspension then - SetVehicleMod(vehicle, 15, props.modSuspension, false) - end - - if props.modArmor then - SetVehicleMod(vehicle, 16, props.modArmor, false) - end - - if props.modTurbo then - ToggleVehicleMod(vehicle, 18, props.modTurbo) - end - - if props.modXenon then - ToggleVehicleMod(vehicle, 22, props.modXenon) - end - - if props.modFrontWheels then - SetVehicleMod(vehicle, 23, props.modFrontWheels, false) - end - - if props.modBackWheels then - SetVehicleMod(vehicle, 24, props.modBackWheels, false) - end - - if props.modPlateHolder then - SetVehicleMod(vehicle, 25, props.modPlateHolder, false) - end - - if props.modVanityPlate then - SetVehicleMod(vehicle, 26, props.modVanityPlate, false) - end - - if props.modTrimA then - SetVehicleMod(vehicle, 27, props.modTrimA, false) - end - - if props.modOrnaments then - SetVehicleMod(vehicle, 28, props.modOrnaments, false) - end - - if props.modDashboard then - SetVehicleMod(vehicle, 29, props.modDashboard, false) - end - - if props.modDial then - SetVehicleMod(vehicle, 30, props.modDial, false) - end - - if props.modDoorSpeaker then - SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false) - end - - if props.modSeats then - SetVehicleMod(vehicle, 32, props.modSeats, false) - end - - if props.modSteeringWheel then - SetVehicleMod(vehicle, 33, props.modSteeringWheel, false) - end - - if props.modShifterLeavers then - SetVehicleMod(vehicle, 34, props.modShifterLeavers, false) - end - - if props.modAPlate then - SetVehicleMod(vehicle, 35, props.modAPlate, false) - end - - if props.modSpeakers then - SetVehicleMod(vehicle, 36, props.modSpeakers, false) - end - - if props.modTrunk then - SetVehicleMod(vehicle, 37, props.modTrunk, false) - end - - if props.modHydrolic then - SetVehicleMod(vehicle, 38, props.modHydrolic, false) - end - - if props.modEngineBlock then - SetVehicleMod(vehicle, 39, props.modEngineBlock, false) - end - - if props.modAirFilter then - SetVehicleMod(vehicle, 40, props.modAirFilter, false) - end - - if props.modStruts then - SetVehicleMod(vehicle, 41, props.modStruts, false) - end - - if props.modArchCover then - SetVehicleMod(vehicle, 42, props.modArchCover, false) - end - - if props.modAerials then - SetVehicleMod(vehicle, 43, props.modAerials, false) - end - - if props.modTrimB then - SetVehicleMod(vehicle, 44, props.modTrimB, false) - end - - if props.modTank then - SetVehicleMod(vehicle, 45, props.modTank, false) - end - - if props.modWindows then - SetVehicleMod(vehicle, 46, props.modWindows, false) - end - - if props.modLivery then - SetVehicleMod(vehicle, 48, props.modLivery, false) - SetVehicleLivery(vehicle, props.modLivery) + if props.modLivery then + SetVehicleMod(vehicle, 48, props.modLivery, false) + SetVehicleLivery(vehicle, props.modLivery) + end end end From ccdd4494c5137556192529b0500fa0183b25a9f2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 21:55:18 +0100 Subject: [PATCH 384/672] Reset color after client print, use async callback for retrieving jobs --- server/common.lua | 57 +++++++++++++++++++++----------------------- server/functions.lua | 4 ++-- server/paycheck.lua | 3 --- 3 files changed, 29 insertions(+), 35 deletions(-) diff --git a/server/common.lua b/server/common.lua index b3c76c71..e2496d75 100644 --- a/server/common.lua +++ b/server/common.lua @@ -30,39 +30,36 @@ MySQL.ready(function() end end) - local result = MySQL.Sync.fetchAll('SELECT * FROM jobs', {}) - - for i=1, #result do - ESX.Jobs[result[i].name] = result[i] - ESX.Jobs[result[i].name].grades = {} - end - - local result2 = MySQL.Sync.fetchAll('SELECT * FROM job_grades', {}) - - for i=1, #result2 do - if ESX.Jobs[result2[i].job_name] then - ESX.Jobs[result2[i].job_name].grades[tostring(result2[i].grade)] = result2[i] - else - print(('[es_extended] [^3WARNING^7] Invalid job "%s" from table job_grades ignored'):format(result2[i].job_name)) + MySQL.Async.fetchAll('SELECT * FROM jobs', {}, function(jobs) + for k,v in ipairs(jobs) do + ESX.Jobs[v.name] = v + ESX.Jobs[v.name].grades = {} end - end - for k,v in pairs(ESX.Jobs) do - if next(v.grades) == nil then - ESX.Jobs[v.name] = nil - print(('[es_extended] [^3WARNING^7] Ignoring job "%s" due to missing job grades'):format(v.name)) - end - end + MySQL.Async.fetchAll('SELECT * FROM job_grades', {}, function(jobGrades) + for k,v in ipairs(jobGrades) do + if ESX.Jobs[v.job_name] then + ESX.Jobs[v.job_name].grades[tostring(v.grade)] = v + else + print(('[es_extended] [^3WARNING^7] Ignoring job grades for "%s" due to missing job'):format(v.job_name)) + end + end + + for k2,v2 in pairs(ESX.Jobs) do + if ESX.Table.SizeOf(v2.grades) == 0 then + ESX.Jobs[v2.name] = nil + print(('[es_extended] [^3WARNING^7] Ignoring job "%s" due to no job grades found'):format(v2.name)) + end + end + end) + end) print('[es_extended] [^2INFO^7] ESX developed by ESX-Org has been initialized') end) -AddEventHandler('esx:playerLoaded', function(source) - local xPlayer = ESX.GetPlayerFromId(source) - local accounts = {} - local items = {} - local xPlayerAccounts = xPlayer.getAccounts() - local xPlayerItems = xPlayer.getInventory() +AddEventHandler('esx:playerLoaded', function(playerId) + local xPlayer, accounts, items = ESX.GetPlayerFromId(playerId), {}, {} + local xPlayerAccounts, xPlayerItems = xPlayer.getAccounts(), xPlayer.getInventory() for i=1, #xPlayerAccounts, 1 do accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money @@ -72,16 +69,16 @@ AddEventHandler('esx:playerLoaded', function(source) items[xPlayerItems[i].name] = xPlayerItems[i].count end - ESX.LastPlayerData[source] = { + ESX.LastPlayerData[playerId] = { accounts = accounts, - items = items + items = items } end) RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) if Config.EnableDebug then - print(('[es_extended] [^2TRACE^7] %s'):format(msg)) + print(('[es_extended] [^2TRACE^7] %s^7'):format(msg)) end end) diff --git a/server/functions.lua b/server/functions.lua index 545e6002..5bd0008f 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -1,6 +1,6 @@ -ESX.Trace = function(str) +ESX.Trace = function(msg) if Config.EnableDebug then - print(('[es_extended] [^2TRACE^7] %s'):format(str)) + print(('[es_extended] [^2TRACE^7] %s^7'):format(msg)) end end diff --git a/server/paycheck.lua b/server/paycheck.lua index 8df7bf95..293898f9 100644 --- a/server/paycheck.lua +++ b/server/paycheck.lua @@ -1,5 +1,4 @@ ESX.StartPayCheck = function() - function payCheck() local xPlayers = ESX.GetPlayers() @@ -39,9 +38,7 @@ ESX.StartPayCheck = function() end SetTimeout(Config.PaycheckInterval, payCheck) - end SetTimeout(Config.PaycheckInterval, payCheck) - end From 5566abca4f5c9e070f25f4b6369f210cb778e47f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 22:04:59 +0100 Subject: [PATCH 385/672] Removed updating loadout from client - usally spawned weapons --- client/main.lua | 1 - server/main.lua | 4 ---- 2 files changed, 5 deletions(-) diff --git a/client/main.lua b/client/main.lua index 261702cb..22292f4e 100644 --- a/client/main.lua +++ b/client/main.lua @@ -449,7 +449,6 @@ Citizen.CreateThread(function() if loadoutChanged and isLoadoutLoaded then ESX.PlayerData.loadout = loadout - TriggerServerEvent('esx:updateLoadout', loadout) end end end) diff --git a/server/main.lua b/server/main.lua index f849c758..b6e1806d 100644 --- a/server/main.lua +++ b/server/main.lua @@ -245,11 +245,7 @@ AddEventHandler('playerDropped', function(reason) end end) -RegisterServerEvent('esx:updateLoadout') -AddEventHandler('esx:updateLoadout', function(loadout) local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.loadout = loadout -end) RegisterServerEvent('esx:updateLastPosition') AddEventHandler('esx:updateLastPosition', function(position) From f89e05175626f47275b4301e6561295414210711 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Jan 2020 22:13:30 +0100 Subject: [PATCH 386/672] BREAKING COMMIT - Player loading improvements (read description!) This commit implements a new way of saving and getting player coords. Player coords are synced with its assigned xPlayer, the syncing interval is defined in the configuration file. Also coords wont sync if the player is too close to their previous location. Existing servers must change their database to account for the new length of the position varchar, at 53 chars max. There's also a column default value specified in the sql file. New xPlayer functions: - .getCoords() - .setCoords() (x,y,z,heading (optional) table - .updateCoords() The last one is used for syncing coords from client (interval). The second one will teleport the player. First one is a renamed .getLastPosition() --- client/main.lua | 89 ++++----- config.lua | 3 +- es_extended.sql | 2 +- server/classes/player.lua | 82 ++++---- server/functions.lua | 7 +- server/main.lua | 405 +++++++++++++++++++------------------- 6 files changed, 277 insertions(+), 311 deletions(-) diff --git a/client/main.lua b/client/main.lua index 22292f4e..48285d2b 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,6 +1,4 @@ - -local isLoadoutLoaded, isPaused, isPlayerSpawned, isDead = false, false, false, false -local lastLoadout, pickups = {}, {} +local isLoadoutLoaded, isPaused, isDead, isFirstSpawn, pickups = false, false, false, true, {} RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) @@ -47,33 +45,26 @@ end) AddEventHandler('playerSpawned', function() while not ESX.PlayerLoaded do - Citizen.Wait(1) + Citizen.Wait(10) end - local playerPed = PlayerPedId() + TriggerEvent('esx:restoreLoadout') - -- Restore position - if ESX.PlayerData.lastPosition then - SetEntityCoords(playerPed, ESX.PlayerData.lastPosition.x, ESX.PlayerData.lastPosition.y, ESX.PlayerData.lastPosition.z) + if isFirstSpawn then + ESX.Game.Teleport(PlayerPedId(), ESX.PlayerData.coords) + isFirstSpawn = false end - TriggerEvent('esx:restoreLoadout') -- restore loadout - - isLoadoutLoaded, isPlayerSpawned, isDead = true, true, false + isLoadoutLoaded, isDead = true, false if Config.EnablePvP then - SetCanAttackFriendly(playerPed, true, false) + SetCanAttackFriendly(PlayerPedId(), true, false) NetworkSetFriendlyFireOption(true) end end) -AddEventHandler('esx:onPlayerDeath', function() - isDead = true -end) - -AddEventHandler('skinchanger:loadDefaultModel', function() - isLoadoutLoaded = false -end) +AddEventHandler('esx:onPlayerDeath', function() isDead = true end) +AddEventHandler('skinchanger:loadDefaultModel', function() isLoadoutLoaded = false end) AddEventHandler('skinchanger:modelLoaded', function() while not ESX.PlayerLoaded do @@ -175,7 +166,6 @@ AddEventHandler('esx:addWeapon', function(weaponName, ammo) local weaponHash = GetHashKey(weaponName) GiveWeaponToPed(playerPed, weaponHash, ammo, false, false) - --AddAmmoToPed(playerPed, weaponHash, ammo) possibly not needed end) RegisterNetEvent('esx:addWeaponComponent') @@ -211,7 +201,6 @@ AddEventHandler('esx:removeWeapon', function(weaponName, ammo) end end) - RegisterNetEvent('esx:removeWeaponComponent') AddEventHandler('esx:removeWeaponComponent', function(weaponName, weaponComponent) local playerPed = PlayerPedId() @@ -221,21 +210,16 @@ AddEventHandler('esx:removeWeaponComponent', function(weaponName, weaponComponen 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 +AddEventHandler('esx:teleport', function(coords) + local playerPed = PlayerPedId() - RequestCollisionAtCoord(pos.x, pos.y, pos.z) + -- ensure decmial number + coords.x = coords.x + 0.0 + coords.y = coords.y + 0.0 + coords.z = coords.z + 0.0 - while not HasCollisionLoadedAroundEntity(PlayerPedId()) do - RequestCollisionAtCoord(pos.x, pos.y, pos.z) - Citizen.Wait(1) - end - - SetEntityCoords(PlayerPedId(), pos.x, pos.y, pos.z) + ESX.Game.Teleport(playerPed, coords) end) RegisterNetEvent('esx:setJob') @@ -384,7 +368,7 @@ AddEventHandler('esx:deleteVehicle', function(radius) end end) --- Pause menu disable HUD display +-- Pause menu disables HUD display if Config.EnableHud then Citizen.CreateThread(function() while true do @@ -405,12 +389,11 @@ end -- Save loadout Citizen.CreateThread(function() + local lastLoadout = {} + while true do Citizen.Wait(5000) - - local playerPed = PlayerPedId() - local loadout = {} - local loadoutChanged = false + local playerPed, loadout, loadoutChanged = PlayerPedId(), {}, false for k,v in ipairs(Config.Weapons) do local weaponName = v.name @@ -469,8 +452,8 @@ 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) @@ -528,22 +511,26 @@ Citizen.CreateThread(function() end end) --- Last position +-- Update current player coords Citizen.CreateThread(function() - while true do + local previousCoords = vector3(0, 0, 0) + + -- wait for player to restore coords + while not isLoadoutLoaded do Citizen.Wait(1000) + end + + while true do + Citizen.Wait(Config.CoordsSyncInterval) local playerPed = PlayerPedId() + local playerCoords = GetEntityCoords(playerPed) + local distance = #(playerCoords - previousCoords) - 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 + if distance > 10 then + previousCoords = playerCoords + local playerHeading = ESX.Math.Round(GetEntityHeading(playerPed), 1) + local formattedCoords = {x = ESX.Math.Round(playerCoords.x, 1), y = ESX.Math.Round(playerCoords.y, 1), z = ESX.Math.Round(playerCoords.z, 1), heading = playerHeading} + TriggerServerEvent('esx:updateCoords', formattedCoords) end end end) diff --git a/config.lua b/config.lua index a332cf44..5dfee80f 100644 --- a/config.lua +++ b/config.lua @@ -10,6 +10,7 @@ Config.EnableHud = true -- enable the default hud? Display current jo Config.EnablePvP = true -- enable pvp? Config.MaxWeight = 24 -- the max inventory weight without backpack -Config.PaycheckInterval = 7 * 60000 +Config.PaycheckInterval = 7 * 60000 -- how often to recieve pay checks in milliseconds +Config.CoordsSyncInterval = 2 * 60000 -- how often to sync coords with server in milliseconds Config.EnableDebug = false diff --git a/es_extended.sql b/es_extended.sql index 52534684..4cab101a 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -6,7 +6,7 @@ ALTER TABLE `users` ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(36) NULL AFTER `loadout` + ADD COLUMN `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}' AFTER `loadout` ; CREATE TABLE `items` ( diff --git a/server/classes/player.lua b/server/classes/player.lua index fe1cf5e0..851bb397 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -1,4 +1,4 @@ -function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, lastPosition) +function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, coords) local self = {} self.player = player @@ -7,8 +7,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.job = job self.loadout = loadout self.name = name - self.lastPosition = lastPosition self.maxWeight = Config.MaxWeight + self.coords = coords self.source = self.player.get('source') self.identifier = self.player.get('identifier') @@ -41,23 +41,25 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l return self.player.get('bank') end - self.getCoords = function(vectorType) - local coords = self.player.get('coords') - coords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1)} + self.setCoords = function(coords) + self.updateCoords(coords) + self.triggerEvent('esx:teleport', coords) + end - if vectorType then - return vector3(coords.x, coords.y, coords.z) + self.updateCoords = function(coords) + self.coords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1), heading = ESX.Math.Round(coords.heading, 1)} + end + + self.getCoords = function(vector) + if vector then + return vector3(self.coords.x, self.coords.y, self.coords.z) else - return coords + return self.coords end end - self.setCoords = function(x, y, z) - self.player.coords = {x = x, y = y, z = z} - end - self.kick = function(reason) - self.player.kick(reason) + DropPlayer(self.source, reason) end self.addMoney = function(money) @@ -194,20 +196,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.name = newName end - self.getLastPosition = function() - if self.lastPosition and self.lastPosition.x and self.lastPosition.y and self.lastPosition.z then - self.lastPosition.x = ESX.Math.Round(self.lastPosition.x, 1) - self.lastPosition.y = ESX.Math.Round(self.lastPosition.y, 1) - self.lastPosition.z = ESX.Math.Round(self.lastPosition.z, 1) - end - - return self.lastPosition - end - - self.setLastPosition = function(position) - self.lastPosition = position - end - self.getMissingAccounts = function(cb) MySQL.Async.fetchAll('SELECT name FROM user_accounts WHERE identifier = @identifier', { ['@identifier'] = self.getIdentifier() @@ -262,7 +250,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.set('bank', newMoney) end - TriggerClientEvent('esx:setAccountMoney', self.source, account) + self.triggerEvent('esx:setAccountMoney', account) end end end @@ -279,7 +267,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.set('bank', newMoney) end - TriggerClientEvent('esx:setAccountMoney', self.source, account) + self.triggerEvent('esx:setAccountMoney', account) end end end @@ -296,7 +284,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.set('bank', newMoney) end - TriggerClientEvent('esx:setAccountMoney', self.source, account) + self.triggerEvent('esx:setAccountMoney', account) end end end @@ -319,7 +307,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l item.count = newCount TriggerEvent('esx:onAddInventoryItem', self.source, item, count) - TriggerClientEvent('esx:addInventoryItem', self.source, item, count) + self.triggerEvent('esx:addInventoryItem', item, count) end end @@ -333,7 +321,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l item.count = newCount TriggerEvent('esx:onRemoveInventoryItem', self.source, item, count) - TriggerClientEvent('esx:removeInventoryItem', self.source, item, count) + self.triggerEvent('esx:removeInventoryItem', item, count) end end end @@ -347,10 +335,10 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if oldCount > item.count then TriggerEvent('esx:onRemoveInventoryItem', self.source, item, oldCount - item.count) - TriggerClientEvent('esx:removeInventoryItem', self.source, item, oldCount - item.count) + self.triggerEvent('esx:removeInventoryItem', item, oldCount - item.count) else TriggerEvent('esx:onAddInventoryItem', self.source, item, item.count - oldCount) - TriggerClientEvent('esx:addInventoryItem', self.source, item, item.count - oldCount) + self.triggerEvent('esx:addInventoryItem', item, item.count - oldCount) end end end @@ -388,7 +376,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l self.setMaxWeight = function(newWeight) self.maxWeight = newWeight - TriggerClientEvent('esx:setMaxWeight', self.source, self.maxWeight) + self.triggerEvent('esx:setMaxWeight', self.maxWeight) end self.setJob = function(job, grade) @@ -419,7 +407,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end TriggerEvent('esx:setJob', self.source, self.job, lastJob) - TriggerClientEvent('esx:setJob', self.source, self.job) + self.triggerEvent('esx:setJob', self.job) else print(('[es_extended] [^3WARNING^7] Ignoring invalid .setJob() usage for "%s"'):format(self.identifier)) end @@ -436,8 +424,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l components = {} }) - TriggerClientEvent('esx:addWeapon', self.source, weaponName, ammo) - TriggerClientEvent('esx:addInventoryItem', self.source, {label = weaponLabel}, 1) + self.triggerEvent('esx:addWeapon', weaponName, ammo) + self.triggerEvent('esx:addInventoryItem', {label = weaponLabel}, 1) end end @@ -447,7 +435,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if weapon then if not self.hasWeaponComponent(weaponName, weaponComponent) then table.insert(self.loadout[loadoutNum].components, weaponComponent) - TriggerClientEvent('esx:addWeaponComponent', self.source, weaponName, weaponComponent) + self.triggerEvent('esx:addWeaponComponent', weaponName, weaponComponent) end end end @@ -457,7 +445,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if weapon then weapon.ammo = weapon.ammo + ammoCount - TriggerClientEvent('esx:setWeaponAmmo', self.source, weaponName, weapon.ammo) + self.triggerEvent('esx:setWeaponAmmo', weaponName, weapon.ammo) end end @@ -469,7 +457,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l weaponLabel = v.label for k2,v2 in ipairs(v.components) do - TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, v2) + self.triggerEvent('esx:removeWeaponComponent', weaponName, v2) end table.remove(self.loadout, k) @@ -478,8 +466,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end if weaponLabel then - TriggerClientEvent('esx:removeWeapon', self.source, weaponName, ammo) - TriggerClientEvent('esx:removeInventoryItem', self.source, {label = weaponLabel}, 1) + self.triggerEvent('esx:removeWeapon', weaponName, ammo) + self.triggerEvent('esx:removeInventoryItem', {label = weaponLabel}, 1) end end @@ -494,7 +482,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end end - TriggerClientEvent('esx:removeWeaponComponent', self.source, weaponName, weaponComponent) + self.triggerEvent('esx:removeWeaponComponent', weaponName, weaponComponent) end end @@ -503,7 +491,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l if weapon then weapon.ammo = weapon.ammo - ammoCount - TriggerClientEvent('esx:setWeaponAmmo', self.source, weaponName, weapon.ammo) + self.triggerEvent('esx:setWeaponAmmo', weaponName, weapon.ammo) end end @@ -544,11 +532,11 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, l end self.showNotification = function(msg) - TriggerClientEvent('esx:showNotification', self.source, msg) + self.triggerEvent('esx:showNotification', msg) end self.showHelpNotification = function(msg) - TriggerClientEvent('esx:showHelpNotification', self.source, msg) + self.triggerEvent('esx:showHelpNotification', msg) end return self diff --git a/server/functions.lua b/server/functions.lua index 5bd0008f..2a20eeea 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -38,7 +38,6 @@ end ESX.SavePlayer = function(xPlayer, cb) local asyncTasks = {} - xPlayer.setLastPosition(xPlayer.getCoords()) -- User accounts for k,v in ipairs(xPlayer.accounts) do @@ -80,7 +79,7 @@ ESX.SavePlayer = function(xPlayer, cb) ['@job'] = xPlayer.job.name, ['@job_grade'] = xPlayer.job.grade, ['@loadout'] = json.encode(xPlayer.getLoadout()), - ['@position'] = json.encode(xPlayer.getLastPosition()), + ['@position'] = json.encode(xPlayer.getCoords()), ['@identifier'] = xPlayer.identifier }, function(rowsChanged) cb() @@ -88,7 +87,7 @@ ESX.SavePlayer = function(xPlayer, cb) end) Async.parallel(asyncTasks, function(results) - print(('[es_extended] [^2INFO^7] Saved %s'):format(xPlayer.getName())) + print(('[es_extended] [^2INFO^7] Saved player "%s^7"'):format(xPlayer.getName())) if cb ~= nil then cb() @@ -190,4 +189,4 @@ ESX.DoesJobExist = function(job, grade) end return false -end \ No newline at end of file +end diff --git a/server/main.lua b/server/main.lua index b6e1806d..49fb94fe 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,233 +1,225 @@ -AddEventHandler('es:playerLoaded', function(source, _player) - local playerId = source - local tasks = {} +AddEventHandler('es:playerLoaded', function(playerId, player) + local tasks = {} local userData = { - accounts = {}, - inventory = {}, - job = {}, - loadout = {}, - playerName = GetPlayerName(playerId), - lastPosition = nil + accounts = {}, + inventory = {}, + job = {}, + loadout = {}, + playerName = GetPlayerName(playerId), + coords = nil } - TriggerEvent('es:getPlayerFromId', playerId, 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) + -- 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 name, money FROM user_accounts WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() - }, function(accounts) - local validAccounts = ESX.Table.Set(Config.Accounts) - for k,v in ipairs(accounts) do - if validAccounts[v.name] then - table.insert(userData.accounts, { - name = v.name, - money = v.money, - label = Config.AccountLabels[v.name] - }) - end + -- Get accounts + table.insert(tasks, function(cb) + MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', { + ['@identifier'] = player.getIdentifier() + }, function(accounts) + local validAccounts = ESX.Table.Set(Config.Accounts) + for k,v in ipairs(accounts) do + if validAccounts[v.name] then + table.insert(userData.accounts, { + name = v.name, + money = v.money, + label = Config.AccountLabels[v.name] + }) end + end - cb() - end) + cb() end) + end) - -- Get inventory - table.insert(tasks, function(cb) + -- Get inventory + table.insert(tasks, function(cb) + MySQL.Async.fetchAll('SELECT item, count FROM user_inventory WHERE identifier = @identifier', { + ['@identifier'] = player.getIdentifier() + }, function(inventory) + local tasks2, foundItems = {}, {} - MySQL.Async.fetchAll('SELECT item, count FROM user_inventory WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() - }, function(inventory) - local tasks2, foundItems = {}, {} + for k,v in ipairs(inventory) do + local item = ESX.Items[v.item] - for k,v in ipairs(inventory) do - local item = ESX.Items[v.item] + if item then + foundItems[v.item] = true - if item then - foundItems[v.item] = true - - table.insert(userData.inventory, { - name = v.item, - count = v.count, - label = item.label, - weight = item.weight, - usable = ESX.UsableItemsCallbacks[v.item] ~= nil, - rare = item.rare, - canRemove = item.canRemove - }) - else - print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(v.item, player.getIdentifier())) - end + table.insert(userData.inventory, { + name = v.item, + count = v.count, + label = item.label, + weight = item.weight, + usable = ESX.UsableItemsCallbacks[v.item] ~= nil, + rare = item.rare, + canRemove = item.canRemove + }) + else + print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(v.item, player.getIdentifier())) end + end - for itemName,item in pairs(ESX.Items) do - if not foundItems[itemName] then - table.insert(userData.inventory, { - name = itemName, - count = 0, - label = item.label, - weight = item.weight, - usable = ESX.UsableItemsCallbacks[itemName] ~= nil, - rare = item.rare, - canRemove = item.canRemove - }) + for name,item in pairs(ESX.Items) do + if not foundItems[name] then + table.insert(userData.inventory, { + name = name, + count = 0, + label = item.label, + weight = item.weight, + usable = ESX.UsableItemsCallbacks[name] ~= nil, + rare = item.rare, + canRemove = item.canRemove + }) - local scope = function(item, identifier) - table.insert(tasks2, function(cb2) - MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', { - ['@identifier'] = identifier, - ['@item'] = item, - ['@count'] = 0 - }, function(rowsChanged) - cb2() - end) + local scope = function(item, identifier) + table.insert(tasks2, function(cb2) + MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', { + ['@identifier'] = identifier, + ['@item'] = item, + ['@count'] = 0 + }, function(rowsChanged) + cb2() end) - end + end) + end - scope(itemName, player.getIdentifier()) + scope(name, player.getIdentifier()) + end + end + + Async.parallelLimit(tasks2, 5, function(results) 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 coords + table.insert(tasks2, function(cb2) + + MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier', { + ['@identifier'] = player.getIdentifier() + }, function(result) + local job, grade = result[1].job, tostring(result[1].job_grade) + + if ESX.DoesJobExist(job, grade) then + local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + + userData.job = {} + + userData.job.id = jobObject.id + userData.job.name = jobObject.name + userData.job.label = jobObject.label + + userData.job.grade = tonumber(grade) + userData.job.grade_name = gradeObject.name + userData.job.grade_label = gradeObject.label + userData.job.grade_salary = gradeObject.salary + + userData.job.skin_male = {} + userData.job.skin_female = {} + + if gradeObject.skin_male then + userData.job.skin_male = json.decode(gradeObject.skin_male) + end + + if gradeObject.skin_female then + userData.job.skin_female = json.decode(gradeObject.skin_female) + end + else + print(('[es_extended] [^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(player.getIdentifier(), job, grade)) + + local job, grade = 'unemployed', '0' + local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + + userData.job = {} + + userData.job.id = jobObject.id + userData.job.name = jobObject.name + userData.job.label = jobObject.label + + userData.job.grade = tonumber(grade) + userData.job.grade_name = gradeObject.name + userData.job.grade_label = gradeObject.label + userData.job.grade_salary = gradeObject.salary + + userData.job.skin_male = {} + userData.job.skin_female = {} + end + + if result[1].loadout then + userData.loadout = json.decode(result[1].loadout) + + -- Compatibility with old loadouts prior to components update + for k,v in ipairs(userData.loadout) do + if v.components == nil then + v.components = {} + end end end - Async.parallelLimit(tasks2, 5, function(results) end) - - table.sort(userData.inventory, function(a,b) - return a.label < b.label - end) - - cb() + userData.coords = json.decode(result[1].position) + cb2() end) end) - -- Get job and loadout - table.insert(tasks, function(cb) + Async.series(tasks2, cb) - local tasks2 = {} + end) - -- Get job name, grade and last position - table.insert(tasks2, function(cb2) + -- Run Tasks + Async.parallel(tasks, function(results) + local xPlayer = CreateExtendedPlayer(player, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords) - MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() - }, function(result) - local job, grade = result[1].job, tostring(result[1].job_grade) - - if ESX.DoesJobExist(job, grade) then - local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] - - userData.job = {} - - userData.job.id = jobObject.id - userData.job.name = jobObject.name - userData.job.label = jobObject.label - - userData.job.grade = tonumber(grade) - userData.job.grade_name = gradeObject.name - userData.job.grade_label = gradeObject.label - userData.job.grade_salary = gradeObject.salary - - userData.job.skin_male = {} - userData.job.skin_female = {} - - if gradeObject.skin_male ~= nil then - userData.job.skin_male = json.decode(gradeObject.skin_male) - end - - if gradeObject.skin_female ~= nil then - userData.job.skin_female = json.decode(gradeObject.skin_female) - end - else - print(('[es_extended] [^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(player.getIdentifier(), job, grade)) - - local job, grade = 'unemployed', '0' - local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] - - userData.job = {} - - userData.job.id = jobObject.id - userData.job.name = jobObject.name - userData.job.label = jobObject.label - - userData.job.grade = tonumber(grade) - userData.job.grade_name = gradeObject.name - userData.job.grade_label = gradeObject.label - userData.job.grade_salary = gradeObject.salary - - userData.job.skin_male = {} - userData.job.skin_female = {} - end - - if result[1].loadout ~= nil then - userData.loadout = json.decode(result[1].loadout) - - -- Compatibility with old loadouts prior to components update - for k,v in ipairs(userData.loadout) do - if v.components == nil then - v.components = {} - end - end - end - - if result[1].position ~= nil then - userData.lastPosition = json.decode(result[1].position) - 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) + 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 - ESX.Players[playerId] = xPlayer + xPlayer.createAccounts(missingAccounts) + end - TriggerEvent('esx:playerLoaded', playerId, xPlayer) + ESX.Players[playerId] = xPlayer - TriggerClientEvent('esx:playerLoaded', playerId, { - identifier = xPlayer.identifier, - accounts = xPlayer.getAccounts(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), - money = xPlayer.getMoney(), - maxWeight = xPlayer.maxWeight - }) + TriggerEvent('esx:playerLoaded', playerId, xPlayer) - xPlayer.displayMoney(xPlayer.getMoney()) - TriggerClientEvent('esx:createMissingPickups', playerId, ESX.Pickups) - end) + xPlayer.triggerEvent('esx:playerLoaded', { + identifier = xPlayer.identifier, + accounts = xPlayer.getAccounts(), + coords = xPlayer.getCoords(), + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + money = xPlayer.getMoney(), + maxWeight = xPlayer.maxWeight + }) + + xPlayer.displayMoney(xPlayer.getMoney()) + xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) end) - end) end) @@ -245,15 +237,16 @@ AddEventHandler('playerDropped', function(reason) end end) +RegisterNetEvent('esx:updateCoords') +AddEventHandler('esx:updateCoords', function(coords) local xPlayer = ESX.GetPlayerFromId(source) -RegisterServerEvent('esx:updateLastPosition') -AddEventHandler('esx:updateLastPosition', function(position) - local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.setLastPosition(position) + if xPlayer then + xPlayer.updateCoords(coords) + end end) -RegisterServerEvent('esx:giveInventoryItem') +RegisterNetEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) local playerId = source local sourceXPlayer = ESX.GetPlayerFromId(playerId) @@ -306,7 +299,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo sourceXPlayer.removeWeapon(itemName) targetXPlayer.addWeapon(itemName, itemCount) - + if itemCount > 0 then sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, targetXPlayer.name)) targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, sourceXPlayer.name)) @@ -339,7 +332,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo end end) -RegisterServerEvent('esx:removeInventoryItem') +RegisterNetEvent('esx:removeInventoryItem') AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) local playerId = source local xPlayer = ESX.GetPlayerFromId(source) @@ -406,7 +399,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end end) -RegisterServerEvent('esx:useItem') +RegisterNetEvent('esx:useItem') AddEventHandler('esx:useItem', function(itemName) local xPlayer = ESX.GetPlayerFromId(source) local count = xPlayer.getInventoryItem(itemName).count @@ -418,7 +411,7 @@ AddEventHandler('esx:useItem', function(itemName) end end) -RegisterServerEvent('esx:onPickup') +RegisterNetEvent('esx:onPickup') AddEventHandler('esx:onPickup', function(id) local pickup, xPlayer, success = ESX.Pickups[id], ESX.GetPlayerFromId(source) @@ -465,7 +458,6 @@ ESX.RegisterServerCallback('esx:getPlayerData', function(source, cb) inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), money = xPlayer.getMoney() }) end) @@ -479,7 +471,6 @@ ESX.RegisterServerCallback('esx:getOtherPlayerData', function(source, cb, target inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), - lastPosition = xPlayer.getLastPosition(), money = xPlayer.getMoney() }) end) From b3a36747a3ba2a546af365bf4870f0637327b6b6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 10:27:07 +0100 Subject: [PATCH 387/672] Removed saving Steam name in database, closes #246 --- es_extended.sql | 1 - server/main.lua | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 4cab101a..399847e9 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,7 +1,6 @@ USE `essentialmode`; ALTER TABLE `users` - ADD COLUMN `name` VARCHAR(50) NULL DEFAULT '' AFTER `money`, ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, diff --git a/server/main.lua b/server/main.lua index 49fb94fe..643797f0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -10,16 +10,6 @@ AddEventHandler('es:playerLoaded', function(playerId, player) coords = nil } - -- 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 name, money FROM user_accounts WHERE identifier = @identifier', { From 1d83a1f2f46c2ea324c0b4196310dcfac68435c1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 11:54:19 +0100 Subject: [PATCH 388/672] Updated native names, added optional values (read desc) Added flash and saveToBreif booleans to ESX.ShowNotification() and ESX.ShowHelpNotification() Added two optional booleans thisFrame, beep to ShowHelpNotification() and last new optional argument duration --- client/functions.lua | 39 +++++++++++++++++++++------------------ server/classes/player.lua | 8 ++++---- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index c5e2021d..854b0b40 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -44,25 +44,28 @@ ESX.SetPlayerData = function(key, val) ESX.PlayerData[key] = val end -ESX.ShowNotification = function(msg) +ESX.ShowNotification = function(msg, flash, saveToBrief) AddTextEntry('esxNotification', msg) - SetNotificationTextEntry('esxNotification') - DrawNotification(false, true) + BeginTextCommandThefeedPost('esxNotification') + EndTextCommandThefeedPostTicker(flash or false, saveToBrief or true) end -ESX.ShowAdvancedNotification = function(title, subject, msg, icon, iconType) +ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief) AddTextEntry('esxAdvancedNotification', msg) - SetNotificationTextEntry('esxAdvancedNotification') - SetNotificationMessage(icon, icon, false, iconType, title, subject) - DrawNotification(false, false) + BeginTextCommandThefeedPost('esxAdvancedNotification') + EndTextCommandThefeedPostMessagetext(textureDict, textureDict, false, iconType, sender, subject) + EndTextCommandThefeedPostTicker(flash, saveToBrief) end -ESX.ShowHelpNotification = function(msg) - --if not IsHelpMessageBeingDisplayed() then - AddTextEntry('esxHelpNotification', msg) +ESX.ShowHelpNotification = function(msg, thisFrame, beep, duration) + AddTextEntry('esxHelpNotification', msg) + + if thisFrame then + DisplayHelpTextThisFrame('esxHelpNotification', true) + else BeginTextCommandDisplayHelp('esxHelpNotification') - EndTextCommandDisplayHelp(0, false, true, -1) - --end + EndTextCommandDisplayHelp(0, false, beep or true, duration or -1) + end end ESX.TriggerServerCallback = function(name, cb, ...) @@ -1104,18 +1107,18 @@ AddEventHandler('esx:serverCallback', function(requestId, ...) end) RegisterNetEvent('esx:showNotification') -AddEventHandler('esx:showNotification', function(msg) - ESX.ShowNotification(msg) +AddEventHandler('esx:showNotification', function(msg, flash, saveToBrief) + ESX.ShowNotification(msg, flash, saveToBrief) end) RegisterNetEvent('esx:showAdvancedNotification') -AddEventHandler('esx:showAdvancedNotification', function(title, subject, msg, icon, iconType) - ESX.ShowAdvancedNotification(title, subject, msg, icon, iconType) +AddEventHandler('esx:showAdvancedNotification', function(sender, subject, msg, textureDict, iconType, flash, saveToBrief) + ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief) end) RegisterNetEvent('esx:showHelpNotification') -AddEventHandler('esx:showHelpNotification', function(msg) - ESX.ShowHelpNotification(msg) +AddEventHandler('esx:showHelpNotification', function(msg, thisFrame, beep, duration) + ESX.ShowHelpNotification(msg, thisFrame, beep, duration) end) -- SetTimeout diff --git a/server/classes/player.lua b/server/classes/player.lua index 851bb397..6909b5c8 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -531,12 +531,12 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c return end - self.showNotification = function(msg) - self.triggerEvent('esx:showNotification', msg) + self.showNotification = function(msg, flash, saveToBrief) + self.triggerEvent('esx:showNotification', msg, flash, saveToBrief) end - self.showHelpNotification = function(msg) - self.triggerEvent('esx:showHelpNotification', msg) + self.showHelpNotification = function(msg, thisFrame, beep, duration) + self.triggerEvent('esx:showHelpNotification', msg, thisFrame, beep, duration) end return self From c345d40374194ef7c2becca7e27bd183fac28239 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 12:11:37 +0100 Subject: [PATCH 389/672] Disable DisplayHelpTextThisFrame saveToBreif, fixed code --- client/functions.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 854b0b40..ec5e3b29 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -45,9 +45,10 @@ ESX.SetPlayerData = function(key, val) end ESX.ShowNotification = function(msg, flash, saveToBrief) + if saveToBrief == nil then saveToBrief = true end AddTextEntry('esxNotification', msg) BeginTextCommandThefeedPost('esxNotification') - EndTextCommandThefeedPostTicker(flash or false, saveToBrief or true) + EndTextCommandThefeedPostTicker(flash or false, saveToBrief) end ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief) @@ -61,10 +62,11 @@ ESX.ShowHelpNotification = function(msg, thisFrame, beep, duration) AddTextEntry('esxHelpNotification', msg) if thisFrame then - DisplayHelpTextThisFrame('esxHelpNotification', true) + DisplayHelpTextThisFrame('esxHelpNotification', false) else + if beep == nil then beep = true end BeginTextCommandDisplayHelp('esxHelpNotification') - EndTextCommandDisplayHelp(0, false, beep or true, duration or -1) + EndTextCommandDisplayHelp(0, false, beep, duration or -1) end end From 60fd7e317ba6aa363f152429e4f918a9e2b7b8d9 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 12:18:39 +0100 Subject: [PATCH 390/672] Added optional notification background color arugment Co-Authored-By: WolfShy1 --- client/functions.lua | 14 ++++++++------ server/classes/player.lua | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index ec5e3b29..c14e9643 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -44,16 +44,18 @@ ESX.SetPlayerData = function(key, val) ESX.PlayerData[key] = val end -ESX.ShowNotification = function(msg, flash, saveToBrief) +ESX.ShowNotification = function(msg, flash, saveToBrief, hudColorIndex) if saveToBrief == nil then saveToBrief = true end AddTextEntry('esxNotification', msg) BeginTextCommandThefeedPost('esxNotification') + if hudColorIndex then ThefeedNextPostBackgroundColor(hudColorIndex) end EndTextCommandThefeedPostTicker(flash or false, saveToBrief) end -ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief) +ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) AddTextEntry('esxAdvancedNotification', msg) BeginTextCommandThefeedPost('esxAdvancedNotification') + if hudColorIndex then ThefeedNextPostBackgroundColor(hudColorIndex) end EndTextCommandThefeedPostMessagetext(textureDict, textureDict, false, iconType, sender, subject) EndTextCommandThefeedPostTicker(flash, saveToBrief) end @@ -1109,13 +1111,13 @@ AddEventHandler('esx:serverCallback', function(requestId, ...) end) RegisterNetEvent('esx:showNotification') -AddEventHandler('esx:showNotification', function(msg, flash, saveToBrief) - ESX.ShowNotification(msg, flash, saveToBrief) +AddEventHandler('esx:showNotification', function(msg, flash, saveToBrief, hudColorIndex) + ESX.ShowNotification(msg, flash, saveToBrief, hudColorIndex) end) RegisterNetEvent('esx:showAdvancedNotification') -AddEventHandler('esx:showAdvancedNotification', function(sender, subject, msg, textureDict, iconType, flash, saveToBrief) - ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief) +AddEventHandler('esx:showAdvancedNotification', function(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) + ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) end) RegisterNetEvent('esx:showHelpNotification') diff --git a/server/classes/player.lua b/server/classes/player.lua index 6909b5c8..f612d74c 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -531,8 +531,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c return end - self.showNotification = function(msg, flash, saveToBrief) - self.triggerEvent('esx:showNotification', msg, flash, saveToBrief) + self.showNotification = function(msg, flash, saveToBrief, hudColorIndex) + self.triggerEvent('esx:showNotification', msg, flash, saveToBrief, hudColorIndex) end self.showHelpNotification = function(msg, thisFrame, beep, duration) From 0d4377042d9ed2ba974305e99493a0e4fdefd420 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 12:33:55 +0100 Subject: [PATCH 391/672] Update functions.lua --- client/functions.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index c14e9643..884254a4 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -53,11 +53,12 @@ ESX.ShowNotification = function(msg, flash, saveToBrief, hudColorIndex) end ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) + if saveToBrief == nil then saveToBrief = true end AddTextEntry('esxAdvancedNotification', msg) BeginTextCommandThefeedPost('esxAdvancedNotification') if hudColorIndex then ThefeedNextPostBackgroundColor(hudColorIndex) end EndTextCommandThefeedPostMessagetext(textureDict, textureDict, false, iconType, sender, subject) - EndTextCommandThefeedPostTicker(flash, saveToBrief) + EndTextCommandThefeedPostTicker(flash or false, saveToBrief) end ESX.ShowHelpNotification = function(msg, thisFrame, beep, duration) From 0fbd5d03a21d9290472738c2895ea7f6713e45aa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 14:10:57 +0100 Subject: [PATCH 392/672] Minor changes, fixed giving weapon? --- client/functions.lua | 43 ++++++++++++++++++++++--------------------- server/main.lua | 2 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 884254a4..10dd84d5 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -278,13 +278,17 @@ ESX.UI.ShowInventoryItemNotification = function(add, item, count) end ESX.Game.GetPedMugshot = function(ped) - local mugshot = RegisterPedheadshot(ped) + if DoesEntityExist(ped) then + local mugshot = RegisterPedheadshot(ped) - while not IsPedheadshotReady(mugshot) do - Citizen.Wait(0) + while not IsPedheadshotReady(mugshot) do + Citizen.Wait(0) + end + + return mugshot, GetPedheadshotTxdString(mugshot) + else + return end - - return mugshot, GetPedheadshotTxdString(mugshot) end ESX.Game.Teleport = function(entity, coords, cb) @@ -512,15 +516,14 @@ ESX.Game.GetClosestPlayer = function(coords) end ESX.Game.GetPlayersInArea = function(coords, area) - local players = ESX.Game.GetPlayers() - local playersInArea = {} + local players, playersInArea = ESX.Game.GetPlayers(), {} + coords = vector3(coords.x, coords.y, coords.z) for i=1, #players, 1 do - local target = GetPlayerPed(players[i]) + local target = GetPlayerPed(players[i]) local targetCoords = GetEntityCoords(target) - local distance = GetDistanceBetweenCoords(targetCoords, coords.x, coords.y, coords.z, true) - if distance <= area then + if #(coords - targetCoords) <= area then table.insert(playersInArea, players[i]) end end @@ -539,23 +542,22 @@ ESX.Game.GetVehicles = function() end ESX.Game.GetClosestVehicle = function(coords) - local vehicles = ESX.Game.GetVehicles() - local closestDistance = -1 - local closestVehicle = -1 - local coords = coords + local vehicles = ESX.Game.GetVehicles() + local closestDistance, closestVehicle, coords = -1, -1, coords - if coords == nil then + if coords then + coords = vector3(coords.x, coords.y, coords.z) + else local playerPed = PlayerPedId() - coords = GetEntityCoords(playerPed) + coords = GetEntityCoords(playerPed) end for i=1, #vehicles, 1 do local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords, coords.x, coords.y, coords.z, true) + local distance = #(coords - vehicleCoords) if closestDistance == -1 or closestDistance > distance then - closestVehicle = vehicles[i] - closestDistance = distance + closestVehicle, closestDistance = vehicles[i], distance end end @@ -677,9 +679,8 @@ ESX.Game.GetVehicleProperties = function(vehicle) IsVehicleNeonLightEnabled(vehicle, 3) }, - extras = extras, - neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + extras = extras, tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(vehicle)), modSpoilers = GetVehicleMod(vehicle, 0), diff --git a/server/main.lua b/server/main.lua index 643797f0..251dcd6a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -284,7 +284,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo local weaponLabel = ESX.GetWeaponLabel(itemName) if not targetXPlayer.hasWeapon(itemName) then - local _,weapon = xPlayer.getWeapon(itemName) + local weaponNum, weapon = xPlayer.getWeapon(itemName) itemCount = weapon.ammo sourceXPlayer.removeWeapon(itemName) From 1e146c32116f3307d06aaaa9c36a43fe76e1a427 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 14:13:15 +0100 Subject: [PATCH 393/672] Added entity check for GetVehicleProperties() --- client/functions.lua | 182 ++++++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 89 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 10dd84d5..edc0ff5f 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -641,98 +641,102 @@ ESX.Game.GetClosestPed = function(coords, ignoreList) end ESX.Game.GetVehicleProperties = function(vehicle) - local colorPrimary, colorSecondary = GetVehicleColours(vehicle) - local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) - local extras = {} + if DoesEntityExist(vehicle) then + local colorPrimary, colorSecondary = GetVehicleColours(vehicle) + local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) + local extras = {} - for id=0, 12 do - if DoesExtraExist(vehicle, id) then - local state = IsVehicleExtraTurnedOn(vehicle, id) == 1 - extras[tostring(id)] = state + for id=0, 12 do + if DoesExtraExist(vehicle, id) then + local state = IsVehicleExtraTurnedOn(vehicle, id) == 1 + extras[tostring(id)] = state + end end + + return { + model = GetEntityModel(vehicle), + + plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)), + plateIndex = GetVehicleNumberPlateTextIndex(vehicle), + + bodyHealth = ESX.Math.Round(GetVehicleBodyHealth(vehicle), 1), + engineHealth = ESX.Math.Round(GetVehicleEngineHealth(vehicle), 1), + + fuelLevel = ESX.Math.Round(GetVehicleFuelLevel(vehicle), 1), + dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), + color1 = colorPrimary, + color2 = colorSecondary, + + pearlescentColor = pearlescentColor, + wheelColor = wheelColor, + + wheels = GetVehicleWheelType(vehicle), + windowTint = GetVehicleWindowTint(vehicle), + + neonEnabled = { + IsVehicleNeonLightEnabled(vehicle, 0), + IsVehicleNeonLightEnabled(vehicle, 1), + IsVehicleNeonLightEnabled(vehicle, 2), + IsVehicleNeonLightEnabled(vehicle, 3) + }, + + neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), + extras = extras, + tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(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), + modSmokeEnabled = IsToggleModOn(vehicle, 20), + modXenon = IsToggleModOn(vehicle, 22), + + modFrontWheels = GetVehicleMod(vehicle, 23), + modBackWheels = GetVehicleMod(vehicle, 24), + + modPlateHolder = GetVehicleMod(vehicle, 25), + modVanityPlate = GetVehicleMod(vehicle, 26), + modTrimA = GetVehicleMod(vehicle, 27), + modOrnaments = GetVehicleMod(vehicle, 28), + modDashboard = GetVehicleMod(vehicle, 29), + modDial = GetVehicleMod(vehicle, 30), + modDoorSpeaker = GetVehicleMod(vehicle, 31), + modSeats = GetVehicleMod(vehicle, 32), + modSteeringWheel = GetVehicleMod(vehicle, 33), + modShifterLeavers = GetVehicleMod(vehicle, 34), + modAPlate = GetVehicleMod(vehicle, 35), + modSpeakers = GetVehicleMod(vehicle, 36), + modTrunk = GetVehicleMod(vehicle, 37), + modHydrolic = GetVehicleMod(vehicle, 38), + modEngineBlock = GetVehicleMod(vehicle, 39), + modAirFilter = GetVehicleMod(vehicle, 40), + modStruts = GetVehicleMod(vehicle, 41), + modArchCover = GetVehicleMod(vehicle, 42), + modAerials = GetVehicleMod(vehicle, 43), + modTrimB = GetVehicleMod(vehicle, 44), + modTank = GetVehicleMod(vehicle, 45), + modWindows = GetVehicleMod(vehicle, 46), + modLivery = GetVehicleLivery(vehicle) + } + else + return end - - return { - model = GetEntityModel(vehicle), - - plate = ESX.Math.Trim(GetVehicleNumberPlateText(vehicle)), - plateIndex = GetVehicleNumberPlateTextIndex(vehicle), - - bodyHealth = ESX.Math.Round(GetVehicleBodyHealth(vehicle), 1), - engineHealth = ESX.Math.Round(GetVehicleEngineHealth(vehicle), 1), - - fuelLevel = ESX.Math.Round(GetVehicleFuelLevel(vehicle), 1), - dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), - color1 = colorPrimary, - color2 = colorSecondary, - - pearlescentColor = pearlescentColor, - wheelColor = wheelColor, - - wheels = GetVehicleWheelType(vehicle), - windowTint = GetVehicleWindowTint(vehicle), - - neonEnabled = { - IsVehicleNeonLightEnabled(vehicle, 0), - IsVehicleNeonLightEnabled(vehicle, 1), - IsVehicleNeonLightEnabled(vehicle, 2), - IsVehicleNeonLightEnabled(vehicle, 3) - }, - - neonColor = table.pack(GetVehicleNeonLightsColour(vehicle)), - extras = extras, - tyreSmokeColor = table.pack(GetVehicleTyreSmokeColor(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), - modSmokeEnabled = IsToggleModOn(vehicle, 20), - modXenon = IsToggleModOn(vehicle, 22), - - modFrontWheels = GetVehicleMod(vehicle, 23), - modBackWheels = GetVehicleMod(vehicle, 24), - - modPlateHolder = GetVehicleMod(vehicle, 25), - modVanityPlate = GetVehicleMod(vehicle, 26), - modTrimA = GetVehicleMod(vehicle, 27), - modOrnaments = GetVehicleMod(vehicle, 28), - modDashboard = GetVehicleMod(vehicle, 29), - modDial = GetVehicleMod(vehicle, 30), - modDoorSpeaker = GetVehicleMod(vehicle, 31), - modSeats = GetVehicleMod(vehicle, 32), - modSteeringWheel = GetVehicleMod(vehicle, 33), - modShifterLeavers = GetVehicleMod(vehicle, 34), - modAPlate = GetVehicleMod(vehicle, 35), - modSpeakers = GetVehicleMod(vehicle, 36), - modTrunk = GetVehicleMod(vehicle, 37), - modHydrolic = GetVehicleMod(vehicle, 38), - modEngineBlock = GetVehicleMod(vehicle, 39), - modAirFilter = GetVehicleMod(vehicle, 40), - modStruts = GetVehicleMod(vehicle, 41), - modArchCover = GetVehicleMod(vehicle, 42), - modAerials = GetVehicleMod(vehicle, 43), - modTrimB = GetVehicleMod(vehicle, 44), - modTank = GetVehicleMod(vehicle, 45), - modWindows = GetVehicleMod(vehicle, 46), - modLivery = GetVehicleLivery(vehicle) - } end ESX.Game.SetVehicleProperties = function(vehicle, props) From 06eb61fa2ae206a21baa8426b8a2f560ab7e7f37 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Jan 2020 15:04:15 +0100 Subject: [PATCH 394/672] Fixed random vehicle colors --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index edc0ff5f..8f020a8a 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -752,7 +752,7 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) if props.fuelLevel then SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end if props.dirtLevel then SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end if props.color1 then SetVehicleColours(vehicle, props.color1, colorSecondary) end - if props.color2 then SetVehicleColours(vehicle, colorPrimary, props.color2) end + if props.color2 then SetVehicleColours(vehicle, props.color1 or colorPrimary, props.color2) end if props.pearlescentColor then SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) end if props.wheelColor then SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) end if props.wheels then SetVehicleWheelType(vehicle, props.wheels) end From 99c43b62c0f800da33f05c922b3109b28c168214 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 16 Jan 2020 12:26:31 +0100 Subject: [PATCH 395/672] Fixed Teleport function with vector3 types --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index 8f020a8a..cb14c356 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -302,7 +302,7 @@ ESX.Game.Teleport = function(entity, coords, cb) SetEntityCoords(entity, coords.x, coords.y, coords.z, false, false, false, false) - if coords.heading then + if type(coords) == 'table' and coords.heading then SetEntityHeading(entity, coords.heading) end end From eb407d980c806972652a7e87e4987f36b3662fe1 Mon Sep 17 00:00:00 2001 From: Julien80 Date: Sat, 18 Jan 2020 20:53:18 +0100 Subject: [PATCH 396/672] Fix give weapon on esx:giveInventoryItem --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 251dcd6a..78086ea5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -284,7 +284,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo local weaponLabel = ESX.GetWeaponLabel(itemName) if not targetXPlayer.hasWeapon(itemName) then - local weaponNum, weapon = xPlayer.getWeapon(itemName) + local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) itemCount = weapon.ammo sourceXPlayer.removeWeapon(itemName) From 133825dbea8145a30aae9a21a93a85ea83cb5d55 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Jan 2020 17:57:28 +0100 Subject: [PATCH 397/672] Use new key register --- client/main.lua | 15 ++++++--------- locales/br.lua | 5 +++++ locales/cs.lua | 6 ++++++ locales/de.lua | 5 +++++ locales/en.lua | 7 ++++++- locales/fi.lua | 5 +++++ locales/fr.lua | 5 +++++ locales/pl.lua | 7 ++++++- locales/sv.lua | 5 +++++ 9 files changed, 49 insertions(+), 11 deletions(-) diff --git a/client/main.lua b/client/main.lua index 48285d2b..18d0ad43 100644 --- a/client/main.lua +++ b/client/main.lua @@ -436,16 +436,13 @@ Citizen.CreateThread(function() 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 +RegisterCommand('showinventory', function() + if not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + ESX.ShowInventory() end -end) +end, false) + +RegisterKeyMapping('showinventory', _U('keymap_showinventory'), 'keyboard', 'F2') -- Disable wanted level if Config.DisableWantedLevel then diff --git a/locales/br.lua b/locales/br.lua index 98d58441..e67cdc54 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -40,6 +40,10 @@ Locales['br'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + -- Salary related ['received_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', ['received_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', @@ -73,6 +77,7 @@ Locales['br'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/cs.lua b/locales/cs.lua index 38521079..7c537b59 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -40,6 +40,11 @@ Locales['cs'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + + -- Salary related ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', @@ -73,6 +78,7 @@ Locales['cs'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/de.lua b/locales/de.lua index 5df299f5..4a9a5f7f 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -40,6 +40,10 @@ Locales['de'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + -- Salary related ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', ['received_help'] = 'du hast deine Sozialhilfe erhalten: ~g~$%s~s~', @@ -73,6 +77,7 @@ Locales['de'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/en.lua b/locales/en.lua index d3c2b4b4..a41b982d 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -40,12 +40,16 @@ Locales['en'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + -- Salary related ['received_salary'] = 'you received your salary: ~g~$%s~s~', ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary', ['received_paycheck'] = 'received paycheck', - ['bank'] = 'bank', + ['bank'] = 'maze Bank', ['black_money'] = 'dirty Money', ['act_imp'] = 'action impossible', @@ -73,6 +77,7 @@ Locales['en'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ',', ['locale_currency'] = '$%s', diff --git a/locales/fi.lua b/locales/fi.lua index b20da9c0..a3a32e6c 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -40,6 +40,10 @@ Locales['fi'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + -- Salary related ['received_salary'] = 'sinä vastaanotit palkkaa: ~g~$%s~s~', ['received_help'] = 'sinä vastaanotit valtion tukea: ~g~$%s~s~', @@ -73,6 +77,7 @@ Locales['fi'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/fr.lua b/locales/fr.lua index 2e134fe4..6a984c9b 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -40,6 +40,10 @@ Locales['fr'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + -- Salary related ['received_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', ['received_help'] = 'vous avez reçu une aide de l\'état: ~g~$%s~s~', @@ -73,6 +77,7 @@ Locales['fr'] = { ['command_clearinventory'] = 'effacer tout les items de l\'inventaire', ['command_clearloadout'] = 'retirer toutes les armes de l\'équipement', ['command_playerid_param'] = 'spécifiez un playerid ou laissez vide pour vous-même', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/pl.lua b/locales/pl.lua index 40e7b373..37408c76 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -40,6 +40,11 @@ Locales['pl'] = { ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + -- Key mapping + ['keymap_showinventory'] = 'show Inventory', + + -- Salary related ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', @@ -72,7 +77,7 @@ Locales['pl'] = { ['command_clearinventory'] = 'usuń wszystkie przedmioty z ekwipunku', ['command_clearloadout'] = 'usuń wszystkie bronie z wyposażenia', ['command_playerid_param'] = 'id gracza lub zostaw puste dla siebie', - + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/sv.lua b/locales/sv.lua index 98605566..47bc4bde 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -40,6 +40,10 @@ Locales['sv'] = { ['threw_weapon_already'] = 'du har redan ett sådant vapen på dig', ['threw_cannot_pickup'] = 'du kan inte plocka upp det på grund av att det kommer ej få plats i ditt förråd!', ['threw_pickup_prompt'] = 'tryck ~y~E~s~ för att plocka upp', + + -- Key mapping + ['keymap_showinventory'] = 'öppna inventory', + -- Salary related ['received_salary'] = 'du har mottagit din lön på ~g~%s SEK~s~', ['received_help'] = 'du har mottagit bidrag på ~g~%s SEK~s~', @@ -73,6 +77,7 @@ Locales['sv'] = { ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '%s SEK', From a1097012538f79b06eac08408e04336e01b480d2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Jan 2020 22:54:45 +0100 Subject: [PATCH 398/672] removed xPlayer .addBank() and .removeBank() Phasing out ES code, and those functions were misleading --- server/classes/player.lua | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index f612d74c..9871426e 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -78,22 +78,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end - self.addBank = function(money) - money = ESX.Math.Round(money) - - if money > 0 then - self.player.addBank(money) - end - end - - self.removeBank = function(money) - money = ESX.Math.Round(money) - - if money > 0 then - self.player.removeBank(money) - end - end - self.displayMoney = function(money) self.player.displayMoney(money) end From cced6c955e1934cfc5ac3bb275ff73261ca8b47a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Jan 2020 22:59:26 +0100 Subject: [PATCH 399/672] Removed xPlayer .setBankBalance(), .getBank(), .setSessionVar(), .getSessionVar(), .getPermissions(), .setPermissions() --- server/classes/player.lua | 44 +++++++-------------------------------- 1 file changed, 8 insertions(+), 36 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 9871426e..391b0e96 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -1,14 +1,14 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, coords) local self = {} - self.player = player - self.accounts = accounts - self.inventory = inventory - self.job = job - self.loadout = loadout - self.name = name - self.maxWeight = Config.MaxWeight - self.coords = coords + self.player = player + self.accounts = accounts + self.inventory = inventory + self.job = job + self.loadout = loadout + self.name = name + self.maxWeight = Config.MaxWeight + self.coords = coords self.source = self.player.get('source') self.identifier = self.player.get('identifier') @@ -29,18 +29,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c return self.player.get('money') end - self.setBankBalance = function(money) - money = ESX.Math.Round(money) - - if money >= 0 then - self.player.setBankBalance(money) - end - end - - self.getBank = function() - return self.player.get('bank') - end - self.setCoords = function(coords) self.updateCoords(coords) self.triggerEvent('esx:teleport', coords) @@ -86,22 +74,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c self.player.displayBank(money) 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 From 4cc96465120a3318555369676df3d1f7cf3a45ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Eskildsen?= Date: Mon, 20 Jan 2020 06:33:17 +0100 Subject: [PATCH 400/672] Added Cash support to /giveaccountmoney Just to have a easy way to give cash to a person i have added a check to see if account == cash, just to avoide having more commands. --- server/commands.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/server/commands.lua b/server/commands.lua index cbee7f24..b2f7b34d 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -74,7 +74,9 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, local amount = tonumber(args[3]) if amount then - if xPlayer.getAccount(account) then + if account == 'cash' then + xPlayer.addMoney(amount) + else if xPlayer.getAccount(account) then xPlayer.addAccountMoney(account, amount) else TriggerClientEvent('esx:showNotification', source, _U('invalid_account')) From 392184ee2776d64af2dd9bc55d57c8e40491dcbd Mon Sep 17 00:00:00 2001 From: Michael Douglas Date: Mon, 20 Jan 2020 07:40:20 -0300 Subject: [PATCH 401/672] Improved Portuguese translation (#433) * Correcting and improving translation * remove incorrectly added capital letters * Update br.lua * fixin translates Co-authored-by: Samuel --- locales/br.lua | 118 +++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index e67cdc54..af7e0f9a 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,59 +1,60 @@ Locales['br'] = { -- Inventory - ['cash'] = 'efectivo', - ['inventory'] = 'inventario %s / %s', + ['cash'] = 'dinheiro', + ['inventory'] = 'inventário %s / %s', ['use'] = 'usar', ['give'] = 'dar', ['remove'] = 'remover', ['return'] = 'voltar', - ['give_to'] = 'give to', + ['give_to'] = 'dar para', ['amount'] = 'quantidade', - ['giveammo'] = 'Dar muniçao', - ['amountammo'] = 'quantidade de muniçao', - ['noammo'] = 'voce nao tem todas essas muniçoes!', + ['giveammo'] = 'dar munição', + ['amountammo'] = 'quantidade de munição', + ['noammo'] = 'voce não tem todas essas munições!', ['gave_item'] = 'voce deu ~y~%sx~s~ ~b~%s~s~ para ~y~%s~s~', ['received_item'] = 'voce recebeu ~y~%sx~s~ ~b~%s~s~ de ~b~%s~s~', - ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', - ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', - ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_weapon'] = 'você deu ~b~%s~s~ para ~y~%s~s~', + ['gave_weapon_ammo'] = 'você deu ~o~%sx~s~ balas para ~b~%s~s~ de ~y~%s~s~', + ['gave_weapon_withammo'] = 'você deu ~b~%s~s~ com ~o~%sx~s~ balas para ~y~%s~s~', + ['gave_weapon_hasalready'] = '~y~%s~s~ já tem um(a) ~y~%s~s~', + ['gave_weapon_noweapon'] = 'não tem essa arma ~y~%s~s~', + ['received_weapon'] = 'você recebeu ~b~%s~s~ de ~b~%s~s~', + ['received_weapon_ammo'] = 'você recebeu ~o~%sx~s~ balas para a sua(o seu) ~b~%s~s~ de ~b~%s~s~', + ['received_weapon_withammo'] = 'você recebeu ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ tentou lhe dar uma ~y~%s~s~, mas você já tem um(a)', + ['received_weapon_noweapon'] = '~b~%s~s~ tentou lhe dar munição para ~y~%s~s~, mas você não tem um(a)', ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', ['received_money'] = 'voce recebeu ~g~$%s~s~ de ~b~%s~s~', ['gave_account_money'] = 'voce deu ~g~$%s~s~ (%s) para ~y~%s~s~', ['received_account_money'] = 'voce recebeu ~g~$%s~s~ (%s) de ~b~%s~s~', - ['amount_invalid'] = 'quantidade invalida', - ['players_nearby'] = 'nenhum jogador por perto', - ['ex_inv_lim'] = 'acao nao e possivel, excedendo o limite de estoque para ~y~%s~s~', - ['imp_invalid_quantity'] = 'acao impossivel, quantidade invalida', - ['imp_invalid_amount'] = 'acao impossivel, valor invalido', - ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', - ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', - ['threw_weapon_already'] = 'you already carry the same weapon', - ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', - ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + + ['amount_invalid'] = 'quantidade inválida', + ['players_nearby'] = 'nenhum cidadão por perto', + ['ex_inv_lim'] = 'ação não e possivel, excedendo o limite de estoque para ~y~%s~s~', + ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', + ['imp_invalid_amount'] = 'ação impossível, valor invalido', + ['threw_standard'] = 'você jogou ~y~%sx~s~ ~b~%s~s~', + ['threw_money'] = 'você jogou ~g~$%s~s~ ~b~cash~s~', + ['threw_account'] = 'você jogou ~g~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'você jogou ~b~%s~s~', + ['threw_weapon_ammo'] = 'você jogou ~b~%s~s~ com ~o~%sx~s~ balas', + ['threw_weapon_already'] = 'você já esta com essa arma', + ['threw_cannot_pickup'] = 'você não pode pegar porque seu inventário está cheio!', + ['threw_pickup_prompt'] = 'pressione ~y~E~s~ para pegar', -- Key mapping ['keymap_showinventory'] = 'show Inventory', -- Salary related - ['received_salary'] = 'voce recebeu seu salario: ~g~$%s~s~ ', + ['received_salary'] = 'voce recebeu seu salário: ~g~$%s~s~ ', ['received_help'] = 'voce recebeu seu cheque de bem-estar: ~g~$%s~s~ ', - ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salario', + ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salário', ['received_paycheck'] = 'recebeu dinheiro', ['bank'] = 'banco', ['black_money'] = 'dinheiro sujo', - ['act_imp'] = 'acao impossivel', - ['in_vehicle'] = 'voce nao pode dar nada para alguem no veiculo', + ['act_imp'] = 'ação impossível', + ['in_vehicle'] = 'voce não pode dar nada para alguem no veículo', -- Commands ['setjob'] = 'atribuir um trabalho a um usuario', @@ -62,8 +63,8 @@ Locales['br'] = { ['setjob_param3'] = 'o nivel de emprego', ['spawn_car'] = 'spawn um carro', ['spawn_car_param'] = 'nome do carro', - ['delete_vehicle'] = 'excluir Veiculo', - ['invalid_account'] = 'conta invalida', + ['delete_vehicle'] = 'excluir veículo', + ['invalid_account'] = 'conta inválida', ['account'] = 'conta', ['giveaccountmoney'] = 'dar dinheiro da conta', ['invalid_item'] = 'item invalido', @@ -71,12 +72,13 @@ Locales['br'] = { ['giveitem'] = 'dar item', ['weapon'] = 'arma', ['giveweapon'] = 'dar arma', - ['disconnect'] = 'disconnect from the server', - ['chat_clear'] = 'clear the chat', - ['chat_clear_all'] = 'clear the chat for everyone', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + + ['disconnect'] = 'desconectar do servidor', + ['chat_clear'] = 'limpar o chat', + ['chat_clear_all'] = 'limpar o chat para todos', + ['command_clearinventory'] = 'remover todos os itens do inventário', + ['command_clearloadout'] = 'remova todas as armas do carregamento', + ['command_playerid_param'] = 'especifique playerId ou deixe em branco para si mesmo', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', @@ -95,16 +97,16 @@ Locales['br'] = { ['weapon_pistol50'] = 'pistola .50', ['weapon_microsmg'] = 'micro smg', ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'assault smg', - ['weapon_assaultrifle'] = 'assault rifle', - ['weapon_carbinerifle'] = 'carbine rifle', - ['weapon_advancedrifle'] = 'advanced rifle', + ['weapon_assaultsmg'] = 'smg de assalto', + ['weapon_assaultrifle'] = 'rifle de assalto', + ['weapon_carbinerifle'] = 'carabina rifle', + ['weapon_advancedrifle'] = 'rifle avançado', ['weapon_mg'] = 'mg', - ['weapon_combatmg'] = 'combat mg', + ['weapon_combatmg'] = 'combate mg', ['weapon_pumpshotgun'] = 'espingarda', - ['weapon_sawnoffshotgun'] = 'sawed off shotgun', - ['weapon_assaultshotgun'] = 'assault shotgun', - ['weapon_bullpupshotgun'] = 'bullpup shotgun', + ['weapon_sawnoffshotgun'] = 'espingarda serrada', + ['weapon_assaultshotgun'] = 'espingarda de assalto', + ['weapon_bullpupshotgun'] = 'espingarda de bullpup', ['weapon_stungun'] = 'arma de choque', ['weapon_sniperrifle'] = 'sniper rifle', ['weapon_heavysniper'] = 'heavy sniper', @@ -144,7 +146,7 @@ Locales['br'] = { ['weapon_knuckle'] = 'soco ingles', ['weapon_hatchet'] = 'machado', ['weapon_railgun'] = 'railgun', - ['weapon_machete'] = 'facao', + ['weapon_machete'] = 'facão', ['weapon_machinepistol'] = 'machine pistol', ['weapon_switchblade'] = 'canivete', ['weapon_revolver'] = 'heavy revolver', @@ -160,18 +162,18 @@ Locales['br'] = { ['weapon_flashlight'] = 'laterna', ['gadget_nightvision'] = 'visao noturna', ['gadget_parachute'] = 'paraquedas', - ['weapon_flare'] = 'Flare', + ['weapon_flare'] = 'flare', ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', + ['component_clip_default'] = 'aderência padrão', + ['component_clip_extended'] = 'aderência prolongada', ['component_clip_drum'] = 'drum Magazine', ['component_clip_box'] = 'box Magazine', - ['component_flashlight'] = 'flashlight', - ['component_scope'] = 'scope', - ['component_scope_advanced'] = 'advanced Scope', - ['component_suppressor'] = 'suppressor', + ['component_flashlight'] = 'lanterna', + ['component_scope'] = 'mira', + ['component_scope_advanced'] = 'mira avançada', + ['component_suppressor'] = 'supressor', ['component_grip'] = 'grip', - ['component_luxary_finish'] = 'luxary Weapon Finish', + ['component_luxary_finish'] = 'acabamento de arma de luxo', } From 17b19893c95f4255d9762b765928a6e5e15a474d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 Jan 2020 13:21:13 +0100 Subject: [PATCH 402/672] Fixed benzon typo --- server/commands.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/commands.lua b/server/commands.lua index b2f7b34d..b57a23bf 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -76,7 +76,7 @@ TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, if amount then if account == 'cash' then xPlayer.addMoney(amount) - else if xPlayer.getAccount(account) then + elseif xPlayer.getAccount(account) then xPlayer.addAccountMoney(account, amount) else TriggerClientEvent('esx:showNotification', source, _U('invalid_account')) From cd1ce6a84954c58e443f5224841d5f280799a180 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 Jan 2020 14:33:24 +0100 Subject: [PATCH 403/672] Don't parse item object to client, added weapon component notifications (more see desc) - Removed xPlayer .displayBank() - Fixed issues with giving weapon using commands - Modified ESX.UI.ShowInventoryItemNotification() to take string instead of table - Minor adjustments and variable renames - Fixed lower case weapons not droppable - Removed /disconnect command becasue fivem implemented their own --- client/main.lua | 22 +++++--- html/js/app.js | 12 +++-- server/classes/player.lua | 108 +++++++++++++++++++++----------------- server/commands.lua | 26 ++++----- server/main.lua | 2 + 5 files changed, 93 insertions(+), 77 deletions(-) diff --git a/client/main.lua b/client/main.lua index 18d0ad43..489d4ae8 100644 --- a/client/main.lua +++ b/client/main.lua @@ -124,15 +124,18 @@ AddEventHandler('es:activateMoney', function(money) end) RegisterNetEvent('esx:addInventoryItem') -AddEventHandler('esx:addInventoryItem', function(item, count) +AddEventHandler('esx:addInventoryItem', function(item, count, showNotification) for k,v in ipairs(ESX.PlayerData.inventory) do - if v.name == item.name then - ESX.PlayerData.inventory[k] = item + if v.name == item then + ESX.UI.ShowInventoryItemNotification(true, v.label, count - v.count) + ESX.PlayerData.inventory[k].count = count break end end - ESX.UI.ShowInventoryItemNotification(true, item, count) + if showNotification then + ESX.UI.ShowInventoryItemNotification(true, item, count) + end if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() @@ -140,15 +143,18 @@ AddEventHandler('esx:addInventoryItem', function(item, count) end) RegisterNetEvent('esx:removeInventoryItem') -AddEventHandler('esx:removeInventoryItem', function(item, count) +AddEventHandler('esx:removeInventoryItem', function(item, count, showNotification) for k,v in ipairs(ESX.PlayerData.inventory) do - if v.name == item.name then - ESX.PlayerData.inventory[k] = item + if v.name == item then + ESX.UI.ShowInventoryItemNotification(false, v.label, v.count - count) + ESX.PlayerData.inventory[k].count = count break end end - ESX.UI.ShowInventoryItemNotification(false, item, count) + if showNotification then + ESX.UI.ShowInventoryItemNotification(false, item, count) + end if ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then ESX.ShowInventory() diff --git a/html/js/app.js b/html/js/app.js index 95308dc6..7705334c 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -22,7 +22,6 @@ }; 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; @@ -51,7 +50,7 @@ } }; - ESX.inventoryNotification = function (add, item, count) { + ESX.inventoryNotification = function (add, label, count) { let notif = ''; if (add) { @@ -60,10 +59,13 @@ notif += '-'; } - notif += count + ' ' + item.label; + if (count) { + notif += count + ' ' + label; + } else { + notif += ' ' + label; + } let elem = $('
' + notif + '
'); - $('#inventory_notifications').append(elem); $(elem).delay(3000).fadeOut(1000, function () { @@ -105,4 +107,4 @@ }); }; -})(); \ No newline at end of file +})(); diff --git a/server/classes/player.lua b/server/classes/player.lua index 391b0e96..3b931af8 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -70,10 +70,6 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c self.player.displayMoney(money) end - self.displayBank = function(money) - self.player.displayBank(money) - end - self.getIdentifier = function() return self.player.getIdentifier() end @@ -97,8 +93,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c self.getAccounts = function() local accounts = {} - for k,v in ipairs(Config.Accounts) do - if v == 'bank' then + for k,account in ipairs(Config.Accounts) do + if account == 'bank' then table.insert(accounts, { name = 'bank', money = self.get('bank'), @@ -106,8 +102,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c }) else for k2,v2 in ipairs(self.accounts) do - if v2.name == v then + if v2.name == account then table.insert(accounts, v2) + break end end end @@ -116,8 +113,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c return accounts end - self.getAccount = function(a) - if a == 'bank' then + self.getAccount = function(account) + if account == 'bank' then return { name = 'bank', money = self.get('bank'), @@ -126,7 +123,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end for k,v in ipairs(self.accounts) do - if v.name == a then + if v.name == account then return v end end @@ -192,9 +189,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end - self.setAccountMoney = function(acc, money) + self.setAccountMoney = function(accountName, money) if money >= 0 then - local account = self.getAccount(acc) + local account = self.getAccount(accountName) if account then local prevMoney = account.money @@ -202,7 +199,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c account.money = newMoney - if acc == 'bank' then + if accountName == 'bank' then self.set('bank', newMoney) end @@ -211,15 +208,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end - self.addAccountMoney = function(acc, money) + self.addAccountMoney = function(accountName, money) if money > 0 then - local account = self.getAccount(acc) + local account = self.getAccount(accountName) if account then local newMoney = account.money + ESX.Math.Round(money) account.money = newMoney - if acc == 'bank' then + if accountName == 'bank' then self.set('bank', newMoney) end @@ -228,15 +225,15 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end - self.removeAccountMoney = function(acc, money) + self.removeAccountMoney = function(accountName, money) if money > 0 then - local account = self.getAccount(acc) + local account = self.getAccount(accountName) if account then local newMoney = account.money - ESX.Math.Round(money) account.money = newMoney - if acc == 'bank' then + if accountName == 'bank' then self.set('bank', newMoney) end @@ -259,11 +256,13 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c local item = self.getInventoryItem(name) if item then - local newCount = item.count + count - item.count = newCount + count = ESX.Math.Round(count) - TriggerEvent('esx:onAddInventoryItem', self.source, item, count) - self.triggerEvent('esx:addInventoryItem', item, count) + local newCount = item.count + count + item.count = newCount + + TriggerEvent('esx:onAddInventoryItem', self.source, item.name, item.count) + self.triggerEvent('esx:addInventoryItem', item.name, item.count) end end @@ -271,13 +270,14 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c local item = self.getInventoryItem(name) if item then + count = ESX.Math.Round(count) local newCount = item.count - count if newCount >= 0 then item.count = newCount - TriggerEvent('esx:onRemoveInventoryItem', self.source, item, count) - self.triggerEvent('esx:removeInventoryItem', item, count) + TriggerEvent('esx:onRemoveInventoryItem', self.source, item.name, item.count) + self.triggerEvent('esx:removeInventoryItem', item.name, item.count) end end end @@ -286,15 +286,12 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c local item = self.getInventoryItem(name) if item and count >= 0 then - local oldCount = item.count - item.count = count + count = ESX.Math.Round(count) - if oldCount > item.count then - TriggerEvent('esx:onRemoveInventoryItem', self.source, item, oldCount - item.count) - self.triggerEvent('esx:removeInventoryItem', item, oldCount - item.count) + if count > item.count then + self.addInventoryItem(item.name, count - item.count) else - TriggerEvent('esx:onAddInventoryItem', self.source, item, item.count - oldCount) - self.triggerEvent('esx:addInventoryItem', item, item.count - oldCount) + self.removeInventoryItem(item.name, item.count - count) end end end @@ -351,15 +348,16 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c self.job.grade_label = gradeObject.label self.job.grade_salary = gradeObject.salary - self.job.skin_male = {} - self.job.skin_female = {} - if gradeObject.skin_male then self.job.skin_male = json.decode(gradeObject.skin_male) + else + self.job.skin_male = {} end if gradeObject.skin_female then self.job.skin_female = json.decode(gradeObject.skin_female) + else + self.job.skin_female = {} end TriggerEvent('esx:setJob', self.source, self.job, lastJob) @@ -370,9 +368,9 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end self.addWeapon = function(weaponName, ammo) - local weaponLabel = ESX.GetWeaponLabel(weaponName) - if not self.hasWeapon(weaponName) then + local weaponLabel = ESX.GetWeaponLabel(weaponName) + table.insert(self.loadout, { name = weaponName, ammo = ammo, @@ -381,7 +379,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c }) self.triggerEvent('esx:addWeapon', weaponName, ammo) - self.triggerEvent('esx:addInventoryItem', {label = weaponLabel}, 1) + self.triggerEvent('esx:addInventoryItem', weaponLabel, false, true) end end @@ -389,9 +387,14 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then - if not self.hasWeaponComponent(weaponName, weaponComponent) then - table.insert(self.loadout[loadoutNum].components, weaponComponent) - self.triggerEvent('esx:addWeaponComponent', weaponName, weaponComponent) + local component = ESX.GetWeaponComponent(weaponName, weaponComponent) + + if component then + if not self.hasWeaponComponent(weaponName, weaponComponent) then + table.insert(self.loadout[loadoutNum].components, weaponComponent) + self.triggerEvent('esx:addWeaponComponent', weaponName, weaponComponent) + self.triggerEvent('esx:addInventoryItem', component.label, false, true) + end end end end @@ -413,7 +416,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c weaponLabel = v.label for k2,v2 in ipairs(v.components) do - self.triggerEvent('esx:removeWeaponComponent', weaponName, v2) + self.removeWeaponComponent(weaponName, v2) end table.remove(self.loadout, k) @@ -423,7 +426,7 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c if weaponLabel then self.triggerEvent('esx:removeWeapon', weaponName, ammo) - self.triggerEvent('esx:removeInventoryItem', {label = weaponLabel}, 1) + self.triggerEvent('esx:removeInventoryItem', weaponLabel, false, true) end end @@ -431,14 +434,21 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c local loadoutNum, weapon = self.getWeapon(weaponName) if weapon then - for k,v in ipairs(self.loadout[loadoutNum].components) do - if v.name == weaponComponent then - table.remove(self.loadout[loadoutNum].components, k) - break + local component = ESX.GetWeaponComponent(weaponName, weaponComponent) + + if component then + if self.hasWeaponComponent(weaponName, weaponComponent) then + for k,v in ipairs(self.loadout[loadoutNum].components) do + if v.name == weaponComponent then + table.remove(self.loadout[loadoutNum].components, k) + break + end + end + + self.triggerEvent('esx:removeWeaponComponent', weaponName, weaponComponent) + self.triggerEvent('esx:removeInventoryItem', component.label, false, true) end end - - self.triggerEvent('esx:removeWeaponComponent', weaponName, weaponComponent) end end diff --git a/server/commands.lua b/server/commands.lua index b57a23bf..90c50375 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -129,6 +129,8 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, local weaponName = args[2] or 'unknown' if ESX.GetWeapon(weaponName) then + weaponName = string.upper(weaponName) + if xPlayer.hasWeapon(weaponName) then TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon.' } }) else @@ -152,19 +154,19 @@ TriggerEvent('es:addGroupCommand', 'giveweaponcomponent', 'admin', function(sour local xPlayer = ESX.GetPlayerFromId(args[1]) if xPlayer then - local weapon = args[2] or 'unknown' + local weaponName = args[2] or 'unknown' - if ESX.GetWeapon(weapon) then - weapon = string.upper(weapon) + if ESX.GetWeapon(weaponName) then + weaponName = string.upper(weaponName) - if xPlayer.hasWeapon(weapon) then - local component = ESX.GetWeaponComponent(weapon, args[3] or 'unknown') + if xPlayer.hasWeapon(weaponName) then + local component = ESX.GetWeaponComponent(weaponName, args[3] or 'unknown') if component then - if xPlayer.hasWeaponComponent(weapon, args[3]) then + if xPlayer.hasWeaponComponent(weaponName, args[3]) then TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon component.' } }) else - xPlayer.addWeaponComponent(weapon, args[3]) + xPlayer.addWeaponComponent(weaponName, args[3]) end else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon component.' } }) @@ -182,20 +184,14 @@ end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = 'Give weapon component', params = { {name = 'playerId', help = _U('id_param')}, - {name = 'weapon', help = _U('weapon')}, - {name = 'component', help = 'weapon component'} + {name = 'weaponName', help = _U('weapon')}, + {name = 'componentName', help = 'weapon component'} }}) TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) DropPlayer(source, 'You have been disconnected') end, function(source, args, user) TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end) - -TriggerEvent('es:addGroupCommand', 'disconnect', 'admin', function(source, args, user) - DropPlayer(source, 'You have been disconnected') -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) end, {help = _U('disconnect')}) TriggerEvent('es:addGroupCommand', 'clear', 'user', function(source, args, user) diff --git a/server/main.lua b/server/main.lua index 78086ea5..16047c86 100644 --- a/server/main.lua +++ b/server/main.lua @@ -373,6 +373,8 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) end end elseif type == 'item_weapon' then + itemName = string.upper(itemName) + if xPlayer.hasWeapon(itemName) then local weaponNum, weapon = xPlayer.getWeapon(itemName) xPlayer.removeWeapon(itemName) From 74ab98d7d7649e27cf1db0f26023976bec38edfb Mon Sep 17 00:00:00 2001 From: Viktor <35453587+LifeGoal@users.noreply.github.com> Date: Mon, 20 Jan 2020 19:26:21 +0100 Subject: [PATCH 404/672] Fixed SQL problem --- es_extended.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/es_extended.sql b/es_extended.sql index 399847e9..253af3b9 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,7 +1,7 @@ USE `essentialmode`; ALTER TABLE `users` - ADD COLUMN `skin` LONGTEXT NULL AFTER `name`, + ADD COLUMN `skin` LONGTEXT NULL, ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, From 6ed2e1c4e7c54ce5fc979d815d35bda6241253f1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 1 Feb 2020 13:02:23 +0100 Subject: [PATCH 405/672] Minor changes --- client/main.lua | 2 +- config.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 489d4ae8..17a3db65 100644 --- a/client/main.lua +++ b/client/main.lua @@ -406,7 +406,7 @@ Citizen.CreateThread(function() local weaponHash = GetHashKey(weaponName) local weaponComponents = {} - if HasPedGotWeapon(playerPed, weaponHash, false) and weaponName ~= 'WEAPON_UNARMED' then + if HasPedGotWeapon(playerPed, weaponHash, false) then local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) for k2,v2 in ipairs(v.components) do diff --git a/config.lua b/config.lua index 5dfee80f..d3bf0edb 100644 --- a/config.lua +++ b/config.lua @@ -1,8 +1,8 @@ Config = {} Config.Locale = 'fr' -Config.Accounts = { 'bank', 'black_money' } -Config.AccountLabels = { bank = _U('bank'), black_money = _U('black_money') } +Config.Accounts = {'bank', 'black_money'} +Config.AccountLabels = {bank = _U('bank'), black_money = _U('black_money')} Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.DisableWantedLevel = true From e25f5dee2ec828fa1e80118087813240f1477093 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 11:37:47 +0100 Subject: [PATCH 406/672] Temp code revert for loadout updating, fixes ammo sync --- client/main.lua | 1 + server/main.lua | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/client/main.lua b/client/main.lua index 17a3db65..39bdf327 100644 --- a/client/main.lua +++ b/client/main.lua @@ -438,6 +438,7 @@ Citizen.CreateThread(function() if loadoutChanged and isLoadoutLoaded then ESX.PlayerData.loadout = loadout + TriggerServerEvent('esx:updateLoadout', loadout) end end end) diff --git a/server/main.lua b/server/main.lua index 16047c86..329fc379 100644 --- a/server/main.lua +++ b/server/main.lua @@ -236,6 +236,12 @@ AddEventHandler('esx:updateCoords', function(coords) end end) +RegisterNetEvent('esx:updateLoadout') +AddEventHandler('esx:updateLoadout', function(loadout) + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.loadout = loadout +end) + RegisterNetEvent('esx:giveInventoryItem') AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCount) local playerId = source From f11e97e0a5c64573e3fe525e0dd9eb9084678c08 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 11:50:59 +0100 Subject: [PATCH 407/672] Improved ammo label handling, extended weapon configuration file with ammo hash and label --- client/functions.lua | 62 +++++++++-------- config.weapons.lua | 157 +++++++++++++++++++++++++------------------ locales/br.lua | 34 +++++++--- locales/cs.lua | 33 ++++++--- locales/de.lua | 33 ++++++--- locales/en.lua | 33 ++++++--- locales/fi.lua | 33 ++++++--- locales/fr.lua | 33 ++++++--- locales/pl.lua | 33 ++++++--- locales/sv.lua | 37 ++++++---- server/commands.lua | 6 +- server/main.lua | 42 +++++++----- 12 files changed, 345 insertions(+), 191 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index ef8b71cc..f15797ed 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -869,12 +869,12 @@ ESX.ShowInventory = function() local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(ESX.PlayerData.money)) table.insert(elements, { - label = ('%s: %s'):format(_U('cash'), formattedMoney), - count = ESX.PlayerData.money, - type = 'item_money', - value = 'money', - usable = false, - rare = false, + label = ('%s: %s'):format(_U('cash'), formattedMoney), + count = ESX.PlayerData.money, + type = 'item_money', + value = 'money', + usable = false, + rare = false, canRemove = true }) end @@ -885,12 +885,12 @@ ESX.ShowInventory = function() local canDrop = v.name ~= 'bank' table.insert(elements, { - label = ('%s: %s'):format(v.label, formattedMoney), - count = v.money, - type = 'item_account', - value = v.name, - usable = false, - rare = false, + label = ('%s: %s'):format(v.label, formattedMoney), + count = v.money, + type = 'item_account', + value = v.name, + usable = false, + rare = false, canRemove = canDrop }) end @@ -899,13 +899,14 @@ ESX.ShowInventory = function() for k,v in ipairs(ESX.PlayerData.inventory) do if v.count > 0 then currentWeight = currentWeight + (v.weight * v.count) + table.insert(elements, { - label = ('%s x%s'):format(v.label, v.count), - count = v.count, - type = 'item_standard', - value = v.name, - usable = v.usable, - rare = v.rare, + label = ('%s x%s'):format(v.label, v.count), + count = v.count, + type = 'item_standard', + value = v.name, + usable = v.usable, + rare = v.rare, canRemove = v.canRemove }) end @@ -915,16 +916,23 @@ ESX.ShowInventory = function() local weaponHash = GetHashKey(v.name) if HasPedGotWeapon(playerPed, weaponHash, false) then - local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + local ammo, label = GetAmmoInPedWeapon(playerPed, weaponHash) + + if v.ammo then + label = ('%s - %s %s'):format(v.label, ammo, v.ammo.label) + else + label = v.label + end table.insert(elements, { - label = ('%s [%s]'):format(v.label, ammo), - count = 1, - type = 'item_weapon', - value = v.name, - ammo = ammo, - usable = false, - rare = false, + label = label, + count = 1, + type = 'item_weapon', + value = v.name, + usable = false, + rare = false, + ammo = ammo, + canGiveAmmo = (v.ammo ~= nil), canRemove = true }) end @@ -953,7 +961,7 @@ ESX.ShowInventory = function() table.insert(elements, {label = _U('remove'), action = 'remove', type = data.current.type, value = data.current.value}) end - if data.current.type == 'item_weapon' and data.current.ammo > 0 and player ~= -1 and distance <= 3.0 then + if data.current.type == 'item_weapon' and data.current.canGiveAmmo and data.current.ammo > 0 and player ~= -1 and distance <= 3.0 then table.insert(elements, {label = _U('giveammo'), action = 'give_ammo', type = data.current.type, value = data.current.value}) end diff --git a/config.weapons.lua b/config.weapons.lua index 8dd7676c..037062fc 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -1,14 +1,8 @@ Config.Weapons = { - {name = 'WEAPON_KNIFE', label = _U('weapon_knife'), components = {}}, - {name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick'), components = {}}, - {name = 'WEAPON_HAMMER', label = _U('weapon_hammer'), components = {}}, - {name = 'WEAPON_BAT', label = _U('weapon_bat'), components = {}}, - {name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub'), components = {}}, - {name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar'), components = {}}, - { name = 'WEAPON_PISTOL', label = _U('weapon_pistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_02')}, @@ -21,6 +15,7 @@ Config.Weapons = { { name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_02')}, @@ -33,6 +28,7 @@ Config.Weapons = { { name = 'WEAPON_APPISTOL', label = _U('weapon_appistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_02')}, @@ -45,6 +41,7 @@ Config.Weapons = { { name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_02')}, @@ -54,11 +51,10 @@ Config.Weapons = { } }, - {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver'), components = {}}, - { name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_02')}, @@ -69,6 +65,7 @@ Config.Weapons = { { name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_02')}, @@ -81,6 +78,7 @@ Config.Weapons = { { name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_02')}, @@ -89,21 +87,25 @@ Config.Weapons = { }, { - name = 'WEAPON_MICROSMG', - label = _U('weapon_microsmg'), + name = 'WEAPON_MACHINEPISTOL', + label = _U('weapon_machinepistol'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, components = { - {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_01')}, - {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_02')}, - {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, - {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO')}, - {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, - {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MICROSMG_VARMOD_LUXE')} + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_02')}, + {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_03')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')} } }, + {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, + {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, + {name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, + { name = 'WEAPON_SMG', label = _U('weapon_smg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SMG_CLIP_02')}, @@ -118,6 +120,7 @@ Config.Weapons = { { name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_02')}, @@ -128,29 +131,34 @@ Config.Weapons = { } }, + { + name = 'WEAPON_MICROSMG', + label = _U('weapon_microsmg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + components = { + {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_01')}, + {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_02')}, + {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_PI_FLSH')}, + {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_MACRO')}, + {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, + {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_MICROSMG_VARMOD_LUXE')} + } + }, + { name = 'WEAPON_MINISMG', label = _U('weapon_minismg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_02')} } }, - { - name = 'WEAPON_MACHINEPISTOL', - label = _U('weapon_machinepistol'), - components = { - {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_01')}, - {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_02')}, - {name = 'clip_drum', label = _U('component_clip_drum'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_03')}, - {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_PI_SUPP')} - } - }, - { name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_02')}, @@ -160,10 +168,11 @@ Config.Weapons = { {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_SMALL')} } }, - + { name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun'), + ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, components = { {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_SR_SUPP')}, @@ -174,6 +183,7 @@ Config.Weapons = { { name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun'), + ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, components = { {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SAWNOFFSHOTGUN_VARMOD_LUXE')} } @@ -182,6 +192,7 @@ Config.Weapons = { { name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun'), + ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_02')}, @@ -194,6 +205,7 @@ Config.Weapons = { { name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun'), + ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, components = { {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, @@ -204,6 +216,7 @@ Config.Weapons = { { name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun'), + ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_02')}, @@ -214,9 +227,14 @@ Config.Weapons = { } }, + {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun'), components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, + {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun'), components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, + {name = 'WEAPON_MUSKET', label = _U('weapon_musket'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SHOTGUN')}}, + { name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_02')}, @@ -232,6 +250,7 @@ Config.Weapons = { { name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_02')}, @@ -247,6 +266,7 @@ Config.Weapons = { { name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_02')}, @@ -260,6 +280,7 @@ Config.Weapons = { { name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_02')}, @@ -275,6 +296,7 @@ Config.Weapons = { { name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_02')}, @@ -289,6 +311,7 @@ Config.Weapons = { { name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_02')}, @@ -299,6 +322,7 @@ Config.Weapons = { { name = 'WEAPON_MG', label = _U('weapon_mg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MG_CLIP_02')}, @@ -310,6 +334,7 @@ Config.Weapons = { { name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_02')}, @@ -322,6 +347,7 @@ Config.Weapons = { { name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_02')}, @@ -331,6 +357,7 @@ Config.Weapons = { { name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, components = { {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')}, @@ -342,6 +369,7 @@ Config.Weapons = { { name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, components = { {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')} @@ -351,6 +379,7 @@ Config.Weapons = { { name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle'), + ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_02')}, @@ -362,46 +391,44 @@ Config.Weapons = { } }, - {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher'), components = {}}, - {name = 'WEAPON_RPG', label = _U('weapon_rpg'), components = {}}, - {name = 'WEAPON_STINGER', label = _U('weapon_stinger'), components = {}}, - {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun'), components = {}}, - {name = 'WEAPON_GRENADE', label = _U('weapon_grenade'), components = {}}, - {name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb'), components = {}}, - {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade'), components = {}}, - {name = 'WEAPON_BZGAS', label = _U('weapon_bzgas'), components = {}}, - {name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov'), components = {}}, - {name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher'), components = {}}, - {name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan'), components = {}}, - {name = 'WEAPON_DIGISCANNER', label = _U('weapon_digiscanner'), components = {}}, - {name = 'WEAPON_BALL', label = _U('weapon_ball'), components = {}}, - {name = 'WEAPON_BOTTLE', label = _U('weapon_bottle'), components = {}}, - {name = 'WEAPON_DAGGER', label = _U('weapon_dagger'), components = {}}, - {name = 'WEAPON_FIREWORK', label = _U('weapon_firework'), components = {}}, - {name = 'WEAPON_MUSKET', label = _U('weapon_musket'), components = {}}, + {name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher'), components = {}, ammo = {label = _U('ammo_charge'), hash = GetHashKey('AMMO_FIREEXTINGUISHER')}}, + {name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan'), components = {}, ammo = {label = _U('ammo_petrol'), hash = GetHashKey('AMMO_PETROLCAN')}}, + {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MINIGUN')}}, + {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RAILGUN')}}, {name = 'WEAPON_STUNGUN', label = _U('weapon_stungun'), components = {}}, - {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher'), components = {}}, - {name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine'), components = {}}, - {name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball'), components = {}}, - {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun'), components = {}}, - {name = 'WEAPON_GARBAGEBAG', label = _U('weapon_garbagebag'), components = {}}, - {name = 'WEAPON_HANDCUFFS', label = _U('weapon_handcuffs'), components = {}}, - {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol'), components = {}}, + {name = 'WEAPON_FIREWORK', label = _U('weapon_firework'), components = {}, ammo = {label = _U('ammo_firework'), hash = GetHashKey('AMMO_FIREWORK')}}, + {name = 'WEAPON_RPG', label = _U('weapon_rpg'), components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_RPG')}}, + {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher'), components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_HOMINGLAUNCHER')}}, + {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher'), components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, + {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher'), components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, + {name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight'), components = {}}, + {name = 'GADGET_PARACHUTE', label = _U('gadget_parachute'), components = {}}, + {name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle'), components = {}}, {name = 'WEAPON_HATCHET', label = _U('weapon_hatchet'), components = {}}, - {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun'), components = {}}, {name = 'WEAPON_MACHETE', label = _U('weapon_machete'), components = {}}, {name = 'WEAPON_SWITCHBLADE', label = _U('weapon_switchblade'), components = {}}, - {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun'), components = {}}, - {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun'), components = {}}, - {name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe'), components = {}}, - {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher'), components = {}}, - {name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb'), components = {}}, + {name = 'WEAPON_BOTTLE', label = _U('weapon_bottle'), components = {}}, + {name = 'WEAPON_DAGGER', label = _U('weapon_dagger'), components = {}}, {name = 'WEAPON_POOLCUE', label = _U('weapon_poolcue'), components = {}}, {name = 'WEAPON_WRENCH', label = _U('weapon_wrench'), components = {}}, - {name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight'), components = {}}, - {name = 'GADGET_NIGHTVISION', label = _U('gadget_nightvision'), components = {}}, - {name = 'GADGET_PARACHUTE', label = _U('gadget_parachute'), components = {}}, - {name = 'WEAPON_FLARE', label = _U('weapon_flare'), components = {}}, - {name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction'), components = {}} -} \ No newline at end of file + {name = 'WEAPON_BATTLEAXE', label = _U('weapon_battleaxe'), components = {}}, + {name = 'WEAPON_KNIFE', label = _U('weapon_knife'), components = {}}, + {name = 'WEAPON_NIGHTSTICK', label = _U('weapon_nightstick'), components = {}}, + {name = 'WEAPON_HAMMER', label = _U('weapon_hammer'), components = {}}, + {name = 'WEAPON_BAT', label = _U('weapon_bat'), components = {}}, + {name = 'WEAPON_GOLFCLUB', label = _U('weapon_golfclub'), components = {}}, + {name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar'), components = {}}, + + {name = 'WEAPON_GRENADE', label = _U('weapon_grenade'), components = {}, ammo = {label = _U('ammo_grenade'), hash = GetHashKey('AMMO_GRENADE')}}, + {name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb'), components = {}, ammo = {label = _U('ammo_stickybomb'), hash = GetHashKey('AMMO_STICKYBOMB')}}, + {name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb'), components = {}, ammo = {label = _U('ammo_pipebomb'), hash = GetHashKey('AMMO_PIPEBOMB')}}, + {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade'), components = {}, ammo = {label = _U('ammo_smokebomb'), hash = GetHashKey('AMMO_SMOKEGRENADE')}}, + {name = 'WEAPON_BZGAS', label = _U('weapon_bzgas'), components = {}, ammo = {label = _U('ammo_bzgas'), hash = GetHashKey('AMMO_BZGAS')}}, + {name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov'), components = {}, ammo = {label = _U('ammo_molotov'), hash = GetHashKey('AMMO_MOLOTOV')}}, + {name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine'), components = {}, ammo = {label = _U('ammo_proxmine'), hash = GetHashKey('AMMO_PROXMINE')}}, + {name = 'WEAPON_BALL', label = _U('weapon_ball'), components = {}, ammo = {label = _U('ammo_ball'), hash = GetHashKey('AMMO_BALL')}}, + {name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball'), components = {}, ammo = {label = _U('ammo_snowball'), hash = GetHashKey('AMMO_SNOWBALL')}}, + {name = 'WEAPON_FLARE', label = _U('weapon_flare'), components = {}, ammo = {label = _U('ammo_flare'), hash = GetHashKey('AMMO_FLARE')}}, + {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun'), components = {}, ammo = {label = _U('ammo_flaregun'), hash = GetHashKey('AMMO_FLAREGUN')}} +} diff --git a/locales/br.lua b/locales/br.lua index af7e0f9a..7b69f877 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -14,20 +14,19 @@ Locales['br'] = { ['gave_item'] = 'voce deu ~y~%sx~s~ ~b~%s~s~ para ~y~%s~s~', ['received_item'] = 'voce recebeu ~y~%sx~s~ ~b~%s~s~ de ~b~%s~s~', ['gave_weapon'] = 'você deu ~b~%s~s~ para ~y~%s~s~', - ['gave_weapon_ammo'] = 'você deu ~o~%sx~s~ balas para ~b~%s~s~ de ~y~%s~s~', - ['gave_weapon_withammo'] = 'você deu ~b~%s~s~ com ~o~%sx~s~ balas para ~y~%s~s~', + ['gave_weapon_ammo'] = 'você deu ~o~%sx %s~s~ para ~b~%s~s~ de ~y~%s~s~', + ['gave_weapon_withammo'] = 'você deu ~b~%s~s~ com ~o~%sx %s~s~ para ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ já tem um(a) ~y~%s~s~', ['gave_weapon_noweapon'] = 'não tem essa arma ~y~%s~s~', ['received_weapon'] = 'você recebeu ~b~%s~s~ de ~b~%s~s~', - ['received_weapon_ammo'] = 'você recebeu ~o~%sx~s~ balas para a sua(o seu) ~b~%s~s~ de ~b~%s~s~', - ['received_weapon_withammo'] = 'você recebeu ~b~%s~s~ com ~o~%sx~s~ balas de ~b~%s~s~', + ['received_weapon_ammo'] = 'você recebeu ~o~%sx %s~s~ para a sua(o seu) ~b~%s~s~ de ~b~%s~s~', + ['received_weapon_withammo'] = 'você recebeu ~b~%s~s~ com ~o~%sx %s~s~ de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ tentou lhe dar uma ~y~%s~s~, mas você já tem um(a)', ['received_weapon_noweapon'] = '~b~%s~s~ tentou lhe dar munição para ~y~%s~s~, mas você não tem um(a)', ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', ['received_money'] = 'voce recebeu ~g~$%s~s~ de ~b~%s~s~', ['gave_account_money'] = 'voce deu ~g~$%s~s~ (%s) para ~y~%s~s~', ['received_account_money'] = 'voce recebeu ~g~$%s~s~ (%s) de ~b~%s~s~', - ['amount_invalid'] = 'quantidade inválida', ['players_nearby'] = 'nenhum cidadão por perto', ['ex_inv_lim'] = 'ação não e possivel, excedendo o limite de estoque para ~y~%s~s~', @@ -37,7 +36,7 @@ Locales['br'] = { ['threw_money'] = 'você jogou ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'você jogou ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'você jogou ~b~%s~s~', - ['threw_weapon_ammo'] = 'você jogou ~b~%s~s~ com ~o~%sx~s~ balas', + ['threw_weapon_ammo'] = 'você jogou ~b~%s~s~ com ~o~%sx %s~s~', ['threw_weapon_already'] = 'você já esta com essa arma', ['threw_cannot_pickup'] = 'você não pode pegar porque seu inventário está cheio!', ['threw_pickup_prompt'] = 'pressione ~y~E~s~ para pegar', @@ -112,7 +111,6 @@ Locales['br'] = { ['weapon_heavysniper'] = 'heavy sniper', ['weapon_grenadelauncher'] = 'lançador de granada', ['weapon_rpg'] = 'lançador de foguetes', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'granada', ['weapon_stickybomb'] = 'bomba pegajosa', @@ -121,7 +119,6 @@ Locales['br'] = { ['weapon_molotov'] = 'molotov', ['weapon_fireextinguisher'] = 'extintor', ['weapon_petrolcan'] = 'galao de combustivel', - ['weapon_digiscanner'] = 'digiscanner', ['weapon_ball'] = 'bola', ['weapon_snspistol'] = 'sns pistol', ['weapon_bottle'] = 'garrafa', @@ -139,8 +136,6 @@ Locales['br'] = { ['weapon_proxmine'] = 'mina de proximidade', ['weapon_snowball'] = 'bola de neve', ['weapon_flaregun'] = 'sinalizador', - ['weapon_garbagebag'] = 'saco de lixo', - ['weapon_handcuffs'] = 'algemas', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', ['weapon_knuckle'] = 'soco ingles', @@ -160,7 +155,6 @@ Locales['br'] = { ['weapon_poolcue'] = 'taco de sinuca', ['weapon_wrench'] = 'chave de cano', ['weapon_flashlight'] = 'laterna', - ['gadget_nightvision'] = 'visao noturna', ['gadget_parachute'] = 'paraquedas', ['weapon_flare'] = 'flare', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -176,4 +170,22 @@ Locales['br'] = { ['component_suppressor'] = 'supressor', ['component_grip'] = 'grip', ['component_luxary_finish'] = 'acabamento de arma de luxo', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/cs.lua b/locales/cs.lua index 7c537b59..565d764d 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -14,13 +14,13 @@ Locales['cs'] = { ['gave_item'] = 'dali jste ~y~%sx~s~ ~b~%s~s~ ~y~%s~s~', ['received_item'] = 'obdrželi jste ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx %s~s~ to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', ['gave_money'] = 'dali jste ~g~$%s~s~ ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['cs'] = { ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -111,7 +111,6 @@ Locales['cs'] = { ['weapon_heavysniper'] = 'heavy sniper', ['weapon_grenadelauncher'] = 'grenade launcher', ['weapon_rpg'] = 'rocket launcher', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'grenade', ['weapon_stickybomb'] = 'sticky bomb', @@ -120,7 +119,6 @@ Locales['cs'] = { ['weapon_molotov'] = 'molotov cocktail', ['weapon_fireextinguisher'] = 'fire extinguisher', ['weapon_petrolcan'] = 'jerrycan', - ['weapon_digiscanner'] = 'digiscanner', ['weapon_ball'] = 'ball', ['weapon_snspistol'] = 'sns pistol', ['weapon_bottle'] = 'bottle', @@ -138,8 +136,6 @@ Locales['cs'] = { ['weapon_proxmine'] = 'proximity mine', ['weapon_snowball'] = 'snow ball', ['weapon_flaregun'] = 'flaregun', - ['weapon_garbagebag'] = 'garbage bag', - ['weapon_handcuffs'] = 'handcuffs', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', ['weapon_knuckle'] = 'knuckledusters', @@ -159,7 +155,6 @@ Locales['cs'] = { ['weapon_poolcue'] = 'pool cue', ['weapon_wrench'] = 'pipe wrench', ['weapon_flashlight'] = 'flashlight', - ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'flare gun', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -175,4 +170,22 @@ Locales['cs'] = { ['component_suppressor'] = 'suppressor', ['component_grip'] = 'grip', ['component_luxary_finish'] = 'luxary Weapon Finish', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/de.lua b/locales/de.lua index 4a9a5f7f..63b4c090 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -14,13 +14,13 @@ Locales['de'] = { ['gave_item'] = 'du gibst ~y~%sx~s~ ~b~%s~s~ an ~y~%s~s~', ['received_item'] = 'du empfängst ~y~%sx~s~ ~b~%s~s~ von ~b~%s~s~', ['gave_weapon'] = 'du gibst ~b~%s~s~ an ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'du gibst ~b~%s~s~ mit ~o~%sx~s~ Schuss an ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'du gibst ~b~%s~s~ mit ~o~%sx %s~s~ an ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ hat bereits eine(n) ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', ['received_weapon'] = 'du erhälst ~b~%s~s~ von ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx~s~ Schuss von ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx %s~s~ von ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ hat versucht dir eine(n) ~y~%s~s~ zu geben, aber du hast bereits eine(n)', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', ['gave_money'] = 'du gibst ~g~$%s~s~ an ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['de'] = { ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -110,7 +110,6 @@ Locales['de'] = { ['weapon_heavysniper'] = 'Schweres Sniper', ['weapon_grenadelauncher'] = 'Granatwerfer', ['weapon_rpg'] = 'RPG', - ['weapon_stinger'] = 'Stinger', ['weapon_minigun'] = 'Minigun', ['weapon_grenade'] = 'Granate', ['weapon_stickybomb'] = 'Haftbombe', @@ -119,7 +118,6 @@ Locales['de'] = { ['weapon_molotov'] = 'Molotov Cocktail', ['weapon_fireextinguisher'] = 'Feuerlöscher', ['weapon_petrolcan'] = 'Benzinkanister', - ['weapon_digiscanner'] = 'Digiscanner', ['weapon_ball'] = 'Ball', ['weapon_snspistol'] = 'SNS Pistole', ['weapon_bottle'] = 'Flasche', @@ -137,8 +135,6 @@ Locales['de'] = { ['weapon_proxmine'] = 'Annäherungsmine', ['weapon_snowball'] = 'Schneeball', ['weapon_flaregun'] = 'Leuchtpistole', - ['weapon_garbagebag'] = 'Müllsack', - ['weapon_handcuffs'] = 'Handschellen', ['weapon_combatpdw'] = 'Kampf PDW', ['weapon_marksmanpistol'] = 'Marksman Pistole', ['weapon_knuckle'] = 'Schlagring', @@ -158,7 +154,6 @@ Locales['de'] = { ['weapon_poolcue'] = 'Kö', ['weapon_wrench'] = 'Rohrzange', ['weapon_flashlight'] = 'Taschenlampe', - ['gadget_nightvision'] = 'Nachtsichtgerät', ['gadget_parachute'] = 'Fallschirm', ['weapon_flare'] = 'Leuchtpistole', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['de'] = { ['component_suppressor'] = 'suppressor', ['component_grip'] = 'grip', ['component_luxary_finish'] = 'luxary Weapon Finish', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/en.lua b/locales/en.lua index a41b982d..a7207cad 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -14,13 +14,13 @@ Locales['en'] = { ['gave_item'] = 'you gave ~y~%sx~s~ ~b~%s~s~ to ~y~%s~s~', ['received_item'] = 'you received ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~', ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx %s~s~ to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', ['gave_money'] = 'you gave ~g~$%s~s~ to ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['en'] = { ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ %s', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -110,7 +110,6 @@ Locales['en'] = { ['weapon_heavysniper'] = 'heavy sniper', ['weapon_grenadelauncher'] = 'grenade launcher', ['weapon_rpg'] = 'rocket launcher', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'grenade', ['weapon_stickybomb'] = 'sticky bomb', @@ -119,7 +118,6 @@ Locales['en'] = { ['weapon_molotov'] = 'molotov cocktail', ['weapon_fireextinguisher'] = 'fire extinguisher', ['weapon_petrolcan'] = 'jerrycan', - ['weapon_digiscanner'] = 'digiscanner', ['weapon_ball'] = 'ball', ['weapon_snspistol'] = 'sns pistol', ['weapon_bottle'] = 'bottle', @@ -137,8 +135,6 @@ Locales['en'] = { ['weapon_proxmine'] = 'proximity mine', ['weapon_snowball'] = 'snow ball', ['weapon_flaregun'] = 'flaregun', - ['weapon_garbagebag'] = 'garbage bag', - ['weapon_handcuffs'] = 'handcuffs', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', ['weapon_knuckle'] = 'knuckledusters', @@ -158,7 +154,6 @@ Locales['en'] = { ['weapon_poolcue'] = 'pool cue', ['weapon_wrench'] = 'pipe wrench', ['weapon_flashlight'] = 'flashlight', - ['gadget_nightvision'] = 'night vision', ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'flare gun', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['en'] = { ['component_suppressor'] = 'suppressor', ['component_grip'] = 'grip', ['component_luxary_finish'] = 'luxary Weapon Finish', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/fi.lua b/locales/fi.lua index a3a32e6c..20fd8173 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -14,13 +14,13 @@ Locales['fi'] = { ['gave_item'] = 'sinä annoit ~y~%sx~s~ ~b~%s~s~ henkilölle ~y~%s~s~', ['received_item'] = 'sinä sait ~y~%sx~s~ ~b~%s~s~ henkilöltä ~b~%s~s~', ['gave_weapon'] = 'you gave ~y~1x~s~ ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx~s~ bullets for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets to ~y~%s~s~', + ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'you gave ~y~1x~s~ ~b~%s~s~ with ~o~%sx %s~s~ to ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', ['received_weapon'] = 'you received ~y~1x~s~ ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx~s~ bullets for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets from ~b~%s~s~', + ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_withammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', ['gave_money'] = 'sinä annoit ~g~$%s~s~ henkilölle ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['fi'] = { ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx~s~ bullets', + ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -110,7 +110,6 @@ Locales['fi'] = { ['weapon_heavysniper'] = 'raskas tarkkuuskivääri', ['weapon_grenadelauncher'] = 'kranaatinheitin', ['weapon_rpg'] = 'raketinheitin', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'kranaatti', ['weapon_stickybomb'] = 'tahma pommi', @@ -119,7 +118,6 @@ Locales['fi'] = { ['weapon_molotov'] = 'polttopullo', ['weapon_fireextinguisher'] = 'palosammutin', ['weapon_petrolcan'] = 'jerrykannu', - ['weapon_digiscanner'] = 'digiskanneri', ['weapon_ball'] = 'pallo', ['weapon_snspistol'] = 'pienpistooli', ['weapon_bottle'] = 'pullo', @@ -137,8 +135,6 @@ Locales['fi'] = { ['weapon_proxmine'] = 'lähellä räjähtävä miina', ['weapon_snowball'] = 'lumipallo', ['weapon_flaregun'] = 'valopyssy', - ['weapon_garbagebag'] = 'roskapussi', - ['weapon_handcuffs'] = 'käsiraudat', ['weapon_combatpdw'] = 'rynnäkkö pdw', ['weapon_marksmanpistol'] = 'marksman pistooli', ['weapon_knuckle'] = 'nyrkkirauta', @@ -158,7 +154,6 @@ Locales['fi'] = { ['weapon_poolcue'] = 'biljardimaila', ['weapon_wrench'] = 'putkipihdit', ['weapon_flashlight'] = 'taskulamppu', - ['gadget_nightvision'] = 'yökiikarit', ['gadget_parachute'] = 'laskuvarjo', ['weapon_flare'] = 'hätäraketti', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['fi'] = { ['component_suppressor'] = 'suppressor', ['component_grip'] = 'grip', ['component_luxary_finish'] = 'luxary Weapon Finish', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/fr.lua b/locales/fr.lua index 6a984c9b..eed3a2f6 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -14,13 +14,13 @@ Locales['fr'] = { ['gave_item'] = 'vous avez donné ~y~%sx~s~ ~b~%s~s~ à ~y~%s~s~', ['received_item'] = 'vous avez reçu ~y~%sx~s~ ~b~%s~s~ par ~b~%s~s~', ['gave_weapon'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ à ~y~%s~s~', - ['gave_weapon_ammo'] = 'vous avez donné ~o~%sx~s~ balles pour ~b~%s~s~ à ~y~%s~s~', - ['gave_weapon_withammo'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles à ~y~%s~s~', + ['gave_weapon_ammo'] = 'vous avez donné ~o~%sx %s~s~ pour ~b~%s~s~ à ~y~%s~s~', + ['gave_weapon_withammo'] = 'vous avez donné ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~ à ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ a déjà ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ n\'a pas cette arme', ['received_weapon'] = 'vous recevez ~y~1x~s~ ~b~%s~s~ de ~b~%s~s~', - ['received_weapon_ammo'] = 'vous avez reçu ~o~%sx~s~ balles pour votre ~b~%s~s~ de ~b~%s~s~', - ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles de ~b~%s~s~', + ['received_weapon_ammo'] = 'vous avez reçu ~o~%sx %s~s~ pour votre ~b~%s~s~ de ~b~%s~s~', + ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~ de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire', ['received_weapon_noweapon'] = '~b~%s~s~ tente de vous donner des munitions pour ~y~%s~s~, mais vous n\'en avez pas', ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['fr'] = { ['threw_money'] = 'vous avez jeté ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'vous avez jeté ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~', - ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx~s~ balles', + ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -110,7 +110,6 @@ Locales['fr'] = { ['weapon_heavysniper'] = 'fusil de sniper lourd', ['weapon_grenadelauncher'] = 'lance-grenade', ['weapon_rpg'] = 'lance-rocket', - ['weapon_stinger'] = 'lance-missile stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'grenade', ['weapon_stickybomb'] = 'bombe collante', @@ -119,7 +118,6 @@ Locales['fr'] = { ['weapon_molotov'] = 'cocktail molotov', ['weapon_fireextinguisher'] = 'extincteur', ['weapon_petrolcan'] = 'jerrican d\'essence', - ['weapon_digiscanner'] = 'digiscanner', ['weapon_ball'] = 'balle', ['weapon_snspistol'] = 'pistolet sns', ['weapon_bottle'] = 'bouteille', @@ -137,8 +135,6 @@ Locales['fr'] = { ['weapon_proxmine'] = 'mine de proximité', ['weapon_snowball'] = 'boule de neige', ['weapon_flaregun'] = 'lance fusée de détresse', - ['weapon_garbagebag'] = 'sac poubelle', - ['weapon_handcuffs'] = 'menottes', ['weapon_combatpdw'] = 'arme de défense personnelle', ['weapon_marksmanpistol'] = 'pistolet marksman', ['weapon_knuckle'] = 'poing américain', @@ -158,7 +154,6 @@ Locales['fr'] = { ['weapon_poolcue'] = 'queue de billard', ['weapon_wrench'] = 'clé', ['weapon_flashlight'] = 'lampe torche', - ['gadget_nightvision'] = 'vision nocturne', ['gadget_parachute'] = 'parachute', ['weapon_flare'] = 'fusée Détresse', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['fr'] = { ['component_suppressor'] = 'réducteur de son', ['component_grip'] = 'poignée', ['component_luxary_finish'] = 'finission de luxe', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/pl.lua b/locales/pl.lua index 37408c76..45793958 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -14,13 +14,13 @@ Locales['pl'] = { ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', ['gave_weapon'] = 'dajesz ~b~%s~s~ dla ~y~%s~s~', - ['gave_weapon_ammo'] = 'dałeś/aś ~o~%sx~s~ naboi do ~b~%s~s~ dla ~y~%s~s~', - ['gave_weapon_withammo'] = 'dałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami dla ~y~%s~s~', + ['gave_weapon_ammo'] = 'dałeś/aś ~o~%sx %s~s~ do ~b~%s~s~ dla ~y~%s~s~', + ['gave_weapon_withammo'] = 'dałeś/aś ~b~%s~s~ z ~o~%sx %s~s~ dla ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ już posiada ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ nie posiada tej broni', ['received_weapon'] = 'otrzymałeś/aś ~b~%s~s~ od ~b~%s~s~', - ['received_weapon_ammo'] = 'otrzymałeś/aś ~o~%sx~s~ naboi do twojego ~b~%s~s~ od ~b~%s~s~', - ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami od ~b~%s~s~', + ['received_weapon_ammo'] = 'otrzymałeś/aś ~o~%sx %s~s~ do twojego ~b~%s~s~ od ~b~%s~s~', + ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx %s~s~ od ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', ['received_weapon_noweapon'] = '~b~%s~s~ próbował/a przekazać ci amunicje do ~y~%s~s~, lecz nie posiadasz tej broni', ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', @@ -36,7 +36,7 @@ Locales['pl'] = { ['threw_money'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~gotówki~s~', ['threw_account'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', - ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx~s~ nabojami', + ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', @@ -110,7 +110,6 @@ Locales['pl'] = { ['weapon_heavysniper'] = 'ciężki karabin snajperski', ['weapon_grenadelauncher'] = 'granatnik', ['weapon_rpg'] = 'wyrzutnia rakiet', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'granat', ['weapon_stickybomb'] = 'ładunek przylepny', @@ -119,7 +118,6 @@ Locales['pl'] = { ['weapon_molotov'] = 'koktajl Mołotowa', ['weapon_fireextinguisher'] = 'gaśnica', ['weapon_petrolcan'] = 'kanister', - ['weapon_digiscanner'] = 'skaner częstotliwości', ['weapon_ball'] = 'piłka', ['weapon_snspistol'] = 'sns pistolet', ['weapon_bottle'] = 'butelka', @@ -137,8 +135,6 @@ Locales['pl'] = { ['weapon_proxmine'] = 'mina zbliżeniowa', ['weapon_snowball'] = 'śnieżka', ['weapon_flaregun'] = 'flara', - ['weapon_garbagebag'] = 'worek na śmieci', - ['weapon_handcuffs'] = 'kajdanki', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', ['weapon_knuckle'] = 'kastety', @@ -158,7 +154,6 @@ Locales['pl'] = { ['weapon_poolcue'] = 'kij bilardowy', ['weapon_wrench'] = 'klucz do rur', ['weapon_flashlight'] = 'latarka', - ['gadget_nightvision'] = 'noktowizor', ['gadget_parachute'] = 'spadochron', ['weapon_flare'] = 'pistolet sygnałowy', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['pl'] = { ['component_suppressor'] = 'tłumik', ['component_grip'] = 'uchwyt', ['component_luxary_finish'] = 'luxary Weapon Finish', + + -- Weapon Ammo + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', } diff --git a/locales/sv.lua b/locales/sv.lua index 47bc4bde..dcc161c0 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -14,14 +14,14 @@ Locales['sv'] = { ['gave_item'] = 'du gav ~y~%sx~s~ ~b~%s~s~ till ~y~%s~s~', ['received_item'] = 'du tog emot ~y~%sx~s~ ~b~%s~s~ från ~b~%s~s~', ['gave_weapon'] = 'du gav ~b~%s~s~ till ~y~%s~s~', - ['gave_weapon_ammo'] = 'du gav ~o~%sx~s~ skott för ~b~%s~s~ till ~y~%s~s~', - ['gave_weapon_withammo'] = 'du gav ~b~%s~s~ med ~o~%sx~s~ skott till ~y~%s~s~', + ['gave_weapon_ammo'] = 'du gav ~o~%sx %s~s~ för ~b~%s~s~ till ~y~%s~s~', + ['gave_weapon_withammo'] = 'du gav ~b~%s~s~ med ~o~%sx %s~s~ till ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ har redan en ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ har inte det vapnet', ['received_weapon'] = 'du tog emot ~b~%s~s~ från ~b~%s~s~', - ['received_weapon_ammo'] = 'du tog emot ~o~%sx~s~ skott för ~b~%s~s~ från ~b~%s~s~', - ['received_weapon_withammo'] = 'du tog emot ~b~%s~s~ med ~o~%sx~s~ skott från ~b~%s~s~', - ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det har du redan', + ['received_weapon_ammo'] = 'du tog emot ~o~%sx %s~s~ för ~b~%s~s~ från ~b~%s~s~', + ['received_weapon_withammo'] = 'du tog emot ~b~%s~s~ med ~o~%sx %s~s~ från ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det vapnet har du redan', ['received_weapon_noweapon'] = '~b~%s~s~ försökte ge dig ammunition för ett ~y~%s~s~, men du har inget sådant vapen', ['gave_money'] = 'du gav ~g~%s SEK~s~ till ~y~%s~s~', ['received_money'] = 'du tog emot ~g~%s SEK~s~ från ~b~%s~s~', @@ -36,7 +36,7 @@ Locales['sv'] = { ['threw_money'] = 'du kastade ~g~%s SEK~s~ ~b~kontanter~s~', ['threw_account'] = 'du kastade ~g~%s SEK~s~ ~b~%s~s~', ['threw_weapon'] = 'du kastade ~b~%s~s~', - ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx~s~ skott', + ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx %s~s~', ['threw_weapon_already'] = 'du har redan ett sådant vapen på dig', ['threw_cannot_pickup'] = 'du kan inte plocka upp det på grund av att det kommer ej få plats i ditt förråd!', ['threw_pickup_prompt'] = 'tryck ~y~E~s~ för att plocka upp', @@ -110,7 +110,6 @@ Locales['sv'] = { ['weapon_heavysniper'] = 'tung prickskytt', ['weapon_grenadelauncher'] = 'granatkastare', ['weapon_rpg'] = 'raketgevär', - ['weapon_stinger'] = 'stinger', ['weapon_minigun'] = 'minigun', ['weapon_grenade'] = 'granat', ['weapon_stickybomb'] = 'klibbig bomb', @@ -119,7 +118,6 @@ Locales['sv'] = { ['weapon_molotov'] = 'molotov cocktail', ['weapon_fireextinguisher'] = 'brandsläckare', ['weapon_petrolcan'] = 'bensindunk', - ['weapon_digiscanner'] = 'digiscanner', ['weapon_ball'] = 'boll', ['weapon_snspistol'] = 'sns pistol', ['weapon_bottle'] = 'flaska', @@ -129,7 +127,7 @@ Locales['sv'] = { ['weapon_bullpuprifle'] = 'bullpup rifle', ['weapon_dagger'] = 'dolk', ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_firework'] = 'fyrverkeri', + ['weapon_fireworkfirework'] = 'fyrverkeri', ['weapon_musket'] = 'musköt', ['weapon_heavyshotgun'] = 'heavy shotgun', ['weapon_marksmanrifle'] = 'marksman rifle', @@ -137,8 +135,6 @@ Locales['sv'] = { ['weapon_proxmine'] = 'proximity mine', ['weapon_snowball'] = 'snöboll', ['weapon_flaregun'] = 'signalpistol', - ['weapon_garbagebag'] = 'soppåse', - ['weapon_handcuffs'] = 'handklovar', ['weapon_combatpdw'] = 'combat pdw', ['weapon_marksmanpistol'] = 'marksman pistol', ['weapon_knuckle'] = 'knogjärn', @@ -158,7 +154,6 @@ Locales['sv'] = { ['weapon_poolcue'] = 'biljardkö', ['weapon_wrench'] = 'rörtång', ['weapon_flashlight'] = 'ficklampa', - ['gadget_nightvision'] = 'mörkerseende', ['gadget_parachute'] = 'fallskärm', ['weapon_flare'] = 'signalpistol', ['weapon_doubleaction'] = 'double-Action Revolver', @@ -174,4 +169,22 @@ Locales['sv'] = { ['component_suppressor'] = 'ljuddämpare', ['component_grip'] = 'handtag', ['component_luxary_finish'] = 'lyxvapen behandling', + + -- Weapon Ammo + ['ammo_rounds'] = 'ammunition', + ['ammo_shells'] = 'hagel', + ['ammo_charge'] = 'laddning', + ['ammo_petrol'] = 'liter bensin', + ['ammo_firework'] = 'fyrverkeri', + ['ammo_rockets'] = 'raket', + ['ammo_grenadelauncher'] = 'granat(er)', + ['ammo_grenade'] = 'granat(er)', + ['ammo_stickybomb'] = 'bomb(er)', + ['ammo_pipebomb'] = 'bomb(er)', + ['ammo_smokebomb'] = 'bomb(er)', + ['ammo_bzgas'] = 'burk(ar)', + ['ammo_ball'] = 'boll(ar)', + ['ammo_snowball'] = 'snöboll(ar)', + ['ammo_flare'] = 'lysraket(er)', + ['ammo_flaregun'] = 'lysraket(er)', } diff --git a/server/commands.lua b/server/commands.lua index 90c50375..965e5bf2 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -134,7 +134,11 @@ TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, if xPlayer.hasWeapon(weaponName) then TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon.' } }) else - xPlayer.addWeapon(weaponName, tonumber(args[3])) + if tonumber(args[3]) then + xPlayer.addWeapon(weaponName, tonumber(args[3])) + else + TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid ammo amount.' } }) + end end else TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon.' } }) diff --git a/server/main.lua b/server/main.lua index 329fc379..ae630198 100644 --- a/server/main.lua +++ b/server/main.lua @@ -290,15 +290,17 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo local weaponLabel = ESX.GetWeaponLabel(itemName) if not targetXPlayer.hasWeapon(itemName) then - local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) + local _, weapon = sourceXPlayer.getWeapon(itemName) + local _, weaponObject = ESX.GetWeapon(itemName) itemCount = weapon.ammo sourceXPlayer.removeWeapon(itemName) targetXPlayer.addWeapon(itemName, itemCount) - if itemCount > 0 then - sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, sourceXPlayer.name)) + if weaponObject.ammo and itemCount > 0 then + local ammoLabel = weaponObject.ammo.label + sourceXPlayer.showNotification(_U('gave_weapon_withammo', weaponLabel, itemCount, ammoLabel, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_withammo', weaponLabel, itemCount, ammoLabel, sourceXPlayer.name)) else sourceXPlayer.showNotification(_U('gave_weapon', weaponLabel, targetXPlayer.name)) targetXPlayer.showNotification(_U('received_weapon', weaponLabel, sourceXPlayer.name)) @@ -312,13 +314,18 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if sourceXPlayer.hasWeapon(itemName) then if targetXPlayer.hasWeapon(itemName) then local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) + local _, weaponObject = ESX.GetWeapon(itemName) - if weapon.ammo >= itemCount then - sourceXPlayer.removeWeaponAmmo(itemName, itemCount) - targetXPlayer.addWeaponAmmo(itemName, itemCount) + if weaponObject.ammo then + local ammoLabel = weaponObject.ammo.label - sourceXPlayer.showNotification(_U('gave_weapon_ammo', itemCount, weapon.label, targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_weapon_ammo', itemCount, weapon.label, sourceXPlayer.name)) + if weapon.ammo >= itemCount then + sourceXPlayer.removeWeaponAmmo(itemName, itemCount) + targetXPlayer.addWeaponAmmo(itemName, itemCount) + + sourceXPlayer.showNotification(_U('gave_weapon_ammo', itemCount, ammoLabel, weapon.label, targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_weapon_ammo', itemCount, ammoLabel, weapon.label, sourceXPlayer.name)) + end end else sourceXPlayer.showNotification(_U('gave_weapon_noweapon', targetXPlayer.name)) @@ -382,17 +389,22 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) itemName = string.upper(itemName) if xPlayer.hasWeapon(itemName) then - local weaponNum, weapon = xPlayer.getWeapon(itemName) + local _, weapon = xPlayer.getWeapon(itemName) + local _, weaponObject = ESX.GetWeapon(itemName) + local pickupLabel + xPlayer.removeWeapon(itemName) - local pickupLabel = ('~y~%s~s~ [~g~%s~s~ ammo]'):format(weapon.label, weapon.ammo) - ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components) - - if weapon.ammo > 0 then - xPlayer.showNotification(_U('threw_weapon_ammo', weapon.label, weapon.ammo)) + if weaponObject.ammo and weapon.ammo > 0 then + local ammoLabel = weaponObject.ammo.label + pickupLabel = ('~y~%s~s~ [~g~%s~s~ %s]'):format(weapon.label, weapon.ammo, ammoLabel) + xPlayer.showNotification(_U('threw_weapon_ammo', weapon.label, weapon.ammo, ammoLabel)) else + pickupLabel = ('~y~%s~s~'):format(weapon.label) xPlayer.showNotification(_U('threw_weapon', weapon.label)) end + + ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components) end end end) From d15cd7d0ec63f78b3cc2bb4f6cccba0513058902 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 11:54:57 +0100 Subject: [PATCH 408/672] Update en.lua --- locales/en.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/en.lua b/locales/en.lua index a7207cad..d519928b 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -36,7 +36,7 @@ Locales['en'] = { ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx~s~ %s', + ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', ['threw_weapon_already'] = 'you already carry the same weapon', ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', From 548b676e5d321b72f547caceadd591908211cafa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 12:01:39 +0100 Subject: [PATCH 409/672] Added missing translations --- locales/br.lua | 2 ++ locales/cs.lua | 2 ++ locales/de.lua | 2 ++ locales/en.lua | 2 ++ locales/fi.lua | 2 ++ locales/fr.lua | 2 ++ locales/pl.lua | 2 ++ locales/sv.lua | 4 +++- 8 files changed, 17 insertions(+), 1 deletion(-) diff --git a/locales/br.lua b/locales/br.lua index 7b69f877..b3db1ee3 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -183,6 +183,8 @@ Locales['br'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/cs.lua b/locales/cs.lua index 565d764d..b980fc6a 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -183,6 +183,8 @@ Locales['cs'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/de.lua b/locales/de.lua index 63b4c090..0068ed65 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -182,6 +182,8 @@ Locales['de'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/en.lua b/locales/en.lua index d519928b..babcb272 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -182,6 +182,8 @@ Locales['en'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/fi.lua b/locales/fi.lua index 20fd8173..2dd566c4 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -182,6 +182,8 @@ Locales['fi'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/fr.lua b/locales/fr.lua index eed3a2f6..5e946a4e 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -182,6 +182,8 @@ Locales['fr'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/pl.lua b/locales/pl.lua index 45793958..9ad79c2e 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -182,6 +182,8 @@ Locales['pl'] = { ['ammo_stickybomb'] = 'bomb(s)', ['ammo_pipebomb'] = 'bomb(s)', ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', ['ammo_bzgas'] = 'can(s)', ['ammo_ball'] = 'ball(s)', ['ammo_snowball'] = 'snowball(s)', diff --git a/locales/sv.lua b/locales/sv.lua index dcc161c0..d1e41405 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -127,7 +127,7 @@ Locales['sv'] = { ['weapon_bullpuprifle'] = 'bullpup rifle', ['weapon_dagger'] = 'dolk', ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_fireworkfirework'] = 'fyrverkeri', + ['weapon_firework'] = 'fyrverkeriraket', ['weapon_musket'] = 'musköt', ['weapon_heavyshotgun'] = 'heavy shotgun', ['weapon_marksmanrifle'] = 'marksman rifle', @@ -182,6 +182,8 @@ Locales['sv'] = { ['ammo_stickybomb'] = 'bomb(er)', ['ammo_pipebomb'] = 'bomb(er)', ['ammo_smokebomb'] = 'bomb(er)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'bomb(er)', ['ammo_bzgas'] = 'burk(ar)', ['ammo_ball'] = 'boll(ar)', ['ammo_snowball'] = 'snöboll(ar)', From 8d308f7c82c96d9f6f101924d470493cfdc3040f Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Tue, 11 Feb 2020 12:32:20 +0100 Subject: [PATCH 410/672] Update fr.lua --- locales/fr.lua | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 5e946a4e..55d849d6 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -37,9 +37,9 @@ Locales['fr'] = { ['threw_account'] = 'vous avez jeté ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~', - ['threw_weapon_already'] = 'you already carry the same weapon', - ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', - ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + ['threw_weapon_already'] = 'vous portez déjà cette arme', + ['threw_cannot_pickup'] = 'vous ne pouvez pas ramasser ça votre inventaire est plein !', + ['threw_pickup_prompt'] = 'appuyez sur ~y~E~s~ pour ramasser', -- Key mapping ['keymap_showinventory'] = 'show Inventory', @@ -155,8 +155,8 @@ Locales['fr'] = { ['weapon_wrench'] = 'clé', ['weapon_flashlight'] = 'lampe torche', ['gadget_parachute'] = 'parachute', - ['weapon_flare'] = 'fusée Détresse', - ['weapon_doubleaction'] = 'double-Action Revolver', + ['weapon_flare'] = 'fusée de détresse', + ['weapon_doubleaction'] = 'revolver double action', -- Weapon Components ['component_clip_default'] = 'chargeur par défaut', @@ -168,25 +168,25 @@ Locales['fr'] = { ['component_scope_advanced'] = 'lunette', ['component_suppressor'] = 'réducteur de son', ['component_grip'] = 'poignée', - ['component_luxary_finish'] = 'finission de luxe', + ['component_luxary_finish'] = 'finition de luxe', -- Weapon Ammo - ['ammo_rounds'] = 'round(s)', - ['ammo_shells'] = 'shell(s)', - ['ammo_charge'] = 'charge', - ['ammo_petrol'] = 'gallons of fuel', - ['ammo_firework'] = 'firework(s)', - ['ammo_rockets'] = 'rocket(s)', + ['ammo_rounds'] = 'cartouche(s)', + ['ammo_shells'] = 'obus', + ['ammo_charge'] = 'charge(s)', + ['ammo_petrol'] = 'jerrican d\'essence', + ['ammo_firework'] = 'feu(x) d\'artifice', + ['ammo_rockets'] = 'roquette(s)', ['ammo_grenadelauncher'] = 'grenade(s)', ['ammo_grenade'] = 'grenade(s)', - ['ammo_stickybomb'] = 'bomb(s)', - ['ammo_pipebomb'] = 'bomb(s)', - ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_stickybomb'] = 'bombe(s)', + ['ammo_pipebomb'] = 'bombe(s)', + ['ammo_smokebomb'] = 'bombe(s)', ['ammo_molotov'] = 'cocktail(s)', ['ammo_proxmine'] = 'mine(s)', - ['ammo_bzgas'] = 'can(s)', - ['ammo_ball'] = 'ball(s)', - ['ammo_snowball'] = 'snowball(s)', - ['ammo_flare'] = 'flare(s)', - ['ammo_flaregun'] = 'flare(s)', + ['ammo_bzgas'] = 'grenade(s)', + ['ammo_ball'] = 'balle(s)', + ['ammo_snowball'] = 'boule(s) de neige', + ['ammo_flare'] = 'fusée(s) éclairante(s)', + ['ammo_flaregun'] = 'fusée(s)', } From 8e13cf6613bb18d7f7711f6d6b5856ee50500fbe Mon Sep 17 00:00:00 2001 From: Jay Date: Tue, 11 Feb 2020 13:45:48 -0500 Subject: [PATCH 411/672] esx:spawnVehicle using Player Heading (#486) * esx:spawnVehicle using Player Heading Updated esx:spawnVehicle to use the players heading as opposed to the default 90.0 degree angle * Update main.lua --- client/main.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/client/main.lua b/client/main.lua index 39bdf327..d99ef51f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -243,10 +243,11 @@ 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) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + local playerHeading = GetEntityHeading(playerPed) - ESX.Game.SpawnVehicle(model, coords, 90.0, function(vehicle) + ESX.Game.SpawnVehicle(model, coords, playerHeading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) else From baa9ca3afc109ec9f34bcfd997810fbebc8ad5e3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 21:11:54 +0100 Subject: [PATCH 412/672] Implemented weapon tint support (desc), closes #477 - Implemented two new xPlayer functions: - .getWeaponTint(weaponName) - .setWeaponTint(weaponName, weaponTintIndex) Thanks to @profex1999 for co authoring this! Co-Authored-By: Andrea Passarini --- client/main.lua | 35 +++++++++++------- config.weapons.lua | 74 ++++++++++++++++++++++++++++++--------- locales/br.lua | 10 ++++++ locales/cs.lua | 10 ++++++ locales/de.lua | 10 ++++++ locales/en.lua | 10 ++++++ locales/fi.lua | 10 ++++++ locales/fr.lua | 10 ++++++ locales/pl.lua | 10 ++++++ locales/sv.lua | 12 ++++++- server/classes/player.lua | 27 +++++++++++++- server/functions.lua | 5 +-- server/main.lua | 8 ++--- 13 files changed, 194 insertions(+), 37 deletions(-) diff --git a/client/main.lua b/client/main.lua index d99ef51f..7e74d212 100644 --- a/client/main.lua +++ b/client/main.lua @@ -85,6 +85,8 @@ AddEventHandler('esx:restoreLoadout', function() local weaponHash = GetHashKey(weaponName) GiveWeaponToPed(playerPed, weaponHash, 0, false, false) + SetPedWeaponTintIndex(playerPed, weaponHash, v.tintIndex) + local ammoType = GetPedAmmoTypeFromWeapon(playerPed, weaponHash) for k2,v2 in ipairs(v.components) do @@ -168,7 +170,7 @@ end) RegisterNetEvent('esx:addWeapon') AddEventHandler('esx:addWeapon', function(weaponName, ammo) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) GiveWeaponToPed(playerPed, weaponHash, ammo, false, false) @@ -176,7 +178,7 @@ end) RegisterNetEvent('esx:addWeaponComponent') AddEventHandler('esx:addWeaponComponent', function(weaponName, weaponComponent) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) local componentHash = ESX.GetWeaponComponent(weaponName, weaponComponent).hash @@ -185,15 +187,23 @@ end) RegisterNetEvent('esx:setWeaponAmmo') AddEventHandler('esx:setWeaponAmmo', function(weaponName, weaponAmmo) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) SetPedAmmo(playerPed, weaponHash, weaponAmmo) end) +RegisterNetEvent('esx:setWeaponTint') +AddEventHandler('esx:setWeaponTint', function(weaponName, weaponTintIndex) + local playerPed = PlayerPedId() + local weaponHash = GetHashKey(weaponName) + + SetPedWeaponTintIndex(playerPed, weaponHash, weaponTintIndex) +end) + RegisterNetEvent('esx:removeWeapon') AddEventHandler('esx:removeWeapon', function(weaponName, ammo) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) RemoveWeaponFromPed(playerPed, weaponHash) @@ -209,7 +219,7 @@ end) RegisterNetEvent('esx:removeWeaponComponent') AddEventHandler('esx:removeWeaponComponent', function(weaponName, weaponComponent) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() local weaponHash = GetHashKey(weaponName) local componentHash = ESX.GetWeaponComponent(weaponName, weaponComponent).hash @@ -243,9 +253,8 @@ 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) - local playerHeading = GetEntityHeading(playerPed) + local playerPed = PlayerPedId() + local playerCoords, playerHeading = GetEntityCoords(playerPed), GetEntityHeading(playerPed) ESX.Game.SpawnVehicle(model, coords, playerHeading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) @@ -256,7 +265,7 @@ AddEventHandler('esx:spawnVehicle', function(vehicle) end) RegisterNetEvent('esx:createPickup') -AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, name, components) +AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, name, components, tintIndex) local playerPed = GetPlayerPed(GetPlayerFromServerId(playerId)) local entityCoords, forward, pickupObject = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) local objectCoords = (entityCoords + forward * 1.0) @@ -264,6 +273,7 @@ AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, na if type == 'item_weapon' then ESX.Streaming.RequestWeaponAsset(GetHashKey(name)) pickupObject = CreateWeaponObject(GetHashKey(name), 50, objectCoords, true, 1.0, 0) + SetWeaponObjectTintIndex(pickupObject, tintIndex) for k,v in ipairs(components) do local component = ESX.GetWeaponComponent(name, v) @@ -300,6 +310,7 @@ AddEventHandler('esx:createMissingPickups', function(missingPickups) if pickup.type == 'item_weapon' then ESX.Streaming.RequestWeaponAsset(GetHashKey(pickup.name)) pickupObject = CreateWeaponObject(GetHashKey(pickup.name), 50, pickup.coords.x, pickup.coords.y, pickup.coords.z, true, 1.0, 0) + SetWeaponObjectTintIndex(pickupObject, pickup.tintIndex) for k,componentName in ipairs(pickup.components) do local component = ESX.GetWeaponComponent(pickup.name, componentName) @@ -405,10 +416,9 @@ Citizen.CreateThread(function() for k,v in ipairs(Config.Weapons) do local weaponName = v.name local weaponHash = GetHashKey(weaponName) - local weaponComponents = {} if HasPedGotWeapon(playerPed, weaponHash, false) then - local ammo = GetAmmoInPedWeapon(playerPed, weaponHash) + local ammo, tintIndex, weaponComponents = GetAmmoInPedWeapon(playerPed, weaponHash), GetPedWeaponTintIndex(playerPed, weaponHash), {} for k2,v2 in ipairs(v.components) do if HasPedGotWeaponComponent(playerPed, weaponHash, v2.hash) then @@ -426,7 +436,8 @@ Citizen.CreateThread(function() name = weaponName, ammo = ammo, label = v.label, - components = weaponComponents + components = weaponComponents, + tintIndex = tintIndex }) else if lastLoadout[weaponName] then diff --git a/config.weapons.lua b/config.weapons.lua index 037062fc..6c08d1a7 100644 --- a/config.weapons.lua +++ b/config.weapons.lua @@ -1,8 +1,20 @@ +Config.DefaultWeaponTints = { + [0] = _U('tint_default'), + [1] = _U('tint_green'), + [2] = _U('tint_gold'), + [3] = _U('tint_pink'), + [4] = _U('tint_army'), + [5] = _U('tint_lspd'), + [6] = _U('tint_orange'), + [7] = _U('tint_platinum') +} + Config.Weapons = { { name = 'WEAPON_PISTOL', label = _U('weapon_pistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL_CLIP_02')}, @@ -16,6 +28,7 @@ Config.Weapons = { name = 'WEAPON_COMBATPISTOL', label = _U('weapon_combatpistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPISTOL_CLIP_02')}, @@ -29,6 +42,7 @@ Config.Weapons = { name = 'WEAPON_APPISTOL', label = _U('weapon_appistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_APPISTOL_CLIP_02')}, @@ -42,6 +56,7 @@ Config.Weapons = { name = 'WEAPON_PISTOL50', label = _U('weapon_pistol50'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_PISTOL50_CLIP_02')}, @@ -55,6 +70,7 @@ Config.Weapons = { name = 'WEAPON_SNSPISTOL', label = _U('weapon_snspistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SNSPISTOL_CLIP_02')}, @@ -66,6 +82,7 @@ Config.Weapons = { name = 'WEAPON_HEAVYPISTOL', label = _U('weapon_heavypistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYPISTOL_CLIP_02')}, @@ -79,6 +96,7 @@ Config.Weapons = { name = 'WEAPON_VINTAGEPISTOL', label = _U('weapon_vintagepistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_VINTAGEPISTOL_CLIP_02')}, @@ -90,6 +108,7 @@ Config.Weapons = { name = 'WEAPON_MACHINEPISTOL', label = _U('weapon_machinepistol'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MACHINEPISTOL_CLIP_02')}, @@ -98,14 +117,15 @@ Config.Weapons = { } }, - {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, - {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, + {name = 'WEAPON_REVOLVER', label = _U('weapon_revolver'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, + {name = 'WEAPON_MARKSMANPISTOL', label = _U('weapon_marksmanpistol'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, {name = 'WEAPON_DOUBLEACTION', label = _U('weapon_doubleaction'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_PISTOL')}}, { name = 'WEAPON_SMG', label = _U('weapon_smg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SMG_CLIP_02')}, @@ -121,6 +141,7 @@ Config.Weapons = { name = 'WEAPON_ASSAULTSMG', label = _U('weapon_assaultsmg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSMG_CLIP_02')}, @@ -135,6 +156,7 @@ Config.Weapons = { name = 'WEAPON_MICROSMG', label = _U('weapon_microsmg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MICROSMG_CLIP_02')}, @@ -149,6 +171,7 @@ Config.Weapons = { name = 'WEAPON_MINISMG', label = _U('weapon_minismg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MINISMG_CLIP_02')} @@ -159,6 +182,7 @@ Config.Weapons = { name = 'WEAPON_COMBATPDW', label = _U('weapon_combatpdw'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SMG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATPDW_CLIP_02')}, @@ -173,6 +197,7 @@ Config.Weapons = { name = 'WEAPON_PUMPSHOTGUN', label = _U('weapon_pumpshotgun'), ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, + tints = Config.DefaultWeaponTints, components = { {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_SR_SUPP')}, @@ -184,6 +209,7 @@ Config.Weapons = { name = 'WEAPON_SAWNOFFSHOTGUN', label = _U('weapon_sawnoffshotgun'), ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, + tints = Config.DefaultWeaponTints, components = { {name = 'luxary_finish', label = _U('component_luxary_finish'), hash = GetHashKey('COMPONENT_SAWNOFFSHOTGUN_VARMOD_LUXE')} } @@ -193,6 +219,7 @@ Config.Weapons = { name = 'WEAPON_ASSAULTSHOTGUN', label = _U('weapon_assaultshotgun'), ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTSHOTGUN_CLIP_02')}, @@ -206,6 +233,7 @@ Config.Weapons = { name = 'WEAPON_BULLPUPSHOTGUN', label = _U('weapon_bullpupshotgun'), ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, + tints = Config.DefaultWeaponTints, components = { {name = 'flashlight', label = _U('component_flashlight'), hash = GetHashKey('COMPONENT_AT_AR_FLSH')}, {name = 'suppressor', label = _U('component_suppressor'), hash = GetHashKey('COMPONENT_AT_AR_SUPP_02')}, @@ -217,6 +245,7 @@ Config.Weapons = { name = 'WEAPON_HEAVYSHOTGUN', label = _U('weapon_heavyshotgun'), ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_HEAVYSHOTGUN_CLIP_02')}, @@ -227,14 +256,15 @@ Config.Weapons = { } }, - {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun'), components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, - {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun'), components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, - {name = 'WEAPON_MUSKET', label = _U('weapon_musket'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SHOTGUN')}}, + {name = 'WEAPON_DBSHOTGUN', label = _U('weapon_dbshotgun'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, + {name = 'WEAPON_AUTOSHOTGUN', label = _U('weapon_autoshotgun'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_shells'), hash = GetHashKey('AMMO_SHOTGUN')}}, + {name = 'WEAPON_MUSKET', label = _U('weapon_musket'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SHOTGUN')}}, { name = 'WEAPON_ASSAULTRIFLE', label = _U('weapon_assaultrifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ASSAULTRIFLE_CLIP_02')}, @@ -251,6 +281,7 @@ Config.Weapons = { name = 'WEAPON_CARBINERIFLE', label = _U('weapon_carbinerifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_CARBINERIFLE_CLIP_02')}, @@ -267,6 +298,7 @@ Config.Weapons = { name = 'WEAPON_ADVANCEDRIFLE', label = _U('weapon_advancedrifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_ADVANCEDRIFLE_CLIP_02')}, @@ -281,6 +313,7 @@ Config.Weapons = { name = 'WEAPON_SPECIALCARBINE', label = _U('weapon_specialcarbine'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_SPECIALCARBINE_CLIP_02')}, @@ -297,6 +330,7 @@ Config.Weapons = { name = 'WEAPON_BULLPUPRIFLE', label = _U('weapon_bullpuprifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_BULLPUPRIFLE_CLIP_02')}, @@ -312,6 +346,7 @@ Config.Weapons = { name = 'WEAPON_COMPACTRIFLE', label = _U('weapon_compactrifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RIFLE')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMPACTRIFLE_CLIP_02')}, @@ -323,6 +358,7 @@ Config.Weapons = { name = 'WEAPON_MG', label = _U('weapon_mg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MG_CLIP_02')}, @@ -335,6 +371,7 @@ Config.Weapons = { name = 'WEAPON_COMBATMG', label = _U('weapon_combatmg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_COMBATMG_CLIP_02')}, @@ -348,6 +385,7 @@ Config.Weapons = { name = 'WEAPON_GUSENBERG', label = _U('weapon_gusenberg'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MG')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_GUSENBERG_CLIP_02')}, @@ -358,6 +396,7 @@ Config.Weapons = { name = 'WEAPON_SNIPERRIFLE', label = _U('weapon_sniperrifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, + tints = Config.DefaultWeaponTints, components = { {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')}, @@ -370,6 +409,7 @@ Config.Weapons = { name = 'WEAPON_HEAVYSNIPER', label = _U('weapon_heavysniper'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, + tints = Config.DefaultWeaponTints, components = { {name = 'scope', label = _U('component_scope'), hash = GetHashKey('COMPONENT_AT_SCOPE_LARGE')}, {name = 'scope_advanced', label = _U('component_scope_advanced'), hash = GetHashKey('COMPONENT_AT_SCOPE_MAX')} @@ -380,6 +420,7 @@ Config.Weapons = { name = 'WEAPON_MARKSMANRIFLE', label = _U('weapon_marksmanrifle'), ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_SNIPER')}, + tints = Config.DefaultWeaponTints, components = { {name = 'clip_default', label = _U('component_clip_default'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_01')}, {name = 'clip_extended', label = _U('component_clip_extended'), hash = GetHashKey('COMPONENT_MARKSMANRIFLE_CLIP_02')}, @@ -391,19 +432,19 @@ Config.Weapons = { } }, + {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MINIGUN')}}, + {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RAILGUN')}}, + {name = 'WEAPON_STUNGUN', label = _U('weapon_stungun'), tints = Config.DefaultWeaponTints, components = {}}, + {name = 'WEAPON_RPG', label = _U('weapon_rpg'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_RPG')}}, + {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_HOMINGLAUNCHER')}}, + {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, + {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, + {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun'), tints = Config.DefaultWeaponTints, components = {}, ammo = {label = _U('ammo_flaregun'), hash = GetHashKey('AMMO_FLAREGUN')}}, {name = 'WEAPON_FIREEXTINGUISHER', label = _U('weapon_fireextinguisher'), components = {}, ammo = {label = _U('ammo_charge'), hash = GetHashKey('AMMO_FIREEXTINGUISHER')}}, {name = 'WEAPON_PETROLCAN', label = _U('weapon_petrolcan'), components = {}, ammo = {label = _U('ammo_petrol'), hash = GetHashKey('AMMO_PETROLCAN')}}, - {name = 'WEAPON_MINIGUN', label = _U('weapon_minigun'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_MINIGUN')}}, - {name = 'WEAPON_RAILGUN', label = _U('weapon_railgun'), components = {}, ammo = {label = _U('ammo_rounds'), hash = GetHashKey('AMMO_RAILGUN')}}, - {name = 'WEAPON_STUNGUN', label = _U('weapon_stungun'), components = {}}, {name = 'WEAPON_FIREWORK', label = _U('weapon_firework'), components = {}, ammo = {label = _U('ammo_firework'), hash = GetHashKey('AMMO_FIREWORK')}}, - {name = 'WEAPON_RPG', label = _U('weapon_rpg'), components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_RPG')}}, - {name = 'WEAPON_HOMINGLAUNCHER', label = _U('weapon_hominglauncher'), components = {}, ammo = {label = _U('ammo_rockets'), hash = GetHashKey('AMMO_HOMINGLAUNCHER')}}, - {name = 'WEAPON_GRENADELAUNCHER', label = _U('weapon_grenadelauncher'), components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, - {name = 'WEAPON_COMPACTLAUNCHER', label = _U('weapon_compactlauncher'), components = {}, ammo = {label = _U('ammo_grenadelauncher'), hash = GetHashKey('AMMO_GRENADELAUNCHER')}}, {name = 'WEAPON_FLASHLIGHT', label = _U('weapon_flashlight'), components = {}}, {name = 'GADGET_PARACHUTE', label = _U('gadget_parachute'), components = {}}, - {name = 'WEAPON_KNUCKLE', label = _U('weapon_knuckle'), components = {}}, {name = 'WEAPON_HATCHET', label = _U('weapon_hatchet'), components = {}}, {name = 'WEAPON_MACHETE', label = _U('weapon_machete'), components = {}}, @@ -421,14 +462,13 @@ Config.Weapons = { {name = 'WEAPON_CROWBAR', label = _U('weapon_crowbar'), components = {}}, {name = 'WEAPON_GRENADE', label = _U('weapon_grenade'), components = {}, ammo = {label = _U('ammo_grenade'), hash = GetHashKey('AMMO_GRENADE')}}, + {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade'), components = {}, ammo = {label = _U('ammo_smokebomb'), hash = GetHashKey('AMMO_SMOKEGRENADE')}}, {name = 'WEAPON_STICKYBOMB', label = _U('weapon_stickybomb'), components = {}, ammo = {label = _U('ammo_stickybomb'), hash = GetHashKey('AMMO_STICKYBOMB')}}, {name = 'WEAPON_PIPEBOMB', label = _U('weapon_pipebomb'), components = {}, ammo = {label = _U('ammo_pipebomb'), hash = GetHashKey('AMMO_PIPEBOMB')}}, - {name = 'WEAPON_SMOKEGRENADE', label = _U('weapon_smokegrenade'), components = {}, ammo = {label = _U('ammo_smokebomb'), hash = GetHashKey('AMMO_SMOKEGRENADE')}}, {name = 'WEAPON_BZGAS', label = _U('weapon_bzgas'), components = {}, ammo = {label = _U('ammo_bzgas'), hash = GetHashKey('AMMO_BZGAS')}}, {name = 'WEAPON_MOLOTOV', label = _U('weapon_molotov'), components = {}, ammo = {label = _U('ammo_molotov'), hash = GetHashKey('AMMO_MOLOTOV')}}, {name = 'WEAPON_PROXMINE', label = _U('weapon_proxmine'), components = {}, ammo = {label = _U('ammo_proxmine'), hash = GetHashKey('AMMO_PROXMINE')}}, - {name = 'WEAPON_BALL', label = _U('weapon_ball'), components = {}, ammo = {label = _U('ammo_ball'), hash = GetHashKey('AMMO_BALL')}}, {name = 'WEAPON_SNOWBALL', label = _U('weapon_snowball'), components = {}, ammo = {label = _U('ammo_snowball'), hash = GetHashKey('AMMO_SNOWBALL')}}, - {name = 'WEAPON_FLARE', label = _U('weapon_flare'), components = {}, ammo = {label = _U('ammo_flare'), hash = GetHashKey('AMMO_FLARE')}}, - {name = 'WEAPON_FLAREGUN', label = _U('weapon_flaregun'), components = {}, ammo = {label = _U('ammo_flaregun'), hash = GetHashKey('AMMO_FLAREGUN')}} + {name = 'WEAPON_BALL', label = _U('weapon_ball'), components = {}, ammo = {label = _U('ammo_ball'), hash = GetHashKey('AMMO_BALL')}}, + {name = 'WEAPON_FLARE', label = _U('weapon_flare'), components = {}, ammo = {label = _U('ammo_flare'), hash = GetHashKey('AMMO_FLARE')}} } diff --git a/locales/br.lua b/locales/br.lua index b3db1ee3..a7b54c8f 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -190,4 +190,14 @@ Locales['br'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/cs.lua b/locales/cs.lua index b980fc6a..72b398de 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -190,4 +190,14 @@ Locales['cs'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/de.lua b/locales/de.lua index 0068ed65..37beefe7 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -189,4 +189,14 @@ Locales['de'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/en.lua b/locales/en.lua index babcb272..e8ed9a67 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -189,4 +189,14 @@ Locales['en'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/fi.lua b/locales/fi.lua index 2dd566c4..5e987651 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -189,4 +189,14 @@ Locales['fi'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/fr.lua b/locales/fr.lua index 55d849d6..4d83dd0e 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -189,4 +189,14 @@ Locales['fr'] = { ['ammo_snowball'] = 'boule(s) de neige', ['ammo_flare'] = 'fusée(s) éclairante(s)', ['ammo_flaregun'] = 'fusée(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/pl.lua b/locales/pl.lua index 9ad79c2e..2c9d3bdc 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -189,4 +189,14 @@ Locales['pl'] = { ['ammo_snowball'] = 'snowball(s)', ['ammo_flare'] = 'flare(s)', ['ammo_flaregun'] = 'flare(s)', + + -- Weapon Tints + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/sv.lua b/locales/sv.lua index d1e41405..66060f6f 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -152,7 +152,7 @@ Locales['sv'] = { ['weapon_minismg'] = 'mini smg', ['weapon_pipebomb'] = 'pipe bomb', ['weapon_poolcue'] = 'biljardkö', - ['weapon_wrench'] = 'rörtång', + ['weapon_wrench'] = 'skiftnyckel', ['weapon_flashlight'] = 'ficklampa', ['gadget_parachute'] = 'fallskärm', ['weapon_flare'] = 'signalpistol', @@ -189,4 +189,14 @@ Locales['sv'] = { ['ammo_snowball'] = 'snöboll(ar)', ['ammo_flare'] = 'lysraket(er)', ['ammo_flaregun'] = 'lysraket(er)', + + -- Weapon Tints + ['tint_default'] = 'standardutseende', + ['tint_green'] = 'grönskinn', + ['tint_gold'] = 'guldskinn', + ['tint_pink'] = 'råsaskinn', + ['tint_army'] = 'arméskinn', + ['tint_lspd'] = 'blåskinn', + ['tint_orange'] = 'orangeskinn', + ['tint_platinum'] = 'platinaskinn', } diff --git a/server/classes/player.lua b/server/classes/player.lua index 3b931af8..0f5bf295 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -375,7 +375,8 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c name = weaponName, ammo = ammo, label = weaponLabel, - components = {} + components = {}, + tintIndex = 0 }) self.triggerEvent('esx:addWeapon', weaponName, ammo) @@ -408,6 +409,30 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end + self.setWeaponTint = function(weaponName, weaponTintIndex) + local loadoutNum, weapon = self.getWeapon(weaponName) + + if weapon then + local weaponNum, weaponObject = ESX.GetWeapon(weaponName) + + if weaponObject.tints and weaponObject.tints[weaponTintIndex] then + self.loadout[loadoutNum].tintIndex = weaponTintIndex + self.triggerEvent('esx:setWeaponTint', weaponName, weaponTintIndex) + self.triggerEvent('esx:addInventoryItem', weaponObject.tints[weaponTintIndex], false, true) + end + end + end + + self.getWeaponTint = function(weaponName) + local loadoutNum, weapon = self.getWeapon(weaponName) + + if weapon then + return weapon.tintIndex + end + + return 0 + end + self.removeWeapon = function(weaponName, ammo) local weaponLabel diff --git a/server/functions.lua b/server/functions.lua index 2a20eeea..b9cc7b87 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -159,7 +159,7 @@ ESX.GetItemLabel = function(item) end end -ESX.CreatePickup = function(type, name, count, label, playerId, components) +ESX.CreatePickup = function(type, name, count, label, playerId, components, tintIndex) local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) local xPlayer = ESX.GetPlayerFromId(playerId) @@ -173,9 +173,10 @@ ESX.CreatePickup = function(type, name, count, label, playerId, components) if type == 'item_weapon' then ESX.Pickups[pickupId].components = components + ESX.Pickups[pickupId].tintIndex = tintIndex end - TriggerClientEvent('esx:createPickup', -1, pickupId, label, playerId, type, name, components) + TriggerClientEvent('esx:createPickup', -1, pickupId, label, playerId, type, name, components, tintIndex) ESX.PickupId = pickupId end diff --git a/server/main.lua b/server/main.lua index ae630198..6e59e989 100644 --- a/server/main.lua +++ b/server/main.lua @@ -159,9 +159,8 @@ AddEventHandler('es:playerLoaded', function(playerId, player) -- Compatibility with old loadouts prior to components update for k,v in ipairs(userData.loadout) do - if v.components == nil then - v.components = {} - end + if not v.components then v.components = {} end + if not v.tintIndex then v.tintIndex = 0 end end end @@ -404,7 +403,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) xPlayer.showNotification(_U('threw_weapon', weapon.label)) end - ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components) + ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components, weapon.tintIndex) end end end) @@ -445,6 +444,7 @@ AddEventHandler('esx:onPickup', function(id) else success = true xPlayer.addWeapon(pickup.name, pickup.count) + xPlayer.setWeaponTint(pickup.name, pickup.tintIndex) for k,v in ipairs(pickup.components) do xPlayer.addWeaponComponent(pickup.name, v) From 48dfa27397be0348eecfe74a68b8dbf649e40c5c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 11 Feb 2020 21:13:25 +0100 Subject: [PATCH 413/672] Removed /disc command, closes #464 Co-Authored-By: Andrea Passarini --- locales/br.lua | 2 -- locales/cs.lua | 1 - locales/de.lua | 1 - locales/en.lua | 1 - locales/fi.lua | 1 - locales/fr.lua | 1 - locales/pl.lua | 1 - locales/sv.lua | 1 - server/commands.lua | 6 ------ 9 files changed, 15 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index a7b54c8f..86fb98d2 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -71,8 +71,6 @@ Locales['br'] = { ['giveitem'] = 'dar item', ['weapon'] = 'arma', ['giveweapon'] = 'dar arma', - - ['disconnect'] = 'desconectar do servidor', ['chat_clear'] = 'limpar o chat', ['chat_clear_all'] = 'limpar o chat para todos', ['command_clearinventory'] = 'remover todos os itens do inventário', diff --git a/locales/cs.lua b/locales/cs.lua index 72b398de..5c1283b8 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -72,7 +72,6 @@ Locales['cs'] = { ['giveitem'] = 'dát věc', ['weapon'] = 'zbraň', ['giveweapon'] = 'dát zbraň', - ['disconnect'] = 'odpojit od serveru', ['chat_clear'] = 'vyčistit chat', ['chat_clear_all'] = 'vyčistit chat pro všechny', ['command_clearinventory'] = 'clear all items from inventory', diff --git a/locales/de.lua b/locales/de.lua index 37beefe7..44f23ed0 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -71,7 +71,6 @@ Locales['de'] = { ['giveitem'] = 'give item', ['weapon'] = 'weapon', ['giveweapon'] = 'give weapon', - ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', ['command_clearinventory'] = 'clear all items from inventory', diff --git a/locales/en.lua b/locales/en.lua index e8ed9a67..73ad1b84 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -71,7 +71,6 @@ Locales['en'] = { ['giveitem'] = 'give item', ['weapon'] = 'weapon', ['giveweapon'] = 'give weapon', - ['disconnect'] = 'disconnect from the server', ['chat_clear'] = 'clear the chat', ['chat_clear_all'] = 'clear the chat for everyone', ['command_clearinventory'] = 'clear all items from inventory', diff --git a/locales/fi.lua b/locales/fi.lua index 5e987651..e996ad77 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -71,7 +71,6 @@ Locales['fi'] = { ['giveitem'] = 'anna itemi', ['weapon'] = 'ase', ['giveweapon'] = 'anna ase', - ['disconnect'] = 'poistu serveriltä', ['chat_clear'] = 'tyhjennä chatti', ['chat_clear_all'] = 'tyhjennä chatti kaikilta', ['command_clearinventory'] = 'clear all items from inventory', diff --git a/locales/fr.lua b/locales/fr.lua index 4d83dd0e..3483566a 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -71,7 +71,6 @@ Locales['fr'] = { ['giveitem'] = 'donner un article', ['weapon'] = 'arme', ['giveweapon'] = 'donner l\'arme', - ['disconnect'] = 'déconnecter du serveur', ['chat_clear'] = 'vider le chat', ['chat_clear_all'] = 'vider le chat pour tous le monde', ['command_clearinventory'] = 'effacer tout les items de l\'inventaire', diff --git a/locales/pl.lua b/locales/pl.lua index 2c9d3bdc..4cdfe07e 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -71,7 +71,6 @@ Locales['pl'] = { ['giveitem'] = 'daj przedmiot', ['weapon'] = 'broń', ['giveweapon'] = 'daj broń', - ['disconnect'] = 'odłącz się od serwera', ['chat_clear'] = 'wyczyść czat', ['chat_clear_all'] = 'wyczyść czat dla wszystkich', ['command_clearinventory'] = 'usuń wszystkie przedmioty z ekwipunku', diff --git a/locales/sv.lua b/locales/sv.lua index 66060f6f..1f23cbc4 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -71,7 +71,6 @@ Locales['sv'] = { ['giveitem'] = 'ge föremål', ['weapon'] = 'vapen', ['giveweapon'] = 'ge vapen', - ['disconnect'] = 'koppla från servern', ['chat_clear'] = 'töm chatten', ['chat_clear_all'] = 'töm chatten för alla', ['command_clearinventory'] = 'clear all items from inventory', diff --git a/server/commands.lua b/server/commands.lua index 965e5bf2..dea5e1ee 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -192,12 +192,6 @@ end, {help = 'Give weapon component', params = { {name = 'componentName', help = 'weapon component'} }}) -TriggerEvent('es:addGroupCommand', 'disc', 'admin', function(source, args, user) - DropPlayer(source, 'You have been disconnected') -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('disconnect')}) - TriggerEvent('es:addGroupCommand', 'clear', 'user', function(source, args, user) TriggerClientEvent('chat:clear', source) end, function(source, args, user) From 11a541b67268334a2901fd2f311167a7551086e7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 10:32:23 +0100 Subject: [PATCH 414/672] Fixed #496 --- client/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 7e74d212..5365f53c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -256,7 +256,7 @@ AddEventHandler('esx:spawnVehicle', function(vehicle) local playerPed = PlayerPedId() local playerCoords, playerHeading = GetEntityCoords(playerPed), GetEntityHeading(playerPed) - ESX.Game.SpawnVehicle(model, coords, playerHeading, function(vehicle) + ESX.Game.SpawnVehicle(model, playerCoords, playerHeading, function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) else From 68712016ed029b392c64b616654fcebe7d97d2d2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 12:04:00 +0100 Subject: [PATCH 415/672] Added failsafe default coords --- server/main.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 6e59e989..5face95b 100644 --- a/server/main.lua +++ b/server/main.lua @@ -164,7 +164,13 @@ AddEventHandler('es:playerLoaded', function(playerId, player) end end - userData.coords = json.decode(result[1].position) + if result[1].position and result[1].position ~= '' then + userData.coords = json.decode(result[1].position) + else + print('[es_extended] [^3WARNING^7] Column "position" in "users" table is missing required default value. Using backup coords, fix your database.') + userData.coords = {x = -269.4, y = -955.3, z = 31.2, heading = 205.8} + end + cb2() end) From b2a46fdfb36fbbc5e5e579255422d0b75c8818fb Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 12:06:05 +0100 Subject: [PATCH 416/672] Reverted new RegisterKeyMapping() native usage for now, its broken :/ --- client/main.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5365f53c..4905e97c 100644 --- a/client/main.lua +++ b/client/main.lua @@ -455,13 +455,17 @@ Citizen.CreateThread(function() end end) -RegisterCommand('showinventory', function() - if not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then - ESX.ShowInventory() - end -end, false) +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) -RegisterKeyMapping('showinventory', _U('keymap_showinventory'), 'keyboard', 'F2') + if IsControlJustReleased(0, 289) then + if IsInputDisabled(0) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then + ESX.ShowInventory() + end + end + end +end) -- Disable wanted level if Config.DisableWantedLevel then From f236a67d63d2ec5979cff3d7ee12e7f3356b84e6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 12:33:14 +0100 Subject: [PATCH 417/672] Implemented json encoded inventory, closes #177 --- server/classes/player.lua | 16 +++++- server/functions.lua | 32 +++--------- server/main.lua | 104 +++++++++++++------------------------- 3 files changed, 58 insertions(+), 94 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 0f5bf295..d5035e09 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -129,8 +129,20 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end end - self.getInventory = function() - return self.inventory + self.getInventory = function(minimal) + if minimal then + local items = {} + + for k,v in ipairs(self.inventory) do + if v.count > 0 then + items[v.name] = v.count + end + end + + return items + else + return self.inventory + end end self.getJob = function() diff --git a/server/functions.lua b/server/functions.lua index b9cc7b87..83c2debc 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -56,31 +56,15 @@ ESX.SavePlayer = function(xPlayer, cb) end end - -- Inventory items - for k,v in ipairs(xPlayer.inventory) do - if ESX.LastPlayerData[xPlayer.source].items[v.name] ~= v.count then - table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE user_inventory SET count = @count WHERE identifier = @identifier AND item = @item', { - ['@count'] = v.count, - ['@identifier'] = xPlayer.identifier, - ['@item'] = v.name - }, function(rowsChanged) - cb() - end) - end) - - ESX.LastPlayerData[xPlayer.source].items[v.name] = v.count - end - end - - -- Job, loadout and position + -- Job, loadout, inventory 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.getLoadout()), - ['@position'] = json.encode(xPlayer.getCoords()), - ['@identifier'] = xPlayer.identifier + MySQL.Async.execute('UPDATE users SET job = @job, job_grade = @job_grade, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { + ['@job'] = xPlayer.job.name, + ['@job_grade'] = xPlayer.job.grade, + ['@loadout'] = json.encode(xPlayer.getLoadout()), + ['@position'] = json.encode(xPlayer.getCoords()), + ['@identifier'] = xPlayer.identifier, + ['@inventory'] = json.encode(xPlayer.getInventory(true)) }, function(rowsChanged) cb() end) diff --git a/server/main.lua b/server/main.lua index 5face95b..d079ded5 100644 --- a/server/main.lua +++ b/server/main.lua @@ -30,72 +30,6 @@ AddEventHandler('es:playerLoaded', function(playerId, player) end) end) - -- Get inventory - table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT item, count FROM user_inventory WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() - }, function(inventory) - local tasks2, foundItems = {}, {} - - for k,v in ipairs(inventory) do - local item = ESX.Items[v.item] - - if item then - foundItems[v.item] = true - - table.insert(userData.inventory, { - name = v.item, - count = v.count, - label = item.label, - weight = item.weight, - usable = ESX.UsableItemsCallbacks[v.item] ~= nil, - rare = item.rare, - canRemove = item.canRemove - }) - else - print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(v.item, player.getIdentifier())) - end - end - - for name,item in pairs(ESX.Items) do - if not foundItems[name] then - table.insert(userData.inventory, { - name = name, - count = 0, - label = item.label, - weight = item.weight, - usable = ESX.UsableItemsCallbacks[name] ~= nil, - rare = item.rare, - canRemove = item.canRemove - }) - - local scope = function(item, identifier) - table.insert(tasks2, function(cb2) - MySQL.Async.execute('INSERT INTO user_inventory (identifier, item, count) VALUES (@identifier, @item, @count)', { - ['@identifier'] = identifier, - ['@item'] = item, - ['@count'] = 0 - }, function(rowsChanged) - cb2() - end) - end) - end - - scope(name, player.getIdentifier()) - end - end - - Async.parallelLimit(tasks2, 5, function(results) 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) @@ -104,7 +38,7 @@ AddEventHandler('es:playerLoaded', function(playerId, player) -- Get job name, grade and coords table.insert(tasks2, function(cb2) - MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position FROM users WHERE identifier = @identifier', { + MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position, inventory FROM users WHERE identifier = @identifier', { ['@identifier'] = player.getIdentifier() }, function(result) local job, grade = result[1].job, tostring(result[1].job_grade) @@ -154,10 +88,44 @@ AddEventHandler('es:playerLoaded', function(playerId, player) userData.job.skin_female = {} end + local foundItems = {} + + if result[1].inventory and result[1].inventory ~= '' then + local inventory = json.decode(result[1].inventory) + + for name,count in pairs(inventory) do + local item = ESX.Items[name] + + if item then + foundItems[name] = count + else + print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(name, player.getIdentifier())) + end + end + end + + for name,item in pairs(ESX.Items) do + local count = foundItems[name] or 0 + + table.insert(userData.inventory, { + name = name, + count = count, + label = item.label, + weight = item.weight, + usable = ESX.UsableItemsCallbacks[name] ~= nil, + rare = item.rare, + canRemove = item.canRemove + }) + end + + table.sort(userData.inventory, function(a,b) + return a.label < b.label + end) + if result[1].loadout then userData.loadout = json.decode(result[1].loadout) - -- Compatibility with old loadouts prior to components update + -- compatibility with old loadouts for k,v in ipairs(userData.loadout) do if not v.components then v.components = {} end if not v.tintIndex then v.tintIndex = 0 end From d2bf5cc73be348bb485a189db4963a16ccae3402 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 12 Feb 2020 12:36:02 +0100 Subject: [PATCH 418/672] Updated sql file --- es_extended.sql | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 253af3b9..dce1fe4d 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -5,7 +5,8 @@ ALTER TABLE `users` ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}' AFTER `loadout` + ADD COLUMN `inventory` LONGTEXT NULL AFTER `loadout`, + ADD COLUMN `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}' AFTER `inventory` ; CREATE TABLE `items` ( @@ -50,12 +51,3 @@ CREATE TABLE `user_accounts` ( PRIMARY KEY (`id`) ); - -CREATE TABLE `user_inventory` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `identifier` VARCHAR(22) NOT NULL, - `item` VARCHAR(50) NOT NULL, - `count` INT(11) NOT NULL, - - PRIMARY KEY (`id`) -); From e6c90ea30eb401798b21c9dcadebcf6c413345ee Mon Sep 17 00:00:00 2001 From: Deliux Date: Wed, 12 Feb 2020 15:40:19 +0200 Subject: [PATCH 419/672] Xenon Color addition Could be used in esx_lscustoms, to change colors of xenons --- client/functions.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index f15797ed..8cff77c4 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -676,6 +676,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) wheels = GetVehicleWheelType(vehicle), windowTint = GetVehicleWindowTint(vehicle), + xenonColor = GetVehicleXenonLightsColour(vehicle), neonEnabled = { IsVehicleNeonLightEnabled(vehicle, 0), @@ -780,6 +781,7 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end if props.neonColor then SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3]) end + if props.xenonColor then SetVehicleXenonLightsColour(vehicle, props.xenonColor) end if props.modSmokeEnabled then ToggleVehicleMod(vehicle, 20, true) end if props.tyreSmokeColor then SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3]) end if props.modSpoilers then SetVehicleMod(vehicle, 0, props.modSpoilers, false) end From 35a726685e81c7e74d13e05d6f9b8e4d5f9bea23 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 15:22:09 +0100 Subject: [PATCH 420/672] =?UTF-8?q?=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8FBRE?= =?UTF-8?q?AKING=20COMMIT=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8F:=20Complete?= =?UTF-8?q?=20ES=20ditch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/functions.lua | 14 -- client/main.lua | 38 ++-- config.lua | 11 +- es_extended.sql | 21 ++- fxmanifest.lua | 5 +- html/img/accounts/money.png | Bin 0 -> 662 bytes locales/br.lua | 9 +- locales/cs.lua | 9 +- locales/de.lua | 9 +- locales/en.lua | 9 +- locales/fi.lua | 9 +- locales/fr.lua | 9 +- locales/pl.lua | 11 +- locales/sv.lua | 19 +- server/classes/player.lua | 140 ++++++--------- server/commands.lua | 334 ++++++++++-------------------------- server/common.lua | 14 +- server/functions.lua | 113 +++++++++++- server/main.lua | 262 +++++++++++++--------------- 19 files changed, 439 insertions(+), 597 deletions(-) create mode 100644 html/img/accounts/money.png diff --git a/client/functions.lua b/client/functions.lua index f15797ed..d801c1b5 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -865,20 +865,6 @@ ESX.ShowInventory = function() local playerPed = PlayerPedId() local elements, currentWeight = {}, 0 - if ESX.PlayerData.money > 0 then - local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(ESX.PlayerData.money)) - - table.insert(elements, { - label = ('%s: %s'):format(_U('cash'), formattedMoney), - count = ESX.PlayerData.money, - type = 'item_money', - value = 'money', - usable = false, - rare = false, - canRemove = true - }) - end - for k,v in pairs(ESX.PlayerData.accounts) do if v.money > 0 then local formattedMoney = _U('locale_currency', ESX.Math.GroupDigits(v.money)) diff --git a/client/main.lua b/client/main.lua index 4905e97c..caccc586 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,40 +1,29 @@ local isLoadoutLoaded, isPaused, isDead, isFirstSpawn, pickups = false, false, false, true, {} RegisterNetEvent('esx:playerLoaded') -AddEventHandler('esx:playerLoaded', function(xPlayer) +AddEventHandler('esx:playerLoaded', function(playerData) ESX.PlayerLoaded = true - ESX.PlayerData = xPlayer + ESX.PlayerData = playerData if Config.EnableHud then - for k,v in ipairs(xPlayer.accounts) do + for k,v in ipairs(playerData.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, { + ESX.UI.HUD.RegisterElement('account_' .. v.name, k, 0, accountTpl, { money = ESX.Math.GroupDigits(v.money) }) end local jobTpl = '
{{job_label}} - {{grade_label}}
' - if xPlayer.job.grade_label == '' then + if playerData.job.grade_label == '' or playerData.job.grade_label == playerData.job.label then jobTpl = '
{{job_label}}
' end - ESX.UI.HUD.RegisterElement('job', #xPlayer.accounts, 0, jobTpl, { - job_label = '', - grade_label = '' + ESX.UI.HUD.RegisterElement('job', #playerData.accounts, 0, jobTpl, { + job_label = playerData.job.label, + grade_label = playerData.job.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) @@ -44,6 +33,10 @@ AddEventHandler('esx:setMaxWeight', function(newMaxWeight) end) AddEventHandler('playerSpawned', function() + if isFirstSpawn then + TriggerServerEvent('esx:playerJoined') + end + while not ESX.PlayerLoaded do Citizen.Wait(10) end @@ -120,11 +113,6 @@ AddEventHandler('esx:setAccountMoney', function(account) end end) -RegisterNetEvent('es:activateMoney') -AddEventHandler('es:activateMoney', function(money) - ESX.PlayerData.money = money -end) - RegisterNetEvent('esx:addInventoryItem') AddEventHandler('esx:addInventoryItem', function(item, count, showNotification) for k,v in ipairs(ESX.PlayerData.inventory) do @@ -394,11 +382,9 @@ if Config.EnableHud then 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 diff --git a/config.lua b/config.lua index d3bf0edb..be3e5171 100644 --- a/config.lua +++ b/config.lua @@ -1,8 +1,11 @@ -Config = {} -Config.Locale = 'fr' +Config = {} +Config.Locale = 'fr' -Config.Accounts = {'bank', 'black_money'} -Config.AccountLabels = {bank = _U('bank'), black_money = _U('black_money')} +Config.Accounts = { + bank = _U('account_bank'), + black_money = _U('account_black_money'), + money = _U('account_money') +} Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.DisableWantedLevel = true diff --git a/es_extended.sql b/es_extended.sql index dce1fe4d..111cef1f 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,13 +1,16 @@ USE `essentialmode`; -ALTER TABLE `users` - ADD COLUMN `skin` LONGTEXT NULL, - ADD COLUMN `job` VARCHAR(50) NULL DEFAULT 'unemployed' AFTER `skin`, - ADD COLUMN `job_grade` INT NULL DEFAULT 0 AFTER `job`, - ADD COLUMN `loadout` LONGTEXT NULL AFTER `job_grade`, - ADD COLUMN `inventory` LONGTEXT NULL AFTER `loadout`, - ADD COLUMN `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}' AFTER `inventory` -; +CREATE TABLE `users` ( + `identifier` VARCHAR(40) NOT NULL, + `group` VARCHAR(50) NULL DEFAULT 'user', + `job` VARCHAR(20) NULL DEFAULT 'unemployed', + `job_grade` INT(11) NULL DEFAULT 0, + `inventory` LONGTEXT NULL DEFAULT NULL, + `loadout` LONGTEXT NULL DEFAULT NULL, + `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}', + + PRIMARY KEY (`identifier`) +); CREATE TABLE `items` ( `name` VARCHAR(50) NOT NULL, @@ -45,7 +48,7 @@ INSERT INTO `jobs` VALUES ('unemployed','Unemployed'); CREATE TABLE `user_accounts` ( `id` INT(11) NOT NULL AUTO_INCREMENT, - `identifier` VARCHAR(22) NOT NULL, + `identifier` VARCHAR(40) NOT NULL, `name` VARCHAR(50) NOT NULL, `money` INT(11) NOT NULL DEFAULT '0', diff --git a/fxmanifest.lua b/fxmanifest.lua index a4be3e72..f40e04a9 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -82,7 +82,8 @@ files { 'html/fonts/bankgothic.ttf', 'html/img/accounts/bank.png', - 'html/img/accounts/black_money.png' + 'html/img/accounts/black_money.png', + 'html/img/accounts/money.png', } exports { @@ -95,7 +96,5 @@ server_exports { dependencies { 'mysql-async', - 'essentialmode', - 'esplugin_mysql', 'async' } diff --git a/html/img/accounts/money.png b/html/img/accounts/money.png new file mode 100644 index 0000000000000000000000000000000000000000..e05c91b0bb0c4faaa5f7a756c8d755f79f16ef1b GIT binary patch literal 662 zcmV;H0%`q;P)X^iM1 zwrODs(MFhlOeu(NQ0k`3E;Jz*K^GS-(n(r$SyU$3qJ?eD zMP*mpn2qSn_kAq}bmn)YvwhF=@_y%VJ|R%M(p`JORs)2MydFE;JyWQAK|q{IAQ}hA zsyhM{0U8AUS5g$`?U^t?HoXv$CIFnf3%s=G2Ql8*L~|;W2a-vRHD=GMab2iXm9)0} zRdo#>4v9U^4yvOKm6E;rerq!GWmBG??mUXnR-`)j9C(kQSg8T_h|1_>OKQn;aJnw#49Ea}Z>7Q03CLP55lYp)h)ynn7D zS6Pu+NrmzJ;Y5uMX`O7DeLCUyXA6OBWqCZ{_|bE!t?IaJzi*t2jdY9)OanO)c3@?H z;Qo*$`xzffB@0Rx;H`nAI~(;KCr0F?*IS*07*qoM6N<$g3p&H&Hw-a literal 0 HcmV?d00001 diff --git a/locales/br.lua b/locales/br.lua index 86fb98d2..f8573d2d 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -1,6 +1,5 @@ Locales['br'] = { -- Inventory - ['cash'] = 'dinheiro', ['inventory'] = 'inventário %s / %s', ['use'] = 'usar', ['give'] = 'dar', @@ -23,8 +22,6 @@ Locales['br'] = { ['received_weapon_withammo'] = 'você recebeu ~b~%s~s~ com ~o~%sx %s~s~ de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ tentou lhe dar uma ~y~%s~s~, mas você já tem um(a)', ['received_weapon_noweapon'] = '~b~%s~s~ tentou lhe dar munição para ~y~%s~s~, mas você não tem um(a)', - ['gave_money'] = 'voce deu ~g~$%s~s~ para ~y~%s~s~', - ['received_money'] = 'voce recebeu ~g~$%s~s~ de ~b~%s~s~', ['gave_account_money'] = 'voce deu ~g~$%s~s~ (%s) para ~y~%s~s~', ['received_account_money'] = 'voce recebeu ~g~$%s~s~ (%s) de ~b~%s~s~', ['amount_invalid'] = 'quantidade inválida', @@ -33,7 +30,6 @@ Locales['br'] = { ['imp_invalid_quantity'] = 'ação impossível, quantidade inválida', ['imp_invalid_amount'] = 'ação impossível, valor invalido', ['threw_standard'] = 'você jogou ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'você jogou ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'você jogou ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'você jogou ~b~%s~s~', ['threw_weapon_ammo'] = 'você jogou ~b~%s~s~ com ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['br'] = { ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salário', ['received_paycheck'] = 'recebeu dinheiro', ['bank'] = 'banco', - ['black_money'] = 'dinheiro sujo', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'ação impossível', ['in_vehicle'] = 'voce não pode dar nada para alguem no veículo', @@ -75,7 +73,6 @@ Locales['br'] = { ['chat_clear_all'] = 'limpar o chat para todos', ['command_clearinventory'] = 'remover todos os itens do inventário', ['command_clearloadout'] = 'remova todas as armas do carregamento', - ['command_playerid_param'] = 'especifique playerId ou deixe em branco para si mesmo', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/cs.lua b/locales/cs.lua index 5c1283b8..de60f089 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -1,6 +1,5 @@ Locales['cs'] = { -- Inventory - ['cash'] = 'hotovost', ['inventory'] = 'inventář %s / %s', ['use'] = 'použít', ['give'] = 'dát', @@ -23,8 +22,6 @@ Locales['cs'] = { ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_money'] = 'dali jste ~g~$%s~s~ ~y~%s~s~', - ['received_money'] = 'obdrželi jste ~g~$%s~s~ od ~b~%s~s~', ['gave_account_money'] = 'dali jste ~g~$%s~s~ (%s) ~y~%s~s~', ['received_account_money'] = 'obdrželi jste ~g~$%s~s~ (%s) od ~b~%s~s~', ['amount_invalid'] = 'neplatné množství', @@ -33,7 +30,6 @@ Locales['cs'] = { ['imp_invalid_quantity'] = 'akce není možná, neplatný počet', ['imp_invalid_amount'] = 'akce není možná, neplatné množství', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', @@ -51,7 +47,9 @@ Locales['cs'] = { ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', ['received_paycheck'] = 'obdržena výplata', ['bank'] = 'bankovní účet', - ['black_money'] = 'špinavé peníze', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'akce není možná', ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', @@ -76,7 +74,6 @@ Locales['cs'] = { ['chat_clear_all'] = 'vyčistit chat pro všechny', ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/de.lua b/locales/de.lua index 44f23ed0..61f77920 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -1,6 +1,5 @@ Locales['de'] = { -- Inventory - ['cash'] = 'bargeld', ['inventory'] = 'inventar %s / %s', ['use'] = 'benutzen', ['give'] = 'geben', @@ -23,8 +22,6 @@ Locales['de'] = { ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx %s~s~ von ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ hat versucht dir eine(n) ~y~%s~s~ zu geben, aber du hast bereits eine(n)', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_money'] = 'du gibst ~g~$%s~s~ an ~y~%s~s~', - ['received_money'] = 'du erhälst ~g~$%s~s~ von ~b~%s~s~', ['gave_account_money'] = 'du gibst ~g~$%s~s~ (%s) an ~y~%s~s~', ['received_account_money'] = 'du empfängst ~g~$%s~s~ (%s) von ~b~%s~s~', ['amount_invalid'] = 'ungültiger Betrag', @@ -33,7 +30,6 @@ Locales['de'] = { ['imp_invalid_quantity'] = 'aktion nicht möglich, ungültige Anzahl', ['imp_invalid_amount'] = 'aktion nicht möglich, ungültiger Betrag', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['de'] = { ['company_nomoney'] = 'die Firma in der du angestellt bist, ist zu arm um dein Gehalt zu zahlen', ['received_paycheck'] = 'erhaltener Gehaltsscheck', ['bank'] = 'bank', - ['black_money'] = 'schwarzgeld', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'Aktion nicht möglich', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', @@ -75,7 +73,6 @@ Locales['de'] = { ['chat_clear_all'] = 'clear the chat for everyone', ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/en.lua b/locales/en.lua index 73ad1b84..44c4c680 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -1,6 +1,5 @@ Locales['en'] = { -- Inventory - ['cash'] = 'cash', ['inventory'] = 'inventory %s / %s', ['use'] = 'use', ['give'] = 'give', @@ -23,8 +22,6 @@ Locales['en'] = { ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_money'] = 'you gave ~g~$%s~s~ to ~y~%s~s~', - ['received_money'] = 'you received ~g~$%s~s~ from ~b~%s~s~', ['gave_account_money'] = 'you gave ~g~$%s~s~ (%s) to ~y~%s~s~', ['received_account_money'] = 'you received ~g~$%s~s~ (%s) from ~b~%s~s~', ['amount_invalid'] = 'invalid amount', @@ -33,7 +30,6 @@ Locales['en'] = { ['imp_invalid_quantity'] = 'action impossible, invalid quantity', ['imp_invalid_amount'] = 'action impossible, invalid amount', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['en'] = { ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary', ['received_paycheck'] = 'received paycheck', ['bank'] = 'maze Bank', - ['black_money'] = 'dirty Money', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', @@ -75,7 +73,6 @@ Locales['en'] = { ['chat_clear_all'] = 'clear the chat for everyone', ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ',', diff --git a/locales/fi.lua b/locales/fi.lua index e996ad77..6e113511 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -1,6 +1,5 @@ Locales['fi'] = { -- Inventory - ['cash'] = 'käteinen', ['inventory'] = 'reppu %s / %s', ['use'] = 'käytä', ['give'] = 'anna', @@ -23,8 +22,6 @@ Locales['fi'] = { ['received_weapon_withammo'] = 'you received ~y~1x~s~ ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', - ['gave_money'] = 'sinä annoit ~g~$%s~s~ henkilölle ~y~%s~s~', - ['received_money'] = 'sinä sait ~g~$%s~s~ henkilöltä ~b~%s~s~', ['gave_account_money'] = 'sinä annoit ~g~$%s~s~ (%s) henkilölle ~y~%s~s~', ['received_account_money'] = 'sinä sait ~g~$%s~s~ (%s) henkilöltä ~b~%s~s~', ['amount_invalid'] = 'virheellinen määrä', @@ -33,7 +30,6 @@ Locales['fi'] = { ['imp_invalid_quantity'] = 'toiminto mahdoton, virheellinen määrä', ['imp_invalid_amount'] = 'toiminto mahdoton, virhellinen summa', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'you threw ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'you threw ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'you threw ~y~1x~s~ ~b~%s~s~ with ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['fi'] = { ['company_nomoney'] = 'yritys jolle teet töitä on köyhä eikä voi maksaa palkkaasi', ['received_paycheck'] = 'sait palkan', ['bank'] = 'pankki', - ['black_money'] = 'likainen Raha', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'toiminto mahdoton', ['in_vehicle'] = 'et voi antaa ajoneuvossa olevalle mitään', @@ -75,7 +73,6 @@ Locales['fi'] = { ['chat_clear_all'] = 'tyhjennä chatti kaikilta', ['command_clearinventory'] = 'clear all items from inventory', ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/fr.lua b/locales/fr.lua index 3483566a..0295f845 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -1,6 +1,5 @@ Locales['fr'] = { -- Inventory - ['cash'] = 'espèces', ['inventory'] = 'inventaire %s / %s', ['use'] = 'utiliser', ['give'] = 'donner', @@ -23,8 +22,6 @@ Locales['fr'] = { ['received_weapon_withammo'] = 'vous avez reçu ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~ de ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ a tenté de vous donner ~y~%s~s~, mais vous en aviez déjà un exemplaire', ['received_weapon_noweapon'] = '~b~%s~s~ tente de vous donner des munitions pour ~y~%s~s~, mais vous n\'en avez pas', - ['gave_money'] = 'vous avez donné ~g~$%s~s~ à ~y~%s~s~', - ['received_money'] = 'vous avez reçu ~g~$%s~s~ par ~b~%s~s~', ['gave_account_money'] = 'vous avez donné ~g~$%s~s~ (%s) à ~y~%s~s~', ['received_account_money'] = 'vous avez reçu ~g~$%s~s~ (%s) par ~b~%s~s~', ['amount_invalid'] = 'montant invalide', @@ -33,7 +30,6 @@ Locales['fr'] = { ['imp_invalid_quantity'] = 'action impossible, ~r~quantité invalide', ['imp_invalid_amount'] = 'action impossible, ~r~montant invalide', ['threw_standard'] = 'vous avez jeté ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'vous avez jeté ~g~$%s~s~ ~b~cash~s~', ['threw_account'] = 'vous avez jeté ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~', ['threw_weapon_ammo'] = 'vous avez jeté ~y~1x~s~ ~b~%s~s~ avec ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['fr'] = { ['company_nomoney'] = 'votre entreprise n\'a plus d\'argent pour vous payer!', ['received_paycheck'] = 'paiement reçu', ['bank'] = 'banque', - ['black_money'] = 'argent sale', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', @@ -75,7 +73,6 @@ Locales['fr'] = { ['chat_clear_all'] = 'vider le chat pour tous le monde', ['command_clearinventory'] = 'effacer tout les items de l\'inventaire', ['command_clearloadout'] = 'retirer toutes les armes de l\'équipement', - ['command_playerid_param'] = 'spécifiez un playerid ou laissez vide pour vous-même', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/pl.lua b/locales/pl.lua index 4cdfe07e..a691437a 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -1,6 +1,5 @@ Locales['pl'] = { -- Inventory - ['cash'] = 'gotówka', ['inventory'] = 'ekwipunek %s / %s', ['use'] = 'użyj', ['give'] = 'daj', @@ -23,8 +22,6 @@ Locales['pl'] = { ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx %s~s~ od ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', ['received_weapon_noweapon'] = '~b~%s~s~ próbował/a przekazać ci amunicje do ~y~%s~s~, lecz nie posiadasz tej broni', - ['gave_money'] = 'dajesz ~g~%s$~s~ dla ~y~%s~s~', - ['received_money'] = 'otrzymujesz ~g~%s$~s~ od ~b~%s~s~', ['gave_account_money'] = 'dajesz ~g~%s$~s~ (%s) dla ~y~%s~s~', ['received_account_money'] = 'otrzymujesz ~g~%s$~s~ (%s) od ~b~%s~s~', ['amount_invalid'] = 'nieprawidłowa ilość', @@ -33,7 +30,6 @@ Locales['pl'] = { ['imp_invalid_quantity'] = 'akcja jest niemożliwa, nieprawidłowa ilość', ['imp_invalid_amount'] = 'akcja jest niemożliwa, nieprawidłowa kwota', ['threw_standard'] = 'wyrzuciłeś/aś ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~gotówki~s~', ['threw_account'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx %s~s~', @@ -44,14 +40,16 @@ Locales['pl'] = { -- Key mapping ['keymap_showinventory'] = 'show Inventory', - -- Salary related ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', ['company_nomoney'] = 'firma, w której pracujesz, jest zbyt biedna, by wypłacić twoją pensję', ['received_paycheck'] = 'otrzymana wypłata', ['bank'] = 'bank', - ['black_money'] = 'brudne pieniądze', + ['account_bank'] = 'bank', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', + ['act_imp'] = 'działanie niemożliwe', ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', @@ -75,7 +73,6 @@ Locales['pl'] = { ['chat_clear_all'] = 'wyczyść czat dla wszystkich', ['command_clearinventory'] = 'usuń wszystkie przedmioty z ekwipunku', ['command_clearloadout'] = 'usuń wszystkie bronie z wyposażenia', - ['command_playerid_param'] = 'id gracza lub zostaw puste dla siebie', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/sv.lua b/locales/sv.lua index 1f23cbc4..8be097c6 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -1,6 +1,5 @@ Locales['sv'] = { -- Inventory - ['cash'] = 'kontanter', ['inventory'] = 'mitt förråd %s / %s', ['use'] = 'använd', ['give'] = 'ge', @@ -23,8 +22,6 @@ Locales['sv'] = { ['received_weapon_withammo'] = 'du tog emot ~b~%s~s~ med ~o~%sx %s~s~ från ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ försökte ge dig en ~y~%s~s~, men det vapnet har du redan', ['received_weapon_noweapon'] = '~b~%s~s~ försökte ge dig ammunition för ett ~y~%s~s~, men du har inget sådant vapen', - ['gave_money'] = 'du gav ~g~%s SEK~s~ till ~y~%s~s~', - ['received_money'] = 'du tog emot ~g~%s SEK~s~ från ~b~%s~s~', ['gave_account_money'] = 'du gav ~g~%s SEK~s~ (%s) till ~y~%s~s~', ['received_account_money'] = 'du tog emot ~g~%s SEK~s~ (%s) från ~b~%s~s~', ['amount_invalid'] = 'ogiltig mängd', @@ -33,7 +30,6 @@ Locales['sv'] = { ['imp_invalid_quantity'] = 'åtgärd omöjlig, ogiltig mängd', ['imp_invalid_amount'] = 'åtgärd omöjlig, ogiltig belopp', ['threw_standard'] = 'du kastade ~y~%sx~s~ ~b~%s~s~', - ['threw_money'] = 'du kastade ~g~%s SEK~s~ ~b~kontanter~s~', ['threw_account'] = 'du kastade ~g~%s SEK~s~ ~b~%s~s~', ['threw_weapon'] = 'du kastade ~b~%s~s~', ['threw_weapon_ammo'] = 'du kastade ~b~%s~s~ med ~o~%sx %s~s~', @@ -50,7 +46,9 @@ Locales['sv'] = { ['company_nomoney'] = 'företaget du är anställt hos har inte råd att betala ut din lön', ['received_paycheck'] = 'mottagit lön', ['bank'] = 'bank', - ['black_money'] = 'svarta pengar', + ['account_bank'] = 'bank', + ['account_black_money'] = 'svarta pengar', + ['account_money'] = 'kontakter', ['act_imp'] = 'åtgärd omöjlig', ['in_vehicle'] = 'du kan inte ge saker till en som sitter i ett fordon!', @@ -59,7 +57,7 @@ Locales['sv'] = { ['setjob'] = 'tilldela ett jobb till en spelare', ['id_param'] = 'spelarens ID', ['setjob_param2'] = 'det jobb du vill tilldela', - ['setjob_param3'] = 'job level', + ['setjob_param3'] = 'job nivå', ['spawn_car'] = 'spawna ett fordon', ['spawn_car_param'] = 'namn på fordon', ['delete_vehicle'] = 'ta bort fordon', @@ -68,14 +66,13 @@ Locales['sv'] = { ['giveaccountmoney'] = 'ge spelarkonto pengar', ['invalid_item'] = 'ogiltigt föremål', ['item'] = 'föremål', - ['giveitem'] = 'ge föremål', + ['giveitem'] = 'ge ett föremål', ['weapon'] = 'vapen', - ['giveweapon'] = 'ge vapen', + ['giveweapon'] = 'ge ett vapen', ['chat_clear'] = 'töm chatten', ['chat_clear_all'] = 'töm chatten för alla', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', - ['command_playerid_param'] = 'specify playerId or leave blank for yourself', + ['command_clearinventory'] = 'töm en spelares inventory', + ['command_clearloadout'] = 'töm en spelares loadout', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/server/classes/player.lua b/server/classes/player.lua index d5035e09..4a41d30b 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -1,41 +1,32 @@ -function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, coords) +function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, job, loadout, name, coords) local self = {} - self.player = player - self.accounts = accounts + self.accounts = accounts self.inventory = inventory - self.job = job - self.loadout = loadout - self.name = name + self.job = job + self.group = group + self.loadout = loadout + self.name = name self.maxWeight = Config.MaxWeight - self.coords = coords + self.coords = coords + self.variables = {} + self.source = playerId + self.playerId = playerId + self.identifier = identifier - self.source = self.player.get('source') - self.identifier = self.player.get('identifier') + ExecuteCommand(('add_principal identifier.license:%s group.%s'):format(self.identifier, self.group)) self.triggerEvent = function(eventName, ...) TriggerClientEvent(eventName, self.source, ...) end - self.setMoney = function(money) - money = ESX.Math.Round(money) - - if money >= 0 then - self.player.setMoney(money) - end - end - - self.getMoney = function() - return self.player.get('money') - end - self.setCoords = function(coords) self.updateCoords(coords) self.triggerEvent('esx:teleport', coords) end self.updateCoords = function(coords) - self.coords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1), heading = ESX.Math.Round(coords.heading, 1)} + self.coords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1), heading = ESX.Math.Round(coords.heading or 0.0, 1)} end self.getCoords = function(vector) @@ -50,78 +41,52 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c DropPlayer(self.source, reason) end + self.setMoney = function(money) + money = ESX.Math.Round(money) + self.setAccountMoney('money', money) + end + + self.getMoney = function() + return self.getAccount('money').money + end + self.addMoney = function(money) money = ESX.Math.Round(money) - - if money >= 0 then - self.player.addMoney(money) - end + self.addAccountMoney('money', money) end self.removeMoney = function(money) money = ESX.Math.Round(money) - - if money > 0 then - self.player.removeMoney(money) - end - end - - self.displayMoney = function(money) - self.player.displayMoney(money) + self.removeAccountMoney('money', money) end self.getIdentifier = function() - return self.player.getIdentifier() + return self.identifier + end + + self.setGroup = function(newGroup) + ExecuteCommand(('remove_principal identifier.license:%s group.%s'):format(self.identifier, self.group)) + self.group = newGroup + ExecuteCommand(('add_principal identifier.license:%s group.%s'):format(self.identifier, self.group)) end self.getGroup = function() - return self.player.getGroup() + return self.group end self.set = function(k, v) - self.player.set(k, v) + self.variables[k] = v end self.get = function(k) - return self.player.get(k) - end - - self.getPlayer = function() - return self.player + return self.variables[k] end self.getAccounts = function() - local accounts = {} - - for k,account in ipairs(Config.Accounts) do - if account == 'bank' then - table.insert(accounts, { - name = 'bank', - money = self.get('bank'), - label = Config.AccountLabels.bank - }) - else - for k2,v2 in ipairs(self.accounts) do - if v2.name == account then - table.insert(accounts, v2) - break - end - end - end - end - - return accounts + return self.accounts end self.getAccount = function(account) - if account == 'bank' then - return { - name = 'bank', - money = self.get('bank'), - label = Config.AccountLabels.bank - } - end - for k,v in ipairs(self.accounts) do if v.name == account then return v @@ -162,36 +127,29 @@ function CreateExtendedPlayer(player, accounts, inventory, job, loadout, name, c end self.getMissingAccounts = function(cb) - MySQL.Async.fetchAll('SELECT name FROM user_accounts WHERE identifier = @identifier', { - ['@identifier'] = self.getIdentifier() - }, function(result) - local missingAccounts = {} + local missingAccounts = {} - for k,v in ipairs(Config.Accounts) do - if v ~= 'bank' then - local found = false + for account,label in pairs(Config.Accounts) do + local found = false - for k2,v2 in ipairs(result) do - if v == v2.name then - found = true - break - end - end - - if not found then - table.insert(missingAccounts, v) - end + for k2,v2 in ipairs(self.accounts) do + if account == v2.name then + found = true end end - cb(missingAccounts) - end) + if not found then + table.insert(missingAccounts, account) + end + end + + cb(missingAccounts) end - self.createAccounts = function(missingAccounts, cb) + self.createMissingAccounts = function(missingAccounts, cb) for k,v in ipairs(missingAccounts) do MySQL.Async.execute('INSERT INTO user_accounts (identifier, name) VALUES (@identifier, @name)', { - ['@identifier'] = self.getIdentifier(), + ['@identifier'] = self.identifier, ['@name'] = v }, function(rowsChanged) if cb then diff --git a/server/commands.lua b/server/commands.lua index dea5e1ee..23892beb 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -1,259 +1,111 @@ -TriggerEvent('es:addGroupCommand', 'tp', 'admin', function(source, args, user) - local x = tonumber(args[1]) - local y = tonumber(args[2]) - local z = tonumber(args[3]) - - if x and y and z then - TriggerClientEvent('esx:teleport', source, { - x = x, - y = y, - z = z - }) - else - TriggerClientEvent('chatMessage', source, 'SYSTEM', {255, 0, 0}, 'Invalid coordinates!') - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = 'Teleport to coordinates', params = { - {name = 'x', help = 'X coords'}, - {name = 'y', help = 'Y coords'}, - {name = 'z', help = 'Z coords'} +ESX.RegisterCommand('setcoords', 'admin', function(xPlayer, args, showError) + xPlayer.setCoords({x = args.x, y = args.y, z = args.z}) +end, false, {help = 'Teleport to coordinates', validate = true, arguments = { + {name = 'x', help = 'X coords', type = 'number'}, + {name = 'y', help = 'Y coords', type = 'number'}, + {name = 'z', help = 'Z coords', type = 'number'} }}) -TriggerEvent('es:addGroupCommand', 'setjob', 'admin', function(source, args, user) - if tonumber(args[1]) and args[2] and tonumber(args[3]) then - local xPlayer = ESX.GetPlayerFromId(args[1]) +ESX.RegisterCommand('setjob', 'admin', function(xPlayer, args, showError) + if ESX.DoesJobExist(args.job, args.grade) then + args.playerId.setJob(args.job, args.grade) + else + showError('That job does not exist') + end +end, true, {help = _U('setjob'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'}, + {name = 'job', help = _U('setjob_param2'), type = 'string'}, + {name = 'grade', help = _U('setjob_param3'), type = 'number'} +}}) - if xPlayer then - if ESX.DoesJobExist(args[2], args[3]) then - xPlayer.setJob(args[2], args[3]) +ESX.RegisterCommand('car', 'admin', function(xPlayer, args, showError) + xPlayer.triggerEvent('esx:spawnVehicle', args.car) +end, false, {help = _U('spawn_car'), validate = false, arguments = { + {name = 'car', help = _U('spawn_car_param'), type = 'any'} +}}) + +ESX.RegisterCommand({'cardel', 'dv'}, 'admin', function(xPlayer, args, showError) + xPlayer.triggerEvent('esx:deleteVehicle', args.radius) +end, false, {help = _U('spawn_car'), validate = false, arguments = { + {name = 'radius', help = 'Optional, delete every vehicle within the specified radius', type = 'any'} +}}) + +ESX.RegisterCommand('giveaccountmoney', 'admin', function(xPlayer, args, showError) + if args.playerId.getAccount(args.account) then + args.playerId.addAccountMoney(args.account, args.amount) + else + showError(_U('invalid_account')) + end +end, true, {help = _U('giveaccountmoney'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'}, + {name = 'account', help = _U('account'), type = 'string'}, + {name = 'amount', help = _U('money_amount'), type = 'number'} +}}) + +ESX.RegisterCommand('giveitem', 'admin', function(xPlayer, args, showError) + args.playerId.addInventoryItem(args.item, args.count) +end, true, {help = _U('giveitem'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'}, + {name = 'item', help = _U('item'), type = 'item'}, + {name = 'count', help = _U('amount'), type = 'number'} +}}) + +ESX.RegisterCommand('giveweapon', 'admin', function(xPlayer, args, showError) + if args.playerId.hasWeapon(args.weapon) then + showError('Player already has that weapon') + else + xPlayer.addWeapon(args.weapon, args.ammo) + end +end, true, {help = _U('giveweapon'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'}, + {name = 'weapon', help = _U('weapon'), type = 'weapon'}, + {name = 'ammo', help = _U('amountammo'), type = 'number'} +}}) + +ESX.RegisterCommand('giveweaponcomponent', 'admin', function(xPlayer, args, showError) + if args.playerId.hasWeapon(args.weaponName) then + local component = ESX.GetWeaponComponent(args.weaponName, args.componentName) + + if component then + if xPlayer.hasWeaponComponent(args.weaponName, args.componentName) then + showError('Player already has that weapon component') else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'That job does not exist.' } }) + xPlayer.addWeaponComponent(args.weaponName, args.componentName) end else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) + showError('Invalid weapon component') end else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid usage.' } }) + showError('Player does not have that weapon') end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('setjob'), params = { - {name = 'playerId', help = _U('id_param')}, - {name = 'job', help = _U('setjob_param2')}, - {name = 'grade_id', help = _U('setjob_param3')} +end, true, {help = 'Give weapon component', validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'}, + {name = 'weaponName', help = _U('weapon'), type = 'weapon'}, + {name = 'componentName', help = 'weapon component', type = 'string'} }}) -TriggerEvent('es:addGroupCommand', 'car', 'admin', function(source, args, user) - TriggerClientEvent('esx:spawnVehicle', source, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('spawn_car'), params = {{name = 'car', help = _U('spawn_car_param')}}}) +ESX.RegisterCommand({'clear', 'cls'}, 'user', function(xPlayer, args, showError) + xPlayer.triggerEvent('chat:clear') +end, false, {help = _U('chat_clear')}) -TriggerEvent('es:addGroupCommand', 'cardel', 'admin', function(source, args, user) - TriggerClientEvent('esx:deleteVehicle', source, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('delete_vehicle'), params = { - {name = 'radius', help = 'Optional, delete every vehicle within the specified radius'} -}}) - -TriggerEvent('es:addGroupCommand', 'dv', 'admin', function(source, args, user) - TriggerClientEvent('esx:deleteVehicle', source, args[1]) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('delete_vehicle'), params = { - {name = 'radius', help = 'Optional, delete every vehicle within the specified radius'} -}}) - -TriggerEvent('es:addGroupCommand', 'giveaccountmoney', 'admin', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[1]) - - if xPlayer then - local account = args[2] - local amount = tonumber(args[3]) - - if amount then - if account == 'cash' then - xPlayer.addMoney(amount) - elseif xPlayer.getAccount(account) then - xPlayer.addAccountMoney(account, amount) - else - TriggerClientEvent('esx:showNotification', source, _U('invalid_account')) - end - else - TriggerClientEvent('esx:showNotification', source, _U('amount_invalid')) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveaccountmoney'), params = { - {name = 'playerId', help = _U('id_param')}, - {name = 'account', help = _U('account')}, - {name = 'amount', help = _U('money_amount')} -}}) - -TriggerEvent('es:addGroupCommand', 'giveitem', 'admin', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[1]) - - if xPlayer then - local item = args[2] - local count = tonumber(args[3]) - - if count then - if xPlayer.getInventoryItem(item) then - xPlayer.addInventoryItem(item, count) - else - TriggerClientEvent('esx:showNotification', source, _U('invalid_item')) - end - else - TriggerClientEvent('esx:showNotification', source, _U('invalid_amount')) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveitem'), params = { - {name = 'playerId', help = _U('id_param')}, - {name = 'item', help = _U('item')}, - {name = 'amount', help = _U('amount')} -}}) - -TriggerEvent('es:addGroupCommand', 'giveweapon', 'admin', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[1]) - - if xPlayer then - local weaponName = args[2] or 'unknown' - - if ESX.GetWeapon(weaponName) then - weaponName = string.upper(weaponName) - - if xPlayer.hasWeapon(weaponName) then - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon.' } }) - else - if tonumber(args[3]) then - xPlayer.addWeapon(weaponName, tonumber(args[3])) - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid ammo amount.' } }) - end - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon.' } }) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('giveweapon'), params = { - {name = 'playerId', help = _U('id_param')}, - {name = 'weapon', help = _U('weapon')}, - {name = 'ammo', help = _U('amountammo')} -}}) - -TriggerEvent('es:addGroupCommand', 'giveweaponcomponent', 'admin', function(source, args, user) - local xPlayer = ESX.GetPlayerFromId(args[1]) - - if xPlayer then - local weaponName = args[2] or 'unknown' - - if ESX.GetWeapon(weaponName) then - weaponName = string.upper(weaponName) - - if xPlayer.hasWeapon(weaponName) then - local component = ESX.GetWeaponComponent(weaponName, args[3] or 'unknown') - - if component then - if xPlayer.hasWeaponComponent(weaponName, args[3]) then - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player already has that weapon component.' } }) - else - xPlayer.addWeaponComponent(weaponName, args[3]) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon component.' } }) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player does not have that weapon.' } }) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Invalid weapon.' } }) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = 'Give weapon component', params = { - {name = 'playerId', help = _U('id_param')}, - {name = 'weaponName', help = _U('weapon')}, - {name = 'componentName', help = 'weapon component'} -}}) - -TriggerEvent('es:addGroupCommand', 'clear', 'user', function(source, args, user) - TriggerClientEvent('chat:clear', source) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('chat_clear')}) - -TriggerEvent('es:addGroupCommand', 'cls', 'user', function(source, args, user) - TriggerClientEvent('chat:clear', source) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end) - -TriggerEvent('es:addGroupCommand', 'clsall', 'admin', function(source, args, user) +ESX.RegisterCommand({'clearall', 'clsall'}, 'admin', function(xPlayer, args, showError) TriggerClientEvent('chat:clear', -1) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end) +end, false, {help = _U('chat_clear_all')}) -TriggerEvent('es:addGroupCommand', 'clearall', 'admin', function(source, args, user) - TriggerClientEvent('chat:clear', -1) -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('chat_clear_all')}) - -TriggerEvent('es:addGroupCommand', 'clearinventory', 'admin', function(source, args, user) - local xPlayer - - if args[1] then - xPlayer = ESX.GetPlayerFromId(args[1]) - else - xPlayer = ESX.GetPlayerFromId(source) - end - - if xPlayer then - for i=1, #xPlayer.inventory, 1 do - if xPlayer.inventory[i].count > 0 then - xPlayer.setInventoryItem(xPlayer.inventory[i].name, 0) - end +ESX.RegisterCommand('clearinventory', 'admin', function(xPlayer, args, showError) + for k,v in ipairs(args.playerId.inventory) do + if v.count > 0 then + args.playerId.setInventoryItem(v.name, 0) end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('command_clearinventory'), params = {{name = 'playerId', help = _U('command_playerid_param')}}}) +end, true, {help = _U('command_clearinventory'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'} +}}) -TriggerEvent('es:addGroupCommand', 'clearloadout', 'admin', function(source, args, user) - local xPlayer - - if args[1] then - xPlayer = ESX.GetPlayerFromId(args[1]) - else - xPlayer = ESX.GetPlayerFromId(source) +ESX.RegisterCommand('clearloadout', 'admin', function(xPlayer, args, showError) + for k,v in ipairs(args.playerId.loadout) do + args.playerId.removeWeapon(v.name) end - - if xPlayer then - for i=#xPlayer.loadout, 1, -1 do - xPlayer.removeWeapon(xPlayer.loadout[i].name) - end - else - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Player not online.' } }) - end -end, function(source, args, user) - TriggerClientEvent('chat:addMessage', source, { args = { '^1SYSTEM', 'Insufficient Permissions.' } }) -end, {help = _U('command_clearloadout'), params = {{name = 'playerId', help = _U('command_playerid_param')}}}) +end, true, {help = _U('command_clearloadout'), validate = true, arguments = { + {name = 'playerId', help = _U('id_param'), type = 'player'} +}}) diff --git a/server/common.lua b/server/common.lua index e2496d75..b9d5f601 100644 --- a/server/common.lua +++ b/server/common.lua @@ -9,6 +9,7 @@ ESX.LastPlayerData = {} ESX.Pickups = {} ESX.PickupId = 0 ESX.Jobs = {} +ESX.RegisteredCommands = {} AddEventHandler('esx:getSharedObject', function(cb) cb(ESX) @@ -58,21 +59,14 @@ MySQL.ready(function() end) AddEventHandler('esx:playerLoaded', function(playerId) - local xPlayer, accounts, items = ESX.GetPlayerFromId(playerId), {}, {} - local xPlayerAccounts, xPlayerItems = xPlayer.getAccounts(), xPlayer.getInventory() + local xPlayer, accounts = ESX.GetPlayerFromId(playerId), {} + local xPlayerAccounts = xPlayer.getAccounts() for i=1, #xPlayerAccounts, 1 do accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money end - for i=1, #xPlayerItems, 1 do - items[xPlayerItems[i].name] = xPlayerItems[i].count - end - - ESX.LastPlayerData[playerId] = { - accounts = accounts, - items = items - } + ESX.LastPlayerData[playerId] = {accounts = accounts} end) RegisterServerEvent('esx:clientLog') diff --git a/server/functions.lua b/server/functions.lua index 83c2debc..6cfd5860 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -20,6 +20,115 @@ ESX.SetTimeout = function(msec, cb) return id end +ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) + if type(name) == 'table' then + for k,v in ipairs(name) do + ESX.RegisterCommand(v, group, cb, allowConsole, suggestion) + end + + return + end + + if ESX.RegisteredCommands[name] then + print(('[es_extended] [^3WARNING^7] An command "%s" is already registered'):format(name)) + else + if suggestion then + if not suggestion.arguments then suggestion.arguments = {} end + if not suggestion.help then suggestion.help = '' end + end + + ESX.RegisteredCommands[name] = {group = group, cb = cb, allowConsole = allowConsole, suggestion = suggestion} + + RegisterCommand(name, function(playerId, args, rawCommand) + local command = ESX.RegisteredCommands[name] + + if not command.allowConsole and playerId == 0 then + print('[es_extended] [^3WARNING^7] That command can not be run from console') + else + local xPlayer, error = ESX.GetPlayerFromId(playerId), nil + + if command.suggestion then + if command.suggestion.validate then + if #args ~= #command.suggestion.arguments then + error = ('Argument count mismatch (passed %s, wanted %s)'):format(#args, #command.suggestion.arguments) + end + end + + if not error and command.suggestion.arguments then + local newArgs = {} + + for k,v in ipairs(command.suggestion.arguments) do + if v.type then + if v.type == 'number' then + local newArg = tonumber(args[k]) + + if newArg then + newArgs[v.name] = newArg + else + error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + end + elseif v.type == 'player' then + local targetPlayer = tonumber(args[k]) + + if targetPlayer then + local xTargetPlayer = ESX.GetPlayerFromId(targetPlayer) + + if xTargetPlayer then + newArgs[v.name] = xTargetPlayer + else + error = 'Player not online' + end + else + error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + end + elseif v.type == 'string' then + newArgs[v.name] = args[k] + elseif v.type == 'item' then + if ESX.Items[args[k]] then + newArgs[v.name] = args[k] + else + error = _U('invalid_item') + end + elseif v.type == 'weapon' then + if ESX.GetWeapon(args[k]) then + newArgs[v.name] = string.upper(args[k]) + else + error = 'Invalid weapon' + end + elseif v.type == 'any' then + newArgs[v.name] = args[k] + end + end + + if error then break end + end + + args = newArgs + end + end + + if error then + if playerId == 0 then + print(('[es_extended] [^3WARNING^7] %s^7'):format(error)) + else + xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', error}}) + end + else + cb(xPlayer, args, function(msg) + if playerId == 0 then + print(('[es_extended] [^3WARNING^7] %s^7'):format(msg)) + else + xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', msg}}) + end + end) + end + end + end, true) + + ExecuteCommand(('add_ace group.%s command.%s allow'):format(group, name)) + end +end + ESX.ClearTimeout = function(id) ESX.CancelledTimeouts[id] = true end @@ -44,9 +153,9 @@ ESX.SavePlayer = function(xPlayer, cb) if ESX.LastPlayerData[xPlayer.source].accounts[v.name] ~= v.money then table.insert(asyncTasks, function(cb) MySQL.Async.execute('UPDATE user_accounts SET money = @money WHERE identifier = @identifier AND name = @name', { - ['@money'] = v.money, + ['@money'] = v.money, ['@identifier'] = xPlayer.identifier, - ['@name'] = v.name + ['@name'] = v.name }, function(rowsChanged) cb() end) diff --git a/server/main.lua b/server/main.lua index d079ded5..38bd8926 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,4 +1,38 @@ -AddEventHandler('es:playerLoaded', function(playerId, player) +RegisterNetEvent('esx:playerJoined') +AddEventHandler('esx:playerJoined', function() + onPlayerJoined(source) +end) + +function onPlayerJoined(playerId) + local identifier + + for k,v in ipairs(GetPlayerIdentifiers(playerId)) do + if string.match(v, 'license:') then + identifier = string.sub(v, 9) + break + end + end + + if identifier then + MySQL.Async.fetchScalar('SELECT 1 FROM users WHERE identifier = @identifier', { + ['@identifier'] = identifier + }, function(result) + if result then + loadESXPlayer(identifier, playerId) + else + MySQL.Async.execute('INSERT INTO users (identifier) VALUES (@identifier)', { + ['@identifier'] = identifier + }, function(rowsChanged) + loadESXPlayer(identifier, playerId) + end) + end + end) + else + DropPlayer(playerId, 'Your Rockstar license could not be found') + end +end + +function loadESXPlayer(identifier, playerId) local tasks = {} local userData = { @@ -6,22 +40,20 @@ AddEventHandler('es:playerLoaded', function(playerId, player) inventory = {}, job = {}, loadout = {}, - playerName = GetPlayerName(playerId), - coords = nil + playerName = GetPlayerName(playerId) } - -- Get accounts + -- get accounts table.insert(tasks, function(cb) MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() + ['@identifier'] = identifier }, function(accounts) - local validAccounts = ESX.Table.Set(Config.Accounts) for k,v in ipairs(accounts) do - if validAccounts[v.name] then + if Config.Accounts[v.name] then table.insert(userData.accounts, { name = v.name, money = v.money, - label = Config.AccountLabels[v.name] + label = Config.Accounts[v.name] }) end end @@ -30,147 +62,120 @@ AddEventHandler('es:playerLoaded', function(playerId, player) end) end) - -- Get job and loadout table.insert(tasks, function(cb) + MySQL.Async.fetchAll('SELECT job, job_grade, `group`, loadout, position, inventory FROM users WHERE identifier = @identifier', { + ['@identifier'] = identifier + }, function(result) + local job, grade, jobObject, gradeObject = result[1].job, tostring(result[1].job_grade) - local tasks2 = {} + if ESX.DoesJobExist(job, grade) then + jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + else + print(('[es_extended] [^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(identifier, job, grade)) + job, grade = 'unemployed', '0' + jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + end - -- Get job name, grade and coords - table.insert(tasks2, function(cb2) + userData.job = {} - MySQL.Async.fetchAll('SELECT job, job_grade, loadout, position, inventory FROM users WHERE identifier = @identifier', { - ['@identifier'] = player.getIdentifier() - }, function(result) - local job, grade = result[1].job, tostring(result[1].job_grade) + userData.job.id = jobObject.id + userData.job.name = jobObject.name + userData.job.label = jobObject.label - if ESX.DoesJobExist(job, grade) then - local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] + userData.job.grade = tonumber(grade) + userData.job.grade_name = gradeObject.name + userData.job.grade_label = gradeObject.label + userData.job.grade_salary = gradeObject.salary - userData.job = {} + userData.job.skin_male = {} + userData.job.skin_female = {} - userData.job.id = jobObject.id - userData.job.name = jobObject.name - userData.job.label = jobObject.label + if gradeObject.skin_male then userData.job.skin_male = json.decode(gradeObject.skin_male) end + if gradeObject.skin_female then userData.job.skin_female = json.decode(gradeObject.skin_female) end - userData.job.grade = tonumber(grade) - userData.job.grade_name = gradeObject.name - userData.job.grade_label = gradeObject.label - userData.job.grade_salary = gradeObject.salary + local foundItems = {} - userData.job.skin_male = {} - userData.job.skin_female = {} + if result[1].inventory and result[1].inventory ~= '' then + local inventory = json.decode(result[1].inventory) - if gradeObject.skin_male then - userData.job.skin_male = json.decode(gradeObject.skin_male) - end + for name,count in pairs(inventory) do + local item = ESX.Items[name] - if gradeObject.skin_female then - userData.job.skin_female = json.decode(gradeObject.skin_female) - end - else - print(('[es_extended] [^3WARNING^7] Ignoring invalid job for %s [job: %s, grade: %s]'):format(player.getIdentifier(), job, grade)) - - local job, grade = 'unemployed', '0' - local jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] - - userData.job = {} - - userData.job.id = jobObject.id - userData.job.name = jobObject.name - userData.job.label = jobObject.label - - userData.job.grade = tonumber(grade) - userData.job.grade_name = gradeObject.name - userData.job.grade_label = gradeObject.label - userData.job.grade_salary = gradeObject.salary - - userData.job.skin_male = {} - userData.job.skin_female = {} - end - - local foundItems = {} - - if result[1].inventory and result[1].inventory ~= '' then - local inventory = json.decode(result[1].inventory) - - for name,count in pairs(inventory) do - local item = ESX.Items[name] - - if item then - foundItems[name] = count - else - print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(name, player.getIdentifier())) - end + if item then + foundItems[name] = count + else + print(('[es_extended] [^3WARNING^7] Ignoring invalid item "%s" for "%s"'):format(name, identifier)) end end + end - for name,item in pairs(ESX.Items) do - local count = foundItems[name] or 0 + for name,item in pairs(ESX.Items) do + local count = foundItems[name] or 0 - table.insert(userData.inventory, { - name = name, - count = count, - label = item.label, - weight = item.weight, - usable = ESX.UsableItemsCallbacks[name] ~= nil, - rare = item.rare, - canRemove = item.canRemove - }) - end + table.insert(userData.inventory, { + name = name, + count = count, + label = item.label, + weight = item.weight, + usable = ESX.UsableItemsCallbacks[name] ~= nil, + rare = item.rare, + canRemove = item.canRemove + }) + end - table.sort(userData.inventory, function(a,b) - return a.label < b.label - end) + if result[1].group then + userData.group = result[1].group + else + userData.group = 'user' + end - if result[1].loadout then - userData.loadout = json.decode(result[1].loadout) - - -- compatibility with old loadouts - for k,v in ipairs(userData.loadout) do - if not v.components then v.components = {} end - if not v.tintIndex then v.tintIndex = 0 end - end - end - - if result[1].position and result[1].position ~= '' then - userData.coords = json.decode(result[1].position) - else - print('[es_extended] [^3WARNING^7] Column "position" in "users" table is missing required default value. Using backup coords, fix your database.') - userData.coords = {x = -269.4, y = -955.3, z = 31.2, heading = 205.8} - end - - cb2() + table.sort(userData.inventory, function(a, b) + return a.label < b.label end) + if result[1].loadout then + userData.loadout = json.decode(result[1].loadout) + + -- compatibility with old loadouts + for k,v in ipairs(userData.loadout) do + if not v.components then v.components = {} end + if not v.tintIndex then v.tintIndex = 0 end + end + end + + if result[1].position and result[1].position ~= '' then + userData.coords = json.decode(result[1].position) + else + print('[es_extended] [^3WARNING^7] Column "position" in "users" table is missing required default value. Using backup coords, fix your database.') + userData.coords = {x = -269.4, y = -955.3, z = 31.2, heading = 205.8} + end + + cb() 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.coords) + local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords) xPlayer.getMissingAccounts(function(missingAccounts) if #missingAccounts > 0 then - for i=1, #missingAccounts, 1 do + for k,v in ipairs(missingAccounts) do table.insert(xPlayer.accounts, { - name = missingAccounts[i], + name = v, money = 0, - label = Config.AccountLabels[missingAccounts[i]] + label = Config.Accounts[v] }) end - xPlayer.createAccounts(missingAccounts) + xPlayer.createMissingAccounts(missingAccounts) end ESX.Players[playerId] = xPlayer - TriggerEvent('esx:playerLoaded', playerId, xPlayer) xPlayer.triggerEvent('esx:playerLoaded', { identifier = xPlayer.identifier, + money = xPlayer.getMoney(), accounts = xPlayer.getAccounts(), coords = xPlayer.getCoords(), inventory = xPlayer.getInventory(), @@ -180,11 +185,10 @@ AddEventHandler('es:playerLoaded', function(playerId, player) maxWeight = xPlayer.maxWeight }) - xPlayer.displayMoney(xPlayer.getMoney()) xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) end) end) -end) +end AddEventHandler('playerDropped', function(reason) local playerId = source @@ -238,23 +242,13 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo else sourceXPlayer.showNotification(_U('imp_invalid_quantity')) end - elseif type == 'item_money' then - if itemCount > 0 and sourceXPlayer.getMoney() >= itemCount then - sourceXPlayer.removeMoney(itemCount) - targetXPlayer.addMoney (itemCount) - - sourceXPlayer.showNotification(_U('gave_money', ESX.Math.GroupDigits(itemCount), targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_money', ESX.Math.GroupDigits(itemCount), sourceXPlayer.name)) - else - sourceXPlayer.showNotification(_U('imp_invalid_amount')) - end elseif type == 'item_account' then if itemCount > 0 and sourceXPlayer.getAccount(itemName).money >= itemCount then sourceXPlayer.removeAccountMoney(itemName, itemCount) targetXPlayer.addAccountMoney (itemName, itemCount) - sourceXPlayer.showNotification(_U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], targetXPlayer.name)) - targetXPlayer.showNotification(_U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.AccountLabels[itemName], sourceXPlayer.name)) + sourceXPlayer.showNotification(_U('gave_account_money', ESX.Math.GroupDigits(itemCount), Config.Accounts[itemName], targetXPlayer.name)) + targetXPlayer.showNotification(_U('received_account_money', ESX.Math.GroupDigits(itemCount), Config.Accounts[itemName], sourceXPlayer.name)) else sourceXPlayer.showNotification(_U('imp_invalid_amount')) end @@ -328,21 +322,6 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) xPlayer.showNotification(_U('threw_standard', itemCount, xItem.label)) end end - elseif type == 'item_money' then - if itemCount == nil or itemCount < 1 then - xPlayer.showNotification(_U('imp_invalid_amount')) - else - local playerCash = xPlayer.getMoney() - - if (itemCount > playerCash or playerCash < 1) then - xPlayer.showNotification(_U('imp_invalid_amount')) - else - xPlayer.removeMoney(itemCount) - local pickupLabel = ('~y~%s~s~ [~g~%s~s~]'):format(_U('cash'), _U('locale_currency', ESX.Math.GroupDigits(itemCount))) - ESX.CreatePickup('item_money', 'money', itemCount, pickupLabel, playerId) - xPlayer.showNotification(_U('threw_money', ESX.Math.GroupDigits(itemCount))) - end - end elseif type == 'item_account' then if itemCount == nil or itemCount < 1 then xPlayer.showNotification(_U('imp_invalid_amount')) @@ -406,9 +385,6 @@ AddEventHandler('esx:onPickup', function(id) else xPlayer.showNotification(_U('threw_cannot_pickup')) end - elseif pickup.type == 'item_money' then - success = true - xPlayer.addMoney(pickup.count) elseif pickup.type == 'item_account' then success = true xPlayer.addAccountMoney(pickup.name, pickup.count) From d8112af6e6cc92e948795cd93b41be149836c5d1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 15:24:32 +0100 Subject: [PATCH 421/672] Final commit v1.2.0 --- fxmanifest.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fxmanifest.lua b/fxmanifest.lua index f40e04a9..a9fe16ba 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -4,7 +4,7 @@ game 'gta5' description 'ES Extended' -version '1.1.0' +version '1.2.0' server_scripts { '@async/async.lua', From baf7af69b9d50cc765206fe76fb37de0c984c216 Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Mon, 17 Feb 2020 16:04:57 +0100 Subject: [PATCH 422/672] Update fr.lua Welcome new ESX without ES :D --- locales/fr.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 0295f845..9e5bd015 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -46,9 +46,9 @@ Locales['fr'] = { ['company_nomoney'] = 'votre entreprise n\'a plus d\'argent pour vous payer!', ['received_paycheck'] = 'paiement reçu', ['bank'] = 'banque', - ['account_bank'] = 'bank', - ['account_black_money'] = 'dirty Money', - ['account_money'] = 'cash', + ['account_bank'] = 'banque', + ['account_black_money'] = 'argent sale', + ['account_money'] = 'espèces', ['act_imp'] = 'action impossible', ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', @@ -187,12 +187,12 @@ Locales['fr'] = { ['ammo_flaregun'] = 'fusée(s)', -- Weapon Tints - ['tint_default'] = 'default skin', - ['tint_green'] = 'green skin', - ['tint_gold'] = 'gold skin', - ['tint_pink'] = 'pink skin', - ['tint_army'] = 'army skin', - ['tint_lspd'] = 'blue skin', - ['tint_orange'] = 'orange skin', - ['tint_platinum'] = 'platinum skin', + ['tint_default'] = 'skin par défaut', + ['tint_green'] = 'skin vert', + ['tint_gold'] = 'skin doré', + ['tint_pink'] = 'skin rose', + ['tint_army'] = 'skin militaire', + ['tint_lspd'] = 'skin bleu', + ['tint_orange'] = 'skin orange', + ['tint_platinum'] = 'skin platine', } From 056633d88a117849108d53480afc5ca69f79ad5d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 20:27:47 +0100 Subject: [PATCH 423/672] Update README.md --- README.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fd1543f1..ee747927 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # es_extended -es_extended is a roleplay framework for FiveM. It is developed on top of EssentialMode (aka ES), where the project ESX is originating from - the **Es**sentialMode E**x**tended framework for FiveM. +es_extended is a roleplay framework for FiveM. ESX is short for **Es**sentialMode E**x**tended. ## Links & Read more @@ -11,20 +11,18 @@ es_extended is a roleplay framework for FiveM. It is developed on top of Essenti ## Features - Weight based inventory system -- Weapons support, including support for attachments -- Supports different money accounts (defaulted with bank & black money) +- Weapons support, including support for attachments and tints +- Supports different money accounts (defaulted with cash, bank and black money) - Many official resources available in our GitHub - Job system, with grades and clothes support - Supports multiple languages, most strings are localized -- Easy to use API +- Easy to use API for developers to easily integrate ESX to their projects ## Requirements This order also applies in the startup order. - [mysql-async](https://github.com/brouznouf/fivem-mysql-async) -- [essentialmode](https://github.com/kanersps/essentialmode) -- [esplugin_mysql](https://github.com/kanersps/esplugin_mysql) - [async](https://github.com/ESX-Org/async) ## Download & Installation @@ -66,9 +64,6 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list ``` start mysql-async -start essentialmode -start esplugin_mysql - start es_extended start esx_menu_default From b6761d106eecbb9a39cc7245c0803d5266ed1d89 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 20:31:45 +0100 Subject: [PATCH 424/672] Added missing required configuration file modification --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index ee747927..a4e358c1 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,9 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list - Configure your `server.cfg` to look like this ``` +add_ace resource.es_extended command.add_ace allow +add_ace resource.es_extended command.add_principal allow + start mysql-async start es_extended From e822960057213728d06547f9800c07089d062488 Mon Sep 17 00:00:00 2001 From: Raven-RP <45501870+DecodazTV@users.noreply.github.com> Date: Mon, 17 Feb 2020 20:36:31 +0100 Subject: [PATCH 425/672] Improved German translation (#495) * german language update * Update de.lua * Update de.lua requested Change * Update de.lua * Update de.lua * Update de.lua Co-authored-by: Samuel --- locales/de.lua | 138 ++++++++++++++++++++++++------------------------- 1 file changed, 69 insertions(+), 69 deletions(-) diff --git a/locales/de.lua b/locales/de.lua index 61f77920..4ccb00a9 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -6,22 +6,22 @@ Locales['de'] = { ['remove'] = 'entfernen', ['return'] = 'zurück', ['give_to'] = 'geben an', - ['amount'] = 'Betrag', + ['amount'] = 'betrag', ['giveammo'] = 'munition geben', ['amountammo'] = 'anzahl der munition', ['noammo'] = 'du hast keine munition!', ['gave_item'] = 'du gibst ~y~%sx~s~ ~b~%s~s~ an ~y~%s~s~', ['received_item'] = 'du empfängst ~y~%sx~s~ ~b~%s~s~ von ~b~%s~s~', ['gave_weapon'] = 'du gibst ~b~%s~s~ an ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_ammo'] = 'du gibst ~o~%sx %s~s~ von ~b~%s~s~ an ~y~%s~s~', ['gave_weapon_withammo'] = 'du gibst ~b~%s~s~ mit ~o~%sx %s~s~ an ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ hat bereits eine(n) ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', + ['gave_weapon_noweapon'] = '~y~%s~s~ hat diese Waffe nicht', ['received_weapon'] = 'du erhälst ~b~%s~s~ von ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', + ['received_weapon_ammo'] = 'du erhälst ~o~%sx %s~s~ für dein ~b~%s~s~ von ~b~%s~s~', ['received_weapon_withammo'] = 'du erhälst ~b~%s~s~ mit ~o~%sx %s~s~ von ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ hat versucht dir eine(n) ~y~%s~s~ zu geben, aber du hast bereits eine(n)', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['received_weapon_noweapon'] = '~b~%s~s~ ahat versucht dir Munition für eine(n) ~y~%s~s~, aber du besitzt diese Waffe nicht', ['gave_account_money'] = 'du gibst ~g~$%s~s~ (%s) an ~y~%s~s~', ['received_account_money'] = 'du empfängst ~g~$%s~s~ (%s) von ~b~%s~s~', ['amount_invalid'] = 'ungültiger Betrag', @@ -30,15 +30,15 @@ Locales['de'] = { ['imp_invalid_quantity'] = 'aktion nicht möglich, ungültige Anzahl', ['imp_invalid_amount'] = 'aktion nicht möglich, ungültiger Betrag', ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', - ['threw_weapon_already'] = 'you already carry the same weapon', - ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', - ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + ['threw_account'] = 'du wirfst ~g~$%s~s~ ~b~%s~s~ weg', + ['threw_weapon'] = 'du wirfst ~b~%s~s~ weg', + ['threw_weapon_ammo'] = 'du wirfst ~b~%s~s~ mit ~o~%sx %s~s~ weg', + ['threw_weapon_already'] = 'Du hast bereits diese Waffe', + ['threw_cannot_pickup'] = 'Du kannst das nicht aufheben, da dein Inventar voll ist', + ['threw_pickup_prompt'] = 'drücke ~y~E~s~ um aufzuheben', -- Key mapping - ['keymap_showinventory'] = 'show Inventory', + ['keymap_showinventory'] = 'inventar anzeigen', -- Salary related ['received_salary'] = 'du hast dein Gehalt erhalten: ~g~$%s~s~', @@ -51,28 +51,28 @@ Locales['de'] = { ['account_money'] = 'cash', ['act_imp'] = 'Aktion nicht möglich', - ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', + ['in_vehicle'] = 'du kannst keine Items in einem Fahrzeug weitergeben', -- Commands - ['setjob'] = 'assign a job to a user', - ['id_param'] = 'the ID of the player', - ['setjob_param2'] = 'the job you wish to assign', - ['setjob_param3'] = 'the job level', - ['spawn_car'] = 'spawn a car', - ['spawn_car_param'] = 'name of car', - ['delete_vehicle'] = 'deletes Vehicle', - ['invalid_account'] = 'invalid account', - ['account'] = 'account', - ['giveaccountmoney'] = 'give account money', - ['invalid_item'] = 'invalid item', + ['setjob'] = 'spieler Job zuweisen', + ['id_param'] = 'ID von Spieler', + ['setjob_param2'] = 'der zu vergebende Job', + ['setjob_param3'] = 'der Jobgrad', + ['spawn_car'] = 'fahrzeug spawnen', + ['spawn_car_param'] = 'fahrzeugname', + ['delete_vehicle'] = 'entfernt Fahrzeuge', + ['invalid_account'] = 'ungültige Anzahl', + ['account'] = 'bank', + ['giveaccountmoney'] = 'bankgeld geben', + ['invalid_item'] = 'ungültiges Item', ['item'] = 'item', - ['giveitem'] = 'give item', - ['weapon'] = 'weapon', - ['giveweapon'] = 'give weapon', - ['chat_clear'] = 'clear the chat', - ['chat_clear_all'] = 'clear the chat for everyone', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', + ['giveitem'] = 'item geben', + ['weapon'] = 'waffe', + ['giveweapon'] = 'waffe geben', + ['chat_clear'] = 'chat leeren', + ['chat_clear_all'] = 'chat für jeden leeren', + ['command_clearinventory'] = 'alle Items aus dem Inventar entfernen', + ['command_clearloadout'] = 'alle Waffen aus dem Loadout entfernen', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', @@ -142,12 +142,12 @@ Locales['de'] = { ['weapon_revolver'] = 'Schwerer Revolver', ['weapon_dbshotgun'] = 'Doppelläufige Schrotflinte', ['weapon_compactrifle'] = 'Kampfgewehr', - ['weapon_autoshotgun'] = 'Auto Shotgun', + ['weapon_autoshotgun'] = 'Auto Schrotflinte', ['weapon_battleaxe'] = 'Kampfaxt', - ['weapon_compactlauncher'] = 'Kompakt Launcher', + ['weapon_compactlauncher'] = 'Kompakt Granatwerfer', ['weapon_minismg'] = 'Mini SMG', ['weapon_pipebomb'] = 'Rohrbombe', - ['weapon_poolcue'] = 'Kö', + ['weapon_poolcue'] = 'Billiard-Kö', ['weapon_wrench'] = 'Rohrzange', ['weapon_flashlight'] = 'Taschenlampe', ['gadget_parachute'] = 'Fallschirm', @@ -155,44 +155,44 @@ Locales['de'] = { ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', - ['component_clip_drum'] = 'drum Magazine', - ['component_clip_box'] = 'box Magazine', - ['component_flashlight'] = 'flashlight', - ['component_scope'] = 'scope', - ['component_scope_advanced'] = 'advanced Scope', - ['component_suppressor'] = 'suppressor', - ['component_grip'] = 'grip', - ['component_luxary_finish'] = 'luxary Weapon Finish', + ['component_clip_default'] = 'standart Griff', + ['component_clip_extended'] = 'erweiterter Griff', + ['component_clip_drum'] = 'trommelmagazin', + ['component_clip_box'] = 'kastenmagazin', + ['component_flashlight'] = 'taschenlampe', + ['component_scope'] = 'zielfernrohr', + ['component_scope_advanced'] = 'erweitertes Zielfernrohr', + ['component_suppressor'] = 'schalldämpfer', + ['component_grip'] = 'griff', + ['component_luxary_finish'] = 'luxus Waffen Design', -- Weapon Ammo - ['ammo_rounds'] = 'round(s)', - ['ammo_shells'] = 'shell(s)', - ['ammo_charge'] = 'charge', - ['ammo_petrol'] = 'gallons of fuel', - ['ammo_firework'] = 'firework(s)', - ['ammo_rockets'] = 'rocket(s)', - ['ammo_grenadelauncher'] = 'grenade(s)', - ['ammo_grenade'] = 'grenade(s)', - ['ammo_stickybomb'] = 'bomb(s)', - ['ammo_pipebomb'] = 'bomb(s)', - ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_rounds'] = 'kugel(n)', + ['ammo_shells'] = 'schrotpatrone(n)', + ['ammo_charge'] = 'ladung', + ['ammo_petrol'] = 'liter Benzin', + ['ammo_firework'] = 'feuerwerksrakete(n)', + ['ammo_rockets'] = 'rakete(n)', + ['ammo_grenadelauncher'] = 'granate(n)', + ['ammo_grenade'] = 'granate(n)', + ['ammo_stickybomb'] = 'bombe(n)', + ['ammo_pipebomb'] = 'bombe(n)', + ['ammo_smokebomb'] = 'bombe(n)', ['ammo_molotov'] = 'cocktail(s)', - ['ammo_proxmine'] = 'mine(s)', - ['ammo_bzgas'] = 'can(s)', - ['ammo_ball'] = 'ball(s)', - ['ammo_snowball'] = 'snowball(s)', - ['ammo_flare'] = 'flare(s)', - ['ammo_flaregun'] = 'flare(s)', + ['ammo_proxmine'] = 'mine(n)', + ['ammo_bzgas'] = 'can(n)', + ['ammo_ball'] = 'ball', + ['ammo_snowball'] = 'schneebälle', + ['ammo_flare'] = 'signalfackel(n)', + ['ammo_flaregun'] = 'signalfackeln(munition)', -- Weapon Tints - ['tint_default'] = 'default skin', - ['tint_green'] = 'green skin', - ['tint_gold'] = 'gold skin', - ['tint_pink'] = 'pink skin', - ['tint_army'] = 'army skin', - ['tint_lspd'] = 'blue skin', - ['tint_orange'] = 'orange skin', - ['tint_platinum'] = 'platinum skin', + ['tint_default'] = 'standard', + ['tint_green'] = 'grün', + ['tint_gold'] = 'gold', + ['tint_pink'] = 'pink', + ['tint_army'] = 'camouflage', + ['tint_lspd'] = 'blau', + ['tint_orange'] = 'orange', + ['tint_platinum'] = 'platin', } From 4b648a8bef4bd897891abd5508d5f4e5a1f63331 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 22:48:44 +0100 Subject: [PATCH 426/672] Override existing commands, and fixed rare bug with cb args all nil --- server/functions.lua | 150 ++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 73 deletions(-) diff --git a/server/functions.lua b/server/functions.lua index 6cfd5860..e9f0d5be 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -30,103 +30,107 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) end if ESX.RegisteredCommands[name] then - print(('[es_extended] [^3WARNING^7] An command "%s" is already registered'):format(name)) - else - if suggestion then - if not suggestion.arguments then suggestion.arguments = {} end - if not suggestion.help then suggestion.help = '' end - end + print(('[es_extended] [^3WARNING^7] An command "%s" is already registered, overriding command'):format(name)) + end - ESX.RegisteredCommands[name] = {group = group, cb = cb, allowConsole = allowConsole, suggestion = suggestion} + if suggestion then + if not suggestion.arguments then suggestion.arguments = {} end + if not suggestion.help then suggestion.help = '' end + end - RegisterCommand(name, function(playerId, args, rawCommand) - local command = ESX.RegisteredCommands[name] + ESX.RegisteredCommands[name] = {group = group, cb = cb, allowConsole = allowConsole, suggestion = suggestion} - if not command.allowConsole and playerId == 0 then - print('[es_extended] [^3WARNING^7] That command can not be run from console') - else - local xPlayer, error = ESX.GetPlayerFromId(playerId), nil + RegisterCommand(name, function(playerId, args, rawCommand) + local command = ESX.RegisteredCommands[name] - if command.suggestion then - if command.suggestion.validate then - if #args ~= #command.suggestion.arguments then - error = ('Argument count mismatch (passed %s, wanted %s)'):format(#args, #command.suggestion.arguments) - end + if not command.allowConsole and playerId == 0 then + print('[es_extended] [^3WARNING^7] That command can not be run from console') + else + local xPlayer, error = ESX.GetPlayerFromId(playerId), nil + + if command.suggestion then + if command.suggestion.validate then + if #args ~= #command.suggestion.arguments then + error = ('Argument count mismatch (passed %s, wanted %s)'):format(#args, #command.suggestion.arguments) end + end - if not error and command.suggestion.arguments then - local newArgs = {} + if not error and command.suggestion.arguments then + local newArgs = {} - for k,v in ipairs(command.suggestion.arguments) do - if v.type then - if v.type == 'number' then - local newArg = tonumber(args[k]) + for k,v in ipairs(command.suggestion.arguments) do + if v.type then + if v.type == 'number' then + local newArg = tonumber(args[k]) - if newArg then - newArgs[v.name] = newArg - else - error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) - end - elseif v.type == 'player' then - local targetPlayer = tonumber(args[k]) + if newArg then + newArgs[v.name] = newArg + else + error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + end + elseif v.type == 'player' or v.type == 'playerId' then + local targetPlayer = tonumber(args[k]) - if targetPlayer then - local xTargetPlayer = ESX.GetPlayerFromId(targetPlayer) + if targetPlayer then + local xTargetPlayer = ESX.GetPlayerFromId(targetPlayer) - if xTargetPlayer then + if xTargetPlayer then + if v.type == 'player' then newArgs[v.name] = xTargetPlayer else - error = 'Player not online' + newArgs[v.name] = targetPlayer end else - error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + error = 'Player not online' end - elseif v.type == 'string' then - newArgs[v.name] = args[k] - elseif v.type == 'item' then - if ESX.Items[args[k]] then - newArgs[v.name] = args[k] - else - error = _U('invalid_item') - end - elseif v.type == 'weapon' then - if ESX.GetWeapon(args[k]) then - newArgs[v.name] = string.upper(args[k]) - else - error = 'Invalid weapon' - end - elseif v.type == 'any' then - newArgs[v.name] = args[k] + else + error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) end + elseif v.type == 'string' then + newArgs[v.name] = args[k] + elseif v.type == 'item' then + if ESX.Items[args[k]] then + newArgs[v.name] = args[k] + else + error = _U('invalid_item') + end + elseif v.type == 'weapon' then + if ESX.GetWeapon(args[k]) then + newArgs[v.name] = string.upper(args[k]) + else + error = 'Invalid weapon' + end + elseif v.type == 'any' then + newArgs[v.name] = args[k] end - - if error then break end end - args = newArgs + if error then break end end - end - if error then - if playerId == 0 then - print(('[es_extended] [^3WARNING^7] %s^7'):format(error)) - else - xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', error}}) - end - else - cb(xPlayer, args, function(msg) - if playerId == 0 then - print(('[es_extended] [^3WARNING^7] %s^7'):format(msg)) - else - xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', msg}}) - end - end) + args = newArgs end end - end, true) - ExecuteCommand(('add_ace group.%s command.%s allow'):format(group, name)) - end + if error then + if playerId == 0 then + print(('[es_extended] [^3WARNING^7] %s^7'):format(error)) + else + xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', error}}) + end + else + cb(xPlayer or false, args, function(msg) + if playerId == 0 then + print(('[es_extended] [^3WARNING^7] %s^7'):format(msg)) + else + xPlayer.triggerEvent('chat:addMessage', {args = {'^1SYSTEM', msg}}) + end + end) + end + end + end, true) + + ExecuteCommand(('add_ace group.%s command.%s allow'):format(group, name)) end ESX.ClearTimeout = function(id) From 8a832aee3bed36c734d1a34705289c9a7b2a9416 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:07:18 +0100 Subject: [PATCH 427/672] Implemented adding chat suggestions, closes #512 --- client/main.lua | 9 +++++++++ server/functions.lua | 2 ++ 2 files changed, 11 insertions(+) diff --git a/client/main.lua b/client/main.lua index caccc586..fd2fc759 100644 --- a/client/main.lua +++ b/client/main.lua @@ -328,6 +328,15 @@ AddEventHandler('esx:createMissingPickups', function(missingPickups) end end) +RegisterNetEvent('esx:registerSuggestions') +AddEventHandler('esx:registerSuggestions', function(registeredCommands) + for name,command in pairs(registeredCommands) do + if command.suggestion then + TriggerEvent('chat:addSuggestion', ('/%s'):format(name), command.suggestion.help, command.suggestion.arguments) + end + end +end) + RegisterNetEvent('esx:removePickup') AddEventHandler('esx:removePickup', function(id) ESX.Game.DeleteObject(pickups[id].obj) diff --git a/server/functions.lua b/server/functions.lua index e9f0d5be..0abdb9a7 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -36,6 +36,8 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) if suggestion then if not suggestion.arguments then suggestion.arguments = {} end if not suggestion.help then suggestion.help = '' end + + TriggerClientEvent('chat:addSuggestion', -1, ('/%s'):format(name), suggestion.help, suggestion.arguments) end ESX.RegisteredCommands[name] = {group = group, cb = cb, allowConsole = allowConsole, suggestion = suggestion} From 73a818aed94a319d26ffb0a028ea6254334d99f5 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:07:38 +0100 Subject: [PATCH 428/672] Implemented adding chat suggestions --- server/main.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/server/main.lua b/server/main.lua index 38bd8926..d1838418 100644 --- a/server/main.lua +++ b/server/main.lua @@ -186,6 +186,7 @@ function loadESXPlayer(identifier, playerId) }) xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) + xPlayer.triggerEvent('esx:registerSuggestions', ESX.RegisteredCommands) end) end) end From 21de2f9420cb439381f33b95e82f5c8423260c68 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 17 Feb 2020 23:21:04 +0100 Subject: [PATCH 429/672] Remove suggestion on command override --- server/functions.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/functions.lua b/server/functions.lua index 0abdb9a7..053f58e1 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -31,6 +31,10 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) if ESX.RegisteredCommands[name] then print(('[es_extended] [^3WARNING^7] An command "%s" is already registered, overriding command'):format(name)) + + if ESX.RegisteredCommands[name].suggestion then + TriggerClientEvent('chat:removeSuggestion', -1, ('/%s'):format(name)) + end end if suggestion then From 4b95e6a2b0ad60b4626b724f740846fa69a37776 Mon Sep 17 00:00:00 2001 From: rex2630 Date: Tue, 18 Feb 2020 22:33:46 +0100 Subject: [PATCH 430/672] Updated Czech locale (#515) * Update cs.lua * Fix --- locales/cs.lua | 325 ++++++++++++++++++++++++------------------------- 1 file changed, 162 insertions(+), 163 deletions(-) diff --git a/locales/cs.lua b/locales/cs.lua index de60f089..bc69b191 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -12,16 +12,16 @@ Locales['cs'] = { ['noammo'] = 'nemáte dostatek munice!', ['gave_item'] = 'dali jste ~y~%sx~s~ ~b~%s~s~ ~y~%s~s~', ['received_item'] = 'obdrželi jste ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', - ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx %s~s~ to ~y~%s~s~', - ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', - ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', - ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', - ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['gave_weapon'] = 'dal jsi ~b~%s~s~ hráči ~y~%s~s~', + ['gave_weapon_ammo'] = 'dal jsi ~o~%sx %s~s~ za ~b~%s~s~ to ~y~%s~s~', + ['gave_weapon_withammo'] = 'dal jwi ~b~%s~s~ s ~o~%sx %s~s~ to ~y~%s~s~', + ['gave_weapon_hasalready'] = '~y~%s~s~ již má ~y~%s~s~', + ['gave_weapon_noweapon'] = '~y~%s~s~ nemá tuhle zbraň', + ['received_weapon'] = 'obdrzel jsi ~b~%s~s~ od ~b~%s~s~', + ['received_weapon_ammo'] = 'obdrzel jsi ~o~%sx %s~s~ za tvůj ~b~%s~s~ od ~b~%s~s~', + ['received_weapon_withammo'] = 'obdzel jsi ~b~%s~s~ s ~o~%sx %s~s~ od ~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~ se pokusil ti dat ~y~%s~s~, ale jiz tento predmet jednou mas', + ['received_weapon_noweapon'] = '~b~%s~s~ se pokusil ti dat naboje pro ~y~%s~s~, ale tuhle zbran nemas', ['gave_account_money'] = 'dali jste ~g~$%s~s~ (%s) ~y~%s~s~', ['received_account_money'] = 'obdrželi jste ~g~$%s~s~ (%s) od ~b~%s~s~', ['amount_invalid'] = 'neplatné množství', @@ -29,171 +29,170 @@ Locales['cs'] = { ['ex_inv_lim'] = 'akce není možná, překročen limit inventáře pro ~y~%s~s~', ['imp_invalid_quantity'] = 'akce není možná, neplatný počet', ['imp_invalid_amount'] = 'akce není možná, neplatné množství', - ['threw_standard'] = 'you threw ~y~%sx~s~ ~b~%s~s~', - ['threw_account'] = 'you threw ~g~$%s~s~ ~b~%s~s~', - ['threw_weapon'] = 'you threw ~b~%s~s~', - ['threw_weapon_ammo'] = 'you threw ~b~%s~s~ with ~o~%sx %s~s~', - ['threw_weapon_already'] = 'you already carry the same weapon', - ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', - ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + ['threw_standard'] = 'vyhodil jsi ~y~%sx~s~ ~b~%s~s~', + ['threw_account'] = 'vyhodil jsi ~g~$%s~s~ ~b~%s~s~', + ['threw_weapon'] = 'vzhodil jsi ~b~%s~s~', + ['threw_weapon_ammo'] = 'vyhodil jsi ~b~%s~s~ s ~o~%sx %s~s~', + ['threw_weapon_already'] = 'jiz stejnou zbraan mas', + ['threw_cannot_pickup'] = 'tohle nemuzes sebrat, protoze tvuj inventar je plny', + ['threw_pickup_prompt'] = 'stiskni ~y~E~s~ po zvednuti', -- Key mapping - ['keymap_showinventory'] = 'show Inventory', + ['keymap_showinventory'] = 'zobrazit inventar', + -- Salary related + ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', + ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', + ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', + ['received_paycheck'] = 'obdržena výplata', + ['bank'] = 'bankovní účet', + ['account_bank'] = 'banka', + ['account_black_money'] = 'spinave penize', + ['account_money'] = 'kapesne', - -- Salary related - ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', - ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', - ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', - ['received_paycheck'] = 'obdržena výplata', - ['bank'] = 'bankovní účet', - ['account_bank'] = 'bank', - ['account_black_money'] = 'dirty Money', - ['account_money'] = 'cash', + ['act_imp'] = 'akce není možná', + ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', - ['act_imp'] = 'akce není možná', - ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', + -- Commands + ['setjob'] = 'přiřadit práci hráči', + ['id_param'] = 'iD hráče', + ['setjob_param2'] = 'název přiřazované práce', + ['setjob_param3'] = 'úroveň práce', + ['spawn_car'] = 'spawn auto', + ['spawn_car_param'] = 'název auta', + ['delete_vehicle'] = 'odstranit vozidlo', + ['invalid_account'] = 'neplatný účet', + ['account'] = 'účet', + ['giveaccountmoney'] = 'dát peníze na účet', + ['invalid_item'] = 'neplatná věc', + ['item'] = 'věc', + ['giveitem'] = 'dát věc', + ['weapon'] = 'zbraň', + ['giveweapon'] = 'dát zbraň', + ['chat_clear'] = 'vyčistit chat', + ['chat_clear_all'] = 'vyčistit chat pro všechny', + ['command_clearinventory'] = 'vycistit vsechny predmety v invetari', + ['command_clearloadout'] = 'odebrat vsechny zbrane z rukz', - -- Commands - ['setjob'] = 'přiřadit práci hráči', - ['id_param'] = 'iD hráče', - ['setjob_param2'] = 'název přiřazované práce', - ['setjob_param3'] = 'úroveň práce', - ['spawn_car'] = 'spawn auto', - ['spawn_car_param'] = 'název auta', - ['delete_vehicle'] = 'odstranit vozidlo', - ['invalid_account'] = 'neplatný účet', - ['account'] = 'účet', - ['giveaccountmoney'] = 'dát peníze na účet', - ['invalid_item'] = 'neplatná věc', - ['item'] = 'věc', - ['giveitem'] = 'dát věc', - ['weapon'] = 'zbraň', - ['giveweapon'] = 'dát zbraň', - ['chat_clear'] = 'vyčistit chat', - ['chat_clear_all'] = 'vyčistit chat pro všechny', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', + -- Locale settings + ['locale_digit_grouping_symbol'] = ' ', + ['locale_currency'] = '$%s', - -- Locale settings - ['locale_digit_grouping_symbol'] = ' ', - ['locale_currency'] = '$%s', - - -- Weapons - ['weapon_knife'] = 'knife', - ['weapon_nightstick'] = 'nightstick', - ['weapon_hammer'] = 'hammer', - ['weapon_bat'] = 'bat', - ['weapon_golfclub'] = 'golf club', - ['weapon_crowbar'] = 'crow bar', - ['weapon_pistol'] = 'pistol', - ['weapon_combatpistol'] = 'combat pistol', - ['weapon_appistol'] = 'ap pistol', - ['weapon_pistol50'] = 'pistol .50', - ['weapon_microsmg'] = 'micro smg', - ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'assault smg', - ['weapon_assaultrifle'] = 'assault rifle', - ['weapon_carbinerifle'] = 'carbine rifle', - ['weapon_advancedrifle'] = 'advanced rifle', - ['weapon_mg'] = 'mg', - ['weapon_combatmg'] = 'combat mg', - ['weapon_pumpshotgun'] = 'pump shotgun', - ['weapon_sawnoffshotgun'] = 'sawed off shotgun', - ['weapon_assaultshotgun'] = 'assault shotgun', - ['weapon_bullpupshotgun'] = 'bullpup shotgun', - ['weapon_stungun'] = 'tazer', - ['weapon_sniperrifle'] = 'sniper rifle', - ['weapon_heavysniper'] = 'heavy sniper', - ['weapon_grenadelauncher'] = 'grenade launcher', - ['weapon_rpg'] = 'rocket launcher', - ['weapon_minigun'] = 'minigun', - ['weapon_grenade'] = 'grenade', - ['weapon_stickybomb'] = 'sticky bomb', - ['weapon_smokegrenade'] = 'smoke grenade', - ['weapon_bzgas'] = 'bz gas', - ['weapon_molotov'] = 'molotov cocktail', - ['weapon_fireextinguisher'] = 'fire extinguisher', - ['weapon_petrolcan'] = 'jerrycan', - ['weapon_ball'] = 'ball', - ['weapon_snspistol'] = 'sns pistol', - ['weapon_bottle'] = 'bottle', - ['weapon_gusenberg'] = 'gusenberg sweeper', - ['weapon_specialcarbine'] = 'special carbine', - ['weapon_heavypistol'] = 'heavy pistol', - ['weapon_bullpuprifle'] = 'bullpup rifle', - ['weapon_dagger'] = 'dagger', - ['weapon_vintagepistol'] = 'vintage pistol', - ['weapon_firework'] = 'firework', - ['weapon_musket'] = 'musket', - ['weapon_heavyshotgun'] = 'heavy shotgun', - ['weapon_marksmanrifle'] = 'marksman rifle', - ['weapon_hominglauncher'] = 'homing launcher', - ['weapon_proxmine'] = 'proximity mine', - ['weapon_snowball'] = 'snow ball', - ['weapon_flaregun'] = 'flaregun', - ['weapon_combatpdw'] = 'combat pdw', - ['weapon_marksmanpistol'] = 'marksman pistol', - ['weapon_knuckle'] = 'knuckledusters', - ['weapon_hatchet'] = 'hatchet', - ['weapon_railgun'] = 'railgun', - ['weapon_machete'] = 'machete', - ['weapon_machinepistol'] = 'machine pistol', - ['weapon_switchblade'] = 'switchblade', - ['weapon_revolver'] = 'heavy revolver', - ['weapon_dbshotgun'] = 'double barrel shotgun', - ['weapon_compactrifle'] = 'compact rifle', - ['weapon_autoshotgun'] = 'auto shotgun', - ['weapon_battleaxe'] = 'battle axe', - ['weapon_compactlauncher'] = 'compact launcher', + -- Weapons + ['weapon_knife'] = 'nuz', + ['weapon_nightstick'] = 'policejni obusek', + ['weapon_hammer'] = 'kladivo', + ['weapon_bat'] = 'basseballka', + ['weapon_golfclub'] = 'gollfova hul', + ['weapon_crowbar'] = 'pacidlo', + ['weapon_pistol'] = 'pistole', + ['weapon_combatpistol'] = 'utocna pistole', + ['weapon_appistol'] = 'ap pistole', + ['weapon_pistol50'] = 'pistole .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'utocne smg', + ['weapon_assaultrifle'] = 'utocna puska', + ['weapon_carbinerifle'] = 'carbine puska', + ['weapon_advancedrifle'] = 'pokrocily puska', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'utocne mg', + ['weapon_pumpshotgun'] = 'pumpovana brokovnice', + ['weapon_sawnoffshotgun'] = 'upilovana brokovnice', + ['weapon_assaultshotgun'] = 'utocna brokovnice', + ['weapon_bullpupshotgun'] = 'bullpup brokovnice', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'sniperka', + ['weapon_heavysniper'] = 'tezka sniperka', + ['weapon_grenadelauncher'] = 'launcher granatu', + ['weapon_rpg'] = 'raketomet', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'granat', + ['weapon_stickybomb'] = 'lepkava bomba', + ['weapon_smokegrenade'] = 'kourovy granat', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'molotov koktejl', + ['weapon_fireextinguisher'] = 'hasicak', + ['weapon_petrolcan'] = 'kanystr', + ['weapon_ball'] = 'koule', + ['weapon_snspistol'] = 'sns pistole', + ['weapon_bottle'] = 'lahev', + ['weapon_gusenberg'] = 'gusenberguv zametac', + ['weapon_specialcarbine'] = 'specialni karabina', + ['weapon_heavypistol'] = 'tezka pistole', + ['weapon_bullpuprifle'] = 'bullpup puska', + ['weapon_dagger'] = 'dyka', + ['weapon_vintagepistol'] = 'velmi stara pistole', + ['weapon_firework'] = 'ohnostroj', + ['weapon_musket'] = 'musketa', + ['weapon_heavyshotgun'] = 'tezka brokovnice', + ['weapon_marksmanrifle'] = 'puska strelce', + ['weapon_hominglauncher'] = 'navadeci launcher', + ['weapon_proxmine'] = 'mina na blizko', + ['weapon_snowball'] = 'snehova koule', + ['weapon_flaregun'] = 'svetlice', + ['weapon_combatpdw'] = 'utocne pdw', + ['weapon_marksmanpistol'] = 'pistole strelce', + ['weapon_knuckle'] = 'knuckledusters', + ['weapon_hatchet'] = 'sekerka', + ['weapon_railgun'] = 'vlakovy launcher', + ['weapon_machete'] = 'maceta', + ['weapon_machinepistol'] = 'kulomet', + ['weapon_switchblade'] = 'vystrelovaci nuz', + ['weapon_revolver'] = 'tezky revolver', + ['weapon_dbshotgun'] = 'dvouhlavnova brokovnice', + ['weapon_compactrifle'] = 'kompaktni puska', + ['weapon_autoshotgun'] = 'automaticka brokovnice', + ['weapon_battleaxe'] = 'bojova sekera', + ['weapon_compactlauncher'] = 'kompaktni launcher', ['weapon_minismg'] = 'mini smg', - ['weapon_pipebomb'] = 'pipe bomb', - ['weapon_poolcue'] = 'pool cue', - ['weapon_wrench'] = 'pipe wrench', - ['weapon_flashlight'] = 'flashlight', - ['gadget_parachute'] = 'parachute', - ['weapon_flare'] = 'flare gun', - ['weapon_doubleaction'] = 'double-Action Revolver', + ['weapon_pipebomb'] = 'dymkova bomba', + ['weapon_poolcue'] = 'kulecnikove tago', + ['weapon_wrench'] = 'klic na trubky', + ['weapon_flashlight'] = 'baterka', + ['gadget_parachute'] = 'padak', + ['weapon_flare'] = 'svetlice', + ['weapon_doubleaction'] = 'dvojhlavnovy revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', + ['component_clip_default'] = 'zakladni rukojet', + ['component_clip_extended'] = 'prodloucena rukojet', ['component_clip_drum'] = 'drum Magazine', - ['component_clip_box'] = 'box Magazine', - ['component_flashlight'] = 'flashlight', - ['component_scope'] = 'scope', - ['component_scope_advanced'] = 'advanced Scope', - ['component_suppressor'] = 'suppressor', - ['component_grip'] = 'grip', - ['component_luxary_finish'] = 'luxary Weapon Finish', + ['component_clip_box'] = 'krabice s naboji', + ['component_flashlight'] = 'baterka', + ['component_scope'] = 'zamerovac', + ['component_scope_advanced'] = 'pokrocily zamerovac', + ['component_suppressor'] = 'tlumic', + ['component_grip'] = 'rukojet', + ['component_luxary_finish'] = 'luxusni vzhled zbrane', - -- Weapon Ammo - ['ammo_rounds'] = 'round(s)', - ['ammo_shells'] = 'shell(s)', - ['ammo_charge'] = 'charge', - ['ammo_petrol'] = 'gallons of fuel', - ['ammo_firework'] = 'firework(s)', - ['ammo_rockets'] = 'rocket(s)', - ['ammo_grenadelauncher'] = 'grenade(s)', - ['ammo_grenade'] = 'grenade(s)', - ['ammo_stickybomb'] = 'bomb(s)', - ['ammo_pipebomb'] = 'bomb(s)', - ['ammo_smokebomb'] = 'bomb(s)', - ['ammo_molotov'] = 'cocktail(s)', - ['ammo_proxmine'] = 'mine(s)', - ['ammo_bzgas'] = 'can(s)', - ['ammo_ball'] = 'ball(s)', - ['ammo_snowball'] = 'snowball(s)', - ['ammo_flare'] = 'flare(s)', - ['ammo_flaregun'] = 'flare(s)', + -- Weapon Ammo + ['ammo_rounds'] = 'naboj(e)', + ['ammo_shells'] = 'patrona(y)', + ['ammo_charge'] = 'naboj(e)', + ['ammo_petrol'] = 'galonu paliva', + ['ammo_firework'] = 'ohnostroj(e)', + ['ammo_rockets'] = 'raketa(y)', + ['ammo_grenadelauncher'] = 'granat(y)', + ['ammo_grenade'] = 'granat(y)', + ['ammo_stickybomb'] = 'bomba(y)', + ['ammo_pipebomb'] = 'bomba(y)', + ['ammo_smokebomb'] = 'bomba(y)', + ['ammo_molotov'] = 'koktejl(y)', + ['ammo_proxmine'] = 'mina(y)', + ['ammo_bzgas'] = 'kanystr(y)', + ['ammo_ball'] = 'koule', + ['ammo_snowball'] = 'snehova(e) koule', + ['ammo_flare'] = 'svetlice', + ['ammo_flaregun'] = 'svetlice', -- Weapon Tints - ['tint_default'] = 'default skin', - ['tint_green'] = 'green skin', - ['tint_gold'] = 'gold skin', - ['tint_pink'] = 'pink skin', - ['tint_army'] = 'army skin', - ['tint_lspd'] = 'blue skin', - ['tint_orange'] = 'orange skin', - ['tint_platinum'] = 'platinum skin', + ['tint_default'] = 'zakladni skin', + ['tint_green'] = 'zeleny skin', + ['tint_gold'] = 'zlaty skin', + ['tint_pink'] = 'ruzovy skin', + ['tint_army'] = 'armadni skin', + ['tint_lspd'] = 'modry skin', + ['tint_orange'] = 'oranzovy skin', + ['tint_platinum'] = 'platinovy skin', } From ecbf340e391f1a3d91607d0e7d1b61917fbd86f5 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 22 Feb 2020 10:05:10 +0100 Subject: [PATCH 431/672] Accept "me" in player or playerId type Co-Authored-By: Dan Sadler --- server/functions.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/server/functions.lua b/server/functions.lua index 053f58e1..f910b945 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -77,6 +77,8 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) elseif v.type == 'player' or v.type == 'playerId' then local targetPlayer = tonumber(args[k]) + if args[k] == 'me' then targetPlayer = playerId end + if targetPlayer then local xTargetPlayer = ESX.GetPlayerFromId(targetPlayer) From 8927aebae13760cc2351ebd096cb195bb27ef4a2 Mon Sep 17 00:00:00 2001 From: Dione Batista Date: Sun, 23 Feb 2020 14:48:37 -0300 Subject: [PATCH 432/672] Updated Portuguese translation (#523) * Update br.lua * uppercase "corrections" --- locales/br.lua | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index f8573d2d..3258ea49 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -38,7 +38,7 @@ Locales['br'] = { ['threw_pickup_prompt'] = 'pressione ~y~E~s~ para pegar', -- Key mapping - ['keymap_showinventory'] = 'show Inventory', + ['keymap_showinventory'] = 'exibir inventario', -- Salary related ['received_salary'] = 'voce recebeu seu salário: ~g~$%s~s~ ', @@ -46,9 +46,9 @@ Locales['br'] = { ['company_nomoney'] = 'a empresa em que voce esta empregado esta muito pobre para pagar seu salário', ['received_paycheck'] = 'recebeu dinheiro', ['bank'] = 'banco', - ['account_bank'] = 'bank', - ['account_black_money'] = 'dirty Money', - ['account_money'] = 'cash', + ['account_bank'] = 'banco', + ['account_black_money'] = 'dinheiro sujo', + ['account_money'] = 'dinheiro', ['act_imp'] = 'ação impossível', ['in_vehicle'] = 'voce não pode dar nada para alguem no veículo', @@ -76,7 +76,7 @@ Locales['br'] = { -- Locale settings ['locale_digit_grouping_symbol'] = ' ', - ['locale_currency'] = '$%s', + ['locale_currency'] = 'R$%s', -- Weapons ['weapon_knife'] = 'faca', From 24a9defca418492b25a91e32efedec8c855746f2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 25 Feb 2020 15:54:38 +0100 Subject: [PATCH 433/672] Removed xPlayer.removeWeapon() second argument --- client/main.lua | 11 ++--------- fxmanifest.lua | 2 +- server/classes/player.lua | 4 ++-- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/client/main.lua b/client/main.lua index fd2fc759..106e0032 100644 --- a/client/main.lua +++ b/client/main.lua @@ -190,19 +190,12 @@ AddEventHandler('esx:setWeaponTint', function(weaponName, weaponTintIndex) end) RegisterNetEvent('esx:removeWeapon') -AddEventHandler('esx:removeWeapon', function(weaponName, ammo) +AddEventHandler('esx:removeWeapon', function(weaponName) 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 + SetPedAmmo(playerPed, weaponHash, 0) -- remove leftover ammo end) RegisterNetEvent('esx:removeWeaponComponent') diff --git a/fxmanifest.lua b/fxmanifest.lua index a9fe16ba..eb6e6f19 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -83,7 +83,7 @@ files { 'html/img/accounts/bank.png', 'html/img/accounts/black_money.png', - 'html/img/accounts/money.png', + 'html/img/accounts/money.png' } exports { diff --git a/server/classes/player.lua b/server/classes/player.lua index 4a41d30b..845b6f8d 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -403,7 +403,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return 0 end - self.removeWeapon = function(weaponName, ammo) + self.removeWeapon = function(weaponName) local weaponLabel for k,v in ipairs(self.loadout) do @@ -420,7 +420,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end if weaponLabel then - self.triggerEvent('esx:removeWeapon', weaponName, ammo) + self.triggerEvent('esx:removeWeapon', weaponName) self.triggerEvent('esx:removeInventoryItem', weaponLabel, false, true) end end From 79d53a5550673b73b349132d5be76312c97909b2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 28 Feb 2020 20:05:27 +0100 Subject: [PATCH 434/672] ESX.Game.GetPedMugshot() second argument transparent --- client/functions.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index e2bace44..07c9cab4 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -281,9 +281,15 @@ ESX.UI.ShowInventoryItemNotification = function(add, item, count) }) end -ESX.Game.GetPedMugshot = function(ped) +ESX.Game.GetPedMugshot = function(ped, transparent) if DoesEntityExist(ped) then - local mugshot = RegisterPedheadshot(ped) + local mugshot + + if transparent then + mugshot = RegisterPedheadshotTransparent(ped) + else + mugshot = RegisterPedheadshot(ped) + end while not IsPedheadshotReady(mugshot) do Citizen.Wait(0) From 4d9af4e1abd8ae8cafedd74c3da0f797a4183ffd Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 1 Mar 2020 10:54:03 +0100 Subject: [PATCH 435/672] Improved saving loadouts (see desc) - Only save weapon components if needed, wont save default clip anymore, and if no other component is available then its not saved at all - Tint index not stored if not above 0 - Weapon label not saved in database since its useless - Validate weapon on player load --- server/classes/player.lua | 43 +++++++++++++++++++++++++++++++-------- server/functions.lua | 2 +- server/main.lua | 23 +++++++++++++++------ 3 files changed, 52 insertions(+), 16 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 845b6f8d..d474a566 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -96,15 +96,15 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.getInventory = function(minimal) if minimal then - local items = {} + local minimalInventory = {} for k,v in ipairs(self.inventory) do if v.count > 0 then - items[v.name] = v.count + minimalInventory[v.name] = v.count end end - return items + return minimalInventory else return self.inventory end @@ -114,8 +114,33 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return self.job end - self.getLoadout = function() - return self.loadout + self.getLoadout = function(minimal) + if minimal then + local minimalLoadout = {} + + for k,v in ipairs(self.loadout) do + minimalLoadout[v.name] = {ammo = v.ammo} + if v.tintIndex > 0 then minimalLoadout[v.name].tintIndex = v.tintIndex end + + if #v.components > 0 then + local components = {} + + for k2,component in ipairs(v.components) do + if component ~= 'clip_default' then + table.insert(components, component) + end + end + + if #components > 0 then + minimalLoadout[v.name].components = components + end + end + end + + return minimalLoadout + else + return self.loadout + end end self.getName = function() @@ -185,11 +210,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if account then local newMoney = account.money + ESX.Math.Round(money) account.money = newMoney - + if accountName == 'bank' then self.set('bank', newMoney) end - + self.triggerEvent('esx:setAccountMoney', account) end end @@ -202,11 +227,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if account then local newMoney = account.money - ESX.Math.Round(money) account.money = newMoney - + if accountName == 'bank' then self.set('bank', newMoney) end - + self.triggerEvent('esx:setAccountMoney', account) end end diff --git a/server/functions.lua b/server/functions.lua index f910b945..a0f3d5aa 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -182,7 +182,7 @@ ESX.SavePlayer = function(xPlayer, cb) MySQL.Async.execute('UPDATE users SET job = @job, job_grade = @job_grade, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { ['@job'] = xPlayer.job.name, ['@job_grade'] = xPlayer.job.grade, - ['@loadout'] = json.encode(xPlayer.getLoadout()), + ['@loadout'] = json.encode(xPlayer.getLoadout(true)), ['@position'] = json.encode(xPlayer.getCoords()), ['@identifier'] = xPlayer.identifier, ['@inventory'] = json.encode(xPlayer.getInventory(true)) diff --git a/server/main.lua b/server/main.lua index d1838418..b52782d0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -133,13 +133,24 @@ function loadESXPlayer(identifier, playerId) return a.label < b.label end) - if result[1].loadout then - userData.loadout = json.decode(result[1].loadout) + if result[1].loadout and result[1].loadout ~= '' then + local loadout = json.decode(result[1].loadout) - -- compatibility with old loadouts - for k,v in ipairs(userData.loadout) do - if not v.components then v.components = {} end - if not v.tintIndex then v.tintIndex = 0 end + for name,weapon in pairs(loadout) do + local label = ESX.GetWeaponLabel(name) + + if label then + if not weapon.components then weapon.components = {} end + if not weapon.tintIndex then weapon.tintIndex = 0 end + + table.insert(userData.loadout, { + name = name, + ammo = weapon.ammo, + label = label, + components = weapon.components, + tintIndex = weapon.tintIndex + }) + end end end From 8c719dcb23f66c1328155d7d186bfeebef837d73 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 4 Mar 2020 11:23:01 +0100 Subject: [PATCH 436/672] Added missing crutial add_principal use to server configuration file --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a4e358c1..4dceab2d 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,10 @@ es_extended is a roleplay framework for FiveM. ESX is short for **Es**sentialMod - Job system, with grades and clothes support - Supports multiple languages, most strings are localized - Easy to use API for developers to easily integrate ESX to their projects +- Register your own commands easily, with argument validation, chat suggestion and using FXServer ACL ## Requirements -This order also applies in the startup order. - - [mysql-async](https://github.com/brouznouf/fivem-mysql-async) - [async](https://github.com/ESX-Org/async) @@ -63,6 +62,7 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list - Configure your `server.cfg` to look like this ``` +add_principal group.admin group.user add_ace resource.es_extended command.add_ace allow add_ace resource.es_extended command.add_principal allow From c4655598f99451060aed2b5f1993b2c7d50976b6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 4 Mar 2020 11:28:34 +0100 Subject: [PATCH 437/672] Removed ES leftover code --- server/classes/player.lua | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index d474a566..042100fd 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -191,13 +191,8 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if account then local prevMoney = account.money local newMoney = ESX.Math.Round(money) - account.money = newMoney - if accountName == 'bank' then - self.set('bank', newMoney) - end - self.triggerEvent('esx:setAccountMoney', account) end end @@ -211,10 +206,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, local newMoney = account.money + ESX.Math.Round(money) account.money = newMoney - if accountName == 'bank' then - self.set('bank', newMoney) - end - self.triggerEvent('esx:setAccountMoney', account) end end @@ -228,10 +219,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, local newMoney = account.money - ESX.Math.Round(money) account.money = newMoney - if accountName == 'bank' then - self.set('bank', newMoney) - end - self.triggerEvent('esx:setAccountMoney', account) end end From 4e4ebfff7b8294be49eaa5269d043e24561c5c56 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 4 Mar 2020 12:41:57 +0100 Subject: [PATCH 438/672] Re-done locale names for commands, moved hardcoded strings to locale and added /setgroup command --- locales/br.lua | 56 +++++++++++++++++++++--------- locales/cs.lua | 64 +++++++++++++++++++++++----------- locales/de.lua | 60 ++++++++++++++++++++++---------- locales/en.lua | 60 ++++++++++++++++++++++---------- locales/fi.lua | 60 ++++++++++++++++++++++---------- locales/fr.lua | 60 ++++++++++++++++++++++---------- locales/pl.lua | 60 ++++++++++++++++++++++---------- locales/sv.lua | 56 +++++++++++++++++++++--------- server/commands.lua | 83 ++++++++++++++++++++++++-------------------- server/functions.lua | 14 ++++---- 10 files changed, 378 insertions(+), 195 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 3258ea49..7b115f96 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -54,25 +54,47 @@ Locales['br'] = { ['in_vehicle'] = 'voce não pode dar nada para alguem no veículo', -- Commands - ['setjob'] = 'atribuir um trabalho a um usuario', - ['id_param'] = 'o ID do jogador', - ['setjob_param2'] = 'o trabalho que voce deseja atribuir', - ['setjob_param3'] = 'o nivel de emprego', - ['spawn_car'] = 'spawn um carro', - ['spawn_car_param'] = 'nome do carro', - ['delete_vehicle'] = 'excluir veículo', - ['invalid_account'] = 'conta inválida', - ['account'] = 'conta', - ['giveaccountmoney'] = 'dar dinheiro da conta', - ['invalid_item'] = 'item invalido', - ['item'] = 'item', - ['giveitem'] = 'dar item', - ['weapon'] = 'arma', - ['giveweapon'] = 'dar arma', - ['chat_clear'] = 'limpar o chat', - ['chat_clear_all'] = 'limpar o chat para todos', + ['command_car'] = 'spawn um carro', + ['command_car_car'] = 'nome do carro', + ['command_cardel'] = 'excluir veículo', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'limpar o chat', + ['command_clearall'] = 'limpar o chat para todos', ['command_clearinventory'] = 'remover todos os itens do inventário', ['command_clearloadout'] = 'remova todas as armas do carregamento', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'atribuir um trabalho a um usuario', + ['command_setjob_job'] = 'o trabalho que voce deseja atribuir', + ['command_setjob_grade'] = 'o nivel de emprego', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'dar dinheiro da conta', + ['command_giveaccountmoney_account'] = 'conta', + ['command_giveaccountmoney_amount'] = 'amount', + ['command_giveaccountmoney_invalid'] = 'conta inválida', + ['command_giveitem'] = 'dar item', + ['command_giveitem_item'] = 'item', + ['command_giveitem_count'] = 'count', + ['command_giveweapon'] = 'dar arma', + ['command_giveweapon_weapon'] = 'arma', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'item invalido', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'o ID do jogador', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/cs.lua b/locales/cs.lua index bc69b191..b99bebf0 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -53,28 +53,50 @@ Locales['cs'] = { ['act_imp'] = 'akce není možná', ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', - -- Commands - ['setjob'] = 'přiřadit práci hráči', - ['id_param'] = 'iD hráče', - ['setjob_param2'] = 'název přiřazované práce', - ['setjob_param3'] = 'úroveň práce', - ['spawn_car'] = 'spawn auto', - ['spawn_car_param'] = 'název auta', - ['delete_vehicle'] = 'odstranit vozidlo', - ['invalid_account'] = 'neplatný účet', - ['account'] = 'účet', - ['giveaccountmoney'] = 'dát peníze na účet', - ['invalid_item'] = 'neplatná věc', - ['item'] = 'věc', - ['giveitem'] = 'dát věc', - ['weapon'] = 'zbraň', - ['giveweapon'] = 'dát zbraň', - ['chat_clear'] = 'vyčistit chat', - ['chat_clear_all'] = 'vyčistit chat pro všechny', - ['command_clearinventory'] = 'vycistit vsechny predmety v invetari', - ['command_clearloadout'] = 'odebrat vsechny zbrane z rukz', + -- Commands + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', - -- Locale settings + -- Locale settings ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', diff --git a/locales/de.lua b/locales/de.lua index 4ccb00a9..86247f0b 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -54,25 +54,47 @@ Locales['de'] = { ['in_vehicle'] = 'du kannst keine Items in einem Fahrzeug weitergeben', -- Commands - ['setjob'] = 'spieler Job zuweisen', - ['id_param'] = 'ID von Spieler', - ['setjob_param2'] = 'der zu vergebende Job', - ['setjob_param3'] = 'der Jobgrad', - ['spawn_car'] = 'fahrzeug spawnen', - ['spawn_car_param'] = 'fahrzeugname', - ['delete_vehicle'] = 'entfernt Fahrzeuge', - ['invalid_account'] = 'ungültige Anzahl', - ['account'] = 'bank', - ['giveaccountmoney'] = 'bankgeld geben', - ['invalid_item'] = 'ungültiges Item', - ['item'] = 'item', - ['giveitem'] = 'item geben', - ['weapon'] = 'waffe', - ['giveweapon'] = 'waffe geben', - ['chat_clear'] = 'chat leeren', - ['chat_clear_all'] = 'chat für jeden leeren', - ['command_clearinventory'] = 'alle Items aus dem Inventar entfernen', - ['command_clearloadout'] = 'alle Waffen aus dem Loadout entfernen', + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/en.lua b/locales/en.lua index 44c4c680..e7a6549b 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -54,25 +54,47 @@ Locales['en'] = { ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', -- Commands - ['setjob'] = 'assign a job to a user', - ['id_param'] = 'the ID of the player', - ['setjob_param2'] = 'the job you wish to assign', - ['setjob_param3'] = 'the job level', - ['spawn_car'] = 'spawn a car', - ['spawn_car_param'] = 'name of car', - ['delete_vehicle'] = 'deletes Vehicle', - ['invalid_account'] = 'invalid account', - ['account'] = 'account', - ['giveaccountmoney'] = 'give account money', - ['invalid_item'] = 'invalid item', - ['item'] = 'item', - ['giveitem'] = 'give item', - ['weapon'] = 'weapon', - ['giveweapon'] = 'give weapon', - ['chat_clear'] = 'clear the chat', - ['chat_clear_all'] = 'clear the chat for everyone', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', -- Locale settings ['locale_digit_grouping_symbol'] = ',', diff --git a/locales/fi.lua b/locales/fi.lua index 6e113511..cd3b3d6b 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -54,25 +54,47 @@ Locales['fi'] = { ['in_vehicle'] = 'et voi antaa ajoneuvossa olevalle mitään', -- Commands - ['setjob'] = 'määritä työ käyttäjälle', - ['id_param'] = 'käyttäjän ID', - ['setjob_param2'] = 'työ jonka haluat määrittää', - ['setjob_param3'] = 'työn taso', - ['spawn_car'] = 'spawnaa ajoneuvo', - ['spawn_car_param'] = 'ajoneuvon nimi', - ['delete_vehicle'] = 'poistaa ajoneuvon', - ['invalid_account'] = 'virheellinen tunnus', - ['account'] = 'tunnus', - ['giveaccountmoney'] = 'anna tilille rahaa', - ['invalid_item'] = 'virheellinen itemi', - ['item'] = 'esine', - ['giveitem'] = 'anna itemi', - ['weapon'] = 'ase', - ['giveweapon'] = 'anna ase', - ['chat_clear'] = 'tyhjennä chatti', - ['chat_clear_all'] = 'tyhjennä chatti kaikilta', - ['command_clearinventory'] = 'clear all items from inventory', - ['command_clearloadout'] = 'remove all weapons from loadout', + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/fr.lua b/locales/fr.lua index 9e5bd015..350055bc 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -54,25 +54,47 @@ Locales['fr'] = { ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', -- Commands - ['setjob'] = 'assigner job', - ['id_param'] = 'identification du joueur', - ['setjob_param2'] = 'le travail que vous souhaitez assigner', - ['setjob_param3'] = 'le niveau d\'emploi', - ['spawn_car'] = 'spawn un véhicule', - ['spawn_car_param'] = 'nom de la voiture', - ['delete_vehicle'] = 'supprimer le véhicule', - ['invalid_account'] = 'compte invalide', - ['account'] = 'compte', - ['giveaccountmoney'] = 'donner de l\'argent au compte', - ['invalid_item'] = 'item invalide', - ['item'] = 'article', - ['giveitem'] = 'donner un article', - ['weapon'] = 'arme', - ['giveweapon'] = 'donner l\'arme', - ['chat_clear'] = 'vider le chat', - ['chat_clear_all'] = 'vider le chat pour tous le monde', - ['command_clearinventory'] = 'effacer tout les items de l\'inventaire', - ['command_clearloadout'] = 'retirer toutes les armes de l\'équipement', + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/pl.lua b/locales/pl.lua index a691437a..3f727d5f 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -54,25 +54,47 @@ Locales['pl'] = { ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', -- Commands - ['setjob'] = 'przydziel prace użytkownikowi', - ['id_param'] = 'ID użytkownika', - ['setjob_param2'] = 'praca, którą chcesz przydzielić', - ['setjob_param3'] = 'poziom pracy', - ['spawn_car'] = 'sprowadź pojazd', - ['spawn_car_param'] = 'nazwa samochodu', - ['delete_vehicle'] = 'usuń pojazd', - ['invalid_account'] = 'błędne konto', - ['account'] = 'konto', - ['giveaccountmoney'] = 'daj pieniądze na konto', - ['invalid_item'] = 'nieprawidłowy przedmiot', - ['item'] = 'przedmiot', - ['giveitem'] = 'daj przedmiot', - ['weapon'] = 'broń', - ['giveweapon'] = 'daj broń', - ['chat_clear'] = 'wyczyść czat', - ['chat_clear_all'] = 'wyczyść czat dla wszystkich', - ['command_clearinventory'] = 'usuń wszystkie przedmioty z ekwipunku', - ['command_clearloadout'] = 'usuń wszystkie bronie z wyposażenia', + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/locales/sv.lua b/locales/sv.lua index 8be097c6..df1f21db 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -54,25 +54,47 @@ Locales['sv'] = { ['in_vehicle'] = 'du kan inte ge saker till en som sitter i ett fordon!', -- Commands - ['setjob'] = 'tilldela ett jobb till en spelare', - ['id_param'] = 'spelarens ID', - ['setjob_param2'] = 'det jobb du vill tilldela', - ['setjob_param3'] = 'job nivå', - ['spawn_car'] = 'spawna ett fordon', - ['spawn_car_param'] = 'namn på fordon', - ['delete_vehicle'] = 'ta bort fordon', - ['invalid_account'] = 'ogiltigt konto', - ['account'] = 'konto', - ['giveaccountmoney'] = 'ge spelarkonto pengar', - ['invalid_item'] = 'ogiltigt föremål', - ['item'] = 'föremål', - ['giveitem'] = 'ge ett föremål', - ['weapon'] = 'vapen', - ['giveweapon'] = 'ge ett vapen', - ['chat_clear'] = 'töm chatten', - ['chat_clear_all'] = 'töm chatten för alla', + ['command_car'] = 'spawna ett fordon', + ['command_car_car'] = 'namn på fordon eller hash', + ['command_cardel'] = 'radera fordon i närheten', + ['command_cardel_radius'] = 'valfri, radera alla fordon inom den angivna radien', + ['command_clear'] = 'töm chatten', + ['command_clearall'] = 'töm chatten för alla spelare', ['command_clearinventory'] = 'töm en spelares inventory', ['command_clearloadout'] = 'töm en spelares loadout', + ['command_setcoords'] = 'teleportera till koordinater', + ['command_setcoords_x'] = 'x axel', + ['command_setcoords_y'] = 'y axel', + ['command_setcoords_z'] = 'z axel', + ['command_setjob'] = 'välj jobb för en spelare', + ['command_setjob_job'] = 'jobbnamn', + ['command_setjob_grade'] = 'jobbnivå', + ['command_setjob_invalid'] = 'jobbet, nivån eller båda är ej giltiga', + ['command_setgroup'] = 'välj grupp åt en spelare', + ['command_setgroup_group'] = 'gruppnamn', + ['command_giveaccountmoney'] = 'ge pengar för ett konto', + ['command_giveaccountmoney_account'] = 'giltigt kontonamn', + ['command_giveaccountmoney_amount'] = 'mängd att ge', + ['command_giveaccountmoney_invalid'] = 'kontonamnet är ej giltigt', + ['command_giveitem'] = 'ge ett item till en spelare', + ['command_giveitem_item'] = 'itemnamn', + ['command_giveitem_count'] = 'mängd av itemet', + ['command_giveweapon'] = 'ge ett vapen till en spelare', + ['command_giveweapon_weapon'] = 'vapennamn', + ['command_giveweapon_ammo'] = 'hur mycket ammo att ge', + ['command_giveweapon_hasalready'] = 'spelaren har redan ett sådant vapen', + ['command_giveweaponcomponent'] = 'ge vapen komponent', + ['command_giveweaponcomponent_component'] = 'vapenkomponent', + ['command_giveweaponcomponent_invalid'] = 'det vapenkomponentet är ej giltigt', + ['command_giveweaponcomponent_hasalready'] = 'spelaren har redan det vapenkomponent', + ['command_giveweaponcomponent_missingweapon'] = 'spelaren har ej det vapnet', + ['commanderror_argumentmismatch'] = 'argumentstorlek mismatch (gav %s, ville ha %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s typ mismatch (gav string, ville ha number)', + ['commanderror_invaliditem'] = 'ej giltigt item', + ['commanderror_invalidweapon'] = 'ej giltigt vapen', + ['commanderror_console'] = 'detta kommando kan ej executas i konsol', + ['commanderror_invalidplayerid'] = 'det finns ingen spelare som matchar det angivna server id', + ['commandgeneric_playerid'] = 'spelarid', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', diff --git a/server/commands.lua b/server/commands.lua index 23892beb..1639edd2 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -1,65 +1,65 @@ ESX.RegisterCommand('setcoords', 'admin', function(xPlayer, args, showError) xPlayer.setCoords({x = args.x, y = args.y, z = args.z}) -end, false, {help = 'Teleport to coordinates', validate = true, arguments = { - {name = 'x', help = 'X coords', type = 'number'}, - {name = 'y', help = 'Y coords', type = 'number'}, - {name = 'z', help = 'Z coords', type = 'number'} +end, false, {help = _U('command_setcoords'), validate = true, arguments = { + {name = 'x', help = _U('command_setcoords_x'), type = 'number'}, + {name = 'y', help = _U('command_setcoords_y'), type = 'number'}, + {name = 'z', help = _U('command_setcoords_z'), type = 'number'} }}) ESX.RegisterCommand('setjob', 'admin', function(xPlayer, args, showError) if ESX.DoesJobExist(args.job, args.grade) then args.playerId.setJob(args.job, args.grade) else - showError('That job does not exist') + showError(_U('command_setjob_invalid')) end -end, true, {help = _U('setjob'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'}, - {name = 'job', help = _U('setjob_param2'), type = 'string'}, - {name = 'grade', help = _U('setjob_param3'), type = 'number'} +end, true, {help = _U('command_setjob'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'job', help = _U('command_setjob_job'), type = 'string'}, + {name = 'grade', help = _U('command_setjob_grade'), type = 'number'} }}) ESX.RegisterCommand('car', 'admin', function(xPlayer, args, showError) xPlayer.triggerEvent('esx:spawnVehicle', args.car) -end, false, {help = _U('spawn_car'), validate = false, arguments = { - {name = 'car', help = _U('spawn_car_param'), type = 'any'} +end, false, {help = _U('command_car'), validate = false, arguments = { + {name = 'car', help = _U('command_car_car'), type = 'any'} }}) ESX.RegisterCommand({'cardel', 'dv'}, 'admin', function(xPlayer, args, showError) xPlayer.triggerEvent('esx:deleteVehicle', args.radius) -end, false, {help = _U('spawn_car'), validate = false, arguments = { - {name = 'radius', help = 'Optional, delete every vehicle within the specified radius', type = 'any'} +end, false, {help = _U('command_cardel'), validate = false, arguments = { + {name = 'radius', help = _U('command_cardel_radius'), type = 'any'} }}) ESX.RegisterCommand('giveaccountmoney', 'admin', function(xPlayer, args, showError) if args.playerId.getAccount(args.account) then args.playerId.addAccountMoney(args.account, args.amount) else - showError(_U('invalid_account')) + showError(_U('command_giveaccountmoney_invalid')) end -end, true, {help = _U('giveaccountmoney'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'}, - {name = 'account', help = _U('account'), type = 'string'}, - {name = 'amount', help = _U('money_amount'), type = 'number'} +end, true, {help = _U('command_giveaccountmoney'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'account', help = _U('command_giveaccountmoney_account'), type = 'string'}, + {name = 'amount', help = _U('command_giveaccountmoney_amount'), type = 'number'} }}) ESX.RegisterCommand('giveitem', 'admin', function(xPlayer, args, showError) args.playerId.addInventoryItem(args.item, args.count) -end, true, {help = _U('giveitem'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'}, - {name = 'item', help = _U('item'), type = 'item'}, - {name = 'count', help = _U('amount'), type = 'number'} +end, true, {help = _U('command_giveitem'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'item', help = _U('command_giveitem_item'), type = 'item'}, + {name = 'count', help = _U('command_giveitem_count'), type = 'number'} }}) ESX.RegisterCommand('giveweapon', 'admin', function(xPlayer, args, showError) if args.playerId.hasWeapon(args.weapon) then - showError('Player already has that weapon') + showError(_U('command_giveweapon_hasalready')) else xPlayer.addWeapon(args.weapon, args.ammo) end -end, true, {help = _U('giveweapon'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'}, - {name = 'weapon', help = _U('weapon'), type = 'weapon'}, - {name = 'ammo', help = _U('amountammo'), type = 'number'} +end, true, {help = _U('command_giveweapon'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'weapon', help = _U('command_giveweapon_weapon'), type = 'weapon'}, + {name = 'ammo', help = _U('command_giveweapon_ammo'), type = 'number'} }}) ESX.RegisterCommand('giveweaponcomponent', 'admin', function(xPlayer, args, showError) @@ -68,29 +68,29 @@ ESX.RegisterCommand('giveweaponcomponent', 'admin', function(xPlayer, args, show if component then if xPlayer.hasWeaponComponent(args.weaponName, args.componentName) then - showError('Player already has that weapon component') + showError(_U('command_giveweaponcomponent_hasalready')) else xPlayer.addWeaponComponent(args.weaponName, args.componentName) end else - showError('Invalid weapon component') + showError(_U('command_giveweaponcomponent_invalid')) end else - showError('Player does not have that weapon') + showError(_U('command_giveweaponcomponent_missingweapon')) end -end, true, {help = 'Give weapon component', validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'}, - {name = 'weaponName', help = _U('weapon'), type = 'weapon'}, - {name = 'componentName', help = 'weapon component', type = 'string'} +end, true, {help = _U('command_giveweaponcomponent'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'weaponName', help = _U('command_giveweapon_weapon'), type = 'weapon'}, + {name = 'componentName', help = _U('command_giveweaponcomponent_component'), type = 'string'} }}) ESX.RegisterCommand({'clear', 'cls'}, 'user', function(xPlayer, args, showError) xPlayer.triggerEvent('chat:clear') -end, false, {help = _U('chat_clear')}) +end, false, {help = _U('command_clear')}) ESX.RegisterCommand({'clearall', 'clsall'}, 'admin', function(xPlayer, args, showError) TriggerClientEvent('chat:clear', -1) -end, false, {help = _U('chat_clear_all')}) +end, false, {help = _U('command_clearall')}) ESX.RegisterCommand('clearinventory', 'admin', function(xPlayer, args, showError) for k,v in ipairs(args.playerId.inventory) do @@ -99,7 +99,7 @@ ESX.RegisterCommand('clearinventory', 'admin', function(xPlayer, args, showError end end end, true, {help = _U('command_clearinventory'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'} + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'} }}) ESX.RegisterCommand('clearloadout', 'admin', function(xPlayer, args, showError) @@ -107,5 +107,12 @@ ESX.RegisterCommand('clearloadout', 'admin', function(xPlayer, args, showError) args.playerId.removeWeapon(v.name) end end, true, {help = _U('command_clearloadout'), validate = true, arguments = { - {name = 'playerId', help = _U('id_param'), type = 'player'} + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'} +}}) + +ESX.RegisterCommand('setgroup', 'admin', function(xPlayer, args, showError) + args.playerId.setGorup(args.group) +end, true, {help = _U('command_setgroup'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'group', help = _U('command_setgroup_group'), type = 'string'}, }}) diff --git a/server/functions.lua b/server/functions.lua index a0f3d5aa..caf97a02 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -50,14 +50,14 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) local command = ESX.RegisteredCommands[name] if not command.allowConsole and playerId == 0 then - print('[es_extended] [^3WARNING^7] That command can not be run from console') + print(('[es_extended] [^3WARNING^7] %s'):format(_U('commanderror_console'))) else local xPlayer, error = ESX.GetPlayerFromId(playerId), nil if command.suggestion then if command.suggestion.validate then if #args ~= #command.suggestion.arguments then - error = ('Argument count mismatch (passed %s, wanted %s)'):format(#args, #command.suggestion.arguments) + error = _U('commanderror_argumentmismatch', #args, #command.suggestion.arguments) end end @@ -72,7 +72,7 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) if newArg then newArgs[v.name] = newArg else - error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + error = _U('commanderror_argumentmismatch_number', k) end elseif v.type == 'player' or v.type == 'playerId' then local targetPlayer = tonumber(args[k]) @@ -89,10 +89,10 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) newArgs[v.name] = targetPlayer end else - error = 'Player not online' + error = _U('commanderror_invalidplayerid') end else - error = ('Argument #%s type mismatch (passed string, wanted number)'):format(k) + error = _U('commanderror_argumentmismatch_number', k) end elseif v.type == 'string' then newArgs[v.name] = args[k] @@ -100,13 +100,13 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) if ESX.Items[args[k]] then newArgs[v.name] = args[k] else - error = _U('invalid_item') + error = _U('commanderror_invaliditem') end elseif v.type == 'weapon' then if ESX.GetWeapon(args[k]) then newArgs[v.name] = string.upper(args[k]) else - error = 'Invalid weapon' + error = _U('commanderror_invalidweapon') end elseif v.type == 'any' then newArgs[v.name] = args[k] From a2308dec59f9e8fe85537a72aacee964bbd513b6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 4 Mar 2020 13:01:46 +0100 Subject: [PATCH 439/672] Implemented starting balance, closes #537 --- config.lua | 2 ++ server/classes/player.lua | 9 +++++---- server/main.lua | 11 +++++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/config.lua b/config.lua index be3e5171..a6f10be3 100644 --- a/config.lua +++ b/config.lua @@ -7,6 +7,8 @@ Config.Accounts = { money = _U('account_money') } +Config.StartingAccountMoney = {bank = 50000} + Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) diff --git a/server/classes/player.lua b/server/classes/player.lua index 042100fd..86c2583b 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -164,7 +164,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end if not found then - table.insert(missingAccounts, account) + missingAccounts[account] = Config.StartingAccountMoney[account] or 0 end end @@ -172,10 +172,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end self.createMissingAccounts = function(missingAccounts, cb) - for k,v in ipairs(missingAccounts) do - MySQL.Async.execute('INSERT INTO user_accounts (identifier, name) VALUES (@identifier, @name)', { + for name,money in pairs(missingAccounts) do + MySQL.Async.execute('INSERT INTO user_accounts (identifier, name, money) VALUES (@identifier, @name, @money)', { ['@identifier'] = self.identifier, - ['@name'] = v + ['@name'] = name, + ['@money'] = money }, function(rowsChanged) if cb then cb() diff --git a/server/main.lua b/server/main.lua index b52782d0..68cc5852 100644 --- a/server/main.lua +++ b/server/main.lua @@ -169,12 +169,12 @@ function loadESXPlayer(identifier, playerId) local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords) xPlayer.getMissingAccounts(function(missingAccounts) - if #missingAccounts > 0 then - for k,v in ipairs(missingAccounts) do + if ESX.Table.SizeOf(missingAccounts) > 0 then + for name,money in pairs(missingAccounts) do table.insert(xPlayer.accounts, { - name = v, - money = 0, - label = Config.Accounts[v] + name = name, + money = money, + label = Config.Accounts[name] }) end @@ -192,7 +192,6 @@ function loadESXPlayer(identifier, playerId) inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), - money = xPlayer.getMoney(), maxWeight = xPlayer.maxWeight }) From e31077efbbdab1df6f3cf0217d9541b1a5ff3b46 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 4 Mar 2020 13:03:19 +0100 Subject: [PATCH 440/672] Update README.md --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4dceab2d..524d5018 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,14 @@ # es_extended -es_extended is a roleplay framework for FiveM. ESX is short for **Es**sentialMode E**x**tended. +es_extended is a roleplay framework for FiveM. ESX is short for EssentialMode Extended. The to-go framework for creating an economy based roleplay server on FiveM and most popular on the platform, too! + +Featuring many extra resources to fit roleplaying servers, here's a taste of what's available: + +- esx_ambulancejob: play as a medic to revive players who are bleeding out. Complete with garages and respawn & bleedout system +- esx_policejob: patrol the city and arrest players commiting crime, with armory, outfit room and garages +- esx_vehicleshop: roleplay working in an vehicle dealership where you sell cars to players + +ESX was initially developed by Gizz back in 2017 for his friend as the were creating an FiveM server and there wasn't any economy roleplaying frameworks available. The original code was written within a week or two and later open sourced, it has ever since been improved and parts been rewritten to further improve on it. ## Links & Read more From 3ba2ed150fda32756259d7c55c37961c2d7996a0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 6 Mar 2020 20:41:37 +0100 Subject: [PATCH 441/672] Save accounts as encoded json text, migrate script found in development discord --- es_extended.sql | 12 +---- server/classes/player.lua | 48 +++++------------- server/common.lua | 14 +----- server/functions.lua | 32 +++--------- server/main.lua | 101 +++++++++++++++++--------------------- 5 files changed, 68 insertions(+), 139 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 111cef1f..9ea30491 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -2,10 +2,11 @@ USE `essentialmode`; CREATE TABLE `users` ( `identifier` VARCHAR(40) NOT NULL, + `accounts` LONGTEXT NULL DEFAULT NULL, `group` VARCHAR(50) NULL DEFAULT 'user', + `inventory` LONGTEXT NULL DEFAULT NULL, `job` VARCHAR(20) NULL DEFAULT 'unemployed', `job_grade` INT(11) NULL DEFAULT 0, - `inventory` LONGTEXT NULL DEFAULT NULL, `loadout` LONGTEXT NULL DEFAULT NULL, `position` VARCHAR(53) NULL DEFAULT '{"x":-269.4,"y":-955.3,"z":31.2,"heading":205.8}', @@ -45,12 +46,3 @@ CREATE TABLE `jobs` ( ); INSERT INTO `jobs` VALUES ('unemployed','Unemployed'); - -CREATE TABLE `user_accounts` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `identifier` VARCHAR(40) NOT NULL, - `name` VARCHAR(50) NOT NULL, - `money` INT(11) NOT NULL DEFAULT '0', - - PRIMARY KEY (`id`) -); diff --git a/server/classes/player.lua b/server/classes/player.lua index 86c2583b..68242e13 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -82,8 +82,18 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return self.variables[k] end - self.getAccounts = function() - return self.accounts + self.getAccounts = function(minimal) + if minimal then + local minimalAccounts = {} + + for k,v in ipairs(self.accounts) do + minimalAccounts[v.name] = v.money + end + + return minimalAccounts + else + return self.accounts + end end self.getAccount = function(account) @@ -151,40 +161,6 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.name = newName end - self.getMissingAccounts = function(cb) - local missingAccounts = {} - - for account,label in pairs(Config.Accounts) do - local found = false - - for k2,v2 in ipairs(self.accounts) do - if account == v2.name then - found = true - end - end - - if not found then - missingAccounts[account] = Config.StartingAccountMoney[account] or 0 - end - end - - cb(missingAccounts) - end - - self.createMissingAccounts = function(missingAccounts, cb) - for name,money in pairs(missingAccounts) do - MySQL.Async.execute('INSERT INTO user_accounts (identifier, name, money) VALUES (@identifier, @name, @money)', { - ['@identifier'] = self.identifier, - ['@name'] = name, - ['@money'] = money - }, function(rowsChanged) - if cb then - cb() - end - end) - end - end - self.setAccountMoney = function(accountName, money) if money >= 0 then local account = self.getAccount(accountName) diff --git a/server/common.lua b/server/common.lua index b9d5f601..4921c75c 100644 --- a/server/common.lua +++ b/server/common.lua @@ -5,7 +5,6 @@ ESX.Items = {} ESX.ServerCallbacks = {} ESX.TimeoutCount = -1 ESX.CancelledTimeouts = {} -ESX.LastPlayerData = {} ESX.Pickups = {} ESX.PickupId = 0 ESX.Jobs = {} @@ -58,17 +57,6 @@ MySQL.ready(function() print('[es_extended] [^2INFO^7] ESX developed by ESX-Org has been initialized') end) -AddEventHandler('esx:playerLoaded', function(playerId) - local xPlayer, accounts = ESX.GetPlayerFromId(playerId), {} - local xPlayerAccounts = xPlayer.getAccounts() - - for i=1, #xPlayerAccounts, 1 do - accounts[xPlayerAccounts[i].name] = xPlayerAccounts[i].money - end - - ESX.LastPlayerData[playerId] = {accounts = accounts} -end) - RegisterServerEvent('esx:clientLog') AddEventHandler('esx:clientLog', function(msg) if Config.EnableDebug then @@ -80,7 +68,7 @@ RegisterServerEvent('esx:triggerServerCallback') AddEventHandler('esx:triggerServerCallback', function(name, requestId, ...) local playerId = source - ESX.TriggerServerCallback(name, requestID, playerId, function(...) + ESX.TriggerServerCallback(name, requestId, playerId, function(...) TriggerClientEvent('esx:serverCallback', playerId, requestId, ...) end, ...) end) diff --git a/server/functions.lua b/server/functions.lua index caf97a02..6cb0b427 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -150,7 +150,7 @@ ESX.RegisterServerCallback = function(name, cb) end ESX.TriggerServerCallback = function(name, requestId, source, cb, ...) - if ESX.ServerCallbacks[name] ~= nil then + if ESX.ServerCallbacks[name] then ESX.ServerCallbacks[name](source, cb, ...) else print(('[es_extended] [^3WARNING^7] Server callback "%s" does not exist. Make sure that the server sided file really is loading, an error in that file might cause it to not load.'):format(name)) @@ -160,26 +160,9 @@ end ESX.SavePlayer = function(xPlayer, cb) local asyncTasks = {} - -- User accounts - for k,v in ipairs(xPlayer.accounts) do - if ESX.LastPlayerData[xPlayer.source].accounts[v.name] ~= v.money then - table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE user_accounts SET money = @money WHERE identifier = @identifier AND name = @name', { - ['@money'] = v.money, - ['@identifier'] = xPlayer.identifier, - ['@name'] = v.name - }, function(rowsChanged) - cb() - end) - end) - - ESX.LastPlayerData[xPlayer.source].accounts[v.name] = v.money - end - end - - -- Job, loadout, inventory and position table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE users SET job = @job, job_grade = @job_grade, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { + MySQL.Async.execute('UPDATE users SET accounts = @accounts, job = @job, job_grade = @job_grade, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { + ['@accounts'] = json.encode(xPlayer.getAccounts(true)), ['@job'] = xPlayer.job.name, ['@job_grade'] = xPlayer.job.grade, ['@loadout'] = json.encode(xPlayer.getLoadout(true)), @@ -194,15 +177,14 @@ ESX.SavePlayer = function(xPlayer, cb) Async.parallel(asyncTasks, function(results) print(('[es_extended] [^2INFO^7] Saved player "%s^7"'):format(xPlayer.getName())) - if cb ~= nil then + if cb then cb() end end) end ESX.SavePlayers = function(cb) - local asyncTasks = {} - local xPlayers = ESX.GetPlayers() + local xPlayers, asyncTasks = ESX.GetPlayers(), {} for i=1, #xPlayers, 1 do table.insert(asyncTasks, function(cb) @@ -213,7 +195,7 @@ ESX.SavePlayers = function(cb) Async.parallelLimit(asyncTasks, 8, function(results) print(('[es_extended] [^2INFO^7] Saved %s player(s)'):format(#xPlayers)) - if cb ~= nil then + if cb then cb() end end) @@ -259,7 +241,7 @@ ESX.UseItem = function(source, item) end ESX.GetItemLabel = function(item) - if ESX.Items[item] ~= nil then + if ESX.Items[item] then return ESX.Items[item].label end end diff --git a/server/main.lua b/server/main.lua index 68cc5852..50b82f48 100644 --- a/server/main.lua +++ b/server/main.lua @@ -20,7 +20,14 @@ function onPlayerJoined(playerId) if result then loadESXPlayer(identifier, playerId) else - MySQL.Async.execute('INSERT INTO users (identifier) VALUES (@identifier)', { + local accounts = {} + + for account,money in pairs(Config.StartingAccountMoney) do + accounts[account] = money + end + + MySQL.Async.execute('INSERT INTO users (accounts, identifier) VALUES (@accounts, @identifier)', { + ['@accounts'] = json.encode(accounts), ['@identifier'] = identifier }, function(rowsChanged) loadESXPlayer(identifier, playerId) @@ -43,31 +50,31 @@ function loadESXPlayer(identifier, playerId) playerName = GetPlayerName(playerId) } - -- get accounts table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT name, money FROM user_accounts WHERE identifier = @identifier', { - ['@identifier'] = identifier - }, function(accounts) - for k,v in ipairs(accounts) do - if Config.Accounts[v.name] then - table.insert(userData.accounts, { - name = v.name, - money = v.money, - label = Config.Accounts[v.name] - }) - end - end - - cb() - end) - end) - - table.insert(tasks, function(cb) - MySQL.Async.fetchAll('SELECT job, job_grade, `group`, loadout, position, inventory FROM users WHERE identifier = @identifier', { + MySQL.Async.fetchAll('SELECT accounts, job, job_grade, `group`, loadout, position, inventory FROM users WHERE identifier = @identifier', { ['@identifier'] = identifier }, function(result) local job, grade, jobObject, gradeObject = result[1].job, tostring(result[1].job_grade) + local fonudAccounts, foundItems = {}, {} + -- Accounts + if result[1].accounts and result[1].accounts ~= '' then + local accounts = json.decode(result[1].accounts) + + for account,money in pairs(accounts) do + fonudAccounts[account] = money + end + end + + for account,label in pairs(Config.Accounts) do + table.insert(userData.accounts, { + name = account, + money = fonudAccounts[account] or Config.StartingAccountMoney[account] or 0, + label = label + }) + end + + -- Job if ESX.DoesJobExist(job, grade) then jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] else @@ -76,8 +83,6 @@ function loadESXPlayer(identifier, playerId) jobObject, gradeObject = ESX.Jobs[job], ESX.Jobs[job].grades[grade] end - userData.job = {} - userData.job.id = jobObject.id userData.job.name = jobObject.name userData.job.label = jobObject.label @@ -93,8 +98,7 @@ function loadESXPlayer(identifier, playerId) if gradeObject.skin_male then userData.job.skin_male = json.decode(gradeObject.skin_male) end if gradeObject.skin_female then userData.job.skin_female = json.decode(gradeObject.skin_female) end - local foundItems = {} - + -- Inventory if result[1].inventory and result[1].inventory ~= '' then local inventory = json.decode(result[1].inventory) @@ -123,6 +127,7 @@ function loadESXPlayer(identifier, playerId) }) end + -- Group if result[1].group then userData.group = result[1].group else @@ -133,6 +138,7 @@ function loadESXPlayer(identifier, playerId) return a.label < b.label end) + -- Loadout if result[1].loadout and result[1].loadout ~= '' then local loadout = json.decode(result[1].loadout) @@ -154,6 +160,7 @@ function loadESXPlayer(identifier, playerId) end end + -- Position if result[1].position and result[1].position ~= '' then userData.coords = json.decode(result[1].position) else @@ -167,37 +174,22 @@ function loadESXPlayer(identifier, playerId) Async.parallel(tasks, function(results) local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords) + ESX.Players[playerId] = xPlayer + TriggerEvent('esx:playerLoaded', playerId, xPlayer) - xPlayer.getMissingAccounts(function(missingAccounts) - if ESX.Table.SizeOf(missingAccounts) > 0 then - for name,money in pairs(missingAccounts) do - table.insert(xPlayer.accounts, { - name = name, - money = money, - label = Config.Accounts[name] - }) - end + xPlayer.triggerEvent('esx:playerLoaded', { + accounts = xPlayer.getAccounts(), + coords = xPlayer.getCoords(), + identifier = xPlayer.identifier, + inventory = xPlayer.getInventory(), + job = xPlayer.getJob(), + loadout = xPlayer.getLoadout(), + maxWeight = xPlayer.maxWeight, + money = xPlayer.getMoney(), + }) - xPlayer.createMissingAccounts(missingAccounts) - end - - ESX.Players[playerId] = xPlayer - TriggerEvent('esx:playerLoaded', playerId, xPlayer) - - xPlayer.triggerEvent('esx:playerLoaded', { - identifier = xPlayer.identifier, - money = xPlayer.getMoney(), - accounts = xPlayer.getAccounts(), - coords = xPlayer.getCoords(), - inventory = xPlayer.getInventory(), - job = xPlayer.getJob(), - loadout = xPlayer.getLoadout(), - maxWeight = xPlayer.maxWeight - }) - - xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) - xPlayer.triggerEvent('esx:registerSuggestions', ESX.RegisteredCommands) - end) + xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) + xPlayer.triggerEvent('esx:registerSuggestions', ESX.RegisteredCommands) end) end @@ -210,7 +202,6 @@ AddEventHandler('playerDropped', function(reason) ESX.SavePlayer(xPlayer, function() ESX.Players[playerId] = nil - ESX.LastPlayerData[playerId] = nil end) end end) From 1d60857a7ef8087f16ba598a231704db5ee01f32 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 6 Mar 2020 20:46:28 +0100 Subject: [PATCH 442/672] Fixed /setgroup command --- README.md | 1 + server/commands.lua | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 524d5018..f10cdc04 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ git clone https://github.com/ESX-Org/esx_menu_list [esx]/[ui]/esx_menu_list add_principal group.admin group.user add_ace resource.es_extended command.add_ace allow add_ace resource.es_extended command.add_principal allow +add_ace resource.es_extended command.remove_principal allow start mysql-async start es_extended diff --git a/server/commands.lua b/server/commands.lua index 1639edd2..b8a187f1 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -111,7 +111,7 @@ end, true, {help = _U('command_clearloadout'), validate = true, arguments = { }}) ESX.RegisterCommand('setgroup', 'admin', function(xPlayer, args, showError) - args.playerId.setGorup(args.group) + args.playerId.setGroup(args.group) end, true, {help = _U('command_setgroup'), validate = true, arguments = { {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, {name = 'group', help = _U('command_setgroup_group'), type = 'string'}, From 829994dd9c26d94509cf9c08bff0fe00379839ab Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Fri, 6 Mar 2020 20:59:18 +0100 Subject: [PATCH 443/672] Updated French translations (#551) * Update fr.lua * Fix indent --- locales/fr.lua | 78 +++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 350055bc..502e360c 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -54,47 +54,47 @@ Locales['fr'] = { ['in_vehicle'] = 'Vous ne pouvez rien donner à quelqu\'un dans un véhicule', -- Commands - ['command_car'] = 'spawn an vehicle', - ['command_car_car'] = 'vehicle spawn name or hash', - ['command_cardel'] = 'delete vehicle in proximity', - ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', - ['command_clear'] = 'clear chat', - ['command_clearall'] = 'clear chat for all players', - ['command_clearinventory'] = 'clear player inventory', - ['command_clearloadout'] = 'clear a player loadout', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', - ['command_giveaccountmoney'] = 'give account money', - ['command_giveaccountmoney_account'] = 'valid account name', - ['command_giveaccountmoney_amount'] = 'amount to add', - ['command_giveaccountmoney_invalid'] = 'invalid account name', - ['command_giveitem'] = 'give an item to a player', - ['command_giveitem_item'] = 'item name', - ['command_giveitem_count'] = 'item count', - ['command_giveweapon'] = 'give a weapon to a player', - ['command_giveweapon_weapon'] = 'weapon name', - ['command_giveweapon_ammo'] = 'ammo count', - ['command_giveweapon_hasalready'] = 'player already has that weapon', - ['command_giveweaponcomponent'] = 'give weapon component', - ['command_giveweaponcomponent_component'] = 'component name', - ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', - ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', - ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_car'] = 'faire appaitre un véhicule', + ['command_car_car'] = 'nom ou hash du véhicule', + ['command_cardel'] = 'supprimer le véhicule à proximité', + ['command_cardel_radius'] = 'optionnel, supprime les véhicules dans un rayon spécifié', + ['command_clear'] = 'vider le chat', + ['command_clearall'] = 'vider le chat pour tous', + ['command_clearinventory'] = 'vider l\'inventaire d\'un joueur', + ['command_clearloadout'] = 'vider le loadout d\'un joueur', + ['command_setcoords'] = 'se téléporter aux coordonnées', + ['command_setcoords_x'] = 'axe X', + ['command_setcoords_y'] = 'axe Y', + ['command_setcoords_z'] = 'axe Z', + ['command_setjob'] = 'assigner job à un joueur', + ['command_setjob_job'] = 'nom du job', + ['command_setjob_grade'] = 'grade du job', + ['command_setjob_invalid'] = 'le job, le grade ou les deux sont invalides', + ['command_setgroup'] = 'assigner un groupe à un joueur', + ['command_setgroup_group'] = 'nom du groupe', + ['command_giveaccountmoney'] = 'donner de l\'argent sur un compte', + ['command_giveaccountmoney_account'] = 'nom de compte valide', + ['command_giveaccountmoney_amount'] = 'quantité à ajouter', + ['command_giveaccountmoney_invalid'] = 'nom de compte invalide', + ['command_giveitem'] = 'donner un objet à un joueur', + ['command_giveitem_item'] = 'nom de l\'objet', + ['command_giveitem_count'] = 'quantité de l\'objet', + ['command_giveweapon'] = 'donner une arme à un joueur', + ['command_giveweapon_weapon'] = 'nom de l\'arme', + ['command_giveweapon_ammo'] = 'quantité de munitions', + ['command_giveweapon_hasalready'] = 'le joueur a déjà cette arme', + ['command_giveweaponcomponent'] = 'donner un accessoire d\'arme', + ['command_giveweaponcomponent_component'] = 'nom de l\'accessoire', + ['command_giveweaponcomponent_invalid'] = 'accessoire invalide', + ['command_giveweaponcomponent_hasalready'] = 'le joueur a déjà cet accessoire', + ['command_giveweaponcomponent_missingweapon'] = 'le joueur n\'a pas cette arme', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', - ['commanderror_invaliditem'] = 'invalid item name', - ['commanderror_invalidweapon'] = 'invalid weapon', - ['commanderror_console'] = 'that command can not be run from console', - ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', - ['commandgeneric_playerid'] = 'player id', + ['commanderror_invaliditem'] = 'nom de l\'objet invalide', + ['commanderror_invalidweapon'] = 'arme invalide', + ['commanderror_console'] = 'cette commande ne peut pas être utilisée dans la console', + ['commanderror_invalidplayerid'] = 'il n\'ya aucun joueur avec cet ID en jeu', + ['commandgeneric_playerid'] = 'id joueur', -- Locale settings ['locale_digit_grouping_symbol'] = ' ', From 086f280a77ab08f7f756f10d49c2473750d4fb66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BA=BB=E8=BE=A3=E6=88=88=E5=A3=81?= Date: Sat, 7 Mar 2020 19:59:45 +0800 Subject: [PATCH 444/672] Fix give weapon ammo on esx:giveInventoryItem --- server/main.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 50b82f48..e30d394a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -281,8 +281,9 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo end elseif type == 'item_ammo' then if sourceXPlayer.hasWeapon(itemName) then + local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) + if targetXPlayer.hasWeapon(itemName) then - local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) local _, weaponObject = ESX.GetWeapon(itemName) if weaponObject.ammo then From 7efcf85abb73d44fed3630a47a756878170fb007 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 9 Mar 2020 12:35:40 +0100 Subject: [PATCH 445/672] Fixed indent mistake --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index e30d394a..9dc9e753 100644 --- a/server/main.lua +++ b/server/main.lua @@ -282,7 +282,7 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo elseif type == 'item_ammo' then if sourceXPlayer.hasWeapon(itemName) then local weaponNum, weapon = sourceXPlayer.getWeapon(itemName) - + if targetXPlayer.hasWeapon(itemName) then local _, weaponObject = ESX.GetWeapon(itemName) From e0d561649b82274604a2e40c40dbfb3b50289927 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 9 Mar 2020 13:05:33 +0100 Subject: [PATCH 446/672] Added invalid command handler --- locales/br.lua | 1 + locales/cs.lua | 1 + locales/de.lua | 1 + locales/en.lua | 1 + locales/fi.lua | 1 + locales/fr.lua | 1 + locales/pl.lua | 1 + locales/sv.lua | 1 + server/main.lua | 8 ++++++++ 9 files changed, 16 insertions(+) diff --git a/locales/br.lua b/locales/br.lua index 7b115f96..c2b46a7b 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -93,6 +93,7 @@ Locales['br'] = { ['commanderror_invaliditem'] = 'item invalido', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'o ID do jogador', diff --git a/locales/cs.lua b/locales/cs.lua index b99bebf0..178bf89f 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -93,6 +93,7 @@ Locales['cs'] = { ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', diff --git a/locales/de.lua b/locales/de.lua index 86247f0b..1b218200 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -93,6 +93,7 @@ Locales['de'] = { ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', diff --git a/locales/en.lua b/locales/en.lua index e7a6549b..9c3efda4 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -93,6 +93,7 @@ Locales['en'] = { ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', diff --git a/locales/fi.lua b/locales/fi.lua index cd3b3d6b..9831b26e 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -93,6 +93,7 @@ Locales['fi'] = { ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', diff --git a/locales/fr.lua b/locales/fr.lua index 502e360c..78aa1bbe 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -93,6 +93,7 @@ Locales['fr'] = { ['commanderror_invaliditem'] = 'nom de l\'objet invalide', ['commanderror_invalidweapon'] = 'arme invalide', ['commanderror_console'] = 'cette commande ne peut pas être utilisée dans la console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'il n\'ya aucun joueur avec cet ID en jeu', ['commandgeneric_playerid'] = 'id joueur', diff --git a/locales/pl.lua b/locales/pl.lua index 3f727d5f..db4f89ae 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -93,6 +93,7 @@ Locales['pl'] = { ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', diff --git a/locales/sv.lua b/locales/sv.lua index df1f21db..b41a434e 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -93,6 +93,7 @@ Locales['sv'] = { ['commanderror_invaliditem'] = 'ej giltigt item', ['commanderror_invalidweapon'] = 'ej giltigt vapen', ['commanderror_console'] = 'detta kommando kan ej executas i konsol', + ['commanderror_invalidcommand'] = '^3%s^0 är inte ett giltigt kommando!', ['commanderror_invalidplayerid'] = 'det finns ingen spelare som matchar det angivna server id', ['commandgeneric_playerid'] = 'spelarid', diff --git a/server/main.lua b/server/main.lua index 9dc9e753..008bc784 100644 --- a/server/main.lua +++ b/server/main.lua @@ -193,6 +193,14 @@ function loadESXPlayer(identifier, playerId) end) end +AddEventHandler('chatMessage', function(playerId, author, message) + if message:sub(1, 1) == '/' and playerId > 0 then + CancelEvent() + local commandName = message:sub(1):gmatch("%w+")() + TriggerClientEvent('chat:addMessage', playerId, {args = {'^1SYSTEM', _U('commanderror_invalidcommand', commandName)}}) + end +end) + AddEventHandler('playerDropped', function(reason) local playerId = source local xPlayer = ESX.GetPlayerFromId(playerId) From a8255ce6e39efa970525dd9a0583408bd01c76a2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 11 Mar 2020 09:44:26 +0100 Subject: [PATCH 447/672] Corrected spelling --- server/main.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/main.lua b/server/main.lua index 008bc784..4d89c235 100644 --- a/server/main.lua +++ b/server/main.lua @@ -55,21 +55,21 @@ function loadESXPlayer(identifier, playerId) ['@identifier'] = identifier }, function(result) local job, grade, jobObject, gradeObject = result[1].job, tostring(result[1].job_grade) - local fonudAccounts, foundItems = {}, {} + local foundAccounts, foundItems = {}, {} -- Accounts if result[1].accounts and result[1].accounts ~= '' then local accounts = json.decode(result[1].accounts) for account,money in pairs(accounts) do - fonudAccounts[account] = money + foundAccounts[account] = money end end for account,label in pairs(Config.Accounts) do table.insert(userData.accounts, { name = account, - money = fonudAccounts[account] or Config.StartingAccountMoney[account] or 0, + money = foundAccounts[account] or Config.StartingAccountMoney[account] or 0, label = label }) end From e712c0158d4835c5e2999509c9709af810aab907 Mon Sep 17 00:00:00 2001 From: MohamedAmrMahdy <36306971+MohamedAmrMahdy@users.noreply.github.com> Date: Wed, 11 Mar 2020 10:53:57 +0200 Subject: [PATCH 448/672] Add xPlayer.getMaxWeight() (#559) * Add xPlayer.getMaxWeight() Add ability to read current maximum weight for player * Remove the tab indent --- server/classes/player.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/server/classes/player.lua b/server/classes/player.lua index 68242e13..4df91ee8 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -265,6 +265,10 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return inventoryWeight end + self.getMaxWeight = function() + return self.maxWeight + end + self.canCarryItem = function(name, count) local currentWeight, itemWeight = self.getWeight(), ESX.Items[name].weight local newWeight = currentWeight + (itemWeight * count) From 9b97d1ea67bdb2a46bf7e3b0e00c1be94b770d91 Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Thu, 12 Mar 2020 17:17:13 +0100 Subject: [PATCH 449/672] Update fr.lua --- locales/fr.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index 78aa1bbe..0e4a4fd2 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -38,7 +38,7 @@ Locales['fr'] = { ['threw_pickup_prompt'] = 'appuyez sur ~y~E~s~ pour ramasser', -- Key mapping - ['keymap_showinventory'] = 'show Inventory', + ['keymap_showinventory'] = 'montrer l\'inventaire', -- Salary related ['received_salary'] = 'vous avez reçu votre salaire: ~g~$%s~s~', @@ -93,7 +93,7 @@ Locales['fr'] = { ['commanderror_invaliditem'] = 'nom de l\'objet invalide', ['commanderror_invalidweapon'] = 'arme invalide', ['commanderror_console'] = 'cette commande ne peut pas être utilisée dans la console', - ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', + ['commanderror_invalidcommand'] = '^3%s^0 n\'est pas une commande valide!', ['commanderror_invalidplayerid'] = 'il n\'ya aucun joueur avec cet ID en jeu', ['commandgeneric_playerid'] = 'id joueur', From ff9930068f83af6adf78275b2581a0e5ea54a3bf Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 15 Mar 2020 12:20:08 +0100 Subject: [PATCH 450/672] Keep weight stored --- es_extended.sql | 1 + server/classes/player.lua | 33 ++++++++++++++------------------- server/main.lua | 6 ++++-- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/es_extended.sql b/es_extended.sql index 9ea30491..c01587aa 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,3 +1,4 @@ +CREATE DATABASE IF NOT EXISTS `essentialmode`; USE `essentialmode`; CREATE TABLE `users` ( diff --git a/server/classes/player.lua b/server/classes/player.lua index 4df91ee8..52f661e2 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -1,18 +1,19 @@ -function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, job, loadout, name, coords) +function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, weight, job, loadout, name, coords) local self = {} self.accounts = accounts + self.coords = coords + self.group = group + self.identifier = identifier self.inventory = inventory self.job = job - self.group = group self.loadout = loadout self.name = name - self.maxWeight = Config.MaxWeight - self.coords = coords - self.variables = {} - self.source = playerId self.playerId = playerId - self.identifier = identifier + self.source = playerId + self.variables = {} + self.weight = weight + self.maxWeight = Config.MaxWeight ExecuteCommand(('add_principal identifier.license:%s group.%s'):format(self.identifier, self.group)) @@ -216,9 +217,8 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if item then count = ESX.Math.Round(count) - - local newCount = item.count + count - item.count = newCount + item.count = item.count + count + self.weight = self.weight + (item.weight * count) TriggerEvent('esx:onAddInventoryItem', self.source, item.name, item.count) self.triggerEvent('esx:addInventoryItem', item.name, item.count) @@ -234,6 +234,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if newCount >= 0 then item.count = newCount + self.weight = self.weight - (item.weight * count) TriggerEvent('esx:onRemoveInventoryItem', self.source, item.name, item.count) self.triggerEvent('esx:removeInventoryItem', item.name, item.count) @@ -256,13 +257,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end self.getWeight = function() - local inventoryWeight = 0 - - for k,v in ipairs(self.inventory) do - inventoryWeight = inventoryWeight + (v.count * v.weight) - end - - return inventoryWeight + return self.weight end self.getMaxWeight = function() @@ -270,7 +265,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end self.canCarryItem = function(name, count) - local currentWeight, itemWeight = self.getWeight(), ESX.Items[name].weight + local currentWeight, itemWeight = self.weight, ESX.Items[name].weight local newWeight = currentWeight + (itemWeight * count) return newWeight <= self.maxWeight @@ -281,7 +276,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, local testItemObject = self.getInventoryItem(testItem) if firstItemObject.count >= firstItemCount then - local weightWithoutFirstItem = ESX.Math.Round(self.getWeight() - (firstItemObject.weight * firstItemCount)) + local weightWithoutFirstItem = ESX.Math.Round(self.weight - (firstItemObject.weight * firstItemCount)) local weightWithTestItem = ESX.Math.Round(weightWithoutFirstItem + (testItemObject.weight * testItemCount)) return weightWithTestItem <= self.maxWeight diff --git a/server/main.lua b/server/main.lua index 4d89c235..5e6b7b61 100644 --- a/server/main.lua +++ b/server/main.lua @@ -47,7 +47,8 @@ function loadESXPlayer(identifier, playerId) inventory = {}, job = {}, loadout = {}, - playerName = GetPlayerName(playerId) + playerName = GetPlayerName(playerId), + weight = 0 } table.insert(tasks, function(cb) @@ -115,6 +116,7 @@ function loadESXPlayer(identifier, playerId) for name,item in pairs(ESX.Items) do local count = foundItems[name] or 0 + if count > 0 then userData.weight = userData.weight + (item.weight * count) end table.insert(userData.inventory, { name = name, @@ -173,7 +175,7 @@ function loadESXPlayer(identifier, playerId) end) Async.parallel(tasks, function(results) - local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.job, userData.loadout, userData.playerName, userData.coords) + local xPlayer = CreateExtendedPlayer(playerId, identifier, userData.group, userData.accounts, userData.inventory, userData.weight, userData.job, userData.loadout, userData.playerName, userData.coords) ESX.Players[playerId] = xPlayer TriggerEvent('esx:playerLoaded', playerId, xPlayer) From 9a1dfa42ca2ed5e135f69d353d8454e1cc5eeffa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Mar 2020 09:43:43 +0100 Subject: [PATCH 451/672] Sync consumed ammo with server properly No more security issues here! --- client/main.lua | 51 +++++++++------------------------------ common/functions.lua | 34 +++++++++++++++----------- server/classes/player.lua | 10 ++++++++ server/main.lua | 9 ++++--- 4 files changed, 48 insertions(+), 56 deletions(-) diff --git a/client/main.lua b/client/main.lua index 106e0032..d768fc58 100644 --- a/client/main.lua +++ b/client/main.lua @@ -393,53 +393,26 @@ if Config.EnableHud then end) end --- Save loadout +-- Keep track of ammo usage Citizen.CreateThread(function() - local lastLoadout = {} - while true do - Citizen.Wait(5000) - local playerPed, loadout, loadoutChanged = PlayerPedId(), {}, false + Citizen.Wait(0) - for k,v in ipairs(Config.Weapons) do - local weaponName = v.name - local weaponHash = GetHashKey(weaponName) + if isDead then + Citizen.Wait(500) + else + local playerPed = PlayerPedId() - if HasPedGotWeapon(playerPed, weaponHash, false) then - local ammo, tintIndex, weaponComponents = GetAmmoInPedWeapon(playerPed, weaponHash), GetPedWeaponTintIndex(playerPed, weaponHash), {} + if IsPedShooting(playerPed) then + local _,weaponHash = GetCurrentPedWeapon(playerPed, true) + local weapon = ESX.GetWeaponFromHash(weaponHash) - for k2,v2 in ipairs(v.components) do - if HasPedGotWeaponComponent(playerPed, weaponHash, v2.hash) then - table.insert(weaponComponents, v2.name) - end + if weapon then + local ammoCount = GetAmmoInPedWeapon(playerPed, weaponHash) + TriggerServerEvent('esx:updateWeaponAmmo', weapon.name, ammoCount) 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, - tintIndex = tintIndex - }) - 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) diff --git a/common/functions.lua b/common/functions.lua index ed9deb82..e47b5b7f 100644 --- a/common/functions.lua +++ b/common/functions.lua @@ -20,11 +20,18 @@ end ESX.GetWeapon = function(weaponName) weaponName = string.upper(weaponName) - local weapons = ESX.GetWeaponList() - for i=1, #weapons, 1 do - if weapons[i].name == weaponName then - return i, weapons[i] + for k,v in ipairs(Config.Weapons) do + if v.name == weaponName then + return k, v + end + end +end + +ESX.GetWeaponFromHash = function(weaponHash) + for k,v in ipairs(Config.Weapons) do + if GetHashKey(v.name) == weaponHash then + return v end end end @@ -35,24 +42,23 @@ end ESX.GetWeaponLabel = function(weaponName) weaponName = string.upper(weaponName) - local weapons = ESX.GetWeaponList() - for i=1, #weapons, 1 do - if weapons[i].name == weaponName then - return weapons[i].label + for k,v in ipairs(Config.Weapons) do + if v.name == weaponName then + return v.label end end end ESX.GetWeaponComponent = function(weaponName, weaponComponent) weaponName = string.upper(weaponName) - local weapons = ESX.GetWeaponList() + local weapons = Config.Weapons - for i=1, #weapons, 1 do - if weapons[i].name == weaponName then - for j=1, #weapons[i].components, 1 do - if weapons[i].components[j].name == weaponComponent then - return weapons[i].components[j] + for k,v in ipairs(Config.Weapons) do + if v.name == weaponName then + for k2,v2 in ipairs(v.components) do + if v2.name == weaponComponent then + return v2 end end end diff --git a/server/classes/player.lua b/server/classes/player.lua index 52f661e2..0705204c 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -367,6 +367,16 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + self.updateWeaponAmmo = function(weaponName, ammoCount) + local loadoutNum, weapon = self.getWeapon(weaponName) + + if weapon then + if ammoCount < weapon.ammo then + weapon.ammo = ammoCount + end + end + end + self.setWeaponTint = function(weaponName, weaponTintIndex) local loadoutNum, weapon = self.getWeapon(weaponName) diff --git a/server/main.lua b/server/main.lua index 5e6b7b61..4d63e12a 100644 --- a/server/main.lua +++ b/server/main.lua @@ -225,10 +225,13 @@ AddEventHandler('esx:updateCoords', function(coords) end end) -RegisterNetEvent('esx:updateLoadout') -AddEventHandler('esx:updateLoadout', function(loadout) +RegisterNetEvent('esx:updateWeaponAmmo') +AddEventHandler('esx:updateWeaponAmmo', function(weaponName, ammoCount) local xPlayer = ESX.GetPlayerFromId(source) - xPlayer.loadout = loadout + + if xPlayer then + xPlayer.updateWeaponAmmo(weaponName, ammoCount) + end end) RegisterNetEvent('esx:giveInventoryItem') From 986cbfb32ae03261f1d970e326cccf1f7f214cd7 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Mar 2020 09:47:04 +0100 Subject: [PATCH 452/672] Added missing trailing spaces --- client/modules/death.lua | 2 +- client/modules/scaleform.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/modules/death.lua b/client/modules/death.lua index a2aeb76b..959d8255 100644 --- a/client/modules/death.lua +++ b/client/modules/death.lua @@ -61,4 +61,4 @@ function PlayerKilled(deathCause) TriggerEvent('esx:onPlayerDeath', data) TriggerServerEvent('esx:onPlayerDeath', data) -end \ No newline at end of file +end diff --git a/client/modules/scaleform.lua b/client/modules/scaleform.lua index 20a9c6e8..681f7db1 100644 --- a/client/modules/scaleform.lua +++ b/client/modules/scaleform.lua @@ -95,4 +95,4 @@ ESX.Scaleform.Utils.RequestScaleformMovie = function(movie) end return scaleform -end \ No newline at end of file +end From d91d34670d9f1254992c158dd27008d5ffa6bee4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Mar 2020 14:32:31 +0100 Subject: [PATCH 453/672] =?UTF-8?q?Added=20sponsorship=20with=20Iceline=20?= =?UTF-8?q?Hosting=E2=9D=A4=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index f10cdc04..087ac490 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,20 @@ ESX was initially developed by Gizz back in 2017 for his friend as the were crea - [mysql-async](https://github.com/brouznouf/fivem-mysql-async) - [async](https://github.com/ESX-Org/async) +## Rent Server + +![Iceline hosting](https://media.discordapp.net/attachments/667787270375473183/667790233441533952/banner.gif) + +Are you thinking of starting a FiveM server of your own? [Iceline Hosting](https://iceline-hosting.com/) provide cost effective game servers, high end game VPS's with DDoS protection included, and more! + +There is an optional Managed Support Addon available for game servers and Game VPS's that add the following services: + +- Investigation and fixing errors in relation to the server or third-party scripts +- Installing third-party scripts or software +- Recovery of lost data + +Go to [Iceline Hosting](https://iceline-hosting.com/) and use promo code `ESX` for 15% off the first month on FiveM game servers, Game VPS's and Singapore VPS's. + ## Download & Installation ### Using [fvm](https://github.com/qlaffont/fvm-installer) From 4cc964b9d5b71b83c4107fef2d72e4460d69c3a4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 22 Mar 2020 14:46:54 +0100 Subject: [PATCH 454/672] Updated sponsor url --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 087ac490..7f62914a 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ ESX was initially developed by Gizz back in 2017 for his friend as the were crea ![Iceline hosting](https://media.discordapp.net/attachments/667787270375473183/667790233441533952/banner.gif) -Are you thinking of starting a FiveM server of your own? [Iceline Hosting](https://iceline-hosting.com/) provide cost effective game servers, high end game VPS's with DDoS protection included, and more! +Are you thinking of starting a FiveM server of your own? [Iceline Hosting](https://iceline-hosting.com/billing/aff.php?aff=94) provide cost effective game servers, high end game VPS's with DDoS protection included, and more! There is an optional Managed Support Addon available for game servers and Game VPS's that add the following services: @@ -44,7 +44,7 @@ There is an optional Managed Support Addon available for game servers and Game V - Installing third-party scripts or software - Recovery of lost data -Go to [Iceline Hosting](https://iceline-hosting.com/) and use promo code `ESX` for 15% off the first month on FiveM game servers, Game VPS's and Singapore VPS's. +Go to [Iceline Hosting](https://iceline-hosting.com/billing/aff.php?aff=94) and use promo code `ESX` for 15% off the first month on FiveM game servers, Game VPS's and Singapore VPS's. ## Download & Installation From d8e4e8d9917dcfd92c30bf9e8ff446be537ee183 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 23 Mar 2020 11:55:55 +0100 Subject: [PATCH 455/672] Fixed group not storing on db when saving player --- server/functions.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/functions.lua b/server/functions.lua index 6cb0b427..eaa7bd2a 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -161,10 +161,11 @@ ESX.SavePlayer = function(xPlayer, cb) local asyncTasks = {} table.insert(asyncTasks, function(cb) - MySQL.Async.execute('UPDATE users SET accounts = @accounts, job = @job, job_grade = @job_grade, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { + MySQL.Async.execute('UPDATE users SET accounts = @accounts, job = @job, job_grade = @job_grade, `group` = @group, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { ['@accounts'] = json.encode(xPlayer.getAccounts(true)), ['@job'] = xPlayer.job.name, ['@job_grade'] = xPlayer.job.grade, + ['@group'] = xPlayer.getGroup(), ['@loadout'] = json.encode(xPlayer.getLoadout(true)), ['@position'] = json.encode(xPlayer.getCoords()), ['@identifier'] = xPlayer.identifier, From 0fc8c4d9c5028944e34ff72b73c4adb039be88d8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 23 Mar 2020 12:10:25 +0100 Subject: [PATCH 456/672] Added /save and /saveall commands --- locales/br.lua | 2 ++ locales/cs.lua | 2 ++ locales/de.lua | 2 ++ locales/en.lua | 2 ++ locales/fi.lua | 2 ++ locales/fr.lua | 2 ++ locales/pl.lua | 2 ++ locales/sv.lua | 2 ++ server/commands.lua | 10 ++++++++++ 9 files changed, 26 insertions(+) diff --git a/locales/br.lua b/locales/br.lua index c2b46a7b..0dd62b99 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -62,6 +62,8 @@ Locales['br'] = { ['command_clearall'] = 'limpar o chat para todos', ['command_clearinventory'] = 'remover todos os itens do inventário', ['command_clearloadout'] = 'remova todas as armas do carregamento', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/cs.lua b/locales/cs.lua index 178bf89f..11441283 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -62,6 +62,8 @@ Locales['cs'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/de.lua b/locales/de.lua index 1b218200..c1d2fb9a 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -62,6 +62,8 @@ Locales['de'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/en.lua b/locales/en.lua index 9c3efda4..b76aba04 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -62,6 +62,8 @@ Locales['en'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/fi.lua b/locales/fi.lua index 9831b26e..ec4eac0e 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -62,6 +62,8 @@ Locales['fi'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/fr.lua b/locales/fr.lua index 0e4a4fd2..c1dd3746 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -62,6 +62,8 @@ Locales['fr'] = { ['command_clearall'] = 'vider le chat pour tous', ['command_clearinventory'] = 'vider l\'inventaire d\'un joueur', ['command_clearloadout'] = 'vider le loadout d\'un joueur', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'se téléporter aux coordonnées', ['command_setcoords_x'] = 'axe X', ['command_setcoords_y'] = 'axe Y', diff --git a/locales/pl.lua b/locales/pl.lua index db4f89ae..1d95f19b 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -62,6 +62,8 @@ Locales['pl'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/sv.lua b/locales/sv.lua index b41a434e..8f9c449a 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -62,6 +62,8 @@ Locales['sv'] = { ['command_clearall'] = 'töm chatten för alla spelare', ['command_clearinventory'] = 'töm en spelares inventory', ['command_clearloadout'] = 'töm en spelares loadout', + ['command_save'] = 'spara en spelare i databas', + ['command_saveall'] = 'spara alla spelare i databas', ['command_setcoords'] = 'teleportera till koordinater', ['command_setcoords_x'] = 'x axel', ['command_setcoords_y'] = 'y axel', diff --git a/server/commands.lua b/server/commands.lua index b8a187f1..39c4a6ce 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -116,3 +116,13 @@ end, true, {help = _U('command_setgroup'), validate = true, arguments = { {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, {name = 'group', help = _U('command_setgroup_group'), type = 'string'}, }}) + +ESX.RegisterCommand('save', 'admin', function(xPlayer, args, showError) + ESX.SavePlayer(args.playerId) +end, true, {help = _U('command_save'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'} +}}) + +ESX.RegisterCommand('saveall', 'admin', function(xPlayer, args, showError) + ESX.SavePlayers() +end, true, {help = _U('command_saveall')}) From 8a586e433cd0f68f32cc1fdf56ab364df9e35d46 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 23 Mar 2020 13:58:41 +0100 Subject: [PATCH 457/672] =?UTF-8?q?=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8FBRE?= =?UTF-8?q?AKING=20COMMIT=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8F:=20mapmanage?= =?UTF-8?q?r=20&=20spawnmanager=20ditch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure you remove or disable mapmanager and spawnmanager --- client/main.lua | 82 ++++++++++++++++++++++++++++++------------------- server/main.lua | 8 +++-- 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/client/main.lua b/client/main.lua index d768fc58..1b2803bb 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,17 +1,44 @@ local isLoadoutLoaded, isPaused, isDead, isFirstSpawn, pickups = false, false, false, true, {} +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + + if NetworkIsPlayerActive(PlayerId()) then + TriggerServerEvent('esx:onPlayerJoined') + break + end + end +end) + RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(playerData) ESX.PlayerLoaded = true ESX.PlayerData = playerData + local defaultModel = GetHashKey('mp_m_freemode_01') + RequestModel(defaultModel) + + while not HasModelLoaded(defaultModel) do + Citizen.Wait(100) + end + + SetPlayerModel(PlayerId(), defaultModel) + local playerPed = PlayerPedId() + + SetPedDefaultComponentVariation(playerPed) + SetModelAsNoLongerNeeded(defaultModel) + FreezeEntityPosition(playerPed, false) + + if Config.EnablePvP then + SetCanAttackFriendly(playerPed, true, false) + NetworkSetFriendlyFireOption(true) + end + if Config.EnableHud then for k,v in ipairs(playerData.accounts) do local accountTpl = '
 {{money}}
' - - ESX.UI.HUD.RegisterElement('account_' .. v.name, k, 0, accountTpl, { - money = ESX.Math.GroupDigits(v.money) - }) + ESX.UI.HUD.RegisterElement('account_' .. v.name, k, 0, accountTpl, {money = ESX.Math.GroupDigits(v.money)}) end local jobTpl = '
{{job_label}} - {{grade_label}}
' @@ -25,43 +52,34 @@ AddEventHandler('esx:playerLoaded', function(playerData) grade_label = playerData.job.grade_label }) end + + ESX.Game.Teleport(playerPed, { + x = playerData.coords.x, + y = playerData.coords.y, + z = playerData.coords.z + 0.25, + heading = playerData.coords.heading + }, function() + isLoadoutLoaded, isDead = true, false + TriggerServerEvent('esx:onPlayerSpawn') + TriggerEvent('esx:onPlayerSpawn') + TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon + TriggerEvent('esx:restoreLoadout') + + Citizen.Wait(3000) + ShutdownLoadingScreen() + DoScreenFadeIn(10000) + end) end) RegisterNetEvent('esx:setMaxWeight') -AddEventHandler('esx:setMaxWeight', function(newMaxWeight) - ESX.PlayerData.maxWeight = newMaxWeight -end) - -AddEventHandler('playerSpawned', function() - if isFirstSpawn then - TriggerServerEvent('esx:playerJoined') - end - - while not ESX.PlayerLoaded do - Citizen.Wait(10) - end - - TriggerEvent('esx:restoreLoadout') - - if isFirstSpawn then - ESX.Game.Teleport(PlayerPedId(), ESX.PlayerData.coords) - isFirstSpawn = false - end - - isLoadoutLoaded, isDead = true, false - - if Config.EnablePvP then - SetCanAttackFriendly(PlayerPedId(), true, false) - NetworkSetFriendlyFireOption(true) - end -end) +AddEventHandler('esx:setMaxWeight', function(newMaxWeight) ESX.PlayerData.maxWeight = newMaxWeight 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) + Citizen.Wait(100) end TriggerEvent('esx:restoreLoadout') diff --git a/server/main.lua b/server/main.lua index 4d63e12a..7150adad 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,6 +1,8 @@ -RegisterNetEvent('esx:playerJoined') -AddEventHandler('esx:playerJoined', function() - onPlayerJoined(source) +RegisterNetEvent('esx:onPlayerJoined') +AddEventHandler('esx:onPlayerJoined', function() + if not ESX.Players[source] then + onPlayerJoined(source) + end end) function onPlayerJoined(playerId) From d41b9a7d909b11a99b16eaa7f44f9e88ce36af76 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Mar 2020 10:52:02 +0100 Subject: [PATCH 458/672] Minor locale adjustment --- locales/br.lua | 24 ++++++++++++------------ locales/cs.lua | 24 ++++++++++++------------ locales/de.lua | 24 ++++++++++++------------ locales/en.lua | 24 ++++++++++++------------ locales/fi.lua | 24 ++++++++++++------------ locales/fr.lua | 24 ++++++++++++------------ locales/pl.lua | 24 ++++++++++++------------ locales/sv.lua | 24 ++++++++++++------------ 8 files changed, 96 insertions(+), 96 deletions(-) diff --git a/locales/br.lua b/locales/br.lua index 0dd62b99..df6faba3 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -62,18 +62,6 @@ Locales['br'] = { ['command_clearall'] = 'limpar o chat para todos', ['command_clearinventory'] = 'remover todos os itens do inventário', ['command_clearloadout'] = 'remova todas as armas do carregamento', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'atribuir um trabalho a um usuario', - ['command_setjob_job'] = 'o trabalho que voce deseja atribuir', - ['command_setjob_grade'] = 'o nivel de emprego', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'dar dinheiro da conta', ['command_giveaccountmoney_account'] = 'conta', ['command_giveaccountmoney_amount'] = 'amount', @@ -90,6 +78,18 @@ Locales['br'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'atribuir um trabalho a um usuario', + ['command_setjob_job'] = 'o trabalho que voce deseja atribuir', + ['command_setjob_grade'] = 'o nivel de emprego', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'item invalido', diff --git a/locales/cs.lua b/locales/cs.lua index 11441283..3c47581e 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -62,18 +62,6 @@ Locales['cs'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'give account money', ['command_giveaccountmoney_account'] = 'valid account name', ['command_giveaccountmoney_amount'] = 'amount to add', @@ -90,6 +78,18 @@ Locales['cs'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', diff --git a/locales/de.lua b/locales/de.lua index c1d2fb9a..34ba3e4f 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -62,18 +62,6 @@ Locales['de'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'give account money', ['command_giveaccountmoney_account'] = 'valid account name', ['command_giveaccountmoney_amount'] = 'amount to add', @@ -90,6 +78,18 @@ Locales['de'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', diff --git a/locales/en.lua b/locales/en.lua index b76aba04..8edbe2a5 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -62,18 +62,6 @@ Locales['en'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'give account money', ['command_giveaccountmoney_account'] = 'valid account name', ['command_giveaccountmoney_amount'] = 'amount to add', @@ -90,6 +78,18 @@ Locales['en'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', diff --git a/locales/fi.lua b/locales/fi.lua index ec4eac0e..a6abf874 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -62,18 +62,6 @@ Locales['fi'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'give account money', ['command_giveaccountmoney_account'] = 'valid account name', ['command_giveaccountmoney_amount'] = 'amount to add', @@ -90,6 +78,18 @@ Locales['fi'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', diff --git a/locales/fr.lua b/locales/fr.lua index c1dd3746..d0be55c0 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -62,18 +62,6 @@ Locales['fr'] = { ['command_clearall'] = 'vider le chat pour tous', ['command_clearinventory'] = 'vider l\'inventaire d\'un joueur', ['command_clearloadout'] = 'vider le loadout d\'un joueur', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'se téléporter aux coordonnées', - ['command_setcoords_x'] = 'axe X', - ['command_setcoords_y'] = 'axe Y', - ['command_setcoords_z'] = 'axe Z', - ['command_setjob'] = 'assigner job à un joueur', - ['command_setjob_job'] = 'nom du job', - ['command_setjob_grade'] = 'grade du job', - ['command_setjob_invalid'] = 'le job, le grade ou les deux sont invalides', - ['command_setgroup'] = 'assigner un groupe à un joueur', - ['command_setgroup_group'] = 'nom du groupe', ['command_giveaccountmoney'] = 'donner de l\'argent sur un compte', ['command_giveaccountmoney_account'] = 'nom de compte valide', ['command_giveaccountmoney_amount'] = 'quantité à ajouter', @@ -90,6 +78,18 @@ Locales['fr'] = { ['command_giveweaponcomponent_invalid'] = 'accessoire invalide', ['command_giveweaponcomponent_hasalready'] = 'le joueur a déjà cet accessoire', ['command_giveweaponcomponent_missingweapon'] = 'le joueur n\'a pas cette arme', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'se téléporter aux coordonnées', + ['command_setcoords_x'] = 'axe X', + ['command_setcoords_y'] = 'axe Y', + ['command_setcoords_z'] = 'axe Z', + ['command_setjob'] = 'assigner job à un joueur', + ['command_setjob_job'] = 'nom du job', + ['command_setjob_grade'] = 'grade du job', + ['command_setjob_invalid'] = 'le job, le grade ou les deux sont invalides', + ['command_setgroup'] = 'assigner un groupe à un joueur', + ['command_setgroup_group'] = 'nom du groupe', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'nom de l\'objet invalide', diff --git a/locales/pl.lua b/locales/pl.lua index 1d95f19b..31f1bf50 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -62,18 +62,6 @@ Locales['pl'] = { ['command_clearall'] = 'clear chat for all players', ['command_clearinventory'] = 'clear player inventory', ['command_clearloadout'] = 'clear a player loadout', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setcoords'] = 'teleport to coordinates', - ['command_setcoords_x'] = 'x axis', - ['command_setcoords_y'] = 'y axis', - ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', ['command_giveaccountmoney'] = 'give account money', ['command_giveaccountmoney_account'] = 'valid account name', ['command_giveaccountmoney_amount'] = 'amount to add', @@ -90,6 +78,18 @@ Locales['pl'] = { ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setcoords'] = 'teleport to coordinates', + ['command_setcoords_x'] = 'x axis', + ['command_setcoords_y'] = 'y axis', + ['command_setcoords_z'] = 'z axis', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', diff --git a/locales/sv.lua b/locales/sv.lua index 8f9c449a..7c222e50 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -62,18 +62,6 @@ Locales['sv'] = { ['command_clearall'] = 'töm chatten för alla spelare', ['command_clearinventory'] = 'töm en spelares inventory', ['command_clearloadout'] = 'töm en spelares loadout', - ['command_save'] = 'spara en spelare i databas', - ['command_saveall'] = 'spara alla spelare i databas', - ['command_setcoords'] = 'teleportera till koordinater', - ['command_setcoords_x'] = 'x axel', - ['command_setcoords_y'] = 'y axel', - ['command_setcoords_z'] = 'z axel', - ['command_setjob'] = 'välj jobb för en spelare', - ['command_setjob_job'] = 'jobbnamn', - ['command_setjob_grade'] = 'jobbnivå', - ['command_setjob_invalid'] = 'jobbet, nivån eller båda är ej giltiga', - ['command_setgroup'] = 'välj grupp åt en spelare', - ['command_setgroup_group'] = 'gruppnamn', ['command_giveaccountmoney'] = 'ge pengar för ett konto', ['command_giveaccountmoney_account'] = 'giltigt kontonamn', ['command_giveaccountmoney_amount'] = 'mängd att ge', @@ -90,6 +78,18 @@ Locales['sv'] = { ['command_giveweaponcomponent_invalid'] = 'det vapenkomponentet är ej giltigt', ['command_giveweaponcomponent_hasalready'] = 'spelaren har redan det vapenkomponent', ['command_giveweaponcomponent_missingweapon'] = 'spelaren har ej det vapnet', + ['command_save'] = 'spara en spelare i databas', + ['command_saveall'] = 'spara alla spelare i databas', + ['command_setcoords'] = 'teleportera till koordinater', + ['command_setcoords_x'] = 'x axel', + ['command_setcoords_y'] = 'y axel', + ['command_setcoords_z'] = 'z axel', + ['command_setjob'] = 'välj jobb för en spelare', + ['command_setjob_job'] = 'jobbnamn', + ['command_setjob_grade'] = 'jobbnivå', + ['command_setjob_invalid'] = 'jobbet, nivån eller båda är ej giltiga', + ['command_setgroup'] = 'välj grupp åt en spelare', + ['command_setgroup_group'] = 'gruppnamn', ['commanderror_argumentmismatch'] = 'argumentstorlek mismatch (gav %s, ville ha %s)', ['commanderror_argumentmismatch_number'] = 'argument #%s typ mismatch (gav string, ville ha number)', ['commanderror_invaliditem'] = 'ej giltigt item', From 8a6579fd7e7c8a8469dbf92dd7c3df6d3842512d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 24 Mar 2020 10:57:25 +0100 Subject: [PATCH 459/672] Added /setaccountmoney command, closes #558 --- locales/br.lua | 2 ++ locales/cs.lua | 2 ++ locales/de.lua | 2 ++ locales/en.lua | 2 ++ locales/fi.lua | 2 ++ locales/fr.lua | 2 ++ locales/pl.lua | 2 ++ locales/sv.lua | 2 ++ server/commands.lua | 12 ++++++++++++ 9 files changed, 28 insertions(+) diff --git a/locales/br.lua b/locales/br.lua index df6faba3..d63f2867 100644 --- a/locales/br.lua +++ b/locales/br.lua @@ -80,6 +80,8 @@ Locales['br'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/cs.lua b/locales/cs.lua index 3c47581e..10c1d3a0 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -80,6 +80,8 @@ Locales['cs'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/de.lua b/locales/de.lua index 34ba3e4f..30ae1a18 100644 --- a/locales/de.lua +++ b/locales/de.lua @@ -80,6 +80,8 @@ Locales['de'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/en.lua b/locales/en.lua index 8edbe2a5..a5ec7122 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -80,6 +80,8 @@ Locales['en'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/fi.lua b/locales/fi.lua index a6abf874..034aebd3 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -80,6 +80,8 @@ Locales['fi'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/fr.lua b/locales/fr.lua index d0be55c0..c5d74c80 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -80,6 +80,8 @@ Locales['fr'] = { ['command_giveweaponcomponent_missingweapon'] = 'le joueur n\'a pas cette arme', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'se téléporter aux coordonnées', ['command_setcoords_x'] = 'axe X', ['command_setcoords_y'] = 'axe Y', diff --git a/locales/pl.lua b/locales/pl.lua index 31f1bf50..2a04b378 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -80,6 +80,8 @@ Locales['pl'] = { ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', ['command_save'] = 'save a player to database', ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', diff --git a/locales/sv.lua b/locales/sv.lua index 7c222e50..5cb32c29 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -80,6 +80,8 @@ Locales['sv'] = { ['command_giveweaponcomponent_missingweapon'] = 'spelaren har ej det vapnet', ['command_save'] = 'spara en spelare i databas', ['command_saveall'] = 'spara alla spelare i databas', + ['command_setaccountmoney'] = 'bestäm ny balans på ett spelarkonto', + ['command_setaccountmoney_amount'] = 'ny balans', ['command_setcoords'] = 'teleportera till koordinater', ['command_setcoords_x'] = 'x axel', ['command_setcoords_y'] = 'y axel', diff --git a/server/commands.lua b/server/commands.lua index 39c4a6ce..11d8f941 100644 --- a/server/commands.lua +++ b/server/commands.lua @@ -30,6 +30,18 @@ end, false, {help = _U('command_cardel'), validate = false, arguments = { {name = 'radius', help = _U('command_cardel_radius'), type = 'any'} }}) +ESX.RegisterCommand('setaccountmoney', 'admin', function(xPlayer, args, showError) + if args.playerId.getAccount(args.account) then + args.playerId.setAccountMoney(args.account, args.amount) + else + showError(_U('command_giveaccountmoney_invalid')) + end +end, true, {help = _U('command_setaccountmoney'), validate = true, arguments = { + {name = 'playerId', help = _U('commandgeneric_playerid'), type = 'player'}, + {name = 'account', help = _U('command_giveaccountmoney_account'), type = 'string'}, + {name = 'amount', help = _U('command_setaccountmoney_amount'), type = 'number'} +}}) + ESX.RegisterCommand('giveaccountmoney', 'admin', function(xPlayer, args, showError) if args.playerId.getAccount(args.account) then args.playerId.addAccountMoney(args.account, args.amount) From 2c4d33defaf7b337ca7d08d308b023e9120010c1 Mon Sep 17 00:00:00 2001 From: Oldarorn <36448848+Oldarorn@users.noreply.github.com> Date: Tue, 24 Mar 2020 13:49:34 +0100 Subject: [PATCH 460/672] Update fr.lua --- locales/fr.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/locales/fr.lua b/locales/fr.lua index c5d74c80..7512e33b 100644 --- a/locales/fr.lua +++ b/locales/fr.lua @@ -78,10 +78,10 @@ Locales['fr'] = { ['command_giveweaponcomponent_invalid'] = 'accessoire invalide', ['command_giveweaponcomponent_hasalready'] = 'le joueur a déjà cet accessoire', ['command_giveweaponcomponent_missingweapon'] = 'le joueur n\'a pas cette arme', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setaccountmoney'] = 'set account money for a player', - ['command_setaccountmoney_amount'] = 'amount of money to set', + ['command_save'] = 'sauvegarder un joueur dans la base de données', + ['command_saveall'] = 'sauvegarder tous les joueurs dans la base de données', + ['command_setaccountmoney'] = 'définir la somme d\'argent pour un joueur', + ['command_setaccountmoney_amount'] = 'quantité d\'argent à définir', ['command_setcoords'] = 'se téléporter aux coordonnées', ['command_setcoords_x'] = 'axe X', ['command_setcoords_y'] = 'axe Y', From be2dc2e9e2d94434b6d8fde1dc1d1ecfd24f89b6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 25 Mar 2020 22:45:23 +0100 Subject: [PATCH 461/672] Minor adjustments --- client/main.lua | 2 +- server/functions.lua | 2 +- server/main.lua | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/main.lua b/client/main.lua index 1b2803bb..16d1f9c3 100644 --- a/client/main.lua +++ b/client/main.lua @@ -56,7 +56,7 @@ AddEventHandler('esx:playerLoaded', function(playerData) ESX.Game.Teleport(playerPed, { x = playerData.coords.x, y = playerData.coords.y, - z = playerData.coords.z + 0.25, + z = playerData.coords.z + 0.5, heading = playerData.coords.heading }, function() isLoadoutLoaded, isDead = true, false diff --git a/server/functions.lua b/server/functions.lua index eaa7bd2a..74e2efcc 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -168,7 +168,7 @@ ESX.SavePlayer = function(xPlayer, cb) ['@group'] = xPlayer.getGroup(), ['@loadout'] = json.encode(xPlayer.getLoadout(true)), ['@position'] = json.encode(xPlayer.getCoords()), - ['@identifier'] = xPlayer.identifier, + ['@identifier'] = xPlayer.getIdentifier(), ['@inventory'] = json.encode(xPlayer.getInventory(true)) }, function(rowsChanged) cb() diff --git a/server/main.lua b/server/main.lua index 7150adad..30e97f82 100644 --- a/server/main.lua +++ b/server/main.lua @@ -131,6 +131,10 @@ function loadESXPlayer(identifier, playerId) }) end + table.sort(userData.inventory, function(a, b) + return a.label < b.label + end) + -- Group if result[1].group then userData.group = result[1].group @@ -138,10 +142,6 @@ function loadESXPlayer(identifier, playerId) userData.group = 'user' end - table.sort(userData.inventory, function(a, b) - return a.label < b.label - end) - -- Loadout if result[1].loadout and result[1].loadout ~= '' then local loadout = json.decode(result[1].loadout) @@ -184,12 +184,12 @@ function loadESXPlayer(identifier, playerId) xPlayer.triggerEvent('esx:playerLoaded', { accounts = xPlayer.getAccounts(), coords = xPlayer.getCoords(), - identifier = xPlayer.identifier, + identifier = xPlayer.getIdentifier(), inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), maxWeight = xPlayer.maxWeight, - money = xPlayer.getMoney(), + money = xPlayer.getMoney() }) xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) From 09e50046c0332f333ca139888a630c9e14326571 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 26 Mar 2020 11:24:51 +0100 Subject: [PATCH 462/672] Only apply a player model if coming from loading screen --- client/main.lua | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/client/main.lua b/client/main.lua index 16d1f9c3..a5f24ce2 100644 --- a/client/main.lua +++ b/client/main.lua @@ -16,20 +16,26 @@ AddEventHandler('esx:playerLoaded', function(playerData) ESX.PlayerLoaded = true ESX.PlayerData = playerData - local defaultModel = GetHashKey('mp_m_freemode_01') - RequestModel(defaultModel) + -- check if player is coming from loading screen + if GetEntityModel(PlayerPedId()) == GetHashKey('PLAYER_ZERO') then + local defaultModel = GetHashKey('a_m_y_stbla_02') + RequestModel(defaultModel) - while not HasModelLoaded(defaultModel) do - Citizen.Wait(100) + while not HasModelLoaded(defaultModel) do + Citizen.Wait(100) + end + + SetPlayerModel(PlayerId(), defaultModel) + local playerPed = PlayerPedId() + + SetPedDefaultComponentVariation(playerPed) + SetPedRandomComponentVariation(playerPed, true) + SetModelAsNoLongerNeeded(defaultModel) + FreezeEntityPosition(playerPed, false) end - SetPlayerModel(PlayerId(), defaultModel) local playerPed = PlayerPedId() - SetPedDefaultComponentVariation(playerPed) - SetModelAsNoLongerNeeded(defaultModel) - FreezeEntityPosition(playerPed, false) - if Config.EnablePvP then SetCanAttackFriendly(playerPed, true, false) NetworkSetFriendlyFireOption(true) From fde5571b43096bc10f5a2369f91a6574c0b28f38 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 26 Mar 2020 11:59:27 +0100 Subject: [PATCH 463/672] Improved error messages and fixed players joining with same identifier, fixes #605 --- server/main.lua | 68 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/server/main.lua b/server/main.lua index 30e97f82..ce395123 100644 --- a/server/main.lua +++ b/server/main.lua @@ -16,31 +16,59 @@ function onPlayerJoined(playerId) end if identifier then - MySQL.Async.fetchScalar('SELECT 1 FROM users WHERE identifier = @identifier', { - ['@identifier'] = identifier - }, function(result) - if result then - loadESXPlayer(identifier, playerId) - else - local accounts = {} - - for account,money in pairs(Config.StartingAccountMoney) do - accounts[account] = money - end - - MySQL.Async.execute('INSERT INTO users (accounts, identifier) VALUES (@accounts, @identifier)', { - ['@accounts'] = json.encode(accounts), - ['@identifier'] = identifier - }, function(rowsChanged) + if ESX.GetPlayerFromIdentifier(identifier) then + DropPlayer(playerId, ('there was an error loading your character!\nError code: identifier-active-ingame\n\nThis error is caused by a player on this server who has the same identifier as you have. Make sure you are not playing on the same Rockstar account.\n\nYour Rockstar identifier: %s'):format(identifier)) + else + MySQL.Async.fetchScalar('SELECT 1 FROM users WHERE identifier = @identifier', { + ['@identifier'] = identifier + }, function(result) + if result then loadESXPlayer(identifier, playerId) - end) - end - end) + else + local accounts = {} + + for account,money in pairs(Config.StartingAccountMoney) do + accounts[account] = money + end + + MySQL.Async.execute('INSERT INTO users (accounts, identifier) VALUES (@accounts, @identifier)', { + ['@accounts'] = json.encode(accounts), + ['@identifier'] = identifier + }, function(rowsChanged) + loadESXPlayer(identifier, playerId) + end) + end + end) + end else - DropPlayer(playerId, 'Your Rockstar license could not be found') + DropPlayer(playerId, 'there was an error loading your character!\nError code: identifier-missing-ingame\n\nThe cause of this error is not known, your identifier could not be found. Please come back later or report this problem to the server administration team.') end end +AddEventHandler('playerConnecting', function(name, setCallback, deferrals) + deferrals.defer() + local playerId, identifier = source + Citizen.Wait(100) + + for k,v in ipairs(GetPlayerIdentifiers(playerId)) do + if string.match(v, 'license:') then + identifier = string.sub(v, 9) + break + end + end + + if identifier then + if ESX.GetPlayerFromIdentifier(identifier) then + deferrals.done(('There was an error loading your character!\nError code: identifier-active\n\nThis error is caused by a player on this server who has the same identifier as you have. Make sure you are not playing on the same Rockstar account.\n\nYour Rockstar identifier: %s'):format(identifier)) + else + deferrals.done() + end + else + deferrals.done('There was an error loading your character!\nError code: identifier-missing\n\nThe cause of this error is not known, your identifier could not be found. Please come back later or report this problem to the server administration team.') + end +end) + + function loadESXPlayer(identifier, playerId) local tasks = {} From 77e810ce9586081fd7a79db6e11a92f08647f60b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Thu, 26 Mar 2020 12:10:45 +0100 Subject: [PATCH 464/672] Fixed setting vehicle pearlescent color Co-Authored-By: Daniel Hawton Co-Authored-By: ChainTastic --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index 07c9cab4..ce849263 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -765,7 +765,7 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) if props.color1 then SetVehicleColours(vehicle, props.color1, colorSecondary) end if props.color2 then SetVehicleColours(vehicle, props.color1 or colorPrimary, props.color2) end if props.pearlescentColor then SetVehicleExtraColours(vehicle, props.pearlescentColor, wheelColor) end - if props.wheelColor then SetVehicleExtraColours(vehicle, pearlescentColor, props.wheelColor) end + if props.wheelColor then SetVehicleExtraColours(vehicle, props.pearlescentColor or pearlescentColor, props.wheelColor) end if props.wheels then SetVehicleWheelType(vehicle, props.wheels) end if props.windowTint then SetVehicleWindowTint(vehicle, props.windowTint) end From 93772d378f25d0520590a9f490a472d835efcc99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BA=BB=E8=BE=A3=E6=88=88=E5=A3=81?= Date: Mon, 30 Mar 2020 16:20:37 +0800 Subject: [PATCH 465/672] Add simplified Chinese and traditional Chinese language (#588) * Add simplified Chinese and traditional Chinese language * Update tc.lua * Added new translations * Added new translations * Update sc.lua * Update tc.lua * Very final strings to translate * Update sc.lua * Update tc.lua Co-authored-by: ElPumpo --- fxmanifest.lua | 4 + locales/sc.lua | 225 +++++++++++++++++++++++++++++++++++++++++++++++++ locales/tc.lua | 225 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 454 insertions(+) create mode 100644 locales/sc.lua create mode 100644 locales/tc.lua diff --git a/fxmanifest.lua b/fxmanifest.lua index eb6e6f19..0f1c2f78 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -19,6 +19,8 @@ server_scripts { 'locales/sv.lua', 'locales/pl.lua', 'locales/cs.lua', + 'locales/sc.lua', + 'locales/tc.lua', 'config.lua', 'config.weapons.lua', @@ -45,6 +47,8 @@ client_scripts { 'locales/sv.lua', 'locales/pl.lua', 'locales/cs.lua', + 'locales/sc.lua', + 'locales/tc.lua', 'config.lua', 'config.weapons.lua', diff --git a/locales/sc.lua b/locales/sc.lua new file mode 100644 index 00000000..050637e2 --- /dev/null +++ b/locales/sc.lua @@ -0,0 +1,225 @@ +Locales['sc'] = { + -- Inventory + ['inventory'] = '库存 %s / %s', + ['use'] = '使用', + ['give'] = '赠送', + ['remove'] = '丢弃', + ['return'] = '返回', + ['give_to'] = '赠给', + ['amount'] = '数量', + ['giveammo'] = '赠送弹药', + ['amountammo'] = '弹药量', + ['noammo'] = '你没有足够的弹药!', + ['gave_item'] = '你把~y~%sx~s~~b~%s~s~赠给了~y~%s~s~', + ['received_item'] = '你收到~y~%sx~s~~b~%s~s~,来自~b~%s~s~', + ['gave_weapon'] = '你把~b~%s~s~赠给了~y~%s~s~', + ['gave_weapon_ammo'] = '你把~o~%sx~s~~b~%s~s~ %s~s~赠给了~y~%s~s~', + ['gave_weapon_withammo'] = '你把~b~%s~s~和~o~%sx~s~ %s~s~赠给了~y~%s~s~', + ['gave_weapon_hasalready'] = '~y~%s~s~已经拥有~y~%s~s~', + ['gave_weapon_noweapon'] = '~y~%s~s~没有那个武器', + ['received_weapon'] = '你收到了~b~%s~s~,来自~b~%s~s~', + ['received_weapon_ammo'] = '你收到了~o~%sx~s~ %s~s~(~b~%s~s~),来自~b~%s~s~', + ['received_weapon_withammo'] = '你收到了~b~%s~s~和~o~%sx~s~ %s~s~,来自~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~试图给你~y~%s~s~,但你已经拥有了', + ['received_weapon_noweapon'] = '~b~%s~s~试图给你~y~%s~s~弹药,但你没有那个武器', + ['gave_account_money'] = '你将 ~g~$%s~s~ (%s) 给予 ~y~%s~s~', + ['received_account_money'] = '你收到了~g~$%s~s~ (%s) 来自 ~b~%s~s~', + ['amount_invalid'] = '无效数量', + ['players_nearby'] = '附近没有玩家', + ['ex_inv_lim'] = '操作失败, 超过~y~%s~s~的物品栏限制', + ['imp_invalid_quantity'] = '操作失败,无效数量', + ['imp_invalid_amount'] = '操作失败,无效金额', + ['threw_standard'] = '你丢弃了~y~%sx~s~~b~%s~s~', + ['threw_account'] = '你丢弃了~g~$%s~s~~b~%s~s~', + ['threw_weapon'] = '你丢弃了~b~%s~s~', + ['threw_weapon_ammo'] = '你丢弃了~b~%s~s~和~o~%sx%s~s~', + ['threw_weapon_already'] = '你已经有同样的武器了', + ['threw_cannot_pickup'] = '你不能再拿起那个了,因为你的库存已经满了', + ['threw_pickup_prompt'] = '按 ~y~E~s~ 拿起', + + -- Key mapping + ['keymap_showinventory'] = '显示库存', + + -- Salary related + ['received_salary'] = '你收到了你的工资: ~g~$%s~s~', + ['received_help'] = '鉴于你良好的表现,系统赠送给你一些奖励: ~g~$%s~s~', + ['company_nomoney'] = '你受雇的公司太穷了,无法支付你的工资。', + ['received_paycheck'] = '收到转账', + ['bank'] = '花园银行', + ['account_bank'] = '银行', + ['account_black_money'] = '黑钱', + ['account_money'] = '现金', + + ['act_imp'] = '操作失败', + ['in_vehicle'] = '请离开载具', + + -- Commands + ['command_car'] = '生成载具', + ['command_car_car'] = '生成载具的模型名称或哈希值', + ['command_cardel'] = '删除附近的载具', + ['command_cardel_radius'] = '可选,删除指定半径内的所有车辆', + ['command_clear'] = '清除聊天记录', + ['command_clearall'] = '清除所有玩家的聊天记录', + ['command_clearinventory'] = '清除玩家库存', + ['command_clearloadout'] = '清除玩家皮肤', + ['command_giveaccountmoney'] = '给帐户钱', + ['command_giveaccountmoney_account'] = '有效的帐户名', + ['command_giveaccountmoney_amount'] = '添加的数量', + ['command_giveaccountmoney_invalid'] = '无效的帐户名', + ['command_giveitem'] = '给玩家一件物品', + ['command_giveitem_item'] = '物品名称', + ['command_giveitem_count'] = '物品数目', + ['command_giveweapon'] = '给玩家一件武器', + ['command_giveweapon_weapon'] = '武器名称', + ['command_giveweapon_ammo'] = '弹药数目', + ['command_giveweapon_hasalready'] = '该玩家已经拥有该武器', + ['command_giveweaponcomponent'] = '给武器配件', + ['command_giveweaponcomponent_component'] = '配件名称', + ['command_giveweaponcomponent_invalid'] = '无效的武器配件', + ['command_giveweaponcomponent_hasalready'] = '玩家已经拥有该武器配件', + ['command_giveweaponcomponent_missingweapon'] = '该玩家没有那个武器', + ['command_save'] = '保存玩家数据至数据库', + ['command_saveall'] = '保存所有玩家数据至数据库', + ['command_setaccountmoney'] = '为玩家设置帐户资金', + ['command_setaccountmoney_amount'] = '要设定的金额', + ['command_setcoords'] = '传送到坐标', + ['command_setcoords_x'] = 'x 轴', + ['command_setcoords_y'] = 'y 轴', + ['command_setcoords_z'] = 'z 轴', + ['command_setjob'] = '为玩家设定工作', + ['command_setjob_job'] = '工作名称', + ['command_setjob_grade'] = '工作等级', + ['command_setjob_invalid'] = '工作、等级或两者都无效', + ['command_setgroup'] = '设置玩家用户组', + ['command_setgroup_group'] = '用户组名称', + ['commanderror_argumentmismatch'] = '参数计数不匹配(该类型为%s, 需要传递 %s)', + ['commanderror_argumentmismatch_number'] = '参数 #%s 类型不匹配(该类型为字符串,需要传递数字类型)', + ['commanderror_invaliditem'] = '无效的物品名称', + ['commanderror_invalidweapon'] = '无效武器', + ['commanderror_console'] = '该命令不能从控制台运行', + ['commanderror_invalidcommand'] = '^3%s^0 不是有效的命令!', + ['commanderror_invalidplayerid'] = '没有在线玩家匹配到该服务id', + ['commandgeneric_playerid'] = '玩家id', + + -- Locale settings + ['locale_digit_grouping_symbol'] = ',', + ['locale_currency'] = '$%s', + + -- Weapons + ['weapon_knife'] = '小刀', + ['weapon_nightstick'] = '警棍', + ['weapon_hammer'] = '铁锤', + ['weapon_bat'] = '棒球棍', + ['weapon_golfclub'] = '高尔夫球杆', + ['weapon_crowbar'] = '撬棍', + ['weapon_pistol'] = '手枪', + ['weapon_combatpistol'] = '战斗手枪', + ['weapon_appistol'] = '穿甲手枪', + ['weapon_pistol50'] = '0.5 口径手枪', + ['weapon_microsmg'] = '微型冲锋枪', + ['weapon_smg'] = '冲锋枪', + ['weapon_assaultsmg'] = '突击冲锋枪', + ['weapon_assaultrifle'] = '突击步枪', + ['weapon_carbinerifle'] = '卡宾步枪', + ['weapon_advancedrifle'] = '高级步枪', + ['weapon_mg'] = '机枪', + ['weapon_combatmg'] = '战斗机枪', + ['weapon_pumpshotgun'] = '泵动式霰弹枪', + ['weapon_sawnoffshotgun'] = '短管霰弹枪', + ['weapon_assaultshotgun'] = '突击霰弹枪', + ['weapon_bullpupshotgun'] = '无托式霰弹枪', + ['weapon_stungun'] = '电击枪', + ['weapon_sniperrifle'] = '狙击步枪', + ['weapon_heavysniper'] = '重型狙击步枪', + ['weapon_grenadelauncher'] = '榴弹发射器', + ['weapon_rpg'] = '火箭炮', + ['weapon_minigun'] = '火神机枪', + ['weapon_grenade'] = '手榴弹', + ['weapon_stickybomb'] = '黏弹', + ['weapon_smokegrenade'] = '烟雾弹', + ['weapon_bzgas'] = '催泪瓦斯', + ['weapon_molotov'] = '汽油弹', + ['weapon_fireextinguisher'] = '灭火器', + ['weapon_petrolcan'] = '汽油桶', + ['weapon_ball'] = '棒球', + ['weapon_snspistol'] = '劣质手枪', + ['weapon_bottle'] = '酒瓶', + ['weapon_gusenberg'] = '古森柏冲锋枪', + ['weapon_specialcarbine'] = '特制卡宾枪', + ['weapon_heavypistol'] = '重型手枪', + ['weapon_bullpuprifle'] = '无托式步枪', + ['weapon_dagger'] = '匕首', + ['weapon_vintagepistol'] = '老式手枪', + ['weapon_firework'] = '烟花发射器', + ['weapon_musket'] = '老式火枪', + ['weapon_heavyshotgun'] = '重型霰弹枪', + ['weapon_marksmanrifle'] = '射手步枪', + ['weapon_hominglauncher'] = '制导火箭发射器', + ['weapon_proxmine'] = '感应地雷', + ['weapon_snowball'] = '雪球', + ['weapon_flaregun'] = '信号枪', + ['weapon_combatpdw'] = '作战自卫冲锋枪', + ['weapon_marksmanpistol'] = '射手手枪', + ['weapon_knuckle'] = '手指虎', + ['weapon_hatchet'] = '手斧', + ['weapon_railgun'] = '电磁轨道炮', + ['weapon_machete'] = '开山刀', + ['weapon_machinepistol'] = '冲锋手枪', + ['weapon_switchblade'] = '弹簧刀', + ['weapon_revolver'] = '重型左轮手枪', + ['weapon_dbshotgun'] = '双管霰弹枪', + ['weapon_compactrifle'] = '紧凑型步枪', + ['weapon_autoshotgun'] = '半自动霰弹枪', + ['weapon_battleaxe'] = '战斧', + ['weapon_compactlauncher'] = '紧凑型榴弹发射器', + ['weapon_minismg'] = '迷你冲锋枪', + ['weapon_pipebomb'] = '土制炸弹', + ['weapon_poolcue'] = '台球杆', + ['weapon_wrench'] = '管钳扳手', + ['weapon_flashlight'] = '手电筒', + ['gadget_parachute'] = '降落伞', + ['weapon_flare'] = '信号棒', + ['weapon_doubleaction'] = '双动式左轮手枪', + + -- Weapon Components + ['component_clip_default'] = '默认弹夹', + ['component_clip_extended'] = '扩容弹夹', + ['component_clip_drum'] = '鼓式弹夹', + ['component_clip_box'] = '盒型弹匣', + ['component_flashlight'] = '手电筒', + ['component_scope'] = '瞄准镜', + ['component_scope_advanced'] = '高级瞄准镜', + ['component_suppressor'] = '消音器', + ['component_grip'] = '握把', + ['component_luxary_finish'] = '奢华涂饰', + + -- Weapon Ammo + ['ammo_rounds'] = '发(子弹)', + ['ammo_shells'] = '发(子弹)', + ['ammo_charge'] = '喷', + ['ammo_petrol'] = '加仑(燃料)', + ['ammo_firework'] = '发(烟花弹)', + ['ammo_rockets'] = '枚(火箭弹)', + ['ammo_grenadelauncher'] = '发(榴弹)', + ['ammo_grenade'] = '枚(手榴弹)', + ['ammo_stickybomb'] = '枚(炸弹)', + ['ammo_pipebomb'] = '枚(炸弹)', + ['ammo_smokebomb'] = '枚(炸弹)', + ['ammo_molotov'] = '瓶(汽油瓶)', + ['ammo_proxmine'] = '个(地雷)', + ['ammo_bzgas'] = '罐', + ['ammo_ball'] = '个(球)', + ['ammo_snowball'] = '个(雪球)', + ['ammo_flare'] = '根(信号棒)', + ['ammo_flaregun'] = '发(信号弹)', + + -- Weapon Tints + ['tint_default'] = '默认色调', + ['tint_green'] = '绿色调', + ['tint_gold'] = '金色调', + ['tint_pink'] = '粉色调', + ['tint_army'] = '军用色调', + ['tint_lspd'] = '洛圣都警局色调', + ['tint_orange'] = '橙色调', + ['tint_platinum'] = '铂金色调', +} diff --git a/locales/tc.lua b/locales/tc.lua new file mode 100644 index 00000000..c0b1e31c --- /dev/null +++ b/locales/tc.lua @@ -0,0 +1,225 @@ +Locales['tc'] = { + -- Inventory + ['inventory'] = '背包 %s / %s', + ['use'] = '使用', + ['give'] = '給', + ['remove'] = '丟棄', + ['return'] = '返回', + ['give_to'] = '給予', + ['amount'] = '數量', + ['giveammo'] = '給予子彈', + ['amountammo'] = '子彈量', + ['noammo'] = '您沒有足夠的子彈!', + ['gave_item'] = '您把~y~%sx~s~~b~%s~s~給予了~y~%s~s~', + ['received_item'] = '您收到~y~%sx~s~~b~%s~s~,來自~b~%s~s~', + ['gave_weapon'] = '您把~b~%s~s~給予了~y~%s~s~', + ['gave_weapon_ammo'] = '您把~o~%sx~s~~b~%s~s~ %s~s~給予了~y~%s~s~', + ['gave_weapon_withammo'] = '您把~b~%s~s~和~o~%sx~s~ %s~s~給予了~y~%s~s~', + ['gave_weapon_hasalready'] = '~y~%s~s~已經有~y~%s~s~', + ['gave_weapon_noweapon'] = '~y~%s~s~沒有那把武器', + ['received_weapon'] = '您收到了~b~%s~s~,來自~b~%s~s~', + ['received_weapon_ammo'] = '您收到了~o~%sx~s~ %s~s~(~b~%s~s~),來自~b~%s~s~', + ['received_weapon_withammo'] = '您收到了~b~%s~s~和~o~%sx~s~ %s~s~,來自~b~%s~s~', + ['received_weapon_hasalready'] = '~b~%s~s~嘗試给您~y~%s~s~,但您已经有了', + ['received_weapon_noweapon'] = '~b~%s~s~嘗試给您~y~%s~s~子彈,但是您沒有那把武器', + ['gave_account_money'] = '您將 ~g~$%s~s~ (%s) 给予 ~y~%s~s~', + ['received_account_money'] = '您收到了~g~$%s~s~ (%s) 来自 ~b~%s~s~', + ['amount_invalid'] = '無效的數量', + ['players_nearby'] = '附近沒有玩家', + ['ex_inv_lim'] = '操作失敗, 超過~y~%s~s~物品欄位的限制', + ['imp_invalid_quantity'] = '操作失敗,無效的數量', + ['imp_invalid_amount'] = '操作失敗,無效的金額', + ['threw_standard'] = '您丟棄了~y~%sx~s~~b~%s~s~', + ['threw_account'] = '您丟棄了~g~$%s~s~~b~%s~s~', + ['threw_weapon'] = '您丟棄了~b~%s~s~', + ['threw_weapon_ammo'] = '您丟棄了~b~%s~s~和~o~%sx%s~s~', + ['threw_weapon_already'] = '您已經有相同的武器了', + ['threw_cannot_pickup'] = '您不能再撿起該物品,因為您的背包已經滿了', + ['threw_pickup_prompt'] = '按下 ~y~E~s~ 撿起', + + -- Key mapping + ['keymap_showinventory'] = '顯示背包', + + -- Salary related + ['received_salary'] = '您收到您的薪水: ~g~$%s~s~', + ['received_help'] = '由於您表現良好,系統給予您一些獎勵: ~g~$%s~s~', + ['company_nomoney'] = '您的公司太窮了,無法給予您薪水。', + ['received_paycheck'] = '收到轉帳', + ['bank'] = '花園銀行', + ['account_bank'] = '銀行', + ['account_black_money'] = '黑錢', + ['account_money'] = '現金', + + ['act_imp'] = '操作失敗', + ['in_vehicle'] = '請離開載具', + + -- Commands + ['command_car'] = '生成載具', + ['command_car_car'] = '生成載具的模型名稱或希哈值', + ['command_cardel'] = '刪除附近的載具', + ['command_cardel_radius'] = '可選擇,刪除指定半徑內的所有車輛', + ['command_clear'] = '清除聊天紀錄', + ['command_clearall'] = '清除所有玩家的聊天紀錄', + ['command_clearinventory'] = '清除玩家背包', + ['command_clearloadout'] = '清除玩家人物造型', + ['command_giveaccountmoney'] = '給予帳戶錢', + ['command_giveaccountmoney_account'] = '有效的帳戶名稱', + ['command_giveaccountmoney_amount'] = '添加的數量', + ['command_giveaccountmoney_invalid'] = '無效的帳戶名稱', + ['command_giveitem'] = '給玩家一個物品', + ['command_giveitem_item'] = '物品名稱', + ['command_giveitem_count'] = '物品數量', + ['command_giveweapon'] = '给玩家一把武器', + ['command_giveweapon_weapon'] = '武器名稱', + ['command_giveweapon_ammo'] = '子彈數量', + ['command_giveweapon_hasalready'] = '該玩家已經擁有了該武器', + ['command_giveweaponcomponent'] = '給予武器配件', + ['command_giveweaponcomponent_component'] = '配件名稱', + ['command_giveweaponcomponent_invalid'] = '無效的武器配件', + ['command_giveweaponcomponent_hasalready'] = '該玩家已經擁有了武器配件', + ['command_giveweaponcomponent_missingweapon'] = '該玩家沒有那把武器', + ['command_save'] = '保存玩家數據至資料庫', + ['command_saveall'] = '保存所有玩家數據至資料庫', + ['command_setaccountmoney'] = '為玩家設置賬戶資金', + ['command_setaccountmoney_amount'] = '要設置的金額', + ['command_setcoords'] = '傳送到座標上', + ['command_setcoords_x'] = 'x 軸', + ['command_setcoords_y'] = 'y 軸', + ['command_setcoords_z'] = 'z 軸', + ['command_setjob'] = '設定該玩家職業', + ['command_setjob_job'] = '職業名稱', + ['command_setjob_grade'] = '職業階級', + ['command_setjob_invalid'] = '職業、階級或者兩者都無效', + ['command_setgroup'] = '設定玩家群組階級', + ['command_setgroup_group'] = '玩家群組階級名稱', + ['commanderror_argumentmismatch'] = '參數數量不正確(該類型為%s, 需要給予 %s)', + ['commanderror_argumentmismatch_number'] = '參數 #%s 類型不匹配(該類型為字串,需要給予的數字類型)', + ['commanderror_invaliditem'] = '無效的物品名稱', + ['commanderror_invalidweapon'] = '無效武器', + ['commanderror_console'] = '該指令不能從控制台執行', + ['commanderror_invalidcommand'] = '^3%s^0 不是有效的指令!', + ['commanderror_invalidplayerid'] = '無效的玩家ID', + ['commandgeneric_playerid'] = '玩家id', + + -- Locale settings + ['locale_digit_grouping_symbol'] = ',', + ['locale_currency'] = '$%s', + + -- Weapons + ['weapon_knife'] = '刀', + ['weapon_nightstick'] = '警棍', + ['weapon_hammer'] = '錘子', + ['weapon_bat'] = '棒球棍', + ['weapon_golfclub'] = '高爾夫球棍', + ['weapon_crowbar'] = '撬棍', + ['weapon_pistol'] = '手槍', + ['weapon_combatpistol'] = '戰鬥手槍', + ['weapon_appistol'] = '穿甲手槍', + ['weapon_pistol50'] = '.50口徑手槍', + ['weapon_microsmg'] = '迷你衝鋒槍', + ['weapon_smg'] = '衝鋒槍', + ['weapon_assaultsmg'] = '突擊衝鋒槍', + ['weapon_assaultrifle'] = '突擊步槍', + ['weapon_carbinerifle'] = '卡賓槍步槍', + ['weapon_advancedrifle'] = '精準步槍', + ['weapon_mg'] = '機槍', + ['weapon_combatmg'] = '戰鬥機槍', + ['weapon_pumpshotgun'] = '霰彈槍', + ['weapon_sawnoffshotgun'] = '削短型霰彈槍', + ['weapon_assaultshotgun'] = '突擊霰彈槍', + ['weapon_bullpupshotgun'] = '泵動式霰彈槍', + ['weapon_stungun'] = '電擊槍', + ['weapon_sniperrifle'] = '狙擊步槍', + ['weapon_heavysniper'] = '重型狙擊槍', + ['weapon_grenadelauncher'] = '榴彈砲', + ['weapon_rpg'] = '火箭炮', + ['weapon_minigun'] = '火神機槍', + ['weapon_grenade'] = '手榴彈', + ['weapon_stickybomb'] = '黏彈', + ['weapon_smokegrenade'] = '煙霧彈', + ['weapon_bzgas'] = '催淚瓦斯', + ['weapon_molotov'] = '汽油彈', + ['weapon_fireextinguisher'] = '滅火器', + ['weapon_petrolcan'] = '汽油桶', + ['weapon_ball'] = '棒球', + ['weapon_snspistol'] = '劣質手槍', + ['weapon_bottle'] = '酒瓶', + ['weapon_gusenberg'] = '古森柏衝鋒槍', + ['weapon_specialcarbine'] = '特製卡賓槍', + ['weapon_heavypistol'] = '重型手槍', + ['weapon_bullpuprifle'] = 'AUG突擊步槍', + ['weapon_dagger'] = '匕首', + ['weapon_vintagepistol'] = '老式手槍', + ['weapon_firework'] = '煙火發射器', + ['weapon_musket'] = '老式火槍', + ['weapon_heavyshotgun'] = '重型霰彈槍', + ['weapon_marksmanrifle'] = '精確射手步槍', + ['weapon_hominglauncher'] = '火箭彈發射器', + ['weapon_proxmine'] = '感應地雷', + ['weapon_snowball'] = '雪球', + ['weapon_flaregun'] = '信號槍', + ['weapon_combatpdw'] = '戰鬥自衛衝鋒槍', + ['weapon_marksmanpistol'] = '神射手槍', + ['weapon_knuckle'] = '指虎', + ['weapon_hatchet'] = '斧頭', + ['weapon_railgun'] = '電磁軌彈炮', + ['weapon_machete'] = '開山刀', + ['weapon_machinepistol'] = '衝鋒手槍', + ['weapon_switchblade'] = '蝴蝶刀', + ['weapon_revolver'] = '重左輪手槍', + ['weapon_dbshotgun'] = '雙槍霰彈槍', + ['weapon_compactrifle'] = '半自動步槍', + ['weapon_autoshotgun'] = '半自動霰彈槍', + ['weapon_battleaxe'] = '戰斧', + ['weapon_compactlauncher'] = '精簡榴彈發射器', + ['weapon_minismg'] = '迷你衝鋒槍', + ['weapon_pipebomb'] = '土製炸彈', + ['weapon_poolcue'] = '桌球桿', + ['weapon_wrench'] = '扳手', + ['weapon_flashlight'] = '手電筒', + ['gadget_parachute'] = '降落傘', + ['weapon_flare'] = '信號棒', + ['weapon_doubleaction'] = '左輪手槍', + + -- Weapon Components + ['component_clip_default'] = '默認彈夾', + ['component_clip_extended'] = '延伸彈夾', + ['component_clip_drum'] = '彈鼓式彈匣', + ['component_clip_box'] = '盒式彈匣', + ['component_flashlight'] = '手電筒', + ['component_scope'] = '瞄準鏡', + ['component_scope_advanced'] = '高級瞄準鏡', + ['component_suppressor'] = '消音管', + ['component_grip'] = '握把', + ['component_luxary_finish'] = '豪華塗裝', + + -- Weapon Ammo + ['ammo_rounds'] = '發(子彈)', + ['ammo_shells'] = '發(子彈)', + ['ammo_charge'] = '噴', + ['ammo_petrol'] = '加崙(燃料)', + ['ammo_firework'] = '發(煙火子彈)', + ['ammo_rockets'] = '枚(火箭彈)', + ['ammo_grenadelauncher'] = '發(榴彈)', + ['ammo_grenade'] = '枚(手榴彈)', + ['ammo_stickybomb'] = '枚(炸彈)', + ['ammo_pipebomb'] = '枚(炸彈)', + ['ammo_smokebomb'] = '枚(炸彈)', + ['ammo_molotov'] = '瓶(汽油瓶)', + ['ammo_proxmine'] = '個(地雷)', + ['ammo_bzgas'] = '罐', + ['ammo_ball'] = '顆(球)', + ['ammo_snowball'] = '顆(雪球)', + ['ammo_flare'] = '根(信號棒)', + ['ammo_flaregun'] = '發(信號彈)', + + -- Weapon Tints + ['tint_default'] = '默認色調', + ['tint_green'] = '綠色調', + ['tint_gold'] = '金色調', + ['tint_pink'] = '粉色調', + ['tint_army'] = '軍用色調', + ['tint_lspd'] = '洛聖都警察局色調', + ['tint_orange'] = '橘色調', + ['tint_platinum'] = '柏金色調', +} From 6c70abd5e8393b6f58180ad22a8d3cc94247d4ef Mon Sep 17 00:00:00 2001 From: RoJea32 <57993332+RoJea32@users.noreply.github.com> Date: Tue, 31 Mar 2020 12:24:30 +0300 Subject: [PATCH 466/672] Fix "attempt to index a nil value field ('?')" (#612) * Update main.lua * Update main.lua --- client/main.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/main.lua b/client/main.lua index a5f24ce2..65527b1f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -356,8 +356,10 @@ end) RegisterNetEvent('esx:removePickup') AddEventHandler('esx:removePickup', function(id) - ESX.Game.DeleteObject(pickups[id].obj) - pickups[id] = nil + if pickups[id] and pickups[id].obj then + ESX.Game.DeleteObject(pickups[id].obj) + pickups[id] = nil + end end) RegisterNetEvent('esx:deleteVehicle') From f4558c85e3e313b7cefba351c1e459418fe38718 Mon Sep 17 00:00:00 2001 From: Vegard Bendiktsen Date: Fri, 3 Apr 2020 09:20:58 +0200 Subject: [PATCH 467/672] Support table/list of groups when registering commands (#616) * Support table/list of groups when registering commands * Adhere to "unwritten code standard" --- server/functions.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/server/functions.lua b/server/functions.lua index 74e2efcc..601f27f0 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -138,7 +138,13 @@ ESX.RegisterCommand = function(name, group, cb, allowConsole, suggestion) end end, true) - ExecuteCommand(('add_ace group.%s command.%s allow'):format(group, name)) + if type(group) == 'table' then + for k,v in ipairs(group) do + ExecuteCommand(('add_ace group.%s command.%s allow'):format(v, name)) + end + else + ExecuteCommand(('add_ace group.%s command.%s allow'):format(group, name)) + end end ESX.ClearTimeout = function(id) From 1f61585917ae400151b84b79fcbbc4e1ff1c8663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs?= <52821987+YisusTM01@users.noreply.github.com> Date: Sat, 4 Apr 2020 19:03:34 +0200 Subject: [PATCH 468/672] Fixed collisions of pickups items and weapons Fixed character and car collisions with objects lying on the ground (also weapons and the bat itself). --- client/main.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/main.lua b/client/main.lua index 65527b1f..c41aa5b4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -297,6 +297,7 @@ AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, na SetEntityAsMissionEntity(pickupObject, true, false) PlaceObjectOnGroundProperly(pickupObject) FreezeEntityPosition(pickupObject, true) + SetEntityCollision(pickupObject, false, true) pickups[pickupId] = { id = pickupId, @@ -334,6 +335,7 @@ AddEventHandler('esx:createMissingPickups', function(missingPickups) SetEntityAsMissionEntity(pickupObject, true, false) PlaceObjectOnGroundProperly(pickupObject) FreezeEntityPosition(pickupObject, true) + SetEntityCollision(pickupObject, false, true) pickups[pickupId] = { id = pickupId, From 2c2978feaa9674862e8ac3d61281abc890520a76 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 6 Apr 2020 12:09:06 +0200 Subject: [PATCH 469/672] Replaced coords sync interval with sync every second Because xPlayer.getCoords() has uses it cant be out of sync code --- client/main.lua | 27 +++++++++++++++------------ config.lua | 1 - 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/client/main.lua b/client/main.lua index c41aa5b4..4c91cf7f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -522,24 +522,27 @@ end) -- Update current player coords Citizen.CreateThread(function() - local previousCoords = vector3(0, 0, 0) - -- wait for player to restore coords while not isLoadoutLoaded do Citizen.Wait(1000) end - while true do - Citizen.Wait(Config.CoordsSyncInterval) - local playerPed = PlayerPedId() - local playerCoords = GetEntityCoords(playerPed) - local distance = #(playerCoords - previousCoords) + local previousCoords = vector3(ESX.PlayerData.coords.x, ESX.PlayerData.coords.y, ESX.PlayerData.coords.z) - if distance > 10 then - previousCoords = playerCoords - local playerHeading = ESX.Math.Round(GetEntityHeading(playerPed), 1) - local formattedCoords = {x = ESX.Math.Round(playerCoords.x, 1), y = ESX.Math.Round(playerCoords.y, 1), z = ESX.Math.Round(playerCoords.z, 1), heading = playerHeading} - TriggerServerEvent('esx:updateCoords', formattedCoords) + while true do + Citizen.Wait(1000) + local playerPed = PlayerPedId() + + if DoesEntityExist(playerPed) then + local playerCoords = GetEntityCoords(playerPed) + local distance = #(playerCoords - previousCoords) + + if distance > 1 then + previousCoords = playerCoords + local playerHeading = ESX.Math.Round(GetEntityHeading(playerPed), 1) + local formattedCoords = {x = ESX.Math.Round(playerCoords.x, 1), y = ESX.Math.Round(playerCoords.y, 1), z = ESX.Math.Round(playerCoords.z, 1), heading = playerHeading} + TriggerServerEvent('esx:updateCoords', formattedCoords) + end end end end) diff --git a/config.lua b/config.lua index a6f10be3..fc28850e 100644 --- a/config.lua +++ b/config.lua @@ -16,6 +16,5 @@ Config.EnablePvP = true -- enable pvp? Config.MaxWeight = 24 -- the max inventory weight without backpack Config.PaycheckInterval = 7 * 60000 -- how often to recieve pay checks in milliseconds -Config.CoordsSyncInterval = 2 * 60000 -- how often to sync coords with server in milliseconds Config.EnableDebug = false From 492f41ca45b301a5388dc317fe0bbca15885b82f Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 6 Apr 2020 13:19:34 +0200 Subject: [PATCH 470/672] Don't spam request asset natives --- client/functions.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index ce849263..8d2ea626 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -306,7 +306,6 @@ ESX.Game.Teleport = function(entity, coords, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(entity) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) Citizen.Wait(0) end @@ -378,7 +377,6 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) Citizen.Wait(0) end @@ -405,7 +403,6 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(vehicle) do - RequestCollisionAtCoord(coords.x, coords.y, coords.z) Citizen.Wait(0) end From b0215b9671b14054d1fde2c5bdf7070dae1acc0e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 6 Apr 2020 17:59:40 +0200 Subject: [PATCH 471/672] Fixed isDead variable not updating properly, closes #635 Co-Authored-By: pitermcflebor --- client/main.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/main.lua b/client/main.lua index 4c91cf7f..0396dea4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -65,7 +65,7 @@ AddEventHandler('esx:playerLoaded', function(playerData) z = playerData.coords.z + 0.5, heading = playerData.coords.heading }, function() - isLoadoutLoaded, isDead = true, false + isLoadoutLoaded = true TriggerServerEvent('esx:onPlayerSpawn') TriggerEvent('esx:onPlayerSpawn') TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon @@ -80,6 +80,7 @@ end) RegisterNetEvent('esx:setMaxWeight') AddEventHandler('esx:setMaxWeight', function(newMaxWeight) ESX.PlayerData.maxWeight = newMaxWeight end) +AddEventHandler('esx:onPlayerSpawn', function() isDead = false end) AddEventHandler('esx:onPlayerDeath', function() isDead = true end) AddEventHandler('skinchanger:loadDefaultModel', function() isLoadoutLoaded = false end) From 9f1a18d4203217690ddc49304aa5bf5cb0422837 Mon Sep 17 00:00:00 2001 From: Andrea Passarini <51895814+Profex1999@users.noreply.github.com> Date: Tue, 7 Apr 2020 04:43:24 +0200 Subject: [PATCH 472/672] Fix removeWeaponComponent not working correctly --- server/classes/player.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/classes/player.lua b/server/classes/player.lua index 0705204c..75a7d83e 100644 --- a/server/classes/player.lua +++ b/server/classes/player.lua @@ -432,7 +432,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, if component then if self.hasWeaponComponent(weaponName, weaponComponent) then for k,v in ipairs(self.loadout[loadoutNum].components) do - if v.name == weaponComponent then + if v == weaponComponent then table.remove(self.loadout[loadoutNum].components, k) break end From 8de2e4311ab21781bb5da56f8c3bde17a87fff8e Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 11 Apr 2020 11:53:50 +0200 Subject: [PATCH 473/672] Unload model where applicable --- client/functions.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 8d2ea626..26bc233b 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -326,8 +326,8 @@ ESX.Game.SpawnObject = function(model, coords, cb) Citizen.CreateThread(function() ESX.Streaming.RequestModel(model) - local obj = CreateObject(model, coords.x, coords.y, coords.z, true, false, true) + SetModelAsNoLongerNeeded(model) if cb then cb(obj) @@ -340,8 +340,8 @@ ESX.Game.SpawnLocalObject = function(model, coords, cb) Citizen.CreateThread(function() ESX.Streaming.RequestModel(model) - local obj = CreateObject(model, coords.x, coords.y, coords.z, false, false, true) + SetModelAsNoLongerNeeded(model) if cb then cb(obj) From ddd3a88336cc336ad439e8e11291d130f20d2a0b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sat, 11 Apr 2020 11:55:27 +0200 Subject: [PATCH 474/672] Minor variable renaming --- client/main.lua | 41 ++++++++++++++++++++--------------------- server/main.lua | 8 ++++---- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/client/main.lua b/client/main.lua index 0396dea4..ac07a4fe 100644 --- a/client/main.lua +++ b/client/main.lua @@ -273,12 +273,13 @@ end) RegisterNetEvent('esx:createPickup') AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, name, components, tintIndex) local playerPed = GetPlayerPed(GetPlayerFromServerId(playerId)) - local entityCoords, forward, pickupObject = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) - local objectCoords = (entityCoords + forward * 1.0) + local entityCoords, forwardVector, pickupObject = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) + local objectCoords = (entityCoords + forwardVector * 1.0) if type == 'item_weapon' then - ESX.Streaming.RequestWeaponAsset(GetHashKey(name)) - pickupObject = CreateWeaponObject(GetHashKey(name), 50, objectCoords, true, 1.0, 0) + local weaponHash = GetHashKey(name) + ESX.Streaming.RequestWeaponAsset(weaponHash) + pickupObject = CreateWeaponObject(weaponHash, 50, objectCoords, true, 1.0, 0) SetWeaponObjectTintIndex(pickupObject, tintIndex) for k,v in ipairs(components) do @@ -301,7 +302,6 @@ AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, na SetEntityCollision(pickupObject, false, true) pickups[pickupId] = { - id = pickupId, obj = pickupObject, label = label, inRange = false, @@ -339,7 +339,6 @@ AddEventHandler('esx:createMissingPickups', function(missingPickups) SetEntityCollision(pickupObject, false, true) pickups[pickupId] = { - id = pickupId, obj = pickupObject, label = pickup.label, inRange = false, @@ -358,10 +357,10 @@ AddEventHandler('esx:registerSuggestions', function(registeredCommands) end) RegisterNetEvent('esx:removePickup') -AddEventHandler('esx:removePickup', function(id) - if pickups[id] and pickups[id].obj then - ESX.Game.DeleteObject(pickups[id].obj) - pickups[id] = nil +AddEventHandler('esx:removePickup', function(pickupId) + if pickups[pickupId] and pickups[pickupId].obj then + ESX.Game.DeleteObject(pickups[pickupId].obj) + pickups[pickupId] = nil end end) @@ -480,24 +479,24 @@ Citizen.CreateThread(function() local playerCoords, letSleep = GetEntityCoords(playerPed), true local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - for k,v in pairs(pickups) do - local distance = #(playerCoords - v.coords) + for pickupId,pickup in pairs(pickups) do + local distance = #(playerCoords - pickup.coords) if distance < 5 then - local label = v.label + local label = pickup.label letSleep = false if distance < 1 then if IsControlJustReleased(0, 38) then - if IsPedOnFoot(playerPed) and (closestDistance == -1 or closestDistance > 3) and not v.inRange then - v.inRange = true + if IsPedOnFoot(playerPed) and (closestDistance == -1 or closestDistance > 3) and not pickup.inRange then + pickup.inRange = true local dict, anim = 'weapons@first_person@aim_rng@generic@projectile@sticky_bomb@', 'plant_floor' ESX.Streaming.RequestAnimDict(dict) TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) Citizen.Wait(1000) - TriggerServerEvent('esx:onPickup', v.id) + TriggerServerEvent('esx:onPickup', pickupId) PlaySoundFrontend(-1, 'PICK_UP', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) end end @@ -506,12 +505,12 @@ Citizen.CreateThread(function() end ESX.Game.Utils.DrawText3D({ - x = v.coords.x, - y = v.coords.y, - z = v.coords.z + 0.25 + x = pickup.coords.x, + y = pickup.coords.y, + z = pickup.coords.z + 0.25 }, label, 1.2, 1) - elseif v.inRange then - v.inRange = false + elseif pickup.inRange then + pickup.inRange = false end end diff --git a/server/main.lua b/server/main.lua index ce395123..5992cfe6 100644 --- a/server/main.lua +++ b/server/main.lua @@ -420,8 +420,8 @@ AddEventHandler('esx:useItem', function(itemName) end) RegisterNetEvent('esx:onPickup') -AddEventHandler('esx:onPickup', function(id) - local pickup, xPlayer, success = ESX.Pickups[id], ESX.GetPlayerFromId(source) +AddEventHandler('esx:onPickup', function(pickupId) + local pickup, xPlayer, success = ESX.Pickups[pickupId], ESX.GetPlayerFromId(source) if pickup then if pickup.type == 'item_standard' then @@ -449,8 +449,8 @@ AddEventHandler('esx:onPickup', function(id) end if success then - ESX.Pickups[id] = nil - TriggerClientEvent('esx:removePickup', -1, id) + ESX.Pickups[pickupId] = nil + TriggerClientEvent('esx:removePickup', -1, pickupId) end end end) From d707b6049355554e03aaf6e5f165a29090d73049 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 12 Apr 2020 18:11:35 +0200 Subject: [PATCH 475/672] Added timeout on HasCollisionLoadedAroundEntity() --- client/functions.lua | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 26bc233b..87292a48 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -304,9 +304,12 @@ end ESX.Game.Teleport = function(entity, coords, cb) if DoesEntityExist(entity) then RequestCollisionAtCoord(coords.x, coords.y, coords.z) + local timeout = 0 - while not HasCollisionLoadedAroundEntity(entity) do + -- we can get stuck here if any of the axies are "invalid" + while not HasCollisionLoadedAroundEntity(entity) and timeout < 2000 do Citizen.Wait(0) + timeout = timeout + 1 end SetEntityCoords(entity, coords.x, coords.y, coords.z, false, false, false, false) @@ -366,22 +369,23 @@ ESX.Game.SpawnVehicle = function(modelName, coords, heading, cb) ESX.Streaming.RequestModel(model) local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, false) - local id = NetworkGetNetworkIdFromEntity(vehicle) + local networkId = NetworkGetNetworkIdFromEntity(vehicle) + local timeout = 0 - SetNetworkIdCanMigrate(id, true) + SetNetworkIdCanMigrate(networkId, true) SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleNeedsToBeHotwired(vehicle, false) + SetVehRadioStation(vehicle, 'OFF') SetModelAsNoLongerNeeded(model) - RequestCollisionAtCoord(coords.x, coords.y, coords.z) - while not HasCollisionLoadedAroundEntity(vehicle) do + -- we can get stuck here if any of the axies are "invalid" + while not HasCollisionLoadedAroundEntity(vehicle) and timeout < 2000 do Citizen.Wait(0) + timeout = timeout + 1 end - SetVehRadioStation(vehicle, 'OFF') - if cb then cb(vehicle) end @@ -395,19 +399,21 @@ ESX.Game.SpawnLocalVehicle = function(modelName, coords, heading, cb) ESX.Streaming.RequestModel(model) local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, heading, false, false) + local timeout = 0 SetEntityAsMissionEntity(vehicle, true, false) SetVehicleHasBeenOwnedByPlayer(vehicle, true) SetVehicleNeedsToBeHotwired(vehicle, false) + SetVehRadioStation(vehicle, 'OFF') SetModelAsNoLongerNeeded(model) RequestCollisionAtCoord(coords.x, coords.y, coords.z) - while not HasCollisionLoadedAroundEntity(vehicle) do + -- we can get stuck here if any of the axies are "invalid" + while not HasCollisionLoadedAroundEntity(vehicle) and timeout < 2000 do Citizen.Wait(0) + timeout = timeout + 1 end - SetVehRadioStation(vehicle, 'OFF') - if cb then cb(vehicle) end From 2b58041abbcc64d177219375d74dad98572661e1 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 13 Apr 2020 16:33:00 +0200 Subject: [PATCH 476/672] Added default map name & game type Co-Authored-By: Thuan Truong --- server/common.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/server/common.lua b/server/common.lua index 4921c75c..0acd1c9b 100644 --- a/server/common.lua +++ b/server/common.lua @@ -19,6 +19,9 @@ function getSharedObject() end MySQL.ready(function() + SetMapName('San Andreas') + SetGameType('Roleplay') + MySQL.Async.fetchAll('SELECT * FROM items', {}, function(result) for k,v in ipairs(result) do ESX.Items[v.name] = { From 238bcae7c0a251f134a6cf15b521d995a694d6e8 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 13 Apr 2020 17:50:20 +0200 Subject: [PATCH 477/672] Stop incompatible resources (see description) Automaticly stop resources that - a) not compatible with ESX, for example spawnmanager - b) does the same as esx does, but what esx probably does better --- config.lua | 14 ++++++++++++++ server/common.lua | 3 --- server/main.lua | 31 ++++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/config.lua b/config.lua index fc28850e..888f7e65 100644 --- a/config.lua +++ b/config.lua @@ -18,3 +18,17 @@ Config.MaxWeight = 24 -- the max inventory weight without backpack Config.PaycheckInterval = 7 * 60000 -- how often to recieve pay checks in milliseconds Config.EnableDebug = false + +Config.IncompatibleResourcesToStop = { + ['essentialmode'] = 'ES for short, the performance heavy RP framework no one uses - and source for the random unwanted ZAP ads you\'re seeing', + ['es_admin2'] = 'Adminstration tool for the ancient ES framework that wont work with ESX', + ['esplugin_mysql'] = 'MySQL "plugin" for the ancient ES framework that has a SQL injection vulnerability', + ['es_ui'] = 'Money HUD for ES', + ['spawnmanager'] = 'Default resource that takes care of spawning players, ESX does this already', + ['mapmanager'] = 'Default resource that was required by spawnmanager, but neither are used', + ['basic-gamemode'] = 'Resource that is solely for choosing the default game type', + ['fivem'] = 'Resource that is solely for choosing the default game type', + ['fivem-map-hipster'] = 'Default spawn locations for mapmanager', + ['fivem-map-skater'] = 'Default spawn locations for mapmanager', + ['baseevents'] = 'Default resource for handling death events, ESX does this already' +} diff --git a/server/common.lua b/server/common.lua index 0acd1c9b..4921c75c 100644 --- a/server/common.lua +++ b/server/common.lua @@ -19,9 +19,6 @@ function getSharedObject() end MySQL.ready(function() - SetMapName('San Andreas') - SetGameType('Roleplay') - MySQL.Async.fetchAll('SELECT * FROM items', {}, function(result) for k,v in ipairs(result) do ESX.Items[v.name] = { diff --git a/server/main.lua b/server/main.lua index 5992cfe6..ea069af0 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,3 +1,32 @@ +Citizen.CreateThread(function() + SetMapName('San Andreas') + SetGameType('Roleplay') + local resourcesStopped = {} + + for resourceName,reason in pairs(Config.IncompatibleResourcesToStop) do + local status = GetResourceState(resourceName) + + if status == 'started' or status == 'starting' then + while status == 'starting' do + Citizen.Wait(100) + end + + StopResource(resourceName) + resourcesStopped[resourceName] = reason + end + end + + if ESX.Table.SizeOf(resourcesStopped) > 0 then + local allStoppedResources = '' + + for resourceName,reason in pairs(resourcesStopped) do + allStoppedResources = ('%s\n- ^3%s^7, %s'):format(allStoppedResources, resourceName, reason) + end + + print(('[es_extended] [^3WARNING^7] Stopped %s incompatible resource(s) that can cause issues when used with ESX. They are not needed and can safely be removed from your server, remove these resource(s) from your resource directory and your configuration file:%s'):format(ESX.Table.SizeOf(resourcesStopped), allStoppedResources)) + end +end) + RegisterNetEvent('esx:onPlayerJoined') AddEventHandler('esx:onPlayerJoined', function() if not ESX.Players[source] then @@ -216,7 +245,7 @@ function loadESXPlayer(identifier, playerId) inventory = xPlayer.getInventory(), job = xPlayer.getJob(), loadout = xPlayer.getLoadout(), - maxWeight = xPlayer.maxWeight, + maxWeight = xPlayer.getMaxWeight(), money = xPlayer.getMoney() }) From 71e24f0a723e6192dfbed765221efb61046ac025 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 13 Apr 2020 19:02:56 +0200 Subject: [PATCH 478/672] Fixed while statement --- server/main.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index ea069af0..651d5c57 100644 --- a/server/main.lua +++ b/server/main.lua @@ -7,7 +7,7 @@ Citizen.CreateThread(function() local status = GetResourceState(resourceName) if status == 'started' or status == 'starting' then - while status == 'starting' do + while GetResourceState(resourceName) == 'starting' do Citizen.Wait(100) end From 779afff503b9774a96f0a35a1a63a0ebad34bc56 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 10:23:55 +0200 Subject: [PATCH 479/672] Fixed typos in locales, closes #658 --- client/functions.lua | 2 +- client/main.lua | 2 +- locales/cs.lua | 156 +++++++++++++++++++++---------------------- locales/en.lua | 6 +- locales/fi.lua | 4 +- locales/sc.lua | 2 +- locales/sv.lua | 2 +- locales/tc.lua | 2 +- 8 files changed, 88 insertions(+), 88 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 87292a48..a15a7812 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -205,7 +205,7 @@ ESX.UI.Menu.Open = function(type, namespace, name, data, submit, cancel, change, menu.setElement = function(i, key, val) menu.data.elements[i][key] = val end - + menu.setElements = function(newElements) menu.data.elements = newElements end diff --git a/client/main.lua b/client/main.lua index ac07a4fe..cbfe984d 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,4 +1,4 @@ -local isLoadoutLoaded, isPaused, isDead, isFirstSpawn, pickups = false, false, false, true, {} +local isLoadoutLoaded, isPaused, isDead, pickups = false, false, false, {} Citizen.CreateThread(function() while true do diff --git a/locales/cs.lua b/locales/cs.lua index 10c1d3a0..27963467 100644 --- a/locales/cs.lua +++ b/locales/cs.lua @@ -38,20 +38,20 @@ Locales['cs'] = { ['threw_pickup_prompt'] = 'stiskni ~y~E~s~ po zvednuti', -- Key mapping - ['keymap_showinventory'] = 'zobrazit inventar', + ['keymap_showinventory'] = 'zobrazit inventar', - -- Salary related - ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', - ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', - ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', - ['received_paycheck'] = 'obdržena výplata', - ['bank'] = 'bankovní účet', - ['account_bank'] = 'banka', - ['account_black_money'] = 'spinave penize', - ['account_money'] = 'kapesne', + -- Salary related + ['received_salary'] = 'obdrželi jste výplatu: ~g~$%s~s~', + ['received_help'] = 'obdrželi jste sociální dávku: ~g~$%s~s~', + ['company_nomoney'] = 'společnost u které jste zaměstananí nemá peníze na váš plat', + ['received_paycheck'] = 'obdržena výplata', + ['bank'] = 'bankovní účet', + ['account_bank'] = 'banka', + ['account_black_money'] = 'spinave penize', + ['account_money'] = 'kapesne', - ['act_imp'] = 'akce není možná', - ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', + ['act_imp'] = 'akce není možná', + ['in_vehicle'] = 'nemůže nic dát osobě ve vozidle', -- Commands ['command_car'] = 'spawn an vehicle', @@ -102,71 +102,71 @@ Locales['cs'] = { ['commandgeneric_playerid'] = 'player id', -- Locale settings - ['locale_digit_grouping_symbol'] = ' ', - ['locale_currency'] = '$%s', + ['locale_digit_grouping_symbol'] = ' ', + ['locale_currency'] = '$%s', - -- Weapons - ['weapon_knife'] = 'nuz', - ['weapon_nightstick'] = 'policejni obusek', - ['weapon_hammer'] = 'kladivo', - ['weapon_bat'] = 'basseballka', - ['weapon_golfclub'] = 'gollfova hul', - ['weapon_crowbar'] = 'pacidlo', - ['weapon_pistol'] = 'pistole', - ['weapon_combatpistol'] = 'utocna pistole', - ['weapon_appistol'] = 'ap pistole', - ['weapon_pistol50'] = 'pistole .50', - ['weapon_microsmg'] = 'micro smg', - ['weapon_smg'] = 'smg', - ['weapon_assaultsmg'] = 'utocne smg', - ['weapon_assaultrifle'] = 'utocna puska', - ['weapon_carbinerifle'] = 'carbine puska', - ['weapon_advancedrifle'] = 'pokrocily puska', - ['weapon_mg'] = 'mg', - ['weapon_combatmg'] = 'utocne mg', - ['weapon_pumpshotgun'] = 'pumpovana brokovnice', - ['weapon_sawnoffshotgun'] = 'upilovana brokovnice', - ['weapon_assaultshotgun'] = 'utocna brokovnice', - ['weapon_bullpupshotgun'] = 'bullpup brokovnice', - ['weapon_stungun'] = 'tazer', - ['weapon_sniperrifle'] = 'sniperka', - ['weapon_heavysniper'] = 'tezka sniperka', - ['weapon_grenadelauncher'] = 'launcher granatu', - ['weapon_rpg'] = 'raketomet', - ['weapon_minigun'] = 'minigun', - ['weapon_grenade'] = 'granat', - ['weapon_stickybomb'] = 'lepkava bomba', - ['weapon_smokegrenade'] = 'kourovy granat', - ['weapon_bzgas'] = 'bz gas', - ['weapon_molotov'] = 'molotov koktejl', - ['weapon_fireextinguisher'] = 'hasicak', - ['weapon_petrolcan'] = 'kanystr', - ['weapon_ball'] = 'koule', - ['weapon_snspistol'] = 'sns pistole', - ['weapon_bottle'] = 'lahev', - ['weapon_gusenberg'] = 'gusenberguv zametac', - ['weapon_specialcarbine'] = 'specialni karabina', - ['weapon_heavypistol'] = 'tezka pistole', - ['weapon_bullpuprifle'] = 'bullpup puska', - ['weapon_dagger'] = 'dyka', - ['weapon_vintagepistol'] = 'velmi stara pistole', - ['weapon_firework'] = 'ohnostroj', - ['weapon_musket'] = 'musketa', - ['weapon_heavyshotgun'] = 'tezka brokovnice', - ['weapon_marksmanrifle'] = 'puska strelce', - ['weapon_hominglauncher'] = 'navadeci launcher', - ['weapon_proxmine'] = 'mina na blizko', - ['weapon_snowball'] = 'snehova koule', - ['weapon_flaregun'] = 'svetlice', - ['weapon_combatpdw'] = 'utocne pdw', - ['weapon_marksmanpistol'] = 'pistole strelce', - ['weapon_knuckle'] = 'knuckledusters', - ['weapon_hatchet'] = 'sekerka', - ['weapon_railgun'] = 'vlakovy launcher', - ['weapon_machete'] = 'maceta', - ['weapon_machinepistol'] = 'kulomet', - ['weapon_switchblade'] = 'vystrelovaci nuz', - ['weapon_revolver'] = 'tezky revolver', + -- Weapons + ['weapon_knife'] = 'nuz', + ['weapon_nightstick'] = 'policejni obusek', + ['weapon_hammer'] = 'kladivo', + ['weapon_bat'] = 'basseballka', + ['weapon_golfclub'] = 'gollfova hul', + ['weapon_crowbar'] = 'pacidlo', + ['weapon_pistol'] = 'pistole', + ['weapon_combatpistol'] = 'utocna pistole', + ['weapon_appistol'] = 'ap pistole', + ['weapon_pistol50'] = 'pistole .50', + ['weapon_microsmg'] = 'micro smg', + ['weapon_smg'] = 'smg', + ['weapon_assaultsmg'] = 'utocne smg', + ['weapon_assaultrifle'] = 'utocna puska', + ['weapon_carbinerifle'] = 'carbine puska', + ['weapon_advancedrifle'] = 'pokrocily puska', + ['weapon_mg'] = 'mg', + ['weapon_combatmg'] = 'utocne mg', + ['weapon_pumpshotgun'] = 'pumpovana brokovnice', + ['weapon_sawnoffshotgun'] = 'upilovana brokovnice', + ['weapon_assaultshotgun'] = 'utocna brokovnice', + ['weapon_bullpupshotgun'] = 'bullpup brokovnice', + ['weapon_stungun'] = 'tazer', + ['weapon_sniperrifle'] = 'sniperka', + ['weapon_heavysniper'] = 'tezka sniperka', + ['weapon_grenadelauncher'] = 'launcher granatu', + ['weapon_rpg'] = 'raketomet', + ['weapon_minigun'] = 'minigun', + ['weapon_grenade'] = 'granat', + ['weapon_stickybomb'] = 'lepkava bomba', + ['weapon_smokegrenade'] = 'kourovy granat', + ['weapon_bzgas'] = 'bz gas', + ['weapon_molotov'] = 'molotov koktejl', + ['weapon_fireextinguisher'] = 'hasicak', + ['weapon_petrolcan'] = 'kanystr', + ['weapon_ball'] = 'koule', + ['weapon_snspistol'] = 'sns pistole', + ['weapon_bottle'] = 'lahev', + ['weapon_gusenberg'] = 'gusenberguv zametac', + ['weapon_specialcarbine'] = 'specialni karabina', + ['weapon_heavypistol'] = 'tezka pistole', + ['weapon_bullpuprifle'] = 'bullpup puska', + ['weapon_dagger'] = 'dyka', + ['weapon_vintagepistol'] = 'velmi stara pistole', + ['weapon_firework'] = 'ohnostroj', + ['weapon_musket'] = 'musketa', + ['weapon_heavyshotgun'] = 'tezka brokovnice', + ['weapon_marksmanrifle'] = 'puska strelce', + ['weapon_hominglauncher'] = 'navadeci launcher', + ['weapon_proxmine'] = 'mina na blizko', + ['weapon_snowball'] = 'snehova koule', + ['weapon_flaregun'] = 'svetlice', + ['weapon_combatpdw'] = 'utocne pdw', + ['weapon_marksmanpistol'] = 'pistole strelce', + ['weapon_knuckle'] = 'knuckledusters', + ['weapon_hatchet'] = 'sekerka', + ['weapon_railgun'] = 'vlakovy launcher', + ['weapon_machete'] = 'maceta', + ['weapon_machinepistol'] = 'kulomet', + ['weapon_switchblade'] = 'vystrelovaci nuz', + ['weapon_revolver'] = 'tezky revolver', ['weapon_dbshotgun'] = 'dvouhlavnova brokovnice', ['weapon_compactrifle'] = 'kompaktni puska', ['weapon_autoshotgun'] = 'automaticka brokovnice', @@ -176,7 +176,7 @@ Locales['cs'] = { ['weapon_pipebomb'] = 'dymkova bomba', ['weapon_poolcue'] = 'kulecnikove tago', ['weapon_wrench'] = 'klic na trubky', - ['weapon_flashlight'] = 'baterka', + ['weapon_flashlight'] = 'baterka', ['gadget_parachute'] = 'padak', ['weapon_flare'] = 'svetlice', ['weapon_doubleaction'] = 'dvojhlavnovy revolver', @@ -193,7 +193,7 @@ Locales['cs'] = { ['component_grip'] = 'rukojet', ['component_luxary_finish'] = 'luxusni vzhled zbrane', - -- Weapon Ammo + -- Weapon Ammo ['ammo_rounds'] = 'naboj(e)', ['ammo_shells'] = 'patrona(y)', ['ammo_charge'] = 'naboj(e)', diff --git a/locales/en.lua b/locales/en.lua index a5ec7122..7dea0545 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -178,12 +178,12 @@ Locales['en'] = { ['weapon_wrench'] = 'pipe wrench', ['weapon_flashlight'] = 'flashlight', ['gadget_parachute'] = 'parachute', - ['weapon_flare'] = 'flare gun', + ['weapon_flare'] = 'flare', ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', + ['component_clip_default'] = 'default Clip', + ['component_clip_extended'] = 'extended Clip', ['component_clip_drum'] = 'drum Magazine', ['component_clip_box'] = 'box Magazine', ['component_flashlight'] = 'flashlight', diff --git a/locales/fi.lua b/locales/fi.lua index 034aebd3..e69271b8 100644 --- a/locales/fi.lua +++ b/locales/fi.lua @@ -182,8 +182,8 @@ Locales['fi'] = { ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components - ['component_clip_default'] = 'default Grip', - ['component_clip_extended'] = 'extended Grip', + ['component_clip_default'] = 'default Clip', + ['component_clip_extended'] = 'extended Clip', ['component_clip_drum'] = 'drum Magazine', ['component_clip_box'] = 'box Magazine', ['component_flashlight'] = 'flashlight', diff --git a/locales/sc.lua b/locales/sc.lua index 050637e2..cfe39ae2 100644 --- a/locales/sc.lua +++ b/locales/sc.lua @@ -49,7 +49,7 @@ Locales['sc'] = { ['account_bank'] = '银行', ['account_black_money'] = '黑钱', ['account_money'] = '现金', - + ['act_imp'] = '操作失败', ['in_vehicle'] = '请离开载具', diff --git a/locales/sv.lua b/locales/sv.lua index 5cb32c29..25c682f0 100644 --- a/locales/sv.lua +++ b/locales/sv.lua @@ -178,7 +178,7 @@ Locales['sv'] = { ['weapon_wrench'] = 'skiftnyckel', ['weapon_flashlight'] = 'ficklampa', ['gadget_parachute'] = 'fallskärm', - ['weapon_flare'] = 'signalpistol', + ['weapon_flare'] = 'blossa', ['weapon_doubleaction'] = 'double-Action Revolver', -- Weapon Components diff --git a/locales/tc.lua b/locales/tc.lua index c0b1e31c..9e31c8db 100644 --- a/locales/tc.lua +++ b/locales/tc.lua @@ -49,7 +49,7 @@ Locales['tc'] = { ['account_bank'] = '銀行', ['account_black_money'] = '黑錢', ['account_money'] = '現金', - + ['act_imp'] = '操作失敗', ['in_vehicle'] = '請離開載具', From 26ac44b35bdfcad0f28b920a7d41f50560d65377 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 10:29:30 +0200 Subject: [PATCH 480/672] Hopefully fixed #633 --- client/functions.lua | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index a15a7812..a4070355 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1001,7 +1001,7 @@ ESX.ShowInventory = function() if playersNearby[selectedPlayer] then local selectedPlayerPed = GetPlayerPed(selectedPlayer) - if IsPedOnFoot(selectedPlayerPed) then + if IsPedOnFoot(selectedPlayerPed) and not IsPedFalling(selectedPlayerPed) then if type == 'item_weapon' then TriggerServerEvent('esx:giveInventoryItem', selectedPlayerId, type, item, nil) menu2.close() @@ -1039,7 +1039,7 @@ ESX.ShowInventory = function() ESX.ShowNotification(_U('players_nearby')) end elseif data1.current.action == 'remove' then - if IsPedOnFoot(playerPed) then + if IsPedOnFoot(playerPed) and not IsPedFalling(playerPed) then local dict, anim = 'weapons@first_person@aim_rng@generic@projectile@sticky_bomb@', 'plant_floor' ESX.Streaming.RequestAnimDict(dict) @@ -1075,10 +1075,9 @@ ESX.ShowInventory = function() ESX.ShowInventory() elseif data1.current.action == 'give_ammo' then local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() - local closestPed = GetPlayerPed(closestPlayer) local pedAmmo = GetAmmoInPedWeapon(playerPed, GetHashKey(item)) - if IsPedOnFoot(closestPed) then + if IsPedOnFoot(closestPed) and not IsPedFalling(closestPed) then if closestPlayer ~= -1 and closestDistance < 3.0 then if pedAmmo > 0 then ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_give', { From e772031094a3615f23f278b5fca00030f6ccf140 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 10:42:03 +0200 Subject: [PATCH 481/672] Fixed some cases of shadowing upvalue --- client/functions.lua | 9 +++++---- client/main.lua | 6 +++--- server/functions.lua | 8 ++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index a4070355..177bf7f5 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -944,7 +944,7 @@ ESX.ShowInventory = function() }, function(data, menu) menu.close() local player, distance = ESX.Game.GetClosestPlayer() - local elements = {} + elements = {} if data.current.usable then table.insert(elements, {label = _U('use'), action = 'use', type = data.current.type, value = data.current.value}) @@ -975,10 +975,11 @@ ESX.ShowInventory = function() local playersNearby = ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0) if #playersNearby > 0 then - local players, elements = {}, {} + local players = {} + elements = {} - for k,player in ipairs(playersNearby) do - players[GetPlayerServerId(player)] = true + for k,playerNearby in ipairs(playersNearby) do + players[GetPlayerServerId(playerNearby)] = true end ESX.TriggerServerCallback('esx:getPlayerNames', function(returnedPlayers) diff --git a/client/main.lua b/client/main.lua index cbfe984d..e66cce33 100644 --- a/client/main.lua +++ b/client/main.lua @@ -255,8 +255,8 @@ AddEventHandler('esx:setJob', function(job) end) RegisterNetEvent('esx:spawnVehicle') -AddEventHandler('esx:spawnVehicle', function(vehicle) - local model = (type(vehicle) == 'number' and vehicle or GetHashKey(vehicle)) +AddEventHandler('esx:spawnVehicle', function(vehicleName) + local model = (type(vehicleName) == 'number' and vehicleName or GetHashKey(vehicleName)) if IsModelInCdimage(model) then local playerPed = PlayerPedId() @@ -266,7 +266,7 @@ AddEventHandler('esx:spawnVehicle', function(vehicle) TaskWarpPedIntoVehicle(playerPed, vehicle, -1) end) else - TriggerEvent('chat:addMessage', { args = { '^1SYSTEM', 'Invalid vehicle model.' } }) + TriggerEvent('chat:addMessage', {args = {'^1SYSTEM', 'Invalid vehicle model.'}}) end end) diff --git a/server/functions.lua b/server/functions.lua index 601f27f0..5038c059 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -166,7 +166,7 @@ end ESX.SavePlayer = function(xPlayer, cb) local asyncTasks = {} - table.insert(asyncTasks, function(cb) + table.insert(asyncTasks, function(cb2) MySQL.Async.execute('UPDATE users SET accounts = @accounts, job = @job, job_grade = @job_grade, `group` = @group, loadout = @loadout, position = @position, inventory = @inventory WHERE identifier = @identifier', { ['@accounts'] = json.encode(xPlayer.getAccounts(true)), ['@job'] = xPlayer.job.name, @@ -177,7 +177,7 @@ ESX.SavePlayer = function(xPlayer, cb) ['@identifier'] = xPlayer.getIdentifier(), ['@inventory'] = json.encode(xPlayer.getInventory(true)) }, function(rowsChanged) - cb() + cb2() end) end) @@ -194,9 +194,9 @@ ESX.SavePlayers = function(cb) local xPlayers, asyncTasks = ESX.GetPlayers(), {} for i=1, #xPlayers, 1 do - table.insert(asyncTasks, function(cb) + table.insert(asyncTasks, function(cb2) local xPlayer = ESX.GetPlayerFromId(xPlayers[i]) - ESX.SavePlayer(xPlayer, cb) + ESX.SavePlayer(xPlayer, cb2) end) end From 55627129756a5a2dcd3cd2038cb8faa765019ce2 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 13:08:10 +0200 Subject: [PATCH 482/672] =?UTF-8?q?=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8FBRE?= =?UTF-8?q?AKING=20COMMIT=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8F:=20Merged=20?= =?UTF-8?q?dupe=20client=20functions=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes arguments on the following functions: - ESX.Game.GetClosestObject() - ESX.Game.GetPeds(), no more arg for ignoreList - ESX.Game.GetClosestPed(), no longer a ignore list, instead a whitelist --- client/entityiter.lua | 6 +- client/functions.lua | 201 +++++------------------------------------- 2 files changed, 26 insertions(+), 181 deletions(-) diff --git a/client/entityiter.lua b/client/entityiter.lua index 20dd2018..c2e87406 100644 --- a/client/entityiter.lua +++ b/client/entityiter.lua @@ -45,11 +45,11 @@ local function EnumerateEntities(initFunc, moveFunc, disposeFunc) local enum = {handle = iter, destructor = disposeFunc} setmetatable(enum, entityEnumerator) - local next = true + repeat - coroutine.yield(id) - next, id = moveFunc(iter) + coroutine.yield(id) + next, id = moveFunc(iter) until not next enum.destructor, enum.handle = nil, nil diff --git a/client/functions.lua b/client/functions.lua index 177bf7f5..814a8c39 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -427,63 +427,9 @@ ESX.Game.IsVehicleEmpty = function(vehicle) return passengers == 0 and driverSeatFree end -ESX.Game.GetObjects = function() - local objects = {} - - for object in EnumerateObjects() do - table.insert(objects, object) - end - - return objects -end - -ESX.Game.GetClosestObject = function(filter, coords) - local objects = ESX.Game.GetObjects() - local closestDistance, closestObject = -1, -1 - local filter, coords = filter, coords - - if type(filter) == 'string' then - if filter ~= '' then - filter = {filter} - end - end - - if coords then - coords = vector3(coords.x, coords.y, coords.z) - else - local playerPed = PlayerPedId() - coords = GetEntityCoords(playerPed) - end - - for i=1, #objects, 1 do - local foundObject = false - - if filter == nil or (type(filter) == 'table' and #filter == 0) then - foundObject = true - else - local objectModel = GetEntityModel(objects[i]) - - for j=1, #filter, 1 do - if objectModel == GetHashKey(filter[j]) then - foundObject = true - break - end - end - end - - if foundObject then - local objectCoords = GetEntityCoords(objects[i]) - local distance = #(objectCoords - coords) - - if closestDistance == -1 or closestDistance > distance then - closestObject = objects[i] - closestDistance = distance - end - end - end - - return closestObject, closestDistance -end +ESX.Game.GetObjects = function() return EnumerateObjects() end +ESX.Game.GetPeds = function() return EnumeratePeds() end +ESX.Game.GetVehicles = function() return EnumerateVehicles() end ESX.Game.GetPlayers = function() local players = {} @@ -499,64 +445,16 @@ ESX.Game.GetPlayers = function() return players end -ESX.Game.GetClosestPlayer = function(coords) - local players, closestDistance, closestPlayer = ESX.Game.GetPlayers(), -1, -1 - local coords, usePlayerPed = coords, false - local playerPed, playerId = PlayerPedId(), PlayerId() +ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumerateObjects(), coords, modelFilter) end +ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumeratePeds(), coords, modelFilter) end +ESX.Game.GetClosestPlayer = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(), coords, modelFilter) end +ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumerateVehicles(), coords, modelFilter) end +ESX.Game.GetPlayersInArea = function(coords, area) return enumerateInArea(ESX.Game.GetPlayers(), coords, area) end +ESX.Game.GetVehiclesInArea = function(coords, area) return enumerateInArea(ESX.Game.GetVehicles(), coords, area) end +ESX.Game.IsSpawnPointClear = function(coords, radius) return #ESX.Game.GetVehiclesInArea(coords, radius) == 0 end - if coords then - coords = vector3(coords.x, coords.y, coords.z) - else - usePlayerPed = true - coords = GetEntityCoords(playerPed) - end - - for i=1, #players, 1 do - local target = GetPlayerPed(players[i]) - - if not usePlayerPed or (usePlayerPed and players[i] ~= playerId) then - local targetCoords = GetEntityCoords(target) - local distance = #(coords - targetCoords) - - 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, playersInArea = ESX.Game.GetPlayers(), {} - coords = vector3(coords.x, coords.y, coords.z) - - for i=1, #players, 1 do - local target = GetPlayerPed(players[i]) - local targetCoords = GetEntityCoords(target) - - if #(coords - targetCoords) <= area then - table.insert(playersInArea, players[i]) - end - end - - return playersInArea -end - -ESX.Game.GetVehicles = function() - local vehicles = {} - - for vehicle in EnumerateVehicles() do - table.insert(vehicles, vehicle) - end - - return vehicles -end - -ESX.Game.GetClosestVehicle = function(coords) - local vehicles = ESX.Game.GetVehicles() - local closestDistance, closestVehicle, coords = -1, -1, coords +ESX.Game.GetClosestEntity = function(entities, coords, modelFilter) + local closestEntity, closestEntityDistance, filteredEntities = -1, -1, nil if coords then coords = vector3(coords.x, coords.y, coords.z) @@ -565,32 +463,25 @@ ESX.Game.GetClosestVehicle = function(coords) coords = GetEntityCoords(playerPed) end - for i=1, #vehicles, 1 do - local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = #(coords - vehicleCoords) + if modelFilter then + filteredEntities = {} - if closestDistance == -1 or closestDistance > distance then - closestVehicle, closestDistance = vehicles[i], distance + for k,entity in ipairs(entities) do + if modelFilter[GetEntityModel(entity)] then + table.insert(filteredEntities, entity) + end end end - return closestVehicle, closestDistance -end + for k,entity in ipairs(filteredEntities or entities) do + local distance = #(coords - GetEntityCoords(entity)) -ESX.Game.GetVehiclesInArea = function(coords, area) - local vehicles = ESX.Game.GetVehicles() - local vehiclesInArea = {} - - for i=1, #vehicles, 1 do - local vehicleCoords = GetEntityCoords(vehicles[i]) - local distance = GetDistanceBetweenCoords(vehicleCoords, coords.x, coords.y, coords.z, true) - - if distance <= area then - table.insert(vehiclesInArea, vehicles[i]) + if closestEntityDistance == -1 or distance < closestEntityDistance then + closestEntity, closestEntityDistance = entity, distance end end - return vehiclesInArea + return closestEntity, closestEntityDistance end ESX.Game.GetVehicleInDirection = function() @@ -607,52 +498,6 @@ ESX.Game.GetVehicleInDirection = function() return nil end -ESX.Game.IsSpawnPointClear = function(coords, radius) - local vehicles = ESX.Game.GetVehiclesInArea(coords, radius) - - return #vehicles == 0 -end - -ESX.Game.GetPeds = function(ignoreList) - local ignoreList = ignoreList or {} - local peds = {} - - for ped in EnumeratePeds() do - local found = false - - for j=1, #ignoreList, 1 do - if ignoreList[j] == ped then - found = true - end - end - - if not found then - table.insert(peds, ped) - end - end - - return peds -end - -ESX.Game.GetClosestPed = function(coords, ignoreList) - local ignoreList = ignoreList or {} - local peds = ESX.Game.GetPeds(ignoreList) - local closestDistance = -1 - local closestPed = -1 - - for i=1, #peds, 1 do - local pedCoords = GetEntityCoords(peds[i]) - local distance = GetDistanceBetweenCoords(pedCoords, coords.x, coords.y, coords.z, true) - - if closestDistance == -1 or closestDistance > distance then - closestPed = peds[i] - closestDistance = distance - end - end - - return closestPed, closestDistance -end - ESX.Game.GetVehicleProperties = function(vehicle) if DoesEntityExist(vehicle) then local colorPrimary, colorSecondary = GetVehicleColours(vehicle) From cf7f6b14f41ec4609e320df9fe8deacc9fd2abe6 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 13:25:45 +0200 Subject: [PATCH 483/672] Finished new code, closes #249 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Lén --- client/entityiter.lua | 21 +++++++++++++++++++++ client/functions.lua | 6 +++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/client/entityiter.lua b/client/entityiter.lua index c2e87406..11a23b8f 100644 --- a/client/entityiter.lua +++ b/client/entityiter.lua @@ -57,6 +57,27 @@ local function EnumerateEntities(initFunc, moveFunc, disposeFunc) end) end +function EnumerateEntitiesWithinDistance(entities, coords, maxDistance) + local nearbyEntities = {} + + if coords then + coords = vector3(coords.x, coords.y, coords.z) + else + local playerPed = PlayerPedId() + coords = GetEntityCoords(playerPed) + end + + for k,entity in ipairs(entities) do + local distance = #(coords - GetEntityCoords(entity)) + + if distance <= maxDistance then + table.insert(nearbyEntities, entity) + end + end + + return nearbyEntities +end + function EnumerateObjects() return EnumerateEntities(FindFirstObject, FindNextObject, EndFindObject) end diff --git a/client/functions.lua b/client/functions.lua index 814a8c39..60f497a4 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -449,9 +449,9 @@ ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClo ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumeratePeds(), coords, modelFilter) end ESX.Game.GetClosestPlayer = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(), coords, modelFilter) end ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumerateVehicles(), coords, modelFilter) end -ESX.Game.GetPlayersInArea = function(coords, area) return enumerateInArea(ESX.Game.GetPlayers(), coords, area) end -ESX.Game.GetVehiclesInArea = function(coords, area) return enumerateInArea(ESX.Game.GetVehicles(), coords, area) end -ESX.Game.IsSpawnPointClear = function(coords, radius) return #ESX.Game.GetVehiclesInArea(coords, radius) == 0 end +ESX.Game.GetPlayersInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetPlayers(), coords, maxDistance) end +ESX.Game.GetVehiclesInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(EnumerateVehicles(), coords, maxDistance) end +ESX.Game.IsSpawnPointClear = function(coords, maxDistance) return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0 end ESX.Game.GetClosestEntity = function(entities, coords, modelFilter) local closestEntity, closestEntityDistance, filteredEntities = -1, -1, nil From 6a0f3ca45267b71c84787f3b844d88f2de570c89 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 13:58:40 +0200 Subject: [PATCH 484/672] Fixed untested new code :/ --- client/functions.lua | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index 60f497a4..e3b1e7ad 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -427,9 +427,35 @@ ESX.Game.IsVehicleEmpty = function(vehicle) return passengers == 0 and driverSeatFree end -ESX.Game.GetObjects = function() return EnumerateObjects() end -ESX.Game.GetPeds = function() return EnumeratePeds() end -ESX.Game.GetVehicles = function() return EnumerateVehicles() end +ESX.Game.GetObjects = function() + local objects = {} + + for object,v in EnumerateObjects() do + table.insert(objects, object) + end + + return objects +end + +ESX.Game.GetPeds = function() + local peds = {} + + for ped,v in EnumeratePeds() do + table.insert(peds, ped) + end + + return peds +end + +ESX.Game.GetVehicles = function() + local vehicles = {} + + for vehicle,v in EnumerateVehicles() do + table.insert(vehicles, vehicle) + end + + return vehicles +end ESX.Game.GetPlayers = function() local players = {} @@ -445,12 +471,12 @@ ESX.Game.GetPlayers = function() return players end -ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumerateObjects(), coords, modelFilter) end -ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumeratePeds(), coords, modelFilter) end +ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetObjects(), coords, modelFilter) end +ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPeds(), coords, modelFilter) end ESX.Game.GetClosestPlayer = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(), coords, modelFilter) end -ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(EnumerateVehicles(), coords, modelFilter) end +ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetVehicles(), coords, modelFilter) end ESX.Game.GetPlayersInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetPlayers(), coords, maxDistance) end -ESX.Game.GetVehiclesInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(EnumerateVehicles(), coords, maxDistance) end +ESX.Game.GetVehiclesInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetVehicles(), coords, maxDistance) end ESX.Game.IsSpawnPointClear = function(coords, maxDistance) return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0 end ESX.Game.GetClosestEntity = function(entities, coords, modelFilter) From 5f9fc94c4d429712370960655005d877c7da6358 Mon Sep 17 00:00:00 2001 From: SW1FT Date: Tue, 14 Apr 2020 13:58:34 +0100 Subject: [PATCH 485/672] Fixed English locale typos (#659) * Minor en locale changes * Forgot this one --- locales/en.lua | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/locales/en.lua b/locales/en.lua index 7dea0545..515b0f50 100644 --- a/locales/en.lua +++ b/locales/en.lua @@ -15,13 +15,13 @@ Locales['en'] = { ['gave_weapon'] = 'you gave ~b~%s~s~ to ~y~%s~s~', ['gave_weapon_ammo'] = 'you gave ~o~%sx %s~s~ for ~b~%s~s~ to ~y~%s~s~', ['gave_weapon_withammo'] = 'you gave ~b~%s~s~ with ~o~%sx %s~s~ to ~y~%s~s~', - ['gave_weapon_hasalready'] = '~y~%s~s~ already have an ~y~%s~s~', + ['gave_weapon_hasalready'] = '~y~%s~s~ already has a ~y~%s~s~', ['gave_weapon_noweapon'] = '~y~%s~s~ does not have that weapon', ['received_weapon'] = 'you received ~b~%s~s~ from ~b~%s~s~', ['received_weapon_ammo'] = 'you received ~o~%sx %s~s~ for your ~b~%s~s~ from ~b~%s~s~', ['received_weapon_withammo'] = 'you received ~b~%s~s~ with ~o~%sx %s~s~ from ~b~%s~s~', - ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you an ~y~%s~s~, but you already have one', - ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for an ~y~%s~s~, but you dont have one', + ['received_weapon_hasalready'] = '~b~%s~s~ attempted to give you a ~y~%s~s~, but you already have one', + ['received_weapon_noweapon'] = '~b~%s~s~ attempted to give you ammo for a ~y~%s~s~, but you dont have one', ['gave_account_money'] = 'you gave ~g~$%s~s~ (%s) to ~y~%s~s~', ['received_account_money'] = 'you received ~g~$%s~s~ (%s) from ~b~%s~s~', ['amount_invalid'] = 'invalid amount', @@ -42,7 +42,7 @@ Locales['en'] = { -- Salary related ['received_salary'] = 'you received your salary: ~g~$%s~s~', - ['received_help'] = 'you recieved your welfare check: ~g~$%s~s~', + ['received_help'] = 'you received your welfare check: ~g~$%s~s~', ['company_nomoney'] = 'the company you\'re employeed at is too poor to pay out your salary', ['received_paycheck'] = 'received paycheck', ['bank'] = 'maze Bank', @@ -51,10 +51,10 @@ Locales['en'] = { ['account_money'] = 'cash', ['act_imp'] = 'action impossible', - ['in_vehicle'] = 'you can\'t give anything to someone in a vehicle', + ['in_vehicle'] = 'you cannot give anything to someone in a vehicle', -- Commands - ['command_car'] = 'spawn an vehicle', + ['command_car'] = 'spawn a vehicle', ['command_car_car'] = 'vehicle spawn name or hash', ['command_cardel'] = 'delete vehicle in proximity', ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', @@ -96,8 +96,8 @@ Locales['en'] = { ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', ['commanderror_invaliditem'] = 'invalid item name', ['commanderror_invalidweapon'] = 'invalid weapon', - ['commanderror_console'] = 'that command can not be run from console', - ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', + ['commanderror_console'] = 'that command cannot be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not a valid command!', ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', ['commandgeneric_playerid'] = 'player id', From bd76482caedc6936d8857fbe0b7ca2145e2cfb08 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Tue, 14 Apr 2020 16:45:28 +0200 Subject: [PATCH 486/672] Minor adjustments, changed sql database name --- client/functions.lua | 22 +++++++++++----------- client/main.lua | 2 +- config.lua | 2 +- es_extended.sql | 4 ++-- html/css/app.css | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/client/functions.lua b/client/functions.lua index e3b1e7ad..33ef31a5 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -530,10 +530,10 @@ ESX.Game.GetVehicleProperties = function(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) local extras = {} - for id=0, 12 do - if DoesExtraExist(vehicle, id) then - local state = IsVehicleExtraTurnedOn(vehicle, id) == 1 - extras[tostring(id)] = state + for extraId=0, 12 do + if DoesExtraExist(vehicle, extraId) then + local state = IsVehicleExtraTurnedOn(vehicle, extraId) == 1 + extras[tostring(extraId)] = state end end @@ -651,11 +651,11 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) end if props.extras then - for id,enabled in pairs(props.extras) do + for extraId,enabled in pairs(props.extras) do if enabled then - SetVehicleExtra(vehicle, tonumber(id), 0) + SetVehicleExtra(vehicle, tonumber(extraId), 0) else - SetVehicleExtra(vehicle, tonumber(id), 1) + SetVehicleExtra(vehicle, tonumber(extraId), 1) end end end @@ -884,7 +884,7 @@ ESX.ShowInventory = function() }, function(data3, menu3) local quantity = tonumber(data3.value) - if quantity then + if quantity and quantity > 0 and data.current.count >= quantity then TriggerServerEvent('esx:giveInventoryItem', selectedPlayerId, type, item, quantity) menu3.close() menu2.close() @@ -926,7 +926,7 @@ ESX.ShowInventory = function() }, function(data2, menu2) local quantity = tonumber(data2.value) - if quantity then + if quantity and quantity > 0 and data.current.count >= quantity then menu2.close() menu1.close() TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) @@ -957,8 +957,8 @@ ESX.ShowInventory = function() }, function(data2, menu2) local quantity = tonumber(data2.value) - if quantity then - if pedAmmo >= quantity and quantity > 0 then + if quantity and quantity > 0 then + if pedAmmo >= quantity then TriggerServerEvent('esx:giveInventoryItem', GetPlayerServerId(closestPlayer), 'item_ammo', item, quantity) menu2.close() menu1.close() diff --git a/client/main.lua b/client/main.lua index e66cce33..4d51a8aa 100644 --- a/client/main.lua +++ b/client/main.lua @@ -477,7 +477,7 @@ Citizen.CreateThread(function() Citizen.Wait(0) local playerPed = PlayerPedId() local playerCoords, letSleep = GetEntityCoords(playerPed), true - local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer(playerCoords) for pickupId,pickup in pairs(pickups) do local distance = #(playerCoords - pickup.coords) diff --git a/config.lua b/config.lua index 888f7e65..97217502 100644 --- a/config.lua +++ b/config.lua @@ -1,5 +1,5 @@ Config = {} -Config.Locale = 'fr' +Config.Locale = 'en' Config.Accounts = { bank = _U('account_bank'), diff --git a/es_extended.sql b/es_extended.sql index c01587aa..b36720c6 100644 --- a/es_extended.sql +++ b/es_extended.sql @@ -1,5 +1,5 @@ -CREATE DATABASE IF NOT EXISTS `essentialmode`; -USE `essentialmode`; +CREATE DATABASE IF NOT EXISTS `es_extended`; +USE `es_extended`; CREATE TABLE `users` ( `identifier` VARCHAR(40) NOT NULL, diff --git a/html/css/app.css b/html/css/app.css index bac47fad..b487523f 100644 --- a/html/css/app.css +++ b/html/css/app.css @@ -84,4 +84,4 @@ html { .menu .menu-items .menu-item.selected { background-color: #ccc; -} \ No newline at end of file +} From 17ac9d58468712a56c8f7316bcbb24a8dd99024d Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 15 Apr 2020 20:08:00 +0200 Subject: [PATCH 487/672] Fixed mistakes with fuctions returning lists of players Fixed some ESX functions that are used to get the closests, I forgot that the functions should've returned the player and not the entity handle :/ Also fixed the ESX.Game.GetClosestPed() function just returning your own ped. Thanks @SSNRSS for helping me iron out the problems! Co-Authored-By: Lucas. --- client/entityiter.lua | 6 +++--- client/functions.lua | 48 ++++++++++++++++++++++++------------------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/client/entityiter.lua b/client/entityiter.lua index 11a23b8f..9263aab6 100644 --- a/client/entityiter.lua +++ b/client/entityiter.lua @@ -57,7 +57,7 @@ local function EnumerateEntities(initFunc, moveFunc, disposeFunc) end) end -function EnumerateEntitiesWithinDistance(entities, coords, maxDistance) +function EnumerateEntitiesWithinDistance(entities, isPlayerEntities, coords, maxDistance) local nearbyEntities = {} if coords then @@ -67,11 +67,11 @@ function EnumerateEntitiesWithinDistance(entities, coords, maxDistance) coords = GetEntityCoords(playerPed) end - for k,entity in ipairs(entities) do + for k,entity in pairs(entities) do local distance = #(coords - GetEntityCoords(entity)) if distance <= maxDistance then - table.insert(nearbyEntities, entity) + table.insert(nearbyEntities, isPlayerEntities and k or entity) end end diff --git a/client/functions.lua b/client/functions.lua index 33ef31a5..7ac4387f 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -430,18 +430,20 @@ end ESX.Game.GetObjects = function() local objects = {} - for object,v in EnumerateObjects() do + for object in EnumerateObjects() do table.insert(objects, object) end return objects end -ESX.Game.GetPeds = function() - local peds = {} +ESX.Game.GetPeds = function(onlyOtherPeds) + local peds, myPed = {}, PlayerPedId() - for ped,v in EnumeratePeds() do - table.insert(peds, ped) + for ped in EnumeratePeds() do + if ((onlyOtherPeds and ped ~= myPed) or not onlyOtherPeds) then + table.insert(peds, ped) + end end return peds @@ -450,36 +452,40 @@ end ESX.Game.GetVehicles = function() local vehicles = {} - for vehicle,v in EnumerateVehicles() do + for vehicle in EnumerateVehicles() do table.insert(vehicles, vehicle) end return vehicles end -ESX.Game.GetPlayers = function() - local players = {} +ESX.Game.GetPlayers = function(onlyOtherPlayers, returnKeyValue, returnPeds) + local players, myPlayer = {}, PlayerId() - for _,player in ipairs(GetActivePlayers()) do + for k,player in ipairs(GetActivePlayers()) do local ped = GetPlayerPed(player) - if DoesEntityExist(ped) then - table.insert(players, player) + if DoesEntityExist(ped) and ((onlyOtherPlayers and player ~= myPlayer) or not onlyOtherPlayers) then + if returnKeyValue then + players[player] = ped + else + table.insert(players, returnPeds and ped or player) + end end end return players end -ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetObjects(), coords, modelFilter) end -ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPeds(), coords, modelFilter) end -ESX.Game.GetClosestPlayer = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(), coords, modelFilter) end -ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetVehicles(), coords, modelFilter) end -ESX.Game.GetPlayersInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetPlayers(), coords, maxDistance) end -ESX.Game.GetVehiclesInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetVehicles(), coords, maxDistance) end +ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetObjects(), false, coords, modelFilter) end +ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPeds(true), false, coords, modelFilter) end +ESX.Game.GetClosestPlayer = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(true, true), true, coords, modelFilter) end +ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetVehicles(), false, coords, modelFilter) end +ESX.Game.GetPlayersInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetPlayers(true, true), true, coords, maxDistance) end +ESX.Game.GetVehiclesInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetVehicles(), false, coords, maxDistance) end ESX.Game.IsSpawnPointClear = function(coords, maxDistance) return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0 end -ESX.Game.GetClosestEntity = function(entities, coords, modelFilter) +ESX.Game.GetClosestEntity = function(entities, isPlayerEntities, coords, modelFilter) local closestEntity, closestEntityDistance, filteredEntities = -1, -1, nil if coords then @@ -492,18 +498,18 @@ ESX.Game.GetClosestEntity = function(entities, coords, modelFilter) if modelFilter then filteredEntities = {} - for k,entity in ipairs(entities) do + for k,entity in pairs(entities) do if modelFilter[GetEntityModel(entity)] then table.insert(filteredEntities, entity) end end end - for k,entity in ipairs(filteredEntities or entities) do + for k,entity in pairs(filteredEntities or entities) do local distance = #(coords - GetEntityCoords(entity)) if closestEntityDistance == -1 or distance < closestEntityDistance then - closestEntity, closestEntityDistance = entity, distance + closestEntity, closestEntityDistance = isPlayerEntities and k or entity, distance end end From ab3cf826da3885ea2f41834f254850d88fb3030d Mon Sep 17 00:00:00 2001 From: Lucas <63737942+SSNRSS@users.noreply.github.com> Date: Wed, 15 Apr 2020 20:44:36 +0200 Subject: [PATCH 488/672] Implemented ShowFloatingHelpNotification() (#662) * Implement Floating Text use `ESX.ShowFloatingHelpNotification("lol")` in a loop * Removed beep and broken duration, fixed indent Co-authored-by: Lucas <63737942+SSNIKRS@users.noreply.github.com> Co-authored-by: ElPumpo --- client/functions.lua | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index 7ac4387f..6cba9fe5 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -73,6 +73,14 @@ ESX.ShowHelpNotification = function(msg, thisFrame, beep, duration) end end +ESX.ShowFloatingHelpNotification = function(msg, coords) + AddTextEntry('esxFloatingHelpNotification', msg) + SetFloatingHelpTextWorldPosition(1, coords) + SetFloatingHelpTextStyle(1, 1, 2, -1, 3, 0) + BeginTextCommandDisplayHelp('esxFloatingHelpNotification') + EndTextCommandDisplayHelp(2, false, false, -1) +end + ESX.TriggerServerCallback = function(name, cb, ...) ESX.ServerCallbacks[ESX.CurrentRequestId] = cb From 33e928008ee8e855044d8277593fc7a3cc11bcfa Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Apr 2020 11:53:45 +0200 Subject: [PATCH 489/672] Fixed StopResource() not allowing some resources to be stopped --- server/main.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/main.lua b/server/main.lua index 651d5c57..f37fa6b3 100644 --- a/server/main.lua +++ b/server/main.lua @@ -2,6 +2,7 @@ Citizen.CreateThread(function() SetMapName('San Andreas') SetGameType('Roleplay') local resourcesStopped = {} + ExecuteCommand('add_ace resource.es_extended command.stop allow') for resourceName,reason in pairs(Config.IncompatibleResourcesToStop) do local status = GetResourceState(resourceName) @@ -11,7 +12,7 @@ Citizen.CreateThread(function() Citizen.Wait(100) end - StopResource(resourceName) + ExecuteCommand(('stop %s'):format(resourceName)) resourcesStopped[resourceName] = reason end end From 849da573bf45c64e936719f1145137aec9ca0dd4 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Sun, 19 Apr 2020 11:54:51 +0200 Subject: [PATCH 490/672] Replaced isLoadoutLoaded variable with a function, removed enable pvp configuration --- client/main.lua | 120 ++++++++++++++++++++---------------------------- config.lua | 4 -- 2 files changed, 51 insertions(+), 73 deletions(-) diff --git a/client/main.lua b/client/main.lua index 4d51a8aa..4bc699af 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,4 +1,4 @@ -local isLoadoutLoaded, isPaused, isDead, pickups = false, false, false, {} +local isPaused, isDead, pickups = false, false, {} Citizen.CreateThread(function() while true do @@ -22,7 +22,7 @@ AddEventHandler('esx:playerLoaded', function(playerData) RequestModel(defaultModel) while not HasModelLoaded(defaultModel) do - Citizen.Wait(100) + Citizen.Wait(10) end SetPlayerModel(PlayerId(), defaultModel) @@ -36,10 +36,13 @@ AddEventHandler('esx:playerLoaded', function(playerData) local playerPed = PlayerPedId() - if Config.EnablePvP then - SetCanAttackFriendly(playerPed, true, false) - NetworkSetFriendlyFireOption(true) - end + -- enable PVP + SetCanAttackFriendly(playerPed, true, false) + NetworkSetFriendlyFireOption(true) + + -- disable wanted level + ClearPlayerWantedLevel(PlayerId()) + SetMaxWantedLevel(0) if Config.EnableHud then for k,v in ipairs(playerData.accounts) do @@ -65,7 +68,6 @@ AddEventHandler('esx:playerLoaded', function(playerData) z = playerData.coords.z + 0.5, heading = playerData.coords.heading }, function() - isLoadoutLoaded = true TriggerServerEvent('esx:onPlayerSpawn') TriggerEvent('esx:onPlayerSpawn') TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon @@ -74,6 +76,7 @@ AddEventHandler('esx:playerLoaded', function(playerData) Citizen.Wait(3000) ShutdownLoadingScreen() DoScreenFadeIn(10000) + StartServerSyncLoops() end) end) @@ -82,7 +85,6 @@ AddEventHandler('esx:setMaxWeight', function(newMaxWeight) ESX.PlayerData.maxWei AddEventHandler('esx:onPlayerSpawn', function() isDead = false end) AddEventHandler('esx:onPlayerDeath', function() isDead = true end) -AddEventHandler('skinchanger:loadDefaultModel', function() isLoadoutLoaded = false end) AddEventHandler('skinchanger:modelLoaded', function() while not ESX.PlayerLoaded do @@ -118,8 +120,6 @@ AddEventHandler('esx:restoreLoadout', function() ammoTypes[ammoType] = true end end - - isLoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') @@ -248,7 +248,7 @@ RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) if Config.EnableHud then ESX.UI.HUD.UpdateElement('job', { - job_label = job.label, + job_label = job.label, grade_label = job.grade_label }) end @@ -421,28 +421,52 @@ if Config.EnableHud then end) end --- Keep track of ammo usage -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) +function StartServerSyncLoops() + -- keep track of ammo + Citizen.CreateThread(function() + while true do + Citizen.Wait(0) - if isDead then - Citizen.Wait(500) - else - local playerPed = PlayerPedId() + if isDead then + Citizen.Wait(500) + else + local playerPed = PlayerPedId() - if IsPedShooting(playerPed) then - local _,weaponHash = GetCurrentPedWeapon(playerPed, true) - local weapon = ESX.GetWeaponFromHash(weaponHash) + if IsPedShooting(playerPed) then + local _,weaponHash = GetCurrentPedWeapon(playerPed, true) + local weapon = ESX.GetWeaponFromHash(weaponHash) - if weapon then - local ammoCount = GetAmmoInPedWeapon(playerPed, weaponHash) - TriggerServerEvent('esx:updateWeaponAmmo', weapon.name, ammoCount) + if weapon then + local ammoCount = GetAmmoInPedWeapon(playerPed, weaponHash) + TriggerServerEvent('esx:updateWeaponAmmo', weapon.name, ammoCount) + end end end end - end -end) + end) + + -- sync current player coords with server + Citizen.CreateThread(function() + local previousCoords = vector3(ESX.PlayerData.coords.x, ESX.PlayerData.coords.y, ESX.PlayerData.coords.z) + + while true do + Citizen.Wait(1000) + local playerPed = PlayerPedId() + + if DoesEntityExist(playerPed) then + local playerCoords = GetEntityCoords(playerPed) + local distance = #(playerCoords - previousCoords) + + if distance > 1 then + previousCoords = playerCoords + local playerHeading = ESX.Math.Round(GetEntityHeading(playerPed), 1) + local formattedCoords = {x = ESX.Math.Round(playerCoords.x, 1), y = ESX.Math.Round(playerCoords.y, 1), z = ESX.Math.Round(playerCoords.z, 1), heading = playerHeading} + TriggerServerEvent('esx:updateCoords', formattedCoords) + end + end + end + end) +end Citizen.CreateThread(function() while true do @@ -456,21 +480,6 @@ Citizen.CreateThread(function() 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 @@ -519,30 +528,3 @@ Citizen.CreateThread(function() end end end) - --- Update current player coords -Citizen.CreateThread(function() - -- wait for player to restore coords - while not isLoadoutLoaded do - Citizen.Wait(1000) - end - - local previousCoords = vector3(ESX.PlayerData.coords.x, ESX.PlayerData.coords.y, ESX.PlayerData.coords.z) - - while true do - Citizen.Wait(1000) - local playerPed = PlayerPedId() - - if DoesEntityExist(playerPed) then - local playerCoords = GetEntityCoords(playerPed) - local distance = #(playerCoords - previousCoords) - - if distance > 1 then - previousCoords = playerCoords - local playerHeading = ESX.Math.Round(GetEntityHeading(playerPed), 1) - local formattedCoords = {x = ESX.Math.Round(playerCoords.x, 1), y = ESX.Math.Round(playerCoords.y, 1), z = ESX.Math.Round(playerCoords.z, 1), heading = playerHeading} - TriggerServerEvent('esx:updateCoords', formattedCoords) - end - end - end -end) diff --git a/config.lua b/config.lua index 97217502..8f6134ff 100644 --- a/config.lua +++ b/config.lua @@ -10,13 +10,9 @@ Config.Accounts = { Config.StartingAccountMoney = {bank = 50000} Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society -Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) -Config.EnablePvP = true -- enable pvp? Config.MaxWeight = 24 -- the max inventory weight without backpack - Config.PaycheckInterval = 7 * 60000 -- how often to recieve pay checks in milliseconds - Config.EnableDebug = false Config.IncompatibleResourcesToStop = { From 0647f4e77febba4e71eeb559594cc73ebc9c9b60 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 Apr 2020 11:31:19 +0200 Subject: [PATCH 491/672] Fixed stuck on loading screen, fixed player falling trough world, fixed #678 --- client/main.lua | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/client/main.lua b/client/main.lua index 4bc699af..5c830e30 100644 --- a/client/main.lua +++ b/client/main.lua @@ -26,18 +26,16 @@ AddEventHandler('esx:playerLoaded', function(playerData) end SetPlayerModel(PlayerId(), defaultModel) - local playerPed = PlayerPedId() - - SetPedDefaultComponentVariation(playerPed) - SetPedRandomComponentVariation(playerPed, true) + SetPedDefaultComponentVariation(PlayerPedId()) + SetPedRandomComponentVariation(PlayerPedId(), true) SetModelAsNoLongerNeeded(defaultModel) - FreezeEntityPosition(playerPed, false) end - local playerPed = PlayerPedId() + -- freeze the player + FreezeEntityPosition(PlayerPedId(), true) -- enable PVP - SetCanAttackFriendly(playerPed, true, false) + SetCanAttackFriendly(PlayerPedId(), true, false) NetworkSetFriendlyFireOption(true) -- disable wanted level @@ -62,10 +60,10 @@ AddEventHandler('esx:playerLoaded', function(playerData) }) end - ESX.Game.Teleport(playerPed, { + ESX.Game.Teleport(PlayerPedId(), { x = playerData.coords.x, y = playerData.coords.y, - z = playerData.coords.z + 0.5, + z = playerData.coords.z + 0.25, heading = playerData.coords.heading }, function() TriggerServerEvent('esx:onPlayerSpawn') @@ -75,6 +73,7 @@ AddEventHandler('esx:playerLoaded', function(playerData) Citizen.Wait(3000) ShutdownLoadingScreen() + FreezeEntityPosition(PlayerPedId(), false) DoScreenFadeIn(10000) StartServerSyncLoops() end) @@ -97,7 +96,6 @@ end) AddEventHandler('esx:restoreLoadout', function() local playerPed = PlayerPedId() local ammoTypes = {} - RemoveAllPedWeapons(playerPed, true) for k,v in ipairs(ESX.PlayerData.loadout) do @@ -111,7 +109,6 @@ AddEventHandler('esx:restoreLoadout', function() for k2,v2 in ipairs(v.components) do local componentHash = ESX.GetWeaponComponent(weaponName, v2).hash - GiveWeaponComponentToPed(playerPed, weaponHash, componentHash) end From c375761c6f86b80f46a38bbf78a5bfb5bdb9ab1a Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Mon, 20 Apr 2020 23:57:14 +0200 Subject: [PATCH 492/672] Improved bad pickup code --- client/main.lua | 75 +++++++++++--------------------------------- server/functions.lua | 10 +++--- 2 files changed, 23 insertions(+), 62 deletions(-) diff --git a/client/main.lua b/client/main.lua index 5c830e30..a833c5f4 100644 --- a/client/main.lua +++ b/client/main.lua @@ -268,79 +268,42 @@ AddEventHandler('esx:spawnVehicle', function(vehicleName) end) RegisterNetEvent('esx:createPickup') -AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, name, components, tintIndex) - local playerPed = GetPlayerPed(GetPlayerFromServerId(playerId)) - local entityCoords, forwardVector, pickupObject = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) - local objectCoords = (entityCoords + forwardVector * 1.0) +AddEventHandler('esx:createPickup', function(pickupId, label, coords, type, name, components, tintIndex) + local function setObjectProperties(object) + SetEntityAsMissionEntity(object, true, false) + PlaceObjectOnGroundProperly(object) + FreezeEntityPosition(object, true) + SetEntityCollision(object, false, true) + + pickups[pickupId] = { + obj = object, + label = label, + inRange = false, + coords = vector3(coords.x, coords.y, coords.z) + } + end if type == 'item_weapon' then local weaponHash = GetHashKey(name) ESX.Streaming.RequestWeaponAsset(weaponHash) - pickupObject = CreateWeaponObject(weaponHash, 50, objectCoords, true, 1.0, 0) + local pickupObject = CreateWeaponObject(weaponHash, 50, coords, true, 1.0, 0) SetWeaponObjectTintIndex(pickupObject, tintIndex) for k,v in ipairs(components) do local component = ESX.GetWeaponComponent(name, v) GiveWeaponComponentToWeaponObject(pickupObject, component.hash) end + + setObjectProperties(pickupObject) else - ESX.Game.SpawnLocalObject('prop_money_bag_01', objectCoords, function(obj) - pickupObject = obj - end) - - while not pickupObject do - Citizen.Wait(10) - end + ESX.Game.SpawnLocalObject('prop_money_bag_01', coords, setObjectProperties) end - - SetEntityAsMissionEntity(pickupObject, true, false) - PlaceObjectOnGroundProperly(pickupObject) - FreezeEntityPosition(pickupObject, true) - SetEntityCollision(pickupObject, false, true) - - pickups[pickupId] = { - obj = pickupObject, - label = label, - inRange = false, - coords = objectCoords - } end) RegisterNetEvent('esx:createMissingPickups') AddEventHandler('esx:createMissingPickups', function(missingPickups) for pickupId,pickup in pairs(missingPickups) do - local pickupObject = nil - - if pickup.type == 'item_weapon' then - ESX.Streaming.RequestWeaponAsset(GetHashKey(pickup.name)) - pickupObject = CreateWeaponObject(GetHashKey(pickup.name), 50, pickup.coords.x, pickup.coords.y, pickup.coords.z, true, 1.0, 0) - SetWeaponObjectTintIndex(pickupObject, pickup.tintIndex) - - for k,componentName in ipairs(pickup.components) do - local component = ESX.GetWeaponComponent(pickup.name, componentName) - GiveWeaponComponentToWeaponObject(pickupObject, component.hash) - end - else - ESX.Game.SpawnLocalObject('prop_money_bag_01', pickup.coords, function(obj) - pickupObject = obj - end) - - while not pickupObject do - Citizen.Wait(10) - end - end - - SetEntityAsMissionEntity(pickupObject, true, false) - PlaceObjectOnGroundProperly(pickupObject) - FreezeEntityPosition(pickupObject, true) - SetEntityCollision(pickupObject, false, true) - - pickups[pickupId] = { - obj = pickupObject, - label = pickup.label, - inRange = false, - coords = vector3(pickup.coords.x, pickup.coords.y, pickup.coords.z) - } + TriggerEvent('esx:createPickup', pickupId, pickup.label, pickup.coords, pickup.type, pickup.name, pickup.components, pickup.tintIndex) end end) diff --git a/server/functions.lua b/server/functions.lua index 5038c059..88348110 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -258,11 +258,9 @@ ESX.CreatePickup = function(type, name, count, label, playerId, components, tint local xPlayer = ESX.GetPlayerFromId(playerId) ESX.Pickups[pickupId] = { - type = type, - name = name, - count = count, - label = label, - coords = xPlayer.getCoords(), + type = type, name = name, + count = count, label = label, + coords = xPlayer.getCoords() } if type == 'item_weapon' then @@ -270,7 +268,7 @@ ESX.CreatePickup = function(type, name, count, label, playerId, components, tint ESX.Pickups[pickupId].tintIndex = tintIndex end - TriggerClientEvent('esx:createPickup', -1, pickupId, label, playerId, type, name, components, tintIndex) + TriggerClientEvent('esx:createPickup', -1, pickupId, label, xPlayer.getCoords(), type, name, components, tintIndex) ESX.PickupId = pickupId end From d6aeab0f7b53560f8f702ca3838ee1b994890c5f Mon Sep 17 00:00:00 2001 From: userMacieG Date: Tue, 21 Apr 2020 09:09:40 +0200 Subject: [PATCH 493/672] Updated Polish translation (#676) * Update pl.lua * Update pl.lua * Update pl.lua --- locales/pl.lua | 175 ++++++++++++++++++++++++------------------------- 1 file changed, 87 insertions(+), 88 deletions(-) diff --git a/locales/pl.lua b/locales/pl.lua index 2a04b378..35012487 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -10,9 +10,9 @@ Locales['pl'] = { ['giveammo'] = 'daj amunicje', ['amountammo'] = 'ilość amunicji', ['noammo'] = 'nie posiadasz wystarczającej ilości amunicji!', - ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', - ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'dajesz ~b~%s~s~ dla ~y~%s~s~', + ['gave_item'] = 'dałeś/aś ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', + ['received_item'] = 'otrzymałeś/aś ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', + ['gave_weapon'] = 'dałeś/aś ~b~%s~s~ dla ~y~%s~s~', ['gave_weapon_ammo'] = 'dałeś/aś ~o~%sx %s~s~ do ~b~%s~s~ dla ~y~%s~s~', ['gave_weapon_withammo'] = 'dałeś/aś ~b~%s~s~ z ~o~%sx %s~s~ dla ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ już posiada ~y~%s~s~', @@ -22,8 +22,8 @@ Locales['pl'] = { ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx %s~s~ od ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', ['received_weapon_noweapon'] = '~b~%s~s~ próbował/a przekazać ci amunicje do ~y~%s~s~, lecz nie posiadasz tej broni', - ['gave_account_money'] = 'dajesz ~g~%s$~s~ (%s) dla ~y~%s~s~', - ['received_account_money'] = 'otrzymujesz ~g~%s$~s~ (%s) od ~b~%s~s~', + ['gave_account_money'] = 'dałeś/aś ~g~%s$~s~ (%s) dla ~y~%s~s~', + ['received_account_money'] = 'otrzymałeś/aś ~g~%s$~s~ (%s) od ~b~%s~s~', ['amount_invalid'] = 'nieprawidłowa ilość', ['players_nearby'] = 'brak graczy w pobliżu', ['ex_inv_lim'] = 'akcja nie jest możliwa, nie możesz mieć więcej ~y~%s~s~', @@ -33,76 +33,75 @@ Locales['pl'] = { ['threw_account'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx %s~s~', - ['threw_weapon_already'] = 'you already carry the same weapon', - ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', - ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', + ['threw_weapon_already'] = 'już posiadasz taką samą broń', + ['threw_cannot_pickup'] = 'nie możesz tego podnieść, gdyż masz pełny ekwipunek!', + ['threw_pickup_prompt'] = 'naciśnij ~y~E~s~ aby podnieść', -- Key mapping - ['keymap_showinventory'] = 'show Inventory', + ['keymap_showinventory'] = 'pokaż ekwipunek', -- Salary related - ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', - ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', + ['received_salary'] = 'otrzymałeś/aś wynagrodzenie: ~g~%s$~s~', + ['received_help'] = 'otrzymałeś/aś zapomogę: ~g~$%s~s~', ['company_nomoney'] = 'firma, w której pracujesz, jest zbyt biedna, by wypłacić twoją pensję', - ['received_paycheck'] = 'otrzymana wypłata', + ['received_paycheck'] = 'otrzymano wypłate', ['bank'] = 'bank', ['account_bank'] = 'bank', - ['account_black_money'] = 'dirty Money', - ['account_money'] = 'cash', - + ['account_black_money'] = 'brudne pieniądze', + ['account_money'] = 'pieniądze', ['act_imp'] = 'działanie niemożliwe', ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', -- Commands - ['command_car'] = 'spawn an vehicle', - ['command_car_car'] = 'vehicle spawn name or hash', - ['command_cardel'] = 'delete vehicle in proximity', - ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', - ['command_clear'] = 'clear chat', - ['command_clearall'] = 'clear chat for all players', - ['command_clearinventory'] = 'clear player inventory', - ['command_clearloadout'] = 'clear a player loadout', - ['command_giveaccountmoney'] = 'give account money', - ['command_giveaccountmoney_account'] = 'valid account name', - ['command_giveaccountmoney_amount'] = 'amount to add', - ['command_giveaccountmoney_invalid'] = 'invalid account name', - ['command_giveitem'] = 'give an item to a player', - ['command_giveitem_item'] = 'item name', - ['command_giveitem_count'] = 'item count', - ['command_giveweapon'] = 'give a weapon to a player', - ['command_giveweapon_weapon'] = 'weapon name', - ['command_giveweapon_ammo'] = 'ammo count', - ['command_giveweapon_hasalready'] = 'player already has that weapon', - ['command_giveweaponcomponent'] = 'give weapon component', - ['command_giveweaponcomponent_component'] = 'component name', - ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', - ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', - ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', - ['command_save'] = 'save a player to database', - ['command_saveall'] = 'save all players to database', - ['command_setaccountmoney'] = 'set account money for a player', - ['command_setaccountmoney_amount'] = 'amount of money to set', - ['command_setcoords'] = 'teleport to coordinates', + ['command_car'] = 'przywołaj pojazd', + ['command_car_car'] = 'nazwa lub hash przywołanego pojazdu', + ['command_cardel'] = 'usuń pojazd w pobliżu', + ['command_cardel_radius'] = 'opcjonalnie usuń każdy pojazd w obszarze', + ['command_clear'] = 'wyczyść czat', + ['command_clearall'] = 'wyczyść czat dla wszystkich graczy', + ['command_clearinventory'] = 'wyczyść ekwipunek gracza', + ['command_clearloadout'] = 'wyczyść wyposarzenie gracza', + ['command_giveaccountmoney'] = 'daj pieniądze na podany typ konta', + ['command_giveaccountmoney_account'] = 'prawidłowy typ konta', + ['command_giveaccountmoney_amount'] = 'ilość do dodania', + ['command_giveaccountmoney_invalid'] = 'nieprawidłowy typ konta', + ['command_giveitem'] = 'daj przedmiot graczowi', + ['command_giveitem_item'] = 'nazwa przedmiotu', + ['command_giveitem_count'] = 'ilość przedimotu', + ['command_giveweapon'] = 'daj broń graczowi', + ['command_giveweapon_weapon'] = 'nazwa broni', + ['command_giveweapon_ammo'] = 'ilość amunicji', + ['command_giveweapon_hasalready'] = 'gracz już posiada tą broń', + ['command_giveweaponcomponent'] = 'daj komponent do broni graczowi', + ['command_giveweaponcomponent_component'] = 'nazwa komponentu', + ['command_giveweaponcomponent_invalid'] = 'nieprawidłowy komponent do broni', + ['command_giveweaponcomponent_hasalready'] = 'gracz już posiada ten komponent do tej broni', + ['command_giveweaponcomponent_missingweapon'] = 'gracz nie posiada tej broni', + ['command_save'] = 'zapisz gracza w bazie danych', + ['command_saveall'] = 'zapisz wszystkich graczy w bazie danych', + ['command_setaccountmoney'] = 'ustaw ilość pieniędzy danego konta dla gracza', + ['command_setaccountmoney_amount'] = 'ilość pieniędzy do ustawienia', + ['command_setcoords'] = 'teleportuj na koordynaty', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'set job for a player', - ['command_setjob_job'] = 'job name', - ['command_setjob_grade'] = 'job grade', - ['command_setjob_invalid'] = 'the job, grade or both are invalid', - ['command_setgroup'] = 'set player group', - ['command_setgroup_group'] = 'group name', - ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', - ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', - ['commanderror_invaliditem'] = 'invalid item name', - ['commanderror_invalidweapon'] = 'invalid weapon', - ['commanderror_console'] = 'that command can not be run from console', - ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', - ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', - ['commandgeneric_playerid'] = 'player id', + ['command_setjob'] = 'ustaw prace dla gracza', + ['command_setjob_job'] = 'nazwa pracy', + ['command_setjob_grade'] = 'stanowisko w pracy', + ['command_setjob_invalid'] = 'praca, stanowisko lub obydwa są nieprawidłowe', + ['command_setgroup'] = 'ustaw grupe gracza', + ['command_setgroup_group'] = 'nazwa grupy', + ['commanderror_argumentmismatch'] = 'nieprawiłowa ilość argumentów (przeszło %s, wymagane %s)', + ['commanderror_argumentmismatch_number'] = 'nieprawidłowy typ argumentu #%s (przeszedł tekst, wymagany numer)', + ['commanderror_invaliditem'] = 'nieprawidłowa nazwa przedmiotu', + ['commanderror_invalidweapon'] = 'nieprawidłowa broń', + ['commanderror_console'] = 'podana komenda nie może zostać uruchomiona przez konsole', + ['commanderror_invalidcommand'] = '^3%s^0 nie jest poprawną komendą!', + ['commanderror_invalidplayerid'] = 'brak dostepnego gracza pasującego do podanego id serwerowego', + ['commandgeneric_playerid'] = 'id gracza', -- Locale settings - ['locale_digit_grouping_symbol'] = ' ', + ['locale_digit_grouping_symbol'] = ',', ['locale_currency'] = '$%s', -- Weapons @@ -184,42 +183,42 @@ Locales['pl'] = { -- Weapon Components ['component_clip_default'] = 'domyślny tłumik', ['component_clip_extended'] = 'rozszerzony tłumik', - ['component_clip_drum'] = 'drum Magazine', - ['component_clip_box'] = 'box Magazine', + ['component_clip_drum'] = 'magazynek bębnowy', + ['component_clip_box'] = 'magazynek', ['component_flashlight'] = 'latarka', ['component_scope'] = 'luneta', ['component_scope_advanced'] = 'zaawansowana luneta', ['component_suppressor'] = 'tłumik', ['component_grip'] = 'uchwyt', - ['component_luxary_finish'] = 'luxary Weapon Finish', + ['component_luxary_finish'] = 'luksusowe wykończenie broni', -- Weapon Ammo - ['ammo_rounds'] = 'round(s)', - ['ammo_shells'] = 'shell(s)', - ['ammo_charge'] = 'charge', - ['ammo_petrol'] = 'gallons of fuel', - ['ammo_firework'] = 'firework(s)', - ['ammo_rockets'] = 'rocket(s)', - ['ammo_grenadelauncher'] = 'grenade(s)', - ['ammo_grenade'] = 'grenade(s)', - ['ammo_stickybomb'] = 'bomb(s)', - ['ammo_pipebomb'] = 'bomb(s)', - ['ammo_smokebomb'] = 'bomb(s)', - ['ammo_molotov'] = 'cocktail(s)', - ['ammo_proxmine'] = 'mine(s)', - ['ammo_bzgas'] = 'can(s)', - ['ammo_ball'] = 'ball(s)', - ['ammo_snowball'] = 'snowball(s)', - ['ammo_flare'] = 'flare(s)', - ['ammo_flaregun'] = 'flare(s)', + ['ammo_rounds'] = 'nabój/oi', + ['ammo_shells'] = 'pocisk(ów)', + ['ammo_charge'] = 'naładowania', + ['ammo_petrol'] = 'galon(y) paliwa', + ['ammo_firework'] = 'fajerwerka/i', + ['ammo_rockets'] = 'rakieta/y', + ['ammo_grenadelauncher'] = 'granat(y)', + ['ammo_grenade'] = 'granat(y)', + ['ammo_stickybomb'] = 'bomba/y', + ['ammo_pipebomb'] = 'bomba/y', + ['ammo_smokebomb'] = 'bomba/y', + ['ammo_molotov'] = 'kontail(e)', + ['ammo_proxmine'] = 'mina/y', + ['ammo_bzgas'] = 'puszka/ek', + ['ammo_ball'] = 'kula/e', + ['ammo_snowball'] = 'snieżka/i', + ['ammo_flare'] = 'flara/y', + ['ammo_flaregun'] = 'flara/y', -- Weapon Tints - ['tint_default'] = 'default skin', - ['tint_green'] = 'green skin', - ['tint_gold'] = 'gold skin', - ['tint_pink'] = 'pink skin', - ['tint_army'] = 'army skin', - ['tint_lspd'] = 'blue skin', - ['tint_orange'] = 'orange skin', - ['tint_platinum'] = 'platinum skin', + ['tint_default'] = 'domyślny skin', + ['tint_green'] = 'zielony skin', + ['tint_gold'] = 'złoty skin', + ['tint_pink'] = 'różowy skin', + ['tint_army'] = 'wojskowy skin', + ['tint_lspd'] = 'niebieski skin', + ['tint_orange'] = 'pomarańczowy skin', + ['tint_platinum'] = 'platynowy skin', } From a9658e0eb82320a6c1f7457dbe5bbbcec96785cd Mon Sep 17 00:00:00 2001 From: AvarianKnight Date: Tue, 21 Apr 2020 13:42:07 -0500 Subject: [PATCH 494/672] add tank health --- client/functions.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/functions.lua b/client/functions.lua index 6cba9fe5..9ea73016 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -559,6 +559,7 @@ ESX.Game.GetVehicleProperties = function(vehicle) bodyHealth = ESX.Math.Round(GetVehicleBodyHealth(vehicle), 1), engineHealth = ESX.Math.Round(GetVehicleEngineHealth(vehicle), 1), + tankHealth = ESX.Math.Round(GetVehiclePetrolTankHealth(vehicle), 1), fuelLevel = ESX.Math.Round(GetVehicleFuelLevel(vehicle), 1), dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), @@ -648,6 +649,7 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) if props.plateIndex then SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) end if props.bodyHealth then SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) end if props.engineHealth then SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) end + if props.tankHealth then SetVehiclePetrolTankHealth(vehicle, props.tankHealth + 0.0) end if props.fuelLevel then SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end if props.dirtLevel then SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end if props.color1 then SetVehicleColours(vehicle, props.color1, colorSecondary) end From c8381b1b4eb4562de3e5384591055bfd084ba62b Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 22 Apr 2020 11:35:04 +0200 Subject: [PATCH 495/672] Removed ESX.Game.GetClosestPlayer() second argument "modelFilter" --- client/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/functions.lua b/client/functions.lua index 9ea73016..aced3015 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -487,7 +487,7 @@ end ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetObjects(), false, coords, modelFilter) end ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPeds(true), false, coords, modelFilter) end -ESX.Game.GetClosestPlayer = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(true, true), true, coords, modelFilter) end +ESX.Game.GetClosestPlayer = function(coords) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(true, true), true, coords, nil) end ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetVehicles(), false, coords, modelFilter) end ESX.Game.GetPlayersInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetPlayers(true, true), true, coords, maxDistance) end ESX.Game.GetVehiclesInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetVehicles(), false, coords, maxDistance) end From 990feb9ca96cab7a14865bdfc084f0f557235d4c Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Wed, 22 Apr 2020 12:25:55 +0200 Subject: [PATCH 496/672] Fixed "Changing ones own access is not permitted" --- README.md | 1 + server/functions.lua | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7f62914a..92f5e3df 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ add_principal group.admin group.user add_ace resource.es_extended command.add_ace allow add_ace resource.es_extended command.add_principal allow add_ace resource.es_extended command.remove_principal allow +add_ace resource.es_extended command.stop allow start mysql-async start es_extended diff --git a/server/functions.lua b/server/functions.lua index 88348110..1271d840 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -256,11 +256,12 @@ end ESX.CreatePickup = function(type, name, count, label, playerId, components, tintIndex) local pickupId = (ESX.PickupId == 65635 and 0 or ESX.PickupId + 1) local xPlayer = ESX.GetPlayerFromId(playerId) + local coords = xPlayer.getCoords() ESX.Pickups[pickupId] = { type = type, name = name, count = count, label = label, - coords = xPlayer.getCoords() + coords = coords } if type == 'item_weapon' then @@ -268,7 +269,7 @@ ESX.CreatePickup = function(type, name, count, label, playerId, components, tint ESX.Pickups[pickupId].tintIndex = tintIndex end - TriggerClientEvent('esx:createPickup', -1, pickupId, label, xPlayer.getCoords(), type, name, components, tintIndex) + TriggerClientEvent('esx:createPickup', -1, pickupId, label, coords, type, name, components, tintIndex) ESX.PickupId = pickupId end From cb9038c9116c6af27f2049a2574d821dc5b6c0d0 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Apr 2020 15:18:16 +0200 Subject: [PATCH 497/672] Fixed #709 throwing weapons, fixed throwing weapons missing components, added player join msg --- client/main.lua | 2 +- server/main.lua | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/client/main.lua b/client/main.lua index a833c5f4..3f1e9c30 100644 --- a/client/main.lua +++ b/client/main.lua @@ -286,7 +286,7 @@ AddEventHandler('esx:createPickup', function(pickupId, label, coords, type, name if type == 'item_weapon' then local weaponHash = GetHashKey(name) ESX.Streaming.RequestWeaponAsset(weaponHash) - local pickupObject = CreateWeaponObject(weaponHash, 50, coords, true, 1.0, 0) + local pickupObject = CreateWeaponObject(weaponHash, 50, coords.x, coords.y, coords.z, true, 1.0, 0) SetWeaponObjectTintIndex(pickupObject, tintIndex) for k,v in ipairs(components) do diff --git a/server/main.lua b/server/main.lua index f37fa6b3..6434e6ec 100644 --- a/server/main.lua +++ b/server/main.lua @@ -252,6 +252,7 @@ function loadESXPlayer(identifier, playerId) xPlayer.triggerEvent('esx:createMissingPickups', ESX.Pickups) xPlayer.triggerEvent('esx:registerSuggestions', ESX.RegisteredCommands) + print(('[es_extended] [^2INFO^7] A player with name "%s^7" has connected to the server with assigned player id %s'):format(xPlayer.getName(), playerId)) end) end @@ -302,7 +303,6 @@ AddEventHandler('esx:giveInventoryItem', function(target, type, itemName, itemCo if type == 'item_standard' then local sourceItem = sourceXPlayer.getInventoryItem(itemName) - local targetItem = targetXPlayer.getInventoryItem(itemName) if itemCount > 0 and sourceItem.count >= itemCount then if targetXPlayer.canCarryItem(itemName, itemCount) then @@ -419,8 +419,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) if xPlayer.hasWeapon(itemName) then local _, weapon = xPlayer.getWeapon(itemName) local _, weaponObject = ESX.GetWeapon(itemName) - local pickupLabel - + local components, pickupLabel = ESX.Table.Clone(weapon.components) xPlayer.removeWeapon(itemName) if weaponObject.ammo and weapon.ammo > 0 then @@ -432,7 +431,7 @@ AddEventHandler('esx:removeInventoryItem', function(type, itemName, itemCount) xPlayer.showNotification(_U('threw_weapon', weapon.label)) end - ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, weapon.components, weapon.tintIndex) + ESX.CreatePickup('item_weapon', itemName, weapon.ammo, pickupLabel, playerId, components, weapon.tintIndex) end end end) From 7d7f72082a9a56f8c49d88c9134b30761485b5f3 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Apr 2020 15:23:25 +0200 Subject: [PATCH 498/672] Only grant ace permission if needed (even if fivem devs changed the behaviour) --- server/main.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/server/main.lua b/server/main.lua index 6434e6ec..2d82d2fe 100644 --- a/server/main.lua +++ b/server/main.lua @@ -1,8 +1,7 @@ Citizen.CreateThread(function() SetMapName('San Andreas') SetGameType('Roleplay') - local resourcesStopped = {} - ExecuteCommand('add_ace resource.es_extended command.stop allow') + local resourcesStopped, isAceGranted = {}, false for resourceName,reason in pairs(Config.IncompatibleResourcesToStop) do local status = GetResourceState(resourceName) @@ -12,6 +11,11 @@ Citizen.CreateThread(function() Citizen.Wait(100) end + if not isAceGranted then + ExecuteCommand('add_ace resource.es_extended command.stop allow') + isAceGranted = true + end + ExecuteCommand(('stop %s'):format(resourceName)) resourcesStopped[resourceName] = reason end From 04bfce640e5d25d19b990452005e18ae83552326 Mon Sep 17 00:00:00 2001 From: ElPumpo Date: Fri, 24 Apr 2020 16:09:53 +0200 Subject: [PATCH 499/672] ESX is no longer short for anything --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 92f5e3df..685a3c27 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # es_extended -es_extended is a roleplay framework for FiveM. ESX is short for EssentialMode Extended. The to-go framework for creating an economy based roleplay server on FiveM and most popular on the platform, too! +es_extended is a roleplay framework for FiveM. The to-go framework for creating an economy based roleplay server on FiveM and most popular on the platform, too! Featuring many extra resources to fit roleplaying servers, here's a taste of what's available: @@ -102,7 +102,7 @@ start esx_menu_dialog ### License -es_extended - EssentialMode Extended framework for FiveM +es_extended - ESX framework for FiveM Copyright (C) 2015-2020 Jérémie N'gadi From 71459c4ad863a88bea93c9f555536f840092055f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BA=BB=E8=BE=A3=E6=88=88=E5=A3=81?= Date: Fri, 24 Apr 2020 22:11:17 +0800 Subject: [PATCH 500/672] Update simplified Chinese translation and traditional Chinese Translation --- locales/sc.lua | 2 +- locales/tc.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/locales/sc.lua b/locales/sc.lua index cfe39ae2..229403de 100644 --- a/locales/sc.lua +++ b/locales/sc.lua @@ -42,7 +42,7 @@ Locales['sc'] = { -- Salary related ['received_salary'] = '你收到了你的工资: ~g~$%s~s~', - ['received_help'] = '鉴于你良好的表现,系统赠送给你一些奖励: ~g~$%s~s~', + ['received_help'] = '你领取到了你的失业救济金: ~g~$%s~s~', ['company_nomoney'] = '你受雇的公司太穷了,无法支付你的工资。', ['received_paycheck'] = '收到转账', ['bank'] = '花园银行', diff --git a/locales/tc.lua b/locales/tc.lua index 9e31c8db..663259fb 100644 --- a/locales/tc.lua +++ b/locales/tc.lua @@ -42,7 +42,7 @@ Locales['tc'] = { -- Salary related ['received_salary'] = '您收到您的薪水: ~g~$%s~s~', - ['received_help'] = '由於您表現良好,系統給予您一些獎勵: ~g~$%s~s~', + ['received_help'] = '你領取到了你的失業救濟金: ~g~$%s~s~', ['company_nomoney'] = '您的公司太窮了,無法給予您薪水。', ['received_paycheck'] = '收到轉帳', ['bank'] = '花園銀行', From 383aceffb408f17e6dad42aa08234a1e8b3d4453 Mon Sep 17 00:00:00 2001 From: FuraXx <33160388+FuraXx@users.noreply.github.com> Date: Sat, 9 May 2020 13:51:46 +0200 Subject: [PATCH 501/672] update readme - iceline removal - update of the discord link - fvm removal --- README.md | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/README.md b/README.md index 685a3c27..e5d3e742 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ ESX was initially developed by Gizz back in 2017 for his friend as the were crea ## Links & Read more - [ESX Documentation](https://esx-org.github.io/) -- [ESX Development Discord](https://discord.gg/MsWzPqE) +- [ESX Development Discord](https://discord.me/esx) - [FiveM Native Reference](https://runtime.fivem.net/doc/reference.html) ## Features @@ -32,30 +32,9 @@ ESX was initially developed by Gizz back in 2017 for his friend as the were crea - [mysql-async](https://github.com/brouznouf/fivem-mysql-async) - [async](https://github.com/ESX-Org/async) -## Rent Server - -![Iceline hosting](https://media.discordapp.net/attachments/667787270375473183/667790233441533952/banner.gif) - -Are you thinking of starting a FiveM server of your own? [Iceline Hosting](https://iceline-hosting.com/billing/aff.php?aff=94) provide cost effective game servers, high end game VPS's with DDoS protection included, and more! - -There is an optional Managed Support Addon available for game servers and Game VPS's that add the following services: - -- Investigation and fixing errors in relation to the server or third-party scripts -- Installing third-party scripts or software -- Recovery of lost data - -Go to [Iceline Hosting](https://iceline-hosting.com/billing/aff.php?aff=94) and use promo code `ESX` for 15% off the first month on FiveM game servers, Game VPS's and Singapore VPS's. ## Download & Installation -### Using [fvm](https://github.com/qlaffont/fvm-installer) - -``` -fvm install --save --folder=essential esx-org/es_extended -fvm install --save --folder=esx esx-org/esx_menu_default -fvm install --save --folder=esx esx-org/esx_menu_dialog -fvm install --save --folder=esx esx-org/esx_menu_list -``` ### Using Git From 799a56c02678a827a5b0f1c8bc25bc46f1eb4b25 Mon Sep 17 00:00:00 2001 From: justtos Date: Sun, 10 May 2020 12:42:15 +0300 Subject: [PATCH 502/672] Allow the callback for the item to have access... to basic info about itself --- server/functions.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/functions.lua b/server/functions.lua index 1271d840..eca0a20d 100644 --- a/server/functions.lua +++ b/server/functions.lua @@ -244,7 +244,7 @@ ESX.RegisterUsableItem = function(item, cb) end ESX.UseItem = function(source, item) - ESX.UsableItemsCallbacks[item](source) + ESX.UsableItemsCallbacks[item](source, item) end ESX.GetItemLabel = function(item) From 390cce619581d6f49b7a31cbd5751b6159367e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9mie=20N=27gadi?= Date: Mon, 11 May 2020 04:21:10 +0200 Subject: [PATCH 503/672] single resource concept + first attempt to reorganize code --- .editorconfig | 8 +- client/bootstrap.lua | 17 + client/functions.lua | 126 +- client/main.lua | 207 ++- client/wrapper.lua | 2 +- common/functions.lua | 13 + config.lua | 21 +- fxmanifest.lua | 52 +- hud/app.css | 14 + hud/app.js | 109 ++ hud/index.html | 13 + hud/wrapper.js | 43 + locale.lua | 10 + locales/pl.lua | 175 +- locales/sc.lua | 2 +- locales/tc.lua | 2 +- modules/hud/client/events.lua | 5 + modules/hud/client/main.lua | 4 + modules/hud/client/module.lua | 5 + {html => modules/hud/data/html}/css/app.css | 4 +- .../hud/data/html}/fonts/bankgothic.ttf | Bin .../hud/data/html}/fonts/pdown.ttf | Bin .../hud/data/html}/img/accounts/bank.png | Bin .../data/html}/img/accounts/black_money.png | Bin .../hud/data/html}/img/accounts/money.png | Bin {html => modules/hud/data/html}/js/app.js | 0 .../hud/data/html}/js/mustache.min.js | 0 {html => modules/hud/data/html}/js/wrapper.js | 2 +- {html => modules/hud/data/html}/ui.html | 0 modules/hud/server/events.lua | 2 + modules/hud/server/main.lua | 3 + modules/hud/server/module.lua | 3 + modules/input/client/events.lua | 1 + modules/input/client/main.lua | 67 + modules/input/client/module.lua | 466 +++++ modules/input/server/events.lua | 1 + modules/input/server/main.lua | 1 + modules/input/server/module.lua | 2 + modules/interact/client/events.lua | 12 + modules/interact/client/main.lua | 194 +++ modules/interact/client/module.lua | 47 + modules/interact/server/events.lua | 2 + modules/interact/server/main.lua | 3 + modules/interact/server/module.lua | 3 + modules/job_police/client/events.lua | 311 ++++ modules/job_police/client/main.lua | 157 ++ modules/job_police/client/module.lua | 1517 +++++++++++++++++ modules/job_police/data/config.lua | 319 ++++ modules/job_police/data/locales/br.lua | 151 ++ modules/job_police/data/locales/cs.lua | 151 ++ modules/job_police/data/locales/de.lua | 151 ++ modules/job_police/data/locales/en.lua | 151 ++ modules/job_police/data/locales/es.lua | 151 ++ modules/job_police/data/locales/fi.lua | 151 ++ modules/job_police/data/locales/fr.lua | 151 ++ modules/job_police/data/locales/ko.lua | 151 ++ modules/job_police/data/locales/pl.lua | 151 ++ modules/job_police/data/locales/sv.lua | 151 ++ modules/job_police/server/events.lua | 515 ++++++ modules/job_police/server/main.lua | 15 + modules/job_police/server/module.lua | 31 + modules/menu_default/client/events.lua | 71 + modules/menu_default/client/main.lua | 11 + modules/menu_default/client/module.lua | 26 + modules/menu_default/data/html/css/app.css | 94 + .../data/html/fonts/bankgothic.ttf | Bin 0 -> 36272 bytes .../menu_default/data/html/fonts/pdown.ttf | Bin 0 -> 151512 bytes modules/menu_default/data/html/js/app.js | 346 ++++ .../menu_default/data/html/js/mustache.min.js | 1 + modules/menu_default/data/html/ui.html | 17 + modules/menu_default/server/events.lua | 2 + modules/menu_default/server/main.lua | 3 + modules/menu_default/server/module.lua | 3 + modules/menu_dialog/client/events.lua | 48 + modules/menu_dialog/client/main.lua | 24 + modules/menu_dialog/client/module.lua | 46 + modules/menu_dialog/data/html/css/app.css | 74 + .../data/html/fonts/bankgothic.ttf | Bin 0 -> 36272 bytes modules/menu_dialog/data/html/fonts/pdown.ttf | Bin 0 -> 151512 bytes modules/menu_dialog/data/html/js/app.js | 176 ++ .../menu_dialog/data/html/js/mustache.min.js | 1 + modules/menu_dialog/data/html/ui.html | 17 + modules/menu_dialog/server/events.lua | 2 + modules/menu_dialog/server/main.lua | 3 + modules/menu_dialog/server/module.lua | 3 + modules/menu_list/client/events.lua | 25 + modules/menu_list/client/main.lua | 6 + modules/menu_list/client/module.lua | 47 + modules/menu_list/data/html/css/app.css | 52 + .../menu_list/data/html/fonts/bankgothic.ttf | Bin 0 -> 36272 bytes modules/menu_list/data/html/fonts/pdown.ttf | Bin 0 -> 151512 bytes modules/menu_list/data/html/js/app.js | 192 +++ .../menu_list/data/html/js/mustache.min.js | 1 + modules/menu_list/data/html/ui.html | 16 + modules/menu_list/server/events.lua | 2 + modules/menu_list/server/main.lua | 3 + modules/menu_list/server/module.lua | 3 + server/common.lua | 1 + server/functions.lua | 11 +- server/main.lua | 57 +- 100 files changed, 7118 insertions(+), 282 deletions(-) create mode 100644 client/bootstrap.lua create mode 100644 hud/app.css create mode 100644 hud/app.js create mode 100644 hud/index.html create mode 100644 hud/wrapper.js create mode 100644 modules/hud/client/events.lua create mode 100644 modules/hud/client/main.lua create mode 100644 modules/hud/client/module.lua rename {html => modules/hud/data/html}/css/app.css (98%) rename {html => modules/hud/data/html}/fonts/bankgothic.ttf (100%) rename {html => modules/hud/data/html}/fonts/pdown.ttf (100%) rename {html => modules/hud/data/html}/img/accounts/bank.png (100%) rename {html => modules/hud/data/html}/img/accounts/black_money.png (100%) rename {html => modules/hud/data/html}/img/accounts/money.png (100%) rename {html => modules/hud/data/html}/js/app.js (100%) rename {html => modules/hud/data/html}/js/mustache.min.js (100%) rename {html => modules/hud/data/html}/js/wrapper.js (88%) rename {html => modules/hud/data/html}/ui.html (100%) create mode 100644 modules/hud/server/events.lua create mode 100644 modules/hud/server/main.lua create mode 100644 modules/hud/server/module.lua create mode 100644 modules/input/client/events.lua create mode 100644 modules/input/client/main.lua create mode 100644 modules/input/client/module.lua create mode 100644 modules/input/server/events.lua create mode 100644 modules/input/server/main.lua create mode 100644 modules/input/server/module.lua create mode 100644 modules/interact/client/events.lua create mode 100644 modules/interact/client/main.lua create mode 100644 modules/interact/client/module.lua create mode 100644 modules/interact/server/events.lua create mode 100644 modules/interact/server/main.lua create mode 100644 modules/interact/server/module.lua create mode 100644 modules/job_police/client/events.lua create mode 100644 modules/job_police/client/main.lua create mode 100644 modules/job_police/client/module.lua create mode 100644 modules/job_police/data/config.lua create mode 100644 modules/job_police/data/locales/br.lua create mode 100644 modules/job_police/data/locales/cs.lua create mode 100644 modules/job_police/data/locales/de.lua create mode 100644 modules/job_police/data/locales/en.lua create mode 100644 modules/job_police/data/locales/es.lua create mode 100644 modules/job_police/data/locales/fi.lua create mode 100644 modules/job_police/data/locales/fr.lua create mode 100644 modules/job_police/data/locales/ko.lua create mode 100644 modules/job_police/data/locales/pl.lua create mode 100644 modules/job_police/data/locales/sv.lua create mode 100644 modules/job_police/server/events.lua create mode 100644 modules/job_police/server/main.lua create mode 100644 modules/job_police/server/module.lua create mode 100644 modules/menu_default/client/events.lua create mode 100644 modules/menu_default/client/main.lua create mode 100644 modules/menu_default/client/module.lua create mode 100644 modules/menu_default/data/html/css/app.css create mode 100644 modules/menu_default/data/html/fonts/bankgothic.ttf create mode 100644 modules/menu_default/data/html/fonts/pdown.ttf create mode 100644 modules/menu_default/data/html/js/app.js create mode 100644 modules/menu_default/data/html/js/mustache.min.js create mode 100644 modules/menu_default/data/html/ui.html create mode 100644 modules/menu_default/server/events.lua create mode 100644 modules/menu_default/server/main.lua create mode 100644 modules/menu_default/server/module.lua create mode 100644 modules/menu_dialog/client/events.lua create mode 100644 modules/menu_dialog/client/main.lua create mode 100644 modules/menu_dialog/client/module.lua create mode 100644 modules/menu_dialog/data/html/css/app.css create mode 100644 modules/menu_dialog/data/html/fonts/bankgothic.ttf create mode 100644 modules/menu_dialog/data/html/fonts/pdown.ttf create mode 100644 modules/menu_dialog/data/html/js/app.js create mode 100644 modules/menu_dialog/data/html/js/mustache.min.js create mode 100644 modules/menu_dialog/data/html/ui.html create mode 100644 modules/menu_dialog/server/events.lua create mode 100644 modules/menu_dialog/server/main.lua create mode 100644 modules/menu_dialog/server/module.lua create mode 100644 modules/menu_list/client/events.lua create mode 100644 modules/menu_list/client/main.lua create mode 100644 modules/menu_list/client/module.lua create mode 100644 modules/menu_list/data/html/css/app.css create mode 100644 modules/menu_list/data/html/fonts/bankgothic.ttf create mode 100644 modules/menu_list/data/html/fonts/pdown.ttf create mode 100644 modules/menu_list/data/html/js/app.js create mode 100644 modules/menu_list/data/html/js/mustache.min.js create mode 100644 modules/menu_list/data/html/ui.html create mode 100644 modules/menu_list/server/events.lua create mode 100644 modules/menu_list/server/main.lua create mode 100644 modules/menu_list/server/module.lua diff --git a/.editorconfig b/.editorconfig index 9b425256..4bfca33b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,9 +1,9 @@ root = true [*] -indent_size = 4 -indent_style = tab -end_of_line = crlf +indent_size = 2 +indent_style = space +end_of_line = lf charset = utf-8 trim_trailing_whitespace = true -insert_final_newline = true \ No newline at end of file +insert_final_newline = true diff --git a/client/bootstrap.lua b/client/bootstrap.lua new file mode 100644 index 00000000..e658763c --- /dev/null +++ b/client/bootstrap.lua @@ -0,0 +1,17 @@ +OnESX = function(cb) + + local ESX = nil + + Citizen.CreateThread(function() + + while ESX == nil do + TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end) + Citizen.Wait(0) + end + + cb(ESX) + + end) + +end + diff --git a/client/functions.lua b/client/functions.lua index aced3015..06db3e2d 100644 --- a/client/functions.lua +++ b/client/functions.lua @@ -1,4 +1,5 @@ ESX = {} +ESX.Modules = {} ESX.PlayerData = {} ESX.PlayerLoaded = false ESX.CurrentRequestId = 0 @@ -32,6 +33,30 @@ ESX.ClearTimeout = function(i) ESX.TimeoutCallbacks[i] = nil end +ESX.CreateFrame = function(name, url, visible) + visible = (visible == nil) and true or false + SendNUIMessage({action = 'create_frame', name = name, url = url, visible = visible}) +end + +ESX.SendFrameMessage = function(name, msg) + SendNUIMessage({target = name, data = msg}) +end + +ESX.FocusFrame = function(name, cursor) + SendNUIMessage({action = 'focus_frame', name = name}) + SetNuiFocus(true, cursor) +end + +RegisterNUICallback('nui_ready', function(data, cb) + TriggerEvent('esx:nui_ready') + cb('') +end) + +RegisterNUICallback('frame_message', function(data, cb) + TriggerEvent('esx:frame_message', data.name, data.msg, data.cb) + cb('') +end) + ESX.IsPlayerLoaded = function() return ESX.PlayerLoaded end @@ -44,41 +69,66 @@ ESX.SetPlayerData = function(key, val) ESX.PlayerData[key] = val end -ESX.ShowNotification = function(msg, flash, saveToBrief, hudColorIndex) - if saveToBrief == nil then saveToBrief = true end - AddTextEntry('esxNotification', msg) - BeginTextCommandThefeedPost('esxNotification') - if hudColorIndex then ThefeedNextPostBackgroundColor(hudColorIndex) end - EndTextCommandThefeedPostTicker(flash or false, saveToBrief) +ESX.ShowNotification = function(msg) + SetNotificationTextEntry('STRING') + AddTextComponentString(msg) + DrawNotification(0,1) end ESX.ShowAdvancedNotification = function(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) - if saveToBrief == nil then saveToBrief = true end - AddTextEntry('esxAdvancedNotification', msg) - BeginTextCommandThefeedPost('esxAdvancedNotification') - if hudColorIndex then ThefeedNextPostBackgroundColor(hudColorIndex) end + + if saveToBrief == nil then + saveToBrief = true + end + + BeginTextCommandThefeedPost('STRING') + AddTextComponentSubstringPlayerName(msg) + + if hudColorIndex then + ThefeedNextPostBackgroundColor(hudColorIndex) + end + EndTextCommandThefeedPostMessagetext(textureDict, textureDict, false, iconType, sender, subject) - EndTextCommandThefeedPostTicker(flash or false, saveToBrief) + EndTextCommandThefeedPostTicker(flash or false, saveToBrief) + end ESX.ShowHelpNotification = function(msg, thisFrame, beep, duration) - AddTextEntry('esxHelpNotification', msg) + + BeginTextCommandDisplayHelp('STRING') + AddTextComponentSubstringPlayerName(msg) if thisFrame then - DisplayHelpTextThisFrame('esxHelpNotification', false) + DisplayHelpTextThisFrame(msg, false) else if beep == nil then beep = true end BeginTextCommandDisplayHelp('esxHelpNotification') EndTextCommandDisplayHelp(0, false, beep, duration or -1) - end + end + end -ESX.ShowFloatingHelpNotification = function(msg, coords) - AddTextEntry('esxFloatingHelpNotification', msg) - SetFloatingHelpTextWorldPosition(1, coords) - SetFloatingHelpTextStyle(1, 1, 2, -1, 3, 0) - BeginTextCommandDisplayHelp('esxFloatingHelpNotification') - EndTextCommandDisplayHelp(2, false, false, -1) +ESX.ShowFloatingHelpNotification = function(msg, coords, timeout) + + timeout = timeout or 5000 + local start = GetGameTimer() + + Citizen.CreateThread(function() + + while (GetGameTimer() - start) < timeout do + + SetFloatingHelpTextWorldPosition(1, coords.x, coords.y, coords.z) + SetFloatingHelpTextStyle(1, 1, 2, -1, 3, 0) + BeginTextCommandDisplayHelp('STRING') + AddTextComponentSubstringPlayerName(msg) + EndTextCommandDisplayHelp(2, false, true, -1) + + Citizen.Wait(0) + + end + + end) + end ESX.TriggerServerCallback = function(name, cb, ...) @@ -94,7 +144,7 @@ ESX.TriggerServerCallback = function(name, cb, ...) end ESX.UI.HUD.SetDisplay = function(opacity) - SendNUIMessage({ + ESX.SendFrameMessage('hud', { action = 'setHUDDisplay', opacity = opacity }) @@ -116,7 +166,7 @@ ESX.UI.HUD.RegisterElement = function(name, index, priority, html, data) table.insert(ESX.UI.HUD.RegisteredElements, name) - SendNUIMessage({ + ESX.SendFrameMessage('hud', { action = 'insertHUDElement', name = name, index = index, @@ -136,14 +186,14 @@ ESX.UI.HUD.RemoveElement = function(name) end end - SendNUIMessage({ + ESX.SendFrameMessage('hud', { action = 'deleteHUDElement', name = name }) end ESX.UI.HUD.UpdateElement = function(name, data) - SendNUIMessage({ + ESX.SendFrameMessage('hud', { action = 'updateHUDElement', name = name, data = data @@ -281,7 +331,7 @@ ESX.UI.Menu.IsOpen = function(type, namespace, name) end ESX.UI.ShowInventoryItemNotification = function(add, item, count) - SendNUIMessage({ + ESX.SendFrameMessage('hud', { action = 'inventoryNotification', add = add, item = item, @@ -487,7 +537,7 @@ end ESX.Game.GetClosestObject = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetObjects(), false, coords, modelFilter) end ESX.Game.GetClosestPed = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPeds(true), false, coords, modelFilter) end -ESX.Game.GetClosestPlayer = function(coords) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(true, true), true, coords, nil) end +ESX.Game.GetClosestPlayer = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(true, true), true, coords, modelFilter) end ESX.Game.GetClosestVehicle = function(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetVehicles(), false, coords, modelFilter) end ESX.Game.GetPlayersInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetPlayers(true, true), true, coords, maxDistance) end ESX.Game.GetVehiclesInArea = function(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetVehicles(), false, coords, maxDistance) end @@ -559,7 +609,6 @@ ESX.Game.GetVehicleProperties = function(vehicle) bodyHealth = ESX.Math.Round(GetVehicleBodyHealth(vehicle), 1), engineHealth = ESX.Math.Round(GetVehicleEngineHealth(vehicle), 1), - tankHealth = ESX.Math.Round(GetVehiclePetrolTankHealth(vehicle), 1), fuelLevel = ESX.Math.Round(GetVehicleFuelLevel(vehicle), 1), dirtLevel = ESX.Math.Round(GetVehicleDirtLevel(vehicle), 1), @@ -649,7 +698,6 @@ ESX.Game.SetVehicleProperties = function(vehicle, props) if props.plateIndex then SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex) end if props.bodyHealth then SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0) end if props.engineHealth then SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0) end - if props.tankHealth then SetVehiclePetrolTankHealth(vehicle, props.tankHealth + 0.0) end if props.fuelLevel then SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0) end if props.dirtLevel then SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0) end if props.color1 then SetVehicleColours(vehicle, props.color1, colorSecondary) end @@ -932,10 +980,15 @@ ESX.ShowInventory = function() ESX.Streaming.RequestAnimDict(dict) if type == 'item_weapon' then + menu1.close() - TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) - Citizen.Wait(1000) - TriggerServerEvent('esx:removeInventoryItem', type, item) + + Citizen.CreateThread(function() + TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) + Citizen.Wait(1000) + TriggerServerEvent('esx:removeInventoryItem', type, item) + end) + else ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'inventory_item_count_remove', { title = _U('amount') @@ -943,11 +996,16 @@ ESX.ShowInventory = function() local quantity = tonumber(data2.value) if quantity and quantity > 0 and data.current.count >= quantity then + menu2.close() menu1.close() - TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) - Citizen.Wait(1000) - TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + + Citizen.CreateThread(function() + TaskPlayAnim(playerPed, dict, anim, 8.0, 1.0, 1000, 16, 0.0, false, false, false) + Citizen.Wait(1000) + TriggerServerEvent('esx:removeInventoryItem', type, item, quantity) + end) + else ESX.ShowNotification(_U('amount_invalid')) end diff --git a/client/main.lua b/client/main.lua index 3f1e9c30..a66d515f 100644 --- a/client/main.lua +++ b/client/main.lua @@ -1,4 +1,4 @@ -local isPaused, isDead, pickups = false, false, {} +local isLoadoutLoaded, isPaused, pickups = false, false, {} Citizen.CreateThread(function() while true do @@ -13,35 +13,17 @@ end) RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(playerData) - ESX.PlayerLoaded = true + + ESX.PlayerLoaded = true ESX.PlayerData = playerData - -- check if player is coming from loading screen - if GetEntityModel(PlayerPedId()) == GetHashKey('PLAYER_ZERO') then - local defaultModel = GetHashKey('a_m_y_stbla_02') - RequestModel(defaultModel) + local playerPed = PlayerPedId() - while not HasModelLoaded(defaultModel) do - Citizen.Wait(10) - end - - SetPlayerModel(PlayerId(), defaultModel) - SetPedDefaultComponentVariation(PlayerPedId()) - SetPedRandomComponentVariation(PlayerPedId(), true) - SetModelAsNoLongerNeeded(defaultModel) + if Config.EnablePvP then + SetCanAttackFriendly(playerPed, true, false) + NetworkSetFriendlyFireOption(true) end - -- freeze the player - FreezeEntityPosition(PlayerPedId(), true) - - -- enable PVP - SetCanAttackFriendly(PlayerPedId(), true, false) - NetworkSetFriendlyFireOption(true) - - -- disable wanted level - ClearPlayerWantedLevel(PlayerId()) - SetMaxWantedLevel(0) - if Config.EnableHud then for k,v in ipairs(playerData.accounts) do local accountTpl = '
 {{money}}
' @@ -60,42 +42,47 @@ AddEventHandler('esx:playerLoaded', function(playerData) }) end - ESX.Game.Teleport(PlayerPedId(), { - x = playerData.coords.x, - y = playerData.coords.y, - z = playerData.coords.z + 0.25, - heading = playerData.coords.heading - }, function() + -- Bringing back spawnmanager, see commit of Smallo92 at https://github.com/extendedmode/extendedmode/commit/9979c204f1237091e94fdd46580c9e7ebc79bca7 + exports.spawnmanager:spawnPlayer({ + x = playerData.coords.x, + y = playerData.coords.y, + z = playerData.coords.z, + heading = playerData.coords.heading, + model = 'mp_m_freemode_01', + skipFade = false + }, function() + TriggerServerEvent('esx:onPlayerSpawn') TriggerEvent('esx:onPlayerSpawn') - TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon - TriggerEvent('esx:restoreLoadout') + TriggerEvent('esx:restoreLoadout') + + StartServerSyncLoops() + + end) - Citizen.Wait(3000) - ShutdownLoadingScreen() - FreezeEntityPosition(PlayerPedId(), false) - DoScreenFadeIn(10000) - StartServerSyncLoops() - end) end) RegisterNetEvent('esx:setMaxWeight') AddEventHandler('esx:setMaxWeight', function(newMaxWeight) ESX.PlayerData.maxWeight = newMaxWeight end) -AddEventHandler('esx:onPlayerSpawn', function() isDead = false end) -AddEventHandler('esx:onPlayerDeath', function() isDead = true end) +AddEventHandler('esx:onPlayerSpawn', function() ESX.IsDead = false end) +AddEventHandler('esx:onPlayerDeath', function() ESX.IsDead = true end) +AddEventHandler('skinchanger:loadDefaultModel', function() isLoadoutLoaded = false end) AddEventHandler('skinchanger:modelLoaded', function() - while not ESX.PlayerLoaded do + + while not ESX.PlayerLoaded do Citizen.Wait(100) end - TriggerEvent('esx:restoreLoadout') + 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 @@ -109,6 +96,7 @@ AddEventHandler('esx:restoreLoadout', function() for k2,v2 in ipairs(v.components) do local componentHash = ESX.GetWeaponComponent(weaponName, v2).hash + GiveWeaponComponentToPed(playerPed, weaponHash, componentHash) end @@ -117,6 +105,8 @@ AddEventHandler('esx:restoreLoadout', function() ammoTypes[ammoType] = true end end + + isLoadoutLoaded = true end) RegisterNetEvent('esx:setAccountMoney') @@ -245,7 +235,7 @@ RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) if Config.EnableHud then ESX.UI.HUD.UpdateElement('job', { - job_label = job.label, + job_label = job.label, grade_label = job.grade_label }) end @@ -268,42 +258,91 @@ AddEventHandler('esx:spawnVehicle', function(vehicleName) end) RegisterNetEvent('esx:createPickup') -AddEventHandler('esx:createPickup', function(pickupId, label, coords, type, name, components, tintIndex) - local function setObjectProperties(object) - SetEntityAsMissionEntity(object, true, false) - PlaceObjectOnGroundProperly(object) - FreezeEntityPosition(object, true) - SetEntityCollision(object, false, true) +AddEventHandler('esx:createPickup', function(pickupId, label, playerId, type, name, components, tintIndex) + + local playerPed = GetPlayerPed(GetPlayerFromServerId(playerId)) + local entityCoords, forwardVector = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) + local objectCoords = (entityCoords + forwardVector * 1.0) + + local function setupPickup(obj) + + SetEntityAsMissionEntity(obj, true, false) + PlaceObjectOnGroundProperly(obj) + FreezeEntityPosition(obj, true) + SetEntityCollision(obj, false, true) pickups[pickupId] = { - obj = object, + obj = obj, label = label, inRange = false, - coords = vector3(coords.x, coords.y, coords.z) + coords = objectCoords } + end if type == 'item_weapon' then - local weaponHash = GetHashKey(name) - ESX.Streaming.RequestWeaponAsset(weaponHash) - local pickupObject = CreateWeaponObject(weaponHash, 50, coords.x, coords.y, coords.z, true, 1.0, 0) - SetWeaponObjectTintIndex(pickupObject, tintIndex) - for k,v in ipairs(components) do - local component = ESX.GetWeaponComponent(name, v) - GiveWeaponComponentToWeaponObject(pickupObject, component.hash) - end + Citizen.CreateThread(function() + + local weaponHash = GetHashKey(name) + + ESX.Streaming.RequestWeaponAsset(weaponHash) + local pickupObject = CreateWeaponObject(weaponHash, 50, objectCoords, true, 1.0, 0) + SetWeaponObjectTintIndex(pickupObject, tintIndex) + + for k,v in ipairs(components) do + local component = ESX.GetWeaponComponent(name, v) + GiveWeaponComponentToWeaponObject(pickupObject, component.hash) + end + + setupPickup(pickupObject) + + end) - setObjectProperties(pickupObject) else - ESX.Game.SpawnLocalObject('prop_money_bag_01', coords, setObjectProperties) + + ESX.Game.SpawnLocalObject('prop_money_bag_01', objectCoords, function(obj) + setupPickup(obj) + end) end end) + RegisterNetEvent('esx:createMissingPickups') AddEventHandler('esx:createMissingPickups', function(missingPickups) for pickupId,pickup in pairs(missingPickups) do - TriggerEvent('esx:createPickup', pickupId, pickup.label, pickup.coords, pickup.type, pickup.name, pickup.components, pickup.tintIndex) + local pickupObject = nil + + if pickup.type == 'item_weapon' then + ESX.Streaming.RequestWeaponAsset(GetHashKey(pickup.name)) + pickupObject = CreateWeaponObject(GetHashKey(pickup.name), 50, pickup.coords.x, pickup.coords.y, pickup.coords.z, true, 1.0, 0) + SetWeaponObjectTintIndex(pickupObject, pickup.tintIndex) + + for k,componentName in ipairs(pickup.components) do + local component = ESX.GetWeaponComponent(pickup.name, componentName) + GiveWeaponComponentToWeaponObject(pickupObject, component.hash) + end + else + ESX.Game.SpawnLocalObject('prop_money_bag_01', pickup.coords, function(obj) + pickupObject = obj + end) + + while not pickupObject do + Citizen.Wait(10) + end + end + + SetEntityAsMissionEntity(pickupObject, true, false) + PlaceObjectOnGroundProperly(pickupObject) + FreezeEntityPosition(pickupObject, true) + SetEntityCollision(pickupObject, false, true) + + pickups[pickupId] = { + obj = pickupObject, + label = pickup.label, + inRange = false, + coords = vector3(pickup.coords.x, pickup.coords.y, pickup.coords.z) + } end end) @@ -387,7 +426,7 @@ function StartServerSyncLoops() while true do Citizen.Wait(0) - if isDead then + if ESX.IsDead then Citizen.Wait(500) else local playerPed = PlayerPedId() @@ -428,17 +467,20 @@ function StartServerSyncLoops() end) end -Citizen.CreateThread(function() - while true do - Citizen.Wait(0) +-- Disable wanted level +if Config.DisableWantedLevel then + Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + local playerId = PlayerId() - if IsControlJustReleased(0, 289) then - if IsInputDisabled(0) and not isDead and not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory') then - ESX.ShowInventory() + if GetPlayerWantedLevel(playerId) ~= 0 then + SetPlayerWantedLevel(playerId, 0, false) + SetPlayerWantedLevelNow(playerId, false) end end - end -end) + end) +end -- Pickups Citizen.CreateThread(function() @@ -470,14 +512,14 @@ Citizen.CreateThread(function() end end - label = ('%s~n~%s'):format(label, _U('threw_pickup_prompt')) end - ESX.Game.Utils.DrawText3D({ + ESX.ShowFloatingHelpNotification(label, { x = pickup.coords.x, y = pickup.coords.y, z = pickup.coords.z + 0.25 - }, label, 1.2, 1) + }, 100) + elseif pickup.inRange then pickup.inRange = false end @@ -488,3 +530,18 @@ Citizen.CreateThread(function() end end end) + +AddEventHandler('luaconsole:getHandlers', function(cb) + + local name = GetCurrentResourceName() + + cb(name, function(code, env) + if env ~= nil then + for k,v in pairs(env) do _ENV[k] = v end + return load(code, 'lc:' .. name, 'bt', _ENV) + else + return load(code, 'lc:' .. name, 'bt') + end + end) + +end) diff --git a/client/wrapper.lua b/client/wrapper.lua index 441312d8..382e08de 100644 --- a/client/wrapper.lua +++ b/client/wrapper.lua @@ -6,7 +6,7 @@ RegisterNUICallback('__chunk', function(data, cb) if data['end'] then local msg = json.decode(Chunks[data.id]) - TriggerEvent(GetCurrentResourceName() .. ':message:' .. data.__type, msg) + TriggerEvent(data.__namespace .. ':message:' .. data.__type, msg) Chunks[data.id] = nil end diff --git a/common/functions.lua b/common/functions.lua index e47b5b7f..ff4099eb 100644 --- a/common/functions.lua +++ b/common/functions.lua @@ -4,6 +4,19 @@ 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 +-- Be careful with this, use it for some config file parsing and such +ESX.EvalFile = function(resource, file, env) + + env = env or {} + env._G = env + local code = LoadResourceFile(resource, file) + + load(code, code, 't', env)() + + return env + +end + ESX.GetRandomString = function(length) math.randomseed(GetGameTimer()) diff --git a/config.lua b/config.lua index 8f6134ff..acba2923 100644 --- a/config.lua +++ b/config.lua @@ -10,21 +10,12 @@ Config.Accounts = { Config.StartingAccountMoney = {bank = 50000} Config.EnableSocietyPayouts = false -- pay from the society account that the player is employed at? Requirement: esx_society +Config.DisableWantedLevel = true Config.EnableHud = true -- enable the default hud? Display current job and accounts (black, bank & cash) +Config.EnablePvP = true -- enable pvp? Config.MaxWeight = 24 -- the max inventory weight without backpack -Config.PaycheckInterval = 7 * 60000 -- how often to recieve pay checks in milliseconds -Config.EnableDebug = false -Config.IncompatibleResourcesToStop = { - ['essentialmode'] = 'ES for short, the performance heavy RP framework no one uses - and source for the random unwanted ZAP ads you\'re seeing', - ['es_admin2'] = 'Adminstration tool for the ancient ES framework that wont work with ESX', - ['esplugin_mysql'] = 'MySQL "plugin" for the ancient ES framework that has a SQL injection vulnerability', - ['es_ui'] = 'Money HUD for ES', - ['spawnmanager'] = 'Default resource that takes care of spawning players, ESX does this already', - ['mapmanager'] = 'Default resource that was required by spawnmanager, but neither are used', - ['basic-gamemode'] = 'Resource that is solely for choosing the default game type', - ['fivem'] = 'Resource that is solely for choosing the default game type', - ['fivem-map-hipster'] = 'Default spawn locations for mapmanager', - ['fivem-map-skater'] = 'Default spawn locations for mapmanager', - ['baseevents'] = 'Default resource for handling death events, ESX does this already' -} +Config.PaycheckInterval = 7 * 60000 -- how often to recieve pay checks in milliseconds + +Config.EnableDebug = false +Config.InventoryKey = 'REPLAY_START_STOP_RECORDING_SECONDARY' -- Key F2 by default diff --git a/fxmanifest.lua b/fxmanifest.lua index 0f1c2f78..77150781 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -4,7 +4,7 @@ game 'gta5' description 'ES Extended' -version '1.2.0' +version '2.0.0' server_scripts { '@async/async.lua', @@ -65,40 +65,54 @@ client_scripts { 'common/modules/math.lua', 'common/modules/table.lua', - 'common/functions.lua' + 'common/functions.lua', } ui_page { - 'html/ui.html' + 'hud/index.html' } files { + 'client/bootstrap.lua', 'locale.js', - 'html/ui.html', - - 'html/css/app.css', - - 'html/js/mustache.min.js', - 'html/js/wrapper.js', - 'html/js/app.js', - - 'html/fonts/pdown.ttf', - 'html/fonts/bankgothic.ttf', - - 'html/img/accounts/bank.png', - 'html/img/accounts/black_money.png', - 'html/img/accounts/money.png' + 'hud/**/*', } exports { - 'getSharedObject' + 'getSharedObject', + 'OnESX', } server_exports { - 'getSharedObject' + 'getSharedObject', + 'OnESX', } dependencies { 'mysql-async', 'async' } + +-- ESX Modules +esxmodule = function(name) + + file('modules/' .. name .. '/data/**/*') + + client_script('modules/' .. name .. '/client/module.lua') + client_script('modules/' .. name .. '/client/main.lua') + client_script('modules/' .. name .. '/client/events.lua') + + server_script('modules/' .. name .. '/server/module.lua') + server_script('modules/' .. name .. '/server/main.lua') + server_script('modules/' .. name .. '/server/events.lua') + +end + +esxmodule 'input' +esxmodule 'hud' +esxmodule 'menu_default' +esxmodule 'menu_dialog' +esxmodule 'menu_list' +esxmodule 'interact' + +esxmodule 'job_police' diff --git a/hud/app.css b/hud/app.css new file mode 100644 index 00000000..d1ab073f --- /dev/null +++ b/hud/app.css @@ -0,0 +1,14 @@ +html, body, #frames, #frames > div, #frames > div > iframe { + width : 100vw; + height : 100vh; + margin : 0; + padding : 0; + border : 0; + background-color: transparent; +} + +#frames > div, #frames > div > iframe { + position: absolute; + left: 0; + top: 0; +} diff --git a/hud/app.js b/hud/app.js new file mode 100644 index 00000000..2a821f5a --- /dev/null +++ b/hud/app.js @@ -0,0 +1,109 @@ +(() => { + + class ESX { + + constructor() { + + this.frames = {}; + this.modulePath = '../modules'; + + window.addEventListener('message', e => this.onMessage(e.data)); + + $.post('http://es_extended/nui_ready', '{}'); + + } + + createFrame(name, url, visible = true) { + + const frame = document.createElement('div'); + const iframe = document.createElement('iframe'); + + frame.appendChild(iframe); + + iframe.src = url; + this.frames[name] = {frame, iframe}; + + this.frames[name].iframe.addEventListener('message', e => this.onFrameMessage(name, e.data)); + this.frames[name].frame.style.pointerEvents = 'none'; + + document.querySelector('#frames').appendChild(frame); + + if(!visible) + this.hideFrame(name); + + return this.frames[name]; + + } + + destroyFrame(name) { + document.querySelector('#frames').removeChild(this.frames[name].frame); + this.frames[name].frame.remove(); + } + + showFrame(name) { + this.frames[name].frame.style.display = 'block'; + } + + hideFrame(name) { + this.frames[name].frame.style.display = 'none'; + } + + focusFrame(name) { + + for(let k in this.frames) { + + if(k === name) + this.frames[k].frame.style.pointerEvents = 'all'; + else + this.frames[k].frame.style.pointerEvents = 'none'; + } + + this.frames[name].iframe.contentWindow.focus(); + + } + + onMessage(msg) { + + if(msg.target) { + + if(this.frames[msg.target]) + this.frames[msg.target].iframe.contentWindow.postMessage(msg.data); + else + console.error('[esx:nui] cannot find frame : ' + msg.target); + + } else { + + switch(msg.action) { + + case 'create_frame' : { + this.createFrame(msg.name, msg.url, msg.visible); + break; + } + + case 'destroy_frame' : { + this.destroyFrame(msg.name); + break; + } + + case 'focus_frame' : { + this.focusFrame(msg.name); + break; + } + + default: break; + } + + } + + + } + + onFrameMessage(name, msg) { + $.post('http://es_extended/frame_message', JSON.stringify({name, msg})); + } + + } + + ESX = new ESX(); + +})(); diff --git a/hud/index.html b/hud/index.html new file mode 100644 index 00000000..cf60df14 --- /dev/null +++ b/hud/index.html @@ -0,0 +1,13 @@ + + + esx + + + + +
+ + + + + diff --git a/hud/wrapper.js b/hud/wrapper.js new file mode 100644 index 00000000..df9523c9 --- /dev/null +++ b/hud/wrapper.js @@ -0,0 +1,43 @@ +(() => { + + let ESXWrapper = {}; + ESXWrapper.MessageSize = 1024; + ESXWrapper.messageId = 0; + + window.SendMessage = function (namespace, type, msg) { + + ESXWrapper.messageId = (ESXWrapper.messageId < 65535) ? ESXWrapper.messageId + 1 : 0; + const str = JSON.stringify(msg); + + for (let i = 0; i < str.length; i++) { + + let count = 0; + let chunk = ''; + + while (count < ESXWrapper.MessageSize && i < str.length) { + + chunk += str[i]; + + count++; + i++; + } + + i--; + + const data = { + __namespace: namespace, + __type: type, + id: ESXWrapper.messageId, + chunk: chunk + } + + if (i == str.length - 1) + data.end = true; + + $.post('http://es_extended/__chunk', JSON.stringify(data)); + + } + + } + +})() diff --git a/locale.lua b/locale.lua index 68de6651..c092385d 100644 --- a/locale.lua +++ b/locale.lua @@ -19,3 +19,13 @@ end function _U(str, ...) -- Translate string first char uppercase return tostring(_(str, ...):gsub("^%l", string.upper)) end + +function LoadLocale(ns, lang, data) + + Locales[lang] = Locales[lang] or {} + + for k,v in pairs(data) do + Locales[lang][ns .. ':' .. k] =v + end + +end diff --git a/locales/pl.lua b/locales/pl.lua index 35012487..2a04b378 100644 --- a/locales/pl.lua +++ b/locales/pl.lua @@ -10,9 +10,9 @@ Locales['pl'] = { ['giveammo'] = 'daj amunicje', ['amountammo'] = 'ilość amunicji', ['noammo'] = 'nie posiadasz wystarczającej ilości amunicji!', - ['gave_item'] = 'dałeś/aś ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', - ['received_item'] = 'otrzymałeś/aś ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', - ['gave_weapon'] = 'dałeś/aś ~b~%s~s~ dla ~y~%s~s~', + ['gave_item'] = 'dajesz ~y~%sx~s~ ~b~%s~s~ dla ~y~%s~s~', + ['received_item'] = 'otrzymujesz ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', + ['gave_weapon'] = 'dajesz ~b~%s~s~ dla ~y~%s~s~', ['gave_weapon_ammo'] = 'dałeś/aś ~o~%sx %s~s~ do ~b~%s~s~ dla ~y~%s~s~', ['gave_weapon_withammo'] = 'dałeś/aś ~b~%s~s~ z ~o~%sx %s~s~ dla ~y~%s~s~', ['gave_weapon_hasalready'] = '~y~%s~s~ już posiada ~y~%s~s~', @@ -22,8 +22,8 @@ Locales['pl'] = { ['received_weapon_withammo'] = 'otrzymałeś/aś ~b~%s~s~ z ~o~%sx %s~s~ od ~b~%s~s~', ['received_weapon_hasalready'] = '~b~%s~s~ próbował/a przekazać ci ~y~%s~s~, lecz już posiadasz jedno', ['received_weapon_noweapon'] = '~b~%s~s~ próbował/a przekazać ci amunicje do ~y~%s~s~, lecz nie posiadasz tej broni', - ['gave_account_money'] = 'dałeś/aś ~g~%s$~s~ (%s) dla ~y~%s~s~', - ['received_account_money'] = 'otrzymałeś/aś ~g~%s$~s~ (%s) od ~b~%s~s~', + ['gave_account_money'] = 'dajesz ~g~%s$~s~ (%s) dla ~y~%s~s~', + ['received_account_money'] = 'otrzymujesz ~g~%s$~s~ (%s) od ~b~%s~s~', ['amount_invalid'] = 'nieprawidłowa ilość', ['players_nearby'] = 'brak graczy w pobliżu', ['ex_inv_lim'] = 'akcja nie jest możliwa, nie możesz mieć więcej ~y~%s~s~', @@ -33,75 +33,76 @@ Locales['pl'] = { ['threw_account'] = 'wyrzuciłeś/aś ~g~$%s~s~ ~b~%s~s~', ['threw_weapon'] = 'wyrzuciłeś/aś ~b~%s~s~', ['threw_weapon_ammo'] = 'wyrzuciłeś/aś ~b~%s~s~ z ~o~%sx %s~s~', - ['threw_weapon_already'] = 'już posiadasz taką samą broń', - ['threw_cannot_pickup'] = 'nie możesz tego podnieść, gdyż masz pełny ekwipunek!', - ['threw_pickup_prompt'] = 'naciśnij ~y~E~s~ aby podnieść', + ['threw_weapon_already'] = 'you already carry the same weapon', + ['threw_cannot_pickup'] = 'you cannot pickup that because your inventory is full!', + ['threw_pickup_prompt'] = 'press ~y~E~s~ to pickup', -- Key mapping - ['keymap_showinventory'] = 'pokaż ekwipunek', + ['keymap_showinventory'] = 'show Inventory', -- Salary related - ['received_salary'] = 'otrzymałeś/aś wynagrodzenie: ~g~%s$~s~', - ['received_help'] = 'otrzymałeś/aś zapomogę: ~g~$%s~s~', + ['received_salary'] = 'otrzymałeś wynagrodzenie: ~g~%s$~s~', + ['received_help'] = 'otrzymałem zapomogę: ~g~$%s~s~', ['company_nomoney'] = 'firma, w której pracujesz, jest zbyt biedna, by wypłacić twoją pensję', - ['received_paycheck'] = 'otrzymano wypłate', + ['received_paycheck'] = 'otrzymana wypłata', ['bank'] = 'bank', ['account_bank'] = 'bank', - ['account_black_money'] = 'brudne pieniądze', - ['account_money'] = 'pieniądze', + ['account_black_money'] = 'dirty Money', + ['account_money'] = 'cash', + ['act_imp'] = 'działanie niemożliwe', ['in_vehicle'] = 'nie możesz przekazywać przedmiotów w pojeździe', -- Commands - ['command_car'] = 'przywołaj pojazd', - ['command_car_car'] = 'nazwa lub hash przywołanego pojazdu', - ['command_cardel'] = 'usuń pojazd w pobliżu', - ['command_cardel_radius'] = 'opcjonalnie usuń każdy pojazd w obszarze', - ['command_clear'] = 'wyczyść czat', - ['command_clearall'] = 'wyczyść czat dla wszystkich graczy', - ['command_clearinventory'] = 'wyczyść ekwipunek gracza', - ['command_clearloadout'] = 'wyczyść wyposarzenie gracza', - ['command_giveaccountmoney'] = 'daj pieniądze na podany typ konta', - ['command_giveaccountmoney_account'] = 'prawidłowy typ konta', - ['command_giveaccountmoney_amount'] = 'ilość do dodania', - ['command_giveaccountmoney_invalid'] = 'nieprawidłowy typ konta', - ['command_giveitem'] = 'daj przedmiot graczowi', - ['command_giveitem_item'] = 'nazwa przedmiotu', - ['command_giveitem_count'] = 'ilość przedimotu', - ['command_giveweapon'] = 'daj broń graczowi', - ['command_giveweapon_weapon'] = 'nazwa broni', - ['command_giveweapon_ammo'] = 'ilość amunicji', - ['command_giveweapon_hasalready'] = 'gracz już posiada tą broń', - ['command_giveweaponcomponent'] = 'daj komponent do broni graczowi', - ['command_giveweaponcomponent_component'] = 'nazwa komponentu', - ['command_giveweaponcomponent_invalid'] = 'nieprawidłowy komponent do broni', - ['command_giveweaponcomponent_hasalready'] = 'gracz już posiada ten komponent do tej broni', - ['command_giveweaponcomponent_missingweapon'] = 'gracz nie posiada tej broni', - ['command_save'] = 'zapisz gracza w bazie danych', - ['command_saveall'] = 'zapisz wszystkich graczy w bazie danych', - ['command_setaccountmoney'] = 'ustaw ilość pieniędzy danego konta dla gracza', - ['command_setaccountmoney_amount'] = 'ilość pieniędzy do ustawienia', - ['command_setcoords'] = 'teleportuj na koordynaty', + ['command_car'] = 'spawn an vehicle', + ['command_car_car'] = 'vehicle spawn name or hash', + ['command_cardel'] = 'delete vehicle in proximity', + ['command_cardel_radius'] = 'optional, delete every vehicle within the specified radius', + ['command_clear'] = 'clear chat', + ['command_clearall'] = 'clear chat for all players', + ['command_clearinventory'] = 'clear player inventory', + ['command_clearloadout'] = 'clear a player loadout', + ['command_giveaccountmoney'] = 'give account money', + ['command_giveaccountmoney_account'] = 'valid account name', + ['command_giveaccountmoney_amount'] = 'amount to add', + ['command_giveaccountmoney_invalid'] = 'invalid account name', + ['command_giveitem'] = 'give an item to a player', + ['command_giveitem_item'] = 'item name', + ['command_giveitem_count'] = 'item count', + ['command_giveweapon'] = 'give a weapon to a player', + ['command_giveweapon_weapon'] = 'weapon name', + ['command_giveweapon_ammo'] = 'ammo count', + ['command_giveweapon_hasalready'] = 'player already has that weapon', + ['command_giveweaponcomponent'] = 'give weapon component', + ['command_giveweaponcomponent_component'] = 'component name', + ['command_giveweaponcomponent_invalid'] = 'invalid weapon component', + ['command_giveweaponcomponent_hasalready'] = 'player already has that weapon component', + ['command_giveweaponcomponent_missingweapon'] = 'player does not have that weapon', + ['command_save'] = 'save a player to database', + ['command_saveall'] = 'save all players to database', + ['command_setaccountmoney'] = 'set account money for a player', + ['command_setaccountmoney_amount'] = 'amount of money to set', + ['command_setcoords'] = 'teleport to coordinates', ['command_setcoords_x'] = 'x axis', ['command_setcoords_y'] = 'y axis', ['command_setcoords_z'] = 'z axis', - ['command_setjob'] = 'ustaw prace dla gracza', - ['command_setjob_job'] = 'nazwa pracy', - ['command_setjob_grade'] = 'stanowisko w pracy', - ['command_setjob_invalid'] = 'praca, stanowisko lub obydwa są nieprawidłowe', - ['command_setgroup'] = 'ustaw grupe gracza', - ['command_setgroup_group'] = 'nazwa grupy', - ['commanderror_argumentmismatch'] = 'nieprawiłowa ilość argumentów (przeszło %s, wymagane %s)', - ['commanderror_argumentmismatch_number'] = 'nieprawidłowy typ argumentu #%s (przeszedł tekst, wymagany numer)', - ['commanderror_invaliditem'] = 'nieprawidłowa nazwa przedmiotu', - ['commanderror_invalidweapon'] = 'nieprawidłowa broń', - ['commanderror_console'] = 'podana komenda nie może zostać uruchomiona przez konsole', - ['commanderror_invalidcommand'] = '^3%s^0 nie jest poprawną komendą!', - ['commanderror_invalidplayerid'] = 'brak dostepnego gracza pasującego do podanego id serwerowego', - ['commandgeneric_playerid'] = 'id gracza', + ['command_setjob'] = 'set job for a player', + ['command_setjob_job'] = 'job name', + ['command_setjob_grade'] = 'job grade', + ['command_setjob_invalid'] = 'the job, grade or both are invalid', + ['command_setgroup'] = 'set player group', + ['command_setgroup_group'] = 'group name', + ['commanderror_argumentmismatch'] = 'argument count mismatch (passed %s, wanted %s)', + ['commanderror_argumentmismatch_number'] = 'argument #%s type mismatch (passed string, wanted number)', + ['commanderror_invaliditem'] = 'invalid item name', + ['commanderror_invalidweapon'] = 'invalid weapon', + ['commanderror_console'] = 'that command can not be run from console', + ['commanderror_invalidcommand'] = '^3%s^0 is not an valid command!', + ['commanderror_invalidplayerid'] = 'there is no player online matching that server id', + ['commandgeneric_playerid'] = 'player id', -- Locale settings - ['locale_digit_grouping_symbol'] = ',', + ['locale_digit_grouping_symbol'] = ' ', ['locale_currency'] = '$%s', -- Weapons @@ -183,42 +184,42 @@ Locales['pl'] = { -- Weapon Components ['component_clip_default'] = 'domyślny tłumik', ['component_clip_extended'] = 'rozszerzony tłumik', - ['component_clip_drum'] = 'magazynek bębnowy', - ['component_clip_box'] = 'magazynek', + ['component_clip_drum'] = 'drum Magazine', + ['component_clip_box'] = 'box Magazine', ['component_flashlight'] = 'latarka', ['component_scope'] = 'luneta', ['component_scope_advanced'] = 'zaawansowana luneta', ['component_suppressor'] = 'tłumik', ['component_grip'] = 'uchwyt', - ['component_luxary_finish'] = 'luksusowe wykończenie broni', + ['component_luxary_finish'] = 'luxary Weapon Finish', -- Weapon Ammo - ['ammo_rounds'] = 'nabój/oi', - ['ammo_shells'] = 'pocisk(ów)', - ['ammo_charge'] = 'naładowania', - ['ammo_petrol'] = 'galon(y) paliwa', - ['ammo_firework'] = 'fajerwerka/i', - ['ammo_rockets'] = 'rakieta/y', - ['ammo_grenadelauncher'] = 'granat(y)', - ['ammo_grenade'] = 'granat(y)', - ['ammo_stickybomb'] = 'bomba/y', - ['ammo_pipebomb'] = 'bomba/y', - ['ammo_smokebomb'] = 'bomba/y', - ['ammo_molotov'] = 'kontail(e)', - ['ammo_proxmine'] = 'mina/y', - ['ammo_bzgas'] = 'puszka/ek', - ['ammo_ball'] = 'kula/e', - ['ammo_snowball'] = 'snieżka/i', - ['ammo_flare'] = 'flara/y', - ['ammo_flaregun'] = 'flara/y', + ['ammo_rounds'] = 'round(s)', + ['ammo_shells'] = 'shell(s)', + ['ammo_charge'] = 'charge', + ['ammo_petrol'] = 'gallons of fuel', + ['ammo_firework'] = 'firework(s)', + ['ammo_rockets'] = 'rocket(s)', + ['ammo_grenadelauncher'] = 'grenade(s)', + ['ammo_grenade'] = 'grenade(s)', + ['ammo_stickybomb'] = 'bomb(s)', + ['ammo_pipebomb'] = 'bomb(s)', + ['ammo_smokebomb'] = 'bomb(s)', + ['ammo_molotov'] = 'cocktail(s)', + ['ammo_proxmine'] = 'mine(s)', + ['ammo_bzgas'] = 'can(s)', + ['ammo_ball'] = 'ball(s)', + ['ammo_snowball'] = 'snowball(s)', + ['ammo_flare'] = 'flare(s)', + ['ammo_flaregun'] = 'flare(s)', -- Weapon Tints - ['tint_default'] = 'domyślny skin', - ['tint_green'] = 'zielony skin', - ['tint_gold'] = 'złoty skin', - ['tint_pink'] = 'różowy skin', - ['tint_army'] = 'wojskowy skin', - ['tint_lspd'] = 'niebieski skin', - ['tint_orange'] = 'pomarańczowy skin', - ['tint_platinum'] = 'platynowy skin', + ['tint_default'] = 'default skin', + ['tint_green'] = 'green skin', + ['tint_gold'] = 'gold skin', + ['tint_pink'] = 'pink skin', + ['tint_army'] = 'army skin', + ['tint_lspd'] = 'blue skin', + ['tint_orange'] = 'orange skin', + ['tint_platinum'] = 'platinum skin', } diff --git a/locales/sc.lua b/locales/sc.lua index 229403de..cfe39ae2 100644 --- a/locales/sc.lua +++ b/locales/sc.lua @@ -42,7 +42,7 @@ Locales['sc'] = { -- Salary related ['received_salary'] = '你收到了你的工资: ~g~$%s~s~', - ['received_help'] = '你领取到了你的失业救济金: ~g~$%s~s~', + ['received_help'] = '鉴于你良好的表现,系统赠送给你一些奖励: ~g~$%s~s~', ['company_nomoney'] = '你受雇的公司太穷了,无法支付你的工资。', ['received_paycheck'] = '收到转账', ['bank'] = '花园银行', diff --git a/locales/tc.lua b/locales/tc.lua index 663259fb..9e31c8db 100644 --- a/locales/tc.lua +++ b/locales/tc.lua @@ -42,7 +42,7 @@ Locales['tc'] = { -- Salary related ['received_salary'] = '您收到您的薪水: ~g~$%s~s~', - ['received_help'] = '你領取到了你的失業救濟金: ~g~$%s~s~', + ['received_help'] = '由於您表現良好,系統給予您一些獎勵: ~g~$%s~s~', ['company_nomoney'] = '您的公司太窮了,無法給予您薪水。', ['received_paycheck'] = '收到轉帳', ['bank'] = '花園銀行', diff --git a/modules/hud/client/events.lua b/modules/hud/client/events.lua new file mode 100644 index 00000000..9c491962 --- /dev/null +++ b/modules/hud/client/events.lua @@ -0,0 +1,5 @@ +local self = ESX.Modules['hud'] + +AddEventHandler('esx:nui_ready', function() + ESX.CreateFrame('hud', 'nui://' .. GetCurrentResourceName() .. '/modules/hud/data/html/ui.html') +end) diff --git a/modules/hud/client/main.lua b/modules/hud/client/main.lua new file mode 100644 index 00000000..3f66e079 --- /dev/null +++ b/modules/hud/client/main.lua @@ -0,0 +1,4 @@ + +local self = ESX.Modules['hud'] + + diff --git a/modules/hud/client/module.lua b/modules/hud/client/module.lua new file mode 100644 index 00000000..8c81ec03 --- /dev/null +++ b/modules/hud/client/module.lua @@ -0,0 +1,5 @@ +ESX.Modules['hud'] = {}; +local self = ESX.Modules['hud'] + + + diff --git a/html/css/app.css b/modules/hud/data/html/css/app.css similarity index 98% rename from html/css/app.css rename to modules/hud/data/html/css/app.css index b487523f..b6f1147c 100644 --- a/html/css/app.css +++ b/modules/hud/data/html/css/app.css @@ -20,8 +20,8 @@ html { 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; + top: 20; + right: 20; } #inventory_notifications { diff --git a/html/fonts/bankgothic.ttf b/modules/hud/data/html/fonts/bankgothic.ttf similarity index 100% rename from html/fonts/bankgothic.ttf rename to modules/hud/data/html/fonts/bankgothic.ttf diff --git a/html/fonts/pdown.ttf b/modules/hud/data/html/fonts/pdown.ttf similarity index 100% rename from html/fonts/pdown.ttf rename to modules/hud/data/html/fonts/pdown.ttf diff --git a/html/img/accounts/bank.png b/modules/hud/data/html/img/accounts/bank.png similarity index 100% rename from html/img/accounts/bank.png rename to modules/hud/data/html/img/accounts/bank.png diff --git a/html/img/accounts/black_money.png b/modules/hud/data/html/img/accounts/black_money.png similarity index 100% rename from html/img/accounts/black_money.png rename to modules/hud/data/html/img/accounts/black_money.png diff --git a/html/img/accounts/money.png b/modules/hud/data/html/img/accounts/money.png similarity index 100% rename from html/img/accounts/money.png rename to modules/hud/data/html/img/accounts/money.png diff --git a/html/js/app.js b/modules/hud/data/html/js/app.js similarity index 100% rename from html/js/app.js rename to modules/hud/data/html/js/app.js diff --git a/html/js/mustache.min.js b/modules/hud/data/html/js/mustache.min.js similarity index 100% rename from html/js/mustache.min.js rename to modules/hud/data/html/js/mustache.min.js diff --git a/html/js/wrapper.js b/modules/hud/data/html/js/wrapper.js similarity index 88% rename from html/js/wrapper.js rename to modules/hud/data/html/js/wrapper.js index 0d208709..d85201b1 100644 --- a/html/js/wrapper.js +++ b/modules/hud/data/html/js/wrapper.js @@ -33,7 +33,7 @@ if (i == str.length - 1) data.end = true; - $.post('http://' + namespace + '/__chunk', JSON.stringify(data)); + $.post('http://' + GetCurrentResourceName() + '/__chunk', JSON.stringify(data)); } diff --git a/html/ui.html b/modules/hud/data/html/ui.html similarity index 100% rename from html/ui.html rename to modules/hud/data/html/ui.html diff --git a/modules/hud/server/events.lua b/modules/hud/server/events.lua new file mode 100644 index 00000000..d0124661 --- /dev/null +++ b/modules/hud/server/events.lua @@ -0,0 +1,2 @@ +local self = ESX.Modules['hud'] + diff --git a/modules/hud/server/main.lua b/modules/hud/server/main.lua new file mode 100644 index 00000000..52b7e9d2 --- /dev/null +++ b/modules/hud/server/main.lua @@ -0,0 +1,3 @@ + +local self = ESX.Modules['hud'] + diff --git a/modules/hud/server/module.lua b/modules/hud/server/module.lua new file mode 100644 index 00000000..e1db6d5c --- /dev/null +++ b/modules/hud/server/module.lua @@ -0,0 +1,3 @@ +ESX.Modules['hud'] = {}; +local self = ESX.Modules['hud'] + diff --git a/modules/input/client/events.lua b/modules/input/client/events.lua new file mode 100644 index 00000000..6a248bdc --- /dev/null +++ b/modules/input/client/events.lua @@ -0,0 +1 @@ +local self = ESX.Modules['input'] diff --git a/modules/input/client/main.lua b/modules/input/client/main.lua new file mode 100644 index 00000000..12f29bb1 --- /dev/null +++ b/modules/input/client/main.lua @@ -0,0 +1,67 @@ +local self = ESX.Modules['input'] + +Citizen.CreateThread(function() + while true do + + local events = { + pressed = {}, + released = {}, + dpressed = {}, + dreleased = {}, + } + + for group, ids in pairs(self.RegisteredControls) do + + for i=1, #ids, 1 do + + local id = ids[i] + + if self.IsControlEnabled(group, id) then + + if IsControlJustPressed(group, id) then + events.pressed[#events.pressed + 1] = {group, id, self.LastPressed[group][id]} + end + + if IsControlJustReleased(group, id) then + events.released[#events.released + 1] = {group, id, self.LastReleased[group][id]} + end + + else + + DisableControlAction(group, id, true); + + if IsDisabledControlJustPressed(group, id) then + events.dpressed[#events.dpressed + 1] = {group, id, self.LastDisabledPressed[group][id]} + self.LastDisabledPressed[group][id] = GetGameTimer() + end + + if IsDisabledControlJustReleased(group, id) then + events.dreleased[#events.dreleased + 1] = {group, id, self.LastDisabledReleased[group][id]} + self.LastDisabledReleased[group][id] = GetGameTimer() + end + + end + + end + end + + for i=1, #events.pressed, 1 do + TriggerEvent('esx:input:pressed:' .. events.pressed[i][1] .. ':' .. events.pressed[i][2], events.pressed[i][3]) + end + + for i=1, #events.released, 1 do + TriggerEvent('esx:input:released:' .. events.released[i][1] .. ':' .. events.released[i][2], events.released[i][3]) + end + + for i=1, #events.dpressed, 1 do + TriggerEvent('esx:input:disabled:pressed:' .. events.dpressed[i][1] .. ':' .. events.dpressed[i][2], events.dpressed[i][3]) + end + + for i=1, #events.dreleased, 1 do + TriggerEvent('esx:input:disabled:released:' .. events.dreleased[i][1] .. ':' .. events.dreleased[i][2], events.dreleased[i][3]) + end + + Citizen.Wait(0) + + end +end) diff --git a/modules/input/client/module.lua b/modules/input/client/module.lua new file mode 100644 index 00000000..7d8c5ea1 --- /dev/null +++ b/modules/input/client/module.lua @@ -0,0 +1,466 @@ +ESX.Modules['input'] = {} +local self = ESX.Modules['input'] +self.RegisteredControls = {} +self.EnabledControls = {} +self.LastPressed = {} +self.LastDisabledPressed = {} +self.LastReleased = {} +self.LastDisabledReleased = {} + +self.Groups = { + MOVE = 0, + LOOK = 1, + WHEEL = 2, + CELLPHONE_NAVIGATE = 3, + CELLPHONE_NAVIGATE_UD = 4, + CELLPHONE_NAVIGATE_LR = 5, + FRONTEND_DPAD_ALL = 6, + FRONTEND_DPAD_UD = 7, + FRONTEND_DPAD_LR = 8, + FRONTEND_LSTICK_ALL = 9, + FRONTEND_RSTICK_ALL = 10, + FRONTEND_GENERIC_UD = 11, + FRONTEND_GENERIC_LR = 12, + FRONTEND_GENERIC_ALL = 13, + FRONTEND_BUMPERS = 14, + FRONTEND_TRIGGERS = 15, + FRONTEND_STICKS = 16, + SCRIPT_DPAD_ALL = 17, + SCRIPT_DPAD_UD = 18, + SCRIPT_DPAD_LR = 19, + SCRIPT_LSTICK_ALL = 20, + SCRIPT_RSTICK_ALL = 21, + SCRIPT_BUMPERS = 22, + SCRIPT_TRIGGERS = 23, + WEAPON_WHEEL_CYCLE = 24, + FLY = 25, + SUB = 26, + VEH_MOVE_ALL = 27, + CURSOR = 28, + CURSOR_SCROLL = 29, + SNIPER_ZOOM_SECONDARY = 30, + VEH_HYDRAULICS_CONTROL = 31, +} + +self.Controls = { + NEXT_CAMERA = 0, + LOOK_LR = 1, + LOOK_UD = 2, + LOOK_UP_ONLY = 3, + LOOK_DOWN_ONLY = 4, + LOOK_LEFT_ONLY = 5, + LOOK_RIGHT_ONLY = 6, + CINEMATIC_SLOWMO = 7, + SCRIPTED_FLY_UD = 8, + SCRIPTED_FLY_LR = 9, + SCRIPTED_FLY_ZUP = 10, + SCRIPTED_FLY_ZDOWN = 11, + WEAPON_WHEEL_UD = 12, + WEAPON_WHEEL_LR = 13, + WEAPON_WHEEL_NEXT = 14, + WEAPON_WHEEL_PREV = 15, + SELECT_NEXT_WEAPON = 16, + SELECT_PREV_WEAPON = 17, + SKIP_CUTSCENE = 18, + CHARACTER_WHEEL = 19, + MULTIPLAYER_INFO = 20, + SPRINT = 21, + JUMP = 22, + ENTER = 23, + ATTACK = 24, + AIM = 25, + LOOK_BEHIND = 26, + PHONE = 27, + SPECIAL_ABILITY = 28, + SPECIAL_ABILITY_SECONDARY = 29, + MOVE_LR = 30, + MOVE_UD = 31, + MOVE_UP_ONLY = 32, + MOVE_DOWN_ONLY = 33, + MOVE_LEFT_ONLY = 34, + MOVE_RIGHT_ONLY = 35, + DUCK = 36, + SELECT_WEAPON = 37, + PICKUP = 38, + SNIPER_ZOOM = 39, + SNIPER_ZOOM_IN_ONLY = 40, + SNIPER_ZOOM_OUT_ONLY = 41, + SNIPER_ZOOM_IN_SECONDARY = 42, + SNIPER_ZOOM_OUT_SECONDARY = 43, + COVER = 44, + RELOAD = 45, + TALK = 46, + DETONATE = 47, + HUD_SPECIAL = 48, + ARREST = 49, + ACCURATE_AIM = 50, + CONTEXT = 51, + CONTEXT_SECONDARY = 52, + WEAPON_SPECIAL = 53, + WEAPON_SPECIAL_TWO = 54, + DIVE = 55, + DROP_WEAPON = 56, + DROP_AMMO = 57, + THROW_GRENADE = 58, + VEH_MOVE_LR = 59, + VEH_MOVE_UD = 60, + VEH_MOVE_UP_ONLY = 61, + VEH_MOVE_DOWN_ONLY = 62, + VEH_MOVE_LEFT_ONLY = 63, + VEH_MOVE_RIGHT_ONLY = 64, + VEH_SPECIAL = 65, + VEH_GUN_LR = 66, + VEH_GUN_UD = 67, + VEH_AIM = 68, + VEH_ATTACK = 69, + VEH_ATTACK2 = 70, + VEH_ACCELERATE = 71, + VEH_BRAKE = 72, + VEH_DUCK = 73, + VEH_HEADLIGHT = 74, + VEH_EXIT = 75, + VEH_HANDBRAKE = 76, + VEH_HOTWIRE_LEFT = 77, + VEH_HOTWIRE_RIGHT = 78, + VEH_LOOK_BEHIND = 79, + VEH_CIN_CAM = 80, + VEH_NEXT_RADIO = 81, + VEH_PREV_RADIO = 82, + VEH_NEXT_RADIO_TRACK = 83, + VEH_PREV_RADIO_TRACK = 84, + VEH_RADIO_WHEEL = 85, + VEH_HORN = 86, + VEH_FLY_THROTTLE_UP = 87, + VEH_FLY_THROTTLE_DOWN = 88, + VEH_FLY_YAW_LEFT = 89, + VEH_FLY_YAW_RIGHT = 90, + VEH_PASSENGER_AIM = 91, + VEH_PASSENGER_ATTACK = 92, + VEH_SPECIAL_ABILITY_FRANKLIN = 93, + VEH_STUNT_UD = 94, + VEH_CINEMATIC_UD = 95, + VEH_CINEMATIC_UP_ONLY = 96, + VEH_CINEMATIC_DOWN_ONLY = 97, + VEH_CINEMATIC_LR = 98, + VEH_SELECT_NEXT_WEAPON = 99, + VEH_SELECT_PREV_WEAPON = 100, + VEH_ROOF = 101, + VEH_JUMP = 102, + VEH_GRAPPLING_HOOK = 103, + VEH_SHUFFLE = 104, + VEH_DROP_PROJECTILE = 105, + VEH_MOUSE_CONTROL_OVERRIDE = 106, + VEH_FLY_ROLL_LR = 107, + VEH_FLY_ROLL_LEFT_ONLY = 108, + VEH_FLY_ROLL_RIGHT_ONLY = 109, + VEH_FLY_PITCH_UD = 110, + VEH_FLY_PITCH_UP_ONLY = 111, + VEH_FLY_PITCH_DOWN_ONLY = 112, + VEH_FLY_UNDERCARRIAGE = 113, + VEH_FLY_ATTACK = 114, + VEH_FLY_SELECT_NEXT_WEAPON = 115, + VEH_FLY_SELECT_PREV_WEAPON = 116, + VEH_FLY_SELECT_TARGET_LEFT = 117, + VEH_FLY_SELECT_TARGET_RIGHT = 118, + VEH_FLY_VERTICAL_FLIGHT_MODE = 119, + VEH_FLY_DUCK = 120, + VEH_FLY_ATTACK_CAMERA = 121, + VEH_FLY_MOUSE_CONTROL_OVERRIDE = 122, + VEH_SUB_TURN_LR = 123, + VEH_SUB_TURN_LEFT_ONLY = 124, + VEH_SUB_TURN_RIGHT_ONLY = 125, + VEH_SUB_PITCH_UD = 126, + VEH_SUB_PITCH_UP_ONLY = 127, + VEH_SUB_PITCH_DOWN_ONLY = 128, + VEH_SUB_THROTTLE_UP = 129, + VEH_SUB_THROTTLE_DOWN = 130, + VEH_SUB_ASCEND = 131, + VEH_SUB_DESCEND = 132, + VEH_SUB_TURN_HARD_LEFT = 133, + VEH_SUB_TURN_HARD_RIGHT = 134, + VEH_SUB_MOUSE_CONTROL_OVERRIDE = 135, + VEH_PUSHBIKE_PEDAL = 136, + VEH_PUSHBIKE_SPRINT = 137, + VEH_PUSHBIKE_FRONT_BRAKE = 138, + VEH_PUSHBIKE_REAR_BRAKE = 139, + MELEE_ATTACK_LIGHT = 140, + MELEE_ATTACK_HEAVY = 141, + MELEE_ATTACK_ALTERNATE = 142, + MELEE_BLOCK = 143, + PARACHUTE_DEPLOY = 144, + PARACHUTE_DETACH = 145, + PARACHUTE_TURN_LR = 146, + PARACHUTE_TURN_LEFT_ONLY = 147, + PARACHUTE_TURN_RIGHT_ONLY = 148, + PARACHUTE_PITCH_UD = 149, + PARACHUTE_PITCH_UP_ONLY = 150, + PARACHUTE_PITCH_DOWN_ONLY = 151, + PARACHUTE_BRAKE_LEFT = 152, + PARACHUTE_BRAKE_RIGHT = 153, + PARACHUTE_SMOKE = 154, + PARACHUTE_PRECISION_LANDING = 155, + MAP = 156, + SELECT_WEAPON_UNARMED = 157, + SELECT_WEAPON_MELEE = 158, + SELECT_WEAPON_HANDGUN = 159, + SELECT_WEAPON_SHOTGUN = 160, + SELECT_WEAPON_SMG = 161, + SELECT_WEAPON_AUTO_RIFLE = 162, + SELECT_WEAPON_SNIPER = 163, + SELECT_WEAPON_HEAVY = 164, + SELECT_WEAPON_SPECIAL = 165, + SELECT_CHARACTER_MICHAEL = 166, + SELECT_CHARACTER_FRANKLIN = 167, + SELECT_CHARACTER_TREVOR = 168, + SELECT_CHARACTER_MULTIPLAYER = 169, + SAVE_REPLAY_CLIP = 170, + SPECIAL_ABILITY_PC = 171, + CELLPHONE_UP = 172, + CELLPHONE_DOWN = 173, + CELLPHONE_LEFT = 174, + CELLPHONE_RIGHT = 175, + CELLPHONE_SELECT = 176, + CELLPHONE_CANCEL = 177, + CELLPHONE_OPTION = 178, + CELLPHONE_EXTRA_OPTION = 179, + CELLPHONE_SCROLL_FORWARD = 180, + CELLPHONE_SCROLL_BACKWARD = 181, + CELLPHONE_CAMERA_FOCUS_LOCK = 182, + CELLPHONE_CAMERA_GRID = 183, + CELLPHONE_CAMERA_SELFIE = 184, + CELLPHONE_CAMERA_DOF = 185, + CELLPHONE_CAMERA_EXPRESSION = 186, + FRONTEND_DOWN = 187, + FRONTEND_UP = 188, + FRONTEND_LEFT = 189, + FRONTEND_RIGHT = 190, + FRONTEND_RDOWN = 191, + FRONTEND_RUP = 192, + FRONTEND_RLEFT = 193, + FRONTEND_RRIGHT = 194, + FRONTEND_AXIS_X = 195, + FRONTEND_AXIS_Y = 196, + FRONTEND_RIGHT_AXIS_X = 197, + FRONTEND_RIGHT_AXIS_Y = 198, + FRONTEND_PAUSE = 199, + FRONTEND_PAUSE_ALTERNATE = 200, + FRONTEND_ACCEPT = 201, + FRONTEND_CANCEL = 202, + FRONTEND_X = 203, + FRONTEND_Y = 204, + FRONTEND_LB = 205, + FRONTEND_RB = 206, + FRONTEND_LT = 207, + FRONTEND_RT = 208, + FRONTEND_LS = 209, + FRONTEND_RS = 210, + FRONTEND_LEADERBOARD = 211, + FRONTEND_SOCIAL_CLUB = 212, + FRONTEND_SOCIAL_CLUB_SECONDARY = 213, + FRONTEND_DELETE = 214, + FRONTEND_ENDSCREEN_ACCEPT = 215, + FRONTEND_ENDSCREEN_EXPAND = 216, + FRONTEND_SELECT = 217, + SCRIPT_LEFT_AXIS_X = 218, + SCRIPT_LEFT_AXIS_Y = 219, + SCRIPT_RIGHT_AXIS_X = 220, + SCRIPT_RIGHT_AXIS_Y = 221, + SCRIPT_RUP = 222, + SCRIPT_RDOWN = 223, + SCRIPT_RLEFT = 224, + SCRIPT_RRIGHT = 225, + SCRIPT_LB = 226, + SCRIPT_RB = 227, + SCRIPT_LT = 228, + SCRIPT_RT = 229, + SCRIPT_LS = 230, + SCRIPT_RS = 231, + SCRIPT_PAD_UP = 232, + SCRIPT_PAD_DOWN = 233, + SCRIPT_PAD_LEFT = 234, + SCRIPT_PAD_RIGHT = 235, + SCRIPT_SELECT = 236, + CURSOR_ACCEPT = 237, + CURSOR_CANCEL = 238, + CURSOR_X = 239, + CURSOR_Y = 240, + CURSOR_SCROLL_UP = 241, + CURSOR_SCROLL_DOWN = 242, + ENTER_CHEAT_CODE = 243, + INTERACTION_MENU = 244, + MP_TEXT_CHAT_ALL = 245, + MP_TEXT_CHAT_TEAM = 246, + MP_TEXT_CHAT_FRIENDS = 247, + MP_TEXT_CHAT_CREW = 248, + PUSH_TO_TALK = 249, + CREATOR_LS = 250, + CREATOR_RS = 251, + CREATOR_LT = 252, + CREATOR_RT = 253, + CREATOR_MENU_TOGGLE = 254, + CREATOR_ACCEPT = 255, + CREATOR_DELETE = 256, + ATTACK2 = 257, + RAPPEL_JUMP = 258, + RAPPEL_LONG_JUMP = 259, + RAPPEL_SMASH_WINDOW = 260, + PREV_WEAPON = 261, + NEXT_WEAPON = 262, + MELEE_ATTACK1 = 263, + MELEE_ATTACK2 = 264, + WHISTLE = 265, + MOVE_LEFT = 266, + MOVE_RIGHT = 267, + MOVE_UP = 268, + MOVE_DOWN = 269, + LOOK_LEFT = 270, + LOOK_RIGHT = 271, + LOOK_UP = 272, + LOOK_DOWN = 273, + SNIPER_ZOOM_IN = 274, + SNIPER_ZOOM_OUT = 275, + SNIPER_ZOOM_IN_ALTERNATE = 276, + SNIPER_ZOOM_OUT_ALTERNATE = 277, + VEH_MOVE_LEFT = 278, + VEH_MOVE_RIGHT = 279, + VEH_MOVE_UP = 280, + VEH_MOVE_DOWN = 281, + VEH_GUN_LEFT = 282, + VEH_GUN_RIGHT = 283, + VEH_GUN_UP = 284, + VEH_GUN_DOWN = 285, + VEH_LOOK_LEFT = 286, + VEH_LOOK_RIGHT = 287, + REPLAY_START_STOP_RECORDING = 288, + REPLAY_START_STOP_RECORDING_SECONDARY = 289, + SCALED_LOOK_LR = 290, + SCALED_LOOK_UD = 291, + SCALED_LOOK_UP_ONLY = 292, + SCALED_LOOK_DOWN_ONLY = 293, + SCALED_LOOK_LEFT_ONLY = 294, + SCALED_LOOK_RIGHT_ONLY = 295, + REPLAY_MARKER_DELETE = 296, + REPLAY_CLIP_DELETE = 297, + REPLAY_PAUSE = 298, + REPLAY_REWIND = 299, + REPLAY_FFWD = 300, + REPLAY_NEWMARKER = 301, + REPLAY_RECORD = 302, + REPLAY_SCREENSHOT = 303, + REPLAY_HIDEHUD = 304, + REPLAY_STARTPOINT = 305, + REPLAY_ENDPOINT = 306, + REPLAY_ADVANCE = 307, + REPLAY_BACK = 308, + REPLAY_TOOLS = 309, + REPLAY_RESTART = 310, + REPLAY_SHOWHOTKEY = 311, + REPLAY_CYCLEMARKERLEFT = 312, + REPLAY_CYCLEMARKERRIGHT = 313, + REPLAY_FOVINCREASE = 314, + REPLAY_FOVDECREASE = 315, + REPLAY_CAMERAUP = 316, + REPLAY_CAMERADOWN = 317, + REPLAY_SAVE = 318, + REPLAY_TOGGLETIME = 319, + REPLAY_TOGGLETIPS = 320, + REPLAY_PREVIEW = 321, + REPLAY_TOGGLE_TIMELINE = 322, + REPLAY_TIMELINE_PICKUP_CLIP = 323, + REPLAY_TIMELINE_DUPLICATE_CLIP = 324, + REPLAY_TIMELINE_PLACE_CLIP = 325, + REPLAY_CTRL = 326, + REPLAY_TIMELINE_SAVE = 327, + REPLAY_PREVIEW_AUDIO = 328, + VEH_DRIVE_LOOK = 329, + VEH_DRIVE_LOOK2 = 330, + VEH_FLY_ATTACK2 = 331, + RADIO_WHEEL_UD = 332, + RADIO_WHEEL_LR = 333, + VEH_SLOWMO_UD = 334, + VEH_SLOWMO_UP_ONLY = 335, + VEH_SLOWMO_DOWN_ONLY = 336, + VEH_HYDRAULICS_CONTROL_TOGGLE = 337, + VEH_HYDRAULICS_CONTROL_LEFT = 338, + VEH_HYDRAULICS_CONTROL_RIGHT = 339, + VEH_HYDRAULICS_CONTROL_UP = 340, + VEH_HYDRAULICS_CONTROL_DOWN = 341, + VEH_HYDRAULICS_CONTROL_UD = 342, + VEH_HYDRAULICS_CONTROL_LR = 343, + MAP_POI = 344, + INPUT_REPLAY_SNAPMATIC_PHOTO = 345, +} + +self.RegisterControl = function(group, id) + if ESX.Table.IndexOf(self.RegisteredControls[group], id) == -1 then + self.RegisteredControls[group][#self.RegisteredControls[group] + 1] = id + end +end + +self.UnregisterControl = function(group, id) + if ESX.Table.IndexOf(self.RegisteredControls[group], id) ~= -1 then + table.remove(self.RegisteredControls[group], ESX.Table.IndexOf(self.RegisteredControls[group], id)) + end +end + +self.EnableControl = function(group, id) + self.EnabledControls[group][id] = self.EnabledControls[group][id] + 1 +end + +self.DisableControl = function(group, id) + self.EnabledControls[group][id] = self.EnabledControls[group][id] - 1 +end + +self.IsControlRegistered = function(group, id) + return ESX.Table.IndexOf(self.RegisteredControls[group], id) ~= -1 +end + +self.IsControlPressed = function(group, id) + return self.IsControlEnabled(group, id) and (IsControlPressed(group, id)) +end + +self.IsDisabledControlPressed = function(group, id) + return (not self.IsControlEnabled(group, id)) and (IsDisabledControlPressed(group, id)) +end + +self.IsControlEnabled = function(group, id) + return self.EnabledControls[group][id] >= 0 +end + +for k1, group in pairs(self.Groups) do + + self.RegisteredControls[group] = {} + self.EnabledControls[group] = {} + self.LastPressed[group] = {} + self.LastDisabledPressed[group] = {} + self.LastReleased[group] = {} + self.LastDisabledReleased[group] = {} + + for k2, id in pairs(self.Controls) do + self.EnabledControls[group][id] = 0 + self.LastPressed[group][id] = -1 + self.LastDisabledPressed[group][id] = -1 + self.LastReleased[group][id] = -1 + self.LastDisabledReleased[group][id] = -1 + end + +end + +self.On = function(event, group, id, cb) + + return AddEventHandler('esx:input:' .. event .. ':' .. group .. ':' .. id, cb) + +end + +self.InitESX = function() + + self.RegisterControl(Input.Groups.MOVE, Input.Controls[Config.InventoryKey]) + self.On('released', Input.Groups.MOVE, Input.Controls[Config.InventoryKey], function(lastPressed) + + if (not ESX.IsDead) and (not ESX.UI.Menu.IsOpen('default', 'es_extended', 'inventory')) then + ESX.ShowInventory() + end + + end) + +end diff --git a/modules/input/server/events.lua b/modules/input/server/events.lua new file mode 100644 index 00000000..6a248bdc --- /dev/null +++ b/modules/input/server/events.lua @@ -0,0 +1 @@ +local self = ESX.Modules['input'] diff --git a/modules/input/server/main.lua b/modules/input/server/main.lua new file mode 100644 index 00000000..6a248bdc --- /dev/null +++ b/modules/input/server/main.lua @@ -0,0 +1 @@ +local self = ESX.Modules['input'] diff --git a/modules/input/server/module.lua b/modules/input/server/module.lua new file mode 100644 index 00000000..1d041737 --- /dev/null +++ b/modules/input/server/module.lua @@ -0,0 +1,2 @@ +ESX.Modules['input'] = {} +local self = ESX.Modules['input'] diff --git a/modules/interact/client/events.lua b/modules/interact/client/events.lua new file mode 100644 index 00000000..caf76c7a --- /dev/null +++ b/modules/interact/client/events.lua @@ -0,0 +1,12 @@ +local self = ESX.Modules['interact'] + +AddEventHandler('esx:interact:register', self.Register) + +-- Do not use this in prod ! internal event only +AddEventHandler('esx:interact:enter', function(name, data) + TriggerEvent('esx:interact:enter:' .. name, data) +end) + +AddEventHandler('esx:interact:exit', function(name, data) + TriggerEvent('esx:interact:exit:' .. name, data) +end) diff --git a/modules/interact/client/main.lua b/modules/interact/client/main.lua new file mode 100644 index 00000000..78a956a9 --- /dev/null +++ b/modules/interact/client/main.lua @@ -0,0 +1,194 @@ +local self = ESX.Modules['interact'] + +self.LOVE_PLAYER_GROUP = AddRelationshipGroup('LOVE_PLAYER') + +SetRelationshipBetweenGroups(0, self.LOVE_PLAYER_GROUP, 'PLAYER') + +Citizen.CreateThread(function() + + while true do + + Citizen.Wait(100) + + local ped = PlayerPedId() + local coords = GetOffsetFromEntityInWorldCoords(ped, 0.0, 0.0, -1.0) + + self.Cache.player.ped = ped + self.Cache.player.coords = vector3(table.unpack(coords)) + + local toRemove = {} + + for i=1, #self.Data, 1 do + + local data = self.Data[i] + + if data.pos == nil then + + print('[esx_interact] data.pos is nil => ' .. json.encode(data)) + + else + + local distance = #(data.pos - self.Cache.player.coords); + if + (distance <= data.distance) and + (ESX.Table.FindIndex(self.Cache.current, function(e) return e.__id == data.__id end) == -1) + then + + if (data.check == nil) or data.check(self.Cache.player.ped, self.Cache.player.coords) then + data.playing = false + self.Cache.current[#self.Cache.current + 1] = data + end + + elseif (distance > data.distance) then + + local idx = ESX.Table.FindIndex(self.Cache.current, function(e) return e.__id == data.__id end) + + if idx ~= -1 then + toRemove[#toRemove + 1] = idx + end + + end + + end + + end + + if #toRemove > 0 then + self.Cache.current = ESX.Table.Filter(self.Cache.current, function(e) return ESX.Table.IndexOf(toRemove, e.__id) ~= -1 end) + end + + end + +end) + +-- Markers +Citizen.CreateThread(function() + while true do + + Citizen.Wait(0) + + for i=1, #self.Cache.current, 1 do + + local curr = self.Cache.current[i] + + if curr.type == 'marker' then + + DrawMarker( + curr.mtype, + curr.pos.x + 0.0, curr.pos.y + 0.0, curr.pos.z + 0.0, + 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, + curr.size.x + 0.0, curr.size.y + 0.0, curr.size.z + 0.0, + curr.color.r, curr.color.g, curr.color.b, curr.color.a, + curr.bobUpAndDown, curr.faceCamera, 2, curr.rotate, nil, nil, false + ) + + end + + end + + end +end) + +-- NPCs +Citizen.CreateThread(function() + while true do + + Citizen.Wait(1000) + + for i=1, #self.Cache.current, 1 do + + local curr = self.Cache.current[i] + + if curr.type == 'npc' then + + if IsModelValid(curr.model) and IsModelInCdimage(curr.model) then + + local found = false + + local closestPed, closestDistance = ESX.Game.GetClosestPed({ + x = curr.pos.x + 0.0, + y = curr.pos.y + 0.0, + z = curr.pos.z + 0.0 + }, {Cache.player.ped}) + + if closestPed ~= -1 then + + local model = GetEntityModel(closestPed) + + if (model == curr.model) and (closestDistance <= 10.0) then + + found = true + + if (curr.lib ~= nil) and (curr.anim ~= nil) then + + if not HasAnimDictLoaded(curr.lib) then + RequestAnimDict(curr.lib) + end + + if HasAnimDictLoaded(curr.lib) and (not curr.playing) then + curr.playing = true + TaskPlayAnim(closestPed, curr.lib, curr.anim, 8.0, -8.0, -1, 1, 1.0, false, false, false) + end + + end + + end + + end + + if not found then + + print('Create ped : ' .. curr.model .. ' @ ' .. curr.pos.x .. ' ' .. curr.pos.y .. ' ' .. curr.pos.z) + + RequestModel(curr.model) + + while not HasModelLoaded(curr.model) do + Citizen.Wait(0) + end + + curr.__ped = CreatePed(26, curr.model, curr.pos.x + 0.0, curr.pos.y + 0.0, curr.pos.z + 0.0, curr.heading + 0.0, true, false) + + SetModelAsNoLongerNeeded(curr.model) + + SetPedRelationshipGroupHash(curr.__ped, self.LOVE_PLAYER_GROUP) + SetBlockingOfNonTemporaryEvents(curr.__ped, true) + TaskStandStill(curr.__ped, -1) + SetEntityInvincible(curr.__ped, true) + FreezeEntityPosition(curr.__ped, true) + + end + + else + print('Invalid/inexistent model => ' .. curr.model) + end + + end + + end + + end +end) + +Citizen.CreateThread(function() + while true do + + Citizen.Wait(100) + + for i=1, #self.Cache.current, 1 do + + local data = self.Cache.current[i] + local distance = #(data.pos - self.Cache.player.coords); + + if (distance <= data.radius) and (not self.Cache.using[data.__id]) then + self.Cache.using[data.__id] = true + TriggerEvent('esx:interact:enter', data.name, data) + elseif (distance > data.radius) and self.Cache.using[data.__id] then + self.Cache.using[data.__id] = nil + TriggerEvent('esx:interact:exit', data.name, data) + end + + end + + end +end) diff --git a/modules/interact/client/module.lua b/modules/interact/client/module.lua new file mode 100644 index 00000000..7fab0039 --- /dev/null +++ b/modules/interact/client/module.lua @@ -0,0 +1,47 @@ +ESX.Modules['interact'] = {}; +local self = ESX.Modules['interact'] + +self.Id = 0 +self.Data = {} + +self.Cache = { + player = { + ped = 0, + coords = vector3(0.0, 0.0, 0.0) + }, + current = {}, + using = {}, +} + +self.Register = function(data) + + local idx = -1 + + for i=1, #self.Data, 1 do + if self.Data[i].name == data.name then + idx = i + break + end + end + + if self.Id >= 65535 then + data.__id = 1 + else + data.__id = self.Id + 1 + end + + data.size = (type(data.size) == 'number') and {x = data.size, y = data.size, z = data.size} or data.size + + if data.faceCamera == nil then data.faceCamera = false end + if data.bobUpAndDown == nil then data.bobUpAndDown = false end + if data.rotate == nil then data.rotate = false end + + self.Id = data.__id + + if idx == -1 then + self.Data[#self.Data + 1] = data + else + self.Data[idx] = data + end + +end diff --git a/modules/interact/server/events.lua b/modules/interact/server/events.lua new file mode 100644 index 00000000..841e735c --- /dev/null +++ b/modules/interact/server/events.lua @@ -0,0 +1,2 @@ +local self = ESX.Modules['interact'] + diff --git a/modules/interact/server/main.lua b/modules/interact/server/main.lua new file mode 100644 index 00000000..d1ba7452 --- /dev/null +++ b/modules/interact/server/main.lua @@ -0,0 +1,3 @@ + +local self = ESX.Modules['interact'] + diff --git a/modules/interact/server/module.lua b/modules/interact/server/module.lua new file mode 100644 index 00000000..fdccf53a --- /dev/null +++ b/modules/interact/server/module.lua @@ -0,0 +1,3 @@ +ESX.Modules['interact'] = {}; +local self = ESX.Modules['interact'] + diff --git a/modules/job_police/client/events.lua b/modules/job_police/client/events.lua new file mode 100644 index 00000000..961c7597 --- /dev/null +++ b/modules/job_police/client/events.lua @@ -0,0 +1,311 @@ +local self = ESX.Modules['job_police'] + +-- Locals +local Input = ESX.Modules['input'] + +RegisterNetEvent('esx:setJob') +AddEventHandler('esx:setJob', function(job) + Citizen.Wait(5000) + TriggerServerEvent('esx_policejob:forceBlip') +end) + +RegisterNetEvent('esx_phone:loaded') +AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) + + local specialContact = { + name = _U('job_police:phone_police'), + number = 'police', + base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDFGQTJDRkI0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDFGQTJDRkM0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MUZBMkNGOTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MUZBMkNGQTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoW66EYAAAjGSURBVHjapJcLcFTV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' + } + + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + +end) + +-- don't show dispatches if the player isn't in service +AddEventHandler('esx_phone:cancelMessage', function(dispatchNumber) + + if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and ESX.PlayerData.job.name == dispatchNumber then + -- if esx_service is enabled + if self.Config.EnableESXService and not playerInService then + CancelEvent() + end + end + +end) + +AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNum) + if part == 'Cloakroom' then + self.CurrentAction = 'menu_cloakroom' + self.CurrentActionMsg = _U('job_police:open_cloackroom') + self.CurrentActionData = {} + elseif part == 'Armory' then + self.CurrentAction = 'menu_armory' + self.CurrentActionMsg = _U('job_police:open_armory') + self.CurrentActionData = {station = station} + elseif part == 'Vehicles' then + self.CurrentAction = 'menu_vehicle_spawner' + self.CurrentActionMsg = _U('job_police:garage_prompt') + self.CurrentActionData = {station = station, part = part, partNum = partNum} + elseif part == 'Helicopters' then + self.CurrentAction = 'Helicopters' + self.CurrentActionMsg = _U('job_police:helicopter_prompt') + self.CurrentActionData = {station = station, part = part, partNum = partNum} + elseif part == 'BossActions' then + self.CurrentAction = 'menu_boss_actions' + self.CurrentActionMsg = _U('job_police:open_bossmenu') + self.CurrentActionData = {} + end +end) + +AddEventHandler('esx_policejob:hasExitedMarker', function(station, part, partNum) + if not isInShopMenu then + ESX.UI.Menu.CloseAll() + end + + self.CurrentAction = nil +end) + +AddEventHandler('esx_policejob:hasEnteredEntityZone', function(entity) + local playerPed = PlayerPedId() + + if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and IsPedOnFoot(playerPed) then + self.CurrentAction = 'remove_entity' + self.CurrentActionMsg = _U('job_police:remove_prop') + self.CurrentActionData = {entity = entity} + end + + if GetEntityModel(entity) == GetHashKey('p_ld_stinger_s') then + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + + if IsPedInAnyVehicle(playerPed, false) then + local vehicle = GetVehiclePedIsIn(playerPed) + + for i=0, 7, 1 do + SetVehicleTyreBurst(vehicle, i, true, 1000) + end + end + end +end) + +AddEventHandler('esx_policejob:hasExitedEntityZone', function(entity) + if self.CurrentAction == 'remove_entity' then + self.CurrentAction = nil + end +end) + +RegisterNetEvent('esx_policejob:handcuff') +AddEventHandler('esx_policejob:handcuff', function() + self.IsHandcuffed = not self.IsHandcuffed + local playerPed = PlayerPedId() + + if self.IsHandcuffed then + RequestAnimDict('mp_arresting') + while not HasAnimDictLoaded('mp_arresting') do + Citizen.Wait(100) + end + + TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0, 0, 0, 0) + + SetEnableHandcuffs(playerPed, true) + DisablePlayerFiring(playerPed, true) + SetCurrentPedWeapon(playerPed, GetHashKey('WEAPON_UNARMED'), true) -- unarm player + SetPedCanPlayGestureAnims(playerPed, false) + FreezeEntityPosition(playerPed, true) + DisplayRadar(false) + + if self.Config.EnableHandcuffTimer then + if handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) + end + + StartHandcuffTimer() + end + else + if self.Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) + end + + ClearPedSecondaryTask(playerPed) + SetEnableHandcuffs(playerPed, false) + DisablePlayerFiring(playerPed, false) + SetPedCanPlayGestureAnims(playerPed, true) + FreezeEntityPosition(playerPed, false) + DisplayRadar(true) + end +end) + +RegisterNetEvent('esx_policejob:unrestrain') +AddEventHandler('esx_policejob:unrestrain', function() + + if self.IsHandcuffed then + + local playerPed = PlayerPedId() + + self.IsHandcuffed = false + + ClearPedSecondaryTask(playerPed) + SetEnableHandcuffs(playerPed, false) + DisablePlayerFiring(playerPed, false) + SetPedCanPlayGestureAnims(playerPed, true) + FreezeEntityPosition(playerPed, false) + DisplayRadar(true) + + -- end timer + if self.Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) + end + end +end) + +RegisterNetEvent('esx_policejob:drag') +AddEventHandler('esx_policejob:drag', function(copId) + if self.IsHandcuffed then + dragStatus.isDragged = not dragStatus.isDragged + dragStatus.CopId = copId + end +end) + +RegisterNetEvent('esx_policejob:putInVehicle') +AddEventHandler('esx_policejob:putInVehicle', function() + if self.IsHandcuffed then + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + + if IsAnyVehicleNearPoint(coords, 5.0) then + local vehicle = GetClosestVehicle(coords, 5.0, 0, 71) + + if DoesEntityExist(vehicle) then + local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) + + for i=maxSeats - 1, 0, -1 do + if IsVehicleSeatFree(vehicle, i) then + freeSeat = i + break + end + end + + if freeSeat then + TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) + dragStatus.isDragged = false + end + end + end + end +end) + +RegisterNetEvent('esx_policejob:OutVehicle') +AddEventHandler('esx_policejob:OutVehicle', function() + local playerPed = PlayerPedId() + + if IsPedSittingInAnyVehicle(playerPed) then + local vehicle = GetVehiclePedIsIn(playerPed, false) + TaskLeaveVehicle(playerPed, vehicle, 16) + end +end) + +RegisterNetEvent('esx_policejob:updateBlip') +AddEventHandler('esx_policejob:updateBlip', function() + + -- Refresh all blips + for k, existingBlip in pairs(self.BlipsCops) do + RemoveBlip(existingBlip) + end + + -- Clean the blip table + self.BlipsCops = {} + + -- Enable blip? + if self.Config.EnableESXService and not playerInService then + return + end + + if not self.Config.EnableJobBlip then + return + end + + -- Is the player a cop? In that case show all the blips for other cops + if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then + ESX.TriggerServerCallback('esx_society:getOnlinePlayers', function(players) + for i=1, #players, 1 do + if players[i].job.name == 'police' then + local id = GetPlayerFromServerId(players[i].source) + if NetworkIsPlayerActive(id) and GetPlayerPed(id) ~= PlayerPedId() then + CreateBlip(id) + end + end + end + end) + end + +end) + +AddEventHandler('playerSpawned', function(spawn) + isDead = false + TriggerEvent('esx_policejob:unrestrain') + + if not hasAlreadyJoined then + TriggerServerEvent('esx_policejob:spawned') + end + hasAlreadyJoined = true +end) + +AddEventHandler('esx:onPlayerDeath', function(data) + isDead = true +end) + +AddEventHandler('onResourceStop', function(resource) + if resource == GetCurrentResourceName() then + TriggerEvent('esx_policejob:unrestrain') + TriggerEvent('esx_phone:removeSpecialContact', 'police') + + if self.Config.EnableESXService then + TriggerServerEvent('esx_service:disableService', 'police') + end + + if self.Config.EnableHandcuffTimer and self.HandcuffTimer.active then + ESX.ClearTimeout(self.HandcuffTimer.task) + end + end +end) + +-- Key Controls +Input.On('released', Input.Groups.MOVE, Input.Controls.PICKUP, function(lastPressed) + + if self.CurrentAction and self.IsPolice() then + self.CurrentAction() + self.CurrentAction = nil + end + +end) + +Input.On('released', Input.Groups.MOVE, Input.Controls.SELECT_CHARACTER_FRANKLIN, function(lastPressed) + + if (not self.IsDead) and self.IsPolice() and (not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions')) then + + if not self.Config.EnableESXService then + OpenPoliceActionsMenu() + elseif playerInService then + OpenPoliceActionsMenu() + else + ESX.ShowNotification(_U('job_police:service_not')) + end + + end + +end) + +Input.On('released', Input.Groups.MOVE, Input.Controls.PICKUP, function(lastPressed) + + if self.CurrentAction and self.IsPolice() and self.CurrentTask.busy then + + ESX.ShowNotification(_U('job_police:impound_canceled')) + ESX.ClearTimeout(self.CurrentTask.task) + ClearPedTasks(PlayerPedId()) + + self.CurrentTask.busy = false + + end + +end) diff --git a/modules/job_police/client/main.lua b/modules/job_police/client/main.lua new file mode 100644 index 00000000..b5a21e69 --- /dev/null +++ b/modules/job_police/client/main.lua @@ -0,0 +1,157 @@ +local self = ESX.Modules['job_police'] + +-- Init +self.Init() + +-- Drag +Citizen.CreateThread(function() + + local wasDragged = false + + while true do + Citizen.Wait(0) + local playerPed = PlayerPedId() + + if self.IsHandcuffed and self.DragStatus.isDragged then + + local targetPed = GetPlayerPed(GetPlayerFromServerId(self.DragStatus.CopId)) + + if DoesEntityExist(targetPed) and IsPedOnFoot(targetPed) and not IsPedDeadOrDying(targetPed, true) then + + if not wasDragged then + AttachEntityToEntity(playerPed, targetPed, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true) + wasDragged = true + else + Citizen.Wait(1000) + end + + else + + wasDragged = false + self.DragStatus.isDragged = false + DetachEntity(playerPed, true, false) + + end + + elseif wasDragged then + + wasDragged = false + DetachEntity(playerPed, true, false) + + else + + Citizen.Wait(500) + + end + + end +end) + +-- Handcuff +Citizen.CreateThread(function() + while true do + Citizen.Wait(0) + local playerPed = PlayerPedId() + + if self.IsHandcuffed then + DisableControlAction(0, 1, true) -- Disable pan + DisableControlAction(0, 2, true) -- Disable tilt + DisableControlAction(0, 24, true) -- Attack + DisableControlAction(0, 257, true) -- Attack 2 + DisableControlAction(0, 25, true) -- Aim + DisableControlAction(0, 263, true) -- Melee Attack 1 + DisableControlAction(0, 32, true) -- W + DisableControlAction(0, 34, true) -- A + DisableControlAction(0, 31, true) -- S + DisableControlAction(0, 30, true) -- D + + DisableControlAction(0, 45, true) -- Reload + DisableControlAction(0, 22, true) -- Jump + DisableControlAction(0, 44, true) -- Cover + DisableControlAction(0, 37, true) -- Select Weapon + DisableControlAction(0, 23, true) -- Also 'enter'? + + DisableControlAction(0, 288, true) -- Disable phone + DisableControlAction(0, 289, true) -- Inventory + DisableControlAction(0, 170, true) -- Animations + DisableControlAction(0, 167, true) -- Job + + DisableControlAction(0, 0, true) -- Disable changing view + DisableControlAction(0, 26, true) -- Disable looking behind + DisableControlAction(0, 73, true) -- Disable clearing animation + DisableControlAction(2, 199, true) -- Disable pause screen + + DisableControlAction(0, 59, true) -- Disable steering in vehicle + DisableControlAction(0, 71, true) -- Disable driving forward in vehicle + DisableControlAction(0, 72, true) -- Disable reversing in vehicle + + DisableControlAction(2, 36, true) -- Disable going stealth + + DisableControlAction(0, 47, true) -- Disable weapon + DisableControlAction(0, 264, true) -- Disable melee + DisableControlAction(0, 257, true) -- Disable melee + DisableControlAction(0, 140, true) -- Disable melee + DisableControlAction(0, 141, true) -- Disable melee + DisableControlAction(0, 142, true) -- Disable melee + DisableControlAction(0, 143, true) -- Disable melee + DisableControlAction(0, 75, true) -- Disable exit vehicle + DisableControlAction(27, 75, true) -- Disable exit vehicle + + if IsEntityPlayingAnim(playerPed, 'mp_arresting', 'idle', 3) ~= 1 then + ESX.Streaming.RequestAnimDict('mp_arresting', function() + TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0.0, false, false, false) + end) + end + else + Citizen.Wait(500) + end + end +end) + +-- Enter / Exit entity zone events +Citizen.CreateThread(function() + local trackedEntities = { + 'prop_roadcone02a', + 'prop_barrier_work05', + 'p_ld_stinger_s', + 'prop_boxpile_07d', + 'hei_prop_cash_crate_half_full' + } + + while true do + Citizen.Wait(500) + + local playerPed = PlayerPedId() + local playerCoords = GetEntityCoords(playerPed) + + local closestDistance = -1 + local closestEntity = nil + + for i=1, #trackedEntities, 1 do + local object = GetClosestObjectOfType(playerCoords, 3.0, GetHashKey(trackedEntities[i]), false, false, false) + + if DoesEntityExist(object) then + local objCoords = GetEntityCoords(object) + local distance = #(playerCoords - objCoords) + + if closestDistance == -1 or closestDistance > distance then + closestDistance = distance + closestEntity = object + end + end + end + + if closestDistance ~= -1 and closestDistance <= 3.0 then + if LastEntity ~= closestEntity then + TriggerEvent('esx_policejob:hasEnteredEntityZone', closestEntity) + LastEntity = closestEntity + end + else + if LastEntity then + TriggerEvent('esx_policejob:hasExitedEntityZone', LastEntity) + LastEntity = nil + end + end + end +end) + diff --git a/modules/job_police/client/module.lua b/modules/job_police/client/module.lua new file mode 100644 index 00000000..ed9d78dd --- /dev/null +++ b/modules/job_police/client/module.lua @@ -0,0 +1,1517 @@ +ESX.Modules['job_police'] = {} +local self = ESX.Modules['job_police'] + +-- Properties +self.Config = ESX.EvalFile(GetCurrentResourceName(), 'modules/job_police/data/config.lua', { + vector3 = vector3 +})['Config'] + +self.CurrentActionData = {} +self.HandcuffTimer = {} +self.DragStatus = {isDragged = false} +self.BlipsCops = {} +self.CurrentTask = {} +self.HasAlreadyEnteredMarker = false +self.IsDead = false +self.IsHandcuffed = false +self.HasAlreadyJoined = false +self.PlayerInService = false +self.LastStation = nil +self.LastPart = nil +self.LastPartNum = nil +self.LastEntity = nil +self.CurrentAction = nil +self.CurrentActionMsg = nil +self.IsInShopMenu = false +self.SpawnedVehicles = {} + +-- Locals +local Interact = ESX.Modules['interact'] +local Input = ESX.Modules['input'] + +-- Methods +self.Init = function() + + self.RegisterControls() + + local translations = ESX.EvalFile(GetCurrentResourceName(), 'modules/job_police/data/locales/' .. Config.Locale .. '.lua')['Translations'] + LoadLocale('job_police', Config.Locale, translations) + + for stationName, station in pairs(self.Config.PoliceStations) do + + -- Blip + local blip = AddBlipForCoord(station.Blip.Coords) + + SetBlipSprite (blip, station.Blip.Sprite) + SetBlipDisplay(blip, station.Blip.Display) + SetBlipScale (blip, station.Blip.Scale) + SetBlipColour (blip, station.Blip.Colour) + SetBlipAsShortRange(blip, true) + + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(_U('job_police:map_blip')) + EndTextCommandSetBlipName(blip) + + -- Cloakrooms + for i=1, #station.Cloakrooms, 1 do + + local cloakroom = station.Cloakrooms[i] + local key = 'job_police:' .. stationName .. 'cloakroom:' .. tostring(i) + + Interact.Register({ + name = key, + type = 'marker', + distance = self.Config.DrawDistance, + radius = 2.0, + pos = cloakroom, + size = 1.0, + mtype = 20, + color = self.Config.MarkerColor, + rotate = true, + check = self.IsPolice, + }) + + AddEventHandler('esx:interact:enter:' .. key, function(data) + + ESX.ShowHelpNotification(_U('job_police:open_cloackroom')) + + self.CurrentAction = function() + self.OpenCloakroomMenu(station) + end + + end) + + AddEventHandler('esx:interact:exit:' .. key, function(data) + self.CurrentAction = nil + end) + + end + + -- Armories + for i=1, #station.Armories, 1 do + + local armory = station.Armories[i] + local key = 'job_police:' .. stationName .. ':armory:' .. tostring(i) + + Interact.Register({ + name = key, + type = 'marker', + distance = self.Config.DrawDistance, + radius = 1.0, + pos = armory, + size = 0.5, + mtype = 21, + color = self.Config.MarkerColor, + rotate = true, + check = self.IsPolice, + }) + + AddEventHandler('esx:interact:enter:' .. key, function(data) + + ESX.ShowHelpNotification(_U('job_police:open_armory')) + + self.CurrentAction = function() + self.OpenArmoryMenu(station) + end + + end) + + AddEventHandler('esx:interact:exit:' .. key, function(data) + self.CurrentAction = nil + end) + + end + + -- Vehicles + for i=1, #station.Vehicles, 1 do + + local vehicle = station.Vehicles[i] + local key = 'job_police:' .. stationName .. ':garage:' .. tostring(i) + + Interact.Register({ + name = key, + type = 'marker', + distance = self.Config.DrawDistance, + radius = 2.0, + pos = vehicle.Spawner, + size = 1.0, + mtype = 36, + color = self.Config.MarkerColor, + rotate = true, + check = self.IsPolice, + config = vehicle + }) + + AddEventHandler('esx:interact:enter:' .. key, function(data) + + ESX.ShowHelpNotification(_U('job_police:garage_prompt')) + + self.CurrentAction = function() + self.OpenVehicleSpawnerMenu('car', data.config) + end + + end) + + AddEventHandler('esx:interact:exit:' .. key, function(data) + self.CurrentAction = nil + end) + + end + + -- Helicopters + for i=1, #station.Helicopters, 1 do + + local heli = station.Helicopters[i] + local key = 'job_police:' .. stationName .. ':garage_heli:' .. tostring(i) + + Interact.Register({ + name = key, + type = 'marker', + distance = self.Config.DrawDistance, + radius = 2.0, + pos = heli.Spawner, + size = 1.0, + mtype = 36, + color = self.Config.MarkerColor, + rotate = true, + check = self.IsPolice, + config = heli + }) + + AddEventHandler('esx:interact:enter:' .. key, function(data) + + ESX.ShowHelpNotification(_U('job_police:helicopter_prompt')) + + self.CurrentAction = function() + self.OpenVehicleSpawnerMenu('helicopter', data.config) + end + + end) + + AddEventHandler('esx:interact:exit:' .. key, function(data) + self.CurrentAction = nil + end) + + end + + end + +end + +self.RegisterControls = function() + + Input.RegisterControl(Input.Groups.MOVE, Input.Controls.PICKUP) + Input.RegisterControl(Input.Groups.MOVE, Input.Controls.SELECT_CHARACTER_FRANKLIN) + Input.RegisterControl(Input.Groups.MOVE, Input.Controls.PICKUP) + +end + +self.IsPolice = function(playerPed, coords) + return ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' +end + +self.CleanPlayer = function(playerPed) + SetPedArmour(playerPed, 0) + ClearPedBloodDamage(playerPed) + ResetPedVisibleDamage(playerPed) + ClearPedLastWeaponDamage(playerPed) + ResetPedMovementClipset(playerPed, 0) +end + +self.SetUniform = function(uniform, playerPed) + + TriggerEvent('skinchanger:getSkin', function(skin) + + local uniformObject + + if skin.sex == 0 then + uniformObject = self.Config.Uniforms[uniform].male + else + uniformObject = self.Config.Uniforms[uniform].female + end + + if uniformObject then + TriggerEvent('skinchanger:loadClothes', skin, uniformObject) + + if uniform == 'bullet_wear' then + SetPedArmour(playerPed, 100) + end + else + ESX.ShowNotification(_U('job_police:no_outfit')) + end + end) + +end + +self.OpenCloakroomMenu = function() + + local playerPed = PlayerPedId() + local grade = ESX.PlayerData.job.grade_name + + local elements = { + {label = _U('job_police:citizen_wear'), value = 'citizen_wear'}, + {label = _U('job_police:bullet_wear'), uniform = 'bullet_wear'}, + {label = _U('job_police:gilet_wear'), uniform = 'gilet_wear'}, + {label = _U('job_police:police_wear'), uniform = grade} + } + + if self.Config.EnableCustomPeds then + for k,v in ipairs(Config.CustomPeds.shared) do + table.insert(elements, {label = v.label, value = 'freemode_ped', maleModel = v.maleModel, femaleModel = v.femaleModel}) + end + + for k,v in ipairs(Config.CustomPeds[grade]) do + table.insert(elements, {label = v.label, value = 'freemode_ped', maleModel = v.maleModel, femaleModel = v.femaleModel}) + end + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'cloakroom', { + title = _U('job_police:cloakroom'), + align = 'top-left', + elements = elements + }, function(data, menu) + + menu.close() + + self.CleanPlayer(playerPed) + + if data.current.value == 'citizen_wear' then + if self.Config.EnableNonFreemodePeds then + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + local isMale = skin.sex == 0 + + TriggerEvent('skinchanger:loadDefaultModel', isMale, function() + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + TriggerEvent('esx:restoreLoadout') + end) + end) + + end) + else + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin) + TriggerEvent('skinchanger:loadSkin', skin) + end) + end + + if self.Config.EnableESXService then + ESX.TriggerServerCallback('esx_service:isInService', function(isInService) + if isInService then + PlayerInService = false + + local notification = { + title = _U('job_police:service_anonunce'), + subject = '', + msg = _U('job_police:service_out_announce', GetPlayerName(PlayerId())), + iconType = 1 + } + + TriggerServerEvent('esx_service:notifyAllInService', notification, 'police') + + TriggerServerEvent('esx_service:disableService', 'police') + TriggerEvent('esx_policejob:updateBlip') + ESX.ShowNotification(_U('job_police:service_out')) + end + end, 'police') + end + end + + if self.Config.EnableESXService and data.current.value ~= 'citizen_wear' then + local awaitService + + ESX.TriggerServerCallback('esx_service:isInService', function(isInService) + if not isInService then + + ESX.TriggerServerCallback('esx_service:enableService', function(canTakeService, maxInService, inServiceCount) + if not canTakeService then + ESX.ShowNotification(_U('job_police:service_max', inServiceCount, maxInService)) + else + awaitService = true + PlayerInService = true + + local notification = { + title = _U('job_police:service_anonunce'), + subject = '', + msg = _U('job_police:service_in_announce', GetPlayerName(PlayerId())), + iconType = 1 + } + + TriggerServerEvent('esx_service:notifyAllInService', notification, 'police') + TriggerEvent('esx_policejob:updateBlip') + ESX.ShowNotification(_U('job_police:service_in')) + end + end, 'police') + + else + awaitService = true + end + end, 'police') + + while awaitService == nil do + Citizen.Wait(5) + end + + -- if we couldn't enter service don't let the player get changed + if not awaitService then + return + end + end + + if data.current.uniform then + self.SetUniform(data.current.uniform, playerPed) + elseif data.current.value == 'freemode_ped' then + local modelHash + + ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin) + if skin.sex == 0 then + modelHash = GetHashKey(data.current.maleModel) + else + modelHash = GetHashKey(data.current.femaleModel) + end + + ESX.Streaming.RequestModel(modelHash, function() + SetPlayerModel(PlayerId(), modelHash) + SetModelAsNoLongerNeeded(modelHash) + SetPedDefaultComponentVariation(PlayerPedId()) + + TriggerEvent('esx:restoreLoadout') + end) + end) + end + end, function(data, menu) + + menu.close() + + end, nil, function() + + ESX.ShowHelpNotification(_U('job_police:open_cloackroom')) + + self.CurrentAction = function() + self.OpenCloakroomMenu(station) + end + + end) + +end + +self.OpenArmoryMenu = function(station) + local elements = { + {label = _U('job_police:buy_weapons'), value = 'buy_weapons'} + } + + if self.Config.EnableArmoryManagement then + table.insert(elements, {label = _U('job_police:get_weapon'), value = 'get_weapon'}) + table.insert(elements, {label = _U('job_police:put_weapon'), value = 'put_weapon'}) + table.insert(elements, {label = _U('job_police:remove_object'), value = 'get_stock'}) + table.insert(elements, {label = _U('job_police:deposit_object'), value = 'put_stock'}) + end + + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory', { + title = _U('job_police:armory'), + align = 'top-left', + elements = elements + }, function(data, menu) + + if data.current.value == 'get_weapon' then + self.OpenGetWeaponMenu() + elseif data.current.value == 'put_weapon' then + self.OpenPutWeaponMenu() + elseif data.current.value == 'buy_weapons' then + self.OpenBuyWeaponsMenu() + elseif data.current.value == 'put_stock' then + self.OpenPutStocksMenu() + elseif data.current.value == 'get_stock' then + self.OpenGetStocksMenu() + end + + end, function(data, menu) + menu.close() + end, nil, function() + + + ESX.ShowHelpNotification(_U('job_police:open_armory')) + + self.CurrentAction = function() + self.OpenArmoryMenu(station) + end + + return true + + end) + +end + +self.OpenPoliceActionsMenu = function() + ESX.UI.Menu.CloseAll() + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'police_actions', { + title = 'Police', + align = 'top-left', + elements = { + {label = _U('job_police:citizen_interaction'), value = 'citizen_interaction'}, + {label = _U('job_police:vehicle_interaction'), value = 'vehicle_interaction'}, + {label = _U('job_police:object_spawner'), value = 'object_spawner'} + }}, function(data, menu) + if data.current.value == 'citizen_interaction' then + local elements = { + {label = _U('job_police:id_card'), value = 'identity_card'}, + {label = _U('job_police:search'), value = 'search'}, + {label = _U('job_police:handcuff'), value = 'handcuff'}, + {label = _U('job_police:drag'), value = 'drag'}, + {label = _U('job_police:put_in_vehicle'), value = 'put_in_vehicle'}, + {label = _U('job_police:out_the_vehicle'), value = 'out_the_vehicle'}, + {label = _U('job_police:fine'), value = 'fine'}, + {label = _U('job_police:unpaid_bills'), value = 'unpaid_bills'} + } + + if self.Config.EnableLicenses then + table.insert(elements, {label = _U('job_police:license_check'), value = 'license'}) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', { + title = _U('job_police:citizen_interaction'), + align = 'top-left', + elements = elements + }, function(data2, menu2) + local closestPlayer, closestDistance = ESX.Game.GetClosestPlayer() + if closestPlayer ~= -1 and closestDistance <= 3.0 then + local action = data2.current.value + + if action == 'identity_card' then + OpenIdentityCardMenu(closestPlayer) + elseif action == 'search' then + OpenBodySearchMenu(closestPlayer) + elseif action == 'handcuff' then + TriggerServerEvent('esx_policejob:handcuff', GetPlayerServerId(closestPlayer)) + elseif action == 'drag' then + TriggerServerEvent('esx_policejob:drag', GetPlayerServerId(closestPlayer)) + elseif action == 'put_in_vehicle' then + TriggerServerEvent('esx_policejob:putInVehicle', GetPlayerServerId(closestPlayer)) + elseif action == 'out_the_vehicle' then + TriggerServerEvent('esx_policejob:OutVehicle', GetPlayerServerId(closestPlayer)) + elseif action == 'fine' then + OpenFineMenu(closestPlayer) + elseif action == 'license' then + ShowPlayerLicense(closestPlayer) + elseif action == 'unpaid_bills' then + OpenUnpaidBillsMenu(closestPlayer) + end + else + ESX.ShowNotification(_U('job_police:no_players_nearby')) + end + end, function(data2, menu2) + menu2.close() + end) + elseif data.current.value == 'vehicle_interaction' then + local elements = {} + local playerPed = PlayerPedId() + local vehicle = ESX.Game.GetVehicleInDirection() + + if DoesEntityExist(vehicle) then + table.insert(elements, {label = _U('job_police:vehicle_info'), value = 'vehicle_infos'}) + table.insert(elements, {label = _U('job_police:pick_lock'), value = 'hijack_vehicle'}) + table.insert(elements, {label = _U('job_police:impound'), value = 'impound'}) + end + + table.insert(elements, {label = _U('job_police:search_database'), value = 'search_database'}) + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_interaction', { + title = _U('job_police:vehicle_interaction'), + align = 'top-left', + elements = elements + }, function(data2, menu2) + local coords = GetEntityCoords(playerPed) + vehicle = ESX.Game.GetVehicleInDirection() + action = data2.current.value + + if action == 'search_database' then + LookupVehicle() + elseif DoesEntityExist(vehicle) then + if action == 'vehicle_infos' then + local vehicleData = ESX.Game.GetVehicleProperties(vehicle) + OpenVehicleInfosMenu(vehicleData) + elseif action == 'hijack_vehicle' then + if IsAnyVehicleNearPoint(coords.x, coords.y, coords.z, 3.0) then + TaskStartScenarioInPlace(playerPed, 'WORLD_HUMAN_WELDING', 0, true) + Citizen.Wait(20000) + ClearPedTasksImmediately(playerPed) + + SetVehicleDoorsLocked(vehicle, 1) + SetVehicleDoorsLockedForAllPlayers(vehicle, false) + ESX.ShowNotification(_U('job_police:vehicle_unlocked')) + end + elseif action == 'impound' then + -- is the script busy? + if CurrentTask.busy then + return + end + + ESX.ShowHelpNotification(_U('job_police:impound_prompt')) + TaskStartScenarioInPlace(playerPed, 'CODE_HUMAN_MEDIC_TEND_TO_DEAD', 0, true) + + CurrentTask.busy = true + CurrentTask.task = ESX.SetTimeout(10000, function() + ClearPedTasks(playerPed) + ImpoundVehicle(vehicle) + Citizen.Wait(100) -- sleep the entire script to let stuff sink back to reality + end) + + -- keep track of that vehicle! + Citizen.CreateThread(function() + while CurrentTask.busy do + Citizen.Wait(1000) + + vehicle = GetClosestVehicle(coords.x, coords.y, coords.z, 3.0, 0, 71) + if not DoesEntityExist(vehicle) and CurrentTask.busy then + ESX.ShowNotification(_U('job_police:impound_canceled_moved')) + ESX.ClearTimeout(CurrentTask.task) + ClearPedTasks(playerPed) + CurrentTask.busy = false + break + end + end + end) + end + else + ESX.ShowNotification(_U('job_police:no_vehicles_nearby')) + end + + end) + + elseif data.current.value == 'object_spawner' then + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', { + title = _U('job_police:traffic_interaction'), + align = 'top-left', + elements = { + {label = _U('job_police:cone'), model = 'prop_roadcone02a'}, + {label = _U('job_police:barrier'), model = 'prop_barrier_work05'}, + {label = _U('job_police:spikestrips'), model = 'p_ld_stinger_s'}, + {label = _U('job_police:box'), model = 'prop_boxpile_07d'}, + {label = _U('job_police:cash'), model = 'hei_prop_cash_crate_half_full'} + }}, function(data2, menu2) + local playerPed = PlayerPedId() + local coords, forward = GetEntityCoords(playerPed), GetEntityForwardVector(playerPed) + local objectCoords = (coords + forward * 1.0) + + ESX.Game.SpawnObject(data2.current.model, objectCoords, function(obj) + SetEntityHeading(obj, GetEntityHeading(playerPed)) + PlaceObjectOnGroundProperly(obj) + end) + end, function(data2, menu2) + menu2.close() + end) + end + end) + +end + +self.OpenIdentityCardMenu = function(player) + ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data) + local elements = { + {label = _U('job_police:name', data.name)}, + {label = _U('job_police:job', ('%s - %s'):format(data.job, data.grade))} + } + + if self.Config.EnableESXIdentity then + table.insert(elements, {label = _U('job_police:sex', _U(data.sex))}) + table.insert(elements, {label = _U('job_police:dob', data.dob)}) + table.insert(elements, {label = _U('job_police:height', data.height)}) + end + + if data.drunk then + table.insert(elements, {label = _U('job_police:bac', data.drunk)}) + end + + if data.licenses then + table.insert(elements, {label = _U('job_police:license_label')}) + + for i=1, #data.licenses, 1 do + table.insert(elements, {label = data.licenses[i].label}) + end + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'citizen_interaction', { + title = _U('job_police:citizen_interaction'), + align = 'top-left', + elements = elements + }, nil, function(data, menu) + menu.close() + end) + end, GetPlayerServerId(player)) +end + +self.OpenBodySearchMenu = function(player) + ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(data) + local elements = {} + + for i=1, #data.accounts, 1 do + if data.accounts[i].name == 'black_money' and data.accounts[i].money > 0 then + table.insert(elements, { + label = _U('job_police:confiscate_dirty', ESX.Math.Round(data.accounts[i].money)), + value = 'black_money', + itemType = 'item_account', + amount = data.accounts[i].money + }) + + break + end + end + + table.insert(elements, {label = _U('job_police:guns_label')}) + + for i=1, #data.weapons, 1 do + table.insert(elements, { + label = _U('job_police:confiscate_weapon', ESX.GetWeaponLabel(data.weapons[i].name), data.weapons[i].ammo), + value = data.weapons[i].name, + itemType = 'item_weapon', + amount = data.weapons[i].ammo + }) + end + + table.insert(elements, {label = _U('job_police:inventory_label')}) + + for i=1, #data.inventory, 1 do + if data.inventory[i].count > 0 then + table.insert(elements, { + label = _U('job_police:confiscate_inv', data.inventory[i].count, data.inventory[i].label), + value = data.inventory[i].name, + itemType = 'item_standard', + amount = data.inventory[i].count + }) + end + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'body_search', { + title = _U('job_police:search'), + align = 'top-left', + elements = elements + }, function(data, menu) + if data.current.value then + TriggerServerEvent('esx_policejob:confiscatePlayerItem', GetPlayerServerId(player), data.current.itemType, data.current.value, data.current.amount) + OpenBodySearchMenu(player) + end + end, function(data, menu) + menu.close() + end) + end, GetPlayerServerId(player)) +end + +self.OpenFineMenu = function(player) + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine', { + title = _U('job_police:fine'), + align = 'top-left', + elements = { + {label = _U('job_police:traffic_offense'), value = 0}, + {label = _U('job_police:minor_offense'), value = 1}, + {label = _U('job_police:average_offense'), value = 2}, + {label = _U('job_police:major_offense'), value = 3} + }}, function(data, menu) + OpenFineCategoryMenu(player, data.current.value) + end, function(data, menu) + menu.close() + end) +end + +self.OpenFineCategoryMenu = function(player, category) + ESX.TriggerServerCallback('esx_policejob:getFineList', function(fines) + local elements = {} + + for k,fine in ipairs(fines) do + table.insert(elements, { + label = ('%s %s'):format(fine.label, _U('job_police:armory_item', ESX.Math.GroupDigits(fine.amount))), + value = fine.id, + amount = fine.amount, + fineLabel = fine.label + }) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'fine_category', { + title = _U('job_police:fine'), + align = 'top-left', + elements = elements + }, function(data, menu) + menu.close() + + if self.Config.EnablePlayerManagement then + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), 'society_police', _U('job_police:fine_total', data.current.fineLabel), data.current.amount) + else + TriggerServerEvent('esx_billing:sendBill', GetPlayerServerId(player), '', _U('job_police:fine_total', data.current.fineLabel), data.current.amount) + end + + ESX.SetTimeout(300, function() + OpenFineCategoryMenu(player, category) + end) + end, function(data, menu) + menu.close() + end) + end, category) +end + +self.LookupVehicle = function() + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'lookup_vehicle', { + title = _U('job_police:search_database_title'), + }, function(data, menu) + local length = string.len(data.value) + if not data.value or length < 2 or length > 8 then + ESX.ShowNotification(_U('job_police:search_database_error_invalid')) + else + ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo) + local elements = {{label = _U('job_police:plate', retrivedInfo.plate)}} + menu.close() + + if not retrivedInfo.owner then + table.insert(elements, {label = _U('job_police:owner_unknown')}) + else + table.insert(elements, {label = _U('job_police:owner', retrivedInfo.owner)}) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', { + title = _U('job_police:vehicle_info'), + align = 'top-left', + elements = elements + }, nil, function(data2, menu2) + menu2.close() + end) + end, data.value) + + end + end, function(data, menu) + menu.close() + end) +end + +self.ShowPlayerLicense = function(player) + local elements = {} + + ESX.TriggerServerCallback('esx_policejob:getOtherPlayerData', function(playerData) + if playerData.licenses then + for i=1, #playerData.licenses, 1 do + if playerData.licenses[i].label and playerData.licenses[i].type then + table.insert(elements, { + label = playerData.licenses[i].label, + type = playerData.licenses[i].type + }) + end + end + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'manage_license', { + title = _U('job_police:license_revoke'), + align = 'top-left', + elements = elements, + }, function(data, menu) + ESX.ShowNotification(_U('job_police:licence_you_revoked', data.current.label, playerData.name)) + TriggerServerEvent('esx_policejob:message', GetPlayerServerId(player), _U('job_police:license_revoked', data.current.label)) + + TriggerServerEvent('esx_license:removeLicense', GetPlayerServerId(player), data.current.type) + + ESX.SetTimeout(300, function() + ShowPlayerLicense(player) + end) + end, function(data, menu) + menu.close() + end) + + end, GetPlayerServerId(player)) +end + +self.OpenUnpaidBillsMenu = function(player) + local elements = {} + + ESX.TriggerServerCallback('esx_billing:getTargetBills', function(bills) + for k,bill in ipairs(bills) do + table.insert(elements, { + label = ('%s - %s'):format(bill.label, _U('job_police:armory_item', ESX.Math.GroupDigits(bill.amount))), + billId = bill.id + }) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'billing', { + title = _U('job_police:unpaid_bills'), + align = 'top-left', + elements = elements + }, nil, function(data, menu) + menu.close() + end) + end, GetPlayerServerId(player)) +end + +self.OpenVehicleInfosMenu = function(vehicleData) + ESX.TriggerServerCallback('esx_policejob:getVehicleInfos', function(retrivedInfo) + local elements = {{label = _U('job_police:plate', retrivedInfo.plate)}} + + if not retrivedInfo.owner then + table.insert(elements, {label = _U('job_police:owner_unknown')}) + else + table.insert(elements, {label = _U('job_police:owner', retrivedInfo.owner)}) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_infos', { + title = _U('job_police:vehicle_info'), + align = 'top-left', + elements = elements + }, nil, function(data, menu) + menu.close() + end) + end, vehicleData.plate) +end + +self.OpenGetWeaponMenu = function() + ESX.TriggerServerCallback('esx_policejob:getArmoryWeapons', function(weapons) + local elements = {} + + for i=1, #weapons, 1 do + if weapons[i].count > 0 then + table.insert(elements, { + label = 'x' .. weapons[i].count .. ' ' .. ESX.GetWeaponLabel(weapons[i].name), + value = weapons[i].name + }) + end + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_get_weapon', { + title = _U('job_police:get_weapon_menu'), + align = 'top-left', + elements = elements + }, function(data, menu) + menu.close() + + ESX.TriggerServerCallback('esx_policejob:removeArmoryWeapon', function() + OpenGetWeaponMenu() + end, data.current.value) + end, function(data, menu) + menu.close() + end) + end) +end + +self.OpenPutWeaponMenu = function() + local elements = {} + local playerPed = PlayerPedId() + local weaponList = ESX.GetWeaponList() + + for i=1, #weaponList, 1 do + local weaponHash = GetHashKey(weaponList[i].name) + + if HasPedGotWeapon(playerPed, weaponHash, false) and weaponList[i].name ~= 'WEAPON_UNARMED' then + table.insert(elements, { + label = weaponList[i].label, + value = weaponList[i].name + }) + end + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_put_weapon', { + title = _U('job_police:put_weapon_menu'), + align = 'top-left', + elements = elements + }, function(data, menu) + menu.close() + + ESX.TriggerServerCallback('esx_policejob:addArmoryWeapon', function() + OpenPutWeaponMenu() + end, data.current.value, true) + end, function(data, menu) + menu.close() + end) +end + +self.OpenBuyWeaponsMenu = function() + local elements = {} + local playerPed = PlayerPedId() + + local authorizedWeapons = {} + + for i=1, ESX.PlayerData.job.grade, 1 do + + local weapons = self.Config.AuthorizedWeapons[i] + + for j=1, #weapons, 1 do + authorizedWeapons[#authorizedWeapons + 1] = weapons[j] + end + + end + + for k,v in ipairs(authorizedWeapons) do + local weaponNum, weapon = ESX.GetWeapon(v.weapon) + local components, label = {} + local hasWeapon = HasPedGotWeapon(playerPed, GetHashKey(v.weapon), false) + + if v.components then + for i=1, #v.components do + if v.components[i] then + local component = weapon.components[i] + local hasComponent = HasPedGotWeaponComponent(playerPed, GetHashKey(v.weapon), component.hash) + + if hasComponent then + label = ('%s: %s'):format(component.label, _U('job_police:armory_owned')) + else + if v.components[i] > 0 then + label = ('%s: %s'):format(component.label, _U('job_police:armory_item', ESX.Math.GroupDigits(v.components[i]))) + else + label = ('%s: %s'):format(component.label, _U('job_police:armory_free')) + end + end + + table.insert(components, { + label = label, + componentLabel = component.label, + hash = component.hash, + name = component.name, + price = v.components[i], + hasComponent = hasComponent, + componentNum = i + }) + end + end + end + + if hasWeapon and v.components then + label = ('%s: >'):format(weapon.label) + elseif hasWeapon and not v.components then + label = ('%s: %s'):format(weapon.label, _U('job_police:armory_owned')) + else + if v.price > 0 then + label = ('%s: %s'):format(weapon.label, _U('job_police:armory_item', ESX.Math.GroupDigits(v.price))) + else + label = ('%s: %s'):format(weapon.label, _U('job_police:armory_free')) + end + end + + table.insert(elements, { + label = label, + weaponLabel = weapon.label, + name = weapon.name, + components = components, + price = v.price, + hasWeapon = hasWeapon + }) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_buy_weapons', { + title = _U('job_police:armory_weapontitle'), + align = 'top-left', + elements = elements + }, function(data, menu) + if data.current.hasWeapon then + if #data.current.components > 0 then + OpenWeaponComponentShop(data.current.components, data.current.name, menu) + end + else + ESX.TriggerServerCallback('esx_policejob:buyWeapon', function(bought) + if bought then + if data.current.price > 0 then + ESX.ShowNotification(_U('job_police:armory_bought', data.current.weaponLabel, ESX.Math.GroupDigits(data.current.price))) + end + + menu.close() + OpenBuyWeaponsMenu() + else + ESX.ShowNotification(_U('job_police:armory_money')) + end + end, data.current.name, 1) + end + end, function(data, menu) + menu.close() + end) +end + +self.OpenWeaponComponentShop = function(components, weaponName, parentShop) + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'armory_buy_weapons_components', { + title = _U('job_police:armory_componenttitle'), + align = 'top-left', + elements = components + }, function(data, menu) + if data.current.hasComponent then + ESX.ShowNotification(_U('job_police:armory_hascomponent')) + else + ESX.TriggerServerCallback('esx_policejob:buyWeapon', function(bought) + if bought then + if data.current.price > 0 then + ESX.ShowNotification(_U('job_police:armory_bought', data.current.componentLabel, ESX.Math.GroupDigits(data.current.price))) + end + + menu.close() + parentShop.close() + OpenBuyWeaponsMenu() + else + ESX.ShowNotification(_U('job_police:armory_money')) + end + end, weaponName, 2, data.current.componentNum) + end + end, function(data, menu) + menu.close() + end) +end + +self.OpenGetStocksMenu = function() + ESX.TriggerServerCallback('esx_policejob:getStockItems', function(items) + local elements = {} + + for i=1, #items, 1 do + table.insert(elements, { + label = 'x' .. items[i].count .. ' ' .. items[i].label, + value = items[i].name + }) + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { + title = _U('job_police:police_stock'), + align = 'top-left', + elements = elements + }, function(data, menu) + local itemName = data.current.value + + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_get_item_count', { + title = _U('job_police:quantity') + }, function(data2, menu2) + local count = tonumber(data2.value) + + if not count then + ESX.ShowNotification(_U('job_police:quantity_invalid')) + else + menu2.close() + menu.close() + TriggerServerEvent('esx_policejob:getStockItem', itemName, count) + + Citizen.Wait(300) + OpenGetStocksMenu() + end + end, function(data2, menu2) + menu2.close() + end) + end, function(data, menu) + menu.close() + end) + end) +end + +self.OpenPutStocksMenu = function() + ESX.TriggerServerCallback('esx_policejob:getPlayerInventory', function(inventory) + local elements = {} + + for i=1, #inventory.items, 1 do + local item = inventory.items[i] + + if item.count > 0 then + table.insert(elements, { + label = item.label .. ' x' .. item.count, + type = 'item_standard', + value = item.name + }) + end + end + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'stocks_menu', { + title = _U('job_police:inventory'), + align = 'top-left', + elements = elements + }, function(data, menu) + local itemName = data.current.value + + ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'stocks_menu_put_item_count', { + title = _U('job_police:quantity') + }, function(data2, menu2) + local count = tonumber(data2.value) + + if not count then + ESX.ShowNotification(_U('job_police:quantity_invalid')) + else + menu2.close() + menu.close() + TriggerServerEvent('esx_policejob:putStockItems', itemName, count) + + Citizen.Wait(300) + OpenPutStocksMenu() + end + end, function(data2, menu2) + menu2.close() + end) + end, function(data, menu) + menu.close() + end) + end) +end + +-- Create blip for colleagues +self.CreateBlip = function(id) + local ped = GetPlayerPed(id) + local blip = GetBlipFromEntity(ped) + + if not DoesBlipExist(blip) then -- Add blip and create head display on player + blip = AddBlipForEntity(ped) + SetBlipSprite(blip, 1) + ShowHeadingIndicatorOnBlip(blip, true) -- Player Blip indicator + SetBlipRotation(blip, math.ceil(GetEntityHeading(ped))) -- update rotation + SetBlipNameToPlayerName(blip, id) -- update blip name + SetBlipScale(blip, 0.85) -- set scale + SetBlipAsShortRange(blip, true) + + table.insert(blipsCops, blip) -- add blip to array so we can remove it later + end +end + +-- handcuff timer, unrestrain the player after an certain amount of time +self.StartHandcuffTimer = function() + if self.Config.EnableHandcuffTimer and handcuffTimer.active then + ESX.ClearTimeout(handcuffTimer.task) + end + + handcuffTimer.active = true + + handcuffTimer.task = ESX.SetTimeout(Config.HandcuffTimer, function() + ESX.ShowNotification(_U('job_police:unrestrained_timer')) + TriggerEvent('esx_policejob:unrestrain') + handcuffTimer.active = false + end) + +end + +-- TODO +-- - return to garage if owned +-- - message owner that his vehicle has been impounded +self.ImpoundVehicle = function(vehicle) + --local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(GetEntityModel(vehicle))) + ESX.Game.DeleteVehicle(vehicle) + ESX.ShowNotification(_U('job_police:impound_successful')) + currentTask.busy = false +end + +self.OpenVehicleSpawnerMenu = function(type, config) + + local playerCoords = GetEntityCoords(PlayerPedId()) + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle', { + title = _U('job_police:garage_title'), + align = 'top-left', + elements = { + {label = _U('job_police:garage_storeditem'), action = 'garage'}, + {label = _U('job_police:garage_storeitem'), action = 'store_garage'}, + {label = _U('job_police:garage_buyitem'), action = 'buy_vehicle'} + }}, function(data, menu) + + if data.current.action == 'buy_vehicle' then + + local shopElements = {} + local authorizedVehicles = {} + + for i=1, ESX.PlayerData.job.grade, 1 do + + local vehicles = self.Config.AuthorizedVehicles[type][i] + + for j=1, #vehicles, 1 do + authorizedVehicles[#authorizedVehicles + 1] = vehicles[j] + end + + end + + if authorizedVehicles then + if #authorizedVehicles > 0 then + for k,vehicle in ipairs(authorizedVehicles) do + if IsModelInCdimage(vehicle.model) then + local vehicleLabel = GetLabelText(GetDisplayNameFromVehicleModel(vehicle.model)) + + table.insert(shopElements, { + label = ('%s - %s'):format(vehicleLabel, _U('job_police:shop_item', ESX.Math.GroupDigits(vehicle.price))), + name = vehicleLabel, + model = vehicle.model, + price = vehicle.price, + props = vehicle.props, + type = type + }) + end + end + + if #shopElements > 0 then + self.OpenShopMenu(shopElements, config) + else + ESX.ShowNotification(_U('job_police:garage_notauthorized')) + end + else + ESX.ShowNotification(_U('job_police:garage_notauthorized')) + end + else + ESX.ShowNotification(_U('job_police:garage_notauthorized')) + end + elseif data.current.action == 'garage' then + local garage = {} + + ESX.TriggerServerCallback('esx_vehicleshop:retrieveJobVehicles', function(jobVehicles) + if #jobVehicles > 0 then + local allVehicleProps = {} + + for k,v in ipairs(jobVehicles) do + local props = json.decode(v.vehicle) + + if IsModelInCdimage(props.model) then + local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(props.model)) + local label = ('%s - %s: '):format(vehicleName, props.plate) + + if v.stored then + label = label .. ('%s'):format(_U('job_police:garage_stored')) + else + label = label .. ('%s'):format(_U('job_police:garage_notstored')) + end + + table.insert(garage, { + label = label, + stored = v.stored, + model = props.model, + plate = props.plate + }) + + allVehicleProps[props.plate] = props + end + end + + if #garage > 0 then + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_garage', { + title = _U('job_police:garage_title'), + align = 'top-left', + elements = garage + }, function(data2, menu2) + if data2.current.stored then + + + local foundSpawn, spawnPoint = self.GetAvailableVehicleSpawnPoint(config.SpawnPoints) + + if foundSpawn then + menu2.close() + + ESX.Game.SpawnVehicle(data2.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) + local vehicleProps = allVehicleProps[data2.current.plate] + ESX.Game.SetVehicleProperties(vehicle, vehicleProps) + + TriggerServerEvent('esx_vehicleshop:setJobVehicleState', data2.current.plate, false) + ESX.ShowNotification(_U('job_police:garage_released')) + end) + end + + else + ESX.ShowNotification(_U('job_police:garage_notavailable')) + end + end, function(data2, menu2) + menu2.close() + end) + else + ESX.ShowNotification(_U('job_police:garage_empty')) + end + else + ESX.ShowNotification(_U('job_police:garage_empty')) + end + end, type) + + elseif data.current.action == 'store_garage' then + StoreNearbyVehicle(playerCoords) + end + end, function(data, menu) + menu.close() + end, nil, function() + + if type == 'car' then + + ESX.ShowHelpNotification(_U('job_police:garage_prompt')) + + self.CurrentAction = function() + self.OpenVehicleSpawnerMenu('car', data.config) + end + + elseif type == 'helicopter' then + + ESX.ShowHelpNotification(_U('job_police:helicopter_prompt')) + + self.CurrentAction = function() + self.OpenVehicleSpawnerMenu('helicopter', data.config) + end + + end + + end) + +end + +self.StoreNearbyVehicle = function(playerCoords) + local vehicles, vehiclePlates = ESX.Game.GetVehiclesInArea(playerCoords, 30.0), {} + + if #vehicles > 0 then + for k,v in ipairs(vehicles) do + + -- Make sure the vehicle we're saving is empty, or else it wont be deleted + if GetVehicleNumberOfPassengers(v) == 0 and IsVehicleSeatFree(v, -1) then + table.insert(vehiclePlates, { + vehicle = v, + plate = ESX.Math.Trim(GetVehicleNumberPlateText(v)) + }) + end + end + else + ESX.ShowNotification(_U('job_police:garage_store_nearby')) + return + end + + ESX.TriggerServerCallback('esx_policejob:storeNearbyVehicle', function(storeSuccess, foundNum) + if storeSuccess then + local vehicleId = vehiclePlates[foundNum] + local attempts = 0 + ESX.Game.DeleteVehicle(vehicleId.vehicle) + IsBusy = true + + Citizen.CreateThread(function() + BeginTextCommandBusyspinnerOn('STRING') + AddTextComponentSubstringPlayerName(_U('job_police:garage_storing')) + EndTextCommandBusyspinnerOn(4) + + while IsBusy do + Citizen.Wait(100) + end + + BusyspinnerOff() + end) + + -- Workaround for vehicle not deleting when other players are near it. + while DoesEntityExist(vehicleId.vehicle) do + Citizen.Wait(500) + attempts = attempts + 1 + + -- Give up + if attempts > 30 then + break + end + + vehicles = ESX.Game.GetVehiclesInArea(playerCoords, 30.0) + if #vehicles > 0 then + for k,v in ipairs(vehicles) do + if ESX.Math.Trim(GetVehicleNumberPlateText(v)) == vehicleId.plate then + ESX.Game.DeleteVehicle(v) + break + end + end + end + end + + IsBusy = false + ESX.ShowNotification(_U('job_police:garage_has_stored')) + else + ESX.ShowNotification(_U('job_police:garage_has_notstored')) + end + end, vehiclePlates) +end + +self.GetAvailableVehicleSpawnPoint = function(spawnPoints) + + local found, foundSpawnPoint = false, nil + + for i=1, #spawnPoints, 1 do + if ESX.Game.IsSpawnPointClear(spawnPoints[i].coords, spawnPoints[i].radius) then + found, foundSpawnPoint = true, spawnPoints[i] + break + end + end + + if found then + return true, foundSpawnPoint + else + ESX.ShowNotification(_U('job_police:vehicle_blocked')) + return false + end +end + +self.OpenShopMenu = function(elements, config) + + local playerPed = PlayerPedId() + isInShopMenu = true + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop', { + title = _U('job_police:vehicleshop_title'), + align = 'top-left', + elements = elements + }, function(data, menu) + + menu.close() + + ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'vehicle_shop_confirm', { + title = _U('job_police:vehicleshop_confirm', data.current.name, data.current.price), + align = 'top-left', + elements = { + {label = _U('job_police:confirm_no'), value = 'no'}, + {label = _U('job_police:confirm_yes'), value = 'yes'} + }}, function(data2, menu2) + + menu2.close() + + if data2.current.value == 'yes' then + + ESX.TriggerServerCallback('esx_policejob:canBuyVehicle', function (success) + + if success then + + local foundSpawn, spawnPoint = self.GetAvailableVehicleSpawnPoint(config.SpawnPoints) + + if foundSpawn then + + ESX.Game.SpawnVehicle(data.current.model, spawnPoint.coords, spawnPoint.heading, function(vehicle) + + local props = ESX.Game.GetVehicleProperties(vehicle) + props.plate = exports['esx_vehicleshop']:GeneratePlate() -- TODO Should be in core + + SetVehicleNumberPlateText(vehicle, props.plate) + TaskWarpPedIntoVehicle(playerPed, vehicle, -1) + + TriggerServerEvent('esx_policejob:buyJobVehicle', props, data.current.type) + + ESX.ShowNotification(_U('job_police:vehicleshop_bought', data.current.name, ESX.Math.GroupDigits(data.current.price))) + + end) + + end + + else + ESX.ShowNotification(_U('job_police:vehicleshop_money')) + menu2.close() + end + + end, data.current.model, data.current.type) + + end + + end, function(data2, menu2) + menu2.close() + end) + + end) + +end + +self.DeleteSpawnedVehicles = function() + + for i=1, #self.SpawnedVehicles, 1 do + ESX.Game.DeleteVehicle(self.SpawnedVehicles[i]) + end + + self.SpawnedVehicles = {} + +end + +self.WaitForVehicleToLoad = function(modelHash) + + modelHash = (type(modelHash) == 'number' and modelHash or GetHashKey(modelHash)) + + if not HasModelLoaded(modelHash) then + RequestModel(modelHash) + + BeginTextCommandBusyspinnerOn('STRING') + AddTextComponentSubstringPlayerName(_U('vehicleshop_awaiting_model')) + EndTextCommandBusyspinnerOn(4) + + while not HasModelLoaded(modelHash) do + Citizen.Wait(0) + DisableAllControlActions(0) + end + + BusyspinnerOff() + end +end diff --git a/modules/job_police/data/config.lua b/modules/job_police/data/config.lua new file mode 100644 index 00000000..b039d9b1 --- /dev/null +++ b/modules/job_police/data/config.lua @@ -0,0 +1,319 @@ +Config = {} + +Config.DrawDistance = 100.0 +Config.MarkerType = 1 +Config.MarkerSize = {x = 1.5, y = 1.5, z = 0.5} +Config.MarkerColor = {r = 50, g = 50, b = 204, a = 100} + +Config.EnablePlayerManagement = false +Config.EnableArmoryManagement = false +Config.EnableESXIdentity = false -- enable if you're using esx_identity +Config.EnableLicenses = false -- enable if you're using esx_license + +Config.EnableHandcuffTimer = true -- enable handcuff timer? will unrestrain player after the time ends +Config.HandcuffTimer = 10 * 60000 -- 10 mins + +Config.EnableJobBlip = false -- enable blips for cops on duty, requires esx_society +Config.EnableCustomPeds = false -- enable custom peds in cloak room? See Config.CustomPeds below to customize peds + +Config.EnableESXService = false -- enable esx service? +Config.MaxInService = 5 + +Config.Locale = 'fr' + +Config.PoliceStations = { + + LSPD = { + + Blip = { + Coords = vector3(425.1, -979.5, 30.7), + Sprite = 60, + Display = 4, + Scale = 1.2, + Colour = 29 + }, + + Cloakrooms = { + vector3(452.6, -992.8, 30.6) + }, + + Armories = { + vector3(451.7, -980.1, 30.6) + }, + + Vehicles = { + { + Spawner = vector3(454.6, -1017.4, 28.4), + InsideShop = vector3(228.5, -993.5, -99.5), + SpawnPoints = { + {coords = vector3(438.4, -1018.3, 27.7), heading = 90.0, radius = 6.0}, + {coords = vector3(441.0, -1024.2, 28.3), heading = 90.0, radius = 6.0}, + {coords = vector3(453.5, -1022.2, 28.0), heading = 90.0, radius = 6.0}, + {coords = vector3(450.9, -1016.5, 28.1), heading = 90.0, radius = 6.0} + } + }, + + { + Spawner = vector3(473.3, -1018.8, 28.0), + InsideShop = vector3(228.5, -993.5, -99.0), + SpawnPoints = { + {coords = vector3(475.9, -1021.6, 28.0), heading = 276.1, radius = 6.0}, + {coords = vector3(484.1, -1023.1, 27.5), heading = 302.5, radius = 6.0} + } + } + }, + + Helicopters = { + { + Spawner = vector3(461.1, -981.5, 43.6), + InsideShop = vector3(477.0, -1106.4, 43.0), + SpawnPoints = { + {coords = vector3(449.5, -981.2, 43.6), heading = 92.6, radius = 10.0} + } + } + }, + + BossActions = { + vector3(448.4, -973.2, 30.6) + } + + } + +} + +Config.AuthorizedWeapons = { + { -- recruit + {weapon = 'WEAPON_APPISTOL', components = {0, 0, 1000, 4000, nil}, price = 10000}, + {weapon = 'WEAPON_NIGHTSTICK', price = 0}, + {weapon = 'WEAPON_STUNGUN', price = 1500}, + {weapon = 'WEAPON_FLASHLIGHT', price = 80} + }, + + { -- officer + {weapon = 'WEAPON_ADVANCEDRIFLE', components = {0, 6000, 1000, 4000, 8000, nil}, price = 50000}, + }, + + { -- sergeant + {weapon = 'WEAPON_PUMPSHOTGUN', components = {2000, 6000, nil}, price = 70000}, + }, + + { -- lieutenant + }, + + { -- boss + } +} + +Config.AuthorizedVehicles = { + car = { + { -- recruit + + }, + + { -- officer + {model = 'police3', price = 20000} + }, + + { -- sergeant + {model = 'policet', price = 18500}, + {model = 'policeb', price = 30500} + }, + + { -- lieutenant + {model = 'riot', price = 70000}, + {model = 'fbi2', price = 60000} + }, + + { -- boss + + } + }, + + helicopter = { + + { -- recruit + + }, + + { -- officer + + }, + + {-- sergeant + + }, + + { -- lieutenant + {model = 'polmav', props = {modLivery = 0}, price = 200000} + }, + + { -- boss + {model = 'polmav', props = {modLivery = 0}, price = 100000} + } + } +} + +Config.CustomPeds = { + shared = { + {label = 'Sheriff Ped', maleModel = 's_m_y_sheriff_01', femaleModel = 's_f_y_sheriff_01'}, + {label = 'Police Ped', maleModel = 's_m_y_cop_01', femaleModel = 's_f_y_cop_01'} + }, + + recruit = {}, + + officer = {}, + + sergeant = {}, + + lieutenant = {}, + + boss = { + {label = 'SWAT Ped', maleModel = 's_m_y_swat_01', femaleModel = 's_m_y_swat_01'} + } +} + +-- CHECK SKINCHANGER CLIENT MAIN.LUA for matching elements +Config.Uniforms = { + recruit = { + male = { + tshirt_1 = 59, tshirt_2 = 1, + torso_1 = 55, torso_2 = 0, + decals_1 = 0, decals_2 = 0, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = 46, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 + }, + female = { + tshirt_1 = 36, tshirt_2 = 1, + torso_1 = 48, torso_2 = 0, + decals_1 = 0, decals_2 = 0, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = 45, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 + } + }, + + officer = { + male = { + tshirt_1 = 58, tshirt_2 = 0, + torso_1 = 55, torso_2 = 0, + decals_1 = 0, decals_2 = 0, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 + }, + female = { + tshirt_1 = 35, tshirt_2 = 0, + torso_1 = 48, torso_2 = 0, + decals_1 = 0, decals_2 = 0, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 + } + }, + + sergeant = { + male = { + tshirt_1 = 58, tshirt_2 = 0, + torso_1 = 55, torso_2 = 0, + decals_1 = 8, decals_2 = 1, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 + }, + female = { + tshirt_1 = 35, tshirt_2 = 0, + torso_1 = 48, torso_2 = 0, + decals_1 = 7, decals_2 = 1, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 + } + }, + + lieutenant = { + male = { + tshirt_1 = 58, tshirt_2 = 0, + torso_1 = 55, torso_2 = 0, + decals_1 = 8, decals_2 = 2, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 + }, + female = { + tshirt_1 = 35, tshirt_2 = 0, + torso_1 = 48, torso_2 = 0, + decals_1 = 7, decals_2 = 2, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 + } + }, + + boss = { + male = { + tshirt_1 = 58, tshirt_2 = 0, + torso_1 = 55, torso_2 = 0, + decals_1 = 8, decals_2 = 3, + arms = 41, + pants_1 = 25, pants_2 = 0, + shoes_1 = 25, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 + }, + female = { + tshirt_1 = 35, tshirt_2 = 0, + torso_1 = 48, torso_2 = 0, + decals_1 = 7, decals_2 = 3, + arms = 44, + pants_1 = 34, pants_2 = 0, + shoes_1 = 27, shoes_2 = 0, + helmet_1 = -1, helmet_2 = 0, + chain_1 = 0, chain_2 = 0, + ears_1 = 2, ears_2 = 0 + } + }, + + bullet_wear = { + male = { + bproof_1 = 11, bproof_2 = 1 + }, + female = { + bproof_1 = 13, bproof_2 = 1 + } + }, + + gilet_wear = { + male = { + tshirt_1 = 59, tshirt_2 = 1 + }, + female = { + tshirt_1 = 36, tshirt_2 = 1 + } + } +} diff --git a/modules/job_police/data/locales/br.lua b/modules/job_police/data/locales/br.lua new file mode 100644 index 00000000..9423af49 --- /dev/null +++ b/modules/job_police/data/locales/br.lua @@ -0,0 +1,151 @@ +Translations = { + -- Cloackroom + ['cloakroom'] = 'Vestiário', + ['citizen_wear'] = 'Roupa casual', + ['police_wear'] = 'Uniforme da Polícia', + ['gilet_wear'] = 'orange reflective jacket', + ['bullet_wear'] = 'bulletproof vest', + ['no_outfit'] = 'there\'s no uniform that fits you!', + ['open_cloackroom'] = 'Pressione ~INPUT_CONTEXT~ para se trocar', + -- Armory + ['remove_object'] = 'take object', + ['deposit_object'] = 'deposit object', + ['get_weapon'] = 'Pegar arma', + ['put_weapon'] = 'Entregar arma', + ['buy_weapons'] = 'Comprar armas', + ['armory'] = 'Arsenal', + ['open_armory'] = 'Pressione ~INPUT_CONTEXT~ para acessar o arsenal', + ['armory_owned'] = 'owned', + ['armory_free'] = 'free', + ['armory_item'] = '$%s', + ['armory_weapontitle'] = 'armory - Buy weapon', + ['armory_componenttitle'] = 'armory - Weapon attatchments', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', + ['armory_money'] = 'you cannot afford that weapon', + ['armory_hascomponent'] = 'you have that attatchment equiped!', + ['get_weapon_menu'] = 'armory - Withdraw Weapon', + ['put_weapon_menu'] = 'armory - Store Weapon', + -- Vehicles + ['vehicle_menu'] = 'vehicle', + ['vehicle_blocked'] = 'all available spawn points are currently blocked!', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['garage_empty'] = 'you dont have any vehicles in your garage.', + ['garage_released'] = 'your vehicle has been released from the garage.', + ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', + ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~g~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', + -- Service + ['service_max'] = 'you cannot enter service, max officers in service: %s/%s', + ['service_not'] = 'you have not entered service! You\'ll have to get changed first.', + ['service_anonunce'] = 'service information', + ['service_in'] = 'you\'ve entered service, welcome!', + ['service_in_announce'] = 'operator ~y~%s~s~ has entered service!', + ['service_out'] = 'you have left service.', + ['service_out_announce'] = 'operator ~y~%s~s~ has left their service.', + -- Action Menu + ['citizen_interaction'] = 'Interagir com o cidadão', + ['vehicle_interaction'] = 'Interagir com o veículo', + ['object_spawner'] = 'Interagir com as rodovias', + + ['id_card'] = 'Carteira de identidade', + ['search'] = 'Procurar', + ['handcuff'] = 'Algemar / Soltar', + ['drag'] = 'drag', + ['put_in_vehicle'] = 'Colocar no veículo', + ['out_the_vehicle'] = 'take out of vehicle', + ['fine'] = 'Multa', + ['unpaid_bills'] = 'manage unpaid bills', + ['license_check'] = 'manage license', + ['license_revoke'] = 'revoke license', + ['license_revoked'] = 'your ~b~%s~s~ has been ~y~revoked~s~!', + ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~', + ['no_players_nearby'] = 'nenhum jogador nas proximidades', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', + -- Vehicle interaction + ['vehicle_info'] = 'Informações', + ['pick_lock'] = 'Trancar veículo', + ['vehicle_unlocked'] = 'Veículo ~g~destravado~s~', + ['no_vehicles_nearby'] = 'Nenhum veículo nas proximidades', + ['impound'] = 'apreender carro', + ['impound_prompt'] = 'Pressione ~INPUT_CONTEXT~ para cancelar a ~y~apreender~s~', + ['impound_canceled'] = 'you canceled the impound', + ['impound_canceled_moved'] = 'o apreender foi cancelado porque o veículo mudou', + ['impound_successful'] = 'você apreendeu o veículo', + ['search_database'] = 'informação do veículo', + ['search_database_title'] = 'informações do veículo - pesquisa com número de registro', + ['search_database_error_invalid'] = 'que ~r~não~s~ é um número de registro ~y~válido~s~', + -- Traffic interaction + ['traffic_interaction'] = 'Interagir com as rodovias', + ['cone'] = 'Cones', + ['barrier'] = 'Barreira', + ['spikestrips'] = 'Fita de pregos', + ['box'] = 'Caixa', + ['cash'] = 'Caixa de dinheiro', + -- ID Card Menu + ['name'] = 'name: %s', + ['job'] = 'job: %s', + ['sex'] = 'sex: %s', + ['dob'] = 'DOB: %s', + ['height'] = 'height: %s', + ['bac'] = 'BAC: %s', + ['unknown'] = 'unknown', + ['male'] = 'male', + ['female'] = 'female', + -- Body Search Menu + ['guns_label'] = '--- Armas ---', + ['inventory_label'] = '--- Inventário ---', + ['license_label'] = ' --- Licenses ---', + ['confiscate'] = 'confiscar %s', + ['confiscate_weapon'] = 'confiscate %s with %s bullets', + ['confiscate_inv'] = 'Confiscar %sx %s', + ['confiscate_dirty'] = 'Confiscar dinheiro sujo: $%s', + ['you_confiscated'] = 'you confiscated ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ were confiscated by ~y~%s~s~', + ['you_confiscated_account'] = 'you confiscated ~g~$%s~s~ (%s) from ~b~%s~s~', + ['got_confiscated_account'] = '~g~$%s~s~ (%s) was confiscated by ~y~%s~s~', + ['you_confiscated_weapon'] = 'you confiscated ~b~%s~s~ from ~b~%s~s~ with ~o~%s~s~ bullets', + ['got_confiscated_weapon'] = 'your ~b~%s~s~ with ~o~%s~s~ bullets was confiscated by ~y~%s~s~', + ['traffic_offense'] = 'Infrações de transito', + ['minor_offense'] = 'Infração leve', + ['average_offense'] = 'Infração média', + ['major_offense'] = 'Infração grave', + ['fine_total'] = 'multa: %s', + -- Vehicle Info Menu + ['plate'] = 'placa: %s', + ['owner_unknown'] = 'proprietário: Desconhecido', + ['owner'] = 'proprietário: %s', + -- Boss Menu + ['open_bossmenu'] = 'Pressione ~INPUT_CONTEXT~ para abrir o menu', + ['quantity_invalid'] = 'invalid quantity', + ['have_withdrawn'] = 'you have withdrawn ~y~%sx~s~ ~b~%s~s~', + ['have_deposited'] = 'you have deposited ~y~%sx~s~ ~b~%s~s~', + ['quantity'] = 'quantity', + ['inventory'] = 'inventory', + ['police_stock'] = 'police Stock', + -- Misc + ['remove_prop'] = 'Pressione ~INPUT_CONTEXT~ para remover o objeto', + ['map_blip'] = 'Departamento de Polícia', + ['unrestrained_timer'] = 'you feel your handcuffs slowly losing grip and fading away.', + -- Notifications + ['alert_police'] = 'Alerta da Polícia', + ['phone_police'] = 'police', +} diff --git a/modules/job_police/data/locales/cs.lua b/modules/job_police/data/locales/cs.lua new file mode 100644 index 00000000..aad0524c --- /dev/null +++ b/modules/job_police/data/locales/cs.lua @@ -0,0 +1,151 @@ +Translations = { + -- Cloakroom + ['cloakroom'] = 'satna', + ['citizen_wear'] = 'civilní oblek', + ['police_wear'] = 'policejní oblek', + ['gilet_wear'] = 'oranžová reflexní vesta', + ['bullet_wear'] = 'neprůstřelná vesta', + ['no_outfit'] = 'není zde žádná uniforma, která by ti sedla!', + ['open_cloackroom'] = 'stiskni ~INPUT_CONTEXT~ pro změnu ~y~oblečení~s~.', + -- Armory + ['remove_object'] = 'vzít objekt', + ['deposit_object'] = 'odevzdat objekt', + ['get_weapon'] = 'vzít zbraň ze zbrojnice', + ['put_weapon'] = 'uchovat zbraň ve zbrojnici', + ['buy_weapons'] = 'koupit zbraně', + ['armory'] = 'zbrojnice', + ['open_armory'] = 'stiskni ~INPUT_CONTEXT~ pro přístup do ~y~zbrojnice~s~.', + ['armory_owned'] = 'vlastněno', + ['armory_free'] = 'zdarma', + ['armory_item'] = '$%s', + ['armory_weapontitle'] = 'zbrojnice', + ['armory_componenttitle'] = 'zbrojnice - Příslušenství ke zbraním', + ['armory_bought'] = 'zakoupil jsi ~y~%s~s~ za ~g~$%s~s~', + ['armory_money'] = 'nemáš dostatek peněz na tuto zbraň', + ['armory_hascomponent'] = 'toto příslušenství máš již nainstalováno!', + ['get_weapon_menu'] = 'zbrojnice - Vzít zbraň', + ['put_weapon_menu'] = 'zbrojnice - Uchovat zbraň', + -- Vehicles + ['vehicle_menu'] = 'vozidlo', + ['vehicle_blocked'] = 'vsechny dostupne spawn pointy jsou blokovany!', + ['garage_prompt'] = 'stiskni ~INPUT_CONTEXT~ pro otevreni ~y~akce vozidel~s~.', + ['garage_title'] = 'akce vozidel', + ['garage_stored'] = 'uloženo', + ['garage_notstored'] = 'není v garáži', + ['garage_storing'] = 'pokousime se o odstraneni vozidla, ujisti se, ze kolem nej nejsou hraci.', + ['garage_has_stored'] = 'vozidlo bylo ulozeno do garaze', + ['garage_has_notstored'] = 'zadne nejblizsi vlastnene vozidlo nenalezeno', + ['garage_notavailable'] = 'tvoje vozidlo neni ulozeno v garazi.', + ['garage_blocked'] = 'nejsou zde zadne spawn pointy!', + ['garage_empty'] = 'zadne vozidlo nemas v garazi.', + ['garage_released'] = 'tvoje vozidlo bylo vyjmuto z garaze.', + ['garage_store_nearby'] = 'nejsou poblíž zádná vozidla.', + ['garage_storeditem'] = 'otevřít garáž', + ['garage_storeitem'] = 'uchovat vozidlo v garáži', + ['garage_buyitem'] = 'prodej vozidel', + ['garage_notauthorized'] = 'nemas opravneni ke koupi tohoto vozidla.', + ['helicopter_prompt'] = 'stiskni ~INPUT_CONTEXT~ pro pristup k ~y~akcim Helikopter~s~.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'prodejce vozidel', + ['vehicleshop_confirm'] = 'opravdu chces koupit toto vozidlo?', + ['vehicleshop_bought'] = 'koupil jsi ~y~%s~s~ za ~r~$%s~s~', + ['vehicleshop_money'] = 'toto vozidlo si nemuzete dovolit', + ['vehicleshop_awaiting_model'] = 'vozidlo se prave ~g~stahuje a nacita~s~ prosim pockej', + ['confirm_no'] = 'ne', + ['confirm_yes'] = 'ano', + -- Service + ['service_max'] = 'nemuzete vstoupit do sluzby, max dustojníci v provozu: %s/%s', + ['service_not'] = 'nezadali jste sluzbu! Nejprve se musíte zmenit.', + ['service_anonunce'] = 'informace o sluzbe', + ['service_in'] = 'vstoupil jsi do sluzby, vitej!', + ['service_in_announce'] = 'operator ~y~%s~s~ se pripojil do sluzby!', + ['service_out'] = 'opustil jsi sluzbu.', + ['service_out_announce'] = 'operator ~y~%s~s~ opustil jejich sluzbu.', + -- Action Menu + ['citizen_interaction'] = 'Interakce s občanem', + ['vehicle_interaction'] = 'Interakce vozidla', + ['object_spawner'] = 'Objekty', + + ['id_card'] = 'Občanský průkaz', + ['search'] = 'prohledat', + ['handcuff'] = 'poutat / odpoutat', + ['drag'] = 'prenést', + ['put_in_vehicle'] = 'vlozit do vozidla', + ['out_the_vehicle'] = 'vytahnout z vozidla', + ['fine'] = 'pokuta', + ['unpaid_bills'] = 'spravovat nezaplacené pokuty', + ['license_check'] = 'spravovat průkazy', + ['license_revoke'] = 'zneplatnit průkaz', + ['license_revoked'] = 'vase ~b~%s~s~ bylo ~y~zruseno~s~!', + ['licence_you_revoked'] = 'zrusil jsi ~b~%s~s~ ktery patril ~y~%s~s~', + ['no_players_nearby'] = 'zadny hrac pobliz!', + ['being_searched'] = 'prave jsi ~y~prohledavan~s~ ~b~policii~s~', + -- Vehicle interaction + ['vehicle_info'] = 'informace o vozidle', + ['pick_lock'] = 'vypáčit vozidlo', + ['vehicle_unlocked'] = 'vozidlo je ~g~Odemčeno~s~', + ['no_vehicles_nearby'] = 'there is no vehicles nearby', + ['impound'] = 'odtahnout vozidlo', + ['impound_prompt'] = 'zmackni ~INPUT_CONTEXT~ pro zruseni ~y~odtahnuti~s~', + ['impound_canceled'] = 'zrusil jsi odtah', + ['impound_canceled_moved'] = 'odtah byl zrusen,protoze se vozidlo pohlo!', + ['impound_successful'] = 'uspesne jsi odtahl vozidlo', + ['search_database'] = 'informace o vozidle', + ['search_database_title'] = 'informace o vozidle - pomocí registracnich cisel', + ['search_database_error_invalid'] = 'tohle ~r~neni~s~ ~y~spravne~s~ registracni cislo', + -- Traffic interaction + ['traffic_interaction'] = 'interakce provozu', + ['cone'] = 'kuzel', + ['barrier'] = 'bariera', + ['spikestrips'] = 'ostnaty pas', + ['box'] = 'box', + ['cash'] = 'box penez', + -- ID Card Menu + ['name'] = 'jméno: %s', + ['job'] = 'práce: %s', + ['sex'] = 'pohlaví: %s', + ['dob'] = 'DOB: %s', + ['height'] = 'výška: %s', + ['bac'] = 'BAC: %s', + ['unknown'] = 'neznámé', + ['male'] = 'muž', + ['female'] = 'žena', + -- Body Search Menu + ['guns_label'] = '--- Zbraně ---', + ['inventory_label'] = '--- Inventář ---', + ['license_label'] = ' --- Průkazy ---', + ['confiscate'] = 'zabavit %s', + ['confiscate_weapon'] = 'zabavit %s s %s naboji', + ['confiscate_inv'] = 'zabavit %sx %s', + ['confiscate_dirty'] = 'zabavit spinave penize: $%s', + ['you_confiscated'] = 'zabavil jsi ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ byly zabaveny od ~y~%s~s~', + ['you_confiscated_account'] = 'zabavil jsi ~g~$%s~s~ (%s) od ~b~%s~s~', + ['got_confiscated_account'] = '~g~$%s~s~ (%s) byly zabaveny ~y~%s~s~', + ['you_confiscated_weapon'] = 'zabavil jsi ~b~%s~s~ od ~b~%s~s~ s ~o~%s~s~ naboji ', + ['got_confiscated_weapon'] = 'tvoje ~b~%s~s~ s ~o~%s~s~ bylo zabaveno od ~y~%s~s~', + ['traffic_offense'] = 'dopravní přestupek', + ['minor_offense'] = 'malý přestupek', + ['average_offense'] = 'přestupek', + ['major_offense'] = 'trestný čin', + ['fine_total'] = 'pokuta: %s', + -- Vehicle Info Menu + ['plate'] = 'SPZ: %s', + ['owner_unknown'] = 'vlastník: Neznámý', + ['owner'] = 'vlastník: %s', + -- Boss Menu + ['open_bossmenu'] = 'stiskni ~INPUT_CONTEXT~ pro otevření menu', + ['quantity_invalid'] = 'neplatné množství', + ['have_withdrawn'] = 'vybral jsi ~y~%sx~s~ ~b~%s~s~', + ['have_deposited'] = 'vložil jsi ~y~%sx~s~ ~b~%s~s~', + ['quantity'] = 'množství', + ['inventory'] = 'inventář', + ['police_stock'] = 'policejní sklad', + -- Misc + ['remove_prop'] = 'stiskni ~INPUT_CONTEXT~ pro odstranění předmětu', + ['map_blip'] = 'policejní stanice', + ['unrestrained_timer'] = 'cítíš, že tvé pouta pomalu ztrácejí přilnavost a padají.', + -- Notifications + ['alert_police'] = 'policejní poplach', + ['phone_police'] = 'policie', +} diff --git a/modules/job_police/data/locales/de.lua b/modules/job_police/data/locales/de.lua new file mode 100644 index 00000000..639fb1d7 --- /dev/null +++ b/modules/job_police/data/locales/de.lua @@ -0,0 +1,151 @@ +Translations = { + -- Cloackroom + ['cloakroom'] = 'Garderobe', + ['citizen_wear'] = 'Zivilkleidung', + ['police_wear'] = 'Arbeitskleidung', + ['gilet_wear'] = 'orange reflective jacket', + ['bullet_wear'] = 'bulletproof vest', + ['no_outfit'] = 'there\'s no uniform that fits you!', + ['open_cloackroom'] = 'Drücke ~INPUT_CONTEXT~ um dich umzuziehen', + -- Armory + ['remove_object'] = 'take object', + ['deposit_object'] = 'deposit object', + ['get_weapon'] = 'Waffen holen', + ['put_weapon'] = 'Waffen bringen', + ['buy_weapons'] = 'Waffen kaufen', + ['armory'] = 'Waffenkammer', + ['open_armory'] = 'Drücke ~INPUT_CONTEXT~ um die Waffenkammer zu öffnen', + ['armory_owned'] = 'owned', + ['armory_free'] = 'free', + ['armory_item'] = '$%s', + ['armory_weapontitle'] = 'armory - Buy weapon', + ['armory_componenttitle'] = 'armory - Weapon attatchments', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', + ['armory_money'] = 'you cannot afford that weapon', + ['armory_hascomponent'] = 'you have that attatchment equiped!', + ['get_weapon_menu'] = 'armory - Withdraw Weapon', + ['put_weapon_menu'] = 'armory - Store Weapon', + -- Vehicles + ['vehicle_menu'] = 'vehicle', + ['vehicle_blocked'] = 'all available spawn points are currently blocked!', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['garage_empty'] = 'you dont have any vehicles in your garage.', + ['garage_released'] = 'your vehicle has been released from the garage.', + ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', + ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', + -- Service + ['service_max'] = 'you cannot enter service, max officers in service: %s/%s', + ['service_not'] = 'you have not entered service! You\'ll have to get changed first.', + ['service_anonunce'] = 'service information', + ['service_in'] = 'you\'ve entered service, welcome!', + ['service_in_announce'] = 'operator ~y~%s~s~ has entered service!', + ['service_out'] = 'you have left service.', + ['service_out_announce'] = 'operator ~y~%s~s~ has left their service.', + -- Action Menu + ['citizen_interaction'] = 'Zivilistenaktionen', + ['vehicle_interaction'] = 'Fahrzeuginteraktionen', + ['object_spawner'] = 'Objekt Spawner', + + ['id_card'] = 'ID Karte', + ['search'] = 'Suche', + ['handcuff'] = 'Festnehmen / Freilassen', + ['drag'] = 'drag', + ['put_in_vehicle'] = 'In Fahrzeug setzen', + ['out_the_vehicle'] = 'take out of vehicle', + ['fine'] = 'Strafe', + ['unpaid_bills'] = 'manage unpaid bills', + ['license_check'] = 'manage license', + ['license_revoke'] = 'revoke license', + ['license_revoked'] = 'your ~b~%s~s~ has been ~y~revoked~s~!', + ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~', + ['no_players_nearby'] = 'keine Spieler in der Nähe', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', + -- Vehicle interaction + ['vehicle_info'] = 'Fahrzeug Info', + ['pick_lock'] = 'Fahrzeug öffnen', + ['vehicle_unlocked'] = 'Fahrzeug ~g~offen~s~', + ['no_vehicles_nearby'] = 'Keine Fahrzeuge in der Nähe', + ['impound'] = 'impound vehicle', + ['impound_prompt'] = 'press ~INPUT_CONTEXT~ to cancel the ~y~impound~s~', + ['impound_canceled'] = 'you canceled the impound', + ['impound_canceled_moved'] = 'the impound has been canceled because the vehicle moved', + ['impound_successful'] = 'you have impounded the vehicle', + ['search_database'] = 'vehicle information', + ['search_database_title'] = 'vehicle information - search with registration number', + ['search_database_error_invalid'] = 'that is ~r~not~s~ a ~y~valid~s~ registration number', + -- Traffic interaction + ['traffic_interaction'] = 'Straßeninteraktionen', + ['cone'] = 'Hütchen', + ['barrier'] = 'Barriere', + ['spikestrips'] = 'Nagelband', + ['box'] = 'Box', + ['cash'] = 'Box mit Geld', + -- ID Card Menu + ['name'] = 'name: %s', + ['job'] = 'job: %s', + ['sex'] = 'sex: %s', + ['dob'] = 'DOB: %s', + ['height'] = 'height: %s', + ['bac'] = 'BAC: %s', + ['unknown'] = 'unknown', + ['male'] = 'male', + ['female'] = 'female', + -- Body Search Menu + ['guns_label'] = '--- Waffen ---', + ['inventory_label'] = '--- Inventar ---', + ['license_label'] = ' --- Licenses ---', + ['confiscate'] = 'konfeszieren %s', + ['confiscate_weapon'] = 'confiscate %s with %s bullets', + ['confiscate_inv'] = 'konfeziere %sx %s', + ['confiscate_dirty'] = 'schwarzgeld konfesziert: $%s', + ['you_confiscated'] = 'you confiscated ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ were confiscated by ~y~%s~s~', + ['you_confiscated_account'] = 'you confiscated ~g~$%s~s~ (%s) from ~b~%s~s~', + ['got_confiscated_account'] = '~g~$%s~s~ (%s) was confiscated by ~y~%s~s~', + ['you_confiscated_weapon'] = 'you confiscated ~b~%s~s~ from ~b~%s~s~ with ~o~%s~s~ bullets', + ['got_confiscated_weapon'] = 'your ~b~%s~s~ with ~o~%s~s~ bullets was confiscated by ~y~%s~s~', + ['traffic_offense'] = 'Verkehrs vergehen', + ['minor_offense'] = 'Geringes vergehen', + ['average_offense'] = 'Normales vergehen', + ['major_offense'] = 'Hohes vergehen', + ['fine_total'] = 'strafe: %s', + -- Vehicle Info Menu + ['plate'] = 'plate: %s', + ['owner_unknown'] = 'besitzer: Unbekannt', + ['owner'] = 'besitzer: %s', + -- Boss Menu + ['open_bossmenu'] = 'Drücke ~INPUT_CONTEXT~ um das Menü zu öffnen', + ['quantity_invalid'] = 'invalid quantity', + ['have_withdrawn'] = 'you have withdrawn ~y~%sx~s~ ~b~%s~s~', + ['have_deposited'] = 'you have deposited ~y~%sx~s~ ~b~%s~s~', + ['quantity'] = 'quantity', + ['inventory'] = 'inventory', + ['police_stock'] = 'police Stock', + -- Misc + ['remove_prop'] = 'Drücke ~INPUT_CONTEXT~ um das Objekt zu entfernen', + ['map_blip'] = 'Polizeistation', + ['unrestrained_timer'] = 'you feel your handcuffs slowly losing grip and fading away.', + -- Notifications + ['alert_police'] = 'Polizei alamieren', + ['phone_police'] = 'police', +} diff --git a/modules/job_police/data/locales/en.lua b/modules/job_police/data/locales/en.lua new file mode 100644 index 00000000..c230c8bc --- /dev/null +++ b/modules/job_police/data/locales/en.lua @@ -0,0 +1,151 @@ +Translations = { + -- Cloakroom + ['cloakroom'] = 'locker room', + ['citizen_wear'] = 'civilian Outfit', + ['police_wear'] = 'police Outfit', + ['gilet_wear'] = 'orange reflective jacket', + ['bullet_wear'] = 'bulletproof vest', + ['no_outfit'] = 'there\'s no uniform that fits you!', + ['open_cloackroom'] = 'press ~INPUT_CONTEXT~ to change ~y~clothes~s~.', + -- Armory + ['remove_object'] = 'withdraw object', + ['deposit_object'] = 'deposit object', + ['get_weapon'] = 'withdraw weapon from armory', + ['put_weapon'] = 'store weapon in armory', + ['buy_weapons'] = 'buy weapons', + ['armory'] = 'armory', + ['open_armory'] = 'press ~INPUT_CONTEXT~ to access the ~y~Armory~s~.', + ['armory_owned'] = 'owned', + ['armory_free'] = 'free', + ['armory_item'] = '$%s', + ['armory_weapontitle'] = 'armory - Buy weapon', + ['armory_componenttitle'] = 'armory - Weapon attatchments', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', + ['armory_money'] = 'you cannot afford that weapon', + ['armory_hascomponent'] = 'you have that attatchment equiped!', + ['get_weapon_menu'] = 'armory - Withdraw Weapon', + ['put_weapon_menu'] = 'armory - Store Weapon', + -- Vehicles + ['vehicle_menu'] = 'vehicle', + ['vehicle_blocked'] = 'all available spawn points are currently blocked!', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['garage_empty'] = 'you dont have any vehicles in your garage.', + ['garage_released'] = 'your vehicle has been released from the garage.', + ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', + ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', + -- Service + ['service_max'] = 'you cannot enter service, max officers in service: %s/%s', + ['service_not'] = 'you have not entered service! You\'ll have to get changed first.', + ['service_anonunce'] = 'service information', + ['service_in'] = 'you\'ve entered service, welcome!', + ['service_in_announce'] = 'operator ~y~%s~s~ has entered service!', + ['service_out'] = 'you have left service.', + ['service_out_announce'] = 'operator ~y~%s~s~ has left their service.', + -- Action Menu + ['citizen_interaction'] = 'citizen Interaction', + ['vehicle_interaction'] = 'vehicle Interaction', + ['object_spawner'] = 'object Spawner', + + ['id_card'] = 'ID Card', + ['search'] = 'search', + ['handcuff'] = 'cuff / Uncuff', + ['drag'] = 'escort', + ['put_in_vehicle'] = 'put in Vehicle', + ['out_the_vehicle'] = 'drag out from vehicle', + ['fine'] = 'fine', + ['unpaid_bills'] = 'manage unpaid bills', + ['license_check'] = 'manage license', + ['license_revoke'] = 'revoke license', + ['license_revoked'] = 'your ~b~%s~s~ has been ~y~revoked~s~!', + ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~', + ['no_players_nearby'] = 'there is no player(s) nearby!', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', + -- Vehicle interaction + ['vehicle_info'] = 'vehicle Info', + ['pick_lock'] = 'lockpick Vehicle', + ['vehicle_unlocked'] = 'vehicle ~g~Unlocked~s~', + ['no_vehicles_nearby'] = 'there is no vehicles nearby', + ['impound'] = 'impound vehicle', + ['impound_prompt'] = 'press ~INPUT_CONTEXT~ to cancel the ~y~impound~s~', + ['impound_canceled'] = 'you canceled the impound', + ['impound_canceled_moved'] = 'the impound has been canceled because the vehicle moved', + ['impound_successful'] = 'you have impounded the vehicle', + ['search_database'] = 'vehicle information', + ['search_database_title'] = 'vehicle information - search with registration number', + ['search_database_error_invalid'] = 'that is ~r~not~s~ a ~y~valid~s~ registration number', + -- Traffic interaction + ['traffic_interaction'] = 'interaction Traffic', + ['cone'] = 'cone', + ['barrier'] = 'barrier', + ['spikestrips'] = 'spikestrips', + ['box'] = 'box', + ['cash'] = 'box of cash', + -- ID Card Menu + ['name'] = 'name: %s', + ['job'] = 'job: %s', + ['sex'] = 'sex: %s', + ['dob'] = 'DOB: %s', + ['height'] = 'height: %s', + ['bac'] = 'BAC: %s', + ['unknown'] = 'unknown', + ['male'] = 'male', + ['female'] = 'female', + -- Body Search Menu + ['guns_label'] = '--- Guns ---', + ['inventory_label'] = '--- Inventory ---', + ['license_label'] = ' --- Licenses ---', + ['confiscate'] = 'confiscate %s', + ['confiscate_weapon'] = 'confiscate %s with %s bullets', + ['confiscate_inv'] = 'confiscate %sx %s', + ['confiscate_dirty'] = 'confiscate dirty money: $%s', + ['you_confiscated'] = 'you confiscated ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ were confiscated by ~y~%s~s~', + ['you_confiscated_account'] = 'you confiscated ~g~$%s~s~ (%s) from ~b~%s~s~', + ['got_confiscated_account'] = '~g~$%s~s~ (%s) was confiscated by ~y~%s~s~', + ['you_confiscated_weapon'] = 'you confiscated ~b~%s~s~ from ~b~%s~s~ with ~o~%s~s~ bullets', + ['got_confiscated_weapon'] = 'your ~b~%s~s~ with ~o~%s~s~ bullets was confiscated by ~y~%s~s~', + ['traffic_offense'] = 'traffic Offense', + ['minor_offense'] = 'minor Offense', + ['average_offense'] = 'average Offense', + ['major_offense'] = 'major Offense', + ['fine_total'] = 'fine: %s', + -- Vehicle Info Menu + ['plate'] = 'plate: %s', + ['owner_unknown'] = 'owner: Unknown', + ['owner'] = 'owner: %s', + -- Boss Menu + ['open_bossmenu'] = 'press ~INPUT_CONTEXT~ to open the menu', + ['quantity_invalid'] = 'invalid quantity', + ['have_withdrawn'] = 'you have withdrawn ~y~%sx~s~ ~b~%s~s~', + ['have_deposited'] = 'you have deposited ~y~%sx~s~ ~b~%s~s~', + ['quantity'] = 'quantity', + ['inventory'] = 'inventory', + ['police_stock'] = 'police Stock', + -- Misc + ['remove_prop'] = 'press ~INPUT_CONTEXT~ to delete the object', + ['map_blip'] = 'police Station', + ['unrestrained_timer'] = 'you feel your handcuffs slowly losing grip and fading away.', + -- Notifications + ['alert_police'] = 'police alert', + ['phone_police'] = 'police', +} diff --git a/modules/job_police/data/locales/es.lua b/modules/job_police/data/locales/es.lua new file mode 100644 index 00000000..21a9af87 --- /dev/null +++ b/modules/job_police/data/locales/es.lua @@ -0,0 +1,151 @@ +Translations = { + -- Cloakroom + ['cloakroom'] = 'Taquilla', + ['citizen_wear'] = 'Ropa civil', + ['police_wear'] = 'Ropa CNP', + ['gilet_wear'] = 'orange reflective jacket', + ['bullet_wear'] = 'bulletproof vest', + ['no_outfit'] = 'there\'s no uniform that fits you!', + ['open_cloackroom'] = 'Presionar ~INPUT_CONTEXT~ para abrir la taquilla', + -- Armory + ['remove_object'] = 'take object', + ['deposit_object'] = 'deposit object', + ['get_weapon'] = 'Coger arma', + ['put_weapon'] = 'Depositar arma', + ['buy_weapons'] = 'Comprar armas', + ['armory'] = 'Arsenal', + ['open_armory'] = 'Presionarr ~INPUT_CONTEXT~ para acceder a la armeria', + ['armory_owned'] = 'owned', + ['armory_free'] = 'free', + ['armory_item'] = '$%s', + ['armory_weapontitle'] = 'armory - Buy weapon', + ['armory_componenttitle'] = 'armory - Weapon attatchments', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', + ['armory_money'] = 'you cannot afford that weapon', + ['armory_hascomponent'] = 'you have that attatchment equiped!', + ['get_weapon_menu'] = 'armory - Withdraw Weapon', + ['put_weapon_menu'] = 'armory - Store Weapon', + -- Vehicles + ['vehicle_menu'] = 'vehicle', + ['vehicle_blocked'] = 'all available spawn points are currently blocked!', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['garage_empty'] = 'you dont have any vehicles in your garage.', + ['garage_released'] = 'your vehicle has been released from the garage.', + ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', + ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', + -- Service + ['service_max'] = 'you cannot enter service, max officers in service: %s/%s', + ['service_not'] = 'you have not entered service! You\'ll have to get changed first.', + ['service_anonunce'] = 'service information', + ['service_in'] = 'you\'ve entered service, welcome!', + ['service_in_announce'] = 'operator ~y~%s~s~ has entered service!', + ['service_out'] = 'you have left service.', + ['service_out_announce'] = 'operator ~y~%s~s~ has left their service.', + -- Action Menu + ['citizen_interaction'] = 'Interacción ciudadana', + ['vehicle_interaction'] = 'Interacción vehículo', + ['object_spawner'] = 'Colocar objetos', + + ['id_card'] = 'Documento de identidad', + ['search'] = 'Buscar', + ['handcuff'] = 'Poner/quitar Esposas', + ['drag'] = 'escoltar', + ['put_in_vehicle'] = 'Meter en el vehículo', + ['out_the_vehicle'] = 'Sacar del vehículo', + ['fine'] = 'Multa', + ['unpaid_bills'] = 'manage unpaid bills', + ['license_check'] = 'manage license', + ['license_revoke'] = 'revoke license', + ['license_revoked'] = 'your ~b~%s~s~ has been ~y~revoked~s~!', + ['licence_you_revoked'] = 'you revoked a ~b~%s~s~ which belonged to ~y~%s~s~', + ['no_players_nearby'] = 'no hay jugadores cerca', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', + -- Vehicle interaction + ['vehicle_info'] = 'Información del vehículo', + ['pick_lock'] = 'Forzar coche', + ['vehicle_unlocked'] = 'Vehículo desbloqueado~s~', + ['no_vehicles_nearby'] = 'No hay vehículos cerca', + ['impound'] = 'impound vehicle', + ['impound_prompt'] = 'press ~INPUT_CONTEXT~ to cancel the ~y~impound~s~', + ['impound_canceled'] = 'you canceled the impound', + ['impound_canceled_moved'] = 'the impound has been canceled because the vehicle moved', + ['impound_successful'] = 'you have impounded the vehicle', + ['search_database'] = 'vehicle information', + ['search_database_title'] = 'vehicle information - search with registration number', + ['search_database_error_invalid'] = 'that is ~r~not~s~ a ~y~valid~s~ registration number', + -- Traffic interaction + ['traffic_interaction'] = 'Rutas de interacción', + ['cone'] = 'Cono', + ['barrier'] = 'Barrera', + ['spikestrips'] = 'Grada', + ['box'] = 'Caja', + ['cash'] = 'Dinero', + -- ID Card Menu + ['name'] = 'name: %s', + ['job'] = 'job: %s', + ['sex'] = 'sex: %s', + ['dob'] = 'DOB: %s', + ['height'] = 'height: %s', + ['bac'] = 'BAC: %s', + ['unknown'] = 'unknown', + ['male'] = 'male', + ['female'] = 'female', + -- Body Search Menu + ['guns_label'] = '--- Armas ---', + ['inventory_label'] = '--- Inventario ---', + ['license_label'] = ' --- Licenses ---', + ['confiscate'] = 'confiscar %s', + ['confiscate_weapon'] = 'confiscate %s with %s bullets', + ['confiscate_inv'] = 'confiscar %sx %s', + ['confiscate_dirty'] = 'confiscar dinero negro: €%s', + ['you_confiscated'] = 'you confiscated ~y~%sx~s~ ~b~%s~s~ from ~b~%s~s~', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ were confiscated by ~y~%s~s~', + ['you_confiscated_account'] = 'you confiscated ~g~€%s~s~ (%s) from ~b~%s~s~', + ['got_confiscated_account'] = '~g~€%s~s~ (%s) was confiscated by ~y~%s~s~', + ['you_confiscated_weapon'] = 'you confiscated ~b~%s~s~ from ~b~%s~s~ with ~o~%s~s~ bullets', + ['got_confiscated_weapon'] = 'your ~b~%s~s~ with ~o~%s~s~ bullets was confiscated by ~y~%s~s~', + ['traffic_offense'] = 'Delito de tráfico', + ['minor_offense'] = 'Delito menor', + ['average_offense'] = 'Delito medio', + ['major_offense'] = 'Delito grave', + ['fine_total'] = 'Multa total: %s', + -- Vehicle Info Menu + ['plate'] = 'n°: %s', + ['owner_unknown'] = 'propietario: Desconocido', + ['owner'] = 'propietario: %s', + -- Boss Menu + ['open_bossmenu'] = 'presionar ~INPUT_CONTEXT~ para abrir el menú', + ['quantity_invalid'] = 'cantidad invalida', + ['have_withdrawn'] = 'you have withdrawn ~y~%sx~s~ ~b~%s~s~', + ['have_deposited'] = 'you have deposited ~y~%sx~s~ ~b~%s~s~', + ['quantity'] = 'cantidad', + ['inventory'] = 'inventario', + ['police_stock'] = 'almacen Policial', + -- Misc + ['remove_prop'] = 'presionar ~INPUT_CONTEXT~ para eliminar el objeto', + ['map_blip'] = 'comisaría de policía', + ['unrestrained_timer'] = 'you feel your handcuffs slowly losing grip and fading away.', + -- Notifications + ['alert_police'] = 'alerta policia', + ['phone_police'] = 'policia', +} diff --git a/modules/job_police/data/locales/fi.lua b/modules/job_police/data/locales/fi.lua new file mode 100644 index 00000000..732f1db7 --- /dev/null +++ b/modules/job_police/data/locales/fi.lua @@ -0,0 +1,151 @@ +Translations = { + -- Cloakroom + ['cloakroom'] = 'vaatelokero', + ['citizen_wear'] = 'siviiliasu', + ['police_wear'] = 'poliisiasu', + ['gilet_wear'] = 'huomioliivi', + ['bullet_wear'] = 'luotiliivi', + ['no_outfit'] = 'täällä ei ole sinulle sopivaa asua', + ['open_cloackroom'] = 'paina ~INPUT_CONTEXT~ vaihtaaksesi ~y~vaatteita~s~.', + -- Armory + ['remove_object'] = 'ota esine', + ['deposit_object'] = 'talleta esine', + ['get_weapon'] = 'ota ase', + ['put_weapon'] = 'laita ase pois', + ['buy_weapons'] = 'osta aseita', + ['armory'] = 'asevarasto', + ['open_armory'] = 'paina ~INPUT_CONTEXT~ avataksesi asevarasto', + ['armory_owned'] = 'owned', + ['armory_free'] = 'free', + ['armory_item'] = '$%s', + ['armory_weapontitle'] = 'armory - Buy weapon', + ['armory_componenttitle'] = 'armory - Weapon attatchments', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', + ['armory_money'] = 'you cannot afford that weapon', + ['armory_hascomponent'] = 'you have that attatchment equiped!', + ['get_weapon_menu'] = 'armory - Withdraw Weapon', + ['put_weapon_menu'] = 'armory - Store Weapon', + -- Vehicles + ['vehicle_menu'] = 'vehicle', + ['vehicle_blocked'] = 'all available spawn points are currently blocked!', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['garage_empty'] = 'you dont have any vehicles in your garage.', + ['garage_released'] = 'your vehicle has been released from the garage.', + ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', + ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', + -- Service + ['service_max'] = 'you cannot enter service, max officers in service: %s/%s', + ['service_not'] = 'you have not entered service! You\'ll have to get changed first.', + ['service_anonunce'] = 'service information', + ['service_in'] = 'you\'ve entered service, welcome!', + ['service_in_announce'] = 'operator ~y~%s~s~ has entered service!', + ['service_out'] = 'you have left service.', + ['service_out_announce'] = 'operator ~y~%s~s~ has left their service.', + -- Action Menu + ['citizen_interaction'] = 'siviilin vuorovaikutus', + ['vehicle_interaction'] = 'ajoneuvon vuorovaikutus', + ['object_spawner'] = 'objekti spawneri', + + ['id_card'] = 'henkilöllisyystodistus', + ['search'] = 'tutki', + ['handcuff'] = 'raudat On/Off', + ['drag'] = 'raahaa', + ['put_in_vehicle'] = 'laita ajoneuvoon', + ['out_the_vehicle'] = 'ota ulos ajoneuvosta', + ['fine'] = 'sakko', + ['unpaid_bills'] = 'hallinoi maksamattomia laskuja', + ['license_check'] = 'hallitse lisenssejä', + ['license_revoke'] = 'kumoa lisenssi', + ['license_revoked'] = 'sinun ~b~%s~s~ ~y~kumottiin~s~!', + ['licence_you_revoked'] = 'sinä kumosit ~b~%s~s~ mikä kuului henkilölle ~y~%s~s~', + ['no_players_nearby'] = 'ei pelaajia lähettyvillä', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', + -- Vehicle interaction + ['vehicle_info'] = 'ajoneuvon tiedot', + ['pick_lock'] = 'tiirikoi ovet', + ['vehicle_unlocked'] = 'ajoneuvo ~g~Avattu~s~', + ['no_vehicles_nearby'] = 'ei ajoneuvoja lähettyvillä', + ['impound'] = 'takavarikoi ajoneuvo', + ['impound_prompt'] = 'paina ~INPUT_CONTEXT~ peruaksesi ~y~takavarikointi~s~', + ['impound_canceled'] = 'sinä peruit takavarikoinnin', + ['impound_canceled_moved'] = 'takavarikointi peruuntui koska ajoneuvo liikku', + ['impound_successful'] = 'takavarikoit ajoneuvon', + ['search_database'] = 'ajoneuvon tiedot', + ['search_database_title'] = 'ajoneuvon tiedot - etsi rekisterinumerolla', + ['search_database_error_invalid'] = 'tämä ~r~ei ole~s~ ~y~voimassa oleva~s~ rekisterinumero', + -- Traffic interaction + ['traffic_interaction'] = 'liikenteen vuorovaikutus', + ['cone'] = 'kartio', + ['barrier'] = 'este', + ['spikestrips'] = 'piikkimatto', + ['box'] = 'laatikko', + ['cash'] = 'rahalaatikko', + -- ID Card Menu + ['name'] = 'nimi: %s', + ['job'] = 'työ: %s', + ['sex'] = 'sukupuoli: %s', + ['dob'] = 'syntymäaika: %s', + ['height'] = 'pituus: %s', + ['bac'] = 'alkometri: %s', + ['unknown'] = 'tuntematon', + ['male'] = 'mies', + ['female'] = 'nainen', + -- Body Search Menu + ['guns_label'] = '--- Aseet ---', + ['inventory_label'] = '--- Reppu ---', + ['license_label'] = ' --- Lisenssit ---', + ['confiscate'] = 'takavarikoi %s', + ['confiscate_weapon'] = 'confiscate %s with %s bullets', + ['confiscate_inv'] = 'takavarikoi %sx %s', + ['confiscate_dirty'] = 'takavarikoi likainen raha: $%s', + ['you_confiscated'] = 'sinä takavarioit ~y~%sx~s~ ~b~%s~s~ pelaajalta ~b~%s~s~', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ takavarikoitiin sinulta pelaajan ~y~%s~s~ toimesta', + ['you_confiscated_account'] = 'sinä takavarikoit ~g~$%s~s~ (%s) pelaajalta ~b~%s~s~', + ['got_confiscated_account'] = '~g~$%s~s~ (%s) takavarikoitiin sinulta pelaajan ~y~%s~s~ toimesta', + ['you_confiscated_weapon'] = 'sinä takavarikoit ~b~%s~s~ pelaajalta ~b~%s~s~ jossa oli ~o~%s~s~ panosta', + ['got_confiscated_weapon'] = 'sinun ~b~%s~s~ jossa oli ~o~%s~s~ panosta takavarikoitiin sinulta~y~%s~s~', + ['traffic_offense'] = 'liikenne rikokset', + ['minor_offense'] = 'lievät rikokset', + ['average_offense'] = 'keskisuuret rikokset', + ['major_offense'] = 'vakavat rikokset', + ['fine_total'] = 'sakko: %s', + --Vehicle Info Menu + ['plate'] = 'kilpi: %s', + ['owner_unknown'] = 'omistaja: Tuntematon', + ['owner'] = 'omistaja: %s', + --Boss Menu + ['open_bossmenu'] = 'paina ~INPUT_CONTEXT~ avataksesi valikon', + ['quantity_invalid'] = 'invalid quantity', + ['have_withdrawn'] = 'sinä otit varastosta ~y~%sx~s~ ~b~%s~s~', + ['have_deposited'] = 'sinä talletit varastoon ~y~%sx~s~ ~b~%s~s~', + ['quantity'] = 'määrä', + ['inventory'] = 'varasto', + ['police_stock'] = 'poliisin Varasto', + -- Misc + ['remove_prop'] = 'paina ~INPUT_CONTEXT~ poistaaksesi objektin', + ['map_blip'] = 'poliisilaitos', + ['unrestrained_timer'] = 'tunnet kuinka hitaasti käsiraudat alkavat löystyä ja irtoavat', + -- Notifications + ['alert_police'] = 'hälyytys Poliisi', + ['phone_police'] = 'poliisi', +} diff --git a/modules/job_police/data/locales/fr.lua b/modules/job_police/data/locales/fr.lua new file mode 100644 index 00000000..42ea497e --- /dev/null +++ b/modules/job_police/data/locales/fr.lua @@ -0,0 +1,151 @@ +Translations = { + -- Cloakroom + ['cloakroom'] = 'vestiaire', + ['citizen_wear'] = 'tenue Civil', + ['police_wear'] = 'tenue Policier', + ['gilet_wear'] = 'gilet orange', + ['bullet_wear'] = 'gilet pare-balles', + ['no_outfit'] = 'il n\'y a pas d\'uniforme à votre taille...', + ['open_cloackroom'] = 'appuyez sur ~INPUT_CONTEXT~ pour vous changer', + -- Armory + ['remove_object'] = 'prendre Objet', + ['deposit_object'] = 'déposer objet', + ['get_weapon'] = 'prendre Arme', + ['put_weapon'] = 'déposer Arme', + ['buy_weapons'] = 'acheter Armes', + ['armory'] = 'armurerie', + ['open_armory'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder à l\'armurerie', + ['armory_owned'] = 'possédé', + ['armory_free'] = 'gratuit', + ['armory_item'] = '$%s', + ['armory_weapontitle'] = 'armurerie - Acheter une arme', + ['armory_componenttitle'] = 'armurerie - Accessoires d\'armes', + ['armory_bought'] = 'vous achetez un ~y~%s~s~ pour ~g~$%s~s~', + ['armory_money'] = 'vous ne pouvez pas acheter cette arme', + ['armory_hascomponent'] = 'vous avez cet accessoire équipé!', + ['get_weapon_menu'] = 'armurerie - Retirer arme', + ['put_weapon_menu'] = 'armurerie - Stocker arme', + -- Vehicles + ['vehicle_menu'] = 'véhicule', + ['vehicle_blocked'] = 'tous les points de spawn sont bloqués!', + ['garage_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder aux ~y~Actions Véhicule~s~.', + ['garage_title'] = 'actions Véhicules', + ['garage_stored'] = 'rangé', + ['garage_notstored'] = 'sorti(e)', + ['garage_storing'] = 'tentative de suppression du véhicule, assurez-vous que personne ne soit autour.', + ['garage_has_stored'] = 'le véhicule a bien été rangé dans le garage', + ['garage_has_notstored'] = 'aucun véhicule dans le garage', + ['garage_notavailable'] = 'votre véhicule n\'est pas rangé dans le garage.', + ['garage_blocked'] = 'la sortie du garage est obstruée!', + ['garage_empty'] = 'vous n\'avez aucun véhicule dans le garage.', + ['garage_released'] = 'votre véhicule a été sorti.', + ['garage_store_nearby'] = 'aucun véhicule a proximité.', + ['garage_storeditem'] = 'ouvrir le garage', + ['garage_storeitem'] = 'ranger le véhicule', + ['garage_buyitem'] = 'magasin véhicule', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', + ['helicopter_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour accéder aux ~y~Actions de l\'hélicoptère~s~.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'magasin véhicule', + ['vehicleshop_confirm'] = 'voulez-vous acheter ce véhicule?', + ['vehicleshop_bought'] = 'vous avez acheté ~y~%s~s~ pour ~r~$%s~s~', + ['vehicleshop_money'] = 'vous ne pouvez pas acheter ce véhicule', + ['vehicleshop_awaiting_model'] = 'le véhicule est actuellement en ~g~PRÉPARATION~s~ veuillez patienter', + ['confirm_no'] = 'non', + ['confirm_yes'] = 'oui', + -- Service + ['service_max'] = 'vous ne pouvez pas entrer en service, officiers en service: %s/%s', + ['service_not'] = 'vous n\'êtes pas en service! Vous devez d\'abord enfiler votre tenue.', + ['service_anonunce'] = 'prise de service', + ['service_in'] = 'vous êtes en service, bon courage!', + ['service_in_announce'] = 'l\'officier ~y~%s~s~ est entré en service!', + ['service_out'] = 'vous avez terminé votre service.', + ['service_out_announce'] = 'l\'officier ~y~%s~s~ a quitté son service.', + -- Action Menu + ['citizen_interaction'] = 'interaction citoyen', + ['vehicle_interaction'] = 'interaction véhicule', + ['object_spawner'] = 'placer objets', + + ['id_card'] = 'carte d\'identité', + ['search'] = 'fouiller', + ['handcuff'] = 'menotter / Démenotter', + ['drag'] = 'escorter', + ['put_in_vehicle'] = 'mettre dans véhicule', + ['out_the_vehicle'] = 'sortir du véhicule', + ['fine'] = 'Amende', + ['unpaid_bills'] = 'gérer les amendes impayées', + ['license_check'] = 'gérer les licences', + ['license_revoke'] = 'révoquer la licence', + ['license_revoked'] = 'votre ~b~%s~s~ a été ~y~révoqué~s~!', + ['licence_you_revoked'] = 'vous avez révoqué un ~b~%s~s~ qui appartenait à ~y~%s~s~', + ['no_players_nearby'] = 'aucun joueur à proximité', + ['being_searched'] = 'vous êtes ~y~recherché(e)~s~ par la ~b~Police~s~', + -- Vehicle interaction + ['vehicle_info'] = 'infos véhicule', + ['pick_lock'] = 'crocheter véhicule', + ['vehicle_unlocked'] = 'véhicule ~g~déverouillé~s~', + ['no_vehicles_nearby'] = 'aucun véhicule à proximité', + ['impound'] = 'véhicule en fourrière', + ['impound_prompt'] = 'appuyez sur ~INPUT_CONTEXT~ pour annuler la ~y~saisie du véhicule~s~', + ['impound_canceled'] = 'vous avez annulé la saisie', + ['impound_canceled_moved'] = 'la saisie a été annulée parce que le véhicule a déménagé', + ['impound_successful'] = 'vous avez saisi le véhicule', + ['search_database'] = 'vehicle information', + ['search_database_title'] = 'informations sur le véhicule - recherche avec numéro d\'enregistrement', + ['search_database_error_invalid'] = 'Ce n\'est ~r~pas~s~ un ~y~numéro d\'enregistrement valide~s~', + -- Traffic interaction + ['traffic_interaction'] = 'interaction routière', + ['cone'] = 'plot', + ['barrier'] = 'barrière', + ['spikestrips'] = 'herse', + ['box'] = 'caisse', + ['cash'] = 'caisse', + -- ID Card Menu + ['name'] = 'nom: %s', + ['job'] = 'métier: %s', + ['sex'] = 'sexe: %s', + ['dob'] = 'DOB: %s', + ['height'] = 'taille: %s', + ['bac'] = 'BAC: %s', + ['unknown'] = 'inconnu', + ['male'] = 'homme', + ['female'] = 'femme', + -- Body Search Menu + ['guns_label'] = '--- Armes ---', + ['inventory_label'] = '--- Inventaire ---', + ['license_label'] = ' --- Licenses ---', + ['confiscate'] = 'confisquer %s', + ['confiscate_weapon'] = 'confisqué %s avec %s balles', + ['confiscate_inv'] = 'confisquer %sx %s', + ['confiscate_dirty'] = 'confisquer argent sale: €%s', + ['you_confiscated'] = 'vous avez confisqué ~y~%sx~s~ ~b~%s~s~ à ~b~%s~s~', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ ont été confisqués par ~y~%s~s~', + ['you_confiscated_account'] = 'vous avez confisqué ~g~$%s~s~ (%s) à ~b~%s~s~', + ['got_confiscated_account'] = '~g~$%s~s~ (%s) ont été confisqués par ~y~%s~s~', + ['you_confiscated_weapon'] = 'vous avez confisqué ~b~%s~s~ à ~b~%s~s~ avec ~o~%s~s~ balles', + ['got_confiscated_weapon'] = 'votre ~b~%s~s~ avec ~o~%s~s~ balles a été confisqué par ~y~%s~s~', + ['traffic_offense'] = 'code de la route', + ['minor_offense'] = 'délit mineur', + ['average_offense'] = 'délit moyen', + ['major_offense'] = 'délit grave', + ['fine_total'] = 'amende: %s', + -- Vehicle Info Menu + ['plate'] = 'n°: %s', + ['owner_unknown'] = 'propriétaire: Inconnu', + ['owner'] = 'propriétaire: %s', + -- Boss Menu + ['open_bossmenu'] = 'appuyez sur ~INPUT_CONTEXT~ pour ouvrir le menu', + ['quantity_invalid'] = 'quantité invalide', + ['have_withdrawn'] = 'vous avez retiré ~y~%sx~s~ ~b~%s~s~', + ['have_deposited'] = 'vous avez déposé ~y~%sx~s~ ~b~%s~s~', + ['quantity'] = 'quantité', + ['inventory'] = 'inventaire', + ['police_stock'] = 'coffre de la police', + -- Misc + ['remove_prop'] = 'appuyez sur ~INPUT_CONTEXT~ pour enlever l\'objet', + ['map_blip'] = 'Commissariat', + ['unrestrained_timer'] = 'vous sentez que vos menottes deviennent fragiles.', + -- Notifications + ['alert_police'] = 'alerte police', + ['phone_police'] = 'police', +} diff --git a/modules/job_police/data/locales/ko.lua b/modules/job_police/data/locales/ko.lua new file mode 100644 index 00000000..29ef383d --- /dev/null +++ b/modules/job_police/data/locales/ko.lua @@ -0,0 +1,151 @@ +Translations = { + -- Cloakroom + ['cloakroom'] = '라커룸', + ['citizen_wear'] = '민간인 복장', + ['police_wear'] = '경찰 복장', + ['gilet_wear'] = '오렌지 반사 재킷', + ['bullet_wear'] = '방탄 조끼', + ['no_outfit'] = '당신에게 맞는 유니폼이 없습니다!', + ['open_cloackroom'] = '~y~옷~s~을 변경하려면 ~INPUT_CONTEXT~를 누르십시오.', + -- Armory + ['remove_object'] = '오브젝트를 빼다', + ['deposit_object'] = '오브젝트를 두다', + ['get_weapon'] = '병기고에서 무기를 빼다', + ['put_weapon'] = '병기고에 무기를 넣다', + ['buy_weapons'] = '무기 구매', + ['armory'] = '병기고', + ['open_armory'] = '~INPUT_CONTEXT~를 눌러 ~y~병기고~s~에 접근하십시오.', + ['armory_owned'] = '소유', + ['armory_free'] = '자유', + ['armory_item'] = '$%s', + ['armory_weapontitle'] = '병기고 - 무기 구매', + ['armory_componenttitle'] = '병기고 - 무기 부착물', + ['armory_bought'] = '당신은 ~g~$%s~s~에 ~y~%s~s~를 구매했습니다', + ['armory_money'] = '당신은 이 무기를 살 수 없습니다', + ['armory_hascomponent'] = '이 부착물이 장착되어 있습니다!', + ['get_weapon_menu'] = '병기고 - 무기 빼다', + ['put_weapon_menu'] = '병기고 - 무기 넣다', + -- Vehicles + ['vehicle_menu'] = '차량', + ['vehicle_blocked'] = '모든 스폰 지점이 차단되었습니다!', + ['garage_prompt'] = '~INPUT_CONTEXT~를 눌러 ~y~차량 동작~s~에 액세스하십시오.', + ['garage_title'] = '차량 행동', + ['garage_stored'] = '저장됨', + ['garage_notstored'] = '차고가 아님', + ['garage_storing'] = '차량을 제거하려고 합니다. 주변에 아무도 없는지 확인하십시오.', + ['garage_has_stored'] = '차량이 차고에 보관되었습니다', + ['garage_has_notstored'] = '차고에 차량이 없습니다', + ['garage_notavailable'] = '차량이 차고에 저장되어 있지 않습니다', + ['garage_blocked'] = '차고 출구가 막혔습니다!', + ['garage_empty'] = '차고에 차량이 없습니다.', + ['garage_released'] = '차량이 출시되었습니다', + ['garage_store_nearby'] = '주변에 차량이 없습니다.', + ['garage_storeditem'] = '차고 열기', + ['garage_storeitem'] = '차량 정리', + ['garage_buyitem'] = '차량 상점', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', + ['helicopter_prompt'] = '~y~헬리콥터 동작~s~에 액세스하려면 ~INPUT_CONTEXT~를 누릅니다.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = '차량 판매점', + ['vehicleshop_confirm'] = '이 차량을 사고 싶습니까?', + ['vehicleshop_bought'] = '당신은 ~r~$%s~s~에 ~y~%s~s~를 구매했습니다', + ['vehicleshop_money'] = '이 차량을 살 수 없습니다', + ['vehicleshop_awaiting_model'] = '차량이 현재 ~g~다운로드 및 로딩중입니다~s~. 잠시만 기다려주십시오', + ['confirm_no'] = '아니요', + ['confirm_yes'] = '예', + -- Service + ['service_max'] = '서비스에 진입 할 수 없습니다. 최대 임원 : %s/%s', + ['service_not'] = '당신은 서비스를 입력하지 않았습니다! 먼저 변경해야합니다.', + ['service_anonunce'] = '서비스 정보', + ['service_in'] = '당신은 서비스에 들어갔다, 환영합니다!', + ['service_in_announce'] = '~y~%s~s~가 서비스에 들어 왔습니다!', + ['service_out'] = '당신은 서비스를 떠났습니다.', + ['service_out_announce'] = '~y~%s~s~가 서비스를 떠났습니다.', + -- Action Menu + ['citizen_interaction'] = '시민 상호 작용', + ['vehicle_interaction'] = '차량 상호 작용', + ['object_spawner'] = '오브젝트 Spawner', + + ['id_card'] = '신분증', + ['search'] = '수색', + ['handcuff'] = '수갑을 채우다 / 수갑을 풀어주다', + ['drag'] = '호위', + ['put_in_vehicle'] = '차량에 넣다', + ['out_the_vehicle'] = '차량을 끌다', + ['fine'] = '벌금', + ['unpaid_bills'] = '미지급 벌금 관리', + ['license_check'] = '라이선스 관리', + ['license_revoke'] = '라이선스 취소', + ['license_revoked'] = '~b~%s~s~는 ~y~취소~s~입니다!', + ['licence_you_revoked'] = '~y~%s~s~에 속하는 ~b~%s~s~를 취소했습니다.', + ['no_players_nearby'] = '근처에 플레이어가 없습니다!', + ['being_searched'] = '~b~경찰~s~이 당신을 ~y~수색~s~', + -- Vehicle interaction + ['vehicle_info'] = '차량 정보', + ['pick_lock'] = '차량 락픽', + ['vehicle_unlocked'] = '차량 ~g~잠금 해제~s~', + ['no_vehicles_nearby'] = '근처에 차량이 없습니다', + ['impound'] = '차량을 견인하다', + ['impound_prompt'] = '~y~견인~s~을 취소하려면 ~INPUT_CONTEXT~를 누릅니다', + ['impound_canceled'] = '당신은 견인을 취소했습니다', + ['impound_canceled_moved'] = '차량이 움직였기 때문에 견인이 취소되었습니다', + ['impound_successful'] = '당신은 차량을 견인했습니다', + ['search_database'] = '차량 정보', + ['search_database_title'] = '차량 정보 - 등록번호로 검색', + ['search_database_error_invalid'] = '~y~유효한~s~ 등록 번호가 ~r~아닙니다.~s~', + -- Traffic interaction + ['traffic_interaction'] = '교통 상호 작용', + ['cone'] = '원뿔', + ['barrier'] = '장벽', + ['spikestrips'] = '스파이크 스트립', + ['box'] = '상자', + ['cash'] = '현금 상자', + -- ID Card Menu + ['name'] = '이름: %s', + ['job'] = '직업: %s', + ['sex'] = '성별: %s', + ['dob'] = '생일: %s', + ['height'] = '키: %s', + ['bac'] = '혈중 알코올 농도: %s', + ['unknown'] = '알 수 없는', + ['male'] = '남자', + ['female'] = '여자', + -- Body Search Menu + ['guns_label'] = '--- 총 ---', + ['inventory_label'] = '--- 인벤토리 ---', + ['license_label'] = ' --- 라이선스 ---', + ['confiscate'] = '%s 을 압수', + ['confiscate_weapon'] = '%s 와 %s 총알을 압수', + ['confiscate_inv'] = '%sx %s 을 압수', + ['confiscate_dirty'] = '더러운 돈을 압수: $%s', + ['you_confiscated'] = '당신은 ~y~%sx~s~ ~b~%s~s~을 ~b~%s~s~에게서 압수했습니다', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~이(가) ~y~%s~s~에 압수되었습니다', + ['you_confiscated_account'] = '당신은 ~g~$%s~s~ (%s) 를 ~b~%s~s~ 에게서 압수했습니다.', + ['got_confiscated_account'] = '~g~$%s~s~ (%s) 이(가) ~y~%s~s~에 압수되었습니다', + ['you_confiscated_weapon'] = '당신은 ~b~%s~s~을 ~b~%s~s~에게서 압수하고 ~o~%s~s~ 총알도 압수했습니다.', + ['got_confiscated_weapon'] = '당신의 ~b~%s~s~와 ~o~%s~s~ 총알이 ~y~%s~s~에 의해 압수되었습니다.', + ['traffic_offense'] = '교통 위반', + ['minor_offense'] = '경범죄', + ['average_offense'] = '일반 범죄', + ['major_offense'] = '심각한 범죄', + ['fine_total'] = '벌금: %s', + -- Vehicle Info Menu + ['plate'] = '번호판: %s', + ['owner_unknown'] = '소유자: 알 수 없는', + ['owner'] = '소유자: %s', + -- Boss Menu + ['open_bossmenu'] = '~INPUT_CONTEXT~를 눌러 메뉴를 엽니다.', + ['quantity_invalid'] = '유효하지 않은 수량', + ['have_withdrawn'] = '당신은 ~y~%sx~s~ ~b~%s~s~ 뺐다 ', + ['have_deposited'] = '당신은 ~y~%sx~s~ ~b~%s~s~ 넣었다', + ['quantity'] = '수량', + ['inventory'] = '인벤토리', + ['police_stock'] = '경찰 자리', + -- Misc + ['remove_prop'] = '~INPUT_CONTEXT~를 눌러 오브젝트를 삭제하십시오.', + ['map_blip'] = '경찰서', + ['unrestrained_timer'] = '당신의 수갑이 천천히 풀리는 것을 느낍니다.', + -- Notifications + ['alert_police'] = '경찰 경보', + ['phone_police'] = '경찰', +} diff --git a/modules/job_police/data/locales/pl.lua b/modules/job_police/data/locales/pl.lua new file mode 100644 index 00000000..f85d4fa3 --- /dev/null +++ b/modules/job_police/data/locales/pl.lua @@ -0,0 +1,151 @@ +Translations = { + -- Cloakroom + ['cloakroom'] = 'szatnia', + ['citizen_wear'] = 'ubranie Cywilne', + ['police_wear'] = 'mundur', + ['gilet_wear'] = 'kamizelka odblaskowa', + ['bullet_wear'] = 'kamizelka kuloodporna', + ['no_outfit'] = 'brak ubrania', + ['open_cloackroom'] = 'naciśnij ~INPUT_CONTEXT~ aby zmienić ~y~ubranie~s~.', + -- Armory + ['remove_object'] = 'weź przedmiot', + ['deposit_object'] = 'zdeponuj przedmiot', + ['get_weapon'] = 'weź broń', + ['put_weapon'] = 'odłóż broń', + ['buy_weapons'] = 'kup Broń', + ['armory'] = 'zbrojownia', + ['open_armory'] = 'naciśnij ~INPUT_CONTEXT~ żeby uzyskać dostęp do zbrojowni', + ['armory_owned'] = 'owned', + ['armory_free'] = 'free', + ['armory_item'] = '$%s', + ['armory_weapontitle'] = 'armory - Buy weapon', + ['armory_componenttitle'] = 'armory - Weapon attatchments', + ['armory_bought'] = 'you bought an ~y~%s~s~ for ~g~$%s~s~', + ['armory_money'] = 'you cannot afford that weapon', + ['armory_hascomponent'] = 'you have that attatchment equiped!', + ['get_weapon_menu'] = 'armory - Withdraw Weapon', + ['put_weapon_menu'] = 'armory - Store Weapon', + -- Vehicles + ['vehicle_menu'] = 'vehicle', + ['vehicle_blocked'] = 'all available spawn points are currently blocked!', + ['garage_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Vehicle Actions~s~.', + ['garage_title'] = 'vehicle Actions', + ['garage_stored'] = 'stored', + ['garage_notstored'] = 'not in garage', + ['garage_storing'] = 'we\'re attempting to remove the vehicle, make sure no players are around it.', + ['garage_has_stored'] = 'the vehicle has been stored in your garage', + ['garage_has_notstored'] = 'no nearby owned vehicles were found', + ['garage_notavailable'] = 'your vehicle is not stored in the garage.', + ['garage_blocked'] = 'there\'s no available spawn points!', + ['garage_empty'] = 'you dont have any vehicles in your garage.', + ['garage_released'] = 'your vehicle has been released from the garage.', + ['garage_store_nearby'] = 'there is no nearby vehicles.', + ['garage_storeditem'] = 'open garage', + ['garage_storeitem'] = 'store vehicle in garage', + ['garage_buyitem'] = 'vehicle shop', + ['garage_notauthorized'] = 'you\'re not authorized to buy this kind of vehicles.', + ['helicopter_prompt'] = 'press ~INPUT_CONTEXT~ to access the ~y~Helicopter Actions~s~.', + ['shop_item'] = '$%s', + ['vehicleshop_title'] = 'vehicle Shop', + ['vehicleshop_confirm'] = 'do you want to buy this vehicle?', + ['vehicleshop_bought'] = 'you have bought ~y~%s~s~ for ~r~$%s~s~', + ['vehicleshop_money'] = 'you cannot afford that vehicle', + ['vehicleshop_awaiting_model'] = 'the vehicle is currently ~g~DOWNLOADING & LOADING~s~ please wait', + ['confirm_no'] = 'no', + ['confirm_yes'] = 'yes', + -- Service + ['service_max'] = 'nie możesz wejść do służby, maksymalna liczba oficerów w służbie: %s/%s', + ['service_not'] = 'nie rozpoczynasz służby! Najpierw musisz się przebrać.', + ['service_anonunce'] = 'informacje o służbie', + ['service_in'] = 'rozpoczynasz służbe, Witaj!', + ['service_in_announce'] = 'operator ~y~%s~s~ rozpoczyna służbę!', + ['service_out'] = 'opuszczasz służbę.', + ['service_out_announce'] = 'operator ~y~%s~s~ opuszcza służbe.', + -- Action Menu + ['citizen_interaction'] = 'interakcja z cywilami', + ['vehicle_interaction'] = 'interakcja z pojazdami', + ['object_spawner'] = 'przedmioty do postawienia', + + ['id_card'] = 'dowód osobisty', + ['search'] = 'przeszukaj', + ['handcuff'] = 'zakuj/Rozkuj Kajdanki ', + ['drag'] = 'przemieść podejrzanego', + ['put_in_vehicle'] = 'wsadź do pojazdu', + ['out_the_vehicle'] = 'wyciągnij z pojazdu', + ['fine'] = 'mandaty', + ['unpaid_bills'] = 'zarządzaj niezapłaconymi rachunkami', + ['license_check'] = 'zarządzaj licencjami', + ['license_revoke'] = 'unieważnij licencje', + ['license_revoked'] = 'twoja licencja ~b~%s~s~ została ~y~unieważniona~s~!', + ['licence_you_revoked'] = 'unieważniasz ~b~%s~s~ które należały do ~y~%s~s~', + ['no_players_nearby'] = 'brak graczy w pobliżu', + ['being_searched'] = 'you are being ~y~searched~s~ by the ~b~Police~s~', + -- Vehicle interaction + ['vehicle_info'] = 'informacje o pojeździe', + ['pick_lock'] = 'odblokuj pojazd', + ['vehicle_unlocked'] = 'pojazd ~g~Odblokowany~s~', + ['no_vehicles_nearby'] = 'brak pojazdu w pobliżu', + ['impound'] = 'zajmij pojazd', + ['impound_prompt'] = 'naciśnij ~INPUT_CONTEXT~ żeby unieważnić ~y~zajęcie~s~', + ['impound_canceled'] = 'unieważniasz zajęcie', + ['impound_canceled_moved'] = 'zajęcie zostało anulowane, ponieważ pojazd przemieścił się', + ['impound_successful'] = 'zajmujesz pojazd', + ['search_database'] = 'informacje o pojeździe', + ['search_database_title'] = 'informacjeo pojeździe - przeszukaj używając numeru rejestracyjnego', + ['search_database_error_invalid'] = 'to ~r~nie~s~ jest ~y~poprawny~s~ rnumer rejestracyjny', + -- Traffic interaction + ['traffic_interaction'] = 'interakcje dla ruchu drogowego', + ['cone'] = 'pachołek', + ['barrier'] = 'barierka', + ['spikestrips'] = 'kolczatka', + ['box'] = 'pudła', + ['cash'] = 'paleta z pieniędzmi', + -- ID Card Menu + ['name'] = 'name: %s', + ['job'] = 'praca: %s', + ['sex'] = 'płeć: %s', + ['dob'] = 'data urodzenia: %s', + ['height'] = 'wzrost: %s', + ['bac'] = 'BAC: %s', + ['unknown'] = 'nieznany', + ['male'] = 'mężczyzna', + ['female'] = 'kobieta', + -- Body Search Menu + ['guns_label'] = '--- Bronie ---', + ['inventory_label'] = '--- Ekwipunek ---', + ['license_label'] = ' --- Licenses ---', + ['confiscate'] = 'skonfiskuj %s', + ['confiscate_weapon'] = 'skonfiskuj %s z %s kulami', + ['confiscate_inv'] = 'skonfiskuj %s x %s', + ['confiscate_dirty'] = 'skonfiskuj brudne pieniądze: $%s', + ['you_confiscated'] = 'skonfiskowałeś ~y~%sx~s~ ~b~%s~s~ od ~b~%s~s~', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ zostały skonfiskowane przez ~y~%s~s~', + ['you_confiscated_account'] = 'skonfiskowałeś ~g~%s$~s~ (%s) od ~b~%s~s~', + ['got_confiscated_account'] = '~g~%s$~s~ (%s) zostały skonfiskowane przez ~y~%s~s~', + ['you_confiscated_weapon'] = 'skonfiskowałeś ~b~%s~s~ od ~b~%s~s~ z ~o~%s~s~ pociskami', + ['got_confiscated_weapon'] = 'twój ~b~%s~s~ z ~o~%s~s~ kulami został skonfiskowany przez ~y~%s~s~', + ['traffic_offense'] = 'wykroczenia drogowe', + ['minor_offense'] = 'niewielkie wykroczenia', + ['average_offense'] = 'średnie wykroczenia', + ['major_offense'] = 'duże wykroczenia', + ['fine_total'] = 'mandat: %s', + -- Vehicle Info Menu + ['plate'] = 'tablica rejestracyjna: %s', + ['owner_unknown'] = 'właściciel: Nieznany', + ['owner'] = 'właściciel: %s', + -- Boss Menu + ['open_bossmenu'] = 'naciśnij ~INPUT_CONTEXT~ aby otworzyć menu', + ['quantity_invalid'] = 'nieprawidłowa ilość', + ['have_withdrawn'] = 'wyjmujesz z depozytu ~y~%sx~s~ ~b~%s~s~', + ['have_deposited'] = 'zdeponowano ~y~%sx~s~ ~b~%s~s~', + ['quantity'] = 'ilość', + ['inventory'] = 'ekwipunek', + ['police_stock'] = 'zapasy policji', + -- Misc + ['remove_prop'] = 'naciśnij ~INPUT_CONTEXT~ aby usunąć ten obiekt', + ['map_blip'] = 'komisariat Policji', + ['unrestrained_timer'] = 'czujesz, że twoje kajdanki powoli tracą przyczepność i znikają.', + -- Notifications + ['alert_police'] = 'ostrzeż policję', + ['phone_police'] = 'police', +} diff --git a/modules/job_police/data/locales/sv.lua b/modules/job_police/data/locales/sv.lua new file mode 100644 index 00000000..e1ac59d1 --- /dev/null +++ b/modules/job_police/data/locales/sv.lua @@ -0,0 +1,151 @@ +Translations = { + -- Cloakroom + ['cloakroom'] = 'omklädningsrum', + ['citizen_wear'] = 'civila kläder', + ['police_wear'] = 'polisuniform', + ['gilet_wear'] = 'reflektiv väst', + ['bullet_wear'] = 'skottsäker väst', + ['no_outfit'] = 'det finns ingen uniform som passar dig!', + ['open_cloackroom'] = 'tryck ~INPUT_CONTEXT~ för att välja ~y~kläder~s~.', + -- Armory + ['remove_object'] = 'ta ut objekt', + ['deposit_object'] = 'lägg in objekt', + ['get_weapon'] = 'ta ut vapen', + ['put_weapon'] = 'lägg in vapen', + ['buy_weapons'] = 'köp vapen', + ['armory'] = 'vapenförråd', + ['open_armory'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~vapenförrådet~s~.', + ['armory_owned'] = 'ägd', + ['armory_free'] = 'gratis', + ['armory_item'] = '%s SEK', + ['armory_weapontitle'] = 'vapenförråd - Köp vapen', + ['armory_componenttitle'] = 'vapenförråd - Vapen tillbehör', + ['armory_bought'] = 'du köpte ~y~%s~s~ för ~g~%s SEK~s~', + ['armory_money'] = 'du har inte råd med det vapnet', + ['armory_hascomponent'] = 'du har redan det tillbehöret!', + ['get_weapon_menu'] = 'vapenförråd - Ta ut vapen', + ['put_weapon_menu'] = 'vapenförråd - Spara vapen', + -- Vehicles + ['vehicle_menu'] = 'fordon', + ['vehicle_blocked'] = 'det finns ingen tillgänglig plats att ställa ut fordonet på!', + ['garage_prompt'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~garaget~s~.', + ['garage_title'] = 'garage', + ['garage_stored'] = 'inställt', + ['garage_notstored'] = 'uttaget', + ['garage_storing'] = 'vi håller på att ställa in ditt fordon, se till att ingen är i närheten.', + ['garage_has_stored'] = 'fordonet har ställts in i garaget', + ['garage_has_notstored'] = 'inget ägt fordon finns i närheten', + ['garage_notavailable'] = 'ditt fordon är inte inställt i ditt garage.', + ['garage_blocked'] = 'det finns ingen tillgänglig plats att ställa ut fordonet på!', + ['garage_empty'] = 'du har inga fordon i ditt garage.', + ['garage_released'] = 'ditt fordon har tagits ut från garaget.', + ['garage_store_nearby'] = 'det finns inget fordon i närheten.', + ['garage_storeditem'] = 'öppna garage', + ['garage_storeitem'] = 'ställ in fordon', + ['garage_buyitem'] = 'fordonshandel', + ['garage_notauthorized'] = 'du har inte tillgång till att köpa dessa fordon.', + ['helicopter_prompt'] = 'tryck ~INPUT_CONTEXT~ för att komma åt ~y~helikoptergaraget~s~.', + ['shop_item'] = '%s SEK', + ['vehicleshop_title'] = 'fordonshandel', + ['vehicleshop_confirm'] = 'vill du köpa detta fordon?', + ['vehicleshop_bought'] = 'du köpte ~y~%s~s~ för ~g~%s SEK~s~', + ['vehicleshop_money'] = 'du har inte råd med detta fordon', + ['vehicleshop_awaiting_model'] = 'fordonet ~g~LADDAS NED OCH LADDAS IN~s~ var god vänta', + ['confirm_no'] = 'nej', + ['confirm_yes'] = 'ja', + -- Service + ['service_max'] = 'du kan inte gå tjänst, poliser i tjänst: %s/%s', + ['service_not'] = 'du är inte i tjänst! Byt om för att gå in i tjänst.', + ['service_anonunce'] = 'tjänsteinformation', + ['service_in'] = 'du deltog i tjänst, välkommen!', + ['service_in_announce'] = 'operatör ~y~%s~s~ har deltagit tjänst!', + ['service_out'] = 'du har lämnat tjänst.', + ['service_out_announce'] = 'operatör ~y~%s~s~ har lämnat deras tjänst.', + -- Action Menu + ['citizen_interaction'] = 'handlingar mot civila', + ['vehicle_interaction'] = 'handlingar på bilar', + ['object_spawner'] = 'ta fram ett objekt', + + ['id_card'] = 'ID-Kort', + ['search'] = 'sök igenom', + ['handcuff'] = 'handbojor', + ['drag'] = 'dra', + ['put_in_vehicle'] = 'sätt in i fordon', + ['out_the_vehicle'] = 'dra ut ur fordon', + ['fine'] = 'Ge böter', + ['unpaid_bills'] = 'se obetalda räkningar', + ['license_check'] = 'se licenser', + ['license_revoke'] = 'återkalla licenser', + ['license_revoked'] = 'ditt ~b~%s~s~ har blivit ~y~återkallat~s~!', + ['licence_you_revoked'] = 'du återkallade ett ~b~%s~s~ som tillhörde ~y~%s~s~', + ['no_players_nearby'] = 'det finns ingen i närheten', + ['being_searched'] = 'du blir ~y~visiterad~s~ av ~b~Polisen~s~', + -- Vehicle interaction + ['vehicle_info'] = 'fordon', + ['pick_lock'] = 'bryt upp fordon', + ['vehicle_unlocked'] = 'fordonet har ~g~låsts upp~s~', + ['no_vehicles_nearby'] = 'inga fordon i närheten', + ['impound'] = 'bärga fordonet', + ['impound_prompt'] = 'tryck ~INPUT_CONTEXT~ för att avbryta ~y~bärgningen~s~', + ['impound_canceled'] = 'du avbröt bärgningen', + ['impound_canceled_moved'] = 'bärgningen avbröts på grund av att fordonet har rört sig', + ['impound_successful'] = 'du har bärgat fordonet', + ['search_database'] = 'fordonsuppgifter', + ['search_database_title'] = 'fordonsuppgifter - sök med registreringsnummer', + ['search_database_error_invalid'] = 'det är ~r~inte~s~ ett ~y~giltigt~s~ registreringsnummer', + -- Traffic interaction + ['traffic_interaction'] = 'trafiksåtgärder', + ['cone'] = 'kon', + ['barrier'] = 'barriär', + ['spikestrips'] = 'spikmatta', + ['box'] = 'låda', + ['cash'] = 'låda med pengar', + -- ID Card Menu + ['name'] = 'namn: %s', + ['job'] = 'jobb: %s', + ['sex'] = 'kön: %s', + ['dob'] = 'födelsedatum: %s', + ['height'] = 'längd: %s', + ['bac'] = 'alkohol i blodet: %s', + ['unknown'] = 'okänt', + ['male'] = 'man', + ['female'] = 'kvinna', + -- Body Search Menu + ['guns_label'] = '--- Vapen ---', + ['inventory_label'] = '--- Inventory ---', + ['license_label'] = ' --- Licenser ---', + ['confiscate'] = 'beslagta %s', + ['confiscate_weapon'] = 'beslagta %s med %s skott', + ['confiscate_inv'] = 'beslagta %sx %s', + ['confiscate_dirty'] = 'beslagta svarta pengar: %s SEK', + ['you_confiscated'] = 'du beslagtog ~y~%sx~s~ ~b~%s~s~ från ~b~%s~s~', + ['got_confiscated'] = '~y~%sx~s~ ~b~%s~s~ beslagtogs av ~y~%s~s~', + ['you_confiscated_account'] = 'du beslagtog ~g~%s SEK~s~ (%s) från ~b~%s~s~', + ['got_confiscated_account'] = '~g~%s SEK~s~ (%s) beslagtogs av ~y~%s~s~', + ['you_confiscated_weapon'] = 'du beslagtog ~b~%s~s~ från ~b~%s~s~ med ~o~%s~s~ skott', + ['got_confiscated_weapon'] = 'din ~b~%s~s~ med ~o~%s~s~ skott beslagtogs av ~y~%s~s~', + ['traffic_offense'] = 'brott mot trafikregler', + ['minor_offense'] = 'mindre lagbrott', + ['average_offense'] = 'medel lagbrott', + ['major_offense'] = 'grovt lagbrott', + ['fine_total'] = 'böter: %s', + -- Vehicle Info Menu + ['plate'] = 'reg nummer: %s', + ['owner_unknown'] = 'ägare: Okänt', + ['owner'] = 'ägare: %s', + -- Boss Menu + ['open_bossmenu'] = 'tryck ~INPUT_CONTEXT~ för att öppna menyn', + ['quantity_invalid'] = 'otillgängligt antal', + ['have_withdrawn'] = 'du har tagit ut ~y~x%s~s~ ~b~%s~s~', + ['have_deposited'] = 'du har lagrat ~y~x%s~s~ ~b~%s~s~', + ['quantity'] = 'antal', + ['inventory'] = 'förråd', + ['police_stock'] = 'polisförråd', + -- Misc + ['remove_prop'] = 'tryck ~INPUT_CONTEXT~ för att ta bort objektet', + ['map_blip'] = 'polisstation', + ['unrestrained_timer'] = 'dina handklovar har försvunnit', + -- Notifications + ['alert_police'] = 'meddela polisen', + ['phone_police'] = 'polisen', +} diff --git a/modules/job_police/server/events.lua b/modules/job_police/server/events.lua new file mode 100644 index 00000000..4b2d0d87 --- /dev/null +++ b/modules/job_police/server/events.lua @@ -0,0 +1,515 @@ +local self = ESX.Modules['job_police'] + +RegisterNetEvent('esx_policejob:confiscatePlayerItem') +AddEventHandler('esx_policejob:confiscatePlayerItem', function(target, itemType, itemName, amount) + local _source = source + local sourceXPlayer = ESX.GetPlayerFromId(_source) + local targetXPlayer = ESX.GetPlayerFromId(target) + + if sourceXPlayer.job.name ~= 'police' then + print(('esx_policejob: %s attempted to confiscate!'):format(xPlayer.identifier)) + return + end + + if itemType == 'item_standard' then + local targetItem = targetXPlayer.getInventoryItem(itemName) + local sourceItem = sourceXPlayer.getInventoryItem(itemName) + + -- does the target player have enough in their inventory? + if targetItem.count > 0 and targetItem.count <= amount then + + -- can the player carry the said amount of x item? + if sourceXPlayer.canCarryItem(itemName, sourceItem.count) then + targetXPlayer.removeInventoryItem(itemName, amount) + sourceXPlayer.addInventoryItem (itemName, amount) + sourceXPlayer.showNotification(_U('you_confiscated', amount, sourceItem.label, targetXPlayer.name)) + targetXPlayer.showNotification(_U('got_confiscated', amount, sourceItem.label, sourceXPlayer.name)) + else + sourceXPlayer.showNotification(_U('quantity_invalid')) + end + else + sourceXPlayer.showNotification(_U('quantity_invalid')) + end + + elseif itemType == 'item_account' then + targetXPlayer.removeAccountMoney(itemName, amount) + sourceXPlayer.addAccountMoney (itemName, amount) + + sourceXPlayer.showNotification(_U('you_confiscated_account', amount, itemName, targetXPlayer.name)) + targetXPlayer.showNotification(_U('got_confiscated_account', amount, itemName, sourceXPlayer.name)) + + elseif itemType == 'item_weapon' then + if amount == nil then amount = 0 end + targetXPlayer.removeWeapon(itemName, amount) + sourceXPlayer.addWeapon (itemName, amount) + + sourceXPlayer.showNotification(_U('you_confiscated_weapon', ESX.GetWeaponLabel(itemName), targetXPlayer.name, amount)) + targetXPlayer.showNotification(_U('got_confiscated_weapon', ESX.GetWeaponLabel(itemName), amount, sourceXPlayer.name)) + end +end) + +RegisterNetEvent('esx_policejob:handcuff') +AddEventHandler('esx_policejob:handcuff', function(target) + local xPlayer = ESX.GetPlayerFromId(source) + + if xPlayer.job.name == 'police' then + TriggerClientEvent('esx_policejob:handcuff', target) + else + print(('esx_policejob: %s attempted to handcuff a player (not cop)!'):format(xPlayer.identifier)) + end +end) + +RegisterNetEvent('esx_policejob:drag') +AddEventHandler('esx_policejob:drag', function(target) + local xPlayer = ESX.GetPlayerFromId(source) + + if xPlayer.job.name == 'police' then + TriggerClientEvent('esx_policejob:drag', target, source) + else + print(('esx_policejob: %s attempted to drag (not cop)!'):format(xPlayer.identifier)) + end +end) + +RegisterNetEvent('esx_policejob:putInVehicle') +AddEventHandler('esx_policejob:putInVehicle', function(target) + local xPlayer = ESX.GetPlayerFromId(source) + + if xPlayer.job.name == 'police' then + TriggerClientEvent('esx_policejob:putInVehicle', target) + else + print(('esx_policejob: %s attempted to put in vehicle (not cop)!'):format(xPlayer.identifier)) + end +end) + +RegisterNetEvent('esx_policejob:OutVehicle') +AddEventHandler('esx_policejob:OutVehicle', function(target) + local xPlayer = ESX.GetPlayerFromId(source) + + if xPlayer.job.name == 'police' then + TriggerClientEvent('esx_policejob:OutVehicle', target) + else + print(('esx_policejob: %s attempted to drag out from vehicle (not cop)!'):format(xPlayer.identifier)) + end +end) + +RegisterNetEvent('esx_policejob:getStockItem') +AddEventHandler('esx_policejob:getStockItem', function(itemName, count) + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + + TriggerEvent('esx_addoninventory:getSharedInventory', 'society_police', function(inventory) + local inventoryItem = inventory.getItem(itemName) + + -- is there enough in the society? + if count > 0 and inventoryItem.count >= count then + + -- can the player carry the said amount of x item? + if xPlayer.canCarryItem(itemName, count) then + inventory.removeItem(itemName, count) + xPlayer.addInventoryItem(itemName, count) + xPlayer.showNotification(_U('have_withdrawn', count, inventoryItem.label)) + else + xPlayer.showNotification(_U('quantity_invalid')) + end + else + xPlayer.showNotification(_U('quantity_invalid')) + end + end) +end) + +RegisterNetEvent('esx_policejob:putStockItems') +AddEventHandler('esx_policejob:putStockItems', function(itemName, count) + local xPlayer = ESX.GetPlayerFromId(source) + local sourceItem = xPlayer.getInventoryItem(itemName) + + TriggerEvent('esx_addoninventory:getSharedInventory', 'society_police', function(inventory) + local inventoryItem = inventory.getItem(itemName) + + -- does the player have enough of the item? + if sourceItem.count >= count and count > 0 then + xPlayer.removeInventoryItem(itemName, count) + inventory.addItem(itemName, count) + xPlayer.showNotification(_U('have_deposited', count, inventoryItem.label)) + else + xPlayer.showNotification(_U('quantity_invalid')) + end + end) +end) + +ESX.RegisterServerCallback('esx_policejob:getOtherPlayerData', function(source, cb, target, notify) + local xPlayer = ESX.GetPlayerFromId(target) + + if notify then + xPlayer.showNotification(_U('being_searched')) + end + + if xPlayer then + local data = { + name = xPlayer.getName(), + job = xPlayer.job.label, + grade = xPlayer.job.grade_label, + inventory = xPlayer.getInventory(), + accounts = xPlayer.getAccounts(), + weapons = xPlayer.getLoadout() + } + + if self.Config.EnableESXIdentity then + data.dob = xPlayer.get('dateofbirth') + data.height = xPlayer.get('height') + + if xPlayer.get('sex') == 'm' then data.sex = 'male' else data.sex = 'female' end + end + + TriggerEvent('esx_status:getStatus', target, 'drunk', function(status) + if status then + data.drunk = ESX.Math.Round(status.percent) + end + + if self.Config.EnableLicenses then + TriggerEvent('esx_license:getLicenses', target, function(licenses) + data.licenses = licenses + cb(data) + end) + else + cb(data) + end + end) + end +end) + +ESX.RegisterServerCallback('esx_policejob:getFineList', function(source, cb, category) + MySQL.Async.fetchAll('SELECT * FROM fine_types WHERE category = @category', { + ['@category'] = category + }, function(fines) + cb(fines) + end) +end) + +ESX.RegisterServerCallback('esx_policejob:getVehicleInfos', function(source, cb, plate) + MySQL.Async.fetchAll('SELECT owner FROM owned_vehicles WHERE plate = @plate', { + ['@plate'] = plate + }, function(result) + local retrivedInfo = {plate = plate} + + if result[1] then + local xPlayer = ESX.GetPlayerFromIdentifier(result[1].owner) + + -- is the owner online? + if xPlayer then + retrivedInfo.owner = xPlayer.getName() + cb(retrivedInfo) + elseif self.Config.EnableESXIdentity then + MySQL.Async.fetchAll('SELECT firstname, lastname FROM users WHERE identifier = @identifier', { + ['@identifier'] = result[1].owner + }, function(result2) + if result2[1] then + retrivedInfo.owner = ('%s %s'):format(result2[1].firstname, result2[1].lastname) + cb(retrivedInfo) + else + cb(retrivedInfo) + end + end) + else + cb(retrivedInfo) + end + else + cb(retrivedInfo) + end + end) +end) + +ESX.RegisterServerCallback('esx_policejob:getArmoryWeapons', function(source, cb) + TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) + local weapons = store.get('weapons') + + if weapons == nil then + weapons = {} + end + + cb(weapons) + end) +end) + +ESX.RegisterServerCallback('esx_policejob:addArmoryWeapon', function(source, cb, weaponName, removeWeapon) + local xPlayer = ESX.GetPlayerFromId(source) + + if removeWeapon then + xPlayer.removeWeapon(weaponName) + end + + TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) + local weapons = store.get('weapons') or {} + local foundWeapon = false + + for i=1, #weapons, 1 do + if weapons[i].name == weaponName then + weapons[i].count = weapons[i].count + 1 + foundWeapon = true + break + end + end + + if not foundWeapon then + table.insert(weapons, { + name = weaponName, + count = 1 + }) + end + + store.set('weapons', weapons) + cb() + end) +end) + +ESX.RegisterServerCallback('esx_policejob:removeArmoryWeapon', function(source, cb, weaponName) + local xPlayer = ESX.GetPlayerFromId(source) + xPlayer.addWeapon(weaponName, 500) + + TriggerEvent('esx_datastore:getSharedDataStore', 'society_police', function(store) + local weapons = store.get('weapons') or {} + + local foundWeapon = false + + for i=1, #weapons, 1 do + if weapons[i].name == weaponName then + weapons[i].count = (weapons[i].count > 0 and weapons[i].count - 1 or 0) + foundWeapon = true + break + end + end + + if not foundWeapon then + table.insert(weapons, { + name = weaponName, + count = 0 + }) + end + + store.set('weapons', weapons) + cb() + end) +end) + +ESX.RegisterServerCallback('esx_policejob:buyWeapon', function(source, cb, weaponName, type, componentNum) + + local xPlayer = ESX.GetPlayerFromId(source) + local authorizedWeapons = {} + + for i=1, xPlayer.job.grade, 1 do + + local weapons = self.Config.AuthorizedWeapons[i] + + for j=1, #weapons, 1 do + authorizedWeapons[#authorizedWeapons + 1] = weapons[j] + end + + end + + for k,v in ipairs(authorizedWeapons) do + if v.weapon == weaponName then + selectedWeapon = v + break + end + end + + if not selectedWeapon then + print(('esx_policejob: %s attempted to buy an invalid weapon.'):format(xPlayer.identifier)) + cb(false) + else + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_police', function(account) + + -- Weapon + if type == 1 then + + if account.money >= selectedWeapon.price then + + account.removeMoney(selectedWeapon.price) + xPlayer.addWeapon(weaponName, 100) + + cb(true) + + else + cb(false) + end + + -- Weapon Component + elseif type == 2 then + local price = selectedWeapon.components[componentNum] + local weaponNum, weapon = ESX.GetWeapon(weaponName) + local component = weapon.components[componentNum] + + if component then + if account.money >= price then + + account.removeMoney(price) + xPlayer.addWeaponComponent(weaponName, component.name) + + cb(true) + + else + cb(false) + end + else + print(('esx_policejob: %s attempted to buy an invalid weapon component.'):format(xPlayer.identifier)) + cb(false) + end + end + + end) + + end +end) + +ESX.RegisterServerCallback('esx_policejob:canBuyVehicle', function(source, cb, model, type) + + local xPlayer = ESX.GetPlayerFromId(source) + local price = self.GetPriceFromHash(GetHashKey(model), xPlayer.job.grade, type) + + -- vehicle model not found + if price == -1 then + cb(false) + else + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_police', function(account) + + if account.money >= price then + cb(true) + else + cb(false) + end + + end) + + end + +end) + +RegisterNetEvent('esx_policejob:buyJobVehicle') +AddEventHandler('esx_policejob:buyJobVehicle', function(vehicleProps, type) + + local _source = source + local xPlayer = ESX.GetPlayerFromId(_source) + local price = self.GetPriceFromHash(vehicleProps.model, xPlayer.job.grade, type) + + -- vehicle model not found + if price == -1 then + print(('esx_policejob: %s attempted to exploit the shop! (invalid vehicle model)'):format(xPlayer.identifier)) + else + + TriggerEvent('esx_addonaccount:getSharedAccount', 'society_police', function(account) + + if account.money >= price then + + account.removeMoney(price) + + MySQL.Async.execute('INSERT INTO owned_vehicles (owner, vehicle, plate, type, job, `stored`) VALUES (@owner, @vehicle, @plate, @type, @job, @stored)', { + ['@owner'] = xPlayer.identifier, + ['@vehicle'] = json.encode(vehicleProps), + ['@plate'] = vehicleProps.plate, + ['@type'] = type, + ['@job'] = xPlayer.job.name, + ['@stored'] = true + }) + + else + print(('esx_policejob: %s attempted to exploit the shop! (not enough money)'):format(xPlayer.identifier)) + end + + end) + + end + +end) + +ESX.RegisterServerCallback('esx_policejob:storeNearbyVehicle', function(source, cb, nearbyVehicles) + local xPlayer = ESX.GetPlayerFromId(source) + local foundPlate, foundNum + + for k,v in ipairs(nearbyVehicles) do + local result = MySQL.Sync.fetchAll('SELECT plate FROM owned_vehicles WHERE owner = @owner AND plate = @plate AND job = @job', { + ['@owner'] = xPlayer.identifier, + ['@plate'] = v.plate, + ['@job'] = xPlayer.job.name + }) + + if result[1] then + foundPlate, foundNum = result[1].plate, k + break + end + end + + if not foundPlate then + cb(false) + else + MySQL.Async.execute('UPDATE owned_vehicles SET `stored` = true WHERE owner = @owner AND plate = @plate AND job = @job', { + ['@owner'] = xPlayer.identifier, + ['@plate'] = foundPlate, + ['@job'] = xPlayer.job.name + }, function (rowsChanged) + if rowsChanged == 0 then + print(('esx_policejob: %s has exploited the garage!'):format(xPlayer.identifier)) + cb(false) + else + cb(true, foundNum) + end + end) + end +end) + +ESX.RegisterServerCallback('esx_policejob:getStockItems', function(source, cb) + TriggerEvent('esx_addoninventory:getSharedInventory', 'society_police', function(inventory) + cb(inventory.items) + end) +end) + +ESX.RegisterServerCallback('esx_policejob:getPlayerInventory', function(source, cb) + local xPlayer = ESX.GetPlayerFromId(source) + local items = xPlayer.inventory + + cb({items = items}) +end) + +AddEventHandler('playerDropped', function() + -- Save the source in case we lose it (which happens a lot) + local playerId = source + + -- Did the player ever join? + if playerId then + local xPlayer = ESX.GetPlayerFromId(playerId) + + -- Is it worth telling all clients to refresh? + if xPlayer and xPlayer.job.name == 'police' then + Citizen.Wait(5000) + TriggerClientEvent('esx_policejob:updateBlip', -1) + end + end +end) + +RegisterNetEvent('esx_policejob:spawned') +AddEventHandler('esx_policejob:spawned', function() + local xPlayer = ESX.GetPlayerFromId(playerId) + + if xPlayer and xPlayer.job.name == 'police' then + Citizen.Wait(5000) + TriggerClientEvent('esx_policejob:updateBlip', -1) + end +end) + +RegisterNetEvent('esx_policejob:forceBlip') +AddEventHandler('esx_policejob:forceBlip', function() + TriggerClientEvent('esx_policejob:updateBlip', -1) +end) + +AddEventHandler('onResourceStart', function(resource) + if resource == GetCurrentResourceName() then + Citizen.Wait(5000) + TriggerClientEvent('esx_policejob:updateBlip', -1) + end +end) + +AddEventHandler('onResourceStop', function(resource) + if resource == GetCurrentResourceName() then + TriggerEvent('esx_phone:removeNumber', 'police') + end +end) diff --git a/modules/job_police/server/main.lua b/modules/job_police/server/main.lua new file mode 100644 index 00000000..449ba44d --- /dev/null +++ b/modules/job_police/server/main.lua @@ -0,0 +1,15 @@ +local self = ESX.Modules['job_police'] + +if self.Config.EnableESXService then + TriggerEvent('esx_service:activateService', 'police', self.Config.MaxInService) +end + +AddEventHandler('onResourceStart', function(resource) + + if resource == 'esx_society' then + TriggerEvent('esx_society:registerSociety', 'police', 'Police', 'society_police', 'society_police', 'society_police', {type = 'public'}) + elseif resource == 'esx_phone' then + TriggerEvent('esx_phone:registerNumber', 'police', _U('alert_police'), true, true) + end + +end) diff --git a/modules/job_police/server/module.lua b/modules/job_police/server/module.lua new file mode 100644 index 00000000..2c8a7409 --- /dev/null +++ b/modules/job_police/server/module.lua @@ -0,0 +1,31 @@ +ESX.Modules['job_police'] = {}; +local self = ESX.Modules['job_police'] + +-- Properties +self.Config = ESX.EvalFile(GetCurrentResourceName(), 'modules/job_police/data/config.lua', { + vector3 = vector3 +})['Config'] + +self.GetPriceFromHash = function(vehicleHash, jobGrade, type) + + local authorizedVehicles = {} + + for i=1, jobGrade, 1 do + + local vehicles = self.Config.AuthorizedVehicles[type][i] + + for j=1, #vehicles, 1 do + authorizedVehicles[#authorizedVehicles + 1] = vehicles[j] + end + + end + + for k,v in ipairs(authorizedVehicles) do + if GetHashKey(v.model) == vehicleHash then + return v.price + end + end + + return -1 + +end diff --git a/modules/menu_default/client/events.lua b/modules/menu_default/client/events.lua new file mode 100644 index 00000000..7d8347e7 --- /dev/null +++ b/modules/menu_default/client/events.lua @@ -0,0 +1,71 @@ +local self = ESX.Modules['menu_default'] + +AddEventHandler('esx:nui_ready', function() + ESX.CreateFrame('menu_default', 'nui://' .. GetCurrentResourceName() .. '/modules/menu_default/data/html/ui.html') +end) + +ESX.Modules['input'].On('pressed', 0, 18, function(lastTime) + if (GetGameTimer() - lastTime) < 150 then return end + ESX.SendFrameMessage('menu_default', {action = 'controlPressed', control = 'ENTER'}) +end) + +ESX.Modules['input'].On('pressed', 0, 177, function(lastTime) + if (GetGameTimer() - lastTime) < 150 then return end + ESX.SendFrameMessage('menu_default', {action = 'controlPressed', control = 'BACKSPACE'}) +end) + +ESX.Modules['input'].On('pressed', 0, 27, function(lastTime) + if (GetGameTimer() - lastTime) < 300 then return end + ESX.SendFrameMessage('menu_default', {action = 'controlPressed', control = 'TOP'}) +end) + +ESX.Modules['input'].On('pressed', 0, 173, function(lastTime) + if (GetGameTimer() - lastTime) < 300 then return end + ESX.SendFrameMessage('menu_default', {action = 'controlPressed', control = 'DOWN'}) +end) + +ESX.Modules['input'].On('pressed', 0, 174, function(lastTime) + if (GetGameTimer() - lastTime) < 300 then return end + ESX.SendFrameMessage('menu_default', {action = 'controlPressed', control = 'LEFT'}) +end) + +ESX.Modules['input'].On('pressed', 0, 175, function(lastTime) + if (GetGameTimer() - lastTime) < 300 then return end + ESX.SendFrameMessage('menu_default', {action = 'controlPressed', control = 'RIGHT'}) +end) + + +AddEventHandler('menu_default:message:menu_submit', function(data) + local menu = ESX.UI.Menu.GetOpened(self.MenuType, data._namespace, data._name) + + if menu.submit ~= nil then + menu.submit(data, menu) + end +end) + +AddEventHandler('menu_default:message:menu_cancel', function(data) + + local menu = ESX.UI.Menu.GetOpened(self.MenuType, data._namespace, data._name) + + if menu.cancel ~= nil then + menu.cancel(data, menu) + end +end) + +AddEventHandler('menu_default:message:menu_change', function(data) + local menu = ESX.UI.Menu.GetOpened(self.MenuType, data._namespace, data._name) + + for i=1, #data.elements, 1 do + menu.setElement(i, 'value', data.elements[i].value) + + if data.elements[i].selected then + menu.setElement(i, 'selected', true) + else + menu.setElement(i, 'selected', false) + end + end + + if menu.change ~= nil then + menu.change(data, menu) + end +end) diff --git a/modules/menu_default/client/main.lua b/modules/menu_default/client/main.lua new file mode 100644 index 00000000..332fbded --- /dev/null +++ b/modules/menu_default/client/main.lua @@ -0,0 +1,11 @@ + +local self = ESX.Modules['menu_default'] + +ESX.UI.Menu.RegisterType(self.MenuType, self.OpenMenu, self.CloseMenu) + +ESX.Modules['input'].RegisterControl(0, 18) +ESX.Modules['input'].RegisterControl(0, 177) +ESX.Modules['input'].RegisterControl(0, 27) +ESX.Modules['input'].RegisterControl(0, 173) +ESX.Modules['input'].RegisterControl(0, 174) +ESX.Modules['input'].RegisterControl(0, 175) diff --git a/modules/menu_default/client/module.lua b/modules/menu_default/client/module.lua new file mode 100644 index 00000000..87355a79 --- /dev/null +++ b/modules/menu_default/client/module.lua @@ -0,0 +1,26 @@ +ESX.Modules['menu_default'] = {}; +local self = ESX.Modules['menu_default'] + +self.GUI = {} +self.GUI.Time = 0 +self.MenuType = 'default' + +self.OpenMenu = function(namespace, name, data) + ESX.SendFrameMessage('menu_default', { + action = 'openMenu', + namespace = namespace, + name = name, + data = data + }) +end + +self.CloseMenu = function(namespace, name) + ESX.SendFrameMessage('menu_default', { + action = 'closeMenu', + namespace = namespace, + name = name, + data = data + }) +end + + diff --git a/modules/menu_default/data/html/css/app.css b/modules/menu_default/data/html/css/app.css new file mode 100644 index 00000000..4ad1a0fb --- /dev/null +++ b/modules/menu_default/data/html/css/app.css @@ -0,0 +1,94 @@ +@font-face { + font-family: bankgothic; + src: url('../fonts/bankgothic.ttf'); +} + +@font-face { + font-family: pcdown; + src: url('../fonts/pdown.ttf'); +} + +.menu { + font-family: bankgothic; + min-width: 400px; + color: #fff; + box-shadow: 0px 0px 50px 0px #000; + position: absolute; +} + +.menu.align-left { + left: 40; + top: 50%; + transform: translate(0, -50%); +} + +.menu.align-top-left { + left: 40; + top: 40; +} + +.menu.align-top { + left: 50%; + top: 40; + transform: translate(-50%, 0); +} + +.menu.align-top-right { + right: 10; + top: 40; +} + +.menu.align-right { + right: 40; + top: 50%; + transform: translate(0, -50%); +} + +.menu.align-bottom-right { + right: 40; + bottom: 40; +} + +.menu.align-bottom { + left: 50%; + bottom: 40; + transform: translate(-50%, 0); +} + +.menu.align-bottom-left { + left: 40; + bottom: 40; +} + +.menu.align-center { + left: 50%; + top: 50%; + transform: translate(-50%, -50%); +} + +.menu .head { + background-color: #506be6; + text-align: center; + height: 40px; + line-height: 40px; +} + +.menu .menu-items { + max-height: 600px; + overflow-y: auto; +} + +.menu .menu-items .menu-item { + 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: #d0d0d0; +} diff --git a/modules/menu_default/data/html/fonts/bankgothic.ttf b/modules/menu_default/data/html/fonts/bankgothic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f3d8049b052a1f9cfd27557eb3675bc85ce4b9fc GIT binary patch literal 36272 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
D;NyGoM}BX%_3nO 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 D`#l06 literal 0 HcmV?d00001 diff --git a/modules/menu_default/data/html/fonts/pdown.ttf b/modules/menu_default/data/html/fonts/pdown.ttf new file mode 100644 index 0000000000000000000000000000000000000000..69c76cf3f2a6bbc93f570124554fec06d7bbac25 GIT binary patch literal 151512 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 literal 0 HcmV?d00001 diff --git a/modules/menu_default/data/html/js/app.js b/modules/menu_default/data/html/js/app.js new file mode 100644 index 00000000..a397695f --- /dev/null +++ b/modules/menu_default/data/html/js/app.js @@ -0,0 +1,346 @@ +(function(){ + let MenuTpl = + '' + + '' + ; + + window.ESX_MENU = {}; + ESX_MENU.ResourceName = 'menu_default'; + ESX_MENU.opened = {}; + ESX_MENU.focus = []; + ESX_MENU.pos = {}; + + ESX_MENU.open = function(namespace, name, data) { + if (typeof ESX_MENU.opened[namespace] == 'undefined') { + ESX_MENU.opened[namespace] = {}; + } + + if (typeof ESX_MENU.opened[namespace][name] != 'undefined') { + ESX_MENU.close(namespace, name); + } + + if (typeof ESX_MENU.pos[namespace] == 'undefined') { + ESX_MENU.pos[namespace] = {}; + } + + for (let i=0; i { + switch (data.action) { + + case 'openMenu': { + ESX_MENU.open(data.namespace, data.name, data.data); + break; + } + + case 'closeMenu': { + ESX_MENU.close(data.namespace, data.name); + break; + } + + case 'controlPressed': { + switch (data.control) { + + case 'ENTER': { + let focused = ESX_MENU.getFocused(); + + if (typeof focused != 'undefined') { + let menu = ESX_MENU.opened[focused.namespace][focused.name]; + let pos = ESX_MENU.pos[focused.namespace][focused.name]; + let elem = menu.elements[pos]; + + if (menu.elements.length > 0) { + ESX_MENU.submit(focused.namespace, focused.name, {...elem, index: pos + 1}); + } + } + + break; + } + + case 'BACKSPACE': { + let focused = ESX_MENU.getFocused(); + + if (typeof focused != 'undefined') { + ESX_MENU.cancel(focused.namespace, focused.name); + } + + break; + } + + case 'TOP': { + let focused = ESX_MENU.getFocused(); + + if (typeof focused != 'undefined') { + let menu = ESX_MENU.opened[focused.namespace][focused.name]; + let pos = ESX_MENU.pos[focused.namespace][focused.name]; + + if (pos > 0) { + ESX_MENU.pos[focused.namespace][focused.name]--; + } else { + ESX_MENU.pos[focused.namespace][focused.name] = menu.elements.length - 1; + } + + let elem = menu.elements[ESX_MENU.pos[focused.namespace][focused.name]]; + + for (let i=0; i min) { + elem.value--; + ESX_MENU.change(focused.namespace, focused.name, elem); + } + + ESX_MENU.render(); + break; + } + + default: break; + } + + $('#menu_' + focused.namespace + '_' + focused.name).find('.menu-item.selected')[0].scrollIntoView(); + } + + break; + } + + case 'RIGHT': { + let focused = ESX_MENU.getFocused(); + + if (typeof focused != 'undefined') { + let menu = ESX_MENU.opened[focused.namespace][focused.name]; + let pos = ESX_MENU.pos[focused.namespace][focused.name]; + let elem = menu.elements[pos]; + + switch(elem.type) { + case 'default': break; + + case 'slider': { + if (typeof elem.options != 'undefined' && elem.value < elem.options.length - 1) { + elem.value++; + ESX_MENU.change(focused.namespace, focused.name, elem); + } + + if (typeof elem.max != 'undefined' && elem.value < elem.max) { + elem.value++; + ESX_MENU.change(focused.namespace, focused.name, elem); + } + + ESX_MENU.render(); + break; + } + + default: break; + } + + $('#menu_' + focused.namespace + '_' + focused.name).find('.menu-item.selected')[0].scrollIntoView(); + } + + break; + } + + default: break; + } + + break; + } + } + }; + + window.onload = function(e){ + window.addEventListener('message', (event) => { + onData(event.data); + }); + }; + +})(); diff --git a/modules/menu_default/data/html/js/mustache.min.js b/modules/menu_default/data/html/js/mustache.min.js new file mode 100644 index 00000000..520cfcb9 --- /dev/null +++ b/modules/menu_default/data/html/js/mustache.min.js @@ -0,0 +1 @@ +(function defineMustache(global,factory){if(typeof exports==="object"&&exports&&typeof exports.nodeName!=="string"){factory(exports)}else if(typeof define==="function"&&define.amd){define(["exports"],factory)}else{global.Mustache={};factory(global.Mustache)}})(this,function mustacheFactory(mustache){var objectToString=Object.prototype.toString;var isArray=Array.isArray||function isArrayPolyfill(object){return objectToString.call(object)==="[object Array]"};function isFunction(object){return typeof object==="function"}function typeStr(obj){return isArray(obj)?"array":typeof obj}function escapeRegExp(string){return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function hasProperty(obj,propName){return obj!=null&&typeof obj==="object"&&propName in obj}var regExpTest=RegExp.prototype.test;function testRegExp(re,string){return regExpTest.call(re,string)}var nonSpaceRe=/\S/;function isWhitespace(string){return!testRegExp(nonSpaceRe,string)}var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function escapeHtml(string){return String(string).replace(/[&<>"'`=\/]/g,function fromEntityMap(s){return entityMap[s]})}var whiteRe=/\s*/;var spaceRe=/\s+/;var equalsRe=/\s*=/;var curlyRe=/\s*\}/;var tagRe=/#|\^|\/|>|\{|&|=|!/;function parseTemplate(template,tags){if(!template)return[];var sections=[];var tokens=[];var spaces=[];var hasTag=false;var nonSpace=false;function stripSpace(){if(hasTag&&!nonSpace){while(spaces.length)delete tokens[spaces.pop()]}else{spaces=[]}hasTag=false;nonSpace=false}var openingTagRe,closingTagRe,closingCurlyRe;function compileTags(tagsToCompile){if(typeof tagsToCompile==="string")tagsToCompile=tagsToCompile.split(spaceRe,2);if(!isArray(tagsToCompile)||tagsToCompile.length!==2)throw new Error("Invalid tags: "+tagsToCompile);openingTagRe=new RegExp(escapeRegExp(tagsToCompile[0])+"\\s*");closingTagRe=new RegExp("\\s*"+escapeRegExp(tagsToCompile[1]));closingCurlyRe=new RegExp("\\s*"+escapeRegExp("}"+tagsToCompile[1]))}compileTags(tags||mustache.tags);var scanner=new Scanner(template);var start,type,value,chr,token,openSection;while(!scanner.eos()){start=scanner.pos;value=scanner.scanUntil(openingTagRe);if(value){for(var i=0,valueLength=value.length;i0?sections[sections.length-1][4]:nestedTokens;break;default:collector.push(token)}}return nestedTokens}function Scanner(string){this.string=string;this.tail=string;this.pos=0}Scanner.prototype.eos=function eos(){return this.tail===""};Scanner.prototype.scan=function scan(re){var match=this.tail.match(re);if(!match||match.index!==0)return"";var string=match[0];this.tail=this.tail.substring(string.length);this.pos+=string.length;return string};Scanner.prototype.scanUntil=function scanUntil(re){var index=this.tail.search(re),match;switch(index){case-1:match=this.tail;this.tail="";break;case 0:match="";break;default:match=this.tail.substring(0,index);this.tail=this.tail.substring(index)}this.pos+=match.length;return match};function Context(view,parentContext){this.view=view;this.cache={".":this.view};this.parent=parentContext}Context.prototype.push=function push(view){return new Context(view,this)};Context.prototype.lookup=function lookup(name){var cache=this.cache;var value;if(cache.hasOwnProperty(name)){value=cache[name]}else{var context=this,names,index,lookupHit=false;while(context){if(name.indexOf(".")>0){value=context.view;names=name.split(".");index=0;while(value!=null&&index")value=this.renderPartial(token,context,partials,originalTemplate);else if(symbol==="&")value=this.unescapedValue(token,context);else if(symbol==="name")value=this.escapedValue(token,context);else if(symbol==="text")value=this.rawValue(token);if(value!==undefined)buffer+=value}return buffer};Writer.prototype.renderSection=function renderSection(token,context,partials,originalTemplate){var self=this;var buffer="";var value=context.lookup(token[1]);function subRender(template){return self.render(template,context,partials)}if(!value)return;if(isArray(value)){for(var j=0,valueLength=value.length;j + + + + + + + + + + + + + + + + diff --git a/modules/menu_default/server/events.lua b/modules/menu_default/server/events.lua new file mode 100644 index 00000000..72967122 --- /dev/null +++ b/modules/menu_default/server/events.lua @@ -0,0 +1,2 @@ +local self = ESX.Modules['menu_default'] + diff --git a/modules/menu_default/server/main.lua b/modules/menu_default/server/main.lua new file mode 100644 index 00000000..cc5d2c39 --- /dev/null +++ b/modules/menu_default/server/main.lua @@ -0,0 +1,3 @@ + +local self = ESX.Modules['menu_default'] + diff --git a/modules/menu_default/server/module.lua b/modules/menu_default/server/module.lua new file mode 100644 index 00000000..df30dce4 --- /dev/null +++ b/modules/menu_default/server/module.lua @@ -0,0 +1,3 @@ +ESX.Modules['menu_default'] = {}; +local self = ESX.Modules['menu_default'] + diff --git a/modules/menu_dialog/client/events.lua b/modules/menu_dialog/client/events.lua new file mode 100644 index 00000000..c1bc558a --- /dev/null +++ b/modules/menu_dialog/client/events.lua @@ -0,0 +1,48 @@ +local self = ESX.Modules['menu_dialog'] + +AddEventHandler('esx:nui_ready', function() + ESX.CreateFrame('menu_dialog', 'nui://' .. GetCurrentResourceName() .. '/modules/menu_dialog/data/html/ui.html') +end) + +AddEventHandler('menu_dialog:message:menu_submit', function(data) + + local menu = ESX.UI.Menu.GetOpened(self.MenuType, data._namespace, data._name) + local cancel = false + + if menu.submit then + -- is the submitted data a number? + if tonumber(data.value) then + data.value = ESX.Math.Round(tonumber(data.value)) + + -- check for negative value + if tonumber(data.value) <= 0 then + cancel = true + end + end + + data.value = ESX.Math.Trim(data.value) + + -- don't submit if the value is negative or if it's 0 + if cancel then + ESX.ShowNotification('That input is not allowed!') + else + menu.submit(data, menu) + end + end +end) + +AddEventHandler('menu_dialog:message:menu_cancel', function(data) + local menu = ESX.UI.Menu.GetOpened(self.MenuType, data._namespace, data._name) + + if menu.cancel ~= nil then + menu.cancel(data, menu) + end +end) + +AddEventHandler('menu_dialog:message:menu_change', function(data) + local menu = ESX.UI.Menu.GetOpened(self.MenuType, data._namespace, data._name) + + if menu.change ~= nil then + menu.change(data, menu) + end +end) \ No newline at end of file diff --git a/modules/menu_dialog/client/main.lua b/modules/menu_dialog/client/main.lua new file mode 100644 index 00000000..60051150 --- /dev/null +++ b/modules/menu_dialog/client/main.lua @@ -0,0 +1,24 @@ + +local self = ESX.Modules['menu_dialog'] + +ESX.UI.Menu.RegisterType(self.MenuType, self.openMenu, self.closeMenu) + +Citizen.CreateThread(function() + while true do + Citizen.Wait(10) + + if ESX.Table.SizeOf(self.OpenedMenus) > 0 then + DisableControlAction(0, 1, true) -- LookLeftRight + DisableControlAction(0, 2, true) -- LookUpDown + DisableControlAction(0, 142, true) -- MeleeAttackAlternate + DisableControlAction(0, 106, true) -- VehicleMouseControlOverride + DisableControlAction(0, 12, true) -- WeaponWheelUpDown + DisableControlAction(0, 14, true) -- WeaponWheelNext + DisableControlAction(0, 15, true) -- WeaponWheelPrev + DisableControlAction(0, 16, true) -- SelectNextWeapon + DisableControlAction(0, 17, true) -- SelectPrevWeapon + else + Citizen.Wait(500) + end + end +end) diff --git a/modules/menu_dialog/client/module.lua b/modules/menu_dialog/client/module.lua new file mode 100644 index 00000000..1bfdd2c0 --- /dev/null +++ b/modules/menu_dialog/client/module.lua @@ -0,0 +1,46 @@ +ESX.Modules['menu_dialog'] = {}; +local self = ESX.Modules['menu_dialog'] + +self.Timeouts = {} +self.OpenedMenus = {} +self.MenuType = 'dialog' + +self.openMenu = function(namespace, name, data) + + for i=1, #self.Timeouts, 1 do + ESX.ClearTimeout(self.Timeouts[i]) + end + + self.OpenedMenus[namespace .. '_' .. name] = true + + ESX.SendFrameMessage('menu_dialog', { + action = 'openMenu', + namespace = namespace, + name = name, + data = data + }) + + local timeoutId = ESX.SetTimeout(200, function() + ESX.FocusFrame('menu_dialog', true, true) + end) + + table.insert(self.Timeouts, timeoutId) +end + +self.closeMenu = function(namespace, name) + + self.OpenedMenus[namespace .. '_' .. name] = nil + + ESX.SendFrameMessage('menu_dialog', { + action = 'closeMenu', + namespace = namespace, + name = name, + data = data + }) + + if ESX.Table.SizeOf(self.OpenedMenus) == 0 then + SetNuiFocus(false) + end + +end + diff --git a/modules/menu_dialog/data/html/css/app.css b/modules/menu_dialog/data/html/css/app.css new file mode 100644 index 00000000..e8f361b5 --- /dev/null +++ b/modules/menu_dialog/data/html/css/app.css @@ -0,0 +1,74 @@ +@font-face { + font-family: bankgothic; + src: url('../fonts/bankgothic.ttf'); +} + +@font-face { + font-family: pcdown; + src: url('../fonts/pdown.ttf'); +} + +#controls { + font-family: pcdown; + font-size: 3em; + color: #FFF; + position: absolute; + bottom: 40; + right: 40; + text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; +} + +.controls { + display: none; +} + +.dialog { + font-family: bankgothic; + background-color: #fff; + color: #fff; + box-shadow: 0px 0px 50px 0px #000; + position: absolute; + overflow: hidden; + top: 50%; + left: 50%; + width: 600px; + height: 104px; + transform: translate(-50%, -50%); +} + +.dialog.big { + height: 200px; +} + +.dialog .head { + background-color: #506be6; + text-align: center; + height: 40px; +} + +.dialog .head span:before { + content: ""; + display: inline-block; + height: 100%; + vertical-align: middle; +} + +.dialog input[type="text"] { + width: 100%; + height: 32px; +} + +.dialog textarea { + width: 100%; + height: 128px; +} + +.dialog button[name="submit"] { + width: 75%; + height: 32px; +} + +.dialog button[name="cancel"] { + width: 25%; + height: 32px; +} diff --git a/modules/menu_dialog/data/html/fonts/bankgothic.ttf b/modules/menu_dialog/data/html/fonts/bankgothic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f3d8049b052a1f9cfd27557eb3675bc85ce4b9fc GIT binary patch literal 36272 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 D`#l06 literal 0 HcmV?d00001 diff --git a/modules/menu_dialog/data/html/fonts/pdown.ttf b/modules/menu_dialog/data/html/fonts/pdown.ttf new file mode 100644 index 0000000000000000000000000000000000000000..69c76cf3f2a6bbc93f570124554fec06d7bbac25 GIT binary patch literal 151512 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 literal 0 HcmV?d00001 diff --git a/modules/menu_dialog/data/html/js/app.js b/modules/menu_dialog/data/html/js/app.js new file mode 100644 index 00000000..c41f6c8b --- /dev/null +++ b/modules/menu_dialog/data/html/js/app.js @@ -0,0 +1,176 @@ +(function () { + let MenuTpl = + '