Vehicle keys as items
Please join my discord : https://discord.gg/kvSwVzD8Rd
- The key is created with the vehicle plate and model in item description
- Keys are given at car buy (events available)
- The locksmith is used to buy additional keys and change locks of a car
- When a player tries to enter the car, it check the lock value of the car
- Npc cars are accessible the gta way (carjacking or window breaking)
- If car is locked the player can lockpick it, else the player can enter
- Once the player is in the car a check is made for the key item in inventory to start the engine
- If the player have no key he can try to hotwire the car
- For admin cars (/car) the car is now yours temporarly, so you have an "old style invisible key"
- When a job spawn a free car, the player receives the same old style key, so no hotwire
- When a car is sold, the key can be removed
- Keys are never deleted or removed, and not given by the garage anymore, you need to keep the keys in your inventory or storage
- [es_extended] or [qb-core]
- [ox_inventory] or [qb-inventory]
- [ox_target] or [qb-target]
- lockpick Lockpick is already included in QBCore
-
Delete qb-vehiclekeys from qbcore
-
Install the new resource with a name THAT IS NOT qb-vehiclekeys
-
Copy the vehiclekeys image in img folder into qb-inventory\html\images
-
Import QBCore part of database.sql into your database
-
Add in qb-core/shared/items.lua
vehiclekey = { name = 'vehiclekey', label = 'Vehicle key', weight = 10, type = 'item', image = 'vehiclekey.png', unique = true, useable = true, shouldClose = true, combinable = nil, description = "This is a car key, take good care of it, if you lose it you probably won't be able to use your car" },
Depending of your qb-inventory version some changes may or may not be required
- Older version :
-
- Add item info to qb-inventory\html\js\app.js in function FormatItemInfo
} else if (itemData.name == "vehiclekey") { //Change Add
$(".item-info-title").html('<p>' + itemData.info.model + '</p>'); //Change Add
$(".item-info-description").html('<p>Plate : ' + itemData.info.plate + '</p>'); //Change Add
- Mid version :
-
- Add item info to qb-inventory\html\js\app.js around line 395 in function generateDescription
case "labkey":
return `<p>Lab: ${itemData.info.lab}</p>`;
case "vehiclekey": //Change Add
return `<p><strong>Car: </strong><span>${itemData.info.model}</span></p>
<p><strong>Plate: </strong><span>${itemData.info.plate}</span></p>`; //Change Add
default:
return itemData.description;
- Latest version :
-
- Modify the line 861 from qb-inventory/html/app.js in generateTooltipContent
if (item.info && Object.keys(item.info).length > 0) {
for (const [key, value] of Object.entries(item.info)) {
if (key !== "description" && key !== "lock") { //Change
let valueStr = value;
if (key === "attachments") {
valueStr = Object.keys(value).length > 0 ? "true" : "false";
}
content += `<div class="tooltip-info"><span class="tooltip-info-key">${this.formatKey(key)}:</span> ${valueStr}</div>`;
}
}
}
-
Copy the vehiclekeys image in img folder into ox_inventory\web\images
-
Import ESX part of database.sql into your database
-
Add in ox_inventory\data\items.lua
['vehiclekey'] = {
label = 'Vehicle Key',
stack = false,
weight = 1,
client = {
image = 'vehiclekey.png'
}
},
The bridge is used to make the script multi framework. The bridge support at the moment
- QBCore with qb-inventory qb-menu and qb-target
- ESX with ox_inventory ox_lib menu and ox_target For any other combination you will need to edit yourself the bridge to adapt it. So for QBcore with ox_inventory you need to take every line with ox_inventory from the ESX bridge and insert them into the QBCore bridge.
Basically this script needs some event to be triggered at some points, 2 client events are available
TriggerEvent("vehiclekeys:client:SetOwner", plate)
TriggerEvent('sna-vehiclekeys:server:BuyVehicle', plate, model)
SetOwner event is used for temporary vehicles (all unowned vehicles like job spawned vehicles or admin cars) it makes you owner of the vehicle without having a physical key This event is present everywhere in QBCore and must remain excepted in the garage script and the vehicle shop script where it must be commented/deleted This event is not present in ESX as there is no native support for keys, you must then add it for the temporary vehicles spawns
BuyVehicle event is used to give a physical key for a vehicle, this event must be added in the vehicle shop script after the vehicle spawn when you have a plate
For QBCore, you can also search for qb-vehiclekeys:server:AcquireVehicleKeys, this must be replaced with the event sna-vehiclekeys:server:BuyVehicle or sna-vehiclekeys:server:GiveTempKey depending of the type of key you want to grant (temporary or physical)
Here are the examples of the events correctly placed, to be adapted to your scripts
RegisterNetEvent('qb-vehicleshop:client:buyShowroomVehicle', function(vehicle, plate)
tempShop = insideShop -- temp hacky way of setting the shop because it changes after the callback has returned since you are outside the zone
QBCore.Functions.TriggerCallback('QBCore:Server:SpawnVehicle', function(netId)
local veh = NetToVeh(netId)
exports['LegacyFuel']:SetFuel(veh, 100)
SetVehicleNumberPlateText(veh, plate)
SetEntityHeading(veh, Config.Shops[tempShop]["VehicleSpawn"].w)
--TriggerEvent("vehiclekeys:client:SetOwner", QBCore.Functions.GetPlate(veh)) --Change comment
TriggerServerEvent("qb-vehicletuning:server:SaveVehicleProps", QBCore.Functions.GetVehicleProperties(veh))
TriggerServerEvent('qb-vehiclekeys:server:BuyVehicle', plate, GetLabelText(GetDisplayNameFromVehicleModel(GetEntityModel(veh)))) --Change Add
end, vehicle, Config.Shops[tempShop]["VehicleSpawn"], true)
end)
RegisterNetEvent('qb-garages:client:takeOutGarage', function(data)
local type = data.type
local vehicle = data.vehicle
local garage = data.garage
local index = data.index
QBCore.Functions.TriggerCallback('qb-garage:server:IsSpawnOk', function(spawn)
if spawn then
local location
if type == "house" then
location = garage.takeVehicle
else
location = garage.spawnPoint
end
QBCore.Functions.TriggerCallback('qb-garage:server:spawnvehicle', function(netId, properties)
local veh = NetToVeh(netId)
QBCore.Functions.SetVehicleProperties(veh, properties)
exports['LegacyFuel']:SetFuel(veh, vehicle.fuel)
doCarDamage(veh, vehicle)
TriggerServerEvent('qb-garage:server:updateVehicleState', 0, vehicle.plate, index)
closeMenuFull()
--TriggerEvent("vehiclekeys:client:SetOwner", QBCore.Functions.GetPlate(veh)) --Change comment
SetVehicleEngineOn(veh, true, true)
if type == "house" then
exports['qb-core']:DrawText(Lang:t("info.park_e"), 'left')
InputOut = false
InputIn = true
end
end, vehicle, location, true)
else
QBCore.Functions.Notify(Lang:t("error.not_impound"), "error", 5000)
end
end, vehicle.plate, type)
end)
ESX.RegisterServerCallback('esx_vehicleshop:buyVehicle', function(source, cb, model, plate)
local xPlayer = ESX.GetPlayerFromId(source)
local modelPrice = getVehicleFromModel(model).price
if modelPrice and xPlayer.getMoney() >= modelPrice then
xPlayer.removeMoney(modelPrice, "Vehicle Purchase")
MySQL.insert('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (?, ?, ?)', {xPlayer.identifier, plate, json.encode({model = joaat(model), plate = plate})
}, function(rowsChanged)
xPlayer.showNotification(TranslateCap('vehicle_belongs', plate))
ESX.OneSync.SpawnVehicle(joaat(model), Config.Zones.ShopOutside.Pos, Config.Zones.ShopOutside.Heading,{plate = plate}, function(vehicle)
Wait(100)
local vehicle = NetworkGetEntityFromNetworkId(vehicle)
Wait(300)
TriggerClientEvent('qb-vehiclekeys:client:BuyVehicle', source, plate) --Change
TaskWarpPedIntoVehicle(GetPlayerPed(source), vehicle, -1)
end)
cb(true)
end)
else
cb(false)
end
end)
This event can be used to automatically remove a key from player's inventory (for exceptionnal use like rent end)
TriggerServerEvent('qb-vehiclekeys:server:RemoveKey', plate)