fix(qb-core): post-update recovery + centralizare notify 17mov_Hud
Restaurat jobs.lua din git (Quasar fork a suprascris joburile 17mov). Adăugat item map în items.lua (lipsea, rupt rv-maphold). Setat licences.driver = false în config.lua. Override QBCore.Functions.Notify + QBCore:Notify event → 17mov_Hud:ShowNotification (toate notificările merg automat prin 17mov_Hud).
This commit is contained in:
Binary file not shown.
+93
@@ -0,0 +1,93 @@
|
||||
--[[
|
||||
Hi dear customer or developer, here you can fully configure your server's
|
||||
framework or you could even duplicate this file to create your own framework.
|
||||
|
||||
If you do not have much experience, we recommend you download the base version
|
||||
of the framework that you use in its latest version and it will work perfectly.
|
||||
]]
|
||||
|
||||
if Config.Framework ~= 'esx' then
|
||||
return
|
||||
end
|
||||
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
|
||||
function GetPlayerData()
|
||||
return ESX.GetPlayerData()
|
||||
end
|
||||
|
||||
local first = true
|
||||
RegisterNetEvent('esx:playerLoaded', function()
|
||||
if first then
|
||||
first = false
|
||||
CreateThread(function()
|
||||
Wait(1000)
|
||||
GetPlayerData(function(PlayerData)
|
||||
PlayerJob = PlayerData.job
|
||||
SetPedArmour(PlayerPedId(), PlayerData.metadata['armor'])
|
||||
currentarmor = PlayerData.metadata['armor']
|
||||
startedsync = true
|
||||
Wait(100)
|
||||
if Config.VestTexture then
|
||||
local ped = PlayerPedId()
|
||||
local PlayerData = GetPlayerData()
|
||||
local GetArmor = GetPedArmour(ped)
|
||||
currentVest = GetPedDrawableVariation(ped, 9)
|
||||
currentVestTexture = GetPedTextureVariation(ped, 9)
|
||||
if GetArmor >= 1 then
|
||||
SetVest()
|
||||
elseif GetArmor >= 51 then
|
||||
SetHeavyVest()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
function SendTextMessage(msg, type)
|
||||
if type == 'inform' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'inform'
|
||||
})
|
||||
end
|
||||
if type == 'error' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'error'
|
||||
})
|
||||
end
|
||||
if type == 'success' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'success'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function ProgressBar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
|
||||
if lib.progressCircle({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation.animDict,
|
||||
clip = animation.anim,
|
||||
flag = animation?.flags
|
||||
},
|
||||
prop = prop
|
||||
}) then
|
||||
onFinish()
|
||||
else
|
||||
if onCancel then
|
||||
onCancel()
|
||||
end
|
||||
end
|
||||
end
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
--[[
|
||||
Hi dear customer or developer, here you can fully configure your server's
|
||||
framework or you could even duplicate this file to create your own framework.
|
||||
|
||||
If you do not have much experience, we recommend you download the base version
|
||||
of the framework that you use in its latest version and it will work perfectly.
|
||||
]]
|
||||
|
||||
if Config.Framework ~= 'qb' then
|
||||
return
|
||||
end
|
||||
|
||||
QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
function GetPlayerData()
|
||||
return QBCore.Functions.GetPlayers()
|
||||
end
|
||||
|
||||
local first = true
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
|
||||
if first then
|
||||
first = false
|
||||
CreateThread(function()
|
||||
Wait(1000)
|
||||
GetPlayerData(function(PlayerData)
|
||||
PlayerJob = PlayerData.job
|
||||
SetPedArmour(PlayerPedId(), PlayerData.metadata['armor'])
|
||||
currentarmor = PlayerData.metadata['armor']
|
||||
startedsync = true
|
||||
Wait(100)
|
||||
if Config.VestTexture then
|
||||
local ped = PlayerPedId()
|
||||
local PlayerData = QS.GetPlayerData()
|
||||
local GetArmor = GetPedArmour(ped)
|
||||
currentVest = GetPedDrawableVariation(ped, 9)
|
||||
currentVestTexture = GetPedTextureVariation(ped, 9)
|
||||
if GetArmor >= 1 then
|
||||
SetVest()
|
||||
elseif GetArmor >= 51 then
|
||||
SetHeavyVest()
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
function SendTextMessage(msg, type)
|
||||
if type == 'inform' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'inform'
|
||||
})
|
||||
end
|
||||
if type == 'error' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'error'
|
||||
})
|
||||
end
|
||||
if type == 'success' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'success'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function ShowHelpNotification(msg)
|
||||
BeginTextCommandDisplayHelp('STRING')
|
||||
AddTextComponentSubstringPlayerName(msg)
|
||||
EndTextCommandDisplayHelp(0, 0, false, -1)
|
||||
end
|
||||
|
||||
function DrawText3D(x, y, z, text)
|
||||
SetTextScale(0.4, 0.4)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry('STRING')
|
||||
SetTextCentre(true)
|
||||
AddTextComponentString(text)
|
||||
SetDrawOrigin(x, y, z, 0)
|
||||
DrawText(0.0, 0.0)
|
||||
ClearDrawOrigin()
|
||||
end
|
||||
|
||||
function ProgressBar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
|
||||
if lib.progressCircle({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation.animDict,
|
||||
clip = animation.anim,
|
||||
flag = animation?.flags
|
||||
},
|
||||
prop = prop
|
||||
}) then
|
||||
onFinish()
|
||||
else
|
||||
if onCancel then
|
||||
onCancel()
|
||||
end
|
||||
end
|
||||
end
|
||||
Binary file not shown.
@@ -0,0 +1,33 @@
|
||||
fx_version 'adamant'
|
||||
|
||||
game 'gta5'
|
||||
|
||||
lua54 'yes'
|
||||
|
||||
shared_scripts {
|
||||
'@ox_lib/init.lua',
|
||||
'shared/*.lua',
|
||||
'locales/*.lua',
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
'server/**/**/**.lua'
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'client/**/**/**.lua'
|
||||
}
|
||||
|
||||
escrow_ignore {
|
||||
'shared/config.lua',
|
||||
'locales/*.lua',
|
||||
'client/custom/framework/*.lua',
|
||||
'server/custom/framework/*.lua',
|
||||
}
|
||||
|
||||
dependencies {
|
||||
'qs-inventory', -- Required.
|
||||
'/server:4752', -- ⚠️PLEASE READ⚠️ This requires at least server build 4700 or higher
|
||||
}
|
||||
|
||||
dependency '/assetpacks'
|
||||
@@ -0,0 +1,8 @@
|
||||
Locales['de'] = {
|
||||
["ARMOR_NOTIFICATION_ALREADY_HAVE"] = "Du hast schon eine Weste an",
|
||||
["ARMOR_NOTIFICATION_DONT_HAVE"] = "Du hast keine Weste!",
|
||||
|
||||
["ARMOR_PROGRESS_USE_ARMOR"] = "Kugelsichere Weste Anziehen ...",
|
||||
["ARMOR_PROGRESS_USE_HEAVYARMOR"] = "Schwere Weste Anziehen ...",
|
||||
["ARMOR_PROGRESS_REMOVE_ARMOR"] = "Weste ausziehen ...",
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
Locales['en'] = {
|
||||
["ARMOR_NOTIFICATION_ALREADY_HAVE"] = "You already have a bulletproof vest",
|
||||
["ARMOR_NOTIFICATION_DONT_HAVE"] = "You don't have a bulletproof vest",
|
||||
|
||||
["ARMOR_PROGRESS_USE_ARMOR"] = "Placing Armor ...",
|
||||
["ARMOR_PROGRESS_USE_HEAVYARMOR"] = "Placing Heavy Armor ...",
|
||||
["ARMOR_PROGRESS_REMOVE_ARMOR"] = "Removing Armor ...",
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
Locales['es'] = {
|
||||
["ARMOR_NOTIFICATION_ALREADY_HAVE"] = "Ya tienes un chaleco antibalas",
|
||||
["ARMOR_NOTIFICATION_DONT_HAVE"] = "No tienes un chaleco antibalas",
|
||||
|
||||
["ARMOR_PROGRESS_USE_ARMOR"] = "Colocando Armor...",
|
||||
["ARMOR_PROGRESS_USE_HEAVYARMOR"] = "Colocando Heavy Armor...",
|
||||
["ARMOR_PROGRESS_REMOVE_ARMOR"] = "Quitando Armor...",
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
Locales['it'] = {
|
||||
["ARMOR_NOTIFICATION_ALREADY_HAVE"] = "Hai già un giubbotto anti-proiettile",
|
||||
["ARMOR_NOTIFICATION_DONT_HAVE"] = "Non hai un giubbotto anti-proiettile",
|
||||
|
||||
["ARMOR_PROGRESS_USE_ARMOR"] = "Indossando giubbotto anti-proiettile...",
|
||||
["ARMOR_PROGRESS_USE_HEAVYARMOR"] = "Indossando giubbotto anti-proiettile pesante...",
|
||||
["ARMOR_PROGRESS_REMOVE_ARMOR"] = "Togliendo armatura...",
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
--[[
|
||||
Hi dear customer or developer, here you can fully configure your server's
|
||||
framework or you could even duplicate this file to create your own framework.
|
||||
|
||||
If you do not have much experience, we recommend you download the base version
|
||||
of the framework that you use in its latest version and it will work perfectly.
|
||||
]]
|
||||
|
||||
if Config.Framework ~= 'esx' then
|
||||
return
|
||||
end
|
||||
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
|
||||
function RegisterUsableItem(name, cb)
|
||||
exports['qs-inventory']:CreateUsableItem(name, cb)
|
||||
end
|
||||
|
||||
function GetPlayerFromId(source)
|
||||
return ESX.GetPlayerFromId(source)
|
||||
end
|
||||
|
||||
function GetIdentifier(source)
|
||||
return ESX.GetPlayerFromId(source).identifier
|
||||
end
|
||||
|
||||
function AddItem(source, item, count, slot)
|
||||
exports['qs-inventory']:AddItem(source, item, count, slot)
|
||||
end
|
||||
|
||||
function RemoveItem(source, item, count)
|
||||
local xPlayer = GetPlayerFromId(source)
|
||||
xPlayer.removeInventoryItem(item, count)
|
||||
end
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
--[[
|
||||
Hi dear customer or developer, here you can fully configure your server's
|
||||
framework or you could even duplicate this file to create your own framework.
|
||||
|
||||
If you do not have much experience, we recommend you download the base version
|
||||
of the framework that you use in its latest version and it will work perfectly.
|
||||
]]
|
||||
|
||||
if Config.Framework ~= 'qb' then
|
||||
return
|
||||
end
|
||||
|
||||
QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
function RegisterUsableItem(name, cb)
|
||||
exports['qs-inventory']:CreateUsableItem(name, cb)
|
||||
end
|
||||
|
||||
function GetPlayerFromId(player)
|
||||
return QBCore.Functions.GetPlayer(player)
|
||||
end
|
||||
|
||||
function GetIdentifier(player)
|
||||
return QBCore.Functions.GetPlayer(player).PlayerData.citizenid
|
||||
end
|
||||
|
||||
function AddItem(source, item, count, slot)
|
||||
exports['qs-inventory']:AddItem(source, item, count, slot)
|
||||
end
|
||||
|
||||
function RemoveItem(source, item, count)
|
||||
local xPlayer = GetPlayerFromId(source)
|
||||
xPlayer.Functions.RemoveItem(item, count)
|
||||
end
|
||||
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,103 @@
|
||||
Config = {}
|
||||
Locales = {}
|
||||
local esxHas = GetResourceState('es_extended') == 'started'
|
||||
local qbHas = GetResourceState('qb-core') == 'started'
|
||||
local qbxHas = GetResourceState('qbx_core') == 'started'
|
||||
|
||||
Config.Framework = esxHas and 'esx' or qbHas and 'qb' or qbxHas and 'qb' or 'esx'
|
||||
|
||||
--[[
|
||||
Set the primary language for the resource.
|
||||
Choose one of the default languages located in locales/*.
|
||||
If your desired language is not listed, feel free to create your own!
|
||||
]]
|
||||
|
||||
Config.Language = 'en'
|
||||
|
||||
--[[
|
||||
General configuration settings for the resource.
|
||||
Customize each option as needed.
|
||||
]]
|
||||
|
||||
Config.Progressbar = { -- Timer durations for progress bars (in milliseconds).
|
||||
UseArmor = 5000, -- Duration for applying regular armor.
|
||||
UseHeavyArmor = 5000, -- Duration for applying heavy armor.
|
||||
ResetArmor = 2500 -- Duration for removing the armor.
|
||||
}
|
||||
|
||||
Config.SetPedArmour = { -- Amount of armor applied to the player.
|
||||
UseArmor = 50, -- Armor value for regular armor.
|
||||
UseHeavyArmor = 100, -- Armor value for heavy armor.
|
||||
ResetArmor = 0 -- Armor value when the vest is removed.
|
||||
}
|
||||
|
||||
--[[
|
||||
Command used to remove the player's vest.
|
||||
]]
|
||||
|
||||
Config.ResetArmor = 'resetarmor' -- Command to reset/remove your vest.
|
||||
|
||||
--[[
|
||||
Configuration to check if a player has a vest equipped.
|
||||
]]
|
||||
|
||||
Config.VestTexture = true -- Should vest textures be used? (true = Yes, false = No)
|
||||
Config.CheckVest = {
|
||||
check = false, -- Enable automatic vest checks? (true = Yes, false = No)
|
||||
time = 30000 -- Frequency of checks (in milliseconds). Ignored if check = false.
|
||||
}
|
||||
|
||||
--[[
|
||||
Vest configuration based on player gender.
|
||||
Customize the vest components for both male and female characters.
|
||||
]]
|
||||
|
||||
Config.Vest = {
|
||||
male = {
|
||||
['bproof_1'] = 6, -- Main vest component ID for males.
|
||||
['bproof_2'] = 1 -- Secondary vest texture ID for males.
|
||||
},
|
||||
female = {
|
||||
['bproof_1'] = 0, -- Main vest component ID for females.
|
||||
['bproof_2'] = 0 -- Secondary vest texture ID for females.
|
||||
},
|
||||
|
||||
maleHeavy = {
|
||||
['bproof_1'] = 27, -- Main heavy vest component ID for males.
|
||||
['bproof_2'] = 2 -- Secondary heavy vest texture ID for males.
|
||||
},
|
||||
|
||||
femaleHeavy = {
|
||||
['bproof_1'] = 6, -- Main heavy vest component ID for females.
|
||||
['bproof_2'] = 0 -- Secondary heavy vest texture ID for females.
|
||||
}
|
||||
}
|
||||
|
||||
--[[
|
||||
Editable functions to handle vest application or removal.
|
||||
These functions are only executed if VestTexture is set to true.
|
||||
]]
|
||||
|
||||
function SetVest() -- Function to apply the regular vest texture.
|
||||
local isMale = GetEntityModel(PlayerPedId()) == joaat('mp_m_freemode_01')
|
||||
local vest = isMale and Config.Vest.male or Config.Vest.female
|
||||
SetPedComponentVariation(PlayerPedId(), 9, vest['bproof_1'], vest['bproof_2'], 0)
|
||||
end
|
||||
|
||||
function SetHeavyVest() -- Function to apply the heavy vest texture.
|
||||
local isMale = GetEntityModel(PlayerPedId()) == joaat('mp_m_freemode_01')
|
||||
local vest = isMale and Config.Vest.maleHeavy or Config.Vest.femaleHeavy
|
||||
SetPedComponentVariation(PlayerPedId(), 9, vest['bproof_1'], vest['bproof_2'], 0)
|
||||
end
|
||||
|
||||
function RemoveVest() -- Function to remove the vest texture.
|
||||
SetPedComponentVariation(PlayerPedId(), 9, 0, 1, 0)
|
||||
end
|
||||
|
||||
--[[
|
||||
Debug mode configuration.
|
||||
When enabled, detailed debug prints/logs are displayed for development purposes.
|
||||
Use this only during development/testing phases.
|
||||
]]
|
||||
|
||||
Config.Debug = false
|
||||
Binary file not shown.
Binary file not shown.
+90
@@ -0,0 +1,90 @@
|
||||
--[[
|
||||
Hi dear customer or developer, here you can fully configure your server's
|
||||
framework or you could even duplicate this file to create your own framework.
|
||||
If you do not have much experience, we recommend you download the base version
|
||||
of the framework that you use in its latest version and it will work perfectly.
|
||||
]]
|
||||
|
||||
if Config.Framework ~= 'esx' then
|
||||
return
|
||||
end
|
||||
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
|
||||
RegisterNetEvent('esx:playerLoaded')
|
||||
AddEventHandler('esx:playerLoaded', function(xPlayer)
|
||||
Wait(10000)
|
||||
StartThread()
|
||||
end)
|
||||
|
||||
AddEventHandler('onClientResourceStart', function(resourceName)
|
||||
if (GetCurrentResourceName() == resourceName) then
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
Wait(10000)
|
||||
StartThread()
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
function getSex()
|
||||
local promise = promise.new()
|
||||
ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin)
|
||||
promise:resolve(skin.sex)
|
||||
end)
|
||||
return Citizen.Await(promise)
|
||||
end
|
||||
|
||||
function OpenStash(metadata)
|
||||
local other = {}
|
||||
other.maxweight = metadata.weight
|
||||
other.slots = metadata.slots
|
||||
TriggerServerEvent('inventory:server:OpenInventory', 'stash', 'Backpack_' .. metadata.ID, other)
|
||||
TriggerEvent('inventory:client:SetCurrentStash', 'Backpack_' .. metadata.ID)
|
||||
repeat Wait(1000) until IsNuiFocused() == false
|
||||
TriggerEvent('backpacks:client:close', metadata.ID)
|
||||
end
|
||||
|
||||
function SendTextMessage(msg, type)
|
||||
if type == 'inform' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'inform'
|
||||
})
|
||||
end
|
||||
if type == 'error' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'error'
|
||||
})
|
||||
end
|
||||
if type == 'success' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'success'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
|
||||
if lib.progressCircle({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation.animDict,
|
||||
clip = animation.anim,
|
||||
flag = animation?.flags
|
||||
},
|
||||
prop = prop
|
||||
}) then
|
||||
onFinish()
|
||||
else
|
||||
onCancel()
|
||||
end
|
||||
end
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
--[[
|
||||
Hi dear customer or developer, here you can fully configure your server's
|
||||
framework or you could even duplicate this file to create your own framework.
|
||||
If you do not have much experience, we recommend you download the base version
|
||||
of the framework that you use in its latest version and it will work perfectly.
|
||||
]]
|
||||
|
||||
if Config.Framework ~= 'qb' then
|
||||
return
|
||||
end
|
||||
|
||||
QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded')
|
||||
AddEventHandler('QBCore:Client:OnPlayerLoaded', function(xPlayer)
|
||||
Wait(10000)
|
||||
StartThread()
|
||||
end)
|
||||
|
||||
AddEventHandler('onClientResourceStart', function(resourceName)
|
||||
if (GetCurrentResourceName() == resourceName) then
|
||||
QBCore = exports['qb-core']:GetCoreObject()
|
||||
Wait(10000)
|
||||
StartThread()
|
||||
end
|
||||
end)
|
||||
|
||||
function getSex()
|
||||
return QBCore.Functions.GetPlayerData()?.charinfo?.gender
|
||||
end
|
||||
|
||||
function OpenStash(metadata)
|
||||
local other = {}
|
||||
other.maxweight = metadata.weight
|
||||
other.slots = metadata.slots
|
||||
TriggerServerEvent('inventory:server:OpenInventory', 'stash', 'Backpack_' .. metadata.ID, other)
|
||||
TriggerEvent('inventory:client:SetCurrentStash', 'Backpack_' .. metadata.ID)
|
||||
repeat Wait(1000) until IsNuiFocused() == false
|
||||
TriggerEvent('backpacks:client:close', metadata.ID)
|
||||
end
|
||||
|
||||
function SendTextMessage(msg, type)
|
||||
if type == 'inform' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'inform'
|
||||
})
|
||||
end
|
||||
if type == 'error' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'error'
|
||||
})
|
||||
end
|
||||
if type == 'success' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'success'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
|
||||
if lib.progressCircle({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation.animDict,
|
||||
clip = animation.anim,
|
||||
flag = animation?.flags
|
||||
},
|
||||
prop = prop
|
||||
}) then
|
||||
onFinish()
|
||||
else
|
||||
onCancel()
|
||||
end
|
||||
end
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
if Config.Menu ~= 'esx_menu_default' then
|
||||
return
|
||||
end
|
||||
|
||||
function CreateBackpack(ID)
|
||||
ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'create_password',
|
||||
{
|
||||
title = Lang('CREATE_PASSWORD'),
|
||||
}, function(data, menu)
|
||||
local length = string.len(data.value)
|
||||
if length <= 0 then
|
||||
SendTextMessage(Lang('BAD_PASSWORD'), 'error')
|
||||
elseif length < Config.PasswordLength.min then
|
||||
SendTextMessage(Lang('MORE_PASSWORD'), 'error')
|
||||
elseif length > Config.PasswordLength.max then
|
||||
SendTextMessage(Lang('LESS_PASSWORD'), 'error')
|
||||
else
|
||||
SendTextMessage(Lang('ADDED_PASSWORD'), 'success')
|
||||
TriggerServerEvent('backpacks:server:add_password', { ID = ID, password = data.value })
|
||||
menu.close()
|
||||
end
|
||||
end, function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
end
|
||||
|
||||
function CheckMeta(backpack_metadata)
|
||||
if backpack_metadata.locked then
|
||||
ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'enter_password',
|
||||
{
|
||||
title = Lang('INTRODUCE_PASSWORD'),
|
||||
}, function(data, menu)
|
||||
if backpack_metadata.password == data.value then
|
||||
menu.close()
|
||||
backpack_metadata.trypassword = data.value
|
||||
OpenBackpack(backpack_metadata)
|
||||
else
|
||||
SendTextMessage(Lang('BAD_PASSWORD'), 'error')
|
||||
menu.close()
|
||||
end
|
||||
end, function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
else
|
||||
OpenBackpack(backpack_metadata)
|
||||
end
|
||||
end
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
if Config.Menu ~= 'ox_lib' then
|
||||
return
|
||||
end
|
||||
|
||||
function CreateBackpack(ID)
|
||||
if not lib then
|
||||
print('You need to uncomment the ox_lib export on line 10 of qs-backpacks/fxmanifest.lua')
|
||||
return
|
||||
end
|
||||
local keyboard1 = lib.inputDialog(Lang('CREATE_PASSWORD') .. ' Min ' .. Config.PasswordLength.min .. ' Max ' .. Config.PasswordLength.max, { Lang('INTRODUCE_PASSWORD_2') })
|
||||
if not keyboard1 then return end
|
||||
|
||||
local pass = tostring(keyboard1[1])
|
||||
local length = string.len(pass)
|
||||
if length <= 0 then
|
||||
SendTextMessage(Lang('BAD_PASSWORD'), 'error')
|
||||
return
|
||||
end
|
||||
if length < Config.PasswordLength.min then
|
||||
SendTextMessage(Lang('MORE_PASSWORD'), 'error')
|
||||
return
|
||||
end
|
||||
if length > Config.PasswordLength.max then
|
||||
SendTextMessage(Lang('LESS_PASSWORD'), 'error')
|
||||
return
|
||||
end
|
||||
|
||||
SendTextMessage(Lang('ADDED_PASSWORD'), 'success')
|
||||
TriggerServerEvent('backpacks:server:add_password', { ID = ID, password = pass })
|
||||
end
|
||||
|
||||
function CheckMeta(backpack_metadata)
|
||||
if backpack_metadata.locked then
|
||||
if not lib then
|
||||
print('You need to uncomment the ox_lib export on line 10 of qs-backpacks/fxmanifest.lua')
|
||||
return
|
||||
end
|
||||
local data = lib.inputDialog(Lang('INTRODUCE_PASSWORD'), { Lang('INTRODUCE_PASSWORD_2') })
|
||||
if not data then
|
||||
SendTextMessage(Lang('BAD_PASSWORD'), 'error')
|
||||
return
|
||||
end
|
||||
backpack_metadata.trypassword = data[1]
|
||||
OpenBackpack(backpack_metadata)
|
||||
else
|
||||
OpenBackpack(backpack_metadata)
|
||||
end
|
||||
end
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
if Config.Menu ~= 'qb-menu' then
|
||||
return
|
||||
end
|
||||
|
||||
function CreateBackpack(ID)
|
||||
local inputData = exports['qb-input']:ShowInput({
|
||||
header = Lang('CREATE_PASSWORD') .. ' Min ' .. Config.PasswordLength.min .. ' Max ' .. Config.PasswordLength.max,
|
||||
inputs = {
|
||||
{
|
||||
type = 'password',
|
||||
isRequired = true,
|
||||
name = 'pass', -- name of the input should be unique otherwise it might override
|
||||
type = 'password', -- type of the input
|
||||
text = Lang('INTRODUCE_PASSWORD_2'),
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
if inputData then
|
||||
if not inputData.pass then return end
|
||||
local length = string.len(inputData.pass)
|
||||
if length <= 0 then
|
||||
SendTextMessage(Lang('BAD_PASSWORD'), 'error')
|
||||
return
|
||||
end
|
||||
if length < Config.PasswordLength.min then
|
||||
SendTextMessage(Lang('MORE_PASSWORD'), 'error')
|
||||
return
|
||||
end
|
||||
if length > Config.PasswordLength.max then
|
||||
SendTextMessage(Lang('LESS_PASSWORD'), 'error')
|
||||
return
|
||||
end
|
||||
|
||||
SendTextMessage(Lang('ADDED_PASSWORD'), 'success')
|
||||
TriggerServerEvent('backpacks:server:add_password', { ID = ID, password = inputData.pass })
|
||||
end
|
||||
end
|
||||
|
||||
function CheckMeta(backpack_metadata)
|
||||
if backpack_metadata.locked then
|
||||
local inputData = exports['qb-input']:ShowInput({
|
||||
header = Lang('INTRODUCE_PASSWORD'),
|
||||
inputs = {
|
||||
{
|
||||
type = 'password',
|
||||
isRequired = true,
|
||||
name = 'pass',
|
||||
text = Lang('INTRODUCE_PASSWORD')
|
||||
},
|
||||
}
|
||||
})
|
||||
if inputData then
|
||||
if not inputData.pass then
|
||||
SendTextMessage(Lang('BAD_PASSWORD'), 'error')
|
||||
return
|
||||
end
|
||||
backpack_metadata.trypassword = inputData.pass
|
||||
OpenBackpack(backpack_metadata)
|
||||
end
|
||||
else
|
||||
OpenBackpack(backpack_metadata)
|
||||
end
|
||||
end
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
if Config.SkinScript ~= 'esx_skin' then
|
||||
return
|
||||
end
|
||||
|
||||
function putClothes(backpack)
|
||||
ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin)
|
||||
local clothes = {
|
||||
male = { ['bags_1'] = backpack.cloth['male'].bag['item'], ['bags_2'] = backpack.cloth['male'].bag['texture'] },
|
||||
female = { ['bags_1'] = backpack.cloth['female'].bag['item'], ['bags_2'] = backpack.cloth['male'].bag['texture'] },
|
||||
}
|
||||
|
||||
if skin.sex == 0 then
|
||||
TriggerEvent('skinchanger:loadClothes', skin, clothes.male)
|
||||
elseif skin.sex == 1 then
|
||||
TriggerEvent('skinchanger:loadClothes', skin, clothes.female)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function RemoveClothes()
|
||||
local cloth = {
|
||||
male = { ['bags_1'] = 0 },
|
||||
female = { ['bags_1'] = 0 },
|
||||
}
|
||||
ESX.TriggerServerCallback('esx_skin:getPlayerSkin', function(skin, jobSkin)
|
||||
if skin.sex == 0 then
|
||||
TriggerEvent('skinchanger:loadClothes', skin, cloth.male)
|
||||
elseif skin.sex == 1 then
|
||||
TriggerEvent('skinchanger:loadClothes', skin, cloth.female)
|
||||
end
|
||||
end)
|
||||
end
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
if Config.SkinScript ~= 'illenium-appearance' then
|
||||
return
|
||||
end
|
||||
|
||||
function putClothes(backpack)
|
||||
if getSex() == 0 then
|
||||
TriggerEvent('qb-clothing:client:loadOutfit', { outfitData = backpack.cloth['male'] })
|
||||
else
|
||||
TriggerEvent('qb-clothing:client:loadOutfit', { outfitData = backpack.cloth['female'] })
|
||||
end
|
||||
end
|
||||
|
||||
function RemoveClothes()
|
||||
TriggerEvent('qb-clothing:client:loadOutfit', {
|
||||
outfitData = {
|
||||
['bag'] = { item = -1, texture = 0 }
|
||||
}
|
||||
})
|
||||
end
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
if Config.SkinScript ~= 'qb-clothing' then
|
||||
return
|
||||
end
|
||||
|
||||
function putClothes(backpack)
|
||||
if getSex() == 0 then
|
||||
TriggerEvent('qb-clothing:client:loadOutfit', { outfitData = backpack.cloth['male'] })
|
||||
else
|
||||
TriggerEvent('qb-clothing:client:loadOutfit', { outfitData = backpack.cloth['female'] })
|
||||
end
|
||||
end
|
||||
|
||||
function RemoveClothes()
|
||||
TriggerEvent('qb-clothing:client:loadOutfit', {
|
||||
outfitData = {
|
||||
['bag'] = { item = -1, texture = 0 }
|
||||
}
|
||||
})
|
||||
end
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,34 @@
|
||||
fx_version 'adamant'
|
||||
|
||||
game 'gta5'
|
||||
|
||||
lua54 'yes'
|
||||
|
||||
shared_scripts {
|
||||
'@ox_lib/init.lua',
|
||||
'shared/*.lua',
|
||||
'locales/*.lua',
|
||||
'client/shared.lua'
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
'server/**/**/**.lua'
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'client/**/**/**.lua'
|
||||
}
|
||||
|
||||
escrow_ignore {
|
||||
'shared/*.lua',
|
||||
'locales/*.lua',
|
||||
'client/custom/**/*.lua'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
'/server:4752', -- ⚠️PLEASE READ⚠️ This requires at least server build 4700 or higher
|
||||
'/assetpacks',
|
||||
'qs-inventory'
|
||||
}
|
||||
|
||||
dependency '/assetpacks'
|
||||
@@ -0,0 +1,60 @@
|
||||
# FOR QBCore `qb-core/shared/items`
|
||||
```lua
|
||||
['backpack'] = { ['name'] = 'backpack', ['label'] = 'backpack', ['weight'] = 0, ['type'] = 'item', ['image'] = 'backpack.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'No have' },
|
||||
['backpack2'] = { ['name'] = 'backpack2', ['label'] = 'backpack2', ['weight'] = 0, ['type'] = 'item', ['image'] = 'backpack2.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'No have' },
|
||||
['briefcase'] = { ['name'] = 'briefcase', ['label'] = 'briefcase', ['weight'] = 0, ['type'] = 'item', ['image'] = 'briefcase.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'No have' },
|
||||
['paramedicbag'] = { ['name'] = 'paramedicbag', ['label'] = 'paramedicbag', ['weight'] = 0, ['type'] = 'item', ['image'] = 'paramedicbag.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'No have' },
|
||||
```
|
||||
|
||||
|
||||
# FOR ESX `qs-inventory/shared/items.lua`
|
||||
```lua
|
||||
['backpack'] = {
|
||||
['name'] = 'backpack',
|
||||
['label'] = 'backpack',
|
||||
['weight'] = 0,
|
||||
['type'] = 'item',
|
||||
['image'] = 'backpack.png',
|
||||
['unique'] = true,
|
||||
['useable'] = true,
|
||||
['shouldClose'] = true,
|
||||
['combinable'] = nil,
|
||||
['description'] = 'No have'
|
||||
},
|
||||
['backpack2'] = {
|
||||
['name'] = 'backpack2',
|
||||
['label'] = 'backpack2',
|
||||
['weight'] = 0,
|
||||
['type'] = 'item',
|
||||
['image'] = 'backpack2.png',
|
||||
['unique'] = true,
|
||||
['useable'] = true,
|
||||
['shouldClose'] = true,
|
||||
['combinable'] = nil,
|
||||
['description'] = 'No have'
|
||||
},
|
||||
['briefcase'] = {
|
||||
['name'] = 'briefcase',
|
||||
['label'] = 'briefcase',
|
||||
['weight'] = 0,
|
||||
['type'] = 'item',
|
||||
['image'] = 'briefcase.png',
|
||||
['unique'] = true,
|
||||
['useable'] = true,
|
||||
['shouldClose'] = true,
|
||||
['combinable'] = nil,
|
||||
['description'] = 'No have'
|
||||
},
|
||||
['paramedicbag'] = {
|
||||
['name'] = 'paramedicbag',
|
||||
['label'] = 'paramedicbag',
|
||||
['weight'] = 0,
|
||||
['type'] = 'item',
|
||||
['image'] = 'paramedicbag.png',
|
||||
['unique'] = true,
|
||||
['useable'] = true,
|
||||
['shouldClose'] = true,
|
||||
['combinable'] = nil,
|
||||
['description'] = 'No have'
|
||||
},
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
Locales['cs'] = {
|
||||
['INTRODUCE_PASSWORD'] = 'Zadejte heslo',
|
||||
['INTRODUCE_PASSWORD_2'] = 'Heslo',
|
||||
['CREATE_PASSWORD'] = 'Vytvořit heslo',
|
||||
['OPEN'] = 'Otevírám...',
|
||||
['CLOSE'] = 'Zavírám...',
|
||||
['BAD_PASSWORD'] = 'Nesprávné heslo...',
|
||||
['ADDED_PASSWORD'] = 'Přidáno heslo..',
|
||||
['MORE_PASSWORD'] = 'Heslo musí mít více znaků',
|
||||
['LESS_PASSWORD'] = 'Heslo musí mít méně znaků',
|
||||
['EMPLY_PASSWORD'] = 'Musíte něco vložit',
|
||||
['NO_BACKPACK'] = 'Batoh nemáte po ruce.',
|
||||
['FAILED_PASSWORD'] = 'Nepodařilo se přidat heslo.',
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
Locales['de'] = {
|
||||
['INTRODUCE_PASSWORD'] = 'Passwort eingeben',
|
||||
['INTRODUCE_PASSWORD_2'] = 'Passwort',
|
||||
['CREATE_PASSWORD'] = 'Erstelle ein Passwort',
|
||||
['OPEN'] = 'Öffnen...',
|
||||
['CLOSE'] = 'Schließen...',
|
||||
['BAD_PASSWORD'] = 'Falsches Passwort...',
|
||||
['ADDED_PASSWORD'] = 'Passwort hinzugefügt...',
|
||||
['MORE_PASSWORD'] = 'Das Passwort muss länger sein',
|
||||
['LESS_PASSWORD'] = 'Das Passwort muss kürzer sein',
|
||||
['EMPLY_PASSWORD'] = 'Du musst ein Passwort eingeben',
|
||||
['NO_BACKPACK'] = 'Der Rucksack befindet sich nicht in deiner Hand.',
|
||||
['FAILED_PASSWORD'] = 'Passwort konnte nicht hinzugefügt werden.',
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
Locales['en'] = {
|
||||
['INTRODUCE_PASSWORD'] = 'Enter the password',
|
||||
['INTRODUCE_PASSWORD_2'] = 'Password',
|
||||
['CREATE_PASSWORD'] = 'Create a password',
|
||||
['OPEN'] = 'Opening...',
|
||||
['CLOSE'] = 'Closing...',
|
||||
['BAD_PASSWORD'] = 'Incorrect password...',
|
||||
['ADDED_PASSWORD'] = 'Added password..',
|
||||
['MORE_PASSWORD'] = 'The password must have more characters',
|
||||
['LESS_PASSWORD'] = 'The password must have fewer characters',
|
||||
['EMPLY_PASSWORD'] = 'You need to put something',
|
||||
['NO_BACKPACK'] = 'Backpack is not on your hand.',
|
||||
['FAILED_PASSWORD'] = 'Failed to add password.',
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
Locales['es'] = {
|
||||
['INTRODUCE_PASSWORD'] = 'Introduce la contraseña',
|
||||
['INTRODUCE_PASSWORD_2'] = 'Contraseña',
|
||||
['CREATE_PASSWORD'] = 'Crea una contraseña',
|
||||
['OPEN'] = 'Abriendo...',
|
||||
['CLOSE'] = 'Cerrando...',
|
||||
['BAD_PASSWORD'] = 'Contraseña incorrecta...',
|
||||
['ADDED_PASSWORD'] = 'Contraseña incorrecta...',
|
||||
['MORE_PASSWORD'] = 'La contraseña tiene que tener mas caracteres',
|
||||
['LESS_PASSWORD'] = 'La contraseña tiene que tener menos caracteres',
|
||||
['EMPLY_PASSWORD'] = 'Necesitas poner algo',
|
||||
['NO_BACKPACK'] = 'La mochila no esta en tu mano.',
|
||||
['FAILED_PASSWORD'] = 'No pudiste agregar la contraseña.',
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
Locales['fr'] = {
|
||||
['INTRODUCE_PASSWORD'] = 'Entrer un mot de passe',
|
||||
['INTRODUCE_PASSWORD_2'] = 'Mot de passe',
|
||||
['CREATE_PASSWORD'] = 'Créez votre mot de passe',
|
||||
['OPEN'] = 'Ouverture...',
|
||||
['CLOSE'] = 'Fermeture...',
|
||||
['BAD_PASSWORD'] = 'Mot de passe incorrect...',
|
||||
['ADDED_PASSWORD'] = 'Nouveau mot de passe..',
|
||||
['MORE_PASSWORD'] = 'Votre mot de passe est trop court.',
|
||||
['LESS_PASSWORD'] = 'Votre mot de passe est trop long.',
|
||||
['EMPLY_PASSWORD'] = 'Vous devez remplir les champs.',
|
||||
['NO_BACKPACK'] = "Le sac n'est pas dans votre inventaire.",
|
||||
['FAILED_PASSWORD'] = "Erreur lors de l'ajout du mot de passe.",
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
Locales['hu'] = {
|
||||
['INTRODUCE_PASSWORD'] = 'Írja be a jelszót',
|
||||
['INTRODUCE_PASSWORD_2'] = 'Jelszó',
|
||||
['CREATE_PASSWORD'] = 'Hozzon létre egy jelszót',
|
||||
['OPEN'] = 'Nyítás...',
|
||||
['CLOSE'] = 'Zárás...',
|
||||
['BAD_PASSWORD'] = 'hibás jelszó...',
|
||||
['ADDED_PASSWORD'] = 'Hozzáadta jelszót..',
|
||||
['MORE_PASSWORD'] = 'A jelszónak több karakterből kell állnia',
|
||||
['LESS_PASSWORD'] = 'A jelszónak kevesebb karakterből kell állnia',
|
||||
['EMPLY_PASSWORD'] = 'Be kell tenni valamit,',
|
||||
['NO_BACKPACK'] = 'A hátizsák nincs a kezedben.',
|
||||
['FAILED_PASSWORD'] = 'Nem sikerült a jelszó hozzáadása.',
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
Locales['nl'] = {
|
||||
['INTRODUCE_PASSWORD'] = 'Vul wachtwoord in',
|
||||
['INTRODUCE_PASSWORD_2'] = 'Wachtwoord',
|
||||
['CREATE_PASSWORD'] = 'Wachtwoord aanmaken',
|
||||
['OPEN'] = 'Openen...',
|
||||
['CLOSE'] = 'Sluiten...',
|
||||
['BAD_PASSWORD'] = 'Onjuist wachtwoord...',
|
||||
['ADDED_PASSWORD'] = 'Wachtwoord toegevoegd..',
|
||||
['MORE_PASSWORD'] = 'Het wachtwoord voldoet niet aan de hoeveelheid tekens',
|
||||
['LESS_PASSWORD'] = 'Het wachtwoord heeft teveel tekens',
|
||||
['EMPLY_PASSWORD'] = 'Je moet iets ingeven',
|
||||
['NO_BACKPACK'] = 'Je draagt momenteel geen tas in je hand.',
|
||||
['FAILED_PASSWORD'] = 'Wachtwoord toevoegen mislukt.',
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
Locales['pl'] = {
|
||||
['INTRODUCE_PASSWORD'] = 'Wprowadź hasło',
|
||||
['INTRODUCE_PASSWORD_2'] = 'Podaj hasło',
|
||||
['CREATE_PASSWORD'] = 'Utwórz hasło',
|
||||
['OPEN'] = 'Otwarcie...',
|
||||
['CLOSE'] = 'Zamknięcie...',
|
||||
['BAD_PASSWORD'] = 'Nieprawidłowe hasło...',
|
||||
['ADDED_PASSWORD'] = 'Dodane hasło...',
|
||||
['MORE_PASSWORD'] = 'Hasło musi mieć więcej znaków',
|
||||
['LESS_PASSWORD'] = 'Hasło musi mieć mniej znaków',
|
||||
['EMPLY_PASSWORD'] = 'Musisz coś wpisać',
|
||||
['NO_BACKPACK'] = 'Plecak nie jest pod ręką',
|
||||
['FAILED_PASSWORD'] = 'Nie udało się dodać hasła.',
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
Locales['pt'] = {
|
||||
['INTRODUCE_PASSWORD'] = 'Insira a senha',
|
||||
['INTRODUCE_PASSWORD_2'] = 'Senha',
|
||||
['CREATE_PASSWORD'] = 'Criar senha',
|
||||
['OPEN'] = 'Abrindo...',
|
||||
['CLOSE'] = 'Fechando...',
|
||||
['BAD_PASSWORD'] = 'Senha incorreta...',
|
||||
['ADDED_PASSWORD'] = 'Password adicionada.',
|
||||
['MORE_PASSWORD'] = 'Senha muito curta',
|
||||
['LESS_PASSWORD'] = 'Senha muito longa',
|
||||
['EMPLY_PASSWORD'] = 'É necessário inserir algum valor',
|
||||
['NO_BACKPACK'] = 'A mochila não está na sua mão.',
|
||||
['FAILED_PASSWORD'] = 'Erro ao adicionar a senha.',
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,151 @@
|
||||
Config = Config or {}
|
||||
|
||||
-- Clarification if you are going to create more backpacks you have to add the information in these parts:
|
||||
|
||||
-- qs-inventory/config/metadata.js
|
||||
-- Save information
|
||||
--[[
|
||||
} else if (itemData.name == "YOUR_BACKPACK_NAME") {
|
||||
$(".item-info-title").html("<p>" + label + "</p>");
|
||||
$(".item-info-description").html(
|
||||
"<p><strong>ID: </strong><span>" +
|
||||
itemData.info.ID +
|
||||
"</span></p><p><strong>Weight: </strong><span>" +
|
||||
itemData.info.weight +
|
||||
"</span></p><p><strong>Slots: </strong><span>" +
|
||||
itemData.info.slots +
|
||||
"</span></p>"
|
||||
);
|
||||
]]
|
||||
|
||||
-- qs-inventory/server/custom/GiveItemToPlayer.lua
|
||||
-- For giveitem admin
|
||||
--[[
|
||||
elseif itemData["name"] == "YOUR_BACKPACK_NAME" then
|
||||
info.ID = 'backpack_'..math.random(111111,999999)
|
||||
info.weight = 10000
|
||||
info.slots = 10
|
||||
]]
|
||||
|
||||
-- (IMPORTANT INTEGRATION WITH qs-advancedshops or qs-shops)
|
||||
-- If you want to add the backpack to a qs-shop, you must add an ID to the item. this is the example :
|
||||
--[[
|
||||
qs-shops/config/config.lua or qs-advancedshops/config/shops.lua
|
||||
|
||||
[1] = {
|
||||
name = "backpack",
|
||||
label = 'Backpack',
|
||||
price = 250,
|
||||
amount = 100,
|
||||
info = {}, -- If you put here info = {}, it will automatically take the weight of your configuration
|
||||
type = "item",
|
||||
slot = 1,
|
||||
},
|
||||
[2] = {
|
||||
name = "my_custom_backpack",
|
||||
label = 'UwU Backpack',
|
||||
price = 250,
|
||||
amount = 100,
|
||||
info = { ID = 'ID_'..math.random(111111,999999), weight = 10000 , slots = 10}, -- If you put this information, it will take the information you put in it
|
||||
type = "item",
|
||||
slot = 2,
|
||||
},
|
||||
]]
|
||||
|
||||
-- (important) do not use both prop and cloth at same time just one.
|
||||
Config.Items = {
|
||||
['backpack'] = { --- Item name
|
||||
slots = 10, -- Change in `qs-inventory/server/custom/GiveItemToPlayer.lua`
|
||||
weight = 100000, -- Change in `qs-inventory/server/custom/GiveItemToPlayer.lua`
|
||||
locked = false, -- If you want to have a password change false to true
|
||||
prop = {
|
||||
model = 'vw_prop_vw_backpack_01a',
|
||||
animation = {
|
||||
dict = 'amb@world_human_hiker_standing@female@base',
|
||||
anim = 'base',
|
||||
bone = 'Back', -- LeftHand | RightHand
|
||||
attaching_position = {
|
||||
x = -0.20, -- Up - Down
|
||||
y = -0.10, -- Forward Backward
|
||||
z = 0.0, -- Left - Right
|
||||
x_rotation = 10.0,
|
||||
y_rotation = 90.0,
|
||||
z_rotation = 175.0,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
['backpack2'] = {
|
||||
slots = 6, -- Change in `qs-inventory/server/custom/GiveItemToPlayer.lua`
|
||||
weight = 10000, -- Change in `qs-inventory/server/custom/GiveItemToPlayer.lua`
|
||||
cloth = {
|
||||
male = {
|
||||
['bag'] = { item = 45, texture = 0 }
|
||||
},
|
||||
female = {
|
||||
['bag'] = { item = 45, texture = 0 }
|
||||
}
|
||||
}
|
||||
},
|
||||
['briefcase'] = {
|
||||
slots = 3,
|
||||
weight = 5000,
|
||||
locked = true, -- If you want to have a password change false to true
|
||||
prop = {
|
||||
model = 'prop_ld_suitcase_01',
|
||||
animation = {
|
||||
dict = 'missheistdocksprep1hold_cellphone',
|
||||
anim = 'static',
|
||||
bone = 'RightHand',
|
||||
attaching_position = {
|
||||
x = 0.10,
|
||||
y = 0.0,
|
||||
z = 0.0,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 280.0,
|
||||
z_rotation = 53.0,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
['paramedicbag'] = {
|
||||
slots = 10, -- Change in `qs-inventory/server/custom/GiveItemToPlayer.lua`
|
||||
weight = 10000, -- Change in `qs-inventory/server/custom/GiveItemToPlayer.lua`
|
||||
prop = {
|
||||
model = 'xm_prop_smug_crate_s_medical',
|
||||
animation = {
|
||||
dict = 'missheistdocksprep1hold_cellphone',
|
||||
anim = 'static',
|
||||
bone = 'RightHand',
|
||||
attaching_position = {
|
||||
x = 0.29,
|
||||
y = -0.05,
|
||||
z = 0.0,
|
||||
x_rotation = -25.0,
|
||||
y_rotation = 280.0,
|
||||
z_rotation = 75.0,
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Config.Bones = {
|
||||
bones = {
|
||||
['RightHand'] = {
|
||||
bone = 57005,
|
||||
current_active_porp = nil,
|
||||
slot = -1,
|
||||
},
|
||||
['Back'] = {
|
||||
bone = 24818,
|
||||
current_active_porp = nil,
|
||||
slot = -1,
|
||||
},
|
||||
['LeftHand'] = {
|
||||
bone = 18905,
|
||||
current_active_porp = nil,
|
||||
slot = -1,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
Config = Config or {}
|
||||
Locales = Locales or {}
|
||||
|
||||
local esxHas = GetResourceState('es_extended') == 'started'
|
||||
local qbHas = GetResourceState('qb-core') == 'started'
|
||||
local qbxHas = GetResourceState('qbx_core') == 'started'
|
||||
|
||||
Config.Framework = esxHas and 'esx' or qbHas and 'qb' or qbxHas and 'qb' or 'esx'
|
||||
|
||||
--[[
|
||||
Language settings.
|
||||
Define the language file located in the locales folder.
|
||||
]]
|
||||
|
||||
Config.Language = 'en' -- Set your lang in locales folder
|
||||
|
||||
--[[
|
||||
Skin script configuration.
|
||||
Supported options:
|
||||
- 'qb-clothing': For servers using QBCore's clothing script.
|
||||
- 'illenium-appearance': For servers using Illenium Appearance.
|
||||
- 'esx_skin': For servers using the ESX Skin system.
|
||||
]]
|
||||
|
||||
Config.SkinScript = 'illenium-appearance' -- 'qb-clothing', 'illenium-appearance', 'esx_skin'
|
||||
|
||||
--[[
|
||||
Menu system configuration.
|
||||
Supported options:
|
||||
- 'qb-menu': For QBCore's menu system.
|
||||
- 'ox_lib': For Ox Library's menu system.
|
||||
- 'esx_menu_default': For ESX's default menu system.
|
||||
]]
|
||||
|
||||
Config.Menu = 'qb-menu' -- 'qb-menu', 'ox_lib', 'esx_menu_default'
|
||||
|
||||
--[[
|
||||
Hotbar slots configuration.
|
||||
Specify the slots that will act as your hotbar.
|
||||
Use an array of numbers, where each number represents a slot.
|
||||
]]
|
||||
|
||||
Config.Hotbar = {
|
||||
1, 2, 3, 4, 5
|
||||
}
|
||||
|
||||
--[[
|
||||
Backpack opening/closing duration.
|
||||
Configure the time (in seconds) it takes to open or close the backpack.
|
||||
]]
|
||||
|
||||
Config.duration = {
|
||||
open = 1, -- Time in seconds to open the backpack.
|
||||
close = 1 -- Time in seconds to close the backpack.
|
||||
}
|
||||
|
||||
--[[
|
||||
Password length settings.
|
||||
Define the minimum and maximum length for passwords when required.
|
||||
]]
|
||||
|
||||
Config.PasswordLength = {
|
||||
min = 3, -- Minimum password length.
|
||||
max = 5 -- Maximum password length.
|
||||
}
|
||||
|
||||
--[[
|
||||
Animation configuration for different backpack actions.
|
||||
Each action includes:
|
||||
- Dict: The animation dictionary used for the action.
|
||||
- Anim: The specific animation name.
|
||||
- Flag: The animation flag (e.g., 49 = upper body only).
|
||||
]]
|
||||
|
||||
Config.Animation = {
|
||||
close = { -- Animation for closing the backpack.
|
||||
Dict = 'clothingshirt', -- Animation dictionary.
|
||||
Anim = 'try_shirt_positive_d', -- Animation name.
|
||||
Flag = 49 -- Animation flag.
|
||||
},
|
||||
|
||||
open = { -- Animation for opening the backpack.
|
||||
Dict = 'clothingshirt', -- Animation dictionary.
|
||||
Anim = 'try_shirt_positive_d', -- Animation name.
|
||||
Flag = 49 -- Animation flag.
|
||||
},
|
||||
|
||||
inBackpack = { -- Animation for interacting with items in the backpack.
|
||||
Dict = 'clothingshirt', -- Animation dictionary.
|
||||
Anim = 'try_shirt_positive_d' -- Animation name.
|
||||
},
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
Example to use a custom trigger
|
||||
```lua
|
||||
local data = {
|
||||
label = 'License Example', ---@param Label on inventory
|
||||
type = 'Weapon license', ---@param Licence type
|
||||
name = 'id_card', ---@param Item name
|
||||
price = 10, --- @param Price of licencie
|
||||
}
|
||||
TriggerEvent('qs-licenses:client:Target', data)
|
||||
```
|
||||
|
||||
You need go to qs-inventory\config\metadata.js
|
||||
|
||||
Modify id_card
|
||||
```js
|
||||
if (itemData.name == "id_card") {
|
||||
$(".item-info-title").html("<p>" + itemData.info.label + "</p>");
|
||||
$(".item-info-description").html(
|
||||
"</p><p><strong>First Name: </strong><span>" +
|
||||
itemData.info.firstname +
|
||||
"</span></p><p><strong>Last Name: </strong><span>" +
|
||||
itemData.info.lastname +
|
||||
"</span></p><p><strong>Birth Date: </strong><span>" +
|
||||
itemData.info.birthdate +
|
||||
"</span></p><p><strong>Gender: </strong><span>" +
|
||||
gender +
|
||||
"</span></p><p><strong>Type: </strong><span>" +
|
||||
itemData.info.type +
|
||||
"</span></p>"
|
||||
);
|
||||
};
|
||||
```
|
||||
@@ -0,0 +1,119 @@
|
||||
if Config.Framework ~= 'esx' then
|
||||
return
|
||||
end
|
||||
|
||||
--[[ Uncomment if use old version
|
||||
ESX = nil
|
||||
CreateThread(function()
|
||||
while ESX == nil do
|
||||
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
|
||||
Citizen.Wait(0)
|
||||
end
|
||||
end)
|
||||
]]
|
||||
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
|
||||
RegisterNetEvent('esx:playerLoaded')
|
||||
AddEventHandler('esx:playerLoaded', function(playerData)
|
||||
CreateBlips()
|
||||
end)
|
||||
|
||||
function GetJob()
|
||||
return ESX.GetPlayerData().job.name
|
||||
end
|
||||
|
||||
function SendTextMessage(msg, type)
|
||||
if type == 'inform' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'inform'
|
||||
})
|
||||
end
|
||||
if type == 'error' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'error'
|
||||
})
|
||||
end
|
||||
if type == 'success' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'success'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
|
||||
if lib.progressCircle({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation.animDict,
|
||||
clip = animation.anim,
|
||||
flag = animation?.flags
|
||||
},
|
||||
prop = prop
|
||||
}) then
|
||||
onFinish()
|
||||
else
|
||||
onCancel()
|
||||
end
|
||||
end
|
||||
|
||||
RegisterNetEvent('qs-licenses:ShowId', function(sourceId, character)
|
||||
local sourcePos = GetEntityCoords(GetPlayerPed(GetPlayerFromServerId(sourceId)), false)
|
||||
local pos = GetEntityCoords(PlayerPedId(), false)
|
||||
if sourceId == GetPlayerServerId(PlayerId()) then
|
||||
ShowCard()
|
||||
end
|
||||
local dist = GetDistanceBetweenCoords(pos.x, pos.y, pos.z, sourcePos.x, sourcePos.y, sourcePos.z, true)
|
||||
if ((dist > 0 and dist < 2.5) or sourceId == GetPlayerServerId(PlayerId())) then
|
||||
TriggerEvent('chat:addMessage', {
|
||||
template = '<div class="chat-message advert"><div class="chat-message-body"><strong style="font-size: 20px">{0}</strong><br>Firstname:</strong> {1} <br><strong>Lastname:</strong> {2} <br><strong>Date of birth:</strong> {3} <br><strong>Gender:</strong> {4}</div></div>',
|
||||
args = { character.type, character.firstname, character.lastname, character.birthdate, character.gender }
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
local texts = {}
|
||||
if GetResourceState('qs-textui') == 'started' then
|
||||
function DrawText3D(x, y, z, text, id, key)
|
||||
local _id = id
|
||||
if not texts[_id] then
|
||||
CreateThread(function()
|
||||
texts[_id] = 5
|
||||
while texts[_id] > 0 do
|
||||
texts[_id] = texts[_id] - 1
|
||||
Wait(0)
|
||||
end
|
||||
texts[_id] = nil
|
||||
exports['qs-textui']:DeleteDrawText3D(id)
|
||||
end)
|
||||
TriggerEvent('textui:DrawText3D', x, y, z, text, id, key)
|
||||
end
|
||||
texts[_id] = 5
|
||||
end
|
||||
else
|
||||
function DrawText3D(x, y, z, text)
|
||||
SetTextScale(0.35, 0.35)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry('STRING')
|
||||
SetTextCentre(true)
|
||||
AddTextComponentString(text)
|
||||
SetDrawOrigin(x, y, z, 0)
|
||||
DrawText(0.0, 0.0)
|
||||
local factor = text:len() / 370
|
||||
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
|
||||
ClearDrawOrigin()
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,109 @@
|
||||
if Config.Framework ~= 'qb' then
|
||||
return
|
||||
end
|
||||
|
||||
QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded')
|
||||
AddEventHandler('QBCore:Client:OnPlayerLoaded', function(playerData)
|
||||
CreateBlips()
|
||||
end)
|
||||
|
||||
function GetJob()
|
||||
return QBCore.Functions.GetPlayerData().job.name
|
||||
end
|
||||
|
||||
function SendTextMessage(msg, type)
|
||||
if type == 'inform' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'inform'
|
||||
})
|
||||
end
|
||||
if type == 'error' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'error'
|
||||
})
|
||||
end
|
||||
if type == 'success' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'success'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
|
||||
if lib.progressCircle({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation.animDict,
|
||||
clip = animation.anim,
|
||||
flag = animation?.flags
|
||||
},
|
||||
prop = prop
|
||||
}) then
|
||||
onFinish()
|
||||
else
|
||||
onCancel()
|
||||
end
|
||||
end
|
||||
|
||||
RegisterNetEvent('qs-licenses:ShowId', function(sourceId, character)
|
||||
local sourcePos = GetEntityCoords(GetPlayerPed(GetPlayerFromServerId(sourceId)), false)
|
||||
local pos = GetEntityCoords(PlayerPedId(), false)
|
||||
if sourceId == GetPlayerServerId(PlayerId()) then
|
||||
ShowCard()
|
||||
end
|
||||
local dist = GetDistanceBetweenCoords(pos.x, pos.y, pos.z, sourcePos.x, sourcePos.y, sourcePos.z, true)
|
||||
if ((dist > 0 and dist < 2.5) or sourceId == GetPlayerServerId(PlayerId())) then
|
||||
TriggerEvent('chat:addMessage', {
|
||||
template = '<div class="chat-message advert"><div class="chat-message-body"><strong style="font-size: 20px">{0}</strong><br>Firstname:</strong> {1} <br><strong>Lastname:</strong> {2} <br><strong>Date of birth:</strong> {3} <br><strong>Gender:</strong> {4}</div></div>',
|
||||
args = { character.type, character.firstname, character.lastname, character.birthdate, character.gender }
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
local texts = {}
|
||||
if GetResourceState('qs-textui') == 'started' then
|
||||
function DrawText3D(x, y, z, text, id, key)
|
||||
local _id = id
|
||||
if not texts[_id] then
|
||||
CreateThread(function()
|
||||
texts[_id] = 5
|
||||
while texts[_id] > 0 do
|
||||
texts[_id] = texts[_id] - 1
|
||||
Wait(0)
|
||||
end
|
||||
texts[_id] = nil
|
||||
exports['qs-textui']:DeleteDrawText3D(id)
|
||||
end)
|
||||
TriggerEvent('textui:DrawText3D', x, y, z, text, id, key)
|
||||
end
|
||||
texts[_id] = 5
|
||||
end
|
||||
else
|
||||
function DrawText3D(x, y, z, text)
|
||||
SetTextScale(0.35, 0.35)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry('STRING')
|
||||
SetTextCentre(true)
|
||||
AddTextComponentString(text)
|
||||
SetDrawOrigin(x, y, z, 0)
|
||||
DrawText(0.0, 0.0)
|
||||
local factor = text:len() / 370
|
||||
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
|
||||
ClearDrawOrigin()
|
||||
end
|
||||
end
|
||||
Binary file not shown.
@@ -0,0 +1,28 @@
|
||||
fx_version "adamant"
|
||||
|
||||
game "gta5"
|
||||
|
||||
lua54 'yes'
|
||||
|
||||
shared_scripts {
|
||||
'@ox_lib/init.lua',
|
||||
'shared/*.lua'
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'client/custom/*.lua',
|
||||
'client/main.lua'
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
'@mysql-async/lib/MySQL.lua',
|
||||
'server/custom/*.lua',
|
||||
'server/main.lua',
|
||||
}
|
||||
|
||||
escrow_ignore {
|
||||
'client/custom/*.lua',
|
||||
'server/custom/*.lua',
|
||||
'shared/*.lua'
|
||||
}
|
||||
dependency '/assetpacks'
|
||||
@@ -0,0 +1,53 @@
|
||||
if Config.Framework ~= "esx" then
|
||||
return
|
||||
end
|
||||
|
||||
local version = GetResourceMetadata('es_extended', 'version', 0)
|
||||
|
||||
if version == '1.1.0' or version == '1.2.0' or version == 'legacy' then
|
||||
ESX = nil
|
||||
TriggerEvent('esx:getSharedObject', function(obj) ESX = obj end)
|
||||
else
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
end
|
||||
|
||||
function GetPlayerFromIdFramework(player)
|
||||
return ESX.GetPlayerFromId(player)
|
||||
end
|
||||
|
||||
function GetCharacterData(source)
|
||||
local xPlayer = GetPlayerFromIdFramework(source)
|
||||
local firstName, lastName, sex, dateofbirth
|
||||
if xPlayer.get then
|
||||
firstName = xPlayer.get("firstName")
|
||||
lastName = xPlayer.get("lastName")
|
||||
if xPlayer.get("sex") == 'm' then
|
||||
sex = Lang('LICENSES_MAN_LABEL')
|
||||
elseif xPlayer.get("sex") == 'f' then
|
||||
sex = Lang('LICENSES_WOMEN_LABEL')
|
||||
end
|
||||
dateofbirth = xPlayer.get("dateofbirth") or "01/01/2000"
|
||||
else
|
||||
local name = MySQL.Sync.fetchAll("SELECT `firstname`, `lastname`, `dateofbirth`, `sex` FROM `users` WHERE `identifier`=@identifier", {["@identifier"] = ESX.GetIdentifier(source)})
|
||||
firstName = name[1]?.firstname
|
||||
lastName = name[1]?.lastname
|
||||
if name[1]?.sex == 'm' then
|
||||
sex = Lang('LICENSES_MAN_LABEL')
|
||||
elseif name[1]?.sex == 'f' then
|
||||
sex = Lang('LICENSES_WOMEN_LABEL')
|
||||
end
|
||||
dateofbirth = name[1]?.dateofbirth
|
||||
end
|
||||
|
||||
return firstName, lastName, sex, dateofbirth
|
||||
end
|
||||
|
||||
function GetBankMoney(source)
|
||||
local xPlayer = GetPlayerFromIdFramework(source)
|
||||
return xPlayer.getAccount('bank').money
|
||||
end
|
||||
|
||||
function RemoveBankMoney(source, price)
|
||||
local xPlayer = GetPlayerFromIdFramework(source)
|
||||
xPlayer.removeAccountMoney('bank', price)
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
if Config.Framework ~= 'qb' then
|
||||
return
|
||||
end
|
||||
|
||||
QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
function GetPlayerFromIdFramework(player)
|
||||
local Player = QBCore.Functions.GetPlayer(player)
|
||||
if Player then
|
||||
Player.citizenid = Player?.PlayerData?.citizenid
|
||||
Player.identifier = Player?.PlayerData?.citizenid
|
||||
Player.source = Player?.PlayerData?.source
|
||||
end
|
||||
return Player
|
||||
end
|
||||
|
||||
function GetCharacterData(source)
|
||||
local player = GetPlayerFromIdFramework(source)?.PlayerData?.charinfo
|
||||
local sex
|
||||
if player.gender == 0 then
|
||||
sex = Lang('LICENSES_MAN_LABEL')
|
||||
elseif player.gender == 1 then
|
||||
sex = Lang('LICENSES_WOMEN_LABEL')
|
||||
end
|
||||
return player.firstname, player.lastname, sex, player.birthdate
|
||||
end
|
||||
|
||||
function GetBankMoney(source)
|
||||
local xPlayer = GetPlayerFromIdFramework(source)
|
||||
return xPlayer?.PlayerData?.money['bank']
|
||||
end
|
||||
|
||||
function RemoveBankMoney(source, price)
|
||||
local xPlayer = GetPlayerFromIdFramework(source)
|
||||
xPlayer.Functions.RemoveMoney('bank', price)
|
||||
end
|
||||
Binary file not shown.
@@ -0,0 +1,75 @@
|
||||
Config = Config or {}
|
||||
|
||||
local esxHas = GetResourceState('es_extended') == 'started'
|
||||
local qbHas = GetResourceState('qb-core') == 'started'
|
||||
local qbxHas = GetResourceState('qbx_core') == 'started'
|
||||
|
||||
Config.Framework = esxHas and 'esx' or qbHas and 'qb' or qbxHas and 'qb' or 'esx'
|
||||
|
||||
-- Marker configuration for the shop locations
|
||||
Config.Marker = {
|
||||
type = 2, -- Marker type (refer to GTA marker types)
|
||||
scale = {x = 0.2, y = 0.2, z = 0.1}, -- Marker scale
|
||||
colour = {r = 71, g = 181, b = 255, a = 120}, -- Marker color with transparency (RGBA)
|
||||
movement = 1 -- Marker animation (0 = no movement, 1 = with movement)
|
||||
}
|
||||
|
||||
-- Shop configuration
|
||||
Config.Shops = {
|
||||
[1] = {
|
||||
name = 'id_card', -- Unique identifier for the item
|
||||
text = "[E] - Identity License", -- Interaction text
|
||||
label = 'ID', -- Item label
|
||||
type = "Document", -- Item type
|
||||
progbar = "Purchasing license...", -- Progress bar text
|
||||
price = 150, -- Item price
|
||||
isjob = false, -- Required job to access this shop (false = no job required)
|
||||
timer = 2500, -- Interaction duration (milliseconds)
|
||||
location = vec3(-545.08, -204.13, 38.22), -- Shop location (vector3 format)
|
||||
blip = { -- Blip configuration for the map
|
||||
enable = true, -- Enable or disable the blip
|
||||
name = 'Identity License', -- Blip name
|
||||
sprite = 409, -- Blip sprite (icon)
|
||||
color = 0, -- Blip color
|
||||
scale = 0.7 -- Blip size
|
||||
},
|
||||
},
|
||||
|
||||
[2] = {
|
||||
name = 'weaponlicense', -- Unique identifier for the item
|
||||
isjob = false, -- Required job to access this shop (false = no job required)
|
||||
text = "[E] - Weapons License", -- Interaction text
|
||||
label = 'License', -- Item label
|
||||
type = "Weapons License", -- Item type
|
||||
price = 10, -- Item price
|
||||
progbar = "Purchasing license...", -- Progress bar text
|
||||
timer = 2500, -- Interaction duration (milliseconds)
|
||||
location = vec3(14.01, -1106.11, 29.8), -- Shop location (vector3 format)
|
||||
blip = { -- Blip configuration for the map
|
||||
enable = false, -- Enable or disable the blip
|
||||
name = 'Weapons License', -- Blip name
|
||||
sprite = 89, -- Blip sprite (icon)
|
||||
color = 1, -- Blip color
|
||||
scale = 0.5 -- Blip size
|
||||
},
|
||||
},
|
||||
|
||||
[3] = {
|
||||
name = 'driver_license', -- Unique identifier for the item
|
||||
isjob = false, -- Required job to access this shop (false = no job required)
|
||||
text = "[E] - Driving License", -- Interaction text
|
||||
label = 'Driving License', -- Item label
|
||||
type = "License", -- Item type
|
||||
price = 10, -- Item price
|
||||
progbar = "Purchasing license...", -- Progress bar text
|
||||
timer = 2500, -- Interaction duration (milliseconds)
|
||||
location = vec3(239.78, -1380.27, 33.74), -- Shop location (vector3 format)
|
||||
blip = { -- Blip configuration for the map
|
||||
enable = true, -- Enable or disable the blip
|
||||
name = 'Driving License', -- Blip name
|
||||
sprite = 67, -- Blip sprite (icon)
|
||||
color = 3, -- Blip color
|
||||
scale = 0.6 -- Blip size
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
Config = Config or {}
|
||||
|
||||
Config.Language = 'en'
|
||||
|
||||
Config.Languages = {
|
||||
['en'] = {
|
||||
['LICENSES_PROGRESS'] = 'Getting licensed...',
|
||||
['LICENSES_SUCCESS'] = 'Thanks for waiting, here is your new',
|
||||
['LICENSES_NO_MONEY'] = "You don't have enough money",
|
||||
['LICENSES_WOMEN_LABEL'] = 'Female',
|
||||
['LICENSES_MAN_LABEL'] = 'Man',
|
||||
|
||||
['LICENSES_DIALOG_HEADER'] = 'Do you want to buy this license?',
|
||||
['LICENSES_DIALOG_CONTENT'] = 'This license will cost you ${price} and will take {timer} seconds to complete.',
|
||||
},
|
||||
|
||||
['es'] = {
|
||||
['LICENSES_PROGRESS'] = 'Obteniendo licencia...',
|
||||
['LICENSES_SUCCESS'] = 'Gracias por esperar, aquí tienes tu nueva',
|
||||
['LICENSES_NO_MONEY'] = 'No tienes dinero suficiente',
|
||||
['LICENSES_WOMEN_LABEL'] = 'Mujer',
|
||||
['LICENSES_MAN_LABEL'] = 'Hombre',
|
||||
|
||||
['LICENSES_DIALOG_HEADER'] = '¿Quieres comprar esta licencia?',
|
||||
['LICENSES_DIALOG_CONTENT'] = 'Esta licencia costará ${price} y tardará {timer} segundos en completarse.',
|
||||
},
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,16 @@
|
||||
Config = {}
|
||||
|
||||
Config.WeapDraw = {
|
||||
variants = { 130, 122, 3, 6, 8 },
|
||||
weapons = {
|
||||
'WEAPON_PISTOL',
|
||||
'WEAPON_PISTOL_MK2',
|
||||
'WEAPON_COMBATPISTOL',
|
||||
'WEAPON_APPISTOL',
|
||||
'WEAPON_PISTOL50',
|
||||
'WEAPON_REVOLVER',
|
||||
'WEAPON_SNSPISTOL',
|
||||
'WEAPON_HEAVYPISTOL',
|
||||
'WEAPON_VINTAGEPISTOL'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
fx_version 'cerulean'
|
||||
|
||||
game 'gta5'
|
||||
|
||||
lua54 'yes'
|
||||
|
||||
shared_scripts {
|
||||
'config.lua'
|
||||
}
|
||||
|
||||
client_script {
|
||||
'client.lua'
|
||||
}
|
||||
|
||||
escrow_ignore {
|
||||
'config.lua'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
'/server:4752', -- ⚠️PLEASE READ⚠️ This requires at least server build 4700 or higher
|
||||
'qs-inventory' -- Required.
|
||||
}
|
||||
|
||||
dependency '/assetpacks'
|
||||
Binary file not shown.
+23
@@ -0,0 +1,23 @@
|
||||
if Config.Framework ~= 'esx' then
|
||||
return
|
||||
end
|
||||
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
|
||||
RegisterNetEvent('esx:playerLoaded')
|
||||
AddEventHandler('esx:playerLoaded', function()
|
||||
Wait(3500)
|
||||
ESX.PlayerLoaded = true
|
||||
end)
|
||||
|
||||
function IsPlayerLoaded()
|
||||
return ESX.PlayerLoaded
|
||||
end
|
||||
|
||||
function GetPlayerData()
|
||||
return ESX.GetPlayerData()
|
||||
end
|
||||
|
||||
function GetInventory()
|
||||
return GetPlayerData().inventory
|
||||
end
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
if Config.Framework ~= 'qb' then
|
||||
return
|
||||
end
|
||||
|
||||
QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded')
|
||||
AddEventHandler('QBCore:Client:OnPlayerLoaded', function()
|
||||
Wait(3500)
|
||||
LocalPlayer.state:set('isLoggedIn', true, false)
|
||||
end)
|
||||
|
||||
function IsPlayerLoaded()
|
||||
return LocalPlayer.state['isLoggedIn']
|
||||
end
|
||||
|
||||
function GetPlayerData()
|
||||
return QBCore.Functions.GetPlayerData()
|
||||
end
|
||||
|
||||
function GetInventory()
|
||||
return GetPlayerData().items
|
||||
end
|
||||
Binary file not shown.
@@ -0,0 +1,242 @@
|
||||
--[[
|
||||
Welcome to the qb-weaponsonback configuration!
|
||||
To start configuring your new asset, please read carefully
|
||||
each step in the documentation that we will attach at the end of this message.
|
||||
|
||||
Each important part of the configuration will be highlighted with a box.
|
||||
like this one you are reading now, where I will explain step by step each
|
||||
configuration available within this file.
|
||||
|
||||
This is not all, most of the settings, you are free to modify it
|
||||
as you wish and adapt it to your framework in the most comfortable way possible.
|
||||
The configurable files you will find all inside client/custom/*
|
||||
or inside server/custom/*.
|
||||
|
||||
Direct link to the resource documentation, read it before you start:
|
||||
https://docs.quasar-store.com/information/welcome
|
||||
]]
|
||||
|
||||
|
||||
Config = {}
|
||||
|
||||
--[[
|
||||
The current system will detect if you use qb-core or es_extended,
|
||||
but if you rename it, you can remove the value from Config.Framework
|
||||
and add it yourself after you have modified the framework files inside
|
||||
this script.
|
||||
|
||||
Please keep in mind that this code is automatic, do not edit if
|
||||
you do not know how to do it.
|
||||
]]
|
||||
|
||||
local esxHas = GetResourceState('es_extended') == 'started'
|
||||
local qbHas = GetResourceState('qb-core') == 'started'
|
||||
|
||||
Config.Framework = esxHas and 'esx' or qbxHas and 'qbx' or qbHas and 'qb' or 'standalone'
|
||||
|
||||
--[[
|
||||
Weapon configuration to be shown on the back, torso
|
||||
or where you configure it on your character's coord.
|
||||
|
||||
Please note that you must have knowledge
|
||||
basics and do everything by trial and error.
|
||||
]]
|
||||
|
||||
Config.WeaponPositions = {
|
||||
['weapon_carbinerifle'] = {
|
||||
model = 'w_ar_carbinerifle',
|
||||
hash = -2084633992,
|
||||
bone = 10706,
|
||||
x = 0.0,
|
||||
y = 0.17,
|
||||
z = -0.25,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 75.0,
|
||||
z_rotation = 180.0
|
||||
},
|
||||
['weapon_carbinerifle_mk2'] = {
|
||||
model = 'w_ar_carbineriflemk2',
|
||||
hash = GetHashKey('WEAPON_CARBINERIFLE_MK2'),
|
||||
bone = 24816,
|
||||
x = 0.2275,
|
||||
y = -0.17,
|
||||
z = -0.110,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 20.0,
|
||||
z_rotation = 1.0
|
||||
},
|
||||
['weapon_assaultrifle'] = {
|
||||
model = 'w_ar_assaultrifle',
|
||||
hash = -1074790547,
|
||||
bone = 24816,
|
||||
x = 0.2275,
|
||||
y = -0.16,
|
||||
z = 0.110,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = -15.0,
|
||||
z_rotation = 2.0
|
||||
},
|
||||
['weapon_tacticalrifle'] = {
|
||||
model = 'w_ar_tacticalrifle',
|
||||
hash = `weapon_tacticalrifle`,
|
||||
bone = 24816,
|
||||
x = 0.2275,
|
||||
y = -0.16,
|
||||
z = 0.110,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = -15.0,
|
||||
z_rotation = 2.0
|
||||
},
|
||||
['weapon_specialcarbine'] = {
|
||||
model = 'w_ar_specialcarbine',
|
||||
hash = -1063057011,
|
||||
bone = 24816,
|
||||
x = 0.2275,
|
||||
y = -0.16,
|
||||
z = 0.030,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 5.0,
|
||||
z_rotation = 1.0
|
||||
},
|
||||
['weapon_bullpuprifle'] = {
|
||||
model = 'w_ar_bullpuprifle',
|
||||
hash = 2132975508,
|
||||
bone = 24816,
|
||||
x = 0.2275,
|
||||
y = -0.16,
|
||||
z = 0.055,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 0.0,
|
||||
z_rotation = 1.0
|
||||
},
|
||||
['weapon_advancedrifle'] = {
|
||||
model = 'w_ar_advancedrifle',
|
||||
hash = -1357824103,
|
||||
bone = 24816,
|
||||
x = 0.2275,
|
||||
y = -0.16,
|
||||
z = -0.055,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 35.0,
|
||||
z_rotation = 1.0
|
||||
},
|
||||
['weapon_appistol'] = {
|
||||
model = 'w_pi_appistol',
|
||||
hash = 584646201,
|
||||
bone = 24816,
|
||||
x = -0.140,
|
||||
y = 0.05,
|
||||
z = -0.210,
|
||||
x_rotation = 90.0,
|
||||
y_rotation = 90.0,
|
||||
z_rotation = 50.0
|
||||
},
|
||||
['weapon_microsmg'] = {
|
||||
model = 'w_sb_microsmg',
|
||||
hash = 324215364,
|
||||
bone = 24816,
|
||||
x = -0.200,
|
||||
y = 0.05,
|
||||
z = -0.210,
|
||||
x_rotation = 90.0,
|
||||
y_rotation = 110.0,
|
||||
z_rotation = 50.0
|
||||
},
|
||||
['weapon_assaultsmg'] = {
|
||||
model = 'w_sb_assaultsmg',
|
||||
hash = -270015777,
|
||||
bone = 10706,
|
||||
x = 0.0,
|
||||
y = 0.17,
|
||||
z = -0.35,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 55.0,
|
||||
z_rotation = 180.0
|
||||
},
|
||||
['weapon_smg'] = {
|
||||
model = 'w_sb_smg',
|
||||
hash = 736523883,
|
||||
bone = 24816,
|
||||
x = 0.1275,
|
||||
y = -0.16,
|
||||
z = -0.055,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 35.0,
|
||||
z_rotation = 1.0
|
||||
},
|
||||
['weapon_smg_mk2'] = {
|
||||
model = 'w_sb_smgmk2',
|
||||
hash = GetHashKey('WEAPON_SMG_MK2'),
|
||||
bone = 24816,
|
||||
x = -0.140,
|
||||
y = 0.05,
|
||||
z = 0.210,
|
||||
x_rotation = 90.0,
|
||||
y_rotation = 120.0,
|
||||
z_rotation = 50.0
|
||||
},
|
||||
['weapon_sniperrifle'] = {
|
||||
model = 'w_sr_sniperrifle',
|
||||
hash = 100416529,
|
||||
bone = 24816,
|
||||
x = 0.005,
|
||||
y = -0.16,
|
||||
z = 0.0,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = -15.0,
|
||||
z_rotation = 2.0
|
||||
},
|
||||
['weapon_assaultshotgun'] = {
|
||||
model = 'w_sg_assaultshotgun',
|
||||
hash = -494615257,
|
||||
bone = 24816,
|
||||
x = 0.2275,
|
||||
y = -0.16,
|
||||
z = 0.015,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 160.0,
|
||||
z_rotation = 1.0
|
||||
},
|
||||
['weapon_pumpshotgun'] = {
|
||||
model = 'w_sg_pumpshotgun',
|
||||
hash = 487013001,
|
||||
bone = 24816,
|
||||
x = 0.1275,
|
||||
y = -0.16,
|
||||
z = 0.030,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 25.0,
|
||||
z_rotation = 1.0
|
||||
},
|
||||
['weapon_musket'] = {
|
||||
model = 'w_ar_musket',
|
||||
hash = -1466123874,
|
||||
bone = 24816,
|
||||
x = 0.0,
|
||||
y = -0.16,
|
||||
z = 0.0,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 15.0,
|
||||
z_rotation = 2.0
|
||||
},
|
||||
['weapon_heavyshotgun'] = {
|
||||
model = 'w_sg_heavyshotgun',
|
||||
hash = GetHashKey('WEAPON_HEAVYSHOTGUN'),
|
||||
bone = 10706,
|
||||
x = 0.100,
|
||||
y = 0.17,
|
||||
z = -0.20,
|
||||
x_rotation = 0.0,
|
||||
y_rotation = 60.0,
|
||||
z_rotation = 190.0
|
||||
},
|
||||
-- Add more weapons as needed
|
||||
}
|
||||
|
||||
--[[
|
||||
Debug mode, this mode is to receive constant prints and information
|
||||
from the system, we do not recommend enabling it if you are not a
|
||||
developer, but it will help to understand how the resource works.
|
||||
]]
|
||||
|
||||
Config.Debug = false
|
||||
@@ -0,0 +1,32 @@
|
||||
fx_version 'bodacious'
|
||||
|
||||
game 'gta5'
|
||||
|
||||
lua54 'yes'
|
||||
|
||||
version '2.0.2'
|
||||
|
||||
shared_scripts {
|
||||
'config.lua',
|
||||
'utils.lua'
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'client/custom/framework/*.lua',
|
||||
'client/*.lua'
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
'server/*.lua'
|
||||
}
|
||||
|
||||
escrow_ignore {
|
||||
'config.lua',
|
||||
'client/custom/framework/*.lua'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
'qs-inventory' -- Required
|
||||
}
|
||||
|
||||
dependency '/assetpacks'
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,69 @@
|
||||
UPDATE `users` SET `inventory` = '[]' WHERE identifier IS NOT NULL;
|
||||
ALTER TABLE `users` ADD IF NOT EXISTS `metadata` mediumtext DEFAULT NULL;
|
||||
ALTER TABLE `users` ADD IF NOT EXISTS `inventory_skill` TEXT NULL DEFAULT NULL;
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_glovebox`;
|
||||
CREATE TABLE IF NOT EXISTS `inventory_glovebox` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`plate` varchar(255) DEFAULT NULL,
|
||||
`items` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
PRIMARY KEY (`plate`),
|
||||
KEY `id` (`id`)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_stash`;
|
||||
CREATE TABLE IF NOT EXISTS `inventory_stash` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`stash` varchar(255) DEFAULT NULL,
|
||||
`items` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
PRIMARY KEY (`stash`),
|
||||
KEY `id` (`id`)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_trunk`;
|
||||
CREATE TABLE IF NOT EXISTS `inventory_trunk` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`plate` varchar(255) DEFAULT NULL,
|
||||
`items` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
PRIMARY KEY (`plate`),
|
||||
KEY `id` (`id`)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_metadata`;
|
||||
CREATE TABLE IF NOT EXISTS `inventory_metadata` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`identifier` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
|
||||
`data` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) COLLATE = 'utf8mb4_unicode_ci' ENGINE = InnoDB;
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_clothes`;
|
||||
CREATE TABLE IF NOT EXISTS `inventory_clothes` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`identifier` VARCHAR(50) NOT NULL DEFAULT '' COLLATE 'utf8mb4_general_ci',
|
||||
`items` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`identifier`) USING BTREE,
|
||||
INDEX `id` (`id`) USING BTREE
|
||||
) COLLATE = 'utf8mb4_general_ci' ENGINE = InnoDB AUTO_INCREMENT = 6;
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_quests`;
|
||||
CREATE TABLE `inventory_quests` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(50) NOT NULL DEFAULT '0' COLLATE 'utf8mb3_general_ci',
|
||||
`owner` VARCHAR(80) NOT NULL DEFAULT '0' COLLATE 'utf8mb3_general_ci',
|
||||
`title` VARCHAR(80) NOT NULL DEFAULT '0' COLLATE 'utf8mb3_general_ci',
|
||||
`description` MEDIUMTEXT NOT NULL COLLATE 'utf8mb3_general_ci',
|
||||
`reward` INT(11) NOT NULL DEFAULT '0',
|
||||
`requiredLevel` INT(11) NOT NULL DEFAULT '0',
|
||||
`default` TINYINT(1) NOT NULL DEFAULT '0',
|
||||
`status` VARCHAR(50) NOT NULL DEFAULT 'active' COLLATE 'utf8mb3_general_ci',
|
||||
`progress` INT(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `name_owner` (`name`, `owner`) USING BTREE
|
||||
)
|
||||
COLLATE='utf8mb3_general_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1
|
||||
;
|
||||
|
||||
ALTER TABLE users ADD COLUMN IF NOT EXISTS unlocked_skills LONGTEXT NULL;
|
||||
@@ -0,0 +1,68 @@
|
||||
ALTER TABLE `players` ADD IF NOT EXISTS `inventory_skill` TEXT NULL DEFAULT NULL;
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_glovebox`;
|
||||
CREATE TABLE IF NOT EXISTS `inventory_glovebox` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`plate` varchar(255) DEFAULT NULL,
|
||||
`items` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
PRIMARY KEY (`plate`),
|
||||
KEY `id` (`id`)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_stash`;
|
||||
CREATE TABLE IF NOT EXISTS `inventory_stash` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`stash` varchar(255) DEFAULT NULL,
|
||||
`items` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
PRIMARY KEY (`stash`),
|
||||
KEY `id` (`id`)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_trunk`;
|
||||
CREATE TABLE IF NOT EXISTS `inventory_trunk` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`plate` varchar(255) DEFAULT NULL,
|
||||
`items` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
PRIMARY KEY (`plate`),
|
||||
KEY `id` (`id`)
|
||||
) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = latin1;
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_metadata`;
|
||||
CREATE TABLE IF NOT EXISTS `inventory_metadata` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`identifier` VARCHAR(50) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
|
||||
`data` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) COLLATE = 'utf8mb4_unicode_ci' ENGINE = InnoDB;
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_clothes`;
|
||||
CREATE TABLE IF NOT EXISTS `inventory_clothes` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`identifier` VARCHAR(50) NOT NULL DEFAULT '' COLLATE 'utf8mb4_general_ci',
|
||||
`items` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`identifier`) USING BTREE,
|
||||
INDEX `id` (`id`) USING BTREE
|
||||
) COLLATE = 'utf8mb4_general_ci' ENGINE = InnoDB AUTO_INCREMENT = 6;
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `inventory_quests`;
|
||||
CREATE TABLE `inventory_quests` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(50) NOT NULL DEFAULT '0' COLLATE 'utf8mb3_general_ci',
|
||||
`owner` VARCHAR(80) NOT NULL DEFAULT '0' COLLATE 'utf8mb3_general_ci',
|
||||
`title` VARCHAR(80) NOT NULL DEFAULT '0' COLLATE 'utf8mb3_general_ci',
|
||||
`description` MEDIUMTEXT NOT NULL COLLATE 'utf8mb3_general_ci',
|
||||
`reward` INT(11) NOT NULL DEFAULT '0',
|
||||
`requiredLevel` INT(11) NOT NULL DEFAULT '0',
|
||||
`default` TINYINT(1) NOT NULL DEFAULT '0',
|
||||
`status` VARCHAR(50) NOT NULL DEFAULT 'active' COLLATE 'utf8mb3_general_ci',
|
||||
`progress` INT(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `name_owner` (`name`, `owner`) USING BTREE
|
||||
)
|
||||
COLLATE='utf8mb3_general_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1
|
||||
;
|
||||
|
||||
ALTER TABLE players ADD COLUMN IF NOT EXISTS unlocked_skills LONGTEXT NULL;
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,61 @@
|
||||
if not Config.UseTarget then
|
||||
return
|
||||
end
|
||||
|
||||
local target_name = GetResourceState('ox_target'):find('started') and 'qtarget' or 'qb-target'
|
||||
|
||||
function InitializeTargetPed(k, v, ped)
|
||||
if ped then
|
||||
exports[target_name]:AddTargetEntity(ped, {
|
||||
options = {
|
||||
{
|
||||
label = v.name .. ' | ' .. v.label,
|
||||
icon = 'fa-solid fa-basket-shopping',
|
||||
action = function()
|
||||
openShop(v)
|
||||
end
|
||||
}
|
||||
},
|
||||
distance = 2.0
|
||||
})
|
||||
else
|
||||
for a, x in pairs(v.coords) do
|
||||
exports[target_name]:AddCircleZone(v.name, vector3(x.coords.x, x.coords.y, x.coords.z), 0.5, {
|
||||
name = v.name,
|
||||
debugPoly = Config.ZoneDebug,
|
||||
useZ = true
|
||||
}, {
|
||||
options = {
|
||||
{
|
||||
label = v.name .. ' | ' .. v.label,
|
||||
icon = 'fa-solid fa-basket-shopping',
|
||||
action = function()
|
||||
openShop(v)
|
||||
end
|
||||
}
|
||||
},
|
||||
distance = 2.0
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
CreateThread(function()
|
||||
for k, v in pairs(Config.Stashes) do
|
||||
exports[target_name]:AddCircleZone(v.label .. k, vector3(v.coords.x, v.coords.y, v.coords.z), 0.5, {
|
||||
name = v.label .. k,
|
||||
debugPoly = false,
|
||||
useZ = true
|
||||
}, {
|
||||
options = {
|
||||
{
|
||||
label = v.targetLabel,
|
||||
icon = 'fas fa-shopping-cart',
|
||||
event = 'shops:openStash',
|
||||
stash = v
|
||||
}
|
||||
},
|
||||
distance = 2.0
|
||||
})
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,173 @@
|
||||
local success, result = pcall(lib.load, ('custom.%s.client'):format(Config.Framework))
|
||||
|
||||
if not success then
|
||||
error(result, 0)
|
||||
end
|
||||
|
||||
_G.cfr = result --[[@as ClientFramework]]
|
||||
|
||||
---@param msg string
|
||||
---@param type 'info' | 'error' | 'success'
|
||||
function Notification(msg, type)
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
if type == 'info' then
|
||||
exports['qs-interface']:AddNotify(msg, 'Inform', 2500, 'fas fa-file')
|
||||
elseif type == 'error' then
|
||||
exports['qs-interface']:AddNotify(msg, 'Error', 2500, 'fas fa-bug')
|
||||
elseif type == 'success' then
|
||||
exports['qs-interface']:AddNotify(msg, 'Success', 2500, 'fas fa-thumbs-up')
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if type == 'info' then
|
||||
lib.notify({
|
||||
title = 'Shops',
|
||||
description = msg,
|
||||
type = 'info'
|
||||
})
|
||||
elseif type == 'error' then
|
||||
lib.notify({
|
||||
title = 'Shops',
|
||||
description = msg,
|
||||
type = 'error'
|
||||
})
|
||||
elseif type == 'success' then
|
||||
lib.notify({
|
||||
title = 'Shops',
|
||||
description = msg,
|
||||
type = 'success'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
RegisterNetEvent('shops:notification', Notification)
|
||||
|
||||
print('^2[INFO]^7 Successfully loaded the framework.', Config.Framework)
|
||||
|
||||
local texts = {}
|
||||
if GetResourceState('qs-textui') == 'started' then
|
||||
function DrawText3D(x, y, z, text, id, key)
|
||||
local _id = id
|
||||
if not texts[_id] then
|
||||
CreateThread(function()
|
||||
texts[_id] = 5
|
||||
while texts[_id] > 0 do
|
||||
texts[_id] = texts[_id] - 1
|
||||
Wait(0)
|
||||
end
|
||||
texts[_id] = nil
|
||||
exports['qs-textui']:DeleteDrawText3D(id)
|
||||
Debug('Deleted text', id)
|
||||
end)
|
||||
TriggerEvent('textui:DrawText3D', x, y, z, text, id, key)
|
||||
end
|
||||
texts[_id] = 5
|
||||
end
|
||||
else
|
||||
function DrawText3D(x, y, z, text)
|
||||
SetTextScale(0.35, 0.35)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry('STRING')
|
||||
SetTextCentre(true)
|
||||
AddTextComponentString(text)
|
||||
SetDrawOrigin(x, y, z, 0)
|
||||
DrawText(0.0, 0.0)
|
||||
local factor = text:len() / 370
|
||||
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
|
||||
ClearDrawOrigin()
|
||||
end
|
||||
end
|
||||
|
||||
function DrawGenericText(text)
|
||||
SetTextColour(186, 186, 186, 255)
|
||||
SetTextFont(4)
|
||||
SetTextScale(0.5, 0.5)
|
||||
SetTextWrap(0.0, 1.0)
|
||||
SetTextCentre(false)
|
||||
SetTextDropshadow(0, 0, 0, 0, 255)
|
||||
SetTextEdge(1, 0, 0, 0, 205)
|
||||
SetTextEntry('STRING')
|
||||
AddTextComponentString(text)
|
||||
DrawText(0.40, 0.00)
|
||||
end
|
||||
|
||||
local _world3dToSreen2d, _getGameplayCamCoords, _getGameplayCamFov = World3dToScreen2d, GetGameplayCamCoords, GetGameplayCamFov
|
||||
DrawText3DX = function(text, coords)
|
||||
local _coords = vec3(coords.x, coords.y, coords.z)
|
||||
local onScreen, x, y = _world3dToSreen2d(_coords.x, _coords.y, _coords.z)
|
||||
local camCoords = _getGameplayCamCoords()
|
||||
local dist = #(camCoords - _coords)
|
||||
|
||||
local size = 2
|
||||
local scale = (size / dist) * 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)
|
||||
|
||||
AddTextComponentString(text)
|
||||
DrawText(x, y)
|
||||
end
|
||||
end
|
||||
|
||||
function ProgressBar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
|
||||
if disableControls then
|
||||
disableControls.move = disableControls.disableMovement
|
||||
disableControls.car = disableControls.disableCarMovement
|
||||
disableControls.mouse = disableControls.disableMouse
|
||||
disableControls.combat = disableControls.disableCombat
|
||||
end
|
||||
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
local success = exports['qs-interface']:ProgressBar({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation?.animDict,
|
||||
clip = animation?.anim,
|
||||
flag = animation?.flags
|
||||
},
|
||||
prop = prop
|
||||
})
|
||||
if success then
|
||||
onFinish()
|
||||
else
|
||||
onCancel()
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if lib.progressCircle({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation?.animDict,
|
||||
clip = animation?.anim,
|
||||
flag = animation?.flags
|
||||
},
|
||||
prop = prop
|
||||
}) then
|
||||
onFinish()
|
||||
else
|
||||
onCancel()
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,38 @@
|
||||
local framework = {}
|
||||
local ESX = exports['es_extended']:getSharedObject()
|
||||
|
||||
RegisterNetEvent('esx:playerLoaded', function(playerData)
|
||||
PlayerData = playerData
|
||||
Debug('player loaded', playerData)
|
||||
end)
|
||||
|
||||
function framework:getPlayerData()
|
||||
return ESX.GetPlayerData()
|
||||
end
|
||||
|
||||
CreateThread(function()
|
||||
PlayerData = framework:getPlayerData()
|
||||
Debug('init playerData')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:setJob', function(jobData)
|
||||
PlayerData.job = jobData
|
||||
end)
|
||||
|
||||
function framework:getIdentifier()
|
||||
return PlayerData?.identifier or 'none'
|
||||
end
|
||||
|
||||
function framework:getJobName()
|
||||
return PlayerData?.job?.name or 'unemployed'
|
||||
end
|
||||
|
||||
function framework:getJobGrade()
|
||||
return PlayerData?.job?.grade or 0
|
||||
end
|
||||
|
||||
function framework:getPlayers()
|
||||
return ESX.Game.GetPlayers()
|
||||
end
|
||||
|
||||
return framework
|
||||
@@ -0,0 +1,129 @@
|
||||
--[[
|
||||
Hi dear customer or developer, here you can fully configure your server's
|
||||
framework or you could even duplicate this file to create your own framework.
|
||||
|
||||
If you do not have much experience, we recommend you download the base version
|
||||
of the framework that you use in its latest version and it will work perfectly.
|
||||
]]
|
||||
|
||||
local framework = {}
|
||||
local ESX = exports['es_extended']:getSharedObject()
|
||||
|
||||
function framework:registerUsableItem(item, cb)
|
||||
ESX.RegisterUsableItem(item, cb)
|
||||
end
|
||||
|
||||
function framework:getPlayerFromId(source)
|
||||
return ESX.GetPlayerFromId(source)
|
||||
end
|
||||
|
||||
function framework:getSourceFromIdentifier(identifier)
|
||||
return ESX.GetPlayerFromIdentifier(identifier).source
|
||||
end
|
||||
|
||||
function framework:getIdentifier(source)
|
||||
if source == 0 then return 'automated' end
|
||||
local player = self:getPlayerFromId(source)
|
||||
return player?.identifier
|
||||
end
|
||||
|
||||
function framework:getAccountMoney(source, account)
|
||||
local player = self:getPlayerFromId(source)
|
||||
return player.getAccount(account).money
|
||||
end
|
||||
|
||||
function framework:removeAccountMoney(source, account, amount)
|
||||
local player = self:getPlayerFromId(source)
|
||||
if self:getAccountMoney(source, account) < amount then
|
||||
return false
|
||||
end
|
||||
player.removeAccountMoney(account, amount)
|
||||
return true
|
||||
end
|
||||
|
||||
function framework:addAccountMoney(source, account, amount)
|
||||
local player = self:getPlayerFromId(source)
|
||||
player.addAccountMoney(account, amount)
|
||||
end
|
||||
|
||||
function framework:removeItem(source, item, count)
|
||||
local player = self:getPlayerFromId(source)
|
||||
player.removeInventoryItem(item, count)
|
||||
end
|
||||
|
||||
function framework:addItem(source, item, count, slot, info)
|
||||
local player = self:getPlayerFromId(source)
|
||||
if player.canCarryItem(item, count) then
|
||||
player.addInventoryItem(item, count, info, slot)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
---@param player table
|
||||
---@param item string
|
||||
function framework:getItem(player, item)
|
||||
local data = player.getInventoryItem(item)
|
||||
if not data then
|
||||
return {
|
||||
count = 0
|
||||
}
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
function framework:playerIsAdmin(source)
|
||||
local player = self:getPlayerFromId(source)
|
||||
return player.getGroup() == 'admin' or player.getGroup() == 'superadmin'
|
||||
end
|
||||
|
||||
function framework:getUserName(source)
|
||||
local xPlayer = self:getPlayerFromId(source)
|
||||
local firstName, lastName
|
||||
if xPlayer.get and xPlayer.get('firstName') and xPlayer.get('lastName') then
|
||||
firstName = xPlayer.get('firstName')
|
||||
lastName = xPlayer.get('lastName')
|
||||
else
|
||||
local name = MySQL.Sync.fetchAll('SELECT firstname, lastname FROM users WHERE identifier = ?', { xPlayer.identifier })
|
||||
firstName, lastName = name[1]?.firstname or '', name[1]?.lastname or ''
|
||||
end
|
||||
|
||||
return firstName, lastName
|
||||
end
|
||||
|
||||
function framework:getUserNameFromIdentifier(identifier)
|
||||
local name = MySQL.Sync.fetchAll('SELECT `firstname`, `lastname` FROM `users` WHERE `identifier`=@identifier', { ['@identifier'] = identifier })
|
||||
return name[1]?.firstname or '', name[1]?.lastname or ''
|
||||
end
|
||||
|
||||
function framework:getJobName(source)
|
||||
local xPlayer = self:getPlayerFromId(source)
|
||||
return xPlayer.getJob().name
|
||||
end
|
||||
|
||||
function framework:getPlayers()
|
||||
return ESX.GetPlayers()
|
||||
end
|
||||
|
||||
-- This is a so much expensive function. Be careful with it !
|
||||
function framework:getItemList()
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
return ESX.Items
|
||||
end
|
||||
|
||||
function framework:getLicenses(source)
|
||||
if not GetResourceState('esx_license'):find('started') then
|
||||
return
|
||||
end
|
||||
local promise = promise.new()
|
||||
TriggerEvent('esx_license:getLicenses', source, function(licenses)
|
||||
local data = {}
|
||||
for k, v in pairs(licenses) do
|
||||
data[v.type] = true
|
||||
end
|
||||
promise:resolve(data)
|
||||
end)
|
||||
return Citizen.Await(promise)
|
||||
end
|
||||
|
||||
return framework
|
||||
@@ -0,0 +1,36 @@
|
||||
local framework = {}
|
||||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
|
||||
PlayerData = framework:getPlayerData()
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnJobUpdate', function(jobData)
|
||||
PlayerData.job = jobData
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
PlayerData = framework:getPlayerData()
|
||||
end)
|
||||
|
||||
function framework:getPlayerData()
|
||||
return QBCore.Functions.GetPlayerData()
|
||||
end
|
||||
|
||||
function framework:getIdentifier()
|
||||
return PlayerData.citizenid
|
||||
end
|
||||
|
||||
function framework:getJobName()
|
||||
return PlayerData?.job?.name or 'unemployed'
|
||||
end
|
||||
|
||||
function framework:getJobGrade()
|
||||
return PlayerData?.job?.grade?.level or 0
|
||||
end
|
||||
|
||||
function framework:getPlayers()
|
||||
return QBCore.Functions.GetPlayers()
|
||||
end
|
||||
|
||||
return framework
|
||||
@@ -0,0 +1,160 @@
|
||||
--[[
|
||||
Hi dear customer or developer, here you can fully configure your server's
|
||||
framework or you could even duplicate this file to create your own framework.
|
||||
|
||||
If you do not have much experience, we recommend you download the base version
|
||||
of the framework that you use in its latest version and it will work perfectly.
|
||||
]]
|
||||
|
||||
local framework = {}
|
||||
local QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
function framework:registerUsableItem(name, cb)
|
||||
QBCore.Functions.CreateUseableItem(name, cb)
|
||||
end
|
||||
|
||||
function framework:getPlayerFromId(source)
|
||||
return QBCore.Functions.GetPlayer(source)
|
||||
end
|
||||
|
||||
function framework:getSourceFromIdentifier(identifier)
|
||||
local src = QBCore.Functions.GetPlayerByCitizenId(identifier).PlayerData.source
|
||||
return src
|
||||
end
|
||||
|
||||
function framework:getIdentifier(source)
|
||||
if source == 0 then return 'automated' end
|
||||
local player = self:getPlayerFromId(source)
|
||||
return player.PlayerData.citizenid
|
||||
end
|
||||
|
||||
---@param player table
|
||||
---@return number
|
||||
local function getBlackMoney(player)
|
||||
local items = player.PlayerData.items
|
||||
local totalWorth = 0
|
||||
for k, v in pairs(items) do
|
||||
if v.name == 'markedbills' then
|
||||
totalWorth = totalWorth + v.info.worth
|
||||
end
|
||||
end
|
||||
return totalWorth
|
||||
end
|
||||
|
||||
function framework:getAccountMoney(source, account)
|
||||
local player = self:getPlayerFromId(source)
|
||||
if account == 'money' then account = 'cash' end
|
||||
if account == 'black_money' then return getBlackMoney(player) end
|
||||
return player.PlayerData.money[account]
|
||||
end
|
||||
|
||||
local function removeBlackMoney(player, amount)
|
||||
local items = player.PlayerData.items
|
||||
local blackMoney = getBlackMoney(player)
|
||||
while blackMoney > 0 and amount > 0 do
|
||||
Wait(10)
|
||||
Debug('blackMoney:', blackMoney, 'removed:', 'amount:', amount)
|
||||
for k, v in pairs(items) do
|
||||
if v.name ~= 'markedbills' then goto continue end
|
||||
if v.info.worth > amount then
|
||||
v.info.worth = v.info.worth - amount
|
||||
amount = 0
|
||||
break
|
||||
else
|
||||
amount = amount - v.info.worth
|
||||
items[k] = nil
|
||||
Debug('removed:', v.info.worth, 'amount:', amount)
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
SaveInventory(player.PlayerData.source, items)
|
||||
end
|
||||
|
||||
function framework:removeAccountMoney(source, account, amount)
|
||||
local player = self:getPlayerFromId(source)
|
||||
if account == 'money' then account = 'cash' end
|
||||
if account == 'black_money' then
|
||||
removeBlackMoney(player, amount)
|
||||
return
|
||||
end
|
||||
if self:getAccountMoney(source, account) < amount then
|
||||
return false
|
||||
end
|
||||
player.Functions.RemoveMoney(account, amount)
|
||||
return true
|
||||
end
|
||||
|
||||
function framework:addAccountMoney(source, account, amount)
|
||||
local player = self:getPlayerFromId(source)
|
||||
if account == 'money' then account = 'cash' end
|
||||
if account == 'black_money' then
|
||||
local info = { worth = amount }
|
||||
sfr:addItem(source, 'markedbills', 1, false, info)
|
||||
return
|
||||
end
|
||||
player.Functions.AddMoney(account, amount)
|
||||
end
|
||||
|
||||
function framework:removeItem(source, item, count)
|
||||
local player = self:getPlayerFromId(source)
|
||||
player.Functions.RemoveItem(item, count)
|
||||
end
|
||||
|
||||
function framework:addItem(source, item, count, slot, info)
|
||||
local player = self:getPlayerFromId(source)
|
||||
return player.Functions.AddItem(item, count, slot, info)
|
||||
end
|
||||
|
||||
function framework:getItem(player, item)
|
||||
local data = player.Functions.GetItemByName(item)
|
||||
if not data then
|
||||
return {
|
||||
count = 0
|
||||
}
|
||||
end
|
||||
data.count = data.amount
|
||||
return data
|
||||
end
|
||||
|
||||
function framework:playerIsAdmin(source)
|
||||
return QBCore.Functions.HasPermission(source, 'god') or IsPlayerAceAllowed(source, 'command') or QBCore.Functions.HasPermission(source, 'admin')
|
||||
end
|
||||
|
||||
function framework:getUserName(source)
|
||||
local player = self:getPlayerFromId(source)
|
||||
return player.PlayerData.charinfo.firstname, player.PlayerData.charinfo.lastname
|
||||
end
|
||||
|
||||
function framework:getUserNameFromIdentifier(identifier)
|
||||
local result = MySQL.Sync.fetchAll('SELECT charinfo FROM `players` WHERE citizenid = ?', { identifier })
|
||||
if not result[1] then
|
||||
return '', ''
|
||||
end
|
||||
result = result[1]
|
||||
result = json.decode(result.charinfo)
|
||||
return result?.firstname, result?.lastname
|
||||
end
|
||||
|
||||
function framework:getJobName(source)
|
||||
local player = self:getPlayerFromId(source)
|
||||
return player.PlayerData.job.name
|
||||
end
|
||||
|
||||
function framework:getPlayers()
|
||||
return QBCore.Functions.GetPlayers()
|
||||
end
|
||||
|
||||
function framework:getItemList()
|
||||
if Config.QBX then
|
||||
return exports['qs-inventory']:GetItemList()
|
||||
end
|
||||
return QBCore.Shared.Items
|
||||
end
|
||||
|
||||
function framework:getLicenses(source)
|
||||
local player = self:getPlayerFromId(source)
|
||||
return player.PlayerData.metadata['licences']
|
||||
end
|
||||
|
||||
return framework ---@type ServerFramework
|
||||
@@ -0,0 +1,8 @@
|
||||
local success, result = pcall(lib.load, ('custom.%s.server'):format(Config.Framework))
|
||||
|
||||
if not success then
|
||||
error(result, 0)
|
||||
end
|
||||
|
||||
_G.sfr = result --[[@as ServerFramework]]
|
||||
print('^2[INFO]^7 Successfully loaded the framework.', Config.Framework)
|
||||
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,59 @@
|
||||
fx_version 'cerulean'
|
||||
|
||||
game 'gta5'
|
||||
|
||||
lua54 'yes'
|
||||
|
||||
name 'qs-advancedshops'
|
||||
author 'Quasar Store'
|
||||
|
||||
ui_page 'html/index.html'
|
||||
|
||||
files {
|
||||
'html/index.html',
|
||||
'html/index.js',
|
||||
'html/style.css',
|
||||
'html/*otf',
|
||||
'html/*png',
|
||||
'fonts/*.ttf',
|
||||
'fonts/*.otf',
|
||||
'custom/**'
|
||||
}
|
||||
|
||||
ox_libs {
|
||||
'table',
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'client/custom/**/**',
|
||||
'custom/client.lua',
|
||||
'client/*.lua',
|
||||
}
|
||||
|
||||
shared_scripts {
|
||||
'@ox_lib/init.lua',
|
||||
'shared/functions.lua',
|
||||
'shared/config.lua',
|
||||
'locales/**'
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
'custom/server.lua',
|
||||
'server/*.lua',
|
||||
}
|
||||
|
||||
dependencies {
|
||||
'ox_lib',
|
||||
'qs-inventory'
|
||||
}
|
||||
|
||||
escrow_ignore {
|
||||
'client/custom/**',
|
||||
'custom/**/*',
|
||||
'shared/**/*',
|
||||
'config/*',
|
||||
'type.lua',
|
||||
'locales/*'
|
||||
}
|
||||
|
||||
dependency '/assetpacks'
|
||||
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user