⚙️Configuration

Configuration guide of Multiplayer Demining Job.


Config.lua

Config = {}

-- If you're experiencing any issues with the framework, check the stg_lib/config.lua file (it's already auto-detected).
Config.Language = "en" -- en, de, fr, es, pt, it, nl, pl, sv, ar, jp, zh, fi, he
Config.Debug = false
Config.digTime = 3 -- Default dig time in seconds when nothing found

-- [ Tasks Configuration ]
Config.Tasks = {
    {
        title = Locales[Config.Language].task1_title,
        description = Locales[Config.Language].task1_desc,
        level = false, -- false = no level requirement
        divingMode = false, -- true = underwater mission (uses boat + scuba gear)
        requirements = { -- Mine types and amounts to find (keys must match Config.Mines)
            { item = "m41", amount = 2 },
            { item = "ap_mine", amount = 2 },
        },
        rewards = { exp = 50, money = 5000 },
        players = { min = 1, max = 4 }, -- Min/max players required to start
        area = {
            center = vec3(-814.0464, -1893.4847, 19.0417), -- Mission area center (Z is approximate for land mines)
            radius = 25.0, -- Search radius around center
            blip = { sprite = 162, color = 1, scale = 1.0, label = "Hazard Zone" }
        },
        delivery = vec4(474.2173, -1079.4603, 29.2020, 183.5736), -- Where to deliver collected mines
    },
    {
        title = Locales[Config.Language].task2_title,
        description = Locales[Config.Language].task2_desc,
        level = 2,
        divingMode = false,
        requirements = {
            { item = "m41", amount = 4 },
            { item = "ap_mine", amount = 3 },
        },
        rewards = { exp = 75, money = 10000 },
        players = { min = 1, max = 4 },
        area = {
            center = vec3(1099.0120, 503.1652, 94.5344),
            radius = 75.0,
            blip = { sprite = 162, color = 1, scale = 0.9, label = "Minefield" }
        },
        delivery = vec4(474.2173, -1079.4603, 29.2020, 183.5736), -- Where to deliver collected mines
    },
    {
        title = Locales[Config.Language].task3_title,
        description = Locales[Config.Language].task3_desc,
        level = 3,
        divingMode = true, -- Underwater mission: spawns boat, enables scuba gear
        requirements = {
            { item = "sea_mine", amount = 7 }, -- Only sea_mine allowed when divingMode = true
        },
        rewards = { exp = 100, money = 15000 },
        players = { min = 1, max = 4 },
        area = {
            center = vec3(-2328.0093, -791.2150, -12.2449), -- Underwater coordinates (negative Z)
            radius = 30.0,
            blip = { sprite = 410, color = 3, scale = 0.8, label = "Underwater Minefield" }
        },
        delivery = vec4(474.2173, -1079.4603, 29.2020, 183.5736), -- Where to deliver collected mines
    },
    {
        title = Locales[Config.Language].task4_title,
        description = Locales[Config.Language].task4_desc,
        level = 4,
        divingMode = false,
        requirements = {
            { item = "m41", amount = 5 },
            { item = "ap_mine", amount = 5 },
        },
        rewards = { exp = 150, money = 20000 },
        players = { min = 1, max = 4 },
        area = {
            center = vec3(2431.1262, 1366.4037, 48.0859),
            radius = 120.0,
            blip = { sprite = 162, color = 1, scale = 1.1, label = "Restricted Zone" }
        },
        delivery = vec4(474.2173, -1079.4603, 29.2020, 183.5736), -- Where to deliver collected mines
    },
}

-- [ Mine Types ]

Config.Mines = {
    ["ap_mine"] = {
        label = "Anti-Personnel Mine",
        prop = "w_ex_apmine",
        dig_time = 3, -- second
    },
    ["m41"] = {
        label = "Anti-Tank Mine (M41)",
        prop = "gr_prop_gr_pmine_01a",
        dig_time = 5, -- second
    },
    ["sea_mine"] = {
        label = "Sea Mine",
        prop = "xm_prop_x17_mine_03a",
        neutralizeTime = 5000,
        neutralizeDistance = 3.5,
    },
}

