mirror of
https://github.com/qbcore-fivem/qb-core.git
synced 2026-08-29 01:08:57 +00:00
reset branch
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
local function hideText()
|
||||
SendNUIMessage({
|
||||
action = 'HIDE_TEXT',
|
||||
})
|
||||
end
|
||||
|
||||
local function drawText(text, position)
|
||||
if type(position) ~= 'string' then position = 'left' end
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'DRAW_TEXT',
|
||||
data = {
|
||||
text = text,
|
||||
position = position
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
local function changeText(text, position)
|
||||
if type(position) ~= 'string' then position = 'left' end
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'CHANGE_TEXT',
|
||||
data = {
|
||||
text = text,
|
||||
position = position
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
local function keyPressed()
|
||||
CreateThread(function() -- Not sure if a thread is needed but why not eh?
|
||||
SendNUIMessage({
|
||||
action = 'KEY_PRESSED',
|
||||
})
|
||||
Wait(500)
|
||||
hideText()
|
||||
end)
|
||||
end
|
||||
|
||||
RegisterNetEvent('qb-core:client:DrawText', function(text, position)
|
||||
drawText(text, position)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qb-core:client:ChangeText', function(text, position)
|
||||
changeText(text, position)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qb-core:client:HideText', function()
|
||||
hideText()
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qb-core:client:KeyPressed', function()
|
||||
keyPressed()
|
||||
end)
|
||||
|
||||
exports('DrawText', drawText)
|
||||
exports('ChangeText', changeText)
|
||||
exports('HideText', hideText)
|
||||
exports('KeyPressed', keyPressed)
|
||||
@@ -1,20 +0,0 @@
|
||||
RegisterNUICallback('saveConfig', function(data, cb)
|
||||
local file = data.file
|
||||
local configData = data.data
|
||||
TriggerServerEvent('qb-core:server:configEditor', file, configData)
|
||||
print("Saving config for file:", file)
|
||||
cb('ok')
|
||||
end)
|
||||
|
||||
RegisterNUICallback('closeEditor', function(data, cb)
|
||||
SetNuiFocus(false, false)
|
||||
cb('ok')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qb-core:client:configEditor', function(allData)
|
||||
SendNUIMessage({
|
||||
action = 'populateData',
|
||||
data = allData
|
||||
})
|
||||
SetNuiFocus(true, true)
|
||||
end)
|
||||
@@ -0,0 +1,279 @@
|
||||
-- Player load and unload handling
|
||||
-- New method for checking if logged in across all scripts (optional)
|
||||
-- if LocalPlayer.state['isLoggedIn'] then
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
|
||||
ShutdownLoadingScreenNui()
|
||||
LocalPlayer.state:set('isLoggedIn', true, false)
|
||||
if not QBCore.Config.Server.PVP then return end
|
||||
SetCanAttackFriendly(PlayerPedId(), true, false)
|
||||
NetworkSetFriendlyFireOption(true)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
|
||||
LocalPlayer.state:set('isLoggedIn', false, false)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:PvpHasToggled', function(pvp_state)
|
||||
SetCanAttackFriendly(PlayerPedId(), pvp_state, false)
|
||||
NetworkSetFriendlyFireOption(pvp_state)
|
||||
end)
|
||||
-- Teleport Commands
|
||||
|
||||
RegisterNetEvent('QBCore:Command:TeleportToPlayer', function(coords)
|
||||
local ped = PlayerPedId()
|
||||
SetPedCoordsKeepVehicle(ped, coords.x, coords.y, coords.z)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Command:TeleportToCoords', function(x, y, z, h)
|
||||
local ped = PlayerPedId()
|
||||
SetPedCoordsKeepVehicle(ped, x, y, z)
|
||||
SetEntityHeading(ped, h or GetEntityHeading(ped))
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Command:GoToMarker', function()
|
||||
local PlayerPedId = PlayerPedId
|
||||
local GetEntityCoords = GetEntityCoords
|
||||
local GetGroundZFor_3dCoord = GetGroundZFor_3dCoord
|
||||
|
||||
local blipMarker <const> = GetFirstBlipInfoId(8)
|
||||
if not DoesBlipExist(blipMarker) then
|
||||
QBCore.Functions.Notify(Lang:t('error.no_waypoint'), 'error', 5000)
|
||||
return 'marker'
|
||||
end
|
||||
|
||||
-- Fade screen to hide how clients get teleported.
|
||||
DoScreenFadeOut(650)
|
||||
while not IsScreenFadedOut() do
|
||||
Wait(0)
|
||||
end
|
||||
|
||||
local ped, coords <const> = PlayerPedId(), GetBlipInfoIdCoord(blipMarker)
|
||||
local vehicle = GetVehiclePedIsIn(ped, false)
|
||||
local oldCoords <const> = GetEntityCoords(ped)
|
||||
|
||||
-- Unpack coords instead of having to unpack them while iterating.
|
||||
-- 825.0 seems to be the max a player can reach while 0.0 being the lowest.
|
||||
local x, y, groundZ, Z_START = coords['x'], coords['y'], 850.0, 950.0
|
||||
local found = false
|
||||
if vehicle > 0 then
|
||||
FreezeEntityPosition(vehicle, true)
|
||||
else
|
||||
FreezeEntityPosition(ped, true)
|
||||
end
|
||||
|
||||
for i = Z_START, 0, -25.0 do
|
||||
local z = i
|
||||
if (i % 2) ~= 0 then
|
||||
z = Z_START - i
|
||||
end
|
||||
|
||||
NewLoadSceneStart(x, y, z, x, y, z, 50.0, 0)
|
||||
local curTime = GetGameTimer()
|
||||
while IsNetworkLoadingScene() do
|
||||
if GetGameTimer() - curTime > 1000 then
|
||||
break
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
NewLoadSceneStop()
|
||||
SetPedCoordsKeepVehicle(ped, x, y, z)
|
||||
|
||||
while not HasCollisionLoadedAroundEntity(ped) do
|
||||
RequestCollisionAtCoord(x, y, z)
|
||||
if GetGameTimer() - curTime > 1000 then
|
||||
break
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
|
||||
-- Get ground coord. As mentioned in the natives, this only works if the client is in render distance.
|
||||
found, groundZ = GetGroundZFor_3dCoord(x, y, z, false);
|
||||
if found then
|
||||
Wait(0)
|
||||
SetPedCoordsKeepVehicle(ped, x, y, groundZ)
|
||||
break
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
|
||||
-- Remove black screen once the loop has ended.
|
||||
DoScreenFadeIn(650)
|
||||
if vehicle > 0 then
|
||||
FreezeEntityPosition(vehicle, false)
|
||||
else
|
||||
FreezeEntityPosition(ped, false)
|
||||
end
|
||||
|
||||
if not found then
|
||||
-- If we can't find the coords, set the coords to the old ones.
|
||||
-- We don't unpack them before since they aren't in a loop and only called once.
|
||||
SetPedCoordsKeepVehicle(ped, oldCoords['x'], oldCoords['y'], oldCoords['z'] - 1.0)
|
||||
QBCore.Functions.Notify(Lang:t('error.tp_error'), 'error', 5000)
|
||||
end
|
||||
|
||||
-- If Z coord was found, set coords in found coords.
|
||||
SetPedCoordsKeepVehicle(ped, x, y, groundZ)
|
||||
QBCore.Functions.Notify(Lang:t('success.teleported_waypoint'), 'success', 5000)
|
||||
end)
|
||||
|
||||
-- Vehicle Commands
|
||||
|
||||
RegisterNetEvent('QBCore:Command:SpawnVehicle', function(vehName)
|
||||
local ped = PlayerPedId()
|
||||
local hash = joaat(vehName)
|
||||
local veh = GetVehiclePedIsUsing(ped)
|
||||
if not IsModelInCdimage(hash) then return end
|
||||
RequestModel(hash)
|
||||
while not HasModelLoaded(hash) do
|
||||
Wait(0)
|
||||
end
|
||||
|
||||
if IsPedInAnyVehicle(ped) then
|
||||
SetEntityAsMissionEntity(veh, true, true)
|
||||
DeleteVehicle(veh)
|
||||
end
|
||||
|
||||
local vehicle = CreateVehicle(hash, GetEntityCoords(ped), GetEntityHeading(ped), true, false)
|
||||
TaskWarpPedIntoVehicle(ped, vehicle, -1)
|
||||
SetVehicleFuelLevel(vehicle, 100.0)
|
||||
SetVehicleDirtLevel(vehicle, 0.0)
|
||||
SetModelAsNoLongerNeeded(hash)
|
||||
TriggerEvent('vehiclekeys:client:SetOwner', QBCore.Functions.GetPlate(vehicle))
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Command:DeleteVehicle', function()
|
||||
local ped = PlayerPedId()
|
||||
local veh = GetVehiclePedIsUsing(ped)
|
||||
if veh ~= 0 then
|
||||
SetEntityAsMissionEntity(veh, true, true)
|
||||
DeleteVehicle(veh)
|
||||
else
|
||||
local pcoords = GetEntityCoords(ped)
|
||||
local vehicles = GetGamePool('CVehicle')
|
||||
for _, v in pairs(vehicles) do
|
||||
if #(pcoords - GetEntityCoords(v)) <= 5.0 then
|
||||
SetEntityAsMissionEntity(v, true, true)
|
||||
DeleteVehicle(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:VehicleInfo', function(info)
|
||||
local plate = QBCore.Functions.GetPlate(info.vehicle)
|
||||
local hasKeys = true
|
||||
|
||||
if GetResourceState('qb-vehiclekeys') == 'started' then
|
||||
hasKeys = exports['qb-vehiclekeys']:HasKeys(plate)
|
||||
end
|
||||
|
||||
local data = {
|
||||
vehicle = info.vehicle,
|
||||
seat = info.seat,
|
||||
name = info.modelName,
|
||||
plate = plate,
|
||||
driver = GetPedInVehicleSeat(info.vehicle, -1),
|
||||
inseat = GetPedInVehicleSeat(info.vehicle, info.seat),
|
||||
haskeys = hasKeys
|
||||
}
|
||||
|
||||
TriggerEvent('QBCore:Client:' .. info.event .. 'Vehicle', data)
|
||||
end)
|
||||
|
||||
-- Other stuff
|
||||
|
||||
RegisterNetEvent('QBCore:Player:SetPlayerData', function(val)
|
||||
QBCore.PlayerData = val
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Player:UpdatePlayerData', function()
|
||||
TriggerServerEvent('QBCore:UpdatePlayer')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Notify', function(text, type, length, icon)
|
||||
QBCore.Functions.Notify(text, type, length, icon)
|
||||
end)
|
||||
|
||||
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon.
|
||||
RegisterNetEvent('QBCore:Client:UseItem', function(item)
|
||||
QBCore.Debug(string.format('%s triggered QBCore:Client:UseItem by ID %s with the following data. This event is deprecated due to exploitation, and will be removed soon. Check qb-inventory for the right use on this event.', GetInvokingResource(), GetPlayerServerId(PlayerId())))
|
||||
QBCore.Debug(item)
|
||||
end)
|
||||
|
||||
RegisterNUICallback('getNotifyConfig', function(_, cb)
|
||||
cb(QBCore.Config.Notify)
|
||||
end)
|
||||
|
||||
-- Callback Events --
|
||||
|
||||
-- Client Callback
|
||||
RegisterNetEvent('QBCore:Client:TriggerClientCallback', function(name, ...)
|
||||
if not QBCore.ClientCallbacks[name] then return end
|
||||
|
||||
QBCore.ClientCallbacks[name](function(...)
|
||||
TriggerServerEvent('QBCore:Server:TriggerClientCallback', name, ...)
|
||||
end, ...)
|
||||
end)
|
||||
|
||||
-- Server Callback
|
||||
RegisterNetEvent('QBCore:Client:TriggerCallback', function(name, ...)
|
||||
if QBCore.ServerCallbacks[name] then
|
||||
QBCore.ServerCallbacks[name].promise:resolve(...)
|
||||
|
||||
if QBCore.ServerCallbacks[name].callback then
|
||||
QBCore.ServerCallbacks[name].callback(...)
|
||||
end
|
||||
|
||||
QBCore.ServerCallbacks[name] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
-- Me command
|
||||
|
||||
local function Draw3DText(coords, str)
|
||||
local onScreen, worldX, worldY = World3dToScreen2d(coords.x, coords.y, coords.z)
|
||||
local camCoords = GetGameplayCamCoord()
|
||||
local scale = 200 / (GetGameplayCamFov() * #(camCoords - coords))
|
||||
if onScreen then
|
||||
SetTextScale(1.0, 0.5 * scale)
|
||||
SetTextFont(4)
|
||||
SetTextColour(255, 255, 255, 255)
|
||||
SetTextEdge(2, 0, 0, 0, 150)
|
||||
SetTextProportional(1)
|
||||
SetTextOutline()
|
||||
SetTextCentre(1)
|
||||
BeginTextCommandDisplayText('STRING')
|
||||
AddTextComponentSubstringPlayerName(str)
|
||||
EndTextCommandDisplayText(worldX, worldY)
|
||||
end
|
||||
end
|
||||
|
||||
RegisterNetEvent('QBCore:Command:ShowMe3D', function(senderId, msg)
|
||||
local sender = GetPlayerFromServerId(senderId)
|
||||
CreateThread(function()
|
||||
local displayTime = 5000 + GetGameTimer()
|
||||
while displayTime > GetGameTimer() do
|
||||
local targetPed = GetPlayerPed(sender)
|
||||
local tCoords = GetEntityCoords(targetPed)
|
||||
Draw3DText(tCoords, msg)
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
|
||||
-- Listen to Shared being updated
|
||||
RegisterNetEvent('QBCore:Client:OnSharedUpdate', function(tableName, key, value)
|
||||
QBCore.Shared[tableName][key] = value
|
||||
TriggerEvent('QBCore:Client:UpdateObject')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnSharedUpdateMultiple', function(tableName, values)
|
||||
for key, value in pairs(values) do
|
||||
QBCore.Shared[tableName][key] = value
|
||||
end
|
||||
TriggerEvent('QBCore:Client:UpdateObject')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:SharedUpdate', function(table)
|
||||
QBCore.Shared = table
|
||||
end)
|
||||
+1077
-2
File diff suppressed because it is too large
Load Diff
+3
-13
@@ -1,11 +1,6 @@
|
||||
-- CreateThread(function()
|
||||
-- while not NetworkIsSessionStarted() do Wait(500) end
|
||||
-- print('player has loaded at this point')
|
||||
-- end)
|
||||
|
||||
CreateThread(function()
|
||||
while true do
|
||||
local sleep = 1000
|
||||
local sleep = 0
|
||||
if LocalPlayer.state.isLoggedIn then
|
||||
sleep = (1000 * 60) * QBCore.Config.UpdateInterval
|
||||
TriggerServerEvent('QBCore:UpdatePlayer')
|
||||
@@ -17,16 +12,11 @@ end)
|
||||
CreateThread(function()
|
||||
while true do
|
||||
if LocalPlayer.state.isLoggedIn then
|
||||
if (LocalPlayer.state['metadata:hunger'] <= 0 or LocalPlayer.state['metadata:thirst'] <= 0)
|
||||
and not (LocalPlayer.state['metadata:isdead'] or LocalPlayer.state['metadata:inlaststand']) then
|
||||
if (QBCore.PlayerData.metadata['hunger'] <= 0 or QBCore.PlayerData.metadata['thirst'] <= 0) and not (QBCore.PlayerData.metadata['isdead'] or QBCore.PlayerData.metadata['inlaststand']) then
|
||||
local ped = PlayerPedId()
|
||||
local currentHealth = GetEntityHealth(ped)
|
||||
local decreaseThreshold = math.random(5, 10)
|
||||
if currentHealth - decreaseThreshold > 0 then
|
||||
SetEntityHealth(ped, currentHealth - decreaseThreshold)
|
||||
else
|
||||
SetEntityHealth(ped, 0)
|
||||
end
|
||||
SetEntityHealth(ped, currentHealth - decreaseThreshold)
|
||||
end
|
||||
end
|
||||
Wait(QBCore.Config.StatusInterval)
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
QBCore = {}
|
||||
QBCore.PlayerData = {}
|
||||
QBCore.Config = QBConfig
|
||||
QBCore.Shared = QBShared
|
||||
QBCore.ClientCallbacks = {}
|
||||
QBCore.ServerCallbacks = {}
|
||||
|
||||
-- Get the full QBCore object (default behavior):
|
||||
-- local QBCore = GetCoreObject()
|
||||
|
||||
-- Get only specific parts of QBCore:
|
||||
-- local QBCore = GetCoreObject({'Players', 'Config'})
|
||||
|
||||
local function GetCoreObject(filters)
|
||||
if not filters then return QBCore end
|
||||
local results = {}
|
||||
for i = 1, #filters do
|
||||
local key = filters[i]
|
||||
if QBCore[key] then
|
||||
results[key] = QBCore[key]
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
exports('GetCoreObject', GetCoreObject)
|
||||
|
||||
local function GetSharedItems()
|
||||
return QBShared.Items
|
||||
end
|
||||
exports('GetSharedItems', GetSharedItems)
|
||||
|
||||
local function GetSharedVehicles()
|
||||
return QBShared.Vehicles
|
||||
end
|
||||
exports('GetSharedVehicles', GetSharedVehicles)
|
||||
|
||||
local function GetSharedWeapons()
|
||||
return QBShared.Weapons
|
||||
end
|
||||
exports('GetSharedWeapons', GetSharedWeapons)
|
||||
|
||||
local function GetSharedJobs()
|
||||
return QBShared.Jobs
|
||||
end
|
||||
exports('GetSharedJobs', GetSharedJobs)
|
||||
|
||||
local function GetSharedGangs()
|
||||
return QBShared.Gangs
|
||||
end
|
||||
exports('GetSharedGangs', GetSharedGangs)
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
QBConfig = {}
|
||||
|
||||
QBConfig.MaxPlayers = GetConvarInt('sv_maxclients', 48) -- Gets max players from config file, default 48
|
||||
QBConfig.DefaultSpawn = vector4(-1035.71, -2731.87, 12.86, 0.0)
|
||||
QBConfig.UpdateInterval = 5 -- how often to update player data in minutes
|
||||
QBConfig.StatusInterval = 5000 -- how often to check hunger/thirst status in milliseconds
|
||||
|
||||
QBConfig.Money = {}
|
||||
QBConfig.Money.MoneyTypes = { cash = 500, bank = 5000, crypto = 0 } -- type = startamount - Add or remove money types for your server (for ex. blackmoney = 0), remember once added it will not be removed from the database!
|
||||
QBConfig.Money.DontAllowMinus = { 'cash', 'crypto' } -- Money that is not allowed going in minus
|
||||
QBConfig.Money.MinusLimit = -5000 -- The maximum amount you can be negative
|
||||
QBConfig.Money.PayCheckTimeOut = 10 -- The time in minutes that it will give the paycheck
|
||||
QBConfig.Money.PayCheckSociety = false -- If true paycheck will come from the society account that the player is employed at, requires qb-management
|
||||
|
||||
QBConfig.Player = {}
|
||||
QBConfig.Player.HungerRate = 4.2 -- Rate at which hunger goes down.
|
||||
QBConfig.Player.ThirstRate = 3.8 -- Rate at which thirst goes down.
|
||||
QBConfig.Player.Bloodtypes = {
|
||||
'A+', 'A-', 'B+', 'B-', 'AB+', 'AB-', 'O+', 'O-',
|
||||
}
|
||||
|
||||
QBConfig.Player.PlayerDefaults = {
|
||||
citizenid = function() return QBCore.Player.CreateCitizenId() end,
|
||||
cid = 1,
|
||||
money = function()
|
||||
local moneyDefaults = {}
|
||||
for moneytype, startamount in pairs(QBConfig.Money.MoneyTypes) do
|
||||
moneyDefaults[moneytype] = startamount
|
||||
end
|
||||
return moneyDefaults
|
||||
end,
|
||||
optin = true,
|
||||
charinfo = {
|
||||
firstname = 'Firstname',
|
||||
lastname = 'Lastname',
|
||||
birthdate = '00-00-0000',
|
||||
gender = 0,
|
||||
nationality = 'USA',
|
||||
phone = function() return QBCore.Functions.CreatePhoneNumber() end,
|
||||
account = function() return QBCore.Functions.CreateAccountNumber() end
|
||||
},
|
||||
job = {
|
||||
name = 'unemployed',
|
||||
label = 'Civilian',
|
||||
payment = 10,
|
||||
type = 'none',
|
||||
onduty = false,
|
||||
isboss = false,
|
||||
grade = {
|
||||
name = 'Freelancer',
|
||||
level = 0
|
||||
}
|
||||
},
|
||||
gang = {
|
||||
name = 'none',
|
||||
label = 'No Gang Affiliation',
|
||||
isboss = false,
|
||||
grade = {
|
||||
name = 'none',
|
||||
level = 0
|
||||
}
|
||||
},
|
||||
metadata = {
|
||||
hunger = 100,
|
||||
thirst = 100,
|
||||
stress = 0,
|
||||
isdead = false,
|
||||
inlaststand = false,
|
||||
armor = 0,
|
||||
ishandcuffed = false,
|
||||
tracker = false,
|
||||
injail = 0,
|
||||
jailitems = {},
|
||||
status = {},
|
||||
phone = {},
|
||||
rep = {},
|
||||
currentapartment = nil,
|
||||
callsign = 'NO CALLSIGN',
|
||||
bloodtype = function() return QBConfig.Player.Bloodtypes[math.random(1, #QBConfig.Player.Bloodtypes)] end,
|
||||
fingerprint = function() return QBCore.Player.CreateFingerId() end,
|
||||
walletid = function() return QBCore.Player.CreateWalletId() end,
|
||||
criminalrecord = {
|
||||
hasRecord = false,
|
||||
date = nil
|
||||
},
|
||||
licences = {
|
||||
driver = true,
|
||||
business = false,
|
||||
weapon = false
|
||||
},
|
||||
inside = {
|
||||
house = nil,
|
||||
apartment = {
|
||||
apartmentType = nil,
|
||||
apartmentId = nil,
|
||||
}
|
||||
},
|
||||
phonedata = {
|
||||
SerialNumber = function() return QBCore.Player.CreateSerialNumber() end,
|
||||
InstalledApps = {}
|
||||
}
|
||||
},
|
||||
position = QBConfig.DefaultSpawn,
|
||||
items = {},
|
||||
}
|
||||
|
||||
QBConfig.Server = {} -- General server config
|
||||
QBConfig.Server.Closed = false -- Set server closed (no one can join except people with ace permission 'qbadmin.join')
|
||||
QBConfig.Server.ClosedReason = 'Server Closed' -- Reason message to display when people can't join the server
|
||||
QBConfig.Server.Uptime = 0 -- Time the server has been up.
|
||||
QBConfig.Server.Whitelist = false -- Enable or disable whitelist on the server
|
||||
QBConfig.Server.WhitelistPermission = 'admin' -- Permission that's able to enter the server when the whitelist is on
|
||||
QBConfig.Server.PVP = true -- Enable or disable pvp on the server (Ability to shoot other players)
|
||||
QBConfig.Server.Discord = '' -- Discord invite link
|
||||
QBConfig.Server.CheckDuplicateLicense = true -- Check for duplicate rockstar license on join
|
||||
QBConfig.Server.Permissions = { 'god', 'admin', 'mod' } -- Add as many groups as you want here after creating them in your server.cfg
|
||||
|
||||
QBConfig.Commands = {} -- Command Configuration
|
||||
QBConfig.Commands.OOCColor = { 255, 151, 133 } -- RGB color code for the OOC command
|
||||
|
||||
QBConfig.Notify = {}
|
||||
|
||||
QBConfig.Notify.NotificationStyling = {
|
||||
group = false, -- Allow notifications to stack with a badge instead of repeating
|
||||
position = 'right', -- top-left | top-right | bottom-left | bottom-right | top | bottom | left | right | center
|
||||
progress = true -- Display Progress Bar
|
||||
}
|
||||
|
||||
-- These are how you define different notification variants
|
||||
-- The "color" key is background of the notification
|
||||
-- The "icon" key is the css-icon code, this project uses `Material Icons` & `Font Awesome`
|
||||
QBConfig.Notify.VariantDefinitions = {
|
||||
success = {
|
||||
classes = 'success',
|
||||
icon = 'check_circle'
|
||||
},
|
||||
primary = {
|
||||
classes = 'primary',
|
||||
icon = 'notifications'
|
||||
},
|
||||
warning = {
|
||||
classes = 'warning',
|
||||
icon = 'warning'
|
||||
},
|
||||
error = {
|
||||
classes = 'error',
|
||||
icon = 'error'
|
||||
},
|
||||
police = {
|
||||
classes = 'police',
|
||||
icon = 'local_police'
|
||||
},
|
||||
ambulance = {
|
||||
classes = 'ambulance',
|
||||
icon = 'fas fa-ambulance'
|
||||
}
|
||||
}
|
||||
+26
-14
@@ -2,37 +2,49 @@ fx_version 'cerulean'
|
||||
game 'gta5'
|
||||
lua54 'yes'
|
||||
author 'Kakarot'
|
||||
description 'Core resource for the framework'
|
||||
version '2.0.0'
|
||||
description 'Core resource for the framework, contains all the core functionality and features'
|
||||
version '1.3.0'
|
||||
|
||||
shared_scripts {
|
||||
'config.lua',
|
||||
'shared/locale.lua',
|
||||
'locale/en.lua',
|
||||
'locale/*.lua',
|
||||
'shared/lua/core.lua',
|
||||
'shared/lua/loader.lua',
|
||||
'shared/lua/functions.lua',
|
||||
'shared/main.lua',
|
||||
'shared/items.lua',
|
||||
'shared/jobs.lua',
|
||||
'shared/vehicles.lua',
|
||||
'shared/gangs.lua',
|
||||
'shared/weapons.lua',
|
||||
'shared/locations.lua'
|
||||
}
|
||||
|
||||
client_scripts {
|
||||
'client/*.lua'
|
||||
'client/main.lua',
|
||||
'client/functions.lua',
|
||||
'client/loops.lua',
|
||||
'client/events.lua',
|
||||
'client/drawtext.lua'
|
||||
}
|
||||
|
||||
server_scripts {
|
||||
'@oxmysql/lib/MySQL.lua',
|
||||
'server/*.lua',
|
||||
'server/main.lua',
|
||||
'server/functions.lua',
|
||||
'server/player.lua',
|
||||
'server/events.lua',
|
||||
'server/commands.lua',
|
||||
'server/exports.lua',
|
||||
'server/debug.lua'
|
||||
}
|
||||
|
||||
ui_page 'html/index.html'
|
||||
|
||||
files {
|
||||
'html/index.html',
|
||||
'html/style.css',
|
||||
'html/script.js',
|
||||
'shared/json/jobs.json',
|
||||
'shared/json/gangs.json',
|
||||
'shared/json/items.json',
|
||||
'shared/json/vehicles.json',
|
||||
'shared/json/weapons.json'
|
||||
'html/css/style.css',
|
||||
'html/css/drawtext.css',
|
||||
'html/js/*.js'
|
||||
}
|
||||
|
||||
dependency 'oxmysql'
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
:root {
|
||||
/* Typography */
|
||||
--font-primary: "Exo 2", sans-serif;
|
||||
--font-weight-regular: 400;
|
||||
--font-weight-medium: 500;
|
||||
--font-weight-bold: 700;
|
||||
--font-weight-light: 300;
|
||||
/* Colors */
|
||||
--md-primary: #1c75d2;
|
||||
--md-primary-container: #6facec;
|
||||
--md-error: #c10114;
|
||||
--md-error-container: #fe4255;
|
||||
--md-success: #20bb44;
|
||||
--md-success-container: #6ae587;
|
||||
--md-warning: #ff9800;
|
||||
--md-warning-container: #ffc107;
|
||||
--md-info: #2197f2;
|
||||
--md-info-container: #7ac1f7;
|
||||
--md-surface: #fffbff;
|
||||
--md-on-surface: #1c1b1f;
|
||||
|
||||
/* Custom Variables */
|
||||
--primary-bg: rgba(23, 23, 23, 90%);
|
||||
--active-bg: var(--md-error);
|
||||
--font-color: white;
|
||||
|
||||
/* Elevation */
|
||||
--md-elevation-1: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
|
||||
|
||||
/* Border Radius */
|
||||
--md-radius-small: 5px;
|
||||
--md-radius-medium: 10px;
|
||||
--md-radius-extra-small: 0.15rem;
|
||||
}
|
||||
|
||||
#drawtext-container {
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: var(--font-primary) !important;
|
||||
font-weight: var(--font-weight-light);
|
||||
}
|
||||
|
||||
.text {
|
||||
position: absolute;
|
||||
background: var(--primary-bg);
|
||||
color: var(--font-color);
|
||||
margin-top: 0.5rem;
|
||||
padding: 0.45rem;
|
||||
border-radius: var(--md-radius-extra-small);
|
||||
box-shadow: var(--md-elevation-1);
|
||||
}
|
||||
|
||||
@media (width: 3840px) and (height: 2160px) {
|
||||
#drawtext-container {
|
||||
display: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: var(--font-primary) !important;
|
||||
font-weight: var(--font-weight-light);
|
||||
font-size: 1.5vh;
|
||||
}
|
||||
}
|
||||
|
||||
.text.pressed {
|
||||
background: var(--active-bg);
|
||||
}
|
||||
|
||||
.top {
|
||||
left: 45vw;
|
||||
top: -100px;
|
||||
}
|
||||
|
||||
.top.show {
|
||||
transition: 0.5s;
|
||||
top: 10px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.top.hide {
|
||||
transition: 0.5s;
|
||||
top: -100px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.right {
|
||||
top: 50%;
|
||||
right: -100px;
|
||||
}
|
||||
|
||||
.right.show {
|
||||
transition: 0.5s;
|
||||
right: 10px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.right.hide {
|
||||
transition: 0.5s;
|
||||
right: -100px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.left {
|
||||
top: 50%;
|
||||
left: -100px;
|
||||
}
|
||||
|
||||
.left.show {
|
||||
transition: 0.5s;
|
||||
left: 10px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.left.hide {
|
||||
transition: 0.5s;
|
||||
left: -100px;
|
||||
opacity: 0;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
:root {
|
||||
/* Typography */
|
||||
--font-primary: "Exo 2", sans-serif;
|
||||
--font-weight-regular: 400;
|
||||
--font-weight-medium: 500;
|
||||
--font-weight-bold: 700;
|
||||
--font-weight-light: 300;
|
||||
|
||||
/* Colors */
|
||||
--md-primary: #0061a4;
|
||||
--md-on-primary: #ffffff;
|
||||
--md-primary-container: #d1e4ff;
|
||||
--md-on-primary-container: #001d36;
|
||||
|
||||
--md-error: #ba1a1a;
|
||||
--md-on-error: #ffffff;
|
||||
--md-error-container: #ffdad6;
|
||||
--md-on-error-container: #410002;
|
||||
|
||||
--md-success: #006e1c;
|
||||
--md-on-success: #ffffff;
|
||||
--md-success-container: #9df996;
|
||||
--md-on-success-container: #002106;
|
||||
|
||||
--md-warning: #7d5800;
|
||||
--md-on-warning: #ffffff;
|
||||
--md-warning-container: #ffdf93;
|
||||
--md-on-warning-container: #271900;
|
||||
|
||||
--md-info: #0062a1;
|
||||
--md-on-info: #ffffff;
|
||||
--md-info-container: #d0e4ff;
|
||||
--md-on-info-container: #001d35;
|
||||
|
||||
/* Surface colors */
|
||||
--md-surface: #fcfcff;
|
||||
--md-on-surface: #1a1c1e;
|
||||
--md-surface-variant: #dfe2eb;
|
||||
--md-on-surface-variant: #43474e;
|
||||
|
||||
/* Elevation */
|
||||
--md-elevation-1: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
|
||||
|
||||
/* Border Radius */
|
||||
--md-radius-small: 4px;
|
||||
--md-radius-medium: 8px;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: var(--font-primary);
|
||||
font-weight: var(--font-weight-regular);
|
||||
}
|
||||
|
||||
html::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (width: 3840px) and (height: 2160px) {
|
||||
.success {
|
||||
background-color: rgba(23, 23, 23, 90%);
|
||||
color: var(--md-on-surface);
|
||||
box-shadow: var(--md-elevation-1);
|
||||
border-left: 0.5rem solid var(--md-success);
|
||||
font-size: 1.5vh;
|
||||
}
|
||||
|
||||
.primary {
|
||||
background-color: rgba(23, 23, 23, 90%);
|
||||
color: var(--md-on-surface);
|
||||
box-shadow: var(--md-elevation-1);
|
||||
border-left: 5px solid var(--md-primary);
|
||||
font-size: 1.5vh;
|
||||
}
|
||||
|
||||
.error {
|
||||
background-color: rgba(23, 23, 23, 90%);
|
||||
color: var(--md-on-surface);
|
||||
box-shadow: var(--md-elevation-1);
|
||||
border-left: 5px solid var(--md-error);
|
||||
font-size: 1.5vh;
|
||||
}
|
||||
|
||||
.warning {
|
||||
background-color: rgba(23, 23, 23, 90%);
|
||||
color: var(--md-on-surface);
|
||||
box-shadow: var(--md-elevation-1);
|
||||
border-left: 5px solid var(--md-warning);
|
||||
font-size: 1.5vh;
|
||||
}
|
||||
|
||||
.police {
|
||||
background-color: rgba(23, 23, 23, 90%);
|
||||
color: var(--md-on-surface);
|
||||
box-shadow: var(--md-elevation-1);
|
||||
border-left: 5px solid var(--md-info);
|
||||
font-size: 1.5vh;
|
||||
}
|
||||
|
||||
.ambulance {
|
||||
background-color: rgba(23, 23, 23, 90%);
|
||||
color: var(--md-on-surface);
|
||||
box-shadow: var(--md-elevation-1);
|
||||
border-left: 5px solid var(--md-error);
|
||||
font-size: 1.5vh;
|
||||
}
|
||||
}
|
||||
|
||||
.success {
|
||||
background-color: var(--md-success-container);
|
||||
color: var(--md-on-success-container);
|
||||
padding: 12px 16px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.primary {
|
||||
background-color: var(--md-primary-container);
|
||||
color: var(--md-on-primary-container);
|
||||
padding: 12px 16px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.warning {
|
||||
background-color: var(--md-warning-container);
|
||||
color: var(--md-on-warning-container);
|
||||
padding: 12px 16px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.error {
|
||||
background-color: var(--md-error-container);
|
||||
color: var(--md-on-error-container);
|
||||
padding: 12px 16px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.police {
|
||||
background-color: var(--md-info-container);
|
||||
color: var(--md-on-info-container);
|
||||
padding: 12px 16px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.ambulance {
|
||||
background-color: var(--md-error-container);
|
||||
color: var(--md-on-error-container);
|
||||
padding: 12px 16px;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
+14
-97
@@ -1,103 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>QB Config Editor</title>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;500&display=swap" rel="stylesheet"/>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@24,400,0,0"/>
|
||||
<link rel="stylesheet" href="style.css"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Exo+2:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
|
||||
<link href="https://cdn.jsdelivr.net/npm/quasar@2.12.0/dist/quasar.prod.css" rel="stylesheet" type="text/css" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" type="text/css" />
|
||||
<link href="css/style.css" rel="stylesheet" />
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js" defer></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/quasar@2.12.0/dist/quasar.umd.prod.js" defer></script>
|
||||
<script type="module" src="js/app.js"></script>
|
||||
<script src="js/drawtext.js"></script>
|
||||
<link rel="stylesheet" href="css/drawtext.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="editor-container">
|
||||
<header>
|
||||
<h1>QB Config Editor</h1>
|
||||
<div class="controls">
|
||||
<button id="save-btn">
|
||||
<span class="material-symbols-rounded">save</span>
|
||||
Save Changes
|
||||
</button>
|
||||
<button id="close-btn">
|
||||
<span class="material-symbols-rounded">close</span>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content">
|
||||
<div class="sidebar">
|
||||
<h2>Files</h2>
|
||||
<ul class="file-list">
|
||||
<li data-file="config">
|
||||
<span class="material-symbols-rounded">settings</span>
|
||||
Server Config
|
||||
</li>
|
||||
<li data-file="playerdata">
|
||||
<span class="material-symbols-rounded">account_circle</span>
|
||||
Player Data
|
||||
</li>
|
||||
<li data-file="jobs">
|
||||
<span class="material-symbols-rounded">work</span>
|
||||
Jobs
|
||||
</li>
|
||||
<li data-file="gangs">
|
||||
<span class="material-symbols-rounded">work</span>
|
||||
Gangs
|
||||
</li>
|
||||
<li data-file="items">
|
||||
<span class="material-symbols-rounded">inventory_2</span>
|
||||
Items
|
||||
</li>
|
||||
<li data-file="vehicles">
|
||||
<span class="material-symbols-rounded">directions_car</span>
|
||||
Vehicles
|
||||
</li>
|
||||
<li data-file="weapons">
|
||||
<span class="material-symbols-rounded">bolt</span>
|
||||
Weapons
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="main-content">
|
||||
<div class="search-container">
|
||||
<div class="search-wrapper">
|
||||
<span class="material-symbols-rounded search-icon">search</span>
|
||||
<input type="text" id="search-input" placeholder="Search..." aria-label="Search through config items"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="data-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="edit-modal" class="hidden">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h2>Edit Item</h2>
|
||||
<button id="close-modal-btn" aria-label="Close Modal">
|
||||
<span class="material-symbols-rounded">close</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div id="editor-form"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button id="cancel-edit-btn">Cancel</button>
|
||||
<button id="save-item-btn">
|
||||
<span class="material-symbols-rounded">check</span>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="q-app" style="min-height: 100vh"></div>
|
||||
<div id="drawtext-container">
|
||||
<div id="text" class="text"></div>
|
||||
</div>
|
||||
|
||||
<!-- Floating Action Button -->
|
||||
<button id="add-item-fab" class="fab" aria-label="Add New Item">
|
||||
<span class="material-symbols-rounded">add</span>
|
||||
</button>
|
||||
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import { determineStyleFromVariant, fetchNotifyConfig, NOTIFY_CONFIG } from "./config.js";
|
||||
|
||||
const { useQuasar } = Quasar;
|
||||
const { onMounted, onUnmounted } = Vue;
|
||||
|
||||
const fetchNui = async (evName, data) => {
|
||||
const resourceName = window.GetParentResourceName();
|
||||
|
||||
const rawResp = await fetch(`https://${resourceName}/${evName}`, {
|
||||
body: JSON.stringify(data),
|
||||
headers: {
|
||||
"Content-Type": "application/json; charset=UTF8",
|
||||
},
|
||||
method: "POST",
|
||||
});
|
||||
|
||||
return await rawResp.json();
|
||||
};
|
||||
|
||||
window.fetchNui = fetchNui;
|
||||
|
||||
const app = Vue.createApp({
|
||||
setup() {
|
||||
const $q = useQuasar();
|
||||
|
||||
const showNotif = async ({ data }) => {
|
||||
if (data?.action !== "notify") return;
|
||||
|
||||
const { text, length, type, caption, icon: dataIcon } = data;
|
||||
let { classes, icon } = determineStyleFromVariant(type);
|
||||
|
||||
if (dataIcon) {
|
||||
icon = dataIcon;
|
||||
}
|
||||
|
||||
if (!NOTIFY_CONFIG) {
|
||||
console.error("The notification config did not load properly, trying again for next time");
|
||||
await fetchNotifyConfig();
|
||||
if (NOTIFY_CONFIG) return showNotif({ data });
|
||||
}
|
||||
|
||||
$q.notify({
|
||||
message: text,
|
||||
multiLine: text.length > 100,
|
||||
group: NOTIFY_CONFIG.NotificationStyling.group ?? false,
|
||||
progress: NOTIFY_CONFIG.NotificationStyling.progress ?? true,
|
||||
position: NOTIFY_CONFIG.NotificationStyling.position ?? "right",
|
||||
timeout: length,
|
||||
caption,
|
||||
classes,
|
||||
icon,
|
||||
});
|
||||
};
|
||||
onMounted(() => {
|
||||
window.addEventListener("message", showNotif);
|
||||
});
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener("message", showNotif);
|
||||
});
|
||||
return {};
|
||||
},
|
||||
});
|
||||
|
||||
app.use(Quasar, { config: {} });
|
||||
app.mount("#q-app");
|
||||
@@ -0,0 +1,53 @@
|
||||
export let NOTIFY_CONFIG = null;
|
||||
|
||||
const defaultConfig = {
|
||||
NotificationStyling: {
|
||||
group: true,
|
||||
position: "top-right",
|
||||
progress: true,
|
||||
},
|
||||
VariantDefinitions: {
|
||||
success: {
|
||||
classes: "success",
|
||||
icon: "done",
|
||||
},
|
||||
primary: {
|
||||
classes: "primary",
|
||||
icon: "info",
|
||||
},
|
||||
error: {
|
||||
classes: "error",
|
||||
icon: "dangerous",
|
||||
},
|
||||
police: {
|
||||
classes: "police",
|
||||
icon: "local_police",
|
||||
},
|
||||
ambulance: {
|
||||
classes: "ambulance",
|
||||
icon: "fas fa-ambulance",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const determineStyleFromVariant = (variant) => {
|
||||
const variantData = NOTIFY_CONFIG.VariantDefinitions[variant];
|
||||
if (!variantData) throw new Error(`Style of type: ${variant}, does not exist in the config`);
|
||||
return variantData;
|
||||
};
|
||||
|
||||
export const fetchNotifyConfig = async () => {
|
||||
try {
|
||||
NOTIFY_CONFIG = await window.fetchNui("getNotifyConfig", {});
|
||||
if (!NOTIFY_CONFIG) {
|
||||
NOTIFY_CONFIG = defaultConfig;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch notification config, using default", error);
|
||||
NOTIFY_CONFIG = defaultConfig;
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("load", async () => {
|
||||
await fetchNotifyConfig();
|
||||
});
|
||||
@@ -0,0 +1,124 @@
|
||||
let direction = null;
|
||||
|
||||
const drawText = async (textData) => {
|
||||
const text = document.getElementById("text");
|
||||
let { position } = textData;
|
||||
switch (textData.position) {
|
||||
case "left":
|
||||
addClass(text, position);
|
||||
direction = "left";
|
||||
break;
|
||||
case "top":
|
||||
addClass(text, position);
|
||||
direction = "top";
|
||||
break;
|
||||
case "right":
|
||||
addClass(text, position);
|
||||
direction = "right";
|
||||
break;
|
||||
default:
|
||||
addClass(text, "left");
|
||||
direction = "left";
|
||||
break;
|
||||
}
|
||||
|
||||
text.innerHTML = textData.text;
|
||||
document.getElementById("drawtext-container").style.display = "block";
|
||||
await sleep(100);
|
||||
addClass(text, "show");
|
||||
};
|
||||
|
||||
const changeText = async (textData) => {
|
||||
const text = document.getElementById("text");
|
||||
let { position } = textData;
|
||||
|
||||
removeClass(text, "show");
|
||||
addClass(text, "pressed");
|
||||
addClass(text, "hide");
|
||||
|
||||
await sleep(500);
|
||||
removeClass(text, "left");
|
||||
removeClass(text, "right");
|
||||
removeClass(text, "top");
|
||||
removeClass(text, "bottom");
|
||||
removeClass(text, "hide");
|
||||
removeClass(text, "pressed");
|
||||
|
||||
switch (textData.position) {
|
||||
case "left":
|
||||
addClass(text, position);
|
||||
direction = "left";
|
||||
break;
|
||||
case "top":
|
||||
addClass(text, position);
|
||||
direction = "top";
|
||||
break;
|
||||
case "right":
|
||||
addClass(text, position);
|
||||
direction = "right";
|
||||
break;
|
||||
default:
|
||||
addClass(text, "left");
|
||||
direction = "left";
|
||||
break;
|
||||
}
|
||||
text.innerHTML = textData.text;
|
||||
|
||||
await sleep(100);
|
||||
text.classList.add("show");
|
||||
};
|
||||
|
||||
const hideText = async () => {
|
||||
const text = document.getElementById("text");
|
||||
removeClass(text, "show");
|
||||
addClass(text, "hide");
|
||||
|
||||
setTimeout(() => {
|
||||
removeClass(text, "left");
|
||||
removeClass(text, "right");
|
||||
removeClass(text, "top");
|
||||
removeClass(text, "bottom");
|
||||
removeClass(text, "hide");
|
||||
removeClass(text, "pressed");
|
||||
document.getElementById("drawtext-container").style.display = "none";
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
const keyPressed = () => {
|
||||
const text = document.getElementById("text");
|
||||
addClass(text, "pressed");
|
||||
};
|
||||
|
||||
window.addEventListener("message", (event) => {
|
||||
const data = event.data;
|
||||
const action = data.action;
|
||||
const textData = data.data;
|
||||
switch (action) {
|
||||
case "DRAW_TEXT":
|
||||
return drawText(textData);
|
||||
case "CHANGE_TEXT":
|
||||
return changeText(textData);
|
||||
case "HIDE_TEXT":
|
||||
return hideText();
|
||||
case "KEY_PRESSED":
|
||||
return keyPressed();
|
||||
default:
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
const sleep = (ms) => {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
};
|
||||
|
||||
const removeClass = (element, name) => {
|
||||
if (element.classList.contains(name)) {
|
||||
element.classList.remove(name);
|
||||
}
|
||||
};
|
||||
|
||||
const addClass = (element, name) => {
|
||||
if (!element.classList.contains(name)) {
|
||||
element.classList.add(name);
|
||||
}
|
||||
};
|
||||
-579
@@ -1,579 +0,0 @@
|
||||
// Main data store
|
||||
let configData = {};
|
||||
let currentFile = "config";
|
||||
let currentEditItem = null;
|
||||
let editPath = null;
|
||||
|
||||
// Elements
|
||||
const dataContainer = document.getElementById("data-container");
|
||||
const searchInput = document.getElementById("search-input");
|
||||
const saveBtn = document.getElementById("save-btn");
|
||||
const closeBtn = document.getElementById("close-btn");
|
||||
const editModal = document.getElementById("edit-modal");
|
||||
const closeModalBtn = document.getElementById("close-modal-btn");
|
||||
const saveItemBtn = document.getElementById("save-item-btn");
|
||||
const cancelEditBtn = document.getElementById("cancel-edit-btn");
|
||||
const editorForm = document.getElementById("editor-form");
|
||||
const fileListItems = document.querySelectorAll(".file-list li");
|
||||
const fabButton = document.getElementById("add-item-fab");
|
||||
let fileInput;
|
||||
|
||||
// Initialize
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
// Add event listeners
|
||||
searchInput.addEventListener("input", filterData);
|
||||
saveBtn.addEventListener("click", saveChanges);
|
||||
closeBtn.addEventListener("click", closeEditor);
|
||||
closeModalBtn.addEventListener("click", closeModal);
|
||||
saveItemBtn.addEventListener("click", saveItemChanges);
|
||||
cancelEditBtn.addEventListener("click", closeModal);
|
||||
fabButton.addEventListener("click", addItemModal);
|
||||
|
||||
fileListItems.forEach((item) => {
|
||||
item.addEventListener("click", () => {
|
||||
// Update active state
|
||||
fileListItems.forEach((i) => i.classList.remove("active"));
|
||||
item.classList.add("active");
|
||||
|
||||
// Change current file
|
||||
currentFile = item.dataset.file;
|
||||
|
||||
// Load file data - in a real implementation, this would trigger a fetch to the server
|
||||
// For now, we'll just use the data we already have
|
||||
currentFile = item.dataset.file;
|
||||
renderData();
|
||||
});
|
||||
});
|
||||
|
||||
// Listen for NUI messages from FiveM
|
||||
window.addEventListener("message", function (event) {
|
||||
const data = event.data;
|
||||
|
||||
if (data.action === "populateData") {
|
||||
// Expect data.data to be an object with each file's data
|
||||
configData = data.data;
|
||||
renderData();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const templates = {
|
||||
jobs: {
|
||||
defaultDuty: false,
|
||||
offDutyPay: false,
|
||||
type: "",
|
||||
label: "",
|
||||
grades: [
|
||||
{
|
||||
name: "",
|
||||
isboss: false,
|
||||
payment: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
gangs: {
|
||||
label: "",
|
||||
grades: [
|
||||
{
|
||||
name: "",
|
||||
isboss: false,
|
||||
level: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
items: {
|
||||
unique: false,
|
||||
shouldClose: false,
|
||||
useable: false,
|
||||
name: "",
|
||||
label: "",
|
||||
weight: 0,
|
||||
type: "",
|
||||
image: "",
|
||||
description: "",
|
||||
ammotype: "",
|
||||
},
|
||||
vehicles: {
|
||||
brand: "",
|
||||
price: 0,
|
||||
name: "",
|
||||
category: "",
|
||||
model: "",
|
||||
type: "",
|
||||
shop: ["pdm"],
|
||||
},
|
||||
weapons: {
|
||||
name: "",
|
||||
label: "",
|
||||
damageReason: "",
|
||||
weapontype: "",
|
||||
ammotype: "",
|
||||
},
|
||||
};
|
||||
|
||||
function addItemModal() {
|
||||
const modal = document.getElementById("edit-modal");
|
||||
const editorForm = document.getElementById("editor-form");
|
||||
|
||||
// Clear the form and set it up for adding a new item
|
||||
editorForm.innerHTML = ""; // Clear any existing content
|
||||
modal.classList.remove("hidden"); // Show the modal
|
||||
|
||||
// Get the template for the current category
|
||||
const template = templates[currentFile] || {};
|
||||
|
||||
// Add fields for the new item based on the template
|
||||
Object.entries(template).forEach(([key, value]) => {
|
||||
const formGroup = document.createElement("div");
|
||||
formGroup.className = "form-group";
|
||||
|
||||
const label = document.createElement("label");
|
||||
label.textContent = key;
|
||||
formGroup.appendChild(label);
|
||||
|
||||
if (typeof value === "boolean" || typeof value === "string" || typeof value === "number") {
|
||||
const field = createInputField({
|
||||
key,
|
||||
value,
|
||||
onChange: () => {}, // No need to handle it now, we'll read from DOM on save
|
||||
});
|
||||
formGroup.appendChild(field.querySelector("input"));
|
||||
} else if (Array.isArray(value)) {
|
||||
const arrayField = createArrayField({
|
||||
key,
|
||||
array: value,
|
||||
onItemChange: () => {}, // Again, no live tracking needed
|
||||
onItemRemove: (index) => {
|
||||
value.splice(index, 1);
|
||||
addItemModal(); // re-render modal
|
||||
},
|
||||
onItemAdd: () => {
|
||||
// Clone first item or fallback
|
||||
if (value.length > 0 && typeof value[0] === "object") {
|
||||
const newItem = {};
|
||||
Object.entries(value[0]).forEach(([k, v]) => {
|
||||
newItem[k] = typeof v === "number" ? 0 : typeof v === "boolean" ? false : "";
|
||||
});
|
||||
value.push(newItem);
|
||||
} else {
|
||||
value.push("");
|
||||
}
|
||||
addItemModal(); // re-render modal
|
||||
},
|
||||
});
|
||||
arrayField.id = `new-item-${key}`;
|
||||
formGroup.appendChild(arrayField);
|
||||
} else {
|
||||
const input = document.createElement("input");
|
||||
input.type = "text";
|
||||
input.className = "form-control";
|
||||
input.value = value;
|
||||
formGroup.appendChild(input);
|
||||
}
|
||||
|
||||
editorForm.appendChild(formGroup);
|
||||
});
|
||||
|
||||
// Add Save and Cancel buttons
|
||||
const saveButton = document.getElementById("save-item-btn");
|
||||
saveButton.onclick = saveNewItem;
|
||||
|
||||
const cancelButton = document.getElementById("cancel-edit-btn");
|
||||
cancelButton.onclick = () => {
|
||||
modal.classList.add("hidden"); // Hide the modal
|
||||
};
|
||||
}
|
||||
|
||||
function saveNewItem() {
|
||||
const template = templates[currentFile] || {};
|
||||
const newItem = {};
|
||||
|
||||
// Populate the new item based on the template
|
||||
Object.entries(template).forEach(([key, value]) => {
|
||||
if (Array.isArray(value)) {
|
||||
// Handle arrays
|
||||
const arrayContainer = document.getElementById(`new-item-${key}`);
|
||||
const arrayItems = Array.from(arrayContainer.querySelectorAll(".array-item"));
|
||||
newItem[key] = arrayItems.map((itemGroup) => {
|
||||
const item = {};
|
||||
Array.from(itemGroup.querySelectorAll("input")).forEach((input) => {
|
||||
const itemKey = input.dataset.itemKey;
|
||||
item[itemKey] = input.type === "number" ? parseFloat(input.value) || 0 : input.value;
|
||||
});
|
||||
return item;
|
||||
});
|
||||
} else {
|
||||
// Handle simple values
|
||||
const input = document.getElementById(`new-item-${key}`);
|
||||
if (input) {
|
||||
newItem[key] = input.type === "checkbox" ? input.checked : input.value;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Add the new item to the current category
|
||||
if (!configData[currentFile]) {
|
||||
configData[currentFile] = {};
|
||||
}
|
||||
const itemName = document.getElementById("new-item-name").value.trim();
|
||||
if (!itemName) {
|
||||
alert("Please provide a name for the new item.");
|
||||
return;
|
||||
}
|
||||
configData[currentFile][itemName] = newItem;
|
||||
|
||||
// Update the UI
|
||||
renderData();
|
||||
|
||||
// Close the modal
|
||||
document.getElementById("edit-modal").classList.add("hidden");
|
||||
}
|
||||
|
||||
// Render data in the container
|
||||
function renderData() {
|
||||
dataContainer.innerHTML = "";
|
||||
|
||||
if (!configData[currentFile]) {
|
||||
dataContainer.innerHTML = "<p>No data available for this file.</p>";
|
||||
return;
|
||||
}
|
||||
|
||||
const data = configData[currentFile];
|
||||
const searchText = searchInput.value.toLowerCase();
|
||||
|
||||
// For object-based data (like jobs)
|
||||
Object.entries(data).forEach(([key, value]) => {
|
||||
// If there's a search term, filter the data
|
||||
if (searchText && !key.toLowerCase().includes(searchText) && !JSON.stringify(value).toLowerCase().includes(searchText)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const card = document.createElement("div");
|
||||
card.className = "data-card";
|
||||
card.dataset.key = key;
|
||||
|
||||
// Create card header
|
||||
const header = document.createElement("h3");
|
||||
header.textContent = key;
|
||||
card.appendChild(header);
|
||||
|
||||
// Create properties section
|
||||
const properties = document.createElement("div");
|
||||
properties.className = "data-properties";
|
||||
|
||||
// Add main properties (not going too deep)
|
||||
Object.entries(value).forEach(([propKey, propValue]) => {
|
||||
// Skip complex objects for the card view
|
||||
if (typeof propValue === "object" && propValue !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
const property = document.createElement("div");
|
||||
property.className = "property";
|
||||
|
||||
const label = document.createElement("span");
|
||||
label.className = "property-label";
|
||||
label.textContent = propKey;
|
||||
|
||||
const val = document.createElement("span");
|
||||
val.className = "property-value";
|
||||
val.textContent = propValue;
|
||||
|
||||
property.appendChild(label);
|
||||
property.appendChild(val);
|
||||
properties.appendChild(property);
|
||||
});
|
||||
|
||||
card.appendChild(properties);
|
||||
|
||||
// Add click event to edit
|
||||
card.addEventListener("click", () => {
|
||||
editItem(key, value);
|
||||
});
|
||||
|
||||
dataContainer.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
// Create form for editing
|
||||
function createForm(obj) {
|
||||
editorForm.innerHTML = "";
|
||||
|
||||
const sortedKeys = Object.keys(obj).sort((a, b) => {
|
||||
const typeOrder = (value) => {
|
||||
if (typeof value === "boolean") return 0;
|
||||
if (typeof value === "string" || typeof value === "number") return 1;
|
||||
if (Array.isArray(value)) return 2;
|
||||
return 3;
|
||||
};
|
||||
return typeOrder(obj[a]) - typeOrder(obj[b]);
|
||||
});
|
||||
|
||||
sortedKeys.forEach((key) => {
|
||||
const value = obj[key];
|
||||
const formGroup = document.createElement("div");
|
||||
formGroup.className = "form-group";
|
||||
|
||||
const label = document.createElement("label");
|
||||
label.htmlFor = `field-${key}`;
|
||||
label.textContent = key;
|
||||
formGroup.appendChild(label);
|
||||
|
||||
if (typeof value === "boolean" || typeof value === "string" || typeof value === "number") {
|
||||
const field = createInputField({
|
||||
key,
|
||||
value,
|
||||
onChange: (val) => updateValue(key, val),
|
||||
});
|
||||
formGroup.appendChild(field.querySelector("input"));
|
||||
} else if (Array.isArray(value)) {
|
||||
const arrayField = createArrayField({
|
||||
key,
|
||||
array: value,
|
||||
onItemChange: (index, itemKey, val) => {
|
||||
if (itemKey) {
|
||||
updateArrayObjectValue(key, index, itemKey, val);
|
||||
} else {
|
||||
updateArrayValue(key, index, val);
|
||||
}
|
||||
},
|
||||
onItemRemove: (index) => removeArrayItem(key, index),
|
||||
onItemAdd: () => addArrayItem(key, value),
|
||||
});
|
||||
formGroup.appendChild(arrayField);
|
||||
} else {
|
||||
// Fallback for objects or unknown types
|
||||
const objectContainer = document.createElement("div");
|
||||
objectContainer.className = "complex-object";
|
||||
|
||||
const header = document.createElement("div");
|
||||
header.className = "complex-object-header";
|
||||
objectContainer.appendChild(header);
|
||||
|
||||
const textarea = document.createElement("textarea");
|
||||
textarea.className = "form-control";
|
||||
textarea.value = JSON.stringify(value, null, 2);
|
||||
textarea.dataset.key = key;
|
||||
|
||||
textarea.addEventListener("input", (e) => {
|
||||
try {
|
||||
const parsed = JSON.parse(e.target.value);
|
||||
updateValue(key, parsed);
|
||||
textarea.style.borderColor = "#3d3d3d";
|
||||
} catch (err) {
|
||||
textarea.style.borderColor = "#ff4d4d";
|
||||
}
|
||||
});
|
||||
|
||||
objectContainer.appendChild(textarea);
|
||||
formGroup.appendChild(objectContainer);
|
||||
}
|
||||
|
||||
editorForm.appendChild(formGroup);
|
||||
});
|
||||
}
|
||||
|
||||
// UTILS
|
||||
|
||||
function createInputField({ key, value, onChange }) {
|
||||
const formGroup = document.createElement("div");
|
||||
formGroup.className = "form-group";
|
||||
|
||||
const label = document.createElement("label");
|
||||
label.textContent = key;
|
||||
formGroup.appendChild(label);
|
||||
|
||||
const input = document.createElement("input");
|
||||
|
||||
if (typeof value === "boolean") {
|
||||
input.type = "checkbox";
|
||||
input.checked = value;
|
||||
} else if (typeof value === "number") {
|
||||
input.type = "number";
|
||||
input.value = value;
|
||||
} else {
|
||||
input.type = "text";
|
||||
input.value = value;
|
||||
}
|
||||
|
||||
input.className = "form-control";
|
||||
|
||||
input.addEventListener("input", (e) => {
|
||||
let newValue;
|
||||
if (input.type === "checkbox") {
|
||||
newValue = input.checked;
|
||||
} else if (input.type === "number") {
|
||||
newValue = parseFloat(e.target.value) || 0;
|
||||
} else {
|
||||
newValue = e.target.value;
|
||||
}
|
||||
|
||||
onChange(newValue);
|
||||
});
|
||||
|
||||
formGroup.appendChild(input);
|
||||
return formGroup;
|
||||
}
|
||||
|
||||
function createArrayField({ key, array, onItemChange, onItemRemove, onItemAdd }) {
|
||||
const container = document.createElement("div");
|
||||
container.className = "complex-object";
|
||||
|
||||
const header = document.createElement("div");
|
||||
header.className = "complex-object-header";
|
||||
|
||||
const addBtn = document.createElement("button");
|
||||
addBtn.className = "add-item-btn";
|
||||
addBtn.textContent = "Add Item";
|
||||
addBtn.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
onItemAdd();
|
||||
});
|
||||
|
||||
header.appendChild(addBtn);
|
||||
container.appendChild(header);
|
||||
|
||||
array.forEach((item, index) => {
|
||||
const arrayItem = document.createElement("div");
|
||||
arrayItem.className = "array-item";
|
||||
|
||||
// Remove button
|
||||
const removeBtn = document.createElement("button");
|
||||
removeBtn.className = "remove-item-btn";
|
||||
removeBtn.textContent = "x";
|
||||
removeBtn.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
onItemRemove(index);
|
||||
});
|
||||
arrayItem.appendChild(removeBtn);
|
||||
|
||||
if (typeof item === "object" && item !== null) {
|
||||
Object.entries(item).forEach(([itemKey, itemValue]) => {
|
||||
const field = createInputField({
|
||||
key: itemKey,
|
||||
value: itemValue,
|
||||
onChange: (val) => onItemChange(index, itemKey, val),
|
||||
});
|
||||
arrayItem.appendChild(field);
|
||||
});
|
||||
} else {
|
||||
const input = document.createElement("input");
|
||||
input.className = "form-control";
|
||||
input.value = item;
|
||||
input.addEventListener("input", (e) => {
|
||||
onItemChange(index, null, e.target.value);
|
||||
});
|
||||
arrayItem.appendChild(input);
|
||||
}
|
||||
|
||||
container.appendChild(arrayItem);
|
||||
});
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
// Filter data based on search input
|
||||
function filterData() {
|
||||
renderData();
|
||||
}
|
||||
|
||||
// Edit an item
|
||||
function editItem(key, value) {
|
||||
currentEditItem = { key, value: JSON.parse(JSON.stringify(value)) };
|
||||
editPath = null; // Reset path for root level editing
|
||||
|
||||
// Create form for editing
|
||||
createForm(value);
|
||||
|
||||
// Show the modal
|
||||
editModal.classList.remove("hidden");
|
||||
}
|
||||
|
||||
function setDeepValue(obj, pathArray, value) {
|
||||
const lastKey = pathArray.pop();
|
||||
const target = pathArray.reduce((acc, key) => acc[key], obj);
|
||||
target[lastKey] = value;
|
||||
}
|
||||
|
||||
function updateValue(key, value) {
|
||||
const path = editPath ? editPath.split(".").concat(key) : [key];
|
||||
setDeepValue(currentEditItem.value, path, value);
|
||||
}
|
||||
|
||||
function updateArrayValue(arrayKey, index, value) {
|
||||
const path = editPath ? editPath.split(".").concat([arrayKey, index]) : [arrayKey, index];
|
||||
setDeepValue(currentEditItem.value, path, value);
|
||||
}
|
||||
|
||||
function updateArrayObjectValue(arrayKey, index, itemKey, value) {
|
||||
const path = editPath ? editPath.split(".").concat([arrayKey, index, itemKey]) : [arrayKey, index, itemKey];
|
||||
setDeepValue(currentEditItem.value, path, value);
|
||||
}
|
||||
|
||||
function updateArray(arrayKey, action, index = null, newItem = null) {
|
||||
const path = editPath ? editPath.split(".").concat([arrayKey]) : [arrayKey];
|
||||
const target = path.reduce((acc, key) => acc[key], currentEditItem.value);
|
||||
|
||||
if (action === "add") {
|
||||
target.push(newItem);
|
||||
} else if (action === "remove" && index !== null) {
|
||||
target.splice(index, 1);
|
||||
}
|
||||
|
||||
createForm(currentEditItem.value);
|
||||
}
|
||||
|
||||
function addArrayItem(arrayKey, array) {
|
||||
let newItem;
|
||||
if (array.length > 0 && typeof array[0] === "object" && array[0] !== null) {
|
||||
newItem = {};
|
||||
Object.keys(array[0]).forEach((key) => {
|
||||
const sample = array[0][key];
|
||||
newItem[key] = typeof sample === "number" ? 0 : typeof sample === "boolean" ? false : "";
|
||||
});
|
||||
} else {
|
||||
newItem = typeof array[0] === "number" ? 0 : "";
|
||||
}
|
||||
updateArray(arrayKey, "add", null, newItem);
|
||||
}
|
||||
|
||||
function removeArrayItem(arrayKey, index) {
|
||||
updateArray(arrayKey, "remove", index);
|
||||
}
|
||||
|
||||
// Save changes to the edited item
|
||||
function saveItemChanges() {
|
||||
configData[currentFile][currentEditItem.key] = currentEditItem.value;
|
||||
closeModal();
|
||||
renderData();
|
||||
}
|
||||
|
||||
// Close the edit modal
|
||||
function closeModal() {
|
||||
editModal.classList.add("hidden");
|
||||
currentEditItem = null;
|
||||
editPath = null;
|
||||
}
|
||||
|
||||
// Save all changes to the server
|
||||
function saveChanges() {
|
||||
// Send data back to the client
|
||||
fetch(`https://${GetParentResourceName()}/saveConfig`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json; charset=UTF-8",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
file: currentFile,
|
||||
data: configData[currentFile],
|
||||
}),
|
||||
}).catch((err) => console.error("Error:", err));
|
||||
}
|
||||
|
||||
// Close the editor
|
||||
function closeEditor() {
|
||||
fetch(`https://${GetParentResourceName()}/closeEditor`, {
|
||||
method: "POST",
|
||||
}).catch((err) => console.error("Error:", err));
|
||||
}
|
||||
-674
@@ -1,674 +0,0 @@
|
||||
@import url("https://fonts.googleapis.com/css2?family=Exo+2:wght@300;400;500;600;700&display=swap");
|
||||
|
||||
:root {
|
||||
/* Primary colors */
|
||||
--md-primary: #f44336;
|
||||
--md-on-primary: #ffffff;
|
||||
--md-primary-container: #ffdad6;
|
||||
--md-on-primary-container: #410002;
|
||||
|
||||
/* Secondary colors */
|
||||
--md-secondary: #d32f2f;
|
||||
--md-on-secondary: #ffffff;
|
||||
--md-secondary-container: #ffdad5;
|
||||
--md-on-secondary-container: #410001;
|
||||
|
||||
/* Tertiary colors */
|
||||
--md-tertiary: #ff8a65;
|
||||
--md-on-tertiary: #ffffff;
|
||||
--md-tertiary-container: #ffdacc;
|
||||
--md-on-tertiary-container: #410002;
|
||||
|
||||
/* Surface colors (dark theme) */
|
||||
--md-surface: #1c1b1f;
|
||||
--md-on-surface: #e6e1e5;
|
||||
--md-surface-variant: #49454f;
|
||||
--md-on-surface-variant: #c9c5d0;
|
||||
--md-surface-container-lowest: #0f0d13;
|
||||
--md-surface-container-low: #1d1b20;
|
||||
--md-surface-container: #211f26;
|
||||
--md-surface-container-high: #2b2930;
|
||||
--md-surface-container-highest: #36343b;
|
||||
|
||||
/* Error colors */
|
||||
--md-error: #b3261e;
|
||||
--md-on-error: #ffffff;
|
||||
--md-error-container: #93000a;
|
||||
--md-on-error-container: #ffdad5;
|
||||
|
||||
/* Notification colors */
|
||||
--md-success: #9bd880;
|
||||
--md-on-success: #193800;
|
||||
--md-success-container: #275000;
|
||||
--md-on-success-container: #b6f397;
|
||||
|
||||
--md-warning: #ffba47;
|
||||
--md-on-warning: #422b00;
|
||||
--md-warning-container: #5f3f00;
|
||||
--md-on-warning-container: #ffddb0;
|
||||
|
||||
--md-info: #b3c5ff;
|
||||
--md-on-info: #002a77;
|
||||
--md-info-container: #003ea7;
|
||||
--md-on-info-container: #dae1ff;
|
||||
|
||||
/* Neutrals */
|
||||
--md-outline: #79747e;
|
||||
--md-outline-variant: #49454f;
|
||||
--md-inverse-surface: #e6e1e5;
|
||||
--md-inverse-on-surface: #1c1b1f;
|
||||
--md-scrim: rgba(0, 0, 0, 0.6);
|
||||
--md-shadow: rgba(0, 0, 0, 0.15);
|
||||
|
||||
/* Elevation */
|
||||
--md-elevation-1: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
|
||||
--md-elevation-2: 0px 2px 6px 2px rgba(0, 0, 0, 0.15);
|
||||
--md-elevation-3: 0px 4px 8px 3px rgba(0, 0, 0, 0.15);
|
||||
|
||||
/* Shapes */
|
||||
--md-radius-small: 8px;
|
||||
--md-radius-medium: 12px;
|
||||
--md-radius-large: 16px;
|
||||
|
||||
/* Typography */
|
||||
--font-primary: "Exo 2", sans-serif;
|
||||
--font-weight-regular: 400;
|
||||
--font-weight-medium: 500;
|
||||
--font-weight-bold: 700;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: var(--font-primary);
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: var(--md-on-surface);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#editor-container {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 80vw;
|
||||
height: 80vh;
|
||||
background-color: var(--md-surface);
|
||||
border-radius: var(--md-radius-medium);
|
||||
box-shadow: var(--md-elevation-3);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
header {
|
||||
padding: 16px;
|
||||
background-color: var(--md-surface-container-high);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
font-size: 22px;
|
||||
color: var(--md-primary);
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: var(--md-radius-small);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-weight: 500;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
#save-btn {
|
||||
background-color: var(--md-success);
|
||||
color: var(--md-on-success);
|
||||
}
|
||||
|
||||
#save-btn:hover {
|
||||
box-shadow: var(--md-elevation-1);
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
#close-btn {
|
||||
background-color: var(--md-secondary);
|
||||
color: var(--md-on-secondary);
|
||||
}
|
||||
|
||||
#close-btn:hover {
|
||||
box-shadow: var(--md-elevation-1);
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
/* Floating Action Button */
|
||||
.fab {
|
||||
position: fixed;
|
||||
right: 24px;
|
||||
bottom: 24px;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--md-primary);
|
||||
color: var(--md-on-primary);
|
||||
box-shadow: var(--md-elevation-3);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.fab:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: var(--md-elevation-2);
|
||||
}
|
||||
|
||||
.fab:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Content layout */
|
||||
.content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
height: calc(100vh - 130px);
|
||||
max-height: calc(100% - 60px);
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-color: var(--md-surface-container-high);
|
||||
width: 220px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.sidebar h2 {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 16px;
|
||||
color: var(--md-on-surface);
|
||||
}
|
||||
|
||||
.file-list {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.file-list li {
|
||||
padding: 12px;
|
||||
border-radius: var(--md-radius-small);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.file-list li .material-symbols-rounded {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.file-list li:hover {
|
||||
background-color: var(--md-surface-container-high);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--md-elevation-1);
|
||||
}
|
||||
|
||||
.file-list li.active {
|
||||
background-color: var(--md-primary);
|
||||
color: var(--md-on-primary);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--md-elevation-1);
|
||||
}
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: var(--md-surface-container-low);
|
||||
}
|
||||
|
||||
/* Search Input */
|
||||
.search-container {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: var(--md-outline);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#search-input {
|
||||
width: 100%;
|
||||
padding: 12px 12px 12px 40px;
|
||||
border: 1px solid var(--md-outline-variant);
|
||||
border-radius: var(--md-radius-small);
|
||||
background-color: var(--md-surface-container);
|
||||
color: var(--md-on-surface);
|
||||
}
|
||||
|
||||
#search-input:focus {
|
||||
border-color: var(--md-primary);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#data-container {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 200px);
|
||||
scrollbar-width: thin; /* For Firefox */
|
||||
scrollbar-color: var(--md-outline-variant) transparent;
|
||||
}
|
||||
|
||||
#data-container::-webkit-scrollbar {
|
||||
width: 6px; /* Scrollbar width for WebKit browsers */
|
||||
}
|
||||
|
||||
#data-container::-webkit-scrollbar-thumb {
|
||||
background-color: var(--md-outline-variant); /* Thumb color */
|
||||
border-radius: 3px; /* Rounded corners for the thumb */
|
||||
}
|
||||
|
||||
#data-container::-webkit-scrollbar-track {
|
||||
background-color: transparent; /* Track color */
|
||||
}
|
||||
|
||||
/* Cards for displaying data items */
|
||||
.data-card {
|
||||
background-color: var(--md-surface-container);
|
||||
border-radius: var(--md-radius-medium);
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
overflow: hidden;
|
||||
word-break: break-word;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.data-card::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: var(--md-primary);
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.data-card:hover {
|
||||
background-color: var(--md-surface-container-high);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--md-elevation-1);
|
||||
}
|
||||
|
||||
.data-card:hover::after {
|
||||
opacity: 0.05;
|
||||
}
|
||||
|
||||
.data-card h3 {
|
||||
color: var(--md-primary);
|
||||
margin-bottom: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.data-properties {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.property {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.property-label {
|
||||
font-size: 12px;
|
||||
color: var(--md-outline);
|
||||
}
|
||||
|
||||
.property-value {
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Modal */
|
||||
#edit-modal {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
place-items: center; /* Perfectly centers the modal */
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
backdrop-filter: blur(2px);
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#edit-modal.hidden {
|
||||
animation: modal-disappear 0.2s ease-out forwards;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: var(--md-surface-container);
|
||||
border-radius: var(--md-radius-large);
|
||||
width: 600px;
|
||||
max-width: 90%;
|
||||
max-height: 90vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-shadow: var(--md-elevation-3);
|
||||
animation: modal-appear 0.2s ease-out;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid var(--md-outline-variant);
|
||||
background-color: var(--md-surface-container-high);
|
||||
}
|
||||
|
||||
.modal-header h2 {
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
color: var(--md-primary);
|
||||
}
|
||||
|
||||
#close-modal-btn {
|
||||
background: none;
|
||||
color: var(--md-on-surface-variant);
|
||||
font-size: 24px;
|
||||
padding: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
#close-modal-btn:hover {
|
||||
color: var(--md-error);
|
||||
background-color: var(--md-surface-container-high);
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 24px;
|
||||
overflow-y: auto;
|
||||
max-height: 60vh;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--md-outline-variant) transparent;
|
||||
}
|
||||
|
||||
.modal-body::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.modal-body::-webkit-scrollbar-thumb {
|
||||
background-color: var(--md-outline-variant);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
padding: 16px 24px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
border-top: 1px solid var(--md-outline-variant);
|
||||
background-color: var(--md-surface-container-high);
|
||||
}
|
||||
|
||||
#save-item-btn {
|
||||
background-color: var(--md-success);
|
||||
color: var(--md-on-success);
|
||||
}
|
||||
|
||||
#save-item-btn:hover {
|
||||
box-shadow: var(--md-elevation-1);
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
#cancel-edit-btn {
|
||||
background-color: var(--md-secondary);
|
||||
color: var(--md-on-secondary);
|
||||
}
|
||||
|
||||
#cancel-edit-btn:hover {
|
||||
box-shadow: var(--md-elevation-1);
|
||||
}
|
||||
|
||||
/* Form elements */
|
||||
.form-group {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
color: var(--md-on-surface);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--md-outline-variant);
|
||||
border-radius: var(--md-radius-small);
|
||||
background-color: var(--md-surface-container-low);
|
||||
color: var(--md-on-surface);
|
||||
transition: border-color 0.2s;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--md-outline-variant) transparent;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
border-color: var(--md-primary);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
textarea.form-control {
|
||||
min-height: 100px;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.form-control::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.form-control::-webkit-scrollbar-thumb {
|
||||
background-color: var(--md-outline-variant);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.complex-object {
|
||||
border: 1px solid var(--md-outline-variant);
|
||||
border-radius: var(--md-radius-small);
|
||||
padding: 12px;
|
||||
margin-top: 8px;
|
||||
background-color: var(--md-surface-container);
|
||||
}
|
||||
|
||||
.complex-object-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.complex-object-title {
|
||||
font-weight: 500;
|
||||
color: var(--md-primary);
|
||||
}
|
||||
|
||||
.add-item-btn {
|
||||
background-color: var(--md-primary-container);
|
||||
color: var(--md-on-primary-container);
|
||||
padding: 4px 8px;
|
||||
font-size: 12px;
|
||||
border-radius: var(--md-radius-small);
|
||||
}
|
||||
|
||||
.add-item-btn:hover {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
/* For handling arrays */
|
||||
.array-item {
|
||||
border: 1px solid var(--md-outline-variant);
|
||||
border-radius: var(--md-radius-small);
|
||||
padding: 12px;
|
||||
margin-bottom: 12px;
|
||||
position: relative;
|
||||
background-color: var(--md-surface-container-low);
|
||||
}
|
||||
|
||||
.remove-item-btn {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 8px;
|
||||
background-color: var(--md-error-container);
|
||||
color: var(--md-on-error-container);
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.remove-item-btn:hover {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
/* Improved checkbox styling */
|
||||
input[type="checkbox"] {
|
||||
/* Remove default styling */
|
||||
appearance: none;
|
||||
-webkit-appearance: none;
|
||||
|
||||
/* Create custom checkbox */
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 2px solid var(--md-outline-variant);
|
||||
border-radius: 4px;
|
||||
background-color: var(--md-surface-container-low);
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
margin-right: 8px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
/* Checked state */
|
||||
input[type="checkbox"]:checked {
|
||||
background-color: var(--md-primary);
|
||||
border-color: var(--md-primary);
|
||||
}
|
||||
|
||||
/* Checkmark */
|
||||
input[type="checkbox"]:checked::after {
|
||||
content: "✓";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
color: var(--md-on-primary);
|
||||
font-size: 14px;
|
||||
opacity: 0;
|
||||
animation: fadeIn 0.2s forwards;
|
||||
}
|
||||
|
||||
/* Hover state */
|
||||
input[type="checkbox"]:hover {
|
||||
border-color: var(--md-primary);
|
||||
}
|
||||
|
||||
input[type="checkbox"]:active {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
/* Add this to the form-group for boolean/checkbox fields */
|
||||
.form-group.checkbox-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-group.checkbox-group label {
|
||||
margin-bottom: 0;
|
||||
margin-left: 8px;
|
||||
order: 2;
|
||||
}
|
||||
|
||||
.form-group.checkbox-group input {
|
||||
order: 1;
|
||||
}
|
||||
|
||||
@keyframes modal-appear {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes modal-disappear {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -60%);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
}
|
||||
+114
-15
@@ -1,22 +1,121 @@
|
||||
local Translations = {
|
||||
error = {
|
||||
not_online = 'Player online nist !',
|
||||
wrong_format = 'Vorodi sahih nist !',
|
||||
missing_args = 'Vorodi naghes ast (x, y, z)',
|
||||
missing_args2 = 'Tamam vorodi hara vared konid !',
|
||||
no_access = 'Shoma dastresi nadarid !',
|
||||
company_too_poor = 'Sherkat shoma, pul kafi baraye hoghogh dadan nadarad !',
|
||||
item_not_exist = 'In item vojod nadarad',
|
||||
too_heavy = 'Inventory kheyli sangin ast !'
|
||||
not_online = 'بازیکن آنلاین نیست',
|
||||
wrong_format = 'فرمت نادرست',
|
||||
missing_args = 'همه اطلاعات وارد نشده است (x, y, z)',
|
||||
missing_args2 = 'باید همه فیلدهای لازم پر شوند!',
|
||||
no_access = 'شما به این دستور دسترسی ندارید',
|
||||
company_too_poor = 'کارفرمای شما پول کافی ندارد',
|
||||
item_not_exist = 'آیتم وجود ندارد',
|
||||
too_heavy = 'فضای کافی در کیف شما نیست',
|
||||
location_not_exist = 'مکان وجود ندارد',
|
||||
duplicate_license = 'لایسنس راکستار تکراری یافت شد',
|
||||
no_valid_license = 'لایسنس راکستار معتبر یافت نشد',
|
||||
not_whitelisted = 'شما در این سرور لیست سفید نیستید',
|
||||
server_already_open = 'سرور قبلاً باز است',
|
||||
server_already_closed = 'سرور قبلاً بسته است',
|
||||
no_permission = 'شما اجازه این کار را ندارید...',
|
||||
no_waypoint = 'هیچ نقطهای تنظیم نشده است.',
|
||||
tp_error = 'خطا در هنگام انتقال.',
|
||||
},
|
||||
success = {
|
||||
server_opened = 'سرور باز شد',
|
||||
server_closed = 'سرور بسته شد',
|
||||
teleported_waypoint = 'به نقطه مشخص شده منتقل شدید.',
|
||||
},
|
||||
success = {},
|
||||
info = {
|
||||
received_paycheck = 'Hoghogh shoma variz shod : $%{value}',
|
||||
job_info = 'Shoghl: %{value} | Daraje: %{value2} | Dar hal kar: %{value3}',
|
||||
gang_info = 'Gang: %{value} | Daraje: %{value2}',
|
||||
on_duty = 'Shoma dar hal kar hastid (on-duty)!',
|
||||
off_duty = 'Shoma az kar kharej shodid (off-duty)!'
|
||||
}
|
||||
received_paycheck = 'شما حقوق خود را به مبلغ $%{value} دریافت کردید',
|
||||
job_info = 'شغل: %{value} | سطح: %{value2} | در حال کار: %{value3}',
|
||||
gang_info = 'گروه: %{value} | سطح: %{value2}',
|
||||
on_duty = 'شما اکنون در حال کار هستید!',
|
||||
off_duty = 'شما اکنون خارج از کار هستید!',
|
||||
checking_ban = 'سلام %s. در حال بررسی وضعیت ممنوعیت شما هستیم.',
|
||||
join_server = 'خوش آمدید %s به {نام سرور}.',
|
||||
checking_whitelisted = 'سلام %s. در حال بررسی وضعیت مجاز بودن شما هستیم.',
|
||||
exploit_banned = 'شما به دلیل تقلب ممنوع شدهاید. برای اطلاعات بیشتر به دیسکورد ما مراجعه کنید: %{discord}',
|
||||
exploit_dropped = 'شما به دلیل تقلب از سرور خارج شدید',
|
||||
},
|
||||
command = {
|
||||
tp = {
|
||||
help = 'انتقال به بازیکن یا مختصات (فقط ادمین)',
|
||||
params = {
|
||||
x = { name = 'id/x', help = 'شناسه بازیکن یا مختصات X' },
|
||||
y = { name = 'y', help = 'مختصات Y' },
|
||||
z = { name = 'z', help = 'مختصات Z' },
|
||||
},
|
||||
},
|
||||
tpm = { help = 'انتقال به نقطه مشخص شده (فقط ادمین)' },
|
||||
togglepvp = { help = 'تغییر وضعیت پی وی پی (فقط ادمین)' },
|
||||
addpermission = {
|
||||
help = 'ادمینی به بازیکن',
|
||||
params = {
|
||||
id = { name = 'id', help = 'شناسه بازیکن' },
|
||||
permission = { name = 'permission', help = 'سطح ادمینی' },
|
||||
},
|
||||
},
|
||||
removepermission = {
|
||||
help = 'حذف ادمینی از بازیکن',
|
||||
params = {
|
||||
id = { name = 'id', help = 'شناسه بازیکن' },
|
||||
permission = { name = 'permission', help = 'سطح ادمینی' },
|
||||
},
|
||||
},
|
||||
openserver = { help = 'باز کردن سرور برای همه (فقط ادمین)' },
|
||||
closeserver = {
|
||||
help = 'بستن سرور برای کسانی که ادمینی ندارند (فقط ادمین)',
|
||||
params = {
|
||||
reason = { name = 'reason', help = 'دلیل بستن (اختیاری)' },
|
||||
},
|
||||
},
|
||||
car = {
|
||||
help = 'اسپاون کردن خودرو (فقط ادمین)',
|
||||
params = {
|
||||
model = { name = 'model', help = 'نام مدل خودرو' },
|
||||
},
|
||||
},
|
||||
dv = { help = 'حذف خودرو (فقط ادمین)' },
|
||||
givemoney = {
|
||||
help = 'دادن پول به بازیکن (فقط ادمین)',
|
||||
params = {
|
||||
id = { name = 'id', help = 'شناسه بازیکن' },
|
||||
moneytype = { name = 'moneytype', help = 'نوع پول (نقدی، بانکی، کریپتو)' },
|
||||
amount = { name = 'amount', help = 'مقدار پول' },
|
||||
},
|
||||
},
|
||||
setmoney = {
|
||||
help = 'تنظیم مقدار پول بازیکن (فقط ادمین)',
|
||||
params = {
|
||||
id = { name = 'id', help = 'شناسه بازیکن' },
|
||||
moneytype = { name = 'moneytype', help = 'نوع پول (نقدی، بانکی، کریپتو)' },
|
||||
amount = { name = 'amount', help = 'مقدار پول' },
|
||||
},
|
||||
},
|
||||
job = { help = 'بررسی شغل' },
|
||||
setjob = {
|
||||
help = 'تنظیم شغل بازیکن (فقط ادمین)',
|
||||
params = {
|
||||
id = { name = 'id', help = 'شناسه بازیکن' },
|
||||
job = { name = 'job', help = 'نام شغل' },
|
||||
grade = { name = 'grade', help = 'سطح شغل' },
|
||||
},
|
||||
},
|
||||
gang = { help = 'بررسی گنگ' },
|
||||
setgang = {
|
||||
help = 'تنظیم گنگ بازیکن (فقط ادمین)',
|
||||
params = {
|
||||
id = { name = 'id', help = 'شناسه بازیکن' },
|
||||
gang = { name = 'gang', help = 'نام گنگ' },
|
||||
grade = { name = 'grade', help = 'سطح گنگ' },
|
||||
},
|
||||
},
|
||||
ooc = { help = 'پیام خارج از آر پی' },
|
||||
me = {
|
||||
help = 'ارسال پیام محلی',
|
||||
params = {
|
||||
message = { name = 'message', help = 'پیام' }
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if GetConvar('qb_locale', 'en') == 'fa' then
|
||||
|
||||
+5
-5
@@ -23,7 +23,7 @@ local Translations = {
|
||||
success = {
|
||||
server_opened = 'O Servidor abriu',
|
||||
server_closed = 'O Servidor fechou',
|
||||
teleported_waypoint = 'Teleportado para o waypoint.',
|
||||
teleported_waypoint = 'Foste teletransportado para o waypoint.',
|
||||
},
|
||||
info = {
|
||||
received_paycheck = 'Recebeste o pagamento de %{value}€',
|
||||
@@ -34,12 +34,12 @@ local Translations = {
|
||||
checking_ban = 'Olá %s. Estamos a verificar se estás banido.',
|
||||
join_server = 'Bem vindo %s ao {Server Name}.',
|
||||
checking_whitelisted = 'Bem vindo %s. Estamos a verificiar se estás na whitelist.',
|
||||
exploit_banned = 'Foste banidos por cheats. Para mais informações visita o nosso discord: %{discord}',
|
||||
exploit_dropped = 'Foste kickado por cheats!',
|
||||
exploit_banned = 'Foste banido por cheats. Para mais informações visita o nosso discord: %{discord}',
|
||||
exploit_dropped = 'Foste expulso por cheats!',
|
||||
},
|
||||
command = {
|
||||
tp = {
|
||||
help = 'TP para jogador ou coordenadas (Apenas Admin)',
|
||||
help = 'TP para um jogador ou coordenadas (Apenas Admin)',
|
||||
params = {
|
||||
x = { name = 'id/x', help = 'ID do jogador ou posição X'},
|
||||
y = { name = 'y', help = 'Posição Y'},
|
||||
@@ -64,7 +64,7 @@ local Translations = {
|
||||
},
|
||||
openserver = { help = 'Abrir o Servidor para todos (Apenas Admin)' },
|
||||
closeserver = {
|
||||
help = 'Fechar o servidor para todos excepto Admins (Apenas Admin)',
|
||||
help = 'Fechar o servidor para todos exceto Admins (Apenas Admin)',
|
||||
params = {
|
||||
reason = { name = 'reason', help = 'Razão para fechar(opcional)' },
|
||||
},
|
||||
|
||||
+256
-18
@@ -1,15 +1,11 @@
|
||||
-- Handle Chat Input
|
||||
QBCore.Commands = {}
|
||||
QBCore.Commands.List = {}
|
||||
QBCore.Commands.IgnoreList = { -- Ignore old perm levels while keeping backwards compatibility
|
||||
['god'] = true, -- We don't need to create an ace because god is allowed all commands
|
||||
['user'] = true -- We don't need to create an ace because builtin.everyone
|
||||
}
|
||||
|
||||
AddEventHandler('chatMessage', function(_, _, message)
|
||||
if string.sub(message, 1, 1) == '/' then
|
||||
CancelEvent()
|
||||
return
|
||||
end
|
||||
end)
|
||||
|
||||
-- Add Aces
|
||||
|
||||
CreateThread(function()
|
||||
CreateThread(function() -- Add ace to node for perm checking
|
||||
local permissions = QBCore.Config.Server.Permissions
|
||||
for i = 1, #permissions do
|
||||
local permission = permissions[i]
|
||||
@@ -20,11 +16,11 @@ end)
|
||||
-- Register & Refresh Commands
|
||||
|
||||
function QBCore.Commands.Add(name, help, arguments, argsrequired, callback, permission, ...)
|
||||
local restricted = true
|
||||
if not permission then permission = 'user' end
|
||||
if permission == 'user' then restricted = false end
|
||||
local restricted = true -- Default to restricted for all commands
|
||||
if not permission then permission = 'user' end -- some commands don't pass permission level
|
||||
if permission == 'user' then restricted = false end -- allow all users to use command
|
||||
|
||||
RegisterCommand(name, function(source, args, rawCommand)
|
||||
RegisterCommand(name, function(source, args, rawCommand) -- Register command within fivem
|
||||
if argsrequired and #args < #arguments then
|
||||
return TriggerClientEvent('chat:addMessage', source, {
|
||||
color = { 255, 0, 0 },
|
||||
@@ -37,18 +33,18 @@ function QBCore.Commands.Add(name, help, arguments, argsrequired, callback, perm
|
||||
|
||||
local extraPerms = ... and table.pack(...) or nil
|
||||
if extraPerms then
|
||||
extraPerms[extraPerms.n + 1] = permission
|
||||
extraPerms[extraPerms.n + 1] = permission -- The `n` field is the number of arguments in the packed table
|
||||
extraPerms.n += 1
|
||||
permission = extraPerms
|
||||
for i = 1, permission.n do
|
||||
if not QBCore.Commands.IgnoreList[permission[i]] then
|
||||
if not QBCore.Commands.IgnoreList[permission[i]] then -- only create aces for extra perm levels
|
||||
ExecuteCommand(('add_ace qbcore.%s command.%s allow'):format(permission[i], name))
|
||||
end
|
||||
end
|
||||
permission.n = nil
|
||||
else
|
||||
permission = tostring(permission:lower())
|
||||
if not QBCore.Commands.IgnoreList[permission] then
|
||||
if not QBCore.Commands.IgnoreList[permission] then -- only create aces for extra perm levels
|
||||
ExecuteCommand(('add_ace qbcore.%s command.%s allow'):format(permission, name))
|
||||
end
|
||||
end
|
||||
@@ -83,3 +79,245 @@ function QBCore.Commands.Refresh(source)
|
||||
TriggerClientEvent('chat:addSuggestions', src, suggestions)
|
||||
end
|
||||
end
|
||||
|
||||
-- Teleport
|
||||
QBCore.Commands.Add('tp', Lang:t('command.tp.help'), { { name = Lang:t('command.tp.params.x.name'), help = Lang:t('command.tp.params.x.help') }, { name = Lang:t('command.tp.params.y.name'), help = Lang:t('command.tp.params.y.help') }, { name = Lang:t('command.tp.params.z.name'), help = Lang:t('command.tp.params.z.help') } }, false, function(source, args)
|
||||
if args[1] and not args[2] and not args[3] then
|
||||
if tonumber(args[1]) then
|
||||
local target = GetPlayerPed(tonumber(args[1]))
|
||||
if target ~= 0 then
|
||||
local coords = GetEntityCoords(target)
|
||||
TriggerClientEvent('QBCore:Command:TeleportToPlayer', source, coords)
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
|
||||
end
|
||||
else
|
||||
local location = QBShared.Locations[args[1]]
|
||||
if location then
|
||||
TriggerClientEvent('QBCore:Command:TeleportToCoords', source, location.x, location.y, location.z, location.w)
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.location_not_exist'), 'error')
|
||||
end
|
||||
end
|
||||
else
|
||||
if args[1] and args[2] and args[3] then
|
||||
local x = tonumber((args[1]:gsub(',', ''))) + .0
|
||||
local y = tonumber((args[2]:gsub(',', ''))) + .0
|
||||
local z = tonumber((args[3]:gsub(',', ''))) + .0
|
||||
local heading = args[4] and tonumber((args[4]:gsub(',', ''))) + .0 or false
|
||||
if x ~= 0 and y ~= 0 and z ~= 0 then
|
||||
TriggerClientEvent('QBCore:Command:TeleportToCoords', source, x, y, z, heading)
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.wrong_format'), 'error')
|
||||
end
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.missing_args'), 'error')
|
||||
end
|
||||
end
|
||||
end, 'admin')
|
||||
|
||||
QBCore.Commands.Add('tpm', Lang:t('command.tpm.help'), {}, false, function(source)
|
||||
TriggerClientEvent('QBCore:Command:GoToMarker', source)
|
||||
end, 'admin')
|
||||
|
||||
QBCore.Commands.Add('togglepvp', Lang:t('command.togglepvp.help'), {}, false, function()
|
||||
QBCore.Config.Server.PVP = not QBCore.Config.Server.PVP
|
||||
TriggerClientEvent('QBCore:Client:PvpHasToggled', -1, QBCore.Config.Server.PVP)
|
||||
end, 'admin')
|
||||
|
||||
-- Permissions
|
||||
|
||||
QBCore.Commands.Add('addpermission', Lang:t('command.addpermission.help'), { { name = Lang:t('command.addpermission.params.id.name'), help = Lang:t('command.addpermission.params.id.help') }, { name = Lang:t('command.addpermission.params.permission.name'), help = Lang:t('command.addpermission.params.permission.help') } }, true, function(source, args)
|
||||
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
|
||||
local permission = tostring(args[2]):lower()
|
||||
if Player then
|
||||
QBCore.Functions.AddPermission(Player.PlayerData.source, permission)
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
|
||||
end
|
||||
end, 'god')
|
||||
|
||||
QBCore.Commands.Add('removepermission', Lang:t('command.removepermission.help'), { { name = Lang:t('command.removepermission.params.id.name'), help = Lang:t('command.removepermission.params.id.help') }, { name = Lang:t('command.removepermission.params.permission.name'), help = Lang:t('command.removepermission.params.permission.help') } }, true, function(source, args)
|
||||
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
|
||||
local permission = tostring(args[2]):lower()
|
||||
if Player then
|
||||
QBCore.Functions.RemovePermission(Player.PlayerData.source, permission)
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
|
||||
end
|
||||
end, 'god')
|
||||
|
||||
-- Open & Close Server
|
||||
|
||||
QBCore.Commands.Add('openserver', Lang:t('command.openserver.help'), {}, false, function(source)
|
||||
if not QBCore.Config.Server.Closed then
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.server_already_open'), 'error')
|
||||
return
|
||||
end
|
||||
if QBCore.Functions.HasPermission(source, 'admin') then
|
||||
QBCore.Config.Server.Closed = false
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('success.server_opened'), 'success')
|
||||
else
|
||||
QBCore.Functions.Kick(source, Lang:t('error.no_permission'), nil, nil)
|
||||
end
|
||||
end, 'admin')
|
||||
|
||||
QBCore.Commands.Add('closeserver', Lang:t('command.closeserver.help'), { { name = Lang:t('command.closeserver.params.reason.name'), help = Lang:t('command.closeserver.params.reason.help') } }, false, function(source, args)
|
||||
if QBCore.Config.Server.Closed then
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.server_already_closed'), 'error')
|
||||
return
|
||||
end
|
||||
if QBCore.Functions.HasPermission(source, 'admin') then
|
||||
local reason = args[1] or 'No reason specified'
|
||||
QBCore.Config.Server.Closed = true
|
||||
QBCore.Config.Server.ClosedReason = reason
|
||||
for k in pairs(QBCore.Players) do
|
||||
if not QBCore.Functions.HasPermission(k, QBCore.Config.Server.WhitelistPermission) then
|
||||
QBCore.Functions.Kick(k, reason, nil, nil)
|
||||
end
|
||||
end
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('success.server_closed'), 'success')
|
||||
else
|
||||
QBCore.Functions.Kick(source, Lang:t('error.no_permission'), nil, nil)
|
||||
end
|
||||
end, 'admin')
|
||||
|
||||
-- Vehicle
|
||||
|
||||
QBCore.Commands.Add('car', Lang:t('command.car.help'), { { name = Lang:t('command.car.params.model.name'), help = Lang:t('command.car.params.model.help') } }, true, function(source, args)
|
||||
TriggerClientEvent('QBCore:Command:SpawnVehicle', source, args[1])
|
||||
end, 'admin')
|
||||
|
||||
QBCore.Commands.Add('dv', Lang:t('command.dv.help'), {}, false, function(source)
|
||||
TriggerClientEvent('QBCore:Command:DeleteVehicle', source)
|
||||
end, 'admin')
|
||||
|
||||
QBCore.Commands.Add('dvall', Lang:t('command.dvall.help'), {}, false, function()
|
||||
local vehicles = GetAllVehicles()
|
||||
for _, vehicle in ipairs(vehicles) do
|
||||
DeleteEntity(vehicle)
|
||||
end
|
||||
end, 'admin')
|
||||
|
||||
-- Peds
|
||||
|
||||
QBCore.Commands.Add('dvp', Lang:t('command.dvp.help'), {}, false, function()
|
||||
local peds = GetAllPeds()
|
||||
for _, ped in ipairs(peds) do
|
||||
DeleteEntity(ped)
|
||||
end
|
||||
end, 'admin')
|
||||
|
||||
-- Objects
|
||||
|
||||
QBCore.Commands.Add('dvo', Lang:t('command.dvo.help'), {}, false, function()
|
||||
local objects = GetAllObjects()
|
||||
for _, object in ipairs(objects) do
|
||||
DeleteEntity(object)
|
||||
end
|
||||
end, 'admin')
|
||||
|
||||
-- Money
|
||||
|
||||
QBCore.Commands.Add('givemoney', Lang:t('command.givemoney.help'), { { name = Lang:t('command.givemoney.params.id.name'), help = Lang:t('command.givemoney.params.id.help') }, { name = Lang:t('command.givemoney.params.moneytype.name'), help = Lang:t('command.givemoney.params.moneytype.help') }, { name = Lang:t('command.givemoney.params.amount.name'), help = Lang:t('command.givemoney.params.amount.help') } }, true, function(source, args)
|
||||
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
|
||||
if Player then
|
||||
Player.Functions.AddMoney(tostring(args[2]), tonumber(args[3]), 'Admin give money')
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
|
||||
end
|
||||
end, 'admin')
|
||||
|
||||
QBCore.Commands.Add('setmoney', Lang:t('command.setmoney.help'), { { name = Lang:t('command.setmoney.params.id.name'), help = Lang:t('command.setmoney.params.id.help') }, { name = Lang:t('command.setmoney.params.moneytype.name'), help = Lang:t('command.setmoney.params.moneytype.help') }, { name = Lang:t('command.setmoney.params.amount.name'), help = Lang:t('command.setmoney.params.amount.help') } }, true, function(source, args)
|
||||
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
|
||||
if Player then
|
||||
Player.Functions.SetMoney(tostring(args[2]), tonumber(args[3]))
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
|
||||
end
|
||||
end, 'admin')
|
||||
|
||||
-- Job
|
||||
|
||||
QBCore.Commands.Add('job', Lang:t('command.job.help'), {}, false, function(source)
|
||||
local PlayerJob = QBCore.Functions.GetPlayer(source).PlayerData.job
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('info.job_info', { value = PlayerJob.label, value2 = PlayerJob.grade.name, value3 = PlayerJob.onduty }))
|
||||
end, 'user')
|
||||
|
||||
QBCore.Commands.Add('setjob', Lang:t('command.setjob.help'), { { name = Lang:t('command.setjob.params.id.name'), help = Lang:t('command.setjob.params.id.help') }, { name = Lang:t('command.setjob.params.job.name'), help = Lang:t('command.setjob.params.job.help') }, { name = Lang:t('command.setjob.params.grade.name'), help = Lang:t('command.setjob.params.grade.help') } }, true, function(source, args)
|
||||
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
|
||||
if Player then
|
||||
Player.Functions.SetJob(tostring(args[2]), tonumber(args[3]))
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
|
||||
end
|
||||
end, 'admin')
|
||||
|
||||
-- Gang
|
||||
|
||||
QBCore.Commands.Add('gang', Lang:t('command.gang.help'), {}, false, function(source)
|
||||
local PlayerGang = QBCore.Functions.GetPlayer(source).PlayerData.gang
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('info.gang_info', { value = PlayerGang.label, value2 = PlayerGang.grade.name }))
|
||||
end, 'user')
|
||||
|
||||
QBCore.Commands.Add('setgang', Lang:t('command.setgang.help'), { { name = Lang:t('command.setgang.params.id.name'), help = Lang:t('command.setgang.params.id.help') }, { name = Lang:t('command.setgang.params.gang.name'), help = Lang:t('command.setgang.params.gang.help') }, { name = Lang:t('command.setgang.params.grade.name'), help = Lang:t('command.setgang.params.grade.help') } }, true, function(source, args)
|
||||
local Player = QBCore.Functions.GetPlayer(tonumber(args[1]))
|
||||
if Player then
|
||||
Player.Functions.SetGang(tostring(args[2]), tonumber(args[3]))
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
|
||||
end
|
||||
end, 'admin')
|
||||
|
||||
-- Out of Character Chat
|
||||
QBCore.Commands.Add('ooc', Lang:t('command.ooc.help'), {}, false, function(source, args)
|
||||
local message = table.concat(args, ' ')
|
||||
local Players = QBCore.Functions.GetPlayers()
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
local playerCoords = GetEntityCoords(GetPlayerPed(source))
|
||||
for _, v in pairs(Players) do
|
||||
if v == source then
|
||||
TriggerClientEvent('chat:addMessage', v, {
|
||||
color = QBCore.Config.Commands.OOCColor,
|
||||
multiline = true,
|
||||
args = { 'OOC | ' .. GetPlayerName(source), message }
|
||||
})
|
||||
elseif #(playerCoords - GetEntityCoords(GetPlayerPed(v))) < 20.0 then
|
||||
TriggerClientEvent('chat:addMessage', v, {
|
||||
color = QBCore.Config.Commands.OOCColor,
|
||||
multiline = true,
|
||||
args = { 'OOC | ' .. GetPlayerName(source), message }
|
||||
})
|
||||
elseif QBCore.Functions.HasPermission(v, 'admin') then
|
||||
if QBCore.Functions.IsOptin(v) then
|
||||
TriggerClientEvent('chat:addMessage', v, {
|
||||
color = QBCore.Config.Commands.OOCColor,
|
||||
multiline = true,
|
||||
args = { 'Proximity OOC | ' .. GetPlayerName(source), message }
|
||||
})
|
||||
TriggerEvent('qb-log:server:CreateLog', 'ooc', 'OOC', 'white', '**' .. GetPlayerName(source) .. '** (CitizenID: ' .. Player.PlayerData.citizenid .. ' | ID: ' .. source .. ') **Message:** ' .. message, false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end, 'user')
|
||||
|
||||
-- Me command
|
||||
|
||||
QBCore.Commands.Add('me', Lang:t('command.me.help'), { { name = Lang:t('command.me.params.message.name'), help = Lang:t('command.me.params.message.help') } }, false, function(source, args)
|
||||
if #args < 1 then
|
||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.missing_args2'), 'error')
|
||||
return
|
||||
end
|
||||
local ped = GetPlayerPed(source)
|
||||
local pCoords = GetEntityCoords(ped)
|
||||
local msg = table.concat(args, ' '):gsub('[~<].-[>~]', '')
|
||||
local Players = QBCore.Functions.GetPlayers()
|
||||
for i = 1, #Players do
|
||||
local Player = Players[i]
|
||||
local target = GetPlayerPed(Player)
|
||||
local tCoords = GetEntityCoords(target)
|
||||
if target == ped or #(pCoords - tCoords) < 20 then
|
||||
TriggerClientEvent('QBCore:Command:ShowMe3D', Player, source, msg)
|
||||
end
|
||||
end
|
||||
end, 'user')
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
local function tPrint(tbl, indent)
|
||||
indent = indent or 0
|
||||
if type(tbl) == 'table' then
|
||||
for k, v in pairs(tbl) do
|
||||
local tblType = type(v)
|
||||
local formatting = ('%s ^3%s:^0'):format(string.rep(' ', indent), k)
|
||||
|
||||
if tblType == 'table' then
|
||||
print(formatting)
|
||||
tPrint(v, indent + 1)
|
||||
elseif tblType == 'boolean' then
|
||||
print(('%s^1 %s ^0'):format(formatting, v))
|
||||
elseif tblType == 'function' then
|
||||
print(('%s^9 %s ^0'):format(formatting, v))
|
||||
elseif tblType == 'number' then
|
||||
print(('%s^5 %s ^0'):format(formatting, v))
|
||||
elseif tblType == 'string' then
|
||||
print(("%s ^2'%s' ^0"):format(formatting, v))
|
||||
else
|
||||
print(('%s^2 %s ^0'):format(formatting, v))
|
||||
end
|
||||
end
|
||||
else
|
||||
print(('%s ^0%s'):format(string.rep(' ', indent), tbl))
|
||||
end
|
||||
end
|
||||
|
||||
RegisterServerEvent('QBCore:DebugSomething', function(tbl, indent, resource)
|
||||
print(('\x1b[4m\x1b[36m[ %s : DEBUG]\x1b[0m'):format(resource))
|
||||
tPrint(tbl, indent)
|
||||
print('\x1b[4m\x1b[36m[ END DEBUG ]\x1b[0m')
|
||||
end)
|
||||
|
||||
function QBCore.Debug(tbl, indent)
|
||||
TriggerEvent('QBCore:DebugSomething', tbl, indent, GetInvokingResource() or 'qb-core')
|
||||
end
|
||||
|
||||
function QBCore.ShowError(resource, msg)
|
||||
print('\x1b[31m[' .. resource .. ':ERROR]\x1b[0m ' .. msg)
|
||||
end
|
||||
|
||||
function QBCore.ShowSuccess(resource, msg)
|
||||
print('\x1b[32m[' .. resource .. ':LOG]\x1b[0m ' .. msg)
|
||||
end
|
||||
@@ -1,56 +0,0 @@
|
||||
RegisterCommand('qbeditor', function(source)
|
||||
local files = {
|
||||
config = LoadResourceFile('qb-core', 'shared/json/config.json'),
|
||||
gangs = LoadResourceFile('qb-core', 'shared/json/gangs.json'),
|
||||
items = LoadResourceFile('qb-core', 'shared/json/items.json'),
|
||||
jobs = LoadResourceFile('qb-core', 'shared/json/jobs.json'),
|
||||
playerdata = LoadResourceFile('qb-core', 'shared/json/player_defaults.json'),
|
||||
vehicles = LoadResourceFile('qb-core', 'shared/json/vehicles.json'),
|
||||
weapons = LoadResourceFile('qb-core', 'shared/json/weapons.json'),
|
||||
}
|
||||
|
||||
local allData = {}
|
||||
for key, fileContent in pairs(files) do
|
||||
if not fileContent then
|
||||
print('^1[QBCore] Failed to load ' .. key .. ' JSON File')
|
||||
else
|
||||
allData[key] = json.decode(fileContent)
|
||||
end
|
||||
end
|
||||
|
||||
TriggerClientEvent('qb-core:client:configEditor', source, allData)
|
||||
end, true)
|
||||
|
||||
RegisterNetEvent('qb-core:server:configEditor', function(fileName, fileData)
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
if not Player then return end
|
||||
if not QBCore.Functions.HasPermission('god') then
|
||||
local filePaths = {
|
||||
['config'] = 'shared/json/config.json',
|
||||
['gangs'] = 'shared/json/gangs.json',
|
||||
['items'] = 'shared/json/items.json',
|
||||
['jobs'] = 'shared/json/jobs.json',
|
||||
['playerdata'] = 'shared/json/player_defaults.json',
|
||||
['vehicles'] = 'shared/json/vehicles.json',
|
||||
['weapons'] = 'shared/json/weapons.json'
|
||||
}
|
||||
local filePath = filePaths[fileName]
|
||||
if not filePath then
|
||||
print('^1[QBCore] Invalid file name: ' .. fileName)
|
||||
return
|
||||
end
|
||||
local encodedData = json.encode(fileData, { indent = true })
|
||||
local saved = SaveResourceFile('qb-core', filePath, encodedData, -1)
|
||||
if saved then
|
||||
print('^2[QBCore] Player ' .. GetPlayerName(src) .. ' (ID: ' .. src .. ') successfully saved ' .. fileName .. ' configuration')
|
||||
TriggerClientEvent('QBCore:Notify', src, 'Configuration saved successfully', 'success')
|
||||
else
|
||||
print('^1[QBCore] Failed to save ' .. fileName .. ' configuration')
|
||||
TriggerClientEvent('QBCore:Notify', src, 'Failed to save configuration', 'error')
|
||||
end
|
||||
else
|
||||
print('^1[QBCore] Player ' .. GetPlayerName(src) .. ' (ID: ' .. src .. ') attempted to save ' .. fileName .. ' configuration without permission')
|
||||
TriggerClientEvent('QBCore:Notify', src, 'You don\'t have permission to edit configs', 'error')
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,285 @@
|
||||
-- Event Handler
|
||||
|
||||
AddEventHandler('chatMessage', function(_, _, message)
|
||||
if string.sub(message, 1, 1) == '/' then
|
||||
CancelEvent()
|
||||
return
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler('playerDropped', function(reason)
|
||||
local src = source
|
||||
if not QBCore.Players[src] then return end
|
||||
local Player = QBCore.Players[src]
|
||||
TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Dropped', 'red', '**' .. GetPlayerName(src) .. '** (' .. Player.PlayerData.license .. ') left..' .. '\n **Reason:** ' .. reason)
|
||||
TriggerEvent('QBCore:Server:PlayerDropped', Player)
|
||||
Player.Functions.Save()
|
||||
QBCore.Player_Buckets[Player.PlayerData.license] = nil
|
||||
QBCore.Players[src] = nil
|
||||
end)
|
||||
|
||||
AddEventHandler("onResourceStop", function(resName)
|
||||
for i,v in pairs(QBCore.UsableItems) do
|
||||
if v.resource == resName then
|
||||
QBCore.UsableItems[i] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Player Connecting
|
||||
local readyFunction = MySQL.ready
|
||||
local databaseConnected, bansTableExists = readyFunction == nil, readyFunction == nil
|
||||
if readyFunction ~= nil then
|
||||
MySQL.ready(function()
|
||||
databaseConnected = true
|
||||
|
||||
local DatabaseInfo = QBCore.Functions.GetDatabaseInfo()
|
||||
if not DatabaseInfo or not DatabaseInfo.exists then return end
|
||||
|
||||
local result = MySQL.query.await('SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = "bans";', {DatabaseInfo.database})
|
||||
if result and result[1] then
|
||||
bansTableExists = true
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
local function onPlayerConnecting(name, _, deferrals)
|
||||
local src = source
|
||||
deferrals.defer()
|
||||
|
||||
if QBCore.Config.Server.Closed and not IsPlayerAceAllowed(src, 'qbadmin.join') then
|
||||
return deferrals.done(QBCore.Config.Server.ClosedReason)
|
||||
end
|
||||
|
||||
if not databaseConnected then
|
||||
return deferrals.done(Lang:t('error.connecting_database_error'))
|
||||
end
|
||||
|
||||
if QBCore.Config.Server.Whitelist then
|
||||
Wait(0)
|
||||
deferrals.update(string.format(Lang:t('info.checking_whitelisted'), name))
|
||||
if not QBCore.Functions.IsWhitelisted(src) then
|
||||
return deferrals.done(Lang:t('error.not_whitelisted'))
|
||||
end
|
||||
end
|
||||
|
||||
Wait(0)
|
||||
deferrals.update(string.format('Hello %s. Your license is being checked', name))
|
||||
local license = QBCore.Functions.GetIdentifier(src, 'license')
|
||||
|
||||
if not license then
|
||||
return deferrals.done(Lang:t('error.no_valid_license'))
|
||||
elseif QBCore.Config.Server.CheckDuplicateLicense and QBCore.Functions.IsLicenseInUse(license) then
|
||||
return deferrals.done(Lang:t('error.duplicate_license'))
|
||||
end
|
||||
|
||||
Wait(0)
|
||||
deferrals.update(string.format(Lang:t('info.checking_ban'), name))
|
||||
|
||||
if not bansTableExists then
|
||||
return deferrals.done(Lang:t('error.ban_table_not_found'))
|
||||
end
|
||||
|
||||
local success, isBanned, reason = pcall(QBCore.Functions.IsPlayerBanned, src)
|
||||
if not success then return deferrals.done(Lang:t('error.connecting_database_error')) end
|
||||
if isBanned then return deferrals.done(reason) end
|
||||
|
||||
Wait(0)
|
||||
deferrals.update(string.format(Lang:t('info.join_server'), name))
|
||||
deferrals.done()
|
||||
|
||||
TriggerClientEvent('QBCore:Client:SharedUpdate', src, QBCore.Shared)
|
||||
end
|
||||
|
||||
AddEventHandler('playerConnecting', onPlayerConnecting)
|
||||
|
||||
-- Open & Close Server (prevents players from joining)
|
||||
|
||||
RegisterNetEvent('QBCore:Server:CloseServer', function(reason)
|
||||
local src = source
|
||||
if QBCore.Functions.HasPermission(src, 'admin') then
|
||||
reason = reason or 'No reason specified'
|
||||
QBCore.Config.Server.Closed = true
|
||||
QBCore.Config.Server.ClosedReason = reason
|
||||
for k in pairs(QBCore.Players) do
|
||||
if not QBCore.Functions.HasPermission(k, QBCore.Config.Server.WhitelistPermission) then
|
||||
QBCore.Functions.Kick(k, reason, nil, nil)
|
||||
end
|
||||
end
|
||||
else
|
||||
QBCore.Functions.Kick(src, Lang:t('error.no_permission'), nil, nil)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Server:OpenServer', function()
|
||||
local src = source
|
||||
if QBCore.Functions.HasPermission(src, 'admin') then
|
||||
QBCore.Config.Server.Closed = false
|
||||
else
|
||||
QBCore.Functions.Kick(src, Lang:t('error.no_permission'), nil, nil)
|
||||
end
|
||||
end)
|
||||
|
||||
-- Callback Events --
|
||||
|
||||
-- Client Callback
|
||||
RegisterNetEvent('QBCore:Server:TriggerClientCallback', function(name, ...)
|
||||
if QBCore.ClientCallbacks[name] then
|
||||
QBCore.ClientCallbacks[name].promise:resolve(...)
|
||||
|
||||
if QBCore.ClientCallbacks[name].callback then
|
||||
QBCore.ClientCallbacks[name].callback(...)
|
||||
end
|
||||
|
||||
QBCore.ClientCallbacks[name] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
-- Server Callback
|
||||
RegisterNetEvent('QBCore:Server:TriggerCallback', function(name, ...)
|
||||
if not QBCore.ServerCallbacks[name] then return end
|
||||
|
||||
local src = source
|
||||
|
||||
QBCore.ServerCallbacks[name](src, function(...)
|
||||
TriggerClientEvent('QBCore:Client:TriggerCallback', src, name, ...)
|
||||
end, ...)
|
||||
end)
|
||||
|
||||
-- Player
|
||||
|
||||
RegisterNetEvent('QBCore:UpdatePlayer', function()
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
if not Player then return end
|
||||
local newHunger = Player.PlayerData.metadata['hunger'] - QBCore.Config.Player.HungerRate
|
||||
local newThirst = Player.PlayerData.metadata['thirst'] - QBCore.Config.Player.ThirstRate
|
||||
if newHunger <= 0 then
|
||||
newHunger = 0
|
||||
end
|
||||
if newThirst <= 0 then
|
||||
newThirst = 0
|
||||
end
|
||||
Player.Functions.SetMetaData('thirst', newThirst)
|
||||
Player.Functions.SetMetaData('hunger', newHunger)
|
||||
TriggerClientEvent('hud:client:UpdateNeeds', src, newHunger, newThirst)
|
||||
Player.Functions.Save()
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:ToggleDuty', function()
|
||||
local src = source
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
if not Player then return end
|
||||
if Player.PlayerData.job.onduty then
|
||||
Player.Functions.SetJobDuty(false)
|
||||
TriggerClientEvent('QBCore:Notify', src, Lang:t('info.off_duty'))
|
||||
else
|
||||
Player.Functions.SetJobDuty(true)
|
||||
TriggerClientEvent('QBCore:Notify', src, Lang:t('info.on_duty'))
|
||||
end
|
||||
|
||||
TriggerEvent('QBCore:Server:SetDuty', src, Player.PlayerData.job.onduty)
|
||||
TriggerClientEvent('QBCore:Client:SetDuty', src, Player.PlayerData.job.onduty)
|
||||
end)
|
||||
|
||||
-- BaseEvents
|
||||
|
||||
-- Vehicles
|
||||
RegisterServerEvent('baseevents:enteringVehicle', function(veh, seat, modelName)
|
||||
local src = source
|
||||
local data = {
|
||||
vehicle = veh,
|
||||
seat = seat,
|
||||
name = modelName,
|
||||
event = 'Entering'
|
||||
}
|
||||
TriggerClientEvent('QBCore:Client:VehicleInfo', src, data)
|
||||
end)
|
||||
|
||||
RegisterServerEvent('baseevents:enteredVehicle', function(veh, seat, modelName)
|
||||
local src = source
|
||||
local data = {
|
||||
vehicle = veh,
|
||||
seat = seat,
|
||||
name = modelName,
|
||||
event = 'Entered'
|
||||
}
|
||||
TriggerClientEvent('QBCore:Client:VehicleInfo', src, data)
|
||||
end)
|
||||
|
||||
RegisterServerEvent('baseevents:enteringAborted', function()
|
||||
local src = source
|
||||
TriggerClientEvent('QBCore:Client:AbortVehicleEntering', src)
|
||||
end)
|
||||
|
||||
RegisterServerEvent('baseevents:leftVehicle', function(veh, seat, modelName)
|
||||
local src = source
|
||||
local data = {
|
||||
vehicle = veh,
|
||||
seat = seat,
|
||||
name = modelName,
|
||||
event = 'Left'
|
||||
}
|
||||
TriggerClientEvent('QBCore:Client:VehicleInfo', src, data)
|
||||
end)
|
||||
|
||||
-- Items
|
||||
|
||||
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon.
|
||||
RegisterNetEvent('QBCore:Server:UseItem', function(item)
|
||||
print(string.format('%s triggered QBCore:Server:UseItem by ID %s with the following data. This event is deprecated due to exploitation, and will be removed soon. Check qb-inventory for the right use on this event.', GetInvokingResource(), source))
|
||||
QBCore.Debug(item)
|
||||
end)
|
||||
|
||||
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon. function(itemName, amount, slot)
|
||||
RegisterNetEvent('QBCore:Server:RemoveItem', function(itemName, amount)
|
||||
local src = source
|
||||
print(string.format('%s triggered QBCore:Server:RemoveItem by ID %s for %s %s. This event is deprecated due to exploitation, and will be removed soon. Adjust your events accordingly to do this server side with player functions.', GetInvokingResource(), src, amount, itemName))
|
||||
end)
|
||||
|
||||
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon. function(itemName, amount, slot, info)
|
||||
RegisterNetEvent('QBCore:Server:AddItem', function(itemName, amount)
|
||||
local src = source
|
||||
print(string.format('%s triggered QBCore:Server:AddItem by ID %s for %s %s. This event is deprecated due to exploitation, and will be removed soon. Adjust your events accordingly to do this server side with player functions.', GetInvokingResource(), src, amount, itemName))
|
||||
end)
|
||||
|
||||
-- Non-Chat Command Calling (ex: qb-adminmenu)
|
||||
|
||||
RegisterNetEvent('QBCore:CallCommand', function(command, args)
|
||||
local src = source
|
||||
if not QBCore.Commands.List[command] then return end
|
||||
local Player = QBCore.Functions.GetPlayer(src)
|
||||
if not Player then return end
|
||||
local hasPerm = QBCore.Functions.HasPermission(src, 'command.' .. QBCore.Commands.List[command].name)
|
||||
if hasPerm then
|
||||
if QBCore.Commands.List[command].argsrequired and #QBCore.Commands.List[command].arguments ~= 0 and not args[#QBCore.Commands.List[command].arguments] then
|
||||
TriggerClientEvent('QBCore:Notify', src, Lang:t('error.missing_args2'), 'error')
|
||||
else
|
||||
QBCore.Commands.List[command].callback(src, args)
|
||||
end
|
||||
else
|
||||
TriggerClientEvent('QBCore:Notify', src, Lang:t('error.no_access'), 'error')
|
||||
end
|
||||
end)
|
||||
|
||||
-- Use this for player vehicle spawning
|
||||
-- Vehicle server-side spawning callback (netId)
|
||||
-- use the netid on the client with the NetworkGetEntityFromNetworkId native
|
||||
-- convert it to a vehicle via the NetToVeh native
|
||||
QBCore.Functions.CreateCallback('QBCore:Server:SpawnVehicle', function(source, cb, model, coords, warp)
|
||||
local veh = QBCore.Functions.SpawnVehicle(source, model, coords, warp)
|
||||
cb(NetworkGetNetworkIdFromEntity(veh))
|
||||
end)
|
||||
|
||||
-- Use this for long distance vehicle spawning
|
||||
-- vehicle server-side spawning callback (netId)
|
||||
-- use the netid on the client with the NetworkGetEntityFromNetworkId native
|
||||
-- convert it to a vehicle via the NetToVeh native
|
||||
QBCore.Functions.CreateCallback('QBCore:Server:CreateVehicle', function(source, cb, model, coords, warp)
|
||||
local veh = QBCore.Functions.CreateAutomobile(source, model, coords, warp)
|
||||
cb(NetworkGetNetworkIdFromEntity(veh))
|
||||
end)
|
||||
|
||||
--QBCore.Functions.CreateCallback('QBCore:HasItem', function(source, cb, items, amount)
|
||||
-- https://github.com/qbcore-framework/qb-inventory/blob/e4ef156d93dd1727234d388c3f25110c350b3bcf/server/main.lua#L2066
|
||||
--end)
|
||||
@@ -0,0 +1,336 @@
|
||||
-- Add or change (a) method(s) in the QBCore.Functions table
|
||||
local function SetMethod(methodName, handler)
|
||||
if type(methodName) ~= 'string' then
|
||||
return false, 'invalid_method_name'
|
||||
end
|
||||
|
||||
QBCore.Functions[methodName] = handler
|
||||
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
|
||||
return true, 'success'
|
||||
end
|
||||
|
||||
QBCore.Functions.SetMethod = SetMethod
|
||||
exports('SetMethod', SetMethod)
|
||||
|
||||
-- Add or change (a) field(s) in the QBCore table
|
||||
local function SetField(fieldName, data)
|
||||
if type(fieldName) ~= 'string' then
|
||||
return false, 'invalid_field_name'
|
||||
end
|
||||
|
||||
QBCore[fieldName] = data
|
||||
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
|
||||
return true, 'success'
|
||||
end
|
||||
|
||||
QBCore.Functions.SetField = SetField
|
||||
exports('SetField', SetField)
|
||||
|
||||
-- Single add job function which should only be used if you planning on adding a single job
|
||||
local function AddJob(jobName, job)
|
||||
if type(jobName) ~= 'string' then
|
||||
return false, 'invalid_job_name'
|
||||
end
|
||||
|
||||
if QBCore.Shared.Jobs[jobName] then
|
||||
return false, 'job_exists'
|
||||
end
|
||||
|
||||
QBCore.Shared.Jobs[jobName] = job
|
||||
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdate', -1, 'Jobs', jobName, job)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, 'success'
|
||||
end
|
||||
|
||||
QBCore.Functions.AddJob = AddJob
|
||||
exports('AddJob', AddJob)
|
||||
|
||||
-- Multiple Add Jobs
|
||||
local function AddJobs(jobs)
|
||||
local shouldContinue = true
|
||||
local message = 'success'
|
||||
local errorItem = nil
|
||||
|
||||
for key, value in pairs(jobs) do
|
||||
if type(key) ~= 'string' then
|
||||
message = 'invalid_job_name'
|
||||
shouldContinue = false
|
||||
errorItem = jobs[key]
|
||||
break
|
||||
end
|
||||
|
||||
if QBCore.Shared.Jobs[key] then
|
||||
message = 'job_exists'
|
||||
shouldContinue = false
|
||||
errorItem = jobs[key]
|
||||
break
|
||||
end
|
||||
|
||||
QBCore.Shared.Jobs[key] = value
|
||||
end
|
||||
|
||||
if not shouldContinue then return false, message, errorItem end
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdateMultiple', -1, 'Jobs', jobs)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, message, nil
|
||||
end
|
||||
|
||||
QBCore.Functions.AddJobs = AddJobs
|
||||
exports('AddJobs', AddJobs)
|
||||
|
||||
-- Single Remove Job
|
||||
local function RemoveJob(jobName)
|
||||
if type(jobName) ~= 'string' then
|
||||
return false, 'invalid_job_name'
|
||||
end
|
||||
|
||||
if not QBCore.Shared.Jobs[jobName] then
|
||||
return false, 'job_not_exists'
|
||||
end
|
||||
|
||||
QBCore.Shared.Jobs[jobName] = nil
|
||||
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdate', -1, 'Jobs', jobName, nil)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, 'success'
|
||||
end
|
||||
|
||||
QBCore.Functions.RemoveJob = RemoveJob
|
||||
exports('RemoveJob', RemoveJob)
|
||||
|
||||
-- Single Update Job
|
||||
local function UpdateJob(jobName, job)
|
||||
if type(jobName) ~= 'string' then
|
||||
return false, 'invalid_job_name'
|
||||
end
|
||||
|
||||
if not QBCore.Shared.Jobs[jobName] then
|
||||
return false, 'job_not_exists'
|
||||
end
|
||||
|
||||
QBCore.Shared.Jobs[jobName] = job
|
||||
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdate', -1, 'Jobs', jobName, job)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, 'success'
|
||||
end
|
||||
|
||||
QBCore.Functions.UpdateJob = UpdateJob
|
||||
exports('UpdateJob', UpdateJob)
|
||||
|
||||
-- Single add item
|
||||
local function AddItem(itemName, item)
|
||||
if type(itemName) ~= 'string' then
|
||||
return false, 'invalid_item_name'
|
||||
end
|
||||
|
||||
if QBCore.Shared.Items[itemName] then
|
||||
return false, 'item_exists'
|
||||
end
|
||||
|
||||
QBCore.Shared.Items[itemName] = item
|
||||
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdate', -1, 'Items', itemName, item)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, 'success'
|
||||
end
|
||||
|
||||
QBCore.Functions.AddItem = AddItem
|
||||
exports('AddItem', AddItem)
|
||||
|
||||
-- Single update item
|
||||
local function UpdateItem(itemName, item)
|
||||
if type(itemName) ~= 'string' then
|
||||
return false, 'invalid_item_name'
|
||||
end
|
||||
if not QBCore.Shared.Items[itemName] then
|
||||
return false, 'item_not_exists'
|
||||
end
|
||||
QBCore.Shared.Items[itemName] = item
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdate', -1, 'Items', itemName, item)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, 'success'
|
||||
end
|
||||
|
||||
QBCore.Functions.UpdateItem = UpdateItem
|
||||
exports('UpdateItem', UpdateItem)
|
||||
|
||||
-- Multiple Add Items
|
||||
local function AddItems(items)
|
||||
local shouldContinue = true
|
||||
local message = 'success'
|
||||
local errorItem = nil
|
||||
|
||||
for key, value in pairs(items) do
|
||||
if type(key) ~= 'string' then
|
||||
message = 'invalid_item_name'
|
||||
shouldContinue = false
|
||||
errorItem = items[key]
|
||||
break
|
||||
end
|
||||
|
||||
if QBCore.Shared.Items[key] then
|
||||
message = 'item_exists'
|
||||
shouldContinue = false
|
||||
errorItem = items[key]
|
||||
break
|
||||
end
|
||||
|
||||
QBCore.Shared.Items[key] = value
|
||||
end
|
||||
|
||||
if not shouldContinue then return false, message, errorItem end
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdateMultiple', -1, 'Items', items)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, message, nil
|
||||
end
|
||||
|
||||
QBCore.Functions.AddItems = AddItems
|
||||
exports('AddItems', AddItems)
|
||||
|
||||
-- Single Remove Item
|
||||
local function RemoveItem(itemName)
|
||||
if type(itemName) ~= 'string' then
|
||||
return false, 'invalid_item_name'
|
||||
end
|
||||
|
||||
if not QBCore.Shared.Items[itemName] then
|
||||
return false, 'item_not_exists'
|
||||
end
|
||||
|
||||
QBCore.Shared.Items[itemName] = nil
|
||||
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdate', -1, 'Items', itemName, nil)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, 'success'
|
||||
end
|
||||
|
||||
QBCore.Functions.RemoveItem = RemoveItem
|
||||
exports('RemoveItem', RemoveItem)
|
||||
|
||||
-- Single Add Gang
|
||||
local function AddGang(gangName, gang)
|
||||
if type(gangName) ~= 'string' then
|
||||
return false, 'invalid_gang_name'
|
||||
end
|
||||
|
||||
if QBCore.Shared.Gangs[gangName] then
|
||||
return false, 'gang_exists'
|
||||
end
|
||||
|
||||
QBCore.Shared.Gangs[gangName] = gang
|
||||
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdate', -1, 'Gangs', gangName, gang)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, 'success'
|
||||
end
|
||||
|
||||
QBCore.Functions.AddGang = AddGang
|
||||
exports('AddGang', AddGang)
|
||||
|
||||
-- Multiple Add Gangs
|
||||
local function AddGangs(gangs)
|
||||
local shouldContinue = true
|
||||
local message = 'success'
|
||||
local errorItem = nil
|
||||
|
||||
for key, value in pairs(gangs) do
|
||||
if type(key) ~= 'string' then
|
||||
message = 'invalid_gang_name'
|
||||
shouldContinue = false
|
||||
errorItem = gangs[key]
|
||||
break
|
||||
end
|
||||
|
||||
if QBCore.Shared.Gangs[key] then
|
||||
message = 'gang_exists'
|
||||
shouldContinue = false
|
||||
errorItem = gangs[key]
|
||||
break
|
||||
end
|
||||
|
||||
QBCore.Shared.Gangs[key] = value
|
||||
end
|
||||
|
||||
if not shouldContinue then return false, message, errorItem end
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdateMultiple', -1, 'Gangs', gangs)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, message, nil
|
||||
end
|
||||
|
||||
QBCore.Functions.AddGangs = AddGangs
|
||||
exports('AddGangs', AddGangs)
|
||||
|
||||
-- Single Remove Gang
|
||||
local function RemoveGang(gangName)
|
||||
if type(gangName) ~= 'string' then
|
||||
return false, 'invalid_gang_name'
|
||||
end
|
||||
|
||||
if not QBCore.Shared.Gangs[gangName] then
|
||||
return false, 'gang_not_exists'
|
||||
end
|
||||
|
||||
QBCore.Shared.Gangs[gangName] = nil
|
||||
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdate', -1, 'Gangs', gangName, nil)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, 'success'
|
||||
end
|
||||
|
||||
QBCore.Functions.RemoveGang = RemoveGang
|
||||
exports('RemoveGang', RemoveGang)
|
||||
|
||||
-- Single Update Gang
|
||||
local function UpdateGang(gangName, gang)
|
||||
if type(gangName) ~= 'string' then
|
||||
return false, 'invalid_gang_name'
|
||||
end
|
||||
|
||||
if not QBCore.Shared.Gangs[gangName] then
|
||||
return false, 'gang_not_exists'
|
||||
end
|
||||
|
||||
QBCore.Shared.Gangs[gangName] = gang
|
||||
|
||||
TriggerClientEvent('QBCore:Client:OnSharedUpdate', -1, 'Gangs', gangName, gang)
|
||||
TriggerEvent('QBCore:Server:UpdateObject')
|
||||
return true, 'success'
|
||||
end
|
||||
|
||||
QBCore.Functions.UpdateGang = UpdateGang
|
||||
exports('UpdateGang', UpdateGang)
|
||||
|
||||
local resourceName = GetCurrentResourceName()
|
||||
local function GetCoreVersion(InvokingResource)
|
||||
local resourceVersion = GetResourceMetadata(resourceName, 'version')
|
||||
if InvokingResource and InvokingResource ~= '' then
|
||||
print(('%s called qbcore version check: %s'):format(InvokingResource or 'Unknown Resource', resourceVersion))
|
||||
end
|
||||
return resourceVersion
|
||||
end
|
||||
|
||||
QBCore.Functions.GetCoreVersion = GetCoreVersion
|
||||
exports('GetCoreVersion', GetCoreVersion)
|
||||
|
||||
local function ExploitBan(playerId, origin)
|
||||
local name = GetPlayerName(playerId)
|
||||
MySQL.insert('INSERT INTO bans (name, license, discord, ip, reason, expire, bannedby) VALUES (?, ?, ?, ?, ?, ?, ?)', {
|
||||
name,
|
||||
QBCore.Functions.GetIdentifier(playerId, 'license'),
|
||||
QBCore.Functions.GetIdentifier(playerId, 'discord'),
|
||||
QBCore.Functions.GetIdentifier(playerId, 'ip'),
|
||||
origin,
|
||||
2147483647,
|
||||
'Anti Cheat'
|
||||
})
|
||||
DropPlayer(playerId, Lang:t('info.exploit_banned', { discord = QBCore.Config.Server.Discord }))
|
||||
TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'Anti-Cheat', 'red', name .. ' has been banned for exploiting ' .. origin, true)
|
||||
end
|
||||
|
||||
exports('ExploitBan', ExploitBan)
|
||||
+671
-112
@@ -1,14 +1,444 @@
|
||||
-- Callbacks
|
||||
QBCore.Functions = {}
|
||||
QBCore.Player_Buckets = {}
|
||||
QBCore.Entity_Buckets = {}
|
||||
QBCore.UsableItems = {}
|
||||
|
||||
function QBCore.Functions.CreateCallback(name, cb)
|
||||
QBCore.ServerCallbacks[name] = cb
|
||||
-- Getters
|
||||
-- Get your player first and then trigger a function on them
|
||||
-- ex: local player = QBCore.Functions.GetPlayer(source)
|
||||
-- ex: local example = player.Functions.functionname(parameter)
|
||||
|
||||
---Gets the coordinates of an entity
|
||||
---@param entity number
|
||||
---@return vector4
|
||||
function QBCore.Functions.GetCoords(entity)
|
||||
local coords = GetEntityCoords(entity, false)
|
||||
local heading = GetEntityHeading(entity)
|
||||
return vector4(coords.x, coords.y, coords.z, heading)
|
||||
end
|
||||
|
||||
---Gets player identifier of the given type
|
||||
---@param source any
|
||||
---@param idtype string
|
||||
---@return string?
|
||||
function QBCore.Functions.GetIdentifier(source, idtype)
|
||||
if GetConvarInt('sv_fxdkMode', 0) == 1 then return 'license:fxdk' end
|
||||
return GetPlayerIdentifierByType(source, idtype or 'license')
|
||||
end
|
||||
|
||||
---Gets a players server id (source). Returns 0 if no player is found.
|
||||
---@param identifier string
|
||||
---@return number
|
||||
function QBCore.Functions.GetSource(identifier)
|
||||
for src, _ in pairs(QBCore.Players) do
|
||||
local idens = GetPlayerIdentifiers(src)
|
||||
for _, id in pairs(idens) do
|
||||
if identifier == id then
|
||||
return src
|
||||
end
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
---Get player with given server id (source)
|
||||
---@param source any
|
||||
---@return table
|
||||
function QBCore.Functions.GetPlayer(source)
|
||||
if tonumber(source) ~= nil then -- If a number is a string ("1"), this will still correctly identify the index to use.
|
||||
return QBCore.Players[tonumber(source)]
|
||||
else
|
||||
return QBCore.Players[QBCore.Functions.GetSource(source)]
|
||||
end
|
||||
end
|
||||
|
||||
---Get player by citizen id
|
||||
---@param citizenid string
|
||||
---@return table?
|
||||
function QBCore.Functions.GetPlayerByCitizenId(citizenid)
|
||||
for src in pairs(QBCore.Players) do
|
||||
if QBCore.Players[src].PlayerData.citizenid == citizenid then
|
||||
return QBCore.Players[src]
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---Get offline player by citizen id
|
||||
---@param citizenid string
|
||||
---@return table?
|
||||
function QBCore.Functions.GetOfflinePlayerByCitizenId(citizenid)
|
||||
return QBCore.Player.GetOfflinePlayer(citizenid)
|
||||
end
|
||||
|
||||
---Get player by license
|
||||
---@param license string
|
||||
---@return table?
|
||||
function QBCore.Functions.GetPlayerByLicense(license)
|
||||
return QBCore.Player.GetPlayerByLicense(license)
|
||||
end
|
||||
|
||||
---Get player by phone number
|
||||
---@param number number
|
||||
---@return table?
|
||||
function QBCore.Functions.GetPlayerByPhone(number)
|
||||
for src in pairs(QBCore.Players) do
|
||||
if QBCore.Players[src].PlayerData.charinfo.phone == number then
|
||||
return QBCore.Players[src]
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---Get player by account id
|
||||
---@param account string
|
||||
---@return table?
|
||||
function QBCore.Functions.GetPlayerByAccount(account)
|
||||
for src in pairs(QBCore.Players) do
|
||||
if QBCore.Players[src].PlayerData.charinfo.account == account then
|
||||
return QBCore.Players[src]
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---Get player passing property and value to check exists
|
||||
---@param property string
|
||||
---@param value string
|
||||
---@return table?
|
||||
function QBCore.Functions.GetPlayerByCharInfo(property, value)
|
||||
for src in pairs(QBCore.Players) do
|
||||
local charinfo = QBCore.Players[src].PlayerData.charinfo
|
||||
if charinfo[property] ~= nil and charinfo[property] == value then
|
||||
return QBCore.Players[src]
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
---Get all players. Returns the server ids of all players.
|
||||
---@return table
|
||||
function QBCore.Functions.GetPlayers()
|
||||
local sources = {}
|
||||
for k in pairs(QBCore.Players) do
|
||||
sources[#sources + 1] = k
|
||||
end
|
||||
return sources
|
||||
end
|
||||
|
||||
---Will return an array of QB Player class instances
|
||||
---unlike the GetPlayers() wrapper which only returns IDs
|
||||
---@return table
|
||||
function QBCore.Functions.GetQBPlayers()
|
||||
return QBCore.Players
|
||||
end
|
||||
|
||||
---Gets a list of all on duty players of a specified job and the number
|
||||
---@param job string
|
||||
---@return table, number
|
||||
function QBCore.Functions.GetPlayersOnDuty(job)
|
||||
local players = {}
|
||||
local count = 0
|
||||
for src, Player in pairs(QBCore.Players) do
|
||||
if Player.PlayerData.job.name == job then
|
||||
if Player.PlayerData.job.onduty then
|
||||
players[#players + 1] = src
|
||||
count += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return players, count
|
||||
end
|
||||
|
||||
---Returns only the amount of players on duty for the specified job
|
||||
---@param job string
|
||||
---@return number
|
||||
function QBCore.Functions.GetDutyCount(job)
|
||||
local count = 0
|
||||
for _, Player in pairs(QBCore.Players) do
|
||||
if Player.PlayerData.job.name == job then
|
||||
if Player.PlayerData.job.onduty then
|
||||
count += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
--- @param source number source player's server ID.
|
||||
--- @param coords vector The coordinates to calculate the distance from. Can be a table with x, y, z fields or a vector3. If not provided, the source player's Ped's coordinates are used.
|
||||
--- @return string closestPlayer - The Player that is closest to the source player (or the provided coordinates). Returns -1 if no Players are found.
|
||||
--- @return number closestDistance - The distance to the closest Player. Returns -1 if no Players are found.
|
||||
function QBCore.Functions.GetClosestPlayer(source, coords)
|
||||
local ped = GetPlayerPed(source)
|
||||
local players = GetPlayers()
|
||||
local closestDistance, closestPlayer = -1, -1
|
||||
if coords then coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords end
|
||||
if not coords then coords = GetEntityCoords(ped) end
|
||||
for i = 1, #players do
|
||||
local playerId = players[i]
|
||||
local playerPed = GetPlayerPed(playerId)
|
||||
if playerPed ~= ped then
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
local distance = #(playerCoords - coords)
|
||||
if closestDistance == -1 or distance < closestDistance then
|
||||
closestPlayer = playerId
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
end
|
||||
return closestPlayer, closestDistance
|
||||
end
|
||||
|
||||
--- @param source number source player's server ID.
|
||||
--- @param coords vector The coordinates to calculate the distance from. Can be a table with x, y, z fields or a vector3. If not provided, the source player's Ped's coordinates are used.
|
||||
--- @return number closestObject - The Object that is closest to the source player (or the provided coordinates). Returns -1 if no Objects are found.
|
||||
--- @return number closestDistance - The distance to the closest Object. Returns -1 if no Objects are found.
|
||||
function QBCore.Functions.GetClosestObject(source, coords)
|
||||
local ped = GetPlayerPed(source)
|
||||
local objects = GetAllObjects()
|
||||
local closestDistance, closestObject = -1, -1
|
||||
if coords then coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords end
|
||||
if not coords then coords = GetEntityCoords(ped) end
|
||||
for i = 1, #objects do
|
||||
local objectCoords = GetEntityCoords(objects[i])
|
||||
local distance = #(objectCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestObject = objects[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
return closestObject, closestDistance
|
||||
end
|
||||
|
||||
--- @param source number source player's server ID.
|
||||
--- @param coords vector The coordinates to calculate the distance from. Can be a table with x, y, z fields or a vector3. If not provided, the source player's Ped's coordinates are used.
|
||||
--- @return number closestVehicle - The Vehicle that is closest to the source player (or the provided coordinates). Returns -1 if no Vehicles are found.
|
||||
--- @return number closestDistance - The distance to the closest Vehicle. Returns -1 if no Vehicles are found.
|
||||
function QBCore.Functions.GetClosestVehicle(source, coords)
|
||||
local ped = GetPlayerPed(source)
|
||||
local vehicles = GetAllVehicles()
|
||||
local closestDistance, closestVehicle = -1, -1
|
||||
if coords then coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords end
|
||||
if not coords then coords = GetEntityCoords(ped) end
|
||||
for i = 1, #vehicles do
|
||||
local vehicleCoords = GetEntityCoords(vehicles[i])
|
||||
local distance = #(vehicleCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestVehicle = vehicles[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
return closestVehicle, closestDistance
|
||||
end
|
||||
|
||||
--- @param source number source player's server ID.
|
||||
--- @param coords vector The coordinates to calculate the distance from. Can be a table with x, y, z fields or a vector3. If not provided, the source player's Ped's coordinates are used.
|
||||
--- @return number closestPed - The Ped that is closest to the source player (or the provided coordinates). Returns -1 if no Peds are found.
|
||||
--- @return number closestDistance - The distance to the closest Ped. Returns -1 if no Peds are found.
|
||||
function QBCore.Functions.GetClosestPed(source, coords)
|
||||
local ped = GetPlayerPed(source)
|
||||
local peds = GetAllPeds()
|
||||
local closestDistance, closestPed = -1, -1
|
||||
if coords then coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords end
|
||||
if not coords then coords = GetEntityCoords(ped) end
|
||||
for i = 1, #peds do
|
||||
if peds[i] ~= ped then
|
||||
local pedCoords = GetEntityCoords(peds[i])
|
||||
local distance = #(pedCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestPed = peds[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
end
|
||||
return closestPed, closestDistance
|
||||
end
|
||||
|
||||
-- Routing buckets (Only touch if you know what you are doing)
|
||||
|
||||
---Returns the objects related to buckets, first returned value is the player buckets, second one is entity buckets
|
||||
---@return table, table
|
||||
function QBCore.Functions.GetBucketObjects()
|
||||
return QBCore.Player_Buckets, QBCore.Entity_Buckets
|
||||
end
|
||||
|
||||
---Will set the provided player id / source into the provided bucket id
|
||||
---@param source any
|
||||
---@param bucket any
|
||||
---@return boolean
|
||||
function QBCore.Functions.SetPlayerBucket(source, bucket)
|
||||
if source and bucket then
|
||||
local plicense = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
Player(source).state:set('instance', bucket, true)
|
||||
SetPlayerRoutingBucket(source, bucket)
|
||||
QBCore.Player_Buckets[plicense] = { id = source, bucket = bucket }
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
---Will set any entity into the provided bucket, for example peds / vehicles / props / etc.
|
||||
---@param entity number
|
||||
---@param bucket number
|
||||
---@return boolean
|
||||
function QBCore.Functions.SetEntityBucket(entity, bucket)
|
||||
if entity and bucket then
|
||||
SetEntityRoutingBucket(entity, bucket)
|
||||
QBCore.Entity_Buckets[entity] = { id = entity, bucket = bucket }
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
---Will return an array of all the player ids inside the current bucket
|
||||
---@param bucket number
|
||||
---@return table|boolean
|
||||
function QBCore.Functions.GetPlayersInBucket(bucket)
|
||||
local curr_bucket_pool = {}
|
||||
if QBCore.Player_Buckets and next(QBCore.Player_Buckets) then
|
||||
for _, v in pairs(QBCore.Player_Buckets) do
|
||||
if v.bucket == bucket then
|
||||
curr_bucket_pool[#curr_bucket_pool + 1] = v.id
|
||||
end
|
||||
end
|
||||
return curr_bucket_pool
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
---Will return an array of all the entities inside the current bucket
|
||||
---(not for player entities, use GetPlayersInBucket for that)
|
||||
---@param bucket number
|
||||
---@return table|boolean
|
||||
function QBCore.Functions.GetEntitiesInBucket(bucket)
|
||||
local curr_bucket_pool = {}
|
||||
if QBCore.Entity_Buckets and next(QBCore.Entity_Buckets) then
|
||||
for _, v in pairs(QBCore.Entity_Buckets) do
|
||||
if v.bucket == bucket then
|
||||
curr_bucket_pool[#curr_bucket_pool + 1] = v.id
|
||||
end
|
||||
end
|
||||
return curr_bucket_pool
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
---Server side vehicle creation with optional callback
|
||||
---the CreateVehicle RPC still uses the client for creation so players must be near
|
||||
---@param source any
|
||||
---@param model any
|
||||
---@param coords vector
|
||||
---@param warp boolean
|
||||
---@return number
|
||||
function QBCore.Functions.SpawnVehicle(source, model, coords, warp)
|
||||
local ped = GetPlayerPed(source)
|
||||
model = type(model) == 'string' and joaat(model) or model
|
||||
if not coords then coords = GetEntityCoords(ped) end
|
||||
local heading = coords.w and coords.w or 0.0
|
||||
local veh = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, true)
|
||||
while not DoesEntityExist(veh) do Wait(0) end
|
||||
if warp then
|
||||
while GetVehiclePedIsIn(ped) ~= veh do
|
||||
Wait(0)
|
||||
TaskWarpPedIntoVehicle(ped, veh, -1)
|
||||
end
|
||||
end
|
||||
while NetworkGetEntityOwner(veh) ~= source do Wait(0) end
|
||||
return veh
|
||||
end
|
||||
|
||||
---Server side vehicle creation with optional callback
|
||||
---the CreateAutomobile native is still experimental but doesn't use client for creation
|
||||
---doesn't work for all vehicles!
|
||||
---comment
|
||||
---@param source any
|
||||
---@param model any
|
||||
---@param coords vector
|
||||
---@param warp boolean
|
||||
---@return number
|
||||
function QBCore.Functions.CreateAutomobile(source, model, coords, warp)
|
||||
model = type(model) == 'string' and joaat(model) or model
|
||||
if not coords then coords = GetEntityCoords(GetPlayerPed(source)) end
|
||||
local heading = coords.w and coords.w or 0.0
|
||||
local CreateAutomobile = `CREATE_AUTOMOBILE`
|
||||
local veh = Citizen.InvokeNative(CreateAutomobile, model, coords, heading, true, true)
|
||||
while not DoesEntityExist(veh) do Wait(0) end
|
||||
if warp then TaskWarpPedIntoVehicle(GetPlayerPed(source), veh, -1) end
|
||||
return veh
|
||||
end
|
||||
|
||||
--- New & more reliable server side native for creating vehicles
|
||||
---comment
|
||||
---@param source any
|
||||
---@param model any
|
||||
---@param vehtype any
|
||||
-- The appropriate vehicle type for the model info.
|
||||
-- Can be one of automobile, bike, boat, heli, plane, submarine, trailer, and (potentially), train.
|
||||
-- This should be the same type as the type field in vehicles.meta.
|
||||
---@param coords vector
|
||||
---@param warp boolean
|
||||
---@return number
|
||||
function QBCore.Functions.CreateVehicle(source, model, vehtype, coords, warp)
|
||||
model = type(model) == 'string' and joaat(model) or model
|
||||
vehtype = type(vehtype) == 'string' and tostring(vehtype) or vehtype
|
||||
if not coords then coords = GetEntityCoords(GetPlayerPed(source)) end
|
||||
local heading = coords.w and coords.w or 0.0
|
||||
local veh = CreateVehicleServerSetter(model, vehtype, coords, heading)
|
||||
while not DoesEntityExist(veh) do Wait(0) end
|
||||
if warp then TaskWarpPedIntoVehicle(GetPlayerPed(source), veh, -1) end
|
||||
return veh
|
||||
end
|
||||
|
||||
function PaycheckInterval()
|
||||
if not next(QBCore.Players) then
|
||||
SetTimeout(QBCore.Config.Money.PayCheckTimeOut * (60 * 1000), PaycheckInterval) -- Prevent paychecks from stopping forever once 0 players
|
||||
return
|
||||
end
|
||||
for _, Player in pairs(QBCore.Players) do
|
||||
if not Player then return end
|
||||
local payment = QBShared.Jobs[Player.PlayerData.job.name]['grades'][tostring(Player.PlayerData.job.grade.level)].payment
|
||||
if not payment then payment = Player.PlayerData.job.payment end
|
||||
if Player.PlayerData.job and payment > 0 and (QBShared.Jobs[Player.PlayerData.job.name].offDutyPay or Player.PlayerData.job.onduty) then
|
||||
if QBCore.Config.Money.PayCheckSociety then
|
||||
local account = exports['qb-banking']:GetAccountBalance(Player.PlayerData.job.name)
|
||||
if account ~= 0 then
|
||||
if account < payment then
|
||||
TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('error.company_too_poor'), 'error')
|
||||
else
|
||||
Player.Functions.AddMoney('bank', payment, 'paycheck')
|
||||
exports['qb-banking']:RemoveMoney(Player.PlayerData.job.name, payment, 'Employee Paycheck')
|
||||
TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment }))
|
||||
end
|
||||
else
|
||||
Player.Functions.AddMoney('bank', payment, 'paycheck')
|
||||
TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment }))
|
||||
end
|
||||
else
|
||||
Player.Functions.AddMoney('bank', payment, 'paycheck')
|
||||
TriggerClientEvent('QBCore:Notify', Player.PlayerData.source, Lang:t('info.received_paycheck', { value = payment }))
|
||||
end
|
||||
end
|
||||
end
|
||||
SetTimeout(QBCore.Config.Money.PayCheckTimeOut * (60 * 1000), PaycheckInterval)
|
||||
end
|
||||
|
||||
-- Callback Functions --
|
||||
|
||||
---Trigger Client Callback
|
||||
---@param name string
|
||||
---@param source any
|
||||
---@param cb function
|
||||
---@param ... any
|
||||
function QBCore.Functions.TriggerClientCallback(name, source, ...)
|
||||
local cb = nil
|
||||
local args = { ... }
|
||||
|
||||
if QBCore.Functions.IsFunction(args[1]) then
|
||||
if QBCore.Shared.IsFunction(args[1]) then
|
||||
cb = args[1]
|
||||
table.remove(args, 1)
|
||||
end
|
||||
@@ -26,8 +456,201 @@ function QBCore.Functions.TriggerClientCallback(name, source, ...)
|
||||
end
|
||||
end
|
||||
|
||||
-- Functions
|
||||
---Create Server Callback
|
||||
---@param name string
|
||||
---@param cb function
|
||||
function QBCore.Functions.CreateCallback(name, cb)
|
||||
QBCore.ServerCallbacks[name] = cb
|
||||
end
|
||||
|
||||
-- Items
|
||||
|
||||
---Create a usable item
|
||||
---@param item string
|
||||
---@param data function
|
||||
function QBCore.Functions.CreateUseableItem(item, data)
|
||||
local rawFunc = nil
|
||||
|
||||
if type(data) == 'table' then
|
||||
if rawget(data, '__cfx_functionReference') then
|
||||
rawFunc = data
|
||||
elseif data.cb and rawget(data.cb, '__cfx_functionReference') then
|
||||
rawFunc = data.cb
|
||||
elseif data.callback and rawget(data.callback, '__cfx_functionReference') then
|
||||
rawFunc = data.callback
|
||||
end
|
||||
elseif type(data) == 'function' then
|
||||
rawFunc = data
|
||||
end
|
||||
|
||||
if rawFunc then
|
||||
QBCore.UsableItems[item] = {
|
||||
func = rawFunc,
|
||||
resource = GetInvokingResource()
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
---Checks if the given item is usable
|
||||
---@param item string
|
||||
---@return any
|
||||
function QBCore.Functions.CanUseItem(item)
|
||||
return QBCore.UsableItems[item]
|
||||
end
|
||||
|
||||
---Use item
|
||||
---@param source any
|
||||
---@param item string
|
||||
function QBCore.Functions.UseItem(source, item)
|
||||
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||
exports['qb-inventory']:UseItem(source, item)
|
||||
end
|
||||
|
||||
---Kick Player
|
||||
---@param source any
|
||||
---@param reason string
|
||||
---@param setKickReason boolean
|
||||
---@param deferrals boolean
|
||||
function QBCore.Functions.Kick(source, reason, setKickReason, deferrals)
|
||||
reason = '\n' .. reason .. '\n🔸 Check our Discord for further information: ' .. QBCore.Config.Server.Discord
|
||||
if setKickReason then
|
||||
setKickReason(reason)
|
||||
end
|
||||
CreateThread(function()
|
||||
if deferrals then
|
||||
deferrals.update(reason)
|
||||
Wait(2500)
|
||||
end
|
||||
if source then
|
||||
DropPlayer(source, reason)
|
||||
end
|
||||
for _ = 0, 4 do
|
||||
while true do
|
||||
if source then
|
||||
if GetPlayerPing(source) >= 0 then
|
||||
break
|
||||
end
|
||||
Wait(100)
|
||||
CreateThread(function()
|
||||
DropPlayer(source, reason)
|
||||
end)
|
||||
end
|
||||
end
|
||||
Wait(5000)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
---Check if player is whitelisted, kept like this for backwards compatibility or future plans
|
||||
---@param source any
|
||||
---@return boolean
|
||||
function QBCore.Functions.IsWhitelisted(source)
|
||||
if not QBCore.Config.Server.Whitelist then return true end
|
||||
if QBCore.Functions.HasPermission(source, QBCore.Config.Server.WhitelistPermission) then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Setting & Removing Permissions
|
||||
|
||||
---Add permission for player
|
||||
---@param source any
|
||||
---@param permission string
|
||||
function QBCore.Functions.AddPermission(source, permission)
|
||||
if not IsPlayerAceAllowed(source, permission) then
|
||||
ExecuteCommand(('add_principal player.%s qbcore.%s'):format(source, permission))
|
||||
QBCore.Commands.Refresh(source)
|
||||
end
|
||||
end
|
||||
|
||||
---Remove permission from player
|
||||
---@param source any
|
||||
---@param permission string
|
||||
function QBCore.Functions.RemovePermission(source, permission)
|
||||
if permission then
|
||||
if IsPlayerAceAllowed(source, permission) then
|
||||
ExecuteCommand(('remove_principal player.%s qbcore.%s'):format(source, permission))
|
||||
QBCore.Commands.Refresh(source)
|
||||
end
|
||||
else
|
||||
for _, v in pairs(QBCore.Config.Server.Permissions) do
|
||||
if IsPlayerAceAllowed(source, v) then
|
||||
ExecuteCommand(('remove_principal player.%s qbcore.%s'):format(source, v))
|
||||
QBCore.Commands.Refresh(source)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Checking for Permission Level
|
||||
|
||||
---Check if player has permission
|
||||
---@param source any
|
||||
---@param permission string
|
||||
---@return boolean
|
||||
function QBCore.Functions.HasPermission(source, permission)
|
||||
if type(permission) == 'string' then
|
||||
if IsPlayerAceAllowed(source, permission) then return true end
|
||||
elseif type(permission) == 'table' then
|
||||
for _, permLevel in pairs(permission) do
|
||||
if IsPlayerAceAllowed(source, permLevel) then return true end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
---Get the players permissions
|
||||
---@param source any
|
||||
---@return table
|
||||
function QBCore.Functions.GetPermission(source)
|
||||
local src = source
|
||||
local perms = {}
|
||||
for _, v in pairs(QBCore.Config.Server.Permissions) do
|
||||
if IsPlayerAceAllowed(src, v) then
|
||||
perms[v] = true
|
||||
end
|
||||
end
|
||||
return perms
|
||||
end
|
||||
|
||||
---Get admin messages opt-in state for player
|
||||
---@param source any
|
||||
---@return boolean
|
||||
function QBCore.Functions.IsOptin(source)
|
||||
local license = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
if not license or not QBCore.Functions.HasPermission(source, 'admin') then return false end
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
return Player.PlayerData.optin
|
||||
end
|
||||
|
||||
---Toggle opt-in to admin messages
|
||||
---@param source any
|
||||
function QBCore.Functions.ToggleOptin(source)
|
||||
local license = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
if not license or not QBCore.Functions.HasPermission(source, 'admin') then return end
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
Player.PlayerData.optin = not Player.PlayerData.optin
|
||||
Player.Functions.SetPlayerData('optin', Player.PlayerData.optin)
|
||||
end
|
||||
|
||||
---Check if player is banned
|
||||
---@param source any
|
||||
---@return boolean, string?
|
||||
function QBCore.Functions.IsPlayerBanned(source)
|
||||
local plicense = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
local result = MySQL.single.await('SELECT id, reason, expire FROM bans WHERE license = ?', { plicense })
|
||||
if not result then return false end
|
||||
if os.time() < result.expire then
|
||||
local timeTable = os.date('*t', tonumber(result.expire))
|
||||
return true, 'You have been banned from the server:\n' .. result.reason .. '\nYour ban expires ' .. timeTable.day .. '/' .. timeTable.month .. '/' .. timeTable.year .. ' ' .. timeTable.hour .. ':' .. timeTable.min .. '\n'
|
||||
else
|
||||
MySQL.query('DELETE FROM bans WHERE id = ?', { result.id })
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Retrieves information about the database connection.
|
||||
--- @return table; A table containing the database information.
|
||||
function QBCore.Functions.GetDatabaseInfo()
|
||||
local details = {
|
||||
exists = false,
|
||||
@@ -56,11 +679,9 @@ function QBCore.Functions.GetDatabaseInfo()
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetIdentifier(source, idtype)
|
||||
if GetConvarInt('sv_fxdkMode', 0) == 1 then return 'license:fxdk' end
|
||||
return GetPlayerIdentifierByType(source, idtype or 'license')
|
||||
end
|
||||
|
||||
---Check for duplicate license
|
||||
---@param license any
|
||||
---@return boolean
|
||||
function QBCore.Functions.IsLicenseInUse(license)
|
||||
local players = GetPlayers()
|
||||
for _, player in pairs(players) do
|
||||
@@ -70,111 +691,49 @@ function QBCore.Functions.IsLicenseInUse(license)
|
||||
return false
|
||||
end
|
||||
|
||||
function QBCore.Functions.HasPermission(source, permission)
|
||||
if type(permission) == 'string' then
|
||||
if IsPlayerAceAllowed(source, permission) then return true end
|
||||
elseif type(permission) == 'table' then
|
||||
for _, permLevel in pairs(permission) do
|
||||
if IsPlayerAceAllowed(source, permLevel) then return true end
|
||||
end
|
||||
-- Utility functions
|
||||
|
||||
---Check if a player has an item [deprecated]
|
||||
---@param source any
|
||||
---@param items table|string
|
||||
---@param amount number
|
||||
---@return boolean
|
||||
function QBCore.Functions.HasItem(source, items, amount)
|
||||
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||
return exports['qb-inventory']:HasItem(source, items, amount)
|
||||
end
|
||||
|
||||
---Notify
|
||||
---@param source any
|
||||
---@param text string
|
||||
---@param type string
|
||||
---@param length number
|
||||
function QBCore.Functions.Notify(source, text, type, length)
|
||||
TriggerClientEvent('QBCore:Notify', source, text, type, length)
|
||||
end
|
||||
|
||||
---???? ... ok
|
||||
---@param source any
|
||||
---@param data any
|
||||
---@param pattern any
|
||||
---@return boolean
|
||||
function QBCore.Functions.PrepForSQL(source, data, pattern)
|
||||
data = tostring(data)
|
||||
local src = source
|
||||
local player = QBCore.Functions.GetPlayer(src)
|
||||
local result = string.match(data, pattern)
|
||||
if not result or string.len(result) ~= string.len(data) then
|
||||
TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'SQL Exploit Attempted', 'red', string.format('%s attempted to exploit SQL!', player.PlayerData.license))
|
||||
return false
|
||||
end
|
||||
return false
|
||||
return true
|
||||
end
|
||||
|
||||
function QBCore.Functions.IsWhitelisted(source)
|
||||
if not QBCore.Config.Server.Whitelist then return true end
|
||||
if QBCore.Functions.HasPermission(source, QBCore.Config.Server.WhitelistPermission) then return true end
|
||||
return false
|
||||
end
|
||||
|
||||
function QBCore.Functions.IsPlayerBanned(source)
|
||||
local plicense = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
local result = MySQL.single.await('SELECT id, reason, expire FROM bans WHERE license = ?', { plicense })
|
||||
if not result then return false end
|
||||
if os.time() < result.expire then
|
||||
local timeTable = os.date('*t', tonumber(result.expire))
|
||||
return true, 'You have been banned from the server:\n' .. result.reason .. '\nYour ban expires ' .. timeTable.day .. '/' .. timeTable.month .. '/' .. timeTable.year .. ' ' .. timeTable.hour .. ':' .. timeTable.min .. '\n'
|
||||
else
|
||||
MySQL.query('DELETE FROM bans WHERE id = ?', { result.id })
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetPlayer(source)
|
||||
if tonumber(source) then
|
||||
return QBCore.Players[tonumber(source)]
|
||||
else
|
||||
return QBCore.Players[QBCore.Functions.GetSource(source)]
|
||||
for functionName, func in pairs(QBCore.Functions) do
|
||||
if type(func) == 'function' then
|
||||
exports(functionName, func)
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetQBPlayers()
|
||||
return QBCore.Players
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreateUseableItem(item, data)
|
||||
local rawFunc = nil
|
||||
|
||||
if type(data) == 'table' then
|
||||
if rawget(data, '__cfx_functionReference') then
|
||||
rawFunc = data
|
||||
elseif data.cb and rawget(data.cb, '__cfx_functionReference') then
|
||||
rawFunc = data.cb
|
||||
elseif data.callback and rawget(data.callback, '__cfx_functionReference') then
|
||||
rawFunc = data.callback
|
||||
end
|
||||
elseif type(data) == 'function' then
|
||||
rawFunc = data
|
||||
end
|
||||
|
||||
if rawFunc then
|
||||
QBCore.UsableItems[item] = {
|
||||
func = rawFunc,
|
||||
resource = GetInvokingResource()
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
-- Player Setup
|
||||
|
||||
function QBCore.Functions.CreateCitizenId()
|
||||
local CitizenId = tostring(QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(5)):upper()
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE citizenid = ?) AS uniqueCheck', { CitizenId })
|
||||
if result == 0 then return CitizenId end
|
||||
return QBCore.Functions.CreateCitizenId()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreateAccountNumber()
|
||||
local AccountNumber = 'US0' .. math.random(1, 9) .. 'QBCore' .. math.random(1111, 9999) .. math.random(1111, 9999) .. math.random(11, 99)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(charinfo, "$.account")) = ?) AS uniqueCheck', { AccountNumber })
|
||||
if result == 0 then return AccountNumber end
|
||||
return QBCore.Functions.CreateAccountNumber()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreatePhoneNumber()
|
||||
local PhoneNumber = math.random(100, 999) .. math.random(1000000, 9999999)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(charinfo, "$.phone")) = ?) AS uniqueCheck', { PhoneNumber })
|
||||
if result == 0 then return PhoneNumber end
|
||||
return QBCore.Functions.CreatePhoneNumber()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreateFingerId()
|
||||
local FingerId = tostring(QBCore.Shared.RandomStr(2) .. QBCore.Shared.RandomInt(3) .. QBCore.Shared.RandomStr(1) .. QBCore.Shared.RandomInt(2) .. QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(4))
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(metadata, "$.fingerprint")) = ?) AS uniqueCheck', { FingerId })
|
||||
if result == 0 then return FingerId end
|
||||
return QBCore.Functions.CreateFingerId()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreateWalletId()
|
||||
local WalletId = 'QB-' .. math.random(11111111, 99999999)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(metadata, "$.walletid")) = ?) AS uniqueCheck', { WalletId })
|
||||
if result == 0 then return WalletId end
|
||||
return QBCore.Functions.CreateWalletId()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreateSerialNumber()
|
||||
local SerialNumber = math.random(11111111, 99999999)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(metadata, "$.phonedata.SerialNumber")) = ?) AS uniqueCheck', { SerialNumber })
|
||||
if result == 0 then return SerialNumber end
|
||||
return QBCore.Functions.CreateSerialNumber()
|
||||
end
|
||||
-- Access a specific function directly:
|
||||
-- exports['qb-core']:Notify(source, 'Hello Player!')
|
||||
|
||||
+42
-67
@@ -1,74 +1,49 @@
|
||||
-- Database Verification
|
||||
QBCore = {}
|
||||
QBCore.Config = QBConfig
|
||||
QBCore.Shared = QBShared
|
||||
QBCore.ClientCallbacks = {}
|
||||
QBCore.ServerCallbacks = {}
|
||||
|
||||
local readyFunction = MySQL.ready
|
||||
local databaseConnected, bansTableExists = readyFunction == nil, readyFunction == nil
|
||||
if readyFunction ~= nil then
|
||||
MySQL.ready(function()
|
||||
databaseConnected = true
|
||||
local DatabaseInfo = QBCore.Functions.GetDatabaseInfo()
|
||||
if not DatabaseInfo or not DatabaseInfo.exists then return end
|
||||
local result = MySQL.query.await('SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ? AND TABLE_NAME = "bans";', { DatabaseInfo.database })
|
||||
if result and result[1] then
|
||||
bansTableExists = true
|
||||
-- Get the full QBCore object (default behavior):
|
||||
-- local QBCore = GetCoreObject()
|
||||
|
||||
-- Get only specific parts of QBCore:
|
||||
-- local QBCore = GetCoreObject({'Players', 'Config'})
|
||||
|
||||
local function GetCoreObject(filters)
|
||||
if not filters then return QBCore end
|
||||
local results = {}
|
||||
for i = 1, #filters do
|
||||
local key = filters[i]
|
||||
if QBCore[key] then
|
||||
results[key] = QBCore[key]
|
||||
end
|
||||
end)
|
||||
end
|
||||
return results
|
||||
end
|
||||
exports('GetCoreObject', GetCoreObject)
|
||||
|
||||
-- Handle player connect
|
||||
local function GetSharedItems()
|
||||
return QBShared.Items
|
||||
end
|
||||
exports('GetSharedItems', GetSharedItems)
|
||||
|
||||
AddEventHandler('playerConnecting', function(name, _, deferrals)
|
||||
local src = source
|
||||
deferrals.defer()
|
||||
if QBCore.Config.Server.Closed and not IsPlayerAceAllowed(src, 'qbadmin.join') then
|
||||
return deferrals.done(QBCore.Config.Server.ClosedReason)
|
||||
end
|
||||
if not databaseConnected then
|
||||
return deferrals.done(Lang:t('error.connecting_database_error'))
|
||||
end
|
||||
if QBCore.Config.Server.Whitelist then
|
||||
Wait(0)
|
||||
deferrals.update(string.format(Lang:t('info.checking_whitelisted'), name))
|
||||
if not QBCore.Functions.IsWhitelisted(src) then
|
||||
return deferrals.done(Lang:t('error.not_whitelisted'))
|
||||
end
|
||||
end
|
||||
Wait(0)
|
||||
deferrals.update(string.format('Hello %s. Your license is being checked', name))
|
||||
local license = QBCore.Functions.GetIdentifier(src, 'license')
|
||||
if not license then
|
||||
return deferrals.done(Lang:t('error.no_valid_license'))
|
||||
elseif QBCore.Config.Server.CheckDuplicateLicense and QBCore.Functions.IsLicenseInUse(license) then
|
||||
return deferrals.done(Lang:t('error.duplicate_license'))
|
||||
end
|
||||
Wait(0)
|
||||
deferrals.update(string.format(Lang:t('info.checking_ban'), name))
|
||||
if not bansTableExists then
|
||||
return deferrals.done(Lang:t('error.ban_table_not_found'))
|
||||
end
|
||||
local success, isBanned, reason = pcall(QBCore.Functions.IsPlayerBanned, src)
|
||||
if not success then return deferrals.done(Lang:t('error.connecting_database_error')) end
|
||||
if isBanned then return deferrals.done(reason) end
|
||||
Wait(0)
|
||||
deferrals.update(string.format(Lang:t('info.join_server'), name))
|
||||
deferrals.done()
|
||||
end)
|
||||
local function GetSharedVehicles()
|
||||
return QBShared.Vehicles
|
||||
end
|
||||
exports('GetSharedVehicles', GetSharedVehicles)
|
||||
|
||||
-- Handle player disconnect
|
||||
local function GetSharedWeapons()
|
||||
return QBShared.Weapons
|
||||
end
|
||||
exports('GetSharedWeapons', GetSharedWeapons)
|
||||
|
||||
AddEventHandler('playerDropped', function(reason)
|
||||
local src = source
|
||||
local state = Player(src).state
|
||||
if not state['citizenid'] then return end
|
||||
local playerName = GetPlayerName(src) or 'Unknown'
|
||||
local license = state['license'] or 'Unknown License'
|
||||
TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Dropped', 'red', '**' .. playerName .. '** (' .. license .. ') left..\n **Reason:** ' .. reason)
|
||||
TriggerEvent('QBCore:Server:PlayerDropped', src)
|
||||
QBCore.Player.Save(src)
|
||||
if GetResourceState('qb-inventory') ~= 'missing' then
|
||||
exports['qb-inventory']:SaveInventory(src)
|
||||
end
|
||||
for _, key in pairs(GetStateBagKeys('player:' .. src)) do
|
||||
state:set(key, nil, true)
|
||||
end
|
||||
QBCore.Player_Buckets[license] = nil
|
||||
end)
|
||||
local function GetSharedJobs()
|
||||
return QBShared.Jobs
|
||||
end
|
||||
exports('GetSharedJobs', GetSharedJobs)
|
||||
|
||||
local function GetSharedGangs()
|
||||
return QBShared.Gangs
|
||||
end
|
||||
exports('GetSharedGangs', GetSharedGangs)
|
||||
|
||||
+629
-306
@@ -1,297 +1,93 @@
|
||||
-- Backwards Compat
|
||||
QBCore.Players = {}
|
||||
QBCore.Player = {}
|
||||
|
||||
local function extractData(source, prefix)
|
||||
local state = Player(source).state
|
||||
local data = {}
|
||||
|
||||
for key, value in pairs(state) do
|
||||
if key:find('^' .. prefix) then
|
||||
local shortKey = key:gsub(prefix, '')
|
||||
data[shortKey] = value or 'Unknown'
|
||||
end
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
local function CreateLegacyPlayerData(player)
|
||||
local source = player.source
|
||||
local state = Player(source).state
|
||||
local legacy = {}
|
||||
legacy.license = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
legacy.source = source
|
||||
legacy.name = GetPlayerName(source)
|
||||
legacy.citizenid = state['citizenid']
|
||||
legacy.money = extractData(source, 'money:')
|
||||
legacy.job = extractData(source, 'job:')
|
||||
legacy.gang = extractData(source, 'gang:')
|
||||
legacy.metadata = extractData(source, 'metadata:')
|
||||
legacy.charinfo = extractData(source, 'charinfo:')
|
||||
legacy.position = extractData(source, 'position:')
|
||||
|
||||
setmetatable(legacy, {
|
||||
__index = function(tbl, key)
|
||||
if key == 'money' then
|
||||
return extractData(source, 'money:')
|
||||
elseif key == 'job' then
|
||||
return extractData(source, 'job:')
|
||||
elseif key == 'gang' then
|
||||
return extractData(source, 'gang:')
|
||||
elseif key == 'metadata' then
|
||||
return extractData(source, 'metadata:')
|
||||
elseif key == 'charinfo' then
|
||||
return extractData(source, 'charinfo:')
|
||||
elseif key == 'position' then
|
||||
return extractData(source, 'position:')
|
||||
else
|
||||
return rawget(tbl, key)
|
||||
end
|
||||
end,
|
||||
__newindex = function(tbl, key, value)
|
||||
local state = Player(source).state
|
||||
if key == 'money' and type(value) == 'table' then
|
||||
for subkey, subvalue in pairs(value) do
|
||||
state:set('money:' .. subkey, subvalue, true)
|
||||
end
|
||||
elseif key == 'job' and type(value) == 'table' then
|
||||
for subkey, subvalue in pairs(value) do
|
||||
state:set('job:' .. subkey, subvalue, true)
|
||||
end
|
||||
elseif key == 'gang' and type(value) == 'table' then
|
||||
for subkey, subvalue in pairs(value) do
|
||||
state:set('gang:' .. subkey, subvalue, true)
|
||||
end
|
||||
elseif key == 'metadata' and type(value) == 'table' then
|
||||
for subkey, subvalue in pairs(value) do
|
||||
state:set('metadata:' .. subkey, subvalue, true)
|
||||
end
|
||||
elseif key == 'charinfo' and type(value) == 'table' then
|
||||
for subkey, subvalue in pairs(value) do
|
||||
state:set('charinfo:' .. subkey, subvalue, true)
|
||||
end
|
||||
elseif key == 'position' and type(value) == 'table' then
|
||||
for subkey, subvalue in pairs(value) do
|
||||
state:set('position:' .. subkey, subvalue, true)
|
||||
end
|
||||
else
|
||||
rawset(tbl, key, value)
|
||||
end
|
||||
end,
|
||||
})
|
||||
return legacy
|
||||
end
|
||||
|
||||
-- JSON STUFF
|
||||
|
||||
local DynamicDefaults = {
|
||||
['citizenid'] = QBCore.Functions.CreateCitizenId,
|
||||
['charinfo.phone'] = QBCore.Functions.CreatePhoneNumber,
|
||||
['charinfo.account'] = QBCore.Functions.CreateAccountNumber,
|
||||
['metadata.bloodtype'] = function() return QBCore.Functions.GetRandomElement(QBCore.Config.Player.Bloodtypes) end,
|
||||
['metadata.fingerprint'] = QBCore.Functions.CreateFingerId,
|
||||
['metadata.walletid'] = QBCore.Functions.CreateWalletId
|
||||
}
|
||||
|
||||
local function ApplyDynamicDefaults(target)
|
||||
for field, func in pairs(DynamicDefaults) do
|
||||
local ref = target
|
||||
local keys = {}
|
||||
for key in field:gmatch('[^.]+') do table.insert(keys, key) end
|
||||
|
||||
for i = 1, #keys - 1 do
|
||||
ref[keys[i]] = ref[keys[i]] or {}
|
||||
ref = ref[keys[i]]
|
||||
end
|
||||
|
||||
ref[keys[#keys]] = ref[keys[#keys]] or func()
|
||||
end
|
||||
end
|
||||
|
||||
local function LoadPlayerDefaults()
|
||||
local success, defaults = pcall(function()
|
||||
return json.decode(LoadResourceFile(resourceName, 'shared/player_defaults.json'))
|
||||
end)
|
||||
|
||||
if not success or not defaults or not next(defaults) then
|
||||
print('^1[ERROR]^0 Could not load player_defaults.json. Ensure the file is valid JSON and not empty.')
|
||||
return {}
|
||||
end
|
||||
|
||||
ApplyDynamicDefaults(defaults)
|
||||
return defaults
|
||||
end
|
||||
|
||||
local function MergePlayerData(target, defaults, debug)
|
||||
for key, value in pairs(defaults) do
|
||||
if type(value) == 'table' then
|
||||
target[key] = target[key] or {}
|
||||
MergePlayerData(target[key], value, debug)
|
||||
else
|
||||
if not debug then
|
||||
if target[key] == nil then
|
||||
print(('^2[INFO]^0 Added new data field: %s = %s'):format(key, tostring(value)))
|
||||
elseif target[key] ~= value then
|
||||
print(('^3[INFO]^0 Updated data field: %s = %s'):format(key, tostring(value)))
|
||||
end
|
||||
end
|
||||
target[key] = (target[key] == nil or target[key] == '') and value or target[key]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Player Creation
|
||||
|
||||
local function InitializePlayerStateBag(source, playerData)
|
||||
local state = Player(source).state
|
||||
local defaults = LoadPlayerDefaults()
|
||||
|
||||
for _, key in pairs(GetStateBagKeys('player:' .. source)) do
|
||||
if not defaults[key] then
|
||||
print(('^1[INFO]^0 Removed outdated data field: %s'):format(key))
|
||||
end
|
||||
state:set(key, nil, true)
|
||||
end
|
||||
|
||||
MergePlayerData(playerData, defaults)
|
||||
|
||||
local function populatePlayerState(data, prefix)
|
||||
for key, value in pairs(data) do
|
||||
if type(value) == 'table' then
|
||||
populatePlayerState(value, prefix .. key .. ':')
|
||||
else
|
||||
state:set(prefix .. key, value, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
populatePlayerState(playerData, '')
|
||||
end
|
||||
-- On player login get their data or set defaults
|
||||
-- Don't touch any of this unless you know what you are doing
|
||||
-- Will cause major issues!
|
||||
|
||||
local resourceName = GetCurrentResourceName()
|
||||
function QBCore.Player.Login(source, citizenid, newData)
|
||||
if not source or source == '' then
|
||||
if source and source ~= '' then
|
||||
if citizenid then
|
||||
local license = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
local PlayerData = MySQL.prepare.await('SELECT * FROM players where citizenid = ?', { citizenid })
|
||||
if PlayerData and license == PlayerData.license then
|
||||
PlayerData.money = json.decode(PlayerData.money)
|
||||
PlayerData.job = json.decode(PlayerData.job)
|
||||
PlayerData.gang = json.decode(PlayerData.gang)
|
||||
PlayerData.position = json.decode(PlayerData.position)
|
||||
PlayerData.metadata = json.decode(PlayerData.metadata)
|
||||
PlayerData.charinfo = json.decode(PlayerData.charinfo)
|
||||
QBCore.Player.CheckPlayerData(source, PlayerData)
|
||||
else
|
||||
DropPlayer(source, Lang:t('info.exploit_dropped'))
|
||||
TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'Anti-Cheat', 'white', GetPlayerName(source) .. ' Has Been Dropped For Character Joining Exploit', false)
|
||||
end
|
||||
else
|
||||
QBCore.Player.CheckPlayerData(source, newData)
|
||||
end
|
||||
return true
|
||||
else
|
||||
QBCore.ShowError(resourceName, 'ERROR QBCORE.PLAYER.LOGIN - NO SOURCE GIVEN!')
|
||||
return false
|
||||
end
|
||||
|
||||
if citizenid then
|
||||
local license = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
local data = MySQL.prepare.await('SELECT * FROM players WHERE citizenid = ?', { citizenid })
|
||||
|
||||
if not data then
|
||||
print('^1[ERROR]^0 Failed to load data for Citizen ID:', citizenid)
|
||||
DropPlayer(source, 'Failed to load your character data. Please contact staff.')
|
||||
return false
|
||||
end
|
||||
|
||||
if data and license == data.license then
|
||||
local success, playerData = pcall(function()
|
||||
return {
|
||||
money = json.decode(data.money) or {},
|
||||
job = json.decode(data.job) or {},
|
||||
gang = json.decode(data.gang) or {},
|
||||
position = json.decode(data.position) or {},
|
||||
metadata = json.decode(data.metadata) or {},
|
||||
charinfo = json.decode(data.charinfo) or {}
|
||||
}
|
||||
end)
|
||||
|
||||
if not success then
|
||||
print('^1[ERROR]^0 Failed to decode player data for Citizen ID:', citizenid)
|
||||
DropPlayer(source, 'Failed to decode your character data. Please contact staff.')
|
||||
return false
|
||||
end
|
||||
|
||||
InitializePlayerStateBag(source, playerData)
|
||||
else
|
||||
DropPlayer(source, Lang:t('info.exploit_dropped'))
|
||||
TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'Anti-Cheat', 'white', GetPlayerName(source) .. ' Has Been Dropped For Character Joining Exploit', false)
|
||||
end
|
||||
else
|
||||
InitializePlayerStateBag(source, newData or {})
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function QBCore.Player.CreatePlayer(PlayerData, Offline)
|
||||
local self = {}
|
||||
self.Offline = Offline
|
||||
self.Functions = {}
|
||||
|
||||
function self.Functions.Notify(text, type, length)
|
||||
TriggerClientEvent('QBCore:Notify', PlayerData.source, text, type, length)
|
||||
function QBCore.Player.GetOfflinePlayer(citizenid)
|
||||
if citizenid then
|
||||
local PlayerData = MySQL.prepare.await('SELECT * FROM players where citizenid = ?', { citizenid })
|
||||
if PlayerData then
|
||||
PlayerData.money = json.decode(PlayerData.money)
|
||||
PlayerData.job = json.decode(PlayerData.job)
|
||||
PlayerData.gang = json.decode(PlayerData.gang)
|
||||
PlayerData.position = json.decode(PlayerData.position)
|
||||
PlayerData.metadata = json.decode(PlayerData.metadata)
|
||||
PlayerData.charinfo = json.decode(PlayerData.charinfo)
|
||||
return QBCore.Player.CheckPlayerData(nil, PlayerData)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function self.Functions.AddMethod(methodName, handler)
|
||||
self.Functions[methodName] = handler
|
||||
function QBCore.Player.GetPlayerByLicense(license)
|
||||
if license then
|
||||
local source = QBCore.Functions.GetSource(license)
|
||||
if source > 0 then
|
||||
return QBCore.Players[source]
|
||||
else
|
||||
return QBCore.Player.GetOfflinePlayerByLicense(license)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function self.Functions.AddField(fieldName, data)
|
||||
self[fieldName] = data
|
||||
local state = Player(PlayerData.source).state
|
||||
state:set(fieldName, data, true)
|
||||
function QBCore.Player.GetOfflinePlayerByLicense(license)
|
||||
if license then
|
||||
local PlayerData = MySQL.prepare.await('SELECT * FROM players where license = ?', { license })
|
||||
if PlayerData then
|
||||
PlayerData.money = json.decode(PlayerData.money)
|
||||
PlayerData.job = json.decode(PlayerData.job)
|
||||
PlayerData.gang = json.decode(PlayerData.gang)
|
||||
PlayerData.position = json.decode(PlayerData.position)
|
||||
PlayerData.metadata = json.decode(PlayerData.metadata)
|
||||
PlayerData.charinfo = json.decode(PlayerData.charinfo)
|
||||
return QBCore.Player.CheckPlayerData(nil, PlayerData)
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function CreateDynamicGetSet(prefix)
|
||||
return {
|
||||
Get = function(key)
|
||||
local state = Player(PlayerData.source).state
|
||||
return state[prefix .. key] or nil
|
||||
end,
|
||||
|
||||
Set = function(key, value)
|
||||
local state = Player(PlayerData.source).state
|
||||
state:set(prefix .. key, value, true)
|
||||
return true
|
||||
end
|
||||
}
|
||||
local function applyDefaults(playerData, defaults)
|
||||
for key, value in pairs(defaults) do
|
||||
if type(value) == 'function' then
|
||||
playerData[key] = playerData[key] or value()
|
||||
elseif type(value) == 'table' then
|
||||
playerData[key] = playerData[key] or {}
|
||||
applyDefaults(playerData[key], value)
|
||||
else
|
||||
playerData[key] = playerData[key] or value
|
||||
end
|
||||
end
|
||||
|
||||
local function CreateDynamicIncremental(prefix)
|
||||
return {
|
||||
Get = function(key)
|
||||
local state = Player(PlayerData.source).state
|
||||
return state[prefix .. key] or 0
|
||||
end,
|
||||
|
||||
Set = function(key, value)
|
||||
local state = Player(PlayerData.source).state
|
||||
state:set(prefix .. key, value, true)
|
||||
return true
|
||||
end,
|
||||
|
||||
Add = function(key, value)
|
||||
local state = Player(PlayerData.source).state
|
||||
local currentValue = state[prefix .. key] or 0
|
||||
state:set(prefix .. key, currentValue + value, true)
|
||||
return true
|
||||
end,
|
||||
|
||||
Remove = function(key, value)
|
||||
local state = Player(PlayerData.source).state
|
||||
local currentValue = state[prefix .. key] or 0
|
||||
if currentValue < value then return false end
|
||||
state:set(prefix .. key, currentValue - value, true)
|
||||
return true
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
self.Metadata = CreateDynamicGetSet('metadata:')
|
||||
self.Job = CreateDynamicGetSet('job:')
|
||||
self.Gang = CreateDynamicGetSet('gang:')
|
||||
self.Money = CreateDynamicIncremental('money:')
|
||||
self.CharInfo = CreateDynamicGetSet('charinfo:')
|
||||
self.Position = CreateDynamicGetSet('position:')
|
||||
self.PlayerData = CreateLegacyPlayerData(PlayerData)
|
||||
|
||||
if not self.Offline then
|
||||
QBCore.Players[PlayerData.source] = self
|
||||
QBCore.Player.Save(PlayerData.source)
|
||||
TriggerEvent('QBCore:Server:PlayerLoaded', self)
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function QBCore.Player.CheckPlayerData(source, PlayerData)
|
||||
@@ -304,40 +100,567 @@ function QBCore.Player.CheckPlayerData(source, PlayerData)
|
||||
PlayerData.name = GetPlayerName(source)
|
||||
end
|
||||
|
||||
InitializePlayerStateBag(source, PlayerData)
|
||||
local validatedJob = false
|
||||
if PlayerData.job and PlayerData.job.name ~= nil and PlayerData.job.grade and PlayerData.job.grade.level ~= nil then
|
||||
local jobInfo = QBCore.Shared.Jobs[PlayerData.job.name]
|
||||
|
||||
if jobInfo then
|
||||
local jobGradeInfo = jobInfo.grades[tostring(PlayerData.job.grade.level)]
|
||||
if jobGradeInfo then
|
||||
PlayerData.job.label = jobInfo.label
|
||||
PlayerData.job.grade.name = jobGradeInfo.name
|
||||
PlayerData.job.payment = jobGradeInfo.payment
|
||||
PlayerData.job.grade.isboss = jobGradeInfo.isboss or false
|
||||
PlayerData.job.isboss = jobGradeInfo.isboss or false
|
||||
validatedJob = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if validatedJob == false then
|
||||
-- set to nil, as the default job (unemployed) will be added by `applyDefaults`
|
||||
PlayerData.job = nil
|
||||
end
|
||||
|
||||
local validatedGang = false
|
||||
if PlayerData.gang and PlayerData.gang.name ~= nil and PlayerData.gang.grade and PlayerData.gang.grade.level ~= nil then
|
||||
local gangInfo = QBCore.Shared.Gangs[PlayerData.gang.name]
|
||||
|
||||
if gangInfo then
|
||||
local gangGradeInfo = gangInfo.grades[tostring(PlayerData.gang.grade.level)]
|
||||
if gangGradeInfo then
|
||||
PlayerData.gang.label = gangInfo.label
|
||||
PlayerData.gang.grade.name = gangGradeInfo.name
|
||||
PlayerData.gang.payment = gangGradeInfo.payment
|
||||
PlayerData.gang.grade.isboss = gangGradeInfo.isboss or false
|
||||
PlayerData.gang.isboss = gangGradeInfo.isboss or false
|
||||
validatedGang = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if validatedGang == false then
|
||||
-- set to nil, as the default gang (unemployed) will be added by `applyDefaults`
|
||||
PlayerData.gang = nil
|
||||
end
|
||||
|
||||
applyDefaults(PlayerData, QBCore.Config.Player.PlayerDefaults)
|
||||
|
||||
if GetResourceState('qb-inventory') ~= 'missing' then
|
||||
PlayerData.items = exports['qb-inventory']:LoadInventory(PlayerData.source, PlayerData.citizenid)
|
||||
end
|
||||
|
||||
return QBCore.Player.CreatePlayer(PlayerData, Offline)
|
||||
end
|
||||
|
||||
local function BuildPlayerSaveData(source)
|
||||
local state = Player(source).state
|
||||
-- On player logout
|
||||
|
||||
return {
|
||||
citizenid = state['citizenid'],
|
||||
money = json.encode(extractData(source, 'money:')),
|
||||
metadata = json.encode(extractData(source, 'metadata:')),
|
||||
position = json.encode(extractData(source, 'position:')),
|
||||
job = json.encode(extractData(source, 'job:')),
|
||||
gang = json.encode(extractData(source, 'gang:'))
|
||||
}
|
||||
function QBCore.Player.Logout(source)
|
||||
TriggerClientEvent('QBCore:Client:OnPlayerUnload', source)
|
||||
TriggerEvent('QBCore:Server:OnPlayerUnload', source)
|
||||
TriggerClientEvent('QBCore:Player:UpdatePlayerData', source)
|
||||
Wait(200)
|
||||
QBCore.Players[source] = nil
|
||||
end
|
||||
|
||||
-- Create a new character
|
||||
-- Don't touch any of this unless you know what you are doing
|
||||
-- Will cause major issues!
|
||||
|
||||
function QBCore.Player.CreatePlayer(PlayerData, Offline)
|
||||
local self = {}
|
||||
self.Functions = {}
|
||||
self.PlayerData = PlayerData
|
||||
self.Offline = Offline
|
||||
|
||||
function self.Functions.UpdatePlayerData()
|
||||
if self.Offline then return end
|
||||
TriggerEvent('QBCore:Player:SetPlayerData', self.PlayerData)
|
||||
TriggerClientEvent('QBCore:Player:SetPlayerData', self.PlayerData.source, self.PlayerData)
|
||||
end
|
||||
|
||||
function self.Functions.SetJob(job, grade)
|
||||
job = job:lower()
|
||||
grade = grade or '0'
|
||||
if not QBCore.Shared.Jobs[job] then return false end
|
||||
self.PlayerData.job = {
|
||||
name = job,
|
||||
label = QBCore.Shared.Jobs[job].label,
|
||||
onduty = QBCore.Shared.Jobs[job].defaultDuty,
|
||||
type = QBCore.Shared.Jobs[job].type or 'none',
|
||||
grade = {
|
||||
name = 'No Grades',
|
||||
level = 0,
|
||||
payment = 30,
|
||||
isboss = false
|
||||
}
|
||||
}
|
||||
local gradeKey = tostring(grade)
|
||||
local jobGradeInfo = QBCore.Shared.Jobs[job].grades[gradeKey]
|
||||
if jobGradeInfo then
|
||||
self.PlayerData.job.grade.name = jobGradeInfo.name
|
||||
self.PlayerData.job.grade.level = tonumber(gradeKey)
|
||||
self.PlayerData.job.grade.payment = jobGradeInfo.payment
|
||||
self.PlayerData.job.grade.isboss = jobGradeInfo.isboss or false
|
||||
self.PlayerData.job.isboss = jobGradeInfo.isboss or false
|
||||
end
|
||||
|
||||
if not self.Offline then
|
||||
self.Functions.UpdatePlayerData()
|
||||
TriggerEvent('QBCore:Server:OnJobUpdate', self.PlayerData.source, self.PlayerData.job)
|
||||
TriggerClientEvent('QBCore:Client:OnJobUpdate', self.PlayerData.source, self.PlayerData.job)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function self.Functions.SetGang(gang, grade)
|
||||
gang = gang:lower()
|
||||
grade = grade or '0'
|
||||
if not QBCore.Shared.Gangs[gang] then return false end
|
||||
self.PlayerData.gang = {
|
||||
name = gang,
|
||||
label = QBCore.Shared.Gangs[gang].label,
|
||||
grade = {
|
||||
name = 'No Grades',
|
||||
level = 0,
|
||||
isboss = false
|
||||
}
|
||||
}
|
||||
local gradeKey = tostring(grade)
|
||||
local gangGradeInfo = QBCore.Shared.Gangs[gang].grades[gradeKey]
|
||||
if gangGradeInfo then
|
||||
self.PlayerData.gang.grade.name = gangGradeInfo.name
|
||||
self.PlayerData.gang.grade.level = tonumber(gradeKey)
|
||||
self.PlayerData.gang.grade.isboss = gangGradeInfo.isboss or false
|
||||
self.PlayerData.gang.isboss = gangGradeInfo.isboss or false
|
||||
end
|
||||
|
||||
if not self.Offline then
|
||||
self.Functions.UpdatePlayerData()
|
||||
TriggerEvent('QBCore:Server:OnGangUpdate', self.PlayerData.source, self.PlayerData.gang)
|
||||
TriggerClientEvent('QBCore:Client:OnGangUpdate', self.PlayerData.source, self.PlayerData.gang)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function self.Functions.Notify(text, type, length)
|
||||
TriggerClientEvent('QBCore:Notify', self.PlayerData.source, text, type, length)
|
||||
end
|
||||
|
||||
function self.Functions.HasItem(items, amount)
|
||||
return QBCore.Functions.HasItem(self.PlayerData.source, items, amount)
|
||||
end
|
||||
|
||||
function self.Functions.GetName()
|
||||
local charinfo = self.PlayerData.charinfo
|
||||
return charinfo.firstname .. ' ' .. charinfo.lastname
|
||||
end
|
||||
|
||||
function self.Functions.SetJobDuty(onDuty)
|
||||
self.PlayerData.job.onduty = not not onDuty
|
||||
TriggerEvent('QBCore:Server:OnJobUpdate', self.PlayerData.source, self.PlayerData.job)
|
||||
TriggerClientEvent('QBCore:Client:OnJobUpdate', self.PlayerData.source, self.PlayerData.job)
|
||||
self.Functions.UpdatePlayerData()
|
||||
end
|
||||
|
||||
function self.Functions.SetPlayerData(key, val)
|
||||
if not key or type(key) ~= 'string' then return end
|
||||
self.PlayerData[key] = val
|
||||
self.Functions.UpdatePlayerData()
|
||||
end
|
||||
|
||||
function self.Functions.SetMetaData(meta, val)
|
||||
if not meta or type(meta) ~= 'string' then return end
|
||||
if meta == 'hunger' or meta == 'thirst' then
|
||||
val = val > 100 and 100 or val
|
||||
end
|
||||
self.PlayerData.metadata[meta] = val
|
||||
self.Functions.UpdatePlayerData()
|
||||
end
|
||||
|
||||
function self.Functions.GetMetaData(meta)
|
||||
if not meta or type(meta) ~= 'string' then return end
|
||||
return self.PlayerData.metadata[meta]
|
||||
end
|
||||
|
||||
function self.Functions.AddRep(rep, amount)
|
||||
if not rep or not amount then return end
|
||||
local addAmount = tonumber(amount)
|
||||
local currentRep = self.PlayerData.metadata['rep'][rep] or 0
|
||||
self.PlayerData.metadata['rep'][rep] = currentRep + addAmount
|
||||
self.Functions.UpdatePlayerData()
|
||||
end
|
||||
|
||||
function self.Functions.RemoveRep(rep, amount)
|
||||
if not rep or not amount then return end
|
||||
local removeAmount = tonumber(amount)
|
||||
local currentRep = self.PlayerData.metadata['rep'][rep] or 0
|
||||
if currentRep - removeAmount < 0 then
|
||||
self.PlayerData.metadata['rep'][rep] = 0
|
||||
else
|
||||
self.PlayerData.metadata['rep'][rep] = currentRep - removeAmount
|
||||
end
|
||||
self.Functions.UpdatePlayerData()
|
||||
end
|
||||
|
||||
function self.Functions.GetRep(rep)
|
||||
if not rep then return end
|
||||
return self.PlayerData.metadata['rep'][rep] or 0
|
||||
end
|
||||
|
||||
function self.Functions.AddMoney(moneytype, amount, reason)
|
||||
reason = reason or 'unknown'
|
||||
moneytype = moneytype:lower()
|
||||
amount = tonumber(amount)
|
||||
if amount < 0 then return end
|
||||
if not self.PlayerData.money[moneytype] then return false end
|
||||
self.PlayerData.money[moneytype] = self.PlayerData.money[moneytype] + amount
|
||||
|
||||
if not self.Offline then
|
||||
self.Functions.UpdatePlayerData()
|
||||
if amount > 100000 then
|
||||
TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'AddMoney', 'lightgreen', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') added, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype] .. ' reason: ' .. reason, true)
|
||||
else
|
||||
TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'AddMoney', 'lightgreen', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') added, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype] .. ' reason: ' .. reason)
|
||||
end
|
||||
TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, amount, false)
|
||||
TriggerClientEvent('QBCore:Client:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'add', reason)
|
||||
TriggerEvent('QBCore:Server:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'add', reason)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function self.Functions.RemoveMoney(moneytype, amount, reason)
|
||||
reason = reason or 'unknown'
|
||||
moneytype = moneytype:lower()
|
||||
amount = tonumber(amount)
|
||||
if amount < 0 then return end
|
||||
if not self.PlayerData.money[moneytype] then return false end
|
||||
for _, mtype in pairs(QBCore.Config.Money.DontAllowMinus) do
|
||||
if mtype == moneytype then
|
||||
if (self.PlayerData.money[moneytype] - amount) < 0 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
if self.PlayerData.money[moneytype] - amount < QBCore.Config.Money.MinusLimit then return false end
|
||||
self.PlayerData.money[moneytype] = self.PlayerData.money[moneytype] - amount
|
||||
|
||||
if not self.Offline then
|
||||
self.Functions.UpdatePlayerData()
|
||||
if amount > 100000 then
|
||||
TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'RemoveMoney', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') removed, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype] .. ' reason: ' .. reason, true)
|
||||
else
|
||||
TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'RemoveMoney', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') removed, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype] .. ' reason: ' .. reason)
|
||||
end
|
||||
TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, amount, true)
|
||||
if moneytype == 'bank' then
|
||||
TriggerClientEvent('qb-phone:client:RemoveBankMoney', self.PlayerData.source, amount)
|
||||
end
|
||||
TriggerClientEvent('QBCore:Client:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'remove', reason)
|
||||
TriggerEvent('QBCore:Server:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'remove', reason)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function self.Functions.SetMoney(moneytype, amount, reason)
|
||||
reason = reason or 'unknown'
|
||||
moneytype = moneytype:lower()
|
||||
amount = tonumber(amount)
|
||||
if amount < 0 then return false end
|
||||
if not self.PlayerData.money[moneytype] then return false end
|
||||
local difference = amount - self.PlayerData.money[moneytype]
|
||||
self.PlayerData.money[moneytype] = amount
|
||||
|
||||
if not self.Offline then
|
||||
self.Functions.UpdatePlayerData()
|
||||
TriggerEvent('qb-log:server:CreateLog', 'playermoney', 'SetMoney', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** $' .. amount .. ' (' .. moneytype .. ') set, new ' .. moneytype .. ' balance: ' .. self.PlayerData.money[moneytype] .. ' reason: ' .. reason)
|
||||
TriggerClientEvent('hud:client:OnMoneyChange', self.PlayerData.source, moneytype, math.abs(difference), difference < 0)
|
||||
TriggerClientEvent('QBCore:Client:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'set', reason)
|
||||
TriggerEvent('QBCore:Server:OnMoneyChange', self.PlayerData.source, moneytype, amount, 'set', reason)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function self.Functions.GetMoney(moneytype)
|
||||
if not moneytype then return false end
|
||||
moneytype = moneytype:lower()
|
||||
return self.PlayerData.money[moneytype]
|
||||
end
|
||||
|
||||
function self.Functions.Save()
|
||||
if self.Offline then
|
||||
QBCore.Player.SaveOffline(self.PlayerData)
|
||||
else
|
||||
QBCore.Player.Save(self.PlayerData.source)
|
||||
end
|
||||
end
|
||||
|
||||
function self.Functions.Logout()
|
||||
if self.Offline then return end
|
||||
QBCore.Player.Logout(self.PlayerData.source)
|
||||
end
|
||||
|
||||
function self.Functions.AddMethod(methodName, handler)
|
||||
self.Functions[methodName] = handler
|
||||
end
|
||||
|
||||
function self.Functions.AddField(fieldName, data)
|
||||
self[fieldName] = data
|
||||
end
|
||||
|
||||
if self.Offline then
|
||||
return self
|
||||
else
|
||||
QBCore.Players[self.PlayerData.source] = self
|
||||
QBCore.Player.Save(self.PlayerData.source)
|
||||
TriggerEvent('QBCore:Server:PlayerLoaded', self)
|
||||
self.Functions.UpdatePlayerData()
|
||||
end
|
||||
end
|
||||
|
||||
-- Add a new function to the Functions table of the player class
|
||||
-- Use-case:
|
||||
--[[
|
||||
AddEventHandler('QBCore:Server:PlayerLoaded', function(Player)
|
||||
QBCore.Functions.AddPlayerMethod(Player.PlayerData.source, "functionName", function(oneArg, orMore)
|
||||
-- do something here
|
||||
end)
|
||||
end)
|
||||
]]
|
||||
|
||||
function QBCore.Functions.AddPlayerMethod(ids, methodName, handler)
|
||||
local idType = type(ids)
|
||||
if idType == 'number' then
|
||||
if ids == -1 then
|
||||
for _, v in pairs(QBCore.Players) do
|
||||
v.Functions.AddMethod(methodName, handler)
|
||||
end
|
||||
else
|
||||
if not QBCore.Players[ids] then return end
|
||||
|
||||
QBCore.Players[ids].Functions.AddMethod(methodName, handler)
|
||||
end
|
||||
elseif idType == 'table' and table.type(ids) == 'array' then
|
||||
for i = 1, #ids do
|
||||
QBCore.Functions.AddPlayerMethod(ids[i], methodName, handler)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Add a new field table of the player class
|
||||
-- Use-case:
|
||||
--[[
|
||||
AddEventHandler('QBCore:Server:PlayerLoaded', function(Player)
|
||||
QBCore.Functions.AddPlayerField(Player.PlayerData.source, "fieldName", "fieldData")
|
||||
end)
|
||||
]]
|
||||
|
||||
function QBCore.Functions.AddPlayerField(ids, fieldName, data)
|
||||
local idType = type(ids)
|
||||
if idType == 'number' then
|
||||
if ids == -1 then
|
||||
for _, v in pairs(QBCore.Players) do
|
||||
v.Functions.AddField(fieldName, data)
|
||||
end
|
||||
else
|
||||
if not QBCore.Players[ids] then return end
|
||||
|
||||
QBCore.Players[ids].Functions.AddField(fieldName, data)
|
||||
end
|
||||
elseif idType == 'table' and table.type(ids) == 'array' then
|
||||
for i = 1, #ids do
|
||||
QBCore.Functions.AddPlayerField(ids[i], fieldName, data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Save player info to database (make sure citizenid is the primary key in your database)
|
||||
|
||||
function QBCore.Player.Save(source)
|
||||
local saveData = BuildPlayerSaveData(source)
|
||||
|
||||
if not saveData.citizenid or not saveData.license then
|
||||
print('^1[ERROR]^0 Skipped saving data for player [%s] due to missing critical data.'):format(GetPlayerName(source))
|
||||
return
|
||||
local ped = GetPlayerPed(source)
|
||||
local pcoords = GetEntityCoords(ped)
|
||||
local PlayerData = QBCore.Players[source].PlayerData
|
||||
if PlayerData then
|
||||
MySQL.insert('INSERT INTO players (citizenid, cid, license, name, money, charinfo, job, gang, position, metadata) VALUES (:citizenid, :cid, :license, :name, :money, :charinfo, :job, :gang, :position, :metadata) ON DUPLICATE KEY UPDATE cid = :cid, name = :name, money = :money, charinfo = :charinfo, job = :job, gang = :gang, position = :position, metadata = :metadata', {
|
||||
citizenid = PlayerData.citizenid,
|
||||
cid = tonumber(PlayerData.cid),
|
||||
license = PlayerData.license,
|
||||
name = PlayerData.name,
|
||||
money = json.encode(PlayerData.money),
|
||||
charinfo = json.encode(PlayerData.charinfo),
|
||||
job = json.encode(PlayerData.job),
|
||||
gang = json.encode(PlayerData.gang),
|
||||
position = json.encode(pcoords),
|
||||
metadata = json.encode(PlayerData.metadata)
|
||||
})
|
||||
if GetResourceState('qb-inventory') ~= 'missing' then exports['qb-inventory']:SaveInventory(source) end
|
||||
QBCore.ShowSuccess(resourceName, PlayerData.name .. ' PLAYER SAVED!')
|
||||
else
|
||||
QBCore.ShowError(resourceName, 'ERROR QBCORE.PLAYER.SAVE - PLAYERDATA IS EMPTY!')
|
||||
end
|
||||
|
||||
MySQL.insert(
|
||||
'INSERT INTO players (citizenid, money, metadata, position, job, gang) VALUES (:citizenid, :money, :metadata, :position, :job, :gang) ON DUPLICATE KEY UPDATE money = :money, metadata = :metadata, position = :position, job = :job, gang = :gang',
|
||||
saveData
|
||||
)
|
||||
|
||||
if GetResourceState('qb-inventory') ~= 'missing' then
|
||||
exports['qb-inventory']:SaveInventory(source)
|
||||
end
|
||||
|
||||
QBCore.ShowSuccess(resourceName, 'Player ' .. GetPlayerName(source) .. ' data saved successfully.')
|
||||
end
|
||||
|
||||
function QBCore.Player.SaveOffline(PlayerData)
|
||||
if PlayerData then
|
||||
MySQL.insert('INSERT INTO players (citizenid, cid, license, name, money, charinfo, job, gang, position, metadata) VALUES (:citizenid, :cid, :license, :name, :money, :charinfo, :job, :gang, :position, :metadata) ON DUPLICATE KEY UPDATE cid = :cid, name = :name, money = :money, charinfo = :charinfo, job = :job, gang = :gang, position = :position, metadata = :metadata', {
|
||||
citizenid = PlayerData.citizenid,
|
||||
cid = tonumber(PlayerData.cid),
|
||||
license = PlayerData.license,
|
||||
name = PlayerData.name,
|
||||
money = json.encode(PlayerData.money),
|
||||
charinfo = json.encode(PlayerData.charinfo),
|
||||
job = json.encode(PlayerData.job),
|
||||
gang = json.encode(PlayerData.gang),
|
||||
position = json.encode(PlayerData.position),
|
||||
metadata = json.encode(PlayerData.metadata)
|
||||
})
|
||||
if GetResourceState('qb-inventory') ~= 'missing' then exports['qb-inventory']:SaveInventory(PlayerData, true) end
|
||||
QBCore.ShowSuccess(resourceName, PlayerData.name .. ' OFFLINE PLAYER SAVED!')
|
||||
else
|
||||
QBCore.ShowError(resourceName, 'ERROR QBCORE.PLAYER.SAVEOFFLINE - PLAYERDATA IS EMPTY!')
|
||||
end
|
||||
end
|
||||
|
||||
-- Delete character
|
||||
|
||||
local playertables = { -- Add tables as needed
|
||||
{ table = 'players' },
|
||||
{ table = 'apartments' },
|
||||
{ table = 'bank_accounts' },
|
||||
{ table = 'crypto_transactions' },
|
||||
{ table = 'phone_invoices' },
|
||||
{ table = 'phone_messages' },
|
||||
{ table = 'playerskins' },
|
||||
{ table = 'player_contacts' },
|
||||
{ table = 'player_houses' },
|
||||
{ table = 'player_mails' },
|
||||
{ table = 'player_outfits' },
|
||||
{ table = 'player_vehicles' }
|
||||
}
|
||||
|
||||
function QBCore.Player.DeleteCharacter(source, citizenid)
|
||||
local license = QBCore.Functions.GetIdentifier(source, 'license')
|
||||
local result = MySQL.scalar.await('SELECT license FROM players where citizenid = ?', { citizenid })
|
||||
if license == result then
|
||||
local query = 'DELETE FROM %s WHERE citizenid = ?'
|
||||
local tableCount = #playertables
|
||||
local queries = table.create(tableCount, 0)
|
||||
|
||||
for i = 1, tableCount do
|
||||
local v = playertables[i]
|
||||
queries[i] = { query = query:format(v.table), values = { citizenid } }
|
||||
end
|
||||
|
||||
MySQL.transaction(queries, function(result2)
|
||||
if result2 then
|
||||
TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Character Deleted', 'red', '**' .. GetPlayerName(source) .. '** ' .. license .. ' deleted **' .. citizenid .. '**..')
|
||||
end
|
||||
end)
|
||||
else
|
||||
DropPlayer(source, Lang:t('info.exploit_dropped'))
|
||||
TriggerEvent('qb-log:server:CreateLog', 'anticheat', 'Anti-Cheat', 'white', GetPlayerName(source) .. ' Has Been Dropped For Character Deletion Exploit', true)
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Player.ForceDeleteCharacter(citizenid)
|
||||
local result = MySQL.scalar.await('SELECT license FROM players where citizenid = ?', { citizenid })
|
||||
if result then
|
||||
local query = 'DELETE FROM %s WHERE citizenid = ?'
|
||||
local tableCount = #playertables
|
||||
local queries = table.create(tableCount, 0)
|
||||
local Player = QBCore.Functions.GetPlayerByCitizenId(citizenid)
|
||||
|
||||
if Player then
|
||||
DropPlayer(Player.PlayerData.source, 'An admin deleted the character which you are currently using')
|
||||
end
|
||||
for i = 1, tableCount do
|
||||
local v = playertables[i]
|
||||
queries[i] = { query = query:format(v.table), values = { citizenid } }
|
||||
end
|
||||
|
||||
MySQL.transaction(queries, function(result2)
|
||||
if result2 then
|
||||
TriggerEvent('qb-log:server:CreateLog', 'joinleave', 'Character Force Deleted', 'red', 'Character **' .. citizenid .. '** got deleted')
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- Inventory Backwards Compatibility
|
||||
|
||||
function QBCore.Player.SaveInventory(source)
|
||||
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||
exports['qb-inventory']:SaveInventory(source, false)
|
||||
end
|
||||
|
||||
function QBCore.Player.SaveOfflineInventory(PlayerData)
|
||||
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||
exports['qb-inventory']:SaveInventory(PlayerData, true)
|
||||
end
|
||||
|
||||
function QBCore.Player.GetTotalWeight(items)
|
||||
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||
return exports['qb-inventory']:GetTotalWeight(items)
|
||||
end
|
||||
|
||||
function QBCore.Player.GetSlotsByItem(items, itemName)
|
||||
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||
return exports['qb-inventory']:GetSlotsByItem(items, itemName)
|
||||
end
|
||||
|
||||
function QBCore.Player.GetFirstSlotByItem(items, itemName)
|
||||
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||
return exports['qb-inventory']:GetFirstSlotByItem(items, itemName)
|
||||
end
|
||||
|
||||
-- Util Functions
|
||||
|
||||
function QBCore.Player.CreateCitizenId()
|
||||
local CitizenId = tostring(QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(5)):upper()
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE citizenid = ?) AS uniqueCheck', { CitizenId })
|
||||
if result == 0 then return CitizenId end
|
||||
return QBCore.Player.CreateCitizenId()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreateAccountNumber()
|
||||
local AccountNumber = 'US0' .. math.random(1, 9) .. 'QBCore' .. math.random(1111, 9999) .. math.random(1111, 9999) .. math.random(11, 99)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(charinfo, "$.account")) = ?) AS uniqueCheck', { AccountNumber })
|
||||
if result == 0 then return AccountNumber end
|
||||
return QBCore.Functions.CreateAccountNumber()
|
||||
end
|
||||
|
||||
function QBCore.Functions.CreatePhoneNumber()
|
||||
local PhoneNumber = math.random(100, 999) .. math.random(1000000, 9999999)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(charinfo, "$.phone")) = ?) AS uniqueCheck', { PhoneNumber })
|
||||
if result == 0 then return PhoneNumber end
|
||||
return QBCore.Functions.CreatePhoneNumber()
|
||||
end
|
||||
|
||||
function QBCore.Player.CreateFingerId()
|
||||
local FingerId = tostring(QBCore.Shared.RandomStr(2) .. QBCore.Shared.RandomInt(3) .. QBCore.Shared.RandomStr(1) .. QBCore.Shared.RandomInt(2) .. QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(4))
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(metadata, "$.fingerprint")) = ?) AS uniqueCheck', { FingerId })
|
||||
if result == 0 then return FingerId end
|
||||
return QBCore.Player.CreateFingerId()
|
||||
end
|
||||
|
||||
function QBCore.Player.CreateWalletId()
|
||||
local WalletId = 'QB-' .. math.random(11111111, 99999999)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(metadata, "$.walletid")) = ?) AS uniqueCheck', { WalletId })
|
||||
if result == 0 then return WalletId end
|
||||
return QBCore.Player.CreateWalletId()
|
||||
end
|
||||
|
||||
function QBCore.Player.CreateSerialNumber()
|
||||
local SerialNumber = math.random(11111111, 99999999)
|
||||
local result = MySQL.prepare.await('SELECT EXISTS(SELECT 1 FROM players WHERE JSON_UNQUOTE(JSON_EXTRACT(metadata, "$.phonedata.SerialNumber")) = ?) AS uniqueCheck', { SerialNumber })
|
||||
if result == 0 then return SerialNumber end
|
||||
return QBCore.Player.CreateSerialNumber()
|
||||
end
|
||||
|
||||
PaycheckInterval() -- This starts the paycheck system
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
QBShared = QBShared or {}
|
||||
QBShared.Gangs = {
|
||||
none = { label = 'No Gang', grades = { ['0'] = { name = 'Unaffiliated' } } },
|
||||
lostmc = {
|
||||
label = 'The Lost MC',
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit' },
|
||||
['1'] = { name = 'Enforcer' },
|
||||
['2'] = { name = 'Shot Caller' },
|
||||
['3'] = { name = 'Boss', isboss = true },
|
||||
},
|
||||
},
|
||||
ballas = {
|
||||
label = 'Ballas',
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit' },
|
||||
['1'] = { name = 'Enforcer' },
|
||||
['2'] = { name = 'Shot Caller' },
|
||||
['3'] = { name = 'Boss', isboss = true },
|
||||
},
|
||||
},
|
||||
vagos = {
|
||||
label = 'Vagos',
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit' },
|
||||
['1'] = { name = 'Enforcer' },
|
||||
['2'] = { name = 'Shot Caller' },
|
||||
['3'] = { name = 'Boss', isboss = true },
|
||||
},
|
||||
},
|
||||
cartel = {
|
||||
label = 'Cartel',
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit' },
|
||||
['1'] = { name = 'Enforcer' },
|
||||
['2'] = { name = 'Shot Caller' },
|
||||
['3'] = { name = 'Boss', isboss = true },
|
||||
},
|
||||
},
|
||||
families = {
|
||||
label = 'Families',
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit' },
|
||||
['1'] = { name = 'Enforcer' },
|
||||
['2'] = { name = 'Shot Caller' },
|
||||
['3'] = { name = 'Boss', isboss = true },
|
||||
},
|
||||
},
|
||||
triads = {
|
||||
label = 'Triads',
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit' },
|
||||
['1'] = { name = 'Enforcer' },
|
||||
['2'] = { name = 'Shot Caller' },
|
||||
['3'] = { name = 'Boss', isboss = true },
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,390 @@
|
||||
QBShared = QBShared or {}
|
||||
QBShared.Items = {
|
||||
-- WEAPONS
|
||||
-- Melee
|
||||
weapon_unarmed = { name = 'weapon_unarmed', label = 'Fists', weight = 1000, type = 'weapon', ammotype = nil, image = 'placeholder.png', unique = true, useable = false, description = 'Fisticuffs' },
|
||||
weapon_dagger = { name = 'weapon_dagger', label = 'Dagger', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_dagger.png', unique = true, useable = false, description = 'A short knife with a pointed and edged blade, used as a weapon' },
|
||||
weapon_bat = { name = 'weapon_bat', label = 'Bat', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_bat.png', unique = true, useable = false, description = 'Used for hitting a ball in sports (or other things)' },
|
||||
weapon_bottle = { name = 'weapon_bottle', label = 'Broken Bottle', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_bottle.png', unique = true, useable = false, description = 'A broken bottle' },
|
||||
weapon_crowbar = { name = 'weapon_crowbar', label = 'Crowbar', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_crowbar.png', unique = true, useable = false, description = 'An iron bar with a flattened end, used as a lever' },
|
||||
weapon_flashlight = { name = 'weapon_flashlight', label = 'Flashlight', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_flashlight.png', unique = true, useable = false, description = 'A battery-operated portable light' },
|
||||
weapon_golfclub = { name = 'weapon_golfclub', label = 'Golfclub', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_golfclub.png', unique = true, useable = false, description = 'A club used to hit the ball in golf' },
|
||||
weapon_hammer = { name = 'weapon_hammer', label = 'Hammer', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_hammer.png', unique = true, useable = false, description = 'Used for jobs such as breaking things (legs) and driving in nails' },
|
||||
weapon_hatchet = { name = 'weapon_hatchet', label = 'Hatchet', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_hatchet.png', unique = true, useable = false, description = 'A small axe with a short handle for use in one hand' },
|
||||
weapon_knuckle = { name = 'weapon_knuckle', label = 'Knuckle', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_knuckle.png', unique = true, useable = false, description = 'A metal guard worn over the knuckles in fighting, especially to increase the effect of the blows' },
|
||||
weapon_knife = { name = 'weapon_knife', label = 'Knife', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_knife.png', unique = true, useable = false, description = 'An instrument composed of a blade fixed into a handle, used for cutting or as a weapon' },
|
||||
weapon_machete = { name = 'weapon_machete', label = 'Machete', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_machete.png', unique = true, useable = false, description = 'A broad, heavy knife used as a weapon' },
|
||||
weapon_switchblade = { name = 'weapon_switchblade', label = 'Switchblade', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_switchblade.png', unique = true, useable = false, description = 'A knife with a blade that springs out from the handle when a button is pressed' },
|
||||
weapon_nightstick = { name = 'weapon_nightstick', label = 'Nightstick', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_nightstick.png', unique = true, useable = false, description = 'A police officer\'s club or billy' },
|
||||
weapon_wrench = { name = 'weapon_wrench', label = 'Wrench', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_wrench.png', unique = true, useable = false, description = 'A tool used for gripping and turning nuts, bolts, pipes, etc' },
|
||||
weapon_battleaxe = { name = 'weapon_battleaxe', label = 'Battle Axe', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_battleaxe.png', unique = true, useable = false, description = 'A large broad-bladed axe used in ancient warfare' },
|
||||
weapon_poolcue = { name = 'weapon_poolcue', label = 'Poolcue', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_poolcue.png', unique = true, useable = false, description = 'A stick used to strike a ball, usually the cue ball (or other things)' },
|
||||
weapon_briefcase = { name = 'weapon_briefcase', label = 'Briefcase', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_briefcase.png', unique = true, useable = false, description = 'A briefcase for storing important documents' },
|
||||
weapon_briefcase_02 = { name = 'weapon_briefcase_02', label = 'Suitcase', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_briefcase2.png', unique = true, useable = false, description = 'Wonderfull for nice vacation to Liberty City' },
|
||||
weapon_garbagebag = { name = 'weapon_garbagebag', label = 'Garbage Bag', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_garbagebag.png', unique = true, useable = false, description = 'A garbage bag' },
|
||||
weapon_handcuffs = { name = 'weapon_handcuffs', label = 'Handcuffs', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_handcuffs.png', unique = true, useable = false, description = 'A pair of lockable linked metal rings for securing a prisoner\'s wrists' },
|
||||
weapon_bread = { name = 'weapon_bread', label = 'Baquette', weight = 1000, type = 'weapon', ammotype = nil, image = 'baquette.png', unique = true, useable = false, description = 'Bread...?' },
|
||||
weapon_stone_hatchet = { name = 'weapon_stone_hatchet', label = 'Stone Hatchet', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_stone_hatchet.png', unique = true, useable = true, description = 'Stone Hatchet' },
|
||||
weapon_candycane = { name = 'weapon_candycane', label = 'Candy Cane', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_candycane', unique = true, useable = true, description = 'Candy Cane' },
|
||||
|
||||
-- Handguns
|
||||
weapon_pistol = { name = 'weapon_pistol', label = 'Walther P99', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_pistol.png', unique = true, useable = false, description = 'A small firearm designed to be held in one hand' },
|
||||
weapon_pistol_mk2 = { name = 'weapon_pistol_mk2', label = 'Pistol Mk II', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_pistol_mk2.png', unique = true, useable = false, description = 'An upgraded small firearm designed to be held in one hand' },
|
||||
weapon_combatpistol = { name = 'weapon_combatpistol', label = 'Combat Pistol', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_combatpistol.png', unique = true, useable = false, description = 'A combat version small firearm designed to be held in one hand' },
|
||||
weapon_appistol = { name = 'weapon_appistol', label = 'AP Pistol', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_appistol.png', unique = true, useable = false, description = 'A small firearm designed to be held in one hand that is automatic' },
|
||||
weapon_stungun = { name = 'weapon_stungun', label = 'Taser', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_stungun.png', unique = true, useable = false, description = 'A weapon firing barbs attached by wires to batteries, causing temporary paralysis' },
|
||||
weapon_pistol50 = { name = 'weapon_pistol50', label = 'Pistol .50', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_pistol50.png', unique = true, useable = false, description = 'A .50 caliber firearm designed to be held with both hands' },
|
||||
weapon_snspistol = { name = 'weapon_snspistol', label = 'SNS Pistol', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_snspistol.png', unique = true, useable = false, description = 'A very small firearm designed to be easily concealed' },
|
||||
weapon_heavypistol = { name = 'weapon_heavypistol', label = 'Heavy Pistol', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_heavypistol.png', unique = true, useable = false, description = 'A hefty firearm designed to be held in one hand (or attempted)' },
|
||||
weapon_vintagepistol = { name = 'weapon_vintagepistol', label = 'Vintage Pistol', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_vintagepistol.png', unique = true, useable = false, description = 'An antique firearm designed to be held in one hand' },
|
||||
weapon_flaregun = { name = 'weapon_flaregun', label = 'Flare Gun', weight = 1000, type = 'weapon', ammotype = 'AMMO_FLARE', image = 'weapon_flaregun.png', unique = true, useable = false, description = 'A handgun for firing signal rockets' },
|
||||
weapon_marksmanpistol = { name = 'weapon_marksmanpistol', label = 'Marksman Pistol', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_marksmanpistol.png', unique = true, useable = false, description = 'A very accurate small firearm designed to be held in one hand' },
|
||||
weapon_revolver = { name = 'weapon_revolver', label = 'Revolver', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_revolver.png', unique = true, useable = false, description = 'A pistol with revolving chambers enabling several shots to be fired without reloading' },
|
||||
weapon_revolver_mk2 = { name = 'weapon_revolver_mk2', label = 'Violence', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_revolver_mk2.png', unique = true, useable = true, description = 'da Violence' },
|
||||
weapon_doubleaction = { name = 'weapon_doubleaction', label = 'Double Action Revolver', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_doubleaction.png', unique = true, useable = true, description = 'Double Action Revolver' },
|
||||
weapon_snspistol_mk2 = { name = 'weapon_snspistol_mk2', label = 'SNS Pistol Mk II', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_snspistol_mk2.png', unique = true, useable = true, description = 'SNS Pistol MK2' },
|
||||
weapon_raypistol = { name = 'weapon_raypistol', label = 'Up-n-Atomizer', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_raypistol.png', unique = true, useable = true, description = 'Weapon Raypistol' },
|
||||
weapon_ceramicpistol = { name = 'weapon_ceramicpistol', label = 'Ceramic Pistol', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_ceramicpistol.png', unique = true, useable = true, description = 'Weapon Ceramicpistol' },
|
||||
weapon_navyrevolver = { name = 'weapon_navyrevolver', label = 'Navy Revolver', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_navyrevolver.png', unique = true, useable = true, description = 'Weapon Navyrevolver' },
|
||||
weapon_gadgetpistol = { name = 'weapon_gadgetpistol', label = 'Perico Pistol', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_gadgetpistol.png', unique = true, useable = true, description = 'Weapon Gadgetpistol' },
|
||||
weapon_pistolxm3 = { name = 'weapon_pistolxm3', label = 'Pistol XM3', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_pistolxm3.png', unique = true, useable = true, description = 'Pistol XM3' },
|
||||
|
||||
-- Submachine Guns
|
||||
weapon_microsmg = { name = 'weapon_microsmg', label = 'Micro SMG', weight = 1000, type = 'weapon', ammotype = 'AMMO_SMG', image = 'weapon_microsmg.png', unique = true, useable = false, description = 'A handheld light weight machine gun' },
|
||||
weapon_smg = { name = 'weapon_smg', label = 'SMG', weight = 1000, type = 'weapon', ammotype = 'AMMO_SMG', image = 'weapon_smg.png', unique = true, useable = false, description = 'A handheld light weight machine gun' },
|
||||
weapon_smg_mk2 = { name = 'weapon_smg_mk2', label = 'SMG Mk II', weight = 1000, type = 'weapon', ammotype = 'AMMO_SMG', image = 'weapon_smg_mk2.png', unique = true, useable = true, description = 'SMG MK2' },
|
||||
weapon_assaultsmg = { name = 'weapon_assaultsmg', label = 'Assault SMG', weight = 1000, type = 'weapon', ammotype = 'AMMO_SMG', image = 'weapon_assaultsmg.png', unique = true, useable = false, description = 'An assault version of a handheld light weight machine gun' },
|
||||
weapon_combatpdw = { name = 'weapon_combatpdw', label = 'Combat PDW', weight = 1000, type = 'weapon', ammotype = 'AMMO_SMG', image = 'weapon_combatpdw.png', unique = true, useable = false, description = 'A combat version of a handheld light weight machine gun' },
|
||||
weapon_machinepistol = { name = 'weapon_machinepistol', label = 'Tec-9', weight = 1000, type = 'weapon', ammotype = 'AMMO_PISTOL', image = 'weapon_machinepistol.png', unique = true, useable = false, description = 'A self-loading pistol capable of burst or fully automatic fire' },
|
||||
weapon_minismg = { name = 'weapon_minismg', label = 'Mini SMG', weight = 1000, type = 'weapon', ammotype = 'AMMO_SMG', image = 'weapon_minismg.png', unique = true, useable = false, description = 'A mini handheld light weight machine gun' },
|
||||
weapon_raycarbine = { name = 'weapon_raycarbine', label = 'Unholy Hellbringer', weight = 1000, type = 'weapon', ammotype = 'AMMO_SMG', image = 'weapon_raycarbine.png', unique = true, useable = true, description = 'Weapon Raycarbine' },
|
||||
|
||||
-- Shotguns
|
||||
weapon_pumpshotgun = { name = 'weapon_pumpshotgun', label = 'Pump Shotgun', weight = 1000, type = 'weapon', ammotype = 'AMMO_SHOTGUN', image = 'weapon_pumpshotgun.png', unique = true, useable = false, description = 'A pump-action smoothbore gun for firing small shot at short range' },
|
||||
weapon_sawnoffshotgun = { name = 'weapon_sawnoffshotgun', label = 'Sawn-off Shotgun', weight = 1000, type = 'weapon', ammotype = 'AMMO_SHOTGUN', image = 'weapon_sawnoffshotgun.png', unique = true, useable = false, description = 'A sawn-off smoothbore gun for firing small shot at short range' },
|
||||
weapon_assaultshotgun = { name = 'weapon_assaultshotgun', label = 'Assault Shotgun', weight = 1000, type = 'weapon', ammotype = 'AMMO_SHOTGUN', image = 'weapon_assaultshotgun.png', unique = true, useable = false, description = 'An assault version of asmoothbore gun for firing small shot at short range' },
|
||||
weapon_bullpupshotgun = { name = 'weapon_bullpupshotgun', label = 'Bullpup Shotgun', weight = 1000, type = 'weapon', ammotype = 'AMMO_SHOTGUN', image = 'weapon_bullpupshotgun.png', unique = true, useable = false, description = 'A compact smoothbore gun for firing small shot at short range' },
|
||||
weapon_musket = { name = 'weapon_musket', label = 'Musket', weight = 1000, type = 'weapon', ammotype = 'AMMO_SHOTGUN', image = 'weapon_musket.png', unique = true, useable = false, description = 'An infantryman\'s light gun with a long barrel, typically smooth-bored, muzzleloading, and fired from the shoulder' },
|
||||
weapon_heavyshotgun = { name = 'weapon_heavyshotgun', label = 'Heavy Shotgun', weight = 1000, type = 'weapon', ammotype = 'AMMO_SHOTGUN', image = 'weapon_heavyshotgun.png', unique = true, useable = false, description = 'A large smoothbore gun for firing small shot at short range' },
|
||||
weapon_dbshotgun = { name = 'weapon_dbshotgun', label = 'Double-barrel Shotgun', weight = 1000, type = 'weapon', ammotype = 'AMMO_SHOTGUN', image = 'weapon_dbshotgun.png', unique = true, useable = false, description = 'A shotgun with two parallel barrels, allowing two single shots to be fired in quick succession' },
|
||||
weapon_autoshotgun = { name = 'weapon_autoshotgun', label = 'Auto Shotgun', weight = 1000, type = 'weapon', ammotype = 'AMMO_SHOTGUN', image = 'weapon_autoshotgun.png', unique = true, useable = false, description = 'A shotgun capable of rapid continous fire' },
|
||||
weapon_pumpshotgun_mk2 = { name = 'weapon_pumpshotgun_mk2', label = 'Pumpshotgun Mk II', weight = 1000, type = 'weapon', ammotype = 'AMMO_SHOTGUN', image = 'weapon_pumpshotgun_mk2.png', unique = true, useable = true, description = 'Pumpshotgun MK2' },
|
||||
weapon_combatshotgun = { name = 'weapon_combatshotgun', label = 'Combat Shotgun', weight = 1000, type = 'weapon', ammotype = 'AMMO_SHOTGUN', image = 'weapon_combatshotgun.png', unique = true, useable = true, description = 'Weapon Combatshotgun' },
|
||||
|
||||
-- Assault Rifles
|
||||
weapon_assaultrifle = { name = 'weapon_assaultrifle', label = 'Assault Rifle', weight = 1000, type = 'weapon', ammotype = 'AMMO_RIFLE', image = 'weapon_assaultrifle.png', unique = true, useable = false, description = 'A rapid-fire, magazine-fed automatic rifle designed for infantry use' },
|
||||
weapon_assaultrifle_mk2 = { name = 'weapon_assaultrifle_mk2', label = 'Assault Rifle Mk II', weight = 1000, type = 'weapon', ammotype = 'AMMO_RIFLE', image = 'weapon_assaultrifle_mk2.png', unique = true, useable = true, description = 'Assault Rifle MK2' },
|
||||
weapon_carbinerifle = { name = 'weapon_carbinerifle', label = 'Carbine Rifle', weight = 1000, type = 'weapon', ammotype = 'AMMO_RIFLE', image = 'weapon_carbinerifle.png', unique = true, useable = false, description = 'A light weight automatic rifle' },
|
||||
weapon_carbinerifle_mk2 = { name = 'weapon_carbinerifle_mk2', label = 'Carbine Rifle Mk II', weight = 1000, type = 'weapon', ammotype = 'AMMO_RIFLE', image = 'weapon_carbinerifle_mk2.png', unique = true, useable = true, description = 'Carbine Rifle MK2' },
|
||||
weapon_advancedrifle = { name = 'weapon_advancedrifle', label = 'Advanced Rifle', weight = 1000, type = 'weapon', ammotype = 'AMMO_RIFLE', image = 'weapon_advancedrifle.png', unique = true, useable = false, description = 'An assault version of a rapid-fire, magazine-fed automatic rifle designed for infantry use' },
|
||||
weapon_specialcarbine = { name = 'weapon_specialcarbine', label = 'Special Carbine', weight = 1000, type = 'weapon', ammotype = 'AMMO_RIFLE', image = 'weapon_specialcarbine.png', unique = true, useable = false, description = 'An extremely versatile assault rifle for any combat situation' },
|
||||
weapon_bullpuprifle = { name = 'weapon_bullpuprifle', label = 'Bullpup Rifle', weight = 1000, type = 'weapon', ammotype = 'AMMO_RIFLE', image = 'weapon_bullpuprifle.png', unique = true, useable = false, description = 'A compact automatic assault rifle' },
|
||||
weapon_compactrifle = { name = 'weapon_compactrifle', label = 'Compact Rifle', weight = 1000, type = 'weapon', ammotype = 'AMMO_RIFLE', image = 'weapon_compactrifle.png', unique = true, useable = false, description = 'A compact version of an assault rifle' },
|
||||
weapon_specialcarbine_mk2 = { name = 'weapon_specialcarbine_mk2', label = 'Special Carbine Mk II', weight = 1000, type = 'weapon', ammotype = 'AMMO_RIFLE', image = 'weapon_specialcarbine_mk2.png', unique = true, useable = true, description = 'Weapon Wpecialcarbine MK2' },
|
||||
weapon_bullpuprifle_mk2 = { name = 'weapon_bullpuprifle_mk2', label = 'Bullpup Rifle Mk II', weight = 1000, type = 'weapon', ammotype = 'AMMO_RIFLE', image = 'weapon_bullpuprifle_mk2.png', unique = true, useable = true, description = 'Bull Puprifle MK2' },
|
||||
weapon_militaryrifle = { name = 'weapon_militaryrifle', label = 'Military Rifle', weight = 1000, type = 'weapon', ammotype = 'AMMO_RIFLE', image = 'weapon_militaryrifle.png', unique = true, useable = true, description = 'Weapon Militaryrifle' },
|
||||
|
||||
-- Light Machine Guns
|
||||
weapon_mg = { name = 'weapon_mg', label = 'Machinegun', weight = 1000, type = 'weapon', ammotype = 'AMMO_MG', image = 'weapon_mg.png', unique = true, useable = false, description = 'An automatic gun that fires bullets in rapid succession for as long as the trigger is pressed' },
|
||||
weapon_combatmg = { name = 'weapon_combatmg', label = 'Combat MG', weight = 1000, type = 'weapon', ammotype = 'AMMO_MG', image = 'weapon_combatmg.png', unique = true, useable = false, description = 'A combat version of an automatic gun that fires bullets in rapid succession for as long as the trigger is pressed' },
|
||||
weapon_gusenberg = { name = 'weapon_gusenberg', label = 'Thompson SMG', weight = 1000, type = 'weapon', ammotype = 'AMMO_MG', image = 'weapon_gusenberg.png', unique = true, useable = false, description = 'An automatic rifle commonly referred to as a tommy gun' },
|
||||
weapon_combatmg_mk2 = { name = 'weapon_combatmg_mk2', label = 'Combat MG Mk II', weight = 1000, type = 'weapon', ammotype = 'AMMO_MG', image = 'weapon_combatmg_mk2.png', unique = true, useable = true, description = 'Weapon Combatmg MK2' },
|
||||
|
||||
-- Sniper Rifles
|
||||
weapon_sniperrifle = { name = 'weapon_sniperrifle', label = 'Sniper Rifle', weight = 1000, type = 'weapon', ammotype = 'AMMO_SNIPER', image = 'weapon_sniperrifle.png', unique = true, useable = false, description = 'A high-precision, long-range rifle' },
|
||||
weapon_heavysniper = { name = 'weapon_heavysniper', label = 'Heavy Sniper', weight = 1000, type = 'weapon', ammotype = 'AMMO_SNIPER', image = 'weapon_heavysniper.png', unique = true, useable = false, description = 'An upgraded high-precision, long-range rifle' },
|
||||
weapon_marksmanrifle = { name = 'weapon_marksmanrifle', label = 'Marksman Rifle', weight = 1000, type = 'weapon', ammotype = 'AMMO_SNIPER', image = 'weapon_marksmanrifle.png', unique = true, useable = false, description = 'A very accurate single-fire rifle' },
|
||||
weapon_remotesniper = { name = 'weapon_remotesniper', label = 'Remote Sniper', weight = 1000, type = 'weapon', ammotype = 'AMMO_SNIPER_REMOTE', image = 'weapon_remotesniper.png', unique = true, useable = false, description = 'A portable high-precision, long-range rifle' },
|
||||
weapon_heavysniper_mk2 = { name = 'weapon_heavysniper_mk2', label = 'Heavy Sniper Mk II', weight = 1000, type = 'weapon', ammotype = 'AMMO_SNIPER', image = 'weapon_heavysniper_mk2.png', unique = true, useable = true, description = 'Weapon Heavysniper MK2' },
|
||||
weapon_marksmanrifle_mk2 = { name = 'weapon_marksmanrifle_mk2', label = 'Marksman Rifle Mk II', weight = 1000, type = 'weapon', ammotype = 'AMMO_SNIPER', image = 'weapon_marksmanrifle_mk2.png', unique = true, useable = true, description = 'Weapon Marksmanrifle MK2' },
|
||||
|
||||
-- Heavy Weapons
|
||||
weapon_rpg = { name = 'weapon_rpg', label = 'RPG', weight = 1000, type = 'weapon', ammotype = 'AMMO_RPG', image = 'weapon_rpg.png', unique = true, useable = false, description = 'A rocket-propelled grenade launcher' },
|
||||
weapon_grenadelauncher = { name = 'weapon_grenadelauncher', label = 'Grenade Launcher', weight = 1000, type = 'weapon', ammotype = 'AMMO_GRENADELAUNCHER', image = 'weapon_grenadelauncher.png', unique = true, useable = false, description = 'A weapon that fires a specially-designed large-caliber projectile, often with an explosive, smoke or gas warhead' },
|
||||
weapon_grenadelauncher_smoke = { name = 'weapon_grenadelauncher_smoke', label = 'Smoke Grenade Launcher', weight = 1000, type = 'weapon', ammotype = 'AMMO_GRENADELAUNCHER', image = 'weapon_smokegrenade.png', unique = true, useable = false, description = 'A bomb that produces a lot of smoke when it explodes' },
|
||||
weapon_minigun = { name = 'weapon_minigun', label = 'Minigun', weight = 1000, type = 'weapon', ammotype = 'AMMO_MINIGUN', image = 'weapon_minigun.png', unique = true, useable = false, description = 'A portable machine gun consisting of a rotating cluster of six barrels and capable of variable rates of fire of up to 6,000 rounds per minute' },
|
||||
weapon_firework = { name = 'weapon_firework', label = 'Firework Launcher', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_firework.png', unique = true, useable = false, description = 'A device containing gunpowder and other combustible chemicals that causes a spectacular explosion when ignited' },
|
||||
weapon_railgun = { name = 'weapon_railgun', label = 'Railgun', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_railgun.png', unique = true, useable = false, description = 'A weapon that uses electromagnetic force to launch high velocity projectiles' },
|
||||
weapon_railgunxm3 = { name = 'weapon_railgunxm3', label = 'Railgun XM3', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_railgunxm3.png', unique = true, useable = false, description = 'A weapon that uses electromagnetic force to launch high velocity projectiles' },
|
||||
weapon_hominglauncher = { name = 'weapon_hominglauncher', label = 'Homing Launcher', weight = 1000, type = 'weapon', ammotype = 'AMMO_STINGER', image = 'weapon_hominglauncher.png', unique = true, useable = false, description = 'A weapon fitted with an electronic device that enables it to find and hit a target' },
|
||||
weapon_compactlauncher = { name = 'weapon_compactlauncher', label = 'Compact Launcher', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_compactlauncher.png', unique = true, useable = false, description = 'A compact grenade launcher' },
|
||||
weapon_rayminigun = { name = 'weapon_rayminigun', label = 'Widowmaker', weight = 1000, type = 'weapon', ammotype = 'AMMO_MINIGUN', image = 'weapon_rayminigun.png', unique = true, useable = true, description = 'Weapon Rayminigun' },
|
||||
|
||||
-- Throwables
|
||||
weapon_grenade = { name = 'weapon_grenade', label = 'Grenade', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_grenade.png', unique = true, useable = false, description = 'A handheld throwable bomb' },
|
||||
weapon_bzgas = { name = 'weapon_bzgas', label = 'BZ Gas', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_bzgas.png', unique = true, useable = false, description = 'A cannister of gas that causes extreme pain' },
|
||||
weapon_molotov = { name = 'weapon_molotov', label = 'Molotov', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_molotov.png', unique = true, useable = false, description = 'A crude bomb made of a bottle filled with a flammable liquid and fitted with a wick for lighting' },
|
||||
weapon_stickybomb = { name = 'weapon_stickybomb', label = 'C4', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_stickybomb.png', unique = true, useable = false, description = 'An explosive charge covered with an adhesive that when thrown against an object sticks until it explodes' },
|
||||
weapon_proxmine = { name = 'weapon_proxmine', label = 'Proxmine Grenade', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_proximitymine.png', unique = true, useable = false, description = 'A bomb placed on the ground that detonates when going within its proximity' },
|
||||
weapon_snowball = { name = 'weapon_snowball', label = 'Snowball', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_snowball.png', unique = true, useable = false, description = 'A ball of packed snow, especially one made for throwing at other people for fun' },
|
||||
weapon_pipebomb = { name = 'weapon_pipebomb', label = 'Pipe Bomb', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_pipebomb.png', unique = true, useable = false, description = 'A homemade bomb, the components of which are contained in a pipe' },
|
||||
weapon_ball = { name = 'weapon_ball', label = 'Ball', weight = 1000, type = 'weapon', ammotype = 'AMMO_BALL', image = 'weapon_ball.png', unique = true, useable = false, description = 'A solid or hollow spherical or egg-shaped object that is kicked, thrown, or hit in a game' },
|
||||
weapon_smokegrenade = { name = 'weapon_smokegrenade', label = 'Smoke Grenade', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_c4.png', unique = true, useable = false, description = 'An explosive charge that can be remotely detonated' },
|
||||
weapon_flare = { name = 'weapon_flare', label = 'Flare pistol', weight = 1000, type = 'weapon', ammotype = 'AMMO_FLARE', image = 'weapon_flare.png', unique = true, useable = false, description = 'A small pyrotechnic devices used for illumination and signalling' },
|
||||
|
||||
-- Miscellaneous
|
||||
weapon_petrolcan = { name = 'weapon_petrolcan', label = 'Petrol Can', weight = 1000, type = 'weapon', ammotype = 'AMMO_PETROLCAN', image = 'weapon_petrolcan.png', unique = true, useable = false, description = 'A robust liquid container made from pressed steel' },
|
||||
weapon_fireextinguisher = { name = 'weapon_fireextinguisher', label = 'Fire Extinguisher', weight = 1000, type = 'weapon', ammotype = nil, image = 'weapon_fireextinguisher.png', unique = true, useable = false, description = 'A portable device that discharges a jet of water, foam, gas, or other material to extinguish a fire' },
|
||||
weapon_hazardcan = { name = 'weapon_hazardcan', label = 'Hazardous Jerry Can', weight = 1000, type = 'weapon', ammotype = 'AMMO_PETROLCAN', image = 'weapon_hazardcan.png', unique = true, useable = true, description = 'Weapon Hazardcan' },
|
||||
|
||||
-- Weapon Attachments
|
||||
clip_attachment = { name = 'clip_attachment', label = 'Clip', weight = 1000, type = 'item', image = 'clip_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A clip for a weapon' },
|
||||
drum_attachment = { name = 'drum_attachment', label = 'Drum', weight = 1000, type = 'item', image = 'drum_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A drum for a weapon' },
|
||||
flashlight_attachment = { name = 'flashlight_attachment', label = 'Flashlight', weight = 1000, type = 'item', image = 'flashlight_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A flashlight for a weapon' },
|
||||
suppressor_attachment = { name = 'suppressor_attachment', label = 'Suppressor', weight = 1000, type = 'item', image = 'suppressor_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A suppressor for a weapon' },
|
||||
smallscope_attachment = { name = 'smallscope_attachment', label = 'Small Scope', weight = 1000, type = 'item', image = 'smallscope_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A small scope for a weapon' },
|
||||
medscope_attachment = { name = 'medscope_attachment', label = 'Medium Scope', weight = 1000, type = 'item', image = 'medscope_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A medium scope for a weapon' },
|
||||
largescope_attachment = { name = 'largescope_attachment', label = 'Large Scope', weight = 1000, type = 'item', image = 'largescope_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A large scope for a weapon' },
|
||||
holoscope_attachment = { name = 'holoscope_attachment', label = 'Holo Scope', weight = 1000, type = 'item', image = 'holoscope_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A holo scope for a weapon' },
|
||||
advscope_attachment = { name = 'advscope_attachment', label = 'Advanced Scope', weight = 1000, type = 'item', image = 'advscope_attachment.png', unique = false, useable = true, shouldClose = true, description = 'An advanced scope for a weapon' },
|
||||
nvscope_attachment = { name = 'nvscope_attachment', label = 'Night Vision Scope', weight = 1000, type = 'item', image = 'nvscope_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A night vision scope for a weapon' },
|
||||
thermalscope_attachment = { name = 'thermalscope_attachment', label = 'Thermal Scope', weight = 1000, type = 'item', image = 'thermalscope_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A thermal scope for a weapon' },
|
||||
flat_muzzle_brake = { name = 'flat_muzzle_brake', label = 'Flat Muzzle Brake', weight = 1000, type = 'item', image = 'flat_muzzle_brake.png', unique = false, useable = true, shouldClose = true, description = 'A muzzle brake for a weapon' },
|
||||
tactical_muzzle_brake = { name = 'tactical_muzzle_brake', label = 'Tactical Muzzle Brake', weight = 1000, type = 'item', image = 'tactical_muzzle_brake.png', unique = false, useable = true, shouldClose = true, description = 'A muzzle brakee for a weapon' },
|
||||
fat_end_muzzle_brake = { name = 'fat_end_muzzle_brake', label = 'Fat End Muzzle Brake', weight = 1000, type = 'item', image = 'fat_end_muzzle_brake.png', unique = false, useable = true, shouldClose = true, description = 'A muzzle brake for a weapon' },
|
||||
precision_muzzle_brake = { name = 'precision_muzzle_brake', label = 'Precision Muzzle Brake', weight = 1000, type = 'item', image = 'precision_muzzle_brake.png', unique = false, useable = true, shouldClose = true, description = 'A muzzle brake for a weapon' },
|
||||
heavy_duty_muzzle_brake = { name = 'heavy_duty_muzzle_brake', label = 'HD Muzzle Brake', weight = 1000, type = 'item', image = 'heavy_duty_muzzle_brake.png', unique = false, useable = true, shouldClose = true, description = 'A muzzle brake for a weapon' },
|
||||
slanted_muzzle_brake = { name = 'slanted_muzzle_brake', label = 'Slanted Muzzle Brake', weight = 1000, type = 'item', image = 'slanted_muzzle_brake.png', unique = false, useable = true, shouldClose = true, description = 'A muzzle brake for a weapon' },
|
||||
split_end_muzzle_brake = { name = 'split_end_muzzle_brake', label = 'Split End Muzzle Brake', weight = 1000, type = 'item', image = 'split_end_muzzle_brake.png', unique = false, useable = true, shouldClose = true, description = 'A muzzle brake for a weapon' },
|
||||
squared_muzzle_brake = { name = 'squared_muzzle_brake', label = 'Squared Muzzle Brake', weight = 1000, type = 'item', image = 'squared_muzzle_brake.png', unique = false, useable = true, shouldClose = true, description = 'A muzzle brake for a weapon' },
|
||||
bellend_muzzle_brake = { name = 'bellend_muzzle_brake', label = 'Bellend Muzzle Brake', weight = 1000, type = 'item', image = 'bellend_muzzle_brake.png', unique = false, useable = true, shouldClose = true, description = 'A muzzle brake for a weapon' },
|
||||
barrel_attachment = { name = 'barrel_attachment', label = 'Barrel', weight = 1000, type = 'item', image = 'barrel_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A barrel for a weapon' },
|
||||
grip_attachment = { name = 'grip_attachment', label = 'Grip', weight = 1000, type = 'item', image = 'grip_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A grip for a weapon' },
|
||||
comp_attachment = { name = 'comp_attachment', label = 'Compensator', weight = 1000, type = 'item', image = 'comp_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A compensator for a weapon' },
|
||||
luxuryfinish_attachment = { name = 'luxuryfinish_attachment', label = 'Luxury Finish', weight = 1000, type = 'item', image = 'luxuryfinish_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A luxury finish for a weapon' },
|
||||
digicamo_attachment = { name = 'digicamo_attachment', label = 'Digital Camo', weight = 1000, type = 'item', image = 'digicamo_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A digital camo for a weapon' },
|
||||
brushcamo_attachment = { name = 'brushcamo_attachment', label = 'Brushstroke Camo', weight = 1000, type = 'item', image = 'brushcamo_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A brushstroke camo for a weapon' },
|
||||
woodcamo_attachment = { name = 'woodcamo_attachment', label = 'Woodland Camo', weight = 1000, type = 'item', image = 'woodcamo_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A woodland camo for a weapon' },
|
||||
skullcamo_attachment = { name = 'skullcamo_attachment', label = 'Skull Camo', weight = 1000, type = 'item', image = 'skullcamo_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A skull camo for a weapon' },
|
||||
sessantacamo_attachment = { name = 'sessantacamo_attachment', label = 'Sessanta Nove Camo', weight = 1000, type = 'item', image = 'sessantacamo_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A sessanta nove camo for a weapon' },
|
||||
perseuscamo_attachment = { name = 'perseuscamo_attachment', label = 'Perseus Camo', weight = 1000, type = 'item', image = 'perseuscamo_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A perseus camo for a weapon' },
|
||||
leopardcamo_attachment = { name = 'leopardcamo_attachment', label = 'Leopard Camo', weight = 1000, type = 'item', image = 'leopardcamo_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A leopard camo for a weapon' },
|
||||
zebracamo_attachment = { name = 'zebracamo_attachment', label = 'Zebra Camo', weight = 1000, type = 'item', image = 'zebracamo_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A zebra camo for a weapon' },
|
||||
geocamo_attachment = { name = 'geocamo_attachment', label = 'Geometric Camo', weight = 1000, type = 'item', image = 'geocamo_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A geometric camo for a weapon' },
|
||||
boomcamo_attachment = { name = 'boomcamo_attachment', label = 'Boom Camo', weight = 1000, type = 'item', image = 'boomcamo_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A boom camo for a weapon' },
|
||||
patriotcamo_attachment = { name = 'patriotcamo_attachment', label = 'Patriot Camo', weight = 1000, type = 'item', image = 'patriotcamo_attachment.png', unique = false, useable = true, shouldClose = true, description = 'A patriot camo for a weapon' },
|
||||
|
||||
-- Weapon Tints
|
||||
weapontint_0 = { name = 'weapontint_0', label = 'Default Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Default/Black Weapon Tint' },
|
||||
weapontint_1 = { name = 'weapontint_1', label = 'Green Tint', weight = 1000, type = 'item', image = 'weapontint_green.png', unique = false, useable = true, shouldClose = true, description = 'Green Weapon Tint' },
|
||||
weapontint_2 = { name = 'weapontint_2', label = 'Gold Tint', weight = 1000, type = 'item', image = 'weapontint_gold.png', unique = false, useable = true, shouldClose = true, description = 'Gold Weapon Tint' },
|
||||
weapontint_3 = { name = 'weapontint_3', label = 'Pink Tint', weight = 1000, type = 'item', image = 'weapontint_pink.png', unique = false, useable = true, shouldClose = true, description = 'Pink Weapon Tint' },
|
||||
weapontint_4 = { name = 'weapontint_4', label = 'Army Tint', weight = 1000, type = 'item', image = 'weapontint_army.png', unique = false, useable = true, shouldClose = true, description = 'Army Weapon Tint' },
|
||||
weapontint_5 = { name = 'weapontint_5', label = 'LSPD Tint', weight = 1000, type = 'item', image = 'weapontint_lspd.png', unique = false, useable = true, shouldClose = true, description = 'LSPD Weapon Tint' },
|
||||
weapontint_6 = { name = 'weapontint_6', label = 'Orange Tint', weight = 1000, type = 'item', image = 'weapontint_orange.png', unique = false, useable = true, shouldClose = true, description = 'Orange Weapon Tint' },
|
||||
weapontint_7 = { name = 'weapontint_7', label = 'Platinum Tint', weight = 1000, type = 'item', image = 'weapontint_plat.png', unique = false, useable = true, shouldClose = true, description = 'Platinum Weapon Tint' },
|
||||
weapontint_mk2_0 = { name = 'weapontint_mk2_0', label = 'Classic Black Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Classic Black Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_1 = { name = 'weapontint_mk2_1', label = 'Classic Gray Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Classic Gray Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_2 = { name = 'weapontint_mk2_2', label = 'Classic Two-Tone Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Classic Two-Tone Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_3 = { name = 'weapontint_mk2_3', label = 'Classic White Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Classic White Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_4 = { name = 'weapontint_mk2_4', label = 'Classic Beige Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Classic Beige Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_5 = { name = 'weapontint_mk2_5', label = 'Classic Green Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Classic Green Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_6 = { name = 'weapontint_mk2_6', label = 'Classic Blue Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Classic Blue Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_7 = { name = 'weapontint_mk2_7', label = 'Classic Earth Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Classic Earth Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_8 = { name = 'weapontint_mk2_8', label = 'Classic Brown & Black Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Classic Brown & Black Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_9 = { name = 'weapontint_mk2_9', label = 'Red Contrast Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Red Contrast Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_10 = { name = 'weapontint_mk2_10', label = 'Blue Contrast Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Blue Contrast Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_11 = { name = 'weapontint_mk2_11', label = 'Yellow Contrast Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Yellow Contrast Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_12 = { name = 'weapontint_mk2_12', label = 'Orange Contrast Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Orange Contrast Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_13 = { name = 'weapontint_mk2_13', label = 'Bold Pink Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Bold Pink Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_14 = { name = 'weapontint_mk2_14', label = 'Bold Purple & Yellow Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Bold Purple & Yellow Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_15 = { name = 'weapontint_mk2_15', label = 'Bold Orange Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Bold Orange Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_16 = { name = 'weapontint_mk2_16', label = 'Bold Green & Purple Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Bold Green & Purple Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_17 = { name = 'weapontint_mk2_17', label = 'Bold Red Features Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Bold Red Features Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_18 = { name = 'weapontint_mk2_18', label = 'Bold Green Features Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Bold Green Features Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_19 = { name = 'weapontint_mk2_19', label = 'Bold Cyan Features Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Bold Cyan Features Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_20 = { name = 'weapontint_mk2_20', label = 'Bold Yellow Features Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Bold Yellow Features Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_21 = { name = 'weapontint_mk2_21', label = 'Bold Red & White Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Bold Red & White Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_22 = { name = 'weapontint_mk2_22', label = 'Bold Blue & White Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Bold Blue & White Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_23 = { name = 'weapontint_mk2_23', label = 'Metallic Gold Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Metallic Gold Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_24 = { name = 'weapontint_mk2_24', label = 'Metallic Platinum Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Metallic Platinum Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_25 = { name = 'weapontint_mk2_25', label = 'Metallic Gray & Lilac Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Metallic Gray & Lilac Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_26 = { name = 'weapontint_mk2_26', label = 'Metallic Purple & Lime Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Metallic Purple & Lime Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_27 = { name = 'weapontint_mk2_27', label = 'Metallic Red Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Metallic Red Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_28 = { name = 'weapontint_mk2_28', label = 'Metallic Green Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Metallic Green Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_29 = { name = 'weapontint_mk2_29', label = 'Metallic Blue Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Metallic Blue Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_30 = { name = 'weapontint_mk2_30', label = 'Metallic White & Aqua Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Metallic White & Aqua Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_31 = { name = 'weapontint_mk2_31', label = 'Metallic Orange & Yellow Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Metallic Orange & Yellow Weapon Tint for MK2 Weapons' },
|
||||
weapontint_mk2_32 = { name = 'weapontint_mk2_32', label = 'Metallic Red and Yellow Tint', weight = 1000, type = 'item', image = 'weapontint_black.png', unique = false, useable = true, shouldClose = true, description = 'Metallic Red and Yellow Weapon Tint for MK2 Weapons' },
|
||||
-- ITEMS
|
||||
|
||||
-- Ammo ITEMS
|
||||
pistol_ammo = { name = 'pistol_ammo', label = 'Pistol ammo', weight = 200, type = 'item', image = 'pistol_ammo.png', unique = false, useable = true, shouldClose = true, description = 'Ammo for Pistols' },
|
||||
rifle_ammo = { name = 'rifle_ammo', label = 'Rifle ammo', weight = 1000, type = 'item', image = 'rifle_ammo.png', unique = false, useable = true, shouldClose = true, description = 'Ammo for Rifles' },
|
||||
smg_ammo = { name = 'smg_ammo', label = 'SMG ammo', weight = 500, type = 'item', image = 'smg_ammo.png', unique = false, useable = true, shouldClose = true, description = 'Ammo for Sub Machine Guns' },
|
||||
shotgun_ammo = { name = 'shotgun_ammo', label = 'Shotgun ammo', weight = 500, type = 'item', image = 'shotgun_ammo.png', unique = false, useable = true, shouldClose = true, description = 'Ammo for Shotguns' },
|
||||
mg_ammo = { name = 'mg_ammo', label = 'MG ammo', weight = 1000, type = 'item', image = 'mg_ammo.png', unique = false, useable = true, shouldClose = true, description = 'Ammo for Machine Guns' },
|
||||
snp_ammo = { name = 'snp_ammo', label = 'Sniper ammo', weight = 1000, type = 'item', image = 'rifle_ammo.png', unique = false, useable = true, shouldClose = true, description = 'Ammo for Sniper Rifles' },
|
||||
emp_ammo = { name = 'emp_ammo', label = 'EMP Ammo', weight = 200, type = 'item', image = 'emp_ammo.png', unique = false, useable = true, shouldClose = true, description = 'Ammo for EMP Launcher' },
|
||||
|
||||
-- Card ITEMS
|
||||
id_card = { name = 'id_card', label = 'ID Card', weight = 0, type = 'item', image = 'id_card.png', unique = true, useable = true, shouldClose = false, description = 'A card containing all your information to identify yourself' },
|
||||
driver_license = { name = 'driver_license', label = 'Drivers License', weight = 0, type = 'item', image = 'driver_license.png', unique = true, useable = true, shouldClose = false, description = 'Permit to show you can drive a vehicle' },
|
||||
lawyerpass = { name = 'lawyerpass', label = 'Lawyer Pass', weight = 0, type = 'item', image = 'lawyerpass.png', unique = true, useable = true, shouldClose = false, description = 'Pass exclusive to lawyers to show they can represent a suspect' },
|
||||
weaponlicense = { name = 'weaponlicense', label = 'Weapon License', weight = 0, type = 'item', image = 'weapon_license.png', unique = true, useable = true, shouldClose = true, description = 'Weapon License' },
|
||||
bank_card = { name = 'bank_card', label = 'Bank Card', weight = 0, type = 'item', image = 'bank_card.png', unique = true, useable = true, shouldClose = true, description = 'Used to access ATM' },
|
||||
security_card_01 = { name = 'security_card_01', label = 'Security Card A', weight = 0, type = 'item', image = 'security_card_01.png', unique = false, useable = true, shouldClose = true, description = 'A security card... I wonder what it goes to' },
|
||||
security_card_02 = { name = 'security_card_02', label = 'Security Card B', weight = 0, type = 'item', image = 'security_card_02.png', unique = false, useable = true, shouldClose = true, description = 'A security card... I wonder what it goes to' },
|
||||
|
||||
-- Eat ITEMS
|
||||
tosti = { name = 'tosti', label = 'Grilled Cheese Sandwich', weight = 200, type = 'item', image = 'tosti.png', unique = false, useable = true, shouldClose = true, description = 'Nice to eat' },
|
||||
twerks_candy = { name = 'twerks_candy', label = 'Twerks', weight = 100, type = 'item', image = 'twerks_candy.png', unique = false, useable = true, shouldClose = true, description = 'Some delicious candy :O' },
|
||||
snikkel_candy = { name = 'snikkel_candy', label = 'Snikkel', weight = 100, type = 'item', image = 'snikkel_candy.png', unique = false, useable = true, shouldClose = true, description = 'Some delicious candy :O' },
|
||||
sandwich = { name = 'sandwich', label = 'Sandwich', weight = 200, type = 'item', image = 'sandwich.png', unique = false, useable = true, shouldClose = true, description = 'Nice bread for your stomach' },
|
||||
|
||||
-- Drink ITEMS
|
||||
water_bottle = { name = 'water_bottle', label = 'Bottle of Water', weight = 500, type = 'item', image = 'water_bottle.png', unique = false, useable = true, shouldClose = true, description = 'For all the thirsty out there' },
|
||||
coffee = { name = 'coffee', label = 'Coffee', weight = 200, type = 'item', image = 'coffee.png', unique = false, useable = true, shouldClose = true, description = 'Pump 4 Caffeine' },
|
||||
kurkakola = { name = 'kurkakola', label = 'Cola', weight = 500, type = 'item', image = 'cola.png', unique = false, useable = true, shouldClose = true, description = 'For all the thirsty out there' },
|
||||
|
||||
-- Alcohol
|
||||
beer = { name = 'beer', label = 'Beer', weight = 500, type = 'item', image = 'beer.png', unique = false, useable = true, shouldClose = true, description = 'Nothing like a good cold beer!' },
|
||||
whiskey = { name = 'whiskey', label = 'Whiskey', weight = 500, type = 'item', image = 'whiskey.png', unique = false, useable = true, shouldClose = true, description = 'For all the thirsty out there' },
|
||||
vodka = { name = 'vodka', label = 'Vodka', weight = 500, type = 'item', image = 'vodka.png', unique = false, useable = true, shouldClose = true, description = 'For all the thirsty out there' },
|
||||
grape = { name = 'grape', label = 'Grape', weight = 100, type = 'item', image = 'grape.png', unique = false, useable = true, shouldClose = false, description = 'Mmmmh yummie, grapes' },
|
||||
wine = { name = 'wine', label = 'Wine', weight = 300, type = 'item', image = 'wine.png', unique = false, useable = true, shouldClose = false, description = 'Some good wine to drink on a fine evening' },
|
||||
grapejuice = { name = 'grapejuice', label = 'Grape Juice', weight = 200, type = 'item', image = 'grapejuice.png', unique = false, useable = true, shouldClose = false, description = 'Grape juice is said to be healthy' },
|
||||
|
||||
-- Drugs
|
||||
joint = { name = 'joint', label = 'Joint', weight = 0, type = 'item', image = 'joint.png', unique = false, useable = true, shouldClose = true, description = 'Sidney would be very proud at you' },
|
||||
cokebaggy = { name = 'cokebaggy', label = 'Bag of Coke', weight = 0, type = 'item', image = 'cocaine_baggy.png', unique = false, useable = true, shouldClose = true, description = 'To get happy real quick' },
|
||||
crack_baggy = { name = 'crack_baggy', label = 'Bag of Crack', weight = 0, type = 'item', image = 'crack_baggy.png', unique = false, useable = true, shouldClose = true, description = 'To get happy faster' },
|
||||
xtcbaggy = { name = 'xtcbaggy', label = 'Bag of XTC', weight = 0, type = 'item', image = 'xtc_baggy.png', unique = false, useable = true, shouldClose = true, description = 'Pop those pills baby' },
|
||||
coke_brick = { name = 'coke_brick', label = 'Coke Brick', weight = 1000, type = 'item', image = 'coke_brick.png', unique = true, useable = false, shouldClose = true, description = 'Heavy package of cocaine, mostly used for deals and takes a lot of space' },
|
||||
weed_brick = { name = 'weed_brick', label = 'Weed Brick', weight = 1000, type = 'item', image = 'weed_brick.png', unique = false, useable = false, shouldClose = true, description = '1KG Weed Brick to sell to large customers.' },
|
||||
coke_small_brick = { name = 'coke_small_brick', label = 'Coke Package', weight = 350, type = 'item', image = 'coke_small_brick.png', unique = true, useable = false, shouldClose = true, description = 'Small package of cocaine, mostly used for deals and takes a lot of space' },
|
||||
oxy = { name = 'oxy', label = 'Prescription Oxy', weight = 0, type = 'item', image = 'oxy.png', unique = false, useable = true, shouldClose = true, description = 'The Label Has Been Ripped Off' },
|
||||
meth = { name = 'meth', label = 'Meth', weight = 100, type = 'item', image = 'meth_baggy.png', unique = false, useable = true, shouldClose = true, description = 'A baggie of Meth' },
|
||||
rolling_paper = { name = 'rolling_paper', label = 'Rolling Paper', weight = 0, type = 'item', image = 'rolling_paper.png', unique = false, useable = false, shouldClose = true, description = 'Paper made specifically for encasing and smoking tobacco or cannabis.' },
|
||||
|
||||
-- Seed And Weed
|
||||
weed_whitewidow = { name = 'weed_whitewidow', label = 'White Widow 2g', weight = 200, type = 'item', image = 'weed_baggy.png', unique = false, useable = true, shouldClose = false, description = 'A weed bag with 2g White Widow' },
|
||||
weed_skunk = { name = 'weed_skunk', label = 'Skunk 2g', weight = 200, type = 'item', image = 'weed_baggy.png', unique = false, useable = true, shouldClose = false, description = 'A weed bag with 2g Skunk' },
|
||||
weed_purplehaze = { name = 'weed_purplehaze', label = 'Purple Haze 2g', weight = 200, type = 'item', image = 'weed_baggy.png', unique = false, useable = true, shouldClose = false, description = 'A weed bag with 2g Purple Haze' },
|
||||
weed_ogkush = { name = 'weed_ogkush', label = 'OGKush 2g', weight = 200, type = 'item', image = 'weed_baggy.png', unique = false, useable = true, shouldClose = false, description = 'A weed bag with 2g OG Kush' },
|
||||
weed_amnesia = { name = 'weed_amnesia', label = 'Amnesia 2g', weight = 200, type = 'item', image = 'weed_baggy.png', unique = false, useable = true, shouldClose = false, description = 'A weed bag with 2g Amnesia' },
|
||||
weed_ak47 = { name = 'weed_ak47', label = 'AK47 2g', weight = 200, type = 'item', image = 'weed_baggy.png', unique = false, useable = true, shouldClose = false, description = 'A weed bag with 2g AK47' },
|
||||
weed_whitewidow_seed = { name = 'weed_whitewidow_seed', label = 'White Widow Seed', weight = 0, type = 'item', image = 'weed_seed.png', unique = false, useable = true, shouldClose = false, description = 'A weed seed of White Widow' },
|
||||
weed_skunk_seed = { name = 'weed_skunk_seed', label = 'Skunk Seed', weight = 0, type = 'item', image = 'weed_seed.png', unique = false, useable = true, shouldClose = true, description = 'A weed seed of Skunk' },
|
||||
weed_purplehaze_seed = { name = 'weed_purplehaze_seed', label = 'Purple Haze Seed', weight = 0, type = 'item', image = 'weed_seed.png', unique = false, useable = true, shouldClose = true, description = 'A weed seed of Purple Haze' },
|
||||
weed_ogkush_seed = { name = 'weed_ogkush_seed', label = 'OGKush Seed', weight = 0, type = 'item', image = 'weed_seed.png', unique = false, useable = true, shouldClose = true, description = 'A weed seed of OG Kush' },
|
||||
weed_amnesia_seed = { name = 'weed_amnesia_seed', label = 'Amnesia Seed', weight = 0, type = 'item', image = 'weed_seed.png', unique = false, useable = true, shouldClose = true, description = 'A weed seed of Amnesia' },
|
||||
weed_ak47_seed = { name = 'weed_ak47_seed', label = 'AK47 Seed', weight = 0, type = 'item', image = 'weed_seed.png', unique = false, useable = true, shouldClose = true, description = 'A weed seed of AK47' },
|
||||
empty_weed_bag = { name = 'empty_weed_bag', label = 'Empty Weed Bag', weight = 0, type = 'item', image = 'weed_baggy_empty.png', unique = false, useable = true, shouldClose = true, description = 'A small empty bag' },
|
||||
weed_nutrition = { name = 'weed_nutrition', label = 'Plant Fertilizer', weight = 2000, type = 'item', image = 'weed_nutrition.png', unique = false, useable = true, shouldClose = true, description = 'Plant nutrition' },
|
||||
|
||||
-- Material
|
||||
plastic = { name = 'plastic', label = 'Plastic', weight = 100, type = 'item', image = 'plastic.png', unique = false, useable = false, shouldClose = false, description = 'RECYCLE! - Greta Thunberg 2019' },
|
||||
metalscrap = { name = 'metalscrap', label = 'Metal Scrap', weight = 100, type = 'item', image = 'metalscrap.png', unique = false, useable = false, shouldClose = false, description = 'You can probably make something nice out of this' },
|
||||
copper = { name = 'copper', label = 'Copper', weight = 100, type = 'item', image = 'copper.png', unique = false, useable = false, shouldClose = false, description = 'Nice piece of metal that you can probably use for something' },
|
||||
aluminum = { name = 'aluminum', label = 'Aluminium', weight = 100, type = 'item', image = 'aluminum.png', unique = false, useable = false, shouldClose = false, description = 'Nice piece of metal that you can probably use for something' },
|
||||
aluminumoxide = { name = 'aluminumoxide', label = 'Aluminium Powder', weight = 100, type = 'item', image = 'aluminumoxide.png', unique = false, useable = false, shouldClose = false, description = 'Some powder to mix with' },
|
||||
iron = { name = 'iron', label = 'Iron', weight = 100, type = 'item', image = 'iron.png', unique = false, useable = false, shouldClose = false, description = 'Handy piece of metal that you can probably use for something' },
|
||||
ironoxide = { name = 'ironoxide', label = 'Iron Powder', weight = 100, type = 'item', image = 'ironoxide.png', unique = false, useable = false, shouldClose = false, description = 'Some powder to mix with.' },
|
||||
steel = { name = 'steel', label = 'Steel', weight = 100, type = 'item', image = 'steel.png', unique = false, useable = false, shouldClose = false, description = 'Nice piece of metal that you can probably use for something' },
|
||||
rubber = { name = 'rubber', label = 'Rubber', weight = 100, type = 'item', image = 'rubber.png', unique = false, useable = false, shouldClose = false, description = 'Rubber, I believe you can make your own rubber ducky with it :D' },
|
||||
glass = { name = 'glass', label = 'Glass', weight = 100, type = 'item', image = 'glass.png', unique = false, useable = false, shouldClose = false, description = 'It is very fragile, watch out' },
|
||||
|
||||
-- Tools
|
||||
lockpick = { name = 'lockpick', label = 'Lockpick', weight = 300, type = 'item', image = 'lockpick.png', unique = false, useable = true, shouldClose = true, description = 'Very useful if you lose your keys a lot.. or if you want to use it for something else...' },
|
||||
advancedlockpick = { name = 'advancedlockpick', label = 'Advanced Lockpick', weight = 500, type = 'item', image = 'advancedlockpick.png', unique = false, useable = true, shouldClose = true, description = 'If you lose your keys a lot this is very useful... Also useful to open your beers' },
|
||||
electronickit = { name = 'electronickit', label = 'Electronic Kit', weight = 100, type = 'item', image = 'electronickit.png', unique = false, useable = true, shouldClose = true, description = 'If you\'ve always wanted to build a robot you can maybe start here. Maybe you\'ll be the new Elon Musk?' },
|
||||
gatecrack = { name = 'gatecrack', label = 'Gatecrack', weight = 0, type = 'item', image = 'usb_device.png', unique = false, useable = false, shouldClose = true, description = 'Handy software to tear down some fences' },
|
||||
thermite = { name = 'thermite', label = 'Thermite', weight = 1000, type = 'item', image = 'thermite.png', unique = false, useable = true, shouldClose = true, description = 'Sometimes you\'d wish for everything to burn' },
|
||||
trojan_usb = { name = 'trojan_usb', label = 'Trojan USB', weight = 0, type = 'item', image = 'usb_device.png', unique = false, useable = false, shouldClose = true, description = 'Handy software to shut down some systems' },
|
||||
screwdriverset = { name = 'screwdriverset', label = 'Toolkit', weight = 1000, type = 'item', image = 'screwdriverset.png', unique = false, useable = false, shouldClose = false, description = 'Very useful to screw... screws...' },
|
||||
drill = { name = 'drill', label = 'Drill', weight = 20000, type = 'item', image = 'drill.png', unique = false, useable = false, shouldClose = false, description = 'The real deal...' },
|
||||
|
||||
-- Vehicle Tools
|
||||
nitrous = { name = 'nitrous', label = 'Nitrous', weight = 1000, type = 'item', image = 'nitrous.png', unique = false, useable = true, shouldClose = true, description = 'Speed up, gas pedal! :D' },
|
||||
repairkit = { name = 'repairkit', label = 'Repairkit', weight = 2500, type = 'item', image = 'repairkit.png', unique = false, useable = true, shouldClose = true, description = 'A nice toolbox with stuff to repair your vehicle' },
|
||||
advancedrepairkit = { name = 'advancedrepairkit', label = 'Advanced Repairkit', weight = 4000, type = 'item', image = 'advancedkit.png', unique = false, useable = true, shouldClose = true, description = 'A nice toolbox with stuff to repair your vehicle' },
|
||||
cleaningkit = { name = 'cleaningkit', label = 'Cleaning Kit', weight = 250, type = 'item', image = 'cleaningkit.png', unique = false, useable = true, shouldClose = true, description = 'A microfiber cloth with some soap will let your car sparkle again!' },
|
||||
tunerlaptop = { name = 'tunerlaptop', label = 'Tunerchip', weight = 2000, type = 'item', image = 'tunerchip.png', unique = true, useable = true, shouldClose = true, description = 'With this tunerchip you can get your car on steroids... If you know what you\'re doing' },
|
||||
harness = { name = 'harness', label = 'Race Harness', weight = 1000, type = 'item', image = 'harness.png', unique = true, useable = true, shouldClose = true, description = 'Racing Harness so no matter what you stay in the car' },
|
||||
jerry_can = { name = 'jerry_can', label = 'Jerrycan 20L', weight = 20000, type = 'item', image = 'jerry_can.png', unique = false, useable = true, shouldClose = true, description = 'A can full of Fuel' },
|
||||
tirerepairkit = { name = 'tirerepairkit', label = 'Tire Repair Kit', weight = 1000, type = 'item', image = 'tirerepairkit.png', unique = false, useable = true, shouldClose = true, description = 'A kit to repair your tires' },
|
||||
|
||||
-- Mechanic Parts
|
||||
veh_toolbox = { name = 'veh_toolbox', label = 'Toolbox', weight = 1000, type = 'item', image = 'veh_toolbox.png', unique = false, useable = true, shouldClose = true, description = 'Check vehicle status' },
|
||||
veh_armor = { name = 'veh_armor', label = 'Armor', weight = 1000, type = 'item', image = 'veh_armor.png', unique = false, useable = true, shouldClose = true, description = 'Upgrade vehicle armor' },
|
||||
veh_brakes = { name = 'veh_brakes', label = 'Brakes', weight = 1000, type = 'item', image = 'veh_brakes.png', unique = false, useable = true, shouldClose = true, description = 'Upgrade vehicle brakes' },
|
||||
veh_engine = { name = 'veh_engine', label = 'Engine', weight = 1000, type = 'item', image = 'veh_engine.png', unique = false, useable = true, shouldClose = true, description = 'Upgrade vehicle engine' },
|
||||
veh_suspension = { name = 'veh_suspension', label = 'Suspension', weight = 1000, type = 'item', image = 'veh_suspension.png', unique = false, useable = true, shouldClose = true, description = 'Upgrade vehicle suspension' },
|
||||
veh_transmission = { name = 'veh_transmission', label = 'Transmission', weight = 1000, type = 'item', image = 'veh_transmission.png', unique = false, useable = true, shouldClose = true, description = 'Upgrade vehicle transmission' },
|
||||
veh_turbo = { name = 'veh_turbo', label = 'Turbo', weight = 1000, type = 'item', image = 'veh_turbo.png', unique = false, useable = true, shouldClose = true, description = 'Install vehicle turbo' },
|
||||
veh_interior = { name = 'veh_interior', label = 'Interior', weight = 1000, type = 'item', image = 'veh_interior.png', unique = false, useable = true, shouldClose = true, description = 'Upgrade vehicle interior' },
|
||||
veh_exterior = { name = 'veh_exterior', label = 'Exterior', weight = 1000, type = 'item', image = 'veh_exterior.png', unique = false, useable = true, shouldClose = true, description = 'Upgrade vehicle exterior' },
|
||||
veh_wheels = { name = 'veh_wheels', label = 'Wheels', weight = 1000, type = 'item', image = 'veh_wheels.png', unique = false, useable = true, shouldClose = true, description = 'Upgrade vehicle wheels' },
|
||||
veh_neons = { name = 'veh_neons', label = 'Neons', weight = 1000, type = 'item', image = 'veh_neons.png', unique = false, useable = true, shouldClose = true, description = 'Upgrade vehicle neons' },
|
||||
veh_xenons = { name = 'veh_xenons', label = 'Xenons', weight = 1000, type = 'item', image = 'veh_xenons.png', unique = false, useable = true, shouldClose = true, description = 'Upgrade vehicle xenons' },
|
||||
veh_tint = { name = 'veh_tint', label = 'Tints', weight = 1000, type = 'item', image = 'veh_tint.png', unique = false, useable = true, shouldClose = true, description = 'Install vehicle tint' },
|
||||
veh_plates = { name = 'veh_plates', label = 'Plates', weight = 1000, type = 'item', image = 'veh_plates.png', unique = false, useable = true, shouldClose = true, description = 'Install vehicle plates' },
|
||||
|
||||
-- Medication
|
||||
firstaid = { name = 'firstaid', label = 'First Aid', weight = 2500, type = 'item', image = 'firstaid.png', unique = false, useable = true, shouldClose = true, description = 'You can use this First Aid kit to get people back on their feet' },
|
||||
bandage = { name = 'bandage', label = 'Bandage', weight = 0, type = 'item', image = 'bandage.png', unique = false, useable = true, shouldClose = true, description = 'A bandage works every time' },
|
||||
ifaks = { name = 'ifaks', label = 'ifaks', weight = 200, type = 'item', image = 'ifaks.png', unique = false, useable = true, shouldClose = true, description = 'ifaks for healing and a complete stress remover.' },
|
||||
painkillers = { name = 'painkillers', label = 'Painkillers', weight = 0, type = 'item', image = 'painkillers.png', unique = false, useable = true, shouldClose = true, description = 'For pain you can\'t stand anymore, take this pill that\'d make you feel great again' },
|
||||
walkstick = { name = 'walkstick', label = 'Walking Stick', weight = 1000, type = 'item', image = 'walkstick.png', unique = false, useable = true, shouldClose = true, description = 'Walking stick for ya\'ll grannies out there.. HAHA' },
|
||||
|
||||
-- Communication
|
||||
phone = { name = 'phone', label = 'Phone', weight = 700, type = 'item', image = 'phone.png', unique = true, useable = false, shouldClose = false, description = 'Neat phone ya got there' },
|
||||
radio = { name = 'radio', label = 'Radio', weight = 2000, type = 'item', image = 'radio.png', unique = true, useable = true, shouldClose = true, description = 'You can communicate with this through a signal' },
|
||||
iphone = { name = 'iphone', label = 'iPhone', weight = 1000, type = 'item', image = 'iphone.png', unique = false, useable = false, shouldClose = true, description = 'Very expensive phone' },
|
||||
samsungphone = { name = 'samsungphone', label = 'Samsung S10', weight = 1000, type = 'item', image = 'samsungphone.png', unique = false, useable = false, shouldClose = true, description = 'Very expensive phone' },
|
||||
laptop = { name = 'laptop', label = 'Laptop', weight = 4000, type = 'item', image = 'laptop.png', unique = false, useable = false, shouldClose = true, description = 'Expensive laptop' },
|
||||
tablet = { name = 'tablet', label = 'Tablet', weight = 2000, type = 'item', image = 'tablet.png', unique = false, useable = false, shouldClose = true, description = 'Expensive tablet' },
|
||||
fitbit = { name = 'fitbit', label = 'Fitbit', weight = 500, type = 'item', image = 'fitbit.png', unique = true, useable = true, shouldClose = true, description = 'I like fitbit' },
|
||||
radioscanner = { name = 'radioscanner', label = 'Radio Scanner', weight = 1000, type = 'item', image = 'radioscanner.png', unique = false, useable = false, shouldClose = true, description = 'With this you can get some police alerts. Not 100% effective however' },
|
||||
pinger = { name = 'pinger', label = 'Pinger', weight = 1000, type = 'item', image = 'pinger.png', unique = false, useable = false, shouldClose = true, description = 'With a pinger and your phone you can send out your location' },
|
||||
cryptostick = { name = 'cryptostick', label = 'Crypto Stick', weight = 200, type = 'item', image = 'cryptostick.png', unique = true, useable = true, shouldClose = true, description = 'Why would someone ever buy money that doesn\'t exist.. How many would it contain..?' },
|
||||
|
||||
-- Theft and Jewelry
|
||||
rolex = { name = 'rolex', label = 'Golden Watch', weight = 1500, type = 'item', image = 'rolex.png', unique = false, useable = false, shouldClose = true, description = 'A golden watch seems like the jackpot to me!' },
|
||||
diamond_ring = { name = 'diamond_ring', label = 'Diamond Ring', weight = 1500, type = 'item', image = 'diamond_ring.png', unique = false, useable = false, shouldClose = true, description = 'A diamond ring seems like the jackpot to me!' },
|
||||
diamond = { name = 'diamond', label = 'Diamond', weight = 1000, type = 'item', image = 'diamond.png', unique = false, useable = false, shouldClose = true, description = 'A diamond seems like the jackpot to me!' },
|
||||
goldchain = { name = 'goldchain', label = 'Golden Chain', weight = 1500, type = 'item', image = 'goldchain.png', unique = false, useable = false, shouldClose = true, description = 'A golden chain seems like the jackpot to me!' },
|
||||
tenkgoldchain = { name = 'tenkgoldchain', label = '10k Gold Chain', weight = 2000, type = 'item', image = '10kgoldchain.png', unique = false, useable = false, shouldClose = true, description = '10 carat golden chain' },
|
||||
goldbar = { name = 'goldbar', label = 'Gold Bar', weight = 7000, type = 'item', image = 'goldbar.png', unique = false, useable = false, shouldClose = true, description = 'Looks pretty expensive to me' },
|
||||
|
||||
-- Cops Tools
|
||||
armor = { name = 'armor', label = 'Armor', weight = 5000, type = 'item', image = 'armor.png', unique = false, useable = true, shouldClose = true, description = 'Some protection won\'t hurt... right?' },
|
||||
heavyarmor = { name = 'heavyarmor', label = 'Heavy Armor', weight = 5000, type = 'item', image = 'armor.png', unique = false, useable = true, shouldClose = true, description = 'Some protection won\'t hurt... right?' },
|
||||
handcuffs = { name = 'handcuffs', label = 'Handcuffs', weight = 100, type = 'item', image = 'handcuffs.png', unique = false, useable = true, shouldClose = true, description = 'Comes in handy when people misbehave. Maybe it can be used for something else?' },
|
||||
police_stormram = { name = 'police_stormram', label = 'Stormram', weight = 18000, type = 'item', image = 'police_stormram.png', unique = false, useable = true, shouldClose = true, description = 'A nice tool to break into doors' },
|
||||
empty_evidence_bag = { name = 'empty_evidence_bag', label = 'Empty Evidence Bag', weight = 0, type = 'item', image = 'evidence.png', unique = false, useable = false, shouldClose = false, description = 'Used a lot to keep DNA from blood, bullet shells and more' },
|
||||
filled_evidence_bag = { name = 'filled_evidence_bag', label = 'Evidence Bag', weight = 200, type = 'item', image = 'evidence.png', unique = true, useable = false, shouldClose = false, description = 'A filled evidence bag to see who committed the crime >:(' },
|
||||
|
||||
-- Firework Tools
|
||||
firework1 = { name = 'firework1', label = '2Brothers', weight = 1000, type = 'item', image = 'firework1.png', unique = false, useable = true, shouldClose = true, description = 'Fireworks' },
|
||||
firework2 = { name = 'firework2', label = 'Poppelers', weight = 1000, type = 'item', image = 'firework2.png', unique = false, useable = true, shouldClose = true, description = 'Fireworks' },
|
||||
firework3 = { name = 'firework3', label = 'WipeOut', weight = 1000, type = 'item', image = 'firework3.png', unique = false, useable = true, shouldClose = true, description = 'Fireworks' },
|
||||
firework4 = { name = 'firework4', label = 'Weeping Willow', weight = 1000, type = 'item', image = 'firework4.png', unique = false, useable = true, shouldClose = true, description = 'Fireworks' },
|
||||
|
||||
-- Sea Tools
|
||||
dendrogyra_coral = { name = 'dendrogyra_coral', label = 'Dendrogyra', weight = 1000, type = 'item', image = 'dendrogyra_coral.png', unique = false, useable = false, shouldClose = true, description = 'Its also known as pillar coral' },
|
||||
antipatharia_coral = { name = 'antipatharia_coral', label = 'Antipatharia', weight = 1000, type = 'item', image = 'antipatharia_coral.png', unique = false, useable = false, shouldClose = true, description = 'Its also known as black corals or thorn corals' },
|
||||
diving_gear = { name = 'diving_gear', label = 'Diving Gear', weight = 30000, type = 'item', image = 'diving_gear.png', unique = true, useable = true, shouldClose = true, description = 'An oxygen tank and a rebreather' },
|
||||
diving_fill = { name = 'diving_fill', label = 'Diving Tube', weight = 3000, type = 'item', image = 'diving_tube.png', unique = true, useable = true, shouldClose = true, description = 'An oxygen tube and a rebreather' },
|
||||
|
||||
-- Other Tools
|
||||
casinochips = { name = 'casinochips', label = 'Casino Chips', weight = 0, type = 'item', image = 'casinochips.png', unique = false, useable = false, shouldClose = false, description = 'Chips For Casino Gambling' },
|
||||
stickynote = { name = 'stickynote', label = 'Sticky note', weight = 0, type = 'item', image = 'stickynote.png', unique = true, useable = false, shouldClose = false, description = 'Sometimes handy to remember something :)' },
|
||||
moneybag = { name = 'moneybag', label = 'Money Bag', weight = 0, type = 'item', image = 'moneybag.png', unique = true, useable = true, shouldClose = true, description = 'A bag with cash' },
|
||||
parachute = { name = 'parachute', label = 'Parachute', weight = 30000, type = 'item', image = 'parachute.png', unique = true, useable = true, shouldClose = true, description = 'The sky is the limit! Woohoo!' },
|
||||
binoculars = { name = 'binoculars', label = 'Binoculars', weight = 600, type = 'item', image = 'binoculars.png', unique = false, useable = true, shouldClose = true, description = 'Sneaky Breaky...' },
|
||||
lighter = { name = 'lighter', label = 'Lighter', weight = 0, type = 'item', image = 'lighter.png', unique = false, useable = false, shouldClose = true, description = 'On new years eve a nice fire to stand next to' },
|
||||
certificate = { name = 'certificate', label = 'Certificate', weight = 0, type = 'item', image = 'certificate.png', unique = false, useable = false, shouldClose = true, description = 'Certificate that proves you own certain stuff' },
|
||||
markedbills = { name = 'markedbills', label = 'Marked Money', weight = 1000, type = 'item', image = 'markedbills.png', unique = true, useable = false, shouldClose = true, description = 'Money?' },
|
||||
labkey = { name = 'labkey', label = 'Key', weight = 500, type = 'item', image = 'labkey.png', unique = true, useable = true, shouldClose = true, description = 'Key for a lock...?' },
|
||||
printerdocument = { name = 'printerdocument', label = 'Document', weight = 500, type = 'item', image = 'printerdocument.png', unique = true, useable = true, shouldClose = true, description = 'A nice document' },
|
||||
newscam = { name = 'newscam', label = 'News Camera', weight = 100, type = 'item', image = 'newscam.png', unique = true, useable = true, shouldClose = true, description = 'A camera for the news' },
|
||||
newsmic = { name = 'newsmic', label = 'News Microphone', weight = 100, type = 'item', image = 'newsmic.png', unique = true, useable = true, shouldClose = true, description = 'A microphone for the news' },
|
||||
newsbmic = { name = 'newsbmic', label = 'Boom Microphone', weight = 100, type = 'item', image = 'newsbmic.png', unique = true, useable = true, shouldClose = true, description = 'A Useable BoomMic' },
|
||||
|
||||
-- Crafting table's
|
||||
item_bench = {name = "item_bench", label = "Workbench", weight = 15000, type = "item", image = "workbench.png", unique = true, useable = true, shouldClose = false, combinable = nil, description = "A workbench to craft items."},
|
||||
attachment_bench = {name = "attachment_bench", label = "Attachment Workbench", weight = 15000, type = "item", image = "attworkbench.png", unique = true, useable = true, shouldClose = false, combinable = nil, description = "A workbench for crafting attachments."},
|
||||
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
QBShared = QBShared or {}
|
||||
QBShared.ForceJobDefaultDutyAtLogin = true -- true: Force duty state to jobdefaultDuty | false: set duty state from database last saved
|
||||
QBShared.Jobs = {
|
||||
unemployed = { label = 'Civilian', defaultDuty = true, offDutyPay = false, grades = { ['0'] = { name = 'Freelancer', payment = 10 } } },
|
||||
bus = { label = 'Bus', defaultDuty = true, offDutyPay = false, grades = { ['0'] = { name = 'Driver', payment = 50 } } },
|
||||
judge = { label = 'Honorary', defaultDuty = true, offDutyPay = false, grades = { ['0'] = { name = 'Judge', payment = 100 } } },
|
||||
lawyer = { label = 'Law Firm', defaultDuty = true, offDutyPay = false, grades = { ['0'] = { name = 'Associate', payment = 50 } } },
|
||||
reporter = { label = 'Reporter', defaultDuty = true, offDutyPay = false, grades = { ['0'] = { name = 'Journalist', payment = 50 } } },
|
||||
trucker = { label = 'Trucker', defaultDuty = true, offDutyPay = false, grades = { ['0'] = { name = 'Driver', payment = 50 } } },
|
||||
tow = { label = 'Towing', defaultDuty = true, offDutyPay = false, grades = { ['0'] = { name = 'Driver', payment = 50 } } },
|
||||
garbage = { label = 'Garbage', defaultDuty = true, offDutyPay = false, grades = { ['0'] = { name = 'Collector', payment = 50 } } },
|
||||
vineyard = { label = 'Vineyard', defaultDuty = true, offDutyPay = false, grades = { ['0'] = { name = 'Picker', payment = 50 } } },
|
||||
hotdog = { label = 'Hotdog', defaultDuty = true, offDutyPay = false, grades = { ['0'] = { name = 'Sales', payment = 50 } } },
|
||||
|
||||
police = {
|
||||
label = 'Law Enforcement',
|
||||
type = 'leo',
|
||||
defaultDuty = true,
|
||||
offDutyPay = false,
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit', payment = 50 },
|
||||
['1'] = { name = 'Officer', payment = 75 },
|
||||
['2'] = { name = 'Sergeant', payment = 100 },
|
||||
['3'] = { name = 'Lieutenant', payment = 125 },
|
||||
['4'] = { name = 'Chief', isboss = true, payment = 150 },
|
||||
},
|
||||
},
|
||||
ambulance = {
|
||||
label = 'EMS',
|
||||
type = 'ems',
|
||||
defaultDuty = true,
|
||||
offDutyPay = false,
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit', payment = 50 },
|
||||
['1'] = { name = 'Paramedic', payment = 75 },
|
||||
['2'] = { name = 'Doctor', payment = 100 },
|
||||
['3'] = { name = 'Surgeon', payment = 125 },
|
||||
['4'] = { name = 'Chief', isboss = true, payment = 150 },
|
||||
},
|
||||
},
|
||||
realestate = {
|
||||
label = 'Real Estate',
|
||||
defaultDuty = true,
|
||||
offDutyPay = false,
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit', payment = 50 },
|
||||
['1'] = { name = 'House Sales', payment = 75 },
|
||||
['2'] = { name = 'Business Sales', payment = 100 },
|
||||
['3'] = { name = 'Broker', payment = 125 },
|
||||
['4'] = { name = 'Manager', isboss = true, payment = 150 },
|
||||
},
|
||||
},
|
||||
taxi = {
|
||||
label = 'Taxi',
|
||||
defaultDuty = true,
|
||||
offDutyPay = false,
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit', payment = 50 },
|
||||
['1'] = { name = 'Driver', payment = 75 },
|
||||
['2'] = { name = 'Event Driver', payment = 100 },
|
||||
['3'] = { name = 'Sales', payment = 125 },
|
||||
['4'] = { name = 'Manager', isboss = true, payment = 150 },
|
||||
},
|
||||
},
|
||||
cardealer = {
|
||||
label = 'Vehicle Dealer',
|
||||
defaultDuty = true,
|
||||
offDutyPay = false,
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit', payment = 50 },
|
||||
['1'] = { name = 'Showroom Sales', payment = 75 },
|
||||
['2'] = { name = 'Business Sales', payment = 100 },
|
||||
['3'] = { name = 'Finance', payment = 125 },
|
||||
['4'] = { name = 'Manager', isboss = true, payment = 150 },
|
||||
},
|
||||
},
|
||||
mechanic = {
|
||||
label = 'LS Customs',
|
||||
type = 'mechanic',
|
||||
defaultDuty = true,
|
||||
offDutyPay = false,
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit', payment = 50 },
|
||||
['1'] = { name = 'Novice', payment = 75 },
|
||||
['2'] = { name = 'Experienced', payment = 100 },
|
||||
['3'] = { name = 'Advanced', payment = 125 },
|
||||
['4'] = { name = 'Manager', isboss = true, payment = 150 },
|
||||
},
|
||||
},
|
||||
mechanic2 = {
|
||||
label = 'LS Customs',
|
||||
type = 'mechanic',
|
||||
defaultDuty = true,
|
||||
offDutyPay = false,
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit', payment = 50 },
|
||||
['1'] = { name = 'Novice', payment = 75 },
|
||||
['2'] = { name = 'Experienced', payment = 100 },
|
||||
['3'] = { name = 'Advanced', payment = 125 },
|
||||
['4'] = { name = 'Manager', isboss = true, payment = 150 },
|
||||
},
|
||||
},
|
||||
mechanic3 = {
|
||||
label = 'LS Customs',
|
||||
type = 'mechanic',
|
||||
defaultDuty = true,
|
||||
offDutyPay = false,
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit', payment = 50 },
|
||||
['1'] = { name = 'Novice', payment = 75 },
|
||||
['2'] = { name = 'Experienced', payment = 100 },
|
||||
['3'] = { name = 'Advanced', payment = 125 },
|
||||
['4'] = { name = 'Manager', isboss = true, payment = 150 },
|
||||
},
|
||||
},
|
||||
beeker = {
|
||||
label = 'Beeker\'s Garage',
|
||||
type = 'mechanic',
|
||||
defaultDuty = true,
|
||||
offDutyPay = false,
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit', payment = 50 },
|
||||
['1'] = { name = 'Novice', payment = 75 },
|
||||
['2'] = { name = 'Experienced', payment = 100 },
|
||||
['3'] = { name = 'Advanced', payment = 125 },
|
||||
['4'] = { name = 'Manager', isboss = true, payment = 150 },
|
||||
},
|
||||
},
|
||||
bennys = {
|
||||
label = 'Benny\'s Original Motor Works',
|
||||
type = 'mechanic',
|
||||
defaultDuty = true,
|
||||
offDutyPay = false,
|
||||
grades = {
|
||||
['0'] = { name = 'Recruit', payment = 50 },
|
||||
['1'] = { name = 'Novice', payment = 75 },
|
||||
['2'] = { name = 'Experienced', payment = 100 },
|
||||
['3'] = { name = 'Advanced', payment = 125 },
|
||||
['4'] = { name = 'Manager', isboss = true, payment = 150 },
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
{
|
||||
"General": {
|
||||
"cash": {
|
||||
"amount": 500,
|
||||
"allowminus": false,
|
||||
"minuslimit": -5000
|
||||
},
|
||||
"bank": {
|
||||
"amount": 5000,
|
||||
"allowminus": false,
|
||||
"minuslimit": -50000
|
||||
},
|
||||
"crypto": {
|
||||
"amount": 0,
|
||||
"allowminus": false,
|
||||
"minuslimit": -5000
|
||||
},
|
||||
"DefaultSpawn": { "x": -1035.71, "y": -2731.87, "z": 12.86, "h": 0.0 },
|
||||
"UpdateInterval": 5,
|
||||
"StatusInterval": 5000,
|
||||
"ForceJobDefaultDutyAtLogin": true,
|
||||
"HungerRate": 4.2,
|
||||
"ThirstRate": 3.8,
|
||||
"PayCheckTimeOut": 10,
|
||||
"PayCheckSociety": false,
|
||||
"Bloodtypes": ["A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"],
|
||||
"items": [
|
||||
{ "item": "driver_license", "amount": 1 },
|
||||
{ "item": "id_card", "amount": 1 },
|
||||
{ "item": "phone", "amount": 1 }
|
||||
]
|
||||
},
|
||||
"Server": {
|
||||
"Closed": false,
|
||||
"ClosedReason": "Server Closed",
|
||||
"Uptime": 0,
|
||||
"Whitelist": false,
|
||||
"WhitelistPermission": "admin",
|
||||
"PVP": true,
|
||||
"Discord": "",
|
||||
"CheckDuplicateLicense": true,
|
||||
"Permissions": ["god", "admin", "mod"]
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
{
|
||||
"none": {
|
||||
"label": "No Gang",
|
||||
"grades": [
|
||||
{
|
||||
"name": "Unaffiliated"
|
||||
}
|
||||
]
|
||||
},
|
||||
"lostmc": {
|
||||
"label": "The Lost MC",
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit"
|
||||
},
|
||||
{
|
||||
"name": "Enforcer"
|
||||
},
|
||||
{
|
||||
"name": "Shot Caller"
|
||||
},
|
||||
{
|
||||
"name": "Boss",
|
||||
"isboss": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"ballas": {
|
||||
"label": "Ballas",
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit"
|
||||
},
|
||||
{
|
||||
"name": "Enforcer"
|
||||
},
|
||||
{
|
||||
"name": "Shot Caller"
|
||||
},
|
||||
{
|
||||
"name": "Boss",
|
||||
"isboss": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"vagos": {
|
||||
"label": "Vagos",
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit"
|
||||
},
|
||||
{
|
||||
"name": "Enforcer"
|
||||
},
|
||||
{
|
||||
"name": "Shot Caller"
|
||||
},
|
||||
{
|
||||
"name": "Boss",
|
||||
"isboss": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"cartel": {
|
||||
"label": "Cartel",
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit"
|
||||
},
|
||||
{
|
||||
"name": "Enforcer"
|
||||
},
|
||||
{
|
||||
"name": "Shot Caller"
|
||||
},
|
||||
{
|
||||
"name": "Boss",
|
||||
"isboss": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"families": {
|
||||
"label": "Families",
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit"
|
||||
},
|
||||
{
|
||||
"name": "Enforcer"
|
||||
},
|
||||
{
|
||||
"name": "Shot Caller"
|
||||
},
|
||||
{
|
||||
"name": "Boss",
|
||||
"isboss": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"triads": {
|
||||
"label": "Triads",
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit"
|
||||
},
|
||||
{
|
||||
"name": "Enforcer"
|
||||
},
|
||||
{
|
||||
"name": "Shot Caller"
|
||||
},
|
||||
{
|
||||
"name": "Boss",
|
||||
"isboss": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,399 +0,0 @@
|
||||
{
|
||||
"unemployed": {
|
||||
"label": "Civilian",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Freelancer",
|
||||
"payment": 10
|
||||
}
|
||||
]
|
||||
},
|
||||
"bus": {
|
||||
"label": "Bus",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Driver",
|
||||
"payment": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
"judge": {
|
||||
"label": "Honorary",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Judge",
|
||||
"payment": 100
|
||||
}
|
||||
]
|
||||
},
|
||||
"lawyer": {
|
||||
"label": "Law Firm",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Associate",
|
||||
"payment": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
"reporter": {
|
||||
"label": "Reporter",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Journalist",
|
||||
"payment": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
"trucker": {
|
||||
"label": "Trucker",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Driver",
|
||||
"payment": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
"tow": {
|
||||
"label": "Towing",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Driver",
|
||||
"payment": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
"garbage": {
|
||||
"label": "Garbage",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Collector",
|
||||
"payment": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
"vineyard": {
|
||||
"label": "Vineyard",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Picker",
|
||||
"payment": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
"hotdog": {
|
||||
"label": "Hotdog",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Sales",
|
||||
"payment": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
"police": {
|
||||
"label": "Law Enforcement",
|
||||
"type": "leo",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit",
|
||||
"payment": 50
|
||||
},
|
||||
{
|
||||
"name": "Officer",
|
||||
"payment": 75
|
||||
},
|
||||
{
|
||||
"name": "Sergeant",
|
||||
"payment": 100
|
||||
},
|
||||
{
|
||||
"name": "Lieutenant",
|
||||
"payment": 125
|
||||
},
|
||||
{
|
||||
"name": "Chief",
|
||||
"isboss": true,
|
||||
"payment": 150
|
||||
}
|
||||
]
|
||||
},
|
||||
"ambulance": {
|
||||
"label": "EMS",
|
||||
"type": "ems",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit",
|
||||
"payment": 50
|
||||
},
|
||||
{
|
||||
"name": "Paramedic",
|
||||
"payment": 75
|
||||
},
|
||||
{
|
||||
"name": "Doctor",
|
||||
"payment": 100
|
||||
},
|
||||
{
|
||||
"name": "Surgeon",
|
||||
"payment": 125
|
||||
},
|
||||
{
|
||||
"name": "Chief",
|
||||
"isboss": true,
|
||||
"payment": 150
|
||||
}
|
||||
]
|
||||
},
|
||||
"realestate": {
|
||||
"label": "Real Estate",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit",
|
||||
"payment": 50
|
||||
},
|
||||
{
|
||||
"name": "House Sales",
|
||||
"payment": 75
|
||||
},
|
||||
{
|
||||
"name": "Business Sales",
|
||||
"payment": 100
|
||||
},
|
||||
{
|
||||
"name": "Broker",
|
||||
"payment": 125
|
||||
},
|
||||
{
|
||||
"name": "Manager",
|
||||
"isboss": true,
|
||||
"payment": 150
|
||||
}
|
||||
]
|
||||
},
|
||||
"taxi": {
|
||||
"label": "Taxi",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit",
|
||||
"payment": 50
|
||||
},
|
||||
{
|
||||
"name": "Driver",
|
||||
"payment": 75
|
||||
},
|
||||
{
|
||||
"name": "Event Driver",
|
||||
"payment": 100
|
||||
},
|
||||
{
|
||||
"name": "Sales",
|
||||
"payment": 125
|
||||
},
|
||||
{
|
||||
"name": "Manager",
|
||||
"isboss": true,
|
||||
"payment": 150
|
||||
}
|
||||
]
|
||||
},
|
||||
"cardealer": {
|
||||
"label": "Vehicle Dealer",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit",
|
||||
"payment": 50
|
||||
},
|
||||
{
|
||||
"name": "Showroom Sales",
|
||||
"payment": 75
|
||||
},
|
||||
{
|
||||
"name": "Business Sales",
|
||||
"payment": 100
|
||||
},
|
||||
{
|
||||
"name": "Finance",
|
||||
"payment": 125
|
||||
},
|
||||
{
|
||||
"name": "Manager",
|
||||
"isboss": true,
|
||||
"payment": 150
|
||||
}
|
||||
]
|
||||
},
|
||||
"mechanic": {
|
||||
"label": "LS Customs",
|
||||
"type": "mechanic",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit",
|
||||
"payment": 50
|
||||
},
|
||||
{
|
||||
"name": "Novice",
|
||||
"payment": 75
|
||||
},
|
||||
{
|
||||
"name": "Experienced",
|
||||
"payment": 100
|
||||
},
|
||||
{
|
||||
"name": "Advanced",
|
||||
"payment": 125
|
||||
},
|
||||
{
|
||||
"name": "Manager",
|
||||
"isboss": true,
|
||||
"payment": 150
|
||||
}
|
||||
]
|
||||
},
|
||||
"mechanic2": {
|
||||
"label": "LS Customs",
|
||||
"type": "mechanic",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit",
|
||||
"payment": 50
|
||||
},
|
||||
{
|
||||
"name": "Novice",
|
||||
"payment": 75
|
||||
},
|
||||
{
|
||||
"name": "Experienced",
|
||||
"payment": 100
|
||||
},
|
||||
{
|
||||
"name": "Advanced",
|
||||
"payment": 125
|
||||
},
|
||||
{
|
||||
"name": "Manager",
|
||||
"isboss": true,
|
||||
"payment": 150
|
||||
}
|
||||
]
|
||||
},
|
||||
"mechanic3": {
|
||||
"label": "LS Customs",
|
||||
"type": "mechanic",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit",
|
||||
"payment": 50
|
||||
},
|
||||
{
|
||||
"name": "Novice",
|
||||
"payment": 75
|
||||
},
|
||||
{
|
||||
"name": "Experienced",
|
||||
"payment": 100
|
||||
},
|
||||
{
|
||||
"name": "Advanced",
|
||||
"payment": 125
|
||||
},
|
||||
{
|
||||
"name": "Manager",
|
||||
"isboss": true,
|
||||
"payment": 150
|
||||
}
|
||||
]
|
||||
},
|
||||
"beeker": {
|
||||
"label": "Beeker's Garage",
|
||||
"type": "mechanic",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit",
|
||||
"payment": 50
|
||||
},
|
||||
{
|
||||
"name": "Novice",
|
||||
"payment": 75
|
||||
},
|
||||
{
|
||||
"name": "Experienced",
|
||||
"payment": 100
|
||||
},
|
||||
{
|
||||
"name": "Advanced",
|
||||
"payment": 125
|
||||
},
|
||||
{
|
||||
"name": "Manager",
|
||||
"isboss": true,
|
||||
"payment": 150
|
||||
}
|
||||
]
|
||||
},
|
||||
"bennys": {
|
||||
"label": "Benny's Original Motor Works",
|
||||
"type": "mechanic",
|
||||
"defaultDuty": true,
|
||||
"offDutyPay": false,
|
||||
"grades": [
|
||||
{
|
||||
"name": "Recruit",
|
||||
"payment": 50
|
||||
},
|
||||
{
|
||||
"name": "Novice",
|
||||
"payment": 75
|
||||
},
|
||||
{
|
||||
"name": "Experienced",
|
||||
"payment": 100
|
||||
},
|
||||
{
|
||||
"name": "Advanced",
|
||||
"payment": 125
|
||||
},
|
||||
{
|
||||
"name": "Manager",
|
||||
"isboss": true,
|
||||
"payment": 150
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
{
|
||||
"citizenid": null,
|
||||
"cid": 1,
|
||||
"money": {
|
||||
"cash": 500,
|
||||
"bank": 5000,
|
||||
"crypto": 0
|
||||
},
|
||||
"optin": true,
|
||||
"charinfo": {
|
||||
"firstname": "Firstname",
|
||||
"lastname": "Lastname",
|
||||
"birthdate": "00-00-0000",
|
||||
"gender": 0,
|
||||
"nationality": "USA",
|
||||
"phone": null,
|
||||
"account": null
|
||||
},
|
||||
"job": {
|
||||
"name": "unemployed",
|
||||
"label": "Civilian",
|
||||
"payment": 10,
|
||||
"type": "none",
|
||||
"onduty": false,
|
||||
"isboss": false,
|
||||
"grade": {
|
||||
"name": "Freelancer",
|
||||
"level": 1,
|
||||
"payment": 10,
|
||||
"isboss": false
|
||||
}
|
||||
},
|
||||
"gang": {
|
||||
"name": "none",
|
||||
"label": "No Gang Affiliation",
|
||||
"isboss": false,
|
||||
"grade": {
|
||||
"name": "none",
|
||||
"level": 1,
|
||||
"isboss": false
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"hunger": 100,
|
||||
"thirst": 100,
|
||||
"stress": 0,
|
||||
"isdead": false,
|
||||
"inlaststand": false,
|
||||
"armor": 0,
|
||||
"ishandcuffed": false,
|
||||
"tracker": false,
|
||||
"injail": 0,
|
||||
"jailitems": [],
|
||||
"status": {},
|
||||
"phone": {},
|
||||
"rep": {},
|
||||
"currentapartment": null,
|
||||
"callsign": "NO CALLSIGN",
|
||||
"bloodtype": null,
|
||||
"fingerprint": null,
|
||||
"walletid": null,
|
||||
"criminalrecord": {
|
||||
"hasRecord": false,
|
||||
"date": null
|
||||
},
|
||||
"licences": {
|
||||
"driver": true,
|
||||
"business": false,
|
||||
"weapon": false
|
||||
},
|
||||
"inside": {
|
||||
"house": null,
|
||||
"apartment": {
|
||||
"apartmentType": null,
|
||||
"apartmentId": null
|
||||
}
|
||||
},
|
||||
"phonedata": {
|
||||
"SerialNumber": null,
|
||||
"InstalledApps": []
|
||||
}
|
||||
},
|
||||
"position": {
|
||||
"x": 1000,
|
||||
"y": 1000,
|
||||
"z": 1000,
|
||||
"h": 1000
|
||||
},
|
||||
"items": []
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,884 +0,0 @@
|
||||
[
|
||||
{
|
||||
"name": "weapon_unarmed",
|
||||
"label": "Fists",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_dagger",
|
||||
"label": "Dagger",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Knifed / Stabbed / Eviscerated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_bat",
|
||||
"label": "Bat",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_bottle",
|
||||
"label": "Broken Bottle",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Knifed / Stabbed / Eviscerated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_crowbar",
|
||||
"label": "Crowbar",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_flashlight",
|
||||
"label": "Flashlight",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_golfclub",
|
||||
"label": "Golfclub",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_hammer",
|
||||
"label": "Hammer",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_hatchet",
|
||||
"label": "Hatchet",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Knifed / Stabbed / Eviscerated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_knuckle",
|
||||
"label": "Knuckle",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_knife",
|
||||
"label": "Knife",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Knifed / Stabbed / Eviscerated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_machete",
|
||||
"label": "Machete",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Knifed / Stabbed / Eviscerated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_switchblade",
|
||||
"label": "Switchblade",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Knifed / Stabbed / Eviscerated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_nightstick",
|
||||
"label": "Nightstick",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_wrench",
|
||||
"label": "Wrench",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_battleaxe",
|
||||
"label": "Battle Axe",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Knifed / Stabbed / Eviscerated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_poolcue",
|
||||
"label": "Poolcue",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_briefcase",
|
||||
"label": "Briefcase",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_briefcase_02",
|
||||
"label": "Briefcase",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_garbagebag",
|
||||
"label": "Garbage Bag",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_handcuffs",
|
||||
"label": "Handcuffs",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_bread",
|
||||
"label": "Baquette",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee killed / Whacked / Executed / Beat down / Murdered / Battered"
|
||||
},
|
||||
{
|
||||
"name": "weapon_stone_hatchet",
|
||||
"label": "Stone Hatchet",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Knifed / Stabbed / Eviscerated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_candycane",
|
||||
"label": "Candy Cane",
|
||||
"weapontype": "Melee",
|
||||
"ammotype": null,
|
||||
"damagereason": "Melee Killed / Whacked / Executed / Beat down / Musrdered / Battered / Candy Caned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_pistol",
|
||||
"label": "Pistol",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_pistol_mk2",
|
||||
"label": "Pistol Mk2",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_combatpistol",
|
||||
"label": "Combat Pistol",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_appistol",
|
||||
"label": "AP Pistol",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_stungun",
|
||||
"label": "Taser",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_STUNGUN",
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_pistol50",
|
||||
"label": "Pistol .50 Cal",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_snspistol",
|
||||
"label": "SNS Pistol",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_snspistol_mk2",
|
||||
"label": "SNS Pistol MK2",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_heavypistol",
|
||||
"label": "Heavy Pistol",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_vintagepistol",
|
||||
"label": "Vintage Pistol",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_flaregun",
|
||||
"label": "Flare Gun",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_FLARE",
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_marksmanpistol",
|
||||
"label": "Marksman Pistol",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_revolver",
|
||||
"label": "Revolver",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_revolver_mk2",
|
||||
"label": "Revolver MK2",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_doubleaction",
|
||||
"label": "Double Action Revolver",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_raypistol",
|
||||
"label": "Ray Pistol",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_ceramicpistol",
|
||||
"label": "Ceramic Pistol",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_navyrevolver",
|
||||
"label": "Navy Revolver",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_gadgetpistol",
|
||||
"label": "Gadget Pistol",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_stungun_mp",
|
||||
"label": "Taser",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_STUNGUN",
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_pistolxm3",
|
||||
"label": "Pistol XM3",
|
||||
"weapontype": "Pistol",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Pistoled / Blasted / Plaugged / Bust a cap in"
|
||||
},
|
||||
{
|
||||
"name": "weapon_microsmg",
|
||||
"label": "Micro SMG",
|
||||
"weapontype": "Submachine Gun",
|
||||
"ammotype": "AMMO_SMG",
|
||||
"damagereason": "Riddled / Drilled / Finished / Submachine Gunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_smg",
|
||||
"label": "SMG",
|
||||
"weapontype": "Submachine Gun",
|
||||
"ammotype": "AMMO_SMG",
|
||||
"damagereason": "Riddled / Drilled / Finished / Submachine Gunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_smg_mk2",
|
||||
"label": "SMG MK2",
|
||||
"weapontype": "Submachine Gun",
|
||||
"ammotype": "AMMO_SMG",
|
||||
"damagereason": "Riddled / Drilled / Finished / Submachine Gunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_assaultsmg",
|
||||
"label": "Assault SMG",
|
||||
"weapontype": "Submachine Gun",
|
||||
"ammotype": "AMMO_SMG",
|
||||
"damagereason": "Riddled / Drilled / Finished / Submachine Gunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_combatpdw",
|
||||
"label": "Combat PDW",
|
||||
"weapontype": "Submachine Gun",
|
||||
"ammotype": "AMMO_SMG",
|
||||
"damagereason": "Riddled / Drilled / Finished / Submachine Gunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_machinepistol",
|
||||
"label": "Tec-9",
|
||||
"weapontype": "Submachine Gun",
|
||||
"ammotype": "AMMO_PISTOL",
|
||||
"damagereason": "Riddled / Drilled / Finished / Submachine Gunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_minismg",
|
||||
"label": "Mini SMG",
|
||||
"weapontype": "Submachine Gun",
|
||||
"ammotype": "AMMO_SMG",
|
||||
"damagereason": "Riddled / Drilled / Finished / Submachine Gunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_raycarbine",
|
||||
"label": "Raycarbine",
|
||||
"weapontype": "Submachine Gun",
|
||||
"ammotype": "AMMO_SMG",
|
||||
"damagereason": "Riddled / Drilled / Finished / Submachine Gunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_pumpshotgun",
|
||||
"label": "Pump Shotgun",
|
||||
"weapontype": "Shotgun",
|
||||
"ammotype": "AMMO_SHOTGUN",
|
||||
"damagereason": "Devastated / Pulverized / Shotgunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_pumpshotgun_mk2",
|
||||
"label": "Pump Shotgun MK2",
|
||||
"weapontype": "Shotgun",
|
||||
"ammotype": "AMMO_SHOTGUN",
|
||||
"damagereason": "Devastated / Pulverized / Shotgunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_sawnoffshotgun",
|
||||
"label": "Sawn-off Shotgun",
|
||||
"weapontype": "Shotgun",
|
||||
"ammotype": "AMMO_SHOTGUN",
|
||||
"damagereason": "Devastated / Pulverized / Shotgunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_assaultshotgun",
|
||||
"label": "Assault Shotgun",
|
||||
"weapontype": "Shotgun",
|
||||
"ammotype": "AMMO_SHOTGUN",
|
||||
"damagereason": "Devastated / Pulverized / Shotgunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_bullpupshotgun",
|
||||
"label": "Bullpup Shotgun",
|
||||
"weapontype": "Shotgun",
|
||||
"ammotype": "AMMO_SHOTGUN",
|
||||
"damagereason": "Devastated / Pulverized / Shotgunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_musket",
|
||||
"label": "Musket",
|
||||
"weapontype": "Shotgun",
|
||||
"ammotype": "AMMO_SHOTGUN",
|
||||
"damagereason": "Devastated / Pulverized / Shotgunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_heavyshotgun",
|
||||
"label": "Heavy Shotgun",
|
||||
"weapontype": "Shotgun",
|
||||
"ammotype": "AMMO_SHOTGUN",
|
||||
"damagereason": "Devastated / Pulverized / Shotgunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_dbshotgun",
|
||||
"label": "Double-barrel Shotgun",
|
||||
"weapontype": "Shotgun",
|
||||
"ammotype": "AMMO_SHOTGUN",
|
||||
"damagereason": "Devastated / Pulverized / Shotgunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_autoshotgun",
|
||||
"label": "Auto Shotgun",
|
||||
"weapontype": "Shotgun",
|
||||
"ammotype": "AMMO_SHOTGUN",
|
||||
"damagereason": "Devastated / Pulverized / Shotgunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_combatshotgun",
|
||||
"label": "Combat Shotgun",
|
||||
"weapontype": "Shotgun",
|
||||
"ammotype": "AMMO_SHOTGUN",
|
||||
"damagereason": "Devastated / Pulverized / Shotgunned"
|
||||
},
|
||||
{
|
||||
"name": "weapon_assaultrifle",
|
||||
"label": "Assault Rifle",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_assaultrifle_mk2",
|
||||
"label": "Assault Rifle MK2",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_carbinerifle",
|
||||
"label": "Carbine Rifle",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_carbinerifle_mk2",
|
||||
"label": "Carbine Rifle MK2",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_advancedrifle",
|
||||
"label": "Advanced Rifle",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_specialcarbine",
|
||||
"label": "Special Carbine",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_specialcarbine_mk2",
|
||||
"label": "Specialcarbine MK2",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_bullpuprifle",
|
||||
"label": "Bullpup Rifle",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_bullpuprifle_mk2",
|
||||
"label": "Bull Puprifle MK2",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_compactrifle",
|
||||
"label": "Compact Rifle",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_militaryrifle",
|
||||
"label": "Military Rifle",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_heavyrifle",
|
||||
"label": "Heavy Rifle",
|
||||
"weapontype": "Assault Rifle",
|
||||
"ammotype": "AMMO_RIFLE",
|
||||
"damagereason": "Ended / Rifled / Shot down / Floored"
|
||||
},
|
||||
{
|
||||
"name": "weapon_mg",
|
||||
"label": "Machinegun",
|
||||
"weapontype": "Light Machine Gun",
|
||||
"ammotype": "AMMO_MG",
|
||||
"damagereason": "Machine gunned / Sprayed / Ruined"
|
||||
},
|
||||
{
|
||||
"name": "weapon_combatmg",
|
||||
"label": "Combat MG",
|
||||
"weapontype": "Light Machine Gun",
|
||||
"ammotype": "AMMO_MG",
|
||||
"damagereason": "Machine gunned / Sprayed / Ruined"
|
||||
},
|
||||
{
|
||||
"name": "weapon_combatmg_mk2",
|
||||
"label": "Combat MG MK2",
|
||||
"weapontype": "Light Machine Gun",
|
||||
"ammotype": "AMMO_MG",
|
||||
"damagereason": "Machine gunned / Sprayed / Ruined"
|
||||
},
|
||||
{
|
||||
"name": "weapon_gusenberg",
|
||||
"label": "Thompson SMG",
|
||||
"weapontype": "Light Machine Gun",
|
||||
"ammotype": "AMMO_MG",
|
||||
"damagereason": "Machine gunned / Sprayed / Ruined"
|
||||
},
|
||||
{
|
||||
"name": "weapon_sniperrifle",
|
||||
"label": "Sniper Rifle",
|
||||
"weapontype": "Sniper Rifle",
|
||||
"ammotype": "AMMO_SNIPER",
|
||||
"damagereason": "Sniped / Picked off / Scoped"
|
||||
},
|
||||
{
|
||||
"name": "weapon_heavysniper",
|
||||
"label": "Heavy Sniper",
|
||||
"weapontype": "Sniper Rifle",
|
||||
"ammotype": "AMMO_SNIPER",
|
||||
"damagereason": "Sniped / Picked off / Scoped"
|
||||
},
|
||||
{
|
||||
"name": "weapon_heavysniper_mk2",
|
||||
"label": "Heavysniper MK2",
|
||||
"weapontype": "Sniper Rifle",
|
||||
"ammotype": "AMMO_SNIPER",
|
||||
"damagereason": "Sniped / Picked off / Scoped"
|
||||
},
|
||||
{
|
||||
"name": "weapon_marksmanrifle",
|
||||
"label": "Marksman Rifle",
|
||||
"weapontype": "Sniper Rifle",
|
||||
"ammotype": "AMMO_SNIPER",
|
||||
"damagereason": "Sniped / Picked off / Scoped"
|
||||
},
|
||||
{
|
||||
"name": "weapon_marksmanrifle_mk2",
|
||||
"label": "Marksman Rifle MK2",
|
||||
"weapontype": "Sniper Rifle",
|
||||
"ammotype": "AMMO_SNIPER",
|
||||
"damagereason": "Sniped / Picked off / Scoped"
|
||||
},
|
||||
{
|
||||
"name": "weapon_remotesniper",
|
||||
"label": "Remote Sniper",
|
||||
"weapontype": "Sniper Rifle",
|
||||
"ammotype": "AMMO_SNIPER_REMOTE",
|
||||
"damagereason": "Sniped / Picked off / Scoped"
|
||||
},
|
||||
{
|
||||
"name": "weapon_rpg",
|
||||
"label": "RPG",
|
||||
"weapontype": "Heavy Weapons",
|
||||
"ammotype": "AMMO_RPG",
|
||||
"damagereason": "Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_grenadelauncher",
|
||||
"label": "Grenade Launcher",
|
||||
"weapontype": "Heavy Weapons",
|
||||
"ammotype": "AMMO_GRENADELAUNCHER",
|
||||
"damagereason": "Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_grenadelauncher_smoke",
|
||||
"label": "Smoke Grenade Launcher",
|
||||
"weapontype": "Heavy Weapons",
|
||||
"ammotype": "AMMO_GRENADELAUNCHER",
|
||||
"damagereason": "Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_minigun",
|
||||
"label": "Minigun",
|
||||
"weapontype": "Heavy Weapons",
|
||||
"ammotype": "AMMO_MINIGUN",
|
||||
"damagereason": "Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_firework",
|
||||
"label": "Firework Launcher",
|
||||
"weapontype": "Heavy Weapons",
|
||||
"ammotype": null,
|
||||
"damagereason": "Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_railgun",
|
||||
"label": "Railgun",
|
||||
"weapontype": "Heavy Weapons",
|
||||
"ammotype": null,
|
||||
"damagereason": "Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_railgunxm3",
|
||||
"label": "Railgun XM3",
|
||||
"weapontype": "Heavy Weapons",
|
||||
"ammotype": null,
|
||||
"damagereason": "Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_hominglauncher",
|
||||
"label": "Homing Launcher",
|
||||
"weapontype": "Heavy Weapons",
|
||||
"ammotype": "AMMO_STINGER",
|
||||
"damagereason": "Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_compactlauncher",
|
||||
"label": "Compact Launcher",
|
||||
"weapontype": "Heavy Weapons",
|
||||
"ammotype": null,
|
||||
"damagereason": "Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_rayminigun",
|
||||
"label": "Ray Minigun",
|
||||
"weapontype": "Heavy Weapons",
|
||||
"ammotype": "AMMO_MINIGUN",
|
||||
"damagereason": "Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_emplauncher",
|
||||
"label": "EMP Launcher",
|
||||
"weapontype": "Heavy Weapons",
|
||||
"ammotype": "AMMO_EMPLAUNCHER",
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_grenade",
|
||||
"label": "Grenade",
|
||||
"weapontype": "Throwable",
|
||||
"ammotype": null,
|
||||
"damagereason": "Bombed / Exploded / Detonated / Blew up"
|
||||
},
|
||||
{
|
||||
"name": "weapon_bzgas",
|
||||
"label": "BZ Gas",
|
||||
"weapontype": "Throwable",
|
||||
"ammotype": null,
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_molotov",
|
||||
"label": "Molotov",
|
||||
"weapontype": "Throwable",
|
||||
"ammotype": null,
|
||||
"damagereason": "Torched / Flambeed / Barbecued"
|
||||
},
|
||||
{
|
||||
"name": "weapon_stickybomb",
|
||||
"label": "C4",
|
||||
"weapontype": "Throwable",
|
||||
"ammotype": null,
|
||||
"damagereason": "Bombed / Exploded / Detonated / Blew up"
|
||||
},
|
||||
{
|
||||
"name": "weapon_proxmine",
|
||||
"label": "Proxmine Grenade",
|
||||
"weapontype": "Throwable",
|
||||
"ammotype": null,
|
||||
"damagereason": "Bombed / Exploded / Detonated / Blew up"
|
||||
},
|
||||
{
|
||||
"name": "weapon_snowball",
|
||||
"label": "Snowball",
|
||||
"weapontype": "Throwable",
|
||||
"ammotype": null,
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_pipebomb",
|
||||
"label": "Pipe Bomb",
|
||||
"weapontype": "Throwable",
|
||||
"ammotype": null,
|
||||
"damagereason": "Bombed / Exploded / Detonated / Blew up"
|
||||
},
|
||||
{
|
||||
"name": "weapon_ball",
|
||||
"label": "Ball",
|
||||
"weapontype": "Throwable",
|
||||
"ammotype": "AMMO_BALL",
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_smokegrenade",
|
||||
"label": "Smoke Grenade",
|
||||
"weapontype": "Throwable",
|
||||
"ammotype": null,
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_flare",
|
||||
"label": "Flare pistol",
|
||||
"weapontype": "Throwable",
|
||||
"ammotype": "AMMO_FLARE",
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_petrolcan",
|
||||
"label": "Petrol Can",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": "AMMO_PETROLCAN",
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "gadget_parachute",
|
||||
"label": "Parachute",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_fireextinguisher",
|
||||
"label": "Fire Extinguisher",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_hazardcan",
|
||||
"label": "Hazardcan",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": "AMMO_PETROLCAN",
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_fertilizercan",
|
||||
"label": "Fertilizer Can",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": "AMMO_FERTILIZERCAN",
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_barbed_wire",
|
||||
"label": "Barbed Wire",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Prodded"
|
||||
},
|
||||
{
|
||||
"name": "weapon_drowning",
|
||||
"label": "Drowning",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_drowning_in_vehicle",
|
||||
"label": "Drowning in a Vehicle",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_bleeding",
|
||||
"label": "Bleeding",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Bled out"
|
||||
},
|
||||
{
|
||||
"name": "weapon_electric_fence",
|
||||
"label": "Electric Fence",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Fried"
|
||||
},
|
||||
{
|
||||
"name": "weapon_explosion",
|
||||
"label": "Explosion",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated"
|
||||
},
|
||||
{
|
||||
"name": "weapon_fall",
|
||||
"label": "Fall",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Committed suicide"
|
||||
},
|
||||
{
|
||||
"name": "weapon_exhaustion",
|
||||
"label": "Exhaustion",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_hit_by_water_cannon",
|
||||
"label": "Water Cannon",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Died"
|
||||
},
|
||||
{
|
||||
"name": "weapon_rammed_by_car",
|
||||
"label": "Rammed - Vehicle",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Flattened / Ran over / Ran down"
|
||||
},
|
||||
{
|
||||
"name": "weapon_run_over_by_car",
|
||||
"label": "Run Over - Vehicle",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Flattened / Ran over / Ran down"
|
||||
},
|
||||
{
|
||||
"name": "weapon_heli_crash",
|
||||
"label": "Heli Crash",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Helicopter Crash"
|
||||
},
|
||||
{
|
||||
"name": "weapon_fire",
|
||||
"label": "Fire",
|
||||
"weapontype": "Miscellaneous",
|
||||
"ammotype": null,
|
||||
"damagereason": "Torched / Flambeed / Barbecued"
|
||||
},
|
||||
{
|
||||
"name": "weapon_animal",
|
||||
"label": "Animal",
|
||||
"weapontype": "Animals",
|
||||
"ammotype": null,
|
||||
"damagereason": "Mauled"
|
||||
},
|
||||
{
|
||||
"name": "weapon_cougar",
|
||||
"label": "Cougar",
|
||||
"weapontype": "Animals",
|
||||
"ammotype": null,
|
||||
"damagereason": "Mauled"
|
||||
}
|
||||
]
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
--- @class Locale
|
||||
Locale = {}
|
||||
Locale.__index = Locale
|
||||
|
||||
@@ -101,7 +102,7 @@ function Locale:t(key, subs)
|
||||
-- At this point we know whether the phrase does not exist for this key
|
||||
else
|
||||
if self.warnOnMissing then
|
||||
print(('^3Warning: Missing phrase for key: "%s"'):format(key))
|
||||
print(('^3Warning: Missing phrase for key: "%s"^0'):format(key))
|
||||
end
|
||||
if self.fallback then
|
||||
return self.fallback:t(key, subs)
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
QBShared.Locations = {
|
||||
-- Base game MLO interiors
|
||||
aircraft_carrier_int = vector4(3081.0042, -4693.6875, 15.2623, 76.8169),
|
||||
apt_1_int = vector4(-1452.4602, -540.2056, 74.0443, 31.9129),
|
||||
apt_2_int = vector4(-912.7861, -365.2444, 114.2748, 110.0791),
|
||||
apt_3_int = vector4(-603.3033, 58.9509, 98.2002, 81.6158),
|
||||
apt_4_int = vector4(-784.6159, 323.849, 211.9972, 260.1097),
|
||||
apt_5_int = vector4(-31.1088, -595.1442, 80.0309, 238.7146),
|
||||
apt_6_int = vector4(-603.0135, 59.0137, -182.3809, 79.5818),
|
||||
apt_hi_1_int = vector4(-18.3525, -590.9888, 90.1148, 331.3955),
|
||||
apt_hi_2_int = vector4(-1450.2595, -525.3569, 56.929, 29.844),
|
||||
bahama_mamas_int = vector4(-1387.0503, -588.4022, 30.3195, 124.4977),
|
||||
biker_clubhouse_1_int = vector4(1121.1473, -3152.606, -37.0627, 354.0713),
|
||||
biker_clubhouse_2_int = vector4(997.1274, -3157.5261, -38.9071, 239.8958),
|
||||
casino_garage_int = vector4(1380.0403, 178.7124, -48.9942, 351.2701),
|
||||
casino_hotel_floor_5_int = vector4(2508.6404, -262.1918, -39.1218, 183.9682),
|
||||
casino_interior_int = vector4(1089.1294, 207.2294, -48.9997, 320.0139),
|
||||
casino_loading_bay_int = vector4(2519.0271, -279.1287, -64.7228, 273.2338),
|
||||
casino_nightclub_int = vector4(1578.2496, 253.7532, -46.0051, 174.0727),
|
||||
casino_offices_int = vector4(2485.0115, -250.7915, -55.1238, 270.4959),
|
||||
casino_security_int = vector4(2548.1143, -267.3465, -58.723, 192.4636),
|
||||
casino_vault_int = vector4(2506.9446, -238.5225, -70.7371, 268.6321),
|
||||
casino_vault_lobby_int = vector4(2465.6365, -278.9171, -70.6942, 264.7971),
|
||||
cocaine_lockup_int = vector4(1088.6353, -3187.8801, -38.9935, 178.8853),
|
||||
counterfeit_cash_int = vector4(1138.2513, -3198.7056, -39.6657, 66.1039),
|
||||
document_forgery_int = vector4(1173.4496, -3196.7759, -39.008, 77.9179),
|
||||
doomsday_facility_int = vector4(453.0641, 4820.2095, -58.9997, 87.7778),
|
||||
exec_apt_1_int = vector4(-786.7757, 315.4629, 217.6385, 269.4638),
|
||||
exec_apt_2_int = vector4(-773.9349, 342.1293, 196.6862, 87.2747),
|
||||
exec_apt_3_int = vector4(-787.0633, 315.7905, 187.9135, 276.2593),
|
||||
fib_floor_47_int = vector4(136.714, -765.5745, 234.152, 76.3983),
|
||||
fib_floor_49_int = vector4(136.2863, -765.8568, 242.1519, 79.0446),
|
||||
fib_top_floor_int = vector4(156.6616, -759.0523, 258.1518, 83.4114),
|
||||
franklins_house_int = vector4(-14.1716, -1440.7046, 31.1015, 2.7505),
|
||||
house_hi_1_int = vector4(-174.1817, 497.7469, 137.6537, 195.447),
|
||||
house_hi_2_int = vector4(342.0325, 437.7024, 149.3897, 125.2541),
|
||||
house_hi_3_int = vector4(373.5483, 423.4114, 145.9079, 162.7296),
|
||||
house_hi_4_int = vector4(-682.3972, 592.3556, 145.3927, 233.6731),
|
||||
house_hi_5_int = vector4(-758.5825, 619.0045, 144.1539, 118.2023),
|
||||
house_hi_6_int = vector4(-860.154, 690.9542, 152.8608, 192.5502),
|
||||
house_hi_7_int = vector4(117.227, 559.6552, 184.3049, 190.2912),
|
||||
house_low_1_int = vector4(266.0239, -1007.0026, -100.9048, 357.9751),
|
||||
house_mid_1_int = vector4(346.855, -1012.7548, -99.1963, 355.3892),
|
||||
iaa_facility_1_int = vector4(2154.9517, 2921.0366, -61.9025, 96.9736),
|
||||
iaa_facility_2_int = vector4(2154.6731, 2921.0784, -81.0755, 268.6461),
|
||||
lesters_factory_int = vector4(717.8725, -974.6326, 24.9142, 359.5224),
|
||||
lesters_house_int = vector4(1273.9886, -1719.4897, 54.7715, 11.6602),
|
||||
meth_lab_int = vector4(997.4726, -3200.6846, -36.3937, 307.2153),
|
||||
morgue_int = vector4(274.9287, -1361.0305, 24.5378, 48.8693),
|
||||
motel_room_int = vector4(151.379, -1007.7512, -99.0, 326.917),
|
||||
movie_theatre_int = vector4(-1437.0271, -243.3148, 16.8335, 200.8791),
|
||||
nightclub_1_int = vector4(-1569.494, -3016.9558, -74.4061, 359.8158),
|
||||
office_1_int = vector4(-140.6184, -619.2825, 168.8203, 183.2728),
|
||||
office_2_int = vector4(-77.2845, -828.4749, 243.3858, 330.7214),
|
||||
office_3_int = vector4(-1579.7123, -562.8762, 108.5229, 217.1494),
|
||||
office_4_int = vector4(-1394.6268, -479.7602, 72.0421, 273.3521),
|
||||
psychiatrist_office_int = vector4(-1902.1859, -572.3267, 19.0972, 106.6428),
|
||||
shell_1_int = vector4(404.9589, -957.7651, -99.0042, 1.7754),
|
||||
submarine_int = vector4(512.8119, 4881.4795, -62.5867, 359.146),
|
||||
uniondepository_int = vector4(5.8001, -708.6383, 16.131, 348.7656),
|
||||
weed_farm_int = vector4(1066.0164, -3183.4456, -39.1635, 96.9736),
|
||||
|
||||
-- Unknown/Random/Vanilla
|
||||
burgershot = vector4(-1199.0568, -882.4495, 13.3500, 209.1105),
|
||||
casino = vector4(923.2289, 47.3113, 81.1063, 237.6052),
|
||||
|
||||
-- Gabz
|
||||
arcade = vector4(-1649.6089, -1083.9313, 13.1575, 46.4121),
|
||||
beanmachinelegion = vector4(116.16, -1022.99, 29.3, 0.0),
|
||||
bowling = vector4(761.5008, -777.7256, 26.3078, 90.5581),
|
||||
pizzaria = vector4(790.4561, -758.4601, 26.7424, 270.2329),
|
||||
catcafe = vector4(-580.8388, -1072.7872, 22.3296, 359.0078),
|
||||
carmeet = vector4(958.8237, -1699.6659, 29.5574, 71.2731),
|
||||
popsdiner = vector4(1595.9753, 6448.6421, 25.3170, 28.3026),
|
||||
harmony = vector4(1183.0693, 2648.5313, 37.8363, 194.0603),
|
||||
haters = vector4(-1117.1525, -1439.4297, 5.1075, 103.4411),
|
||||
hayes = vector4(-1435.7040, -445.7360, 35.5964, 220.1762),
|
||||
pdm = vector4(-48.2113, -1105.4769, 27.2634, 339.5899),
|
||||
bennys = vector4(-47.5289, -1042.6086, 28.3532, 247.9748),
|
||||
lamesaauto = vector4(720.4776, -1092.1934, 22.2866, 310.1469),
|
||||
lostmc = vector4(982.6339, -104.7095, 74.8488, 30.8738),
|
||||
pillbox = vector4(298.1153, -584.2825, 43.2609, 252.7553),
|
||||
mirrorparkhouse1 = vector4(945.9535, -652.9119, 58.0228, 90.5541),
|
||||
pacificbank = vector4(229.9529, 214.3890, 105.5561, 294.6791),
|
||||
paletoliquor = vector4(-154.2287, 6328.8682, 31.5665, 133.1992),
|
||||
paletogasstation = vector4(120.2420, 6625.4722, 31.9580, 36.5687),
|
||||
pinkcage = vector4(323.9055, -203.2524, 54.0866, 186.8505),
|
||||
ponsonbys1 = vector4(-165.2497, -304.3988, 38.07126, 0.0),
|
||||
ponsonbys2 = vector4(-1448.1, -236.8420, 48.15098, 0.0),
|
||||
ponsonbys3 = vector4(-709.8120, -150.6267, 35.75312, 0.0),
|
||||
rangerstation = vector4(387.3204, 790.1508, 187.6927, 4.7656),
|
||||
recordastudio = vector4(473.3006, -109.4360, 62.7418, 350.8488),
|
||||
suburban1 = vector4(124.9756, -217.6290, 55.81879, 0.0),
|
||||
suburban2 = vector4(617.4776, 2757.4810, 43.34935, 0.0),
|
||||
suburban3 = vector4(-1195.8690, -773.5746, 18.58485, 0.0),
|
||||
suburban4 = vector4(-3170.9670, 1049.9310, 22.12445, 0.0),
|
||||
triadrecords = vector4(-829.0061, -698.2049, 28.0583, 291.2052),
|
||||
tuner = vector4(157.5888, -3017.9968, 7.0400, 94.0695),
|
||||
vu = vector4(129.4555, -1299.6754, 29.2327, 27.6378),
|
||||
|
||||
-- Patoche
|
||||
luxerydealership = vector4(-1273.22, -371.11, 36.64, 301.8),
|
||||
|
||||
-- Unclejust
|
||||
digitalden = vector4(-656.28, -849.92, 24.51, 167.42),
|
||||
ifruitstore1 = vector4(-646.78, -288.17, 35.49, 297.73),
|
||||
ifruitstore2 = vector4(-778.7451, -598.2717, 30.2772, 181.0197)
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
QBCore = {
|
||||
Config = {},
|
||||
Shared = {
|
||||
Jobs = {},
|
||||
Gangs = {},
|
||||
Items = {},
|
||||
Vehicles = {},
|
||||
Weapons = {},
|
||||
VehicleHashes = {},
|
||||
},
|
||||
Player = {},
|
||||
Players = {},
|
||||
PlayerData = {},
|
||||
Functions = {},
|
||||
ClientCallbacks = {},
|
||||
ServerCallbacks = {},
|
||||
Player_Buckets = {},
|
||||
Entity_Buckets = {},
|
||||
UsableItems = {},
|
||||
Commands = {
|
||||
List = {},
|
||||
IgnoreList = {
|
||||
['god'] = true,
|
||||
['user'] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local function GetCoreObject(filters)
|
||||
if not filters then return QBCore end
|
||||
local results = {}
|
||||
for i = 1, #filters do
|
||||
local key = filters[i]
|
||||
if QBCore[key] then
|
||||
results[key] = QBCore[key]
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
exports('GetCoreObject', GetCoreObject)
|
||||
exports('GetSharedItems', function() return QBCore.Shared.Items end)
|
||||
exports('GetSharedVehicles', function() return QBCore.Shared.Vehicles end)
|
||||
exports('GetSharedWeapons', function() return QBCore.Shared.Weapons end)
|
||||
exports('GetSharedJobs', function() return QBCore.Shared.Jobs end)
|
||||
exports('GetSharedGangs', function() return QBCore.Shared.Gangs end)
|
||||
@@ -1,523 +0,0 @@
|
||||
function QBCore.Functions.GetVehicles()
|
||||
if IsDuplicityVersion() then
|
||||
return GetAllVehicles()
|
||||
else
|
||||
return GetGamePool('CVehicle')
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetObjects()
|
||||
if IsDuplicityVersion() then
|
||||
return GetAllObjects()
|
||||
else
|
||||
return GetGamePool('CObject')
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetPeds()
|
||||
if IsDuplicityVersion() then
|
||||
local pedPool = GetAllPeds()
|
||||
local peds = {}
|
||||
|
||||
for i = 1, #pedPool do
|
||||
if NetworkGetEntityOwner(pedPool[i]) == 0 then
|
||||
table.insert(peds, pedPool[i])
|
||||
end
|
||||
end
|
||||
|
||||
return peds
|
||||
else
|
||||
local pedPool = GetGamePool('CPed')
|
||||
local peds = {}
|
||||
|
||||
for i = 1, #pedPool do
|
||||
if not IsPedAPlayer(pedPool[i]) then
|
||||
table.insert(peds, pedPool[i])
|
||||
end
|
||||
end
|
||||
|
||||
return peds
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetPlayers()
|
||||
if IsDuplicityVersion() then
|
||||
local sources = {}
|
||||
for k in pairs(QBCore.Players) do
|
||||
sources[#sources + 1] = k
|
||||
end
|
||||
return sources
|
||||
else
|
||||
return GetActivePlayers()
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetCoords(entity)
|
||||
local coords = GetEntityCoords(entity, false)
|
||||
local heading = GetEntityHeading(entity)
|
||||
return vector4(coords.x, coords.y, coords.z, heading)
|
||||
end
|
||||
|
||||
function QBCore.Functions.HasItem(...)
|
||||
if GetResourceState('qb-inventory') == 'missing' then return false end
|
||||
if IsDuplicityVersion() then
|
||||
local source, items, amount = ...
|
||||
return exports['qb-inventory']:HasItem(source, items, amount)
|
||||
else
|
||||
local items, amount = ...
|
||||
return exports['qb-inventory']:HasItem(items, amount)
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.Notify(...)
|
||||
if IsDuplicityVersion() then
|
||||
local source, text, texttype, length = ...
|
||||
TriggerClientEvent('QBCore:Notify', source, text, texttype, length)
|
||||
else
|
||||
local text, texttype, length, icon = ...
|
||||
local message = {
|
||||
action = 'notify',
|
||||
type = texttype or 'primary',
|
||||
length = length or 5000,
|
||||
}
|
||||
if type(text) == 'table' then
|
||||
message.text = text.text or 'Placeholder'
|
||||
message.caption = text.caption or 'Placeholder'
|
||||
else
|
||||
message.text = text
|
||||
end
|
||||
if icon then
|
||||
message.icon = icon
|
||||
end
|
||||
SendNUIMessage(message)
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.SpawnVehicle(...)
|
||||
if IsDuplicityVersion() then
|
||||
local source, model, coords, warp = ...
|
||||
local ped = GetPlayerPed(source)
|
||||
model = type(model) == 'string' and joaat(model) or model
|
||||
if not coords then coords = GetEntityCoords(ped) end
|
||||
local heading = coords.w and coords.w or 0.0
|
||||
local veh = CreateVehicle(model, coords.x, coords.y, coords.z, heading, true, true)
|
||||
while not DoesEntityExist(veh) do Wait(0) end
|
||||
if warp then
|
||||
while GetVehiclePedIsIn(ped, false) ~= veh do
|
||||
Wait(0)
|
||||
TaskWarpPedIntoVehicle(ped, veh, -1)
|
||||
end
|
||||
end
|
||||
while NetworkGetEntityOwner(veh) ~= source do Wait(0) end
|
||||
return veh
|
||||
else
|
||||
local model, cb, coords, isnetworked, teleportInto = ...
|
||||
local ped = PlayerPedId()
|
||||
model = type(model) == 'string' and joaat(model) or model
|
||||
if not IsModelInCdimage(model) then return end
|
||||
if coords then
|
||||
coords = type(coords) == 'table' and vec3(coords.x, coords.y, coords.z) or coords
|
||||
else
|
||||
coords = GetEntityCoords(ped)
|
||||
end
|
||||
isnetworked = isnetworked == nil or isnetworked
|
||||
QBCore.Functions.LoadModel(model)
|
||||
local veh = CreateVehicle(model, coords.x, coords.y, coords.z, coords.w or 0.0, isnetworked, false)
|
||||
local netid = NetworkGetNetworkIdFromEntity(veh)
|
||||
SetVehicleHasBeenOwnedByPlayer(veh, true)
|
||||
SetNetworkIdCanMigrate(netid, true)
|
||||
SetVehicleNeedsToBeHotwired(veh, false)
|
||||
SetVehRadioStation(veh, 'OFF')
|
||||
SetVehicleFuelLevel(veh, 100.0)
|
||||
SetModelAsNoLongerNeeded(model)
|
||||
if teleportInto then TaskWarpPedIntoVehicle(PlayerPedId(), veh, -1) end
|
||||
if cb then cb(veh) end
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetClosestPed(...)
|
||||
if IsDuplicityVersion() then
|
||||
local source, coords = ...
|
||||
local ped = GetPlayerPed(source)
|
||||
local peds = GetAllPeds()
|
||||
local closestDistance, closestPed = -1, -1
|
||||
|
||||
if coords then
|
||||
coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords
|
||||
else
|
||||
coords = GetEntityCoords(ped)
|
||||
end
|
||||
|
||||
for i = 1, #peds do
|
||||
if peds[i] ~= ped then
|
||||
local pedCoords = GetEntityCoords(peds[i])
|
||||
local distance = #(pedCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestPed = peds[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
end
|
||||
return closestPed, closestDistance
|
||||
else
|
||||
local coords, ignoreList = ...
|
||||
local ped = PlayerPedId()
|
||||
if coords then
|
||||
coords = type(coords) == 'table' and vec3(coords.x, coords.y, coords.z) or coords
|
||||
else
|
||||
coords = GetEntityCoords(ped)
|
||||
end
|
||||
|
||||
ignoreList = ignoreList or {}
|
||||
local peds = QBCore.Functions.GetPeds(ignoreList)
|
||||
local closestDistance, closestPed = -1, -1
|
||||
|
||||
for i = 1, #peds do
|
||||
local pedCoords = GetEntityCoords(peds[i])
|
||||
local distance = #(pedCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestPed = peds[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
return closestPed, closestDistance
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetClosestVehicle(...)
|
||||
if IsDuplicityVersion() then
|
||||
local source, coords = ...
|
||||
local ped = GetPlayerPed(source)
|
||||
local vehicles = GetAllVehicles()
|
||||
local closestDistance, closestVehicle = -1, -1
|
||||
|
||||
if coords then
|
||||
coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords
|
||||
else
|
||||
coords = GetEntityCoords(ped)
|
||||
end
|
||||
|
||||
for i = 1, #vehicles do
|
||||
local vehicleCoords = GetEntityCoords(vehicles[i])
|
||||
local distance = #(vehicleCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestVehicle = vehicles[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
return closestVehicle, closestDistance
|
||||
else
|
||||
local coords = ...
|
||||
local ped = PlayerPedId()
|
||||
local vehicles = GetGamePool('CVehicle')
|
||||
local closestDistance, closestVehicle = -1, -1
|
||||
|
||||
if coords then
|
||||
coords = type(coords) == 'table' and vec3(coords.x, coords.y, coords.z) or coords
|
||||
else
|
||||
coords = GetEntityCoords(ped)
|
||||
end
|
||||
|
||||
for i = 1, #vehicles do
|
||||
local vehicleCoords = GetEntityCoords(vehicles[i])
|
||||
local distance = #(vehicleCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestVehicle = vehicles[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
return closestVehicle, closestDistance
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetClosestObject(...)
|
||||
if IsDuplicityVersion() then
|
||||
local source, coords = ...
|
||||
local ped = GetPlayerPed(source)
|
||||
local objects = GetAllObjects()
|
||||
local closestDistance, closestObject = -1, -1
|
||||
|
||||
if coords then
|
||||
coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords
|
||||
else
|
||||
coords = GetEntityCoords(ped)
|
||||
end
|
||||
|
||||
for i = 1, #objects do
|
||||
local objectCoords = GetEntityCoords(objects[i])
|
||||
local distance = #(objectCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestObject = objects[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
return closestObject, closestDistance
|
||||
else
|
||||
local coords = ...
|
||||
local ped = PlayerPedId()
|
||||
local objects = GetGamePool('CObject')
|
||||
local closestDistance, closestObject = -1, -1
|
||||
|
||||
if coords then
|
||||
coords = type(coords) == 'table' and vec3(coords.x, coords.y, coords.z) or coords
|
||||
else
|
||||
coords = GetEntityCoords(ped)
|
||||
end
|
||||
|
||||
for i = 1, #objects do
|
||||
local objectCoords = GetEntityCoords(objects[i])
|
||||
local distance = #(objectCoords - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestObject = objects[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
return closestObject, closestDistance
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetClosestPlayer(...)
|
||||
if IsDuplicityVersion() then
|
||||
local source, coords = ...
|
||||
local ped = GetPlayerPed(source)
|
||||
local players = GetPlayers()
|
||||
local closestDistance, closestPlayer = -1, -1
|
||||
|
||||
if coords then
|
||||
coords = type(coords) == 'table' and vector3(coords.x, coords.y, coords.z) or coords
|
||||
else
|
||||
coords = GetEntityCoords(ped)
|
||||
end
|
||||
|
||||
for i = 1, #players do
|
||||
local playerId = players[i]
|
||||
local playerPed = GetPlayerPed(playerId)
|
||||
if playerPed ~= ped then
|
||||
local playerCoords = GetEntityCoords(playerPed)
|
||||
local distance = #(playerCoords - coords)
|
||||
if closestDistance == -1 or distance < closestDistance then
|
||||
closestPlayer = playerId
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
end
|
||||
return closestPlayer, closestDistance
|
||||
else
|
||||
local coords = ...
|
||||
local ped = PlayerPedId()
|
||||
|
||||
if coords then
|
||||
coords = type(coords) == 'table' and vec3(coords.x, coords.y, coords.z) or coords
|
||||
else
|
||||
coords = GetEntityCoords(ped)
|
||||
end
|
||||
|
||||
local closestPlayers = QBCore.Functions.GetPlayersFromCoords(coords)
|
||||
local closestDistance, closestPlayer = -1, -1
|
||||
|
||||
for i = 1, #closestPlayers do
|
||||
if closestPlayers[i] ~= PlayerId() and closestPlayers[i] ~= -1 then
|
||||
local pos = GetEntityCoords(GetPlayerPed(closestPlayers[i]))
|
||||
local distance = #(pos - coords)
|
||||
if closestDistance == -1 or closestDistance > distance then
|
||||
closestPlayer = closestPlayers[i]
|
||||
closestDistance = distance
|
||||
end
|
||||
end
|
||||
end
|
||||
return closestPlayer, closestDistance
|
||||
end
|
||||
end
|
||||
|
||||
local StringCharset = {}
|
||||
local NumberCharset = {}
|
||||
|
||||
for i = 48, 57 do NumberCharset[#NumberCharset + 1] = string.char(i) end
|
||||
for i = 65, 90 do StringCharset[#StringCharset + 1] = string.char(i) end
|
||||
for i = 97, 122 do StringCharset[#StringCharset + 1] = string.char(i) end
|
||||
|
||||
-- String Functions
|
||||
|
||||
function QBCore.Functions.RandomStr(length)
|
||||
local result = ''
|
||||
for i = 1, length do
|
||||
result = result .. StringCharset[math.random(1, #StringCharset)]
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function QBCore.Functions.SplitStr(str, delimiter)
|
||||
local result = {}
|
||||
local from = 1
|
||||
local delim_from, delim_to = string.find(str, delimiter, from)
|
||||
while delim_from do
|
||||
result[#result + 1] = string.sub(str, from, delim_from - 1)
|
||||
from = delim_to + 1
|
||||
delim_from, delim_to = string.find(str, delimiter, from)
|
||||
end
|
||||
result[#result + 1] = string.sub(str, from)
|
||||
return result
|
||||
end
|
||||
|
||||
function QBCore.Functions.Trim(value)
|
||||
if not value then return nil end
|
||||
return (string.gsub(value, '^%s*(.-)%s*$', '%1'))
|
||||
end
|
||||
|
||||
function QBCore.Functions.FirstToUpper(value)
|
||||
if not value then return nil end
|
||||
return (value:gsub('^%l', string.upper))
|
||||
end
|
||||
|
||||
function QBCore.Functions.SplitLines(str)
|
||||
local lines = {}
|
||||
for line in str:gmatch('[^\r\n]+') do
|
||||
table.insert(lines, line)
|
||||
end
|
||||
return lines
|
||||
end
|
||||
|
||||
function QBCore.Functions.NormalizeString(str)
|
||||
return str:gsub('[^%w]', ''):lower()
|
||||
end
|
||||
|
||||
-- Number Functions
|
||||
|
||||
function QBCore.Functions.RandomInt(length)
|
||||
local result = ''
|
||||
for i = 1, length do
|
||||
result = result .. NumberCharset[math.random(1, #NumberCharset)]
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function QBCore.Functions.Round(value, numDecimalPlaces)
|
||||
if not numDecimalPlaces then return math.floor(value + 0.5) end
|
||||
local power = 10 ^ numDecimalPlaces
|
||||
return math.floor((value * power) + 0.5) / (power)
|
||||
end
|
||||
|
||||
function QBCore.Functions.Clamp(value, min, max)
|
||||
return math.max(min, math.min(value, max))
|
||||
end
|
||||
|
||||
-- Table Functions
|
||||
|
||||
function QBCore.Functions.TableLength(tbl)
|
||||
local count = 0
|
||||
for _ in pairs(tbl) do count = count + 1 end
|
||||
return count
|
||||
end
|
||||
|
||||
function QBCore.Functions.ShuffleTable(tbl)
|
||||
for i = #tbl, 2, -1 do
|
||||
local j = math.random(1, i)
|
||||
tbl[i], tbl[j] = tbl[j], tbl[i]
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
function QBCore.Functions.DeepCopy(tbl)
|
||||
if type(tbl) ~= 'table' then return tbl end
|
||||
local copy = {}
|
||||
for k, v in pairs(tbl) do
|
||||
copy[k] = QBCore.Functions.DeepCopy(v)
|
||||
end
|
||||
return copy
|
||||
end
|
||||
|
||||
function QBCore.Functions.ContainsKey(tbl, key)
|
||||
return tbl[key] ~= nil
|
||||
end
|
||||
|
||||
function QBCore.Functions.Contains(tbl, value)
|
||||
for _, v in pairs(tbl) do
|
||||
if v == value then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function QBCore.Functions.MergeTables(tbl1, tbl2)
|
||||
local merged = QBCore.Functions.DeepCopy(tbl1)
|
||||
for k, v in pairs(tbl2) do
|
||||
merged[k] = v
|
||||
end
|
||||
return merged
|
||||
end
|
||||
|
||||
function QBCore.Functions.ReverseTable(tbl)
|
||||
local reversed = {}
|
||||
for i = #tbl, 1, -1 do
|
||||
table.insert(reversed, tbl[i])
|
||||
end
|
||||
return reversed
|
||||
end
|
||||
|
||||
function QBCore.Functions.RandomWeightedChoice(choices)
|
||||
local totalWeight = 0
|
||||
for _, choice in pairs(choices) do
|
||||
totalWeight = totalWeight + choice.weight
|
||||
end
|
||||
|
||||
local rand = math.random() * totalWeight
|
||||
local cumulative = 0
|
||||
|
||||
for key, choice in pairs(choices) do
|
||||
cumulative = cumulative + choice.weight
|
||||
if rand <= cumulative then return key, choice end
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.GetRandomElement(tbl)
|
||||
return tbl[math.random(1, #tbl)]
|
||||
end
|
||||
|
||||
function QBCore.Functions.PrintTable(tbl, indent)
|
||||
indent = indent or 0
|
||||
if type(tbl) == 'table' then
|
||||
for k, v in pairs(tbl) do
|
||||
local tblType = type(v)
|
||||
local formatting = ('%s ^3%s:^0'):format(string.rep(' ', indent), k)
|
||||
if tblType == 'table' then
|
||||
print(formatting)
|
||||
QBCore.Functions.PrintTable(v, indent + 1)
|
||||
elseif tblType == 'boolean' then
|
||||
print(('%s^1 %s ^0'):format(formatting, tostring(v)))
|
||||
elseif tblType == 'function' then
|
||||
print(('%s^9 %s ^0'):format(formatting, tostring(v)))
|
||||
elseif tblType == 'number' then
|
||||
print(('%s^5 %s ^0'):format(formatting, v))
|
||||
elseif tblType == 'string' then
|
||||
print(("%s ^2'%s' ^0"):format(formatting, v))
|
||||
else
|
||||
print(('%s^2 %s ^0'):format(formatting, tostring(v)))
|
||||
end
|
||||
end
|
||||
else
|
||||
print(('%s^0 %s'):format(string.rep(' ', indent), tostring(tbl)))
|
||||
end
|
||||
end
|
||||
|
||||
function QBCore.Functions.Debug(tbl, indent, resource)
|
||||
local resource_name = resource or GetInvokingResource() or 'qb-core'
|
||||
print(('\x1b[4m\x1b[36m[ %s : DEBUG]\x1b[0m'):format(resource_name))
|
||||
QBCore.Functions.PrintTable(tbl, indent)
|
||||
print('\x1b[4m\x1b[36m[ END DEBUG ]\x1b[0m')
|
||||
end
|
||||
|
||||
function QBCore.Functions.ShowError(resource, msg)
|
||||
local resource_name = resource or GetInvokingResource() or 'qb-core'
|
||||
print('\x1b[31m[' .. resource_name .. ':ERROR]\x1b[0m ' .. msg)
|
||||
end
|
||||
|
||||
function QBCore.Functions.ShowSuccess(resource, msg)
|
||||
local resource_name = resource or GetInvokingResource() or 'qb-core'
|
||||
print('\x1b[32m[' .. resource_name .. ':LOG]\x1b[0m ' .. msg)
|
||||
end
|
||||
|
||||
function QBCore.Functions.IsFunction(value)
|
||||
if type(value) == 'table' then
|
||||
return value.__cfx_functionReference ~= nil and type(value.__cfx_functionReference) == 'string'
|
||||
end
|
||||
return type(value) == 'function'
|
||||
end
|
||||
@@ -1,70 +0,0 @@
|
||||
local resourceName = GetCurrentResourceName()
|
||||
|
||||
-- Load Config
|
||||
|
||||
if IsDuplicityVersion() then
|
||||
local configData = LoadResourceFile(resourceName, 'shared/json/config.json')
|
||||
if not configData then return print('^1[QBCore] Failed to Load Config JSON File') end
|
||||
QBCore.Config = json.decode(configData) or {}
|
||||
print('^2[QBCore] Loaded Config.json')
|
||||
end
|
||||
|
||||
-- Load Vehicles
|
||||
|
||||
local Vehicles = LoadResourceFile(resourceName, 'shared/json/vehicles.json')
|
||||
if not Vehicles then return print('^1[QBCore] Failed to Load Vehicles JSON File') end
|
||||
Vehicles = json.decode(Vehicles)
|
||||
for i = 1, #Vehicles do
|
||||
local hash = joaat(Vehicles[i].model)
|
||||
QBCore.Shared.Vehicles[Vehicles[i].model] = {
|
||||
spawncode = Vehicles[i].model,
|
||||
name = Vehicles[i].name,
|
||||
brand = Vehicles[i].brand,
|
||||
model = Vehicles[i].model,
|
||||
price = Vehicles[i].price,
|
||||
category = Vehicles[i].category,
|
||||
hash = hash,
|
||||
type = Vehicles[i].type,
|
||||
shop = Vehicles[i].shop
|
||||
}
|
||||
QBCore.Shared.VehicleHashes[hash] = QBCore.Shared.Vehicles[Vehicles[i].model]
|
||||
end
|
||||
print('^2[QBCore] Loaded Vehicles.json')
|
||||
|
||||
-- Load Jobs
|
||||
|
||||
local Jobs = LoadResourceFile(resourceName, 'shared/json/jobs.json')
|
||||
if not Jobs then return print('^1[QBCore] Failed to Load Jobs JSON File') end
|
||||
QBCore.Shared.Jobs = json.decode(Jobs) or {}
|
||||
print('^2[QBCore] Loaded Jobs.json')
|
||||
|
||||
-- Load Gangs
|
||||
|
||||
local Gangs = LoadResourceFile(resourceName, 'shared/json/gangs.json')
|
||||
if not Gangs then return print('^1[QBCore] Failed to Load Gangs JSON File') end
|
||||
QBCore.Shared.Gangs = json.decode(Gangs) or {}
|
||||
print('^2[QBCore] Loaded Gangs.json')
|
||||
|
||||
-- Load Items
|
||||
|
||||
local Items = LoadResourceFile(resourceName, 'shared/json/items.json')
|
||||
if not Items then return print('^1[QBCore] Failed to Load Items JSON File') end
|
||||
QBCore.Shared.Items = json.decode(Items) or {}
|
||||
print('^2[QBCore] Loaded Items.json')
|
||||
|
||||
-- Load Weapons
|
||||
|
||||
local Weapons = LoadResourceFile(resourceName, 'shared/json/weapons.json')
|
||||
if not Weapons then return print('^1[QBCore] Failed to Load Weapons JSON File') end
|
||||
Weapons = json.decode(Weapons)
|
||||
for i = 1, #Weapons do
|
||||
local weaponHash = joaat(Weapons[i].name)
|
||||
QBCore.Shared.Weapons[weaponHash] = {
|
||||
name = Weapons[i].name,
|
||||
label = Weapons[i].label,
|
||||
weapontype = Weapons[i].weapontype,
|
||||
ammotype = Weapons[i].ammotype,
|
||||
damagereason = Weapons[i].damagereason
|
||||
}
|
||||
end
|
||||
print('^2[QBCore] Loaded Weapons.json')
|
||||
+175
@@ -0,0 +1,175 @@
|
||||
QBShared = QBShared or {}
|
||||
|
||||
local StringCharset = {}
|
||||
local NumberCharset = {}
|
||||
|
||||
QBShared.StarterItems = {
|
||||
['phone'] = { amount = 1, item = 'phone' },
|
||||
['id_card'] = { amount = 1, item = 'id_card' },
|
||||
['driver_license'] = { amount = 1, item = 'driver_license' },
|
||||
}
|
||||
|
||||
for i = 48, 57 do NumberCharset[#NumberCharset + 1] = string.char(i) end
|
||||
for i = 65, 90 do StringCharset[#StringCharset + 1] = string.char(i) end
|
||||
for i = 97, 122 do StringCharset[#StringCharset + 1] = string.char(i) end
|
||||
|
||||
function QBShared.RandomStr(length)
|
||||
if length <= 0 then return '' end
|
||||
return QBShared.RandomStr(length - 1) .. StringCharset[math.random(1, #StringCharset)]
|
||||
end
|
||||
|
||||
function QBShared.RandomInt(length)
|
||||
if length <= 0 then return '' end
|
||||
return QBShared.RandomInt(length - 1) .. NumberCharset[math.random(1, #NumberCharset)]
|
||||
end
|
||||
|
||||
function QBShared.SplitStr(str, delimiter)
|
||||
local result = {}
|
||||
local from = 1
|
||||
local delim_from, delim_to = string.find(str, delimiter, from)
|
||||
while delim_from do
|
||||
result[#result + 1] = string.sub(str, from, delim_from - 1)
|
||||
from = delim_to + 1
|
||||
delim_from, delim_to = string.find(str, delimiter, from)
|
||||
end
|
||||
result[#result + 1] = string.sub(str, from)
|
||||
return result
|
||||
end
|
||||
|
||||
function QBShared.Trim(value)
|
||||
if not value then return nil end
|
||||
return (string.gsub(value, '^%s*(.-)%s*$', '%1'))
|
||||
end
|
||||
|
||||
function QBShared.FirstToUpper(value)
|
||||
if not value then return nil end
|
||||
return (value:gsub("^%l", string.upper))
|
||||
end
|
||||
|
||||
function QBShared.Round(value, numDecimalPlaces)
|
||||
if not numDecimalPlaces then return math.floor(value + 0.5) end
|
||||
local power = 10 ^ numDecimalPlaces
|
||||
return math.floor((value * power) + 0.5) / (power)
|
||||
end
|
||||
|
||||
function QBShared.ChangeVehicleExtra(vehicle, extra, enable)
|
||||
if DoesExtraExist(vehicle, extra) then
|
||||
if enable then
|
||||
SetVehicleExtra(vehicle, extra, false)
|
||||
if not IsVehicleExtraTurnedOn(vehicle, extra) then
|
||||
QBShared.ChangeVehicleExtra(vehicle, extra, enable)
|
||||
end
|
||||
else
|
||||
SetVehicleExtra(vehicle, extra, true)
|
||||
if IsVehicleExtraTurnedOn(vehicle, extra) then
|
||||
QBShared.ChangeVehicleExtra(vehicle, extra, enable)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function QBShared.IsFunction(value)
|
||||
if type(value) == 'table' then
|
||||
return value.__cfx_functionReference ~= nil and type(value.__cfx_functionReference) == "string"
|
||||
end
|
||||
|
||||
return type(value) == 'function'
|
||||
end
|
||||
|
||||
function QBShared.SetDefaultVehicleExtras(vehicle, config)
|
||||
-- Clear Extras
|
||||
for i = 1, 20 do
|
||||
if DoesExtraExist(vehicle, i) then
|
||||
SetVehicleExtra(vehicle, i, 1)
|
||||
end
|
||||
end
|
||||
|
||||
for id, enabled in pairs(config) do
|
||||
if type(enabled) ~= 'boolean' then
|
||||
enabled = true
|
||||
end
|
||||
|
||||
QBShared.ChangeVehicleExtra(vehicle, tonumber(id), enabled)
|
||||
end
|
||||
end
|
||||
|
||||
QBShared.MaleNoGloves = {
|
||||
[0] = true,
|
||||
[1] = true,
|
||||
[2] = true,
|
||||
[3] = true,
|
||||
[4] = true,
|
||||
[5] = true,
|
||||
[6] = true,
|
||||
[7] = true,
|
||||
[8] = true,
|
||||
[9] = true,
|
||||
[10] = true,
|
||||
[11] = true,
|
||||
[12] = true,
|
||||
[13] = true,
|
||||
[14] = true,
|
||||
[15] = true,
|
||||
[18] = true,
|
||||
[26] = true,
|
||||
[52] = true,
|
||||
[53] = true,
|
||||
[54] = true,
|
||||
[55] = true,
|
||||
[56] = true,
|
||||
[57] = true,
|
||||
[58] = true,
|
||||
[59] = true,
|
||||
[60] = true,
|
||||
[61] = true,
|
||||
[62] = true,
|
||||
[112] = true,
|
||||
[113] = true,
|
||||
[114] = true,
|
||||
[118] = true,
|
||||
[125] = true,
|
||||
[132] = true
|
||||
}
|
||||
|
||||
QBShared.FemaleNoGloves = {
|
||||
[0] = true,
|
||||
[1] = true,
|
||||
[2] = true,
|
||||
[3] = true,
|
||||
[4] = true,
|
||||
[5] = true,
|
||||
[6] = true,
|
||||
[7] = true,
|
||||
[8] = true,
|
||||
[9] = true,
|
||||
[10] = true,
|
||||
[11] = true,
|
||||
[12] = true,
|
||||
[13] = true,
|
||||
[14] = true,
|
||||
[15] = true,
|
||||
[19] = true,
|
||||
[59] = true,
|
||||
[60] = true,
|
||||
[61] = true,
|
||||
[62] = true,
|
||||
[63] = true,
|
||||
[64] = true,
|
||||
[65] = true,
|
||||
[66] = true,
|
||||
[67] = true,
|
||||
[68] = true,
|
||||
[69] = true,
|
||||
[70] = true,
|
||||
[71] = true,
|
||||
[129] = true,
|
||||
[130] = true,
|
||||
[131] = true,
|
||||
[135] = true,
|
||||
[142] = true,
|
||||
[149] = true,
|
||||
[153] = true,
|
||||
[157] = true,
|
||||
[161] = true,
|
||||
[165] = true
|
||||
}
|
||||
@@ -0,0 +1,783 @@
|
||||
QBShared = QBShared or {}
|
||||
QBShared.Vehicles = QBShared.Vehicles or {}
|
||||
|
||||
local Vehicles = {
|
||||
--- Compacts (0)
|
||||
{
|
||||
model = 'asbo', -- This has to match the spawn code of the vehicle
|
||||
name = 'Asbo', -- This is the display of the vehicle
|
||||
brand = 'Maxwell', -- This is the vehicle's brand
|
||||
price = 4000, -- The price that the vehicle sells for
|
||||
category = 'compacts', -- Catgegory of the vehilce, stick with GetVehicleClass() options https://docs.fivem.net/natives/?_0x29439776AAA00A62
|
||||
type = 'automobile', -- Vehicle type, refer here https://docs.fivem.net/natives/?_0x6AE51D4B & here https://docs.fivem.net/natives/?_0xA273060E
|
||||
shop = 'pdm', -- Can be a single shop or multiple shops. For multiple shops for example {'shopname1','shopname2','shopname3'}
|
||||
},
|
||||
{ model = 'blista', name = 'Blista', brand = 'Dinka', price = 13000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'brioso', name = 'Brioso R/A', brand = 'Grotti', price = 20000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'club', name = 'Club', brand = 'BF', price = 8000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dilettante', name = 'Dilettante', brand = 'Karin', price = 9000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dilettante2', name = 'Dilettante Patrol', brand = 'Karin', price = 12000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'kanjo', name = 'Blista Kanjo', brand = 'Dinka', price = 12000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'issi2', name = 'Issi', brand = 'Weeny', price = 7000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'issi3', name = 'Issi Classic', brand = 'Weeny', price = 5000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'issi4', name = 'Issi Arena', brand = 'Weeny', price = 80000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'issi5', name = 'Issi Future Shock', brand = 'Weeny', price = 80000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'issi6', name = 'Issi Nightmare', brand = 'Weeny', price = 80000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'panto', name = 'Panto', brand = 'Benefactor', price = 3200, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'prairie', name = 'Prairie', brand = 'Bollokan', price = 30000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'rhapsody', name = 'Rhapsody', brand = 'Declasse', price = 10000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'brioso2', name = 'Brioso 300', brand = 'Grotti', price = 12000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'weevil', name = 'Weevil', brand = 'BF', price = 9000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'issi7', name = 'Issi Sport', brand = 'Weeny', price = 100000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'blista2', name = 'Blista Compact', brand = 'Dinka', price = 18950, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'blista3', name = 'Blista Go Go Monkey', brand = 'Dinka', price = 15000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'brioso3', name = 'Brioso 300 Widebody', brand = 'Grotti', price = 125000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'boor', name = 'Boor', brand = 'Karin', price = 23000, category = 'compacts', type = 'automobile', shop = 'pdm' },
|
||||
--- Sedans (1)
|
||||
{ model = 'asea', name = 'Asea', brand = 'Declasse', price = 2500, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'asterope', name = 'Asterope', brand = 'Karin', price = 11000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'cog55', name = 'Cognoscenti 55', brand = 'Enus', price = 22000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'cognoscenti', name = 'Cognoscenti', brand = 'Enus', price = 22500, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'emperor', name = 'Emperor', brand = 'Albany', price = 4250, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'fugitive', name = 'Fugitive', brand = 'Cheval', price = 20000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'glendale', name = 'Glendale', brand = 'Benefactor', price = 3400, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'glendale2', name = 'Glendale Custom', brand = 'Benefactor', price = 12000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'ingot', name = 'Ingot', brand = 'Vulcar', price = 4999, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'intruder', name = 'Intruder', brand = 'Karin', price = 11250, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'premier', name = 'Premier', brand = 'Declasse', price = 12000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'primo', name = 'Primo', brand = 'Albany', price = 5000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'primo2', name = 'Primo Custom', brand = 'Albany', price = 14500, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'regina', name = 'Regina', brand = 'Dundreary', price = 7000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'stafford', name = 'Stafford', brand = 'Enus', price = 30000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'stanier', name = 'Stanier', brand = 'Vapid', price = 19000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'stratum', name = 'Stratum', brand = 'Zirconium', price = 15000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'stretch', name = 'Stretch', brand = 'Dundreary', price = 19000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'superd', name = 'Super Diamond', brand = 'Enus', price = 17000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'surge', name = 'Surge', brand = 'Cheval', price = 20000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'tailgater', name = 'Tailgater', brand = 'Obey', price = 22000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'warrener', name = 'Warrener', brand = 'Vulcar', price = 4000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'washington', name = 'Washington', brand = 'Albany', price = 7000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'tailgater2', name = 'Tailgater S', brand = 'Obey', price = 51000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'cinquemila', name = 'Lampadati', brand = 'Cinquemila', price = 125000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'iwagen', name = 'Obey', brand = 'I-Wagen', price = 225000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'astron', name = 'Astron', brand = 'Pfister', price = 150000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'baller7', name = 'Baller ST', brand = 'Gallivanter', price = 145000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'comet7', name = 'Comet', brand = 'S2 Cabrio', price = 25000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'deity', name = 'Deity', brand = 'Enus', price = 505000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'jubilee', name = 'Jubilee', brand = 'Enus', price = 485000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'oracle', name = 'Oracle', brand = 'Übermacht', price = 22000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'schafter2', name = 'Schafter', brand = 'Benefactor', price = 16000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'warrener2', name = 'Warrener HKR', brand = 'Vulcar', price = 30000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'rhinehart', name = 'Rhinehart', brand = 'Übermacht', price = 105000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'eudora', name = 'Eudora', brand = 'Willard', price = 17000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'asterope2', name = 'Asterope GZ', brand = 'Karin', price = 459000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'impaler5', name = 'Impaler SZ', brand = 'Declasse', price = 768000, category = 'sedans', type = 'automobile', shop = 'pdm' },
|
||||
--- SUV (2)
|
||||
{ model = 'baller', name = 'Baller', brand = 'Gallivanter', price = 22000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'baller2', name = 'Baller II', brand = 'Gallivanter', price = 15000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'baller3', name = 'Baller LE', brand = 'Gallivanter', price = 15000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'baller4', name = 'Baller LE LWB', brand = 'Gallivanter', price = 29000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'baller5', name = 'Baller LE (Armored)', brand = 'Gallivanter', price = 78000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'baller6', name = 'Baller LE LWB (Armored)', brand = 'Gallivanter', price = 82000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'bjxl', name = 'BeeJay XL', brand = 'Karin', price = 19000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'cavalcade', name = 'Cavalcade', brand = 'Albany', price = 14000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'cavalcade2', name = 'Cavalcade II', brand = 'Albany', price = 16500, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'contender', name = 'Contender', brand = 'Vapid', price = 35000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dubsta', name = 'Dubsta', brand = 'Benefactor', price = 19000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dubsta2', name = 'Dubsta Luxury', brand = 'Benefactor', price = 19500, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'fq2', name = 'FQ2', brand = 'Fathom', price = 18500, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'granger', name = 'Granger', brand = 'Declasse', price = 22000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'gresley', name = 'Gresley', brand = 'Bravado', price = 25000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'habanero', name = 'Habanero', brand = 'Emperor', price = 20000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'huntley', name = 'Huntley S', brand = 'Enus', price = 24500, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'landstalker', name = 'Landstalker', brand = 'Dundreary', price = 12000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'landstalker2', name = 'Landstalker XL', brand = 'Dundreary', price = 26000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'novak', name = 'Novak', brand = 'Lampadati', price = 70000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'patriot', name = 'Patriot', brand = 'Mammoth', price = 21000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'patriot2', name = 'Patriot Stretch', brand = 'Mammoth', price = 21000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'radi', name = 'Radius', brand = 'Vapid', price = 18000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'rebla', name = 'Rebla GTS', brand = 'Übermacht', price = 21000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'rocoto', name = 'Rocoto', brand = 'Obey', price = 13000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'seminole', name = 'Seminole', brand = 'Canis', price = 20000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'seminole2', name = 'Seminole Frontier', brand = 'Canis', price = 13000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'serrano', name = 'Serrano', brand = 'Benefactor', price = 48000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'toros', name = 'Toros', brand = 'Pegassi', price = 65000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'xls', name = 'XLS', brand = 'Benefactor', price = 17000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'granger2', name = 'Granger 3600LX', brand = 'Declasse', price = 221000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'patriot3', name = 'Patriot Military', brand = 'Mil-Spec', price = 270000, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'aleutian', name = 'Aleutian', brand = 'Vapid', price = 183500, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'baller8', name = 'Baller ST-D', brand = 'Gallivanter', price = 171500, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'cavalcade3', name = 'Cavalcade XL', brand = 'Albany', price = 166500, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dorado', name = 'Dorado', brand = 'Bravado', price = 137500, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'vivanite', name = 'Vivanite', brand = 'Karin', price = 160500, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'castigator', name = 'Castigator', brand = 'Canis', price = 160500, category = 'suvs', type = 'automobile', shop = 'pdm' },
|
||||
--- Coupes (3)
|
||||
{ model = 'cogcabrio', name = 'Cognoscenti Cabrio', brand = 'Enus', price = 30000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'exemplar', name = 'Exemplar', brand = 'Dewbauchee', price = 40000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'f620', name = 'F620', brand = 'Ocelot', price = 32500, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'felon', name = 'Felon', brand = 'Lampadati', price = 31000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'felon2', name = 'Felon GT', brand = 'Lampadati', price = 37000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'jackal', name = 'Jackal', brand = 'Ocelot', price = 19000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'oracle2', name = 'Oracle XS', brand = 'Übermacht', price = 28000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'sentinel', name = 'Sentinel', brand = 'Übermacht', price = 30000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'sentinel2', name = 'Sentinel XS', brand = 'Übermacht', price = 33000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'windsor', name = 'Windsor', brand = 'Enus', price = 27000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'windsor2', name = 'Windsor Drop', brand = 'Enus', price = 34000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'zion', name = 'Zion', brand = 'Übermacht', price = 22000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'zion2', name = 'Zion Cabrio', brand = 'Übermacht', price = 28000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'previon', name = 'Previon', brand = 'Karin', price = 149000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'champion', name = 'Champion', brand = 'Dewbauchee', price = 205000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'futo', name = 'Futo', brand = 'Karin', price = 17500, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'sentinel3', name = 'Sentinel Classic', brand = 'Übermacht', price = 70000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'kanjosj', name = 'Kanjo SJ', brand = 'Dinka', price = 143000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'postlude', name = 'Postlude', brand = 'Dinka', price = 90000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'tahoma', name = 'Tahoma Coupe', brand = 'Declasse', price = 12000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'broadway', name = 'Broadway', brand = 'Classique', price = 20000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'fr36', name = 'FR36', brand = 'Fathom', price = 161000, category = 'coupes', type = 'automobile', shop = 'pdm' },
|
||||
--- Muscle (4)
|
||||
{ model = 'blade', name = 'Blade', brand = 'Vapid', price = 23500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'buccaneer', name = 'Buccaneer', brand = 'Albany', price = 22500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'buccaneer2', name = 'Buccaneer Rider', brand = 'Albany', price = 24500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'chino', name = 'Chino', brand = 'Vapid', price = 5000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'chino2', name = 'Chino Luxe', brand = 'Vapid', price = 8000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'clique', name = 'Clique', brand = 'Vapid', price = 20000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'coquette3', name = 'Coquette BlackFin', brand = 'Invetero', price = 180000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'deviant', name = 'Deviant', brand = 'Schyster', price = 70000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dominator', name = 'Dominator', brand = 'Vapid', price = 62500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dominator2', name = 'Pißwasser Dominator', brand = 'Vapid', price = 50000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dominator3', name = 'Dominator GTX', brand = 'Vapid', price = 70000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dominator4', name = 'Dominator Arena', brand = 'Vapid', price = 200000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dominator7', name = 'Dominator ASP', brand = 'Vapid', price = 110000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dominator8', name = 'Dominator GTT', brand = 'Vapid', price = 80000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dukes', name = 'Dukes', brand = 'Imponte', price = 23500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dukes2', name = 'Duke O\'Death', brand = 'Imponte', price = 60000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dukes3', name = 'Beater Dukes', brand = 'Imponte', price = 45000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'faction', name = 'Faction', brand = 'Willard', price = 17000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'faction2', name = 'Faction Rider', brand = 'Willard', price = 19000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'faction3', name = 'Faction Custom Donk', brand = 'Willard', price = 35000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'ellie', name = 'Ellie', brand = 'Vapid', price = 42250, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'gauntlet', name = 'Gauntlet', brand = 'Bravado', price = 28500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'gauntlet2', name = 'Redwood Gauntlet', brand = 'Bravado', price = 70000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'gauntlet3', name = 'Classic Gauntlet', brand = 'Bravado', price = 75000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'gauntlet4', name = 'Gauntlet Hellfire', brand = 'Bravado', price = 80000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'gauntlet5', name = 'Gauntlet Classic Custom', brand = 'Bravado', price = 120000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'hermes', name = 'Hermes', brand = 'Albany', price = 535000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'hotknife', name = 'Hotknife', brand = 'Vapid', price = 90000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'hustler', name = 'Hustler', brand = 'Vapid', price = 95000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'impaler', name = 'Impaler', brand = 'Vapid', price = 95000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'impaler2', name = 'Impaler Arena', brand = 'Vapid', price = 95000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'impaler3', name = 'Impaler Future Shock', brand = 'Vapid', price = 95000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'impaler4', name = 'Impaler Nightmare', brand = 'Vapid', price = 95000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'imperator', name = 'Imperator Arena', brand = 'Vapid', price = 95000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'imperator2', name = 'imperator Future Shock', brand = 'Vapid', price = 95000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'imperator3', name = 'Imperator Nightmare', brand = 'Vapid', price = 95000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'lurcher', name = 'Lurcher', brand = 'Bravado', price = 21000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'nightshade', name = 'Nightshade', brand = 'Imponte', price = 70000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'phoenix', name = 'Phoenix', brand = 'Imponte', price = 65000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'picador', name = 'Picador', brand = 'Cheval', price = 20000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'ratloader2', name = 'Ratloader', brand = 'Ratloader2', price = 20000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'ruiner', name = 'Ruiner', brand = 'Imponte', price = 29000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'ruiner2', name = 'Ruiner 2000', brand = 'Imponte', price = 50000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'sabregt', name = 'Sabre GT Turbo', brand = 'Declasse', price = 23000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'sabregt2', name = 'Sabre GT Turbo Custom', brand = 'Declasse', price = 26500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'slamvan', name = 'Slam Van', brand = 'Vapid', price = 30000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'slamvan2', name = 'Lost Slam Van', brand = 'Vapid', price = 90000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'slamvan3', name = 'Slam Van Custom', brand = 'Vapid', price = 17000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'stalion', name = 'Stallion', brand = 'Declasse', price = 33000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'stalion2', name = 'Stallion Burgershot', brand = 'Declasse', price = 40000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'tampa', name = 'Tampa', brand = 'Declasse', price = 24500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'tulip', name = 'Tulip', brand = 'Declasse', price = 80000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'vamos', name = 'Vamos', brand = 'Declasse', price = 30000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'vigero', name = 'Vigero', brand = 'Declasse', price = 39500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'virgo', name = 'Virgo', brand = 'Albany', price = 22000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'virgo2', name = 'Virgo Custom Classic', brand = 'Dundreary', price = 21000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'virgo3', name = 'Virgo Classic', brand = 'Dundreary', price = 21000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'voodoo', name = 'Voodoo', brand = 'Declasse', price = 13000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'yosemite', name = 'Yosemite', brand = 'Declasse', price = 19500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'yosemite2', name = 'Yosemite Drift', brand = 'Declasse', price = 55000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'buffalo4', name = 'Buffalo STX', brand = 'Bravado', price = 345000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'manana', name = 'Manana', brand = 'Albany', price = 12800, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'manana2', name = 'Manana Custom', brand = 'Albany', price = 24000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'tampa2', name = 'Drift Tampa', brand = 'Declasse', price = 80000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'ruiner4', name = 'Ruiner ZZ-8', brand = 'Imponte', price = 85000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'vigero2', name = 'Vigero ZX', brand = 'Declasse', price = 105000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'weevil2', name = 'Weevil Custom', brand = 'BF', price = 95000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'buffalo5', name = 'Buffalo EVX', brand = 'Bravado', price = 214000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'tulip2', name = 'Tulip M-100', brand = 'Declasse', price = 80000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'clique2', name = 'Clique Wagon', brand = 'Vapid', price = 102500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'brigham', name = 'Brigham', brand = 'Albany', price = 149900, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'greenwood', name = 'Greenwood', brand = 'Bravado', price = 105000, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dominator9', name = 'Dominator GT', brand = 'Vapid', price = 219500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'impaler6', name = 'Impaler LX', brand = 'Declasse', price = 146500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'vigero3', name = 'Vigero ZX Convertible', brand = 'Declasse', price = 229500, category = 'muscle', type = 'automobile', shop = 'pdm' },
|
||||
--- Sports Classic (5)
|
||||
{ model = 'ardent', name = 'Ardent', brand = 'Ocelot', price = 30000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'btype', name = 'Roosevelt', brand = 'Albany', price = 75000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'btype2', name = 'Franken Stange', brand = 'Albany', price = 87000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'btype3', name = 'Roosevelt Valor', brand = 'Albany', price = 63000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'casco', name = 'Casco', brand = 'Lampadati', price = 100000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'deluxo', name = 'Deluxo', brand = 'Imponte', price = 55000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dynasty', name = 'Dynasty', brand = 'Weeny', price = 25000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'fagaloa', name = 'Fagaloa', brand = 'Vulcar', price = 13000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'feltzer3', name = 'Stirling GT', brand = 'Benefactor', price = 115000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'gt500', name = 'GT500', brand = 'Grotti', price = 130000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'infernus2', name = 'Infernus Classic', brand = 'Pegassi', price = 245000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'jb700', name = 'JB 700', brand = 'Dewbauchee', price = 240000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'jb7002', name = 'JB 700W', brand = 'Dewbauchee', price = 40000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'mamba', name = 'Mamba', brand = 'Declasse', price = 140000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'michelli', name = 'Michelli GT', brand = 'Lampadati', price = 30000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'monroe', name = 'Monroe', brand = 'Pegassi', price = 115000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'nebula', name = 'Nebula', brand = 'Vulcar', price = 22000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'peyote', name = 'Peyote', brand = 'Vapid', price = 23500, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'peyote3', name = 'Peyote Custom', brand = 'Vapid', price = 48000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'pigalle', name = 'Pigalle', brand = 'Lampadati', price = 92000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'rapidgt3', name = 'Rapid GT Classic', brand = 'Dewbauchee', price = 90000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'retinue', name = 'Retinue', brand = 'Vapid', price = 32000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'retinue2', name = 'Retinue MKII', brand = 'Vapid', price = 38000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'savestra', name = 'Savestra', brand = 'Annis', price = 67000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'stinger', name = 'Stinger', brand = 'Grotti', price = 39500, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'stingergt', name = 'Stinger GT', brand = 'Grotti', price = 70000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'stromberg', name = 'Stromberg', brand = 'Ocelot', price = 80000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'swinger', name = 'Swinger', brand = 'Ocelot', price = 221000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'torero', name = 'Torero', brand = 'Pegassi', price = 84000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'tornado', name = 'Tornado', brand = 'Declasse', price = 21000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'tornado2', name = 'Tornado Convertible', brand = 'Declasse', price = 22000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'tornado5', name = 'Tornado Custom', brand = 'Declasse', price = 22000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'turismo2', name = 'Turismo Classic', brand = 'Grotti', price = 170000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'viseris', name = 'Viseris', brand = 'Lampadati', price = 210000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'z190', name = '190Z', brand = 'Karin', price = 78000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'ztype', name = 'Z-Type', brand = 'Truffade', price = 270000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'zion3', name = 'Zion Classic', brand = 'Übermacht', price = 45000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'cheburek', name = 'Cheburek', brand = 'Rune', price = 7000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'toreador', name = 'Toreador', brand = 'Pegassi', price = 50000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'peyote2', name = 'Peyote Gasser', brand = 'Vapid', price = 40000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'coquette2', name = 'Coquette Classic', brand = 'Invetero', price = 165000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'envisage', name = 'Envisage', brand = 'Bollokan', price = 190000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'driftnebula', name = 'Nebula Turbo', brand = 'Vulcar', price = 100000, category = 'sportsclassics', type = 'automobile', shop = 'pdm' },
|
||||
--- Sports (6)
|
||||
{ model = 'alpha', name = 'Alpha', brand = 'Albany', price = 53000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'banshee', name = 'Banshee', brand = 'Bravado', price = 56000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'bestiagts', name = 'Bestia GTS', brand = 'Grotti', price = 37000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'buffalo', name = 'Buffalo', brand = 'Bravado', price = 18750, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'buffalo2', name = 'Buffalo S', brand = 'Bravado', price = 24500, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'carbonizzare', name = 'Carbonizzare', brand = 'Grotti', price = 155000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'comet2', name = 'Comet', brand = 'Pfister', price = 130000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'comet3', name = 'Comet Retro Custom', brand = 'Pfister', price = 175000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'comet4', name = 'Comet Safari', brand = 'Pfister', price = 110000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'comet5', name = 'Comet SR', brand = 'Pfister', price = 155000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'coquette', name = 'Coquette', brand = 'Invetero', price = 145000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'coquette4', name = 'Coquette D10', brand = 'Invetero', price = 220000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'drafter', name = '8F Drafter', brand = 'Obey', price = 80000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'elegy', name = 'Elegy Retro Custom', brand = 'Annis', price = 145000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'elegy2', name = 'Elegy RH8', brand = 'Annis', price = 150000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'feltzer2', name = 'Feltzer', brand = 'Benefactor', price = 97000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'flashgt', name = 'Flash GT', brand = 'Vapid', price = 48000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'furoregt', name = 'Furore GT', brand = 'Lampadati', price = 78000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'gb200', name = 'GB 200', brand = 'Vapid', price = 140000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'komoda', name = 'Komoda', brand = 'Lampadati', price = 55000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'imorgon', name = 'Imorgon', brand = 'Överflöd', price = 120000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'italigto', name = 'Itali GTO', brand = 'Progen', price = 260000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'jugular', name = 'Jugular', brand = 'Ocelot', price = 80000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'jester', name = 'Jester', brand = 'Dinka', price = 132250, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'jester2', name = 'Jester Racecar', brand = 'Dinka', price = 210000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'jester3', name = 'Jester Classic', brand = 'Dinka', price = 85000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'khamelion', name = 'Khamelion', brand = 'Hijak', price = 90000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'kuruma', name = 'Kuruma', brand = 'Karin', price = 72000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'kuruma2', name = 'kuruma2', brand = 'Karin2', price = 72000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'locust', name = 'Locust', brand = 'Ocelot', price = 200000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'lynx', name = 'Lynx', brand = 'Ocelot', price = 150000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'massacro', name = 'Massacro', brand = 'Dewbauchee', price = 110000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'massacro2', name = 'Massacro Racecar', brand = 'Dewbauchee', price = 80000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'neo', name = 'Neo', brand = 'Vysser', price = 230000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'neon', name = 'Neon', brand = 'Pfister', price = 220000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'ninef', name = '9F', brand = 'Obey', price = 95000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'ninef2', name = '9F Cabrio', brand = 'Obey', price = 105000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'omnis', name = 'Omnis', brand = 'Wow', price = 90000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'paragon', name = 'Paragon', brand = 'Enus', price = 60000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'pariah', name = 'Pariah', brand = 'Ocelot', price = 90000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'penumbra', name = 'Penumbra', brand = 'Maibatsu', price = 22000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'penumbra2', name = 'Penumbra FF', brand = 'Maibatsu', price = 30000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'rapidgt', name = 'Rapid GT', brand = 'Dewbauchee', price = 86000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'rapidgt2', name = 'Rapid GT Convertible', brand = 'Dewbauchee', price = 92000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'raptor', name = 'Raptor', brand = 'BF', price = 90000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'revolter', name = 'Revolter', brand = 'Übermacht', price = 95000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'ruston', name = 'Ruston', brand = 'Hijak', price = 130000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'schafter3', name = 'Schafter V12', brand = 'Benefactor', price = 35000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'schafter4', name = 'Schafter LWB', brand = 'Benefactor', price = 21000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'schlagen', name = 'Schlagen GT', brand = 'Benefactor', price = 160000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'schwarzer', name = 'Schwartzer', brand = 'Benefactor', price = 47000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'seven70', name = 'Seven-70', brand = 'Dewbauchee', price = 140000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'specter', name = 'Specter', brand = 'Dewbauchee', price = 160000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'streiter', name = 'Streiter', brand = 'Benefactor', price = 40000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'sugoi', name = 'Sugoi', brand = 'Dinka', price = 85000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'sultan', name = 'Sultan', brand = 'Karin', price = 50000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'sultan2', name = 'Sultan Custom', brand = 'Karin', price = 55000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'surano', name = 'Surano', brand = 'Benefactor', price = 80000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'tropos', name = 'Tropos Rallye', brand = 'Lampadati', price = 65000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'verlierer2', name = 'Verlierer', brand = 'Bravado', price = 90500, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'vstr', name = 'V-STR', brand = 'Albany', price = 80000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'italirsx', name = 'Itali RSX', brand = 'Progen', price = 260000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'zr350', name = 'ZR350', brand = 'Annis', price = 38000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'calico', name = 'Calico GTF', brand = 'Karin', price = 39000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'futo2', name = 'Futo GTX', brand = 'Karin', price = 39000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'euros', name = 'Euros', brand = 'Annis', price = 80000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'jester4', name = 'Jester RR', brand = 'Dinka', price = 240000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'remus', name = 'Remus', brand = 'Annis', price = 48000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'comet6', name = 'Comet S2', brand = 'Pfister', price = 230000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'growler', name = 'Growler', brand = 'Pfister', price = 205000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'vectre', name = 'Vectre', brand = 'Emperor', price = 80000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'cypher', name = 'Cypher', brand = 'Übermacht', price = 155000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'sultan3', name = 'Sultan Classic Custom', brand = 'Karin', price = 56000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'rt3000', name = 'RT3000', brand = 'Dinka', price = 65000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'sultanrs', name = 'Sultan RS', brand = 'Karin', price = 76500, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'visione', name = 'Visione', brand = 'Grotti', price = 750000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'cheetah2', name = 'Cheetah Classic', brand = 'Grotti', price = 195000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'stingertt', name = 'Itali GTO Stinger TT', brand = 'Maibatsu', price = 238000, category = 'sports', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'omnisegt', name = 'Omnis e-GT', brand = 'Obey', price = 185000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'sentinel4', name = 'Sentinel Classic Widebody', brand = 'Übermacht', price = 140000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'sm722', name = 'SM722', brand = 'Benefactor', price = 125000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'tenf', name = '10F', brand = 'Obey', price = 185000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'tenf2', name = '10F Widebody', brand = 'Obey', price = 215000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'everon2', name = 'Everon Hotring', brand = 'Karin', price = 80000, category = 'sports', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'issi8', name = 'Issi Rally', brand = 'Weeny', price = 10000, category = 'sports', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'corsita', name = 'Corsita', brand = 'Lampadati', price = 90000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'gauntlet6', name = 'Hotring Hellfire', brand = 'Bravado', price = 181000, category = 'sports', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'coureur', name = 'La Coureuse', brand = 'Penaud', price = 199000, category = 'sports', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'r300', name = '300R', brand = 'Annis', price = 56000, category = 'sports', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'panthere', name = 'Panthere', brand = 'Toundra', price = 55000, category = 'sports', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'driftsentinel', name = 'Drift Sentinel Classic', brand = 'Ubermacht', price = 150000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'paragon3', name = 'Paragon S', brand = 'Enus', price = 220000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'eurosX32', name = 'Euros X32', brand = 'Annis', price = 180000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'vorschlaghammer', name = 'Vorschlaghammer', brand = 'Pfister', price = 250000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'driftcypher', name = 'Drift Cypher', brand = 'Ubermacht', price = 160000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'coquette5', name = 'Coquette D1', brand = 'Invetero', price = 220000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'pipistrello', name = 'Pipistrello', brand = 'Overflod', price = 240000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'niobe', name = 'Niobe', brand = 'Ubermacht', price = 180000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'driftvorschlag', name = 'Vorschlaghammer', brand = 'Pfister', price = 250000, category = 'sports', type = 'automobile', shop = 'luxury' },
|
||||
--- Super (7)
|
||||
{ model = 'adder', name = 'Adder', brand = 'Truffade', price = 280000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'autarch', name = 'Autarch', brand = 'Överflöd', price = 224000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'banshee2', name = 'Banshee 900R', brand = 'Bravado', price = 120000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'bullet', name = 'Bullet', brand = 'Vapid', price = 120000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'cheetah', name = 'Cheetah', brand = 'Grotti', price = 214000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'cyclone', name = 'Cyclone', brand = 'Coil', price = 300000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'entity2', name = 'Entity XXR', brand = 'Överflöd', price = 164000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'entityxf', name = 'Entity XF', brand = 'Överflöd', price = 180000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'emerus', name = 'Emerus', brand = 'Progen', price = 220000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'fmj', name = 'FMJ', brand = 'Vapid', price = 125000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'furia', name = 'Furia', brand = 'Grotti', price = 230000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'gp1', name = 'GP1', brand = 'Progen', price = 110000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'infernus', name = 'Infernus', brand = 'Pegassi', price = 235000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'italigtb', name = 'Itali GTB', brand = 'Progen', price = 170000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'italigtb2', name = 'Itali GTB Custom', brand = 'Progen', price = 250000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'krieger', name = 'Krieger', brand = 'Benefactor', price = 222000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'le7b', name = 'RE-7B', brand = 'Annis', price = 260000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'nero', name = 'Nero', brand = 'Truffade', price = 200000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'nero2', name = 'Nero Custom', brand = 'Truffade', price = 260000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'osiris', name = 'Osiris', brand = 'Pegassi', price = 220000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'penetrator', name = 'Penetrator', brand = 'Ocelot', price = 130000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'pfister811', name = '811', brand = 'Pfister', price = 220000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'prototipo', name = 'X80 Proto', brand = 'Grotti', price = 235000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'reaper', name = 'Reaper', brand = 'Pegassi', price = 100000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 's80', name = 'S80RR', brand = 'Annis', price = 205000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'sc1', name = 'SC1', brand = 'Übermacht', price = 90000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'sheava', name = 'ETR1', brand = 'Emperor', price = 220000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 't20', name = 'T20', brand = 'Progen', price = 1650000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'taipan', name = 'Taipan', brand = 'Cheval', price = 1850000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'tempesta', name = 'Tempesta', brand = 'Pegassi', price = 120000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'tezeract', name = 'Tezeract', brand = 'Pegassi', price = 220000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'thrax', name = 'Thrax', brand = 'Truffade', price = 180000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'tigon', name = 'Tigon', brand = 'Lampadati', price = 240000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'turismor', name = 'Turismo R', brand = 'Grotti', price = 140000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'tyrant', name = 'Tyrant', brand = 'Överflöd', price = 2100000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'tyrus', name = 'Tyrus', brand = 'Progen', price = 230000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'vacca', name = 'Vacca', brand = 'Pegassi', price = 105000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'vagner', name = 'Vagner', brand = 'Dewbauchee', price = 1660000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'voltic', name = 'Voltic', brand = 'Coil', price = 120000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'voltic2', name = 'Rocket Voltic', brand = 'Coil', price = 9830400, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'xa21', name = 'XA-21', brand = 'Ocelot', price = 180000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'zentorno', name = 'Zentorno', brand = 'Pegassi', price = 340000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'zorrusso', name = 'Zorrusso', brand = 'Pegassi', price = 277000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'ignus', name = 'Ignus', brand = 'Pegassi', price = 1120000, category = 'super', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'zeno', name = 'Zeno', brand = 'Överflöd', price = 1350000, category = 'super', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'deveste', name = 'Deveste', brand = 'Principe', price = 234000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'lm87', name = 'LM87', brand = 'Benefactor', price = 155000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'torero2', name = 'Torero XO', brand = 'Pegassi', price = 245000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'entity3', name = 'Entity MT', brand = 'Overflod', price = 200000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'virtue', name = 'Virtue', brand = 'Ocelot', price = 72000, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
{ model = 'turismo3', name = 'Turismo Omaggio', brand = 'Grotti', price = 284500, category = 'super', type = 'automobile', shop = 'luxury' },
|
||||
--- Motorcycles (8)
|
||||
{ model = 'akuma', name = 'Akuma', brand = 'Dinka', price = 55000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'avarus', name = 'Avarus', brand = 'LCC', price = 20000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'bagger', name = 'Bagger', brand = 'WMC', price = 13500, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'bati', name = 'Bati 801', brand = 'Pegassi', price = 24000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'bati2', name = 'Bati 801RR', brand = 'Pegassi', price = 19000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'bf400', name = 'BF400', brand = 'Nagasaki', price = 22000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'carbonrs', name = 'Carbon RS', brand = 'Nagasaki', price = 22000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'chimera', name = 'Chimera', brand = 'Nagasaki', price = 21000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'cliffhanger', name = 'Cliffhanger', brand = 'Western', price = 28500, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'daemon', name = 'Daemon', brand = 'WMC', price = 14000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'daemon2', name = 'Daemon Custom', brand = 'Western', price = 23000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'defiler', name = 'Defiler', brand = 'Shitzu', price = 30000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'deathbike', name = 'Deathbike Apocalypse', brand = 'Deathbike', price = 30000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'deathbike2', name = 'Deathbike Future Shock', brand = 'Deathbike', price = 30000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'deathbike3', name = 'Deathbike Nightmare', brand = 'Deathbike', price = 30000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'diablous', name = 'Diablous', brand = 'Principe', price = 30000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'diablous2', name = 'Diablous Custom', brand = 'Principe', price = 38000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'double', name = 'Double-T', brand = 'Dinka', price = 28000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'enduro', name = 'Enduro', brand = 'Dinka', price = 5500, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'esskey', name = 'Esskey', brand = 'Pegassi', price = 12000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'faggio', name = 'Faggio Sport', brand = 'Pegassi', price = 2000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'faggio2', name = 'Faggio', brand = 'Pegassi', price = 1900, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'faggio3', name = 'Faggio Mod', brand = 'Pegassi', price = 2500, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'fcr', name = 'FCR 1000', brand = 'Pegassi', price = 5000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'fcr2', name = 'FCR 1000 Custom', brand = 'Pegassi', price = 19000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'gargoyle', name = 'Gargoyle', brand = 'Western', price = 32000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'hakuchou', name = 'Hakuchou', brand = 'Shitzu', price = 17000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'hakuchou2', name = 'Hakuchou Drag', brand = 'Shitzu', price = 45000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'hexer', name = 'Hexer', brand = 'LCC', price = 16000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'innovation', name = 'Innovation', brand = 'LLC', price = 33500, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'lectro', name = 'Lectro', brand = 'Principe', price = 28000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'manchez', name = 'Manchez', brand = 'Maibatsu', price = 8300, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'nemesis', name = 'Nemesis', brand = 'Principe', price = 20000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'nightblade', name = 'Nightblade', brand = 'WMC', price = 23000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'oppressor', name = 'Oppressor', brand = 'Pegassi', price = 9999999, category = 'motorcycles', type = 'bike', shop = 'luxury' },
|
||||
{ model = 'pcj', name = 'PCJ-600', brand = 'Shitzu', price = 15000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'ratbike', name = 'Rat Bike', brand = 'Western', price = 3000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'ruffian', name = 'Ruffian', brand = 'Pegassi', price = 25000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'sanchez', name = 'Sanchez Livery', brand = 'Maibatsu', price = 5300, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'sanchez2', name = 'Sanchez', brand = 'Maibatsu', price = 5300, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'sanctus', name = 'Sanctus', brand = 'LCC', price = 35000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'shotaro', name = 'Shotaro', brand = 'Nagasaki', price = 320000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'sovereign', name = 'Sovereign', brand = 'WMC', price = 8000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'stryder', name = 'Stryder', brand = 'Nagasaki', price = 50000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'thrust', name = 'Thrust', brand = 'Dinka', price = 22000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'vader', name = 'Vader', brand = 'Shitzu', price = 7200, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'vindicator', name = 'Vindicator', brand = 'Dinka', price = 19000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'vortex', name = 'Vortex', brand = 'Pegassi', price = 31000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'wolfsbane', name = 'Wolfsbane', brand = 'Western', price = 14000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'zombiea', name = 'Zombie Bobber', brand = 'Western', price = 28000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'zombieb', name = 'Zombie Chopper', brand = 'Western', price = 27000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'manchez2', name = 'Manchez Scout', brand = 'Maibatsu', price = 14000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'shinobi', name = 'Shinobi', brand = 'Nagasaki', price = 25000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'reever', name = 'Reever', brand = 'Western', price = 25000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'manchez3', name = 'Manchez Scout Classic', brand = 'Maibatsu', price = 15000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'powersurge', name = 'Powersurge', brand = 'Western', price = 7000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'pizzaboy', name = 'Pizza Boy', brand = 'Pegassi', price = 50000, category = 'motorcycles', type = 'bike', shop = 'pdm' },
|
||||
--- Off-Road (9)
|
||||
{ model = 'bfinjection', name = 'Bf Injection', brand = 'Annis', price = 9000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'bifta', name = 'Bifta', brand = 'Annis', price = 15500, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'blazer', name = 'Blazer', brand = 'Annis', price = 7500, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'blazer2', name = 'Blazer Lifeguard', brand = 'Nagasaki', price = 7000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'blazer3', name = 'Blazer Hot Rod', brand = 'Nagasaki', price = 7000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'blazer4', name = 'Blazer Sport', brand = 'Annis', price = 9250, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'blazer5', name = 'Blazer Aqua', brand = 'Nagasaki', price = 40000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'brawler', name = 'Brawler', brand = 'Annis', price = 40000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'caracara', name = 'Caracara', brand = 'Vapid', price = 60000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'caracara2', name = 'Caracara 4x4', brand = 'Vapid', price = 80000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dubsta3', name = 'Dubsta 6x6', brand = 'Annis', price = 34000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'dune', name = 'Dune Buggy', brand = 'Annis', price = 14000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'everon', name = 'Everon', brand = 'Karin', price = 60000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'freecrawler', name = 'Freecrawler', brand = 'Canis', price = 24000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'hellion', name = 'Hellion', brand = 'Annis', price = 38000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'kalahari', name = 'Kalahari', brand = 'Canis', price = 14000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'kamacho', name = 'Kamacho', brand = 'Canis', price = 50000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'mesa3', name = 'Mesa Merryweather', brand = 'Canis', price = 400000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'outlaw', name = 'Outlaw', brand = 'Nagasaki', price = 15000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'rancherxl', name = 'Rancher XL', brand = 'Declasse', price = 24000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'rebel2', name = 'Rebel', brand = 'Vapid', price = 20000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'riata', name = 'Riata', brand = 'Vapid', price = 380000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'sandking', name = 'Sandking XL', brand = 'Vapid', price = 25000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'sandking2', name = 'Sandking SWB', brand = 'Vapid', price = 38000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'trophytruck', name = 'Trophy Truck', brand = 'Vapid', price = 60000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'trophytruck2', name = 'Desert Raid', brand = 'Vapid', price = 80000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'vagrant', name = 'Vagrant', brand = 'Maxwell', price = 50000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'verus', name = 'Verus', brand = 'Dinka', price = 20000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'winky', name = 'Winky', brand = 'Vapid', price = 10000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'yosemite3', name = 'Yosemite Rancher', brand = 'Declasse', price = 425000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'mesa', name = 'Mesa', brand = 'Canis', price = 12000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'ratel', name = 'Ratel', brand = 'Vapid', price = 199000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'l35', name = 'Walton L35', brand = 'Declasse', price = 167000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'monstrociti', name = 'MonstroCiti', brand = 'Maibatsu', price = 48000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'draugur', name = 'Draugur', brand = 'Declasse', price = 99000, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'terminus', name = 'Terminus', brand = 'Canis', price = 187750, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'yosemite4', name = 'Yosemite 1500', brand = 'Declasse', price = 187750, category = 'offroad', type = 'automobile', shop = 'pdm' },
|
||||
--- Industrial (10)
|
||||
{ model = 'guardian', name = 'Guardian', brand = 'Vapid', price = 30000, category = 'industrial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'mixer2', name = 'Mixer II', brand = 'HVY', price = 30000, category = 'industrial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'tiptruck2', name = 'Tipper II', brand = 'Brute', price = 30000, category = 'industrial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'tiptruck', name = 'Tipper', brand = 'Brute', price = 30000, category = 'industrial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'rubble', name = 'Rubble', brand = 'Jobuilt', price = 30000, category = 'industrial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'mixer', name = 'Mixer', brand = 'HVY', price = 30000, category = 'industrial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'flatbed', name = 'Flatbed Truck', brand = 'MTL', price = 30000, category = 'industrial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'dump', name = 'Dump Truck', brand = 'HVY', price = 30000, category = 'industrial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'bulldozer', name = 'Dozer', brand = 'HVY', price = 30000, category = 'industrial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'handler', name = 'Dock Handler', brand = 'HVY', price = 30000, category = 'industrial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'cutter', name = 'Cutter', brand = 'HVY', price = 30000, category = 'industrial', type = 'automobile', shop = 'truck' },
|
||||
--- Utility (11)
|
||||
{ model = 'slamtruck', name = 'Slam Truck', brand = 'Vapid', price = 100000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'caddy3', name = 'Caddy (Bunker)', brand = 'Nagasaki', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'caddy2', name = 'Caddy (Civilian)', brand = 'Nagasaki', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'caddy3', name = 'Caddy (Golf)', brand = 'Nagasaki', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'utillitruck', name = 'Utility Truck (Cherry Picker)', brand = 'Brute', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'utillitruck2', name = 'Utility Truck (Van)', brand = 'Brute', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'utillitruck3', name = 'Utility Truck (Contender)', brand = 'Vapid', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'tractor', name = 'Tractor', brand = 'Stanley', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'tractor2', name = 'Fieldmaster', brand = 'Stanley', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'tractor3', name = 'Fieldmaster', brand = 'Stanley', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'towtruck', name = 'Tow Truck (Large)', brand = 'Vapid', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'towtruck2', name = 'Tow Truck (Small)', brand = 'Vapid', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'scrap', name = 'Scrap Truck', brand = 'Vapid', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'sadler', name = 'Sadler', brand = 'Vapid', price = 20000, category = 'utility', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'ripley', name = 'Ripley', brand = 'HVY', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'mower', name = 'Lawn Mower', brand = 'Jacksheepe', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'forklift', name = 'Forklift', brand = 'HVY', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'docktug', name = 'Docktug', brand = 'HVY', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'airtug', name = 'Airtug', brand = 'HVY', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'trailers5', name = 'Trailer (Christmas)', brand = 'Unknown', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'tvtrailer2', name = 'Trailer (TV)', brand = 'Unknown', price = 30000, category = 'utility', type = 'automobile', shop = 'truck' },
|
||||
--- Vans (12)
|
||||
{ model = 'bison', name = 'Bison', brand = 'Bravado', price = 18000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'bobcatxl', name = 'Bobcat XL Open', brand = 'Vapid', price = 13500, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'burrito3', name = 'Burrito', brand = 'Declasse', price = 4000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'gburrito2', name = 'Burrito Custom', brand = 'Declasse', price = 11500, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'rumpo', name = 'Rumpo', brand = 'Bravado', price = 9000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'journey', name = 'Journey', brand = 'Zirconium', price = 6500, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'minivan', name = 'Minivan', brand = 'Vapid', price = 7000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'minivan2', name = 'Minivan Custom', brand = 'Vapid', price = 10000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'paradise', name = 'Paradise', brand = 'Bravado', price = 9000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'rumpo3', name = 'Rumpo Custom', brand = 'Bravado', price = 19500, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'speedo', name = 'Speedo', brand = 'Vapid', price = 10000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'speedo4', name = 'Speedo Custom', brand = 'Vapid', price = 15000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'surfer', name = 'Surfer', brand = 'BF', price = 9000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'youga3', name = 'Youga Classic 4x4', brand = 'Bravado', price = 15000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'youga', name = 'Youga', brand = 'Bravado', price = 8000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'youga2', name = 'Youga Classic', brand = 'Bravado', price = 14500, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'youga4', name = 'Youga Custom', brand = 'Bravado', price = 85000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'moonbeam', name = 'Moonbeam', brand = 'Declasse', price = 13000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'moonbeam2', name = 'Moonbeam Custom', brand = 'Declasse', price = 15000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'boxville', name = 'Boxville LSDWP', brand = 'Brute', price = 45000, category = 'vans', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'boxville2', name = 'Boxville Go Postal', brand = 'Brute', price = 45000, category = 'vans', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'boxville3', name = 'Boxville Humane Labs', brand = 'Brute', price = 45000, category = 'vans', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'boxville4', name = 'Boxville Post OP', brand = 'Brute', price = 45000, category = 'vans', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'boxville5', name = 'Armored Boxville', brand = 'Brute', price = 45000, category = 'vans', type = 'automobile', shop = 'none' },
|
||||
{ model = 'pony', name = 'Pony', brand = 'Brute', price = 45000, category = 'vans', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'pony2', name = 'Pony (Smoke on the water)', brand = 'Brute', price = 45000, category = 'vans', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'journey2', name = 'Journey II', brand = 'Zirconium', price = 7000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'surfer3', name = 'Surfer Custom', brand = 'BF', price = 15000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'speedo5', name = 'Speedo Custom', brand = 'Vapid', price = 238000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'mule2', name = 'Mule', brand = 'Maibatsu', price = 40000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'mule3', name = 'Mule', brand = 'Maibatsu', price = 40000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'taco', name = 'Taco Truck', brand = 'Brute', price = 45000, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
{ model = 'boxville6', name = 'Boxville (LSDS)', brand = 'Brute', price = 47500, category = 'vans', type = 'automobile', shop = 'pdm' },
|
||||
--- Cycles (13)
|
||||
{ model = 'bmx', name = 'BMX', brand = 'Bike', price = 160, category = 'cycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'cruiser', name = 'Cruiser', brand = 'Bike', price = 510, category = 'cycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'fixter', name = 'Fixter', brand = 'Bike', price = 225, category = 'cycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'scorcher', name = 'Scorcher', brand = 'Bike', price = 280, category = 'cycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'tribike', name = 'Whippet Race Bike', brand = 'Bike', price = 500, category = 'cycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'tribike2', name = 'Endurex Race Bike', brand = 'Bike', price = 700, category = 'cycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'tribike3', name = 'Tri-Cycles Race Bike', brand = 'Bike', price = 520, category = 'cycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'inductor', name = 'Inductor', brand = 'Coil', price = 5000, category = 'cycles', type = 'bike', shop = 'pdm' },
|
||||
{ model = 'inductor2', name = 'Junk Energy Inductor', brand = 'Coil', price = 5000, category = 'cycles', type = 'bike', shop = 'pdm' },
|
||||
--- Boats (14)
|
||||
{ model = 'avisa', name = 'Avisa', brand = 'Kraken Subs', price = 40000, category = 'boats', type = 'boat', shop = 'none' },
|
||||
{ model = 'patrolboat', name = 'Kurtz 31 Patrol Boat', brand = 'Unknown', price = 40000, category = 'boats', type = 'boat', shop = 'none' },
|
||||
{ model = 'longfin', name = 'Longfin', brand = 'Shitzu', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'tug', name = 'Tug', brand = 'Buckingham', price = 40000, category = 'boats', type = 'boat', shop = 'none' },
|
||||
{ model = 'toro', name = 'Toro', brand = 'Lampadati', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'toro2', name = 'Toro Yacht', brand = 'Lampadati', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'submersible2', name = 'Kraken', brand = 'Kraken Subs', price = 40000, category = 'boats', type = 'boat', shop = 'none' },
|
||||
{ model = 'speeder', name = 'Speeder', brand = 'Pegassi', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'speeder2', name = 'Speeder Yacht', brand = 'Pegassi', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'tropic', name = 'Tropic', brand = 'Shitzu', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'tropic2', name = 'Tropic Yacht', brand = 'Shitzu', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'suntrap', name = 'Suntrap', brand = 'Shitzu', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'submersible', name = 'Submersible', brand = 'Kraken Subs', price = 40000, category = 'boats', type = 'boat', shop = 'none' },
|
||||
{ model = 'squalo', name = 'Squalo', brand = 'Shitzu', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'seashark', name = 'Seashark', brand = 'Speedophile', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'seashark3', name = 'Seashark Yacht', brand = 'Speedophile', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'marquis', name = 'Marquis', brand = 'Dinka', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'jetmax', name = 'Jetmax', brand = 'Shitzu', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'dinghy', name = 'Dinghy 2-Seater', brand = 'Nagasaki', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'dinghy2', name = 'Dinghy 4-Seater', brand = 'Nagasaki', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'dinghy3', name = 'Dinghy (Heist)', brand = 'Nagasaki', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
{ model = 'dinghy4', name = 'Dinghy Yacht', brand = 'Nagasaki', price = 40000, category = 'boats', type = 'boat', shop = 'boats' },
|
||||
--- Helicopters (15)
|
||||
{ model = 'conada2', name = 'Weaponized Conada', brand = 'Buckingham', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'conada', name = 'Conada', brand = 'Buckingham', price = 115000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'seasparrow2', name = 'Sparrow', brand = 'Unknown', price = 52000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'annihilator2', name = 'Annihilator Stealth', brand = 'Western Company', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'seasparrow', name = 'Sea Sparrow', brand = 'Unknown', price = 52000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'akula', name = 'Akula', brand = 'Unknown', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'hunter', name = 'FH-1 Hunter', brand = 'Unknown', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'havok', name = 'Havok', brand = 'Nagasaki', price = 52000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'volatus', name = 'Volatus', brand = 'Buckingham', price = 52000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'supervolito2', name = 'SuperVolito Carbon', brand = 'Buckingham', price = 52000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'supervolito', name = 'SuperVolito', brand = 'Buckingham', price = 52000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'swift2', name = 'Swift Deluxe', brand = 'Buckingham', price = 52000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'valkyrie', name = 'Valkyrie', brand = 'Buckingham', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'savage', name = 'Savage', brand = 'Unknown', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'swift', name = 'Swift', brand = 'Buckingham', price = 52000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'annihilator', name = 'Annihilator', brand = 'Western Company', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'cargobob2', name = 'Cargobob Jetsam', brand = 'Western Company', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'skylift', name = 'Skylift', brand = 'HVY', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'maverick', name = 'Maverick', brand = 'Buckingham', price = 52000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'frogger', name = 'Frogger', brand = 'Maibatsu', price = 52000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'frogger2', name = 'Frogger', brand = 'Maibatsu', price = 52000, category = 'helicopters', type = 'heli', shop = 'air' },
|
||||
{ model = 'cargobob', name = 'Cargobob', brand = 'Western Company', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'cargobob3', name = 'Cargobob', brand = 'Western Company', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'seasparrow3', name = 'Sparrow (Prop)', brand = 'Unknown', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'buzzard', name = 'Buzzard Attack Chopper', brand = 'Nagasaki', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
{ model = 'buzzard2', name = 'Buzzard', brand = 'Nagasaki', price = 52000, category = 'helicopters', type = 'heli', shop = 'none' },
|
||||
--- Planes (16)
|
||||
{ model = 'streamer216', name = 'Streamer216', brand = 'Mammoth', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'raiju', name = 'F-160 Raiju', brand = 'Mammoth', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'alkonost', name = 'RO-86 Alkonost', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'strikeforce', name = 'B-11 Strikeforce', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'blimp3', name = 'Blimp', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'avenger', name = 'Avenger', brand = 'Mammoth', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'avenger2', name = 'Avenger', brand = 'Mammoth', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'volatol', name = 'Volatol', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'nokota', name = 'P-45 Nokota', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'seabreeze', name = 'Seabreeze', brand = 'Western Company', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'pyro', name = 'Pyro', brand = 'Buckingham', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'mogul', name = 'Mogul', brand = 'Mammoth', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'howard', name = 'Howard NX-25', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'bombushka', name = 'RM-10 Bombushka', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'molotok', name = 'V-65 Molotok', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'microlight', name = 'Ultralight', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'tula', name = 'Tula', brand = 'Mammoth', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'rogue', name = 'Rogue', brand = 'Western Company', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'starling', name = 'LF-22 Starling', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'alphaz1', name = 'Alpha-Z1', brand = 'Buckingham', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'nimbus', name = 'Nimbus', brand = 'Buckingham', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'luxor2', name = 'Luxor Deluxe', brand = 'Buckingham', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'velum2', name = 'Velum 5-seater', brand = 'JoBuilt', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'hydra', name = 'Hydra', brand = 'Mammoth', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'blimp2', name = 'Xero Blimp', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'dodo', name = 'Dodo', brand = 'Mammoth', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'miljet', name = 'Miljet', brand = 'Buckingham', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'besra', name = 'Besra', brand = 'Western Company', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'vestra', name = 'Vestra', brand = 'Buckingham', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'cargoplane', name = 'Cargo Plane', brand = 'JoBuilt', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'velum', name = 'Velum', brand = 'JoBuilt', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'titan', name = 'Titan', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'shamal', name = 'Shamal', brand = 'Buckingham', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'lazer', name = 'P-996 Lazer', brand = 'JoBuilt', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'mammatus', name = 'Mammatus', brand = 'JoBuilt', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'stunt', name = 'Mallard', brand = 'Western Company', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'luxor', name = 'Luxor', brand = 'Buckingham', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'jet', name = 'Jet', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
{ model = 'duster', name = 'Duster', brand = 'Western Company', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'cuban800', name = 'Cuban 800', brand = 'Western Company', price = 45000, category = 'planes', type = 'plane', shop = 'air' },
|
||||
{ model = 'blimp', name = 'Atomic Blimp', brand = 'Unknown', price = 45000, category = 'planes', type = 'plane', shop = 'none' },
|
||||
--- Service (17)
|
||||
{ model = 'brickade', name = 'Brickade', brand = 'MTL', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'brickade2', name = 'Brickade 6x6', brand = 'MTL', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'pbus2', name = 'Festival Bus', brand = 'Unknown', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'wastelander', name = 'Wastelander', brand = 'MTL', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'rallytruck', name = 'Dune', brand = 'MTL', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'metrotrain', name = 'Metro Train', brand = 'Unknown', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'freight', name = 'Freight Train', brand = 'Unknown', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'cablecar', name = 'Cable Car', brand = 'Unknown', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'trash', name = 'Trashmaster', brand = 'JoBuilt', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'trash2', name = 'Trashmaster', brand = 'JoBuilt', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'tourbus', name = 'Tour Bus', brand = 'Brute', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'taxi', name = 'Taxi', brand = 'Vapid', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'rentalbus', name = 'Rental Shuttle Bus', brand = 'Brute', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'coach', name = 'Dashound', brand = 'Brute', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'bus', name = 'Bus', brand = 'Brute', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
{ model = 'airbus', name = 'Airport Bus', brand = 'Brute', price = 100000, category = 'service', type = 'automobile', shop = 'none' },
|
||||
--- Emergency (18)
|
||||
{ model = 'riot', name = 'Police Riot', brand = 'Brute', price = 100000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'riot2', name = 'RCV', brand = 'Unknown', price = 100000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'pbus', name = 'Police Prison Bus', brand = 'Vapid', price = 100000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'police', name = 'Police Cruiser', brand = 'Vapid', price = 100000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'police2', name = 'Police Buffalo', brand = 'Vapid', price = 100000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'police3', name = 'Police Interceptor', brand = 'Vapid', price = 100000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'police4', name = 'Unmarked Cruiser', brand = 'Vapid', price = 100000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'sheriff', name = 'Sheriff SUV', brand = 'Declasse', price = 100000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'sheriff2', name = 'Sheriff Cruiser', brand = 'Vapid', price = 100000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'policeold1', name = 'Police Rancher', brand = 'Declasse', price = 110000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'policeold2', name = 'Police Roadcruiser', brand = 'Albany', price = 110000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'policet', name = 'Police Transporter', brand = 'Vapid', price = 110000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'policeb', name = 'Police Bike', brand = 'Vapid', price = 110000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'polmav', name = 'Police Maverick', brand = 'Buckingham', price = 110000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'ambulance', name = 'Ambulance', brand = 'Brute', price = 110000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'firetruk', name = 'Fire Truck', brand = 'MTL', price = 110000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'lguard', name = 'Lifeguard', brand = 'Declasse', price = 110000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'seashark2', name = 'Seashark Lifeguard', brand = 'Speedophile', price = 40000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'pranger', name = 'Park Ranger', brand = 'Declasse', price = 40000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'fbi', name = 'FIB Buffalo', brand = 'Bravado', price = 40000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'fbi2', name = 'FIB Granger', brand = 'Declasse', price = 40000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'predator', name = 'Police Predator', brand = 'Unknown', price = 40000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'polgauntlet', name = 'Gauntlet Interceptor', brand = 'Bravado', price = 40000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'police5', name = 'Stanier LE Cruiser', brand = 'Vapid', price = 40000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'polimpaler5', name = 'Impaler SZ Cruiser', brand = 'Declasse', price = 80000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'polimpaler6', name = 'Impaler LX Cruiser', brand = 'Declasse', price = 90000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'poldominator10', name = 'Dominator FX Interceptor', brand = 'Vapid', price = 230000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'policet3', name = 'Burrito (Bail Enforcement)', brand = 'Declasse', price = 60000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'polgreenwood', name = 'Greenwood Cruiser', brand = 'Bravado', price = 80000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
{ model = 'poldorado', name = 'Dorado Cruiser', brand = 'Vapid', price = 80000, category = 'emergency', type = 'automobile', shop = 'none' },
|
||||
--- Military (19)
|
||||
{ model = 'vetir', name = 'Vetir', brand = 'Unknown', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'kosatka', name = 'Kosatka', brand = 'Rune', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'minitank', name = 'RC Tank', brand = 'Unknown', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'scarab', name = 'Scarab', brand = 'HVY', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'terbyte', name = 'Terrorbyte', brand = 'Benefactor', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'thruster', name = 'Thruster', brand = 'Mammoth', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'khanjali', name = 'TM-02 Khanjali Tank', brand = 'Unknown', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'chernobog', name = 'Chernobog', brand = 'HVY', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'barrage', name = 'Barrage', brand = 'HVY', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'trailerlarge', name = 'Mobile Operations Center', brand = 'Unknown', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'halftrack', name = 'Half-track', brand = 'Bravado', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'apc', name = 'APC Tank', brand = 'HVY', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'trailersmall2', name = 'Anti-Aircraft Trailer', brand = 'Vom Feuer', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'rhino', name = 'Rhino Tank', brand = 'Unknown', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'crusader', name = 'Crusader', brand = 'Canis', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'barracks', name = 'Barracks', brand = 'HVY', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'barracks2', name = 'Barracks Semi', brand = 'HVY', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
{ model = 'barracks3', name = 'Barracks', brand = 'HVY', price = 100000, category = 'military', type = 'automobile', shop = 'none' },
|
||||
--- Commercial (20)
|
||||
{ model = 'cerberus', name = 'Apocalypse Cerberus', brand = 'MTL', price = 100000, category = 'commercial', type = 'automobile', shop = 'none' },
|
||||
{ model = 'pounder2', name = 'Pounder Custom', brand = 'MTL', price = 55000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'mule4', name = 'Mule Custom', brand = 'Maibatsu', price = 40000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'phantom3', name = 'Phantom Custom', brand = 'Jobuilt', price = 110000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'hauler2', name = 'Hauler Custom', brand = 'Jobuilt', price = 100000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'phantom2', name = 'Phantom Wedge', brand = 'Jobuilt', price = 100000, category = 'commercial', type = 'automobile', shop = 'none' },
|
||||
{ model = 'mule5', name = 'Mule (Heist)', brand = 'Maibatsu', price = 40000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'stockade', name = 'Stockade', brand = 'Brute', price = 100000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'pounder', name = 'Pounder', brand = 'MTL', price = 55000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'phantom', name = 'Phantom', brand = 'Jobuilt', price = 100000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'packer', name = 'Packer', brand = 'MTL', price = 100000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'mule', name = 'Mule', brand = 'Maibatsu', price = 40000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'hauler', name = 'Hauler', brand = 'Jobuilt', price = 100000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'biff', name = 'Biff', brand = 'Brute', price = 100000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'benson', name = 'Benson', brand = 'Vapid', price = 55000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'benson2', name = 'Benson (Cluckin Bell)', brand = 'Vapid', price = 55000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
{ model = 'phantom4', name = 'Phantom (Christmas)', brand = 'Vapid', price = 100000, category = 'commercial', type = 'automobile', shop = 'truck' },
|
||||
--- Trains (21)
|
||||
--- Open Wheel (22)
|
||||
{ model = 'openwheel2', name = 'DR1', brand = 'Declasse', price = 100000, category = 'openwheel', type = 'automobile', shop = 'none' },
|
||||
{ model = 'openwheel1', name = 'BR8', brand = 'Benefactor', price = 100000, category = 'openwheel', type = 'automobile', shop = 'none' },
|
||||
{ model = 'formula2', name = 'R88', brand = 'Ocelot', price = 100000, category = 'openwheel', type = 'automobile', shop = 'none' },
|
||||
{ model = 'formula', name = 'PR4', brand = 'Progen', price = 100000, category = 'openwheel', type = 'automobile', shop = 'none' },
|
||||
}
|
||||
|
||||
QBShared.VehicleHashes = QBShared.VehicleHashes or {}
|
||||
for i = 1, #Vehicles do
|
||||
local hash = joaat(Vehicles[i].model)
|
||||
QBShared.Vehicles[Vehicles[i].model] = {
|
||||
spawncode = Vehicles[i].model,
|
||||
name = Vehicles[i].name,
|
||||
brand = Vehicles[i].brand,
|
||||
model = Vehicles[i].model,
|
||||
price = Vehicles[i].price,
|
||||
category = Vehicles[i].category,
|
||||
hash = hash,
|
||||
type = Vehicles[i].type,
|
||||
shop = Vehicles[i].shop
|
||||
}
|
||||
QBShared.VehicleHashes[hash] = QBShared.Vehicles[Vehicles[i].model]
|
||||
end
|
||||
@@ -0,0 +1,151 @@
|
||||
QBShared = QBShared or {}
|
||||
QBShared.Weapons = {
|
||||
-- // WEAPONS
|
||||
-- Melee
|
||||
[`weapon_unarmed`] = { name = 'weapon_unarmed', label = 'Fists', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_dagger`] = { name = 'weapon_dagger', label = 'Dagger', weapontype = 'Melee', ammotype = nil, damagereason = 'Knifed / Stabbed / Eviscerated' },
|
||||
[`weapon_bat`] = { name = 'weapon_bat', label = 'Bat', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_bottle`] = { name = 'weapon_bottle', label = 'Broken Bottle', weapontype = 'Melee', ammotype = nil, damagereason = 'Knifed / Stabbed / Eviscerated' },
|
||||
[`weapon_crowbar`] = { name = 'weapon_crowbar', label = 'Crowbar', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_flashlight`] = { name = 'weapon_flashlight', label = 'Flashlight', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_golfclub`] = { name = 'weapon_golfclub', label = 'Golfclub', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_hammer`] = { name = 'weapon_hammer', label = 'Hammer', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_hatchet`] = { name = 'weapon_hatchet', label = 'Hatchet', weapontype = 'Melee', ammotype = nil, damagereason = 'Knifed / Stabbed / Eviscerated' },
|
||||
[`weapon_knuckle`] = { name = 'weapon_knuckle', label = 'Knuckle', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_knife`] = { name = 'weapon_knife', label = 'Knife', weapontype = 'Melee', ammotype = nil, damagereason = 'Knifed / Stabbed / Eviscerated' },
|
||||
[`weapon_machete`] = { name = 'weapon_machete', label = 'Machete', weapontype = 'Melee', ammotype = nil, damagereason = 'Knifed / Stabbed / Eviscerated' },
|
||||
[`weapon_switchblade`] = { name = 'weapon_switchblade', label = 'Switchblade', weapontype = 'Melee', ammotype = nil, damagereason = 'Knifed / Stabbed / Eviscerated' },
|
||||
[`weapon_nightstick`] = { name = 'weapon_nightstick', label = 'Nightstick', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_wrench`] = { name = 'weapon_wrench', label = 'Wrench', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_battleaxe`] = { name = 'weapon_battleaxe', label = 'Battle Axe', weapontype = 'Melee', ammotype = nil, damagereason = 'Knifed / Stabbed / Eviscerated' },
|
||||
[`weapon_poolcue`] = { name = 'weapon_poolcue', label = 'Poolcue', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_briefcase`] = { name = 'weapon_briefcase', label = 'Briefcase', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_briefcase_02`] = { name = 'weapon_briefcase_02', label = 'Briefcase', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_garbagebag`] = { name = 'weapon_garbagebag', label = 'Garbage Bag', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_handcuffs`] = { name = 'weapon_handcuffs', label = 'Handcuffs', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_bread`] = { name = 'weapon_bread', label = 'Baquette', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee killed / Whacked / Executed / Beat down / Murdered / Battered' },
|
||||
[`weapon_stone_hatchet`] = { name = 'weapon_stone_hatchet', label = 'Stone Hatchet', weapontype = 'Melee', ammotype = nil, damagereason = 'Knifed / Stabbed / Eviscerated' },
|
||||
[`weapon_candycane`] = { name = 'weapon_candycane', label = 'Candy Cane', weapontype = 'Melee', ammotype = nil, damagereason = 'Melee Killed / Whacked / Executed / Beat down / Musrdered / Battered / Candy Caned' },
|
||||
|
||||
-- Handguns
|
||||
[`weapon_pistol`] = { name = 'weapon_pistol', label = 'Pistol', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_pistol_mk2`] = { name = 'weapon_pistol_mk2', label = 'Pistol Mk2', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_combatpistol`] = { name = 'weapon_combatpistol', label = 'Combat Pistol', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_appistol`] = { name = 'weapon_appistol', label = 'AP Pistol', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_stungun`] = { name = 'weapon_stungun', label = 'Taser', weapontype = 'Pistol', ammotype = 'AMMO_STUNGUN', damagereason = 'Died' },
|
||||
[`weapon_pistol50`] = { name = 'weapon_pistol50', label = 'Pistol .50 Cal', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_snspistol`] = { name = 'weapon_snspistol', label = 'SNS Pistol', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_snspistol_mk2`] = { name = 'weapon_snspistol_mk2', label = 'SNS Pistol MK2', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_heavypistol`] = { name = 'weapon_heavypistol', label = 'Heavy Pistol', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_vintagepistol`] = { name = 'weapon_vintagepistol', label = 'Vintage Pistol', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_flaregun`] = { name = 'weapon_flaregun', label = 'Flare Gun', weapontype = 'Pistol', ammotype = 'AMMO_FLARE', damagereason = 'Died' },
|
||||
[`weapon_marksmanpistol`] = { name = 'weapon_marksmanpistol', label = 'Marksman Pistol', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_revolver`] = { name = 'weapon_revolver', label = 'Revolver', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_revolver_mk2`] = { name = 'weapon_revolver_mk2', label = 'Revolver MK2', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_doubleaction`] = { name = 'weapon_doubleaction', label = 'Double Action Revolver', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_raypistol`] = { name = 'weapon_raypistol', label = 'Ray Pistol', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_ceramicpistol`] = { name = 'weapon_ceramicpistol', label = 'Ceramic Pistol', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_navyrevolver`] = { name = 'weapon_navyrevolver', label = 'Navy Revolver', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_gadgetpistol`] = { name = 'weapon_gadgetpistol', label = 'Gadget Pistol', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plugged / Bust a cap in' },
|
||||
[`weapon_stungun_mp`] = { name = 'weapon_stungun_mp', label = 'Taser', weapontype = 'Pistol', ammotype = 'AMMO_STUNGUN', damagereason = 'Died' },
|
||||
[`weapon_pistolxm3`] = { name = 'weapon_pistolxm3', label = 'Pistol XM3', weapontype = 'Pistol', ammotype = 'AMMO_PISTOL', damagereason = 'Pistoled / Blasted / Plaugged / Bust a cap in' },
|
||||
|
||||
-- Submachine Guns
|
||||
[`weapon_microsmg`] = { name = 'weapon_microsmg', label = 'Micro SMG', weapontype = 'Submachine Gun', ammotype = 'AMMO_SMG', damagereason = 'Riddled / Drilled / Finished / Submachine Gunned' },
|
||||
[`weapon_smg`] = { name = 'weapon_smg', label = 'SMG', weapontype = 'Submachine Gun', ammotype = 'AMMO_SMG', damagereason = 'Riddled / Drilled / Finished / Submachine Gunned' },
|
||||
[`weapon_smg_mk2`] = { name = 'weapon_smg_mk2', label = 'SMG MK2', weapontype = 'Submachine Gun', ammotype = 'AMMO_SMG', damagereason = 'Riddled / Drilled / Finished / Submachine Gunned' },
|
||||
[`weapon_assaultsmg`] = { name = 'weapon_assaultsmg', label = 'Assault SMG', weapontype = 'Submachine Gun', ammotype = 'AMMO_SMG', damagereason = 'Riddled / Drilled / Finished / Submachine Gunned' },
|
||||
[`weapon_combatpdw`] = { name = 'weapon_combatpdw', label = 'Combat PDW', weapontype = 'Submachine Gun', ammotype = 'AMMO_SMG', damagereason = 'Riddled / Drilled / Finished / Submachine Gunned' },
|
||||
[`weapon_machinepistol`] = { name = 'weapon_machinepistol', label = 'Tec-9', weapontype = 'Submachine Gun', ammotype = 'AMMO_PISTOL', damagereason = 'Riddled / Drilled / Finished / Submachine Gunned' },
|
||||
[`weapon_minismg`] = { name = 'weapon_minismg', label = 'Mini SMG', weapontype = 'Submachine Gun', ammotype = 'AMMO_SMG', damagereason = 'Riddled / Drilled / Finished / Submachine Gunned' },
|
||||
[`weapon_raycarbine`] = { name = 'weapon_raycarbine', label = 'Raycarbine', weapontype = 'Submachine Gun', ammotype = 'AMMO_SMG', damagereason = 'Riddled / Drilled / Finished / Submachine Gunned' },
|
||||
|
||||
-- Shotguns
|
||||
[`weapon_pumpshotgun`] = { name = 'weapon_pumpshotgun', label = 'Pump Shotgun', weapontype = 'Shotgun', ammotype = 'AMMO_SHOTGUN', damagereason = 'Devastated / Pulverized / Shotgunned' },
|
||||
[`weapon_pumpshotgun_mk2`] = { name = 'weapon_pumpshotgun_mk2', label = 'Pump Shotgun MK2', weapontype = 'Shotgun', ammotype = 'AMMO_SHOTGUN', damagereason = 'Devastated / Pulverized / Shotgunned' },
|
||||
[`weapon_sawnoffshotgun`] = { name = 'weapon_sawnoffshotgun', label = 'Sawn-off Shotgun', weapontype = 'Shotgun', ammotype = 'AMMO_SHOTGUN', damagereason = 'Devastated / Pulverized / Shotgunned' },
|
||||
[`weapon_assaultshotgun`] = { name = 'weapon_assaultshotgun', label = 'Assault Shotgun', weapontype = 'Shotgun', ammotype = 'AMMO_SHOTGUN', damagereason = 'Devastated / Pulverized / Shotgunned' },
|
||||
[`weapon_bullpupshotgun`] = { name = 'weapon_bullpupshotgun', label = 'Bullpup Shotgun', weapontype = 'Shotgun', ammotype = 'AMMO_SHOTGUN', damagereason = 'Devastated / Pulverized / Shotgunned' },
|
||||
[`weapon_musket`] = { name = 'weapon_musket', label = 'Musket', weapontype = 'Shotgun', ammotype = 'AMMO_SHOTGUN', damagereason = 'Devastated / Pulverized / Shotgunned' },
|
||||
[`weapon_heavyshotgun`] = { name = 'weapon_heavyshotgun', label = 'Heavy Shotgun', weapontype = 'Shotgun', ammotype = 'AMMO_SHOTGUN', damagereason = 'Devastated / Pulverized / Shotgunned' },
|
||||
[`weapon_dbshotgun`] = { name = 'weapon_dbshotgun', label = 'Double-barrel Shotgun', weapontype = 'Shotgun', ammotype = 'AMMO_SHOTGUN', damagereason = 'Devastated / Pulverized / Shotgunned' },
|
||||
[`weapon_autoshotgun`] = { name = 'weapon_autoshotgun', label = 'Auto Shotgun', weapontype = 'Shotgun', ammotype = 'AMMO_SHOTGUN', damagereason = 'Devastated / Pulverized / Shotgunned' },
|
||||
[`weapon_combatshotgun`] = { name = 'weapon_combatshotgun', label = 'Combat Shotgun', weapontype = 'Shotgun', ammotype = 'AMMO_SHOTGUN', damagereason = 'Devastated / Pulverized / Shotgunned' },
|
||||
|
||||
-- Assault Rifles
|
||||
[`weapon_assaultrifle`] = { name = 'weapon_assaultrifle', label = 'Assault Rifle', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
[`weapon_assaultrifle_mk2`] = { name = 'weapon_assaultrifle_mk2', label = 'Assault Rifle MK2', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
[`weapon_carbinerifle`] = { name = 'weapon_carbinerifle', label = 'Carbine Rifle', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
[`weapon_carbinerifle_mk2`] = { name = 'weapon_carbinerifle_mk2', label = 'Carbine Rifle MK2', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
[`weapon_advancedrifle`] = { name = 'weapon_advancedrifle', label = 'Advanced Rifle', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
[`weapon_specialcarbine`] = { name = 'weapon_specialcarbine', label = 'Special Carbine', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
[`weapon_specialcarbine_mk2`] = { name = 'weapon_specialcarbine_mk2', label = 'Specialcarbine MK2', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
[`weapon_bullpuprifle`] = { name = 'weapon_bullpuprifle', label = 'Bullpup Rifle', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
[`weapon_bullpuprifle_mk2`] = { name = 'weapon_bullpuprifle_mk2', label = 'Bull Puprifle MK2', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
[`weapon_compactrifle`] = { name = 'weapon_compactrifle', label = 'Compact Rifle', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
[`weapon_militaryrifle`] = { name = 'weapon_militaryrifle', label = 'Military Rifle', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
[`weapon_heavyrifle`] = { name = 'weapon_heavyrifle', label = 'Heavy Rifle', weapontype = 'Assault Rifle', ammotype = 'AMMO_RIFLE', damagereason = 'Ended / Rifled / Shot down / Floored' },
|
||||
|
||||
-- Light Machine Guns
|
||||
[`weapon_mg`] = { name = 'weapon_mg', label = 'Machinegun', weapontype = 'Light Machine Gun', ammotype = 'AMMO_MG', damagereason = 'Machine gunned / Sprayed / Ruined' },
|
||||
[`weapon_combatmg`] = { name = 'weapon_combatmg', label = 'Combat MG', weapontype = 'Light Machine Gun', ammotype = 'AMMO_MG', damagereason = 'Machine gunned / Sprayed / Ruined' },
|
||||
[`weapon_combatmg_mk2`] = { name = 'weapon_combatmg_mk2', label = 'Combat MG MK2', weapontype = 'Light Machine Gun', ammotype = 'AMMO_MG', damagereason = 'Machine gunned / Sprayed / Ruined' },
|
||||
[`weapon_gusenberg`] = { name = 'weapon_gusenberg', label = 'Thompson SMG', weapontype = 'Light Machine Gun', ammotype = 'AMMO_MG', damagereason = 'Machine gunned / Sprayed / Ruined' },
|
||||
|
||||
-- Sniper Rifles
|
||||
[`weapon_sniperrifle`] = { name = 'weapon_sniperrifle', label = 'Sniper Rifle', weapontype = 'Sniper Rifle', ammotype = 'AMMO_SNIPER', damagereason = 'Sniped / Picked off / Scoped' },
|
||||
[`weapon_heavysniper`] = { name = 'weapon_heavysniper', label = 'Heavy Sniper', weapontype = 'Sniper Rifle', ammotype = 'AMMO_SNIPER', damagereason = 'Sniped / Picked off / Scoped' },
|
||||
[`weapon_heavysniper_mk2`] = { name = 'weapon_heavysniper_mk2', label = 'Heavysniper MK2', weapontype = 'Sniper Rifle', ammotype = 'AMMO_SNIPER', damagereason = 'Sniped / Picked off / Scoped' },
|
||||
[`weapon_marksmanrifle`] = { name = 'weapon_marksmanrifle', label = 'Marksman Rifle', weapontype = 'Sniper Rifle', ammotype = 'AMMO_SNIPER', damagereason = 'Sniped / Picked off / Scoped' },
|
||||
[`weapon_marksmanrifle_mk2`] = { name = 'weapon_marksmanrifle_mk2', label = 'Marksman Rifle MK2', weapontype = 'Sniper Rifle', ammotype = 'AMMO_SNIPER', damagereason = 'Sniped / Picked off / Scoped' },
|
||||
[`weapon_remotesniper`] = { name = 'weapon_remotesniper', label = 'Remote Sniper', weapontype = 'Sniper Rifle', ammotype = 'AMMO_SNIPER_REMOTE', damagereason = 'Sniped / Picked off / Scoped' },
|
||||
|
||||
-- Heavy Weapons
|
||||
[`weapon_rpg`] = { name = 'weapon_rpg', label = 'RPG', weapontype = 'Heavy Weapons', ammotype = 'AMMO_RPG', damagereason = 'Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated' },
|
||||
[`weapon_grenadelauncher`] = { name = 'weapon_grenadelauncher', label = 'Grenade Launcher', weapontype = 'Heavy Weapons', ammotype = 'AMMO_GRENADELAUNCHER', damagereason = 'Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated' },
|
||||
[`weapon_grenadelauncher_smoke`] = { name = 'weapon_grenadelauncher_smoke', label = 'Smoke Grenade Launcher', weapontype = 'Heavy Weapons', ammotype = 'AMMO_GRENADELAUNCHER', damagereason = 'Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated' },
|
||||
[`weapon_minigun`] = { name = 'weapon_minigun', label = 'Minigun', weapontype = 'Heavy Weapons', ammotype = 'AMMO_MINIGUN', damagereason = 'Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated' },
|
||||
[`weapon_firework`] = { name = 'weapon_firework', label = 'Firework Launcher', weapontype = 'Heavy Weapons', ammotype = nil, damagereason = 'Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated' },
|
||||
[`weapon_railgun`] = { name = 'weapon_railgun', label = 'Railgun', weapontype = 'Heavy Weapons', ammotype = nil, damagereason = 'Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated' },
|
||||
[`weapon_railgunxm3`] = { name = 'weapon_railgunxm3', label = 'Railgun XM3', weapontype = 'Heavy Weapons', ammotype = nil, damagereason = 'Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated' },
|
||||
[`weapon_hominglauncher`] = { name = 'weapon_hominglauncher', label = 'Homing Launcher', weapontype = 'Heavy Weapons', ammotype = 'AMMO_STINGER', damagereason = 'Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated' },
|
||||
[`weapon_compactlauncher`] = { name = 'weapon_compactlauncher', label = 'Compact Launcher', weapontype = 'Heavy Weapons', ammotype = nil, damagereason = 'Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated' },
|
||||
[`weapon_rayminigun`] = { name = 'weapon_rayminigun', label = 'Ray Minigun', weapontype = 'Heavy Weapons', ammotype = 'AMMO_MINIGUN', damagereason = 'Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated' },
|
||||
[`weapon_emplauncher`] = { name = 'weapon_emplauncher', label = 'EMP Launcher', weapontype = 'Heavy Weapons', ammotype = 'AMMO_EMPLAUNCHER', damagereason = 'Died' },
|
||||
|
||||
-- Throwables
|
||||
[`weapon_grenade`] = { name = 'weapon_grenade', label = 'Grenade', weapontype = 'Throwable', ammotype = nil, damagereason = 'Bombed / Exploded / Detonated / Blew up' },
|
||||
[`weapon_bzgas`] = { name = 'weapon_bzgas', label = 'BZ Gas', weapontype = 'Throwable', ammotype = nil, damagereason = 'Died' },
|
||||
[`weapon_molotov`] = { name = 'weapon_molotov', label = 'Molotov', weapontype = 'Throwable', ammotype = nil, damagereason = 'Torched / Flambeed / Barbecued' },
|
||||
[`weapon_stickybomb`] = { name = 'weapon_stickybomb', label = 'C4', weapontype = 'Throwable', ammotype = nil, damagereason = 'Bombed / Exploded / Detonated / Blew up' },
|
||||
[`weapon_proxmine`] = { name = 'weapon_proxmine', label = 'Proxmine Grenade', weapontype = 'Throwable', ammotype = nil, damagereason = 'Bombed / Exploded / Detonated / Blew up' },
|
||||
[`weapon_snowball`] = { name = 'weapon_snowball', label = 'Snowball', weapontype = 'Throwable', ammotype = nil, damagereason = 'Died' },
|
||||
[`weapon_pipebomb`] = { name = 'weapon_pipebomb', label = 'Pipe Bomb', weapontype = 'Throwable', ammotype = nil, damagereason = 'Bombed / Exploded / Detonated / Blew up' },
|
||||
[`weapon_ball`] = { name = 'weapon_ball', label = 'Ball', weapontype = 'Throwable', ammotype = 'AMMO_BALL', damagereason = 'Died' },
|
||||
[`weapon_smokegrenade`] = { name = 'weapon_smokegrenade', label = 'Smoke Grenade', weapontype = 'Throwable', ammotype = nil, damagereason = 'Died' },
|
||||
[`weapon_flare`] = { name = 'weapon_flare', label = 'Flare pistol', weapontype = 'Throwable', ammotype = 'AMMO_FLARE', damagereason = 'Died' },
|
||||
|
||||
-- Miscellaneous
|
||||
[`weapon_petrolcan`] = { name = 'weapon_petrolcan', label = 'Petrol Can', weapontype = 'Miscellaneous', ammotype = 'AMMO_PETROLCAN', damagereason = 'Died' },
|
||||
[`gadget_parachute`] = { name = 'gadget_parachute', label = 'Parachute', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Died' },
|
||||
[`weapon_fireextinguisher`] = { name = 'weapon_fireextinguisher', label = 'Fire Extinguisher', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Died' },
|
||||
[`weapon_hazardcan`] = { name = 'weapon_hazardcan', label = 'Hazardcan', weapontype = 'Miscellaneous', ammotype = 'AMMO_PETROLCAN', damagereason = 'Died' },
|
||||
[`weapon_fertilizercan`] = { name = 'weapon_fertilizercan', label = 'Fertilizer Can', weapontype = 'Miscellaneous', ammotype = 'AMMO_FERTILIZERCAN', damagereason = 'Died' },
|
||||
[`weapon_barbed_wire`] = { name = 'weapon_barbed_wire', label = 'Barbed Wire', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Prodded' },
|
||||
[`weapon_drowning`] = { name = 'weapon_drowning', label = 'Drowning', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Died' },
|
||||
[`weapon_drowning_in_vehicle`] = { name = 'weapon_drowning_in_vehicle', label = 'Drowning in a Vehicle', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Died' },
|
||||
[`weapon_bleeding`] = { name = 'weapon_bleeding', label = 'Bleeding', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Bled out' },
|
||||
[`weapon_electric_fence`] = { name = 'weapon_electric_fence', label = 'Electric Fence', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Fried' },
|
||||
[`weapon_explosion`] = { name = 'weapon_explosion', label = 'Explosion', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Killed / Exploded / Obliterated / Destroyed / Erased / Annihilated' },
|
||||
[`weapon_fall`] = { name = 'weapon_fall', label = 'Fall', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Committed suicide' },
|
||||
[`weapon_exhaustion`] = { name = 'weapon_exhaustion', label = 'Exhaustion', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Died' },
|
||||
[`weapon_hit_by_water_cannon`] = { name = 'weapon_hit_by_water_cannon', label = 'Water Cannon', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Died' },
|
||||
[`weapon_rammed_by_car`] = { name = 'weapon_rammed_by_car', label = 'Rammed - Vehicle', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Flattened / Ran over / Ran down' },
|
||||
[`weapon_run_over_by_car`] = { name = 'weapon_run_over_by_car', label = 'Run Over - Vehicle', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Flattened / Ran over / Ran down' },
|
||||
[`weapon_heli_crash`] = { name = 'weapon_heli_crash', label = 'Heli Crash', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Helicopter Crash' },
|
||||
[`weapon_fire`] = { name = 'weapon_fire', label = 'Fire', weapontype = 'Miscellaneous', ammotype = nil, damagereason = 'Torched / Flambeed / Barbecued' },
|
||||
|
||||
-- Animals
|
||||
[`weapon_animal`] = { name = 'weapon_animal', label = 'Animal', weapontype = 'Animals', ammotype = nil, damagereason = 'Mauled' },
|
||||
[`weapon_cougar`] = { name = 'weapon_cougar', label = 'Cougar', weapontype = 'Animals', ammotype = nil, damagereason = 'Mauled' },
|
||||
}
|
||||
Reference in New Issue
Block a user