NR_Harness

A professional vehicle modification script for QBX/QBCore that allows authorized mechanics to install and remove racing harnesses with persistent database storage.

Features

Dependencies

Resource Description Required
qbx_core Core framework Yes
ox_lib UI library (context menus, progress bars, notifications) Yes
ox_inventory Inventory system Yes
ox_target Interaction system Yes
oxmysql Database connector Yes

Installation

Step 1: Database Setup

Execute the included SQL file to create the vehicle_harnesses table. This stores all harness installations persistently.

Step 2: Download

Download NR_Harness and extract it to your resources folder:

server/
  └── resources/
      └── [nightrider]/
          └── NR_Harness/

Step 3: server.cfg

Add the resource to your server configuration:

ensure NR_Harness

Step 4: Add Inventory Item

Add a harness item to your ox_inventory:

['harness'] = {
    label = 'Racing Harness',
    weight = 2500,
    stack = false,
    close = true,
    description = 'A racing harness for improved vehicle safety'
}

Step 5: Configure

Edit config.lua to set authorized jobs, harness item name, and installation/removal times.

Step 6: Restart

Restart your server to load the resource.

⚠️ Dependencies

Make sure qbx_core, ox_lib, ox_inventory, ox_target, and oxmysql are all started before NR_Harness in your server.cfg.

How It Works

1. Obtaining Harnesses

Mechanics receive or purchase harness items. Items are stored in ox_inventory like normal.

2. Installation Process

Mechanic approaches a vehicle (within 3 meters default) and uses /harness or ox_target on the vehicle. Select "Install Racing Harness" from the menu. A 10-second progress bar plays with a repair animation. The harness item is consumed from inventory, the installation is saved to the database, and all clients are notified of the harness status.

3. Removal Process

Mechanic approaches a vehicle that has a harness and uses /harness or ox_target. Select "Remove Racing Harness". An 8-second progress bar plays with a repair animation. The harness is removed from the database, the item is returned to inventory (if configured), and all clients are notified of the status change.

Database Schema

vehicle_harnesses
├── id (INT) - Primary key
├── plate (VARCHAR) - Vehicle plate (unique)
└── installed_at (TIMESTAMP) - Installation date/time

Features a unique constraint on plate (one harness per vehicle), indexed plate column for fast lookups, timestamp tracking for installation history, and ON DUPLICATE KEY UPDATE for reinstallation handling.

Configuration

Job Permissions

Config.Jobs = {
    'flywheel',      -- Mechanic shop 1
    'afterlife',     -- Mechanic shop 2
    'bennys',        -- Add more as needed
}

Item Settings

Config.HarnessItem = 'harness'  -- Item name in ox_inventory

Distance & Timing

Config.InstallDistance = 3.0  -- Meters from vehicle

Config.HarnessSettings = {
    installTime = 10000,  -- 10 seconds
    removeTime = 8000,    -- 8 seconds
    returnItemOnRemove = true,  -- Give item back when removing
}

Custom Notifications

Config.Notifications = {
    installSuccess = 'Racing harness installed successfully!',
    removeSuccess = 'Racing harness removed successfully!',
    alreadyInstalled = 'This vehicle already has a harness installed!',
    noHarness = 'This vehicle does not have a harness installed!',
    noItem = 'You need a racing harness to install!',
    wrongJob = 'You are not qualified to install/remove harnesses!',
    cancelled = 'Installation cancelled!',
    vehicleNotFound = 'No vehicle found nearby!',
}

Integration with Other Scripts

Export: Check Harness Status

Other scripts can check if a vehicle has a harness installed:

local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
local hasHarness = exports['NR_Harness']:hasHarness(vehicle)

if hasHarness then
    -- Apply harness benefits (reduced ejection, etc.)
else
    -- Normal vehicle behavior
end

Example: Ejection Prevention

CreateThread(function()
    while true do
        Wait(100)
        local ped = PlayerPedId()

        if IsPedInAnyVehicle(ped, false) then
            local vehicle = GetVehiclePedIsIn(ped, false)
            local hasHarness = exports['NR_Harness']:hasHarness(vehicle)

            if hasHarness then
                SetPedConfigFlag(ped, 32, false) -- Disable exit on impact
            end
        end
    end
end)

Example: Racing Script Integration

AddEventHandler('baseevents:onPlayerWasted', function()
    local ped = PlayerPedId()
    if IsPedInAnyVehicle(ped, false) then
        local vehicle = GetVehiclePedIsIn(ped, false)
        local hasHarness = exports['NR_Harness']:hasHarness(vehicle)

        if hasHarness then
            SetEntityHealth(ped, GetEntityHealth(ped) + 50)
        end
    end
end)

Common use cases:

Security Features

Server-Side Validation

Protection Description
Job verification Every action double-checks job permission, prevents client-side exploits
Item possession Validates harness item via ox_inventory:Search() before installation
Database integrity UNIQUE constraint on plate prevents duplicates, ON DUPLICATE KEY UPDATE handles edge cases
State validation Checks if harness exists before install/remove, prevents impossible state transitions

Client-Side Protection

Customization

Adding More Jobs

Config.Jobs = {
    'mechanic',
    'tuner',
    'customs',
    'garage',
}

Custom Animations

Modify the animation in progress circles:

anim = {
    dict = 'anim@amb@clubhouse@tutorial@bkr_tut_ig3@',
    clip = 'machinic_loop_mechandplayer'
}

Popular mechanic animations:

Different Item Per Job

Modify the item check in server.lua:

local itemToUse = Config.HarnessItem
if player.PlayerData.job.name == 'premium_mechanic' then
    itemToUse = 'premium_harness'
end

Commands

Command Description Permission
/harness Open harness installation menu for nearest vehicle Configured jobs only

Performance

Metric Value
Resmon impact ~0.00ms (idle), ~0.01ms (in vehicle check)
Network traffic Minimal (event on install/remove only)
Database queries 1 on resource start (load all), 1 per install/remove
Memory usage ~0.8 MB
Threads 1 (vehicle entry detection)

Database Maintenance

-- Check harness count
SELECT COUNT(*) FROM vehicle_harnesses;

-- List all harnessed vehicles
SELECT plate, installed_at FROM vehicle_harnesses ORDER BY installed_at DESC;

-- Remove harness from specific vehicle
DELETE FROM vehicle_harnesses WHERE plate = 'ABC123';

-- Clear old harnesses (vehicles likely deleted)
DELETE FROM vehicle_harnesses WHERE installed_at < DATE_SUB(NOW(), INTERVAL 90 DAY);

Troubleshooting

Harness not installing

Database errors

ox_target not showing option

Harness status not updating

Item not returning on removal

Wrong vehicle getting harness

Support

Need help? Join our Discord server for community support and updates.