fix(qb-core): add global CreateUsableItem alias for qs-inventory compatibility
qs-inventory apelează CreateUsableItem ca funcție globală, dar qb-core definea doar QBCore.Functions.CreateUseableItem (cu 'e'). Adăugat alias global + fix 16 stringuri sparte în items.lua care blocau parsarea.
2
.gitignore
vendored
@@ -13,3 +13,5 @@ cache/files/17mov_JobCenter/resource.rpf
|
|||||||
_fix_dupes.py
|
_fix_dupes.py
|
||||||
_check_dupes.py
|
_check_dupes.py
|
||||||
_find_dupes.py
|
_find_dupes.py
|
||||||
|
artifacts/crashes/136f1640-ac9a-4693-824a-5ccd58f1b359-full.dmp
|
||||||
|
artifacts/crashes/136f1640-ac9a-4693-824a-5ccd58f1b359.dmp
|
||||||
|
|||||||
24
_find_broken.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
path = r'E:\FiveMserver\server\resources\[framework]\[core]\qb-core\shared\items.lua'
|
||||||
|
with open(path, 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
|
||||||
|
broken = []
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
stripped = line.strip()
|
||||||
|
if "['description']" not in stripped:
|
||||||
|
continue
|
||||||
|
if "['name']" not in stripped:
|
||||||
|
continue
|
||||||
|
# Count single quotes after ['description']
|
||||||
|
idx = stripped.index("['description']")
|
||||||
|
after = stripped[idx:]
|
||||||
|
# Should end with ...'}, or ...'}},
|
||||||
|
# Check if description value has matching quotes
|
||||||
|
if after.count("'") % 2 != 0:
|
||||||
|
broken.append((i+1, stripped[:120]))
|
||||||
|
|
||||||
|
print(f"Found {len(broken)} broken strings:")
|
||||||
|
for ln, txt in broken:
|
||||||
|
print(f" L{ln}: {txt}")
|
||||||
34
_fix_strings.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
path = r'E:\FiveMserver\server\resources\[framework]\[core]\qb-core\shared\items.lua'
|
||||||
|
with open(path, 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Fix pattern: find description strings that don't end with closing quote before },
|
||||||
|
# Pattern: ['description'] = 'text without closing quote},
|
||||||
|
# Should be: ['description'] = 'text with closing quote'},
|
||||||
|
|
||||||
|
fixed = 0
|
||||||
|
|
||||||
|
lines = content.split('\n')
|
||||||
|
new_lines = []
|
||||||
|
for line in lines:
|
||||||
|
if "['description']" in line and "['name']" in line:
|
||||||
|
idx = line.index("['description']")
|
||||||
|
after = line[idx:]
|
||||||
|
if after.count("'") % 2 != 0:
|
||||||
|
# Find the last }, and insert closing quote before it
|
||||||
|
# Pattern: some text}, -> some text'},
|
||||||
|
# Or: some text}}, -> some text'}},
|
||||||
|
line = re.sub(r"([^'])\},\s*$", r"\1'},", line)
|
||||||
|
line = re.sub(r"([^'])\}\},\s*$", r"\1'}},", line)
|
||||||
|
# Handle CRLF
|
||||||
|
line = re.sub(r"([^'])\},\r$", r"\1'},\r", line)
|
||||||
|
line = re.sub(r"([^'])\}\},\r$", r"\1'}},\r", line)
|
||||||
|
fixed += 1
|
||||||
|
new_lines.append(line)
|
||||||
|
|
||||||
|
with open(path, 'w', encoding='utf-8') as f:
|
||||||
|
f.write('\n'.join(new_lines))
|
||||||
|
|
||||||
|
print(f"Fixed {fixed} broken description strings")
|
||||||
@@ -16,4 +16,3 @@ ensure phone-props
|
|||||||
ensure [casino]
|
ensure [casino]
|
||||||
ensure [stream]
|
ensure [stream]
|
||||||
ensure luxu_admin
|
ensure luxu_admin
|
||||||
ensure [weapons]
|
|
||||||
BIN
resources/[framework]/[addons]/[quasar]/qs-armor/.fxap
Normal file
@@ -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
|
||||||
@@ -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
|
||||||
BIN
resources/[framework]/[addons]/[quasar]/qs-armor/client/main.lua
Normal file
@@ -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...",
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
BIN
resources/[framework]/[addons]/[quasar]/qs-armor/server/main.lua
Normal file
@@ -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
|
||||||
BIN
resources/[framework]/[addons]/[quasar]/qs-backpacks/.fxap
Normal file
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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.',
|
||||||
|
}
|
||||||
@@ -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.
|
||||||
|
},
|
||||||
|
}
|
||||||
BIN
resources/[framework]/[addons]/[quasar]/qs-inventory/.fxap
Normal file
@@ -1,3 +1,34 @@
|
|||||||
|
local function SyncEquippedWeaponAmmoOnOpen(inventory)
|
||||||
|
if not inventory then return inventory end
|
||||||
|
|
||||||
|
local ped = cache.ped
|
||||||
|
local weaponHash = GetSelectedPedWeapon(ped)
|
||||||
|
local weaponData = WeaponList and WeaponList[weaponHash]
|
||||||
|
if not weaponData or weaponData.name == 'weapon_unarmed' then
|
||||||
|
return inventory
|
||||||
|
end
|
||||||
|
|
||||||
|
local ammo = GetAmmoInPedWeapon(ped, weaponHash) or 0
|
||||||
|
|
||||||
|
-- Prefer the equipped slot if CurrentWeaponData is available.
|
||||||
|
local preferredSlot = CurrentWeaponData and CurrentWeaponData.slot
|
||||||
|
if preferredSlot and inventory[preferredSlot] and inventory[preferredSlot].name == weaponData.name then
|
||||||
|
inventory[preferredSlot].info = inventory[preferredSlot].info or {}
|
||||||
|
inventory[preferredSlot].info.ammo = ammo
|
||||||
|
return inventory
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, item in pairs(inventory) do
|
||||||
|
if item and item.type == 'weapon' and item.name == weaponData.name then
|
||||||
|
item.info = item.info or {}
|
||||||
|
item.info.ammo = ammo
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return inventory
|
||||||
|
end
|
||||||
|
|
||||||
local checkDistanceInventories = {
|
local checkDistanceInventories = {
|
||||||
'shop',
|
'shop',
|
||||||
'stash',
|
'stash',
|
||||||
@@ -38,6 +69,7 @@ RegisterNetEvent(Config.InventoryPrefix .. ':client:OpenInventory', function(Pla
|
|||||||
end
|
end
|
||||||
|
|
||||||
inventory = data.inventory
|
inventory = data.inventory
|
||||||
|
inventory = SyncEquippedWeaponAmmoOnOpen(inventory)
|
||||||
other = data.other
|
other = data.other
|
||||||
|
|
||||||
data = GetPlayerData()
|
data = GetPlayerData()
|
||||||
@@ -2,7 +2,7 @@ if not GetResourceState('jobs_creator') == 'missing' then
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Warning('Started the compatibility module with jobs_creator')
|
Warning('Started the compatibility module with jobs_creator')
|
||||||
|
|
||||||
CreateThread(function()
|
CreateThread(function()
|
||||||
local other = {}
|
local other = {}
|
||||||
@@ -15,28 +15,22 @@ local function LoadAnimDict(dict)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
RegisterKeyMapping('+handsup', Lang('INVENTORY_KEYMAPPING_HANDSUP_LABEL'), 'keyboard', Config.KeyBinds.handsup)
|
RegisterKeyMapping('handsup', Lang('INVENTORY_KEYMAPPING_HANDSUP_LABEL'), 'keyboard', Config.KeyBinds.handsup)
|
||||||
|
|
||||||
local handsUpActive = false
|
RegisterCommand('handsup', function()
|
||||||
|
|
||||||
RegisterCommand('+handsup', function()
|
|
||||||
if not IsPedInAnyVehicle(PlayerPedId(), false) and GetEntityHealth(PlayerPedId()) > 1 then
|
if not IsPedInAnyVehicle(PlayerPedId(), false) and GetEntityHealth(PlayerPedId()) > 1 then
|
||||||
if canHandsUp and not handsUpActive then
|
|
||||||
handsUpActive = true
|
|
||||||
RequestAnimDict(lib)
|
RequestAnimDict(lib)
|
||||||
while not HasAnimDictLoaded(lib) do
|
while not HasAnimDictLoaded(lib) do
|
||||||
Wait(100)
|
Wait(100)
|
||||||
end
|
end
|
||||||
SetCurrentPedWeapon(PlayerPedId(), GetHashKey('WEAPON_UNARMED'), true)
|
SetCurrentPedWeapon(PlayerPedId(), GetHashKey('WEAPON_UNARMED'), true)
|
||||||
|
if IsEntityPlayingAnim(PlayerPedId(), lib, anim, 3) then
|
||||||
|
ClearPedSecondaryTask(PlayerPedId())
|
||||||
|
else
|
||||||
|
if canHandsUp then
|
||||||
TaskPlayAnim(PlayerPedId(), lib, anim, 2.0, 2.5, -1, 49, 0, 0, 0, 0)
|
TaskPlayAnim(PlayerPedId(), lib, anim, 2.0, 2.5, -1, 49, 0, 0, 0, 0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
|
||||||
|
|
||||||
RegisterCommand('-handsup', function()
|
|
||||||
if handsUpActive then
|
|
||||||
handsUpActive = false
|
|
||||||
ClearPedSecondaryTask(PlayerPedId())
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
if not Config.Debug then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
Debug('Debug Command', 'inventory:openStash command initialized')
|
||||||
|
RegisterCommand('inventory:openStash', function(source, args)
|
||||||
|
local id = args[1] or source
|
||||||
|
local stashId = 'inventory_debug_stash' .. id
|
||||||
|
|
||||||
|
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'stash', stashId)
|
||||||
|
TriggerEvent(Config.InventoryPrefix .. ':client:SetCurrentStash', stashId)
|
||||||
|
end)
|
||||||
|
|
||||||
|
Debug('Debug Command', 'inventory:search command initialized')
|
||||||
|
RegisterCommand('inventory:search', function(source, args)
|
||||||
|
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'otherplayer', tonumber(args[1]))
|
||||||
|
end)
|
||||||
|
|
||||||
|
Debug('Debug Command', 'inventory:openOther command initialized')
|
||||||
|
RegisterCommand('inventory:openOther', function(source, args, raw)
|
||||||
|
local target = tonumber(args[1])
|
||||||
|
if not target then
|
||||||
|
Debug('Debug Command', 'Invalid target ID')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'otherplayer', target)
|
||||||
|
end)
|
||||||
|
TriggerEvent('chat:addSuggestion', '/inventory:openOther', 'Open inventory of another player', {
|
||||||
|
{ name = 'targetId', help = 'Target player ID' },
|
||||||
|
})
|
||||||
@@ -2,6 +2,8 @@ local PlayerData = GetPlayerData()
|
|||||||
local CanShoot, MultiplierAmount = true, 0
|
local CanShoot, MultiplierAmount = true, 0
|
||||||
CurrentWeaponData = {}
|
CurrentWeaponData = {}
|
||||||
|
|
||||||
|
local weaponTrackingActive = false
|
||||||
|
|
||||||
exports('GetCurrentWeapon', function()
|
exports('GetCurrentWeapon', function()
|
||||||
return CurrentWeaponData
|
return CurrentWeaponData
|
||||||
end)
|
end)
|
||||||
@@ -10,6 +12,55 @@ lib.callback.register('weapons:client:GetCurrentWeapon', function()
|
|||||||
return CurrentWeaponData
|
return CurrentWeaponData
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
local function SyncWeaponToServer()
|
||||||
|
if not CurrentWeaponData or not CurrentWeaponData.info or not CurrentWeaponData.name then return end
|
||||||
|
|
||||||
|
local ammo = CurrentWeaponData.info.ammo or 0
|
||||||
|
|
||||||
|
TriggerServerEvent('weapons:server:UpdateWeaponAmmo', CurrentWeaponData, ammo)
|
||||||
|
|
||||||
|
if MultiplierAmount > 0 then
|
||||||
|
TriggerServerEvent('weapons:server:UpdateWeaponQuality', CurrentWeaponData, MultiplierAmount, ammo)
|
||||||
|
MultiplierAmount = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function StartWeaponTracking()
|
||||||
|
if weaponTrackingActive then return end
|
||||||
|
weaponTrackingActive = true
|
||||||
|
|
||||||
|
CreateThread(function()
|
||||||
|
while weaponTrackingActive and CurrentWeaponData and next(CurrentWeaponData) do
|
||||||
|
local ped = PlayerPedId()
|
||||||
|
local weapon = GetSelectedPedWeapon(ped)
|
||||||
|
|
||||||
|
if weapon ~= `WEAPON_UNARMED` and CurrentWeaponData.info then
|
||||||
|
CurrentWeaponData.info.ammo = GetAmmoInPedWeapon(ped, weapon)
|
||||||
|
end
|
||||||
|
|
||||||
|
if IsPedShooting(ped) then
|
||||||
|
if CanShoot then
|
||||||
|
if weapon and weapon ~= 0 and WeaponList[weapon] then
|
||||||
|
MultiplierAmount = MultiplierAmount + 1
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if weapon ~= `WEAPON_UNARMED` then
|
||||||
|
TriggerEvent(Config.InventoryPrefix .. ':client:CheckWeapon', WeaponList[weapon]['name'])
|
||||||
|
SendTextMessage(Lang('INVENTORY_NOTIFICATION_WEAPON_BROKEN'), 'error')
|
||||||
|
MultiplierAmount = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Wait(100)
|
||||||
|
end
|
||||||
|
weaponTrackingActive = false
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function StopWeaponTracking()
|
||||||
|
weaponTrackingActive = false
|
||||||
|
end
|
||||||
|
|
||||||
CreateThread(function()
|
CreateThread(function()
|
||||||
while not Config.WeaponsOnVehicle do
|
while not Config.WeaponsOnVehicle do
|
||||||
Wait(250)
|
Wait(250)
|
||||||
@@ -92,12 +143,19 @@ RegisterNetEvent('addAttachment', function(component, urltint)
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
RegisterNetEvent('weapons:client:SetCurrentWeapon', function(data, bool)
|
RegisterNetEvent('weapons:client:SetCurrentWeapon', function(data, bool)
|
||||||
if data ~= false then
|
if CurrentWeaponData and next(CurrentWeaponData) then
|
||||||
|
SyncWeaponToServer()
|
||||||
|
StopWeaponTracking()
|
||||||
|
end
|
||||||
|
|
||||||
|
if data ~= false and data ~= nil then
|
||||||
CurrentWeaponData = data
|
CurrentWeaponData = data
|
||||||
|
CanShoot = bool
|
||||||
|
StartWeaponTracking()
|
||||||
else
|
else
|
||||||
CurrentWeaponData = {}
|
CurrentWeaponData = {}
|
||||||
end
|
|
||||||
CanShoot = bool
|
CanShoot = bool
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
RegisterNetEvent('weapons:client:SetWeaponQuality', function(amount)
|
RegisterNetEvent('weapons:client:SetWeaponQuality', function(amount)
|
||||||
@@ -291,52 +349,6 @@ CreateThread(function()
|
|||||||
SetWeaponsNoAutoswap(true)
|
SetWeaponsNoAutoswap(true)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
LastUpdatedAmmoTime = nil
|
|
||||||
CreateThread(function()
|
|
||||||
while true do
|
|
||||||
local ped = PlayerPedId()
|
|
||||||
if GetSelectedPedWeapon(ped) ~= `WEAPON_UNARMED` and CurrentWeaponData?.info and (IsControlJustReleased(0, 24) or IsDisabledControlJustReleased(0, 24)) then
|
|
||||||
local weapon = GetSelectedPedWeapon(ped)
|
|
||||||
local ammo = GetAmmoInPedWeapon(ped, weapon)
|
|
||||||
TriggerServerEvent('weapons:server:UpdateWeaponAmmo', CurrentWeaponData, tonumber(ammo))
|
|
||||||
CurrentWeaponData.info.ammo = ammo
|
|
||||||
LastUpdatedAmmoTime = GetGameTimer()
|
|
||||||
if MultiplierAmount > 0 then
|
|
||||||
TriggerServerEvent('weapons:server:UpdateWeaponQuality', CurrentWeaponData, MultiplierAmount, ammo)
|
|
||||||
MultiplierAmount = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Wait(0)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
CreateThread(function()
|
|
||||||
while true do
|
|
||||||
local ped = PlayerPedId()
|
|
||||||
if CurrentWeaponData and next(CurrentWeaponData) then
|
|
||||||
if IsPedShooting(ped) or IsControlJustPressed(0, 24) then
|
|
||||||
local weapon = GetSelectedPedWeapon(ped)
|
|
||||||
if CanShoot then
|
|
||||||
if weapon and weapon ~= 0 and WeaponList[weapon] then
|
|
||||||
TriggerServerCallback('prison:server:checkThrowable', function(result)
|
|
||||||
if result or GetAmmoInPedWeapon(ped, weapon) <= 0 then return end
|
|
||||||
MultiplierAmount += 1
|
|
||||||
end, weapon)
|
|
||||||
Wait(200)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if weapon ~= `WEAPON_UNARMED` then
|
|
||||||
TriggerEvent(Config.InventoryPrefix .. ':client:CheckWeapon', WeaponList[weapon]['name'])
|
|
||||||
SendTextMessage(Lang('INVENTORY_NOTIFICATION_WEAPON_BROKEN'), 'error')
|
|
||||||
MultiplierAmount = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Wait(0)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
RegisterNetEvent(Config.InventoryPrefix .. ':client:LegacyFuel', function(fuel)
|
RegisterNetEvent(Config.InventoryPrefix .. ':client:LegacyFuel', function(fuel)
|
||||||
Debug('Your gasoline can has: %', fuel)
|
Debug('Your gasoline can has: %', fuel)
|
||||||
TriggerServerEvent('weapons:server:UpdateWeaponAmmo', CurrentWeaponData, fuel)
|
TriggerServerEvent('weapons:server:UpdateWeaponAmmo', CurrentWeaponData, fuel)
|
||||||
@@ -36,7 +36,7 @@ Locales = Locales or {} -- [CORE] Language packs container.
|
|||||||
-- 'ar','bg','ca','cs','da','de','el','en','es','fa','fr','hi','hu','it','ja',
|
-- 'ar','bg','ca','cs','da','de','el','en','es','fa','fr','hi','hu','it','ja',
|
||||||
-- 'ko','nl','no','pl','pt','ro','ru','sl','sv','th','tr','zh-CN','zh-TW'
|
-- 'ko','nl','no','pl','pt','ro','ru','sl','sv','th','tr','zh-CN','zh-TW'
|
||||||
--──────────────────────────────────────────────────────────────────────────────
|
--──────────────────────────────────────────────────────────────────────────────
|
||||||
Config.Language = 'ro' -- [EDIT]
|
Config.Language = 'en' -- [EDIT]
|
||||||
|
|
||||||
--[[ [INFO]
|
--[[ [INFO]
|
||||||
Choose your preferred language!
|
Choose your preferred language!
|
||||||
@@ -123,7 +123,7 @@ Config.KQPlaceableItems = false -- [EDIT] Use KQ
|
|||||||
-- [INFO] Changing weight/slots can require wipes to avoid dupes. Be cautious.
|
-- [INFO] Changing weight/slots can require wipes to avoid dupes. Be cautious.
|
||||||
--──────────────────────────────────────────────────────────────────────────────
|
--──────────────────────────────────────────────────────────────────────────────
|
||||||
Config.InventoryWeight = { -- [EDIT]
|
Config.InventoryWeight = { -- [EDIT]
|
||||||
weight = 5000, -- [INFO] Max weight (grams).
|
weight = 120000, -- [INFO] Max weight (grams).
|
||||||
slots = 41, -- [INFO] Set 40 to remove protected 6th slot.
|
slots = 41, -- [INFO] Set 40 to remove protected 6th slot.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +138,7 @@ Config.DropWeight = { -- [EDIT]
|
|||||||
--──────────────────────────────────────────────────────────────────────────────
|
--──────────────────────────────────────────────────────────────────────────────
|
||||||
-- Label Change [EDIT]
|
-- Label Change [EDIT]
|
||||||
--──────────────────────────────────────────────────────────────────────────────
|
--──────────────────────────────────────────────────────────────────────────────
|
||||||
Config.LabelChange = false -- [EDIT] Allow item renaming.
|
Config.LabelChange = true -- [EDIT] Allow item renaming.
|
||||||
Config.LabelChangePrice = false -- [EDIT] Price or false for free.
|
Config.LabelChangePrice = false -- [EDIT] Price or false for free.
|
||||||
Config.BlockedLabelChangeItems = { -- [EDIT] Items that cannot be renamed.
|
Config.BlockedLabelChangeItems = { -- [EDIT] Items that cannot be renamed.
|
||||||
money = true,
|
money = true,
|
||||||
@@ -358,8 +358,8 @@ Config.InventoryOptions = {
|
|||||||
['thirst'] = true, -- [EDIT] Show thirst
|
['thirst'] = true, -- [EDIT] Show thirst
|
||||||
['id'] = true, -- [EDIT] Show player ID
|
['id'] = true, -- [EDIT] Show player ID
|
||||||
['money'] = true, -- [EDIT] Show cash
|
['money'] = true, -- [EDIT] Show cash
|
||||||
['bank'] = false, -- [EDIT] Show bank balance
|
['bank'] = true, -- [EDIT] Show bank balance
|
||||||
['blackmoney'] = false, -- [EDIT] Show black money
|
['blackmoney'] = true, -- [EDIT] Show black money
|
||||||
}
|
}
|
||||||
|
|
||||||
--──────────────────────────────────────────────────────────────────────────────
|
--──────────────────────────────────────────────────────────────────────────────
|
||||||
@@ -442,7 +442,7 @@ Config.KeyBinds = { -- [EDIT]
|
|||||||
-- Debug & Development Tools [EDIT]
|
-- Debug & Development Tools [EDIT]
|
||||||
-- [INFO] Enables development logs and debugging prints. Use only during testing.
|
-- [INFO] Enables development logs and debugging prints. Use only during testing.
|
||||||
--──────────────────────────────────────────────────────────────────────────────
|
--──────────────────────────────────────────────────────────────────────────────
|
||||||
Config.Debug = false -- [EDIT] Detailed console prints
|
Config.Debug = true -- [EDIT] Detailed console prints
|
||||||
Config.ZoneDebug = false -- [EDIT] Display additional zone debug info
|
Config.ZoneDebug = false -- [EDIT] Display additional zone debug info
|
||||||
Config.InventoryPrefix = 'inventory' -- [ADV] Internal prefix; changing requires code adjustments
|
Config.InventoryPrefix = 'inventory' -- [ADV] Internal prefix; changing requires code adjustments
|
||||||
Config.SaveInventoryInterval = 12500 -- [EDIT] Autosave interval (ms)
|
Config.SaveInventoryInterval = 12500 -- [EDIT] Autosave interval (ms)
|
||||||
@@ -107,130 +107,130 @@ end
|
|||||||
-- [INFO] Define mesas de crafteo por job/ubicación, con blip y recetas propias.
|
-- [INFO] Define mesas de crafteo por job/ubicación, con blip y recetas propias.
|
||||||
--──────────────────────────────────────────────────────────────────────────────
|
--──────────────────────────────────────────────────────────────────────────────
|
||||||
Config.CraftingTables = {
|
Config.CraftingTables = {
|
||||||
-- [1] = {
|
[1] = {
|
||||||
-- name = 'Police Crafting',
|
name = 'Police Crafting',
|
||||||
-- isjob = 'police',
|
isjob = 'police',
|
||||||
-- grades = 'all',
|
grades = 'all',
|
||||||
-- text = '[E] - Police Craft',
|
text = '[E] - Police Craft',
|
||||||
-- blip = {
|
blip = {
|
||||||
-- enabled = true,
|
enabled = true,
|
||||||
-- title = 'Police Crafting',
|
title = 'Police Crafting',
|
||||||
-- scale = 1.0,
|
scale = 1.0,
|
||||||
-- display = 4,
|
display = 4,
|
||||||
-- colour = 0,
|
colour = 0,
|
||||||
-- id = 365
|
id = 365
|
||||||
-- },
|
},
|
||||||
-- location = vec3(459.771423, -989.050537, 24.898926),
|
location = vec3(459.771423, -989.050537, 24.898926),
|
||||||
-- items = {
|
items = {
|
||||||
-- [1] = {
|
[1] = {
|
||||||
-- name = 'weapon_pistol',
|
name = 'weapon_pistol',
|
||||||
-- amount = 50,
|
amount = 50,
|
||||||
-- info = {},
|
info = {},
|
||||||
-- costs = {
|
costs = {
|
||||||
-- ['iron'] = 80,
|
['iron'] = 80,
|
||||||
-- ['metalscrap'] = 70,
|
['metalscrap'] = 70,
|
||||||
-- ['rubber'] = 8,
|
['rubber'] = 8,
|
||||||
-- ['steel'] = 60,
|
['steel'] = 60,
|
||||||
-- ['lockpick'] = 5,
|
['lockpick'] = 5,
|
||||||
-- },
|
},
|
||||||
-- type = 'weapon',
|
type = 'weapon',
|
||||||
-- slot = 1,
|
slot = 1,
|
||||||
-- rep = 'attachmentcraftingrep',
|
rep = 'attachmentcraftingrep',
|
||||||
-- points = 1,
|
points = 1,
|
||||||
-- threshold = 0,
|
threshold = 0,
|
||||||
-- time = 5500,
|
time = 5500,
|
||||||
-- chance = 100
|
chance = 100
|
||||||
-- },
|
},
|
||||||
-- [2] = {
|
[2] = {
|
||||||
-- name = 'weapon_smg',
|
name = 'weapon_smg',
|
||||||
-- amount = 1,
|
amount = 1,
|
||||||
-- info = {},
|
info = {},
|
||||||
-- costs = {
|
costs = {
|
||||||
-- ['iron'] = 80,
|
['iron'] = 80,
|
||||||
-- ['metalscrap'] = 120,
|
['metalscrap'] = 120,
|
||||||
-- ['rubber'] = 10,
|
['rubber'] = 10,
|
||||||
-- ['steel'] = 65,
|
['steel'] = 65,
|
||||||
-- ['lockpick'] = 10,
|
['lockpick'] = 10,
|
||||||
-- },
|
},
|
||||||
-- type = 'weapon',
|
type = 'weapon',
|
||||||
-- slot = 2,
|
slot = 2,
|
||||||
-- rep = 'attachmentcraftingrep',
|
rep = 'attachmentcraftingrep',
|
||||||
-- points = 1,
|
points = 1,
|
||||||
-- threshold = 0,
|
threshold = 0,
|
||||||
-- time = 8500,
|
time = 8500,
|
||||||
-- chance = 100
|
chance = 100
|
||||||
-- },
|
},
|
||||||
-- [3] = {
|
[3] = {
|
||||||
-- name = 'weapon_carbinerifle',
|
name = 'weapon_carbinerifle',
|
||||||
-- amount = 1,
|
amount = 1,
|
||||||
-- info = {},
|
info = {},
|
||||||
-- costs = {
|
costs = {
|
||||||
-- ['iron'] = 120,
|
['iron'] = 120,
|
||||||
-- ['metalscrap'] = 120,
|
['metalscrap'] = 120,
|
||||||
-- ['rubber'] = 20,
|
['rubber'] = 20,
|
||||||
-- ['steel'] = 90,
|
['steel'] = 90,
|
||||||
-- ['lockpick'] = 14,
|
['lockpick'] = 14,
|
||||||
-- },
|
},
|
||||||
-- type = 'weapon',
|
type = 'weapon',
|
||||||
-- slot = 3,
|
slot = 3,
|
||||||
-- rep = 'craftingrep',
|
rep = 'craftingrep',
|
||||||
-- points = 2,
|
points = 2,
|
||||||
-- threshold = 0,
|
threshold = 0,
|
||||||
-- time = 12000,
|
time = 12000,
|
||||||
-- chance = 100
|
chance = 100
|
||||||
-- }
|
}
|
||||||
-- }
|
}
|
||||||
-- },
|
},
|
||||||
-- [2] = {
|
[2] = {
|
||||||
-- name = 'Attachment Crafting',
|
name = 'Attachment Crafting',
|
||||||
-- isjob = false,
|
isjob = false,
|
||||||
-- grades = 'all',
|
grades = 'all',
|
||||||
-- text = '[E] - Craft Attachment',
|
text = '[E] - Craft Attachment',
|
||||||
-- blip = {
|
blip = {
|
||||||
-- enabled = true,
|
enabled = true,
|
||||||
-- title = 'Attachment Crafting',
|
title = 'Attachment Crafting',
|
||||||
-- scale = 1.0,
|
scale = 1.0,
|
||||||
-- display = 4,
|
display = 4,
|
||||||
-- colour = 0,
|
colour = 0,
|
||||||
-- id = 365
|
id = 365
|
||||||
-- },
|
},
|
||||||
-- location = vec3(90.303299, 3745.503418, 39.771484),
|
location = vec3(90.303299, 3745.503418, 39.771484),
|
||||||
-- items = {
|
items = {
|
||||||
-- [1] = {
|
[1] = {
|
||||||
-- name = 'pistol_extendedclip',
|
name = 'pistol_extendedclip',
|
||||||
-- amount = 50,
|
amount = 50,
|
||||||
-- info = {},
|
info = {},
|
||||||
-- costs = {
|
costs = {
|
||||||
-- ['metalscrap'] = 140,
|
['metalscrap'] = 140,
|
||||||
-- ['steel'] = 250,
|
['steel'] = 250,
|
||||||
-- ['rubber'] = 60,
|
['rubber'] = 60,
|
||||||
-- },
|
},
|
||||||
-- type = 'item',
|
type = 'item',
|
||||||
-- slot = 1,
|
slot = 1,
|
||||||
-- rep = 'attachmentcraftingrep',
|
rep = 'attachmentcraftingrep',
|
||||||
-- points = 1,
|
points = 1,
|
||||||
-- threshold = 0,
|
threshold = 0,
|
||||||
-- time = 8000,
|
time = 8000,
|
||||||
-- chance = 90
|
chance = 90
|
||||||
-- },
|
},
|
||||||
-- [2] = {
|
[2] = {
|
||||||
-- name = 'pistol_suppressor',
|
name = 'pistol_suppressor',
|
||||||
-- amount = 50,
|
amount = 50,
|
||||||
-- info = {},
|
info = {},
|
||||||
-- costs = {
|
costs = {
|
||||||
-- ['metalscrap'] = 165,
|
['metalscrap'] = 165,
|
||||||
-- ['steel'] = 285,
|
['steel'] = 285,
|
||||||
-- ['rubber'] = 75,
|
['rubber'] = 75,
|
||||||
-- },
|
},
|
||||||
-- type = 'item',
|
type = 'item',
|
||||||
-- slot = 2,
|
slot = 2,
|
||||||
-- rep = 'attachmentcraftingrep',
|
rep = 'attachmentcraftingrep',
|
||||||
-- points = 1,
|
points = 1,
|
||||||
-- threshold = 0,
|
threshold = 0,
|
||||||
-- time = 8000,
|
time = 8000,
|
||||||
-- chance = 90
|
chance = 90
|
||||||
-- },
|
},
|
||||||
-- }
|
}
|
||||||
-- },
|
},
|
||||||
-- Continue with the same structure for the other Crafting Tables...
|
-- Continue with the same structure for the other Crafting Tables...
|
||||||
}
|
}
|
||||||
@@ -676,6 +676,7 @@ Config.WeaponAttachments = {
|
|||||||
holographic = { component = 'COMPONENT_AT_SIGHTS', item = 'sniper_holoscope' },
|
holographic = { component = 'COMPONENT_AT_SIGHTS', item = 'sniper_holoscope' },
|
||||||
smallscope = { component = 'COMPONENT_AT_SCOPE_SMALL_MK2', item = 'sniper_smallscope' },
|
smallscope = { component = 'COMPONENT_AT_SCOPE_SMALL_MK2', item = 'sniper_smallscope' },
|
||||||
largescope = { component = 'COMPONENT_AT_SCOPE_LARGE_MK2', item = 'sniper_largescope' },
|
largescope = { component = 'COMPONENT_AT_SCOPE_LARGE_MK2', item = 'sniper_largescope' },
|
||||||
|
thermalscope = { component = 'COMPONENT_AT_SCOPE_THERMAL', item = 'sniper_thermalscope' },
|
||||||
suppressor = { component = 'COMPONENT_AT_SR_SUPP_03', item = 'sniper_suppressor' },
|
suppressor = { component = 'COMPONENT_AT_SR_SUPP_03', item = 'sniper_suppressor' },
|
||||||
squaredmuzzle = { component = 'COMPONENT_AT_MUZZLE_08', item = 'sniper_squaredmuzzle' },
|
squaredmuzzle = { component = 'COMPONENT_AT_MUZZLE_08', item = 'sniper_squaredmuzzle' },
|
||||||
barrel = { component = 'COMPONENT_AT_SR_BARREL_02', item = 'sniper_barrel' },
|
barrel = { component = 'COMPONENT_AT_SR_BARREL_02', item = 'sniper_barrel' },
|
||||||
@@ -4,7 +4,7 @@ game 'gta5'
|
|||||||
|
|
||||||
lua54 'yes'
|
lua54 'yes'
|
||||||
|
|
||||||
version '3.7.16'
|
version '3.7.22'
|
||||||
|
|
||||||
name 'qs-inventory'
|
name 'qs-inventory'
|
||||||
author 'Quasar Store'
|
author 'Quasar Store'
|
||||||
@@ -74,7 +74,8 @@ escrow_ignore {
|
|||||||
'server/custom/webhook/*.lua',
|
'server/custom/webhook/*.lua',
|
||||||
'server/custom/misc/*.lua',
|
'server/custom/misc/*.lua',
|
||||||
'client/modules/weapons.lua',
|
'client/modules/weapons.lua',
|
||||||
'server/modules/weapons.lua'
|
'server/modules/weapons.lua',
|
||||||
|
'client/modules/debug.lua'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |