# Aviation — documentation

> A flight school and pilot contracts in one resource, paid by how well you land.

- URL: https://xexstudio.com/docs/aviation
- Version: 2.0.2
- Product page: https://xexstudio.com/scripts/aviation
Flight school and pilot contracts in one resource. Players earn their licenses with a theory test and practical
exams, then fly contracts that pay by distance and by how well they land. Every landing gets a score and a grade,
shown in a landing report. Pilots rank up and unlock bigger aircraft and better contracts. ESX, QBCore and Qbox.

Everything that grants money or a license is validated on the server: it spawns the aircraft, builds the route,
checks every stage against the aircraft's real position and timing, and calculates every payment.

## Features

- **Flight school:** theory test (questions never reach the client), helicopter exam (hover, circuit, landing on the
  pad) and plane exam (circuit and landing at the airport). Each exam needs a minimum landing score.
- **Four contract types:** scheduled passenger flights (round trip), VIP charters, air rescue against the clock and
  Cargobob sling loads.
- **Landing score:** 0–100 and a grade from S to F, from the vertical speed at touchdown, bounces and, on helipads,
  how close to the center the aircraft sets down. The grade multiplies the pay.
- **Progression:** XP for every landing, flight hours, ranks with a pay bonus that unlock aircraft classes and
  contract types. Logbook with the last flights.
- **Flightpad tablet:** contracts board, school and pilot profile in one UI. Brand name and accent color configurable.
- **In-flight HUD:** current stage, distance, timer, and altitude, vertical speed and speed near the ground.
- **Co-pilot:** a player in the co-pilot seat gets a share of every payment.
- **Rental with deposit:** contracts charge a rent and a refundable deposit that comes back minus damage.
- **Optimized:** no threads while nobody is flying; 10 checks per second in flight, every frame only on short final.
  Passengers are local peds: no network or server cost.
- **Modular:** turn the school or the contracts off. Contracts read licenses through the bridge, so they also work
  with another school.

## Requirements

