# esx_taxijob (/docs/addons/esx_taxijob)

esx_taxijob adds a `taxi` job: drivers spawn a cab at the depot, bill player passengers from an F6 menu, and run NPC fares that pick up a pedestrian and drive them to a random destination for a payout. It is the simplest official job addon and a good template for your own delivery-style jobs.

## Overview [#overview]

| | |
| --- | --- |
| Resource | `esx_taxijob` (version `1.0`) |
| Side | client + server |
| Job name | `taxi` (grades `recrue`, `novice`, `experimente`, `uber`, `boss`) |
| Society | `society_taxi`, registered as a public society |
| Dependencies (fxmanifest) | `esx_lib`, `es_extended` |
| Also required at runtime | `oxmysql`, [esx_society](/docs/addons/esx_society), [esx_addonaccount](/docs/addons/esx_addonaccount), [esx_addoninventory](/docs/addons/esx_addoninventory), [esx_datastore](/docs/addons/esx_datastore), [esx_billing](/docs/addons/esx_billing) |
| Optional | [esx_service](/docs/addons/esx_service) when `Config.MaxInService` is not `-1` |
| OneSync | Required. Vehicles are spawned server-side with `ESX.OneSync.SpawnVehicle`. |

### Depot markers [#depot-markers]

| Zone | Purpose |
| --- | --- |
| `TaxiActions` | Stock deposit and withdraw, and the boss menu for the `boss` grade. |
| `Cloakroom` | Switch between work and civilian clothes (from `job_grades` skins). |
| `VehicleSpawner` | Take out a cab. |
| `VehicleSpawnPoint` | Where the cab appears. |
| `VehicleDeleter` | Return the cab. |

## Installation [#installation]

<Steps>
<Step>
### Import the SQL [#import-the-sql]

Run `esx_taxijob.sql`. It creates the `society_taxi` account, datastore and inventory, and the `taxi` job with five grades and uniforms. Skip this if your database came from the ESX txAdmin recipe, which already contains these rows.
</Step>
<Step>
### Start it [#start-it]

```bash title="server.cfg"
ensure esx_society
ensure esx_billing
ensure esx_taxijob
```
</Step>
</Steps>

## Configuration [#configuration]

| Key | Default | Description |
| --- | --- | --- |
| `Config.DrawDistance` | `10.0` | Distance at which markers are drawn. |
| `Config.NPCJobEarnings` | `{ min = 300, max = 600 }` | Random total per NPC fare. Doubled for grade 3 and higher. |
| `Config.MinimumDistance` | `3000` | Minimum distance between pickup and drop-off, in GTA units. The server rejects shorter missions. |
| `Config.MaxInService` | `-1` | Service limit through esx_service. `-1` disables it. |
| `Config.EnablePlayerManagement` | `true` | Enables the boss menu and the F6 mobile menu. |
| `Config.EnableSocietyOwnedVehicles` | `false` | Take cabs from the esx_society vehicle garage instead of spawning `Config.AuthorizedVehicles`. |
| `Config.Locale` | `GetConvar('esx:locale', 'en')` | Language. |
| `Config.OxInventory` | `ESX.GetConfig().OxInventory` | Read from es_extended. |
| `Config.AuthorizedVehicles` | `{ { model = 'taxi', title = 'Taxi', icon = 'fas fa-car' } }` | Cabs offered at the spawner. Grades below 3 must drive one of these for NPC fares. |
| `Config.Zones` | see table above | `Pos`, `Size`, `Color`, `Type` and `Rotate` per marker. `VehicleSpawnPoint` also has a `Heading`. |
| `Config.JobLocations` | list of `vector3` | Possible NPC drop-off points. The server only accepts destinations within 5 units of one of them. |

```lua title="config.lua"
-- Offer a second cab model
Config.AuthorizedVehicles = {
    { model = 'taxi', title = 'Taxi', icon = 'fas fa-car' },
    { model = 'stretch', title = 'Limousine', icon = 'fas fa-car' },
}
```

## How NPC fares work [#how-npc-fares-work]

1. Open F6 and choose **Start NPC job** while driving an authorized cab (or any car at grade 3+).
2. The client finds a pedestrian, and when they get in, sends `esx_taxijob:startMission` with the pickup and destination.
3. The server stores the mission only if the destination is one of `Config.JobLocations`, the player is within 80 units of the pickup, and the trip is at least `Config.MinimumDistance` long.
4. At the destination the client sends `esx_taxijob:success`. The server pays only if the player is within 18 units of the stored drop-off, still in an authorized vehicle, and at least 10 seconds have passed since the last payout.

With the `society_taxi` account available the payout is split: 30% to the driver as cash and 70% to the society. Without it, the driver gets the full amount.

## Commands and keybinds [#commands-and-keybinds]

| Command | Default key | Description |
| --- | --- | --- |
| `taximenu` | `F6` | Opens the mobile taxi menu: bill the closest player, start or stop NPC fares. |

Depot markers use the `E` key (control 38).

## Server events [#server-events]

| Event | Arguments | Server checks |
| --- | --- | --- |
| `esx_taxijob:startMission` | `pickupCoords, dropoffCoords` | Taxi job, authorized vehicle, valid drop-off, distance rules. |
| `esx_taxijob:success` | none | Active mission, near drop-off, authorized vehicle, 10 second cooldown. |
| `esx_taxijob:getStockItem` | `itemName, count` | Taxi job, within 8 units of `TaxiActions`. |
| `esx_taxijob:putStockItems` | `itemName, count` | Taxi job, within 8 units of `TaxiActions`. |

`esx_taxijob:success` pays money, so it is the event an exploiter would spam. The mission state lives on the server, and the payout requires a stored mission, so calling it without a real fare only logs a warning.

## Server callbacks [#server-callbacks]

| Callback | Arguments | Returns |
| --- | --- | --- |
| `esx_taxijob:SpawnVehicle` | `model, props` | `true` if a cab was spawned. Requires the taxi job, the player within 15 units of `VehicleSpawner`, and a clear spawn point. |
| `esx_taxijob:getStockItems` | none | Items in `society_taxi`. |
| `esx_taxijob:getPlayerInventory` | none | `{ items = ... }` of the caller. |

## Integration tips [#integration-tips]

- Player fares from the F6 menu are sent through `esx_billing:sendBill` to `society_taxi`, so the society receives the money once the passenger pays.
- To adjust the 30/70 split, edit the `esx_taxijob:success` handler in `server/main.lua`. There is no config key for it.
- Add more drop-off points by appending `vector3` positions to `Config.JobLocations`. Keep them on roads so the AI passenger can walk away.

## Common issues [#common-issues]

- **Cab does not spawn.** The spawn point is blocked by another vehicle, OneSync is off, or the player is not near the spawner.
- **"Must be in a taxi" for a car that looks like a taxi.** Only exact models from `Config.AuthorizedVehicles` count for grades 0 to 2.
- **Fare never pays.** The destination must be within 18 units when you arrive. Stopping far from the marker or switching vehicles cancels the payout.

## Related [#related]

- [esx_society](/docs/addons/esx_society)
- [esx_billing](/docs/addons/esx_billing)
- [esx_service](/docs/addons/esx_service)
- [Create a job](/docs/guides/create-a-job)