-- [ Levels & Progression ]

Config.Levels = {
    [1] = { xpRequired = 0 },
    [2] = { xpRequired = 100 },
    [3] = { xpRequired = 250 },
    [4] = { xpRequired = 500 },
    [5] = { xpRequired = 800 },
    [6] = { xpRequired = 1200 },
    [7] = { xpRequired = 1700 },
    [8] = { xpRequired = 2300 },
    [9] = { xpRequired = 3000 },
    [10] = { xpRequired = 4000 },
}

-- [ Menu & Lobby ]

Config.Menu = {
    coord = vec4(453.6183, -810.1638, 27.7028, 222.1004), -- Lobby menu coordinates
    camera_coord = vec4(-126.0261, -641.0304, 168.8204, 30.8314),
    ped_base_distance = 3.0,
    ped_spacing = 0.9,
    max_members = 4,

    npc = {
        enabled = true, -- Enable/disable NPC
        model = `s_m_y_ammucity_01`, -- https://docs.fivem.net/docs/game-references/ped-models/
        scenario = "WORLD_HUMAN_CLIPBOARD_FACILITY", -- https://wiki.rage.mp/wiki/Scenarios
    },

    drawmarker = {
        enabled = true, -- Enable/disable marker
        scale = vec3(0.3, 0.3, 0.3),
        color = { r = 255, g = 255, b = 255, a = 255 }, -- RGBA
    },

    blip = {
        enabled = true, -- Enable/disable blip
        sprite = 626, -- https://docs.fivem.net/docs/game-references/blips/
        color = 1, -- https://docs.fivem.net/docs/game-references/blips/#blip-colors
        scale = 0.8,
        label = "Demining",
    },

    member_spots = {
        [1] = {
            coord = vec4(-125.5979, -642.6937, 168.8203, 24.5379),
            animDict = "anim@amb@casino@hangout@ped_male@stand@02b@idles",
            animName = "idle_a",
        },
        [2] = {
            coord = vec4(-126.0261, -641.0304, 168.8204, 30.8314),
            animDict = "timetable@reunited@ig_10",
            animName = "base_amanda",
        },
        [3] = {
            coord = vec4(-124.7194, -640.8194, 168.8205, 36.6985),
            animDict = "anim@amb@nightclub@peds@",
            animName = "rcmme_amanda1_stand_loop_cop",
        },
    }
}

-- [ Vehicle & Boat ]

Config.Vehicle = {
    model = "bison",
    spawnPoint = vec4(457.3053, -809.5168, 27.0318, 179.6624),
    platePrefix = "DMNING",
}

Config.Boat = {
    model = "dinghy",
    spawnPoint = vec4(-857.8867, -1485.7896, 0.1229, 289.6063),
}

-- [ Delivery Settings ]

Config.DeliveryNPC = {
    model = `s_m_y_armymech_01`,
    scenario = "WORLD_HUMAN_CLIPBOARD",
}

Config.DeliveryBlip = { sprite = 478, color = 2, scale = 0.7 }

-- [ Ballistic Armor ]

Config.BallisticArmor = {
    active = true, -- Enable/disable ballistic armor outfit
    male = {
        components = {
            { id = 8, drawable = 97, texture = 0 },   -- Tshirt
            { id = 11, drawable = 186, texture = 0 },  -- Torso
            { id = 3, drawable = 17, texture = 0 },   -- Arms
            { id = 4, drawable = 84, texture = 0 },   -- Pants
            { id = 6, drawable = 61, texture = 0 },   -- Shoes
        },
        props = {
            { id = 0, index = 125, texture = 0 },     -- Helmet
        }
    },
    female = {
        components = {
            { id = 8, drawable = 105, texture = 0 },  -- Tshirt
            { id = 11, drawable = 188, texture = 0 },  -- Torso
            { id = 3, drawable = 17, texture = 0 },   -- Arms
            { id = 4, drawable = 86, texture = 0 },   -- Pants
            { id = 6, drawable = 34, texture = 0 },   -- Shoes
        },
        props = {
            { id = 0, index = 124, texture = 0 },     -- Helmet
        }
    }
}

