lib.locale('en')
cfg = {}
---@type 'auto' | 'qb' | 'esx'
cfg.framework = 'auto'
---@type 'auto' | 'ox_target' | 'qb-target' | false
cfg.target = 'auto'
---@type 'ox_lib' | 'qb' | 'esx' | 'okokNotify' | 'ps-ui'
cfg.notification = 'ox_lib'
---@type 'ox_lib' | 'esx' | 'qb' | 'okokTextUI' | 'jg-textui'
cfg.textUI = 'ox_lib'
cfg.interaction = {
controlId = 38, ---@type number
text = 'E', ---@type string
colors = {
background = { r = 241, g = 93, b = 56, a = 255 },
text = { r = 226, g = 232, b = 240, a = 255 },
},
}
---@type { original: { model: number, coords: vector4, blip: table|boolean, prices: table<string,number>, moneyType: string }[], fake: { model: number, coords: vector4, blip: table|boolean, prices: table<string,number>, moneyType: string }[] }
cfg.npcs = {
original = {
{
model = `a_m_m_prolhost_01`, ---@type number
coords = vec4(-265.97, -965.67, 31.22, 222.74), ---@type vector4
blip = false, ---@type false | { sprite: number, color: number, scale: number, label: string }
scenario = 'WORLD_HUMAN_STAND_MOBILE', ---@type string | nil
prices = {
['id_card'] = 50,
['driver_license'] = 50,
},
moneyType = 'cash',
},
},
fake = {
{
model = `a_m_y_genstreet_01`, ---@type number
coords = vec4(-273.64, -912.6, 31.22, 76.5), ---@type vector4
blip = false, ---@type false | { sprite: number, color: number, scale: number, label: string }
prices = {
['id_card'] = 500,
['driver_license'] = 500,
['weaponlicense'] = 500,
},
moneyType = 'cash',
},
},
}
---@type table<string, { label: string, canCreateFake?: boolean, background: string, titles?: { text: string, offset: {x:number, y:number}, color?: string, font?: string, textAlign?: string, textBaseline?: string }[], logos?: { fileName: string, offset: {x:number, y:number}, size: {width:number, height:number}, opacity?: number }[], fields: table<string, { label?: table, value?: table, offset?: table, size?: table }> }>
cfg.cards = {
['id_card'] = {
label = 'ID Card',
canCreateFake = true,
background = 'bg_id.png',
titles = {
{
text = 'IDENTIFICATION',
offset = { x = 640, y = 64 },
color = '#FFFFFF',
font = 'normal 600 64px Rubik',
textAlign = 'center',
textBaseline = 'middle',
},
},
logos = {},
fields = {
['mugshot'] = {
offset = { x = 56, y = 152 },
size = { width = 400, height = 400 },
},
['citizenid'] = {
label = {
text = 'CITIZEN ID',
offset = { x = 495, y = 180 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 220 },
font = 'normal 500 40px Rubik',
},
},
-- ['nationality'] = {
-- label = {
-- text = 'NATIONALITY',
-- offset = { x = 840, y = 180 },
-- font = 'normal 400 32px Rubik',
-- },
-- value = {
-- offset = { x = 840, y = 220 },
-- font = 'normal 500 40px Rubik',
-- },
-- },
['firstname'] = {
label = {
text = 'FIRSTNAME',
offset = { x = 495, y = 275 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 315 },
font = 'normal 500 40px Rubik',
},
},
['dob'] = {
label = {
text = 'DATE OF BIRTH',
offset = { x = 840, y = 275 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 840, y = 315 },
font = 'normal 500 40px Rubik',
},
},
['lastname'] = {
label = {
text = 'LASTNAME',
offset = { x = 495, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['gender'] = {
label = {
text = 'GENDER',
offset = { x = 840, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 840, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['signature'] = {
value = {
offset = { x = 890, y = 530 },
font = 'normal 500 70px ActerumSignaturePersonalUse',
},
},
['serial'] = {
value = {
offset = { x = 56, y = 650 },
font = 'normal 500 50px Rubik',
},
},
},
},
['driver_license'] = {
label = 'Driver License',
canCreateFake = true,
background = 'bg_driver.png',
titles = {
{
text = 'DRIVER\'S',
offset = { x = 492, y = 64 },
color = '#FFFFFF',
font = 'normal 600 64px Rubik',
textAlign = 'center',
textBaseline = 'middle',
},
{
text = 'LICENSE',
offset = { x = 775, y = 64 },
color = '#FFFFFF',
font = 'normal 300 64px Rubik',
textAlign = 'center',
textBaseline = 'middle',
},
},
logos = {
{
fileName = 'logo_driver.png',
offset = { x = 935, y = 150 },
size = { width = 180, height = 180 },
opacity = 1,
},
},
fields = {
['citizenid'] = {
label = {
text = 'CITIZEN ID',
offset = { x = 495, y = 180 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 220 },
font = 'normal 500 40px Rubik',
},
},
['serial'] = {
value = {
offset = { x = 56, y = 650 },
font = 'normal 500 50px Rubik',
},
},
['gender'] = {
label = {
text = 'GENDER',
offset = { x = 840, y = 465 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 840, y = 505 },
font = 'normal 500 40px Rubik',
},
},
['dob'] = {
label = {
text = 'DATE OF BIRTH',
offset = { x = 840, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 840, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['mugshot'] = {
offset = { x = 56, y = 152 },
size = { width = 400, height = 400 },
},
['lastname'] = {
label = {
text = 'LASTNAME',
offset = { x = 495, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['firstname'] = {
label = {
text = 'FIRSTNAME',
offset = { x = 495, y = 275 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 315 },
font = 'normal 500 40px Rubik',
},
},
['driver_class'] = {
label = {
text = 'CLASS',
offset = { x = 495, y = 465 },
color = '#000',
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 505 },
color = '#000',
font = 'normal 500 40px Rubik',
},
},
},
},
['weaponlicense'] = {
label = 'Weapon License',
canCreateFake = true,
background = 'bg_weapon.png',
titles = {
{
text = 'WEAPON',
offset = { x = 492, y = 64 },
color = '#FFFFFF',
font = 'normal 600 64px Rubik',
textAlign = 'center',
textBaseline = 'middle',
},
{
text = 'LICENSE',
offset = { x = 775, y = 64 },
color = '#FFFFFF',
font = 'normal 300 64px Rubik',
textAlign = 'center',
textBaseline = 'middle',
},
},
logos = {
{
fileName = 'logo_pd.png',
offset = { x = 935, y = 150 },
size = { width = 180, height = 180 },
opacity = 1,
},
},
fields = {
['lastname'] = {
label = {
text = 'LASTNAME',
offset = { x = 495, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['gender'] = {
label = {
text = 'GENDER',
offset = { x = 495, y = 465 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 505 },
font = 'normal 500 40px Rubik',
},
},
['citizenid'] = {
label = {
text = 'CITIZEN ID',
offset = { x = 495, y = 180 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 220 },
font = 'normal 500 40px Rubik',
},
},
['mugshot'] = {
offset = { x = 56, y = 152 },
size = { width = 400, height = 400 },
},
['firstname'] = {
label = {
text = 'FIRSTNAME',
offset = { x = 495, y = 275 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 315 },
font = 'normal 500 40px Rubik',
},
},
['dob'] = {
label = {
text = 'DATE OF BIRTH',
offset = { x = 840, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 840, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['serial'] = {
value = {
offset = { x = 56, y = 650 },
font = 'normal 500 50px Rubik',
},
},
},
},
['lawyerpass'] = {
label = 'DOJ Card',
background = 'bg_lawyer.png',
titles = {
{
text = 'DOJ',
offset = { x = 440, y = 64 },
color = '#FFFFFF',
font = 'normal 600 64px Rubik',
textAlign = 'center',
textBaseline = 'middle',
},
{
text = 'IDENTIFICATION',
offset = { x = 750, y = 64 },
color = '#FFFFFF',
font = 'normal 300 64px Rubik',
textAlign = 'center',
textBaseline = 'middle',
},
},
logos = {
{
fileName = 'logo_doj.png',
offset = { x = 935, y = 150 },
size = { width = 180, height = 180 },
opacity = 1,
},
},
fields = {
['serial'] = {
value = {
offset = { x = 56, y = 650 },
font = 'normal 500 50px Rubik',
},
},
['citizenid'] = {
label = {
text = 'CITIZEN ID',
offset = { x = 495, y = 180 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 220 },
font = 'normal 500 40px Rubik',
},
},
['lastname'] = {
label = {
text = 'LASTNAME',
offset = { x = 495, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['firstname'] = {
label = {
text = 'FIRSTNAME',
offset = { x = 495, y = 275 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 315 },
font = 'normal 500 40px Rubik',
},
},
['gender'] = {
label = {
text = 'GENDER',
offset = { x = 840, y = 465 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 840, y = 505 },
font = 'normal 500 40px Rubik',
},
},
['dob'] = {
label = {
text = 'DATE OF BIRTH',
offset = { x = 840, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 840, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['mugshot'] = {
offset = { x = 56, y = 152 },
size = { width = 400, height = 400 },
},
['job_grade'] = {
label = {
text = 'RANK',
offset = { x = 495, y = 465 },
color = '#000',
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 505 },
color = '#000',
font = 'normal 500 40px Rubik',
},
},
},
},
['pd_card'] = {
label = 'PD Card',
background = 'bg_pd.png',
titles = {
{
text = 'OFFICER',
offset = { x = 405, y = 64 },
color = '#FFFFFF',
font = 'normal 600 64px Rubik',
textAlign = 'center',
textBaseline = 'middle',
},
{
text = 'IDENTIFICATION',
offset = { x = 785, y = 64 },
color = '#FFFFFF',
font = 'normal 300 64px Rubik',
textAlign = 'center',
textBaseline = 'middle',
},
},
logos = {
{
fileName = 'logo_pd.png',
offset = { x = 935, y = 150 },
size = { width = 180, height = 180 },
opacity = 1,
},
},
fields = {
['dob'] = {
label = {
text = 'DATE OF BIRTH',
offset = { x = 840, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 840, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['gender'] = {
label = {
text = 'GENDER',
offset = { x = 840, y = 465 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 840, y = 505 },
font = 'normal 500 40px Rubik',
},
},
['mugshot'] = {
offset = { x = 56, y = 152 },
size = { width = 400, height = 400 },
},
['citizenid'] = {
label = {
text = 'CITIZEN ID',
offset = { x = 495, y = 180 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 220 },
font = 'normal 500 40px Rubik',
},
},
['serial'] = {
value = {
offset = { x = 56, y = 650 },
font = 'normal 500 50px Rubik',
},
},
['lastname'] = {
label = {
text = 'LASTNAME',
offset = { x = 495, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['job_grade'] = {
label = {
text = 'RANK',
offset = { x = 495, y = 465 },
color = '#000',
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 505 },
color = '#000',
font = 'normal 500 40px Rubik',
},
},
['firstname'] = {
label = {
text = 'FIRSTNAME',
offset = { x = 495, y = 275 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 315 },
font = 'normal 500 40px Rubik',
},
},
},
},
['ems_card'] = {
label = 'EMS Card',
background = 'bg_ems.png',
titles = {
{
text = 'DOCTOR',
offset = { x = 405, y = 64 },
color = '#FFFFFF',
font = 'normal 600 64px Rubik',
textAlign = 'center',
textBaseline = 'middle',
},
{
text = 'IDENTIFICATION',
offset = { x = 780, y = 64 },
color = '#FFFFFF',
font = 'normal 300 64px Rubik',
textAlign = 'center',
textBaseline = 'middle',
},
},
logos = {
{
fileName = 'logo_ems.png',
offset = { x = 935, y = 150 },
size = { width = 180, height = 180 },
opacity = 1,
},
},
fields = {
['job_grade'] = {
label = {
text = 'RANK',
offset = { x = 495, y = 465 },
color = '#000',
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 505 },
color = '#000',
font = 'normal 500 40px Rubik',
},
},
['mugshot'] = {
offset = { x = 56, y = 152 },
size = { width = 400, height = 400 },
},
['gender'] = {
label = {
text = 'GENDER',
offset = { x = 840, y = 465 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 840, y = 505 },
font = 'normal 500 40px Rubik',
},
},
['citizenid'] = {
label = {
text = 'CITIZEN ID',
offset = { x = 495, y = 180 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 220 },
font = 'normal 500 40px Rubik',
},
},
['firstname'] = {
label = {
text = 'FIRSTNAME',
offset = { x = 495, y = 275 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 315 },
font = 'normal 500 40px Rubik',
},
},
['dob'] = {
label = {
text = 'DATE OF BIRTH',
offset = { x = 840, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 840, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['lastname'] = {
label = {
text = 'LASTNAME',
offset = { x = 495, y = 370 },
font = 'normal 400 32px Rubik',
},
value = {
offset = { x = 495, y = 410 },
font = 'normal 500 40px Rubik',
},
},
['serial'] = {
value = {
offset = { x = 56, y = 650 },
font = 'normal 500 50px Rubik',
},
},
},
},
}
cfg.displayTypes = {
['onPlayer'] = true,
['onScreen'] = true,
['onObject'] = true,
}
---@type 'top-left'|'top-center'|'top-right'|'center-left'|'center-center'|'center-right'|'bottom-left'|'bottom-center'|'bottom-right' -- the position of the card on the screen
cfg.onScreenPosition = 'top-right'
cfg.allowedToGiveCard = { ---@type table<string, true> -- Allowed identifiers for the give command
-- ['steam:00000000a000a00'] = true,
-- ['license:0aa00a00a00aa000a000000a00000a00a00aa000'] = true,
-- ['license2:0aa00a00a00aa000a000000a00000a00a00aa000'] = true,
-- ['fivem:0000000'] = true,
}
cfg.allowedJobsToCheckCard = { 'police' } ---@type table<string> -- Allowed jobs for the check command
cfg.allowedToCheckCard = { ---@type table<string, true> -- Allowed identifiers for the check command
-- ['steam:00000000a000a00'] = true,
-- ['license:0aa00a00a00aa000a000000a00000a00a00aa000'] = true,
-- ['license2:0aa00a00a00aa000a000000a00000a00a00aa000'] = true,
-- ['fivem:0000000'] = true,
}
cfg.allowedToManageForgeryOffices = { ---@type table<string, true> -- Allowed identifiers for the create command
-- ['steam:00000000a000a00'] = true,
-- ['license:0aa00a00a00aa000a000000a00000a00a00aa000'] = true,
-- ['license2:0aa00a00a00aa000a000000a00000a00a00aa000'] = true,
-- ['fivem:0000000'] = true,
}
cfg.allowedToCardDesignEditor = { ---@type table<string, true> -- Allowed identifiers for the card design editor command
-- ['steam:00000000a000a00'] = true,
-- ['license:0aa00a00a00aa000a000000a00000a00a00aa000'] = true,
-- ['license2:0aa00a00a00aa000a000000a00000a00a00aa000'] = true,
-- ['fivem:0000000'] = true,
}
cfg.commands = { ---@type table<string, string|false> -- equate to false to disable the command
give = 'givecard',
check = 'checkserial',
manageforgeryoffices = 'manageforgeryoffices',
carddesigneditor = 'carddesigneditor',
}
cfg.blipColors = {
['White'] = 0,
['Light Red'] = 6,
['Violet'] = 7,
['Pink'] = 8,
['Light Orange'] = 9,
['Light Brown'] = 10,
['Light Green'] = 11,
['Light Blue'] = 12,
['Light Purple'] = 13,
['Dark Purple'] = 14,
['Cyan'] = 15,
['Light Yellow'] = 16,
['Orange'] = 17,
['Dark Pink'] = 19,
['Dark Yellow'] = 20,
['Dark Orange'] = 21,
['Light Gray'] = 22,
['Light Pink'] = 23,
['Lemon Green'] = 24,
['Forest Green'] = 25,
['Electric Blue'] = 26,
['Bright Purple'] = 27,
['Dark Blue'] = 29,
['Dark Cyan'] = 30,
['Beige'] = 36,
['Gold'] = 46,
['Brilliant Rose'] = 48,
['Medium Purple'] = 50,
['Salmon'] = 51,
['Dark Green'] = 52,
['Blizzard Blue'] = 53,
['Oracle Blue'] = 54,
['Silver'] = 55,
['Brown'] = 56,
['East Bay'] = 58,
['Yellow Orange'] = 60,
['Mulberry Pink'] = 61,
['Alto Gray'] = 62,
['Jelly Bean Blue'] = 63,
['Mamba'] = 65,
['Deep red'] = 76,
['Oracle Blue 2'] = 78,
['Transparent Black'] = 72,
['Transparent Red'] = 79,
['Transparent Blue'] = 80,
['Purple'] = 83,
}
cfg.forgeryOffice = {
fallbackExitCoord = vec4(76.56, -871.92, 31.51, 67.0),
blipDefaults = { sprite = 498, color = cfg.blipColors['Cyan'], scale = 0.7 }, ---@type { sprite: number, color: number, scale: number }
settingsDefaults = { blip = false, name = 'Forgery Office' }, ---@type { blip: boolean, name: string }
settingsEditable = false,
hideAllBlips = false, ---@type boolean -- Disables blip customizations for all offices, making blips invisible in all offices
npcJob = {
disable = false, ---@type boolean -- Hides the option to start and stop NPC job
items = { 'id_card', 'driver_license', 'weaponlicense' }, ---@type string[] -- Must be found in cfg.cards and cfg.fakeFields
models = {
['male'] = { `a_m_m_eastsa_02`, `a_m_m_ktown_01`, `a_m_m_socenlat_01`, `a_m_y_genstreet_01`, `a_m_y_vindouche_01`, `g_m_m_mexboss_02`, `g_m_m_chigoon_02` },
['female'] = { `a_f_m_bevhills_01`, `a_f_m_bevhills_02`, `a_f_y_epsilon_01`, `s_f_y_clubbar_01`, `s_f_y_shop_low` },
},
reward = 250, ---@type number | number[]
customerWaitingTime = { 5, 30 }, ---@type number[] | number -- delays for a random second between the specified two durations
},
}
cfg.serialNumberLength = 7 ---@type number
cfg.displayDuration = 10 ---@type number -- seconds
cfg.dateFieldFormat = 'DD/MM/YYYY'
cfg.inactiveCardsDeleteInterval = '2 WEEK'
cfg.customFonts = {
['ActerumSignaturePersonalUse'] = 'https://fonts.cdnfonts.com/css/acterumsignaturepersonaluse',
['Rubik'] = 'https://fonts.googleapis.com/css2?family=Rubik:ital,wght@0,300..900;1,300..900&display=swap',
}
cfg.fakeFields = {
['citizenid'] = function()
return lib.string.random('A.......')
end,
['dob'] = function()
local minYear, maxYear = 1990, 2005
local format = cfg.dateFieldFormat or 'DD/MM/YYYY'
local year = math.random(minYear, maxYear)
local month = math.random(1, 12)
local daysInMonth = 28
if month == 1 or month == 3 or month == 5 or month == 7 or month == 8 or month == 10 or month == 12 then
daysInMonth = 31
elseif month == 4 or month == 6 or month == 9 or month == 11 then
daysInMonth = 30
elseif month == 2 then
if (year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0) then
daysInMonth = 29
end
end
local day = math.random(1, daysInMonth)
if format == 'DD/MM/YYYY' then
return ('%02d/%02d/%04d'):format(day, month, year)
elseif format == 'MM/DD/YYYY' then
return ('%02d/%02d/%04d'):format(month, day, year)
elseif format == 'YYYY-MM-DD' then
return ('%04d-%02d-%02d'):format(year, month, day)
else
return ('%02d/%02d/%04d'):format(day, month, year)
end
end,
['nationality'] = {
'United States',
'Canada',
'Germany',
'France',
'Italy',
'United Kingdom',
'Australia',
},
['firstname'] = {
['male'] = {
'James',
'Michael',
'David',
'Robert',
'John',
'Daniel',
},
['female'] = {
'Emily',
'Sarah',
'Jessica',
'Emma',
'Olivia',
'Sophia',
},
},
['lastname'] = {
'Smith',
'Johnson',
'Williams',
'Brown',
'Jones',
'Taylor',
},
}
if not lib.checkDependency('rm_stream', '1.1.1') then print('^3[WARN] rm_stream version 1.1.1 or higher is required for the script to run stably, please update') end