Rent a Car: Exports & Events
Rent vehicles from other resources, read a player's rentals, listen for rental changes and use the framework and module bridges.
Resource name
Because the resource name contains a hyphen, call exports as exports["hype-rentacar"] rather than
exports.hype-rentacar.
| Export | Side | Purpose |
|---|---|---|
IsOpen | Client | Whether the rental menu is open |
Close | Client | Closes the rental menu |
GetCatalog | Server | Vehicles, durations, offices, accounts and rental rules |
GetPlayerData | Server | A player's balance, license state and active rentals |
Rent | Server | Books a rental that is collected later at an office |
Respawn | Server | Respawns a lost rental next to the player |
SendNotify | Both | Shows a notification with the configured resource |
GetModules | Both | Returns the script's module table |
GetFrameworkObject | Both | Returns the framework bridge |
Client exports
IsOpen
Returns true while the rental menu is open. Useful to block your own UI or keybinds.
if exports["hype-rentacar"]:IsOpen() then return endClose
Closes the rental menu and gives the camera back.
exports["hype-rentacar"]:Close()Server exports
These are the exports hype-rentacar-app is built on. They go through the same checks as the office: cooldown, request lock, license, rental limit and balance.
GetCatalog
Returns everything needed to show a rental catalog outside of an office.
local catalog = exports["hype-rentacar"]:GetCatalog()
print(catalog.company, #catalog.vehicles)| Field | Type | Content |
|---|---|---|
company | string | CompanyName |
ui | table | UI (accent, numberLocale, currency) |
vehicles | { model, label, category, price, deposit, image }[] | Vehicles offered at one office or more |
durations | { hours, discount }[] | Durations |
locations | { id, label, coords = { x, y } }[] | Offices |
accounts | string[] | PaymentAccounts |
requireLicense | boolean | License.required |
maxRentals | number | MaxActiveRentals |
remote | { enabled, fee } | Phone rental rules |
respawn | { enabled, fee } | true only when Respawn.enabled and Respawn.remote |
GetPlayerData
Returns a player's info, license state and active rentals, or nil when the player is not loaded.
local data = exports["hype-rentacar"]:GetPlayerData(source)
if data and #data.rentals > 0 then
print(data.rentals[1].plate, data.rentals[1].remaining)
endProp
Type
| Field | Type | Content |
|---|---|---|
player | { id, firstname, lastname, cash, bank } | Character name and balances |
license | boolean | Whether the player passes the license check |
rentals | table[] | Active rentals, oldest first |
Each rental has id, model, label, plate, hours, deposit, payment, location, locationLabel, image,
remaining (seconds), pickedUp, vehicleExists and coords ({ x, y } while the vehicle exists).
Rent
Books a rental for a player. No vehicle is spawned; the player collects it at any office that offers the model. The
Remote.fee is added, and the call fails when Remote.enabled is false.
local success, result = exports["hype-rentacar"]:Rent(source, {
model = "blista",
hours = 4,
payment = "bank",
})
if success then
print(("Rental #%d, plate %s"):format(result.id, result.plate))
else
print("Rent failed: " .. result)
endProp
Type
Returns true, { id, plate, label, hours } on success, or false, errorCode.
Respawn
Spawns a picked up rental whose vehicle no longer exists at the given point, and charges Respawn.fee. The point must
be within Respawn.maxDistance of the player and free of vehicles.
local coords = GetEntityCoords(GetPlayerPed(source))
local success, result = exports["hype-rentacar"]:Respawn(source, rentalId, {
x = coords.x + 4.0, y = coords.y, z = coords.z, w = 90.0,
})Prop
Type
Returns true, { id, plate, label, fee, coords } on success, or false, errorCode.
Error codes
On failure result is one of these codes. Each one is a key under ui.errors in the locale files.
| Code | Meaning |
|---|---|
no_money | Not enough money in the selected account |
no_license | The license check failed |
max_rentals | MaxActiveRentals is reached |
too_far | The player is too far from the office |
spawn_blocked | Every spawn point is blocked |
spawn_failed | The vehicle could not be created, the payment was refunded |
vehicle_far | The vehicle is outside the office's returnRadius |
no_rental | The rental does not exist or belongs to someone else |
no_player | The player is not loaded |
busy | Another request of this player is still running |
cooldown | Security.cooldown has not passed yet |
remote_disabled | Remote.enabled is false |
respawn_disabled | Respawn.enabled or Respawn.remote is false |
almost_expired | Less than a minute is left |
vehicle_exists | The vehicle is still out, nothing to respawn |
already_picked_up | The phone rental was already collected |
not_picked_up | The phone rental must be collected at an office first |
not_available_here | This office does not offer the model |
invalid | Invalid data, see the console with Security.logSuspicious |
Shared exports
SendNotify
Shows a notification with the resource set in Notifications (okokNotify, ps-ui or ox_lib). On the server the first
argument is the player, -1 notifies everyone.
exports["hype-rentacar"]:SendNotify("Los Santos Rent a Car", "Your rental is ready.", 5000, "success")exports["hype-rentacar"]:SendNotify(source, "Los Santos Rent a Car", "Your rental is ready.", 5000, "success")Prop
Type
GetModules
Returns the module table of the side it is called on. With a name, only that module: Notify, Target and Fuel on
the client, Notify, Inventory, VehicleKeys and Fuel on the server.
local keys = exports["hype-rentacar"]:GetModules("VehicleKeys")
keys.GiveKeys(source, vehicle, "RENT1234", "blista")Prop
Type
The module functions are exported on their own as well: GiveKeys(playerId, vehicle, plate?, model?),
SetFuel(playerId, vehicle, level?) and HasItem / GetItemCount on the server, SetFuel on the client.
GetFrameworkObject
Returns the framework bridge of the side it is called on (Framework.Server or Framework.Client).
local framework = exports["hype-rentacar"]:GetFrameworkObject()
local bank = framework.GetPlayerMoney(source, "bank")Framework bridges
The framework bridges in frameworks/ and the modules in modules/ are not escrow protected. If your economy,
license or vehicle system is customized, you can change them there. Each bridge implements the same functions:
| Function | Purpose |
|---|---|
GetPlayerIdentifier(playerId) | Character id, citizenid on QB/QBox, identifier on ESX |
GetSourceFromIdentifier(identifier) | Server ID of an online character, for expiry notifications |
GetCharacterName(playerId, split) | First and last name shown in the menu |
GetPlayerMoney(playerId, type) | Balance of "cash" or "bank" |
RemovePlayerMoney(playerId, type, amount, reason) | Charges rent, deposit and fees, returns true on success |
AddPlayerMoney(playerId, type, amount, reason) | Deposit refunds and failed rentals |
HasLicense(playerId, license) | metadata.licences on QB/QBox, user_licenses on ESX |
IsPlateTaken(plate) | Skips plates of owned vehicles |
Keep the return values
The script relies on RemovePlayerMoney returning true only when the money really moved. Returning true on a
failed payment lets players rent for free.
Events
hype-rentacar:client:updated
Fired on the player's client whenever their rentals change: rent, pickup, return, respawn and expiry. The phone app refreshes on it. Trigger it yourself from the server to refresh a player's app.
RegisterNetEvent("hype-rentacar:client:updated", function()
-- the player's rentals changed
end)TriggerClientEvent("hype-rentacar:client:updated", source)