-- [ Diving Mode ]

Config.DivingMode = {
    enabled = true,
    maxUnderwaterTime = 2000.0,
    tank = {
        model = "p_s_scuba_tank_s",
        bone = 24818, -- SKEL_Spine3
        offset = vec3(-0.25, -0.25, 0.0),
        rotation = vec3(180.0, 90.0, 0.0),
    },
    mask = {
        model = "p_d_scuba_mask_s",
        bone = 12844, -- SKEL_Head
        offset = vec3(0.0, 0.0, 0.0),
        rotation = vec3(180.0, 90.0, 0.0),
    },
}

-- [ Framework Functions ]

Config.Functions = {
    ["giveKey"] = function(plate)
        if GetResourceState('qb-vehiclekeys') == 'started' then -- QB-Core
            TriggerEvent('vehiclekeys:client:SetOwner', plate)
        elseif GetResourceState('Renewed-Vehiclekeys') == 'started' then -- Renewed
            exports['Renewed-Vehiclekeys']:addKey(plate)
        elseif GetResourceState('qs-vehiclekeys') == 'started' then -- Quasar
            TriggerEvent('qs-vehiclekeys:client:GiveKey', plate)
        elseif GetResourceState('wasabi_carlock') == 'started' then -- Wasabi
            exports.wasabi_carlock:GiveKey(plate)
        elseif GetResourceState('vehicles_keys') == 'started' then -- Jaksam
            TriggerServerEvent('vehicles_keys:selfGiveVehicleKeys', plate)
        elseif GetResourceState('t1ger_keys') == 'started' then -- T1GER
            exports.t1ger_keys:GiveTemporaryKeys(plate)
        elseif GetResourceState('esx_vehiclelock') == 'started' then -- ESX
            TriggerEvent('esx_vehiclelock:setKey', plate, true)
        end
    end,

    ["removeKey"] = function(plate)
        if GetResourceState('qb-vehiclekeys') == 'started' then -- QB-Core
            TriggerEvent('vehiclekeys:client:RemoveKey', plate)
        elseif GetResourceState('Renewed-Vehiclekeys') == 'started' then -- Renewed
            exports['Renewed-Vehiclekeys']:removeKey(plate)
        elseif GetResourceState('qs-vehiclekeys') == 'started' then -- Quasar
            TriggerEvent('qs-vehiclekeys:client:RemoveKey', plate)
        elseif GetResourceState('wasabi_carlock') == 'started' then -- Wasabi
            exports.wasabi_carlock:RemoveKey(plate)
        elseif GetResourceState('vehicles_keys') == 'started' then -- Jaksam
            TriggerServerEvent('vehicles_keys:selfRemoveVehicleKeys', plate)
        elseif GetResourceState('t1ger_keys') == 'started' then -- T1GER
            exports.t1ger_keys:RemoveTemporaryKeys(plate)
        elseif GetResourceState('esx_vehiclelock') == 'started' then -- ESX
            TriggerEvent('esx_vehiclelock:setKey', plate, false)
        end
    end,

    ["helpNotify"] = function(message)
        lib.showTextUI(message, {
            position = "right-center",
            icon = "bomb",
            style = {
                borderRadius = 1,
                whiteSpace = 'pre-line'
            }
        })
    end,

    ["hideHelpNotify"] = function()
        lib.hideTextUI()
    end,

    ["notify"] = function(type, message)
        lib.notify({
            title = Locales[Config.Language].notify_title,
            icon = 'bomb',
            description = message,
            type = type,
            duration = 5000,
        })
    end
}

Config.HudFunctions = {
    -- targeting when lobby is opened
    ["show"] = function()
        -- your code here
    end,

    ["hide"] = function()
        -- your code here
    end
}

Last updated