> For the complete documentation index, see [llms.txt](https://risenova-scripts.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://risenova-scripts.gitbook.io/docs/risenova-black-market/config.md).

# Config

```lua
Config = {}

-- Language: en | es | fr | de
Config.Locale = 'en' 

-- Framework: qbcore | qbox | esx
Config.Framework = 'qbcore' 

-- Inventory:  qb | ox | custom
Config.Inventory = 'qb'

Config.ItemImagePath = {
    qb = "nui://qb-inventory/html/images/",
    ox = "nui://ox_inventory/web/images/",
    custom = "nui://custom-inventory/html/images/",
}

-- Vehicle Keys: qb | qbx | sna | custom
Config.VehicleKeys = 'qb' 

-- Target: qb | ox
Config.Target = 'qb'

-- Notification: framework | ox_lib | risenova (FREE - https://risenova-scripts.tebex.io/package/7610671)
Config.Notify = 'framework'

Config.AutoCreateDatabase = true 
-- true: create our table automatically on startup.
-- false: manually import sql/install.sql before starting this resource.

Config.MoneyAccount = 'cash' -- 'cash' or 'bank' (ESX = 'money')

Config.Webhooks = {
    Enabled = false, 
    WebhookURL = 'YOUR_WEBHOOK_HERE',
    BotName = 'RiseNova BlackMarket',
    Color = 65280,
}

-- These jobs cannot shop and do not receive dealer relocation notifications
Config.BlockedJobs = { police = true, ambulance = true }

-- true = fixed location, false = rotate between dealer locations
Config.FixedLocation = false 
Config.FixedVector = vector4(706.49, -966.96, 30.41, 8.46)
Config.RotationMinutes = 60 -- Dealer rotation interval in minutes.

Config.ContractCommand = {
    Enabled = true, -- false disables the command
    Name = 'bmcontract', -- Command name
}

Config.MissionMinutes = 20 -- Time to complete the job
Config.PickupMinutes = 10 -- Time to purchase the item after finishing the job
Config.CooldownMinutes = 30 -- Cool down time for jobs
Config.ReputationPerMission = 10 -- Reputation earned per completed job


-- PURCHASE MODES:
-- 'buy'      = Buy at full price.
-- 'optional' = Player chooses: buy at full price OR do a job for a discount.
-- 'contract' = Must do a job first.

-- ITEM FIELDS:
-- id         = Unique ID for each item. Don't use the same ID twice.
-- item       = Item name from your inventory.
-- label      = Name shown in the shop.
-- price      = Price per item.
-- stock      = How many are available.
-- reputation = Minimum reputation needed (0 = no requirement).
-- discount   = Discount after completing a job (25 = 25% off). Doesn't apply to 'buy'.
-- missions   = Jobs available for this item. One is chosen randomly.

Config.Dealers = {
    ghost = {
        name = 'Ghost', model = 'g_m_y_mexgoon_02',
        locations = {
            vector4(706.49, -966.96, 30.41, 8.46),
            vector4(1240.06, -3179.99, 7.15, 6.23), 
            vector4(-1165.72, -1566.95, 4.45, 308.27)
        },
        items = {
            -- Full-price purchases only
            { id = 'lockpick', item = 'lockpick', label = 'Lockpick', purchaseMode = 'buy', price = 500, stock = 20, reputation = 0, },
            { id = 'advancedlockpick', item = 'advancedlockpick', label = 'Advanced Lockpick', purchaseMode = 'buy', price = 1500, stock = 15, reputation = 0, },
            { id = 'switchblade', item = 'weapon_switchblade', label = 'Switchblade', purchaseMode = 'buy', price = 3500, stock = 8, reputation = 0, },

            -- Buy now OR do a job and get a discount
            { id = 'pistol', item = 'weapon_pistol', label = 'Pistol', purchaseMode = 'optional', price = 18000, stock = 5, reputation = 0, discount = 25, missions = { 'supply_run' , 'data_heist' }, },
            { id = 'electronickit', item = 'electronickit', label = 'Electronic Kit', purchaseMode = 'optional', price = 4500, stock = 10, reputation = 0, discount = 15, missions = { 'supply_run', 'stash' }, },
            { id = 'trojan_usb', item = 'trojan_usb', label = 'Trojan USB', purchaseMode = 'optional', price = 8000, stock = 6, reputation = 10, discount = 20, missions = { 'data_heist' }, },

            -- Contract required
            { id = 'smg', item = 'weapon_microsmg', label = 'Micro SMG', purchaseMode = 'contract', price = 55000, stock = 2, reputation = 50, discount = 20, missions = { 'vehicle', 'data_heist', 'sabotage' }, },
            { id = 'thermite', item = 'thermite', label = 'Thermite', purchaseMode = 'contract', price = 12000, stock = 5, reputation = 20, discount = 20, missions = { 'sabotage', 'supply_run' }, },
            { id = 'security_card', item = 'security_card_01', label = 'Security Card A', purchaseMode = 'contract', price = 15000, stock = 3, reputation = 30, discount = 25, missions = { 'data_heist' }, },
        }
    }
}

-- vehicle    = Steal and deliver a car.
-- stash      = Easy cache recovery.
-- supply_run = Medium multi-stop collection.
-- sabotage   = Hard relay job.
-- data_heist = Hard terminal/access-code job.

-- Every mission is configured in Config.Missions below
-- Vehicle contract spawn locations
Config.Spawns = {
    vector4(1141.82, -1330.63, 34.05, 272.78),
    vector4(1116.21, -2234.75, 29.47, 84.84),
    vector4(543.36, -3055.27, 5.46, 0.46),
    vector4(117.18, -3291.16, 5.41, 180.0)
}

Config.DropoffsVehicles = {
    vector3(-46.44, -2095.84, 16.36), 
    vector3(20.18, -1776.73, 28.97),
    vector3(142.26, -1282.59, 28.96),
    vector3(487.54, -30.39, 77.37)
}
-- Stash, supply_run, sabotage and data_heist
Config.Dropoffs = {
    vector4(68.04, 179.2, 106.61, 350.77),
    vector4(1099.26, -345.83, 67.18, 308.93),
    vector4(-588.73, -797.51, 26.14, 185.12),
    vector4(-1337.67, -1251.97, 5.94, 113.7)
}

-- Private sellers for the purchase after any contract.
Config.Handoffs = {
    vector4(1239.36, -3174.46, 7.1, 272.5),
    vector4(877.3, -3301.49, 7.09, 95.63),
    vector4(110.51, -2576.99, 6.69, 271.91),
    vector4(-1083.21, -1262.14, 5.59, 304.87)
}

-- Keep these separate from Dropoffs (delivery) and Handoffs (item purchase)
Config.MissionLocations = {
    Stash = {
        vector4(752.81, -3198.57, 6.19, 0.7),
        vector4(1208.71, -3115.43, 5.54, 88.3)
    },

    SupplyFirst = {
        vector4(752.75, -3192.07, 6.07, 178.2)
    },

    SupplySecond = {
        vector4(1006.3, -1556.45, 30.83, 95.13)
    },

    SupplyFinal = {
        vector4(1145.37, -1402.91, 34.80, 180.0)
    },

    RelayFirst = {
        vector4(892.47, -2171.85, 32.29, 170.75)
    },

    RelayBackup = {
        vector4(1004.76, -1572.7, 30.83, 359.89)
    },

    DataTerminal = {
        vector4(1207.59, -3122.34, 5.54, 1.14)
    },

    DataAccess = {
        vector4(911.01, -2535.05, 28.31, 202.3)
    },
}

Config.Minigames = {
    Enabled = true,       
    MaxFailures = 3,      -- Max failed attempts before the contract fails.
    RetrySeconds = 10,    -- Wait after a failed puzzle before retrying.
}

-- Vehicle routes use Config.Spawns. Other missions use steps.
-- Puzzle types: 'memory', 'wires', 'decode', or false to disable.
-- length = number of symbols/wires
-- seconds = time limit
-- reveal = how long the memory puzzle is shown

-- Don't change activity values. They're used for mission animations.

Config.Missions = {
    vehicle = {
        label = 'Vehicle acquisition',
        models = { 'sultan', 'buffalo', 'baller' },
    },
    stash = {
        label = 'Hidden cache', difficulty = 'Easy', minutes = 15,
        steps = {
            { label = 'Open the hidden cache', activity = 'cache', game = 'memory', length = 3, seconds = 18, reveal = 3,
              locations = Config.MissionLocations.Stash },
            { label = 'Deliver the sealed cache', activity = 'deliver', game = false, locations = Config.Dropoffs },
        },
    },
    supply_run = {
        label = 'Scattered shipment', difficulty = 'Medium', minutes = 18,
        steps = {
            { label = 'Collect the first package', activity = 'supplies', game = false, locations = Config.MissionLocations.SupplyFirst },
            { label = 'Unlock the second package', activity = 'supplies', game = 'memory', length = 4, seconds = 18, reveal = 3,
              locations = Config.MissionLocations.SupplySecond },
            { label = 'Collect the final package', activity = 'supplies', game = false, locations = Config.MissionLocations.SupplyFinal },
            { label = 'Deliver the complete shipment', activity = 'deliver', game = false, locations = Config.Dropoffs },
        },
    },
    sabotage = {
        label = 'Cut the connection', difficulty = 'Hard', minutes = 12,
        steps = {
            { label = 'Disable the first relay', activity = 'relay', game = 'wires', length = 4, seconds = 18,
              locations = Config.MissionLocations.RelayFirst },
            { label = 'Disable the backup relay', activity = 'relay', game = 'wires', length = 6, seconds = 16,
              locations = Config.MissionLocations.RelayBackup },
            { label = 'Give the relay report to the technician', activity = 'report', game = false, locations = Config.Dropoffs },
        },
    },
    data_heist = {
        label = 'Ghost protocol', difficulty = 'Hard', minutes = 10,
        steps = {
            { label = 'Decode the terminal challenge', activity = 'terminal', game = 'decode', length = 3, seconds = 25,
              locations = Config.MissionLocations.DataTerminal },
            { label = 'Copy the rotating access code', activity = 'access', game = 'memory', length = 7, seconds = 18, reveal = 4,
              locations = Config.MissionLocations.DataAccess },
            { label = 'Deliver the stolen data', activity = 'report', game = false, locations = Config.Dropoffs },
        },
    },
}


```
