Configuration
lib.locale('en')
local gamebuild = GetGameBuildNumber()
cfg = {}
---@type 'auto'|'qb'|'esx'
cfg.framework = 'auto'
---@type 'auto'|'ox'|'qb'|false
cfg.target = 'auto'
---@type 'rm_minigames'|'ox_lib'|'qb-minigames'|'ps-ui'|'bl_ui'|false
cfg.minigame = 'ox_lib'
---@type 'ox_lib'|'qb'|'esx'|'okokNotify'|'ps-ui'
cfg.notification = 'ox_lib'
---@type 'ox_lib'|'esx'|'qb'|'okokTextUI'|'jg-textui'
cfg.textUI = 'ox_lib'
---@type 'ox_lib'|'qb'|'esx'|false
cfg.progressbar = 'ox_lib'
---@type 'auto'|'false'|'qb-vehiclekeys'|'wasabi_carlock'|'qs-vehiclekeys'|'cd_garage'|'Renewed-Vehiclekeys'|'okokGarage'|'t1ger_keys'|'MrNewbVehicleKeys'
cfg.vehiclelock = 'auto'
---@type false|'default_dispatch'|'cd_dispatch'|'qs-dispatch'|'ps-dispatch'|'rcore_dispatch'|'sonoran_cad'|'origen_police'|'redutzu-mdt'|'lb-tablet'|'core_dispatch'|'tk_dispatch'
cfg.dispatch = false
cfg.enteredShipZoneDispatchChance = 100 ---@type number -- Chance of police notification when entering ship zone
cfg.containerOpenDispatchChance = 100 ---@type number -- Chance of police notification when opening container
cfg.interaction = { ---@type {controlId: number, text: string, colors: {background: {r: number, g: number, b: number, a: number}, text: {r: number, g: number, b: number, a: number}}}
controlId = 38,
text = 'E',
colors = {
background = { r = 241, g = 93, b = 56, a = 255 },
text = { r = 226, g = 232, b = 240, a = 255 },
},
}
cfg.requiredPoliceCount = 0 ---@type number -- Required police count for heist
cfg.enableOldMethodForPoliceCount = false ---@type boolean -- All players' jobs are checked one by one, not recommended
cfg.timecycleInShipZone = 'MP_island_heist' ---@type string|false -- Timecycle effect in ship zone
cfg.shipBlip = { ---@type {sprite: number, scale: number, color: number, label: string}
sprite = gamebuild >= 3258 and 911 or 371,
scale = 0.8,
color = 17,
label = locale('ship_blip'),
}
cfg.shipZone = { ---@type {coords: vector3, rotation: number, size: vector3, debug?: boolean}
coords = vec3(-360.3204, -4087.394, 5.510296),
rotation = 1,
size = vec3(200.0, 200.0, 150.0),
}
---@type boolean -- the robbery can only be initiated by the driver of the vehicle entering the ship zone, prevents people who teleport to the ship zone or enter the game there from accidentally starting heist
cfg.heistInitiatedByDriverOnly = true
cfg.searchDurations = { ---@type {lootbox: number, medCabinet: number, guard: number, container: number}
lootbox = 10, -- seconds
medCabinet = 4, -- seconds
guard = 2, -- seconds
container = 15, -- seconds
}
cfg.heistCooldown = 40 ---@type number -- Heist cooldown in minutes
cfg.heistFinishDelay = 10 ---@type number -- Delay before the cooldown starts after the player who initiated the heist leaves the area
cfg.lootboxModel = `sm_prop_smug_crate_s_antiques` ---@type number|string
cfg.lootboxes = { ---@type vector4[]
vec4(-391.967, -4126.331, 16.682, 220.0),
vec4(-401.533, -4134.391, 16.683, -140.0),
vec4(-414.516, -4137.154, 16.684, -50.0),
vec4(-413.430, -4122.431, 16.684, 130.0),
vec4(-391.881, -4119.606, 16.683, -50.0),
vec4(-397.475, -4113.052, 16.683, -50.0),
vec4(-399.024, -4132.277, 8.667, -135.0),
vec4(-376.237, -4097.304, 8.666, -140.0),
vec4(-402.412, -4112.944, 25.808, 50.0),
vec4(-394.084, -4123.205, 29.037, 30.0),
vec4(-409.036, -4126.086, 24.687, 130.0),
vec4(-408.307, -4118.301, 20.684, -50.0),
vec4(-423.456, -4143.009, 8.667, -50.0),
vec4(-419.881, -4130.935, 8.667, 130.0),
vec4(-353.530, -4090.467, 8.666, -50.0),
vec4(-361.990, -4080.351, 8.666, -50.0),
vec4(-327.756, -4062.174, 8.666, 40.0),
vec4(-305.112, -4033.252, 13.644, 130.0),
vec4(-302.432, -4038.576, 13.644, 130.0),
vec4(-297.922, -4041.764, 13.644, 130.0),
vec4(-296.237, -4033.220, 13.644, -50.0),
}
cfg.medicineCabinets = { ---@type vector3[]
vec3(-409.869751, -4116.516, 9.918709),
vec3(-408.675964, -4115.51465, 13.8886061),
vec3(-407.037567, -4118.24072, 22.03735),
vec3(-404.796875, -4122.598, 26.0608025),
vec3(-396.707825, -4129.778, 13.8886061),
vec3(-360.0354, -4100.73975, 10.333847),
vec3(-334.827759, -4079.588, 10.333847),
vec3(-348.498932, -4063.29517, 10.333847),
vec3(-373.6595, -4084.503, 10.333847),
}
cfg.guards = { ---@type {patrol: {[0]: vector3, [1]: vector3}[], heli: vector3[]}
patrol = { -- [0] = spawning point --[1] = point to walk to
{
[0] = vec3(-416.72, -4148.03, 9.32),
[1] = vec3(-430.2, -4132.03, 9.32),
},
{
[0] = vec3(-384.1, -4123.8, 9.32),
[1] = vec3(-400.91, -4103.48, 9.32),
},
{
[0] = vec3(-359.55, -4104.09, 9.32),
[1] = vec3(-376.55, -4083.91, 9.32),
},
{
[0] = vec3(-347.0, -4093.69, 9.32),
[1] = vec3(-364.14, -4073.28, 9.32),
},
{
[0] = vec3(-334.4, -4083.04, 9.32),
[1] = vec3(-351.52, -4062.82, 9.32),
},
{
[0] = vec3(-323.92, -4073.31, 9.32),
[1] = vec3(-340.72, -4052.96, 9.32),
},
{
[0] = vec3(-303.35, -4052.04, 9.37),
[1] = vec3(-315.92, -4037.05, 9.37),
},
{
[0] = vec3(-296.6, -4047.54, 14.29),
[1] = vec3(-310.2, -4031.07, 14.29),
},
{
[0] = vec3(-409.3, -4143.1, 9.32),
[1] = vec3(-387.76, -4125.57, 9.32),
},
{
[0] = vec3(-423.86, -4125.67, 9.32),
[1] = vec3(-402.77, -4107.54, 9.32),
},
{
[0] = vec3(-400.74, -4136.42, 13.34),
[1] = vec3(-393.59, -4130.41, 13.34),
},
{
[0] = vec3(-415.85, -4118.41, 13.34),
[1] = vec3(-408.66, -4112.28, 13.33),
},
{
[0] = vec3(-386.62, -4124.85, 17.33),
[1] = vec3(-401.76, -4106.87, 17.34),
},
{
[0] = vec3(-407.06, -4131.52, 25.34),
[1] = vec3(-397.85, -4123.88, 25.34),
},
{
[0] = vec3(-411.53, -4121.38, 25.34),
[1] = vec3(-404.68, -4115.76, 25.34),
},
{
[0] = vec3(-395.28, -4123.84, 29.69),
[1] = vec3(-402.84, -4115.38, 29.69),
},
},
heli = {
vec3(-419.5, -4215.8, 71.54),
},
}
cfg.containers = { ---@type vector4[]
vec4(-342.868, -4062.062, 16.804, 130.0),
vec4(-332.732, -4074.141, 16.816, 130.0),
vec4(-369.243, -4082.519, 13.996, 130.0),
vec4(-384.424, -4108.926, 19.624, 130.0),
}
cfg.alarmCoords = vec3(-396.12, -4117.12, 29.69) ---@type vector3
cfg.heliModel = `maverick` ---@type number|string
cfg.guardModel = `s_m_y_blackops_01` ---@type number|string
cfg.guardHealth = 200 ---@type number
cfg.guardArmor = 100 ---@type number
cfg.guardWeapon = `WEAPON_MICROSMG` ---@type number|string
cfg.skyliftCoords = vec4(-317.23, -4049.88, 13.2, 15.0) ---@type vector4
cfg.skyliftAttachHelpSphere = true ---@type boolean -- Marker indicating the area that the helicopter can capture, can be used to assist in container capture
cfg.skyliftAttachHelpSphereOpacity = 0.03 ---@type number
cfg.manifestBook = vec3(-396.058, -4117.742, 26.397) ---@type vector3
cfg.containerModels = { `prop_container_03mb`, `prop_container_03_ld`, `prop_container_04mb` } ---@type (number|string)[]
cfg.weldingSpeed = 0.03 ---@type number
cfg.drillingSpeed = 0.1 ---@type number
cfg.containerRewardOffsets = { ---@type table<string, {model: number|string, pos: vector3, rot: vector3}[]>
['default'] = {
{
model = `ex_prop_crate_closed_bc`,
pos = vec3(0.34014892578125, 2.48583984375, 0.32612037658691),
rot = vec3(0, 0, 0),
},
{
model = `ex_prop_crate_closed_sc`,
pos = vec3(-0.47303771972656, -1.0576171875, 0.35152435302734),
rot = vec3(0, 0, 90.0),
},
},
['medicine'] = {
{
model = `ex_prop_crate_med_bc`,
pos = vec3(0.34014892578125, 2.48583984375, 0.32612037658691),
rot = vec3(0, 0, 0),
},
{
model = `ex_prop_crate_med_sc`,
pos = vec3(-0.47303771972656, -1.0576171875, 0.35152435302734),
rot = vec3(0, 0, 90.0),
},
},
['chemical'] = {
{
model = `ex_prop_crate_highend_pharma_bc`,
pos = vec3(0.34014892578125, 2.48583984375, 0.32612037658691),
rot = vec3(0, 0, 0),
},
{
model = `ex_prop_crate_pharma_sc`,
pos = vec3(-0.47303771972656, -1.0576171875, 0.35152435302734),
rot = vec3(0, 0, 90.0),
},
},
['jewelry'] = {
{
model = `ex_prop_crate_jewels_racks_bc`,
pos = vec3(0.24014892578125, 2.48583984375, 0.32612037658691),
rot = vec3(0, 0, 0),
},
{
model = `ex_prop_crate_jewels_racks_sc`,
pos = vec3(-0.36303771972656, -1.0576171875, 0.35152435302734),
rot = vec3(0, 0, 90.0),
},
},
['art'] = {
{
model = `ex_prop_crate_art_bc`,
pos = vec3(0.34014892578125, 2.48583984375, 0.32612037658691),
rot = vec3(0, 0, 0),
},
{
model = `ex_prop_crate_art_sc`,
pos = vec3(-0.47303771972656, -1.0576171875, 0.35152435302734),
rot = vec3(0, 0, 90.0),
},
},
['electronic'] = {
{
model = `ex_prop_crate_elec_bc`,
pos = vec3(0.33014892578125, 2.48583984375, 0.32612037658691),
rot = vec3(0, 0, 0),
},
{
model = `ex_prop_crate_elec_sc`,
pos = vec3(-0.47303771972656, -1.0576171875, 0.35152435302734),
rot = vec3(0, 0, 90.0),
},
},
['drug'] = {
{
model = `ex_prop_crate_narc_bc`,
pos = vec3(0.34014892578125, 2.48583984375, 0.32612037658691),
rot = vec3(0, 0, 0),
},
{
model = `ex_prop_crate_narc_sc`,
pos = vec3(-0.47303771972656, -1.0576171875, 0.35152435302734),
rot = vec3(0, 0, 90.0),
},
},
}
cfg.containerDrillOffsets = { ---@type vector3[]
vec3(-1.295, -3.43, 1.73), -- left 2
vec3(1.295, -3.43, 1.73), -- right 2
vec3(-1.295, -3.43, 1.06), -- left 3
vec3(1.295, -3.43, 1.06), -- right 3
--- To increase the difficulty, you can remove the following parts from the comment line
-- vec3(-1.295, -3.43, 2.43), -- left 1
-- vec3(1.295, -3.43, 2.43), -- right 1
-- vec3(-1.295, -3.43, 0.36), -- left 4
-- vec3(1.295, -3.43, 0.36), -- right 4
}
cfg.items = { ---@type table<string, string>
c4 = 'cs_c4',
thermite = 'cs_thermite',
weld = 'WEAPON_WELD',
drill = 'WEAPON_DRILL',
}
cfg.containerAttachOffsets = { ---@type table<string, {model: number|string, pos: vector3 | vector3[], rot: vector3}[]>
[cfg.items.c4] = {
model = `prop_bomb_01_s`,
pos = {
[1] = vec3(0.0064811706542969, -3.3897705078125, 1.1990509033203),
[2] = vec3(-0.64724349975586, -3.5531005859375, 1.6194725036621),
},
rot = vec3(0, 0, 0),
},
[cfg.items.thermite] = {
model = `hei_prop_heist_thermite`,
pos = {
[1] = vec3(0.02130126953125, -3.42236328125, 1.1963558197021),
[2] = vec3(-0.64724349975586, -3.5531005859375, 1.6194725036621),
},
rot = vec3(90.0, 00.0, 0),
},
['doors'] = {
-- front doors
{
model = `prop_container_door_mb_r`,
pos = vec3(1.2979125976562, -3.390869140625, 1.4021835327148),
rot = vec3(0, 0, 0),
},
{
model = `prop_container_door_mb_l`,
pos = vec3(-1.2979125976562, -3.390869140625, 1.4021835327148),
rot = vec3(0, 0, 0),
},
-- back doors
{
model = `prop_container_door_mb_l`,
pos = vec3(1.2979125976562, 3.390869140625, 1.4021835327148),
rot = vec3(0, 0, 180.0),
},
{
model = `prop_container_door_mb_r`,
pos = vec3(-1.2979125976562, 3.390869140625, 1.4021835327148),
rot = vec3(0, 0, 180.0),
},
},
}
cfg.c4DetonationDuration = 9.6 ---@type number
cfg.thermiteMeltDuration = 10 ---@type number
cfg.disableContainerDrilling = false ---@type boolean
---@type 'top-left'|'top-center'|'top-right'|'center-left'|'center-center'|'center-right'|'bottom-left'|'bottom-center'|'bottom-right'
cfg.heistInfoPosition = 'bottom-right' -- the position where the remaining time or remaining unsearched guard info will be display
-- If you don't have the k4mb1-ship map, you can download rm_shipmap from the portal, but features like keypad minigame will be disabled.
-- Never run two map files(k4mb1-ship, rm_shipmap) together, it may crash
if GetResourceState('k4mb1-cargoship'):find('start') then
lib.load('data.maps.k4mb1')
if GetResourceState('rm_shipmap'):find('start') then
lib.print.error('k4mb1-cargoship found, please remove rm_shipmap.')
end
elseif GetResourceState('rm_shipmap'):find('start') then
lib.load('data.maps.standalone')
else
lib.print.error('Ship heist requires k4mb1-cargoship or rm_shipmap.')
end
lib.load('data.rewards')
lib.load('data.prices')
-- equate to empty table to turn off npc
cfg.missionSuppliers = {
{
coords = vec4(155.1, -3323.87, 6.02, 187.26),
model = `ig_joeminuteman`,
blip = { -- false | { sprite = number; color = number; scale = number; label = string }
sprite = 52,
color = 17,
scale = 0.6,
label = locale('supplier_label'),
},
},
}
cfg.deleteItemOnUse = true
cfg.prices = {}
-- equate to empty table to hide the menu
cfg.prices.buy = {
[cfg.items.drill] = {
label = 'Portable Drill',
price = 5000,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
[cfg.items.weld] = {
label = 'Portable Weld',
price = 5000,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
[cfg.items.c4] = {
label = 'Small C4',
price = 7000,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
[cfg.items.thermite] = {
label = 'Thermite',
price = 7000,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
}
-- equate to empty table to hide the menu
cfg.prices.sell = {
-- electronic
['cs_electronickit_1'] = {
label = 'Electronickit 1',
price = 100,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
-- tradeItems = {
-- ['steel'] = {
-- label = 'Steel',
-- quantity = 15,
-- },
-- ['metalscrap'] = {
-- label = 'Metal Scrap',
-- quantity = 25,
-- },
-- },
},
['cs_electronickit_2'] = {
label = 'Electronickit 2',
price = 200,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_electronickit_3'] = {
label = 'Electronickit 3',
price = 300,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_electronickit_4'] = {
label = 'Electronickit 4',
price = 400,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
-- chemical
['cs_acetone'] = {
label = 'Acetone',
price = 100,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_lithium'] = {
label = 'Lithium',
price = 150,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_phosphorus'] = {
label = 'Phosphorus',
price = 200,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
-- jewelry
['cs_silverchain'] = {
label = 'Silver Chain',
price = 200,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_goldchain'] = {
label = 'Gold Chain',
price = 400,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_diamond_earring'] = {
label = 'Diamond Earring',
price = 1000,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_diamond_necklace'] = {
label = 'Diamond Necklace',
price = 1200,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_diamond_ring'] = {
label = 'Diamond Ring',
price = 800,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
-- art
['cs_painting_1'] = {
label = 'Painting 1',
price = 300,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_painting_2'] = {
label = 'Painting 2',
price = 500,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_painting_3'] = {
label = 'Painting 3',
price = 700,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_painting_4'] = {
label = 'Painting 4',
price = 900,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_painting_5'] = {
label = 'Painting 5',
price = 1100,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
-- drug
['cs_brick_coke'] = {
label = 'Coke Brick',
price = 1500,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_brick_meth'] = {
label = 'Meth Brick',
price = 1300,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_brick_opium'] = {
label = 'Opium Brick',
price = 1100,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
['cs_brick_weed'] = {
label = 'Weed Brick',
price = 800,
moneyType = 'cash', -- 'cash' | 'money' | 'black_money'
},
}
---@class ContainerType
---@field type string -- (weapon, medicine, chemical, jewelry, art, electronic, drug)
---@field customer string
---@field items table<string, {amount: number|number[], chance: number}>
---@field money {type: 'cash'|'money'|'black_money', amount: number|number[], chance: number}
---@class RewardPool
---@field items table<string, {amount: number|number[], chance: number}>
---@field money {type: 'cash'|'money'|'black_money', amount: number|number[], chance: number}
---@type ContainerType[]
cfg.containerTypes = {
{
type = 'weapon',
customer = 'Ammu-Nation',
items = {
['WEAPON_KNIFE'] = {
amount = { 10, 30 },
chance = 100,
},
['WEAPON_PISTOL'] = {
amount = { 5, 10 },
chance = 75,
},
['WEAPON_SMG'] = {
amount = { 1, 5 },
chance = 50,
},
['WEAPON_ASSAULTRIFLE'] = {
amount = 1,
chance = 10,
},
},
},
{
type = 'medicine',
customer = 'Dollar Pills Pharmacy',
items = {
['bandage'] = {
amount = { 50, 100 },
chance = 100,
},
},
money = {
type = 'cash',
amount = { 1000, 5000 },
chance = 25,
},
},
{
type = 'chemical',
customer = 'Humane Labs and Research',
items = {
['cs_acetone'] = {
amount = { 15, 50 },
chance = 100,
},
['cs_lithium'] = {
amount = { 15, 50 },
chance = 50,
},
['cs_phosphorus'] = {
amount = { 15, 50 },
chance = 50,
},
},
money = {
type = 'cash',
amount = { 1000, 5000 },
chance = 25,
},
},
{
type = 'jewelry',
customer = 'Vangelico Jewelry Store',
items = {
['cs_silverchain'] = {
amount = { 25, 50 },
chance = 100,
},
['cs_goldchain'] = {
amount = { 25, 50 },
chance = 50,
},
['cs_diamond_earring'] = {
amount = { 5, 20 },
chance = 10,
},
['cs_diamond_necklace'] = {
amount = { 5, 20 },
chance = 10,
},
['cs_diamond_ring'] = {
amount = { 5, 20 },
chance = 10,
},
},
money = {
type = 'cash',
amount = { 1000, 5000 },
chance = 25,
},
},
{
type = 'art',
customer = 'Los Santos Museum of Art',
items = {
['cs_painting_1'] = {
amount = { 15, 30 },
chance = 100,
},
['cs_painting_2'] = {
amount = { 5, 10 },
chance = 50,
},
['cs_painting_3'] = {
amount = { 5, 10 },
chance = 30,
},
['cs_painting_4'] = {
amount = { 5, 10 },
chance = 20,
},
['cs_painting_5'] = {
amount = { 5, 10 },
chance = 10,
},
},
money = {
type = 'cash',
amount = { 1000, 5000 },
chance = 25,
},
},
{
type = 'electronic',
customer = 'Digital Den',
items = {
['cs_electronickit_1'] = {
amount = { 50, 100 },
chance = 100,
},
['cs_electronickit_2'] = {
amount = { 25, 75 },
chance = 50,
},
['cs_electronickit_3'] = {
amount = { 5, 20 },
chance = 20,
},
['cs_electronickit_4'] = {
amount = { 2, 5 },
chance = 10,
},
},
money = {
type = 'cash',
amount = { 1000, 5000 },
chance = 25,
},
},
{
type = 'drug',
customer = 'Anonim',
items = {
['cs_brick_weed'] = {
amount = { 5, 20 },
chance = 100,
},
['cs_brick_coke'] = {
amount = { 5, 20 },
chance = 75,
},
['cs_brick_meth'] = {
amount = { 5, 20 },
chance = 75,
},
['cs_brick_opium'] = {
amount = { 5, 20 },
chance = 75,
},
},
money = {
type = 'cash',
amount = { 1000, 5000 },
chance = 25,
},
},
}
---@type RewardPool
cfg.lootboxRewards = {
-- items = {
-- ['bandage'] = {
-- amount = { 1, 100 },
-- chance = 100,
-- },
-- },
money = {
type = 'cash',
amount = { 500, 1000 },
chance = 100,
},
}
---@type RewardPool
cfg.guardRewards = {
items = {
['bandage'] = {
amount = { 1, 2 },
chance = 10,
},
},
money = {
type = 'cash',
amount = { 50, 100 },
chance = 50,
},
}
---@type RewardPool
cfg.medCabinetRewards = {
items = {
['bandage'] = {
amount = { 1, 3 },
chance = 70,
},
},
}
Last updated