- [ox_lib](https://github.com/overextended/ox_lib) and [oxmysql](https://github.com/overextended/oxmysql)
- One framework: **ESX** (with `esx_license`), **QBCore** or **Qbox**
- OneSync (on by default on current servers)

## Install

1. Drop `xex_aviation` into your resources folder.
2. **ESX only:** run `install/esx.sql` (adds the three license types). The pilot tables are created automatically.
3. Add to `server.cfg` after your framework, ox_lib and oxmysql:
   ```cfg
   ensure xex_aviation
   ```
4. Set the language with `setr ox:locale en` (or `es`).

## How it works

1. **Flight school** (blip at the airport): the player takes the theory test, then the helicopter and plane exams.
   Each exam spawns its own aircraft and is graded on the final landing.
2. **Flight Ops desk:** shows a board of contracts for that player. Locked ones say what is missing (license or rank).
   Accepting charges the rent and the deposit and puts the player in the aircraft.
3. **In flight:** the HUD shows the next stage. Passengers board and leave the aircraft at the parking spots, the
   casualty walks to the helicopter, the cargo is hooked and set down in the drop zone.
4. **Landing report:** after each landing, the score, the grade and the payment.
5. **Return:** handing the aircraft back returns the deposit minus damage and adds the flight to the logbook.

The tablet also opens anywhere with `/flightpad` (logbook and licenses). Contracts and exams only start at the desks.

## Configure

| File | What it contains |
| --- | --- |
| `config.lua` | All settings (table below) |
| `data/airfields.lua` | Airfields (landing area, stands, parking) and helipads |
| `data/routes.lua` | Exam routes, rescue sites and cargo jobs |
| `questions/<locale>.lua` | Theory questions (server only) |
| `locales/<locale>.json` | Every text: notifications, HUD and UI |
| `bridge/server.lua` | Framework, money, licenses, jobs, vehicle keys, fuel |
| `bridge/client.lua` | Client-side fuel resources, notifications |

| Setting | What it does |
| --- | --- |
| `Config.Framework` | `auto`, or force `esx` / `qb` / `qbox` |
| `Config.Accounts` | Account for exam fees, rent and deposit, and pay |
| `Config.Licenses` | License names. Change them to match your existing license system |
| `Config.UI` | Brand name, accent color, tablet command and optional key |
| `Config.Landing` | Vertical speed limits (ideal, hard, crash) for planes and helicopters, bounce penalty, weight of the helipad accuracy |
| `Config.Grades` | Score needed for each grade and its pay multiplier |
| `Config.Session` | Time allowed outside the aircraft, flight time limit, maximum plausible speed, plate prefix |
| `Config.School` | Location, theory test, and price, aircraft, minimum score, damage and time limit of each exam |
| `Config.Jobs` | Desks, board size and refresh, contracts per hour, cooldown, payment cap, co-pilot share, required job |
| `Config.Classes` | Aircraft classes: models, rent, deposit and rank needed |
| `Config.Contracts` | Each contract type: on/off, how often it appears, license, rank, classes and pay |
| `Config.Peds` | Models of passengers, VIPs and casualties |
| `Config.Progression` | XP per grade, XP for an exam, ranks with their pay bonus, logbook size |

### Pay

Every payment is calculated on the server:

```
(base + perKm × route km) × grade multiplier × type bonus × (1 + rank bonus)
```

The type bonus is the rescue time bonus (up to +30% when there is time left) or the cargo condition (a damaged load
pays less). A crash landing pays 30% of the normal rate. `Config.Jobs.maxPayout` caps any single payment.

### Existing licenses

If your server already has pilot licenses, put their names in `Config.Licenses` and players keep them:

```lua
Config.Licenses = { theory = 'pilot_theory', helicopter = 'helicopter', plane = 'aircraft' }
```

### Adding airfields, stands and helipads

Admins can run `/aviationtool point | stand | pad` in game. It prints a line ready to paste into `data/*.lua`
and copies it to the clipboard. Every airfield with a `parking` becomes a passenger destination, and every pad listed
in a desk's `helipads` lets one more helicopter contract run at the same time (the same goes for `stands` and planes).

### Keys and fuel

`bridge/server.lua` gives keys with `qbx_vehiclekeys` or `qb-vehiclekeys` and sets fuel for `ox_fuel`.
`bridge/client.lua` covers LegacyFuel, cdn-fuel and ps-fuel. Add your own resource there if it isn't listed.
Notifications go through `Bridge.Notify` in `bridge/client.lua`: swap `lib.notify` there for your own resource.

## Exports and events (server)

```lua
exports.xex_aviation:GetPilot(source)        -- { xp, rank, rankName, hours, flights, bestFpm, ... }
exports.xex_aviation:AddXP(source, amount)
exports.xex_aviation:HasPilotLicense(source, 'theory' | 'helicopter' | 'plane')
exports.xex_aviation:IsFlying(source)
```

| Event (server, local) | Arguments |
| --- | --- |
| `xex_aviation:flightStarted` | `source, { kind, type, route, model }` |
| `xex_aviation:flightCompleted` | `source, { kind, route, grade, score, fpm, payout, duration }` |
| `xex_aviation:licenseGranted` | `source, licenseKey, licenseName` |
| `xex_aviation:suspicious` | `source, reason, details` (e.g. impossible speed between two stages) |

Use them for battle passes, logs or your anticheat without editing the resource.

## FAQ

**Can I use only the contracts with my own flight school?**
Yes. Set `Config.School.enabled = false` and put your school's license names in `Config.Licenses`.

**Can I use only the school?**
Yes. Set `Config.Jobs.enabled = false`.

**Why does a contract say "every stand is taken"?**
Each stand or helipad holds one aircraft at a time. Add more with `/aviationtool stand` or `/aviationtool pad`.

**Can players fly their own aircraft?**
No. Contracts and exams use aircraft spawned by the server, so the route and the payment can be checked.

**Do other players see the passengers?**
No. Passengers are local to the pilot, which keeps the server and network free of extra peds.

**How do I switch from Pilot Jobs (xex_pilotjob)?**
Aviation replaces it. Stop `xex_pilotjob`, start `xex_aviation` and set `Config.Licenses` to the license names you
used (`LicenseNeeded` / `ExtraLicenseNeeded` in the old config).
