# Functions/Events

## client/editable-main.lua

### `HasAnyMoney()`

Checks if the player has money based on the configured framework.

#### Supported Frameworks

* **ESX** → Checks cash + all accounts
* **QBCore / Qbox** → Checks `cash` and `bank`
* **vRP** → Checks wallet + bank

#### Returns

* `true` → Player has money
* `false` → Player has no money

***

### &#x20;`giveKey(vehicle)`

Gives vehicle keys to the player.

#### Parameter

* `vehicle` (entity)

#### Default Support

* **QBCore / Qbox** → Uses `qb-vehiclekeys`
* **ESX** → Add your logic

#### Custom Key Scripts

If you use another vehicle key system, simply implement its logic inside this function.

***

### `TrainPunishment()`

Executed when a player passes an illegal train station.

* Return `true` → Apply punishment
* Add your own fine/kick/jail logic inside the function

***

### client/bridge.lua

### UI Functions

#### `openTicketsUi()`

Opens the **Train Ticket UI**.

* Detects nearest station
* Sends station list, pricing, and time to NUI
* Prevents duplicate UI opening

***

#### `openDeparturesUi()`

Opens the **Plane Departures UI**.

* Filters nearby plane routes
* Sends routes + frequency to NUI

***

#### `openFerryUi()`

Opens the **Boat/Ferry Departures UI**.

* Filters nearby boat routes
* Sends routes + frequency to NUI

***

#### `closeAllUI()`

Closes any open UI and removes NUI focus.

***

### Ticket Display

#### `UpdateDynamicTicket(ticketData)`

Controls the floating ticket display.

* Pass ticket data → shows ticket
* Pass `nil` → hides ticket
* Automatically formats train / plane / boat types

***

### Station & Route Helpers

ALL train routes are customisable.

#### `GetClosestStation(coords)`

Returns the nearest train station ID.

***

#### `GetStationCoords(id)`

Returns coordinates of a train station.

***

#### `GetNearbyRoutes(routes, playerCoords, maxDistance)`

Returns nearby plane or boat routes within range.

***

### Ticket Sync (Server → Client)

#### `transport:client:addVisualTicket`

Adds a purchased ticket locally (train, plane, or boat).

***

#### `transport:client:removeVisualTicket`

Removes a ticket locally and updates UI.

***

### Ticket Validation

#### `CheckTicket(type, data)`

Checks with the server if the player owns a valid ticket.

**Returns:**

* `true` → Valid ticket
* `false` → Invalid / missing ticket

***

### Debug

#### `/debugtickets`

Prints owned tickets in F8 console.

***

### server/bridge.lua

This bridge handles all interactions between the transport system and your server's inventory provider. It manages the giving, checking, and removal of physical ticket items.

> \[!IMPORTANT] Custom Inventory Support: If your inventory is not supported by default (Ox or QB), you can simply add your custom logic inside the conditional blocks of the functions listed below.

***

#### `GiveTicketItem(src, itemType, metadata)`

This function grants a physical item to the player after a successful purchase.

* Ox Inventory: Uses `exports.ox_inventory:AddItem` with metadata.
* QB Inventory: Uses `Player.Functions.AddItem` and triggers the `ItemBox` UI.

#### `HasTicketItem(src, itemType, requiredData)`

Performs a check to see if the player owns a valid ticket without removing it.

* Logic: It iterates through the player's inventory and compares the metadata (stops for trains, or route/time for transport) against the requirements.
* Returns: The number of stops (for trains) or a boolean (for transport).

#### `RemoveTicketItem(src, itemType, requiredData)`

Validates the ticket and then consumes (deletes) it from the player's inventory.

* Validation: It ensures the ticket in the slot matches the specific route or has enough stops before removal.
* UI: Triggers framework-specific notifications (like QB's ItemBox) to show the item has been removed.

#### `CreateUsableItem(itemName, cb)`

Registers the item so that when a player "uses" it in their inventory, it triggers a visual preview of the ticket.

* Frameworks: Handles registration via `QBCore.Functions.CreateUseableItem`, `ESX.RegisterUsableItem`, or Ox Inventory's internal callback table.

***

#### How to add your own Inventory

If you are using a custom inventory system, locate these functions in the code and add a new `else` block like this:

```lua
local function GiveTicketItem(src, itemType, metadata)
    local itemName = Config.TicketItems[itemType]
    if Config.Inventory == 'ox' then
        return exports.ox_inventory:AddItem(src, itemName, 1, metadata)
    elseif Config.Inventory == 'qb' and QBCore then
        local Player = QBCore.Functions.GetPlayer(src)
        Player.Functions.AddItem(itemName, 1, nil, metadata)
        TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[itemName], "add")
        return true
    else
     -- add your inventory logic here
    end
    return false
end
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://enyo-scripts.gitbook.io/documentations/fivem-scripts/ai-transport/functions-events.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
